1
0
forked from cheng/wallet

Massive bug, in that a long time ago I made changes to sqlite.h

but not to the corresponding copy of sqlite.h
Fixed case that there are no yet any names in
the database - it now automatically nags you.
This commit is contained in:
Cheng 2023-11-13 00:41:38 +00:00
parent 224ab60395
commit 3e480213cc
No known key found for this signature in database
GPG Key ID: 571C3A9C3B9E6FCA
4 changed files with 72 additions and 1 deletions

View File

@ -395,6 +395,28 @@ extern "C" {
** SQLITE_SYSAPI macros are used only when building for environments
** that require non-default calling conventions.
*/
//My custom compile options
#define SQLITE_DQS 0 //Doublequote names, single quote strings. This setting disables the double - quoted string literal misfeature.
#define SQLITE_THREADSAFE 2 //Sets the default mode to SQLITE_CONFIG_MULTITHREAD. One thread, one database connection. Data structures such as compiled SQL are threadlocal. But sqlite3 is empowered to do its own multithreading. Many databases per database connection. Database connection and compiled sql statements are threadlocal. last_insert_rowid() is not subject to race conditions in this mode.
#define SQLITE_DEFAULT_MEMSTATUS 0 //Don't track memory usage. Disables the ability of the program using sqlite3 to monitor its memory usage. This setting causes the sqlite3_status() interfaces that track memory usage to be disabled. This helps the sqlite3_malloc() routines run much faster, and since SQLite uses sqlite3_malloc() internally, this helps to make the entire library faster.
#define SQLITE_DEFAULT_WAL_SYNCHRONOUS 1 // in WAL mode, recent changes to the database might be rolled back by a power loss, but the database will not be corrupted. Furthermore, transaction commit is much faster in WAL mode using synchronous=NORMAL than with the default synchronous=FULL. For these reasons, it is recommended that the synchronous setting be changed from FULL to NORMAL when switching to WAL mode. This compile-time option will accomplish that.
#define SQLITE_DEFAULT_FOREIGN_KEYS 0 //Dont handle foreign key constraints. Programmer has to do it himself.
#define SQLITE_LIKE_DOESNT_MATCH_BLOBS 1 //Blobs are not strings. Historically, SQLite has allowed BLOB operands to the LIKE and GLOB operators. But having a BLOB as an operand of LIKE or GLOB complicates and slows the LIKE optimization. When this option is set, it means that the LIKE and GLOB operators always return FALSE if either operand is a BLOB. That simplifies the implementation of the LIKE optimization and allows queries that use the LIKE optimization to run faster.
#define SQLITE_MAX_EXPR_DEPTH 0 //Setting the maximum expression parse-tree depth to zero disables all checking of the expression parse-tree depth, which simplifies the code resulting in faster execution, and helps the parse tree to use less memory.
#define SQLITE_OMIT_DECLTYPE 1 // By omitting the (seldom-needed) ability to return the declared type of columns from the result set of query, prepared statements can be made to consume less memory.
#define SQLITE_OMIT_DEPRECATED 1
#define SQLITE_DQS 0 //Don't accept double quoted string literals.
#define SQLITE_OMIT_PROGRESS_CALLBACK 1
#define SQLITE_OMIT_SHARED_CACHE 1
#define SQLITE_OMIT_UTF16 1
#define SQLITE_USE_ALLOCA 1 //Make use of alloca() for dynamically allocating temporary stack space for use within a single function, on systems that support alloca(). Without this option, temporary space is allocated from the heap
#define SQLITE_OMIT_LOAD_EXTENSION 1
#define SQLITE_TEMP_STORE 1 //Temporary files are stashed on disk when their cache overflows.
#define SQLITE_OMIT_AUTOINIT 1 //.The SQLite library needs to be initialized using a call to sqlite3_initialize() before certain interfaces are used.This initialization normally happens automatically the first time it is needed.However, with the SQLITE_OMIT_AUTOINIT option, the automatic initialization is omitted.This helps many API calls to run a little faster(since they do not have to check to see if initialization has already occurred and then run initialization if it has not previously been invoked) but it also means that the application must call sqlite3_initialize() manually.If SQLite is compiled with - DSQLITE_OMIT_AUTOINIT and a routine like sqlite3_malloc() or sqlite3_vfs_find() or sqlite3_open() is invoked without first calling sqlite3_initialize(), the likely result will be a segfault
//end my custom compile options*/
#ifndef SQLITE_EXTERN
# define SQLITE_EXTERN extern
#endif

View File

@ -15,6 +15,45 @@
#include <span>
#include "ISqlite3.h"
#include "sqlite3.h"
/*Because sqlite3.h is frigging enormous and does no end of strange,
clever things that I do not understand, I do not include it my standard header files,
only in this file, which does not include my standard header files.
The ISqlit3Impl.cpp provides a low level C++ interface to the
even lower level C interface of sqlite3.c,
and ISqlite3.h provides an interface between high level c++ish code,
and the low level C++ish code of ISqlit3Impl, and sqlite3.h,
included only in ISqlit3Imp.cpp, provides an even lower level interface,
which the rest of my code does not use, only ISqlite3Impl.cpp, between C++ and C
The rest of my code cannot see the interface class, only is purely virtual
base class. Objects of the implementation class generated by the factories
in Sqlit3Impl are naked old fashioned pointers to the heap, which are presented by
db_accessors.cpp wrapped in std:unique.ptrs. The rest of my code
cannot contain variables of the implementation class on the stack.
The interface classes in db_accessors cannot be default constructed.
which is to say, cannot contain a nullptr. The default constructor
is explicitly deleted, because it is a bug waiting to happen which
has tripped me up too many times.
I avoid having any file that includes both sqlite3.h and the headers
for my standard high level environment. It is just too big and too
complicated.
Note that sqlite3.cpp does *not* include sqlite3.h either. Any changes to
the sqlite3.h headers have to be duplicated in both files.
Also note that the copy of sqlite.h that lives in sqlite3.c does
not work in the main program environment, and vice versa. They
are not the same even though the documentation says they
are the same and will work. Like I said, too clever by half.
sqlite3.cpp is very low level C code, assembly written in C.
only includes stdarg.h, does not link to most standard
libraries. In lieu of linking to standard libraries, tries
to adapt to its environment independently.
*/
static auto error_message(int rc, sqlite3* pdb) {
return std::string("Sqlite3 Error: ") + sqlite3_errmsg(pdb) + ". Sqlite3 error number=" + std::to_string(rc);

View File

@ -39,6 +39,10 @@ WHERE LOWER("name")<LOWER(?1) OR (LOWER("name")=LOWER(?1) AND "name"<?1);)|")
this, myID_DISPLAY_WALLET_ADD_NAME
);
m_DisplayWalletEditMenu.Replace();
if (m_lSizer->IsEmpty()) {
auto event = new wxCommandEvent(wxEVT_MENU, myID_DISPLAY_WALLET_ADD_NAME);
wxQueueEvent(m_DisplayWalletEditMenu.Menu, event);
}
}
catch (const MyException&) {
throw;
@ -96,7 +100,7 @@ struct display_wallet::cleanup {
}
};
void display_wallet::add_name_event_handler(wxCommandEvent& event) {
void display_wallet::add_name_event_handler(wxCommandEvent&) {
wxTextEntryDialog dialog(this,
R"("A Zooko name has a human readable name,
and a public key defined by the name and the wallet master secret)",
@ -153,6 +157,8 @@ void display_wallet::OnClose(wxCloseEvent& event) {
void display_wallet::refresh_from_database() {
cleanup cln(this);
m_lSizer->Clear(true);
m_rSizer->Clear(true);
try {
m_read_names_and_keys.reset();
while (m_read_names_and_keys.step() == Icompiled_sql::ROW) {

View File

@ -522,6 +522,7 @@ void Frame::OnFileOpen(wxCommandEvent&) {
wxFileName walletfile(dialog.GetPath());
if (m_panel)m_panel->Close(); //Destroy somehow manages to execute
// the correct derived destructor regardless of what kind of object it is.
// but no destruction happens until idle. It is not destroyed immediately
m_panel = nullptr;
display_wallet* panel = new display_wallet(this, walletfile);
m_panel = panel;
@ -579,5 +580,8 @@ Frame::~Frame() {
wxMenuTracker::check_dynamic_menus_absent();
}
singletonFrame = nullptr;
// Not safe to do sqlite shutdown until dynamic menus absent, because
// compiled sql has not been finalized, and database connections not
// closed.
if (sqlite3_shutdown())wxMessageBox(wxT(R"|(Sqlite3 shutdown error)|"), wsz_error, wxICON_ERROR);
}