From aa5f2e43d439c032155df6622f4b431e96c275d0 Mon Sep 17 00:00:00 2001 From: Alexander Akhmetov Date: Fri, 7 Mar 2025 08:36:14 +0100 Subject: [PATCH] Alerting: Use upsert to set or update provenance (#101688) Alerting: Use upsert to update provenance --- .../ngalert/store/provisioning_store.go | 25 +++++++++---------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/pkg/services/ngalert/store/provisioning_store.go b/pkg/services/ngalert/store/provisioning_store.go index 52c828090c1..d6999eec31d 100644 --- a/pkg/services/ngalert/store/provisioning_store.go +++ b/pkg/services/ngalert/store/provisioning_store.go @@ -70,21 +70,20 @@ func (st DBstore) SetProvenance(ctx context.Context, o models.Provisionable, org // TODO: Add a unit-of-work pattern, so updating objects + provenance will happen consistently with rollbacks across stores. // TODO: Need to make sure that writing a record where our concurrency key fails will also fail the whole transaction. That way, this gets rolled back too. can't just check that 0 updates happened inmemory. Check with jp. If not possible, we need our own concurrency key. // TODO: Clean up stale provenance records periodically. - filter := "record_key = ? AND record_type = ? AND org_id = ?" - _, err := sess.Table(provenanceRecord{}).Where(filter, recordKey, recordType, org).Delete(provenanceRecord{}) + upsertSQL := st.SQLStore.GetDialect().UpsertSQL( + provenanceRecord{}.TableName(), + []string{"record_key", "record_type", "org_id"}, + []string{"record_key", "record_type", "org_id", "provenance"}) + params := []interface{}{ + recordKey, + recordType, + org, + p, + } + + _, err := sess.SQL(upsertSQL, params...).Query() if err != nil { - return fmt.Errorf("failed to delete pre-existing provisioning status: %w", err) - } - - record := provenanceRecord{ - RecordKey: recordKey, - RecordType: recordType, - Provenance: p, - OrgID: org, - } - - if _, err := sess.Insert(record); err != nil { return fmt.Errorf("failed to store provisioning status: %w", err) }