diff options
author | Christian Mollekopf <chrigi_1@fastmail.fm> | 2015-12-01 15:48:54 +0100 |
---|---|---|
committer | Christian Mollekopf <chrigi_1@fastmail.fm> | 2015-12-01 15:48:54 +0100 |
commit | ae7cc26c8350b427870f83687f83184c2c211250 (patch) | |
tree | d0b6e2d0e387858f97a673ade79ba4659fca1321 /examples/dummyresource/resourcefactory.cpp | |
parent | d5606030b5eb6f7ec92bc9b9d4218692af43a628 (diff) | |
download | sink-ae7cc26c8350b427870f83687f83184c2c211250.tar.gz sink-ae7cc26c8350b427870f83687f83184c2c211250.zip |
Synchronizer: One transaction per sync, and check if entity already
exists.
With this we no longer repeatedly create entities on every sync.
Diffstat (limited to 'examples/dummyresource/resourcefactory.cpp')
-rw-r--r-- | examples/dummyresource/resourcefactory.cpp | 59 |
1 files changed, 30 insertions, 29 deletions
diff --git a/examples/dummyresource/resourcefactory.cpp b/examples/dummyresource/resourcefactory.cpp index 73b2eb5..9a577a0 100644 --- a/examples/dummyresource/resourcefactory.cpp +++ b/examples/dummyresource/resourcefactory.cpp | |||
@@ -141,7 +141,7 @@ DummyResource::DummyResource(const QByteArray &instanceIdentifier, const QShared | |||
141 | } | 141 | } |
142 | } | 142 | } |
143 | 143 | ||
144 | void DummyResource::createEvent(const QByteArray &ridBuffer, const QMap<QString, QVariant> &data, flatbuffers::FlatBufferBuilder &entityFbb) | 144 | void DummyResource::createEvent(const QByteArray &ridBuffer, const QMap<QString, QVariant> &data, flatbuffers::FlatBufferBuilder &entityFbb, Akonadi2::Storage::Transaction &transaction) |
145 | { | 145 | { |
146 | //Map the source format to the buffer format (which happens to be an exact copy here) | 146 | //Map the source format to the buffer format (which happens to be an exact copy here) |
147 | auto summary = m_fbb.CreateString(data.value("summary").toString().toStdString()); | 147 | auto summary = m_fbb.CreateString(data.value("summary").toString().toStdString()); |
@@ -160,7 +160,7 @@ void DummyResource::createEvent(const QByteArray &ridBuffer, const QMap<QString, | |||
160 | Akonadi2::EntityBuffer::assembleEntityBuffer(entityFbb, 0, 0, m_fbb.GetBufferPointer(), m_fbb.GetSize(), 0, 0); | 160 | Akonadi2::EntityBuffer::assembleEntityBuffer(entityFbb, 0, 0, m_fbb.GetBufferPointer(), m_fbb.GetSize(), 0, 0); |
161 | } | 161 | } |
162 | 162 | ||
163 | void DummyResource::createMail(const QByteArray &ridBuffer, const QMap<QString, QVariant> &data, flatbuffers::FlatBufferBuilder &entityFbb) | 163 | void DummyResource::createMail(const QByteArray &ridBuffer, const QMap<QString, QVariant> &data, flatbuffers::FlatBufferBuilder &entityFbb, Akonadi2::Storage::Transaction &transaction) |
164 | { | 164 | { |
165 | //Map the source format to the buffer format (which happens to be an exact copy here) | 165 | //Map the source format to the buffer format (which happens to be an exact copy here) |
166 | auto subject = m_fbb.CreateString(data.value("subject").toString().toStdString()); | 166 | auto subject = m_fbb.CreateString(data.value("subject").toString().toStdString()); |
@@ -182,11 +182,9 @@ void DummyResource::createMail(const QByteArray &ridBuffer, const QMap<QString, | |||
182 | Akonadi2::EntityBuffer::assembleEntityBuffer(entityFbb, 0, 0, 0, 0, m_fbb.GetBufferPointer(), m_fbb.GetSize()); | 182 | Akonadi2::EntityBuffer::assembleEntityBuffer(entityFbb, 0, 0, 0, 0, m_fbb.GetBufferPointer(), m_fbb.GetSize()); |
183 | } | 183 | } |
184 | 184 | ||
185 | QString DummyResource::resolveRemoteId(const QString &remoteId) | 185 | QString DummyResource::resolveRemoteId(const QString &remoteId, Akonadi2::Storage::Transaction &transaction) |
186 | { | 186 | { |
187 | //Lookup local id for remote id, or insert a new pair otherwise | 187 | //Lookup local id for remote id, or insert a new pair otherwise |
188 | Akonadi2::Storage store(Akonadi2::storageLocation(), mResourceInstanceIdentifier + ".synchronization", Akonadi2::Storage::ReadWrite); | ||
189 | auto transaction = store.createTransaction(Akonadi2::Storage::ReadWrite); | ||
190 | QByteArray akonadiId = Index("rid.mapping", transaction).lookup(remoteId.toLatin1()); | 188 | QByteArray akonadiId = Index("rid.mapping", transaction).lookup(remoteId.toLatin1()); |
191 | if (akonadiId.isEmpty()) { | 189 | if (akonadiId.isEmpty()) { |
192 | akonadiId = QUuid::createUuid().toString().toUtf8(); | 190 | akonadiId = QUuid::createUuid().toString().toUtf8(); |
@@ -195,7 +193,7 @@ QString DummyResource::resolveRemoteId(const QString &remoteId) | |||
195 | return akonadiId; | 193 | return akonadiId; |
196 | } | 194 | } |
197 | 195 | ||
198 | void DummyResource::createFolder(const QByteArray &ridBuffer, const QMap<QString, QVariant> &data, flatbuffers::FlatBufferBuilder &entityFbb) | 196 | void DummyResource::createFolder(const QByteArray &ridBuffer, const QMap<QString, QVariant> &data, flatbuffers::FlatBufferBuilder &entityFbb, Akonadi2::Storage::Transaction &transaction) |
199 | { | 197 | { |
200 | //Map the source format to the buffer format (which happens to be an exact copy here) | 198 | //Map the source format to the buffer format (which happens to be an exact copy here) |
201 | auto name = m_fbb.CreateString(data.value("name").toString().toStdString()); | 199 | auto name = m_fbb.CreateString(data.value("name").toString().toStdString()); |
@@ -203,7 +201,7 @@ void DummyResource::createFolder(const QByteArray &ridBuffer, const QMap<QString | |||
203 | bool hasParent = false; | 201 | bool hasParent = false; |
204 | if (!data.value("parent").toString().isEmpty()) { | 202 | if (!data.value("parent").toString().isEmpty()) { |
205 | hasParent = true; | 203 | hasParent = true; |
206 | auto akonadiId = resolveRemoteId(data.value("parent").toString()); | 204 | auto akonadiId = resolveRemoteId(data.value("parent").toString(), transaction); |
207 | parent = m_fbb.CreateString(akonadiId.toStdString()); | 205 | parent = m_fbb.CreateString(akonadiId.toStdString()); |
208 | } | 206 | } |
209 | 207 | ||
@@ -217,26 +215,27 @@ void DummyResource::createFolder(const QByteArray &ridBuffer, const QMap<QString | |||
217 | Akonadi2::EntityBuffer::assembleEntityBuffer(entityFbb, 0, 0, 0, 0, m_fbb.GetBufferPointer(), m_fbb.GetSize()); | 215 | Akonadi2::EntityBuffer::assembleEntityBuffer(entityFbb, 0, 0, 0, 0, m_fbb.GetBufferPointer(), m_fbb.GetSize()); |
218 | } | 216 | } |
219 | 217 | ||
220 | void DummyResource::synchronize(const QString &bufferType, const QMap<QString, QMap<QString, QVariant> > &data, Akonadi2::Storage::Transaction &transaction, std::function<void(const QByteArray &ridBuffer, const QMap<QString, QVariant> &data, flatbuffers::FlatBufferBuilder &entityFbb)> createEntity) | 218 | void DummyResource::synchronize(const QString &bufferType, const QMap<QString, QMap<QString, QVariant> > &data, Akonadi2::Storage::Transaction &transaction, std::function<void(const QByteArray &ridBuffer, const QMap<QString, QVariant> &data, flatbuffers::FlatBufferBuilder &entityFbb, Akonadi2::Storage::Transaction &)> createEntity) |
221 | { | 219 | { |
222 | Index uidIndex("index.uid", transaction); | 220 | Akonadi2::Storage store(Akonadi2::storageLocation(), mResourceInstanceIdentifier + ".synchronization", Akonadi2::Storage::ReadWrite); |
221 | auto synchronizationTransaction = store.createTransaction(Akonadi2::Storage::ReadWrite); | ||
222 | Index ridMapping("rid.mapping", synchronizationTransaction); | ||
223 | for (auto it = data.constBegin(); it != data.constEnd(); it++) { | 223 | for (auto it = data.constBegin(); it != data.constEnd(); it++) { |
224 | bool isNew = true; | 224 | const auto remoteId = it.key().toUtf8(); |
225 | uidIndex.lookup(it.key().toLatin1(), [&](const QByteArray &value) { | 225 | auto akonadiId = resolveRemoteId(remoteId, synchronizationTransaction); |
226 | isNew = false; | 226 | |
227 | }, | 227 | bool found = false; |
228 | [](const Index::Error &error) { | 228 | transaction.openDatabase(bufferType.toUtf8() + ".main").scan(akonadiId.toUtf8(), [&found](const QByteArray &, const QByteArray &) -> bool { |
229 | if (error.code != Index::IndexNotAvailable) { | 229 | found = true; |
230 | Warning() << "Error in uid index: " << error.message; | 230 | return false; |
231 | } | 231 | }, [this](const Akonadi2::Storage::Error &error) { |
232 | }); | 232 | }, true); |
233 | if (isNew) { | 233 | |
234 | if (!found) { //A new entity | ||
234 | m_fbb.Clear(); | 235 | m_fbb.Clear(); |
235 | 236 | ||
236 | flatbuffers::FlatBufferBuilder entityFbb; | 237 | flatbuffers::FlatBufferBuilder entityFbb; |
237 | createEntity(it.key().toUtf8(), it.value(), entityFbb); | 238 | createEntity(remoteId, it.value(), entityFbb, synchronizationTransaction); |
238 | |||
239 | auto akonadiId = resolveRemoteId(it.key()); | ||
240 | 239 | ||
241 | flatbuffers::FlatBufferBuilder fbb; | 240 | flatbuffers::FlatBufferBuilder fbb; |
242 | //This is the resource type and not the domain type | 241 | //This is the resource type and not the domain type |
@@ -246,8 +245,10 @@ void DummyResource::synchronize(const QString &bufferType, const QMap<QString, Q | |||
246 | auto location = Akonadi2::Commands::CreateCreateEntity(fbb, entityId, type, delta); | 245 | auto location = Akonadi2::Commands::CreateCreateEntity(fbb, entityId, type, delta); |
247 | Akonadi2::Commands::FinishCreateEntityBuffer(fbb, location); | 246 | Akonadi2::Commands::FinishCreateEntityBuffer(fbb, location); |
248 | 247 | ||
248 | Trace() << "Found a new entity: " << remoteId; | ||
249 | enqueueCommand(mSynchronizerQueue, Akonadi2::Commands::CreateEntityCommand, QByteArray::fromRawData(reinterpret_cast<char const *>(fbb.GetBufferPointer()), fbb.GetSize())); | 249 | enqueueCommand(mSynchronizerQueue, Akonadi2::Commands::CreateEntityCommand, QByteArray::fromRawData(reinterpret_cast<char const *>(fbb.GetBufferPointer()), fbb.GetSize())); |
250 | } else { //modification | 250 | } else { //modification |
251 | Trace() << "Found a modified entity: " << remoteId; | ||
251 | //TODO diff and create modification if necessary | 252 | //TODO diff and create modification if necessary |
252 | } | 253 | } |
253 | } | 254 | } |
@@ -260,14 +261,14 @@ KAsync::Job<void> DummyResource::synchronizeWithSource() | |||
260 | return KAsync::start<void>([this](KAsync::Future<void> &f) { | 261 | return KAsync::start<void>([this](KAsync::Future<void> &f) { |
261 | auto transaction = Akonadi2::Storage(Akonadi2::storageLocation(), mResourceInstanceIdentifier, Akonadi2::Storage::ReadOnly).createTransaction(Akonadi2::Storage::ReadOnly); | 262 | auto transaction = Akonadi2::Storage(Akonadi2::storageLocation(), mResourceInstanceIdentifier, Akonadi2::Storage::ReadOnly).createTransaction(Akonadi2::Storage::ReadOnly); |
262 | 263 | ||
263 | synchronize(ENTITY_TYPE_EVENT, DummyStore::instance().events(), transaction, [this](const QByteArray &ridBuffer, const QMap<QString, QVariant> &data, flatbuffers::FlatBufferBuilder &entityFbb) { | 264 | synchronize(ENTITY_TYPE_EVENT, DummyStore::instance().events(), transaction, [this](const QByteArray &ridBuffer, const QMap<QString, QVariant> &data, flatbuffers::FlatBufferBuilder &entityFbb, Akonadi2::Storage::Transaction &synchronizationTransaction) { |
264 | createEvent(ridBuffer, data, entityFbb); | 265 | createEvent(ridBuffer, data, entityFbb, synchronizationTransaction); |
265 | }); | 266 | }); |
266 | synchronize(ENTITY_TYPE_MAIL, DummyStore::instance().mails(), transaction, [this](const QByteArray &ridBuffer, const QMap<QString, QVariant> &data, flatbuffers::FlatBufferBuilder &entityFbb) { | 267 | synchronize(ENTITY_TYPE_MAIL, DummyStore::instance().mails(), transaction, [this](const QByteArray &ridBuffer, const QMap<QString, QVariant> &data, flatbuffers::FlatBufferBuilder &entityFbb, Akonadi2::Storage::Transaction &synchronizationTransaction) { |
267 | createMail(ridBuffer, data, entityFbb); | 268 | createMail(ridBuffer, data, entityFbb, synchronizationTransaction); |
268 | }); | 269 | }); |
269 | synchronize(ENTITY_TYPE_FOLDER, DummyStore::instance().folders(), transaction, [this](const QByteArray &ridBuffer, const QMap<QString, QVariant> &data, flatbuffers::FlatBufferBuilder &entityFbb) { | 270 | synchronize(ENTITY_TYPE_FOLDER, DummyStore::instance().folders(), transaction, [this](const QByteArray &ridBuffer, const QMap<QString, QVariant> &data, flatbuffers::FlatBufferBuilder &entityFbb, Akonadi2::Storage::Transaction &synchronizationTransaction) { |
270 | createFolder(ridBuffer, data, entityFbb); | 271 | createFolder(ridBuffer, data, entityFbb, synchronizationTransaction); |
271 | }); | 272 | }); |
272 | 273 | ||
273 | f.setFinished(); | 274 | f.setFinished(); |
@@ -277,7 +278,7 @@ KAsync::Job<void> DummyResource::synchronizeWithSource() | |||
277 | void DummyResource::removeFromDisk(const QByteArray &instanceIdentifier) | 278 | void DummyResource::removeFromDisk(const QByteArray &instanceIdentifier) |
278 | { | 279 | { |
279 | GenericResource::removeFromDisk(instanceIdentifier); | 280 | GenericResource::removeFromDisk(instanceIdentifier); |
280 | Akonadi2::Storage(Akonadi2::storageLocation(), instanceIdentifier + ".event.index.uid", Akonadi2::Storage::ReadWrite).removeFromDisk(); | 281 | Akonadi2::Storage(Akonadi2::storageLocation(), instanceIdentifier + ".synchronization", Akonadi2::Storage::ReadWrite).removeFromDisk(); |
281 | } | 282 | } |
282 | 283 | ||
283 | DummyResourceFactory::DummyResourceFactory(QObject *parent) | 284 | DummyResourceFactory::DummyResourceFactory(QObject *parent) |