aboutsummaryrefslogtreecommitdiffstats
path: root/src/libs/sqlite/sqlitesessionchangeset.h
diff options
context:
space:
mode:
authorMarco Bubke <[email protected]>2020-10-27 15:09:25 +0100
committerMarco Bubke <[email protected]>2020-11-03 09:19:54 +0000
commitc3873fcf40facd9cdf7ffc80a00f7112c3dbb8ce (patch)
tree1815d0075d9ebbd0e9ac11d1e9df0bac92494643 /src/libs/sqlite/sqlitesessionchangeset.h
parent3c7ab41e9efdb673d53572ab940fadc6cc68e984 (diff)
Sqlite: Add change set iterator
Task-number: QDS-2998 Change-Id: I7bfa8af51d9d7e6122902ee132ad51019e20afb5 Reviewed-by: Tim Jenssen <[email protected]> Reviewed-by: Thomas Hartmann <[email protected]>
Diffstat (limited to 'src/libs/sqlite/sqlitesessionchangeset.h')
-rw-r--r--src/libs/sqlite/sqlitesessionchangeset.h185
1 files changed, 174 insertions, 11 deletions
diff --git a/src/libs/sqlite/sqlitesessionchangeset.h b/src/libs/sqlite/sqlitesessionchangeset.h
index 8ea2dba0086..8dc27d1ef8f 100644
--- a/src/libs/sqlite/sqlitesessionchangeset.h
+++ b/src/libs/sqlite/sqlitesessionchangeset.h
@@ -27,17 +27,173 @@
#include "sqliteblob.h"
#include "sqliteglobal.h"
+#include "sqlitevalue.h"
+
+#include <utils/smallstring.h>
#include <memory>
#include <vector>
-
#include <iosfwd>
+struct sqlite3_changeset_iter;
+
namespace Sqlite {
class Sessions;
-class SessionChangeSet
+namespace SessionChangeSetInternal {
+enum class Operation : char { Invalid, Insert, Update, Delete };
+
+class SentinelIterator
+{};
+
+class ValueViews
+{
+public:
+ ValueView newValue;
+ ValueView oldValue;
+};
+
+class ConstTupleIterator
+{
+public:
+ using difference_type = int;
+ using value_type = ValueView;
+ using pointer = const ValueView *;
+ using reference = const ValueView &;
+ using iterator_category = std::forward_iterator_tag;
+
+ ConstTupleIterator(sqlite3_changeset_iter *sessionIterator, int index, Operation operation)
+ : m_sessionIterator{sessionIterator}
+ , m_column{index}
+ , m_operation{operation}
+ {}
+
+ ConstTupleIterator operator++()
+ {
+ ++m_column;
+
+ return *this;
+ }
+
+ friend bool operator==(const ConstTupleIterator &first, const ConstTupleIterator &second)
+ {
+ return first.m_column == second.m_column;
+ }
+
+ friend bool operator!=(const ConstTupleIterator &first, const ConstTupleIterator &second)
+ {
+ return !(first == second);
+ }
+
+ ValueViews operator*() const;
+
+private:
+ sqlite3_changeset_iter *m_sessionIterator = {};
+ int m_column = 0;
+ Operation m_operation = Operation::Invalid;
+};
+
+class Tuple
+{
+public:
+ using difference_type = int;
+ using value_type = ValueView;
+ using reference = ValueView &;
+ using const_reference = const ValueView &;
+ using iterator = ConstTupleIterator;
+ using const_iterator = ConstTupleIterator;
+ using size_type = int;
+
+ Utils::SmallStringView table;
+ sqlite3_changeset_iter *sessionIterator = {};
+ int columnCount = 0;
+ Operation operation = Operation::Invalid;
+
+ ValueViews operator[](int column) const;
+ ConstTupleIterator begin() const { return {sessionIterator, 0, operation}; }
+ ConstTupleIterator end() const { return {sessionIterator, columnCount, operation}; }
+};
+
+enum class State : char { Invalid, Row, Done };
+
+class ConstIterator
+{
+public:
+ using difference_type = long;
+ using value_type = Tuple;
+ using pointer = const Tuple *;
+ using reference = const Tuple &;
+ using iterator_category = std::input_iterator_tag;
+
+ ConstIterator(sqlite3_changeset_iter *sessionIterator)
+ : m_sessionIterator(sessionIterator)
+ {}
+
+ ConstIterator(const ConstIterator &) = delete;
+ void operator=(const ConstIterator &) = delete;
+
+ ConstIterator(ConstIterator &&other)
+ : m_sessionIterator(other.m_sessionIterator)
+ , m_state(other.m_state)
+ {
+ other.m_sessionIterator = {};
+ other.m_state = State::Done;
+ }
+
+ ConstIterator &operator=(ConstIterator &&other)
+ {
+ auto tmp = std::move(other);
+ std::swap(tmp, *this);
+
+ return *this;
+ }
+
+ ~ConstIterator();
+
+ ConstIterator &operator++();
+
+ friend bool operator==(const ConstIterator &first, const ConstIterator &second)
+ {
+ return first.m_sessionIterator == second.m_sessionIterator;
+ }
+
+ friend bool operator!=(const ConstIterator &first, const ConstIterator &second)
+ {
+ return !(first == second);
+ }
+
+ friend bool operator==(const ConstIterator &first, SentinelIterator)
+ {
+ return first.m_state == State::Done;
+ }
+
+ friend bool operator!=(const ConstIterator &first, SentinelIterator)
+ {
+ return first.m_state == State::Row;
+ }
+
+ friend bool operator==(SentinelIterator first, const ConstIterator &second)
+ {
+ return second == first;
+ }
+
+ friend bool operator!=(SentinelIterator first, const ConstIterator &second)
+ {
+ return second != first;
+ }
+
+ Tuple operator*() const;
+
+ State state() const { return m_state; }
+
+private:
+ sqlite3_changeset_iter *m_sessionIterator = {};
+ State m_state = State::Invalid;
+};
+} // namespace SessionChangeSetInternal
+
+class SQLITE_EXPORT SessionChangeSet
{
public:
SessionChangeSet(BlobView blob);
@@ -58,20 +214,27 @@ public:
friend void swap(SessionChangeSet &first, SessionChangeSet &second) noexcept
{
SessionChangeSet temp;
- std::swap(temp.data, first.data);
- std::swap(temp.size, first.size);
- std::swap(first.data, second.data);
- std::swap(first.size, second.size);
- std::swap(temp.data, second.data);
- std::swap(temp.size, second.size);
+ std::swap(temp.m_data, first.m_data);
+ std::swap(temp.m_size, first.m_size);
+ std::swap(first.m_data, second.m_data);
+ std::swap(first.m_size, second.m_size);
+ std::swap(temp.m_data, second.m_data);
+ std::swap(temp.m_size, second.m_size);
}
+ SessionChangeSetInternal::ConstIterator begin() const;
+ SessionChangeSetInternal::SentinelIterator end() const { return {}; }
+
+ void *data() const { return m_data; }
+
+ int size() const { return m_size; }
+
private:
SessionChangeSet() = default;
-public:
- void *data = nullptr;
- int size = {};
+private:
+ void *m_data = nullptr;
+ int m_size = {};
};
using SessionChangeSets = std::vector<SessionChangeSet>;