1use std::fmt::{Display, Formatter};
2use serde::Serialize;
3use teo_parser::ast::schema::Schema;
4use teo_parser::r#type::Type;
5use teo_result::{Error, Result};
6use crate::database::mongo::r#type::MongoDBType;
7use crate::database::mysql::r#type::{MySQLEnum, MySQLType};
8use crate::database::postgres::r#type::PostgreSQLType;
9use crate::database::sqlite::r#type::SQLiteType;
10use crate::database::r#type::DatabaseType;
11
12#[derive(Debug, Serialize, Clone, Copy)]
13pub enum Database {
14 MongoDB,
15 MySQL,
16 PostgreSQL,
17 SQLite,
18}
19
20impl Display for Database {
21
22 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
23 match self {
24 Database::MongoDB => f.write_str("MongoDB")?,
25 Database::MySQL => f.write_str("MySQL")?,
26 Database::PostgreSQL => f.write_str("PostgreSQL")?,
27 Database::SQLite => f.write_str("SQLite")?,
28 }
29 Ok(())
30 }
31}
32
33impl Database {
34
35 pub fn lowercase_desc(&self) -> &'static str {
36 match self {
37 Database::MongoDB => "mongo",
38 Database::MySQL => "mysql",
39 Database::PostgreSQL => "postgres",
40 Database::SQLite => "sqlite",
41 }
42 }
43
44 pub fn is_mongo(&self) -> bool {
45 match self {
46 Database::MongoDB => true,
47 _ => false,
48 }
49 }
50
51 pub fn is_sql(&self) -> bool {
52 match self {
53 Database::MongoDB => false,
54 _ => true,
55 }
56 }
57
58 pub fn default_database_type(&self, r#type: &Type, parser_namespace: &Schema) -> Result<DatabaseType> {
59 match self {
60 Database::MongoDB => self.default_mongo_database_type(r#type),
61 Database::MySQL => self.default_mysql_database_type(r#type, parser_namespace),
62 Database::PostgreSQL => self.default_postgres_database_type(r#type),
63 Database::SQLite => self.default_sqlite_database_type(r#type),
64 }
65 }
66
67 fn default_mongo_database_type(&self, r#type: &Type) -> Result<DatabaseType> {
68 match r#type {
69 Type::Bool => Ok(DatabaseType::MongoDBType(MongoDBType::Bool)),
70 Type::Int => Ok(DatabaseType::MongoDBType(MongoDBType::Int)),
71 Type::Int64 => Ok(DatabaseType::MongoDBType(MongoDBType::Long)),
72 Type::Float32 => Ok(DatabaseType::MongoDBType(MongoDBType::Double)),
73 Type::Float => Ok(DatabaseType::MongoDBType(MongoDBType::Double)),
74 Type::String => Ok(DatabaseType::MongoDBType(MongoDBType::String)),
75 Type::ObjectId => Ok(DatabaseType::MongoDBType(MongoDBType::ObjectId)),
76 Type::Date => Ok(DatabaseType::MongoDBType(MongoDBType::Date)),
77 Type::DateTime => Ok(DatabaseType::MongoDBType(MongoDBType::Date)),
78 Type::Array(inner) => Ok(DatabaseType::MongoDBType(MongoDBType::Array(Box::new(self.default_mongo_database_type(inner.as_ref())?.as_mongo().unwrap().clone())))),
79 Type::EnumVariant(_) => Ok(DatabaseType::MongoDBType(MongoDBType::String)),
80 Type::Optional(inner) => self.default_mongo_database_type(inner.as_ref()),
81 _ => Err(Error::new(format!("unsupported mongo database type {}", r#type))),
82 }
83 }
84
85 fn default_mysql_database_type(&self, r#type: &Type, parser_namespace: &Schema) -> Result<DatabaseType> {
86 match r#type {
87 Type::Bool => Ok(DatabaseType::MySQLType(MySQLType::TinyInt(Some(1), false))),
88 Type::Int => Ok(DatabaseType::MySQLType(MySQLType::Int(None, false))),
89 Type::Int64 => Ok(DatabaseType::MySQLType(MySQLType::BigInt(None, false))),
90 Type::Float32 => Ok(DatabaseType::MySQLType(MySQLType::Float)),
91 Type::Float => Ok(DatabaseType::MySQLType(MySQLType::Double)),
92 Type::Decimal => Ok(DatabaseType::MySQLType(MySQLType::Decimal(65, 30))),
93 Type::String => Ok(DatabaseType::MySQLType(MySQLType::VarChar(191))),
94 Type::Date => Ok(DatabaseType::MySQLType(MySQLType::Date)),
95 Type::DateTime => Ok(DatabaseType::MySQLType(MySQLType::DateTime(3))),
96 Type::EnumVariant(reference) => Ok(DatabaseType::MySQLType(MySQLType::Enum(MySQLEnum::build(parser_namespace, reference)))),
97 Type::Optional(inner) => self.default_mysql_database_type(inner.as_ref(), parser_namespace),
98 _ => Err(Error::new(format!("unsupported mysql database type {}", r#type))),
99 }
100 }
101
102 fn default_postgres_database_type(&self, r#type: &Type) -> Result<DatabaseType> {
103 match r#type {
104 Type::Bool => Ok(DatabaseType::PostgreSQLType(PostgreSQLType::Boolean)),
105 Type::Int => Ok(DatabaseType::PostgreSQLType(PostgreSQLType::Integer)),
106 Type::Int64 => Ok(DatabaseType::PostgreSQLType(PostgreSQLType::BigInt)),
107 Type::Float32 => Ok(DatabaseType::PostgreSQLType(PostgreSQLType::Real)),
108 Type::Float => Ok(DatabaseType::PostgreSQLType(PostgreSQLType::DoublePrecision)),
109 Type::Decimal => Ok(DatabaseType::PostgreSQLType(PostgreSQLType::Decimal(65, 30))),
110 Type::String => Ok(DatabaseType::PostgreSQLType(PostgreSQLType::Text)),
111 Type::Date => Ok(DatabaseType::PostgreSQLType(PostgreSQLType::Date)),
112 Type::DateTime => Ok(DatabaseType::PostgreSQLType(PostgreSQLType::Timestamp(3,true))),
113 Type::Array(inner) => Ok(DatabaseType::PostgreSQLType(PostgreSQLType::Array(Box::new(self.default_postgres_database_type(inner.as_ref())?.as_postgres().unwrap().clone())))),
114 Type::EnumVariant(_) => Ok(DatabaseType::PostgreSQLType(PostgreSQLType::Text)),
115 Type::Optional(inner) => self.default_postgres_database_type(inner.as_ref()),
116 _ => Err(Error::new(format!("unsupported postgres database type {}", r#type))),
117 }
118 }
119
120 fn default_sqlite_database_type(&self, r#type: &Type) -> Result<DatabaseType> {
121 match r#type {
122 Type::Bool => Ok(DatabaseType::SQLiteType(SQLiteType::Integer)),
123 Type::Int => Ok(DatabaseType::SQLiteType(SQLiteType::Integer)),
124 Type::Int64 => Ok(DatabaseType::SQLiteType(SQLiteType::Integer)),
125 Type::Float32 => Ok(DatabaseType::SQLiteType(SQLiteType::Real)),
126 Type::Float => Ok(DatabaseType::SQLiteType(SQLiteType::Real)),
127 Type::Decimal => Ok(DatabaseType::SQLiteType(SQLiteType::Decimal)),
128 Type::String => Ok(DatabaseType::SQLiteType(SQLiteType::Text)),
129 Type::Date => Ok(DatabaseType::SQLiteType(SQLiteType::Text)),
130 Type::DateTime => Ok(DatabaseType::SQLiteType(SQLiteType::Text)),
131 Type::EnumVariant(_) => Ok(DatabaseType::SQLiteType(SQLiteType::Text)),
132 Type::Optional(inner) => self.default_sqlite_database_type(inner.as_ref()),
133 _ => Err(Error::new(format!("unsupported sqlite database type {}", r#type))),
134 }
135 }
136}