fix: Unique constraint should account for soft deleted records (#11048)

FIXES FRMW-2878

**What**
Currently, the `one-to-one` unique constraints does not account for deleted record. This prevents from inserting a new record wth the same fk if another one is deleted.

**Caveat**
`hasOne` with FK option is meant to be a special case, for example a many to one - one to many without defining the other side of the relation. In that case we don't handle this behaviour and keep it as it is
This commit is contained in:
Adrien de Peretti
2025-01-22 07:42:06 +00:00
committed by GitHub
parent ecc8efcb04
commit da3906efa4
22 changed files with 361 additions and 217 deletions
@@ -242,15 +242,6 @@
"name": "promotion_campaign_budget",
"schema": "public",
"indexes": [
{
"columnNames": [
"campaign_id"
],
"composite": false,
"keyName": "promotion_campaign_budget_campaign_id_unique",
"primary": false,
"unique": true
},
{
"keyName": "IDX_campaign_budget_type",
"columnNames": [],
@@ -260,12 +251,12 @@
"expression": "CREATE INDEX IF NOT EXISTS \"IDX_campaign_budget_type\" ON \"promotion_campaign_budget\" (type) WHERE deleted_at IS NULL"
},
{
"keyName": "IDX_promotion_campaign_budget_campaign_id",
"keyName": "IDX_promotion_campaign_budget_campaign_id_unique",
"columnNames": [],
"composite": false,
"primary": false,
"unique": false,
"expression": "CREATE INDEX IF NOT EXISTS \"IDX_promotion_campaign_budget_campaign_id\" ON \"promotion_campaign_budget\" (campaign_id) WHERE deleted_at IS NULL"
"expression": "CREATE UNIQUE INDEX IF NOT EXISTS \"IDX_promotion_campaign_budget_campaign_id_unique\" ON \"promotion_campaign_budget\" (campaign_id) WHERE deleted_at IS NULL"
},
{
"keyName": "IDX_promotion_campaign_budget_deleted_at",
@@ -630,15 +621,6 @@
"name": "promotion_application_method",
"schema": "public",
"indexes": [
{
"columnNames": [
"promotion_id"
],
"composite": false,
"keyName": "promotion_application_method_promotion_id_unique",
"primary": false,
"unique": true
},
{
"keyName": "IDX_application_method_type",
"columnNames": [],
@@ -664,12 +646,12 @@
"expression": "CREATE INDEX IF NOT EXISTS \"IDX_application_method_allocation\" ON \"promotion_application_method\" (allocation) WHERE deleted_at IS NULL"
},
{
"keyName": "IDX_promotion_application_method_promotion_id",
"keyName": "IDX_promotion_application_method_promotion_id_unique",
"columnNames": [],
"composite": false,
"primary": false,
"unique": false,
"expression": "CREATE INDEX IF NOT EXISTS \"IDX_promotion_application_method_promotion_id\" ON \"promotion_application_method\" (promotion_id) WHERE deleted_at IS NULL"
"expression": "CREATE UNIQUE INDEX IF NOT EXISTS \"IDX_promotion_application_method_promotion_id_unique\" ON \"promotion_application_method\" (promotion_id) WHERE deleted_at IS NULL"
},
{
"keyName": "IDX_promotion_application_method_deleted_at",
@@ -0,0 +1,25 @@
import { Migration } from '@mikro-orm/migrations';
export class Migration20250120110700 extends Migration {
async up(): Promise<void> {
this.addSql('alter table if exists "promotion_campaign_budget" drop constraint if exists "promotion_campaign_budget_campaign_id_unique";');
this.addSql('drop index if exists "IDX_promotion_campaign_budget_campaign_id";');
this.addSql('CREATE UNIQUE INDEX IF NOT EXISTS "IDX_promotion_campaign_budget_campaign_id_unique" ON "promotion_campaign_budget" (campaign_id) WHERE deleted_at IS NULL;');
this.addSql('alter table if exists "promotion_application_method" drop constraint if exists "promotion_application_method_promotion_id_unique";');
this.addSql('drop index if exists "IDX_promotion_application_method_promotion_id";');
this.addSql('CREATE UNIQUE INDEX IF NOT EXISTS "IDX_promotion_application_method_promotion_id_unique" ON "promotion_application_method" (promotion_id) WHERE deleted_at IS NULL;');
}
async down(): Promise<void> {
this.addSql('drop index if exists "IDX_promotion_campaign_budget_campaign_id_unique";');
this.addSql('alter table if exists "promotion_campaign_budget" add constraint "promotion_campaign_budget_campaign_id_unique" unique ("campaign_id");');
this.addSql('CREATE INDEX IF NOT EXISTS "IDX_promotion_campaign_budget_campaign_id" ON "promotion_campaign_budget" (campaign_id) WHERE deleted_at IS NULL;');
this.addSql('drop index if exists "IDX_promotion_application_method_promotion_id_unique";');
this.addSql('alter table if exists "promotion_application_method" add constraint "promotion_application_method_promotion_id_unique" unique ("promotion_id");');
this.addSql('CREATE INDEX IF NOT EXISTS "IDX_promotion_application_method_promotion_id" ON "promotion_application_method" (promotion_id) WHERE deleted_at IS NULL;');
}
}