From c08c329580a6f5e5da1ebba931461e7e7e47ba72 Mon Sep 17 00:00:00 2001 From: Christian Mollekopf Date: Wed, 1 Mar 2017 01:03:18 +0100 Subject: Filter resources by the types they support. This avoid uselessly querying resources only to discover that they don't have a facade for the type. --- common/domain/applicationdomaintype.h | 2 + common/store.cpp | 13 ++++-- examples/dummyresource/resourcefactory.cpp | 8 +++- examples/imapresource/imapresource.cpp | 4 +- examples/maildirresource/maildirresource.cpp | 4 +- .../mailtransportresource.cpp | 6 ++- tests/clientapitest.cpp | 52 +++++++++++----------- 7 files changed, 56 insertions(+), 33 deletions(-) diff --git a/common/domain/applicationdomaintype.h b/common/domain/applicationdomaintype.h index fee6344..be04db9 100644 --- a/common/domain/applicationdomaintype.h +++ b/common/domain/applicationdomaintype.h @@ -418,6 +418,8 @@ struct SINK_EXPORT ImapResource { namespace ResourceCapabilities { namespace Mail { + static constexpr const char *mail = "mail"; + static constexpr const char *folder = "folder"; static constexpr const char *storage = "mail.storage"; static constexpr const char *drafts = "mail.drafts"; static constexpr const char *sent = "mail.sent"; diff --git a/common/store.cpp b/common/store.cpp index 9550d3e..1c8620b 100644 --- a/common/store.cpp +++ b/common/store.cpp @@ -96,14 +96,21 @@ QPair::Ptr, typenam SinkTraceCtx(ctx) << "Listening for new resources."; resourceQuery.setFlags(Query::LiveQuery); } - resourceQuery.setFilter(query.getResourceFilter()); + + //Filter resources by available content types (unless the query already specifies a capability filter) + auto resourceFilter = query.getResourceFilter(); + if (!resourceFilter.propertyFilter.contains(ApplicationDomain::SinkResource::Capabilities::name)) { + resourceFilter.propertyFilter.insert(ApplicationDomain::SinkResource::Capabilities::name, Query::Comparator{ApplicationDomain::getTypeName(), Query::Comparator::Contains}); + } + resourceQuery.setFilter(resourceFilter); + auto result = facade->load(resourceQuery, resourceCtx); auto emitter = result.second; - emitter->onAdded([query, aggregatingEmitter, resourceCtx](const ApplicationDomain::SinkResource::Ptr &resource) { + emitter->onAdded([=](const ApplicationDomain::SinkResource::Ptr &resource) { SinkTraceCtx(resourceCtx) << "Found new resources: " << resource->identifier(); const auto resourceType = ResourceConfig::getResourceType(resource->identifier()); Q_ASSERT(!resourceType.isEmpty()); - queryResource(resourceType, resource->identifier(), query, aggregatingEmitter, resourceCtx).exec(); + queryResource(resourceType, resource->identifier(), query, aggregatingEmitter, ctx).exec(); }); emitter->onModified([](const ApplicationDomain::SinkResource::Ptr &) { }); diff --git a/examples/dummyresource/resourcefactory.cpp b/examples/dummyresource/resourcefactory.cpp index 0663bdb..a7d30c5 100644 --- a/examples/dummyresource/resourcefactory.cpp +++ b/examples/dummyresource/resourcefactory.cpp @@ -176,7 +176,13 @@ DummyResource::~DummyResource() } DummyResourceFactory::DummyResourceFactory(QObject *parent) - : Sink::ResourceFactory(parent, QByteArrayList() << Sink::ApplicationDomain::ResourceCapabilities::Mail::storage << "-folder.rename" << Sink::ApplicationDomain::ResourceCapabilities::Mail::sent) + : Sink::ResourceFactory(parent, {Sink::ApplicationDomain::ResourceCapabilities::Mail::mail, + "event", + Sink::ApplicationDomain::ResourceCapabilities::Mail::folder, + Sink::ApplicationDomain::ResourceCapabilities::Mail::storage, + "-folder.rename", + Sink::ApplicationDomain::ResourceCapabilities::Mail::sent} + ) { } diff --git a/examples/imapresource/imapresource.cpp b/examples/imapresource/imapresource.cpp index 5bf0c30..09f57d5 100644 --- a/examples/imapresource/imapresource.cpp +++ b/examples/imapresource/imapresource.cpp @@ -879,7 +879,9 @@ ImapResource::ImapResource(const ResourceContext &resourceContext) ImapResourceFactory::ImapResourceFactory(QObject *parent) : Sink::ResourceFactory(parent, - {Sink::ApplicationDomain::ResourceCapabilities::Mail::storage, + {Sink::ApplicationDomain::ResourceCapabilities::Mail::mail, + Sink::ApplicationDomain::ResourceCapabilities::Mail::folder, + Sink::ApplicationDomain::ResourceCapabilities::Mail::storage, Sink::ApplicationDomain::ResourceCapabilities::Mail::drafts, Sink::ApplicationDomain::ResourceCapabilities::Mail::folderhierarchy, Sink::ApplicationDomain::ResourceCapabilities::Mail::trash, diff --git a/examples/maildirresource/maildirresource.cpp b/examples/maildirresource/maildirresource.cpp index 3d299b4..813d84f 100644 --- a/examples/maildirresource/maildirresource.cpp +++ b/examples/maildirresource/maildirresource.cpp @@ -572,7 +572,9 @@ MaildirResource::MaildirResource(const Sink::ResourceContext &resourceContext) MaildirResourceFactory::MaildirResourceFactory(QObject *parent) : Sink::ResourceFactory(parent, - {Sink::ApplicationDomain::ResourceCapabilities::Mail::storage, + {Sink::ApplicationDomain::ResourceCapabilities::Mail::mail, + Sink::ApplicationDomain::ResourceCapabilities::Mail::folder, + Sink::ApplicationDomain::ResourceCapabilities::Mail::storage, Sink::ApplicationDomain::ResourceCapabilities::Mail::drafts, "-folder.rename", Sink::ApplicationDomain::ResourceCapabilities::Mail::trash, diff --git a/examples/mailtransportresource/mailtransportresource.cpp b/examples/mailtransportresource/mailtransportresource.cpp index 0118140..88a90c6 100644 --- a/examples/mailtransportresource/mailtransportresource.cpp +++ b/examples/mailtransportresource/mailtransportresource.cpp @@ -91,6 +91,9 @@ public: modifiedMail.setSent(true); auto resource = Store::readOne(Query{}.filter(mResourceInstanceIdentifier).request()); + if (resource.identifier().isEmpty()) { + SinkWarning() << "Failed to retrieve target resource: " << mResourceInstanceIdentifier; + } //Then copy the mail to the target resource Query query; query.containsFilter(ApplicationDomain::ResourceCapabilities::Mail::sent); @@ -193,7 +196,8 @@ MailtransportResource::MailtransportResource(const Sink::ResourceContext &resour } MailtransportResourceFactory::MailtransportResourceFactory(QObject *parent) - : Sink::ResourceFactory(parent, {Sink::ApplicationDomain::ResourceCapabilities::Mail::transport}) + : Sink::ResourceFactory(parent, {Sink::ApplicationDomain::ResourceCapabilities::Mail::mail, + Sink::ApplicationDomain::ResourceCapabilities::Mail::transport}) { } diff --git a/tests/clientapitest.cpp b/tests/clientapitest.cpp index ea72ae0..008b408 100644 --- a/tests/clientapitest.cpp +++ b/tests/clientapitest.cpp @@ -122,6 +122,18 @@ public: class ClientAPITest : public QObject { Q_OBJECT + + template + std::shared_ptr > setupFacade(const QByteArray &identifier) + { + auto facade = TestDummyResourceFacade::registerFacade(identifier); + ResourceConfig::addResource(identifier, "dummyresource"); + QMap config = ResourceConfig::getConfiguration(identifier); + config.insert(Sink::ApplicationDomain::SinkResource::Capabilities::name, QVariant::fromValue(QByteArrayList() << Sink::ApplicationDomain::getTypeName())); + ResourceConfig::configureResource(identifier, config); + return facade; + } + private slots: void initTestCase() @@ -133,9 +145,8 @@ private slots: void testLoad() { - auto facade = TestDummyResourceFacade::registerFacade(); + auto facade = setupFacade("dummyresource.instance1"); facade->results << QSharedPointer::create("resource", "id", 0, QSharedPointer::create()); - ResourceConfig::addResource("dummyresource.instance1", "dummyresource"); Sink::Query query; query.resourceFilter("dummyresource.instance1"); @@ -156,9 +167,8 @@ private slots: void testModelSingle() { - auto facade = TestDummyResourceFacade::registerFacade(); + auto facade = setupFacade("dummyresource.instance1"); facade->results << QSharedPointer::create("resource", "id", 0, QSharedPointer::create()); - ResourceConfig::addResource("dummyresource.instance1", "dummyresource"); Sink::Query query; query.resourceFilter("dummyresource.instance1"); @@ -169,12 +179,11 @@ private slots: void testModelNested() { - auto facade = TestDummyResourceFacade::registerFacade(); + auto facade = setupFacade("dummyresource.instance1"); auto folder = QSharedPointer::create("resource", "id", 0, QSharedPointer::create()); auto subfolder = QSharedPointer::create("resource", "subId", 0, QSharedPointer::create()); subfolder->setParent("id"); facade->results << folder << subfolder; - ResourceConfig::addResource("dummyresource.instance1", "dummyresource"); // Test Sink::Query query; @@ -191,12 +200,11 @@ private slots: void testModelSignals() { - auto facade = TestDummyResourceFacade::registerFacade(); + auto facade = setupFacade("dummyresource.instance1"); auto folder = QSharedPointer::create("resource", "id", 0, QSharedPointer::create()); auto subfolder = QSharedPointer::create("resource", "subId", 0, QSharedPointer::create()); subfolder->setParent("id"); facade->results << folder << subfolder; - ResourceConfig::addResource("dummyresource.instance1", "dummyresource"); // Test Sink::Query query; @@ -212,13 +220,12 @@ private slots: void testModelNestedLive() { - auto facade = TestDummyResourceFacade::registerFacade(); + auto facade = setupFacade("dummyresource.instance1"); auto folder = QSharedPointer::create("dummyresource.instance1", "id", 0, QSharedPointer::create()); auto subfolder = QSharedPointer::create("dummyresource.instance1", "subId", 0, QSharedPointer::create()); subfolder->setParent("id"); facade->results << folder << subfolder; - ResourceConfig::addResource("dummyresource.instance1", "dummyresource"); // Test Sink::Query query; @@ -266,12 +273,10 @@ private slots: void testLoadMultiResource() { - auto facade1 = TestDummyResourceFacade::registerFacade("dummyresource.instance1"); + auto facade1 = setupFacade("dummyresource.instance1"); facade1->results << QSharedPointer::create("resource1", "id", 0, QSharedPointer::create()); - auto facade2 = TestDummyResourceFacade::registerFacade("dummyresource.instance2"); + auto facade2 = setupFacade("dummyresource.instance2"); facade2->results << QSharedPointer::create("resource2", "id", 0, QSharedPointer::create()); - ResourceConfig::addResource("dummyresource.instance1", "dummyresource"); - ResourceConfig::addResource("dummyresource.instance2", "dummyresource"); Sink::Query query; @@ -291,9 +296,8 @@ private slots: void testImperativeLoad() { - auto facade = TestDummyResourceFacade::registerFacade(); + auto facade = setupFacade("dummyresource.instance1"); facade->results << QSharedPointer::create("resource", "id", 0, QSharedPointer::create()); - ResourceConfig::addResource("dummyresource.instance1", "dummyresource"); Sink::Query query; query.resourceFilter("dummyresource.instance1"); @@ -309,16 +313,15 @@ private slots: void testMultiresourceIncrementalLoad() { - auto facade1 = TestDummyResourceFacade::registerFacade("dummyresource.instance1"); + auto facade1 = setupFacade("dummyresource.instance1"); for (int i = 0; i < 4; i++) { facade1->results << QSharedPointer::create("resource1", "id" + QByteArray::number(i), 0, QSharedPointer::create()); } - auto facade2 = TestDummyResourceFacade::registerFacade("dummyresource.instance2"); + + auto facade2 = setupFacade("dummyresource.instance2"); for (int i = 0; i < 6; i++) { facade2->results << QSharedPointer::create("resource2", "id" + QByteArray::number(i), 0, QSharedPointer::create()); } - ResourceConfig::addResource("dummyresource.instance1", "dummyresource"); - ResourceConfig::addResource("dummyresource.instance2", "dummyresource"); Sink::Query query; query.limit(2); @@ -344,8 +347,7 @@ private slots: void testCreateModifyDelete() { - auto facade = TestDummyResourceFacade::registerFacade(); - ResourceConfig::addResource("dummyresource.instance1", "dummyresource"); + auto facade = setupFacade("dummyresource.instance1"); auto event = Sink::ApplicationDomain::Event::createEntity("dummyresource.instance1"); Sink::Store::create(event).exec().waitForFinished(); @@ -358,10 +360,9 @@ private slots: } void testMultiModify() { - auto facade = TestDummyResourceFacade::registerFacade(); + auto facade = setupFacade("dummyresource.instance1"); facade->results << QSharedPointer::create("dummyresource.instance1", "id1", 0, QSharedPointer::create()); facade->results << QSharedPointer::create("dummyresource.instance1", "id2", 0, QSharedPointer::create()); - ResourceConfig::addResource("dummyresource.instance1", "dummyresource"); Sink::Query query; query.resourceFilter("dummyresource.instance1"); @@ -377,12 +378,11 @@ private slots: void testModelStress() { - auto facade = TestDummyResourceFacade::registerFacade(); + auto facade = setupFacade("dummyresource.instance1"); facade->runAsync = true; for (int i = 0; i < 100; i++) { facade->results << QSharedPointer::create("resource", "id" + QByteArray::number(i), 0, QSharedPointer::create()); } - ResourceConfig::addResource("dummyresource.instance1", "dummyresource"); Sink::Query query; query.resourceFilter("dummyresource.instance1"); -- cgit v1.2.3