From 59aa460cf704d5f1a1fb1fe6b8ede4457da083ff Mon Sep 17 00:00:00 2001 From: Christian Mollekopf Date: Sun, 4 Dec 2016 10:36:58 +0100 Subject: Copy command and proper move --- common/facade.cpp | 12 ++++++++++++ common/facade.h | 1 + common/facadeinterface.h | 12 ++++++++++++ common/pipeline.cpp | 14 +++++++++++++- common/resourcefacade.cpp | 6 ++++++ common/resourcefacade.h | 1 + common/storage/entitystore.cpp | 4 ++-- common/storage_lmdb.cpp | 1 + common/store.cpp | 10 ++++++++++ common/store.h | 6 ++++++ common/test.cpp | 5 +++++ 11 files changed, 69 insertions(+), 3 deletions(-) (limited to 'common') diff --git a/common/facade.cpp b/common/facade.cpp index c618d4e..4f03073 100644 --- a/common/facade.cpp +++ b/common/facade.cpp @@ -80,6 +80,18 @@ KAsync::Job GenericFacade::move(const DomainType &domainObject SinkWarning() << "No domain type adaptor factory available"; return KAsync::error(); } + return mResourceAccess->sendModifyCommand(domainObject.identifier(), domainObject.revision(), bufferTypeForDomainType(), QByteArrayList(), BufferUtils::extractBuffer(entityFbb), domainObject.changedProperties(), newResource, true); +} + +template +KAsync::Job GenericFacade::copy(const DomainType &domainObject, const QByteArray &newResource) +{ + SinkTrace() << "Copying entity: " << domainObject.identifier() << domainObject.changedProperties() << newResource; + flatbuffers::FlatBufferBuilder entityFbb; + if (!mResourceContext.adaptorFactory().createBuffer(domainObject, entityFbb)) { + SinkWarning() << "No domain type adaptor factory available"; + return KAsync::error(); + } return mResourceAccess->sendModifyCommand(domainObject.identifier(), domainObject.revision(), bufferTypeForDomainType(), QByteArrayList(), BufferUtils::extractBuffer(entityFbb), domainObject.changedProperties(), newResource, false); } diff --git a/common/facade.h b/common/facade.h index 0fba34a..c10886f 100644 --- a/common/facade.h +++ b/common/facade.h @@ -64,6 +64,7 @@ public: KAsync::Job create(const DomainType &domainObject) Q_DECL_OVERRIDE; KAsync::Job modify(const DomainType &domainObject) Q_DECL_OVERRIDE; KAsync::Job move(const DomainType &domainObject, const QByteArray &newResource) Q_DECL_OVERRIDE; + KAsync::Job copy(const DomainType &domainObject, const QByteArray &newResource) Q_DECL_OVERRIDE; KAsync::Job remove(const DomainType &domainObject) Q_DECL_OVERRIDE; virtual QPair, typename ResultEmitter::Ptr> load(const Sink::Query &query) Q_DECL_OVERRIDE; diff --git a/common/facadeinterface.h b/common/facadeinterface.h index 136791e..5d12360 100644 --- a/common/facadeinterface.h +++ b/common/facadeinterface.h @@ -69,6 +69,13 @@ public: */ virtual KAsync::Job move(const DomainType &domainObject, const QByteArray &newResource) = 0; + /** + * Copy an entity to a new resource. + * + * The job returns succefully once the task has been successfully placed in the queue + */ + virtual KAsync::Job copy(const DomainType &domainObject, const QByteArray &newResource) = 0; + /** * Remove an entity from the store. * @@ -102,6 +109,11 @@ public: return KAsync::error(-1, "Failed to create a facade"); } + KAsync::Job copy(const DomainType &domainObject, const QByteArray &newResource) + { + return KAsync::error(-1, "Failed to create a facade"); + } + KAsync::Job remove(const DomainType &domainObject) { return KAsync::error(-1, "Failed to create a facade"); diff --git a/common/pipeline.cpp b/common/pipeline.cpp index 8ace855..b94e3f0 100644 --- a/common/pipeline.cpp +++ b/common/pipeline.cpp @@ -249,6 +249,7 @@ KAsync::Job Pipeline::modifiedEntity(void const *command, size_t size) } if (modifyEntity->targetResource()) { + auto isMove = modifyEntity->removeEntity(); auto targetResource = BufferUtils::extractBuffer(modifyEntity->targetResource()); auto changeset = diff.changedProperties(); const auto current = d->entityStore.readLatest(bufferType, diff.identifier()); @@ -276,9 +277,20 @@ KAsync::Job Pipeline::modifiedEntity(void const *command, size_t size) SinkTrace() << "Moving entity to new resource " << newEntity.identifier() << newEntity.resourceInstanceIdentifier() << targetResource; auto job = TypeHelper{bufferType}.operator(), ApplicationDomain::ApplicationDomainType&>(newEntity); - job = job.syncThen([=](const KAsync::Error &error) { + job = job.syncThen([this, newEntity, isMove, targetResource, bufferType](const KAsync::Error &error) { if (!error) { SinkTrace() << "Move of " << newEntity.identifier() << "was successfull"; + if (isMove) { + startTransaction(); + flatbuffers::FlatBufferBuilder fbb; + auto entityId = fbb.CreateString(newEntity.identifier()); + auto type = fbb.CreateString(bufferType); + auto location = Sink::Commands::CreateDeleteEntity(fbb, newEntity.revision(), entityId, type, true); + Sink::Commands::FinishDeleteEntityBuffer(fbb, location); + const auto data = BufferUtils::extractBuffer(fbb); + deletedEntity(data, data.size()).exec(); + commit(); + } } else { SinkError() << "Failed to move entity " << targetResource << " to resource " << newEntity.identifier(); } diff --git a/common/resourcefacade.cpp b/common/resourcefacade.cpp index 0a05bd9..c4e16b1 100644 --- a/common/resourcefacade.cpp +++ b/common/resourcefacade.cpp @@ -224,6 +224,12 @@ KAsync::Job LocalStorageFacade::move(const DomainType &, const return KAsync::error(1, "Resources and Accounts cannot be moved."); } +template +KAsync::Job LocalStorageFacade::copy(const DomainType &, const QByteArray &) +{ + return KAsync::error(1, "Resources and Accounts cannot be copied."); +} + template KAsync::Job LocalStorageFacade::remove(const DomainType &domainObject) { diff --git a/common/resourcefacade.h b/common/resourcefacade.h index ea552c2..4575e72 100644 --- a/common/resourcefacade.h +++ b/common/resourcefacade.h @@ -82,6 +82,7 @@ public: virtual KAsync::Job create(const DomainType &resource) Q_DECL_OVERRIDE; virtual KAsync::Job modify(const DomainType &resource) Q_DECL_OVERRIDE; virtual KAsync::Job move(const DomainType &resource, const QByteArray &) Q_DECL_OVERRIDE; + virtual KAsync::Job copy(const DomainType &resource, const QByteArray &) Q_DECL_OVERRIDE; virtual KAsync::Job remove(const DomainType &resource) Q_DECL_OVERRIDE; virtual QPair, typename Sink::ResultEmitter::Ptr> load(const Sink::Query &query) Q_DECL_OVERRIDE; diff --git a/common/storage/entitystore.cpp b/common/storage/entitystore.cpp index b6251b6..1417861 100644 --- a/common/storage/entitystore.cpp +++ b/common/storage/entitystore.cpp @@ -239,11 +239,11 @@ bool EntityStore::remove(const QByteArray &type, const QByteArray &uid, bool rep [](const DataStore::Error &error) { SinkWarning() << "Failed to read old revision from storage: " << error.message; }); if (!found) { - SinkWarning() << "Failed to find entity " << uid; + SinkWarning() << "Remove: Failed to find entity " << uid; return false; } if (alreadyRemoved) { - SinkWarning() << "Entity is already removed " << uid; + SinkWarning() << "Remove: Entity is already removed " << uid; return false; } diff --git a/common/storage_lmdb.cpp b/common/storage_lmdb.cpp index e418472..fa99a80 100644 --- a/common/storage_lmdb.cpp +++ b/common/storage_lmdb.cpp @@ -520,6 +520,7 @@ bool DataStore::Transaction::validateNamedDatabases() DataStore::NamedDatabase DataStore::Transaction::openDatabase(const QByteArray &db, const std::function &errorHandler, bool allowDuplicates) const { if (!d) { + SinkError() << "Tried to open database on invalid transaction: " << db; return DataStore::NamedDatabase(); } Q_ASSERT(d->transaction); diff --git a/common/store.cpp b/common/store.cpp index fad8c5e..ef8a593 100644 --- a/common/store.cpp +++ b/common/store.cpp @@ -224,6 +224,15 @@ KAsync::Job Store::move(const DomainType &domainObject, const QByteArray & return facade->move(domainObject, newResource).addToContext(std::shared_ptr(facade)).onError([](const KAsync::Error &error) { SinkWarning() << "Failed to move"; }); } +template +KAsync::Job Store::copy(const DomainType &domainObject, const QByteArray &newResource) +{ + SinkTrace() << "Copy: " << domainObject << newResource; + // Potentially copy to separate thread as well + auto facade = getFacade(domainObject.resourceInstanceIdentifier()); + return facade->copy(domainObject, newResource).addToContext(std::shared_ptr(facade)).onError([](const KAsync::Error &error) { SinkWarning() << "Failed to copy"; }); +} + template KAsync::Job Store::remove(const DomainType &domainObject) { @@ -396,6 +405,7 @@ QList Store::read(const Sink::Query &q) template KAsync::Job Store::create(const T &domainObject); \ template KAsync::Job Store::modify(const T &domainObject); \ template KAsync::Job Store::move(const T &domainObject, const QByteArray &newResource); \ + template KAsync::Job Store::copy(const T &domainObject, const QByteArray &newResource); \ template QSharedPointer Store::loadModel(Query query); \ template KAsync::Job Store::fetchOne(const Query &); \ template KAsync::Job> Store::fetchAll(const Query &); \ diff --git a/common/store.h b/common/store.h index 7c7d2fe..b261f47 100644 --- a/common/store.h +++ b/common/store.h @@ -87,6 +87,12 @@ KAsync::Job SINK_EXPORT remove(const DomainType &domainObject); template KAsync::Job SINK_EXPORT move(const DomainType &domainObject, const QByteArray &newResource); +/** + * Copy an entity to a new resource. + */ +template +KAsync::Job SINK_EXPORT copy(const DomainType &domainObject, const QByteArray &newResource); + /** * Synchronize data to local cache. */ diff --git a/common/test.cpp b/common/test.cpp index 74c499c..0c7ba10 100644 --- a/common/test.cpp +++ b/common/test.cpp @@ -130,6 +130,11 @@ public: // mTestAccount->moveEntity(domainObject, newResource); return KAsync::null(); }; + KAsync::Job copy(const T &domainObject, const QByteArray &newResource) Q_DECL_OVERRIDE + { + // mTestAccount->copyEntity(domainObject, newResource); + return KAsync::null(); + }; KAsync::Job remove(const T &domainObject) Q_DECL_OVERRIDE { //FIXME -- cgit v1.2.3