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_read_only = false; 22 : bool m_cursor_init = false; 23 : 24 : bool ReadKey(CDataStream&& key, CDataStream& value) override; 25 : bool WriteKey(CDataStream&& key, CDataStream&& value, bool overwrite=true) override; 26 : bool EraseKey(CDataStream&& key) override; 27 : bool HasKey(CDataStream&& key) override; 28 : 29 : public: 30 : explicit SQLiteBatch(SQLiteDatabase& database, const char* mode); 31 39111 : ~SQLiteBatch() override { Close(); } 32 : 33 : void Flush() override; 34 : void Close() override; 35 : 36 : bool StartCursor() override; 37 : bool ReadAtCursor(CDataStream& ssKey, CDataStream& ssValue, bool& complete) override; 38 : void CloseCursor() override; 39 : bool TxnBegin() override; 40 : bool TxnCommit() override; 41 : bool TxnAbort() override; 42 : }; 43 : 44 : /** An instance of this class represents one SQLite3 database. 45 : **/ 46 : class SQLiteDatabase : public WalletDatabase 47 : { 48 : private: 49 : bool m_mock = false; 50 : 51 : const std::string m_dir_path; 52 : 53 : const std::string m_file_path; 54 : 55 : bool PrepareDirectory() const; 56 : 57 : void SetupSQLStatements(); 58 : 59 : public: 60 : SQLiteDatabase() = delete; 61 : 62 : /** Create DB handle to real database */ 63 : SQLiteDatabase(const fs::path& dir_path, const fs::path& file_path, bool mock=false); 64 : 65 : ~SQLiteDatabase(); 66 : 67 : bool Verify(bilingual_str& error); 68 : 69 : /** Open the database if it is not already opened */ 70 : void Open(const char* mode) override; 71 : 72 : /** Close the database */ 73 : void Close() override; 74 : 75 : /** Indicate the a new database user has began using the database. Increments m_refcount */ 76 : void AddRef() override; 77 : /** Indicate that database user has stopped using the database. Decrement m_refcount */ 78 : void RemoveRef() override; 79 : 80 : /** Rewrite the entire database on disk, with the exception of key pszSkip if non-zero 81 : */ 82 : bool Rewrite(const char* skip=nullptr) override; 83 : 84 : /** Back up the entire database to a file. 85 : */ 86 : bool Backup(const std::string& dest) const override; 87 : 88 : /** Make sure all changes are flushed to disk. 89 : */ 90 : void Flush() override; 91 : /* flush the wallet passively (TRY_LOCK) 92 : ideal to be called periodically */ 93 : bool PeriodicFlush() override; 94 : 95 16518 : void IncrementUpdateCounter() override { ++nUpdateCounter; } 96 : 97 : void ReloadDbEnv() override; 98 : 99 78 : std::string Filename() override { return m_file_path; }; 100 : 101 : /** Make a SQLiteBatch connected to this database */ 102 : std::unique_ptr<DatabaseBatch> MakeBatch(const char* mode = "r+", bool flush_on_close = true) override; 103 : 104 : sqlite3* m_db{nullptr}; 105 : 106 : sqlite3_stmt* m_read_stmt = nullptr; 107 : sqlite3_stmt* m_insert_stmt = nullptr; 108 : sqlite3_stmt* m_overwrite_stmt = nullptr; 109 : sqlite3_stmt* m_delete_stmt = nullptr; 110 : sqlite3_stmt* m_cursor_stmt = nullptr; 111 : }; 112 : 113 : bool ExistsSQLiteDatabase(const fs::path& path); 114 : std::unique_ptr<SQLiteDatabase> MakeSQLiteDatabase(const fs::path& path, const DatabaseOptions& options, DatabaseStatus& status, bilingual_str& error); 115 : 116 : std::string SQLiteDatabaseVersion(); 117 : bool IsSQLiteFile(const fs::path& path); 118 : 119 : #endif // BITCOIN_WALLET_SQLITE_H