fix(indexer): recover cleanly from indexing failures
Move sqlite-vec embedding deletions outside the image transaction to avoid transactional virtual-table failures. Emit a terminal indexing progress event on errors so the frontend reloads partial state and clears its active scan state.
This commit is contained in:
+6
-2
@@ -901,10 +901,14 @@ pub fn get_folder_media_index(conn: &Connection, folder_id: i64) -> Result<Vec<I
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn delete_images_by_ids(conn: &Connection, image_ids: &[i64]) -> Result<()> {
|
pub fn delete_images_by_ids(conn: &Connection, image_ids: &[i64]) -> Result<()> {
|
||||||
|
// Delete from sqlite-vec virtual tables outside the transaction — sqlite-vec
|
||||||
|
// has known issues with transactional DML in early versions.
|
||||||
|
for image_id in image_ids {
|
||||||
|
vector::delete_embedding(conn, *image_id)?;
|
||||||
|
vector::delete_caption_embedding(conn, *image_id)?;
|
||||||
|
}
|
||||||
let tx = conn.unchecked_transaction()?;
|
let tx = conn.unchecked_transaction()?;
|
||||||
for image_id in image_ids {
|
for image_id in image_ids {
|
||||||
vector::delete_embedding(&tx, *image_id)?;
|
|
||||||
vector::delete_caption_embedding(&tx, *image_id)?;
|
|
||||||
tx.execute("DELETE FROM images WHERE id = ?1", [image_id])?;
|
tx.execute("DELETE FROM images WHERE id = ?1", [image_id])?;
|
||||||
}
|
}
|
||||||
tx.commit()?;
|
tx.commit()?;
|
||||||
|
|||||||
@@ -150,8 +150,19 @@ pub fn index_folder(app: AppHandle, pool: DbPool, folder_id: i64, folder_path: P
|
|||||||
let storage_profile = detect_storage_profile(&folder_path);
|
let storage_profile = detect_storage_profile(&folder_path);
|
||||||
set_folder_storage_profile(folder_id, RuntimeAdaptiveProfile::new(storage_profile));
|
set_folder_storage_profile(folder_id, RuntimeAdaptiveProfile::new(storage_profile));
|
||||||
set_folder_indexing_state(folder_id, true);
|
set_folder_indexing_state(folder_id, true);
|
||||||
if let Err(error) = do_index(app, pool, folder_id, folder_path) {
|
if let Err(error) = do_index(app.clone(), pool, folder_id, folder_path) {
|
||||||
eprintln!("Indexing error: {}", error);
|
eprintln!("Indexing error for folder {}: {}", folder_id, error);
|
||||||
|
// Always emit done so the frontend reloads and recovers from partial state.
|
||||||
|
emit_progress(
|
||||||
|
&app,
|
||||||
|
&IndexProgress {
|
||||||
|
folder_id,
|
||||||
|
total: 0,
|
||||||
|
indexed: 0,
|
||||||
|
current_file: String::new(),
|
||||||
|
done: true,
|
||||||
|
},
|
||||||
|
);
|
||||||
}
|
}
|
||||||
set_folder_indexing_state(folder_id, false);
|
set_folder_indexing_state(folder_id, false);
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user