use crate::{Database, migrate::Schema, migration::Config};
impl<S: Send + Sync + Schema> Database<S> {
fn check_schema(&self, expect: expect_test::Expect) {
let mut schema = self.transaction(|txn| txn.schema());
schema.sort();
expect.assert_eq(&schema.join("\n"));
}
}
fn open_db<S: Schema>(file: &str) -> Database<S> {
Database::new(Config::open(file))
}
#[test]
fn fix_indices1() {
mod without_index {
#[crate::migration::schema(Schema)]
pub mod vN {
pub struct Foo {
pub bar: String,
}
}
}
mod with_index {
#[crate::migration::schema(Schema)]
pub mod vN {
pub struct Foo {
#[index]
pub bar: String,
}
}
}
static FILE_NAME: &str = "index_test1.sqlite";
let _ = std::fs::remove_file(FILE_NAME);
let db = open_db::<without_index::v0::Schema>(FILE_NAME);
db.check_schema(expect_test::expect![[
r#"CREATE TABLE "foo" ("id" INTEGER PRIMARY KEY, "bar" TEXT NOT NULL) STRICT"#
]]);
let db_with_index = open_db::<with_index::v0::Schema>(FILE_NAME);
db_with_index.check_schema(expect_test::expect![[r#"
CREATE INDEX "foo_index_0" ON "foo" ("bar")
CREATE TABLE "foo" ("id" INTEGER PRIMARY KEY, "bar" TEXT NOT NULL) STRICT"#]]);
db.check_schema(expect_test::expect![[r#"
CREATE INDEX "foo_index_0" ON "foo" ("bar")
CREATE TABLE "foo" ("id" INTEGER PRIMARY KEY, "bar" TEXT NOT NULL) STRICT"#]]);
let db = open_db::<without_index::v0::Schema>(FILE_NAME);
db.check_schema(expect_test::expect![[
r#"CREATE TABLE "foo" ("id" INTEGER PRIMARY KEY, "bar" TEXT NOT NULL) STRICT"#
]]);
}
#[test]
fn fix_indices2() {
mod normal {
#[crate::migration::schema(Schema)]
pub mod vN {
#[unique(field1, baz)]
pub struct Foo {
pub field1: String,
pub baz: String,
}
}
}
mod reversed {
#[crate::migration::schema(Schema)]
pub mod vN {
#[unique(baz, field1)]
pub struct Foo {
pub field1: String,
pub baz: String,
}
}
}
static FILE_NAME: &str = "index_test2.sqlite";
let _ = std::fs::remove_file(FILE_NAME);
let db = open_db::<normal::v0::Schema>(FILE_NAME);
db.check_schema(expect_test::expect![[r#"CREATE TABLE "foo" ("id" INTEGER PRIMARY KEY, "baz" TEXT NOT NULL, "field1" TEXT NOT NULL, UNIQUE ("field1", "baz")) STRICT"#]]);
let db_with_reversed = open_db::<reversed::v0::Schema>(FILE_NAME);
db_with_reversed.check_schema(expect_test::expect![[r#"CREATE TABLE "foo" ("id" INTEGER PRIMARY KEY, "baz" TEXT NOT NULL, "field1" TEXT NOT NULL, UNIQUE ("baz", "field1")) STRICT"#]]);
db.check_schema(expect_test::expect![[r#"CREATE TABLE "foo" ("id" INTEGER PRIMARY KEY, "baz" TEXT NOT NULL, "field1" TEXT NOT NULL, UNIQUE ("baz", "field1")) STRICT"#]]);
let db = open_db::<normal::v0::Schema>(FILE_NAME);
db.check_schema(expect_test::expect![[r#"CREATE TABLE "foo" ("id" INTEGER PRIMARY KEY, "baz" TEXT NOT NULL, "field1" TEXT NOT NULL, UNIQUE ("field1", "baz")) STRICT"#]]);
}
#[test]
fn diagnostics() {
mod base {
#[crate::migration::schema(Schema)]
pub mod vN {
#[unique(baz, field1)]
pub struct Foo {
pub field1: String,
pub baz: String,
}
}
}
mod table_changes {
#[crate::migration::schema(Schema)]
pub mod vN {
pub struct House {
pub name: String,
}
}
}
mod column_changes {
#[crate::migration::schema(Schema)]
pub mod vN {
#[unique(baz, field2)]
pub struct Foo {
pub field2: String,
pub baz: i64,
}
}
}
static FILE_NAME: &str = "diagnostic_test.sqlite";
let _ = std::fs::remove_file(FILE_NAME);
open_db::<base::v0::Schema>(FILE_NAME);
let err = std::panic::catch_unwind(|| {
open_db::<table_changes::v0::Schema>(FILE_NAME);
})
.unwrap_err();
expect_test::expect![[r#"
error: Table mismatch for `#[version(0)]`
╭▸ src/schema/test.rs:122:36
│
LL │ #[crate::migration::schema(Schema)]
│ ━━━━━━ database has table `foo`
LL │ pub mod vN {
LL │ pub struct House {
╰╴ ━━━━━ database does not have this table"#]]
.assert_eq(err.downcast_ref::<String>().unwrap());
let err = std::panic::catch_unwind(|| {
open_db::<column_changes::v0::Schema>(FILE_NAME);
})
.unwrap_err();
expect_test::expect![[r#"
error: Column mismatch for `#[version(0)]`
╭▸ src/schema/test.rs:134:24
│
LL │ pub struct Foo {
│ ━━━ database has column `field1: String`
LL │ pub field2: String,
│ ━━━━━━ database does not have this column
LL │ pub baz: i64,
│ ━━━ database column has type `String`
╰╴
error: Unique constraint mismatch for `#[version(0)]`
╭▸ src/schema/test.rs:133:15
│
LL │ #[unique(baz, field2)]
│ ━━━━━━ database does not have this unique constraint
LL │ pub struct Foo {
╰╴ ━━━ database has `#[unique(baz, field1)]`"#]]
.assert_eq(err.downcast_ref::<String>().unwrap());
}