// Code generated by sqlc. DO NOT EDIT. // versions: // sqlc v1.29.0 // source: payments.sql package sqlc import ( "context" "database/sql" "strings" "time" ) const countPayments = `-- name: CountPayments :one SELECT COUNT(*) FROM payments ` func (q *Queries) CountPayments(ctx context.Context) (int64, error) { row := q.db.QueryRowContext(ctx, countPayments) var count int64 err := row.Scan(&count) return count, err } const deleteFailedAttempts = `-- name: DeleteFailedAttempts :exec DELETE FROM payment_htlc_attempts WHERE payment_id = $1 AND EXISTS ( SELECT 1 FROM payment_htlc_attempt_resolutions hr WHERE hr.attempt_index = payment_htlc_attempts.attempt_index AND hr.resolution_type = 2 ) ` // Delete all failed HTLC attempts for the given payment. Resolution type 2 // indicates a failed attempt. Uses EXISTS to scope the resolution lookup to // only this payment's attempts, avoiding an O(N) scan of all failed // resolutions across all payments. func (q *Queries) DeleteFailedAttempts(ctx context.Context, paymentID int64) error { _, err := q.db.ExecContext(ctx, deleteFailedAttempts, paymentID) return err } const deletePayment = `-- name: DeletePayment :exec DELETE FROM payments WHERE id = $1 ` func (q *Queries) DeletePayment(ctx context.Context, id int64) error { _, err := q.db.ExecContext(ctx, deletePayment, id) return err } const failAttempt = `-- name: FailAttempt :exec INSERT INTO payment_htlc_attempt_resolutions ( attempt_index, resolution_time, resolution_type, failure_source_index, htlc_fail_reason, failure_msg ) VALUES ( $1, $2, $3, $4, $5, $6 ) ` type FailAttemptParams struct { AttemptIndex int64 ResolutionTime time.Time ResolutionType int32 FailureSourceIndex sql.NullInt32 HtlcFailReason sql.NullInt32 FailureMsg []byte } func (q *Queries) FailAttempt(ctx context.Context, arg FailAttemptParams) error { _, err := q.db.ExecContext(ctx, failAttempt, arg.AttemptIndex, arg.ResolutionTime, arg.ResolutionType, arg.FailureSourceIndex, arg.HtlcFailReason, arg.FailureMsg, ) return err } const failPayment = `-- name: FailPayment :execresult UPDATE payments SET fail_reason = $1 WHERE payment_identifier = $2 ` type FailPaymentParams struct { FailReason sql.NullInt32 PaymentIdentifier []byte } func (q *Queries) FailPayment(ctx context.Context, arg FailPaymentParams) (sql.Result, error) { return q.db.ExecContext(ctx, failPayment, arg.FailReason, arg.PaymentIdentifier) } const fetchHopLevelCustomRecords = `-- name: FetchHopLevelCustomRecords :many SELECT l.id, l.hop_id, l.key, l.value FROM payment_hop_custom_records l WHERE l.hop_id IN (/*SLICE:hop_ids*/?) ORDER BY l.hop_id ASC, l.key ASC ` func (q *Queries) FetchHopLevelCustomRecords(ctx context.Context, hopIds []int64) ([]PaymentHopCustomRecord, error) { query := fetchHopLevelCustomRecords var queryParams []interface{} if len(hopIds) > 0 { for _, v := range hopIds { queryParams = append(queryParams, v) } query = strings.Replace(query, "/*SLICE:hop_ids*/?", makeQueryParams(len(queryParams), len(hopIds)), 1) } else { query = strings.Replace(query, "/*SLICE:hop_ids*/?", "NULL", 1) } rows, err := q.db.QueryContext(ctx, query, queryParams...) if err != nil { return nil, err } defer rows.Close() var items []PaymentHopCustomRecord for rows.Next() { var i PaymentHopCustomRecord if err := rows.Scan( &i.ID, &i.HopID, &i.Key, &i.Value, ); 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 fetchHopsForAttempts = `-- name: FetchHopsForAttempts :many SELECT h.id, h.htlc_attempt_index, h.hop_index, h.pub_key, h.scid, h.outgoing_time_lock, h.amt_to_forward, h.meta_data, m.payment_addr AS mpp_payment_addr, m.total_msat AS mpp_total_msat, a.root_share AS amp_root_share, a.set_id AS amp_set_id, a.child_index AS amp_child_index, b.encrypted_data, b.blinding_point, b.blinded_path_total_amt FROM payment_route_hops h LEFT JOIN payment_route_hop_mpp m ON m.hop_id = h.id LEFT JOIN payment_route_hop_amp a ON a.hop_id = h.id LEFT JOIN payment_route_hop_blinded b ON b.hop_id = h.id WHERE h.htlc_attempt_index IN (/*SLICE:htlc_attempt_indices*/?) ORDER BY h.htlc_attempt_index ASC, h.hop_index ASC ` type FetchHopsForAttemptsRow struct { ID int64 HtlcAttemptIndex int64 HopIndex int32 PubKey []byte Scid string OutgoingTimeLock int32 AmtToForward int64 MetaData []byte MppPaymentAddr []byte MppTotalMsat sql.NullInt64 AmpRootShare []byte AmpSetID []byte AmpChildIndex sql.NullInt32 EncryptedData []byte BlindingPoint []byte BlindedPathTotalAmt sql.NullInt64 } func (q *Queries) FetchHopsForAttempts(ctx context.Context, htlcAttemptIndices []int64) ([]FetchHopsForAttemptsRow, error) { query := fetchHopsForAttempts var queryParams []interface{} if len(htlcAttemptIndices) > 0 { for _, v := range htlcAttemptIndices { queryParams = append(queryParams, v) } query = strings.Replace(query, "/*SLICE:htlc_attempt_indices*/?", makeQueryParams(len(queryParams), len(htlcAttemptIndices)), 1) } else { query = strings.Replace(query, "/*SLICE:htlc_attempt_indices*/?", "NULL", 1) } rows, err := q.db.QueryContext(ctx, query, queryParams...) if err != nil { return nil, err } defer rows.Close() var items []FetchHopsForAttemptsRow for rows.Next() { var i FetchHopsForAttemptsRow if err := rows.Scan( &i.ID, &i.HtlcAttemptIndex, &i.HopIndex, &i.PubKey, &i.Scid, &i.OutgoingTimeLock, &i.AmtToForward, &i.MetaData, &i.MppPaymentAddr, &i.MppTotalMsat, &i.AmpRootShare, &i.AmpSetID, &i.AmpChildIndex, &i.EncryptedData, &i.BlindingPoint, &i.BlindedPathTotalAmt, ); 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 fetchHtlcAttemptResolutionsForPayments = `-- name: FetchHtlcAttemptResolutionsForPayments :many SELECT ha.payment_id, hr.resolution_type FROM payment_htlc_attempts ha LEFT JOIN payment_htlc_attempt_resolutions hr ON hr.attempt_index = ha.attempt_index WHERE ha.payment_id IN (/*SLICE:payment_ids*/?) ` type FetchHtlcAttemptResolutionsForPaymentsRow struct { PaymentID int64 ResolutionType sql.NullInt32 } // Batch query to fetch only HTLC resolution status for multiple payments. // We don't need to order by payment_id and attempt_time because we will // group the resolutions by payment_id in the background. func (q *Queries) FetchHtlcAttemptResolutionsForPayments(ctx context.Context, paymentIds []int64) ([]FetchHtlcAttemptResolutionsForPaymentsRow, error) { query := fetchHtlcAttemptResolutionsForPayments 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 []FetchHtlcAttemptResolutionsForPaymentsRow for rows.Next() { var i FetchHtlcAttemptResolutionsForPaymentsRow if err := rows.Scan(&i.PaymentID, &i.ResolutionType); 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 fetchHtlcAttemptsForPayments = `-- name: FetchHtlcAttemptsForPayments :many SELECT ha.id, ha.attempt_index, ha.payment_id, ha.session_key, ha.attempt_time, ha.payment_hash, ha.first_hop_amount_msat, ha.route_total_time_lock, ha.route_total_amount, ha.route_source_key, hr.resolution_type, hr.resolution_time, hr.failure_source_index, hr.htlc_fail_reason, hr.failure_msg, hr.settle_preimage FROM payment_htlc_attempts ha LEFT JOIN payment_htlc_attempt_resolutions hr ON hr.attempt_index = ha.attempt_index WHERE ha.payment_id IN (/*SLICE:payment_ids*/?) ORDER BY ha.payment_id ASC, ha.attempt_time ASC ` type FetchHtlcAttemptsForPaymentsRow struct { ID int64 AttemptIndex int64 PaymentID int64 SessionKey []byte AttemptTime time.Time PaymentHash []byte FirstHopAmountMsat int64 RouteTotalTimeLock int32 RouteTotalAmount int64 RouteSourceKey []byte ResolutionType sql.NullInt32 ResolutionTime sql.NullTime FailureSourceIndex sql.NullInt32 HtlcFailReason sql.NullInt32 FailureMsg []byte SettlePreimage []byte } func (q *Queries) FetchHtlcAttemptsForPayments(ctx context.Context, paymentIds []int64) ([]FetchHtlcAttemptsForPaymentsRow, error) { query := fetchHtlcAttemptsForPayments 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 []FetchHtlcAttemptsForPaymentsRow for rows.Next() { var i FetchHtlcAttemptsForPaymentsRow if err := rows.Scan( &i.ID, &i.AttemptIndex, &i.PaymentID, &i.SessionKey, &i.AttemptTime, &i.PaymentHash, &i.FirstHopAmountMsat, &i.RouteTotalTimeLock, &i.RouteTotalAmount, &i.RouteSourceKey, &i.ResolutionType, &i.ResolutionTime, &i.FailureSourceIndex, &i.HtlcFailReason, &i.FailureMsg, &i.SettlePreimage, ); 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 fetchNonTerminalPayments = `-- name: FetchNonTerminalPayments :many SELECT p.id, p.amount_msat, p.created_at, p.payment_identifier, p.fail_reason, pi.intent_type, pi.intent_payload FROM payments p LEFT JOIN payment_intents pi ON pi.payment_id = p.id WHERE p.id > $1 AND ( ( p.fail_reason IS NULL AND NOT EXISTS ( SELECT 1 FROM payment_htlc_attempts ha JOIN payment_htlc_attempt_resolutions hr ON hr.attempt_index = ha.attempt_index WHERE ha.payment_id = p.id AND hr.resolution_type = 1 ) ) OR EXISTS ( SELECT 1 FROM payment_htlc_attempts ha WHERE ha.payment_id = p.id AND NOT EXISTS ( SELECT 1 FROM payment_htlc_attempt_resolutions hr WHERE hr.attempt_index = ha.attempt_index ) ) ) ORDER BY p.id ASC LIMIT $2 ` type FetchNonTerminalPaymentsParams struct { ID int64 Limit int32 } type FetchNonTerminalPaymentsRow struct { ID int64 AmountMsat int64 CreatedAt time.Time PaymentIdentifier []byte FailReason sql.NullInt32 IntentType sql.NullInt16 IntentPayload []byte } // Fetch all non-terminal payments using pagination. A payment is // non-terminal if it has an unresolved attempt, or if it has not been // permanently failed and has no settled attempt yet. func (q *Queries) FetchNonTerminalPayments(ctx context.Context, arg FetchNonTerminalPaymentsParams) ([]FetchNonTerminalPaymentsRow, error) { rows, err := q.db.QueryContext(ctx, fetchNonTerminalPayments, arg.ID, arg.Limit) if err != nil { return nil, err } defer rows.Close() var items []FetchNonTerminalPaymentsRow for rows.Next() { var i FetchNonTerminalPaymentsRow if err := rows.Scan( &i.ID, &i.AmountMsat, &i.CreatedAt, &i.PaymentIdentifier, &i.FailReason, &i.IntentType, &i.IntentPayload, ); 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 fetchPayment = `-- name: FetchPayment :one SELECT p.id, p.amount_msat, p.created_at, p.payment_identifier, p.fail_reason, i.intent_type AS "intent_type", i.intent_payload AS "intent_payload" FROM payments p LEFT JOIN payment_intents i ON i.payment_id = p.id WHERE p.payment_identifier = $1 ` type FetchPaymentRow struct { Payment Payment IntentType sql.NullInt16 IntentPayload []byte } func (q *Queries) FetchPayment(ctx context.Context, paymentIdentifier []byte) (FetchPaymentRow, error) { row := q.db.QueryRowContext(ctx, fetchPayment, paymentIdentifier) var i FetchPaymentRow err := row.Scan( &i.Payment.ID, &i.Payment.AmountMsat, &i.Payment.CreatedAt, &i.Payment.PaymentIdentifier, &i.Payment.FailReason, &i.IntentType, &i.IntentPayload, ) return i, err } const fetchPaymentDuplicates = `-- name: FetchPaymentDuplicates :many SELECT id, payment_id, amount_msat, created_at, fail_reason, settle_preimage, settle_time FROM payment_duplicates WHERE payment_id = $1 ORDER BY id ASC ` // Fetch all duplicate payment records from the payment_duplicates table for // a given payment ID. func (q *Queries) FetchPaymentDuplicates(ctx context.Context, paymentID int64) ([]PaymentDuplicate, error) { rows, err := q.db.QueryContext(ctx, fetchPaymentDuplicates, paymentID) if err != nil { return nil, err } defer rows.Close() var items []PaymentDuplicate for rows.Next() { var i PaymentDuplicate if err := rows.Scan( &i.ID, &i.PaymentID, &i.AmountMsat, &i.CreatedAt, &i.FailReason, &i.SettlePreimage, &i.SettleTime, ); 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 fetchPaymentLevelFirstHopCustomRecords = `-- name: FetchPaymentLevelFirstHopCustomRecords :many SELECT l.id, l.payment_id, l.key, l.value FROM payment_first_hop_custom_records l WHERE l.payment_id IN (/*SLICE:payment_ids*/?) ORDER BY l.payment_id ASC, l.key ASC ` func (q *Queries) FetchPaymentLevelFirstHopCustomRecords(ctx context.Context, paymentIds []int64) ([]PaymentFirstHopCustomRecord, error) { query := fetchPaymentLevelFirstHopCustomRecords 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 []PaymentFirstHopCustomRecord for rows.Next() { var i PaymentFirstHopCustomRecord if err := rows.Scan( &i.ID, &i.PaymentID, &i.Key, &i.Value, ); 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 fetchPaymentsByIDs = `-- name: FetchPaymentsByIDs :many SELECT p.id, p.amount_msat, p.created_at, p.payment_identifier, p.fail_reason, pi.intent_type, pi.intent_payload FROM payments p LEFT JOIN payment_intents pi ON pi.payment_id = p.id WHERE p.id IN (/*SLICE:payment_ids*/?) ORDER BY p.id ASC ` type FetchPaymentsByIDsRow struct { ID int64 AmountMsat int64 CreatedAt time.Time PaymentIdentifier []byte FailReason sql.NullInt32 IntentType sql.NullInt16 IntentPayload []byte } // Batch fetch payment and intent data for a set of payment IDs. // Used to avoid fetching redundant payment data when processing multiple // attempts for the same payment. func (q *Queries) FetchPaymentsByIDs(ctx context.Context, paymentIds []int64) ([]FetchPaymentsByIDsRow, error) { query := fetchPaymentsByIDs 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 []FetchPaymentsByIDsRow for rows.Next() { var i FetchPaymentsByIDsRow if err := rows.Scan( &i.ID, &i.AmountMsat, &i.CreatedAt, &i.PaymentIdentifier, &i.FailReason, &i.IntentType, &i.IntentPayload, ); 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 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 SELECT l.id, l.htlc_attempt_index, l.key, l.value FROM payment_attempt_first_hop_custom_records l WHERE l.htlc_attempt_index IN (/*SLICE:htlc_attempt_indices*/?) ORDER BY l.htlc_attempt_index ASC, l.key ASC ` func (q *Queries) FetchRouteLevelFirstHopCustomRecords(ctx context.Context, htlcAttemptIndices []int64) ([]PaymentAttemptFirstHopCustomRecord, error) { query := fetchRouteLevelFirstHopCustomRecords var queryParams []interface{} if len(htlcAttemptIndices) > 0 { for _, v := range htlcAttemptIndices { queryParams = append(queryParams, v) } query = strings.Replace(query, "/*SLICE:htlc_attempt_indices*/?", makeQueryParams(len(queryParams), len(htlcAttemptIndices)), 1) } else { query = strings.Replace(query, "/*SLICE:htlc_attempt_indices*/?", "NULL", 1) } rows, err := q.db.QueryContext(ctx, query, queryParams...) if err != nil { return nil, err } defer rows.Close() var items []PaymentAttemptFirstHopCustomRecord for rows.Next() { var i PaymentAttemptFirstHopCustomRecord if err := rows.Scan( &i.ID, &i.HtlcAttemptIndex, &i.Key, &i.Value, ); 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 filterPayments = `-- name: FilterPayments :many /* ───────────────────────────────────────────── fetch queries ───────────────────────────────────────────── */ SELECT p.id, p.amount_msat, p.created_at, p.payment_identifier, p.fail_reason, i.intent_type AS "intent_type", i.intent_payload AS "intent_payload" FROM payments p LEFT JOIN payment_intents i ON i.payment_id = p.id WHERE p.id > COALESCE($1, -1) AND p.id < COALESCE($2, 9223372036854775807) -- NOTE: We use non-nullable time params with Go-side defaults instead of -- COALESCE, because COALESCE with text fallback causes type mismatch on -- Postgres (timestamp vs text), and OR-based optional filters can prevent -- the planner from using the created_at index. AND p.created_at >= $3 AND p.created_at <= $4 AND ( i.intent_type = $5 OR $5 IS NULL OR i.intent_type IS NULL ) ORDER BY p.id ASC LIMIT $6 ` type FilterPaymentsParams struct { IndexOffsetGet sql.NullInt64 IndexOffsetLet sql.NullInt64 CreatedAfter time.Time CreatedBefore time.Time IntentType sql.NullInt16 NumLimit int32 } type FilterPaymentsRow struct { Payment Payment IntentType sql.NullInt16 IntentPayload []byte } func (q *Queries) FilterPayments(ctx context.Context, arg FilterPaymentsParams) ([]FilterPaymentsRow, error) { rows, err := q.db.QueryContext(ctx, filterPayments, arg.IndexOffsetGet, arg.IndexOffsetLet, arg.CreatedAfter, arg.CreatedBefore, arg.IntentType, arg.NumLimit, ) if err != nil { return nil, err } defer rows.Close() var items []FilterPaymentsRow for rows.Next() { var i FilterPaymentsRow if err := rows.Scan( &i.Payment.ID, &i.Payment.AmountMsat, &i.Payment.CreatedAt, &i.Payment.PaymentIdentifier, &i.Payment.FailReason, &i.IntentType, &i.IntentPayload, ); 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 filterPaymentsDesc = `-- name: FilterPaymentsDesc :many SELECT p.id, p.amount_msat, p.created_at, p.payment_identifier, p.fail_reason, i.intent_type AS "intent_type", i.intent_payload AS "intent_payload" FROM payments p LEFT JOIN payment_intents i ON i.payment_id = p.id WHERE p.id > COALESCE($1, -1) AND p.id < COALESCE($2, 9223372036854775807) -- NOTE: We use non-nullable time params with Go-side defaults instead of -- COALESCE, because COALESCE with text fallback causes type mismatch on -- Postgres (timestamp vs text), and OR-based optional filters can prevent -- the planner from using the created_at index. AND p.created_at >= $3 AND p.created_at <= $4 AND ( i.intent_type = $5 OR $5 IS NULL OR i.intent_type IS NULL ) ORDER BY p.id DESC LIMIT $6 ` type FilterPaymentsDescParams struct { IndexOffsetGet sql.NullInt64 IndexOffsetLet sql.NullInt64 CreatedAfter time.Time CreatedBefore time.Time IntentType sql.NullInt16 NumLimit int32 } type FilterPaymentsDescRow struct { Payment Payment IntentType sql.NullInt16 IntentPayload []byte } func (q *Queries) FilterPaymentsDesc(ctx context.Context, arg FilterPaymentsDescParams) ([]FilterPaymentsDescRow, error) { rows, err := q.db.QueryContext(ctx, filterPaymentsDesc, arg.IndexOffsetGet, arg.IndexOffsetLet, arg.CreatedAfter, arg.CreatedBefore, arg.IntentType, arg.NumLimit, ) if err != nil { return nil, err } defer rows.Close() var items []FilterPaymentsDescRow for rows.Next() { var i FilterPaymentsDescRow if err := rows.Scan( &i.Payment.ID, &i.Payment.AmountMsat, &i.Payment.CreatedAt, &i.Payment.PaymentIdentifier, &i.Payment.FailReason, &i.IntentType, &i.IntentPayload, ); 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 insertHtlcAttempt = `-- name: InsertHtlcAttempt :one INSERT INTO payment_htlc_attempts ( payment_id, attempt_index, session_key, attempt_time, payment_hash, first_hop_amount_msat, route_total_time_lock, route_total_amount, route_source_key) VALUES ( $1, $2, $3, $4, $5, $6, $7, $8, $9) RETURNING id ` type InsertHtlcAttemptParams struct { PaymentID int64 AttemptIndex int64 SessionKey []byte AttemptTime time.Time PaymentHash []byte FirstHopAmountMsat int64 RouteTotalTimeLock int32 RouteTotalAmount int64 RouteSourceKey []byte } func (q *Queries) InsertHtlcAttempt(ctx context.Context, arg InsertHtlcAttemptParams) (int64, error) { row := q.db.QueryRowContext(ctx, insertHtlcAttempt, arg.PaymentID, arg.AttemptIndex, arg.SessionKey, arg.AttemptTime, arg.PaymentHash, arg.FirstHopAmountMsat, arg.RouteTotalTimeLock, arg.RouteTotalAmount, arg.RouteSourceKey, ) var id int64 err := row.Scan(&id) return id, err } const insertPayment = `-- name: InsertPayment :one INSERT INTO payments ( amount_msat, created_at, payment_identifier, fail_reason) VALUES ( $1, $2, $3, NULL ) RETURNING id ` type InsertPaymentParams struct { AmountMsat int64 CreatedAt time.Time PaymentIdentifier []byte } // Insert a new payment and return its ID. // When creating a payment we don't have a fail reason because we start the // payment process. func (q *Queries) InsertPayment(ctx context.Context, arg InsertPaymentParams) (int64, error) { row := q.db.QueryRowContext(ctx, insertPayment, arg.AmountMsat, arg.CreatedAt, arg.PaymentIdentifier) var id int64 err := row.Scan(&id) return id, err } const insertPaymentAttemptFirstHopCustomRecord = `-- name: InsertPaymentAttemptFirstHopCustomRecord :exec INSERT INTO payment_attempt_first_hop_custom_records ( htlc_attempt_index, key, value ) VALUES ( $1, $2, $3 ) ` type InsertPaymentAttemptFirstHopCustomRecordParams struct { HtlcAttemptIndex int64 Key int64 Value []byte } func (q *Queries) InsertPaymentAttemptFirstHopCustomRecord(ctx context.Context, arg InsertPaymentAttemptFirstHopCustomRecordParams) error { _, err := q.db.ExecContext(ctx, insertPaymentAttemptFirstHopCustomRecord, arg.HtlcAttemptIndex, arg.Key, arg.Value) return err } const insertPaymentDuplicateMig = `-- name: InsertPaymentDuplicateMig :one INSERT INTO payment_duplicates ( payment_id, amount_msat, created_at, fail_reason, settle_preimage, settle_time ) VALUES ( $1, $2, $3, $4, $5, $6 ) RETURNING id ` type InsertPaymentDuplicateMigParams struct { PaymentID int64 AmountMsat int64 CreatedAt time.Time FailReason sql.NullInt32 SettlePreimage []byte SettleTime sql.NullTime } // Insert a duplicate payment record into the payment_duplicates table and // return its ID. func (q *Queries) InsertPaymentDuplicateMig(ctx context.Context, arg InsertPaymentDuplicateMigParams) (int64, error) { row := q.db.QueryRowContext(ctx, insertPaymentDuplicateMig, arg.PaymentID, arg.AmountMsat, arg.CreatedAt, arg.FailReason, arg.SettlePreimage, arg.SettleTime, ) var id int64 err := row.Scan(&id) return id, err } const insertPaymentFirstHopCustomRecord = `-- name: InsertPaymentFirstHopCustomRecord :exec INSERT INTO payment_first_hop_custom_records ( payment_id, key, value ) VALUES ( $1, $2, $3 ) ` type InsertPaymentFirstHopCustomRecordParams struct { PaymentID int64 Key int64 Value []byte } func (q *Queries) InsertPaymentFirstHopCustomRecord(ctx context.Context, arg InsertPaymentFirstHopCustomRecordParams) error { _, err := q.db.ExecContext(ctx, insertPaymentFirstHopCustomRecord, arg.PaymentID, arg.Key, arg.Value) return err } const insertPaymentHopCustomRecord = `-- name: InsertPaymentHopCustomRecord :exec INSERT INTO payment_hop_custom_records ( hop_id, key, value ) VALUES ( $1, $2, $3 ) ` type InsertPaymentHopCustomRecordParams struct { HopID int64 Key int64 Value []byte } func (q *Queries) InsertPaymentHopCustomRecord(ctx context.Context, arg InsertPaymentHopCustomRecordParams) error { _, err := q.db.ExecContext(ctx, insertPaymentHopCustomRecord, arg.HopID, arg.Key, arg.Value) return err } const insertPaymentIntent = `-- name: InsertPaymentIntent :one INSERT INTO payment_intents ( payment_id, intent_type, intent_payload) VALUES ( $1, $2, $3 ) RETURNING id ` type InsertPaymentIntentParams struct { PaymentID int64 IntentType int16 IntentPayload []byte } // Insert a payment intent for a given payment and return its ID. func (q *Queries) InsertPaymentIntent(ctx context.Context, arg InsertPaymentIntentParams) (int64, error) { row := q.db.QueryRowContext(ctx, insertPaymentIntent, arg.PaymentID, arg.IntentType, arg.IntentPayload) var id int64 err := row.Scan(&id) 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 INSERT INTO payment_route_hops ( htlc_attempt_index, hop_index, pub_key, scid, outgoing_time_lock, amt_to_forward, meta_data ) VALUES ( $1, $2, $3, $4, $5, $6, $7 ) RETURNING id ` type InsertRouteHopParams struct { HtlcAttemptIndex int64 HopIndex int32 PubKey []byte Scid string OutgoingTimeLock int32 AmtToForward int64 MetaData []byte } func (q *Queries) InsertRouteHop(ctx context.Context, arg InsertRouteHopParams) (int64, error) { row := q.db.QueryRowContext(ctx, insertRouteHop, arg.HtlcAttemptIndex, arg.HopIndex, arg.PubKey, arg.Scid, arg.OutgoingTimeLock, arg.AmtToForward, arg.MetaData, ) var id int64 err := row.Scan(&id) return id, err } const insertRouteHopAmp = `-- name: InsertRouteHopAmp :exec INSERT INTO payment_route_hop_amp ( hop_id, root_share, set_id, child_index ) VALUES ( $1, $2, $3, $4 ) ` type InsertRouteHopAmpParams struct { HopID int64 RootShare []byte SetID []byte ChildIndex int32 } func (q *Queries) InsertRouteHopAmp(ctx context.Context, arg InsertRouteHopAmpParams) error { _, err := q.db.ExecContext(ctx, insertRouteHopAmp, arg.HopID, arg.RootShare, arg.SetID, arg.ChildIndex, ) return err } const insertRouteHopBlinded = `-- name: InsertRouteHopBlinded :exec INSERT INTO payment_route_hop_blinded ( hop_id, encrypted_data, blinding_point, blinded_path_total_amt ) VALUES ( $1, $2, $3, $4 ) ` type InsertRouteHopBlindedParams struct { HopID int64 EncryptedData []byte BlindingPoint []byte BlindedPathTotalAmt sql.NullInt64 } func (q *Queries) InsertRouteHopBlinded(ctx context.Context, arg InsertRouteHopBlindedParams) error { _, err := q.db.ExecContext(ctx, insertRouteHopBlinded, arg.HopID, arg.EncryptedData, arg.BlindingPoint, arg.BlindedPathTotalAmt, ) return err } const insertRouteHopMpp = `-- name: InsertRouteHopMpp :exec INSERT INTO payment_route_hop_mpp ( hop_id, payment_addr, total_msat ) VALUES ( $1, $2, $3 ) ` type InsertRouteHopMppParams struct { HopID int64 PaymentAddr []byte TotalMsat int64 } func (q *Queries) InsertRouteHopMpp(ctx context.Context, arg InsertRouteHopMppParams) error { _, err := q.db.ExecContext(ctx, insertRouteHopMpp, arg.HopID, arg.PaymentAddr, arg.TotalMsat) return err } const settleAttempt = `-- name: SettleAttempt :exec INSERT INTO payment_htlc_attempt_resolutions ( attempt_index, resolution_time, resolution_type, settle_preimage ) VALUES ( $1, $2, $3, $4 ) ` type SettleAttemptParams struct { AttemptIndex int64 ResolutionTime time.Time ResolutionType int32 SettlePreimage []byte } func (q *Queries) SettleAttempt(ctx context.Context, arg SettleAttemptParams) error { _, err := q.db.ExecContext(ctx, settleAttempt, arg.AttemptIndex, arg.ResolutionTime, arg.ResolutionType, arg.SettlePreimage, ) return err }