textmachine/platform/internal/pgstore/idempotency.sql.go

215 lines
5.5 KiB
Go

// Code generated by sqlc. DO NOT EDIT.
// versions:
// sqlc v1.31.1
// source: idempotency.sql
package pgstore
import (
"context"
"time"
)
const completeIdempotencyKey = `-- name: CompleteIdempotencyKey :execrows
update idempotency_keys
set status = $1, location = $2, body = $3,
finished_at = $4, content_sha256 = $5
where user_id = $6 and method = $7
and path_sha256 = $8 and key = $9
and claim_token = $10 and finished_at is null
`
type CompleteIdempotencyKeyParams struct {
Status *int32
Location string
Body []byte
FinishedAt *time.Time
ContentSha256 []byte
UserID string
Method string
PathSha256 []byte
Key string
ClaimToken string
}
// Only the attempt that still HOLDS the claim may write the receipt.
func (q *Queries) CompleteIdempotencyKey(ctx context.Context, arg CompleteIdempotencyKeyParams) (int64, error) {
result, err := q.db.Exec(ctx, completeIdempotencyKey,
arg.Status,
arg.Location,
arg.Body,
arg.FinishedAt,
arg.ContentSha256,
arg.UserID,
arg.Method,
arg.PathSha256,
arg.Key,
arg.ClaimToken,
)
if err != nil {
return 0, err
}
return result.RowsAffected(), nil
}
const insertIdempotencyClaim = `-- name: InsertIdempotencyClaim :execrows
insert into idempotency_keys (user_id, method, path, path_sha256, key, request_sha256, claimed_at, claim_token)
values ($1, $2, $3, $4, $5,
$6, $7, $8)
on conflict (user_id, method, path_sha256, key) do nothing
`
type InsertIdempotencyClaimParams struct {
UserID string
Method string
Path string
PathSha256 []byte
Key string
RequestSha256 []byte
ClaimedAt time.Time
ClaimToken string
}
// `do nothing` plus a re-read decides between two simultaneous first attempts; a bare insert made
// the loser raise a unique violation — a 500 on the one case this header exists for.
func (q *Queries) InsertIdempotencyClaim(ctx context.Context, arg InsertIdempotencyClaimParams) (int64, error) {
result, err := q.db.Exec(ctx, insertIdempotencyClaim,
arg.UserID,
arg.Method,
arg.Path,
arg.PathSha256,
arg.Key,
arg.RequestSha256,
arg.ClaimedAt,
arg.ClaimToken,
)
if err != nil {
return 0, err
}
return result.RowsAffected(), nil
}
const readIdempotencyKey = `-- name: ReadIdempotencyKey :one
select request_sha256, status, location, body, claimed_at, finished_at, content_sha256
from idempotency_keys
where user_id = $1 and method = $2
and path_sha256 = $3 and key = $4 for update
`
type ReadIdempotencyKeyParams struct {
UserID string
Method string
PathSha256 []byte
Key string
}
type ReadIdempotencyKeyRow struct {
RequestSha256 []byte
Status *int32
Location string
Body []byte
ClaimedAt time.Time
FinishedAt *time.Time
ContentSha256 []byte
}
// The storage half of `Idempotency-Key`.
// `for update` on a MISSING row locks nothing, which is why the caller has an insert-then-re-read
// path behind this and not a bare insert.
func (q *Queries) ReadIdempotencyKey(ctx context.Context, arg ReadIdempotencyKeyParams) (ReadIdempotencyKeyRow, error) {
row := q.db.QueryRow(ctx, readIdempotencyKey,
arg.UserID,
arg.Method,
arg.PathSha256,
arg.Key,
)
var i ReadIdempotencyKeyRow
err := row.Scan(
&i.RequestSha256,
&i.Status,
&i.Location,
&i.Body,
&i.ClaimedAt,
&i.FinishedAt,
&i.ContentSha256,
)
return i, err
}
const releaseIdempotencyKey = `-- name: ReleaseIdempotencyKey :execrows
delete from idempotency_keys
where user_id = $1 and method = $2
and path_sha256 = $3 and key = $4
and claim_token = $5 and finished_at is null
`
type ReleaseIdempotencyKeyParams struct {
UserID string
Method string
PathSha256 []byte
Key string
ClaimToken string
}
// On the token for the same reason as the completion: a slow attempt that finally failed used to
// delete the row of the successor which had taken the key over and was already doing the work.
func (q *Queries) ReleaseIdempotencyKey(ctx context.Context, arg ReleaseIdempotencyKeyParams) (int64, error) {
result, err := q.db.Exec(ctx, releaseIdempotencyKey,
arg.UserID,
arg.Method,
arg.PathSha256,
arg.Key,
arg.ClaimToken,
)
if err != nil {
return 0, err
}
return result.RowsAffected(), nil
}
const retakeIdempotencyClaim = `-- name: RetakeIdempotencyClaim :exec
update idempotency_keys
set claimed_at = $1, request_sha256 = $2,
claim_token = $3
where user_id = $4 and method = $5
and path_sha256 = $6 and key = $7
`
type RetakeIdempotencyClaimParams struct {
ClaimedAt time.Time
RequestSha256 []byte
ClaimToken string
UserID string
Method string
PathSha256 []byte
Key string
}
// The NEW token is what stops the old attempt — which may still be alive and merely slow — from
// completing or releasing what is no longer its claim.
func (q *Queries) RetakeIdempotencyClaim(ctx context.Context, arg RetakeIdempotencyClaimParams) error {
_, err := q.db.Exec(ctx, retakeIdempotencyClaim,
arg.ClaimedAt,
arg.RequestSha256,
arg.ClaimToken,
arg.UserID,
arg.Method,
arg.PathSha256,
arg.Key,
)
return err
}
const sweepIdempotency = `-- name: SweepIdempotency :execrows
delete from idempotency_keys where claimed_at < $1
`
// Forgets records past the window the contract promises ("at least 24 hours").
func (q *Queries) SweepIdempotency(ctx context.Context, before time.Time) (int64, error) {
result, err := q.db.Exec(ctx, sweepIdempotency, before)
if err != nil {
return 0, err
}
return result.RowsAffected(), nil
}