From baa9182aa7b77965ca4c3268c39aef09afd6e491 Mon Sep 17 00:00:00 2001 From: Yonas Habteab Date: Tue, 14 Jul 2026 12:36:14 +0200 Subject: [PATCH] Add superfluous PK to `incident_contact` table --- go.mod | 2 +- go.sum | 4 ++-- internal/incident/db_types.go | 1 + internal/incident/sync.go | 2 +- schema/mysql/schema.sql | 2 ++ schema/mysql/upgrades/incident_contact-pk.sql | 3 +++ schema/pgsql/schema.sql | 3 +++ schema/pgsql/upgrades/incident_contact-pk.sql | 3 +++ 8 files changed, 16 insertions(+), 4 deletions(-) create mode 100644 schema/mysql/upgrades/incident_contact-pk.sql create mode 100644 schema/pgsql/upgrades/incident_contact-pk.sql diff --git a/go.mod b/go.mod index 4f8fd88d..6f8b9c69 100644 --- a/go.mod +++ b/go.mod @@ -7,7 +7,7 @@ require ( github.com/emersion/go-sasl v0.0.0-20241020182733-b788ff22d5a6 github.com/emersion/go-smtp v0.24.0 github.com/google/uuid v1.6.0 - github.com/icinga/icinga-go-library v0.9.1-0.20260703073729-01bbc172ffe3 + github.com/icinga/icinga-go-library v0.9.1-0.20260714123216-927526041e77 github.com/jhillyerd/enmime v1.3.0 github.com/jmoiron/sqlx v1.4.0 github.com/okzk/sdnotify v0.0.0-20180710141335-d9becc38acbd diff --git a/go.sum b/go.sum index f300d76b..f2fdeeda 100644 --- a/go.sum +++ b/go.sum @@ -36,8 +36,8 @@ github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/icinga/icinga-go-library v0.9.1-0.20260703073729-01bbc172ffe3 h1:SQfajIIhA8MSEz4/TvvkoZ3KelZqehN0p5cO+s6V+oY= -github.com/icinga/icinga-go-library v0.9.1-0.20260703073729-01bbc172ffe3/go.mod h1:XFsuZEn2hrE3YXQ3NHqnI2UkjdZgJJWb/7D/+VH6MsE= +github.com/icinga/icinga-go-library v0.9.1-0.20260714123216-927526041e77 h1:YQS63i/R9rHd72SYfNdSDZzgiU4kp1tv3vkdYyf4skM= +github.com/icinga/icinga-go-library v0.9.1-0.20260714123216-927526041e77/go.mod h1:HDw4ODUuK0oineNCDzrJjFBdI0i1F3O2ODbQsiAiZ8k= github.com/jaytaylor/html2text v0.0.0-20230321000545-74c2419ad056 h1:iCHtR9CQyktQ5+f3dMVZfwD2KWJUgm7M0gdL9NGr8KA= github.com/jaytaylor/html2text v0.0.0-20230321000545-74c2419ad056/go.mod h1:CVKlgaMiht+LXvHG173ujK6JUhZXKb2u/BQtjPDIvyk= github.com/jessevdk/go-flags v1.6.1 h1:Cvu5U8UGrLay1rZfv/zP7iLpSHGUZ/Ou68T0iX1bBK4= diff --git a/internal/incident/db_types.go b/internal/incident/db_types.go index 6dd5a2ef..1b705c95 100644 --- a/internal/incident/db_types.go +++ b/internal/incident/db_types.go @@ -12,6 +12,7 @@ import ( // ContactRow represents a single incident contact database entry. type ContactRow struct { + ID int64 `db:"id"` IncidentID int64 `db:"incident_id"` recipient.Key `db:",inline"` Role ContactRole `db:"role"` diff --git a/internal/incident/sync.go b/internal/incident/sync.go index f012c7bd..314592d3 100644 --- a/internal/incident/sync.go +++ b/internal/incident/sync.go @@ -102,7 +102,7 @@ func (i *Incident) AddRecipient(ctx context.Context, tx *sqlx.Tx, escalation *ru cr.Role = state.Role } - stmt, _ := i.db.BuildUpsertStmt(cr) + stmt, _ := i.db.BuildUpsertStmt(cr, "id") _, err := tx.NamedExecContext(ctx, stmt, cr) if err != nil { i.logger.Errorw( diff --git a/schema/mysql/schema.sql b/schema/mysql/schema.sql index 907e1dee..93af1e35 100644 --- a/schema/mysql/schema.sql +++ b/schema/mysql/schema.sql @@ -363,6 +363,7 @@ CREATE TABLE incident ( CREATE INDEX idx_incident_recovered_at ON incident(recovered_at); CREATE TABLE incident_contact ( + id bigint NOT NULL AUTO_INCREMENT, -- not used for anything, but is required to satisfy some Galera cluster constraints not allowing to replicate a table without a PK. incident_id bigint NOT NULL, contact_id bigint, contactgroup_id bigint, @@ -370,6 +371,7 @@ CREATE TABLE incident_contact ( role enum('recipient', 'subscriber', 'manager'), -- NOT NULL is enforced via CHECK not to default to 'recipient' changed_at bigint NOT NULL, -- used only by Notifications Web to show when the recipients role was last changed. + CONSTRAINT pk_incident_contact PRIMARY KEY (id), CONSTRAINT uk_incident_contact_incident_id_contact_id UNIQUE (incident_id, contact_id), CONSTRAINT uk_incident_contact_incident_id_contactgroup_id UNIQUE (incident_id, contactgroup_id), CONSTRAINT uk_incident_contact_incident_id_schedule_id UNIQUE (incident_id, schedule_id), diff --git a/schema/mysql/upgrades/incident_contact-pk.sql b/schema/mysql/upgrades/incident_contact-pk.sql new file mode 100644 index 00000000..b5f08132 --- /dev/null +++ b/schema/mysql/upgrades/incident_contact-pk.sql @@ -0,0 +1,3 @@ +ALTER TABLE incident_contact + ADD COLUMN id bigint NOT NULL AUTO_INCREMENT FIRST, + ADD CONSTRAINT pk_incident_contact PRIMARY KEY (id); diff --git a/schema/pgsql/schema.sql b/schema/pgsql/schema.sql index aff16842..ec62995e 100644 --- a/schema/pgsql/schema.sql +++ b/schema/pgsql/schema.sql @@ -392,6 +392,7 @@ CREATE INDEX idx_incident_recovered_at ON incident(recovered_at); CREATE TYPE incident_contact_role AS ENUM ('recipient', 'subscriber', 'manager'); CREATE TABLE incident_contact ( + id bigserial, -- not used for anything, but is required to satisfy some Galera cluster constraints not allowing to replicate a table without a PK. incident_id bigint NOT NULL, contact_id bigint, contactgroup_id bigint, @@ -399,6 +400,8 @@ CREATE TABLE incident_contact ( role incident_contact_role NOT NULL, changed_at bigint NOT NULL, -- used only by Notifications Web to show when the recipients role was last changed. + CONSTRAINT pk_incident_contact PRIMARY KEY (id), + -- Keep in sync with internal/incident/db_types.go! CONSTRAINT uk_incident_contact_incident_id_contact_id UNIQUE (incident_id, contact_id), CONSTRAINT uk_incident_contact_incident_id_contactgroup_id UNIQUE (incident_id, contactgroup_id), diff --git a/schema/pgsql/upgrades/incident_contact-pk.sql b/schema/pgsql/upgrades/incident_contact-pk.sql new file mode 100644 index 00000000..a4fcc683 --- /dev/null +++ b/schema/pgsql/upgrades/incident_contact-pk.sql @@ -0,0 +1,3 @@ +ALTER TABLE incident_contact + ADD COLUMN id bigserial, + ADD CONSTRAINT pk_incident_contact PRIMARY KEY (id);