// SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Commercial // SPDX-FileCopyrightText: 2025-2026 Christian Galo // Code generated by sqlc. DO NOT EDIT. // versions: // sqlc v1.29.0 // source: entitlement_set_changes.sql package entitlements import ( "context" "database/sql" "encoding/json" "time" "github.com/google/uuid" "github.com/lib/pq" "github.com/sqlc-dev/pqtype" ) const commitRuleChange = `-- name: CommitRuleChange :one SELECT (r).change_id::uuid AS change_id, (r).rule_id::uuid AS rule_id, (r).sync_path::varchar AS sync_path, (r).pool_count::integer AS pool_count, (r).org_count::integer AS org_count, (r).suspended_only_count::integer AS suspended_only_count FROM core.commit_rule_change( $1::uuid, $2::varchar, $3::uuid, $4::jsonb, $5::varchar, $6::uuid, $7::uuid, $8::text, $9::varchar, $10::timestamptz, $11::integer ) AS r ` type CommitRuleChangeParams struct { SetID string `json:"set_id"` ChangeKind string `json:"change_kind"` RuleID uuid.NullUUID `json:"rule_id"` Rule json.RawMessage `json:"rule"` ActorType string `json:"actor_type"` ActorPersonID uuid.NullUUID `json:"actor_person_id"` ActorServiceAccountID uuid.NullUUID `json:"actor_service_account_id"` Note sql.NullString `json:"note"` RequestID sql.NullString `json:"request_id"` EffectiveAt time.Time `json:"effective_at"` SyncCap int32 `json:"sync_cap"` } type CommitRuleChangeRow struct { ChangeID string `json:"change_id"` RuleID string `json:"rule_id"` SyncPath string `json:"sync_path"` PoolCount int32 `json:"pool_count"` OrgCount int32 `json:"org_count"` SuspendedOnlyCount int32 `json:"suspended_only_count"` } // The act rows (core.entitlement_set_changes) and the effect rows // (core.entitlement_set_change_effects) are append-only: nothing in this file // updates or deletes one. Both are written by core.commit_rule_change and // core.settle_obligation, so no Create query exists for any of the three // tables. The obligations are the one mutable table, a work list rather than // history, and only its status columns move. // The only write path to core.entitlement_set_rules. The calling transaction // must hold the exclusive materialization rendezvous, which the function // asserts: open it with BeginRuleChange. func (q *Queries) CommitRuleChange(ctx context.Context, arg CommitRuleChangeParams) (CommitRuleChangeRow, error) { row := q.db.QueryRowContext(ctx, commitRuleChange, arg.SetID, arg.ChangeKind, arg.RuleID, arg.Rule, arg.ActorType, arg.ActorPersonID, arg.ActorServiceAccountID, arg.Note, arg.RequestID, arg.EffectiveAt, arg.SyncCap, ) var i CommitRuleChangeRow err := row.Scan( &i.ChangeID, &i.RuleID, &i.SyncPath, &i.PoolCount, &i.OrgCount, &i.SuspendedOnlyCount, ) return i, err } const countEntitlementSetChangeEffectsByOrg = `-- name: CountEntitlementSetChangeEffectsByOrg :one SELECT COUNT(*)::BIGINT AS effect_count FROM core.entitlement_set_change_effects WHERE org_id = $1 ` func (q *Queries) CountEntitlementSetChangeEffectsByOrg(ctx context.Context, orgID string) (int64, error) { row := q.db.QueryRowContext(ctx, countEntitlementSetChangeEffectsByOrg, orgID) var effect_count int64 err := row.Scan(&effect_count) return effect_count, err } const countEntitlementSetChanges = `-- name: CountEntitlementSetChanges :one SELECT COUNT(*)::BIGINT AS change_count FROM core.entitlement_set_changes WHERE set_id = $1 ` func (q *Queries) CountEntitlementSetChanges(ctx context.Context, setID string) (int64, error) { row := q.db.QueryRowContext(ctx, countEntitlementSetChanges, setID) var change_count int64 err := row.Scan(&change_count) return change_count, err } const countFailedObligationsBySets = `-- name: CountFailedObligationsBySets :many SELECT c.set_id, COUNT(*)::BIGINT AS failed_count FROM core.entitlement_set_change_obligations o JOIN core.entitlement_set_changes c ON c.change_id = o.change_id WHERE c.set_id = ANY($1::uuid[]) AND o.status = 'failed' GROUP BY c.set_id ORDER BY c.set_id ASC ` type CountFailedObligationsBySetsRow struct { SetID string `json:"set_id"` FailedCount int64 `json:"failed_count"` } // The same count for a page of sets in one query rather than one per row. func (q *Queries) CountFailedObligationsBySets(ctx context.Context, setIds []string) ([]CountFailedObligationsBySetsRow, error) { rows, err := q.db.QueryContext(ctx, countFailedObligationsBySets, pq.Array(setIds)) if err != nil { return nil, err } defer rows.Close() items := []CountFailedObligationsBySetsRow{} for rows.Next() { var i CountFailedObligationsBySetsRow if err := rows.Scan(&i.SetID, &i.FailedCount); err != nil { return nil, err } items = append(items, i) } if err := rows.Close(); err != nil { return nil, err } if err := rows.Err(); err != nil { return nil, err } return items, nil } const countUnsettledObligationsBySet = `-- name: CountUnsettledObligationsBySet :one SELECT COUNT(*) FILTER (WHERE o.status = 'pending')::BIGINT AS pending_count, COUNT(*) FILTER (WHERE o.status = 'failed')::BIGINT AS failed_count FROM core.entitlement_set_change_obligations o JOIN core.entitlement_set_changes c ON c.change_id = o.change_id WHERE c.set_id = $1 ` type CountUnsettledObligationsBySetRow struct { PendingCount int64 `json:"pending_count"` FailedCount int64 `json:"failed_count"` } // What the set's Rules section reads: still draining and failed, separately. func (q *Queries) CountUnsettledObligationsBySet(ctx context.Context, setID string) (CountUnsettledObligationsBySetRow, error) { row := q.db.QueryRowContext(ctx, countUnsettledObligationsBySet, setID) var i CountUnsettledObligationsBySetRow err := row.Scan(&i.PendingCount, &i.FailedCount) return i, err } const getObligationStatus = `-- name: GetObligationStatus :one SELECT status, attempts FROM core.entitlement_set_change_obligations WHERE change_id = $1 AND pool_id = $2 ` type GetObligationStatusParams struct { ChangeID string `json:"change_id"` PoolID string `json:"pool_id"` } type GetObligationStatusRow struct { Status string `json:"status"` Attempts int32 `json:"attempts"` } // One obligation's state, which the drain reads before it does any work: an // obligation already settled is returned to a redispatched drain untouched. func (q *Queries) GetObligationStatus(ctx context.Context, arg GetObligationStatusParams) (GetObligationStatusRow, error) { row := q.db.QueryRowContext(ctx, getObligationStatus, arg.ChangeID, arg.PoolID) var i GetObligationStatusRow err := row.Scan(&i.Status, &i.Attempts) return i, err } const getRuleChangeStamp = `-- name: GetRuleChangeStamp :one SELECT r.resource_key, r.tier_reduction_policy FROM core.entitlement_set_changes c JOIN core.entitlement_set_rules r ON r.rule_id = c.rule_id WHERE c.change_id = $1 ` type GetRuleChangeStampRow struct { ResourceKey sql.NullString `json:"resource_key"` TierReductionPolicy string `json:"tier_reduction_policy"` } // The changed rule's resource key and reduction policy. The policy is // stamped on that key's effect row alone (doc-47 ยง5.2: the reduction policy // is the changed rule's, where the key is the rule's), so the key comes back // with it. The drain reads the pair once per change. func (q *Queries) GetRuleChangeStamp(ctx context.Context, changeID string) (GetRuleChangeStampRow, error) { row := q.db.QueryRowContext(ctx, getRuleChangeStamp, changeID) var i GetRuleChangeStampRow err := row.Scan(&i.ResourceKey, &i.TierReductionPolicy) return i, err } const listChangesSharingRequest = `-- name: ListChangesSharingRequest :many SELECT c.change_id, r.resource_key, r.tier_reduction_policy FROM core.entitlement_set_changes c JOIN core.entitlement_set_rules r ON r.rule_id = c.rule_id JOIN core.entitlement_set_changes named ON named.change_id = $1::uuid WHERE c.set_id = named.set_id AND (c.change_id = named.change_id OR (named.request_id IS NOT NULL AND c.request_id = named.request_id)) ORDER BY r.resource_key COLLATE "C" ASC NULLS FIRST, c.change_id ASC ` type ListChangesSharingRequestRow struct { ChangeID string `json:"change_id"` ResourceKey sql.NullString `json:"resource_key"` TierReductionPolicy string `json:"tier_reduction_policy"` } // The acts of one applied batch: the change named and every other act on the // same set carrying the same request identifier, which is what relates them // (entitlement-set-history, "Every committed act writes one change row and // one effect row per pool and key that moved"). Each comes back with its // rule's key and reduction policy, so the drain stamps and routes from one // read. The order is the commit's own, resource key ascending under the C // collation, which is the byte order Go sorted the deltas by, so the drain // re-derives the order the acts were filed in whatever the database's own // collation is; the first row is then the batch's first act, the one a // movement on a key no act names hangs off. A change with no request // identifier returns itself alone. func (q *Queries) ListChangesSharingRequest(ctx context.Context, changeID string) ([]ListChangesSharingRequestRow, error) { rows, err := q.db.QueryContext(ctx, listChangesSharingRequest, changeID) if err != nil { return nil, err } defer rows.Close() items := []ListChangesSharingRequestRow{} for rows.Next() { var i ListChangesSharingRequestRow if err := rows.Scan(&i.ChangeID, &i.ResourceKey, &i.TierReductionPolicy); err != nil { return nil, err } items = append(items, i) } if err := rows.Close(); err != nil { return nil, err } if err := rows.Err(); err != nil { return nil, err } return items, nil } const listChangesWithUnsettledObligations = `-- name: ListChangesWithUnsettledObligations :many SELECT DISTINCT o.change_id, c.set_id, MIN(o.created_at)::timestamptz AS oldest_created_at FROM core.entitlement_set_change_obligations o JOIN core.entitlement_set_changes c ON c.change_id = o.change_id WHERE o.status = 'pending' GROUP BY o.change_id, c.set_id ORDER BY oldest_created_at ASC, o.change_id ASC LIMIT $1 ` type ListChangesWithUnsettledObligationsRow struct { ChangeID string `json:"change_id"` SetID string `json:"set_id"` OldestCreatedAt time.Time `json:"oldest_created_at"` } // The poller's entry point, oldest act first: changes that still owe a // pending pool. A change whose remaining rows are all failed owes the drain // nothing until an operator's Retry requeues them. func (q *Queries) ListChangesWithUnsettledObligations(ctx context.Context, limit int32) ([]ListChangesWithUnsettledObligationsRow, error) { rows, err := q.db.QueryContext(ctx, listChangesWithUnsettledObligations, limit) if err != nil { return nil, err } defer rows.Close() items := []ListChangesWithUnsettledObligationsRow{} for rows.Next() { var i ListChangesWithUnsettledObligationsRow if err := rows.Scan(&i.ChangeID, &i.SetID, &i.OldestCreatedAt); err != nil { return nil, err } items = append(items, i) } if err := rows.Close(); err != nil { return nil, err } if err := rows.Err(); err != nil { return nil, err } return items, nil } const listEntitlementSetChangeEffects = `-- name: ListEntitlementSetChangeEffects :many SELECT e.effect_id, e.change_id, e.pool_id, e.org_id, e.org_name, e.resource_key, e.resource_label, e.limit_before, e.limit_after, e.granted_before, e.granted_after, e.usage_at_effect, e.over_usage, e.was_over_before, e.reduction_policy, e.created_at, e.governing_policy FROM core.entitlement_set_change_effects e WHERE e.change_id = $1 ORDER BY e.org_name ASC, e.resource_key ASC LIMIT $2 ` type ListEntitlementSetChangeEffectsParams struct { ChangeID string `json:"change_id"` Limit int32 `json:"limit"` } // The History row's expander: what one change did, per organization and key. func (q *Queries) ListEntitlementSetChangeEffects(ctx context.Context, arg ListEntitlementSetChangeEffectsParams) ([]EntitlementSetChangeEffect, error) { rows, err := q.db.QueryContext(ctx, listEntitlementSetChangeEffects, arg.ChangeID, arg.Limit) if err != nil { return nil, err } defer rows.Close() items := []EntitlementSetChangeEffect{} for rows.Next() { var i EntitlementSetChangeEffect if err := rows.Scan( &i.EffectID, &i.ChangeID, &i.PoolID, &i.OrgID, &i.OrgName, &i.ResourceKey, &i.ResourceLabel, &i.LimitBefore, &i.LimitAfter, &i.GrantedBefore, &i.GrantedAfter, &i.UsageAtEffect, &i.OverUsage, &i.WasOverBefore, &i.ReductionPolicy, &i.CreatedAt, &i.GoverningPolicy, ); err != nil { return nil, err } items = append(items, i) } if err := rows.Close(); err != nil { return nil, err } if err := rows.Err(); err != nil { return nil, err } return items, nil } const listEntitlementSetChangeEffectsByOrg = `-- name: ListEntitlementSetChangeEffectsByOrg :many SELECT e.effect_id, e.change_id, e.pool_id, e.org_id, e.org_name, e.resource_key, e.resource_label, e.limit_before, e.limit_after, e.granted_before, e.granted_after, e.usage_at_effect, e.over_usage, e.was_over_before, e.reduction_policy, e.governing_policy, e.created_at, c.set_id, c.set_name, c.change_kind, c.effective_at, c.note, c.actor_type, c.actor_person_id, c.actor_service_account_id FROM core.entitlement_set_change_effects e JOIN core.entitlement_set_changes c ON c.change_id = e.change_id WHERE e.org_id = $1 ORDER BY e.created_at DESC, e.effect_id DESC LIMIT $2 OFFSET $3 ` type ListEntitlementSetChangeEffectsByOrgParams struct { OrgID string `json:"org_id"` Limit int32 `json:"limit"` Offset int32 `json:"offset"` } type ListEntitlementSetChangeEffectsByOrgRow struct { EffectID string `json:"effect_id"` ChangeID string `json:"change_id"` PoolID string `json:"pool_id"` OrgID string `json:"org_id"` OrgName string `json:"org_name"` ResourceKey string `json:"resource_key"` ResourceLabel string `json:"resource_label"` LimitBefore sql.NullInt64 `json:"limit_before"` LimitAfter sql.NullInt64 `json:"limit_after"` GrantedBefore sql.NullBool `json:"granted_before"` GrantedAfter sql.NullBool `json:"granted_after"` UsageAtEffect sql.NullInt64 `json:"usage_at_effect"` OverUsage bool `json:"over_usage"` WasOverBefore bool `json:"was_over_before"` ReductionPolicy sql.NullString `json:"reduction_policy"` GoverningPolicy sql.NullString `json:"governing_policy"` CreatedAt time.Time `json:"created_at"` SetID string `json:"set_id"` SetName string `json:"set_name"` ChangeKind string `json:"change_kind"` EffectiveAt time.Time `json:"effective_at"` Note sql.NullString `json:"note"` ActorType string `json:"actor_type"` ActorPersonID uuid.NullUUID `json:"actor_person_id"` ActorServiceAccountID uuid.NullUUID `json:"actor_service_account_id"` } // The organization's trail: every rule change that moved one of its pools. // This is the effect row's audit projection (entitlement-set-history, "The // change row and every effect row project onto the audit view shape"): the // pool as the resource, the act's actor triple and occurrence reached through // the foreign key, and the payload's fields, which carry both policies, the // rule's own and the one that governed the pool and key. func (q *Queries) ListEntitlementSetChangeEffectsByOrg(ctx context.Context, arg ListEntitlementSetChangeEffectsByOrgParams) ([]ListEntitlementSetChangeEffectsByOrgRow, error) { rows, err := q.db.QueryContext(ctx, listEntitlementSetChangeEffectsByOrg, arg.OrgID, arg.Limit, arg.Offset) if err != nil { return nil, err } defer rows.Close() items := []ListEntitlementSetChangeEffectsByOrgRow{} for rows.Next() { var i ListEntitlementSetChangeEffectsByOrgRow if err := rows.Scan( &i.EffectID, &i.ChangeID, &i.PoolID, &i.OrgID, &i.OrgName, &i.ResourceKey, &i.ResourceLabel, &i.LimitBefore, &i.LimitAfter, &i.GrantedBefore, &i.GrantedAfter, &i.UsageAtEffect, &i.OverUsage, &i.WasOverBefore, &i.ReductionPolicy, &i.GoverningPolicy, &i.CreatedAt, &i.SetID, &i.SetName, &i.ChangeKind, &i.EffectiveAt, &i.Note, &i.ActorType, &i.ActorPersonID, &i.ActorServiceAccountID, ); err != nil { return nil, err } items = append(items, i) } if err := rows.Close(); err != nil { return nil, err } if err := rows.Err(); err != nil { return nil, err } return items, nil } const listEntitlementSetChanges = `-- name: ListEntitlementSetChanges :many SELECT c.change_id, c.set_id, c.set_name, c.change_kind, c.rule_id, c.resource_key, c.resource_label, c.rule_before, c.rule_after, c.rule_type, c.value_before, c.value_after, c.per_unit_before, c.per_unit_after, c.actor_type, c.actor_person_id, c.actor_service_account_id, c.note, c.request_id, c.sync_path, c.effective_at, c.created_at, (SELECT COUNT(*) FROM core.entitlement_set_change_obligations o WHERE o.change_id = c.change_id)::BIGINT AS pools_enumerated, (SELECT COUNT(*) FROM core.entitlement_set_change_obligations o WHERE o.change_id = c.change_id AND o.status = 'settled')::BIGINT AS pools_settled, (SELECT COUNT(*) FROM core.entitlement_set_change_obligations o WHERE o.change_id = c.change_id AND o.status = 'failed')::BIGINT AS pools_failed, (SELECT COUNT(DISTINCT e.pool_id) FROM core.entitlement_set_change_effects e WHERE e.change_id = c.change_id)::BIGINT AS pools_with_effects, (SELECT COUNT(DISTINCT e.pool_id) FROM core.entitlement_set_change_effects e WHERE e.change_id = c.change_id AND e.over_usage)::BIGINT AS pools_over_usage FROM core.entitlement_set_changes c WHERE c.set_id = $1 ORDER BY c.effective_at DESC, c.created_at DESC, c.change_id DESC LIMIT $2 OFFSET $3 ` type ListEntitlementSetChangesParams struct { SetID string `json:"set_id"` Limit int32 `json:"limit"` Offset int32 `json:"offset"` } type ListEntitlementSetChangesRow struct { ChangeID string `json:"change_id"` SetID string `json:"set_id"` SetName string `json:"set_name"` ChangeKind string `json:"change_kind"` RuleID string `json:"rule_id"` ResourceKey sql.NullString `json:"resource_key"` ResourceLabel sql.NullString `json:"resource_label"` RuleBefore pqtype.NullRawMessage `json:"rule_before"` RuleAfter json.RawMessage `json:"rule_after"` RuleType sql.NullString `json:"rule_type"` ValueBefore sql.NullInt64 `json:"value_before"` ValueAfter sql.NullInt64 `json:"value_after"` PerUnitBefore sql.NullBool `json:"per_unit_before"` PerUnitAfter sql.NullBool `json:"per_unit_after"` ActorType string `json:"actor_type"` ActorPersonID uuid.NullUUID `json:"actor_person_id"` ActorServiceAccountID uuid.NullUUID `json:"actor_service_account_id"` Note sql.NullString `json:"note"` RequestID sql.NullString `json:"request_id"` SyncPath string `json:"sync_path"` EffectiveAt time.Time `json:"effective_at"` CreatedAt time.Time `json:"created_at"` PoolsEnumerated int64 `json:"pools_enumerated"` PoolsSettled int64 `json:"pools_settled"` PoolsFailed int64 `json:"pools_failed"` PoolsWithEffects int64 `json:"pools_with_effects"` PoolsOverUsage int64 `json:"pools_over_usage"` } // The paged History of one set. The per-change counts are correlated // subqueries over the obligations and the effects, not stored columns. func (q *Queries) ListEntitlementSetChanges(ctx context.Context, arg ListEntitlementSetChangesParams) ([]ListEntitlementSetChangesRow, error) { rows, err := q.db.QueryContext(ctx, listEntitlementSetChanges, arg.SetID, arg.Limit, arg.Offset) if err != nil { return nil, err } defer rows.Close() items := []ListEntitlementSetChangesRow{} for rows.Next() { var i ListEntitlementSetChangesRow if err := rows.Scan( &i.ChangeID, &i.SetID, &i.SetName, &i.ChangeKind, &i.RuleID, &i.ResourceKey, &i.ResourceLabel, &i.RuleBefore, &i.RuleAfter, &i.RuleType, &i.ValueBefore, &i.ValueAfter, &i.PerUnitBefore, &i.PerUnitAfter, &i.ActorType, &i.ActorPersonID, &i.ActorServiceAccountID, &i.Note, &i.RequestID, &i.SyncPath, &i.EffectiveAt, &i.CreatedAt, &i.PoolsEnumerated, &i.PoolsSettled, &i.PoolsFailed, &i.PoolsWithEffects, &i.PoolsOverUsage, ); err != nil { return nil, err } items = append(items, i) } if err := rows.Close(); err != nil { return nil, err } if err := rows.Err(); err != nil { return nil, err } return items, nil } const listFailedObligations = `-- name: ListFailedObligations :many SELECT o.change_id, o.pool_id, o.attempts, o.last_attempt_at, o.last_error, rp.org_id, org.name AS org_name, c.resource_key, c.resource_label FROM core.entitlement_set_change_obligations o JOIN core.entitlement_set_changes c ON c.change_id = o.change_id JOIN core.resource_pools rp ON rp.pool_id = o.pool_id JOIN core.organizations org ON org.org_id = rp.org_id WHERE c.set_id = $1 AND o.status = 'failed' ORDER BY org.name ASC, o.pool_id ASC LIMIT $2 ` type ListFailedObligationsParams struct { SetID string `json:"set_id"` Limit int32 `json:"limit"` } type ListFailedObligationsRow struct { ChangeID string `json:"change_id"` PoolID string `json:"pool_id"` Attempts int32 `json:"attempts"` LastAttemptAt sql.NullTime `json:"last_attempt_at"` LastError sql.NullString `json:"last_error"` OrgID string `json:"org_id"` OrgName string `json:"org_name"` ResourceKey sql.NullString `json:"resource_key"` ResourceLabel sql.NullString `json:"resource_label"` } func (q *Queries) ListFailedObligations(ctx context.Context, arg ListFailedObligationsParams) ([]ListFailedObligationsRow, error) { rows, err := q.db.QueryContext(ctx, listFailedObligations, arg.SetID, arg.Limit) if err != nil { return nil, err } defer rows.Close() items := []ListFailedObligationsRow{} for rows.Next() { var i ListFailedObligationsRow if err := rows.Scan( &i.ChangeID, &i.PoolID, &i.Attempts, &i.LastAttemptAt, &i.LastError, &i.OrgID, &i.OrgName, &i.ResourceKey, &i.ResourceLabel, ); err != nil { return nil, err } items = append(items, i) } if err := rows.Close(); err != nil { return nil, err } if err := rows.Err(); err != nil { return nil, err } return items, nil } const listPendingObligations = `-- name: ListPendingObligations :many SELECT change_id, pool_id, status, attempts, last_attempt_at, last_error, settled_at, created_at FROM core.entitlement_set_change_obligations WHERE change_id = $1 AND status = 'pending' ORDER BY pool_id ASC LIMIT $2 ` type ListPendingObligationsParams struct { ChangeID string `json:"change_id"` Limit int32 `json:"limit"` } // The drain's work list for one change. failed is the dead letter: the drain // never picks one up again, and only RequeueFailedObligations, which the // operator's Retry calls, returns it to pending. func (q *Queries) ListPendingObligations(ctx context.Context, arg ListPendingObligationsParams) ([]EntitlementSetChangeObligation, error) { rows, err := q.db.QueryContext(ctx, listPendingObligations, arg.ChangeID, arg.Limit) if err != nil { return nil, err } defer rows.Close() items := []EntitlementSetChangeObligation{} for rows.Next() { var i EntitlementSetChangeObligation if err := rows.Scan( &i.ChangeID, &i.PoolID, &i.Status, &i.Attempts, &i.LastAttemptAt, &i.LastError, &i.SettledAt, &i.CreatedAt, ); err != nil { return nil, err } items = append(items, i) } if err := rows.Close(); err != nil { return nil, err } if err := rows.Err(); err != nil { return nil, err } return items, nil } const markObligationFailed = `-- name: MarkObligationFailed :exec SELECT core.settle_obligation( $1::uuid, $2::uuid, '[]'::jsonb, $3::text, $4::integer ) ` type MarkObligationFailedParams struct { ChangeID string `json:"change_id"` PoolID string `json:"pool_id"` Failure string `json:"failure"` MaxAttempts int32 `json:"max_attempts"` } // The failure half of the same function: no effect rows, the attempt and its // error recorded, and the row failed once attempts reach max_attempts. func (q *Queries) MarkObligationFailed(ctx context.Context, arg MarkObligationFailedParams) error { _, err := q.db.ExecContext(ctx, markObligationFailed, arg.ChangeID, arg.PoolID, arg.Failure, arg.MaxAttempts, ) return err } const requeueFailedObligations = `-- name: RequeueFailedObligations :exec UPDATE core.entitlement_set_change_obligations o SET status = 'pending', attempts = 0, last_error = NULL FROM core.entitlement_set_changes c WHERE c.change_id = o.change_id AND c.set_id = $1 AND o.status = 'failed' ` // The Retry control: failed rows go back on the work list with their attempt // count reset, so the drain gives each a fresh run of recomputeMaxAttempts. func (q *Queries) RequeueFailedObligations(ctx context.Context, setID string) error { _, err := q.db.ExecContext(ctx, requeueFailedObligations, setID) return err } const settleObligation = `-- name: SettleObligation :one SELECT core.settle_obligation( $1::uuid, $2::uuid, $3::jsonb, NULL )::integer AS effects_written ` type SettleObligationParams struct { ChangeID string `json:"change_id"` PoolID string `json:"pool_id"` Effects json.RawMessage `json:"effects"` } // Records what one pool's recomputation did and marks the obligation. The // calling transaction must hold the rendezvous in either mode. func (q *Queries) SettleObligation(ctx context.Context, arg SettleObligationParams) (int32, error) { row := q.db.QueryRowContext(ctx, settleObligation, arg.ChangeID, arg.PoolID, arg.Effects) var effects_written int32 err := row.Scan(&effects_written) return effects_written, err }