diff options
| author | bitflash-maintainer <noreply@bitflash.invalid> | 2026-09-06 01:53:03 +0000 |
|---|---|---|
| committer | bitflash-maintainer <noreply@bitflash.invalid> | 2026-09-06 01:53:03 +0000 |
| commit | ef9f06d43fc6577c15df2256abbb25b20d4227b8 (patch) | |
| tree | 7e9132aa871fdc01cb95268d2f5ea3bb11853ddf /src/wallet_sqlite.h | |
| parent | be63e83d79e7e00e6b8ca889a70e6a19886aa1d8 (diff) | |
| parent | ceae3d076b5ad11ee84729ae43f14e9312896646 (diff) | |
Bring main onto the line this project actually ships (incl. the 1.2.23 compactblock port)
Closes #6, #7, #8, #11, #35, #34, #29, #28, #27, and #16
See merge request !16
Diffstat (limited to 'src/wallet_sqlite.h')
| -rw-r--r-- | src/wallet_sqlite.h | 120 |
1 files changed, 120 insertions, 0 deletions
diff --git a/src/wallet_sqlite.h b/src/wallet_sqlite.h new file mode 100644 index 0000000..d27e13a --- /dev/null +++ b/src/wallet_sqlite.h | |||
| @@ -0,0 +1,120 @@ | |||
| 1 | // Copyright (c) 2026 Bitflash developers | ||
| 2 | // Distributed under the MIT/X11 software license. | ||
| 3 | |||
| 4 | #ifndef BITFLASH_WALLET_SQLITE_H | ||
| 5 | #define BITFLASH_WALLET_SQLITE_H | ||
| 6 | |||
| 7 | #include <sqlite3.h> | ||
| 8 | |||
| 9 | class CWalletRecordVisitor; | ||
| 10 | |||
| 11 | class CWalletDBSQLite | ||
| 12 | { | ||
| 13 | public: | ||
| 14 | CWalletDBSQLite(); | ||
| 15 | ~CWalletDBSQLite(); | ||
| 16 | |||
| 17 | bool Open(const string& strPath, string& strError); | ||
| 18 | bool OpenReadOnly(const string& strPath, string& strError); | ||
| 19 | void Close(); | ||
| 20 | |||
| 21 | bool BeginTransaction(string& strError); | ||
| 22 | bool CommitTransaction(string& strError); | ||
| 23 | bool RollbackTransaction(string& strError); | ||
| 24 | bool Checkpoint(string& strError); | ||
| 25 | |||
| 26 | bool WriteRecord(const vector<unsigned char>& vchKey, | ||
| 27 | const vector<unsigned char>& vchValue, | ||
| 28 | string& strError, | ||
| 29 | bool fOverwrite=true); | ||
| 30 | bool ReadRecord(const vector<unsigned char>& vchKey, | ||
| 31 | vector<unsigned char>& vchValueRet, | ||
| 32 | string& strError); | ||
| 33 | bool EraseRecord(const vector<unsigned char>& vchKey, | ||
| 34 | string& strError); | ||
| 35 | bool ScanRecords(CWalletRecordVisitor& visitor, string& strError); | ||
| 36 | bool CountRecords(int& nRecordsRet, string& strError); | ||
| 37 | |||
| 38 | template<typename K, typename T> | ||
| 39 | bool WriteTypedRecord(const K& key, const T& value, string& strError, | ||
| 40 | bool fOverwrite=true) | ||
| 41 | { | ||
| 42 | CDataStream ssKey(SER_DISK); | ||
| 43 | ssKey.reserve(1000); | ||
| 44 | ssKey << key; | ||
| 45 | |||
| 46 | CDataStream ssValue(SER_DISK); | ||
| 47 | ssValue.reserve(10000); | ||
| 48 | ssValue << value; | ||
| 49 | |||
| 50 | vector<unsigned char> vchKey(ssKey.begin(), ssKey.end()); | ||
| 51 | vector<unsigned char> vchValue(ssValue.begin(), ssValue.end()); | ||
| 52 | bool fOk = WriteRecord(vchKey, vchValue, strError, fOverwrite); | ||
| 53 | |||
| 54 | if (!vchKey.empty()) | ||
| 55 | memset(&vchKey[0], 0, vchKey.size()); | ||
| 56 | if (!vchValue.empty()) | ||
| 57 | memset(&vchValue[0], 0, vchValue.size()); | ||
| 58 | if (!ssKey.empty()) | ||
| 59 | memset(&ssKey[0], 0, ssKey.size()); | ||
| 60 | if (!ssValue.empty()) | ||
| 61 | memset(&ssValue[0], 0, ssValue.size()); | ||
| 62 | return fOk; | ||
| 63 | } | ||
| 64 | |||
| 65 | template<typename K, typename T> | ||
| 66 | bool ReadTypedRecord(const K& key, T& valueRet, string& strError) | ||
| 67 | { | ||
| 68 | CDataStream ssKey(SER_DISK); | ||
| 69 | ssKey.reserve(1000); | ||
| 70 | ssKey << key; | ||
| 71 | vector<unsigned char> vchKey(ssKey.begin(), ssKey.end()); | ||
| 72 | |||
| 73 | vector<unsigned char> vchValue; | ||
| 74 | bool fOk = ReadRecord(vchKey, vchValue, strError); | ||
| 75 | if (!vchKey.empty()) | ||
| 76 | memset(&vchKey[0], 0, vchKey.size()); | ||
| 77 | if (!ssKey.empty()) | ||
| 78 | memset(&ssKey[0], 0, ssKey.size()); | ||
| 79 | if (!fOk) | ||
| 80 | return false; | ||
| 81 | |||
| 82 | CDataStream ssValue(vchValue, SER_DISK); | ||
| 83 | ssValue >> valueRet; | ||
| 84 | bool fReadOk = !ssValue.fail(); | ||
| 85 | if (!vchValue.empty()) | ||
| 86 | memset(&vchValue[0], 0, vchValue.size()); | ||
| 87 | if (!ssValue.empty()) | ||
| 88 | memset(&ssValue[0], 0, ssValue.size()); | ||
| 89 | if (!fReadOk) | ||
| 90 | strError = "SQLite wallet record could not be deserialized"; | ||
| 91 | return fReadOk; | ||
| 92 | } | ||
| 93 | |||
| 94 | template<typename K> | ||
| 95 | bool EraseTypedRecord(const K& key, string& strError) | ||
| 96 | { | ||
| 97 | CDataStream ssKey(SER_DISK); | ||
| 98 | ssKey.reserve(1000); | ||
| 99 | ssKey << key; | ||
| 100 | vector<unsigned char> vchKey(ssKey.begin(), ssKey.end()); | ||
| 101 | |||
| 102 | bool fOk = EraseRecord(vchKey, strError); | ||
| 103 | if (!vchKey.empty()) | ||
| 104 | memset(&vchKey[0], 0, vchKey.size()); | ||
| 105 | if (!ssKey.empty()) | ||
| 106 | memset(&ssKey[0], 0, ssKey.size()); | ||
| 107 | return fOk; | ||
| 108 | } | ||
| 109 | |||
| 110 | private: | ||
| 111 | sqlite3* pdb; | ||
| 112 | |||
| 113 | bool Exec(const char* pszSql, string& strError); | ||
| 114 | bool InitSchema(string& strError); | ||
| 115 | |||
| 116 | CWalletDBSQLite(const CWalletDBSQLite&); | ||
| 117 | void operator=(const CWalletDBSQLite&); | ||
| 118 | }; | ||
| 119 | |||
| 120 | #endif | ||