Branch data Line data Source code
# 1 : : // Copyright (c) 2020 The Bitcoin Core developers # 2 : : // Distributed under the MIT software license, see the accompanying # 3 : : // file COPYING or http://www.opensource.org/licenses/mit-license.php. # 4 : : # 5 : : #ifndef BITCOIN_WALLET_SQLITE_H # 6 : : #define BITCOIN_WALLET_SQLITE_H # 7 : : # 8 : : #include <wallet/db.h> # 9 : : # 10 : : #include <sqlite3.h> # 11 : : # 12 : : struct bilingual_str; # 13 : : class SQLiteDatabase; # 14 : : # 15 : : /** RAII class that provides access to a WalletDatabase */ # 16 : : class SQLiteBatch : public DatabaseBatch # 17 : : { # 18 : : private: # 19 : : SQLiteDatabase& m_database; # 20 : : # 21 : : bool m_cursor_init = false; # 22 : : # 23 : : sqlite3_stmt* m_read_stmt{nullptr}; # 24 : : sqlite3_stmt* m_insert_stmt{nullptr}; # 25 : : sqlite3_stmt* m_overwrite_stmt{nullptr}; # 26 : : sqlite3_stmt* m_delete_stmt{nullptr}; # 27 : : sqlite3_stmt* m_cursor_stmt{nullptr}; # 28 : : # 29 : : void SetupSQLStatements(); # 30 : : # 31 : : bool ReadKey(CDataStream&& key, CDataStream& value) override; # 32 : : bool WriteKey(CDataStream&& key, CDataStream&& value, bool overwrite = true) override; # 33 : : bool EraseKey(CDataStream&& key) override; # 34 : : bool HasKey(CDataStream&& key) override; # 35 : : # 36 : : public: # 37 : : explicit SQLiteBatch(SQLiteDatabase& database); # 38 : 61390 : ~SQLiteBatch() override { Close(); } # 39 : : # 40 : : /* No-op. See comment on SQLiteDatabase::Flush */ # 41 : 41 : void Flush() override {} # 42 : : # 43 : : void Close() override; # 44 : : # 45 : : bool StartCursor() override; # 46 : : bool ReadAtCursor(CDataStream& key, CDataStream& value, bool& complete) override; # 47 : : void CloseCursor() override; # 48 : : bool TxnBegin() override; # 49 : : bool TxnCommit() override; # 50 : : bool TxnAbort() override; # 51 : : }; # 52 : : # 53 : : /** An instance of this class represents one SQLite3 database. # 54 : : **/ # 55 : : class SQLiteDatabase : public WalletDatabase # 56 : : { # 57 : : private: # 58 : : const bool m_mock{false}; # 59 : : # 60 : : const std::string m_dir_path; # 61 : : # 62 : : const std::string m_file_path; # 63 : : # 64 : : void Cleanup() noexcept; # 65 : : # 66 : : public: # 67 : : SQLiteDatabase() = delete; # 68 : : # 69 : : /** Create DB handle to real database */ # 70 : : SQLiteDatabase(const fs::path& dir_path, const fs::path& file_path, bool mock = false); # 71 : : # 72 : : ~SQLiteDatabase(); # 73 : : # 74 : : bool Verify(bilingual_str& error); # 75 : : # 76 : : /** Open the database if it is not already opened */ # 77 : : void Open() override; # 78 : : # 79 : : /** Close the database */ # 80 : : void Close() override; # 81 : : # 82 : : /* These functions are unused */ # 83 : 0 : void AddRef() override { assert(false); } # 84 : 0 : void RemoveRef() override { assert(false); } # 85 : : # 86 : : /** Rewrite the entire database on disk */ # 87 : : bool Rewrite(const char* skip = nullptr) override; # 88 : : # 89 : : /** Back up the entire database to a file. # 90 : : */ # 91 : : bool Backup(const std::string& dest) const override; # 92 : : # 93 : : /** No-ops # 94 : : * # 95 : : * SQLite always flushes everything to the database file after each transaction # 96 : : * (each Read/Write/Erase that we do is its own transaction unless we called # 97 : : * TxnBegin) so there is no need to have Flush or Periodic Flush. # 98 : : * # 99 : : * There is no DB env to reload, so ReloadDbEnv has nothing to do # 100 : : */ # 101 : 454 : void Flush() override {} # 102 : 2341 : bool PeriodicFlush() override { return false; } # 103 : 11 : void ReloadDbEnv() override {} # 104 : : # 105 : 74834 : void IncrementUpdateCounter() override { ++nUpdateCounter; } # 106 : : # 107 : 256 : std::string Filename() override { return m_file_path; } # 108 : 327 : std::string Format() override { return "sqlite"; } # 109 : : # 110 : : /** Make a SQLiteBatch connected to this database */ # 111 : : std::unique_ptr<DatabaseBatch> MakeBatch(bool flush_on_close = true) override; # 112 : : # 113 : : sqlite3* m_db{nullptr}; # 114 : : }; # 115 : : # 116 : : std::unique_ptr<SQLiteDatabase> MakeSQLiteDatabase(const fs::path& path, const DatabaseOptions& options, DatabaseStatus& status, bilingual_str& error); # 117 : : # 118 : : std::string SQLiteDatabaseVersion(); # 119 : : # 120 : : #endif // BITCOIN_WALLET_SQLITE_H