Line data Source code
1 : // Copyright (c) 2020-2021 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 <sync.h> 9 : #include <wallet/db.h> 10 : 11 : struct bilingual_str; 12 : 13 : struct sqlite3_stmt; 14 : struct sqlite3; 15 : 16 : namespace wallet { 17 : class SQLiteDatabase; 18 : 19 : /** RAII class that provides a database cursor */ 20 : class SQLiteCursor : public DatabaseCursor 21 : { 22 : public: 23 0 : sqlite3_stmt* m_cursor_stmt{nullptr}; 24 : // Copies of the prefix things for the prefix cursor. 25 : // Prevents SQLite from accessing temp variables for the prefix things. 26 : std::vector<std::byte> m_prefix_range_start; 27 : std::vector<std::byte> m_prefix_range_end; 28 : 29 0 : explicit SQLiteCursor() {} 30 0 : explicit SQLiteCursor(std::vector<std::byte> start_range, std::vector<std::byte> end_range) 31 0 : : m_prefix_range_start(std::move(start_range)), 32 0 : m_prefix_range_end(std::move(end_range)) 33 0 : {} 34 : ~SQLiteCursor() override; 35 : 36 : Status Next(DataStream& key, DataStream& value) override; 37 : }; 38 : 39 : /** RAII class that provides access to a WalletDatabase */ 40 : class SQLiteBatch : public DatabaseBatch 41 : { 42 : private: 43 : SQLiteDatabase& m_database; 44 : 45 : sqlite3_stmt* m_read_stmt{nullptr}; 46 : sqlite3_stmt* m_insert_stmt{nullptr}; 47 : sqlite3_stmt* m_overwrite_stmt{nullptr}; 48 : sqlite3_stmt* m_delete_stmt{nullptr}; 49 : sqlite3_stmt* m_delete_prefix_stmt{nullptr}; 50 : 51 : void SetupSQLStatements(); 52 : bool ExecStatement(sqlite3_stmt* stmt, Span<const std::byte> blob); 53 : 54 : bool ReadKey(DataStream&& key, DataStream& value) override; 55 : bool WriteKey(DataStream&& key, DataStream&& value, bool overwrite = true) override; 56 : bool EraseKey(DataStream&& key) override; 57 : bool HasKey(DataStream&& key) override; 58 : bool ErasePrefix(Span<const std::byte> prefix) override; 59 : 60 : public: 61 : explicit SQLiteBatch(SQLiteDatabase& database); 62 0 : ~SQLiteBatch() override { Close(); } 63 : 64 : /* No-op. See comment on SQLiteDatabase::Flush */ 65 0 : void Flush() override {} 66 : 67 : void Close() override; 68 : 69 : std::unique_ptr<DatabaseCursor> GetNewCursor() override; 70 : std::unique_ptr<DatabaseCursor> GetNewPrefixCursor(Span<const std::byte> prefix) override; 71 : bool TxnBegin() override; 72 : bool TxnCommit() override; 73 : bool TxnAbort() override; 74 : }; 75 : 76 : /** An instance of this class represents one SQLite3 database. 77 : **/ 78 : class SQLiteDatabase : public WalletDatabase 79 : { 80 : private: 81 : const bool m_mock{false}; 82 : 83 : const std::string m_dir_path; 84 : 85 : const std::string m_file_path; 86 : 87 : /** 88 : * This mutex protects SQLite initialization and shutdown. 89 : * sqlite3_config() and sqlite3_shutdown() are not thread-safe (sqlite3_initialize() is). 90 : * Concurrent threads that execute SQLiteDatabase::SQLiteDatabase() should have just one 91 : * of them do the init and the rest wait for it to complete before all can proceed. 92 : */ 93 : static Mutex g_sqlite_mutex; 94 : static int g_sqlite_count GUARDED_BY(g_sqlite_mutex); 95 : 96 : void Cleanup() noexcept EXCLUSIVE_LOCKS_REQUIRED(!g_sqlite_mutex); 97 : 98 : public: 99 : SQLiteDatabase() = delete; 100 : 101 : /** Create DB handle to real database */ 102 : SQLiteDatabase(const fs::path& dir_path, const fs::path& file_path, const DatabaseOptions& options, bool mock = false); 103 : 104 : ~SQLiteDatabase(); 105 : 106 : bool Verify(bilingual_str& error); 107 : 108 : /** Open the database if it is not already opened */ 109 : void Open() override; 110 : 111 : /** Close the database */ 112 : void Close() override; 113 : 114 : /* These functions are unused */ 115 0 : void AddRef() override { assert(false); } 116 0 : void RemoveRef() override { assert(false); } 117 : 118 : /** Rewrite the entire database on disk */ 119 : bool Rewrite(const char* skip = nullptr) override; 120 : 121 : /** Back up the entire database to a file. 122 : */ 123 : bool Backup(const std::string& dest) const override; 124 : 125 : /** No-ops 126 : * 127 : * SQLite always flushes everything to the database file after each transaction 128 : * (each Read/Write/Erase that we do is its own transaction unless we called 129 : * TxnBegin) so there is no need to have Flush or Periodic Flush. 130 : * 131 : * There is no DB env to reload, so ReloadDbEnv has nothing to do 132 : */ 133 0 : void Flush() override {} 134 0 : bool PeriodicFlush() override { return false; } 135 0 : void ReloadDbEnv() override {} 136 : 137 0 : void IncrementUpdateCounter() override { ++nUpdateCounter; } 138 : 139 0 : std::string Filename() override { return m_file_path; } 140 0 : std::string Format() override { return "sqlite"; } 141 : 142 : /** Make a SQLiteBatch connected to this database */ 143 : std::unique_ptr<DatabaseBatch> MakeBatch(bool flush_on_close = true) override; 144 : 145 : sqlite3* m_db{nullptr}; 146 : bool m_use_unsafe_sync; 147 : }; 148 : 149 : std::unique_ptr<SQLiteDatabase> MakeSQLiteDatabase(const fs::path& path, const DatabaseOptions& options, DatabaseStatus& status, bilingual_str& error); 150 : 151 : std::string SQLiteDatabaseVersion(); 152 : } // namespace wallet 153 : 154 : #endif // BITCOIN_WALLET_SQLITE_H