diff options
| author | Owen Jacobson <owen@grimoire.ca> | 2024-10-05 00:36:53 -0400 |
|---|---|---|
| committer | Owen Jacobson <owen@grimoire.ca> | 2024-10-05 00:48:12 -0400 |
| commit | 142690963c0b297e7e76bd6aca170d016ea261ff (patch) | |
| tree | 20e21f60117c7abcdee8f77cc7ffa6514de2a395 | |
| parent | e1551113323d5a496b826d7b0265b1be6235f45c (diff) | |
Use sqlx's API, not SQL groveling, to find unwanted migrations.
| -rw-r--r-- | .sqlx/query-a811cce764f6e5c5b5565d5c29e56e2fd229c024dacb6ad817988eed9a8e0c22.json | 20 | ||||
| -rw-r--r-- | .sqlx/query-e7fcc523a4487a901460e904c0720b3c43c87fb335c2f7ca9fa694b9ca4822f7.json | 20 | ||||
| -rw-r--r-- | Cargo.lock | 7 | ||||
| -rw-r--r-- | Cargo.toml | 12 | ||||
| -rw-r--r-- | src/db/mod.rs | 46 |
5 files changed, 26 insertions, 79 deletions
diff --git a/.sqlx/query-a811cce764f6e5c5b5565d5c29e56e2fd229c024dacb6ad817988eed9a8e0c22.json b/.sqlx/query-a811cce764f6e5c5b5565d5c29e56e2fd229c024dacb6ad817988eed9a8e0c22.json deleted file mode 100644 index c4d2414..0000000 --- a/.sqlx/query-a811cce764f6e5c5b5565d5c29e56e2fd229c024dacb6ad817988eed9a8e0c22.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "db_name": "SQLite", - "query": "\n select count(*) as \"exists: bool\"\n from _sqlx_migrations\n where version = $1\n and description = $2\n and hex(checksum) = $3\n ", - "describe": { - "columns": [ - { - "name": "exists: bool", - "ordinal": 0, - "type_info": "Integer" - } - ], - "parameters": { - "Right": 3 - }, - "nullable": [ - false - ] - }, - "hash": "a811cce764f6e5c5b5565d5c29e56e2fd229c024dacb6ad817988eed9a8e0c22" -} diff --git a/.sqlx/query-e7fcc523a4487a901460e904c0720b3c43c87fb335c2f7ca9fa694b9ca4822f7.json b/.sqlx/query-e7fcc523a4487a901460e904c0720b3c43c87fb335c2f7ca9fa694b9ca4822f7.json deleted file mode 100644 index 0309783..0000000 --- a/.sqlx/query-e7fcc523a4487a901460e904c0720b3c43c87fb335c2f7ca9fa694b9ca4822f7.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "db_name": "SQLite", - "query": "\n select count(*) as \"exists: bool\"\n from sqlite_master\n where name = '_sqlx_migrations'\n ", - "describe": { - "columns": [ - { - "name": "exists: bool", - "ordinal": 0, - "type_info": "Integer" - } - ], - "parameters": { - "Right": 0 - }, - "nullable": [ - false - ] - }, - "hash": "e7fcc523a4487a901460e904c0720b3c43c87fb335c2f7ca9fa694b9ca4822f7" -} @@ -775,6 +775,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" [[package]] +name = "hex-literal" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6fe2267d4ed49bc07b63801559be28c718ea06c4738b7a03c94df7386d2cde46" + +[[package]] name = "hi" version = "0.1.0" dependencies = [ @@ -787,6 +793,7 @@ dependencies = [ "faker_rand", "futures", "headers", + "hex-literal", "itertools", "libsqlite3-sys", "password-hash", @@ -4,11 +4,6 @@ version = "0.1.0" edition = "2021" [dependencies] -# Pinned to keep sqlx and libsqlite3 in lockstep. See also: -# <https://docs.rs/sqlx/latest/sqlx/sqlite/index.html> -sqlx = { version = "=0.8.2", features = ["chrono", "runtime-tokio", "sqlite"] } -libsqlite3-sys = { version = "=0.30.1", features = ["bundled"] } - argon2 = "0.5.3" async-trait = "0.1.83" axum = { version = "0.7.6", features = ["form"] } @@ -17,12 +12,19 @@ chrono = { version = "0.4.38", features = ["serde"] } clap = { version = "4.5.18", features = ["derive", "env"] } futures = "0.3.30" headers = "0.4.0" +hex-literal = "0.4.1" itertools = "0.13.0" +# Pinned to keep sqlx and libsqlite3 in lockstep. See also: +# <https://docs.rs/sqlx/latest/sqlx/sqlite/index.html> +libsqlite3-sys = { version = "=0.30.1", features = ["bundled"] } password-hash = { version = "0.5.0", features = ["std"] } rand = "0.8.5" rand_core = { version = "0.6.4", features = ["getrandom"] } serde = { version = "1.0.210", features = ["derive"] } serde_json = "1.0.128" +# Pinned to keep sqlx and libsqlite3 in lockstep. See also: +# <https://docs.rs/sqlx/latest/sqlx/sqlite/index.html> +sqlx = { version = "=0.8.2", features = ["chrono", "runtime-tokio", "sqlite"] } thiserror = "1.0.64" tokio = { version = "1.40.0", features = ["rt", "macros", "rt-multi-thread"] } tokio-stream = { version = "0.1.16", features = ["sync"] } diff --git a/src/db/mod.rs b/src/db/mod.rs index 61d5c18..090fa38 100644 --- a/src/db/mod.rs +++ b/src/db/mod.rs @@ -2,8 +2,9 @@ mod backup; use std::str::FromStr; +use hex_literal::hex; use sqlx::{ - migrate::MigrateDatabase as _, + migrate::{Migrate as _, MigrateDatabase as _}, sqlite::{Sqlite, SqliteConnectOptions, SqlitePool, SqlitePoolOptions}, }; @@ -16,7 +17,7 @@ pub async fn prepare(url: &str, backup_url: &str) -> Result<SqlitePool, Error> { // First migration of original migration series, from commit // 9bd6d9862b1c243def02200bca2cfbf578ad2a2f or earlier. - reject_migration(&pool, "20240831024047", "login", "9949D238C4099295EC4BEE734BFDA8D87513B2973DFB895352A11AB01DD46CB95314B7F1B3431B77E3444A165FE3DC28").await?; + reject_migration(&pool, "20240831024047", "login", &hex!("9949D238C4099295EC4BEE734BFDA8D87513B2973DFB895352A11AB01DD46CB95314B7F1B3431B77E3444A165FE3DC28")).await?; let backup_pool = create(backup_url).await?; backup::Backup::from(&pool) @@ -57,42 +58,19 @@ async fn reject_migration( pool: &SqlitePool, version: &str, description: &str, - checksum_hex: &str, + checksum: &[u8], ) -> Result<(), Error> { - if !sqlx::query_scalar!( - r#" - select count(*) as "exists: bool" - from sqlite_master - where name = '_sqlx_migrations' - "# - ) - .fetch_one(pool) - .await? - { - // No migrations table; this is a fresh DB. - return Ok(()); - } + let mut conn = pool.acquire().await?; + conn.ensure_migrations_table().await?; + let applied = conn.list_applied_migrations().await?; - if !sqlx::query_scalar!( - r#" - select count(*) as "exists: bool" - from _sqlx_migrations - where version = $1 - and description = $2 - and hex(checksum) = $3 - "#, - version, - description, - checksum_hex, - ) - .fetch_one(pool) - .await? - { - // Rejected migration does not exist; this DB never ran it. - return Ok(()); + for migration in applied { + if migration.checksum == checksum { + return Err(Error::Rejected(version.into(), description.into())); + } } - Err(Error::Rejected(version.into(), description.into())) + Ok(()) } /// Errors occurring during database setup. |
