[prev in list] [next in list] [prev in thread] [next in thread] 

List:       kde-commits
Subject:    [sink/develop] /: interresource move
From:       Christian Mollekopf <chrigi_1 () fastmail ! fm>
Date:       2016-12-09 15:45:47
Message-ID: E1cFNMp-0007L1-VH () code ! kde ! org
[Download RAW message or body]

Git commit 41006b5cab7b0260f8abc42aa2d2e959a013764e by Christian Mollekopf.
Committed on 02/12/2016 at 20:32.
Pushed by cmollekopf into branch 'develop'.

interresource move

M  +2    -0    common/commands/modifyentity.fbs
M  +5    -0    common/domain/applicationdomaintype.cpp
M  +1    -0    common/domain/applicationdomaintype.h
M  +13   -1    common/facade.cpp
M  +1    -0    common/facade.h
M  +12   -0    common/facadeinterface.h
M  +48   -0    common/pipeline.cpp
M  +3    -4    common/resourceaccess.cpp
M  +2    -2    common/resourceaccess.h
M  +6    -0    common/resourcefacade.cpp
M  +1    -0    common/resourcefacade.h
M  +10   -0    common/store.cpp
M  +6    -0    common/store.h
M  +5    -0    common/test.cpp
M  +1    -0    tests/CMakeLists.txt
M  +4    -0    tests/clientapitest.cpp

https://commits.kde.org/sink/41006b5cab7b0260f8abc42aa2d2e959a013764e

diff --git a/common/commands/modifyentity.fbs b/common/commands/modifyentity.fbs
index da6f0e2..d81bacf 100644
--- a/common/commands/modifyentity.fbs
+++ b/common/commands/modifyentity.fbs
@@ -8,6 +8,8 @@ table ModifyEntity {
     delta: [ubyte]; //Contains an entity buffer with all changed properties set
     replayToSource: bool = true;
     modifiedProperties: [string];
+    targetResource: string; //Contains the target resource for a move/copy operation
+    removeEntity: bool = false; //This modification removes the entity
 }
 
 root_type ModifyEntity;
diff --git a/common/domain/applicationdomaintype.cpp \
b/common/domain/applicationdomaintype.cpp index b30eb36..105ae56 100644
--- a/common/domain/applicationdomaintype.cpp
+++ b/common/domain/applicationdomaintype.cpp
@@ -98,6 +98,11 @@ void ApplicationDomainType::setProperty(const QByteArray &key, \
const QVariant &v  mAdaptor->setProperty(key, value);
 }
 
+void ApplicationDomainType::setResource(const QByteArray &identifier)
+{
+    mResourceInstanceIdentifier = identifier;
+}
+
 void ApplicationDomainType::setProperty(const QByteArray &key, const \
ApplicationDomainType &value)  {
     Q_ASSERT(!value.identifier().isEmpty());
diff --git a/common/domain/applicationdomaintype.h \
b/common/domain/applicationdomaintype.h index 4621316..d6bbdd4 100644
--- a/common/domain/applicationdomaintype.h
+++ b/common/domain/applicationdomaintype.h
@@ -168,6 +168,7 @@ public:
     QByteArrayList availableProperties() const;
     qint64 revision() const;
     QByteArray resourceInstanceIdentifier() const;
+    void setResource(const QByteArray &identifier);
     QByteArray identifier() const;
 
 private:
diff --git a/common/facade.cpp b/common/facade.cpp
index 3ec58e3..c618d4e 100644
--- a/common/facade.cpp
+++ b/common/facade.cpp
@@ -68,7 +68,19 @@ KAsync::Job<void> GenericFacade<DomainType>::modify(const \
DomainType &domainObje  SinkWarning() << "No domain type adaptor factory available";
         return KAsync::error<void>();
     }
-    return mResourceAccess->sendModifyCommand(domainObject.identifier(), \
domainObject.revision(), bufferTypeForDomainType(), QByteArrayList(), \
BufferUtils::extractBuffer(entityFbb), domainObject.changedProperties()); +    return \
mResourceAccess->sendModifyCommand(domainObject.identifier(), \
domainObject.revision(), bufferTypeForDomainType(), QByteArrayList(), \
BufferUtils::extractBuffer(entityFbb), domainObject.changedProperties(), \
QByteArray(), false); +}
+
+template <class DomainType>
+KAsync::Job<void> GenericFacade<DomainType>::move(const DomainType &domainObject, \
const QByteArray &newResource) +{
+    SinkTrace() << "Moving entity: " << domainObject.identifier() << \
domainObject.changedProperties() << newResource; +    flatbuffers::FlatBufferBuilder \
entityFbb; +    if (!mResourceContext.adaptorFactory<DomainType>().createBuffer(domainObject, \
entityFbb)) { +        SinkWarning() << "No domain type adaptor factory available";
+        return KAsync::error<void>();
+    }
+    return mResourceAccess->sendModifyCommand(domainObject.identifier(), \
domainObject.revision(), bufferTypeForDomainType(), QByteArrayList(), \
BufferUtils::extractBuffer(entityFbb), domainObject.changedProperties(), newResource, \
false);  }
 
 template <class DomainType>
