summaryrefslogtreecommitdiffstats
path: root/common/sourcewriteback.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'common/sourcewriteback.cpp')
-rw-r--r--common/sourcewriteback.cpp124
1 files changed, 124 insertions, 0 deletions
diff --git a/common/sourcewriteback.cpp b/common/sourcewriteback.cpp
new file mode 100644
index 0000000..1ef20d2
--- /dev/null
+++ b/common/sourcewriteback.cpp
@@ -0,0 +1,124 @@
1/*
2 * Copyright (C) 2016 Christian Mollekopf <mollekopf@kolabsys.com>
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) version 3, or any
8 * later version accepted by the membership of KDE e.V. (or its
9 * successor approved by the membership of KDE e.V.), which shall
10 * act as a proxy defined in Section 6 of version 3 of the license.
11 *
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library. If not, see <http://www.gnu.org/licenses/>.
19 */
20#include "sourcewriteback.h"
21
22#include "definitions.h"
23#include "log.h"
24
25#define ENTITY_TYPE_MAIL "mail"
26#define ENTITY_TYPE_FOLDER "folder"
27
28using namespace Sink;
29
30SourceWriteBack::SourceWriteBack(const QByteArray &resourceType, const QByteArray &resourceInstanceIdentifier)
31 : ChangeReplay(resourceInstanceIdentifier),
32 mSyncStorage(Sink::storageLocation(), resourceInstanceIdentifier + ".synchronization", Sink::Storage::ReadWrite),
33 mResourceType(resourceType),
34 mResourceInstanceIdentifier(resourceInstanceIdentifier)
35{
36
37}
38
39EntityStore &SourceWriteBack::store()
40{
41 if (!mEntityStore) {
42 mEntityStore = QSharedPointer<EntityStore>::create(mResourceType, mResourceInstanceIdentifier, mTransaction);
43 }
44 return *mEntityStore;
45}
46
47RemoteIdMap &SourceWriteBack::syncStore()
48{
49 if (!mSyncStore) {
50 mSyncStore = QSharedPointer<RemoteIdMap>::create(mSyncTransaction);
51 }
52 return *mSyncStore;
53}
54
55KAsync::Job<void> SourceWriteBack::replay(const QByteArray &type, const QByteArray &key, const QByteArray &value)
56{
57 mTransaction = mStorage.createTransaction(Sink::Storage::ReadOnly);
58 mSyncTransaction = mSyncStorage.createTransaction(Sink::Storage::ReadWrite);
59
60 Sink::EntityBuffer buffer(value);
61 const Sink::Entity &entity = buffer.entity();
62 const auto metadataBuffer = Sink::EntityBuffer::readBuffer<Sink::Metadata>(entity.metadata());
63 Q_ASSERT(metadataBuffer);
64 if (!metadataBuffer->replayToSource()) {
65 Trace() << "Change is coming from the source";
66 return KAsync::null<void>();
67 }
68 const qint64 revision = metadataBuffer ? metadataBuffer->revision() : -1;
69 const auto operation = metadataBuffer ? metadataBuffer->operation() : Sink::Operation_Creation;
70 const auto uid = Sink::Storage::uidFromKey(key);
71 QByteArray oldRemoteId;
72
73 if (operation != Sink::Operation_Creation) {
74 oldRemoteId = syncStore().resolveLocalId(type, uid);
75 }
76 Trace() << "Replaying " << key << type;
77
78 KAsync::Job<QByteArray> job = KAsync::null<QByteArray>();
79 if (type == ENTITY_TYPE_FOLDER) {
80 auto folder = store().read<ApplicationDomain::Folder>(uid);
81 job = replay(folder, operation, oldRemoteId);
82 } else if (type == ENTITY_TYPE_MAIL) {
83 auto mail = store().read<ApplicationDomain::Mail>(uid);
84 job = replay(mail, operation, oldRemoteId);
85 }
86
87 return job.then<void, QByteArray>([this, operation, type, uid](const QByteArray &remoteId) {
88 Trace() << "Replayed change with remote id: " << remoteId;
89 if (operation == Sink::Operation_Creation) {
90 if (remoteId.isEmpty()) {
91 Warning() << "Returned an empty remoteId from the creation";
92 } else {
93 syncStore().recordRemoteId(type, uid, remoteId);
94 }
95 } else if (operation == Sink::Operation_Modification) {
96 if (remoteId.isEmpty()) {
97 Warning() << "Returned an empty remoteId from the creation";
98 } else {
99 syncStore().updateRemoteId(type, uid, remoteId);
100 }
101 } else if (operation == Sink::Operation_Removal) {
102 syncStore().removeRemoteId(type, uid, remoteId);
103 } else {
104 Warning() << "Unkown operation" << operation;
105 }
106
107 mTransaction.abort();
108 mSyncTransaction.commit();
109 mSyncStore.clear();
110 mEntityStore.clear();
111 }, [](int errorCode, const QString &errorMessage) {
112 Warning() << "Failed to replay change: " << errorMessage;
113 });
114}
115
116KAsync::Job<QByteArray> SourceWriteBack::replay(const ApplicationDomain::Mail &, Sink::Operation, const QByteArray &)
117{
118 return KAsync::null<QByteArray>();
119}
120
121KAsync::Job<QByteArray> SourceWriteBack::replay(const ApplicationDomain::Folder &, Sink::Operation, const QByteArray &)
122{
123 return KAsync::null<QByteArray>();
124}