pub trait Dialect: Send + Sync + 'static {
const AUTO_PK: &'static str;
const INSERT_IGNORE: &'static str;
const CONFLICT_NOTHING: &'static str;
const COLLATE_NOCASE: &'static str;
const EPOCH_NOW: &'static str;
fn ilike(col: &str) -> String;
fn epoch_from_col(col: &str) -> String;
}
pub struct Sqlite;
impl Dialect for Sqlite {
const AUTO_PK: &'static str = "INTEGER PRIMARY KEY AUTOINCREMENT";
const INSERT_IGNORE: &'static str = "INSERT OR IGNORE";
const CONFLICT_NOTHING: &'static str = "";
const COLLATE_NOCASE: &'static str = "COLLATE NOCASE";
const EPOCH_NOW: &'static str = "unixepoch('now')";
fn ilike(col: &str) -> String {
format!("{col} COLLATE NOCASE")
}
fn epoch_from_col(col: &str) -> String {
format!("COALESCE(CAST(strftime('%s', {col}) AS INTEGER), 0)")
}
}
pub struct Postgres;
impl Dialect for Postgres {
const AUTO_PK: &'static str = "BIGSERIAL PRIMARY KEY";
const INSERT_IGNORE: &'static str = "INSERT";
const CONFLICT_NOTHING: &'static str = "ON CONFLICT DO NOTHING";
const COLLATE_NOCASE: &'static str = "";
const EPOCH_NOW: &'static str = "EXTRACT(EPOCH FROM NOW())::BIGINT";
fn ilike(col: &str) -> String {
format!("LOWER({col})")
}
fn epoch_from_col(col: &str) -> String {
format!("COALESCE(CAST(EXTRACT(EPOCH FROM {col}) AS BIGINT), 0)")
}
}
#[cfg(test)]
mod tests {
use super::*;
#[cfg(feature = "sqlite")]
mod sqlite {
use super::*;
#[test]
fn auto_pk() {
assert_eq!(Sqlite::AUTO_PK, "INTEGER PRIMARY KEY AUTOINCREMENT");
}
#[test]
fn insert_ignore() {
assert_eq!(Sqlite::INSERT_IGNORE, "INSERT OR IGNORE");
assert_eq!(Sqlite::CONFLICT_NOTHING, "");
}
#[test]
fn epoch_now() {
assert_eq!(Sqlite::EPOCH_NOW, "unixepoch('now')");
}
#[test]
fn epoch_from_col() {
assert_eq!(
Sqlite::epoch_from_col("created_at"),
"COALESCE(CAST(strftime('%s', created_at) AS INTEGER), 0)"
);
}
#[test]
fn ilike() {
assert_eq!(Sqlite::ilike("name"), "name COLLATE NOCASE");
}
}
#[cfg(feature = "postgres")]
mod postgres {
use super::*;
#[test]
fn auto_pk() {
assert_eq!(Postgres::AUTO_PK, "BIGSERIAL PRIMARY KEY");
}
#[test]
fn insert_ignore() {
assert_eq!(Postgres::INSERT_IGNORE, "INSERT");
assert_eq!(Postgres::CONFLICT_NOTHING, "ON CONFLICT DO NOTHING");
}
#[test]
fn epoch_now() {
assert_eq!(Postgres::EPOCH_NOW, "EXTRACT(EPOCH FROM NOW())::BIGINT");
}
#[test]
fn epoch_from_col() {
assert_eq!(
Postgres::epoch_from_col("created_at"),
"COALESCE(CAST(EXTRACT(EPOCH FROM created_at) AS BIGINT), 0)"
);
}
#[test]
fn ilike() {
assert_eq!(Postgres::ilike("name"), "LOWER(name)");
}
}
}