fix: four more correctness bugs from PR review
- Duplicate scanner now emits one DuplicateGroup per distinct full hash within a sample-hash bucket, preventing disjoint sets (A,A vs B,B) from being merged and presented as a single deletable group - Tagger model download now installs the shared ONNX runtime DLLs via ensure_onnx_runtime so the tagger is ready on a clean install without requiring the caption model to have been downloaded first - Caption queue clear now follows the tagging worker pattern: marks in-flight rows as cancelled and deletes only non-processing rows; the caption worker skips writing results for cancelled jobs; startup cleanup removes any leftover cancelled caption rows - Region search pagination now stores the crop rect in state and uses find_similar_by_region for subsequent pages instead of falling through to loadImages which appended unrelated folder results
This commit is contained in:
+32
-4
@@ -511,6 +511,7 @@ pub fn reset_inflight_jobs(conn: &Connection) -> Result<()> {
|
||||
// Delete any rows that were cancelled before the previous shutdown so
|
||||
// they don't silently linger in the DB across restarts.
|
||||
conn.execute("DELETE FROM tagging_jobs WHERE status = 'cancelled'", [])?;
|
||||
conn.execute("DELETE FROM caption_jobs WHERE status = 'cancelled'", [])?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -588,13 +589,22 @@ pub fn requeue_processing_caption_jobs_for_folder(
|
||||
}
|
||||
|
||||
pub fn clear_caption_jobs(conn: &Connection, folder_id: Option<i64>) -> Result<usize> {
|
||||
// Mirror the tagging worker pattern: mark in-flight rows as cancelled so
|
||||
// the worker can detect cancellation before writing results, then delete
|
||||
// every non-processing row immediately (pending, failed, etc.).
|
||||
match folder_id {
|
||||
Some(folder_id) => {
|
||||
conn.execute(
|
||||
"UPDATE caption_jobs
|
||||
SET status = 'cancelled', last_error = NULL, updated_at = datetime('now')
|
||||
WHERE status = 'processing'
|
||||
AND image_id IN (SELECT id FROM images WHERE folder_id = ?1)",
|
||||
[folder_id],
|
||||
)?;
|
||||
let deleted = conn.execute(
|
||||
"DELETE FROM caption_jobs
|
||||
WHERE image_id IN (
|
||||
SELECT id FROM images WHERE folder_id = ?1
|
||||
)",
|
||||
WHERE status NOT IN ('processing', 'cancelled')
|
||||
AND image_id IN (SELECT id FROM images WHERE folder_id = ?1)",
|
||||
[folder_id],
|
||||
)?;
|
||||
conn.execute(
|
||||
@@ -607,7 +617,16 @@ pub fn clear_caption_jobs(conn: &Connection, folder_id: Option<i64>) -> Result<u
|
||||
Ok(deleted)
|
||||
}
|
||||
None => {
|
||||
let deleted = conn.execute("DELETE FROM caption_jobs", [])?;
|
||||
conn.execute(
|
||||
"UPDATE caption_jobs
|
||||
SET status = 'cancelled', last_error = NULL, updated_at = datetime('now')
|
||||
WHERE status = 'processing'",
|
||||
[],
|
||||
)?;
|
||||
let deleted = conn.execute(
|
||||
"DELETE FROM caption_jobs WHERE status NOT IN ('processing', 'cancelled')",
|
||||
[],
|
||||
)?;
|
||||
conn.execute(
|
||||
"UPDATE images
|
||||
SET caption_error = NULL
|
||||
@@ -619,6 +638,15 @@ pub fn clear_caption_jobs(conn: &Connection, folder_id: Option<i64>) -> Result<u
|
||||
}
|
||||
}
|
||||
|
||||
pub fn is_caption_job_cancelled(conn: &Connection, image_id: i64) -> Result<bool> {
|
||||
let count: i64 = conn.query_row(
|
||||
"SELECT COUNT(*) FROM caption_jobs WHERE image_id = ?1 AND status = 'cancelled'",
|
||||
[image_id],
|
||||
|row| row.get(0),
|
||||
)?;
|
||||
Ok(count > 0)
|
||||
}
|
||||
|
||||
pub fn reset_generated_captions(conn: &Connection, folder_id: Option<i64>) -> Result<usize> {
|
||||
let image_ids = match folder_id {
|
||||
Some(folder_id) => {
|
||||
|
||||
Reference in New Issue
Block a user