QtDataSync  4.2.0
A simple offline-first synchronisation framework, to synchronize data of Qt applications between devices
Public Slots | Signals | Public Member Functions | Static Public Member Functions | Properties | List of all members
QtDataSync::EventCursor Class Reference

A cursor style class to read from the global change event log. More...

#include <eventcursor.h>

+ Inheritance diagram for QtDataSync::EventCursor:

Public Slots

void setSkipObsolete (bool skipObsolete)
 WRITE accessor for EventCursor::skipObsolete.
 
void clearEventLog (quint64 offset=0)
 Clears all events from the log up to offset entries before the one this cursor points at. More...
 

Signals

void eventLogChanged (QPrivateSignal)
 Is emitted whenever a new change event was added to the database. More...
 
void indexChanged (quint64 index, QPrivateSignal)
 NOTIFY accessor for EventCursor::index.
 
void keyChanged (const QtDataSync::ObjectKey &key, QPrivateSignal)
 NOTIFY accessor for EventCursor::key.
 
void wasRemovedChanged (bool wasRemoved, QPrivateSignal)
 NOTIFY accessor for EventCursor::wasRemoved.
 
void timestampChanged (const QDateTime &timestamp, QPrivateSignal)
 NOTIFY accessor for EventCursor::timestamp.
 
void skipObsoleteChanged (bool skipObsolete, QPrivateSignal)
 NOTIFY accessor for EventCursor::skipObsolete.
 

Public Member Functions

Q_INVOKABLE QByteArray save () const
 Returns encoded position data of the cursor to be loaded again. More...
 
bool isValid () const
 READ accessor for EventCursor::valid.
 
QString setupName () const
 READ accessor for EventCursor::setupName.
 
quint64 index () const
 READ accessor for EventCursor::index.
 
QtDataSync::ObjectKey key () const
 READ accessor for EventCursor::key.
 
bool wasRemoved () const
 READ accessor for EventCursor::wasRemoved.
 
QDateTime timestamp () const
 READ accessor for EventCursor::timestamp.
 
bool skipObsolete () const
 READ accessor for EventCursor::skipObsolete.
 
Q_INVOKABLE bool hasNext () const
 Checks if there is a newer change event after the one this cursor points to. More...
 
Q_INVOKABLE bool next ()
 Advances the cursor to the next newer change event, if one exists. More...
 
Q_INVOKABLE void autoScanLog ()
 Automatically scans though all change events. More...
 
void autoScanLog (std::function< bool(const EventCursor *)> function, bool scanCurrent=true)
 Automatically scans though all change events, calling the given function on each event. More...
 
void autoScanLog (QObject *scope, std::function< bool(const EventCursor *)> function, bool scanCurrent=true)
 Automatically scans though all change events, calling the given function on each event. More...
 
template<typename TClass >
void autoScanLog (TClass *scope, bool(TClass::*function)(const EventCursor *), bool scanCurrent=true)
 Automatically scans though all change events, calling the given function on each event. More...
 
- Public Member Functions inherited from QObject
virtual const QMetaObjectmetaObject () const const
 
virtual void * qt_metacast (const char *)
 
virtual int qt_metacall (QMetaObject::Call, int, void **)
 
 QObject (QObject *parent)
 
virtual bool event (QEvent *e)
 
virtual bool eventFilter (QObject *watched, QEvent *event)
 
QString objectName () const const
 
void setObjectName (const QString &name)
 
bool isWidgetType () const const
 
bool isWindowType () const const
 
bool signalsBlocked () const const
 
bool blockSignals (bool block)
 
QThreadthread () const const
 
void moveToThread (QThread *targetThread)
 
int startTimer (int interval, Qt::TimerType timerType)
 
int startTimer (std::chrono::milliseconds time, Qt::TimerType timerType)
 
void killTimer (int id)
 
findChild (const QString &name, Qt::FindChildOptions options) const const
 
QList< T > findChildren (const QString &name, Qt::FindChildOptions options) const const
 
QList< T > findChildren (const QRegExp &regExp, Qt::FindChildOptions options) const const
 
QList< T > findChildren (const QRegularExpression &re, Qt::FindChildOptions options) const const
 
const QObjectList & children () const const
 
void setParent (QObject *parent)
 
