diff options
| author | Marco Bubke <[email protected]> | 2020-10-27 15:09:25 +0100 |
|---|---|---|
| committer | Marco Bubke <[email protected]> | 2020-11-03 09:19:54 +0000 |
| commit | c3873fcf40facd9cdf7ffc80a00f7112c3dbb8ce (patch) | |
| tree | 1815d0075d9ebbd0e9ac11d1e9df0bac92494643 /src/libs/sqlite/sqlitesessionchangeset.h | |
| parent | 3c7ab41e9efdb673d53572ab940fadc6cc68e984 (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.h | 185 |
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>; |
