-- name: InsertLibraryChange :exec INSERT INTO library_changes (entity_type, entity_id, op) VALUES ($1, $2, $3); -- name: InsertLibraryChanges :exec -- Batch form, for a mutation that touches many rows at once (the scan's -- reconcile pass can mark up to a quarter of a library missing in one go). A -- loop of single inserts would be thousands of round-trips inside a scan that -- is already the slow path. INSERT INTO library_changes (entity_type, entity_id, op) SELECT sqlc.arg(entity_type)::text, unnest(sqlc.arg(entity_ids)::text[]), sqlc.arg(op)::text; -- name: GetLibraryChangesSince :many SELECT id, entity_type, entity_id, op, changed_at FROM library_changes WHERE id > $1 ORDER BY id ASC LIMIT $2; -- name: GetMaxLibraryChangeCursor :one SELECT COALESCE(MAX(id), 0)::BIGINT FROM library_changes; -- name: GetLastIssuedLibraryChangeCursor :one -- The highest cursor this server has handed out, even once the compactor has -- trimmed the rows: the id sequence's last value. A restored server's -- sequence stands at the backup's last change. SELECT COALESCE(pg_sequence_last_value(pg_get_serial_sequence('library_changes', 'id')::regclass), 0)::BIGINT; -- name: GetLibraryChangesTrimmedThrough :one -- The highest id of a delete the compactor has dropped. A cursor below it may -- have missed that delete. SELECT through FROM library_changes_trimmed; -- name: DeleteSupersededLibraryChanges :execrows -- Removes every row a newer row for the same entity has superseded. An app -- reading from any cursor still meets the newer row, so it loses nothing. DELETE FROM library_changes old WHERE EXISTS (SELECT 1 FROM library_changes newer WHERE newer.entity_type = old.entity_type AND newer.entity_id = old.entity_id AND newer.id > old.id); -- name: DeleteOldLibraryDeletes :one -- Removes deletes older than the cutoff and raises the trimmed mark past the -- highest one, so an app whose cursor is below it starts over. Returns how -- many went. WITH gone AS ( DELETE FROM library_changes WHERE op = 'delete' AND changed_at < $1 RETURNING id ), mark AS ( UPDATE library_changes_trimmed SET through = GREATEST(through, (SELECT COALESCE(max(id), 0) FROM gone)) ) SELECT count(*)::BIGINT FROM gone;