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); ~SQLiteBatch()38 ~SQLiteBatch() override { Close(); } 39 40 /* No-op. See comment on SQLiteDatabase::Flush */ Flush()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 */ AddRef()83 void AddRef() override { assert(false); } RemoveRef()84 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 */ Flush()101 void Flush() override {} PeriodicFlush()102 bool PeriodicFlush() override { return false; } ReloadDbEnv()103 void ReloadDbEnv() override {} 104 IncrementUpdateCounter()105 void IncrementUpdateCounter() override { ++nUpdateCounter; } 106 Filename()107 std::string Filename() override { return m_file_path; } Format()108 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 121