forked from cheng/wallet
removed a the redundantly explicit std::uniques
from display_wallet.h and display_wallet.cpp They are now all wrapped in the long promised and long forgotten wrapper class. Long, long ago, I intended to implement the Pimpl idiom, but these days std::unique takes care of all that work for you. You just wrap your low level pimple class in a high level wrapper whose base class is an std_unique_ptr to to an instance of your low level class.
This commit is contained in:
parent
f819b98d9e
commit
ffa392b922
@ -150,6 +150,7 @@
|
|||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClCompile Include="../src/app.cpp" />
|
<ClCompile Include="../src/app.cpp" />
|
||||||
<ClCompile Include="../src/display_wallet.cpp" />
|
<ClCompile Include="../src/display_wallet.cpp" />
|
||||||
|
<ClCompile Include="../src/db_accessors.cpp" />
|
||||||
<ClCompile Include="../src/frame.cpp" />
|
<ClCompile Include="../src/frame.cpp" />
|
||||||
<ClCompile Include="../src/ILog.cpp" />
|
<ClCompile Include="../src/ILog.cpp" />
|
||||||
<ClCompile Include="../src/ISqlit3Impl.cpp">
|
<ClCompile Include="../src/ISqlit3Impl.cpp">
|
||||||
|
@ -1,13 +1,8 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "ILog.h"
|
#include "ILog.h"
|
||||||
// this is pure virtual interface base class between sqlite3, which speaks only C and utf8 char[]
|
// this is an interface base class between sqlite3, which speaks only C and utf8 char[]
|
||||||
// and wxWidgets which speaks only C++ and unicode strings.
|
// and wxWidgets which speaks only C++ and unicode strings.
|
||||||
|
|
||||||
// Usage: Call the factory function std::shared_ptr<ISqlite3> sqlite3_open(const char *) to get a shared
|
|
||||||
// pointer to the // Sqlite3 database object. Then call the factory function
|
|
||||||
// sqlite3_prepare(std::shared_ptr<ISqlite3>, const char *) to get a unique pointer to
|
|
||||||
// a compiled SQL statement
|
|
||||||
|
|
||||||
// Its primary purpose is to avoid code that needs both the wxWidgets header files,
|
// Its primary purpose is to avoid code that needs both the wxWidgets header files,
|
||||||
// and the sqlite3.h header file.
|
// and the sqlite3.h header file.
|
||||||
//
|
//
|
||||||
@ -25,8 +20,6 @@
|
|||||||
// substantially more difficult in C++14, because one is effectively rolling one's own
|
// substantially more difficult in C++14, because one is effectively rolling one's own
|
||||||
// unique pointer.
|
// unique pointer.
|
||||||
//
|
//
|
||||||
// It is therefore easier to implement a pure virtual base class with a virtual destructor and
|
|
||||||
// factory function that returns a smart pointer to a member of the derived implementation
|
|
||||||
//
|
//
|
||||||
/* This code is at a low level abstraction, because it provides low level C++ interface to inherently low level C
|
/* This code is at a low level abstraction, because it provides low level C++ interface to inherently low level C
|
||||||
It is intended to be wrapped in higher level code that does not know about the nuts and bolts of sqlite3, but which supports throwing, templated functions, and all that.*/
|
It is intended to be wrapped in higher level code that does not know about the nuts and bolts of sqlite3, but which supports throwing, templated functions, and all that.*/
|
||||||
|
45
src/db_accessors.cpp
Normal file
45
src/db_accessors.cpp
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
#include "stdafx.h"
|
||||||
|
namespace ro {
|
||||||
|
static constexpr char SrcFilename[]{ "src/db_accessors.cpp" };
|
||||||
|
|
||||||
|
dbconnect::dbconnect(const wxFileName& filename) {
|
||||||
|
if (!filename.IsOk() || !filename.HasName() || !filename.HasExt()) throw
|
||||||
|
MyException("unexpected file name", __LINE__, __func__, SrcFilename);
|
||||||
|
if (!filename.FileExists())throw MyException(
|
||||||
|
std::string(filename.GetFullPath().ToUTF8()) + " does not exist.",
|
||||||
|
__LINE__, __func__, SrcFilename);
|
||||||
|
this->reset(Sqlite3_open(filename.GetFullPath().ToUTF8()));
|
||||||
|
}
|
||||||
|
|
||||||
|
// move constructor
|
||||||
|
dbconnect::dbconnect(dbconnect&& p) noexcept :std::unique_ptr<ISqlite3>(p.release()) {
|
||||||
|
}
|
||||||
|
|
||||||
|
// Move assignment
|
||||||
|
dbconnect& dbconnect::operator=(dbconnect&& p) noexcept {
|
||||||
|
std::unique_ptr<ISqlite3>::reset(p.release());
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
sql::sql(const std::unique_ptr<ISqlite3>& p, const char* sz) :
|
||||||
|
std::unique_ptr<Icompiled_sql>(sqlite3_prepare(p.get(), sz)) {
|
||||||
|
}
|
||||||
|
|
||||||
|
// move constructor
|
||||||
|
sql::sql(sql&& p) noexcept :std::unique_ptr<Icompiled_sql>(p.release()) {
|
||||||
|
}
|
||||||
|
|
||||||
|
// Move assignment
|
||||||
|
sql& sql::operator=(sql&& p) noexcept {
|
||||||
|
std::unique_ptr<Icompiled_sql>::reset(p.release());
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
sql::sql(Icompiled_sql* p) :
|
||||||
|
std::unique_ptr<Icompiled_sql>(p) {
|
||||||
|
}
|
||||||
|
|
||||||
|
sql::sql(std::unique_ptr<Icompiled_sql>&& p) :
|
||||||
|
std::unique_ptr<Icompiled_sql>(p.release()) {
|
||||||
|
}
|
||||||
|
}
|
@ -15,26 +15,43 @@ namespace ro {
|
|||||||
|
|
||||||
static_assert(is_sqlite3_field_type<int>::value);
|
static_assert(is_sqlite3_field_type<int>::value);
|
||||||
|
|
||||||
|
//Owns a database connection and closes it when it is deconstructed
|
||||||
|
//Has move semantics
|
||||||
|
class dbconnect : public std::unique_ptr<ISqlite3> {
|
||||||
|
public:
|
||||||
|
dbconnect(const wxFileName&); //And here we wrap our Cish implementation in C++ish implementation
|
||||||
|
dbconnect() = delete;
|
||||||
|
~dbconnect() = default; //Our base class takes care of it
|
||||||
|
// copy constructor
|
||||||
|
dbconnect(const dbconnect& a) = delete; //Move semantics
|
||||||
|
// move constructor
|
||||||
|
dbconnect(dbconnect&& p) noexcept;
|
||||||
|
// copy assignment
|
||||||
|
dbconnect& operator=(const dbconnect) = delete; //Move semantics
|
||||||
|
// Move assignment
|
||||||
|
dbconnect& operator=(dbconnect&& p) noexcept;
|
||||||
|
};
|
||||||
|
|
||||||
//Owns a compiled sql statement and destroys it when it is deconstructed.
|
//Owns a compiled sql statement and destroys it when it is deconstructed.
|
||||||
//Has move semantics.
|
//Has move semantics.
|
||||||
class sql : public std::unique_ptr<Icompiled_sql> {
|
class sql : public std::unique_ptr<Icompiled_sql> {
|
||||||
public:
|
public:
|
||||||
class monostate {};
|
class monostate {};
|
||||||
|
sql() = delete;
|
||||||
sql(ISqlite3* p, const char* sz) :std::unique_ptr<Icompiled_sql>(sqlite3_prepare(p, sz)) {}
|
sql(ISqlite3* p, const char* sz) :std::unique_ptr<Icompiled_sql>(sqlite3_prepare(p, sz)) {}
|
||||||
sql(const std::unique_ptr<ISqlite3>& p, const char* sz) :std::unique_ptr<Icompiled_sql>(sqlite3_prepare(p.get(), sz)) {}
|
sql(const std::unique_ptr<ISqlite3>& p, const char* sz);
|
||||||
// copy constructor
|
// copy constructor
|
||||||
sql(const sql& a) = delete;
|
sql(const sql& a) = delete;
|
||||||
// move constructor
|
// move constructor
|
||||||
sql(sql&& p) noexcept :std::unique_ptr<Icompiled_sql>(p.release()) { }
|
sql(sql&& p) noexcept;
|
||||||
// copy assignment
|
// copy assignment
|
||||||
sql& operator=(const sql) = delete;
|
sql& operator=(const sql) = delete;
|
||||||
// Move assignment
|
// Move assignment
|
||||||
sql& operator=(sql&& p) noexcept {
|
sql& operator=(sql&& p) noexcept;
|
||||||
std::unique_ptr<Icompiled_sql>::reset(p.release());
|
sql(Icompiled_sql* p);
|
||||||
}
|
sql(std::unique_ptr<Icompiled_sql>&& p);
|
||||||
sql(Icompiled_sql* p) :std::unique_ptr<Icompiled_sql>(p) {}
|
|
||||||
sql(std::unique_ptr<Icompiled_sql>&& p) :std::unique_ptr<Icompiled_sql>(p.release()) { }
|
|
||||||
~sql() = default;
|
~sql() = default;
|
||||||
|
|
||||||
template <typename T>auto column(int i) const {
|
template <typename T>auto column(int i) const {
|
||||||
if constexpr (ro::blob_type<T>) {
|
if constexpr (ro::blob_type<T>) {
|
||||||
auto st = (*this)->Isqlite3_column_blob(i);
|
auto st = (*this)->Isqlite3_column_blob(i);
|
||||||
|
@ -1,23 +1,19 @@
|
|||||||
#include "stdafx.h"
|
#include "stdafx.h"
|
||||||
using ro::base58;
|
using ro::base58;
|
||||||
static constexpr char SrcFilename[]{ "src/display_wallet.cpp" };
|
static constexpr char SrcFilename[]{ "src/display_wallet.cpp" };
|
||||||
|
|
||||||
display_wallet::display_wallet(wxWindow* parent, wxFileName& walletfile) :
|
display_wallet::display_wallet(wxWindow* parent, wxFileName& walletfile) :
|
||||||
wxPanel(parent, myID_WALLET_UI, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL, wxT("Wallet")),
|
wxPanel(parent, myID_WALLET_UI, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL, wxT("Wallet")),
|
||||||
m_db(nullptr), m_DisplayWalletEditMenu(1)
|
m_db(walletfile), m_DisplayWalletEditMenu(1),
|
||||||
|
m_read_names_and_keys(m_db, R"|(SELECT * FROM "UserZookoIDs"; )|"),
|
||||||
|
m_read_from_misc(m_db),
|
||||||
|
m_find_position(m_db, R"|( SELECT COUNT(*) FROM UserZookoIDs WHERE LOWER("name")<LOWER(?1) AND "name"<?1;)|")
|
||||||
{
|
{
|
||||||
wxLogMessage(wxT("Loading %s"), walletfile.GetFullPath());
|
wxLogMessage(wxT("Loading %s"), walletfile.GetFullPath());
|
||||||
try {
|
try {
|
||||||
if (!walletfile.IsOk() || !walletfile.HasName() || !walletfile.HasExt()) throw MyException("unexpected file name", __LINE__, __func__, SrcFilename);
|
if (!m_read_from_misc(1) || m_read_from_misc.value<int64_t>() != WALLET_FILE_IDENTIFIER)throw MyException(sz_unrecognizable_wallet_file_format);
|
||||||
if (!walletfile.FileExists())throw MyException(
|
if (!m_read_from_misc(2) || m_read_from_misc.value<int64_t>() != WALLET_FILE_SCHEMA_VERSION_0_0 || !m_read_from_misc(4))throw MyException(sz_unrecognized_wallet_schema);
|
||||||
walletfile.GetFullPath().append(" does not exist.").ToUTF8(),
|
m_MasterSecret= *(m_read_from_misc.value<ristretto255::scalar>());
|
||||||
__LINE__, __func__, SrcFilename);
|
|
||||||
m_db.reset(Sqlite3_open(walletfile.GetFullPath().ToUTF8()));
|
|
||||||
m_insert_name.reset(new sql_insert_name(m_db));
|
|
||||||
m_read_from_misc.reset(new sql_read_from_misc(m_db));
|
|
||||||
m_read_names_and_keys.reset(new ro::sql(m_db, R"|(SELECT * FROM "UserZookoIDs" )|"));
|
|
||||||
if (!(*m_read_from_misc)(1) || m_read_from_misc->value<int64_t>() != WALLET_FILE_IDENTIFIER)throw MyException(sz_unrecognizable_wallet_file_format);
|
|
||||||
if (!(*m_read_from_misc)(2) || m_read_from_misc->value<int64_t>() != WALLET_FILE_SCHEMA_VERSION_0_0 || !(*m_read_from_misc)(4))throw MyException(sz_unrecognized_wallet_schema);
|
|
||||||
m_MasterSecret= *(m_read_from_misc->value<ristretto255::scalar>());
|
|
||||||
ILogMessage(std::format("\t\tmaster secret: #{}", ro::base58(m_MasterSecret).operator const char* ()).c_str());
|
ILogMessage(std::format("\t\tmaster secret: #{}", ro::base58(m_MasterSecret).operator const char* ()).c_str());
|
||||||
if(!m_MasterSecret.valid()) throw MyException(sz_cold_wallets_not_yet_implemented, __LINE__, __func__, SrcFilename);
|
if(!m_MasterSecret.valid()) throw MyException(sz_cold_wallets_not_yet_implemented, __LINE__, __func__, SrcFilename);
|
||||||
auto sizer = new wxBoxSizer(wxHORIZONTAL);
|
auto sizer = new wxBoxSizer(wxHORIZONTAL);
|
||||||
@ -102,10 +98,10 @@ void display_wallet::refresh_from_database() {
|
|||||||
m_lsizer->Clear(true);
|
m_lsizer->Clear(true);
|
||||||
m_rsizer->Clear(true);
|
m_rsizer->Clear(true);
|
||||||
try {
|
try {
|
||||||
m_read_names_and_keys->reset();
|
m_read_names_and_keys.reset();
|
||||||
while (m_read_names_and_keys->step() == Icompiled_sql::ROW) {
|
while (m_read_names_and_keys.step() == Icompiled_sql::ROW) {
|
||||||
std::string name = m_read_names_and_keys->column<const char*>(0);
|
std::string name = m_read_names_and_keys.column<const char*>(0);
|
||||||
auto pubkey = *(m_read_names_and_keys->column<ristretto255::point>(1));
|
auto pubkey = *(m_read_names_and_keys.column<ristretto255::point>(1));
|
||||||
if (m_MasterSecret(name).timesBase() != pubkey)throw MyException(std::string(sz_public_key_of) + name + sz_fails_to_correspond);
|
if (m_MasterSecret(name).timesBase() != pubkey)throw MyException(std::string(sz_public_key_of) + name + sz_fails_to_correspond);
|
||||||
m_lSizer->Add(
|
m_lSizer->Add(
|
||||||
new wxStaticText(
|
new wxStaticText(
|
||||||
|
@ -6,10 +6,11 @@ public:
|
|||||||
~display_wallet();
|
~display_wallet();
|
||||||
private:
|
private:
|
||||||
typedef MenuLink<display_wallet> MenuLink;
|
typedef MenuLink<display_wallet> MenuLink;
|
||||||
std::unique_ptr<ISqlite3> m_db;
|
ro::dbconnect m_db;
|
||||||
std::unique_ptr <sql_read_from_misc> m_read_from_misc;
|
sql_read_from_misc m_read_from_misc;
|
||||||
std::unique_ptr <ro::sql> m_read_names_and_keys;
|
ro::sql m_read_names_and_keys;
|
||||||
std::unique_ptr <sql_insert_name> m_insert_name;
|
std::unique_ptr <sql_insert_name> m_insert_name;
|
||||||
|
ro::sql m_find_position;
|
||||||
|
|
||||||
ristretto255::CMasterSecret m_MasterSecret;
|
ristretto255::CMasterSecret m_MasterSecret;
|
||||||
wxBoxSizer* m_lSizer;
|
wxBoxSizer* m_lSizer;
|
||||||
|
Loading…
Reference in New Issue
Block a user