Skip to content

Commit

Permalink
customizable db locking during migration (#2063)
Browse files Browse the repository at this point in the history
* customizable db locking during migration

* Update sqlx-core/src/migrate/migrator.rs

Co-authored-by: Austin Bonander <austin.bonander@gmail.com>

* [migrator.rs] cargo fmt

* fix Migrator 'locking' param doctest fail

Co-authored-by: Austin Bonander <austin.bonander@gmail.com>
  • Loading branch information
fuzzbuck and abonander authored Sep 6, 2022
1 parent c5f3513 commit 18a76fb
Show file tree
Hide file tree
Showing 3 changed files with 29 additions and 4 deletions.
31 changes: 27 additions & 4 deletions sqlx-core/src/migrate/migrator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ use std::slice;
pub struct Migrator {
pub migrations: Cow<'static, [Migration]>,
pub ignore_missing: bool,
pub locking: bool,
}

fn validate_applied_migrations(
Expand Down Expand Up @@ -56,6 +57,7 @@ impl Migrator {
Ok(Self {
migrations: Cow::Owned(source.resolve().await.map_err(MigrateError::Source)?),
ignore_missing: false,
locking: true,
})
}

Expand All @@ -65,6 +67,19 @@ impl Migrator {
self
}

/// Specify whether or not to lock database during migration. Defaults to `true`.
///
/// ### Warning
/// Disabling locking can lead to errors or data loss if multiple clients attempt to apply migrations simultaneously
/// without some sort of mutual exclusion.
///
/// This should only be used if the database does not support locking, e.g. CockroachDB which talks the Postgres
/// protocol but does not support advisory locks used by SQLx's migrations support for Postgres.
pub fn set_locking(&mut self, locking: bool) -> &Self {
self.locking = locking;
self
}

/// Get an iterator over all known migrations.
pub fn iter(&self) -> slice::Iter<'_, Migration> {
self.migrations.iter()
Expand Down Expand Up @@ -103,7 +118,9 @@ impl Migrator {
C: Migrate,
{
// lock the database for exclusive access by the migrator
conn.lock().await?;
if self.locking {
conn.lock().await?;
}

// creates [_migrations] table only if needed
// eventually this will likely migrate previous versions of the table
Expand Down Expand Up @@ -141,7 +158,9 @@ impl Migrator {

// unlock the migrator to allow other migrators to run
// but do nothing as we already migrated
conn.unlock().await?;
if self.locking {
conn.unlock().await?;
}

Ok(())
}
Expand Down Expand Up @@ -170,7 +189,9 @@ impl Migrator {
let mut conn = migrator.acquire().await?;

// lock the database for exclusive access by the migrator
conn.lock().await?;
if self.locking {
conn.lock().await?;
}

// creates [_migrations] table only if needed
// eventually this will likely migrate previous versions of the table
Expand Down Expand Up @@ -201,7 +222,9 @@ impl Migrator {

// unlock the migrator to allow other migrators to run
// but do nothing as we already migrated
conn.unlock().await?;
if self.locking {
conn.unlock().await?;
}

Ok(())
}
Expand Down
1 change: 1 addition & 0 deletions sqlx-macros/src/migrate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,7 @@ pub(crate) fn expand_migrator(path: &Path) -> crate::Result<TokenStream> {
#(#migrations),*
]),
ignore_missing: false,
locking: true,
}
})
}
1 change: 1 addition & 0 deletions src/macros/test.md
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,7 @@ use sqlx::PgPool;
# static MIGRATOR: sqlx::migrate::Migrator = sqlx::migrate::Migrator {
# migrations: Cow::Borrowed(&[]),
# ignore_missing: false,
# locking: true,
# };
# }
Expand Down

0 comments on commit 18a76fb

Please sign in to comment.