teo_runtime/database/
database.rs

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}