use rusticx_core::column::ColumnType;
pub trait SqlDialect: Send + Sync {
fn placeholder(&self, index: usize) -> String;
fn quote_ident(&self, name: &str) -> String;
fn sql_type(&self, col_type: &ColumnType) -> String;
fn supports_returning(&self) -> bool;
fn upsert_syntax(&self) -> UpsertSyntax;
}
#[derive(Debug, Clone, Copy)]
pub enum UpsertSyntax {
OnConflict,
InsertIgnore,
None,
}
pub struct PostgresDialect;
impl SqlDialect for PostgresDialect {
fn placeholder(&self, index: usize) -> String {
format!("${index}")
}
fn quote_ident(&self, name: &str) -> String {
format!("\"{name}\"")
}
fn sql_type(&self, col_type: &ColumnType) -> String {
match col_type {
ColumnType::Bool => "BOOLEAN".into(),
ColumnType::SmallInt => "SMALLINT".into(),
ColumnType::Int => "INTEGER".into(),
ColumnType::BigInt => "BIGINT".into(),
ColumnType::Float => "REAL".into(),
ColumnType::Double => "DOUBLE PRECISION".into(),
ColumnType::Decimal { precision, scale } => format!("DECIMAL({precision},{scale})"),
ColumnType::Text => "TEXT".into(),
ColumnType::Varchar(n) => format!("VARCHAR({n})"),
ColumnType::Char(n) => format!("CHAR({n})"),
ColumnType::Bytes => "BYTEA".into(),
ColumnType::Uuid => "UUID".into(),
ColumnType::Timestamp => "TIMESTAMP".into(),
ColumnType::TimestampTz => "TIMESTAMPTZ".into(),
ColumnType::Date => "DATE".into(),
ColumnType::Time => "TIME".into(),
ColumnType::Json => "JSON".into(),
ColumnType::Jsonb => "JSONB".into(),
ColumnType::Array(inner) => format!("{}[]", self.sql_type(inner)),
ColumnType::Dynamic => "JSONB".into(),
}
}
fn supports_returning(&self) -> bool {
true
}
fn upsert_syntax(&self) -> UpsertSyntax {
UpsertSyntax::OnConflict
}
}
pub struct MysqlDialect;
impl SqlDialect for MysqlDialect {
fn placeholder(&self, _index: usize) -> String {
"?".into()
}
fn quote_ident(&self, name: &str) -> String {
format!("`{name}`")
}
fn sql_type(&self, col_type: &ColumnType) -> String {
match col_type {
ColumnType::Bool => "TINYINT(1)".into(),
ColumnType::SmallInt => "SMALLINT".into(),
ColumnType::Int => "INT".into(),
ColumnType::BigInt => "BIGINT".into(),
ColumnType::Float => "FLOAT".into(),
ColumnType::Double => "DOUBLE".into(),
ColumnType::Decimal { precision, scale } => format!("DECIMAL({precision},{scale})"),
ColumnType::Text => "TEXT".into(),
ColumnType::Varchar(n) => format!("VARCHAR({n})"),
ColumnType::Char(n) => format!("CHAR({n})"),
ColumnType::Bytes => "BLOB".into(),
ColumnType::Uuid => "CHAR(36)".into(),
ColumnType::Timestamp | ColumnType::TimestampTz => "DATETIME(6)".into(),
ColumnType::Date => "DATE".into(),
ColumnType::Time => "TIME".into(),
ColumnType::Json | ColumnType::Jsonb => "JSON".into(),
ColumnType::Array(_) => "JSON".into(), ColumnType::Dynamic => "JSON".into(),
}
}
fn supports_returning(&self) -> bool {
false
}
fn upsert_syntax(&self) -> UpsertSyntax {
UpsertSyntax::InsertIgnore
}
}