Skip to content

Commit 4f5d3ce

Browse files
committed
Merge bitcoin/bitcoin#24486: wallet: refactor: dedup sqlite blob binding
8ea6167 wallet: refactor: dedup sqlite blob binding (Sebastian Falbesoner) Pull request description: This refactoring PR deduplicates repeated SQLite blob binding to a statement with a newly introduced helper function `BindBlobToStatement`, abstracting away the calls to `sqlite3_bind_blob(...)`. This should be more readable and less error-prone, e.g. in case that the error handling has to be adapted. As a slight drawback, the function where the binding happens is not printed anymore (`__func__`), i.e. one could argue this is not strictly a refactoring, but IMHO the advantages of deduplication outweigh this; binding errors are purely internal logic errors (wrong use of the sqlite API) rather than something that is dependend on external data like DB content. ACKs for top commit: laanwj: Code review ACK 8ea6167 achow101: ACK 8ea6167 klementtan: ACK 8ea6167 Tree-SHA512: 1de0d214f836bc405a01e98a3a2d71f2deaddc7d23c31cad80219d1614bec92619c06d9a4a091dd563d3e95ffb879649c29745d8f89669b2a5330552c212af3f
2 parents 76d44e8 + 8ea6167 commit 4f5d3ce

File tree

1 file changed

+26
-41
lines changed

1 file changed

+26
-41
lines changed

src/wallet/sqlite.cpp

Lines changed: 26 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,22 @@ static void ErrorLogCallback(void* arg, int code, const char* msg)
3737
LogPrintf("SQLite Error. Code: %d. Message: %s\n", code, msg);
3838
}
3939

40+
static bool BindBlobToStatement(sqlite3_stmt* stmt,
41+
int index,
42+
Span<const std::byte> blob,
43+
const std::string& description)
44+
{
45+
int res = sqlite3_bind_blob(stmt, index, blob.data(), blob.size(), SQLITE_STATIC);
46+
if (res != SQLITE_OK) {
47+
LogPrintf("Unable to bind %s to statement: %s\n", description, sqlite3_errstr(res));
48+
sqlite3_clear_bindings(stmt);
49+
sqlite3_reset(stmt);
50+
return false;
51+
}
52+
53+
return true;
54+
}
55+
4056
static std::optional<int> ReadPragmaInteger(sqlite3* db, const std::string& key, const std::string& description, bilingual_str& error)
4157
{
4258
std::string stmt_text = strprintf("PRAGMA %s", key);
@@ -377,14 +393,8 @@ bool SQLiteBatch::ReadKey(CDataStream&& key, CDataStream& value)
377393
assert(m_read_stmt);
378394

379395
// Bind: leftmost parameter in statement is index 1
380-
int res = sqlite3_bind_blob(m_read_stmt, 1, key.data(), key.size(), SQLITE_STATIC);
381-
if (res != SQLITE_OK) {
382-
LogPrintf("%s: Unable to bind statement: %s\n", __func__, sqlite3_errstr(res));
383-
sqlite3_clear_bindings(m_read_stmt);
384-
sqlite3_reset(m_read_stmt);
385-
return false;
386-
}
387-
res = sqlite3_step(m_read_stmt);
396+
if (!BindBlobToStatement(m_read_stmt, 1, key, "key")) return false;
397+
int res = sqlite3_step(m_read_stmt);
388398
if (res != SQLITE_ROW) {
389399
if (res != SQLITE_DONE) {
390400
// SQLITE_DONE means "not found", don't log an error in that case.
@@ -418,23 +428,11 @@ bool SQLiteBatch::WriteKey(CDataStream&& key, CDataStream&& value, bool overwrit
418428

419429
// Bind: leftmost parameter in statement is index 1
420430
// Insert index 1 is key, 2 is value
421-
int res = sqlite3_bind_blob(stmt, 1, key.data(), key.size(), SQLITE_STATIC);
422-
if (res != SQLITE_OK) {
423-
LogPrintf("%s: Unable to bind key to statement: %s\n", __func__, sqlite3_errstr(res));
424-
sqlite3_clear_bindings(stmt);
425-
sqlite3_reset(stmt);
426-
return false;
427-
}
428-
res = sqlite3_bind_blob(stmt, 2, value.data(), value.size(), SQLITE_STATIC);
429-
if (res != SQLITE_OK) {
430-
LogPrintf("%s: Unable to bind value to statement: %s\n", __func__, sqlite3_errstr(res));
431-
sqlite3_clear_bindings(stmt);
432-
sqlite3_reset(stmt);
433-
return false;
434-
}
431+
if (!BindBlobToStatement(stmt, 1, key, "key")) return false;
432+
if (!BindBlobToStatement(stmt, 2, value, "value")) return false;
435433

436434
// Execute
437-
res = sqlite3_step(stmt);
435+
int res = sqlite3_step(stmt);
438436
sqlite3_clear_bindings(stmt);
439437
sqlite3_reset(stmt);
440438
if (res != SQLITE_DONE) {
@@ -449,16 +447,10 @@ bool SQLiteBatch::EraseKey(CDataStream&& key)
449447
assert(m_delete_stmt);
450448

451449
// Bind: leftmost parameter in statement is index 1
452-
int res = sqlite3_bind_blob(m_delete_stmt, 1, key.data(), key.size(), SQLITE_STATIC);
453-
if (res != SQLITE_OK) {
454-
LogPrintf("%s: Unable to bind statement: %s\n", __func__, sqlite3_errstr(res));
455-
sqlite3_clear_bindings(m_delete_stmt);
456-
sqlite3_reset(m_delete_stmt);
457-
return false;
458-
}
450+
if (!BindBlobToStatement(m_delete_stmt, 1, key, "key")) return false;
459451

460452
// Execute
461-
res = sqlite3_step(m_delete_stmt);
453+
int res = sqlite3_step(m_delete_stmt);
462454
sqlite3_clear_bindings(m_delete_stmt);
463455
sqlite3_reset(m_delete_stmt);
464456
if (res != SQLITE_DONE) {
@@ -473,18 +465,11 @@ bool SQLiteBatch::HasKey(CDataStream&& key)
473465
assert(m_read_stmt);
474466

475467
// Bind: leftmost parameter in statement is index 1
476-
bool ret = false;
477-
int res = sqlite3_bind_blob(m_read_stmt, 1, key.data(), key.size(), SQLITE_STATIC);
478-
if (res == SQLITE_OK) {
479-
res = sqlite3_step(m_read_stmt);
480-
if (res == SQLITE_ROW) {
481-
ret = true;
482-
}
483-
}
484-
468+
if (!BindBlobToStatement(m_read_stmt, 1, key, "key")) return false;
469+
int res = sqlite3_step(m_read_stmt);
485470
sqlite3_clear_bindings(m_read_stmt);
486471
sqlite3_reset(m_read_stmt);
487-
return ret;
472+
return res == SQLITE_ROW;
488473
}
489474

490475
bool SQLiteBatch::StartCursor()

0 commit comments

Comments
 (0)