Changeset View
Changeset View
Standalone View
Standalone View
src/wallet/sqlite.cpp
Show First 20 Lines • Show All 597 Lines • ▼ Show 20 Lines | int res = sqlite3_exec(m_database.m_db, "ROLLBACK TRANSACTION", nullptr, | ||||
nullptr, nullptr); | nullptr, nullptr); | ||||
if (res != SQLITE_OK) { | if (res != SQLITE_OK) { | ||||
LogPrintf("SQLiteBatch: Failed to abort the transaction\n"); | LogPrintf("SQLiteBatch: Failed to abort the transaction\n"); | ||||
} | } | ||||
return res == SQLITE_OK; | return res == SQLITE_OK; | ||||
} | } | ||||
bool ExistsSQLiteDatabase(const fs::path &path) { | bool ExistsSQLiteDatabase(const fs::path &path) { | ||||
return false; | const fs::path file = path / DATABASE_FILENAME; | ||||
return fs::symlink_status(file).type() == fs::regular_file && | |||||
IsSQLiteFile(file); | |||||
} | } | ||||
std::unique_ptr<SQLiteDatabase> | std::unique_ptr<SQLiteDatabase> | ||||
MakeSQLiteDatabase(const fs::path &path, const DatabaseOptions &options, | MakeSQLiteDatabase(const fs::path &path, const DatabaseOptions &options, | ||||
DatabaseStatus &status, bilingual_str &error) { | DatabaseStatus &status, bilingual_str &error) { | ||||
const fs::path file = path / DATABASE_FILENAME; | const fs::path file = path / DATABASE_FILENAME; | ||||
try { | try { | ||||
auto db = std::make_unique<SQLiteDatabase>(path, file); | auto db = std::make_unique<SQLiteDatabase>(path, file); | ||||
if (options.verify && !db->Verify(error)) { | if (options.verify && !db->Verify(error)) { | ||||
status = DatabaseStatus::FAILED_VERIFY; | status = DatabaseStatus::FAILED_VERIFY; | ||||
return nullptr; | return nullptr; | ||||
} | } | ||||
return db; | return db; | ||||
} catch (const std::runtime_error &e) { | } catch (const std::runtime_error &e) { | ||||
status = DatabaseStatus::FAILED_LOAD; | status = DatabaseStatus::FAILED_LOAD; | ||||
error.original = e.what(); | error.original = e.what(); | ||||
return nullptr; | return nullptr; | ||||
} | } | ||||
} | } | ||||
std::string SQLiteDatabaseVersion() { | std::string SQLiteDatabaseVersion() { | ||||
return std::string(sqlite3_libversion()); | return std::string(sqlite3_libversion()); | ||||
} | } | ||||
bool IsSQLiteFile(const fs::path &path) { | |||||
if (!fs::exists(path)) { | |||||
return false; | |||||
} | |||||
// A SQLite Database file is at least 512 bytes. | |||||
boost::system::error_code ec; | |||||
auto size = fs::file_size(path, ec); | |||||
if (ec) { | |||||
LogPrintf("%s: %s %s\n", __func__, ec.message(), path.string()); | |||||
} | |||||
if (size < 512) { | |||||
return false; | |||||
} | |||||
fsbridge::ifstream file(path, std::ios::binary); | |||||
if (!file.is_open()) { | |||||
return false; | |||||
} | |||||
// Magic is at beginning and is 16 bytes long | |||||
char magic[16]; | |||||
file.read(magic, 16); | |||||
file.close(); | |||||
// Check the magic, see https://sqlite.org/fileformat2.html | |||||
std::string magic_str(magic, 16); | |||||
return magic_str == std::string("SQLite format 3", 16); | |||||
} |