rat_quickdb/table/
schema.rs

1//! 表模式定义
2//!
3//! 定义表结构、列类型、索引和约束
4
5use crate::types::DataValue;
6use chrono::{DateTime, Utc};
7use serde::{Deserialize, Serialize};
8use std::collections::HashMap;
9
10/// 表模式定义
11#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
12pub struct TableSchema {
13    /// 表名
14    pub name: String,
15    /// 列定义
16    pub columns: Vec<ColumnDefinition>,
17    /// 索引定义
18    pub indexes: Vec<IndexDefinition>,
19    /// 约束定义
20    pub constraints: Vec<ConstraintDefinition>,
21    /// 表选项
22    pub options: TableOptions,
23    /// 模式版本
24    pub version: u32,
25    /// 创建时间
26    pub created_at: Option<chrono::DateTime<chrono::Utc>>,
27    /// 最后修改时间
28    pub updated_at: Option<chrono::DateTime<chrono::Utc>>,
29}
30
31/// 列定义
32#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
33pub struct ColumnDefinition {
34    /// 列名
35    pub name: String,
36    /// 列类型
37    pub column_type: ColumnType,
38    /// 是否可为空
39    pub nullable: bool,
40    /// 默认值
41    pub default_value: Option<String>,
42    /// 是否为主键
43    pub primary_key: bool,
44    /// 是否自增
45    pub auto_increment: bool,
46    /// 是否唯一
47    pub unique: bool,
48    /// 列注释
49    pub comment: Option<String>,
50    /// 列长度(用于字符串类型)
51    pub length: Option<u32>,
52    /// 精度(用于数值类型)
53    pub precision: Option<u32>,
54    /// 小数位数(用于数值类型)
55    pub scale: Option<u32>,
56}
57
58/// 列类型
59#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
60pub enum ColumnType {
61    /// 整数类型
62    Integer,
63    /// 大整数类型
64    BigInteger,
65    /// 小整数类型
66    SmallInteger,
67    /// 浮点数类型
68    Float,
69    /// 双精度浮点数类型
70    Double,
71    /// 精确数值类型
72    Decimal { precision: u32, scale: u32 },
73    /// 字符串类型
74    String { length: Option<u32> },
75    /// 文本类型
76    Text,
77    /// 长文本类型
78    LongText,
79    /// 布尔类型
80    Boolean,
81    /// 日期类型
82    Date,
83    /// 时间类型
84    Time,
85    /// 日期时间类型
86    DateTime,
87    /// 时间戳类型
88    Timestamp,
89    /// 二进制数据类型
90    Binary { length: Option<u32> },
91    /// 大二进制数据类型
92    Blob,
93    /// JSON类型
94    Json,
95    /// UUID类型
96    Uuid,
97    /// 枚举类型
98    Enum { values: Vec<String> },
99    /// 自定义类型
100    Custom { type_name: String },
101}
102
103/// 索引定义
104#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
105pub struct IndexDefinition {
106    /// 索引名
107    pub name: String,
108    /// 索引类型
109    pub index_type: IndexType,
110    /// 索引列
111    pub columns: Vec<String>,
112    /// 是否唯一
113    pub unique: bool,
114    /// 索引选项
115    pub options: HashMap<String, String>,
116}
117
118/// 索引类型
119#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
120pub enum IndexType {
121    /// B-Tree索引(默认)
122    BTree,
123    /// 哈希索引
124    Hash,
125    /// 全文索引
126    FullText,
127    /// 空间索引
128    Spatial,
129    /// 自定义索引类型
130    Custom(String),
131}
132
133/// 约束定义
134#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
135pub struct ConstraintDefinition {
136    /// 约束名
137    pub name: String,
138    /// 约束类型
139    pub constraint_type: ConstraintType,
140    /// 约束列
141    pub columns: Vec<String>,
142    /// 引用表(用于外键约束)
143    pub reference_table: Option<String>,
144    /// 引用列(用于外键约束)
145    pub reference_columns: Option<Vec<String>>,
146    /// 删除时的动作
147    pub on_delete: Option<ReferentialAction>,
148    /// 更新时的动作
149    pub on_update: Option<ReferentialAction>,
150    /// 检查条件(用于检查约束)
151    pub check_condition: Option<String>,
152}
153
154/// 约束类型
155#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
156pub enum ConstraintType {
157    /// 主键约束
158    PrimaryKey,
159    /// 外键约束
160    ForeignKey,
161    /// 唯一约束
162    Unique,
163    /// 检查约束
164    Check,
165    /// 非空约束
166    NotNull,
167}
168
169/// 引用动作
170#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
171pub enum ReferentialAction {
172    /// 级联
173    Cascade,
174    /// 设置为NULL
175    SetNull,
176    /// 设置为默认值
177    SetDefault,
178    /// 限制(默认)
179    Restrict,
180    /// 无动作
181    NoAction,
182}
183
184/// 表选项
185#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
186pub struct TableOptions {
187    /// 存储引擎(MySQL)
188    pub engine: Option<String>,
189    /// 字符集
190    pub charset: Option<String>,
191    /// 排序规则
192    pub collation: Option<String>,
193    /// 表注释
194    pub comment: Option<String>,
195    /// 自增起始值
196    pub auto_increment: Option<u64>,
197    /// 行格式
198    pub row_format: Option<String>,
199    /// 其他选项
200    pub extra_options: HashMap<String, String>,
201}
202
203impl Default for TableOptions {
204    fn default() -> Self {
205        Self {
206            engine: None,
207            charset: Some("utf8mb4".to_string()),
208            collation: Some("utf8mb4_unicode_ci".to_string()),
209            comment: None,
210            auto_increment: None,
211            row_format: None,
212            extra_options: HashMap::new(),
213        }
214    }
215}
216
217impl TableSchema {
218    /// 创建新的表模式
219    pub fn new(name: String) -> Self {
220        Self {
221            name,
222            columns: Vec::new(),
223            indexes: Vec::new(),
224            constraints: Vec::new(),
225            options: TableOptions::default(),
226            version: 1,
227            created_at: Some(chrono::Utc::now()),
228            updated_at: Some(chrono::Utc::now()),
229        }
230    }
231
232    /// 添加列
233    pub fn add_column(mut self, column: ColumnDefinition) -> Self {
234        self.columns.push(column);
235        self.updated_at = Some(chrono::Utc::now());
236        self
237    }
238
239    /// 添加索引
240    pub fn add_index(mut self, index: IndexDefinition) -> Self {
241        self.indexes.push(index);
242        self.updated_at = Some(chrono::Utc::now());
243        self
244    }
245
246    /// 添加约束
247    pub fn add_constraint(mut self, constraint: ConstraintDefinition) -> Self {
248        self.constraints.push(constraint);
249        self.updated_at = Some(chrono::Utc::now());
250        self
251    }
252
253    /// 设置表选项
254    pub fn with_options(mut self, options: TableOptions) -> Self {
255        self.options = options;
256        self.updated_at = Some(chrono::Utc::now());
257        self
258    }
259
260    /// 获取主键列
261    pub fn get_primary_key_columns(&self) -> Vec<&ColumnDefinition> {
262        self.columns.iter().filter(|col| col.primary_key).collect()
263    }
264
265    /// 检查列是否存在
266    pub fn has_column(&self, column_name: &str) -> bool {
267        self.columns.iter().any(|col| col.name == column_name)
268    }
269
270    /// 获取列定义
271    pub fn get_column(&self, column_name: &str) -> Option<&ColumnDefinition> {
272        self.columns.iter().find(|col| col.name == column_name)
273    }
274
275    /// 检查索引是否存在
276    pub fn has_index(&self, index_name: &str) -> bool {
277        self.indexes.iter().any(|idx| idx.name == index_name)
278    }
279
280    /// 获取索引定义
281    pub fn get_index(&self, index_name: &str) -> Option<&IndexDefinition> {
282        self.indexes.iter().find(|idx| idx.name == index_name)
283    }
284
285    /// 验证模式定义
286    pub fn validate(&self) -> Result<(), String> {
287        // 检查是否有列定义
288        if self.columns.is_empty() {
289            return Err("表必须至少有一个列".to_string());
290        }
291
292        // 检查列名是否重复
293        let mut column_names = std::collections::HashSet::new();
294        for column in &self.columns {
295            if !column_names.insert(&column.name) {
296                return Err(format!("列名 '{}' 重复", column.name));
297            }
298        }
299
300        // 检查索引名是否重复
301        let mut index_names = std::collections::HashSet::new();
302        for index in &self.indexes {
303            if !index_names.insert(&index.name) {
304                return Err(format!("索引名 '{}' 重复", index.name));
305            }
306
307            // 检查索引列是否存在
308            for column_name in &index.columns {
309                if !self.has_column(column_name) {
310                    return Err(format!(
311                        "索引 '{}' 引用的列 '{}' 不存在",
312                        index.name, column_name
313                    ));
314                }
315            }
316        }
317
318        // 检查约束名是否重复
319        let mut constraint_names = std::collections::HashSet::new();
320        for constraint in &self.constraints {
321            if !constraint_names.insert(&constraint.name) {
322                return Err(format!("约束名 '{}' 重复", constraint.name));
323            }
324
325            // 检查约束列是否存在
326            for column_name in &constraint.columns {
327                if !self.has_column(column_name) {
328                    return Err(format!(
329                        "约束 '{}' 引用的列 '{}' 不存在",
330                        constraint.name, column_name
331                    ));
332                }
333            }
334        }
335
336        Ok(())
337    }
338
339    /// 从数据字段推断表结构
340    pub fn infer_from_data(table_name: String, data: &HashMap<String, DataValue>) -> Self {
341        let mut columns = Vec::new();
342        let mut has_id_field = false;
343
344        // 根据数据字段推断列类型
345        for (field_name, field_value) in data {
346            if field_name == "id" {
347                has_id_field = true;
348                // 如果数据中包含id字段,对于Null值使用BigInteger类型,其他使用推断类型
349                let column_type = match field_value {
350                    DataValue::Null => ColumnType::BigInteger, // id字段为Null时默认使用BigInteger
351                    _ => Self::infer_column_type(field_value),
352                };
353                columns.push(ColumnDefinition {
354                    name: field_name.clone(),
355                    column_type,
356                    nullable: false, // 主键不能为空
357                    default_value: None,
358                    primary_key: true,
359                    auto_increment: matches!(field_value, DataValue::Int(_) | DataValue::Null), // 整数类型或Null都设置为自增
360                    unique: true,
361                    comment: Some("主键ID".to_string()),
362                    length: None,
363                    precision: None,
364                    scale: None,
365                });
366            } else {
367                let column_type = Self::infer_column_type(field_value);
368                columns.push(ColumnDefinition {
369                    name: field_name.clone(),
370                    column_type,
371                    nullable: matches!(field_value, DataValue::Null),
372                    default_value: None,
373                    primary_key: false,
374                    auto_increment: false,
375                    unique: false,
376                    comment: None,
377                    length: None,
378                    precision: None,
379                    scale: None,
380                });
381            }
382        }
383
384        // 如果数据中没有id字段,添加默认的id主键列
385        if !has_id_field {
386            columns.insert(
387                0,
388                ColumnDefinition {
389                    name: "id".to_string(),
390                    column_type: ColumnType::BigInteger,
391                    nullable: false,
392                    default_value: None,
393                    primary_key: true,
394                    auto_increment: true,
395                    unique: true,
396                    comment: Some("主键ID".to_string()),
397                    length: None,
398                    precision: None,
399                    scale: None,
400                },
401            );
402        }
403
404        Self {
405            name: table_name,
406            columns,
407            indexes: Vec::new(),
408            constraints: Vec::new(),
409            options: TableOptions::default(),
410            version: 1,
411            created_at: Some(chrono::Utc::now()),
412            updated_at: Some(chrono::Utc::now()),
413        }
414    }
415
416    /// 从DataValue推断列类型
417    fn infer_column_type(value: &DataValue) -> ColumnType {
418        match value {
419            DataValue::Null => ColumnType::String { length: Some(255) }, // 默认为字符串
420            DataValue::Bool(_) => ColumnType::Boolean,
421            DataValue::Int(_) => ColumnType::BigInteger,
422            DataValue::UInt(_) => ColumnType::BigInteger,
423            DataValue::Float(_) => ColumnType::Double,
424            DataValue::String(s) => {
425                // 根据字符串长度决定类型
426                if s.len() > 65535 {
427                    ColumnType::LongText
428                } else if s.len() > 255 {
429                    ColumnType::Text
430                } else {
431                    ColumnType::String { length: Some(255) }
432                }
433            }
434            DataValue::Bytes(_) => ColumnType::Blob,
435            DataValue::DateTime(_) => ColumnType::DateTime,
436            DataValue::DateTimeUTC(_) => ColumnType::DateTime,
437            DataValue::Uuid(_) => ColumnType::Uuid,
438            DataValue::Json(_) => ColumnType::Json,
439            DataValue::Array(_) => ColumnType::Json, // 数组存储为JSON
440            DataValue::Object(_) => ColumnType::Json, // 对象存储为JSON
441        }
442    }
443}
444
445impl ColumnDefinition {
446    /// 创建新的列定义
447    pub fn new(name: String, column_type: ColumnType) -> Self {
448        Self {
449            name,
450            column_type,
451            nullable: true,
452            default_value: None,
453            primary_key: false,
454            auto_increment: false,
455            unique: false,
456            comment: None,
457            length: None,
458            precision: None,
459            scale: None,
460        }
461    }
462
463    /// 设置为主键
464    pub fn primary_key(mut self) -> Self {
465        self.primary_key = true;
466        self.nullable = false;
467        self
468    }
469
470    /// 设置为非空
471    pub fn not_null(mut self) -> Self {
472        self.nullable = false;
473        self
474    }
475
476    /// 设置为唯一
477    pub fn unique(mut self) -> Self {
478        self.unique = true;
479        self
480    }
481
482    /// 设置为自增
483    pub fn auto_increment(mut self) -> Self {
484        self.auto_increment = true;
485        self.nullable = false;
486        self
487    }
488
489    /// 设置默认值
490    pub fn default_value<T: ToString>(mut self, value: T) -> Self {
491        self.default_value = Some(value.to_string());
492        self
493    }
494
495    /// 设置注释
496    pub fn comment<T: ToString>(mut self, comment: T) -> Self {
497        self.comment = Some(comment.to_string());
498        self
499    }
500}
501
502impl IndexDefinition {
503    /// 创建新的索引定义
504    pub fn new(name: String, columns: Vec<String>) -> Self {
505        Self {
506            name,
507            index_type: IndexType::BTree,
508            columns,
509            unique: false,
510            options: HashMap::new(),
511        }
512    }
513
514    /// 设置为唯一索引
515    pub fn unique(mut self) -> Self {
516        self.unique = true;
517        self
518    }
519
520    /// 设置索引类型
521    pub fn index_type(mut self, index_type: IndexType) -> Self {
522        self.index_type = index_type;
523        self
524    }
525
526    /// 添加选项
527    pub fn option<K: ToString, V: ToString>(mut self, key: K, value: V) -> Self {
528        self.options.insert(key.to_string(), value.to_string());
529        self
530    }
531}
532
533impl ConstraintDefinition {
534    /// 创建主键约束
535    pub fn primary_key(name: String, columns: Vec<String>) -> Self {
536        Self {
537            name,
538            constraint_type: ConstraintType::PrimaryKey,
539            columns,
540            reference_table: None,
541            reference_columns: None,
542            on_delete: None,
543            on_update: None,
544            check_condition: None,
545        }
546    }
547
548    /// 创建外键约束
549    pub fn foreign_key(
550        name: String,
551        columns: Vec<String>,
552        reference_table: String,
553        reference_columns: Vec<String>,
554    ) -> Self {
555        Self {
556            name,
557            constraint_type: ConstraintType::ForeignKey,
558            columns,
559            reference_table: Some(reference_table),
560            reference_columns: Some(reference_columns),
561            on_delete: Some(ReferentialAction::Restrict),
562            on_update: Some(ReferentialAction::Restrict),
563            check_condition: None,
564        }
565    }
566
567    /// 创建唯一约束
568    pub fn unique(name: String, columns: Vec<String>) -> Self {
569        Self {
570            name,
571            constraint_type: ConstraintType::Unique,
572            columns,
573            reference_table: None,
574            reference_columns: None,
575            on_delete: None,
576            on_update: None,
577            check_condition: None,
578        }
579    }
580
581    /// 创建检查约束
582    pub fn check(name: String, condition: String) -> Self {
583        Self {
584            name,
585            constraint_type: ConstraintType::Check,
586            columns: Vec::new(),
587            reference_table: None,
588            reference_columns: None,
589            on_delete: None,
590            on_update: None,
591            check_condition: Some(condition),
592        }
593    }
594
595    /// 设置删除时的动作
596    pub fn on_delete(mut self, action: ReferentialAction) -> Self {
597        self.on_delete = Some(action);
598        self
599    }
600
601    /// 设置更新时的动作
602    pub fn on_update(mut self, action: ReferentialAction) -> Self {
603        self.on_update = Some(action);
604        self
605    }
606}