customizable db locking during migration (#2063)

* 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>
This commit is contained in:
fuzzbuck
2022-09-06 22:42:56 +02:00
committed by GitHub
parent c5f3513f7d
commit 18a76fbdbf
3 changed files with 29 additions and 4 deletions

View File

@@ -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(
@@ -56,6 +57,7 @@ impl Migrator {
Ok(Self {
migrations: Cow::Owned(source.resolve().await.map_err(MigrateError::Source)?),
ignore_missing: false,
locking: true,
})
}
@@ -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()
@@ -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
@@ -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(())
}
@@ -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
@@ -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(())
}