void installEventFilter (QObject *filterObj)
 
void removeEventFilter (QObject *obj)
 
QMetaObject::Connection connect (const QObject *sender, const char *signal, const char *method, Qt::ConnectionType type) const const
 
bool disconnect (const char *signal, const QObject *receiver, const char *method) const const
 
bool disconnect (const QObject *receiver, const char *method) const const
 
void dumpObjectTree ()
 
void dumpObjectInfo ()
 
void dumpObjectTree () const const
 
void dumpObjectInfo () const const
 
bool setProperty (const char *name, const QVariant &value)
 
QVariant property (const char *name) const const
 
QList< QByteArraydynamicPropertyNames () const const
 
void destroyed (QObject *obj)
 
void objectNameChanged (const QString &objectName)
 
QObjectparent () const const
 
bool inherits (const char *className) const const
 
void deleteLater ()
 

Static Public Member Functions

static bool isEventLogActive (const QString &setupName=DefaultSetup)
 Checks if the eventlog is currently beeing collected or not. More...
 
static EventCursorfirst (QObject *parent=nullptr)
 Create a cursor positioned on the oldest change event. More...
 
static EventCursorfirst (const QString &setupName, QObject *parent=nullptr)
 Create a cursor positioned on the oldest change event. More...
 
static EventCursorlast (QObject *parent=nullptr)
 Create a cursor positioned on the newest change event. More...
 
static EventCursorlast (const QString &setupName, QObject *parent=nullptr)
 Create a cursor positioned on the newest change event. More...
 
static EventCursorcreate (quint64 index, QObject *parent=nullptr)
 Create a cursor positioned on the given index, if it is a valid index. More...
 
static EventCursorcreate (quint64 index, const QString &setupName, QObject *parent=nullptr)
 Create a cursor positioned on the given index, if it is a valid index. More...
 
static EventCursorload (const QByteArray &data, QObject *parent=nullptr)
 Create a cursor positioned on the index provided by the previously stored data, if still valid. More...
 
static EventCursorload (const QByteArray &data, const QString &setupName, QObject *parent=nullptr)
 Create a cursor positioned on the index provided by the previously stored data, if still valid. More...
 
- Static Public Member Functions inherited from QObject
QString tr (const char *sourceText, const char *disambiguation, int n)
 
QString trUtf8 (const char *sourceText, const char *disambiguation, int n)
 
