From 63919d3040295415306267df7b66e7a5e2c9395f Mon Sep 17 00:00:00 2001 From: Christian Mollekopf Date: Mon, 8 Jun 2015 10:47:57 +0200 Subject: Differentiate between resource name and instance identifier --- common/clientapi.h | 15 +++++++++++---- common/domain/event.cpp | 4 ++-- common/resourceaccess.cpp | 29 +++++++++++++++++++---------- examples/dummyresource/facade.cpp | 8 ++++---- examples/dummyresource/resourcefacade.cpp | 2 +- examples/dummyresource/resourcefactory.cpp | 2 +- synchronizer/listener.cpp | 17 +++++++++-------- synchronizer/listener.h | 1 + tests/dummyresourcetest.cpp | 28 ++++++++++++++-------------- 9 files changed, 62 insertions(+), 44 deletions(-) diff --git a/common/clientapi.h b/common/clientapi.h index 38ec1ee..4948c59 100644 --- a/common/clientapi.h +++ b/common/clientapi.h @@ -193,6 +193,13 @@ public: return QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation) + "/akonadi2/storage"; } + static QByteArray resourceName(const QByteArray &instanceIdentifier) + { + auto split = instanceIdentifier.split('.'); + split.removeLast(); + return split.join('.'); + } + /** * Asynchronusly load a dataset */ @@ -209,7 +216,7 @@ public: KAsync::iterate(query.resources) .template each([query, resultSet](const QByteArray &resource, KAsync::Future &future) { //TODO pass resource identifier to factory - auto facade = FacadeFactory::instance().getFacade(resource); + auto facade = FacadeFactory::instance().getFacade(resourceName(resource)); if (facade) { facade->load(query, resultSet).template then([&future](){future.setFinished();}).exec(); //Keep the facade alive for the lifetime of the resultSet. @@ -254,7 +261,7 @@ public: template static void create(const DomainType &domainObject, const QByteArray &resourceIdentifier) { //Potentially move to separate thread as well - auto facade = FacadeFactory::instance().getFacade(resourceIdentifier); + auto facade = FacadeFactory::instance().getFacade(resourceName(resourceIdentifier)); facade->create(domainObject).exec().waitForFinished(); //TODO return job? } @@ -267,7 +274,7 @@ public: template static void modify(const DomainType &domainObject, const QByteArray &resourceIdentifier) { //Potentially move to separate thread as well - auto facade = FacadeFactory::instance().getFacade(resourceIdentifier); + auto facade = FacadeFactory::instance().getFacade(resourceName(resourceIdentifier)); facade->modify(domainObject).exec().waitForFinished(); //TODO return job? } @@ -278,7 +285,7 @@ public: template static void remove(const DomainType &domainObject, const QByteArray &resourceIdentifier) { //Potentially move to separate thread as well - auto facade = FacadeFactory::instance().getFacade(resourceIdentifier); + auto facade = FacadeFactory::instance().getFacade(resourceName(resourceIdentifier)); facade->remove(domainObject).exec().waitForFinished(); //TODO return job? } diff --git a/common/domain/event.cpp b/common/domain/event.cpp index c435c6b..08ce698 100644 --- a/common/domain/event.cpp +++ b/common/domain/event.cpp @@ -36,7 +36,7 @@ ResultSet TypeImplementation::queryIndexes(const Akonadi2::Query &query, { QVector keys; if (query.propertyFilter.contains("uid")) { - Index uidIndex(Akonadi2::Store::storageLocation(), resourceInstanceIdentifier + "index.uid", Akonadi2::Storage::ReadOnly); + Index uidIndex(Akonadi2::Store::storageLocation(), resourceInstanceIdentifier + ".index.uid", Akonadi2::Storage::ReadOnly); uidIndex.lookup(query.propertyFilter.value("uid").toByteArray(), [&](const QByteArray &value) { keys << value; }, @@ -50,7 +50,7 @@ ResultSet TypeImplementation::queryIndexes(const Akonadi2::Query &query, void TypeImplementation::index(const Event &type) { - Index uidIndex(Akonadi2::Store::storageLocation(), type.resourceInstanceIdentifier() + "index.uid", Akonadi2::Storage::ReadWrite); + Index uidIndex(Akonadi2::Store::storageLocation(), type.resourceInstanceIdentifier() + ".index.uid", Akonadi2::Storage::ReadWrite); const auto uid = type.getProperty("uid"); if (uid.isValid()) { uidIndex.add(uid.toByteArray(), type.identifier()); diff --git a/common/resourceaccess.cpp b/common/resourceaccess.cpp index feffcf4..249dd55 100644 --- a/common/resourceaccess.cpp +++ b/common/resourceaccess.cpp @@ -69,10 +69,11 @@ public: class ResourceAccess::Private { public: - Private(const QByteArray &name, ResourceAccess *ra); + Private(const QByteArray &name, const QByteArray &instanceIdentifier, ResourceAccess *ra); KAsync::Job tryToConnect(); KAsync::Job initializeSocket(); QByteArray resourceName; + QByteArray resourceInstanceIdentifier; QSharedPointer socket; QByteArray partialMessageBuffer; flatbuffers::FlatBufferBuilder fbb; @@ -82,8 +83,9 @@ public: uint messageId; }; -ResourceAccess::Private::Private(const QByteArray &name, ResourceAccess *q) +ResourceAccess::Private::Private(const QByteArray &name, const QByteArray &instanceIdentifier, ResourceAccess *q) : resourceName(name), + resourceInstanceIdentifier(instanceIdentifier), messageId(0) { } @@ -118,7 +120,7 @@ KAsync::Job ResourceAccess::Private::tryToConnect() [this](KAsync::Future &future) { Trace() << "Loop"; KAsync::wait(50) - .then(connectToServer(resourceName)) + .then(connectToServer(resourceInstanceIdentifier)) .then >([this, &future](const QSharedPointer &s) { Q_ASSERT(s); socket = s; @@ -134,7 +136,7 @@ KAsync::Job ResourceAccess::Private::initializeSocket() { return KAsync::start([this](KAsync::Future &future) { Trace() << "Trying to connect"; - connectToServer(resourceName).then >([this, &future](const QSharedPointer &s) { + connectToServer(resourceInstanceIdentifier).then >([this, &future](const QSharedPointer &s) { Trace() << "Connected to resource, without having to start it."; Q_ASSERT(s); socket = s; @@ -144,7 +146,7 @@ KAsync::Job ResourceAccess::Private::initializeSocket() Trace() << "Failed to connect, starting resource"; //We failed to connect, so let's start the resource QStringList args; - args << resourceName; + args << resourceInstanceIdentifier; qint64 pid = 0; if (QProcess::startDetached("akonadi2_synchronizer", args, QDir::homePath(), &pid)) { Trace() << "Started resource " << pid; @@ -159,9 +161,16 @@ KAsync::Job ResourceAccess::Private::initializeSocket() }); } -ResourceAccess::ResourceAccess(const QByteArray &resourceName, QObject *parent) +static QByteArray getResourceName(const QByteArray &instanceIdentifier) +{ + auto split = instanceIdentifier.split('.'); + split.removeLast(); + return split.join('.'); +} + +ResourceAccess::ResourceAccess(const QByteArray &resourceInstanceIdentifier, QObject *parent) : QObject(parent), - d(new Private(resourceName, this)) + d(new Private(getResourceName(resourceInstanceIdentifier), resourceInstanceIdentifier, this)) { log("Starting access"); } @@ -316,7 +325,7 @@ void ResourceAccess::disconnected() void ResourceAccess::connectionError(QLocalSocket::LocalSocketError error) { if (error == QLocalSocket::PeerClosedError) { - Log(d->resourceName) << "The resource closed the connection."; + Log(d->resourceInstanceIdentifier) << "The resource closed the connection."; } else { Warning() << QString("Connection error: %1 : %2").arg(error).arg(d->socket->errorString()); } @@ -379,7 +388,7 @@ bool ResourceAccess::processMessageBuffer() auto buffer = GetNotification(d->partialMessageBuffer.constData() + headerSize); switch (buffer->type()) { case Akonadi2::NotificationType::NotificationType_Shutdown: - Log(d->resourceName) << "Received shutdown notification."; + Log(d->resourceInstanceIdentifier) << "Received shutdown notification."; close(); break; default: @@ -406,7 +415,7 @@ void ResourceAccess::callCallbacks(int id) void ResourceAccess::log(const QString &message) { - Log(d->resourceName) << this << message; + Log(d->resourceInstanceIdentifier) << this << message; } } diff --git a/examples/dummyresource/facade.cpp b/examples/dummyresource/facade.cpp index 9849a92..9d4f64b 100644 --- a/examples/dummyresource/facade.cpp +++ b/examples/dummyresource/facade.cpp @@ -40,7 +40,7 @@ using namespace flatbuffers; DummyResourceFacade::DummyResourceFacade() - : Akonadi2::GenericFacade("org.kde.dummy", QSharedPointer::create()) + : Akonadi2::GenericFacade("org.kde.dummy.instance1", QSharedPointer::create()) { } @@ -82,7 +82,7 @@ void DummyResourceFacade::readValue(const QSharedPointer &sto //Not i.e. for tags that are stored as flags in each entity of an imap store. //additional properties that don't have a 1:1 mapping (such as separately stored tags), //could be added to the adaptor - auto event = QSharedPointer::create("org.kde.dummy", key, revision, mDomainTypeAdaptorFactory->createAdaptor(entity)); + auto event = QSharedPointer::create("org.kde.dummy.instance1", key, revision, mDomainTypeAdaptorFactory->createAdaptor(entity)); resultCallback(event); return true; }); @@ -91,7 +91,7 @@ void DummyResourceFacade::readValue(const QSharedPointer &sto static ResultSet getResultSet(const Akonadi2::Query &query, const QSharedPointer &storage) { QSet appliedFilters; - ResultSet resultSet = Akonadi2::ApplicationDomain::TypeImplementation::queryIndexes(query, "org.kde.dummy", appliedFilters); + ResultSet resultSet = Akonadi2::ApplicationDomain::TypeImplementation::queryIndexes(query, "org.kde.dummy.instance1", appliedFilters); const auto remainingFilters = query.propertyFilter.keys().toSet() - appliedFilters; if (resultSet.isEmpty()) { @@ -109,7 +109,7 @@ static ResultSet getResultSet(const Akonadi2::Query &query, const QSharedPointer KAsync::Job DummyResourceFacade::load(const Akonadi2::Query &query, const QSharedPointer > &resultProvider, qint64 oldRevision, qint64 newRevision) { return KAsync::start([=]() { - auto storage = QSharedPointer::create(Akonadi2::Store::storageLocation(), "org.kde.dummy"); + auto storage = QSharedPointer::create(Akonadi2::Store::storageLocation(), "org.kde.dummy.instance1"); storage->setDefaultErrorHandler([](const Akonadi2::Storage::Error &error) { Warning() << "Error during query: " << error.store << error.message; }); diff --git a/examples/dummyresource/resourcefacade.cpp b/examples/dummyresource/resourcefacade.cpp index af293d4..31c0b21 100644 --- a/examples/dummyresource/resourcefacade.cpp +++ b/examples/dummyresource/resourcefacade.cpp @@ -78,6 +78,6 @@ KAsync::Job DummyResourceConfigFacade::load(const Akonadi2::Query &query, // //TODO use correct instance identifier //TODO key == instance identifier ? - resultProvider->add(QSharedPointer::create("org.kde.dummy", "org.kde.dummy.config", 0, memoryAdaptor)); + resultProvider->add(QSharedPointer::create("org.kde.dummy.instance1", "org.kde.dummy.config", 0, memoryAdaptor)); }); } diff --git a/examples/dummyresource/resourcefactory.cpp b/examples/dummyresource/resourcefactory.cpp index 31ec972..e244131 100644 --- a/examples/dummyresource/resourcefactory.cpp +++ b/examples/dummyresource/resourcefactory.cpp @@ -158,7 +158,7 @@ KAsync::Job DummyResource::synchronizeWithSource(Akonadi2::Pipeline *pipel { return KAsync::start([this, pipeline](KAsync::Future &f) { //TODO use a read-only transaction during the complete sync to sync against a defined revision - auto storage = QSharedPointer::create(Akonadi2::Store::storageLocation(), "org.kde.dummy"); + auto storage = QSharedPointer::create(Akonadi2::Store::storageLocation(), "org.kde.dummy.instance1"); for (auto it = s_dataSource.constBegin(); it != s_dataSource.constEnd(); it++) { bool isNew = true; if (storage->exists()) { diff --git a/synchronizer/listener.cpp b/synchronizer/listener.cpp index 71723c9..c8b81e8 100644 --- a/synchronizer/listener.cpp +++ b/synchronizer/listener.cpp @@ -35,12 +35,13 @@ #include #include -Listener::Listener(const QByteArray &resourceName, QObject *parent) +Listener::Listener(const QByteArray &resourceInstanceIdentifier, QObject *parent) : QObject(parent), m_server(new QLocalServer(this)), - m_resourceName(resourceName), + m_resourceName(Akonadi2::Store::resourceName(resourceInstanceIdentifier)), + m_resourceInstanceIdentifier(resourceInstanceIdentifier), m_resource(0), - m_pipeline(new Akonadi2::Pipeline(resourceName, parent)), + m_pipeline(new Akonadi2::Pipeline(resourceInstanceIdentifier, parent)), m_clientBufferProcessesTimer(new QTimer(this)), m_messageId(0) { @@ -48,19 +49,19 @@ Listener::Listener(const QByteArray &resourceName, QObject *parent) this, &Listener::refreshRevision); connect(m_server, &QLocalServer::newConnection, this, &Listener::acceptConnection); - Trace() << "Trying to open " << m_resourceName; + Trace() << "Trying to open " << m_resourceInstanceIdentifier; - m_lockfile = new QLockFile(resourceName + ".lock"); + m_lockfile = new QLockFile(m_resourceInstanceIdentifier + ".lock"); m_lockfile->setStaleLockTime(0); if (!m_lockfile->tryLock(0)) { Warning() << "Failed to acquire exclusive lock on socket."; exit(-1); } - if (!m_server->listen(QString::fromLatin1(resourceName))) { + if (!m_server->listen(QString::fromLatin1(m_resourceInstanceIdentifier))) { // FIXME: multiple starts need to be handled here - m_server->removeServer(resourceName); - if (!m_server->listen(QString::fromLatin1(resourceName))) { + m_server->removeServer(m_resourceInstanceIdentifier); + if (!m_server->listen(QString::fromLatin1(m_resourceInstanceIdentifier))) { Warning() << "Utter failure to start server"; exit(-1); } diff --git a/synchronizer/listener.h b/synchronizer/listener.h index b3929e7..2577673 100644 --- a/synchronizer/listener.h +++ b/synchronizer/listener.h @@ -90,6 +90,7 @@ private: QVector m_connections; flatbuffers::FlatBufferBuilder m_fbb; const QByteArray m_resourceName; + const QByteArray m_resourceInstanceIdentifier; Akonadi2::Resource *m_resource; Akonadi2::Pipeline *m_pipeline; QTimer *m_clientBufferProcessesTimer; diff --git a/tests/dummyresourcetest.cpp b/tests/dummyresourcetest.cpp index 9523e5d..fe04d99 100644 --- a/tests/dummyresourcetest.cpp +++ b/tests/dummyresourcetest.cpp @@ -26,19 +26,19 @@ private Q_SLOTS: { auto factory = Akonadi2::ResourceFactory::load("org.kde.dummy"); QVERIFY(factory); - removeFromDisk("org.kde.dummy"); - removeFromDisk("org.kde.dummy.userqueue"); - removeFromDisk("org.kde.dummy.synchronizerqueue"); - removeFromDisk("org.kde.dummy.index.uid"); + removeFromDisk("org.kde.dummy.instance1"); + removeFromDisk("org.kde.dummy.instance1.userqueue"); + removeFromDisk("org.kde.dummy.instance1.synchronizerqueue"); + removeFromDisk("org.kde.dummy.instance1.index.uid"); } void cleanup() { - Akonadi2::Store::shutdown("org.kde.dummy"); - removeFromDisk("org.kde.dummy"); - removeFromDisk("org.kde.dummy.userqueue"); - removeFromDisk("org.kde.dummy.synchronizerqueue"); - removeFromDisk("org.kde.dummy.index.uid"); + Akonadi2::Store::shutdown("org.kde.dummy.instance1"); + removeFromDisk("org.kde.dummy.instance1"); + removeFromDisk("org.kde.dummy.instance1.userqueue"); + removeFromDisk("org.kde.dummy.instance1.synchronizerqueue"); + removeFromDisk("org.kde.dummy.instance1.index.uid"); auto factory = Akonadi2::ResourceFactory::load("org.kde.dummy"); QVERIFY(factory); } @@ -83,7 +83,7 @@ private Q_SLOTS: } //Actual test - Akonadi2::Pipeline pipeline("org.kde.dummy"); + Akonadi2::Pipeline pipeline("org.kde.dummy.instance1"); QSignalSpy revisionSpy(&pipeline, SIGNAL(revisionUpdated())); DummyResource resource; resource.configurePipeline(&pipeline); @@ -109,10 +109,10 @@ private Q_SLOTS: event.setProperty("uid", "testuid"); QCOMPARE(event.getProperty("uid").toByteArray(), QByteArray("testuid")); event.setProperty("summary", "summaryValue"); - Akonadi2::Store::create(event, "org.kde.dummy"); + Akonadi2::Store::create(event, "org.kde.dummy.instance1"); Akonadi2::Query query; - query.resources << "org.kde.dummy"; + query.resources << "org.kde.dummy.instance1"; query.syncOnDemand = false; query.processAll = true; @@ -126,7 +126,7 @@ private Q_SLOTS: void testResourceSync() { - Akonadi2::Pipeline pipeline("org.kde.dummy"); + Akonadi2::Pipeline pipeline("org.kde.dummy.instance1"); DummyResource resource; resource.configurePipeline(&pipeline); auto job = resource.synchronizeWithSource(&pipeline); @@ -143,7 +143,7 @@ private Q_SLOTS: void testSyncAndFacade() { Akonadi2::Query query; - query.resources << "org.kde.dummy"; + query.resources << "org.kde.dummy.instance1"; query.syncOnDemand = true; query.processAll = true; -- cgit v1.2.3