summaryrefslogtreecommitdiffstats
path: root/examples
diff options
context:
space:
mode:
authorChristian Mollekopf <chrigi_1@fastmail.fm>2016-11-11 13:06:27 +0100
committerChristian Mollekopf <chrigi_1@fastmail.fm>2016-11-11 15:26:32 +0100
commit4e6b3ce7d1ce97c3e1fb9ae53c5b2be1787acc6b (patch)
tree08d80bbe1cc890f949110a760cba18e8f2b5249b /examples
parente5bec3abfe2f2463244d65386dbd1088bf56f5f3 (diff)
downloadsink-4e6b3ce7d1ce97c3e1fb9ae53c5b2be1787acc6b.tar.gz
sink-4e6b3ce7d1ce97c3e1fb9ae53c5b2be1787acc6b.zip
Prepared new query based synchronization API
Diffstat (limited to 'examples')
-rw-r--r--examples/imapresource/imapresource.cpp121
-rw-r--r--examples/imapresource/imapserverproxy.h16
-rw-r--r--examples/maildirresource/maildirresource.cpp54
3 files changed, 149 insertions, 42 deletions
diff --git a/examples/imapresource/imapresource.cpp b/examples/imapresource/imapresource.cpp
index d5a59b9..302d681 100644
--- a/examples/imapresource/imapresource.cpp
+++ b/examples/imapresource/imapresource.cpp
@@ -272,41 +272,102 @@ public:
272 272
273 } 273 }
274 274
275 KAsync::Job<void> synchronizeWithSource(const Sink::QueryBase &query) Q_DECL_OVERRIDE 275 QList<Synchronizer::SyncRequest> getSyncRequests(const Sink::QueryBase &query) Q_DECL_OVERRIDE
276 { 276 {
277 SinkLog() << " Synchronizing"; 277 QList<Synchronizer::SyncRequest> list;
278 return KAsync::start<void>([this]() { 278 if (query.type() == ApplicationDomain::getTypeName<ApplicationDomain::Mail>()) {
279 SinkTrace() << "Connecting to:" << mServer << mPort; 279 list << Synchronizer::SyncRequest{query};
280 SinkTrace() << "as:" << mUser; 280 } else if (query.type() == ApplicationDomain::getTypeName<ApplicationDomain::Folder>()) {
281 auto imap = QSharedPointer<ImapServerProxy>::create(mServer, mPort); 281 list << Synchronizer::SyncRequest{query};
282 } else {
283 list << Synchronizer::SyncRequest{Sink::QueryBase(ApplicationDomain::getTypeName<ApplicationDomain::Folder>())};
284 list << Synchronizer::SyncRequest{Sink::QueryBase(ApplicationDomain::getTypeName<ApplicationDomain::Mail>())};
285 }
286 return list;
287 }
282 288
283 return imap->login(mUser, mPassword) 289 KAsync::Job<void> login(QSharedPointer<ImapServerProxy> imap)
284 .addToContext(imap) 290 {
285 .onError([](const KAsync::Error &error) { 291 SinkTrace() << "Connecting to:" << mServer << mPort;
286 SinkWarning() << "Login failed."; 292 SinkTrace() << "as:" << mUser;
287 }) 293 return imap->login(mUser, mPassword)
288 .then<QVector<Folder>>([this, imap]() { 294 .addToContext(imap)
289 auto folderList = QSharedPointer<QVector<Folder>>::create(); 295 .onError([](const KAsync::Error &error) {
290 SinkLog() << "Login was successful"; 296 SinkWarning() << "Login failed.";
291 return imap->fetchFolders([folderList](const Folder &folder) { 297 });
292 *folderList << folder; 298 }
293 }) 299
294 .onError([](const KAsync::Error &error) { 300 KAsync::Job<void> synchronizeWithSource(const Sink::QueryBase &query) Q_DECL_OVERRIDE
295 SinkWarning() << "Folder list sync failed."; 301 {
302 if (query.type() == ApplicationDomain::getTypeName<ApplicationDomain::Folder>()) {
303 return KAsync::start<void>([this]() {
304 auto imap = QSharedPointer<ImapServerProxy>::create(mServer, mPort);
305 auto job = login(imap);
306 job = job.then<QVector<Folder>>([this, imap]() {
307 auto folderList = QSharedPointer<QVector<Folder>>::create();
308 return imap->fetchFolders([folderList](const Folder &folder) {
309 *folderList << folder;
310 })
311 .onError([](const KAsync::Error &error) {
312 SinkWarning() << "Folder list sync failed.";
313 })
314 .syncThen<QVector<Folder>>([this, folderList]() {
315 synchronizeFolders(*folderList);
316 commit();
317 return *folderList;
318 });
319 });
320 return job;
321 });
322 } else if (query.type() == ApplicationDomain::getTypeName<ApplicationDomain::Mail>()) {
323 //TODO
324 //if we have a folder filter:
325 //* execute the folder query and resolve the results to the remote identifier
326 //* query only those folders
327 //if we have a date filter:
328 //* apply the date filter to the fetch
329 //if we have no folder filter:
330 //* fetch list of folders from server directly and sync (because we have no guarantee that the folder sync was already processed by the pipeline).
331 return KAsync::start<void>([this, query]() {
332 auto imap = QSharedPointer<ImapServerProxy>::create(mServer, mPort);
333 auto job = login(imap);
334 job = job.then<QVector<Folder>>([this, imap, query]() {
335 SinkLog() << "Login was successful";
336 //FIXME If we were able to to flush in between we could just query the local store for the folder list.
337 //
338 if (query.hasFilter<ApplicationDomain::Mail::Folder>()) {
339 QVector<Folder> folders;
340 auto folderFilter = query.getFilter<ApplicationDomain::Mail::Folder>();
341 auto localIds = resolveFilter(folderFilter);
342 auto folderRemoteIds = syncStore().resolveLocalIds(ApplicationDomain::getTypeName<ApplicationDomain::Folder>(), localIds);
343 for (const auto &r : folderRemoteIds) {
344 folders << Folder{r};
345 }
346 return KAsync::value(folders);
347 } else {
348 auto folderList = QSharedPointer<QVector<Folder>>::create();
349 return imap->fetchFolders([folderList](const Folder &folder) {
350 *folderList << folder;
351 })
352 .onError([](const KAsync::Error &error) {
353 SinkWarning() << "Folder list sync failed.";
354 })
355 .syncThen<QVector<Folder>>([this, folderList]() {
356 return *folderList;
357 });
358 }
296 }) 359 })
297 .syncThen<QVector<Folder>>([this, folderList]() { 360 .serialEach<void>([this, imap](const Folder &folder) {
298 synchronizeFolders(*folderList); 361 if (folder.noselect) {
299 commit(); 362 return KAsync::null<void>();
300 return *folderList; 363 }
364 return synchronizeFolder(imap, folder);
301 }); 365 });
302 }) 366
303 .serialEach<void>([this, imap](const Folder &folder) { 367 return job;
304 if (folder.noselect) {
305 return KAsync::null<void>();
306 }
307 return synchronizeFolder(imap, folder);
308 }); 368 });
309 }); 369 }
370 return KAsync::error<void>("Nothing to do");
310 } 371 }
311 372
312public: 373public:
diff --git a/examples/imapresource/imapserverproxy.h b/examples/imapresource/imapserverproxy.h
index 8b39f23..6e6626e 100644
--- a/examples/imapresource/imapserverproxy.h
+++ b/examples/imapresource/imapserverproxy.h
@@ -58,6 +58,20 @@ struct Message {
58}; 58};
59 59
60struct Folder { 60struct Folder {
61 Folder() = default;
62 Folder(QList<QString> pathParts_, const QString &path_, const QChar &separator_, bool noselect_)
63 : pathParts(pathParts_),
64 path(path_),
65 separator(separator_),
66 noselect(noselect_)
67 {
68 }
69
70 Folder(const QString &path_)
71 : path(path_)
72 {
73 }
74
61 QString normalizedPath() const 75 QString normalizedPath() const
62 { 76 {
63 return pathParts.join('/'); 77 return pathParts.join('/');
@@ -73,7 +87,7 @@ struct Folder {
73 QList<QString> pathParts; 87 QList<QString> pathParts;
74 QString path; 88 QString path;
75 QChar separator; 89 QChar separator;
76 bool noselect; 90 bool noselect = false;
77}; 91};
78 92
79struct SelectResult { 93struct SelectResult {
diff --git a/examples/maildirresource/maildirresource.cpp b/examples/maildirresource/maildirresource.cpp
index 820ec2f..fc77315 100644
--- a/examples/maildirresource/maildirresource.cpp
+++ b/examples/maildirresource/maildirresource.cpp
@@ -330,25 +330,57 @@ public:
330 SinkLog() << "Synchronized " << count << " mails in " << listingPath << Sink::Log::TraceTime(elapsed) << " " << elapsed/qMax(count, 1) << " [ms/mail]"; 330 SinkLog() << "Synchronized " << count << " mails in " << listingPath << Sink::Log::TraceTime(elapsed) << " " << elapsed/qMax(count, 1) << " [ms/mail]";
331 } 331 }
332 332
333 QList<Synchronizer::SyncRequest> getSyncRequests(const Sink::QueryBase &query) Q_DECL_OVERRIDE
334 {
335 QList<Synchronizer::SyncRequest> list;
336 if (!query.type().isEmpty()) {
337 //We want to synchronize something specific
338 list << Synchronizer::SyncRequest{query};
339 } else {
340 //We want to synchronize everything
341 list << Synchronizer::SyncRequest{Sink::QueryBase(ApplicationDomain::getTypeName<ApplicationDomain::Folder>())};
342 //FIXME we can't process the second synchronization before the pipeline of the first one is processed, otherwise we can't execute a query on the local data.
343 /* list << Synchronizer::SyncRequest{Flush}; */
344 list << Synchronizer::SyncRequest{Sink::QueryBase(ApplicationDomain::getTypeName<ApplicationDomain::Mail>())};
345 }
346 return list;
347 }
348
333 KAsync::Job<void> synchronizeWithSource(const Sink::QueryBase &query) Q_DECL_OVERRIDE 349 KAsync::Job<void> synchronizeWithSource(const Sink::QueryBase &query) Q_DECL_OVERRIDE
334 { 350 {
335 SinkLog() << " Synchronizing"; 351 auto job = KAsync::start<void>([this] {
336 return KAsync::start<void>([this]() {
337 KPIM::Maildir maildir(mMaildirPath, true); 352 KPIM::Maildir maildir(mMaildirPath, true);
338 if (!maildir.isValid(false)) { 353 if (!maildir.isValid(false)) {
339 return KAsync::error<void>(1, "Maildir path doesn't point to a valid maildir: " + mMaildirPath); 354 return KAsync::error<void>(1, "Maildir path doesn't point to a valid maildir: " + mMaildirPath);
340 } 355 }
341 synchronizeFolders();
342 //The next sync needs the folders available
343 commit();
344 for (const auto &folder : listAvailableFolders()) {
345 synchronizeMails(folder);
346 //Don't let the transaction grow too much
347 commit();
348 }
349 SinkLog() << "Done Synchronizing";
350 return KAsync::null<void>(); 356 return KAsync::null<void>();
351 }); 357 });
358
359 if (query.type() == ApplicationDomain::getTypeName<ApplicationDomain::Folder>()) {
360 job = job.syncThen<void>([this] {
361 synchronizeFolders();
362 });
363 } else if (query.type() == ApplicationDomain::getTypeName<ApplicationDomain::Mail>()) {
364 job = job.syncThen<void>([this, query] {
365 QStringList folders;
366 if (query.hasFilter<ApplicationDomain::Mail::Folder>()) {
367 auto folderFilter = query.getFilter<ApplicationDomain::Mail::Folder>();
368 auto localIds = resolveFilter(folderFilter);
369 auto folderRemoteIds = syncStore().resolveLocalIds(ApplicationDomain::getTypeName<ApplicationDomain::Folder>(), localIds);
370 for (const auto &r : folderRemoteIds) {
371 folders << r;
372 }
373 } else {
374 folders = listAvailableFolders();
375 }
376 for (const auto &folder : folders) {
377 synchronizeMails(folder);
378 //Don't let the transaction grow too much
379 commit();
380 }
381 });
382 }
383 return job;
352 } 384 }
353 385
354public: 386public: