use sea_query::{ColumnDef, Index, IndexCreateStatement, Table, TableCreateStatement};
use super::Dialect;
pub fn id(name: &'static str) -> ColumnDef {
let mut column = ColumnDef::new(name);
column.big_integer().not_null().auto_increment().primary_key();
column
}
pub fn foreign_id(name: &'static str) -> ColumnDef {
let mut column = ColumnDef::new(name);
column.big_integer().not_null();
column
}
pub fn unix_millis(name: &'static str) -> ColumnDef {
let mut column = ColumnDef::new(name);
column.big_integer().not_null();
column
}
pub fn big_int(name: &'static str) -> ColumnDef {
let mut column = ColumnDef::new(name);
column.big_integer().not_null();
column
}
pub fn string(name: &'static str, len: u32) -> ColumnDef {
let mut column = ColumnDef::new(name);
column.string_len(len).not_null();
column
}
pub fn boolean(name: &'static str) -> ColumnDef {
let mut column = ColumnDef::new(name);
column.boolean().not_null();
column
}
pub fn bytes(name: &'static str, dialect: Dialect) -> ColumnDef {
let mut column = ColumnDef::new(name);
match dialect {
Dialect::MySql => column.custom("LONGBLOB"),
Dialect::Postgres => column.custom("BYTEA"),
Dialect::Sqlite => column.custom("BLOB"),
};
column.not_null();
column
}
pub fn create_table(name: &'static str) -> TableCreateStatement {
let mut table = Table::create();
table.table(name).if_not_exists();
table
}
pub fn render_table(table: &TableCreateStatement, dialect: Dialect) -> String {
match dialect {
Dialect::MySql => {
let mut table = table.clone();
table.engine("InnoDB").character_set("utf8mb4").collate("utf8mb4_bin");
table.to_string(sea_query::MysqlQueryBuilder)
}
Dialect::Postgres => table.to_string(sea_query::PostgresQueryBuilder),
Dialect::Sqlite => table.to_string(sea_query::SqliteQueryBuilder),
}
}
pub fn create_index(name: &'static str, table: &'static str, columns: &[&'static str]) -> IndexCreateStatement {
let mut index = Index::create();
index.name(name).table(table);
for column in columns {
index.col(*column);
}
index
}
pub fn render_index(index: &IndexCreateStatement, dialect: Dialect) -> String {
match dialect {
Dialect::MySql => index.to_string(sea_query::MysqlQueryBuilder),
Dialect::Postgres => index.to_string(sea_query::PostgresQueryBuilder),
Dialect::Sqlite => index.to_string(sea_query::SqliteQueryBuilder),
}
}
#[cfg(test)]
mod tests {
use super::*;
fn example(dialect: Dialect) -> String {
let mut table = create_table("scores");
table.col(id("id")).col(foreign_id("user_id")).col(big_int("points")).col(bytes("data", dialect)).col(unix_millis("created_at"));
render_table(&table, dialect)
}
#[test]
fn portable_types_per_dialect() {
let mysql = example(Dialect::MySql);
assert!(mysql.starts_with("CREATE TABLE IF NOT EXISTS `scores`"), "{mysql}");
assert!(mysql.contains("`id` bigint NOT NULL PRIMARY KEY AUTO_INCREMENT"), "{mysql}");
assert!(mysql.contains("`data` LONGBLOB NOT NULL"), "{mysql}");
assert!(mysql.contains("ENGINE=InnoDB") && mysql.contains("COLLATE=utf8mb4_bin"), "{mysql}");
let pg = example(Dialect::Postgres);
assert!(pg.contains("\"id\" bigint GENERATED BY DEFAULT AS IDENTITY NOT NULL PRIMARY KEY"), "{pg}");
assert!(pg.contains("\"data\" BYTEA NOT NULL"), "{pg}");
assert!(pg.contains("\"created_at\" bigint NOT NULL"), "{pg}");
let sqlite = example(Dialect::Sqlite);
assert!(sqlite.contains("\"id\" integer NOT NULL PRIMARY KEY AUTOINCREMENT"), "{sqlite}");
assert!(sqlite.contains("\"data\" BLOB NOT NULL"), "{sqlite}");
assert!(sqlite.contains("\"created_at\" integer NOT NULL"), "{sqlite}");
let index = create_index("scores_user", "scores", &["user_id", "points"]);
assert!(render_index(&index, Dialect::Postgres).contains("CREATE INDEX \"scores_user\" ON \"scores\" (\"user_id\", \"points\")"));
}
}