MCPcopy Create free account
hub / github.com/ElementsProject/elements / Open

Method Open

src/wallet/sqlite.cpp:201–284  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

199}
200
201void SQLiteDatabase::Open()
202{
203 int flags = SQLITE_OPEN_FULLMUTEX | SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE;
204 if (m_mock) {
205 flags |= SQLITE_OPEN_MEMORY; // In memory database for mock db
206 }
207
208 if (m_db == nullptr) {
209 if (!m_mock) {
210 TryCreateDirectories(fs::PathFromString(m_dir_path));
211 }
212 int ret = sqlite3_open_v2(m_file_path.c_str(), &m_db, flags, nullptr);
213 if (ret != SQLITE_OK) {
214 throw std::runtime_error(strprintf("SQLiteDatabase: Failed to open database: %s\n", sqlite3_errstr(ret)));
215 }
216 ret = sqlite3_extended_result_codes(m_db, 1);
217 if (ret != SQLITE_OK) {
218 throw std::runtime_error(strprintf("SQLiteDatabase: Failed to enable extended result codes: %s\n", sqlite3_errstr(ret)));
219 }
220 }
221
222 if (sqlite3_db_readonly(m_db, "main") != 0) {
223 throw std::runtime_error("SQLiteDatabase: Database opened in readonly mode but read-write permissions are needed");
224 }
225
226 // Acquire an exclusive lock on the database
227 // First change the locking mode to exclusive
228 SetPragma(m_db, "locking_mode", "exclusive", "Unable to change database locking mode to exclusive");
229 // Now begin a transaction to acquire the exclusive lock. This lock won't be released until we close because of the exclusive locking mode.
230 int ret = sqlite3_exec(m_db, "BEGIN EXCLUSIVE TRANSACTION", nullptr, nullptr, nullptr);
231 if (ret != SQLITE_OK) {
232 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");
233 }
234 ret = sqlite3_exec(m_db, "COMMIT", nullptr, nullptr, nullptr);
235 if (ret != SQLITE_OK) {
236 throw std::runtime_error(strprintf("SQLiteDatabase: Unable to end exclusive lock transaction: %s\n", sqlite3_errstr(ret)));
237 }
238
239 // Enable fullfsync for the platforms that use it
240 SetPragma(m_db, "fullfsync", "true", "Failed to enable fullfsync");
241
242 if (gArgs.GetBoolArg("-unsafesqlitesync", false)) {
243 // Use normal synchronous mode for the journal
244 LogPrintf("WARNING SQLite is configured to not wait for data to be flushed to disk. Data loss and corruption may occur.\n");
245 SetPragma(m_db, "synchronous", "OFF", "Failed to set synchronous mode to OFF");
246 }
247
248 // Make the table for our key-value pairs
249 // First check that the main table exists
250 sqlite3_stmt* check_main_stmt{nullptr};
251 ret = sqlite3_prepare_v2(m_db, "SELECT name FROM sqlite_master WHERE type='table' AND name='main'", -1, &check_main_stmt, nullptr);
252 if (ret != SQLITE_OK) {
253 throw std::runtime_error(strprintf("SQLiteDatabase: Failed to prepare statement to check table existence: %s\n", sqlite3_errstr(ret)));
254 }
255 ret = sqlite3_step(check_main_stmt);
256 if (sqlite3_finalize(check_main_stmt) != SQLITE_OK) {
257 throw std::runtime_error(strprintf("SQLiteDatabase: Failed to finalize statement checking table existence: %s\n", sqlite3_errstr(ret)));
258 }

Callers

nothing calls this directly

Calls 6

TryCreateDirectoriesFunction · 0.85
PathFromStringFunction · 0.85
SetPragmaFunction · 0.85
GetBoolArgMethod · 0.80
ReadBE32Function · 0.50
ParamsClass · 0.50

Tested by

no test coverage detected