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}