Skip to main content

cqlite_core/schema/discovery/
model.rs

1//! Shared data model for schema discovery.
2//!
3//! Configuration, the discovered-schema representation, type metadata, and
4//! validation/metric result types used across the discovery submodules.
5
6use std::collections::HashMap;
7use std::path::PathBuf;
8use std::time::SystemTime;
9
10use serde::{Deserialize, Serialize};
11
12use crate::{parser::header::CassandraVersion, schema::ClusteringColumn, types::Value};
13
14/// Enhanced schema discovery configuration
15#[derive(Debug, Clone)]
16pub struct SchemaDiscoveryConfig {
17    /// Maximum number of rows to sample for type inference
18    pub max_sample_rows: usize,
19    /// Enable aggressive type inference
20    pub aggressive_inference: bool,
21    /// Cache discovered schemas
22    pub enable_schema_cache: bool,
23    /// Schema cache TTL in seconds
24    pub cache_ttl_seconds: u64,
25    /// Enable schema versioning
26    pub enable_versioning: bool,
27    /// Maximum schema versions to keep
28    pub max_versions: usize,
29    /// Enable UDT discovery
30    pub enable_udt_discovery: bool,
31    /// Enable collection type analysis
32    pub enable_collection_analysis: bool,
33    /// Enable index discovery
34    pub enable_index_discovery: bool,
35    /// Enable cross-file validation
36    pub enable_cross_file_validation: bool,
37    /// Minimum confidence threshold for type inference
38    pub min_confidence_threshold: f64,
39}
40
41impl Default for SchemaDiscoveryConfig {
42    fn default() -> Self {
43        Self {
44            max_sample_rows: 2000,
45            aggressive_inference: true,
46            enable_schema_cache: true,
47            cache_ttl_seconds: 3600, // 1 hour
48            enable_versioning: true,
49            max_versions: 10,
50            enable_udt_discovery: true,
51            enable_collection_analysis: true,
52            enable_index_discovery: true,
53            enable_cross_file_validation: true,
54            min_confidence_threshold: 0.7,
55        }
56    }
57}
58
59/// Comprehensive schema information extracted from SSTables
60#[derive(Debug, Clone, Serialize, Deserialize)]
61pub struct SchemaInfo {
62    /// Keyspace name
63    pub keyspace: String,
64    /// Table name
65    pub table: String,
66    /// Partition key columns with ordering
67    pub partition_key: Vec<ColumnDefinition>,
68    /// Clustering key columns with ordering
69    pub clustering_keys: Vec<ClusteringColumn>,
70    /// Regular data columns
71    pub regular_columns: Vec<ColumnDefinition>,
72    /// Static columns (if any)
73    pub static_columns: Vec<ColumnDefinition>,
74    /// Collection type definitions
75    pub collection_types: HashMap<String, CollectionType>,
76    /// User-defined type definitions
77    pub user_defined_types: Vec<UDTDefinition>,
78    /// Secondary index definitions
79    pub indexes: Vec<IndexDefinition>,
80    /// Table configuration options
81    pub table_options: TableOptions,
82    /// Schema discovery metadata
83    pub metadata: SchemaMetadata,
84}
85
86/// Enhanced column definition with Cassandra-specific details
87#[derive(Debug, Clone, Serialize, Deserialize)]
88pub struct ColumnDefinition {
89    /// Column name
90    pub name: String,
91    /// CQL data type
92    pub data_type: String,
93    /// Parsed type information
94    pub type_info: TypeInfo,
95    /// Whether column accepts null values
96    pub nullable: bool,
97    /// Whether column is static (for clustering tables)
98    pub is_static: bool,
99    /// Default value if specified
100    pub default_value: Option<Value>,
101    /// Column position in table definition
102    pub position: usize,
103    /// Type inference confidence (0.0 - 1.0)
104    pub confidence: f64,
105}
106
107/// Detailed type information for complex types
108#[derive(Debug, Clone, Serialize, Deserialize)]
109pub struct TypeInfo {
110    /// Base type ID as string representation
111    pub type_id: String,
112    /// Type parameters for generic types
113    pub type_params: Vec<String>,
114    /// Whether type is frozen
115    pub is_frozen: bool,
116    /// Element type for collections
117    pub element_type: Option<Box<TypeInfo>>,
118    /// Key type for maps
119    pub key_type: Option<Box<TypeInfo>>,
120    /// Value type for maps
121    pub value_type: Option<Box<TypeInfo>>,
122    /// UDT field definitions if this is a UDT
123    pub udt_fields: Option<Vec<UdtFieldInfo>>,
124    /// Tuple element types if this is a tuple
125    pub tuple_elements: Option<Vec<TypeInfo>>,
126}
127
128/// UDT field information
129#[derive(Debug, Clone, Serialize, Deserialize)]
130pub struct UdtFieldInfo {
131    /// Field name
132    pub name: String,
133    /// Field type
134    pub field_type: TypeInfo,
135    /// Whether field is nullable
136    pub nullable: bool,
137}
138
139/// Collection type definition
140#[derive(Debug, Clone, Serialize, Deserialize)]
141pub struct CollectionType {
142    /// Collection kind (list, set, map)
143    pub kind: CollectionKind,
144    /// Element type for lists and sets
145    pub element_type: Option<String>,
146    /// Key type for maps
147    pub key_type: Option<String>,
148    /// Value type for maps
149    pub value_type: Option<String>,
150    /// Whether the collection is frozen
151    pub is_frozen: bool,
152}
153
154/// Collection kind enumeration
155#[derive(Debug, Clone, Serialize, Deserialize)]
156pub enum CollectionKind {
157    List,
158    Set,
159    Map,
160    Tuple,
161}
162
163/// User-defined type definition
164#[derive(Debug, Clone, Serialize, Deserialize)]
165pub struct UDTDefinition {
166    /// UDT name
167    pub name: String,
168    /// Keyspace where UDT is defined
169    pub keyspace: String,
170    /// Field definitions
171    pub fields: Vec<UdtFieldDefinition>,
172    /// Version when UDT was created
173    pub version: Option<u32>,
174}
175
176/// UDT field definition
177#[derive(Debug, Clone, Serialize, Deserialize)]
178pub struct UdtFieldDefinition {
179    /// Field name
180    pub name: String,
181    /// Field type
182    pub field_type: String,
183    /// Field position
184    pub position: usize,
185    /// Whether field is nullable
186    pub nullable: bool,
187}
188
189/// Secondary index definition
190#[derive(Debug, Clone, Serialize, Deserialize)]
191pub struct IndexDefinition {
192    /// Index name
193    pub name: String,
194    /// Target column
195    pub target_column: String,
196    /// Index type
197    pub index_type: IndexType,
198    /// Index options
199    pub options: HashMap<String, String>,
200}
201
202/// Index type enumeration
203#[derive(Debug, Clone, Serialize, Deserialize)]
204pub enum IndexType {
205    /// Regular secondary index
206    Secondary,
207    /// Composite index
208    Composite,
209    /// Custom index
210    Custom(String),
211}
212
213/// Table configuration options
214#[derive(Debug, Clone, Serialize, Deserialize)]
215pub struct TableOptions {
216    /// Compaction strategy
217    pub compaction: Option<CompactionStrategy>,
218    /// Compression options
219    pub compression: Option<CompressionOptions>,
220    /// Cache settings
221    pub caching: Option<CachingOptions>,
222    /// Bloom filter settings
223    pub bloom_filter_fp_chance: Option<f64>,
224    /// GC grace seconds
225    pub gc_grace_seconds: Option<u32>,
226    /// Default time to live
227    pub default_time_to_live: Option<u32>,
228    /// Memtable flush period
229    pub memtable_flush_period_in_ms: Option<u32>,
230    /// Additional properties
231    pub additional_properties: HashMap<String, String>,
232}
233
234/// Compaction strategy information
235#[derive(Debug, Clone, Serialize, Deserialize)]
236pub struct CompactionStrategy {
237    /// Strategy class name
238    pub class: String,
239    /// Strategy options
240    pub options: HashMap<String, String>,
241}
242
243/// Compression options
244#[derive(Debug, Clone, Serialize, Deserialize)]
245pub struct CompressionOptions {
246    /// Compression algorithm
247    pub algorithm: String,
248    /// Chunk length
249    pub chunk_length_kb: Option<u32>,
250    /// CRC check chance
251    pub crc_check_chance: Option<f32>,
252}
253
254/// Caching options
255#[derive(Debug, Clone, Serialize, Deserialize)]
256pub struct CachingOptions {
257    /// Keys cache setting
258    pub keys: String,
259    /// Rows cache setting
260    pub rows_per_partition: String,
261}
262
263/// Schema discovery metadata
264#[derive(Debug, Clone, Serialize, Deserialize)]
265pub struct SchemaMetadata {
266    /// When schema was discovered
267    pub discovered_at: SystemTime,
268    /// Source SSTable files
269    pub source_files: Vec<PathBuf>,
270    /// Total rows sampled across all files
271    pub total_rows_sampled: usize,
272    /// Cassandra version detected
273    pub cassandra_version: Option<CassandraVersion>,
274    /// Discovery method used
275    pub discovery_method: DiscoveryMethod,
276    /// Schema version
277    pub version: u32,
278    /// Validation results
279    pub validation_results: ValidationResults,
280    /// Discovery performance metrics
281    pub performance_metrics: DiscoveryMetrics,
282}
283
284/// Schema discovery method
285#[derive(Debug, Clone, Serialize, Deserialize)]
286pub enum DiscoveryMethod {
287    /// Extracted from SSTable header metadata
288    HeaderMetadata,
289    /// Inferred from data sampling and analysis
290    DataSampling,
291    /// Combination of header metadata and data sampling
292    Hybrid,
293    /// From external schema definition file
294    External,
295}
296
297/// Schema validation results
298#[derive(Debug, Clone, Serialize, Deserialize)]
299pub struct ValidationResults {
300    /// Overall validation status
301    pub status: ValidationStatus,
302    /// Validation errors
303    pub errors: Vec<ValidationError>,
304    /// Validation warnings
305    pub warnings: Vec<ValidationWarning>,
306    /// Cross-file consistency results
307    pub consistency_results: ConsistencyResults,
308}
309
310/// Validation status
311#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
312pub enum ValidationStatus {
313    /// Schema is valid and consistent
314    Valid,
315    /// Schema has minor issues but is usable
316    ValidWithWarnings,
317    /// Schema has significant issues
318    Invalid,
319    /// Schema validation failed
320    ValidationFailed,
321}
322
323/// Validation error
324#[derive(Debug, Clone, Serialize, Deserialize)]
325pub struct ValidationError {
326    /// Error type
327    pub error_type: ValidationErrorType,
328    /// Error message
329    pub message: String,
330    /// Affected column or component
331    pub component: Option<String>,
332    /// Source file where error was found
333    pub source_file: Option<PathBuf>,
334}
335
336/// Validation error types
337#[derive(Debug, Clone, Serialize, Deserialize)]
338pub enum ValidationErrorType {
339    /// Type mismatch between files
340    TypeMismatch,
341    /// Missing required component
342    MissingComponent,
343    /// Invalid type definition
344    InvalidTypeDefinition,
345    /// Constraint violation
346    ConstraintViolation,
347    /// UDT definition inconsistency
348    UdtInconsistency,
349    /// Index definition error
350    IndexError,
351}
352
353/// Validation warning
354#[derive(Debug, Clone, Serialize, Deserialize)]
355pub struct ValidationWarning {
356    /// Warning type
357    pub warning_type: ValidationWarningType,
358    /// Warning message
359    pub message: String,
360    /// Affected component
361    pub component: Option<String>,
362}
363
364/// Validation warning types
365#[derive(Debug, Clone, Serialize, Deserialize)]
366pub enum ValidationWarningType {
367    /// Low confidence type inference
368    LowConfidence,
369    /// Deprecated feature usage
370    DeprecatedFeature,
371    /// Version compatibility issue
372    VersionCompatibility,
373    /// Performance recommendation
374    PerformanceRecommendation,
375}
376
377/// Cross-file consistency results
378#[derive(Debug, Clone, Serialize, Deserialize)]
379pub struct ConsistencyResults {
380    /// Files analyzed
381    pub files_analyzed: usize,
382    /// Schema mismatches found
383    pub schema_mismatches: usize,
384    /// Type inconsistencies
385    pub type_inconsistencies: Vec<TypeInconsistency>,
386    /// UDT definition conflicts
387    pub udt_conflicts: Vec<UdtConflict>,
388}
389
390/// Type inconsistency information
391#[derive(Debug, Clone, Serialize, Deserialize)]
392pub struct TypeInconsistency {
393    /// Column name
394    pub column_name: String,
395    /// Conflicting type definitions
396    pub conflicting_types: Vec<String>,
397    /// Files with different definitions
398    pub conflicting_files: Vec<PathBuf>,
399}
400
401/// UDT definition conflict
402#[derive(Debug, Clone, Serialize, Deserialize)]
403pub struct UdtConflict {
404    /// UDT name
405    pub udt_name: String,
406    /// Conflicting field definitions
407    pub field_conflicts: Vec<FieldConflict>,
408    /// Files with conflicts
409    pub conflicting_files: Vec<PathBuf>,
410}
411
412/// UDT field conflict
413#[derive(Debug, Clone, Serialize, Deserialize)]
414pub struct FieldConflict {
415    /// Field name
416    pub field_name: String,
417    /// Conflicting types
418    pub conflicting_types: Vec<String>,
419}
420
421/// Discovery performance metrics
422#[derive(Debug, Clone, Serialize, Deserialize)]
423pub struct DiscoveryMetrics {
424    /// Total discovery time in milliseconds
425    pub total_time_ms: u64,
426    /// Time spent on header parsing
427    pub header_parsing_time_ms: u64,
428    /// Time spent on data sampling
429    pub data_sampling_time_ms: u64,
430    /// Time spent on type inference
431    pub type_inference_time_ms: u64,
432    /// Time spent on validation
433    pub validation_time_ms: u64,
434    /// Memory usage peak during discovery
435    pub peak_memory_usage_bytes: usize,
436}