teo_runtime/database/
type.rs

1use serde::Serialize;
2use teo_parser::availability::Availability;
3use crate::database::mongo::r#type::MongoDBType;
4use crate::database::mysql::r#type::MySQLType;
5use crate::database::postgres::r#type::PostgreSQLType;
6use crate::database::sqlite::r#type::SQLiteType;
7use crate::value::interface_enum_variant::InterfaceEnumVariant;
8use teo_result::{Result, Error};
9
10#[derive(Debug, Serialize, Clone, PartialEq, Eq, Hash)]
11pub enum DatabaseType {
12    Undetermined,
13    MySQLType(MySQLType),
14    PostgreSQLType(PostgreSQLType),
15    SQLiteType(SQLiteType),
16    MongoDBType(MongoDBType),
17}
18
19impl DatabaseType {
20
21    pub fn is_undetermined(&self) -> bool {
22        match self {
23            DatabaseType::Undetermined => true,
24            _ => false,
25        }
26    }
27
28    pub fn is_mysql(&self) -> bool {
29        self.as_mysql().is_some()
30    }
31
32    pub fn as_mysql(&self) -> Option<&MySQLType> {
33        match self {
34            DatabaseType::MySQLType(t) => Some(t),
35            _ => None,
36        }
37    }
38
39    pub fn is_postgres(&self) -> bool {
40        self.as_postgres().is_some()
41    }
42
43    pub fn as_postgres(&self) -> Option<&PostgreSQLType> {
44        match self {
45            DatabaseType::PostgreSQLType(t) => Some(t),
46            _ => None,
47        }
48    }
49
50    pub fn is_sqlite(&self) -> bool {
51        self.as_sqlite().is_some()
52    }
53
54    pub fn as_sqlite(&self) -> Option<&SQLiteType> {
55        match self {
56            DatabaseType::SQLiteType(t) => Some(t),
57            _ => None,
58        }
59    }
60
61    pub fn is_mongo(&self) -> bool {
62        self.as_mongo().is_some()
63    }
64
65    pub fn as_mongo(&self) -> Option<&MongoDBType> {
66        match self {
67            DatabaseType::MongoDBType(t) => Some(t),
68            _ => None,
69        }
70    }
71
72    pub fn from_interface_enum_variant(interface_enum_variant: &InterfaceEnumVariant, availability: Availability) -> Result<Self> {
73        if availability == Availability::mysql() {
74            match interface_enum_variant.value.as_str() {
75                "varChar" => {
76                    let len: i32 = interface_enum_variant.args.as_ref().unwrap().get("len")?;
77                    Ok(DatabaseType::MySQLType(MySQLType::VarChar(len)))
78                },
79                "text" => Ok(DatabaseType::MySQLType(MySQLType::Text)),
80                "char" => {
81                    let len: i32 = interface_enum_variant.args.as_ref().unwrap().get("len")?;
82                    Ok(DatabaseType::MySQLType(MySQLType::Char(len)))
83                },
84                "tinyText" => Ok(DatabaseType::MySQLType(MySQLType::TinyText)),
85                "mediumText" => Ok(DatabaseType::MySQLType(MySQLType::MediumText)),
86                "longText" => Ok(DatabaseType::MySQLType(MySQLType::LongText)),
87                "bit" => {
88                    let len: i32 = interface_enum_variant.args.as_ref().unwrap().get("len")?;
89                    Ok(DatabaseType::MySQLType(MySQLType::Bit(Some(len))))
90                },
91                "tinyInt" => {
92                    let len: i32 = interface_enum_variant.args.as_ref().unwrap().get("len")?;
93                    let signed: bool = interface_enum_variant.args.as_ref().unwrap().get("signed")?;
94                    Ok(DatabaseType::MySQLType(MySQLType::TinyInt(Some(len), signed)))
95                },
96                "int" => {
97                    let len: Option<i32> = interface_enum_variant.args.as_ref().unwrap().get_optional("len")?;
98                    let signed: bool = interface_enum_variant.args.as_ref().unwrap().get("signed")?;
99                    Ok(DatabaseType::MySQLType(MySQLType::Int(len, signed)))
100                },
101                "smallInt" => {
102                    let len: Option<i32> = interface_enum_variant.args.as_ref().unwrap().get_optional("len")?;
103                    let signed: bool = interface_enum_variant.args.as_ref().unwrap().get("signed")?;
104                    Ok(DatabaseType::MySQLType(MySQLType::SmallInt(len, signed)))
105                },
106                "mediumInt" => {
107                    let len: Option<i32> = interface_enum_variant.args.as_ref().unwrap().get_optional("len")?;
108                    let signed: bool = interface_enum_variant.args.as_ref().unwrap().get("signed")?;
109                    Ok(DatabaseType::MySQLType(MySQLType::MediumInt(len, signed)))
110                },
111                "bigInt" => {
112                    let len: Option<i32> = interface_enum_variant.args.as_ref().unwrap().get_optional("len")?;
113                    let signed: bool = interface_enum_variant.args.as_ref().unwrap().get("signed")?;
114                    Ok(DatabaseType::MySQLType(MySQLType::BigInt(len, signed)))
115                },
116                "year" => Ok(DatabaseType::MySQLType(MySQLType::Year)),
117                "float" => Ok(DatabaseType::MySQLType(MySQLType::Float)),
118                "double" => Ok(DatabaseType::MySQLType(MySQLType::Double)),
119                "decimal" => {
120                    let precision: i32 = interface_enum_variant.args.as_ref().unwrap().get("precision")?;
121                    let scale: i32 = interface_enum_variant.args.as_ref().unwrap().get("scale")?;
122                    Ok(DatabaseType::MySQLType(MySQLType::Decimal(precision, scale)))
123                },
124                "dateTime" => {
125                    let len: i32 = interface_enum_variant.args.as_ref().unwrap().get("len")?;
126                    Ok(DatabaseType::MySQLType(MySQLType::DateTime(len)))
127                },
128                "date" => Ok(DatabaseType::MySQLType(MySQLType::Date)),
129                "time" => {
130                    let len: i32 = interface_enum_variant.args.as_ref().unwrap().get("len")?;
131                    Ok(DatabaseType::MySQLType(MySQLType::Time(len)))
132                },
133                "timestamp" => {
134                    let len: i32 = interface_enum_variant.args.as_ref().unwrap().get("len")?;
135                    Ok(DatabaseType::MySQLType(MySQLType::Timestamp(len)))
136                },
137                "json" => Ok(DatabaseType::MySQLType(MySQLType::Json)),
138                "longBlob" => Ok(DatabaseType::MySQLType(MySQLType::LongBlob)),
139                "binary" => Ok(DatabaseType::MySQLType(MySQLType::Binary)),
140                "varBinary" => Ok(DatabaseType::MySQLType(MySQLType::VarBinary)),
141                "tinyBlob" => Ok(DatabaseType::MySQLType(MySQLType::TinyBlob)),
142                "blob" => Ok(DatabaseType::MySQLType(MySQLType::Blob)),
143                "mediumBlob" => Ok(DatabaseType::MySQLType(MySQLType::MediumBlob)),
144                _ => panic!(),
145            }
146        } else if availability == Availability::postgres() {
147            match interface_enum_variant.value.as_str() {
148                "varChar" => {
149                    let len: i32 = interface_enum_variant.args.as_ref().unwrap().get("len")?;
150                    Ok(DatabaseType::PostgreSQLType(PostgreSQLType::VarChar(len)))
151                },
152                "text" => Ok(DatabaseType::PostgreSQLType(PostgreSQLType::Text)),
153                "char" => {
154                    let len: i32 = interface_enum_variant.args.as_ref().unwrap().get("len")?;
155                    Ok(DatabaseType::PostgreSQLType(PostgreSQLType::Char(len)))
156                },
157                "bit" => {
158                    let len: i32 = interface_enum_variant.args.as_ref().unwrap().get("len")?;
159                    Ok(DatabaseType::PostgreSQLType(PostgreSQLType::Bit(len)))
160                },
161                "varBit" => Ok(DatabaseType::PostgreSQLType(PostgreSQLType::VarBit)),
162                "uuid" => Ok(DatabaseType::PostgreSQLType(PostgreSQLType::UUID)),
163                "xml" => Ok(DatabaseType::PostgreSQLType(PostgreSQLType::Xml)),
164                "inet" => Ok(DatabaseType::PostgreSQLType(PostgreSQLType::Inet)),
165                "boolean" => Ok(DatabaseType::PostgreSQLType(PostgreSQLType::Boolean)),
166                "integer" => Ok(DatabaseType::PostgreSQLType(PostgreSQLType::Integer)),
167                "smallInt" => Ok(DatabaseType::PostgreSQLType(PostgreSQLType::SmallInt)),
168                "int" => Ok(DatabaseType::PostgreSQLType(PostgreSQLType::Int)),
169                "bigInt" => Ok(DatabaseType::PostgreSQLType(PostgreSQLType::BigInt)),
170                "oid" => Ok(DatabaseType::PostgreSQLType(PostgreSQLType::Oid)),
171                "doublePrecision" => Ok(DatabaseType::PostgreSQLType(PostgreSQLType::DoublePrecision)),
172                "real" => Ok(DatabaseType::PostgreSQLType(PostgreSQLType::Real)),
173                "decimal" => {
174                    let precision: i32 = interface_enum_variant.args.as_ref().unwrap().get("precision")?;
175                    let scale: i32 = interface_enum_variant.args.as_ref().unwrap().get("scale")?;
176                    Ok(DatabaseType::PostgreSQLType(PostgreSQLType::Decimal(precision, scale)))
177                },
178                "money" => Ok(DatabaseType::PostgreSQLType(PostgreSQLType::Money)),
179                "timestamp" => {
180                    let len: i32 = interface_enum_variant.args.as_ref().unwrap().get("len")?;
181                    let tz: bool = interface_enum_variant.args.as_ref().unwrap().get("tz")?;
182                    Ok(DatabaseType::PostgreSQLType(PostgreSQLType::Timestamp(len, tz)))
183                },
184                "date" => Ok(DatabaseType::PostgreSQLType(PostgreSQLType::Date)),
185                "time" => {
186                    let tz: bool = interface_enum_variant.args.as_ref().unwrap().get("tz")?;
187                    Ok(DatabaseType::PostgreSQLType(PostgreSQLType::Time(tz)))
188                },
189                "json" => Ok(DatabaseType::PostgreSQLType(PostgreSQLType::Json)),
190                "jsonB" => Ok(DatabaseType::PostgreSQLType(PostgreSQLType::JsonB)),
191                "byteA" => Ok(DatabaseType::PostgreSQLType(PostgreSQLType::ByteA)),
192                _ => panic!(),
193            }
194        } else if availability == Availability::sqlite() {
195            match interface_enum_variant.value.as_str() {
196                "text" => Ok(DatabaseType::SQLiteType(SQLiteType::Text)),
197                "integer" => Ok(DatabaseType::SQLiteType(SQLiteType::Integer)),
198                "real" => Ok(DatabaseType::SQLiteType(SQLiteType::Real)),
199                "decimal" => Ok(DatabaseType::SQLiteType(SQLiteType::Decimal)),
200                "blob" => Ok(DatabaseType::SQLiteType(SQLiteType::Blob)),
201                _ => panic!(),
202            }
203        } else if availability == Availability::mongo() {
204            match interface_enum_variant.value.as_str() {
205                "string" => Ok(DatabaseType::MongoDBType(MongoDBType::String)),
206                "bool" => Ok(DatabaseType::MongoDBType(MongoDBType::Bool)),
207                "int" => Ok(DatabaseType::MongoDBType(MongoDBType::Int)),
208                "long" => Ok(DatabaseType::MongoDBType(MongoDBType::Long)),
209                "double" => Ok(DatabaseType::MongoDBType(MongoDBType::Double)),
210                "date" => Ok(DatabaseType::MongoDBType(MongoDBType::Date)),
211                "timestamp" => Ok(DatabaseType::MongoDBType(MongoDBType::Timestamp)),
212                "binData" => Ok(DatabaseType::MongoDBType(MongoDBType::BinData)),
213                _ => panic!(),
214            }
215        } else {
216            Err(Error::new("invalid availability when fetching database type"))
217        }
218    }
219}