aboutsummaryrefslogtreecommitdiff
path: root/src/wallet
diff options
context:
space:
mode:
authorfanquake <fanquake@gmail.com>2021-04-07 14:09:13 +0800
committerfanquake <fanquake@gmail.com>2021-04-07 14:17:25 +0800
commitc0160ea52ea849d7a10f9f5c97100b434e62d798 (patch)
tree0682f3e79f994252f518560c0e9722b1fdbd3b29 /src/wallet
parent41a8d2b96ff5cbc2efa9b0996f30228d0a625fdb (diff)
parentea19cc844e780b29825b26aee321204be981a3ae (diff)
downloadbitcoin-c0160ea52ea849d7a10f9f5c97100b434e62d798.tar.xz
Merge #21540: wallet: refactor: dedup sqlite statement preparations/deletions
ea19cc844e780b29825b26aee321204be981a3ae wallet: refactor: dedup sqlite statement deletions (Sebastian Falbesoner) 9a3670930eaf6b495f81ef9c5f6e68883a3a2750 wallet: refactor: dedup sqlite statement preparations (Sebastian Falbesoner) Pull request description: This refactoring PR deduplicates repeated SQLite statement preparation calls (`sqlite3_prepare_v2(...)`) / deletions (`sqlite3_finalize(...)`) and its surrounding logic by putting each prepared statement and its corresponding text representation into a ~std::map~ ~`std::array`~ `std::vector`. This should be more readable and less error-prone, e.g. in case an additional statement needs to be added in the future or the error handling has to be adapted. ACKs for top commit: achow101: ACK ea19cc844e780b29825b26aee321204be981a3ae meshcollider: utACK ea19cc844e780b29825b26aee321204be981a3ae Tree-SHA512: ced89869b2147e088e7a4cda2acbbdd4a806f66dbc2d6999953d0d702c0655aa53c0eb699cc7e5e3732f2d24206d577a9d9e1b5de7f439100dead2696ade1092
Diffstat (limited to 'src/wallet')
-rw-r--r--src/wallet/sqlite.cpp81
1 files changed, 33 insertions, 48 deletions
diff --git a/src/wallet/sqlite.cpp b/src/wallet/sqlite.cpp
index 975974cb6a..91891c5fc2 100644
--- a/src/wallet/sqlite.cpp
+++ b/src/wallet/sqlite.cpp
@@ -16,6 +16,9 @@
#include <sqlite3.h>
#include <stdint.h>
+#include <utility>
+#include <vector>
+
static constexpr int32_t WALLET_SCHEMA_VERSION = 0;
static Mutex g_sqlite_mutex;
@@ -69,30 +72,21 @@ SQLiteDatabase::SQLiteDatabase(const fs::path& dir_path, const fs::path& file_pa
void SQLiteBatch::SetupSQLStatements()
{
- int res;
- if (!m_read_stmt) {
- if ((res = sqlite3_prepare_v2(m_database.m_db, "SELECT value FROM main WHERE key = ?", -1, &m_read_stmt, nullptr)) != SQLITE_OK) {
- throw std::runtime_error(strprintf("SQLiteDatabase: Failed to setup SQL statements: %s\n", sqlite3_errstr(res)));
- }
- }
- if (!m_insert_stmt) {
- if ((res = sqlite3_prepare_v2(m_database.m_db, "INSERT INTO main VALUES(?, ?)", -1, &m_insert_stmt, nullptr)) != SQLITE_OK) {
- throw std::runtime_error(strprintf("SQLiteDatabase: Failed to setup SQL statements: %s\n", sqlite3_errstr(res)));
- }
- }
- if (!m_overwrite_stmt) {
- if ((res = sqlite3_prepare_v2(m_database.m_db, "INSERT or REPLACE into main values(?, ?)", -1, &m_overwrite_stmt, nullptr)) != SQLITE_OK) {
- throw std::runtime_error(strprintf("SQLiteDatabase: Failed to setup SQL statements: %s\n", sqlite3_errstr(res)));
- }
- }
- if (!m_delete_stmt) {
- if ((res = sqlite3_prepare_v2(m_database.m_db, "DELETE FROM main WHERE key = ?", -1, &m_delete_stmt, nullptr)) != SQLITE_OK) {
- throw std::runtime_error(strprintf("SQLiteDatabase: Failed to setup SQL statements: %s\n", sqlite3_errstr(res)));
- }
- }
- if (!m_cursor_stmt) {
- if ((res = sqlite3_prepare_v2(m_database.m_db, "SELECT key, value FROM main", -1, &m_cursor_stmt, nullptr)) != SQLITE_OK) {
- throw std::runtime_error(strprintf("SQLiteDatabase: Failed to setup SQL statements : %s\n", sqlite3_errstr(res)));
+ const std::vector<std::pair<sqlite3_stmt**, const char*>> statements{
+ {&m_read_stmt, "SELECT value FROM main WHERE key = ?"},
+ {&m_insert_stmt, "INSERT INTO main VALUES(?, ?)"},
+ {&m_overwrite_stmt, "INSERT or REPLACE into main values(?, ?)"},
+ {&m_delete_stmt, "DELETE FROM main WHERE key = ?"},
+ {&m_cursor_stmt, "SELECT key, value FROM main"},
+ };
+
+ for (const auto& [stmt_prepared, stmt_text] : statements) {
+ if (*stmt_prepared == nullptr) {
+ int res = sqlite3_prepare_v2(m_database.m_db, stmt_text, -1, stmt_prepared, nullptr);
+ if (res != SQLITE_OK) {
+ throw std::runtime_error(strprintf(
+ "SQLiteDatabase: Failed to setup SQL statements: %s\n", sqlite3_errstr(res)));
+ }
}
}
}
@@ -353,31 +347,22 @@ void SQLiteBatch::Close()
}
// Free all of the prepared statements
- int ret = sqlite3_finalize(m_read_stmt);
- if (ret != SQLITE_OK) {
- LogPrintf("SQLiteBatch: Batch closed but could not finalize read statement: %s\n", sqlite3_errstr(ret));
- }
- ret = sqlite3_finalize(m_insert_stmt);
- if (ret != SQLITE_OK) {
- LogPrintf("SQLiteBatch: Batch closed but could not finalize insert statement: %s\n", sqlite3_errstr(ret));
- }
- ret = sqlite3_finalize(m_overwrite_stmt);
- if (ret != SQLITE_OK) {
- LogPrintf("SQLiteBatch: Batch closed but could not finalize overwrite statement: %s\n", sqlite3_errstr(ret));
- }
- ret = sqlite3_finalize(m_delete_stmt);
- if (ret != SQLITE_OK) {
- LogPrintf("SQLiteBatch: Batch closed but could not finalize delete statement: %s\n", sqlite3_errstr(ret));
- }
- ret = sqlite3_finalize(m_cursor_stmt);
- if (ret != SQLITE_OK) {
- LogPrintf("SQLiteBatch: Batch closed but could not finalize cursor statement: %s\n", sqlite3_errstr(ret));
+ const std::vector<std::pair<sqlite3_stmt**, const char*>> statements{
+ {&m_read_stmt, "read"},
+ {&m_insert_stmt, "insert"},
+ {&m_overwrite_stmt, "overwrite"},
+ {&m_delete_stmt, "delete"},
+ {&m_cursor_stmt, "cursor"},
+ };
+
+ for (const auto& [stmt_prepared, stmt_description] : statements) {
+ int res = sqlite3_finalize(*stmt_prepared);
+ if (res != SQLITE_OK) {
+ LogPrintf("SQLiteBatch: Batch closed but could not finalize %s statement: %s\n",
+ stmt_description, sqlite3_errstr(res));
+ }
+ *stmt_prepared = nullptr;
}
- m_read_stmt = nullptr;
- m_insert_stmt = nullptr;
- m_overwrite_stmt = nullptr;
- m_delete_stmt = nullptr;
- m_cursor_stmt = nullptr;
}
bool SQLiteBatch::ReadKey(CDataStream&& key, CDataStream& value)