16
16
#include < sqlite3.h>
17
17
#include < stdint.h>
18
18
19
+ #include < optional>
19
20
#include < utility>
20
21
#include < vector>
21
22
@@ -35,6 +36,27 @@ static void ErrorLogCallback(void* arg, int code, const char* msg)
35
36
LogPrintf (" SQLite Error. Code: %d. Message: %s\n " , code, msg);
36
37
}
37
38
39
+ static std::optional<int > ReadPragmaInteger (sqlite3* db, const std::string& key, const std::string& description, bilingual_str& error)
40
+ {
41
+ std::string stmt_text = strprintf (" PRAGMA %s" , key);
42
+ sqlite3_stmt* pragma_read_stmt{nullptr };
43
+ int ret = sqlite3_prepare_v2 (db, stmt_text.c_str (), -1 , &pragma_read_stmt, nullptr );
44
+ if (ret != SQLITE_OK) {
45
+ sqlite3_finalize (pragma_read_stmt);
46
+ error = Untranslated (strprintf (" SQLiteDatabase: Failed to prepare the statement to fetch %s: %s" , description, sqlite3_errstr (ret)));
47
+ return std::nullopt;
48
+ }
49
+ ret = sqlite3_step (pragma_read_stmt);
50
+ if (ret != SQLITE_ROW) {
51
+ sqlite3_finalize (pragma_read_stmt);
52
+ error = Untranslated (strprintf (" SQLiteDatabase: Failed to fetch %s: %s" , description, sqlite3_errstr (ret)));
53
+ return std::nullopt;
54
+ }
55
+ int result = sqlite3_column_int (pragma_read_stmt, 0 );
56
+ sqlite3_finalize (pragma_read_stmt);
57
+ return result;
58
+ }
59
+
38
60
SQLiteDatabase::SQLiteDatabase (const fs::path& dir_path, const fs::path& file_path, bool mock)
39
61
: WalletDatabase(), m_mock(mock), m_dir_path(dir_path.string()), m_file_path(file_path.string())
40
62
{
@@ -114,50 +136,26 @@ bool SQLiteDatabase::Verify(bilingual_str& error)
114
136
assert (m_db);
115
137
116
138
// Check the application ID matches our network magic
117
- sqlite3_stmt* app_id_stmt{nullptr };
118
- int ret = sqlite3_prepare_v2 (m_db, " PRAGMA application_id" , -1 , &app_id_stmt, nullptr );
119
- if (ret != SQLITE_OK) {
120
- sqlite3_finalize (app_id_stmt);
121
- error = strprintf (_ (" SQLiteDatabase: Failed to prepare the statement to fetch the application id: %s" ), sqlite3_errstr (ret));
122
- return false ;
123
- }
124
- ret = sqlite3_step (app_id_stmt);
125
- if (ret != SQLITE_ROW) {
126
- sqlite3_finalize (app_id_stmt);
127
- error = strprintf (_ (" SQLiteDatabase: Failed to fetch the application id: %s" ), sqlite3_errstr (ret));
128
- return false ;
129
- }
130
- uint32_t app_id = static_cast <uint32_t >(sqlite3_column_int (app_id_stmt, 0 ));
131
- sqlite3_finalize (app_id_stmt);
139
+ auto read_result = ReadPragmaInteger (m_db, " application_id" , " the application id" , error);
140
+ if (!read_result.has_value ()) return false ;
141
+ uint32_t app_id = static_cast <uint32_t >(read_result.value ());
132
142
uint32_t net_magic = ReadBE32 (Params ().MessageStart ());
133
143
if (app_id != net_magic) {
134
144
error = strprintf (_ (" SQLiteDatabase: Unexpected application id. Expected %u, got %u" ), net_magic, app_id);
135
145
return false ;
136
146
}
137
147
138
148
// Check our schema version
139
- sqlite3_stmt* user_ver_stmt{nullptr };
140
- ret = sqlite3_prepare_v2 (m_db, " PRAGMA user_version" , -1 , &user_ver_stmt, nullptr );
141
- if (ret != SQLITE_OK) {
142
- sqlite3_finalize (user_ver_stmt);
143
- error = strprintf (_ (" SQLiteDatabase: Failed to prepare the statement to fetch sqlite wallet schema version: %s" ), sqlite3_errstr (ret));
144
- return false ;
145
- }
146
- ret = sqlite3_step (user_ver_stmt);
147
- if (ret != SQLITE_ROW) {
148
- sqlite3_finalize (user_ver_stmt);
149
- error = strprintf (_ (" SQLiteDatabase: Failed to fetch sqlite wallet schema version: %s" ), sqlite3_errstr (ret));
150
- return false ;
151
- }
152
- int32_t user_ver = sqlite3_column_int (user_ver_stmt, 0 );
153
- sqlite3_finalize (user_ver_stmt);
149
+ read_result = ReadPragmaInteger (m_db, " user_version" , " sqlite wallet schema version" , error);
150
+ if (!read_result.has_value ()) return false ;
151
+ int32_t user_ver = read_result.value ();
154
152
if (user_ver != WALLET_SCHEMA_VERSION) {
155
153
error = strprintf (_ (" SQLiteDatabase: Unknown sqlite wallet schema version %d. Only version %d is supported" ), user_ver, WALLET_SCHEMA_VERSION);
156
154
return false ;
157
155
}
158
156
159
157
sqlite3_stmt* stmt{nullptr };
160
- ret = sqlite3_prepare_v2 (m_db, " PRAGMA integrity_check" , -1 , &stmt, nullptr );
158
+ int ret = sqlite3_prepare_v2 (m_db, " PRAGMA integrity_check" , -1 , &stmt, nullptr );
161
159
if (ret != SQLITE_OK) {
162
160
sqlite3_finalize (stmt);
163
161
error = strprintf (_ (" SQLiteDatabase: Failed to prepare statement to verify database: %s" ), sqlite3_errstr (ret));
0 commit comments