diff --git a/common/facade.h b/common/facade.h
index 50d93e0..0fba34a 100644
--- a/common/facade.h
+++ b/common/facade.h
@@ -63,6 +63,7 @@ public:
     static QByteArray bufferTypeForDomainType();
     KAsync::Job<void> create(const DomainType &domainObject) Q_DECL_OVERRIDE;
     KAsync::Job<void> modify(const DomainType &domainObject) Q_DECL_OVERRIDE;
+    KAsync::Job<void> move(const DomainType &domainObject, const QByteArray \
                &newResource) Q_DECL_OVERRIDE;
     KAsync::Job<void> remove(const DomainType &domainObject) Q_DECL_OVERRIDE;
     virtual QPair<KAsync::Job<void>, typename ResultEmitter<typename \
DomainType::Ptr>::Ptr> load(const Sink::Query &query) Q_DECL_OVERRIDE;  
diff --git a/common/facadeinterface.h b/common/facadeinterface.h
index 7d5dd7d..136791e 100644
--- a/common/facadeinterface.h
+++ b/common/facadeinterface.h
@@ -63,6 +63,13 @@ public:
     virtual KAsync::Job<void> modify(const DomainType &domainObject) = 0;
 
     /**
+     * Move an entity to a new resource.
+     *
+     * The job returns succefully once the task has been successfully placed in the \
queue +     */
+    virtual KAsync::Job<void> move(const DomainType &domainObject, const QByteArray \
&newResource) = 0; +
+    /**
      * Remove an entity from the store.
      *
      * The job returns succefully once the task has been successfully placed in the \
queue @@ -90,6 +97,11 @@ public:
         return KAsync::error<void>(-1, "Failed to create a facade");
     }
 
+    KAsync::Job<void> move(const DomainType &domainObject, const QByteArray \
&newResource) +    {
+        return KAsync::error<void>(-1, "Failed to create a facade");
+    }
+
     KAsync::Job<void> remove(const DomainType &domainObject)
     {
         return KAsync::error<void>(-1, "Failed to create a facade");
diff --git a/common/pipeline.cpp b/common/pipeline.cpp
index 1eea631..8ace855 100644
--- a/common/pipeline.cpp
+++ b/common/pipeline.cpp
@@ -34,10 +34,12 @@
 #include "entitybuffer.h"
 #include "log.h"
 #include "domain/applicationdomaintype.h"
+#include "domain/applicationdomaintype_p.h"
 #include "adaptorfactoryregistry.h"
 #include "definitions.h"
 #include "bufferutils.h"
 #include "storage/entitystore.h"
+#include "store.h"
 
 SINK_DEBUG_AREA("pipeline")
 
@@ -186,6 +188,13 @@ KAsync::Job<qint64> Pipeline::newEntity(void const *command, \
size_t size)  return KAsync::value(d->entityStore.maxRevision());
 }
 
+template <class T>
+struct CreateHelper {
+    KAsync::Job<void> operator()(const ApplicationDomain::ApplicationDomainType \
&arg) const { +        return Sink::Store::create<T>(arg);
+    }
+};
+
 KAsync::Job<qint64> Pipeline::modifiedEntity(void const *command, size_t size)
 {
     d->transactionItemCount++;
@@ -239,6 +248,45 @@ KAsync::Job<qint64> Pipeline::modifiedEntity(void const \
*command, size_t size)  deletions = \
BufferUtils::fromVector(*modifyEntity->deletions());  }
 
+    if (modifyEntity->targetResource()) {
+        auto targetResource = \
BufferUtils::extractBuffer(modifyEntity->targetResource()); +        auto changeset = \
diff.changedProperties(); +        const auto current = \
d->entityStore.readLatest(bufferType, diff.identifier()); +        if \
(current.identifier().isEmpty()) { +            SinkWarning() << "Failed to read \
current version: " << diff.identifier(); +            return \
KAsync::error<qint64>(0); +        }
+
+        auto newEntity = \
*ApplicationDomain::ApplicationDomainType::getInMemoryRepresentation<ApplicationDomain::ApplicationDomainType>(current, \
current.availableProperties()); +
+        // Apply diff
+        for (const auto &property : changeset) {
+            const auto value = diff.getProperty(property);
+            if (value.isValid()) {
+                newEntity.setProperty(property, value);
+            }
+        }
+
+        // Remove deletions
+        for (const auto property : deletions) {
+            newEntity.setProperty(property, QVariant());
+        }
+        newEntity.setResource(targetResource);
+        newEntity.setChangedProperties(newEntity.availableProperties().toSet());
+
+        SinkTrace() << "Moving entity to new resource " << newEntity.identifier() << \
newEntity.resourceInstanceIdentifier() << targetResource; +        auto job = \
TypeHelper<CreateHelper>{bufferType}.operator()<KAsync::Job<void>, \
ApplicationDomain::ApplicationDomainType&>(newEntity); +        job = \
job.syncThen<void>([=](const KAsync::Error &error) { +            if (!error) {
+                SinkTrace() << "Move of " << newEntity.identifier() << "was \
successfull"; +            } else {
+                SinkError() << "Failed to move entity " << targetResource << " to \
resource " << newEntity.identifier(); +            }
+        });
+        job.exec();
+        return KAsync::value<qint64>(0);
+    }
+
     auto preprocess = [&, this](const ApplicationDomain::ApplicationDomainType \
&oldEntity, ApplicationDomain::ApplicationDomainType &newEntity) {  foreach (const \
auto &processor, d->processors[bufferType]) {  processor->modifiedEntity(oldEntity, \
                newEntity);
diff --git a/common/resourceaccess.cpp b/common/resourceaccess.cpp
index b46e8b2..81715e5 100644
--- a/common/resourceaccess.cpp
+++ b/common/resourceaccess.cpp
@@ -323,16 +323,16 @@ KAsync::Job<void> ResourceAccess::sendCreateCommand(const \
QByteArray &uid, const  }
 
 KAsync::Job<void>
-ResourceAccess::sendModifyCommand(const QByteArray &uid, qint64 revision, const \
QByteArray &resourceBufferType, const QByteArrayList &deletedProperties, const \
QByteArray &buffer, const QByteArrayList &changedProperties) \
+ResourceAccess::sendModifyCommand(const QByteArray &uid, qint64 revision, const \
QByteArray &resourceBufferType, const QByteArrayList &deletedProperties, const \
QByteArray &buffer, const QByteArrayList &changedProperties, const QByteArray \
&newResource, bool remove)  {
     flatbuffers::FlatBufferBuilder fbb;
     auto entityId = fbb.CreateString(uid.constData());
-    // This is the resource buffer type and not the domain type
     auto type = fbb.CreateString(resourceBufferType.constData());
     auto modifiedProperties = BufferUtils::toVector(fbb, changedProperties);
     auto deletions = BufferUtils::toVector(fbb, deletedProperties);
     auto delta = Sink::EntityBuffer::appendAsVector(fbb, buffer.constData(), \
                buffer.size());
-    auto location = Sink::Commands::CreateModifyEntity(fbb, revision, entityId, \
deletions, type, delta, true, modifiedProperties); +    auto resource = \
newResource.isEmpty() ? 0 : fbb.CreateString(newResource.constData()); +    auto \
location = Sink::Commands::CreateModifyEntity(fbb, revision, entityId, deletions, \
type, delta, true, modifiedProperties, resource, remove);  \
Sink::Commands::FinishModifyEntityBuffer(fbb, location);  open();
     return sendCommand(Sink::Commands::ModifyEntityCommand, fbb);
@@ -342,7 +342,6 @@ KAsync::Job<void> ResourceAccess::sendDeleteCommand(const \
QByteArray &uid, qint6  {
     flatbuffers::FlatBufferBuilder fbb;
     auto entityId = fbb.CreateString(uid.constData());
-    // This is the resource buffer type and not the domain type
     auto type = fbb.CreateString(resourceBufferType.constData());
     auto location = Sink::Commands::CreateDeleteEntity(fbb, revision, entityId, \
type);  Sink::Commands::FinishDeleteEntityBuffer(fbb, location);
diff --git a/common/resourceaccess.h b/common/resourceaccess.h
index 4229161..de15125 100644
--- a/common/resourceaccess.h
+++ b/common/resourceaccess.h
@@ -57,7 +57,7 @@ public:
     {
         return KAsync::null<void>();
     };
-    virtual KAsync::Job<void> sendModifyCommand(const QByteArray &uid, qint64 \
revision, const QByteArray &resourceBufferType, const QByteArrayList \
&deletedProperties, const QByteArray &buffer, const QByteArrayList \
&changedProperties) +    virtual KAsync::Job<void> sendModifyCommand(const QByteArray \
&uid, qint64 revision, const QByteArray &resourceBufferType, const QByteArrayList \
&deletedProperties, const QByteArray &buffer, const QByteArrayList \
&changedProperties, const QByteArray &newResource, bool remove)  {
         return KAsync::null<void>();
     };
@@ -116,7 +116,7 @@ public:
     KAsync::Job<void> synchronizeResource(const Sink::QueryBase &filter) \
                Q_DECL_OVERRIDE;
     KAsync::Job<void> sendCreateCommand(const QByteArray &uid, const QByteArray \
&resourceBufferType, const QByteArray &buffer) Q_DECL_OVERRIDE;  KAsync::Job<void>
-    sendModifyCommand(const QByteArray &uid, qint64 revision, const QByteArray \
&resourceBufferType, const QByteArrayList &deletedProperties, const QByteArray \
&buffer, const QByteArrayList &changedProperties) Q_DECL_OVERRIDE; +    \
sendModifyCommand(const QByteArray &uid, qint64 revision, const QByteArray \
&resourceBufferType, const QByteArrayList &deletedProperties, const QByteArray \
&buffer, const QByteArrayList &changedProperties, const QByteArray &newResource, bool \
                remove) Q_DECL_OVERRIDE;
     KAsync::Job<void> sendDeleteCommand(const QByteArray &uid, qint64 revision, \
                const QByteArray &resourceBufferType) Q_DECL_OVERRIDE;
     KAsync::Job<void> sendRevisionReplayedCommand(qint64 revision) Q_DECL_OVERRIDE;
     KAsync::Job<void>
diff --git a/common/resourcefacade.cpp b/common/resourcefacade.cpp
index e5b4496..0a05bd9 100644
--- a/common/resourcefacade.cpp
+++ b/common/resourcefacade.cpp
@@ -219,6 +219,12 @@ KAsync::Job<void> LocalStorageFacade<DomainType>::modify(const \
DomainType &domai  }
 
 template <typename DomainType>
+KAsync::Job<void> LocalStorageFacade<DomainType>::move(const DomainType &, const \
QByteArray &) +{
+    return KAsync::error<void>(1, "Resources and Accounts cannot be moved.");
+}
+
+template <typename DomainType>
 KAsync::Job<void> LocalStorageFacade<DomainType>::remove(const DomainType \
&domainObject)  {
     auto configStoreIdentifier = mIdentifier;
diff --git a/common/resourcefacade.h b/common/resourcefacade.h
index d259d4f..ea552c2 100644
--- a/common/resourcefacade.h
+++ b/common/resourcefacade.h
@@ -81,6 +81,7 @@ public:
     virtual ~LocalStorageFacade();
     virtual KAsync::Job<void> create(const DomainType &resource) Q_DECL_OVERRIDE;
     virtual KAsync::Job<void> modify(const DomainType &resource) Q_DECL_OVERRIDE;
+    virtual KAsync::Job<void> move(const DomainType &resource, const QByteArray &) \
                Q_DECL_OVERRIDE;
     virtual KAsync::Job<void> remove(const DomainType &resource) Q_DECL_OVERRIDE;
     virtual QPair<KAsync::Job<void>, typename Sink::ResultEmitter<typename \
DomainType::Ptr>::Ptr> load(const Sink::Query &query) Q_DECL_OVERRIDE;  
diff --git a/common/store.cpp b/common/store.cpp
index f91973d..fad8c5e 100644
--- a/common/store.cpp
+++ b/common/store.cpp
@@ -216,6 +216,15 @@ KAsync::Job<void> Store::modify(const DomainType &domainObject)
 }
 
 template <class DomainType>
+KAsync::Job<void> Store::move(const DomainType &domainObject, const QByteArray \
&newResource) +{
+    SinkTrace() << "Move: " << domainObject << newResource;
+    // Potentially move to separate thread as well
+    auto facade = getFacade<DomainType>(domainObject.resourceInstanceIdentifier());
+    return facade->move(domainObject, \
newResource).addToContext(std::shared_ptr<void>(facade)).onError([](const \
KAsync::Error &error) { SinkWarning() << "Failed to move"; }); +}
+
+template <class DomainType>
 KAsync::Job<void> Store::remove(const DomainType &domainObject)
 {
     SinkTrace() << "Remove: " << domainObject;
@@ -386,6 +395,7 @@ QList<DomainType> Store::read(const Sink::Query &q)
     template KAsync::Job<void> Store::remove<T>(const T &domainObject);           \
     template KAsync::Job<void> Store::create<T>(const T &domainObject);           \
     template KAsync::Job<void> Store::modify<T>(const T &domainObject);           \
+    template KAsync::Job<void> Store::move<T>(const T &domainObject, const \
                QByteArray &newResource);           \
     template QSharedPointer<QAbstractItemModel> Store::loadModel<T>(Query query); \
     template KAsync::Job<T> Store::fetchOne<T>(const Query &);                    \
     template KAsync::Job<QList<T::Ptr>> Store::fetchAll<T>(const Query &);        \
diff --git a/common/store.h b/common/store.h
index c9bd9cf..7c7d2fe 100644
--- a/common/store.h
+++ b/common/store.h
@@ -82,6 +82,12 @@ template <class DomainType>
 KAsync::Job<void> SINK_EXPORT remove(const DomainType &domainObject);
 
 /**
+ * Move an entity to a new resource.
+ */
+template <class DomainType>
+KAsync::Job<void> SINK_EXPORT move(const DomainType &domainObject, const QByteArray \
&newResource); +
+/**
  * Synchronize data to local cache.
  */
 KAsync::Job<void> SINK_EXPORT synchronize(const Sink::Query &query);
