mirror of
https://github.com/ElementsProject/lightning.git
synced 2025-02-20 13:54:36 +01:00
db: Remove sqlite3 from db.c and db.h
Now that all the users are migrated to the abstraction layer we can remove the legacy implementation. Signed-off-by: Christian Decker <decker.christian@gmail.com>
This commit is contained in:
parent
a29bedb5b8
commit
c6b6958ae6
2 changed files with 52 additions and 579 deletions
429
wallet/db.c
429
wallet/db.c
|
@ -1,7 +1,6 @@
|
|||
#include "db.h"
|
||||
|
||||
#include <ccan/array_size/array_size.h>
|
||||
#include <ccan/json_escape/json_escape.h>
|
||||
#include <ccan/tal/str/str.h>
|
||||
#include <common/node_id.h>
|
||||
#include <common/version.h>
|
||||
|
@ -470,29 +469,6 @@ static void db_assert_no_outstanding_statements(struct db *db)
|
|||
}
|
||||
#endif
|
||||
|
||||
void db_stmt_done(sqlite3_stmt *stmt)
|
||||
{
|
||||
sqlite3_finalize(stmt);
|
||||
}
|
||||
|
||||
sqlite3_stmt *db_select_prepare_(const char *location, struct db *db, const char *query)
|
||||
{
|
||||
int err;
|
||||
sqlite3_stmt *stmt;
|
||||
|
||||
/* Since these queries will be treated as read-only they need to start
|
||||
* with "SELECT" and have no side-effects. */
|
||||
assert(strncmp(query, "SELECT", 6) == 0);
|
||||
assert(db->in_transaction);
|
||||
|
||||
err = sqlite3_prepare_v2(db->sql, query, -1, &stmt, NULL);
|
||||
|
||||
if (err != SQLITE_OK)
|
||||
db_fatal("%s: %s: %s", location, query, sqlite3_errmsg(db->sql));
|
||||
|
||||
return stmt;
|
||||
}
|
||||
|
||||
static void db_stmt_free(struct db_stmt *stmt)
|
||||
{
|
||||
if (stmt->inner_stmt)
|
||||
|
@ -601,53 +577,6 @@ u64 db_last_insert_id_v2(struct db_stmt *stmt TAKES)
|
|||
return id;
|
||||
}
|
||||
|
||||
bool db_select_step_(const char *location, struct db *db, struct sqlite3_stmt *stmt)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = sqlite3_step(stmt);
|
||||
if (ret == SQLITE_ROW)
|
||||
return true;
|
||||
if (ret != SQLITE_DONE)
|
||||
db_fatal("%s: %s", location, sqlite3_errmsg(db->sql));
|
||||
db_stmt_done(stmt);
|
||||
return false;
|
||||
}
|
||||
sqlite3_stmt *db_prepare_(const char *location, struct db *db, const char *query)
|
||||
{
|
||||
int err;
|
||||
sqlite3_stmt *stmt;
|
||||
|
||||
assert(db->in_transaction);
|
||||
|
||||
err = sqlite3_prepare_v2(db->sql, query, -1, &stmt, NULL);
|
||||
|
||||
if (err != SQLITE_OK)
|
||||
db_fatal("%s: %s: %s", location, query, sqlite3_errmsg(db->sql));
|
||||
|
||||
return stmt;
|
||||
}
|
||||
|
||||
void db_exec_prepared_(const char *caller, struct db *db, sqlite3_stmt *stmt)
|
||||
{
|
||||
assert(db->in_transaction);
|
||||
|
||||
if (sqlite3_step(stmt) != SQLITE_DONE)
|
||||
db_fatal("%s: %s", caller, sqlite3_errmsg(db->sql));
|
||||
|
||||
db_stmt_done(stmt);
|
||||
}
|
||||
|
||||
sqlite3_stmt *db_select_(const char *location, struct db *db, const char *query)
|
||||
{
|
||||
sqlite3_stmt *stmt;
|
||||
|
||||
assert(db->in_transaction);
|
||||
|
||||
stmt = db_select_prepare(db, query);
|
||||
return stmt;
|
||||
}
|
||||
|
||||
static void destroy_db(struct db *db)
|
||||
{
|
||||
db_assert_no_outstanding_statements(db);
|
||||
|
@ -679,16 +608,6 @@ bool db_in_transaction(struct db *db)
|
|||
return db->in_transaction;
|
||||
}
|
||||
|
||||
u64 db_last_insert_id(struct db *db)
|
||||
{
|
||||
return sqlite3_last_insert_rowid(db->sql);
|
||||
}
|
||||
|
||||
size_t db_changes(struct db *db)
|
||||
{
|
||||
return sqlite3_changes(db->sql);
|
||||
}
|
||||
|
||||
void db_begin_transaction_(struct db *db, const char *location)
|
||||
{
|
||||
bool ok;
|
||||
|
@ -728,12 +647,6 @@ static void setup_open_db(struct db *db)
|
|||
db_report_changes(db, NULL, 0);
|
||||
}
|
||||
|
||||
void db_close(struct db *db)
|
||||
{
|
||||
if (db->config->teardown_fn)
|
||||
db->config->teardown_fn(db);
|
||||
}
|
||||
|
||||
/**
|
||||
* db_open - Open or create a sqlite3 database
|
||||
*/
|
||||
|
@ -906,332 +819,6 @@ void db_set_intvar(struct db *db, char *varname, s64 val)
|
|||
tal_free(v);
|
||||
}
|
||||
|
||||
void *sqlite3_column_arr_(const tal_t *ctx, sqlite3_stmt *stmt, int col,
|
||||
size_t bytes, const char *label, const char *caller)
|
||||
{
|
||||
size_t sourcelen = sqlite3_column_bytes(stmt, col);
|
||||
void *p;
|
||||
|
||||
if (sqlite3_column_type(stmt, col) == SQLITE_NULL)
|
||||
return NULL;
|
||||
|
||||
if (sourcelen % bytes != 0)
|
||||
db_fatal("%s: column size %zu not a multiple of %s (%zu)",
|
||||
caller, sourcelen, label, bytes);
|
||||
|
||||
p = tal_arr_label(ctx, char, sourcelen, label);
|
||||
memcpy(p, sqlite3_column_blob(stmt, col), sourcelen);
|
||||
return p;
|
||||
}
|
||||
|
||||
bool sqlite3_bind_short_channel_id(sqlite3_stmt *stmt, int col,
|
||||
const struct short_channel_id *id)
|
||||
{
|
||||
char *ser = short_channel_id_to_str(id, id);
|
||||
int err = sqlite3_bind_blob(stmt, col, ser, strlen(ser), SQLITE_TRANSIENT);
|
||||
tal_free(ser);
|
||||
return err == SQLITE_OK;
|
||||
}
|
||||
|
||||
bool sqlite3_column_short_channel_id(sqlite3_stmt *stmt, int col,
|
||||
struct short_channel_id *dest)
|
||||
{
|
||||
const char *source = sqlite3_column_blob(stmt, col);
|
||||
size_t sourcelen = sqlite3_column_bytes(stmt, col);
|
||||
return short_channel_id_from_str(source, sourcelen, dest, true);
|
||||
}
|
||||
bool sqlite3_bind_short_channel_id_array(sqlite3_stmt *stmt, int col,
|
||||
const struct short_channel_id *id)
|
||||
{
|
||||
u8 *ser;
|
||||
size_t num;
|
||||
size_t i;
|
||||
|
||||
/* Handle nulls early. */
|
||||
if (!id) {
|
||||
int err = sqlite3_bind_null(stmt, col);
|
||||
return err == SQLITE_OK;
|
||||
}
|
||||
|
||||
ser = tal_arr(NULL, u8, 0);
|
||||
num = tal_count(id);
|
||||
|
||||
for (i = 0; i < num; ++i)
|
||||
towire_short_channel_id(&ser, &id[i]);
|
||||
|
||||
int err = sqlite3_bind_blob(stmt, col, ser, tal_count(ser), SQLITE_TRANSIENT);
|
||||
|
||||
tal_free(ser);
|
||||
return err == SQLITE_OK;
|
||||
}
|
||||
struct short_channel_id *
|
||||
sqlite3_column_short_channel_id_array(const tal_t *ctx,
|
||||
sqlite3_stmt *stmt, int col)
|
||||
{
|
||||
const u8 *ser;
|
||||
size_t len;
|
||||
struct short_channel_id *ret;
|
||||
|
||||
/* Handle nulls early. */
|
||||
if (sqlite3_column_type(stmt, col) == SQLITE_NULL)
|
||||
return NULL;
|
||||
|
||||
ser = sqlite3_column_blob(stmt, col);
|
||||
len = sqlite3_column_bytes(stmt, col);
|
||||
ret = tal_arr(ctx, struct short_channel_id, 0);
|
||||
|
||||
while (len != 0) {
|
||||
struct short_channel_id scid;
|
||||
fromwire_short_channel_id(&ser, &len, &scid);
|
||||
tal_arr_expand(&ret, scid);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool sqlite3_bind_tx(sqlite3_stmt *stmt, int col, const struct bitcoin_tx *tx)
|
||||
{
|
||||
u8 *ser = linearize_tx(NULL, tx);
|
||||
int err = sqlite3_bind_blob(stmt, col, ser, tal_count(ser), SQLITE_TRANSIENT);
|
||||
tal_free(ser);
|
||||
return err == SQLITE_OK;
|
||||
}
|
||||
|
||||
struct bitcoin_tx *sqlite3_column_tx(const tal_t *ctx, sqlite3_stmt *stmt,
|
||||
int col)
|
||||
{
|
||||
const u8 *src = sqlite3_column_blob(stmt, col);
|
||||
size_t len = sqlite3_column_bytes(stmt, col);
|
||||
return pull_bitcoin_tx(ctx, &src, &len);
|
||||
}
|
||||
bool sqlite3_bind_signature(sqlite3_stmt *stmt, int col,
|
||||
const secp256k1_ecdsa_signature *sig)
|
||||
{
|
||||
bool ok;
|
||||
u8 buf[64];
|
||||
ok = secp256k1_ecdsa_signature_serialize_compact(secp256k1_ctx, buf,
|
||||
sig) == 1;
|
||||
int err = sqlite3_bind_blob(stmt, col, buf, sizeof(buf), SQLITE_TRANSIENT);
|
||||
return ok && err == SQLITE_OK;
|
||||
}
|
||||
|
||||
bool sqlite3_column_signature(sqlite3_stmt *stmt, int col,
|
||||
secp256k1_ecdsa_signature *sig)
|
||||
{
|
||||
assert(sqlite3_column_bytes(stmt, col) == 64);
|
||||
return secp256k1_ecdsa_signature_parse_compact(
|
||||
secp256k1_ctx, sig, sqlite3_column_blob(stmt, col)) == 1;
|
||||
}
|
||||
|
||||
bool sqlite3_column_pubkey(sqlite3_stmt *stmt, int col, struct pubkey *dest)
|
||||
{
|
||||
assert(sqlite3_column_bytes(stmt, col) == PUBKEY_CMPR_LEN);
|
||||
return pubkey_from_der(sqlite3_column_blob(stmt, col), PUBKEY_CMPR_LEN, dest);
|
||||
}
|
||||
|
||||
bool sqlite3_bind_pubkey(sqlite3_stmt *stmt, int col, const struct pubkey *pk)
|
||||
{
|
||||
u8 der[PUBKEY_CMPR_LEN];
|
||||
pubkey_to_der(der, pk);
|
||||
int err = sqlite3_bind_blob(stmt, col, der, sizeof(der), SQLITE_TRANSIENT);
|
||||
return err == SQLITE_OK;
|
||||
}
|
||||
|
||||
bool sqlite3_column_node_id(sqlite3_stmt *stmt, int col, struct node_id *dest)
|
||||
{
|
||||
assert(sqlite3_column_bytes(stmt, col) == sizeof(dest->k));
|
||||
memcpy(dest->k, sqlite3_column_blob(stmt, col), sizeof(dest->k));
|
||||
return node_id_valid(dest);
|
||||
}
|
||||
|
||||
bool sqlite3_bind_node_id(sqlite3_stmt *stmt, int col, const struct node_id *id)
|
||||
{
|
||||
assert(node_id_valid(id));
|
||||
int err = sqlite3_bind_blob(stmt, col, id->k, sizeof(id->k), SQLITE_TRANSIENT);
|
||||
return err == SQLITE_OK;
|
||||
}
|
||||
|
||||
bool sqlite3_bind_pubkey_array(sqlite3_stmt *stmt, int col,
|
||||
const struct pubkey *pks)
|
||||
{
|
||||
size_t n;
|
||||
size_t i;
|
||||
u8 *ders;
|
||||
|
||||
if (!pks) {
|
||||
int err = sqlite3_bind_null(stmt, col);
|
||||
return err == SQLITE_OK;
|
||||
}
|
||||
|
||||
n = tal_count(pks);
|
||||
ders = tal_arr(NULL, u8, n * PUBKEY_CMPR_LEN);
|
||||
|
||||
for (i = 0; i < n; ++i)
|
||||
pubkey_to_der(&ders[i * PUBKEY_CMPR_LEN], &pks[i]);
|
||||
int err = sqlite3_bind_blob(stmt, col, ders, tal_count(ders), SQLITE_TRANSIENT);
|
||||
|
||||
tal_free(ders);
|
||||
return err == SQLITE_OK;
|
||||
}
|
||||
struct pubkey *sqlite3_column_pubkey_array(const tal_t *ctx,
|
||||
sqlite3_stmt *stmt, int col)
|
||||
{
|
||||
size_t i;
|
||||
size_t n;
|
||||
struct pubkey *ret;
|
||||
const u8 *ders;
|
||||
|
||||
if (sqlite3_column_type(stmt, col) == SQLITE_NULL)
|
||||
return NULL;
|
||||
|
||||
n = sqlite3_column_bytes(stmt, col) / PUBKEY_CMPR_LEN;
|
||||
assert(n * PUBKEY_CMPR_LEN == (size_t)sqlite3_column_bytes(stmt, col));
|
||||
ret = tal_arr(ctx, struct pubkey, n);
|
||||
ders = sqlite3_column_blob(stmt, col);
|
||||
|
||||
for (i = 0; i < n; ++i) {
|
||||
if (!pubkey_from_der(&ders[i * PUBKEY_CMPR_LEN], PUBKEY_CMPR_LEN, &ret[i]))
|
||||
return tal_free(ret);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool sqlite3_bind_node_id_array(sqlite3_stmt *stmt, int col,
|
||||
const struct node_id *ids)
|
||||
{
|
||||
size_t n;
|
||||
u8 *arr;
|
||||
|
||||
if (!ids) {
|
||||
int err = sqlite3_bind_null(stmt, col);
|
||||
return err == SQLITE_OK;
|
||||
}
|
||||
|
||||
/* Copy into contiguous array: ARM will add padding to struct node_id! */
|
||||
n = tal_count(ids);
|
||||
arr = tal_arr(NULL, u8, n * sizeof(ids[0].k));
|
||||
for (size_t i = 0; i < n; ++i) {
|
||||
assert(node_id_valid(&ids[i]));
|
||||
memcpy(arr + sizeof(ids[i].k) * i,
|
||||
ids[i].k,
|
||||
sizeof(ids[i].k));
|
||||
}
|
||||
int err = sqlite3_bind_blob(stmt, col, arr, tal_count(arr), SQLITE_TRANSIENT);
|
||||
|
||||
tal_free(arr);
|
||||
return err == SQLITE_OK;
|
||||
}
|
||||
|
||||
struct node_id *sqlite3_column_node_id_array(const tal_t *ctx,
|
||||
sqlite3_stmt *stmt, int col)
|
||||
{
|
||||
size_t n;
|
||||
struct node_id *ret;
|
||||
const u8 *arr;
|
||||
|
||||
if (sqlite3_column_type(stmt, col) == SQLITE_NULL)
|
||||
return NULL;
|
||||
|
||||
n = sqlite3_column_bytes(stmt, col) / sizeof(ret->k);
|
||||
assert(n * sizeof(ret->k) == (size_t)sqlite3_column_bytes(stmt, col));
|
||||
ret = tal_arr(ctx, struct node_id, n);
|
||||
arr = sqlite3_column_blob(stmt, col);
|
||||
|
||||
for (size_t i = 0; i < n; i++) {
|
||||
memcpy(ret[i].k, arr + i * sizeof(ret[i].k), sizeof(ret[i].k));
|
||||
if (!node_id_valid(&ret[i]))
|
||||
return tal_free(ret);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool sqlite3_column_preimage(sqlite3_stmt *stmt, int col, struct preimage *dest)
|
||||
{
|
||||
assert(sqlite3_column_bytes(stmt, col) == sizeof(struct preimage));
|
||||
return memcpy(dest, sqlite3_column_blob(stmt, col), sizeof(struct preimage));
|
||||
}
|
||||
|
||||
bool sqlite3_bind_preimage(sqlite3_stmt *stmt, int col, const struct preimage *p)
|
||||
{
|
||||
int err = sqlite3_bind_blob(stmt, col, p, sizeof(struct preimage), SQLITE_TRANSIENT);
|
||||
return err == SQLITE_OK;
|
||||
}
|
||||
|
||||
bool sqlite3_column_sha256(sqlite3_stmt *stmt, int col, struct sha256 *dest)
|
||||
{
|
||||
assert(sqlite3_column_bytes(stmt, col) == sizeof(struct sha256));
|
||||
return memcpy(dest, sqlite3_column_blob(stmt, col), sizeof(struct sha256));
|
||||
}
|
||||
|
||||
bool sqlite3_bind_sha256(sqlite3_stmt *stmt, int col, const struct sha256 *p)
|
||||
{
|
||||
int err = sqlite3_bind_blob(stmt, col, p, sizeof(struct sha256), SQLITE_TRANSIENT);
|
||||
return err == SQLITE_OK;
|
||||
}
|
||||
|
||||
bool sqlite3_column_sha256_double(sqlite3_stmt *stmt, int col, struct sha256_double *dest)
|
||||
{
|
||||
assert(sqlite3_column_bytes(stmt, col) == sizeof(struct sha256_double));
|
||||
return memcpy(dest, sqlite3_column_blob(stmt, col), sizeof(struct sha256_double));
|
||||
}
|
||||
|
||||
struct secret *sqlite3_column_secrets(const tal_t *ctx,
|
||||
sqlite3_stmt *stmt, int col)
|
||||
{
|
||||
return sqlite3_column_arr(ctx, stmt, col, struct secret);
|
||||
}
|
||||
|
||||
bool sqlite3_bind_sha256_double(sqlite3_stmt *stmt, int col, const struct sha256_double *p)
|
||||
{
|
||||
int err = sqlite3_bind_blob(stmt, col, p, sizeof(struct sha256_double), SQLITE_TRANSIENT);
|
||||
return err == SQLITE_OK;
|
||||
}
|
||||
|
||||
struct json_escape *sqlite3_column_json_escape(const tal_t *ctx,
|
||||
sqlite3_stmt *stmt, int col)
|
||||
{
|
||||
return json_escape_string_(ctx,
|
||||
sqlite3_column_blob(stmt, col),
|
||||
sqlite3_column_bytes(stmt, col));
|
||||
}
|
||||
|
||||
bool sqlite3_bind_json_escape(sqlite3_stmt *stmt, int col,
|
||||
const struct json_escape *esc)
|
||||
{
|
||||
int err = sqlite3_bind_text(stmt, col, esc->s, strlen(esc->s), SQLITE_TRANSIENT);
|
||||
return err == SQLITE_OK;
|
||||
}
|
||||
|
||||
struct amount_msat sqlite3_column_amount_msat(sqlite3_stmt *stmt, int col)
|
||||
{
|
||||
struct amount_msat msat;
|
||||
|
||||
msat.millisatoshis = sqlite3_column_int64(stmt, col); /* Raw: low level function */
|
||||
return msat;
|
||||
}
|
||||
|
||||
struct amount_sat sqlite3_column_amount_sat(sqlite3_stmt *stmt, int col)
|
||||
{
|
||||
struct amount_sat sat;
|
||||
|
||||
sat.satoshis = sqlite3_column_int64(stmt, col); /* Raw: low level function */
|
||||
return sat;
|
||||
}
|
||||
|
||||
void sqlite3_bind_amount_msat(sqlite3_stmt *stmt, int col,
|
||||
struct amount_msat msat)
|
||||
{
|
||||
sqlite3_bind_int64(stmt, col, msat.millisatoshis); /* Raw: low level function */
|
||||
}
|
||||
|
||||
void sqlite3_bind_amount_sat(sqlite3_stmt *stmt, int col,
|
||||
struct amount_sat sat)
|
||||
{
|
||||
sqlite3_bind_int64(stmt, col, sat.satoshis); /* Raw: low level function */
|
||||
}
|
||||
|
||||
/* Will apply the current config fee settings to all channels */
|
||||
void migrate_pr2342_feerate_per_channel(struct lightningd *ld, struct db *db)
|
||||
{
|
||||
|
@ -1245,22 +832,6 @@ void migrate_pr2342_feerate_per_channel(struct lightningd *ld, struct db *db)
|
|||
tal_free(stmt);
|
||||
}
|
||||
|
||||
void sqlite3_bind_timeabs(sqlite3_stmt *stmt, int col, struct timeabs t)
|
||||
{
|
||||
u64 timestamp = t.ts.tv_nsec + (((u64) t.ts.tv_sec) * ((u64) NSEC_IN_SEC));
|
||||
sqlite3_bind_int64(stmt, col, timestamp);
|
||||
}
|
||||
|
||||
struct timeabs sqlite3_column_timeabs(sqlite3_stmt *stmt, int col)
|
||||
{
|
||||
struct timeabs t;
|
||||
u64 timestamp = sqlite3_column_int64(stmt, col);
|
||||
t.ts.tv_sec = timestamp / NSEC_IN_SEC;
|
||||
t.ts.tv_nsec = timestamp % NSEC_IN_SEC;
|
||||
return t;
|
||||
|
||||
}
|
||||
|
||||
void db_bind_null(struct db_stmt *stmt, int pos)
|
||||
{
|
||||
assert(pos < tal_count(stmt->bindings));
|
||||
|
|
202
wallet/db.h
202
wallet/db.h
|
@ -7,12 +7,12 @@
|
|||
#include <bitcoin/short_channel_id.h>
|
||||
#include <bitcoin/tx.h>
|
||||
#include <ccan/autodata/autodata.h>
|
||||
#include <ccan/json_escape/json_escape.h>
|
||||
#include <ccan/short_types/short_types.h>
|
||||
#include <ccan/tal/tal.h>
|
||||
#include <ccan/time/time.h>
|
||||
#include <common/amount.h>
|
||||
#include <secp256k1_ecdh.h>
|
||||
#include <sqlite3.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
struct lightningd;
|
||||
|
@ -57,15 +57,6 @@ struct db;
|
|||
*/
|
||||
struct db *db_setup(const tal_t *ctx, struct lightningd *ld, struct log *log);
|
||||
|
||||
/**
|
||||
* db_select - Prepare and execute a SELECT, and return the result
|
||||
*
|
||||
* A simpler version of db_select_prepare.
|
||||
*/
|
||||
sqlite3_stmt *db_select_(const char *location, struct db *db, const char *query);
|
||||
#define db_select(db, query) \
|
||||
db_select_(__FILE__ ":" stringify(__LINE__), db, query)
|
||||
|
||||
/**
|
||||
* db_begin_transaction - Begin a transaction
|
||||
*
|
||||
|
@ -77,14 +68,6 @@ void db_begin_transaction_(struct db *db, const char *location);
|
|||
|
||||
bool db_in_transaction(struct db *db);
|
||||
|
||||
// FIXME(cdecker) Need to maybe add a pointer to the db_stmt we are referring to
|
||||
// FIXME(cdecker) Comment
|
||||
u64 db_last_insert_id(struct db *db);
|
||||
|
||||
// FIXME(cdecker) Need to maybe add a pointer to the db_stmt we are referring to
|
||||
// FIXME(cdecker) Comment
|
||||
size_t db_changes(struct db *db);
|
||||
|
||||
/**
|
||||
* db_commit_transaction - Commit a running transaction
|
||||
*
|
||||
|
@ -109,136 +92,6 @@ void db_set_intvar(struct db *db, char *varname, s64 val);
|
|||
*/
|
||||
s64 db_get_intvar(struct db *db, char *varname, s64 defval);
|
||||
|
||||
/**
|
||||
* db_select_prepare -- Prepare a DB select statement (read-only!)
|
||||
*
|
||||
* Tiny wrapper around `sqlite3_prepare_v2` that checks and sets
|
||||
* errors like `db_query` and `db_exec` do. It calls fatal if
|
||||
* the stmt is not valid.
|
||||
*
|
||||
* Call db_select_step() until it returns false (which will also consume
|
||||
* the stmt).
|
||||
*
|
||||
* @db: Database to query/exec
|
||||
* @query: The SELECT SQL statement to compile
|
||||
*/
|
||||
#define db_select_prepare(db, query) \
|
||||
db_select_prepare_(__FILE__ ":" stringify(__LINE__), db, query)
|
||||
sqlite3_stmt *db_select_prepare_(const char *location,
|
||||
struct db *db, const char *query);
|
||||
|
||||
/**
|
||||
* db_select_step -- iterate through db results.
|
||||
*
|
||||
* Returns false and frees stmt if we've reached end, otherwise
|
||||
* it means sqlite3_step has returned SQLITE_ROW.
|
||||
*/
|
||||
#define db_select_step(db, stmt) \
|
||||
db_select_step_(__FILE__ ":" stringify(__LINE__), db, stmt)
|
||||
bool db_select_step_(const char *location,
|
||||
struct db *db, struct sqlite3_stmt *stmt);
|
||||
|
||||
/**
|
||||
* db_prepare -- Prepare a DB query/command
|
||||
*
|
||||
* Tiny wrapper around `sqlite3_prepare_v2` that checks and sets
|
||||
* errors like `db_query` and `db_exec` do. It returns a statement
|
||||
* `stmt` if the given query/command was successfully compiled into a
|
||||
* statement, `NULL` otherwise. On failure `db->err` will be set with
|
||||
* the human readable error.
|
||||
*
|
||||
* @db: Database to query/exec
|
||||
* @query: The SQL statement to compile
|
||||
*/
|
||||
#define db_prepare(db,query) \
|
||||
db_prepare_(__FILE__ ":" stringify(__LINE__), db, query)
|
||||
sqlite3_stmt *db_prepare_(const char *location, struct db *db, const char *query);
|
||||
|
||||
/**
|
||||
* db_exec_prepared -- Execute a prepared statement
|
||||
*
|
||||
* After preparing a statement using `db_prepare`, and after binding
|
||||
* all non-null variables using the `sqlite3_bind_*` functions, it can
|
||||
* be executed with this function. It is a small, transaction-aware,
|
||||
* wrapper around `sqlite3_step`, that calls fatal() if the execution
|
||||
* fails. This will take ownership of `stmt` and will free
|
||||
* it before returning.
|
||||
*
|
||||
* @db: The database to execute on
|
||||
* @stmt: The prepared statement to execute
|
||||
*/
|
||||
#define db_exec_prepared(db,stmt) db_exec_prepared_(__func__,db,stmt)
|
||||
void db_exec_prepared_(const char *caller, struct db *db, sqlite3_stmt *stmt);
|
||||
|
||||
/* Wrapper around sqlite3_finalize(), for tracking statements. */
|
||||
void db_stmt_done(sqlite3_stmt *stmt);
|
||||
|
||||
#define sqlite3_column_arr(ctx, stmt, col, type) \
|
||||
((type *)sqlite3_column_arr_((ctx), (stmt), (col), \
|
||||
sizeof(type), TAL_LABEL(type, "[]"), \
|
||||
__func__))
|
||||
void *sqlite3_column_arr_(const tal_t *ctx, sqlite3_stmt *stmt, int col,
|
||||
size_t bytes, const char *label, const char *caller);
|
||||
|
||||
bool sqlite3_bind_short_channel_id(sqlite3_stmt *stmt, int col,
|
||||
const struct short_channel_id *id);
|
||||
WARN_UNUSED_RESULT bool sqlite3_column_short_channel_id(sqlite3_stmt *stmt, int col,
|
||||
struct short_channel_id *dest);
|
||||
bool sqlite3_bind_short_channel_id_array(sqlite3_stmt *stmt, int col,
|
||||
const struct short_channel_id *id);
|
||||
struct short_channel_id *
|
||||
sqlite3_column_short_channel_id_array(const tal_t *ctx,
|
||||
sqlite3_stmt *stmt, int col);
|
||||
bool sqlite3_bind_tx(sqlite3_stmt *stmt, int col, const struct bitcoin_tx *tx);
|
||||
struct bitcoin_tx *sqlite3_column_tx(const tal_t *ctx, sqlite3_stmt *stmt,
|
||||
int col);
|
||||
bool sqlite3_bind_signature(sqlite3_stmt *stmt, int col, const secp256k1_ecdsa_signature *sig);
|
||||
bool sqlite3_column_signature(sqlite3_stmt *stmt, int col, secp256k1_ecdsa_signature *sig);
|
||||
|
||||
bool sqlite3_column_pubkey(sqlite3_stmt *stmt, int col, struct pubkey *dest);
|
||||
bool sqlite3_bind_pubkey(sqlite3_stmt *stmt, int col, const struct pubkey *pk);
|
||||
|
||||
bool sqlite3_column_node_id(sqlite3_stmt *stmt, int col, struct node_id *dest);
|
||||
bool sqlite3_bind_node_id(sqlite3_stmt *stmt, int col, const struct node_id *id);
|
||||
|
||||
bool sqlite3_bind_pubkey_array(sqlite3_stmt *stmt, int col,
|
||||
const struct pubkey *pks);
|
||||
struct pubkey *sqlite3_column_pubkey_array(const tal_t *ctx,
|
||||
sqlite3_stmt *stmt, int col);
|
||||
|
||||
bool sqlite3_bind_node_id_array(sqlite3_stmt *stmt, int col,
|
||||
const struct node_id *ids);
|
||||
struct node_id *sqlite3_column_node_id_array(const tal_t *ctx,
|
||||
sqlite3_stmt *stmt, int col);
|
||||
|
||||
bool sqlite3_column_preimage(sqlite3_stmt *stmt, int col, struct preimage *dest);
|
||||
bool sqlite3_bind_preimage(sqlite3_stmt *stmt, int col, const struct preimage *p);
|
||||
|
||||
bool sqlite3_column_sha256(sqlite3_stmt *stmt, int col, struct sha256 *dest);
|
||||
bool sqlite3_bind_sha256(sqlite3_stmt *stmt, int col, const struct sha256 *p);
|
||||
|
||||
bool sqlite3_column_sha256_double(sqlite3_stmt *stmt, int col, struct sha256_double *dest);
|
||||
bool sqlite3_bind_sha256_double(sqlite3_stmt *stmt, int col, const struct sha256_double *p);
|
||||
struct secret *sqlite3_column_secrets(const tal_t *ctx,
|
||||
sqlite3_stmt *stmt, int col);
|
||||
|
||||
struct json_escape *sqlite3_column_json_escape(const tal_t *ctx,
|
||||
sqlite3_stmt *stmt, int col);
|
||||
bool sqlite3_bind_json_escape(sqlite3_stmt *stmt, int col,
|
||||
const struct json_escape *esc);
|
||||
|
||||
struct amount_msat sqlite3_column_amount_msat(sqlite3_stmt *stmt, int col);
|
||||
struct amount_sat sqlite3_column_amount_sat(sqlite3_stmt *stmt, int col);
|
||||
void sqlite3_bind_amount_msat(sqlite3_stmt *stmt, int col,
|
||||
struct amount_msat msat);
|
||||
void sqlite3_bind_amount_sat(sqlite3_stmt *stmt, int col,
|
||||
struct amount_sat sat);
|
||||
|
||||
/* Helpers to read and write absolute times from and to the database. */
|
||||
void sqlite3_bind_timeabs(sqlite3_stmt *stmt, int col, struct timeabs t);
|
||||
struct timeabs sqlite3_column_timeabs(sqlite3_stmt *stmt, int col);
|
||||
|
||||
|
||||
void db_bind_null(struct db_stmt *stmt, int pos);
|
||||
void db_bind_int(struct db_stmt *stmt, int pos, int val);
|
||||
void db_bind_u64(struct db_stmt *stmt, int pos, u64 val);
|
||||
|
@ -306,14 +159,63 @@ struct bitcoin_tx *db_column_tx(const tal_t *ctx, struct db_stmt *stmt, int col)
|
|||
void *db_column_arr_(const tal_t *ctx, struct db_stmt *stmt, int col,
|
||||
size_t bytes, const char *label, const char *caller);
|
||||
|
||||
void db_close(struct db *db);
|
||||
/**
|
||||
* db_exec_prepared -- Execute a prepared statement
|
||||
*
|
||||
* After preparing a statement using `db_prepare`, and after binding all
|
||||
* non-null variables using the `db_bind_*` functions, it can be executed with
|
||||
* this function. It is a small, transaction-aware, wrapper around `db_step`,
|
||||
* that calls fatal() if the execution fails. This may take ownership of
|
||||
* `stmt` if annotated with `take()`and will free it before returning.
|
||||
*
|
||||
* If you'd like to issue a query and access the rows returned by the query
|
||||
* please use `db_query_prepared` instead, since this function will not expose
|
||||
* returned results, and the `stmt` can only be used for calls to
|
||||
* `db_count_changes` and `db_last_insert_id` after executing.
|
||||
*
|
||||
* @stmt: The prepared statement to execute
|
||||
*/
|
||||
bool db_exec_prepared_v2(struct db_stmt *stmt TAKES);
|
||||
|
||||
/**
|
||||
* db_query_prepared -- Execute a prepared query
|
||||
*
|
||||
* After preparing a query using `db_prepare`, and after binding all non-null
|
||||
* variables using the `db_bind_*` functions, it can be executed with this
|
||||
* function. This function must be called before calling `db_step` or any of
|
||||
* the `db_column_*` column access functions.
|
||||
*
|
||||
* If you are not executing a read-only statement, please use
|
||||
* `db_exec_prepared` instead.
|
||||
*
|
||||
* @stmt: The prepared statement to execute
|
||||
*/
|
||||
bool db_query_prepared(struct db_stmt *stmt);
|
||||
size_t db_count_changes(struct db_stmt *stmt);
|
||||
u64 db_last_insert_id_v2(struct db_stmt *stmt);
|
||||
|
||||
/**
|
||||
* db_prepare -- Prepare a DB query/command
|
||||
*
|
||||
* Create an instance of `struct db_stmt` that encapsulates a SQL query or command.
|
||||
*
|
||||
* @query MUST be wrapped in a `SQL()` macro call, since that allows the
|
||||
* extraction and translation of the query into the target SQL dialect.
|
||||
*
|
||||
* It does not execute the query and does not check its validity, but
|
||||
* allocates the placeholders detected in the query. The placeholders in the
|
||||
* `stmt` can then be bound using the `db_bind_*` functions, and executed
|
||||
* using `db_exec_prepared` for write-only statements and `db_query_prepared`
|
||||
* for read-only statements.
|
||||
*
|
||||
* @db: Database to query/exec
|
||||
* @query: The SQL statement to compile
|
||||
*/
|
||||
struct db_stmt *db_prepare_v2_(const char *location, struct db *db,
|
||||
const char *query_id);
|
||||
#define db_prepare_v2(db,query) \
|
||||
|
||||
/* TODO(cdecker) Remove the v2 suffix after finishing the migration */
|
||||
#define db_prepare_v2(db,query) \
|
||||
db_prepare_v2_(__FILE__ ":" stringify(__LINE__), db, query)
|
||||
|
||||
#endif /* LIGHTNING_WALLET_DB_H */
|
||||
|
|
Loading…
Add table
Reference in a new issue