mirror of
https://github.com/lightninglabs/lightning-terminal.git
synced 2026-08-13 12:33:36 +02:00
accounts+sqlc: improve ListAccounts for SQL store
Optimize SQL account listing by preloading linked invoices and payments for all accounts in bulk. Before this change, Accounts() queried ListAllAccounts and then did two extra queries per account (ListAccountInvoices/ListAccountPayments), which scales poorly as account count grows. Add ListAllAccountInvoices and ListAllAccountPayments queries, group their rows by account_id in memory, and marshal each account from the preloaded data. Keep conversion logic shared through marshalDBAccountWithLinkedData to preserve behavior between single-account and list-account paths. This reduces query count from 1 + 2N to 3 and improves list-path performance without changing external semantics.
This commit is contained in:
parent
067eeafd7e
commit
fb5b0af8d8
4 changed files with 118 additions and 10 deletions
|
|
@ -44,6 +44,8 @@ type SQLQueries interface {
|
|||
GetAccountIndex(ctx context.Context, name string) (int64, error)
|
||||
GetAccountPayment(ctx context.Context, arg sqlc.GetAccountPaymentParams) (sqlc.AccountPayment, error)
|
||||
InsertAccount(ctx context.Context, arg sqlc.InsertAccountParams) (int64, error)
|
||||
ListAllAccountInvoices(ctx context.Context) ([]sqlc.AccountInvoice, error)
|
||||
ListAllAccountPayments(ctx context.Context) ([]sqlc.AccountPayment, error)
|
||||
ListAccountInvoices(ctx context.Context, id int64) ([]sqlc.AccountInvoice, error)
|
||||
ListAccountPayments(ctx context.Context, id int64) ([]sqlc.AccountPayment, error)
|
||||
ListAllAccounts(ctx context.Context) ([]sqlc.Account, error)
|
||||
|
|
@ -200,6 +202,23 @@ func getAndMarshalAccount(ctx context.Context, db SQLQueries, id int64) (
|
|||
func marshalDBAccount(ctx context.Context, db SQLQueries,
|
||||
dbAcct sqlc.Account) (*OffChainBalanceAccount, error) {
|
||||
|
||||
invoices, err := db.ListAccountInvoices(ctx, dbAcct.ID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
payments, err := db.ListAccountPayments(ctx, dbAcct.ID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return marshalDBAccountWithLinkedData(dbAcct, invoices, payments)
|
||||
}
|
||||
|
||||
func marshalDBAccountWithLinkedData(dbAcct sqlc.Account,
|
||||
invoices []sqlc.AccountInvoice,
|
||||
payments []sqlc.AccountPayment) (*OffChainBalanceAccount, error) {
|
||||
|
||||
alias, err := AccountIDFromInt64(dbAcct.Alias)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
|
@ -217,21 +236,12 @@ func marshalDBAccount(ctx context.Context, db SQLQueries,
|
|||
Label: dbAcct.Label.String,
|
||||
}
|
||||
|
||||
invoices, err := db.ListAccountInvoices(ctx, dbAcct.ID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for _, invoice := range invoices {
|
||||
var hash lntypes.Hash
|
||||
copy(hash[:], invoice.Hash)
|
||||
account.Invoices[hash] = struct{}{}
|
||||
}
|
||||
|
||||
payments, err := db.ListAccountPayments(ctx, dbAcct.ID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for _, payment := range payments {
|
||||
var hash lntypes.Hash
|
||||
copy(hash[:], payment.Hash)
|
||||
|
|
@ -560,9 +570,36 @@ func (s *SQLStore) Accounts(ctx context.Context) ([]*OffChainBalanceAccount,
|
|||
return err
|
||||
}
|
||||
|
||||
dbInvoices, err := db.ListAllAccountInvoices(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
dbPayments, err := db.ListAllAccountPayments(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
accountInvoices := make(map[int64][]sqlc.AccountInvoice)
|
||||
for _, invoice := range dbInvoices {
|
||||
accountInvoices[invoice.AccountID] = append(
|
||||
accountInvoices[invoice.AccountID], invoice,
|
||||
)
|
||||
}
|
||||
|
||||
accountPayments := make(map[int64][]sqlc.AccountPayment)
|
||||
for _, payment := range dbPayments {
|
||||
accountPayments[payment.AccountID] = append(
|
||||
accountPayments[payment.AccountID], payment,
|
||||
)
|
||||
}
|
||||
|
||||
accounts = make([]*OffChainBalanceAccount, len(dbAccounts))
|
||||
for i, dbAccount := range dbAccounts {
|
||||
account, err := marshalDBAccount(ctx, db, dbAccount)
|
||||
account, err := marshalDBAccountWithLinkedData(
|
||||
dbAccount, accountInvoices[dbAccount.ID],
|
||||
accountPayments[dbAccount.ID],
|
||||
)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
|
|||
|
|
@ -258,6 +258,67 @@ func (q *Queries) ListAccountPayments(ctx context.Context, accountID int64) ([]A
|
|||
return items, nil
|
||||
}
|
||||
|
||||
const listAllAccountInvoices = `-- name: ListAllAccountInvoices :many
|
||||
SELECT account_id, hash
|
||||
FROM account_invoices
|
||||
`
|
||||
|
||||
func (q *Queries) ListAllAccountInvoices(ctx context.Context) ([]AccountInvoice, error) {
|
||||
rows, err := q.db.QueryContext(ctx, listAllAccountInvoices)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
var items []AccountInvoice
|
||||
for rows.Next() {
|
||||
var i AccountInvoice
|
||||
if err := rows.Scan(&i.AccountID, &i.Hash); 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 listAllAccountPayments = `-- name: ListAllAccountPayments :many
|
||||
SELECT account_id, hash, status, full_amount_msat
|
||||
FROM account_payments
|
||||
`
|
||||
|
||||
func (q *Queries) ListAllAccountPayments(ctx context.Context) ([]AccountPayment, error) {
|
||||
rows, err := q.db.QueryContext(ctx, listAllAccountPayments)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
var items []AccountPayment
|
||||
for rows.Next() {
|
||||
var i AccountPayment
|
||||
if err := rows.Scan(
|
||||
&i.AccountID,
|
||||
&i.Hash,
|
||||
&i.Status,
|
||||
&i.FullAmountMsat,
|
||||
); 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 listAllAccounts = `-- name: ListAllAccounts :many
|
||||
SELECT id, alias, label, type, initial_balance_msat, current_balance_msat, last_updated, expiration
|
||||
FROM accounts
|
||||
|
|
|
|||
|
|
@ -58,6 +58,8 @@ type Querier interface {
|
|||
InsertSessionPrivacyFlag(ctx context.Context, arg InsertSessionPrivacyFlagParams) error
|
||||
ListAccountInvoices(ctx context.Context, accountID int64) ([]AccountInvoice, error)
|
||||
ListAccountPayments(ctx context.Context, accountID int64) ([]AccountPayment, error)
|
||||
ListAllAccountInvoices(ctx context.Context) ([]AccountInvoice, error)
|
||||
ListAllAccountPayments(ctx context.Context) ([]AccountPayment, error)
|
||||
ListAllAccounts(ctx context.Context) ([]Account, error)
|
||||
ListAllKVStoresRecords(ctx context.Context) ([]Kvstore, error)
|
||||
ListSessions(ctx context.Context) ([]Session, error)
|
||||
|
|
|
|||
|
|
@ -76,11 +76,19 @@ SELECT *
|
|||
FROM account_payments
|
||||
WHERE account_id = $1;
|
||||
|
||||
-- name: ListAllAccountPayments :many
|
||||
SELECT *
|
||||
FROM account_payments;
|
||||
|
||||
-- name: ListAccountInvoices :many
|
||||
SELECT *
|
||||
FROM account_invoices
|
||||
WHERE account_id = $1;
|
||||
|
||||
-- name: ListAllAccountInvoices :many
|
||||
SELECT *
|
||||
FROM account_invoices;
|
||||
|
||||
-- name: GetAccountInvoice :one
|
||||
SELECT *
|
||||
FROM account_invoices
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue