7 #include <chainparams.h> 29 return {
reinterpret_cast<const std::byte*
>(sqlite3_column_blob(stmt, col)),
30 static_cast<size_t>(sqlite3_column_bytes(stmt, col))};
41 LogPrintf(
"SQLite Error. Code: %d. Message: %s\n", code,
msg);
47 if (code == SQLITE_TRACE_STMT) {
48 auto* stmt =
static_cast<sqlite3_stmt*
>(param1);
52 char* expanded{sqlite3_stmt_readonly(stmt) ? sqlite3_expanded_sql(stmt) :
nullptr};
53 LogPrintf(
"[%s] SQLite Statement: %s\n", db->Filename(), expanded ? expanded : sqlite3_sql(stmt));
54 if (expanded) sqlite3_free(expanded);
62 const std::string& description)
68 int res = sqlite3_bind_blob(stmt, index, blob.
data() ?
static_cast<const void*
>(blob.
data()) :
"", blob.
size(), SQLITE_STATIC);
69 if (res != SQLITE_OK) {
70 LogPrintf(
"Unable to bind %s to statement: %s\n", description, sqlite3_errstr(res));
71 sqlite3_clear_bindings(stmt);
81 std::string stmt_text =
strprintf(
"PRAGMA %s", key);
82 sqlite3_stmt* pragma_read_stmt{
nullptr};
83 int ret = sqlite3_prepare_v2(db, stmt_text.c_str(), -1, &pragma_read_stmt,
nullptr);
84 if (
ret != SQLITE_OK) {
85 sqlite3_finalize(pragma_read_stmt);
89 ret = sqlite3_step(pragma_read_stmt);
90 if (
ret != SQLITE_ROW) {
91 sqlite3_finalize(pragma_read_stmt);
95 int result = sqlite3_column_int(pragma_read_stmt, 0);
96 sqlite3_finalize(pragma_read_stmt);
100 static void SetPragma(sqlite3* db,
const std::string& key,
const std::string& value,
const std::string& err_msg)
102 std::string stmt_text =
strprintf(
"PRAGMA %s = %s", key, value);
103 int ret = sqlite3_exec(db, stmt_text.c_str(),
nullptr,
nullptr,
nullptr);
104 if (
ret != SQLITE_OK) {
105 throw std::runtime_error(
strprintf(
"SQLiteDatabase: %s: %s\n", err_msg, sqlite3_errstr(
ret)));
110 int SQLiteDatabase::g_sqlite_count = 0;
120 if (++g_sqlite_count == 1) {
123 if (
ret != SQLITE_OK) {
124 throw std::runtime_error(
strprintf(
"SQLiteDatabase: Failed to setup error log: %s\n", sqlite3_errstr(
ret)));
127 ret = sqlite3_config(SQLITE_CONFIG_SERIALIZED);
128 if (
ret != SQLITE_OK) {
129 throw std::runtime_error(
strprintf(
"SQLiteDatabase: Failed to configure serialized threading mode: %s\n", sqlite3_errstr(
ret)));
132 int ret = sqlite3_initialize();
133 if (
ret != SQLITE_OK) {
134 throw std::runtime_error(
strprintf(
"SQLiteDatabase: Failed to initialize SQLite: %s\n", sqlite3_errstr(
ret)));
140 }
catch (
const std::runtime_error&) {
149 const std::vector<std::pair<sqlite3_stmt**, const char*>> statements{
150 {&
m_read_stmt,
"SELECT value FROM main WHERE key = ?"},
157 for (
const auto& [stmt_prepared, stmt_text] : statements) {
158 if (*stmt_prepared ==
nullptr) {
159 int res = sqlite3_prepare_v2(
m_database.
m_db, stmt_text, -1, stmt_prepared,
nullptr);
160 if (res != SQLITE_OK) {
162 "SQLiteDatabase: Failed to setup SQL statements: %s\n", sqlite3_errstr(res)));
180 if (--g_sqlite_count == 0) {
181 int ret = sqlite3_shutdown();
182 if (
ret != SQLITE_OK) {
183 LogPrintf(
"SQLiteDatabase: Failed to shutdown SQLite: %s\n", sqlite3_errstr(
ret));
194 if (!read_result.has_value())
return false;
195 uint32_t app_id =
static_cast<uint32_t
>(read_result.value());
197 if (app_id != net_magic) {
198 error =
strprintf(
_(
"SQLiteDatabase: Unexpected application id. Expected %u, got %u"), net_magic, app_id);
204 if (!read_result.has_value())
return false;
205 int32_t user_ver = read_result.value();
211 sqlite3_stmt* stmt{
nullptr};
212 int ret = sqlite3_prepare_v2(
m_db,
"PRAGMA integrity_check", -1, &stmt,
nullptr);
213 if (
ret != SQLITE_OK) {
214 sqlite3_finalize(stmt);
215 error =
strprintf(
_(
"SQLiteDatabase: Failed to prepare statement to verify database: %s"), sqlite3_errstr(
ret));
219 ret = sqlite3_step(stmt);
220 if (
ret == SQLITE_DONE) {
223 if (
ret != SQLITE_ROW) {
224 error =
strprintf(
_(
"SQLiteDatabase: Failed to execute statement to verify database: %s"), sqlite3_errstr(
ret));
227 const char*
msg = (
const char*)sqlite3_column_text(stmt, 0);
229 error =
strprintf(
_(
"SQLiteDatabase: Failed to read database verification error: %s"), sqlite3_errstr(
ret));
232 std::string str_msg(
msg);
233 if (str_msg ==
"ok") {
241 sqlite3_finalize(stmt);
242 return error.empty();
247 int flags = SQLITE_OPEN_FULLMUTEX | SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE;
249 flags |= SQLITE_OPEN_MEMORY;
252 if (
m_db ==
nullptr) {
257 if (
ret != SQLITE_OK) {
258 throw std::runtime_error(
strprintf(
"SQLiteDatabase: Failed to open database: %s\n", sqlite3_errstr(
ret)));
260 ret = sqlite3_extended_result_codes(
m_db, 1);
261 if (
ret != SQLITE_OK) {
262 throw std::runtime_error(
strprintf(
"SQLiteDatabase: Failed to enable extended result codes: %s\n", sqlite3_errstr(
ret)));
267 if (
ret != SQLITE_OK) {
273 if (sqlite3_db_readonly(
m_db,
"main") != 0) {
274 throw std::runtime_error(
"SQLiteDatabase: Database opened in readonly mode but read-write permissions are needed");
279 SetPragma(
m_db,
"locking_mode",
"exclusive",
"Unable to change database locking mode to exclusive");
281 int ret = sqlite3_exec(
m_db,
"BEGIN EXCLUSIVE TRANSACTION",
nullptr,
nullptr,
nullptr);
282 if (
ret != SQLITE_OK) {
283 throw std::runtime_error(
"SQLiteDatabase: Unable to obtain an exclusive lock on the database, is it being used by another instance of " PACKAGE_NAME "?\n");
285 ret = sqlite3_exec(
m_db,
"COMMIT",
nullptr,
nullptr,
nullptr);
286 if (
ret != SQLITE_OK) {
287 throw std::runtime_error(
strprintf(
"SQLiteDatabase: Unable to end exclusive lock transaction: %s\n", sqlite3_errstr(
ret)));
291 SetPragma(
m_db,
"fullfsync",
"true",
"Failed to enable fullfsync");
295 LogPrintf(
"WARNING SQLite is configured to not wait for data to be flushed to disk. Data loss and corruption may occur.\n");
296 SetPragma(
m_db,
"synchronous",
"OFF",
"Failed to set synchronous mode to OFF");
301 sqlite3_stmt* check_main_stmt{
nullptr};
302 ret = sqlite3_prepare_v2(
m_db,
"SELECT name FROM sqlite_master WHERE type='table' AND name='main'", -1, &check_main_stmt,
nullptr);
303 if (
ret != SQLITE_OK) {
304 throw std::runtime_error(
strprintf(
"SQLiteDatabase: Failed to prepare statement to check table existence: %s\n", sqlite3_errstr(
ret)));
306 ret = sqlite3_step(check_main_stmt);
307 if (sqlite3_finalize(check_main_stmt) != SQLITE_OK) {
308 throw std::runtime_error(
strprintf(
"SQLiteDatabase: Failed to finalize statement checking table existence: %s\n", sqlite3_errstr(
ret)));
311 if (
ret == SQLITE_DONE) {
312 table_exists =
false;
313 }
else if (
ret == SQLITE_ROW) {
316 throw std::runtime_error(
strprintf(
"SQLiteDatabase: Failed to execute statement to check table existence: %s\n", sqlite3_errstr(
ret)));
321 ret = sqlite3_exec(
m_db,
"CREATE TABLE main(key BLOB PRIMARY KEY NOT NULL, value BLOB NOT NULL)",
nullptr,
nullptr,
nullptr);
322 if (
ret != SQLITE_OK) {
323 throw std::runtime_error(
strprintf(
"SQLiteDatabase: Failed to create new database: %s\n", sqlite3_errstr(
ret)));
329 "Failed to set the application id");
333 "Failed to set the wallet schema version");
340 int ret = sqlite3_exec(
m_db,
"VACUUM",
nullptr,
nullptr,
nullptr);
341 return ret == SQLITE_OK;
347 int res = sqlite3_open(dest.c_str(), &db_copy);
348 if (res != SQLITE_OK) {
349 sqlite3_close(db_copy);
352 sqlite3_backup* backup = sqlite3_backup_init(db_copy,
"main",
m_db,
"main");
354 LogPrintf(
"%s: Unable to begin backup: %s\n", __func__, sqlite3_errmsg(
m_db));
355 sqlite3_close(db_copy);
359 res = sqlite3_backup_step(backup, -1);
360 if (res != SQLITE_DONE) {
361 LogPrintf(
"%s: Unable to backup: %s\n", __func__, sqlite3_errstr(res));
362 sqlite3_backup_finish(backup);
363 sqlite3_close(db_copy);
366 res = sqlite3_backup_finish(backup);
367 sqlite3_close(db_copy);
368 return res == SQLITE_OK;
373 int res = sqlite3_close(
m_db);
374 if (res != SQLITE_OK) {
375 throw std::runtime_error(
strprintf(
"SQLiteDatabase: Failed to close database: %s\n", sqlite3_errstr(res)));
383 return std::make_unique<SQLiteBatch>(*this);
387 : m_database(database)
400 LogPrintf(
"SQLiteBatch: Batch closed unexpectedly without the transaction being explicitly committed or aborted\n");
402 LogPrintf(
"SQLiteBatch: Batch closed and failed to abort transaction\n");
407 const std::vector<std::pair<sqlite3_stmt**, const char*>> statements{
415 for (
const auto& [stmt_prepared, stmt_description] : statements) {
416 int res = sqlite3_finalize(*stmt_prepared);
417 if (res != SQLITE_OK) {
418 LogPrintf(
"SQLiteBatch: Batch closed but could not finalize %s statement: %s\n",
419 stmt_description, sqlite3_errstr(res));
421 *stmt_prepared =
nullptr;
433 if (res != SQLITE_ROW) {
434 if (res != SQLITE_DONE) {
436 LogPrintf(
"%s: Unable to execute statement: %s\n", __func__, sqlite3_errstr(res));
469 int res = sqlite3_step(stmt);
470 sqlite3_clear_bindings(stmt);
472 if (res != SQLITE_DONE) {
473 LogPrintf(
"%s: Unable to execute statement: %s\n", __func__, sqlite3_errstr(res));
475 return res == SQLITE_DONE;
487 int res = sqlite3_step(stmt);
488 sqlite3_clear_bindings(stmt);
490 if (res != SQLITE_DONE) {
491 LogPrintf(
"%s: Unable to execute statement: %s\n", __func__, sqlite3_errstr(res));
493 return res == SQLITE_DONE;
516 return res == SQLITE_ROW;
522 if (res == SQLITE_DONE) {
525 if (res != SQLITE_ROW) {
526 LogPrintf(
"%s: Unable to execute cursor step: %s\n", __func__, sqlite3_errstr(res));
544 if (res != SQLITE_OK) {
545 LogPrintf(
"%s: cursor closed but could not finalize cursor statement: %s\n",
546 __func__, sqlite3_errstr(res));
553 auto cursor = std::make_unique<SQLiteCursor>();
555 const char* stmt_text =
"SELECT key, value FROM main";
556 int res = sqlite3_prepare_v2(
m_database.
m_db, stmt_text, -1, &cursor->m_cursor_stmt,
nullptr);
557 if (res != SQLITE_OK) {
559 "%s: Failed to setup cursor SQL statement: %s\n", __func__, sqlite3_errstr(res)));
572 std::vector<std::byte> start_range(
prefix.begin(),
prefix.end());
573 std::vector<std::byte> end_range(
prefix.begin(),
prefix.end());
574 auto it = end_range.rbegin();
575 for (; it != end_range.rend(); ++it) {
576 if (*it == std::byte(std::numeric_limits<unsigned char>::max())) {
580 *it = std::byte(std::to_integer<unsigned char>(*it) + 1);
583 if (it == end_range.rend()) {
588 auto cursor = std::make_unique<SQLiteCursor>(start_range, end_range);
589 if (!cursor)
return nullptr;
591 const char* stmt_text = end_range.empty() ?
"SELECT key, value FROM main WHERE key >= ?" :
592 "SELECT key, value FROM main WHERE key >= ? AND key < ?";
593 int res = sqlite3_prepare_v2(
m_database.
m_db, stmt_text, -1, &cursor->m_cursor_stmt,
nullptr);
594 if (res != SQLITE_OK) {
596 "SQLiteDatabase: Failed to setup cursor SQL statement: %s\n", sqlite3_errstr(res)));
599 if (!
BindBlobToStatement(cursor->m_cursor_stmt, 1, cursor->m_prefix_range_start,
"prefix_start"))
return nullptr;
600 if (!end_range.empty()) {
601 if (!
BindBlobToStatement(cursor->m_cursor_stmt, 2, cursor->m_prefix_range_end,
"prefix_end"))
return nullptr;
610 int res = sqlite3_exec(
m_database.
m_db,
"BEGIN TRANSACTION",
nullptr,
nullptr,
nullptr);
611 if (res != SQLITE_OK) {
612 LogPrintf(
"SQLiteBatch: Failed to begin the transaction\n");
614 return res == SQLITE_OK;
620 int res = sqlite3_exec(
m_database.
m_db,
"COMMIT TRANSACTION",
nullptr,
nullptr,
nullptr);
621 if (res != SQLITE_OK) {
622 LogPrintf(
"SQLiteBatch: Failed to commit the transaction\n");
624 return res == SQLITE_OK;
630 int res = sqlite3_exec(
m_database.
m_db,
"ROLLBACK TRANSACTION",
nullptr,
nullptr,
nullptr);
631 if (res != SQLITE_OK) {
632 LogPrintf(
"SQLiteBatch: Failed to abort the transaction\n");
634 return res == SQLITE_OK;
641 auto db = std::make_unique<SQLiteDatabase>(data_file.parent_path(), data_file, options);
648 }
catch (
const std::runtime_error& e) {
657 return std::string(sqlite3_libversion());
bool TryCreateDirectories(const fs::path &p)
Ignores exceptions thrown by create_directories if the requested directory exists.
static path PathFromString(const std::string &string)
Convert byte string to path object.
static bool BindBlobToStatement(sqlite3_stmt *stmt, int index, Span< const std::byte > blob, const std::string &description)
void Cleanup() noexcept EXCLUSIVE_LOCKS_REQUIRED(!g_sqlite_mutex)
static Mutex g_sqlite_mutex
This mutex protects SQLite initialization and shutdown.
std::unique_ptr< SQLiteDatabase > MakeSQLiteDatabase(const fs::path &path, const DatabaseOptions &options, DatabaseStatus &status, bilingual_str &error)
bilingual_str Untranslated(std::string original)
Mark a bilingual_str as untranslated.
bool TxnCommit() override
const std::string m_file_path
void SetupSQLStatements()
constexpr std::size_t size() const noexcept
SQLiteDatabase & m_database
bool HasKey(DataStream &&key) override
std::string SQLiteDatabaseVersion()
static int TraceSqlCallback(unsigned code, void *context, void *param1, void *param2)
sqlite3_stmt * m_overwrite_stmt
void write(Span< const value_type > src)
sqlite3_stmt * m_insert_stmt
std::unique_ptr< DatabaseCursor > GetNewCursor() override
static std::optional< int > ReadPragmaInteger(sqlite3 *db, const std::string &key, const std::string &description, bilingual_str &error)
Filesystem operations and types.
fs::path SQLiteDataFile(const fs::path &path)
bool Verify(bilingual_str &error)
static std::string PathToString(const path &path)
Convert path object to a byte string.
bool Rewrite(const char *skip=nullptr) override
Rewrite the entire database on disk.
Double ended buffer combining vector and stream-like interfaces.
bilingual_str _(const char *psz)
Translation function.
void Open() override
Open the database if it is not already opened.
bool WriteKey(DataStream &&key, DataStream &&value, bool overwrite=true) override
std::unique_ptr< DatabaseCursor > GetNewPrefixCursor(Span< const std::byte > prefix) override
bool EraseKey(DataStream &&key) override
static uint32_t ReadBE32(const unsigned char *ptr)
static constexpr int32_t WALLET_SCHEMA_VERSION
std::unique_ptr< DatabaseBatch > MakeBatch(bool flush_on_close=true) override
Make a SQLiteBatch connected to this database.
SQLiteBatch(SQLiteDatabase &database)
Status Next(DataStream &key, DataStream &value) override
const std::string m_dir_path
std::string Filename() override
Return path to main database file for logs and error messages.
sqlite3_stmt * m_cursor_stmt
bool ReadKey(DataStream &&key, DataStream &value) override
constexpr C * data() const noexcept
bool error(const char *fmt, const Args &... args)
const CChainParams & Params()
Return the currently selected parameters.
bool ExecStatement(sqlite3_stmt *stmt, Span< const std::byte > blob)
static void ErrorLogCallback(void *arg, int code, const char *msg)
bool ErasePrefix(Span< const std::byte > prefix) override
#define AssertLockNotHeld(cs)
An instance of this class represents one SQLite3 database.
static bool LogAcceptCategory(BCLog::LogFlags category, BCLog::Level level)
Return true if log accepts specified category, at the specified level.
sqlite3_stmt * m_delete_stmt
sqlite3_stmt * m_delete_prefix_stmt
static void SetPragma(sqlite3 *db, const std::string &key, const std::string &value, const std::string &err_msg)
Path class wrapper to block calls to the fs::path(std::string) implicit constructor and the fs::path:...
bool verify
Check data integrity on load.
bool Backup(const std::string &dest) const override
Back up the entire database to a file.
An instance of this class represents one database.
sqlite3_stmt * m_read_stmt
static Span< const std::byte > SpanFromBlob(sqlite3_stmt *stmt, int col)
void Close() override
Close the database.