silent_db/core/
fields.rs

1pub trait FieldType {
2    fn get_type_str(&self) -> String;
3}
4
5pub trait Field {
6    fn get_name(&self) -> String;
7    fn get_type(&self) -> Box<dyn FieldType>;
8    fn get_default(&self) -> Option<String> {
9        None
10    }
11    fn get_nullable(&self) -> bool {
12        true
13    }
14    fn get_primary_key(&self) -> bool {
15        false
16    }
17    fn get_unique(&self) -> bool {
18        false
19    }
20    fn get_auto_increment(&self) -> bool {
21        false
22    }
23    fn get_comment(&self) -> Option<String> {
24        None
25    }
26    fn get_create_sql(&self) -> String {
27        let mut sql = format!("`{}` {}", self.get_name(), self.get_type().get_type_str());
28        if let Some(default) = self.get_default() {
29            sql.push_str(&format!(" DEFAULT {}", default));
30        }
31        if !self.get_nullable() {
32            sql.push_str(" NOT NULL");
33        }
34        if self.get_primary_key() {
35            sql.push_str(" PRIMARY KEY");
36        }
37        if self.get_unique() {
38            sql.push_str(" UNIQUE");
39        }
40        if self.get_auto_increment() {
41            sql.push_str(" AUTO_INCREMENT");
42        }
43        if let Some(comment) = self.get_comment() {
44            sql.push_str(&format!(" COMMENT '{}'", comment));
45        }
46        sql
47    }
48}
49
50#[cfg(test)]
51mod tests {
52    use super::*;
53    use serde::{Deserialize, Serialize};
54
55    #[derive(Debug, Serialize, Deserialize, Eq, PartialEq)]
56    struct TestIntField {
57        name: String,
58        default: Option<String>,
59        nullable: bool,
60        primary_key: bool,
61        unique: bool,
62        auto_increment: bool,
63        comment: Option<String>,
64    }
65
66    impl Field for TestIntField {
67        fn get_name(&self) -> String {
68            self.name.clone()
69        }
70        fn get_type(&self) -> Box<dyn FieldType> {
71            Box::new(IntType)
72        }
73        fn get_default(&self) -> Option<String> {
74            self.default.clone()
75        }
76        fn get_nullable(&self) -> bool {
77            self.nullable
78        }
79        fn get_primary_key(&self) -> bool {
80            self.primary_key
81        }
82        fn get_unique(&self) -> bool {
83            self.unique
84        }
85        fn get_auto_increment(&self) -> bool {
86            self.auto_increment
87        }
88        fn get_comment(&self) -> Option<String> {
89            self.comment.clone()
90        }
91    }
92
93    struct IntType;
94
95    impl FieldType for IntType {
96        fn get_type_str(&self) -> String {
97            "INT".to_string()
98        }
99    }
100
101    #[test]
102    fn test_int_field() {
103        let field = TestIntField {
104            name: "id".to_string(),
105            default: None,
106            nullable: false,
107            primary_key: true,
108            unique: true,
109            auto_increment: true,
110            comment: Some("ID".to_string()),
111        };
112        assert_eq!(field.get_name(), "id");
113        assert_eq!(field.get_type().get_type_str(), "INT");
114        assert_eq!(
115            field.get_create_sql(),
116            "`id` INT NOT NULL PRIMARY KEY UNIQUE AUTO_INCREMENT COMMENT 'ID'"
117        );
118    }
119}