diff --git a/src/wallet/CMakeLists.txt b/src/wallet/CMakeLists.txt --- a/src/wallet/CMakeLists.txt +++ b/src/wallet/CMakeLists.txt @@ -27,6 +27,7 @@ rpcwallet.cpp salvage.cpp scriptpubkeyman.cpp + sqlite.cpp wallet.cpp walletdb.cpp walletutil.cpp diff --git a/src/wallet/sqlite.h b/src/wallet/sqlite.h new file mode 100644 --- /dev/null +++ b/src/wallet/sqlite.h @@ -0,0 +1,104 @@ +// Copyright (c) 2020 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#ifndef BITCOIN_WALLET_SQLITE_H +#define BITCOIN_WALLET_SQLITE_H + +#include + +struct bilingual_str; +class SQLiteDatabase; + +/** RAII class that provides access to a WalletDatabase */ +class SQLiteBatch : public DatabaseBatch { +private: + SQLiteDatabase &m_database; + + bool ReadKey(CDataStream &&key, CDataStream &value) override; + bool WriteKey(CDataStream &&key, CDataStream &&value, + bool overwrite = true) override; + bool EraseKey(CDataStream &&key) override; + bool HasKey(CDataStream &&key) override; + +public: + explicit SQLiteBatch(SQLiteDatabase &database); + + /** No-op. See comment on SQLiteDatabase::Flush */ + void Flush() override {} + + void Close() override; + + bool StartCursor() override; + bool ReadAtCursor(CDataStream &key, CDataStream &value, + bool &complete) override; + void CloseCursor() override; + bool TxnBegin() override; + bool TxnCommit() override; + bool TxnAbort() override; +}; + +/** An instance of this class represents one SQLite3 database. */ +class SQLiteDatabase : public WalletDatabase { +private: + // FIXME: uncomment this line when m_mock is used in commit a0de833 + // const bool m_mock{false}; + + const std::string m_dir_path; + + const std::string m_file_path; + +public: + SQLiteDatabase() = delete; + + /** Create DB handle to real database */ + SQLiteDatabase(const fs::path &dir_path, const fs::path &file_path, + bool mock = false); + + ~SQLiteDatabase(); + + /** Open the database if it is not already opened */ + void Open() override; + + /** Close the database */ + void Close() override; + + /* These functions are unused */ + void AddRef() override { assert(false); } + void RemoveRef() override { assert(false); } + + /** Rewrite the entire database on disk */ + bool Rewrite(const char *skip = nullptr) override; + + /** Back up the entire database to a file. */ + bool Backup(const std::string &dest) const override; + + /** + * No-ops + * + * SQLite always flushes everything to the database file after each + * transaction (each Read/Write/Erase that we do is its own transaction + * unless we called TxnBegin) so there is no need to have Flush or Periodic + * Flush. + * + * There is no DB env to reload, so ReloadDbEnv has nothing to do + */ + void Flush() override {} + bool PeriodicFlush() override { return false; } + void ReloadDbEnv() override {} + + void IncrementUpdateCounter() override { ++nUpdateCounter; } + + std::string Filename() override { return m_file_path; } + + /** Make a SQLiteBatch connected to this database */ + std::unique_ptr + MakeBatch(bool flush_on_close = true) override; +}; + +bool ExistsSQLiteDatabase(const fs::path &path); +std::unique_ptr +MakeSQLiteDatabase(const fs::path &path, const DatabaseOptions &options, + DatabaseStatus &status, bilingual_str &error); + +#endif // BITCOIN_WALLET_SQLITE_H diff --git a/src/wallet/sqlite.cpp b/src/wallet/sqlite.cpp new file mode 100644 --- /dev/null +++ b/src/wallet/sqlite.cpp @@ -0,0 +1,89 @@ +// Copyright (c) 2020 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#include + +#include +#include +#include + +#include + +static const char *const DATABASE_FILENAME = "wallet.dat"; + +SQLiteDatabase::SQLiteDatabase(const fs::path &dir_path, + const fs::path &file_path, bool mock) + // FIXME: uncomment m_mock when backporting commit a0de833 + : WalletDatabase(), /* m_mock(mock), */ m_dir_path(dir_path.string()), + m_file_path(file_path.string()) {} + +SQLiteDatabase::~SQLiteDatabase() {} + +void SQLiteDatabase::Open() {} + +bool SQLiteDatabase::Rewrite(const char *skip) { + return false; +} + +bool SQLiteDatabase::Backup(const std::string &dest) const { + return false; +} + +void SQLiteDatabase::Close() {} + +std::unique_ptr SQLiteDatabase::MakeBatch(bool flush_on_close) { + return nullptr; +} + +void SQLiteBatch::Close() {} + +bool SQLiteBatch::ReadKey(CDataStream &&key, CDataStream &value) { + return false; +} + +bool SQLiteBatch::WriteKey(CDataStream &&key, CDataStream &&value, + bool overwrite) { + return false; +} + +bool SQLiteBatch::EraseKey(CDataStream &&key) { + return false; +} + +bool SQLiteBatch::HasKey(CDataStream &&key) { + return false; +} + +bool SQLiteBatch::StartCursor() { + return false; +} + +bool SQLiteBatch::ReadAtCursor(CDataStream &key, CDataStream &value, + bool &complete) { + return false; +} + +void SQLiteBatch::CloseCursor() {} + +bool SQLiteBatch::TxnBegin() { + return false; +} + +bool SQLiteBatch::TxnCommit() { + return false; +} + +bool SQLiteBatch::TxnAbort() { + return false; +} + +bool ExistsSQLiteDatabase(const fs::path &path) { + return false; +} + +std::unique_ptr +MakeSQLiteDatabase(const fs::path &path, const DatabaseOptions &options, + DatabaseStatus &status, bilingual_str &error) { + return std::make_unique(path, path / DATABASE_FILENAME); +}