diff --git a/src/imports/mvvmdatasynccore/plugins.qmltypes b/src/imports/mvvmdatasynccore/plugins.qmltypes index c5469d6..26cac33 100644 --- a/src/imports/mvvmdatasynccore/plugins.qmltypes +++ b/src/imports/mvvmdatasynccore/plugins.qmltypes @@ -115,7 +115,7 @@ Module { Property { name: "key"; type: "string" } Property { name: "dataVersion"; type: "int" } Property { name: "value"; type: "QByteArray" } - Property { name: "varValue"; type: "QVariant" } + Property { name: "variantValue"; type: "QVariant" } } Component { name: "QtMvvm::DataSyncSettingsViewModel" diff --git a/src/mvvmdatasynccore/datasyncsettingsaccessor.cpp b/src/mvvmdatasynccore/datasyncsettingsaccessor.cpp new file mode 100644 index 0000000..01cda18 --- /dev/null +++ b/src/mvvmdatasynccore/datasyncsettingsaccessor.cpp @@ -0,0 +1,96 @@ +#include "datasyncsettingsaccessor.h" +#include "datasyncsettingsaccessor_p.h" +#include + +#undef logDebug +#undef logInfo +#undef logWarning +#undef logCritical +#include + +using namespace QtMvvm; + +DataSyncSettingsAccessor::DataSyncSettingsAccessor(QObject *parent) : + DataSyncSettingsAccessor{QtDataSync::DefaultSetup, parent} +{} + +DataSyncSettingsAccessor::DataSyncSettingsAccessor(const QString &setupName, QObject *parent) : + DataSyncSettingsAccessor{new QtDataSync::DataTypeStore{setupName}, parent} +{ + d->store->setParent(this); +} + +DataSyncSettingsAccessor::DataSyncSettingsAccessor(QtDataSync::DataStore *store, QObject *parent) : + DataSyncSettingsAccessor{new QtDataSync::DataTypeStore{store}, parent} +{ + d->store->setParent(this); +} + +DataSyncSettingsAccessor::DataSyncSettingsAccessor(QtDataSync::DataTypeStore *store, QObject *parent) : + ISettingsAccessor{parent}, + d{new DataSyncSettingsAccessorPrivate{store}} +{} + +DataSyncSettingsAccessor::~DataSyncSettingsAccessor() = default; + +bool DataSyncSettingsAccessor::contains(const QString &key) const +{ + try { + return d->store->keys().contains(key); + } catch(QException &e) { + logCritical() << "Failed to check if entry" << key << "exists with error:" + << e.what(); + return false; + } +} + +QVariant DataSyncSettingsAccessor::load(const QString &key, const QVariant &defaultValue) const +{ + try { + return d->store->load(key).value(); + } catch (QtDataSync::NoDataException &e) { + Q_UNUSED(e) + return defaultValue; + } catch (QException &e) { + logCritical() << "Failed to load entry" << key << "from datasync settings with error:" + << e.what(); + return defaultValue; + } +} + +void DataSyncSettingsAccessor::save(const QString &key, const QVariant &value) +{ + try { + d->store->save({key, value}); + } catch (QException &e) { + logCritical() << "Failed to save entry" << key << "to datasync settings with error:" + << e.what(); + } +} + +void DataSyncSettingsAccessor::remove(const QString &key) +{ + try { + auto rmKeys = d->store->keys().filter(QRegularExpression{ + QStringLiteral(R"__(^%1\/.*)__").arg(QRegularExpression::escape(key)), + QRegularExpression::DontCaptureOption + }); + for(const auto &rmKey : rmKeys) + d->store->remove(rmKey); + d->store->remove(key); + } catch (QException &e) { + logCritical() << "Failed to remove entry" << key << "from datasync settings with error:" + << e.what(); + } +} + +void DataSyncSettingsAccessor::sync() +{ + // nothing needs to be done +} + +// ------------- Private Implementation ------------- + +DataSyncSettingsAccessorPrivate::DataSyncSettingsAccessorPrivate(QtDataSync::DataTypeStore *store) : + store{store} +{} diff --git a/src/mvvmdatasynccore/datasyncsettingsaccessor.h b/src/mvvmdatasynccore/datasyncsettingsaccessor.h new file mode 100644 index 0000000..e7d1eb6 --- /dev/null +++ b/src/mvvmdatasynccore/datasyncsettingsaccessor.h @@ -0,0 +1,40 @@ +#ifndef QTMVVM_DATASYNCSETTINGSACCESSOR_H +#define QTMVVM_DATASYNCSETTINGSACCESSOR_H + +#include +#include +#include + +#include "QtMvvmDataSyncCore/qtmvvmdatasynccore_global.h" +#include "QtMvvmDataSyncCore/datasyncsettingsentry.h" + +namespace QtMvvm { + +class DataSyncSettingsAccessorPrivate; +class Q_MVVMDATASYNCCORE_EXPORT DataSyncSettingsAccessor : public ISettingsAccessor +{ + Q_OBJECT + Q_INTERFACES(QtMvvm::ISettingsAccessor) + +public: + Q_INVOKABLE explicit DataSyncSettingsAccessor(QObject *parent = nullptr); + explicit DataSyncSettingsAccessor(const QString &setupName, QObject *parent = nullptr); + explicit DataSyncSettingsAccessor(QtDataSync::DataStore *store, QObject *parent = nullptr); + explicit DataSyncSettingsAccessor(QtDataSync::DataTypeStore *store, QObject *parent = nullptr); + ~DataSyncSettingsAccessor() override; + + bool contains(const QString &key) const override; + QVariant load(const QString &key, const QVariant &defaultValue) const override; + void save(const QString &key, const QVariant &value) override; + void remove(const QString &key) override; + +public Q_SLOTS: + void sync() override; + +private: + QScopedPointer d; +}; + +} + +#endif // QTMVVM_DATASYNCSETTINGSACCESSOR_H diff --git a/src/mvvmdatasynccore/datasyncsettingsaccessor_p.h b/src/mvvmdatasynccore/datasyncsettingsaccessor_p.h new file mode 100644 index 0000000..bd22a75 --- /dev/null +++ b/src/mvvmdatasynccore/datasyncsettingsaccessor_p.h @@ -0,0 +1,19 @@ +#ifndef QTMVVM_DATASYNCSETTINGSACCESSOR_P_H +#define QTMVVM_DATASYNCSETTINGSACCESSOR_P_H + +#include "qtmvvmdatasynccore_global.h" +#include "datasyncsettingsaccessor.h" + +namespace QtMvvm { + +class DataSyncSettingsAccessorPrivate +{ +public: + DataSyncSettingsAccessorPrivate(QtDataSync::DataTypeStore *store); + + QtDataSync::DataTypeStore *store; +}; + +} + +#endif // QTMVVM_DATASYNCSETTINGSACCESSOR_P_H diff --git a/src/mvvmdatasynccore/datasyncsettingsentry.cpp b/src/mvvmdatasynccore/datasyncsettingsentry.cpp new file mode 100644 index 0000000..1baf017 --- /dev/null +++ b/src/mvvmdatasynccore/datasyncsettingsentry.cpp @@ -0,0 +1,128 @@ +#include "datasyncsettingsentry.h" +#include +#if QT_HAS_INCLUDE() +#include +#define QTMVVM_HAS_OPTIONAL +#endif +using namespace QtMvvm; + +namespace QtMvvm { + +class DataSyncSettingsEntryData : public QSharedData +{ +public: + inline DataSyncSettingsEntryData() = default; + inline DataSyncSettingsEntryData(QString key) : + key{std::move(key)} + {} + + QString key; + int version = QDataStream::Qt_DefaultCompiledVersion; + QByteArray data; +#ifdef QTMVVM_HAS_OPTIONAL + mutable std::optional value; +#else + mutable QVariant value; +#endif +}; + +} + +DataSyncSettingsEntry::DataSyncSettingsEntry() : + d{new DataSyncSettingsEntryData{}} +{} + +DataSyncSettingsEntry::~DataSyncSettingsEntry() = default; + +DataSyncSettingsEntry::DataSyncSettingsEntry(const DataSyncSettingsEntry &other) = default; + +DataSyncSettingsEntry::DataSyncSettingsEntry(DataSyncSettingsEntry &&other) noexcept = default; + +DataSyncSettingsEntry &DataSyncSettingsEntry::operator=(const DataSyncSettingsEntry &other) = default; + +DataSyncSettingsEntry &DataSyncSettingsEntry::operator=(DataSyncSettingsEntry &&other) noexcept = default; + +DataSyncSettingsEntry::DataSyncSettingsEntry(QString key, QVariant value) : + d{new DataSyncSettingsEntryData{std::move(key)}} +{ + setValue(std::move(value)); +} + +QString DataSyncSettingsEntry::key() const +{ + return d->key; +} + +int DataSyncSettingsEntry::dataVersion() const +{ + return d->version; +} + +QVariant DataSyncSettingsEntry::value() const +{ +#ifdef QTMVVM_HAS_OPTIONAL + if(!d->data.isNull() && !d->value) { + QDataStream stream{d->data}; + stream.setVersion(d->version); + d->value = QVariant{}; + stream >> d->value.value(); + } + return d->value.value_or(QVariant{}); +#else + if(!d->data.isNull() && !d->value.isValid()) { + QDataStream stream{d->data}; + stream.setVersion(d->version); + stream >> d->value; + } + return d->value; +#endif +} + +void DataSyncSettingsEntry::setKey(QString key) +{ + d->key = std::move(key); +} + +void DataSyncSettingsEntry::setDataVersion(int dataVersion) +{ + if(d->version == dataVersion) + return; + + if(d->data.isNull()) + d->version = dataVersion; + else { + // update the internally stored data based on the version + auto mValue = value(); + d->version = dataVersion; + setValue(mValue); + } +} + +void DataSyncSettingsEntry::setValue(QVariant value) +{ +#ifdef QTMVVM_HAS_OPTIONAL + d->value.reset(); +#else + d->value.clear(); +#endif + d->data.clear(); + QDataStream stream{&d->data, QIODevice::WriteOnly}; + stream.setVersion(d->version); + stream << value; + d->value = std::move(value); +} + +QByteArray DataSyncSettingsEntry::valueData() const +{ + return d->data; +} + +void DataSyncSettingsEntry::setValueData(QByteArray data) +{ +#ifdef QTMVVM_HAS_OPTIONAL + d->value.reset(); +#else + d->value.clear(); +#endif + d->data = std::move(data); +} diff --git a/src/mvvmdatasynccore/datasyncsettingsentry.h b/src/mvvmdatasynccore/datasyncsettingsentry.h new file mode 100644 index 0000000..1ef55ef --- /dev/null +++ b/src/mvvmdatasynccore/datasyncsettingsentry.h @@ -0,0 +1,70 @@ +#ifndef QTMVVM_DATASYNCSETTINGSENTRY_H +#define QTMVVM_DATASYNCSETTINGSENTRY_H + +#include +#include +#include + +#include "QtMvvmDataSyncCore/qtmvvmdatasynccore_global.h" + +namespace QtMvvm { + +class DataSyncSettingsEntryData; +struct Q_MVVMDATASYNCCORE_EXPORT DataSyncSettingsEntry +{ + Q_GADGET + + Q_PROPERTY(QString key READ key WRITE setKey USER true) + Q_PROPERTY(int dataVersion READ dataVersion WRITE setDataVersion) + Q_PROPERTY(QByteArray value READ valueData WRITE setValueData) + + Q_PROPERTY(QVariant variantValue READ value WRITE setValue STORED false) + +public: + DataSyncSettingsEntry(); + ~DataSyncSettingsEntry(); + DataSyncSettingsEntry(const DataSyncSettingsEntry &other); + DataSyncSettingsEntry(DataSyncSettingsEntry &&other) noexcept; + DataSyncSettingsEntry &operator=(const DataSyncSettingsEntry &other); + DataSyncSettingsEntry &operator=(DataSyncSettingsEntry &&other) noexcept; + + DataSyncSettingsEntry(QString key, QVariant value); + template + DataSyncSettingsEntry(QString key, const T &value); + + QString key() const; + int dataVersion() const; + + QVariant value() const; + template + T value() const; + + void setKey(QString key); + void setDataVersion(int dataVersion); + void setValue(QVariant value); + +private: + QByteArray valueData() const; + void setValueData(QByteArray value); + + QSharedDataPointer d; +}; + +// ------------- Generic Implementation ------------- + +template +DataSyncSettingsEntry::DataSyncSettingsEntry(QString key, const T &value) : + DataSyncSettingsEntry{std::move(key), QVariant::fromValue(value)} +{} + +template +T DataSyncSettingsEntry::value() const +{ + return value().template value(); +} + +} + +Q_DECLARE_METATYPE(QtMvvm::DataSyncSettingsEntry) + +#endif // QTMVVM_DATASYNCSETTINGSENTRY_H diff --git a/src/mvvmdatasynccore/datasyncsettingsviewmodel.cpp b/src/mvvmdatasynccore/datasyncsettingsviewmodel.cpp index bc0d649..823639e 100644 --- a/src/mvvmdatasynccore/datasyncsettingsviewmodel.cpp +++ b/src/mvvmdatasynccore/datasyncsettingsviewmodel.cpp @@ -1,7 +1,5 @@ #include "datasyncsettingsviewmodel.h" #include "datasyncsettingsviewmodel_p.h" -#include -#include #undef logDebug #undef logInfo @@ -40,8 +38,8 @@ void DataSyncSettingsViewModel::saveValue(const QString &key, const QVariant &va try { d->store->save({key, value}); } catch (QException &e) { - qCritical() << "Failed to save entry" << key << "to datasync settings with error:" - << e.what(); + logCritical() << "Failed to save entry" << key << "to datasync settings with error:" + << e.what(); } } @@ -50,43 +48,11 @@ void DataSyncSettingsViewModel::resetValue(const QString &key) try { d->store->remove(key); } catch (QException &e) { - qCritical() << "Failed to remove entry" << key << "from datasync settings with error:" - << e.what(); + logCritical() << "Failed to remove entry" << key << "from datasync settings with error:" + << e.what(); } } - - -DataSyncSettingsEntry::DataSyncSettingsEntry() = default; - -DataSyncSettingsEntry::DataSyncSettingsEntry(QString key, const QVariant &value) : - _key{std::move(key)} -{ - setValue(value); -} - -QString DataSyncSettingsEntry::key() const -{ - return _key; -} - -QVariant DataSyncSettingsEntry::value() const -{ - QVariant value; - QDataStream stream(_value); - stream.setVersion(_dataVersion); - stream >> value; - return value; -} - -void DataSyncSettingsEntry::setValue(const QVariant &value) -{ - _value.clear(); - QDataStream stream(&_value, QIODevice::WriteOnly); - _dataVersion = stream.version(); - stream << value; -} - // ------------- Private Implementation ------------- DataSyncSettingsViewModelPrivate::DataSyncSettingsViewModelPrivate(DataSyncSettingsViewModel *q_ptr) : diff --git a/src/mvvmdatasynccore/datasyncsettingsviewmodel.h b/src/mvvmdatasynccore/datasyncsettingsviewmodel.h index 92dfa62..43c4a68 100644 --- a/src/mvvmdatasynccore/datasyncsettingsviewmodel.h +++ b/src/mvvmdatasynccore/datasyncsettingsviewmodel.h @@ -7,38 +7,10 @@ #include #include "QtMvvmDataSyncCore/qtmvvmdatasynccore_global.h" +#include "QtMvvmDataSyncCore/datasyncsettingsentry.h" namespace QtMvvm { -struct Q_MVVMDATASYNCCORE_EXPORT DataSyncSettingsEntry -{ - Q_GADGET - - Q_PROPERTY(QString key MEMBER _key USER true) - Q_PROPERTY(int dataVersion MEMBER _dataVersion) - Q_PROPERTY(QByteArray value MEMBER _value) - - Q_PROPERTY(QVariant varValue READ value WRITE setValue STORED false) - -public: - DataSyncSettingsEntry(); - DataSyncSettingsEntry(QString key, const QVariant &value); - template - DataSyncSettingsEntry(QString key, const T &value); - - QString key() const; - QVariant value() const; - template - T value() const; - - void setValue(const QVariant &value); - -private: - QString _key; - int _dataVersion = 0; - QByteArray _value; -}; - class DataSyncSettingsViewModelPrivate; class Q_MVVMDATASYNCCORE_EXPORT DataSyncSettingsViewModel : public QtMvvm::SettingsViewModel { @@ -56,21 +28,6 @@ private: QScopedPointer d; }; -// ------------- Generic Implementation ------------- - -template -DataSyncSettingsEntry::DataSyncSettingsEntry(QString key, const T &value) : - DataSyncSettingsEntry{std::move(key), QVariant::fromValue(value)} -{} - -template -T DataSyncSettingsEntry::value() const -{ - return value().template value(); -} - } -Q_DECLARE_METATYPE(QtMvvm::DataSyncSettingsEntry) - #endif // QTMVVM_DATASYNCSETTINGSVIEWMODEL_H diff --git a/src/mvvmdatasynccore/mvvmdatasynccore.pro b/src/mvvmdatasynccore/mvvmdatasynccore.pro index 58db5fb..a096c0c 100644 --- a/src/mvvmdatasynccore/mvvmdatasynccore.pro +++ b/src/mvvmdatasynccore/mvvmdatasynccore.pro @@ -16,7 +16,10 @@ HEADERS += \ exchangedevicesmodel.h \ exchangedevicesmodel_p.h \ datasyncsettingsviewmodel.h \ - datasyncsettingsviewmodel_p.h + datasyncsettingsviewmodel_p.h \ + datasyncsettingsaccessor.h \ + datasyncsettingsentry.h \ + datasyncsettingsaccessor_p.h SOURCES += \ datasyncviewmodel.cpp \ @@ -26,7 +29,9 @@ SOURCES += \ identityeditviewmodel.cpp \ networkexchangeviewmodel.cpp \ exchangedevicesmodel.cpp \ - datasyncsettingsviewmodel.cpp + datasyncsettingsviewmodel.cpp \ + datasyncsettingsaccessor.cpp \ + datasyncsettingsentry.cpp TRANSLATIONS += \ translations/qtmvvmdatasynccore_de.ts \