use openehr_mariadb::MariadbDialect;
use openehr_mssql::MssqlDialect;
use openehr_mysql::MysqlDialect;
use openehr_oracle::OracleDialect;
use openehr_postgresql::PostgresqlDialect;
use openehr_sqlite::SqliteDialect;
use openehr_store::{ColTy, Dialect, Idempotence, conformance, ddl_script};
fn all() -> Vec<&'static dyn Dialect> {
vec![
&PostgresqlDialect,
&SqliteDialect,
&MysqlDialect,
&MariadbDialect,
&MssqlDialect,
&OracleDialect,
]
}
#[test]
fn every_engine_crate_is_in_the_comparison() {
const ENGINE_CRATES: usize = 6;
assert_eq!(
all().len(),
ENGINE_CRATES,
"a dialect crate is missing from `all()`; the distinctness check does not cover it"
);
let names: std::collections::HashSet<&str> = all().iter().map(|d| d.name()).collect();
assert_eq!(names.len(), ENGINE_CRATES, "two dialects report one name");
}
#[test]
fn no_two_dialects_emit_the_same_ddl() {
conformance::dialects_are_distinct(&all());
}
#[test]
fn every_dialect_is_self_consistent() {
for dialect in all() {
conformance::check_dialect(dialect);
}
}
#[test]
fn the_types_that_differ_between_engines_actually_differ() {
let boolean: Vec<String> = all().iter().map(|d| d.col_sql(ColTy::Bool)).collect();
let distinct: std::collections::HashSet<_> = boolean.iter().collect();
assert!(
distinct.len() >= 4,
"booleans collapsed to {distinct:?} — a dialect is not its own engine"
);
let json: std::collections::HashSet<String> =
all().iter().map(|d| d.col_sql(ColTy::Json)).collect();
assert!(json.len() >= 3, "JSON storage collapsed to {json:?}");
}
#[test]
fn every_dialect_keeps_the_two_instant_columns_apart() {
for dialect in all() {
assert_ne!(
dialect.col_sql(ColTy::Instant),
dialect.col_sql(ColTy::InstantUtc),
"{}: the authoritative lexical form and the derived instant share a type",
dialect.name()
);
}
}
#[test]
fn placeholders_match_their_drivers() {
assert_eq!(PostgresqlDialect.placeholder().render(1), "$1");
assert_eq!(SqliteDialect.placeholder().render(1), "?");
assert_eq!(MysqlDialect.placeholder().render(1), "?");
assert_eq!(MssqlDialect.placeholder().render(1), "@p1");
assert_eq!(OracleDialect.placeholder().render(1), ":1");
}
#[test]
fn only_engines_with_if_not_exists_emit_it() {
for dialect in all() {
let script = ddl_script(dialect);
assert_eq!(
script.contains("CREATE TABLE IF NOT EXISTS"),
dialect.table_idempotence() == Idempotence::IfNotExists,
"{}: CREATE TABLE IF NOT EXISTS emitted but not supported, or the reverse",
dialect.name()
);
assert_eq!(
script.contains("INDEX IF NOT EXISTS"),
dialect.index_idempotence() == Idempotence::IfNotExists,
"{}: CREATE INDEX IF NOT EXISTS emitted but not supported, or the reverse",
dialect.name()
);
}
}
#[test]
fn every_dialect_enforces_append_only_in_the_schema() {
for dialect in all() {
for table in openehr_store::TABLES.iter().filter(|t| t.append_only) {
let statements = dialect.append_only_sql(table);
assert!(
!statements.is_empty(),
"{}: {} is append-only and nothing enforces it",
dialect.name(),
table.name
);
assert!(
statements.iter().any(|s| s.contains("UPDATE"))
&& statements.iter().any(|s| s.contains("DELETE")),
"{}: {} must refuse both UPDATE and DELETE",
dialect.name(),
table.name
);
}
}
}
#[test]
fn every_dialect_names_itself_and_no_two_share_a_name() {
let names: Vec<&str> = all().iter().map(|d| d.name()).collect();
assert_eq!(
names,
vec!["PostgreSQL", "SQLite", "MySQL", "MariaDB", "SQL Server", "Oracle"]
);
let mut sorted = names.clone();
sorted.sort_unstable();
sorted.dedup();
assert_eq!(sorted.len(), names.len(), "two dialects share a name: {names:?}");
}