silent_db/core/
indices.rs

1pub trait IndexTypeTrait {
2    fn get_type_str(&self) -> String;
3}
4
5#[derive(Debug, Clone, Eq, PartialEq)]
6pub enum IndexSort {
7    ASC,
8    DESC,
9}
10
11impl IndexSort {
12    pub fn to_str(&self) -> &str {
13        match self {
14            IndexSort::ASC => "ASC",
15            IndexSort::DESC => "DESC",
16        }
17    }
18}
19
20pub trait IndexTrait {
21    fn get_alias(&self) -> Option<String>;
22    fn get_type(&self) -> Box<dyn IndexTypeTrait>;
23    fn get_fields(&self) -> Vec<String>;
24    fn get_sort(&self) -> IndexSort {
25        IndexSort::ASC
26    }
27    fn get_create_sql(&self) -> String {
28        if self.get_fields().is_empty() {
29            panic!("Index fields is empty");
30        }
31        let fields = self
32            .get_fields()
33            .iter()
34            .map(|f| format!("`{}`", f))
35            .collect::<Vec<String>>()
36            .join(",");
37        let mut sql = self.get_type().get_type_str().to_string();
38        if let Some(alias) = self.get_alias() {
39            sql.push_str(&format!(" `{}`", alias));
40        }
41        sql.push_str(&format!(" ({})", fields));
42        sql.push_str(&format!(" {}", self.get_sort().to_str()));
43        sql
44    }
45}
46
47#[cfg(test)]
48mod tests {
49    use super::*;
50
51    #[derive(Debug, Eq, PartialEq)]
52    struct TestIndex {
53        alias: Option<String>,
54        index_type: TestIndexType,
55        fields: Vec<String>,
56        sort: IndexSort,
57    }
58
59    impl IndexTrait for TestIndex {
60        fn get_alias(&self) -> Option<String> {
61            self.alias.clone()
62        }
63
64        fn get_type(&self) -> Box<dyn IndexTypeTrait> {
65            Box::new(self.index_type.clone())
66        }
67
68        fn get_fields(&self) -> Vec<String> {
69            self.fields.clone()
70        }
71
72        fn get_sort(&self) -> IndexSort {
73            self.sort.clone()
74        }
75    }
76
77    #[allow(dead_code)]
78    #[derive(Debug, Clone, Eq, PartialEq)]
79    pub enum TestIndexType {
80        Unique,
81        Index,
82        FullText,
83        Spatial,
84    }
85
86    impl IndexTypeTrait for TestIndexType {
87        fn get_type_str(&self) -> String {
88            match self {
89                TestIndexType::Unique => "UNIQUE KEY",
90                TestIndexType::Index => "INDEX",
91                TestIndexType::FullText => "FULLTEXT KEY",
92                TestIndexType::Spatial => "SPATIAL KEY",
93            }
94            .to_string()
95        }
96    }
97
98    #[test]
99    fn test_int_field() {
100        let index = TestIndex {
101            alias: Some("idx".to_string()),
102            index_type: TestIndexType::Unique,
103            fields: vec!["id".to_string()],
104            sort: IndexSort::ASC,
105        };
106        assert_eq!(index.get_alias().unwrap(), "idx");
107        assert_eq!(index.get_fields(), vec!["id"]);
108        assert_eq!(index.get_type().get_type_str(), "UNIQUE KEY");
109        assert_eq!(index.get_create_sql(), "UNIQUE KEY `idx` (`id`) ASC");
110    }
111}