forked from qt-creator/qt-creator
Sqlite: Add change set iterator
Task-number: QDS-2998 Change-Id: I7bfa8af51d9d7e6122902ee132ad51019e20afb5 Reviewed-by: Tim Jenssen <tim.jenssen@qt.io> Reviewed-by: Thomas Hartmann <thomas.hartmann@qt.io>
This commit is contained in:
@@ -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>;
|
||||
|
||||
Reference in New Issue
Block a user