paymentsdb+sqldb: add migration related query

Add a migration specific query which allows to set the failure
reason when inserting a payment into the db.
This commit is contained in:
ziggie committed 2026-02-25 18:52:31 +01:00
1 parent e9a88267ff
commit 2596d34619
4 files changed
+179

No files matched your search

+19
View File
@@ -87,6 +87,25 @@ type SQLQueries interface {
// DeleteFailedAttempts removes all failed HTLCs from the db for a // DeleteFailedAttempts removes all failed HTLCs from the db for a
// given payment. // given payment.
DeleteFailedAttempts(ctx context.Context, paymentID int64) error DeleteFailedAttempts(ctx context.Context, paymentID int64) error
/*
Migration specific queries.
These queries are used ONLY for the one-time migration from KV
to SQL.
*/
// FetchPaymentsByIDsMig is a migration-only batch fetch that returns
// payment data along with HTLC attempt counts for structural
// validation.
FetchPaymentsByIDsMig(ctx context.Context, paymentIDs []int64) ([]sqlc.FetchPaymentsByIDsMigRow, error)
// InsertPaymentMig is a migration-only variant of InsertPayment that
// allows setting fail_reason when inserting historical payments, since
// for real payments they have not failed at creation time and so no
// failure reason would exist yet.
InsertPaymentMig(ctx context.Context, arg sqlc.InsertPaymentMigParams) (int64, error)
} }
// BatchedSQLQueries is a version of the SQLQueries that's capable // BatchedSQLQueries is a version of the SQLQueries that's capable
+111
View File
@@ -597,6 +597,72 @@ func (q *Queries) FetchPaymentsByIDs(ctx context.Context, paymentIds []int64) ([
return items, nil return items, nil
} }
const fetchPaymentsByIDsMig = `-- name: FetchPaymentsByIDsMig :many
SELECT
p.id,
p.amount_msat,
p.created_at,
p.payment_identifier,
p.fail_reason,
COUNT(ha.id) AS htlc_attempt_count
FROM payments p
LEFT JOIN payment_htlc_attempts ha ON ha.payment_id = p.id
WHERE p.id IN (/*SLICE:payment_ids*/?)
GROUP BY p.id, p.amount_msat, p.created_at, p.payment_identifier, p.fail_reason
ORDER BY p.id ASC
`
type FetchPaymentsByIDsMigRow struct {
ID int64
AmountMsat int64
CreatedAt time.Time
PaymentIdentifier []byte
FailReason sql.NullInt32
HtlcAttemptCount int64
}
// Migration-specific batch fetch that returns payment data along with HTLC
// attempt counts for structural validation during KV to SQL migration.
func (q *Queries) FetchPaymentsByIDsMig(ctx context.Context, paymentIds []int64) ([]FetchPaymentsByIDsMigRow, error) {
query := fetchPaymentsByIDsMig
var queryParams []interface{}
if len(paymentIds) > 0 {
for _, v := range paymentIds {
queryParams = append(queryParams, v)
}
query = strings.Replace(query, "/*SLICE:payment_ids*/?", makeQueryParams(len(queryParams), len(paymentIds)), 1)
} else {
query = strings.Replace(query, "/*SLICE:payment_ids*/?", "NULL", 1)
}
rows, err := q.db.QueryContext(ctx, query, queryParams...)
if err != nil {
return nil, err
}
defer rows.Close()
var items []FetchPaymentsByIDsMigRow
for rows.Next() {
var i FetchPaymentsByIDsMigRow
if err := rows.Scan(
&i.ID,
&i.AmountMsat,
&i.CreatedAt,
&i.PaymentIdentifier,
&i.FailReason,
&i.HtlcAttemptCount,
); 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 fetchRouteLevelFirstHopCustomRecords = `-- name: FetchRouteLevelFirstHopCustomRecords :many const fetchRouteLevelFirstHopCustomRecords = `-- name: FetchRouteLevelFirstHopCustomRecords :many
SELECT SELECT
l.id, l.id,
@@ -918,6 +984,51 @@ func (q *Queries) InsertPaymentIntent(ctx context.Context, arg InsertPaymentInte
return id, err return id, err
} }
const insertPaymentMig = `-- name: InsertPaymentMig :one
/* ─────────────────────────────────────────────
Migration-specific queries
These queries are used ONLY for the one-time migration from KV to SQL.
─────────────────────────────────────────────
*/
INSERT INTO payments (
amount_msat,
created_at,
payment_identifier,
fail_reason)
VALUES (
$1,
$2,
$3,
$4
)
RETURNING id
`
type InsertPaymentMigParams struct {
AmountMsat int64
CreatedAt time.Time
PaymentIdentifier []byte
FailReason sql.NullInt32
}
// Migration-specific payment insert that allows setting fail_reason.
// Normal InsertPayment forces fail_reason to NULL since new payments
// aren't failed yet. During migration, we're inserting historical data
// that may already be failed.
func (q *Queries) InsertPaymentMig(ctx context.Context, arg InsertPaymentMigParams) (int64, error) {
row := q.db.QueryRowContext(ctx, insertPaymentMig,
arg.AmountMsat,
arg.CreatedAt,
arg.PaymentIdentifier,
arg.FailReason,
)
var id int64
err := row.Scan(&id)
return id, err
}
const insertRouteHop = `-- name: InsertRouteHop :one const insertRouteHop = `-- name: InsertRouteHop :one
INSERT INTO payment_route_hops ( INSERT INTO payment_route_hops (
htlc_attempt_index, htlc_attempt_index,
+8
View File
@@ -54,6 +54,9 @@ type Querier interface {
// Used to avoid fetching redundant payment data when processing multiple // Used to avoid fetching redundant payment data when processing multiple
// attempts for the same payment. // attempts for the same payment.
FetchPaymentsByIDs(ctx context.Context, paymentIds []int64) ([]FetchPaymentsByIDsRow, error) FetchPaymentsByIDs(ctx context.Context, paymentIds []int64) ([]FetchPaymentsByIDsRow, error)
// Migration-specific batch fetch that returns payment data along with HTLC
// attempt counts for structural validation during KV to SQL migration.
FetchPaymentsByIDsMig(ctx context.Context, paymentIds []int64) ([]FetchPaymentsByIDsMigRow, error)
// FetchPendingInvoices returns all invoices in a pending state (open or // FetchPendingInvoices returns all invoices in a pending state (open or
// accepted). The invoices_state_idx index on the state column makes this a // accepted). The invoices_state_idx index on the state column makes this a
// fast index scan rather than a full table scan. // fast index scan rather than a full table scan.
@@ -178,6 +181,11 @@ type Querier interface {
InsertPaymentHopCustomRecord(ctx context.Context, arg InsertPaymentHopCustomRecordParams) error InsertPaymentHopCustomRecord(ctx context.Context, arg InsertPaymentHopCustomRecordParams) error
// Insert a payment intent for a given payment and return its ID. // Insert a payment intent for a given payment and return its ID.
InsertPaymentIntent(ctx context.Context, arg InsertPaymentIntentParams) (int64, error) InsertPaymentIntent(ctx context.Context, arg InsertPaymentIntentParams) (int64, error)
// Migration-specific payment insert that allows setting fail_reason.
// Normal InsertPayment forces fail_reason to NULL since new payments
// aren't failed yet. During migration, we're inserting historical data
// that may already be failed.
InsertPaymentMig(ctx context.Context, arg InsertPaymentMigParams) (int64, error)
InsertRouteHop(ctx context.Context, arg InsertRouteHopParams) (int64, error) InsertRouteHop(ctx context.Context, arg InsertRouteHopParams) (int64, error)
InsertRouteHopAmp(ctx context.Context, arg InsertRouteHopAmpParams) error InsertRouteHopAmp(ctx context.Context, arg InsertRouteHopAmpParams) error
InsertRouteHopBlinded(ctx context.Context, arg InsertRouteHopBlindedParams) error InsertRouteHopBlinded(ctx context.Context, arg InsertRouteHopBlindedParams) error
+41
View File
@@ -368,3 +368,44 @@ VALUES (
-- name: FailPayment :execresult -- name: FailPayment :execresult
UPDATE payments SET fail_reason = $1 WHERE payment_identifier = $2; UPDATE payments SET fail_reason = $1 WHERE payment_identifier = $2;
/* ─────────────────────────────────────────────
Migration-specific queries
These queries are used ONLY for the one-time migration from KV to SQL.
─────────────────────────────────────────────
*/
-- name: InsertPaymentMig :one
-- Migration-specific payment insert that allows setting fail_reason.
-- Normal InsertPayment forces fail_reason to NULL since new payments
-- aren't failed yet. During migration, we're inserting historical data
-- that may already be failed.
INSERT INTO payments (
amount_msat,
created_at,
payment_identifier,
fail_reason)
VALUES (
@amount_msat,
@created_at,
@payment_identifier,
@fail_reason
)
RETURNING id;
-- name: FetchPaymentsByIDsMig :many
-- Migration-specific batch fetch that returns payment data along with HTLC
-- attempt counts for structural validation during KV to SQL migration.
SELECT
p.id,
p.amount_msat,
p.created_at,
p.payment_identifier,
p.fail_reason,
COUNT(ha.id) AS htlc_attempt_count
FROM payments p
LEFT JOIN payment_htlc_attempts ha ON ha.payment_id = p.id
WHERE p.id IN (sqlc.slice('payment_ids')/*SLICE:payment_ids*/)
GROUP BY p.id, p.amount_msat, p.created_at, p.payment_identifier, p.fail_reason
ORDER BY p.id ASC;