ChangeSet.h
Go to the documentation of this file.
1 /*--------------------------------------------------------------------------------------+
2 |
3 | Supplied under applicable software license agreement.
4 |
5 | Copyright (c) 2018 Bentley Systems, Incorporated. All rights reserved.
6 |
7 +---------------------------------------------------------------------------------------*/
8 #pragma once
9 
10 #include "BeSQLite.h"
11 
18 
20 
21 //=======================================================================================
22 // @bsiclass Bentley Systems
23 //=======================================================================================
24 struct IByteArray
25 {
26 protected:
27  virtual int _GetSize() const = 0;
28  virtual void const* _GetData() const = 0;
29 public:
31  int GetSize() const { return _GetSize(); }
32 
34  void const* GetData() const { return _GetData(); }
35 };
36 
37 //=======================================================================================
38 // @bsiclass Bentley Systems
39 //=======================================================================================
41 {
42 private:
43  Utf8String m_ddl;
44 
45  int _GetSize() const override { return IsEmpty() ? 0 : (int) m_ddl.SizeInBytes(); }
46  void const* _GetData() const override { return m_ddl.c_str(); }
47 
48 public:
50  SchemaChangeSet(Utf8CP ddl = nullptr) { m_ddl.AssignOrClear(ddl); }
51 
53  BE_SQLITE_EXPORT void AddDDL(Utf8CP ddl);
54 
56  bool IsEmpty() const { return m_ddl.empty(); }
57 
59  void Clear() { m_ddl.clear(); }
60 
62  Utf8StringCR ToString() const { return m_ddl; }
63 
65  BE_SQLITE_EXPORT void Dump(Utf8CP label) const;
66 };
67 
68 //=======================================================================================
78 // @bsiclass Bentley Systems
79 //=======================================================================================
81 {
82 friend struct Db;
83 friend struct DbFile;
84 
85 private:
86  SchemaChangeSet m_schemaChanges;
87  DbResult RecordSchemaChange(Utf8CP ddl);
88 
89 protected:
91  Db* m_db;
92  SqlSessionP m_session;
94 
95  enum class OnCommitStatus {Continue=0, Abort, Completed};
96  enum class TrackChangesForTable : bool {No=0, Yes=1};
97 
98  BE_SQLITE_EXPORT DbResult CreateSession();
99  virtual OnCommitStatus _OnCommit(bool isCommit, Utf8CP operation) = 0;
100  void SetDb(Db* db) {m_db = db;}
101  Db* GetDb() {return m_db;}
102  Utf8CP GetName() const {return m_name.c_str();}
103 
104  SchemaChangeSetCR GetSchemaChanges() const { return m_schemaChanges; }
105 
106 public:
107  ChangeTracker(Utf8CP name=NULL) : m_name(name) {m_session=0; m_db=0; m_isTracking=false;}
108  virtual ~ChangeTracker() {EndTracking();}
109  virtual TrackChangesForTable _FilterTable(Utf8CP tableName) {return TrackChangesForTable::Yes;}
110  SqlSessionP GetSqlSession() {return m_session;}
111 
117  BE_SQLITE_EXPORT DbResult DifferenceToDb(Utf8StringP errMsg, BeFileNameCR baseFile);
118 
120  BE_SQLITE_EXPORT void EndTracking();
121 
124  BE_SQLITE_EXPORT bool EnableTracking(bool val);
125 
127  enum class Mode
128  {
129  Direct = 0,
130  Indirect = 1,
131  };
132 
134  BE_SQLITE_EXPORT Mode GetMode() const;
135 
138  BE_SQLITE_EXPORT void SetMode(Mode mode);
139 
141  BE_SQLITE_EXPORT bool HasChanges() const;
142 
144  BE_SQLITE_EXPORT bool HasDataChanges() const;
145 
147  bool HasSchemaChanges() const { return !m_schemaChanges.IsEmpty(); }
148 
150  void Restart() {EndTracking(); EnableTracking(true);}
151  bool IsTracking() const {return m_isTracking;}
152 };
153 
154 //=======================================================================================
157 // @bsiclass Bentley Systems
158 //=======================================================================================
159 struct Changes
160 {
161 private:
162  ChangeStream* m_changeStream = nullptr;
163  int m_size = 0;
164  void* m_data = nullptr;
165  mutable SqlChangesetIterP m_iter = 0;
166 
167  void Finalize() const;
168 
169 public:
171  BE_SQLITE_EXPORT explicit Changes(ChangeSet const& changeSet);
172 
175  explicit Changes(ChangeStream& changeStream) : m_changeStream(&changeStream) {}
176 
178  Changes(void* data, int size) : m_data(data), m_size(size) {}
179 
181  Changes(Changes const& other) : m_data(other.m_data), m_size(other.m_size), m_changeStream(other.m_changeStream), m_iter(0) {}
182 
183  BE_SQLITE_EXPORT ~Changes();
184 
186  struct Change : std::iterator<std::input_iterator_tag, Change const>
187  {
188  private:
189  bool m_isValid;
190  SqlChangesetIterP m_iter;
191 
192  public:
193  Change(SqlChangesetIterP iter, bool isValid) {m_iter=iter; m_isValid=isValid;}
201  BE_SQLITE_EXPORT DbResult GetOperation(Utf8CP* tableName, int* nCols, DbOpcode* opcode, int* indirect) const;
202 
204  BE_SQLITE_EXPORT DbResult GetPrimaryKeyColumns(Byte** cols, int* nCols) const;
205 
210  BE_SQLITE_EXPORT DbValue GetOldValue(int colNum) const;
211 
216  BE_SQLITE_EXPORT DbValue GetNewValue(int colNum) const;
217 
218  enum class Stage : bool {Old=0, New=1};
219  DbValue GetValue(int colNum, Stage stage) const {return (stage==Stage::Old) ? GetOldValue(colNum) : GetNewValue(colNum);}
220 
222  BE_SQLITE_EXPORT Change& operator++();
223 
224  bool IsValid() const {return m_isValid;}
225 
226  Change const& operator* () const {return *this;}
227  bool operator!=(Change const& rhs) const {return (m_iter != rhs.m_iter) || (m_isValid != rhs.m_isValid);}
228  bool operator==(Change const& rhs) const {return (m_iter == rhs.m_iter) && (m_isValid == rhs.m_isValid);}
229 
231  BE_SQLITE_EXPORT void Dump(Db const&, bool isPatchSet, bset<Utf8String>& tablesSeen, int detailLevel) const;
232 
233  void Dump(Db const& db, bool isPatchSet, int detailLevel) const {bset<Utf8String> tablesSeen; Dump(db, isPatchSet, tablesSeen, detailLevel);}
234 
236  BE_SQLITE_EXPORT void DumpColumns(int startCol, int endCol, Changes::Change::Stage stage, bvector<Utf8String> const& columns, int detailLevel) const;
237 
239  BE_SQLITE_EXPORT Utf8String FormatPrimarykeyColumns(bool isInsert, int detailLevel) const;
240 
241  BE_SQLITE_EXPORT void OnPropertyUpdateReversed(Db&) const;
242  };
243 
245 
247  BE_SQLITE_EXPORT Change begin() const;
248 
250  Change end() const {return Change(m_iter, false);}
251 
252 };
253 
254 //=======================================================================================
255 // @bsiclass Bentley Systems
256 //=======================================================================================
258 {
259  friend struct ChangeSet;
260  friend struct ChangeStream;
261 private:
262  void* m_changegroup;
263 
264 public:
267  BE_SQLITE_EXPORT DbResult AddChanges(int size, void const* data);
268 };
269 
270 //=======================================================================================
271 // @bsiclass Bentley Systems
272 //=======================================================================================
274 {
275 public:
276  enum class SetType : bool {Full=0, Patch=1};
277  enum class ApplyChangesForTable : bool {No=0, Yes=1};
278  enum class ConflictCause : int {Data=1, NotFound=2, Conflict=3, Constraint=4, ForeignKey=5};
279  enum class ConflictResolution : int {Skip=0, Replace=1, Abort=2};
280 protected:
281  virtual ~IChangeSet() { }
282 
283  virtual ApplyChangesForTable _FilterTable(Utf8CP tableName) {return ApplyChangesForTable::Yes;}
284  virtual ConflictResolution _OnConflict(ConflictCause clause, Changes::Change iter) = 0;
285  virtual DbResult _FromChangeTrack(ChangeTracker& tracker, SetType setType) = 0;
286  virtual DbResult _FromChangeGroup(ChangeGroupCR changeGroup) = 0;
287  virtual DbResult _ApplyChanges(DbR db) = 0;
288  virtual Changes _GetChanges() = 0;
289 public:
292  ApplyChangesForTable FilterTable(Utf8CP tableName) { return _FilterTable(tableName); }
293 
296  ConflictResolution OnConflict(ConflictCause cause, Changes::Change iter) { return _OnConflict(cause, iter); }
297 
303  DbResult FromChangeTrack(ChangeTracker& tracker, SetType setType=SetType::Full) { return _FromChangeTrack(tracker, setType); }
304 
309  DbResult FromChangeGroup(ChangeGroupCR changeGroup) { return _FromChangeGroup(changeGroup); }
310 
315  DbResult ApplyChanges(DbR db) { return _ApplyChanges(db); }
316 
319  Changes GetChanges() { return _GetChanges(); }
320 };
321 
322 //=======================================================================================
332 // @bsiclass Bentley Systems
333 //=======================================================================================
335 {
336 private:
337  int m_size;
338  void* m_changeset;
339 
340  int _GetSize() const override { return m_size; }
341  void const* _GetData() const override { return m_changeset; }
342 
343 protected:
344  BE_SQLITE_EXPORT virtual DbResult _FromChangeTrack(ChangeTracker& tracker, SetType setType) override;
345  BE_SQLITE_EXPORT virtual DbResult _FromChangeGroup(ChangeGroupCR changeGroup) override;
346  BE_SQLITE_EXPORT virtual DbResult _ApplyChanges(DbR db) override;
347  virtual Changes _GetChanges() override { return Changes(*this); }
348 public:
350  ChangeSet() {m_size=0; m_changeset=nullptr;}
351  ~ChangeSet() {Free();}
352 
355  BE_SQLITE_EXPORT void Free();
356 
357  BE_SQLITE_EXPORT DbResult Invert();
358 
361  BE_SQLITE_EXPORT DbResult FromData(int size, void const* data, bool invert);
362 
366  BE_SQLITE_EXPORT DbResult ConcatenateWith(ChangeSet const& second);
367 
369  bool IsValid() {return 0 != m_changeset;}
370 
372  BE_SQLITE_EXPORT void Dump(Utf8CP label, Db const&, bool isPatchSet=false, int detailLevel=0) const;
373 
375  BE_SQLITE_EXPORT static Utf8String InterpretConflictCause(ChangeSet::ConflictCause);
376 };
377 
378 //=======================================================================================
380 // @bsiclass Bentley Systems
381 //=======================================================================================
383 {
385  {
386  BeAssert(false);
387  return ChangeSet::ConflictResolution::Abort;
388  }
389 };
390 
391 //=======================================================================================
395 // @bsiclass Bentley Systems
396 //=======================================================================================
398 {
399 friend struct Changes;
400 private:
401  static int OutputCallback(void *pOut, const void *pData, int nData);
402  static int InputCallback(void *pIn, void *pData, int *pnData);
403  static int ConflictCallback(void *pCtx, int cause, SqlChangesetIterP iter);
404  static int FilterTableCallback(void *pCtx, Utf8CP tableName);
405 
406  // Resets the change stream, and is internally called at the
407  // end of various change stream operations
408  void Reset() { _Reset(); }
409  static DbResult TransferBytesBetweenStreams(ChangeStream& inStream, ChangeStream& outStream);
410 
411 protected:
412  BE_SQLITE_EXPORT virtual DbResult _FromChangeTrack(ChangeTracker& tracker, SetType setType) override;
413  BE_SQLITE_EXPORT virtual DbResult _FromChangeGroup(ChangeGroupCR changeGroup) override;
414  BE_SQLITE_EXPORT virtual DbResult _ApplyChanges(DbR db) override;
415  virtual Changes _GetChanges() override { return Changes(*this); }
416 
422  virtual DbResult _InputPage(void *pData, int *pnData) { return BE_SQLITE_OK; }
423 
428  virtual DbResult _OutputPage(const void *pData, int nData) { return BE_SQLITE_OK; }
429 
433  virtual void _Reset() {}
434 
435 public:
438 
443  BE_SQLITE_EXPORT DbResult ToChangeGroup(ChangeGroup& changeGroup);
444 
450  BE_SQLITE_EXPORT DbResult ToChangeSet(ChangeSet& changeSet, bool invert = false);
451 
458  BE_SQLITE_EXPORT DbResult FromChangeStream(ChangeStream& inStream, bool invert = false);
459 
466  BE_SQLITE_EXPORT DbResult ToChangeStream(ChangeStream& outStream, bool invert = false);
467 
474  BE_SQLITE_EXPORT DbResult FromConcatenatedChangeStreams(ChangeStream& inStream1, ChangeStream& inStream2);
475 
477  BE_SQLITE_EXPORT void Dump(Utf8CP label, DbCR db, bool isPatchSet = false, int detailLevel = 0);
478 };
479 
Contains a UTF-8 encoded string.
Definition: WString.h:275
Definition: ChangeSet.h:24
virtual ApplyChangesForTable _FilterTable(Utf8CP tableName)
Definition: ChangeSet.h:283
A "value" from a BeSQLite function.
Definition: BeSQLite.h:960
ConflictResolution
Definition: ChangeSet.h:279
Changes(Changes const &other)
Copy constructor.
Definition: ChangeSet.h:181
SchemaChangeSet(Utf8CP ddl=nullptr)
Create a new schema change set.
Definition: ChangeSet.h:50
ApplyChangesForTable
Definition: ChangeSet.h:277
#define END_BENTLEY_SQLITE_NAMESPACE
Definition: BeSQLite.h:139
virtual Changes _GetChanges() override
Definition: ChangeSet.h:347
struct Bentley::BeFileName const & BeFileNameCR
Definition: Bentley.h:242
Stage
Definition: ChangeSet.h:218
Changes(ChangeStream &changeStream)
Construct an iterator for a ChangeStream.
Definition: ChangeSet.h:175
bool IsEmpty() const
Returns true if the schema change set is empty.
Definition: ChangeSet.h:56
Mode
All changes are marked as either direct or indirect according to the mode in which the ChangeTracker ...
Definition: ChangeSet.h:127
ChangeSet()
construct a blank, empty ChangeSet
Definition: ChangeSet.h:350
Successful result.
Definition: BeSQLite.h:365
OnCommitStatus
Definition: ChangeSet.h:95
DbResult ApplyChanges(DbR db)
Apply all of the changes in this IChangeSet to the supplied database.
Definition: ChangeSet.h:315
Utf8CP GetName() const
Definition: ChangeSet.h:102
iterator begin()
Definition: stdcxx/bstdmap.h:178
A base class for a streaming version of the ChangeSet.
Definition: ChangeSet.h:397
bool operator!=(Change const &rhs) const
Definition: ChangeSet.h:227
ApplyChangesForTable FilterTable(Utf8CP tableName)
Implement to handle conflicts when applying changes.
Definition: ChangeSet.h:292
Utf8StringCR ToString() const
Return the contents of the schema change set.
Definition: ChangeSet.h:62
DbOpcode
Definition: BeSQLite.h:473
ConflictCause
Definition: ChangeSet.h:278
Change(SqlChangesetIterP iter, bool isValid)
Definition: ChangeSet.h:193
SchemaChangeSet const & SchemaChangeSetCR
Definition: ChangeSet.h:17
struct Bentley::Utf8String const & Utf8StringCR
Definition: Bentley.h:241
bool IsValid() const
Definition: ChangeSet.h:224
bool IsValid()
Determine whether this ChangeSet holds valid data or not.
Definition: ChangeSet.h:369
#define NULL
Definition: Bentley.h:157
void Restart()
Clear the contents of this ChangeTracker and re-start it.
Definition: ChangeSet.h:150
void Clear()
Clear the schema change set.
Definition: ChangeSet.h:59
A single change to a database row.
Definition: ChangeSet.h:186
virtual Changes _GetChanges() override
Definition: ChangeSet.h:415
Change const_iterator
Definition: ChangeSet.h:244
Changes(void *data, int size)
Construct an iterator for a page of changes in a ChangeStream.
Definition: ChangeSet.h:178
virtual ~IChangeSet()
Definition: ChangeSet.h:281
virtual DbResult _OutputPage(const void *pData, int nData)
Application implements this to receive data from the system.
Definition: ChangeSet.h:428
ChangeGroup const & ChangeGroupCR
Definition: ChangeSet.h:13
size_type SizeInBytes() const
Computes the size, in bytes, of this string's data, including its NULL-terminator.
Definition: WString.h:297
virtual TrackChangesForTable _FilterTable(Utf8CP tableName)
Definition: ChangeSet.h:109
DbResult FromChangeGroup(ChangeGroupCR changeGroup)
Create a ChangeSet/ChangeStream by merging the contents of a ChangeGroup.
Definition: ChangeSet.h:309
void Dump(Db const &db, bool isPatchSet, int detailLevel) const
Definition: ChangeSet.h:233
ConflictResolution OnConflict(ConflictCause cause, Changes::Change iter)
Implement to filter out specific tables when applying changes.
Definition: ChangeSet.h:296
ChangeTracker(Utf8CP name=0)
Definition: ChangeSet.h:107
virtual ~ChangeTracker()
Definition: ChangeSet.h:108
A set of changes to database rows.
Definition: ChangeSet.h:334
bool IsTracking() const
Definition: ChangeSet.h:151
SqlSessionP GetSqlSession()
Definition: ChangeSet.h:110
#define BEGIN_BENTLEY_SQLITE_NAMESPACE
Definition: BeSQLite.h:138
Base class to make a class non-copyable.
Definition: NonCopyableClass.h:23
#define BE_SQLITE_EXPORT
Definition: BeSQLite.h:124
Definition: msinput.fdf:965
Db const & DbCR
Definition: BeSQLite.h:159
bool HasSchemaChanges() const
Determine whether any schema changes have beeen tracked by this ChangeTracker.
Definition: ChangeSet.h:147
Utf8String m_name
Definition: ChangeSet.h:93
When enabled, this class maintains a list of "changed rows" (inserts, updates and deletes) for a BeSQ...
Definition: ChangeSet.h:80
DVec3d operator*(Transform const &transform, DVec3d const &vector)
operator overload for multiplication of a transform and a vector li>The vector appears on the left as...
Concrete class that can be used to implement the reference-counting pattern.
Definition: RefCounted.h:109
!! N.B.
Definition: mscons.h:421
Definition: ChangeSet.h:273
Utf8Char const * Utf8CP
Definition: Bentley.h:229
SetType
Definition: ChangeSet.h:276
bool m_isTracking
Definition: ChangeSet.h:90
Db * m_db
Definition: ChangeSet.h:91
bool operator==(Change const &rhs) const
Definition: ChangeSet.h:228
Db * GetDb()
Definition: ChangeSet.h:101
#define BeAssert(_Expression)
BeAssert performs the same function as the standard assert, plus it prevents the most common cases of...
Definition: BeAssert.h:56
A BeSQLite database file.
Definition: BeSQLite.h:2020
unsigned char Byte
Definition: Bentley.r.h:143
#define BESQLITE_TYPEDEFS(_name_)
Definition: BeSQLite.h:156
Definition: ChangeSet.h:40
ConflictResolution _OnConflict(ConflictCause cause, BeSQLite::Changes::Change iter) override
Definition: ChangeSet.h:384
virtual DbResult _InputPage(void *pData, int *pnData)
Application implements this to supply input to the system.
Definition: ChangeSet.h:422
Change end() const
Get the last entry in the ChangeSet.
Definition: ChangeSet.h:250
DbValue GetValue(int colNum, Stage stage) const
Definition: ChangeSet.h:219
TrackChangesForTable
Definition: ChangeSet.h:96
An Iterator for a ChangeSet or a ChangeStream.
Definition: ChangeSet.h:159
SqlSessionP m_session
Definition: ChangeSet.h:92
DbResult FromChangeTrack(ChangeTracker &tracker, SetType setType=SetType::Full)
Create a ChangeSet/ChangeStream from a ChangeTracker.
Definition: ChangeSet.h:303
size_type size() const
Definition: stdcxx/bstdmap.h:214
A ChangeSet implementation for where conflicts are just not expected.
Definition: ChangeSet.h:382
virtual void _Reset()
Override to reset any state of the change stream.
Definition: ChangeSet.h:433
int GetSize() const
Get the number of bytes.
Definition: ChangeSet.h:31
Definition: ChangeSet.h:257
ChangeStream()
Constructor.
Definition: ChangeSet.h:437
void SetDb(Db *db)
Definition: ChangeSet.h:100
A physical Db file.
Definition: BeSQLite.h:1948
void const * GetData() const
Get a pointer to the data.
Definition: ChangeSet.h:34
SchemaChangeSetCR GetSchemaChanges() const
Definition: ChangeSet.h:104
~ChangeSet()
Definition: ChangeSet.h:351
Changes GetChanges()
Returns a Changes object for iterating over the changes contained within this IChangeSet.
Definition: ChangeSet.h:319
DbResult
Definition: BeSQLite.h:363

Copyright © 2017 Bentley Systems, Incorporated. All rights reserved.