use expect_test::expect;
use toasty_core::{
driver::operation::{IsolationLevel, Transaction, TransactionMode},
schema::db::Schema,
};
use toasty_sql::Serializer;
#[derive(Clone, Copy)]
enum Flavor {
Sqlite,
Postgresql,
Mysql,
}
fn render(flavor: Flavor, op: &Transaction) -> String {
let schema = Schema::default();
match flavor {
Flavor::Sqlite => Serializer::sqlite(&schema).serialize_transaction(op),
Flavor::Postgresql => Serializer::postgresql(&schema).serialize_transaction(op),
Flavor::Mysql => Serializer::mysql(&schema).serialize_transaction(op),
}
}
fn start(isolation: Option<IsolationLevel>, read_only: bool, mode: TransactionMode) -> Transaction {
Transaction::Start {
isolation,
read_only,
mode,
}
}
#[test]
fn sqlite_default_and_deferred_emit_plain_begin() {
expect!["BEGIN;"].assert_eq(&render(
Flavor::Sqlite,
&start(None, false, TransactionMode::Default),
));
expect!["BEGIN;"].assert_eq(&render(
Flavor::Sqlite,
&start(None, false, TransactionMode::Deferred),
));
}
#[test]
fn sqlite_immediate() {
expect!["BEGIN IMMEDIATE;"].assert_eq(&render(
Flavor::Sqlite,
&start(None, false, TransactionMode::Immediate),
));
}
#[test]
fn sqlite_exclusive() {
expect!["BEGIN EXCLUSIVE;"].assert_eq(&render(
Flavor::Sqlite,
&start(None, false, TransactionMode::Exclusive),
));
}
#[test]
fn sqlite_ignores_isolation_and_read_only() {
expect!["BEGIN;"].assert_eq(&render(
Flavor::Sqlite,
&start(
Some(IsolationLevel::Serializable),
true,
TransactionMode::Default,
),
));
expect!["BEGIN EXCLUSIVE;"].assert_eq(&render(
Flavor::Sqlite,
&start(
Some(IsolationLevel::Serializable),
true,
TransactionMode::Exclusive,
),
));
}
#[test]
fn postgresql_default() {
expect!["BEGIN;"].assert_eq(&render(
Flavor::Postgresql,
&start(None, false, TransactionMode::Default),
));
}
#[test]
fn postgresql_isolation_levels() {
let cases = [
(
IsolationLevel::ReadUncommitted,
"BEGIN ISOLATION LEVEL READ UNCOMMITTED;",
),
(
IsolationLevel::ReadCommitted,
"BEGIN ISOLATION LEVEL READ COMMITTED;",
),
(
IsolationLevel::RepeatableRead,
"BEGIN ISOLATION LEVEL REPEATABLE READ;",
),
(
IsolationLevel::Serializable,
"BEGIN ISOLATION LEVEL SERIALIZABLE;",
),
];
for (level, sql) in cases {
assert_eq!(
render(
Flavor::Postgresql,
&start(Some(level), false, TransactionMode::Default)
),
sql,
);
}
}
#[test]
fn postgresql_read_only_and_isolation_combine() {
expect!["BEGIN ISOLATION LEVEL SERIALIZABLE READ ONLY;"].assert_eq(&render(
Flavor::Postgresql,
&start(
Some(IsolationLevel::Serializable),
true,
TransactionMode::Default,
),
));
}
#[test]
fn postgresql_ignores_lock_mode() {
expect!["BEGIN;"].assert_eq(&render(
Flavor::Postgresql,
&start(None, false, TransactionMode::Immediate),
));
expect!["BEGIN;"].assert_eq(&render(
Flavor::Postgresql,
&start(None, false, TransactionMode::Exclusive),
));
}
#[test]
fn mysql_default() {
expect!["START TRANSACTION;"].assert_eq(&render(
Flavor::Mysql,
&start(None, false, TransactionMode::Default),
));
}
#[test]
fn mysql_isolation_and_read_only() {
expect!["SET TRANSACTION ISOLATION LEVEL SERIALIZABLE; START TRANSACTION READ ONLY;"]
.assert_eq(&render(
Flavor::Mysql,
&start(
Some(IsolationLevel::Serializable),
true,
TransactionMode::Default,
),
));
}
#[test]
fn mysql_ignores_lock_mode() {
expect!["START TRANSACTION;"].assert_eq(&render(
Flavor::Mysql,
&start(None, false, TransactionMode::Immediate),
));
}
#[test]
fn commit_and_rollback() {
for flavor in [Flavor::Sqlite, Flavor::Postgresql, Flavor::Mysql] {
assert_eq!(render(flavor, &Transaction::Commit), "COMMIT;");
assert_eq!(render(flavor, &Transaction::Rollback), "ROLLBACK;");
}
}
#[test]
fn savepoints_quote_identifier() {
expect![[r#"SAVEPOINT "sp_1";"#]].assert_eq(&render(
Flavor::Sqlite,
&Transaction::Savepoint("sp_1".into()),
));
expect![[r#"RELEASE SAVEPOINT "sp_1";"#]].assert_eq(&render(
Flavor::Postgresql,
&Transaction::ReleaseSavepoint("sp_1".into()),
));
expect![[r#"ROLLBACK TO SAVEPOINT "sp_1";"#]].assert_eq(&render(
Flavor::Sqlite,
&Transaction::RollbackToSavepoint("sp_1".into()),
));
expect!["SAVEPOINT `sp_1`;"].assert_eq(&render(
Flavor::Mysql,
&Transaction::Savepoint("sp_1".into()),
));
}