diff --git a/common/test.cpp b/common/test.cpp
index 1a0d9bc..74c499c 100644
--- a/common/test.cpp
+++ b/common/test.cpp
@@ -125,6 +125,11 @@ public:
         // mTestAccount->modifyEntity<T>(domainObject);
         return KAsync::null<void>();
     };
+    KAsync::Job<void> move(const T &domainObject, const QByteArray &newResource) \
Q_DECL_OVERRIDE +    {
+        // mTestAccount->moveEntity<T>(domainObject, newResource);
+        return KAsync::null<void>();
+    };
     KAsync::Job<void> remove(const T &domainObject) Q_DECL_OVERRIDE
     {
         //FIXME
diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt
index f8fe3b3..a69fcb3 100644
--- a/tests/CMakeLists.txt
+++ b/tests/CMakeLists.txt
@@ -47,6 +47,7 @@ auto_tests (
     accountstest
     testaccounttest
     dummyresourcemailtest
+    interresourcemovetest
 )
 generate_flatbuffers(dummyresourcetest calendar)
 target_link_libraries(dummyresourcetest sink_resource_dummy)
diff --git a/tests/clientapitest.cpp b/tests/clientapitest.cpp
index ae9286c..71be514 100644
--- a/tests/clientapitest.cpp
+++ b/tests/clientapitest.cpp
@@ -41,6 +41,10 @@ public:
     {
         return KAsync::null<void>();
     };
+    KAsync::Job<void> move(const T &domainObject, const QByteArray &) \
Q_DECL_OVERRIDE +    {
+        return KAsync::null<void>();
+    };
     KAsync::Job<void> remove(const T &domainObject) Q_DECL_OVERRIDE
     {
         return KAsync::null<void>();


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic