-- Non-destructive photo editing: the parameters live in the photo metadata and -- the edited image is stored as separate objects next to the base variants. -- SQLite cannot alter a CHECK constraint, so photo_objects is rebuilt with the -- extended role set. ALTER TABLE photos ADD COLUMN edit_params TEXT NOT NULL DEFAULT '{}'; CREATE TABLE photo_objects_new ( photo_id TEXT NOT NULL REFERENCES photos(id) ON DELETE CASCADE, object_id TEXT NOT NULL REFERENCES objects(id) ON DELETE RESTRICT, role TEXT NOT NULL CHECK (role IN ('original', 'thumb', 'medium', 'preview', 'playback', 'edit', 'edit_thumb', 'edit_medium', 'edit_preview')), PRIMARY KEY (photo_id, role) ); INSERT INTO photo_objects_new (photo_id, object_id, role) SELECT photo_id, object_id, role FROM photo_objects; DROP TABLE photo_objects; ALTER TABLE photo_objects_new RENAME TO photo_objects; CREATE INDEX IF NOT EXISTS photo_objects_object_idx ON photo_objects (object_id); -- Durable queue of pending edit renders, one job per photo. CREATE TABLE edit_jobs ( photo_id TEXT PRIMARY KEY REFERENCES photos(id) ON DELETE CASCADE, attempts INTEGER NOT NULL DEFAULT 0, next_attempt_at TEXT NOT NULL DEFAULT (strftime('%Y-%m-%dT%H:%M:%fZ', 'now')), last_error TEXT NOT NULL DEFAULT '', created_at TEXT NOT NULL DEFAULT (strftime('%Y-%m-%dT%H:%M:%fZ', 'now')) ); CREATE INDEX edit_jobs_due_idx ON edit_jobs (next_attempt_at);