diff --git a/src/Makefile.am b/src/Makefile.am index 398d904fe61..e359ae2cb2d 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -257,6 +257,7 @@ BITCOIN_CORE_H = \ wallet/rpcwallet.h \ wallet/salvage.h \ wallet/scriptpubkeyman.h \ + wallet/sqlite.h \ wallet/wallet.h \ wallet/walletdb.h \ wallet/wallettool.h \ @@ -370,6 +371,7 @@ libbitcoin_wallet_a_SOURCES = \ wallet/rpcwallet.cpp \ wallet/salvage.cpp \ wallet/scriptpubkeyman.cpp \ + wallet/sqlite.cpp \ wallet/wallet.cpp \ wallet/walletdb.cpp \ wallet/walletutil.cpp \ diff --git a/src/wallet/sqlite.cpp b/src/wallet/sqlite.cpp new file mode 100644 index 00000000000..0ea13177955 --- /dev/null +++ b/src/wallet/sqlite.cpp @@ -0,0 +1,109 @@ +// 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 + +#include + +static const char* const DATABASE_FILENAME = "wallet.dat"; + +SQLiteDatabase::SQLiteDatabase(const fs::path& dir_path, const fs::path& file_path, bool mock) + : 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 MakeUnique(path, path / DATABASE_FILENAME); +} diff --git a/src/wallet/sqlite.h b/src/wallet/sqlite.h new file mode 100644 index 00000000000..0c9ab32fc82 --- /dev/null +++ b/src/wallet/sqlite.h @@ -0,0 +1,99 @@ +// 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 commeng 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: + 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