1 /**************************************************************************** 2 ** 3 ** Copyright (C) 2020 The Qt Company Ltd. 4 ** Contact: https://www.qt.io/licensing/ 5 ** 6 ** This file is part of Qt Creator. 7 ** 8 ** Commercial License Usage 9 ** Licensees holding valid commercial Qt licenses may use this file in 10 ** accordance with the commercial license agreement provided with the 11 ** Software or, alternatively, in accordance with the terms contained in 12 ** a written agreement between you and The Qt Company. For licensing terms 13 ** and conditions see https://www.qt.io/terms-conditions. For further 14 ** information use the contact form at https://www.qt.io/contact-us. 15 ** 16 ** GNU General Public License Usage 17 ** Alternatively, this file may be used under the terms of the GNU 18 ** General Public License version 3 as published by the Free Software 19 ** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT 20 ** included in the packaging of this file. Please review the following 21 ** information to ensure the GNU General Public License requirements will 22 ** be met: https://www.gnu.org/licenses/gpl-3.0.html. 23 ** 24 ****************************************************************************/ 25 26 #pragma once 27 28 #include "sqliteblob.h" 29 #include "sqliteglobal.h" 30 #include "sqlitevalue.h" 31 32 #include <utils/smallstring.h> 33 34 #include <memory> 35 #include <vector> 36 #include <iosfwd> 37 38 struct sqlite3_changeset_iter; 39 40 namespace Sqlite { 41 42 class Sessions; 43 44 enum class Operation : char { Invalid, Insert, Update, Delete }; 45 46 namespace SessionChangeSetInternal { 47 48 class SentinelIterator 49 {}; 50 51 class ValueViews 52 { 53 public: 54 ValueView newValue; 55 ValueView oldValue; 56 }; 57 58 class SQLITE_EXPORT ConstTupleIterator 59 { 60 public: 61 using difference_type = int; 62 using value_type = ValueViews; 63 using pointer = const ValueViews *; 64 using reference = const ValueViews &; 65 using iterator_category = std::forward_iterator_tag; 66 ConstTupleIterator(sqlite3_changeset_iter * sessionIterator,int index,Sqlite::Operation operation)67 ConstTupleIterator(sqlite3_changeset_iter *sessionIterator, 68 int index, 69 Sqlite::Operation operation) 70 : m_sessionIterator{sessionIterator} 71 , m_column{index} 72 , m_operation{operation} 73 {} 74 75 ConstTupleIterator operator++() 76 { 77 ++m_column; 78 79 return *this; 80 } 81 82 friend bool operator==(const ConstTupleIterator &first, const ConstTupleIterator &second) 83 { 84 return first.m_column == second.m_column; 85 } 86 87 friend bool operator!=(const ConstTupleIterator &first, const ConstTupleIterator &second) 88 { 89 return !(first == second); 90 } 91 92 ValueViews operator*() const; 93 94 private: 95 sqlite3_changeset_iter *m_sessionIterator = {}; 96 int m_column = 0; 97 Sqlite::Operation m_operation = Sqlite::Operation::Invalid; 98 }; 99 100 class SQLITE_EXPORT Tuple 101 { 102 public: 103 using difference_type = int; 104 using value_type = ValueView; 105 using reference = ValueView &; 106 using const_reference = const ValueView &; 107 using iterator = ConstTupleIterator; 108 using const_iterator = ConstTupleIterator; 109 using size_type = int; 110 111 Utils::SmallStringView table; 112 sqlite3_changeset_iter *sessionIterator = {}; 113 int columnCount = 0; 114 Sqlite::Operation operation = Sqlite::Operation::Invalid; 115 116 ValueViews operator[](int column) const; begin()117 ConstTupleIterator begin() const { return {sessionIterator, 0, operation}; } end()118 ConstTupleIterator end() const { return {sessionIterator, columnCount, operation}; } 119 }; 120 121 enum class State : char { Invalid, Row, Done }; 122 123 class SQLITE_EXPORT ConstIterator 124 { 125 public: 126 using difference_type = long; 127 using value_type = Tuple; 128 using pointer = const Tuple *; 129 using reference = const Tuple &; 130 using iterator_category = std::input_iterator_tag; 131 ConstIterator(sqlite3_changeset_iter * sessionIterator)132 ConstIterator(sqlite3_changeset_iter *sessionIterator) 133 : m_sessionIterator(sessionIterator) 134 {} 135 136 ConstIterator(const ConstIterator &) = delete; 137 void operator=(const ConstIterator &) = delete; 138 ConstIterator(ConstIterator && other)139 ConstIterator(ConstIterator &&other) 140 : m_sessionIterator(other.m_sessionIterator) 141 , m_state(other.m_state) 142 { 143 other.m_sessionIterator = {}; 144 other.m_state = State::Done; 145 } 146 147 ConstIterator &operator=(ConstIterator &&other) 148 { 149 auto tmp = std::move(other); 150 swap(tmp, *this); 151 152 return *this; 153 } 154 155 ~ConstIterator(); 156 swap(ConstIterator & first,ConstIterator & second)157 friend void swap(ConstIterator &first, ConstIterator &second) noexcept 158 { 159 std::swap(first.m_sessionIterator, second.m_sessionIterator); 160 std::swap(first.m_state, second.m_state); 161 } 162 163 ConstIterator &operator++(); 164 165 friend bool operator==(const ConstIterator &first, const ConstIterator &second) 166 { 167 return first.m_sessionIterator == second.m_sessionIterator; 168 } 169 170 friend bool operator!=(const ConstIterator &first, const ConstIterator &second) 171 { 172 return !(first == second); 173 } 174 175 friend bool operator==(const ConstIterator &first, SentinelIterator) 176 { 177 return first.m_state == State::Done; 178 } 179 180 friend bool operator!=(const ConstIterator &first, SentinelIterator) 181 { 182 return first.m_state == State::Row; 183 } 184 185 friend bool operator==(SentinelIterator first, const ConstIterator &second) 186 { 187 return second == first; 188 } 189 190 friend bool operator!=(SentinelIterator first, const ConstIterator &second) 191 { 192 return second != first; 193 } 194 195 Tuple operator*() const; 196 state()197 State state() const { return m_state; } 198 199 private: 200 sqlite3_changeset_iter *m_sessionIterator = {}; 201 State m_state = State::Invalid; 202 }; 203 } // namespace SessionChangeSetInternal 204 205 class SQLITE_EXPORT SessionChangeSet 206 { 207 public: 208 SessionChangeSet(BlobView blob); 209 SessionChangeSet(Sessions &session); 210 ~SessionChangeSet(); 211 SessionChangeSet(const SessionChangeSet &) = delete; 212 void operator=(const SessionChangeSet &) = delete; SessionChangeSet(SessionChangeSet && other)213 SessionChangeSet(SessionChangeSet &&other) noexcept 214 { 215 SessionChangeSet temp; 216 swap(temp, other); 217 swap(temp, *this); 218 } 219 void operator=(SessionChangeSet &); 220 221 BlobView asBlobView() const; 222 swap(SessionChangeSet & first,SessionChangeSet & second)223 friend void swap(SessionChangeSet &first, SessionChangeSet &second) noexcept 224 { 225 SessionChangeSet temp; 226 std::swap(temp.m_data, first.m_data); 227 std::swap(temp.m_size, first.m_size); 228 std::swap(first.m_data, second.m_data); 229 std::swap(first.m_size, second.m_size); 230 std::swap(temp.m_data, second.m_data); 231 std::swap(temp.m_size, second.m_size); 232 } 233 234 SessionChangeSetInternal::ConstIterator begin() const; end()235 SessionChangeSetInternal::SentinelIterator end() const { return {}; } 236 data()237 void *data() const { return m_data; } 238 size()239 int size() const { return m_size; } 240 241 private: 242 SessionChangeSet() = default; 243 244 private: 245 void *m_data = nullptr; 246 int m_size = {}; 247 }; 248 249 using SessionChangeSets = std::vector<SessionChangeSet>; 250 251 } // namespace Sqlite 252