From 18c3a842ca1b63dbcd00434421c7b9586a2d2ae6 Mon Sep 17 00:00:00 2001 From: nickbrowne Date: Wed, 22 Oct 2025 16:58:59 +1100 Subject: [PATCH] Guard against multiple snapshots inserted during PUT for given doc This change is temporary to give us an opportunity to clean up the data and fix the db constraints. --- src/server/db/pg.coffee | 31 ++++++++++++++++++++++--------- 1 file changed, 22 insertions(+), 9 deletions(-) diff --git a/src/server/db/pg.coffee b/src/server/db/pg.coffee index 8ec6c89..a56d14c 100644 --- a/src/server/db/pg.coffee +++ b/src/server/db/pg.coffee @@ -88,18 +88,31 @@ module.exports = PgDb = (options) -> callback? error.message @create = (docName, docData, callback) -> - sql = """ - INSERT INTO #{snapshot_table} ("doc", "v", "snapshot", "meta", "type", "created_at") - VALUES ($1, $2, ($3)::jsonb, $4, $5, now() at time zone 'UTC') + # Temporarily guard against improper constraints allowing + # multiple snapshots to be inserted for a given docName + check_snapshots_sql = """ + SELECT count("doc") FROM #{snapshot_table} + WHERE "doc" = $1 """ - values = [docName, docData.v, JSON.stringify(docData.snapshot), docData.meta, docData.type] - client.query sql, values, (error, result) -> - if !error? - callback?() - else if error.toString().match "duplicate key value violates unique constraint" + + client.query check_snapshots_sql, [docName], (error, result) -> + if !error? and result.rows.length > 0 and result.rows[0].count > 0 callback? "Document already exists" - else + else if error? callback? error?.message + else + sql = """ + INSERT INTO #{snapshot_table} ("doc", "v", "snapshot", "meta", "type", "created_at") + VALUES ($1, $2, ($3)::jsonb, $4, $5, now() at time zone 'UTC') + """ + values = [docName, docData.v, JSON.stringify(docData.snapshot), docData.meta, docData.type] + client.query sql, values, (error, result) -> + if !error? + callback?() + else if error.toString().match "duplicate key value violates unique constraint" + callback? "Document already exists" + else + callback? error?.message @delete = (docName, dbMeta, callback) -> sql = """