mirror of
https://github.com/ElementsProject/lightning.git
synced 2024-11-19 09:54:16 +01:00
db: Track the data_version in the database
This increments the `data_version` upon committing dirty transactions, reads the last data_version upon startup, and tracks the number in memory in parallel to the DB (see next commit for rationale). Changelog-Changed: JSON-RPC: Added a `data_version` field to the `db_write` hook which returns a numeric transaction counter.
This commit is contained in:
parent
4a4184be70
commit
2c11c54dd2
@ -175,6 +175,8 @@ void plugin_hook_db_sync(struct db *db)
|
||||
ph_req->hook = hook;
|
||||
ph_req->db = db;
|
||||
|
||||
json_add_num(req->stream, "data_version", db_data_version_get(db));
|
||||
|
||||
json_array_start(req->stream, "writes");
|
||||
for (size_t i = 0; i < tal_count(changes); i++)
|
||||
json_add_string(req->stream, NULL, changes[i]);
|
||||
|
28
wallet/db.c
28
wallet/db.c
@ -802,11 +802,27 @@ void db_begin_transaction_(struct db *db, const char *location)
|
||||
db->in_transaction = location;
|
||||
}
|
||||
|
||||
static void db_data_version_incr(struct db *db)
|
||||
{
|
||||
struct db_stmt *stmt = db_prepare_v2(
|
||||
db, SQL("UPDATE vars "
|
||||
"SET intval = intval + 1 "
|
||||
"WHERE name = 'data_version'"));
|
||||
db_exec_prepared_v2(stmt);
|
||||
tal_free(stmt);
|
||||
db->data_version++;
|
||||
}
|
||||
|
||||
void db_commit_transaction(struct db *db)
|
||||
{
|
||||
bool ok;
|
||||
assert(db->in_transaction);
|
||||
db_assert_no_outstanding_statements(db);
|
||||
|
||||
/* Increment before reporting changes to an eventual plugin. */
|
||||
if (db->dirty)
|
||||
db_data_version_incr(db);
|
||||
|
||||
db_report_changes(db, NULL, 0);
|
||||
ok = db->config->commit_tx_fn(db);
|
||||
|
||||
@ -954,7 +970,18 @@ static void db_migrate(struct lightningd *ld, struct db *db)
|
||||
db_exec_prepared_v2(stmt);
|
||||
tal_free(stmt);
|
||||
}
|
||||
}
|
||||
|
||||
u32 db_data_version_get(struct db *db)
|
||||
{
|
||||
struct db_stmt *stmt;
|
||||
u32 version;
|
||||
stmt = db_prepare_v2(db, SQL("SELECT intval FROM vars WHERE name = 'data_version'"));
|
||||
db_query_prepared(stmt);
|
||||
db_step(stmt);
|
||||
version = db_column_int(stmt, 0);
|
||||
tal_free(stmt);
|
||||
return version;
|
||||
}
|
||||
|
||||
struct db *db_setup(const tal_t *ctx, struct lightningd *ld)
|
||||
@ -966,6 +993,7 @@ struct db *db_setup(const tal_t *ctx, struct lightningd *ld)
|
||||
|
||||
db_migrate(ld, db);
|
||||
|
||||
db->data_version = db_data_version_get(db);
|
||||
db_commit_transaction(db);
|
||||
return db;
|
||||
}
|
||||
|
@ -229,4 +229,7 @@ struct db_stmt *db_prepare_v2_(const char *location, struct db *db,
|
||||
*/
|
||||
const char **db_changes(struct db *db);
|
||||
|
||||
/* Get the current data version. */
|
||||
u32 db_data_version_get(struct db *db);
|
||||
|
||||
#endif /* LIGHTNING_WALLET_DB_H */
|
||||
|
@ -34,6 +34,10 @@ struct db {
|
||||
/* Were there any modifying statements in the current transaction?
|
||||
* Used to bump the data_version in the DB.*/
|
||||
bool dirty;
|
||||
|
||||
/* The current DB version we expect to update if changes are
|
||||
* committed. */
|
||||
u32 data_version;
|
||||
};
|
||||
|
||||
struct db_query {
|
||||
|
@ -63,6 +63,7 @@ static struct db *create_test_db(void)
|
||||
|
||||
dsn = tal_fmt(NULL, "sqlite3://%s", filename);
|
||||
db = db_open(NULL, dsn);
|
||||
db->data_version = 0;
|
||||
tal_free(dsn);
|
||||
return db;
|
||||
}
|
||||
@ -107,6 +108,10 @@ static bool test_primitives(void)
|
||||
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;
|
||||
db_commit_transaction(db);
|
||||
CHECK(!db->in_transaction);
|
||||
tal_free(db);
|
||||
|
@ -749,6 +749,7 @@ static struct wallet *create_test_wallet(struct lightningd *ld, const tal_t *ctx
|
||||
CHECK_MSG(w->db, "Failed opening the db");
|
||||
db_begin_transaction(w->db);
|
||||
db_migrate(ld, w->db);
|
||||
w->db->data_version = 0;
|
||||
db_commit_transaction(w->db);
|
||||
CHECK_MSG(!wallet_err, "DB migration failed");
|
||||
w->max_channel_dbid = 0;
|
||||
|
Loading…
Reference in New Issue
Block a user