From ae4b64b198a143240aa5dd1e202e5016abfdae71 Mon Sep 17 00:00:00 2001 From: Christian Mollekopf Date: Thu, 8 Dec 2016 13:18:19 +0100 Subject: Wrap references in a Reerence type. This allows us to make sure that references are not taken out of context (the resource). Because we need to use the type-specific accessors more we also ran into a problem that we cannot "downcast" a reference with the change recording still working, for that we have the cast() operator now. --- common/domain/applicationdomaintype.cpp | 35 ++++++++++++---- common/domain/applicationdomaintype.h | 61 +++++++++++++++++++++++++--- common/propertymapper.cpp | 19 +++++++++ common/query.h | 11 ++--- common/queryrunner.cpp | 6 +-- common/specialpurposepreprocessor.cpp | 20 +++++---- common/storage/entitystore.cpp | 3 +- common/typeindex.cpp | 6 +++ examples/dummyresource/resourcefactory.cpp | 25 ++++++------ examples/imapresource/imapresource.cpp | 8 ++-- examples/maildirresource/maildirresource.cpp | 8 ++-- tests/clientapitest.cpp | 6 +-- tests/domainadaptortest.cpp | 2 + tests/mailquerybenchmark.cpp | 10 ++--- tests/pipelinebenchmark.cpp | 8 ++-- tests/querytest.cpp | 60 +++++++++++---------------- 16 files changed, 188 insertions(+), 100 deletions(-) diff --git a/common/domain/applicationdomaintype.cpp b/common/domain/applicationdomaintype.cpp index a655871..f00f3ed 100644 --- a/common/domain/applicationdomaintype.cpp +++ b/common/domain/applicationdomaintype.cpp @@ -31,7 +31,16 @@ namespace ApplicationDomain { constexpr const char *Mail::ThreadId::name; -void copyBuffer(Sink::ApplicationDomain::BufferAdaptor &buffer, Sink::ApplicationDomain::BufferAdaptor &memoryAdaptor, const QList &properties, bool copyBlobs) +int foo = [] { + QMetaType::registerEqualsComparator(); + QMetaType::registerDebugStreamOperator(); + QMetaType::registerConverter(); + QMetaType::registerDebugStreamOperator(); + QMetaType::registerDebugStreamOperator(); + return 0; +}(); + +void copyBuffer(Sink::ApplicationDomain::BufferAdaptor &buffer, Sink::ApplicationDomain::BufferAdaptor &memoryAdaptor, const QList &properties, bool copyBlobs, bool pruneReferences) { auto propertiesToCopy = properties; if (properties.isEmpty()) { @@ -44,6 +53,8 @@ void copyBuffer(Sink::ApplicationDomain::BufferAdaptor &buffer, Sink::Applicatio auto newPath = oldPath + "copy"; QFile::copy(oldPath, newPath); memoryAdaptor.setProperty(property, QVariant::fromValue(BLOB{newPath})); + } else if (pruneReferences && value.canConvert()) { + continue; } else { memoryAdaptor.setProperty(property, value); } @@ -51,14 +62,16 @@ void copyBuffer(Sink::ApplicationDomain::BufferAdaptor &buffer, Sink::Applicatio } ApplicationDomainType::ApplicationDomainType() - :mAdaptor(new MemoryBufferAdaptor()) + :mAdaptor(new MemoryBufferAdaptor()), + mChangeSet(new QSet()) { } ApplicationDomainType::ApplicationDomainType(const QByteArray &resourceInstanceIdentifier) :mAdaptor(new MemoryBufferAdaptor()), - mResourceInstanceIdentifier(resourceInstanceIdentifier) + mResourceInstanceIdentifier(resourceInstanceIdentifier), + mChangeSet(new QSet()) { } @@ -67,11 +80,13 @@ ApplicationDomainType::ApplicationDomainType(const QByteArray &resourceInstanceI : mAdaptor(adaptor), mResourceInstanceIdentifier(resourceInstanceIdentifier), mIdentifier(identifier), - mRevision(revision) + mRevision(revision), + mChangeSet(new QSet()) { } ApplicationDomainType::ApplicationDomainType(const ApplicationDomainType &other) + : mChangeSet(new QSet()) { *this = other; } @@ -79,7 +94,9 @@ ApplicationDomainType::ApplicationDomainType(const ApplicationDomainType &other) ApplicationDomainType& ApplicationDomainType::operator=(const ApplicationDomainType &other) { mAdaptor = other.mAdaptor; - mChangeSet = other.mChangeSet; + if (other.mChangeSet) { + *mChangeSet = *other.mChangeSet; + } mResourceInstanceIdentifier = other.mResourceInstanceIdentifier; mIdentifier = other.mIdentifier; mRevision = other.mRevision; @@ -110,7 +127,7 @@ QVariant ApplicationDomainType::getProperty(const QByteArray &key) const void ApplicationDomainType::setProperty(const QByteArray &key, const QVariant &value) { Q_ASSERT(mAdaptor); - mChangeSet.insert(key); + mChangeSet->insert(key); mAdaptor->setProperty(key, value); } @@ -122,7 +139,7 @@ void ApplicationDomainType::setResource(const QByteArray &identifier) void ApplicationDomainType::setProperty(const QByteArray &key, const ApplicationDomainType &value) { Q_ASSERT(!value.identifier().isEmpty()); - setProperty(key, value.identifier()); + setProperty(key, QVariant::fromValue(Reference{value.identifier()})); } QByteArray ApplicationDomainType::getBlobProperty(const QByteArray &key) const @@ -152,12 +169,12 @@ void ApplicationDomainType::setBlobProperty(const QByteArray &key, const QByteAr void ApplicationDomainType::setChangedProperties(const QSet &changeset) { - mChangeSet = changeset; + *mChangeSet = changeset; } QByteArrayList ApplicationDomainType::changedProperties() const { - return mChangeSet.toList(); + return mChangeSet->toList(); } QByteArrayList ApplicationDomainType::availableProperties() const diff --git a/common/domain/applicationdomaintype.h b/common/domain/applicationdomaintype.h index 21e42cf..1c0f208 100644 --- a/common/domain/applicationdomaintype.h +++ b/common/domain/applicationdomaintype.h @@ -73,12 +73,12 @@ #define SINK_REFERENCE_PROPERTY(TYPE, NAME, LOWERCASENAME) \ struct NAME { \ static constexpr const char *name = #LOWERCASENAME; \ - typedef QByteArray Type; \ + typedef Reference Type; \ typedef ApplicationDomain::TYPE ReferenceType; \ }; \ void set##NAME(const ApplicationDomain::TYPE &value) { setProperty(NAME::name, value); } \ - void set##NAME(const QByteArray &value) { setProperty(NAME::name, QVariant::fromValue(value)); } \ - QByteArray get##NAME() const { return getProperty(NAME::name).value(); } \ + void set##NAME(const QByteArray &value) { setProperty(NAME::name, QVariant::fromValue(Reference{value})); } \ + QByteArray get##NAME() const { return getProperty(NAME::name).value().value; } \ #define SINK_INDEX_PROPERTY(TYPE, NAME, LOWERCASENAME) \ struct NAME { \ @@ -102,7 +102,27 @@ struct BLOB { QString value; }; -void copyBuffer(Sink::ApplicationDomain::BufferAdaptor &buffer, Sink::ApplicationDomain::BufferAdaptor &memoryAdaptor, const QList &properties, bool copyBlobs); +/** + * Internal type. + * + * Represents a reference to another entity in the same resource. + */ +struct Reference { + Reference() = default; + Reference(const Reference &) = default; + Reference(const QByteArray &id) : value(id) {}; + Reference(const char *id) : value(id) {}; + ~Reference() = default; + bool operator==(const Reference &other) const { + return value == other.value; + } + operator QByteArray() const { + return value; + } + QByteArray value; +}; + +void copyBuffer(Sink::ApplicationDomain::BufferAdaptor &buffer, Sink::ApplicationDomain::BufferAdaptor &memoryAdaptor, const QList &properties, bool copyBlobs, bool pruneReferences); /** * The domain type interface has two purposes: @@ -121,6 +141,14 @@ public: ApplicationDomainType(const ApplicationDomainType &other); ApplicationDomainType& operator=(const ApplicationDomainType &other); + template + DomainType cast() { + static_assert(std::is_base_of::value, "You can only cast to base classes of ApplicationDomainType."); + DomainType t = *this; + t.mChangeSet = mChangeSet; + return t; + } + /** * Returns an in memory representation of the same entity. */ @@ -140,7 +168,7 @@ public: { auto memoryAdaptor = QSharedPointer::create(); Q_ASSERT(domainType.mAdaptor); - copyBuffer(*(domainType.mAdaptor), *memoryAdaptor, properties, true); + copyBuffer(*(domainType.mAdaptor), *memoryAdaptor, properties, true, true); return QSharedPointer::create(QByteArray{}, QByteArray{}, 0, memoryAdaptor); } @@ -195,7 +223,7 @@ public: private: friend QDebug operator<<(QDebug, const ApplicationDomainType &); QSharedPointer mAdaptor; - QSet mChangeSet; + QSharedPointer> mChangeSet; /* * Each domain object needs to store the resource, identifier, revision triple so we can link back to the storage location. */ @@ -223,6 +251,19 @@ inline QDebug operator<< (QDebug d, const ApplicationDomainType &type) return d; } +inline QDebug operator<< (QDebug d, const Reference &ref) +{ + d << ref.value; + return d; +} + +inline QDebug operator<< (QDebug d, const BLOB &blob) +{ + d << blob.value; + return d; +} + + struct SINK_EXPORT SinkAccount : public ApplicationDomainType { typedef QSharedPointer Ptr; explicit SinkAccount(const QByteArray &resourceInstanceIdentifier, const QByteArray &identifier, qint64 revision, const QSharedPointer &adaptor); @@ -318,6 +359,13 @@ struct SINK_EXPORT Mail : public Entity { SINK_INDEX_PROPERTY(QByteArray, ThreadId, threadId); }; +inline QDebug operator<< (QDebug d, const Mail::Contact &c) +{ + d << "Contact(" << c.name << ", " << c.emailAddress << ")"; + return d; +} + + /** * The status of an account or resource. * @@ -454,3 +502,4 @@ Q_DECLARE_METATYPE(Sink::ApplicationDomain::Mail::Contact) Q_DECLARE_METATYPE(Sink::ApplicationDomain::Error) Q_DECLARE_METATYPE(Sink::ApplicationDomain::Progress) Q_DECLARE_METATYPE(Sink::ApplicationDomain::BLOB) +Q_DECLARE_METATYPE(Sink::ApplicationDomain::Reference) diff --git a/common/propertymapper.cpp b/common/propertymapper.cpp index 249221a..4cfe154 100644 --- a/common/propertymapper.cpp +++ b/common/propertymapper.cpp @@ -41,6 +41,15 @@ flatbuffers::uoffset_t variantToProperty(const QV return 0; } +template <> +flatbuffers::uoffset_t variantToProperty(const QVariant &property, flatbuffers::FlatBufferBuilder &fbb) +{ + if (property.isValid()) { + return fbb.CreateString(property.value().value.toStdString()).o; + } + return 0; +} + template <> flatbuffers::uoffset_t variantToProperty(const QVariant &property, flatbuffers::FlatBufferBuilder &fbb) { @@ -129,6 +138,16 @@ QVariant propertyToVariant(const flatbuffers::Str return QVariant(); } +template <> +QVariant propertyToVariant(const flatbuffers::String *property) +{ + if (property) { + // We have to copy the memory, otherwise it would become eventually invalid + return QVariant::fromValue(Sink::ApplicationDomain::Reference{QString::fromStdString(property->c_str()).toUtf8()}); + } + return QVariant(); +} + template <> QVariant propertyToVariant(const flatbuffers::String *property) { diff --git a/common/query.h b/common/query.h index b69639b..c265f92 100644 --- a/common/query.h +++ b/common/query.h @@ -325,16 +325,17 @@ public: } template - Query &filter(const QVariant &value) + Query &filter(const typename T::Type &value) { - filter(T::name, value); + filter(T::name, QVariant::fromValue(value)); return *this; } template - Query &containsFilter(const QVariant &value) + Query &containsFilter(const QByteArray &value) { - QueryBase::filter(T::name, QueryBase::Comparator(value, QueryBase::Comparator::Contains)); + static_assert(std::is_same::value, "The contains filter is only implemented for QByteArray in QByteArrayList"); + QueryBase::filter(T::name, QueryBase::Comparator(QVariant::fromValue(value), QueryBase::Comparator::Contains)); return *this; } @@ -366,7 +367,7 @@ public: template Query &filter(const ApplicationDomain::Entity &value) { - filter(T::name, QVariant::fromValue(value.identifier())); + filter(T::name, QVariant::fromValue(ApplicationDomain::Reference{value.identifier()})); return *this; } diff --git a/common/queryrunner.cpp b/common/queryrunner.cpp index cf56268..d6a90de 100644 --- a/common/queryrunner.cpp +++ b/common/queryrunner.cpp @@ -224,15 +224,15 @@ QPair QueryWorker::executeInitialQuery( if (!query.parentProperty().isEmpty()) { if (parent) { SinkTrace() << "Running initial query for parent:" << parent->identifier(); - modifiedQuery.filter(query.parentProperty(), Query::Comparator(parent->identifier())); + modifiedQuery.filter(query.parentProperty(), Query::Comparator(QVariant::fromValue(Sink::ApplicationDomain::Reference{parent->identifier()}))); } else { SinkTrace() << "Running initial query for toplevel"; - modifiedQuery.filter(query.parentProperty(), Query::Comparator(QVariant())); + modifiedQuery.filter(query.parentProperty(), Query::Comparator(QVariant{})); } } auto entityStore = EntityStore{mResourceContext}; - auto preparedQuery = DataStoreQuery{query, ApplicationDomain::getTypeName(), entityStore}; + auto preparedQuery = DataStoreQuery{modifiedQuery, ApplicationDomain::getTypeName(), entityStore}; auto resultSet = preparedQuery.execute(); SinkTrace() << "Filtered set retrieved. " << Log::TraceTime(time.elapsed()); diff --git a/common/specialpurposepreprocessor.cpp b/common/specialpurposepreprocessor.cpp index ce1a218..e73e4ce 100644 --- a/common/specialpurposepreprocessor.cpp +++ b/common/specialpurposepreprocessor.cpp @@ -59,7 +59,7 @@ QByteArray SpecialPurposeProcessor::ensureFolder(const QByteArray &specialPurpos }); if (!mSpecialPurposeFolders.contains(specialPurpose)) { - SinkTrace() << "Failed to find a drafts folder, creating a new one"; + SinkTrace() << "Failed to find a " << specialPurpose << " folder, creating a new one"; auto folder = ApplicationDomain::Folder::create(mResourceInstanceIdentifier); folder.setSpecialPurpose(QByteArrayList() << specialPurpose); folder.setName(sSpecialPurposeFolders.value(specialPurpose)); @@ -74,15 +74,21 @@ QByteArray SpecialPurposeProcessor::ensureFolder(const QByteArray &specialPurpos void SpecialPurposeProcessor::moveToFolder(Sink::ApplicationDomain::ApplicationDomainType &newEntity) { - if (newEntity.getProperty(ApplicationDomain::Mail::Trash::name).toBool()) { - newEntity.setProperty("folder", ensureFolder(ApplicationDomain::SpecialPurpose::Mail::trash)); + using namespace Sink::ApplicationDomain; + auto mail = newEntity.cast(); + if (mail.getTrash()) { + auto f = ensureFolder(ApplicationDomain::SpecialPurpose::Mail::trash); + SinkTrace() << "Setting trash folder: " << f; + mail.setFolder(f); return; } - if (newEntity.getProperty(ApplicationDomain::Mail::Draft::name).toBool()) { - newEntity.setProperty("folder", ensureFolder(ApplicationDomain::SpecialPurpose::Mail::drafts)); + if (mail.getDraft()) { + mail.setFolder(ensureFolder(ApplicationDomain::SpecialPurpose::Mail::drafts)); + return; } - if (newEntity.getProperty(ApplicationDomain::Mail::Sent::name).toBool()) { - newEntity.setProperty("folder", ensureFolder(ApplicationDomain::SpecialPurpose::Mail::sent)); + if (mail.getSent()) { + mail.setFolder(ensureFolder(ApplicationDomain::SpecialPurpose::Mail::sent)); + return; } } diff --git a/common/storage/entitystore.cpp b/common/storage/entitystore.cpp index 7414f49..999bb2c 100644 --- a/common/storage/entitystore.cpp +++ b/common/storage/entitystore.cpp @@ -205,9 +205,10 @@ bool EntityStore::modify(const QByteArray &type, const ApplicationDomain::Applic auto metadataBuffer = metadataBuilder.Finish(); FinishMetadataBuffer(metadataFbb, metadataBuffer); } + SinkTrace() << "Modified entity: " << newEntity; + SinkTrace() << "Changed properties: " << changeset + newEntity.changedProperties(); newEntity.setChangedProperties(newEntity.availableProperties().toSet()); - SinkTrace() << "Modified entity " << newEntity; flatbuffers::FlatBufferBuilder fbb; d->resourceContext.adaptorFactory(type).createBuffer(newEntity, fbb, metadataFbb.GetBufferPointer(), metadataFbb.GetSize()); diff --git a/common/typeindex.cpp b/common/typeindex.cpp index b0494f3..9d71463 100644 --- a/common/typeindex.cpp +++ b/common/typeindex.cpp @@ -34,6 +34,12 @@ static QByteArray getByteArray(const QVariant &value) return "nodate"; } } + if (value.canConvert()) { + const auto ba = value.value().value; + if (!ba.isEmpty()) { + return ba; + } + } if (value.isValid() && !value.toByteArray().isEmpty()) { return value.toByteArray(); } diff --git a/examples/dummyresource/resourcefactory.cpp b/examples/dummyresource/resourcefactory.cpp index d230ea3..07021b9 100644 --- a/examples/dummyresource/resourcefactory.cpp +++ b/examples/dummyresource/resourcefactory.cpp @@ -59,34 +59,33 @@ class DummySynchronizer : public Sink::Synchronizer { { static uint8_t rawData[100]; auto event = Sink::ApplicationDomain::Event::Ptr::create(); - event->setProperty("summary", data.value("summary").toString()); + event->setSummary(data.value("summary").toString()); event->setProperty("remoteId", ridBuffer); - event->setProperty("description", data.value("description").toString()); - event->setProperty("attachment", QByteArray::fromRawData(reinterpret_cast(rawData), 100)); + event->setDescription(data.value("description").toString()); + event->setAttachment(QByteArray::fromRawData(reinterpret_cast(rawData), 100)); return event; } Sink::ApplicationDomain::Mail::Ptr createMail(const QByteArray &ridBuffer, const QMap &data) { auto mail = Sink::ApplicationDomain::Mail::Ptr::create(); - mail->setProperty("subject", data.value("subject").toString()); - mail->setProperty("senderEmail", data.value("senderEmail").toString()); - mail->setProperty("senderName", data.value("senderName").toString()); - mail->setProperty("date", data.value("date").toString()); - mail->setProperty("folder", syncStore().resolveRemoteId(ENTITY_TYPE_FOLDER, data.value("parentFolder").toByteArray())); - mail->setProperty("unread", data.value("unread").toBool()); - mail->setProperty("important", data.value("important").toBool()); + mail->setExtractedSubject(data.value("subject").toString()); + mail->setExtractedSender(Sink::ApplicationDomain::Mail::Contact{data.value("senderName").toString(), data.value("senderEmail").toString()}); + mail->setExtractedDate(data.value("date").toDateTime()); + mail->setFolder(syncStore().resolveRemoteId(ENTITY_TYPE_FOLDER, data.value("parentFolder").toByteArray())); + mail->setUnread(data.value("unread").toBool()); + mail->setImportant(data.value("important").toBool()); return mail; } Sink::ApplicationDomain::Folder::Ptr createFolder(const QByteArray &ridBuffer, const QMap &data) { auto folder = Sink::ApplicationDomain::Folder::Ptr::create(); - folder->setProperty("name", data.value("name").toString()); - folder->setProperty("icon", data.value("icon").toString()); + folder->setName(data.value("name").toString()); + folder->setIcon(data.value("icon").toByteArray()); if (!data.value("parent").toString().isEmpty()) { auto sinkId = syncStore().resolveRemoteId(ENTITY_TYPE_FOLDER, data.value("parent").toByteArray()); - folder->setProperty("parent", sinkId); + folder->setParent(sinkId); } return folder; } diff --git a/examples/imapresource/imapresource.cpp b/examples/imapresource/imapresource.cpp index 9577f3e..238fb0c 100644 --- a/examples/imapresource/imapresource.cpp +++ b/examples/imapresource/imapresource.cpp @@ -92,17 +92,17 @@ public: const auto remoteId = folderPath.toUtf8(); const auto bufferType = ENTITY_TYPE_FOLDER; Sink::ApplicationDomain::Folder folder; - folder.setProperty(ApplicationDomain::Folder::Name::name, folderName); - folder.setProperty(ApplicationDomain::Folder::Icon::name, icon); + folder.setName(folderName); + folder.setIcon(icon); QHash mergeCriteria; if (SpecialPurpose::isSpecialPurposeFolderName(folderName)) { auto type = SpecialPurpose::getSpecialPurposeType(folderName); - folder.setProperty(ApplicationDomain::Folder::SpecialPurpose::name, QVariant::fromValue(QByteArrayList() << type)); + folder.setSpecialPurpose(QByteArrayList() << type); mergeCriteria.insert(ApplicationDomain::Folder::SpecialPurpose::name, Query::Comparator(type, Query::Comparator::Contains)); } if (!parentFolderRid.isEmpty()) { - folder.setProperty("parent", syncStore().resolveRemoteId(ENTITY_TYPE_FOLDER, parentFolderRid.toUtf8())); + folder.setParent(syncStore().resolveRemoteId(ENTITY_TYPE_FOLDER, parentFolderRid.toUtf8())); } createOrModify(bufferType, remoteId, folder, mergeCriteria); return remoteId; diff --git a/examples/maildirresource/maildirresource.cpp b/examples/maildirresource/maildirresource.cpp index 1eee786..a05afc6 100644 --- a/examples/maildirresource/maildirresource.cpp +++ b/examples/maildirresource/maildirresource.cpp @@ -129,16 +129,16 @@ public: void newEntity(Sink::ApplicationDomain::ApplicationDomainType &newEntity) Q_DECL_OVERRIDE { - const ApplicationDomain::Mail mail{newEntity}; + auto mail = newEntity.cast(); const auto mimeMessage = mail.getMimeMessagePath(); if (!mimeMessage.isNull()) { - ApplicationDomain::Mail{newEntity}.setMimeMessagePath(moveMessage(mimeMessage, mail.getFolder())); + mail.setMimeMessagePath(moveMessage(mimeMessage, mail.getFolder())); } } void modifiedEntity(const Sink::ApplicationDomain::ApplicationDomainType &oldEntity, Sink::ApplicationDomain::ApplicationDomainType &newEntity) Q_DECL_OVERRIDE { - ApplicationDomain::Mail newMail{newEntity}; + auto newMail = newEntity.cast(); const ApplicationDomain::Mail oldMail{oldEntity}; const auto mimeMessage = newMail.getMimeMessagePath(); const auto newFolder = newMail.getFolder(); @@ -190,7 +190,7 @@ public: void newEntity(Sink::ApplicationDomain::ApplicationDomainType &newEntity) Q_DECL_OVERRIDE { - auto folderName = newEntity.getProperty("name").toString(); + auto folderName = Sink::ApplicationDomain::Folder{newEntity}.getName(); const auto path = mMaildirPath + "/" + folderName; KPIM::Maildir maildir(path, false); maildir.create(); diff --git a/tests/clientapitest.cpp b/tests/clientapitest.cpp index 4a33d17..4afe328 100644 --- a/tests/clientapitest.cpp +++ b/tests/clientapitest.cpp @@ -148,7 +148,7 @@ private slots: auto facade = TestDummyResourceFacade::registerFacade(); auto folder = QSharedPointer::create("resource", "id", 0, QSharedPointer::create()); auto subfolder = QSharedPointer::create("resource", "subId", 0, QSharedPointer::create()); - subfolder->setProperty("parent", "id"); + subfolder->setParent("id"); facade->results << folder << subfolder; ResourceConfig::addResource("dummyresource.instance1", "dummyresource"); @@ -170,7 +170,7 @@ private slots: auto facade = TestDummyResourceFacade::registerFacade(); auto folder = QSharedPointer::create("resource", "id", 0, QSharedPointer::create()); auto subfolder = QSharedPointer::create("resource", "subId", 0, QSharedPointer::create()); - subfolder->setProperty("parent", "id"); + subfolder->setParent("id"); facade->results << folder << subfolder; ResourceConfig::addResource("dummyresource.instance1", "dummyresource"); @@ -192,7 +192,7 @@ private slots: auto folder = QSharedPointer::create("dummyresource.instance1", "id", 0, QSharedPointer::create()); auto subfolder = QSharedPointer::create("dummyresource.instance1", "subId", 0, QSharedPointer::create()); - subfolder->setProperty("parent", "id"); + subfolder->setParent("id"); facade->results << folder << subfolder; ResourceConfig::addResource("dummyresource.instance1", "dummyresource"); diff --git a/tests/domainadaptortest.cpp b/tests/domainadaptortest.cpp index 4fd04db..a17152e 100644 --- a/tests/domainadaptortest.cpp +++ b/tests/domainadaptortest.cpp @@ -110,6 +110,7 @@ private slots: Sink::ApplicationDomain::Mail mail; mail.setExtractedSubject("summary"); mail.setMimeMessage("foobar"); + mail.setFolder("folder"); flatbuffers::FlatBufferBuilder metadataFbb; auto metadataBuilder = Sink::MetadataBuilder(metadataFbb); @@ -134,6 +135,7 @@ private slots: Sink::ApplicationDomain::Mail readMail{QByteArray{}, QByteArray{}, 0, adaptor}; QCOMPARE(readMail.getSubject(), mail.getSubject()); QCOMPARE(readMail.getMimeMessage(), mail.getMimeMessage()); + QCOMPARE(readMail.getFolder(), mail.getFolder()); } } diff --git a/tests/mailquerybenchmark.cpp b/tests/mailquerybenchmark.cpp index 702239d..0e2f6fa 100644 --- a/tests/mailquerybenchmark.cpp +++ b/tests/mailquerybenchmark.cpp @@ -69,11 +69,11 @@ class MailQueryBenchmark : public QObject const auto date = QDateTime::currentDateTimeUtc(); for (int i = 0; i < count; i++) { auto domainObject = Mail::Ptr::create(); - domainObject->setProperty("uid", "uid"); - domainObject->setProperty("subject", QString("subject%1").arg(i)); - domainObject->setProperty("date", date.addSecs(count)); - domainObject->setProperty("folder", "folder1"); - // domainObject->setProperty("attachment", attachment); + domainObject->setUid("uid"); + domainObject->setExtractedSubject(QString("subject%1").arg(i)); + domainObject->setExtractedDate(date.addSecs(count)); + domainObject->setFolder("folder1"); + // domainObject->setAttachment(attachment); const auto command = createCommand(*domainObject, *domainTypeAdaptorFactory); pipeline->newEntity(command.data(), command.size()); } diff --git a/tests/pipelinebenchmark.cpp b/tests/pipelinebenchmark.cpp index 2e614ef..341c733 100644 --- a/tests/pipelinebenchmark.cpp +++ b/tests/pipelinebenchmark.cpp @@ -73,10 +73,10 @@ class PipelineBenchmark : public QObject const auto date = QDateTime::currentDateTimeUtc(); for (int i = 0; i < count; i++) { auto domainObject = Sink::ApplicationDomain::Mail::Ptr::create(); - domainObject->setProperty("uid", "uid"); - domainObject->setProperty("subject", QString("subject%1").arg(i)); - domainObject->setProperty("date", date.addSecs(count)); - domainObject->setProperty("folder", "folder1"); + domainObject->setUid("uid"); + domainObject->setExtractedSubject(QString("subject%1").arg(i)); + domainObject->setExtractedDate(date.addSecs(count)); + domainObject->setFolder("folder1"); // domainObject->setProperty("attachment", attachment); const auto command = createCommand(*domainObject, *domainTypeAdaptorFactory); pipeline->newEntity(command.data(), command.size()); diff --git a/tests/querytest.cpp b/tests/querytest.cpp index 2eb1239..574e68d 100644 --- a/tests/querytest.cpp +++ b/tests/querytest.cpp @@ -228,25 +228,13 @@ private slots: { // Setup { - Folder folder("sink.dummy.instance1"); - Sink::Store::create(folder).exec().waitForFinished(); - - Sink::Query query; - query.resourceFilter("sink.dummy.instance1"); - + auto folder = ApplicationDomainType::createEntity("sink.dummy.instance1"); + VERIFYEXEC(Sink::Store::create(folder)); + auto subfolder = ApplicationDomainType::createEntity("sink.dummy.instance1"); + subfolder.setParent(folder.identifier()); + VERIFYEXEC(Sink::Store::create(subfolder)); // Ensure all local data is processed VERIFYEXEC(Sink::ResourceControl::flushMessageQueue(QByteArrayList() << "sink.dummy.instance1")); - - auto model = Sink::Store::loadModel(query); - QTRY_VERIFY(model->data(QModelIndex(), Sink::Store::ChildrenFetchedRole).toBool()); - QCOMPARE(model->rowCount(), 1); - - auto folderEntity = model->index(0, 0).data(Sink::Store::DomainObjectRole).value(); - QVERIFY(!folderEntity->identifier().isEmpty()); - - Folder subfolder("sink.dummy.instance1"); - subfolder.setProperty("parent", folderEntity->identifier()); - Sink::Store::create(subfolder).exec().waitForFinished(); } // Test @@ -271,14 +259,14 @@ private slots: // Setup { Mail mail("sink.dummy.instance1"); - mail.setProperty("uid", "test1"); + mail.setUid("test1"); mail.setProperty("sender", "doe@example.org"); Sink::Store::create(mail).exec().waitForFinished(); } { Mail mail("sink.dummy.instance1"); - mail.setProperty("uid", "test2"); + mail.setUid("test2"); mail.setProperty("sender", "doe@example.org"); Sink::Store::create(mail).exec().waitForFinished(); } @@ -319,8 +307,8 @@ private slots: QVERIFY(!folderEntity->identifier().isEmpty()); Mail mail("sink.dummy.instance1"); - mail.setProperty("uid", "test1"); - mail.setProperty("folder", folderEntity->identifier()); + mail.setUid("test1"); + mail.setFolder(folderEntity->identifier()); Sink::Store::create(mail).exec().waitForFinished(); } @@ -363,18 +351,18 @@ private slots: QVERIFY(!folderEntity->identifier().isEmpty()); Mail mail("sink.dummy.instance1"); - mail.setProperty("uid", "test1"); - mail.setProperty("folder", folderEntity->identifier()); + mail.setUid("test1"); + mail.setFolder(folderEntity->identifier()); Sink::Store::create(mail).exec().waitForFinished(); Mail mail1("sink.dummy.instance1"); - mail1.setProperty("uid", "test1"); - mail1.setProperty("folder", "foobar"); + mail1.setUid("test1"); + mail1.setFolder("foobar"); Sink::Store::create(mail1).exec().waitForFinished(); Mail mail2("sink.dummy.instance1"); - mail2.setProperty("uid", "test2"); - mail2.setProperty("folder", folderEntity->identifier()); + mail2.setUid("test2"); + mail2.setFolder(folderEntity->identifier()); Sink::Store::create(mail2).exec().waitForFinished(); } @@ -417,23 +405,23 @@ private slots: const auto date = QDateTime(QDate(2015, 7, 7), QTime(12, 0)); { Mail mail("sink.dummy.instance1"); - mail.setProperty("uid", "testSecond"); - mail.setProperty("folder", folderEntity->identifier()); - mail.setProperty("date", date.addDays(-1)); + mail.setUid("testSecond"); + mail.setFolder(folderEntity->identifier()); + mail.setExtractedDate(date.addDays(-1)); Sink::Store::create(mail).exec().waitForFinished(); } { Mail mail("sink.dummy.instance1"); - mail.setProperty("uid", "testLatest"); - mail.setProperty("folder", folderEntity->identifier()); - mail.setProperty("date", date); + mail.setUid("testLatest"); + mail.setFolder(folderEntity->identifier()); + mail.setExtractedDate(date); Sink::Store::create(mail).exec().waitForFinished(); } { Mail mail("sink.dummy.instance1"); - mail.setProperty("uid", "testLast"); - mail.setProperty("folder", folderEntity->identifier()); - mail.setProperty("date", date.addDays(-2)); + mail.setUid("testLast"); + mail.setFolder(folderEntity->identifier()); + mail.setExtractedDate(date.addDays(-2)); Sink::Store::create(mail).exec().waitForFinished(); } } -- cgit v1.2.3