galleria_photo_face_rknn_op.../db/faceScanAutomation.js
2026-10-03 12:16:58 +02:00

219 lines
4.8 KiB
JavaScript

async function ensureFaceScanAutomation(db) {
const triggerNames = [
'photos_face_enqueue_insert',
'photos_face_enqueue_update',
'photos_face_cleanup_update',
'photos_face_cleanup_delete',
];
for (const triggerName of triggerNames) {
await db.raw(
`DROP TRIGGER IF EXISTS ${triggerName}`,
);
}
await db.raw(`
CREATE TRIGGER photos_face_enqueue_insert
AFTER INSERT ON photos
WHEN
NEW.deleted_at IS NULL
AND NEW.path IS NOT NULL
AND NEW.path != ''
AND (
NEW.mime_type IS NULL
OR NEW.mime_type LIKE 'image/%'
)
BEGIN
INSERT INTO face_scan_jobs (
photo_id,
status,
attempts,
rescan_requested,
created_at,
updated_at
)
VALUES (
NEW.id,
'pending',
0,
0,
CURRENT_TIMESTAMP,
CURRENT_TIMESTAMP
)
ON CONFLICT(photo_id) DO UPDATE SET
status = CASE
WHEN face_scan_jobs.status = 'processing'
THEN face_scan_jobs.status
ELSE 'pending'
END,
rescan_requested = CASE
WHEN face_scan_jobs.status = 'processing'
THEN 1
ELSE 0
END,
faces_detected = CASE
WHEN face_scan_jobs.status = 'processing'
THEN face_scan_jobs.faces_detected
ELSE NULL
END,
execution_ms = CASE
WHEN face_scan_jobs.status = 'processing'
THEN face_scan_jobs.execution_ms
ELSE NULL
END,
applied_rotation = CASE
WHEN face_scan_jobs.status = 'processing'
THEN face_scan_jobs.applied_rotation
ELSE NULL
END,
last_error = NULL,
started_at = CASE
WHEN face_scan_jobs.status = 'processing'
THEN face_scan_jobs.started_at
ELSE NULL
END,
completed_at = NULL,
updated_at = CURRENT_TIMESTAMP;
END
`);
await db.raw(`
CREATE TRIGGER photos_face_enqueue_update
AFTER UPDATE OF
path,
fast_hash,
mtimeMs,
size_bytes,
rotation,
mime_type,
deleted_at
ON photos
WHEN
NEW.deleted_at IS NULL
AND NEW.path IS NOT NULL
AND NEW.path != ''
AND (
NEW.mime_type IS NULL
OR NEW.mime_type LIKE 'image/%'
)
AND (
OLD.path IS NOT NEW.path
OR OLD.fast_hash IS NOT NEW.fast_hash
OR OLD.mtimeMs IS NOT NEW.mtimeMs
OR OLD.size_bytes IS NOT NEW.size_bytes
OR OLD.rotation IS NOT NEW.rotation
OR OLD.mime_type IS NOT NEW.mime_type
OR OLD.deleted_at IS NOT NEW.deleted_at
)
BEGIN
INSERT INTO face_scan_jobs (
photo_id,
status,
attempts,
rescan_requested,
created_at,
updated_at
)
VALUES (
NEW.id,
'pending',
0,
0,
CURRENT_TIMESTAMP,
CURRENT_TIMESTAMP
)
ON CONFLICT(photo_id) DO UPDATE SET
status = CASE
WHEN face_scan_jobs.status = 'processing'
THEN face_scan_jobs.status
ELSE 'pending'
END,
rescan_requested = CASE
WHEN face_scan_jobs.status = 'processing'
THEN 1
ELSE 0
END,
faces_detected = CASE
WHEN face_scan_jobs.status = 'processing'
THEN face_scan_jobs.faces_detected
ELSE NULL
END,
execution_ms = CASE
WHEN face_scan_jobs.status = 'processing'
THEN face_scan_jobs.execution_ms
ELSE NULL
END,
applied_rotation = CASE
WHEN face_scan_jobs.status = 'processing'
THEN face_scan_jobs.applied_rotation
ELSE NULL
END,
last_error = NULL,
started_at = CASE
WHEN face_scan_jobs.status = 'processing'
THEN face_scan_jobs.started_at
ELSE NULL
END,
completed_at = NULL,
updated_at = CURRENT_TIMESTAMP;
END
`);
await db.raw(`
CREATE TRIGGER photos_face_cleanup_update
AFTER UPDATE OF
path,
mime_type,
deleted_at
ON photos
WHEN
NEW.deleted_at IS NOT NULL
OR NEW.path IS NULL
OR NEW.path = ''
OR (
NEW.mime_type IS NOT NULL
AND NEW.mime_type NOT LIKE 'image/%'
)
BEGIN
DELETE FROM faces
WHERE photo_id = NEW.id;
DELETE FROM face_scan_jobs
WHERE photo_id = NEW.id;
END
`);
await db.raw(`
CREATE TRIGGER photos_face_cleanup_delete
AFTER DELETE ON photos
BEGIN
DELETE FROM faces
WHERE photo_id = OLD.id;
DELETE FROM face_scan_jobs
WHERE photo_id = OLD.id;
END
`);
console.log(
'✔ trigger automatici scansione volti creati',
);
}
module.exports = {
ensureFaceScanAutomation,
};