wallet: use standard-style iterators for invoices.

Same as we use for offers, etc.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
Rusty Russell
2023-07-14 09:58:43 +09:30
parent c814cd0142
commit d17506b899
5 changed files with 45 additions and 83 deletions

View File

@@ -1223,7 +1223,6 @@ static void json_add_invoices(struct json_stream *response,
const struct sha256 *payment_hash,
const struct sha256 *local_offer_id)
{
struct invoice_iterator it;
const struct invoice_details *details;
u64 inv_dbid;
@@ -1242,10 +1241,13 @@ static void json_add_invoices(struct json_stream *response,
json_add_invoice(response, NULL, details);
}
} else {
memset(&it, 0, sizeof(it));
while (invoices_iterate(wallet->invoices, &it)) {
details = invoices_iterator_deref(response,
wallet->invoices, &it);
struct db_stmt *stmt;
for (stmt = invoices_first(wallet->invoices, &inv_dbid);
stmt;
stmt = invoices_next(wallet->invoices, stmt, &inv_dbid)) {
details = invoices_get_details(tmpctx,
wallet->invoices, inv_dbid);
/* FIXME: db can filter this better! */
if (local_offer_id) {
if (!details->local_offer_id

View File

@@ -393,20 +393,20 @@ bool invoices_find_unpaid(struct invoices *invoices UNNEEDED,
u64 *inv_dbid UNNEEDED,
const struct sha256 *rhash UNNEEDED)
{ fprintf(stderr, "invoices_find_unpaid called!\n"); abort(); }
/* Generated stub for invoices_first */
struct db_stmt *invoices_first(struct invoices *invoices UNNEEDED,
u64 *inv_dbid UNNEEDED)
{ fprintf(stderr, "invoices_first called!\n"); abort(); }
/* Generated stub for invoices_get_details */
struct invoice_details *invoices_get_details(const tal_t *ctx UNNEEDED,
struct invoices *invoices UNNEEDED,
u64 inv_dbid UNNEEDED)
{ fprintf(stderr, "invoices_get_details called!\n"); abort(); }
/* Generated stub for invoices_iterate */
bool invoices_iterate(struct invoices *invoices UNNEEDED,
struct invoice_iterator *it UNNEEDED)
{ fprintf(stderr, "invoices_iterate called!\n"); abort(); }
/* Generated stub for invoices_iterator_deref */
const struct invoice_details *invoices_iterator_deref(
const tal_t *ctx UNNEEDED, struct invoices *invoices UNNEEDED,
const struct invoice_iterator *it UNNEEDED)
{ fprintf(stderr, "invoices_iterator_deref called!\n"); abort(); }
/* Generated stub for invoices_next */
struct db_stmt *invoices_next(struct invoices *invoices UNNEEDED,
struct db_stmt *stmt UNNEEDED,
u64 *inv_dbid UNNEEDED)
{ fprintf(stderr, "invoices_next called!\n"); abort(); }
/* Generated stub for invoices_resolve */
bool invoices_resolve(struct invoices *invoices UNNEEDED,
u64 inv_dbid UNNEEDED,

View File

@@ -442,50 +442,26 @@ void invoices_delete_expired(struct invoices *invoices,
db_exec_prepared_v2(take(stmt));
}
bool invoices_iterate(struct invoices *invoices,
struct invoice_iterator *it)
struct db_stmt *invoices_first(struct invoices *invoices,
u64 *inv_dbid)
{
struct db_stmt *stmt;
if (!it->p) {
stmt = db_prepare_v2(invoices->wallet->db, SQL("SELECT"
" state"
", payment_key"
", payment_hash"
", label"
", msatoshi"
", expiry_time"
", pay_index"
", msatoshi_received"
", paid_timestamp"
", bolt11"
", description"
", features"
", local_offer_id"
" FROM invoices"
" ORDER BY id;"));
db_query_prepared(stmt);
it->p = stmt;
} else
stmt = it->p;
stmt = db_prepare_v2(invoices->wallet->db, SQL("SELECT id FROM invoices ORDER by id;"));
db_query_prepared(stmt);
if (db_step(stmt))
/* stmt doesn't need to be freed since we expect to be called
* again, and stmt will be freed on the last iteration. */
return true;
tal_free(stmt);
it->p = NULL;
return false;
return invoices_next(invoices, stmt, inv_dbid);
}
const struct invoice_details *
invoices_iterator_deref(const tal_t *ctx, struct invoices *invoices UNUSED,
const struct invoice_iterator *it)
struct db_stmt *invoices_next(struct invoices *invoices,
struct db_stmt *stmt,
u64 *inv_dbid)
{
assert(it->p);
return wallet_stmt2invoice_details(ctx, (struct db_stmt*) it->p);
if (!db_step(stmt))
return tal_free(stmt);
*inv_dbid = db_col_u64(stmt, "id");
return stmt;
}
static s64 get_next_pay_index(struct db *db)

View File

@@ -9,7 +9,6 @@ struct db;
struct json_escape;
struct invoice;
struct invoice_details;
struct invoice_iterator;
struct invoices;
struct sha256;
struct timers;
@@ -130,36 +129,28 @@ void invoices_delete_expired(struct invoices *invoices,
u64 max_expiry_time);
/**
* invoices_iterate - Iterate over all existing invoices
* Iterate through all the invoices.
* @invoices: the invoices
* @inv_dbid: the first invoice dbid (if returns non-NULL)
*
* @invoices - the invoice handler.
* @iterator - the iterator object to use.
*
* Return false at end-of-sequence, true if still iterating.
* Usage:
*
* struct invoice_iterator it;
* memset(&it, 0, sizeof(it))
* while (invoices_iterate(wallet, &it)) {
* ...
* }
* Returns pointer to hand as @stmt to invoices_next(), or NULL.
* If you choose not to call invoices_next() you must free it!
*/
bool invoices_iterate(struct invoices *invoices,
struct invoice_iterator *it);
struct db_stmt *invoices_first(struct invoices *invoices,
u64 *inv_dbid);
/**
* wallet_invoice_iterator_deref - Read the details of the
* invoice currently pointed to by the given iterator.
*
* @ctx - the owner of the label and msatoshi fields returned.
* @wallet - the wallet whose invoices are to be iterated over.
* @iterator - the iterator object to use.
* @return The invoice details allocated off of `ctx`
* Iterate through all the offers.
* @invoices: the invoices
* @stmt: return from invoices_first() or previous invoices_next()
* @inv_dbid: the first invoice dbid (if returns non-NULL)
*
* Returns NULL once we're out of invoices. If you choose not to call
* invoices_next() again you must free return.
*/
const struct invoice_details *invoices_iterator_deref(
const tal_t *ctx, struct invoices *invoices,
const struct invoice_iterator *it);
struct db_stmt *invoices_next(struct invoices *invoices,
struct db_stmt *stmt,
u64 *inv_dbid);
/**
* invoices_resolve - Mark an invoice as paid

View File

@@ -63,13 +63,6 @@ static inline enum output_status output_status_in_db(enum output_status s)
fatal("%s: %u is invalid", __func__, s);
}
/* An object that handles iteration over the set of invoices */
struct invoice_iterator {
/* The contents of this object is subject to change
* and should not be depended upon */
void *p;
};
/* Enumeration of all known output types. These include all types that
* could ever end up on-chain and we may need to react upon. Notice
* that `to_local`, `htlc_offer`, and `htlc_recv` may need immediate