Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Db code cleanups #6128

Merged
merged 4 commits into from
Apr 6, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 7 additions & 9 deletions db/exec.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ int db_get_version(struct db *db)
* table that doesn't exist yet, so we need to terminate and restart
* the DB transaction.
*/
if (!db_query_prepared(stmt)) {
if (!db_query_prepared_canfail(stmt)) {
db_commit_transaction(stmt->db);
db_begin_transaction(stmt->db);
tal_free(stmt);
Expand All @@ -45,7 +45,7 @@ u32 db_data_version_get(struct db *db)
u32 version;
stmt = db_prepare_v2(db, SQL("SELECT intval FROM vars WHERE name = 'data_version'"));
/* postgres will act upset if the table doesn't exist yet. */
if (!db_query_prepared(stmt)) {
if (!db_query_prepared_canfail(stmt)) {
tal_free(stmt);
return 0;
}
Expand All @@ -58,34 +58,32 @@ u32 db_data_version_get(struct db *db)
return version;
}

void db_set_intvar(struct db *db, char *varname, s64 val)
void db_set_intvar(struct db *db, const char *varname, s64 val)
{
size_t changes;
struct db_stmt *stmt = db_prepare_v2(db, SQL("UPDATE vars SET intval=? WHERE name=?;"));
db_bind_int(stmt, 0, val);
db_bind_text(stmt, 1, varname);
if (!db_exec_prepared_v2(stmt))
db_fatal("Error executing update: %s", stmt->error);
db_exec_prepared_v2(stmt);
changes = db_count_changes(stmt);
tal_free(stmt);

if (changes == 0) {
stmt = db_prepare_v2(db, SQL("INSERT INTO vars (name, intval) VALUES (?, ?);"));
db_bind_text(stmt, 0, varname);
db_bind_int(stmt, 1, val);
if (!db_exec_prepared_v2(stmt))
db_fatal("Error executing insert: %s", stmt->error);
db_exec_prepared_v2(stmt);
tal_free(stmt);
}
}

s64 db_get_intvar(struct db *db, char *varname, s64 defval)
s64 db_get_intvar(struct db *db, const char *varname, s64 defval)
{
s64 res = defval;
struct db_stmt *stmt = db_prepare_v2(
db, SQL("SELECT intval FROM vars WHERE name= ? LIMIT 1"));
db_bind_text(stmt, 0, varname);
if (db_query_prepared(stmt) && db_step(stmt))
if (db_query_prepared_canfail(stmt) && db_step(stmt))
res = db_col_int(stmt, "intval");

tal_free(stmt);
Expand Down
4 changes: 2 additions & 2 deletions db/exec.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,15 @@ struct db;
* Utility function to store generic integer values in the
* database.
*/
void db_set_intvar(struct db *db, char *varname, s64 val);
void db_set_intvar(struct db *db, const char *varname, s64 val);

/**
* db_get_intvar - Retrieve an integer variable from the database
*
* Either returns the value in the database, or @defval if
* the query failed or no such variable exists.
*/
s64 db_get_intvar(struct db *db, char *varname, s64 defval);
s64 db_get_intvar(struct db *db, const char *varname, s64 defval);

/* Get the current data version (entries). */
u32 db_data_version_get(struct db *db);
Expand Down
13 changes: 9 additions & 4 deletions db/utils.c
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ struct db_stmt *db_prepare_untranslated(struct db *db, const char *query)
return stmt;
}

bool db_query_prepared(struct db_stmt *stmt)
bool db_query_prepared_canfail(struct db_stmt *stmt)
{
/* Make sure we don't accidentally execute a modifying query using a
* read-only path. */
Expand All @@ -147,6 +147,13 @@ bool db_query_prepared(struct db_stmt *stmt)
return ret;
}

void db_query_prepared(struct db_stmt *stmt)
{
if (!db_query_prepared_canfail(stmt))
db_fatal("query failed: %s: %s",
stmt->location, stmt->query->query);
}

bool db_step(struct db_stmt *stmt)
{
bool ret;
Expand All @@ -164,7 +171,7 @@ bool db_step(struct db_stmt *stmt)
return ret;
}

bool db_exec_prepared_v2(struct db_stmt *stmt TAKES)
void db_exec_prepared_v2(struct db_stmt *stmt TAKES)
{
bool ret = stmt->db->config->exec_fn(stmt);

Expand All @@ -184,8 +191,6 @@ bool db_exec_prepared_v2(struct db_stmt *stmt TAKES)

if (taken(stmt))
tal_free(stmt);

return ret;
}

size_t db_count_changes(struct db_stmt *stmt)
Expand Down
9 changes: 7 additions & 2 deletions db/utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ bool db_step(struct db_stmt *stmt);
*
* @stmt: The prepared statement to execute
*/
bool db_exec_prepared_v2(struct db_stmt *stmt TAKES);
void db_exec_prepared_v2(struct db_stmt *stmt TAKES);

/**
* db_query_prepared -- Execute a prepared query
Expand All @@ -49,7 +49,12 @@ bool db_exec_prepared_v2(struct db_stmt *stmt TAKES);
*
* @stmt: The prepared statement to execute
*/
bool db_query_prepared(struct db_stmt *stmt);
void db_query_prepared(struct db_stmt *stmt);

/**
* Variation which allows failure.
*/
bool db_query_prepared_canfail(struct db_stmt *stmt);

size_t db_count_changes(struct db_stmt *stmt);
void db_report_changes(struct db *db, const char *final, size_t min);
Expand Down
8 changes: 0 additions & 8 deletions gossipd/test/run-check_channel_announcement.c
Original file line number Diff line number Diff line change
Expand Up @@ -86,14 +86,6 @@ const u8 *gossip_store_get_private_update(const tal_t *ctx UNNEEDED,
void gossip_store_mark_channel_deleted(struct gossip_store *gs UNNEEDED,
const struct short_channel_id *scid UNNEEDED)
{ fprintf(stderr, "gossip_store_mark_channel_deleted called!\n"); abort(); }
/* Generated stub for gossip_store_mark_channel_zombie */
void gossip_store_mark_channel_zombie(struct gossip_store *gs UNNEEDED,
struct broadcastable *bcast UNNEEDED)
{ fprintf(stderr, "gossip_store_mark_channel_zombie called!\n"); abort(); }
/* Generated stub for gossip_store_mark_cupdate_zombie */
void gossip_store_mark_cupdate_zombie(struct gossip_store *gs UNNEEDED,
struct broadcastable *bcast UNNEEDED)
{ fprintf(stderr, "gossip_store_mark_cupdate_zombie called!\n"); abort(); }
/* Generated stub for gossip_store_new */
struct gossip_store *gossip_store_new(struct routing_state *rstate UNNEEDED,
struct list_head *peers UNNEEDED)
Expand Down
8 changes: 0 additions & 8 deletions gossipd/test/run-txout_failure.c
Original file line number Diff line number Diff line change
Expand Up @@ -57,14 +57,6 @@ const u8 *gossip_store_get_private_update(const tal_t *ctx UNNEEDED,
void gossip_store_mark_channel_deleted(struct gossip_store *gs UNNEEDED,
const struct short_channel_id *scid UNNEEDED)
{ fprintf(stderr, "gossip_store_mark_channel_deleted called!\n"); abort(); }
/* Generated stub for gossip_store_mark_channel_zombie */
void gossip_store_mark_channel_zombie(struct gossip_store *gs UNNEEDED,
struct broadcastable *bcast UNNEEDED)
{ fprintf(stderr, "gossip_store_mark_channel_zombie called!\n"); abort(); }
/* Generated stub for gossip_store_mark_cupdate_zombie */
void gossip_store_mark_cupdate_zombie(struct gossip_store *gs UNNEEDED,
struct broadcastable *bcast UNNEEDED)
{ fprintf(stderr, "gossip_store_mark_cupdate_zombie called!\n"); abort(); }
/* Generated stub for memleak_add_helper_ */
void memleak_add_helper_(const tal_t *p UNNEEDED, void (*cb)(struct htable *memtable UNNEEDED,
const tal_t *)){ }
Expand Down
2 changes: 1 addition & 1 deletion lightningd/test/run-find_my_abspath.c
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ void db_begin_transaction_(struct db *db UNNEEDED, const char *location UNNEEDED
void db_commit_transaction(struct db *db UNNEEDED)
{ fprintf(stderr, "db_commit_transaction called!\n"); abort(); }
/* Generated stub for db_get_intvar */
s64 db_get_intvar(struct db *db UNNEEDED, char *varname UNNEEDED, s64 defval UNNEEDED)
s64 db_get_intvar(struct db *db UNNEEDED, const char *varname UNNEEDED, s64 defval UNNEEDED)
{ fprintf(stderr, "db_get_intvar called!\n"); abort(); }
/* Generated stub for db_in_transaction */
bool db_in_transaction(struct db *db UNNEEDED)
Expand Down
3 changes: 1 addition & 2 deletions lightningd/test/run-invoice-select-inchan.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,7 @@ struct channel *any_channel_by_scid(struct lightningd *ld UNNEEDED,
bool privacy_leak_ok UNNEEDED)
{ fprintf(stderr, "any_channel_by_scid called!\n"); abort(); }
/* Generated stub for bip32_pubkey */
void bip32_pubkey(struct lightningd *ld UNNEEDED,
struct pubkey *pubkey UNNEEDED, u32 index UNNEEDED)
void bip32_pubkey(struct lightningd *ld UNNEEDED, struct pubkey *pubkey UNNEEDED, u32 index UNNEEDED)
{ fprintf(stderr, "bip32_pubkey called!\n"); abort(); }
/* Generated stub for bitcoind_getutxout_ */
void bitcoind_getutxout_(struct bitcoind *bitcoind UNNEEDED,
Expand Down
2 changes: 1 addition & 1 deletion plugins/bkpr/recorder.c
Original file line number Diff line number Diff line change
Expand Up @@ -342,7 +342,7 @@ struct fee_sum **find_account_onchain_fees(const tal_t *ctx,
", CAST(SUM(debit) AS BIGINT) as debit"
" FROM onchain_fees"
" WHERE account_id = ?"
" GROUP BY txid"
" GROUP BY txid, update_count"
" ORDER BY txid, update_count"));

db_bind_u64(stmt, 0, acct->db_id);
Expand Down
28 changes: 11 additions & 17 deletions wallet/test/run-db.c
Original file line number Diff line number Diff line change
Expand Up @@ -127,16 +127,10 @@ static bool test_primitives(void)

db_begin_transaction(db);
stmt = db_prepare_v2(db, SQL("SELECT name FROM sqlite_master WHERE type='table';"));
CHECK_MSG(db_exec_prepared_v2(stmt), "db_exec_prepared must succeed");
db_exec_prepared_v2(stmt);
CHECK_MSG(!db_err, "Simple correct SQL command");
tal_free(stmt);

stmt = db_prepare_v2(db, SQL("not a valid SQL statement"));
CHECK_MSG(!db_exec_prepared_v2(stmt), "db_exec_prepared must fail");
CHECK_MSG(db_err, "Failing SQL command");
tal_free(stmt);
db_err = tal_free(db_err);

/* We didn't migrate the DB, so don't have the vars table. Pretend we
* didn't change anything so we don't bump the data_version. */
db->dirty = false;
Expand Down Expand Up @@ -184,35 +178,35 @@ static bool test_manip_columns(void)
" id BIGSERIAL"
", field1 INTEGER"
", PRIMARY KEY (id))"));
CHECK_MSG(db_exec_prepared_v2(stmt), "db_exec_prepared must succeed");
db_exec_prepared_v2(stmt);
CHECK_MSG(!db_err, "Simple correct SQL command");
tal_free(stmt);

stmt = db_prepare_v2(db, SQL("INSERT INTO tablea (id, field1) VALUES (0, 1);"));
CHECK_MSG(db_exec_prepared_v2(stmt), "db_exec_prepared must succeed");
db_exec_prepared_v2(stmt);
CHECK_MSG(!db_err, "Simple correct SQL command");
tal_free(stmt);

stmt = db_prepare_v2(db, SQL("CREATE TABLE tableb ("
" id REFERENCES tablea(id) ON DELETE CASCADE"
", field1 INTEGER"
", field2 INTEGER);"));
CHECK_MSG(db_exec_prepared_v2(stmt), "db_exec_prepared must succeed");
db_exec_prepared_v2(stmt);
CHECK_MSG(!db_err, "Simple correct SQL command");
tal_free(stmt);

stmt = db_prepare_v2(db, SQL("INSERT INTO tableb (id, field1, field2) VALUES (0, 1, 2);"));
CHECK_MSG(db_exec_prepared_v2(stmt), "db_exec_prepared must succeed");
db_exec_prepared_v2(stmt);
CHECK_MSG(!db_err, "Simple correct SQL command");
tal_free(stmt);

/* Needs vars table, since this changes db. */
stmt = db_prepare_v2(db, SQL("CREATE TABLE vars (name VARCHAR(32), intval);"));
CHECK_MSG(db_exec_prepared_v2(stmt), "db_exec_prepared must succeed");
db_exec_prepared_v2(stmt);
CHECK_MSG(!db_err, "Simple correct SQL command");
tal_free(stmt);
stmt = db_prepare_v2(db, SQL("INSERT INTO vars VALUES ('data_version', 0);"));
CHECK_MSG(db_exec_prepared_v2(stmt), "db_exec_prepared must succeed");
db_exec_prepared_v2(stmt);
CHECK_MSG(!db_err, "Simple correct SQL command");
tal_free(stmt);

Expand All @@ -222,7 +216,7 @@ static bool test_manip_columns(void)
CHECK(db->config->delete_columns(db, "tableb", &field1, 1));

stmt = db_prepare_v2(db, SQL("SELECT id, field1a FROM tablea;"));
CHECK_MSG(db_query_prepared(stmt), "db_query_prepared must succeed");
CHECK_MSG(db_query_prepared_canfail(stmt), "db_query_prepared must succeed");
CHECK_MSG(!db_err, "Simple correct SQL command");
CHECK(db_step(stmt));
CHECK(db_col_u64(stmt, "id") == 0);
Expand All @@ -231,7 +225,7 @@ static bool test_manip_columns(void)
tal_free(stmt);

stmt = db_prepare_v2(db, SQL("SELECT id, field2 FROM tableb;"));
CHECK_MSG(db_query_prepared(stmt), "db_query_prepared must succeed");
CHECK_MSG(db_query_prepared_canfail(stmt), "db_query_prepared must succeed");
CHECK_MSG(!db_err, "Simple correct SQL command");
CHECK(db_step(stmt));
CHECK(db_col_u64(stmt, "id") == 0);
Expand All @@ -245,15 +239,15 @@ static bool test_manip_columns(void)
db_begin_transaction(db);
/* This will actually fail */
stmt = db_prepare_v2(db, SQL("SELECT field1 FROM tablea;"));
CHECK_MSG(!db_query_prepared(stmt), "db_query_prepared must fail");
CHECK_MSG(!db_query_prepared_canfail(stmt), "db_query_prepared must fail");
db->dirty = false;
db->changes = tal_arr(db, const char *, 0);
db_commit_transaction(db);

db_begin_transaction(db);
/* This will actually fail */
stmt = db_prepare_v2(db, SQL("SELECT field1 FROM tableb;"));
CHECK_MSG(!db_query_prepared(stmt), "db_query_prepared must fail");
CHECK_MSG(!db_query_prepared_canfail(stmt), "db_query_prepared must fail");
db->dirty = false;
db->changes = tal_arr(db, const char *, 0);
db_commit_transaction(db);
Expand Down