QMetaObject::Connection connect (const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
 
QMetaObject::Connection connect (const QObject *sender, const QMetaMethod &signal, const QObject *receiver, const QMetaMethod &method, Qt::ConnectionType type)
 
QMetaObject::Connection connect (const QObject *sender, PointerToMemberFunction signal, const QObject *receiver, PointerToMemberFunction method, Qt::ConnectionType type)
 
QMetaObject::Connection connect (const QObject *sender, PointerToMemberFunction signal, Functor functor)
 
QMetaObject::Connection connect (const QObject *sender, PointerToMemberFunction signal, const QObject *context, Functor functor, Qt::ConnectionType type)
 
bool disconnect (const QObject *sender, const char *signal, const QObject *receiver, const char *method)
 
bool disconnect (const QObject *sender, const QMetaMethod &signal, const QObject *receiver, const QMetaMethod &method)
 
bool disconnect (const QMetaObject::Connection &connection)
 
bool disconnect (const QObject *sender, PointerToMemberFunction signal, const QObject *receiver, PointerToMemberFunction method)
 

Properties

bool valid
 Holds whether the cursor is positioned on a valid record. More...
 
QString setupName
 Holds the name of the setup this cursor operates on. More...
 
quint64 index
 Holds the current position of the cursor. More...
 
QtDataSync::ObjectKey key
 Holds the key of the dataset this cursor is positioned on. More...
 
bool wasRemoved
 Holds the information whether the dataset was changed or removed. More...
 
QDateTime timestamp
 Provides the timestamp of when the change occured. More...
 
bool skipObsolete
 Specify if the cursor should automatically skip obsolete changes when advancing. More...
 
- Properties inherited from QObject
 objectName
 

Additional Inherited Members

- Protected Member Functions inherited from QObject
QObjectsender () const const
 
int senderSignalIndex () const const
 
int receivers (const char *signal) const const
 
bool isSignalConnected (const QMetaMethod &signal) const const
 
virtual void timerEvent (QTimerEvent *event)
 
virtual void childEvent (QChildEvent *event)
 
virtual void customEvent (QEvent *event)
 
virtual void connectNotify (const QMetaMethod &signal)
 
virtual void disconnectNotify (const QMetaMethod &signal)
 

Detailed Description

A cursor style class to read from the global change event log.

The EventCursor class provides a simple interface to walk through all the changes that have been done on the internal data set. Unlike the DataStore, which presents the actual data but does give no guarantees on completeness of change events, this class can be used to deterministically handle all changes in chronological order.

Note
By default, a datasync instance does not create an eventlog. Enable it via the Setup::eventLoggingMode property
Attention
This class does not hold any data itself, only what was changed, when it happend and whether it was changed or deleted. This means if the same dataset is changed multiple times in a row, you will get as many change events as it was changed, but you can only ever read the most recent dataset from the current datastore.
See also
DataStore, Setup::eventLoggingMode, EventCursor::skipObsolete

Definition at line 19 of file eventcursor.h.

Member Function Documentation

◆ autoScanLog() [1/4]

QtDataSync::EventCursor::autoScanLog ( )

Automatically scans though all change events.

Exceptions
EventCursorExceptionThrown if access to the underlying database failed

This method basically just calles next() in a loop to walk through all existing change events until it reaches the current one. After that happend, the cursor will now react on changes to the events in the database and automatically advance forward as soon as a new event was logged there.

This method honors the value of skipObsolete

See also
EventCursor::hasNext, EventCursor::next, EventCursor::skipObsolete, EventCursor::indexChanged

◆ autoScanLog() [2/4]

QtDataSync::EventCursor::autoScanLog ( std::function< bool(const EventCursor *)>  function,
bool  scanCurrent = true 
)

Automatically scans though all change events, calling the given function on each event.

Parameters
functionThe callback to be called for each event visited
scanCurrentSpecify if the event currently pointed should be passed to the function before advancing to the next one
Exceptions
EventCursorExceptionThrown if access to the underlying database failed

This method basically just calles next() in a loop to walk through all existing change events until it reaches the current one. After that happend, the cursor will now react on changes to the events in the database and automatically advance forward as soon as a new event was logged there.

For every event visited that way, the function callback is called once with this cursor passed to it. The method can return true to continue the loop or false to end it.

This method honors the value of skipObsolete

See also
EventCursor::hasNext, EventCursor::next, EventCursor::skipObsolete, EventCursor::indexChanged

◆ autoScanLog() [3/4]

QtDataSync::EventCursor::autoScanLog ( QObject scope,
std::function< bool(const EventCursor *)>  function,
bool  scanCurrent = true 
)

Automatically scans though all change events, calling the given function on each event.

Parameters
scopeThe object scope to limit the callback to. Only call as long as the scope still exists
functionThe callback to be called for each event visited
scanCurrentSpecify if the event currently pointed should be passed to the function before advancing to the next one
Exceptions
EventCursorExceptionThrown if access to the underlying database failed

This method basically just calles next() in a loop to walk through all existing change events until it reaches the current one. After that happend, the cursor will now react on changes to the events in the database and automatically advance forward as soon as a new event was logged there.

For every event visited that way, the function callback is called once with this cursor passed to it. The method can return true to continue the loop or false to end it.

This method honors the value of skipObsolete

See also
EventCursor::hasNext, EventCursor::next, EventCursor::skipObsolete, EventCursor::indexChanged

◆ autoScanLog() [4/4]

template<typename TClass >
void QtDataSync::EventCursor::autoScanLog ( TClass *  scope,
bool(TClass::*)(const EventCursor *)  function,
bool  scanCurrent = true 
)

Automatically scans though all change events, calling the given function on each event.

Parameters
scopeThe object scope to limit the callback to. Only call as long as the scope still exists
functionThe callback to be called for each event visited
scanCurrentSpecify if the event currently pointed should be passed to the function before advancing to the next one
Exceptions
EventCursorExceptionThrown if access to the underlying database failed

This method basically just calles next() in a loop to walk through all existing change events until it reaches the current one. After that happend, the cursor will now react on changes to the events in the database and automatically advance forward as soon as a new event was logged there.

For every event visited that way, the function callback is called once with this cursor passed to it. The method can return true to continue the loop or false to end it.

This method honors the value of skipObsolete

See also
EventCursor::hasNext, EventCursor::next, EventCursor::skipObsolete, EventCursor::indexChanged

Definition at line 160 of file eventcursor.h.

◆ clearEventLog

QtDataSync::EventCursor::clearEventLog ( quint64  offset = 0)
slot

Clears all events from the log up to offset entries before the one this cursor points at.

Parameters
offsetThe number of events to keep before the current one
Exceptions
EventCursorExceptionThrown if access to the underlying database failed

When called, all events that are older than the one currently pointed to are deleted. You can additionally keep entries by specifing an offset. If the offset is for example 5, there will be 5 entries left that are older than the current one after the cleanup.

Note
This method does not the value of skipObsolete
See also
EventCursor::index

◆ create() [1/2]

QtDataSync::EventCursor::create ( quint64  index,
QObject parent = nullptr 
)
static

Create a cursor positioned on the given index, if it is a valid index.

Parameters
indexThe index of the change event to position the cursor on
parentThe parent object to set as parent of the event cursor
Returns
A valid eventcursor, positioned on the given index, or an invalid cursor if no changes exist for that index
Exceptions
EventCursorExceptionThrown if access to the underlying database failed

If no setup name is specified, the cursor is created for the default setup name

See also
EventCursor::first, EventCursor::last, EventCursor::load, EventCursor::valid, EventCursor::isEventLogActive

◆ create() [2/2]

QtDataSync::EventCursor::create ( quint64  index,
const QString setupName,
QObject parent = nullptr 
)
static

Create a cursor positioned on the given index, if it is a valid index.

Parameters
setupNameThe name of the setup to create the cursor for
indexThe index of the change event to position the cursor on
parentThe parent object to set as parent of the event cursor
Returns
A valid eventcursor, positioned on the given index, or an invalid cursor if no changes exist for that index
Exceptions
EventCursorExceptionThrown if access to the underlying database failed

If no setup name is specified, the cursor is created for the default setup name

See also
EventCursor::first, EventCursor::last, EventCursor::load, EventCursor::valid, EventCursor::isEventLogActive

◆ eventLogChanged

QtDataSync::EventCursor::eventLogChanged ( QPrivateSignal  )
signal

Is emitted whenever a new change event was added to the database.

This signal does not mean that the event the current cursor is pointing to has changed. It only notifies you that there are new events that have been added to the underlying event log. This signal is used by autoScanLog() to automatically advance through new events.

See also
EventCursor::autoScanLog, EventCursor::indexChanged

◆ first() [1/2]

QtDataSync::EventCursor::first ( QObject parent = nullptr)
static

Create a cursor positioned on the oldest change event.

Parameters
parentThe parent object to set as parent of the event cursor
Returns
A valid eventcursor, positioned on the oldest available change, or an invalid cursor if no changes exist
Exceptions
EventCursorExceptionThrown if access to the underlying database failed

If no setup name is specified, the cursor is created for the default setup name

See also
EventCursor::last, EventCursor::create, EventCursor::load, EventCursor::valid, EventCursor::isEventLogActive

◆ first() [2/2]

QtDataSync::EventCursor::first ( const QString setupName,
QObject parent = nullptr 
)
static

Create a cursor positioned on the oldest change event.

Parameters
setupNameThe name of the setup to create the cursor for
parentThe parent object to set as parent of the event cursor
Returns
A valid eventcursor, positioned on the oldest available change, or an invalid cursor if no changes exist
Exceptions
EventCursorExceptionThrown if access to the underlying database failed

If no setup name is specified, the cursor is created for the default setup name

See also
EventCursor::last, EventCursor::create, EventCursor::load, EventCursor::valid, EventCursor::isEventLogActive

◆ hasNext()

QtDataSync::EventCursor::hasNext ( ) const

Checks if there is a newer change event after the one this cursor points to.

Returns
True if there is at least one newer change event currently available, false if not
Exceptions
EventCursorExceptionThrown if access to the underlying database failed

This method does not change the position or general state of the current cursor. This method honors the value of skipObsolete

See also
EventCursor::next, EventCursor::valid, EventCursor::skipObsolete

◆ isEventLogActive()

QtDataSync::EventCursor::isEventLogActive ( const QString setupName = DefaultSetup)
static

Checks if the eventlog is currently beeing collected or not.

Parameters
setupNameThe name of the setup to check for an active log

Eventlogging must be explicitly enabled when creating a setup. In case you do not know at the point of using the cursor whether the log is actually available, you can use this method to check

Attention
In case the log is not enabled, all creation methods to obtain a cursor will fail and instead return invalid cursors
See also
Setup::eventLoggingMode, EventCursor::valid

◆ last() [1/2]

QtDataSync::EventCursor::last ( QObject parent = nullptr)
static

Create a cursor positioned on the newest change event.

Parameters
parentThe parent object to set as parent of the event cursor
Returns
A valid eventcursor, positioned on the newest available change, or an invalid cursor if no changes exist
Exceptions
EventCursorExceptionThrown if access to the underlying database failed

If no setup name is specified, the cursor is created for the default setup name

See also
EventCursor::first, EventCursor::create, EventCursor::load, EventCursor::valid, EventCursor::isEventLogActive

◆ last() [2/2]

QtDataSync::EventCursor::last ( const QString setupName,
QObject parent = nullptr 
)
static

Create a cursor positioned on the newest change event.

Parameters
setupNameThe name of the setup to create the cursor for
parentThe parent object to set as parent of the event cursor
Returns
A valid eventcursor, positioned on the newest available change, or an invalid cursor if no changes exist
Exceptions
EventCursorExceptionThrown if access to the underlying database failed

If no setup name is specified, the cursor is created for the default setup name

See also
EventCursor::first, EventCursor::create, EventCursor::load, EventCursor::valid, EventCursor::isEventLogActive

◆ load() [1/2]

QtDataSync::EventCursor::load ( const QByteArray data,
QObject parent = nullptr 
)
static

Create a cursor positioned on the index provided by the previously stored data, if still valid.

Parameters
dataThe data to create the cursor from
parentThe parent object to set as parent of the event cursor
Returns
A valid eventcursor, positioned on the index part of the data, or an invalid cursor if no changes exist for that index
Exceptions
EventCursorExceptionThrown if access to the underlying database failed

If no setup name is specified, the cursor is created for the default setup name. The following properties are restored from the data:

Use save() to save the data of an existing cursor so you can later load it again using this method.

Note
The index is only set in case the returned cursor is valid. For an invalid cursor, only the skipObsolete property will be set.
See also
EventCursor::first, EventCursor::last, EventCursor::create, EventCursor::valid, EventCursor::isEventLogActive, EventCursor::save, EventCursor::skipObsolete

◆ load() [2/2]

QtDataSync::EventCursor::load ( const QByteArray data,
const QString setupName,
QObject parent = nullptr 
)
static

Create a cursor positioned on the index provided by the previously stored data, if still valid.

Parameters
setupNameThe name of the setup to create the cursor for
dataThe data to create the cursor from
parentThe parent object to set as parent of the event cursor
Returns
A valid eventcursor, positioned on the index part of the data, or an invalid cursor if no changes exist for that index
Exceptions
EventCursorExceptionThrown if access to the underlying database failed

If no setup name is specified, the cursor is created for the default setup name. The following properties are restored from the data:

Use save() to save the data of an existing cursor so you can later load it again using this method.

Note
The index is only set in case the returned cursor is valid. For an invalid cursor, only the skipObsolete property will be set.
See also
EventCursor::first, EventCursor::last, EventCursor::create, EventCursor::valid, EventCursor::isEventLogActive, EventCursor::save, EventCursor::skipObsolete

◆ next()

QtDataSync::EventCursor::next ( )

Advances the cursor to the next newer change event, if one exists.

Returns
True if the cursor was able to advance to a new change event, false if not
Exceptions
EventCursorExceptionThrown if access to the underlying database failed

In case there was a new change event, after calling this method the cursor is now positioned on that newer record and in case it was previously valid now still is valid and true is returned. If however there was no new change event to advance to, the cursor stayes unchanged and false is returned. This means the cursor is not set to be invalid if this method fails, only the return value or the index can be used to check if the next operation actually did anything.

This method honors the value of skipObsolete

See also
EventCursor::hasNext, EventCursor::autoScanLog, EventCursor::skipObsolete

◆ save()

QtDataSync::EventCursor::save ( ) const

Returns encoded position data of the cursor to be loaded again.

Returns
Encoded data of the current cursor that can be used to recreate it.

The following properties are encoded into the data:

See also
EventCursor::load

Property Documentation

◆ index

QtDataSync::EventCursor::index
read

Holds the current position of the cursor.

Default: 0

This index is unqiue and can uniquely identify an event. They are automatically generate and are strictly ascending, meaning that newer events will always have a higher index compared to an older event.

Accessors
READindex()
NOTIFYindexChanged()
See also
EventCursor::create, EventCursor::key

Definition at line 29 of file eventcursor.h.

◆ key

QtDataSync::EventCursor::key
read

Holds the key of the dataset this cursor is positioned on.

Default: empty

This key contains both, the name of the class and the id of the dataset that was changed.

Accessors
READkey()
NOTIFYkeyChanged()
See also
QtDataSync::ObjectKey, EventCursor::wasRemoved

Definition at line 31 of file eventcursor.h.

◆ setupName

QtDataSync::EventCursor::setupName
read

Holds the name of the setup this cursor operates on.

Default: QtDataSync::DefaultSetup

The setup name is the name that was passed to the Setup::create method to create the datasync instance this cursor is refering to.

Accessors
READsetupName()
CONSTANT
See also
QtDataSync::DefaultSetup, Setup::create

Definition at line 26 of file eventcursor.h.

◆ skipObsolete

QtDataSync::EventCursor::skipObsolete
readwrite

Specify if the cursor should automatically skip obsolete changes when advancing.

Default: true

If skipping obsolete entries is enabled, the cursor will automatically skip multiple change events on the same dataset and only consider the most recent ones. If set to false, all entries are used instead.

A simple example. Consider the following chain of events:

001 [MyType:Id1] change <- cursor positioned here
002 [MyType:Id2] change
003 [MyType:Id1] delete
004 [MyType:Id3] delete
005 [MyType:Id1] change

If this property is set to true, calling next() will move it to 002. Calling next again will make it skip 003 and move to 004 instead, because there is a newer change event for the same dataset (005). Calling next one more time then moves to 005. If this property had been disabled, entry 003 would not have been skipped, event though the change that was done has already been succeeded by a newer one.

Note
This property *only** affects the next(), hasNext() and autoScanLog() methods. It is still possible to create a cursor on an obsolete event via create()
Accessors
READskipObsolete()
WRITEsetSkipObsolete()
NOTIFYskipObsoleteChanged()
See also
EventCursor::next, EventCursor::hasNext, EventCursor::autoScanLog, EventCursor::create, EventCursor::index

Definition at line 38 of file eventcursor.h.

◆ timestamp

QtDataSync::EventCursor::timestamp
read

Provides the timestamp of when the change occured.

Default: invalid

Timestamps are generated internally based on the current local time and then converted to UTC the moment a dataset was changed. This property loads the UTC variant and converts it back to the current local time, which means this property always returns the time converter to the current local time. If you need UTC timestamps, convert it back. The timestamp contains the date and time with milliseconds precision.

Accessors
READtimestamp()
NOTIFYtimestampChanged()
See also
EventCursor::key, EventCursor::index

Definition at line 35 of file eventcursor.h.

◆ valid

QtDataSync::EventCursor::valid
read

Holds whether the cursor is positioned on a valid record.

Default: false

This can be used to check if an eventcursor returned from one of the static functions is actually valid.

Note
A once valid eventcursor will only ever advance forward to another valid position and thus cannot become invalid
Accessors
READisValid()
CONSTANT
See also
EventCursor::first, EventCursor::last, EventCursor::create, EventCursor::load

Definition at line 24 of file eventcursor.h.

◆ wasRemoved

QtDataSync::EventCursor::wasRemoved
read

Holds the information whether the dataset was changed or removed.

Default: false

If a change event created a new dataset or modified an existing one, than this property is set to false. If an existing dataset was deleted it is set to true.

Accessors
READwasRemoved()
NOTIFYwasRemovedChanged()
See also
EventCursor::key

Definition at line 33 of file eventcursor.h.


The documentation for this class was generated from the following files: