diff --git a/wallet/db_postgres_sqlgen.c b/wallet/db_postgres_sqlgen.c index 21a3d8dda..9c4ded79f 100644 --- a/wallet/db_postgres_sqlgen.c +++ b/wallet/db_postgres_sqlgen.c @@ -2006,6 +2006,36 @@ struct db_query db_postgres_queries[] = { .placeholders = 1, .readonly = true, }, + { + .name = "SELECT 1 FROM datastore WHERE key = ?;", + .query = "SELECT 1 FROM datastore WHERE key = $1;", + .placeholders = 1, + .readonly = true, + }, + { + .name = "INSERT INTO datastore VALUES (?, ?);", + .query = "INSERT INTO datastore VALUES ($1, $2);", + .placeholders = 2, + .readonly = false, + }, + { + .name = "DELETE FROM datastore WHERE key = ?", + .query = "DELETE FROM datastore WHERE key = $1", + .placeholders = 1, + .readonly = false, + }, + { + .name = "SELECT data FROM datastore WHERE key = ?;", + .query = "SELECT data FROM datastore WHERE key = $1;", + .placeholders = 1, + .readonly = true, + }, + { + .name = "SELECT key, data FROM datastore;", + .query = "SELECT key, data FROM datastore;", + .placeholders = 0, + .readonly = true, + }, { .name = "SELECT name FROM sqlite_master WHERE type='table';", .query = "SELECT name FROM sqlite_master WHERE type='table';", @@ -2032,10 +2062,10 @@ struct db_query db_postgres_queries[] = { }, }; -#define DB_POSTGRES_QUERY_COUNT 337 +#define DB_POSTGRES_QUERY_COUNT 342 #endif /* HAVE_POSTGRES */ #endif /* LIGHTNINGD_WALLET_GEN_DB_POSTGRES */ -// SHA256STAMP:765ebe6f1bf58b1d492d8d1715e423fbe0764e3440c8bd2be8d0a09dccc95a5c +// SHA256STAMP:743e13b59241ab495a7ebd6e0e50887f399e7816cc73fd90154f761f1b484f89 diff --git a/wallet/db_sqlite3_sqlgen.c b/wallet/db_sqlite3_sqlgen.c index 383eccf21..6dccf0ca0 100644 --- a/wallet/db_sqlite3_sqlgen.c +++ b/wallet/db_sqlite3_sqlgen.c @@ -2006,6 +2006,36 @@ struct db_query db_sqlite3_queries[] = { .placeholders = 1, .readonly = true, }, + { + .name = "SELECT 1 FROM datastore WHERE key = ?;", + .query = "SELECT 1 FROM datastore WHERE key = ?;", + .placeholders = 1, + .readonly = true, + }, + { + .name = "INSERT INTO datastore VALUES (?, ?);", + .query = "INSERT INTO datastore VALUES (?, ?);", + .placeholders = 2, + .readonly = false, + }, + { + .name = "DELETE FROM datastore WHERE key = ?", + .query = "DELETE FROM datastore WHERE key = ?", + .placeholders = 1, + .readonly = false, + }, + { + .name = "SELECT data FROM datastore WHERE key = ?;", + .query = "SELECT data FROM datastore WHERE key = ?;", + .placeholders = 1, + .readonly = true, + }, + { + .name = "SELECT key, data FROM datastore;", + .query = "SELECT key, data FROM datastore;", + .placeholders = 0, + .readonly = true, + }, { .name = "SELECT name FROM sqlite_master WHERE type='table';", .query = "SELECT name FROM sqlite_master WHERE type='table';", @@ -2032,10 +2062,10 @@ struct db_query db_sqlite3_queries[] = { }, }; -#define DB_SQLITE3_QUERY_COUNT 337 +#define DB_SQLITE3_QUERY_COUNT 342 #endif /* HAVE_SQLITE3 */ #endif /* LIGHTNINGD_WALLET_GEN_DB_SQLITE3 */ -// SHA256STAMP:765ebe6f1bf58b1d492d8d1715e423fbe0764e3440c8bd2be8d0a09dccc95a5c +// SHA256STAMP:743e13b59241ab495a7ebd6e0e50887f399e7816cc73fd90154f761f1b484f89 diff --git a/wallet/statements_gettextgen.po b/wallet/statements_gettextgen.po index d65d92999..8a74fed9b 100644 --- a/wallet/statements_gettextgen.po +++ b/wallet/statements_gettextgen.po @@ -1330,6 +1330,26 @@ msgstr "" msgid "SELECT status FROM offers WHERE offer_id = ?;" msgstr "" +#: wallet/wallet.c:4746 +msgid "SELECT 1 FROM datastore WHERE key = ?;" +msgstr "" + +#: wallet/wallet.c:4759 +msgid "INSERT INTO datastore VALUES (?, ?);" +msgstr "" + +#: wallet/wallet.c:4773 +msgid "DELETE FROM datastore WHERE key = ?" +msgstr "" + +#: wallet/wallet.c:4788 +msgid "SELECT data FROM datastore WHERE key = ?;" +msgstr "" + +#: wallet/wallet.c:4809 +msgid "SELECT key, data FROM datastore;" +msgstr "" + #: wallet/test/run-db.c:126 msgid "SELECT name FROM sqlite_master WHERE type='table';" msgstr "" @@ -1345,4 +1365,4 @@ msgstr "" #: wallet/test/run-wallet.c:1753 msgid "INSERT INTO channels (id) VALUES (1);" msgstr "" -# SHA256STAMP:17f1c19add21aa2c5b771cb0f19300e9c50cdd8458ccf02a0368cf29d6958374 +# SHA256STAMP:65a48a3f7b7223e68e12148b699342842b394228141583f008d0cd7002b18f97 diff --git a/wallet/wallet.c b/wallet/wallet.c index 91fe8a8e5..44f3b425f 100644 --- a/wallet/wallet.c +++ b/wallet/wallet.c @@ -4737,3 +4737,92 @@ void wallet_offer_mark_used(struct db *db, const struct sha256 *offer_id) offer_status_update(db, offer_id, status, newstatus); } } + +bool wallet_datastore_add(struct wallet *w, const char *key, const u8 *data) +{ + struct db_stmt *stmt; + + /* Test if already exists. */ + stmt = db_prepare_v2(w->db, SQL("SELECT 1" + " FROM datastore" + " WHERE key = ?;")); + db_bind_text(stmt, 0, key); + db_query_prepared(stmt); + + if (db_step(stmt)) { + tal_free(stmt); + return false; + } + tal_free(stmt); + + stmt = db_prepare_v2(w->db, + SQL("INSERT INTO datastore VALUES (?, ?);")); + + db_bind_text(stmt, 0, key); + db_bind_talarr(stmt, 1, data); + db_exec_prepared_v2(take(stmt)); + return true; +} + +u8 *wallet_datastore_remove(const tal_t *ctx, struct wallet *w, const char *key) +{ + u8 *data = wallet_datastore_fetch(ctx, w, key); + if (data) { + struct db_stmt *stmt; + + stmt = db_prepare_v2(w->db, SQL("DELETE FROM datastore" + " WHERE key = ?")); + db_bind_text(stmt, 0, key); + db_exec_prepared_v2(take(stmt)); + } + return data; +} + +u8 *wallet_datastore_fetch(const tal_t *ctx, + struct wallet *w, const char *key) +{ + struct db_stmt *stmt; + u8 *data; + + /* Test if already exists. */ + stmt = db_prepare_v2(w->db, SQL("SELECT data" + " FROM datastore" + " WHERE key = ?;")); + db_bind_text(stmt, 0, key); + db_query_prepared(stmt); + + if (db_step(stmt)) + data = db_column_talarr(ctx, stmt, 0); + else + data = NULL; + tal_free(stmt); + return data; +} + +struct db_stmt *wallet_datastore_first(const tal_t *ctx, + struct wallet *w, + const char **key, + const u8 **data) +{ + struct db_stmt *stmt; + + stmt = db_prepare_v2(w->db, SQL("SELECT key, data FROM datastore;")); + db_query_prepared(stmt); + + return wallet_datastore_next(ctx, w, stmt, key, data); +} + +struct db_stmt *wallet_datastore_next(const tal_t *ctx, + struct wallet *w, + struct db_stmt *stmt, + const char **key, + const u8 **data) +{ + if (!db_step(stmt)) + return tal_free(stmt); + + *key = tal_strdup(ctx, (const char *)db_column_text(stmt, 0)); + *data = db_column_talarr(ctx, stmt, 1); + + return stmt; +} diff --git a/wallet/wallet.h b/wallet/wallet.h index 398fd948a..16b044af5 100644 --- a/wallet/wallet.h +++ b/wallet/wallet.h @@ -1529,4 +1529,68 @@ enum offer_status wallet_offer_disable(struct wallet *w, */ void wallet_offer_mark_used(struct db *db, const struct sha256 *offer_id) NO_NULL_ARGS; + +/** + * Add a key/value to the datastore. + * @w: the wallet + * @key: the first key (if returns non-NULL) + * @data: the first data (if returns non-NULL) + * + * Returns false if the key is already in the store. + */ +bool wallet_datastore_add(struct wallet *w, const char *key, const u8 *data); + +/** + * Remove a key from the datastore (return the old data). + * @ctx: the tal ctx to allocate return off + * @w: the wallet + * @key: the key + * + * Returns NULL if the key was not in the store. + */ +u8 *wallet_datastore_remove(const tal_t *ctx, struct wallet *w, const char *key); + +/** + * Retreive a value from the datastore. + * @ctx: the tal ctx to allocate return off + * @w: the wallet + * @key: the first key (if returns non-NULL) + * + * Returns NULL if the key is not in the store. + */ +u8 *wallet_datastore_fetch(const tal_t *ctx, + struct wallet *w, const char *key); + +/** + * Iterate through the datastore. + * @ctx: the tal ctx to allocate off + * @w: the wallet + * @key: the first key (if returns non-NULL) + * @data: the first data (if returns non-NULL) + * + * Returns pointer to hand as @stmt to wallet_datastore_next(), or NULL. + * If you choose not to call wallet_datastore_next() you must free it! + */ +struct db_stmt *wallet_datastore_first(const tal_t *ctx, + struct wallet *w, + const char **key, + const u8 **data); + +/** + * Iterate through the datastore. + * @ctx: the tal ctx to allocate off + * @w: the wallet + * @stmt: the previous statement. + * @key: the first key (if returns non-NULL) + * @data: the first data (if returns non-NULL) + * + * Returns pointer to hand as @stmt to wallet_datastore_next(), or NULL. + * If you choose not to call wallet_datastore_next() you must free it! + */ +struct db_stmt *wallet_datastore_next(const tal_t *ctx, + struct wallet *w, + struct db_stmt *stmt, + const char **key, + const u8 **data); + #endif /* LIGHTNING_WALLET_WALLET_H */