#[cfg(feature = "postgres")]
pub mod postgres;
#[cfg(feature = "mysql")]
pub mod mysql;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum DialectKind {
Postgres,
Mysql,
}
impl DialectKind {
pub fn name(&self) -> &'static str {
match self {
DialectKind::Postgres => "postgres",
DialectKind::Mysql => "mysql",
}
}
pub fn from_url(url: &str) -> Option<Self> {
let lower = url.trim_start().to_lowercase();
if lower.starts_with("postgres://") || lower.starts_with("postgresql://") {
Some(DialectKind::Postgres)
} else if lower.starts_with("mysql://") {
Some(DialectKind::Mysql)
} else {
None
}
}
}
pub trait DatabaseDialect: Send + Sync {
fn kind(&self) -> DialectKind;
fn quote_ident(&self, name: &str) -> String;
fn qualified_table(&self, schema: &str, table: &str) -> String {
format!("{}.{}", self.quote_ident(schema), self.quote_ident(table))
}
fn history_table_ddl(&self, schema: &str, table: &str) -> String;
fn supports_transactional_ddl(&self) -> bool;
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn from_url_recognises_postgres() {
assert_eq!(
DialectKind::from_url("postgres://u:p@h/d"),
Some(DialectKind::Postgres)
);
assert_eq!(
DialectKind::from_url("postgresql://u:p@h/d"),
Some(DialectKind::Postgres)
);
assert_eq!(
DialectKind::from_url("POSTGRES://u:p@h/d"),
Some(DialectKind::Postgres)
);
}
#[test]
fn from_url_recognises_mysql() {
assert_eq!(
DialectKind::from_url("mysql://u:p@h/d"),
Some(DialectKind::Mysql)
);
assert_eq!(
DialectKind::from_url(" mysql://h/d"),
Some(DialectKind::Mysql)
);
}
#[test]
fn from_url_returns_none_for_kv_or_unknown() {
assert_eq!(DialectKind::from_url("host=localhost user=postgres"), None);
assert_eq!(DialectKind::from_url("sqlite://x"), None);
assert_eq!(DialectKind::from_url(""), None);
}
}