pinakes-core: wrap save_markdown_links in transactions for atomicity
Signed-off-by: NotAShelf <raf@notashelf.dev> Change-Id: I44eaeda5bc1d6894137ee9a3c902cdac6a6a6964
This commit is contained in:
parent
9afe4a4f6a
commit
4ed61bc62e
2 changed files with 43 additions and 27 deletions
|
|
@ -6047,7 +6047,7 @@ impl StorageBackend for PostgresBackend {
|
|||
media_id: MediaId,
|
||||
links: &[crate::model::MarkdownLink],
|
||||
) -> Result<()> {
|
||||
let client = self
|
||||
let mut client = self
|
||||
.pool
|
||||
.get()
|
||||
.await
|
||||
|
|
@ -6055,9 +6055,14 @@ impl StorageBackend for PostgresBackend {
|
|||
|
||||
let media_id_str = media_id.0.to_string();
|
||||
|
||||
// Wrap DELETE + INSERT in transaction to ensure atomicity
|
||||
let tx = client
|
||||
.transaction()
|
||||
.await
|
||||
.map_err(|e| PinakesError::Database(e.to_string()))?;
|
||||
|
||||
// Delete existing links for this source
|
||||
client
|
||||
.execute(
|
||||
tx.execute(
|
||||
"DELETE FROM markdown_links WHERE source_media_id = $1",
|
||||
&[&media_id_str],
|
||||
)
|
||||
|
|
@ -6067,8 +6072,7 @@ impl StorageBackend for PostgresBackend {
|
|||
// Insert new links
|
||||
for link in links {
|
||||
let target_media_id = link.target_media_id.map(|id| id.0.to_string());
|
||||
client
|
||||
.execute(
|
||||
tx.execute(
|
||||
"INSERT INTO markdown_links (
|
||||
id, source_media_id, target_path, target_media_id,
|
||||
link_type, link_text, line_number, context, created_at
|
||||
|
|
@ -6089,6 +6093,11 @@ impl StorageBackend for PostgresBackend {
|
|||
.map_err(|e| PinakesError::Database(e.to_string()))?;
|
||||
}
|
||||
|
||||
// Commit transaction - if this fails, all changes are rolled back
|
||||
tx.commit()
|
||||
.await
|
||||
.map_err(|e| PinakesError::Database(e.to_string()))?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -6400,16 +6400,19 @@ impl StorageBackend for SqliteBackend {
|
|||
let links: Vec<_> = links.to_vec();
|
||||
|
||||
tokio::task::spawn_blocking(move || {
|
||||
let conn = conn.lock().unwrap();
|
||||
let mut conn = conn.lock().unwrap();
|
||||
|
||||
// Wrap DELETE + INSERT in transaction to ensure atomicity
|
||||
let tx = conn.transaction()?;
|
||||
|
||||
// Delete existing links for this source
|
||||
conn.execute(
|
||||
tx.execute(
|
||||
"DELETE FROM markdown_links WHERE source_media_id = ?1",
|
||||
[&media_id_str],
|
||||
)?;
|
||||
|
||||
// Insert new links
|
||||
let mut stmt = conn.prepare(
|
||||
let mut stmt = tx.prepare(
|
||||
"INSERT INTO markdown_links (
|
||||
id, source_media_id, target_path, target_media_id,
|
||||
link_type, link_text, line_number, context, created_at
|
||||
|
|
@ -6430,6 +6433,10 @@ impl StorageBackend for SqliteBackend {
|
|||
])?;
|
||||
}
|
||||
|
||||
// Commit transaction - if this fails, all changes are rolled back
|
||||
drop(stmt);
|
||||
tx.commit()?;
|
||||
|
||||
Ok::<_, rusqlite::Error>(())
|
||||
})
|
||||
.await
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue