Add exclusion constraint to prevent duplicate items within 10m (#1747)
* Add exclusion constraint to prevent duplicate items within 10m * Fix missing extension * More user-friendly error message * Use MD5 for slightly better performance * Always use MD5 for columns of type TEXT * shift constraint into the future --------- Co-authored-by: k00b <k00b@stacker.news>
This commit is contained in:
parent
9783df8e3b
commit
c89220dbde
|
@ -2,6 +2,7 @@ import { ANON_ITEM_SPAM_INTERVAL, ITEM_SPAM_INTERVAL, PAID_ACTION_PAYMENT_METHOD
|
||||||
import { notifyItemMention, notifyItemParents, notifyMention, notifyTerritorySubscribers, notifyUserSubscribers } from '@/lib/webPush'
|
import { notifyItemMention, notifyItemParents, notifyMention, notifyTerritorySubscribers, notifyUserSubscribers } from '@/lib/webPush'
|
||||||
import { getItemMentions, getMentions, performBotBehavior } from './lib/item'
|
import { getItemMentions, getMentions, performBotBehavior } from './lib/item'
|
||||||
import { msatsToSats, satsToMsats } from '@/lib/format'
|
import { msatsToSats, satsToMsats } from '@/lib/format'
|
||||||
|
import { GqlInputError } from '@/lib/error'
|
||||||
|
|
||||||
export const anonable = true
|
export const anonable = true
|
||||||
|
|
||||||
|
@ -137,7 +138,15 @@ export async function perform (args, context) {
|
||||||
}
|
}
|
||||||
})).bio
|
})).bio
|
||||||
} else {
|
} else {
|
||||||
item = await tx.item.create({ data: itemData })
|
try {
|
||||||
|
item = await tx.item.create({ data: itemData })
|
||||||
|
} catch (err) {
|
||||||
|
if (err.message.includes('violates exclusion constraint \\"Item_unique_time_constraint\\"')) {
|
||||||
|
const message = `you already submitted this ${itemData.title ? 'post' : 'comment'}`
|
||||||
|
throw new GqlInputError(message)
|
||||||
|
}
|
||||||
|
throw err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// store a reference to the item in the invoice
|
// store a reference to the item in the invoice
|
||||||
|
|
|
@ -0,0 +1,15 @@
|
||||||
|
-- create a partial exclusion constraint that prevents insertion of duplicate items within 10 minutes
|
||||||
|
CREATE EXTENSION IF NOT EXISTS btree_gist;
|
||||||
|
ALTER TABLE "Item" ADD CONSTRAINT "Item_unique_time_constraint"
|
||||||
|
EXCLUDE USING gist (
|
||||||
|
"userId" WITH =,
|
||||||
|
-- we use COALESCE so NULL is considered equal to itself. we also use md5 hashes because columns
|
||||||
|
-- of type TEXT can make index row too large and columns of type CITEXT are not supported by GiST.
|
||||||
|
COALESCE("parentId", -1) WITH =,
|
||||||
|
md5(COALESCE("title", '')) WITH =,
|
||||||
|
md5(COALESCE("subName", '')) WITH =,
|
||||||
|
md5(COALESCE("text", '')) WITH =,
|
||||||
|
tsrange(created_at, created_at + INTERVAL '10 minutes') WITH &&
|
||||||
|
)
|
||||||
|
-- enforce constraint after this date
|
||||||
|
WHERE (created_at > '2024-12-30');
|
Loading…
Reference in New Issue