mirror of
https://github.com/logos-messaging/libchat.git
synced 2026-03-26 22:23:14 +00:00
fix: transactional sql migration
This commit is contained in:
parent
c3e5f361bb
commit
030ab475be
@ -25,8 +25,8 @@ impl ChatStorage {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Applies all migrations and returns the storage instance.
|
/// Applies all migrations and returns the storage instance.
|
||||||
fn run_migrations(db: SqliteDb) -> Result<Self, StorageError> {
|
fn run_migrations(mut db: SqliteDb) -> Result<Self, StorageError> {
|
||||||
migrations::apply_migrations(db.connection())?;
|
migrations::apply_migrations(db.connection_mut())?;
|
||||||
Ok(Self { db })
|
Ok(Self { db })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
//! Database migrations module.
|
//! Database migrations module.
|
||||||
//!
|
//!
|
||||||
//! SQL migrations are embedded at compile time and applied in order.
|
//! SQL migrations are embedded at compile time and applied in order.
|
||||||
|
//! Each migration is applied atomically within a transaction.
|
||||||
|
|
||||||
use storage::{Connection, StorageError};
|
use storage::{Connection, StorageError};
|
||||||
|
|
||||||
@ -13,8 +14,9 @@ pub fn get_migrations() -> Vec<(&'static str, &'static str)> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Applies all migrations to the database.
|
/// Applies all migrations to the database.
|
||||||
|
///
|
||||||
/// Uses a simple version tracking table to avoid re-running migrations.
|
/// Uses a simple version tracking table to avoid re-running migrations.
|
||||||
pub fn apply_migrations(conn: &Connection) -> Result<(), StorageError> {
|
pub fn apply_migrations(conn: &mut Connection) -> Result<(), StorageError> {
|
||||||
// Create migrations tracking table if it doesn't exist
|
// Create migrations tracking table if it doesn't exist
|
||||||
conn.execute_batch(
|
conn.execute_batch(
|
||||||
"CREATE TABLE IF NOT EXISTS _migrations (
|
"CREATE TABLE IF NOT EXISTS _migrations (
|
||||||
@ -32,11 +34,11 @@ pub fn apply_migrations(conn: &Connection) -> Result<(), StorageError> {
|
|||||||
)?;
|
)?;
|
||||||
|
|
||||||
if !already_applied {
|
if !already_applied {
|
||||||
// Apply migration
|
// Apply migration and record it atomically in a transaction
|
||||||
conn.execute_batch(sql)?;
|
let tx = conn.transaction()?;
|
||||||
|
tx.execute_batch(sql)?;
|
||||||
// Record migration
|
tx.execute("INSERT INTO _migrations (name) VALUES (?1)", [name])?;
|
||||||
conn.execute("INSERT INTO _migrations (name) VALUES (?1)", [name])?;
|
tx.commit()?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -66,6 +66,13 @@ impl SqliteDb {
|
|||||||
&self.conn
|
&self.conn
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns a mutable reference to the underlying connection.
|
||||||
|
///
|
||||||
|
/// Use this for operations that require mutable access, such as transactions.
|
||||||
|
pub fn connection_mut(&mut self) -> &mut Connection {
|
||||||
|
&mut self.conn
|
||||||
|
}
|
||||||
|
|
||||||
/// Begins a transaction.
|
/// Begins a transaction.
|
||||||
pub fn transaction(&mut self) -> Result<rusqlite::Transaction<'_>, StorageError> {
|
pub fn transaction(&mut self) -> Result<rusqlite::Transaction<'_>, StorageError> {
|
||||||
Ok(self.conn.transaction()?)
|
Ok(self.conn.transaction()?)
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user