wallet: Add GetPrefixCursor to DatabaseBatch

In order to get records beginning with a prefix, we will need a cursor
specifically for that prefix. So add a GetPrefixCursor function and
DatabaseCursor classes for dealing with those prefixes.

Tested on each supported db engine.

1) Write two different key->value elements to db.
2) Create a new prefix cursor and walk-through every returned element,
   verifying that it gets parsed properly.
3) Try to move the cursor outside the filtered range: expect failure
   and flag complete=true.

Co-Authored-By: Ryan Ofsky <ryan@ofsky.org>
Co-Authored-By: furszy <matiasfurszyfer@protonmail.com>
This commit is contained in:
Andrew Chow
2022-04-11 17:11:37 -04:00
committed by Andrew Chow
parent 1d858b055d
commit ba616b932c
10 changed files with 239 additions and 15 deletions

View File

@@ -15,12 +15,21 @@ struct bilingual_str;
namespace wallet {
class SQLiteDatabase;
/** RAII class that provides a database cursor */
class SQLiteCursor : public DatabaseCursor
{
public:
sqlite3_stmt* m_cursor_stmt{nullptr};
// Copies of the prefix things for the prefix cursor.
// Prevents SQLite from accessing temp variables for the prefix things.
std::vector<std::byte> m_prefix_range_start;
std::vector<std::byte> m_prefix_range_end;
explicit SQLiteCursor() {}
explicit SQLiteCursor(std::vector<std::byte> start_range, std::vector<std::byte> end_range)
: m_prefix_range_start(std::move(start_range)),
m_prefix_range_end(std::move(end_range))
{}
~SQLiteCursor() override;
Status Next(DataStream& key, DataStream& value) override;
@@ -57,6 +66,7 @@ public:
void Close() override;
std::unique_ptr<DatabaseCursor> GetNewCursor() override;
std::unique_ptr<DatabaseCursor> GetNewPrefixCursor(Span<const std::byte> prefix) override;
bool TxnBegin() override;
bool TxnCommit() override;
bool TxnAbort() override;