Skip to content

Commit

Permalink
[sociald] Reduce mkcal database activity during calendar sync. Contri…
Browse files Browse the repository at this point in the history
…butes to JB#15840

Previously, changes were committed to the mkcal database unnecessarily,
causing change signals to be emitted and unnecessary work to be done.
This commit ensures that changes are committed to the database only
when the sync process is complete.

Contributes to JB#15840
  • Loading branch information
Chris Adams committed Feb 14, 2014
1 parent 2b4ea46 commit c7529d3
Show file tree
Hide file tree
Showing 4 changed files with 80 additions and 68 deletions.
81 changes: 42 additions & 39 deletions src/facebook/facebookcalendartypesyncadaptor.cpp
Expand Up @@ -24,6 +24,9 @@ static const char *FACEBOOK_COLOR = "#3B5998";
FacebookCalendarTypeSyncAdaptor::FacebookCalendarTypeSyncAdaptor(SyncService *syncService,
QObject *parent)
: FacebookDataTypeSyncAdaptor(syncService, SyncService::Calendars, parent)
, m_calendar(mKCal::ExtendedCalendar::Ptr(new mKCal::ExtendedCalendar(QLatin1String("UTC"))))
, m_storage(mKCal::ExtendedCalendar::defaultStorage(m_calendar))
, m_storageNeedsSave(false)
{
setInitialActive(m_db.isValid());
}
Expand All @@ -32,32 +35,46 @@ FacebookCalendarTypeSyncAdaptor::~FacebookCalendarTypeSyncAdaptor()
{
}

void FacebookCalendarTypeSyncAdaptor::sync(const QString &dataTypeString)
{
m_storageNeedsSave = false;
m_storage->open(); // we close it in finalCleanup()
FacebookDataTypeSyncAdaptor::sync(dataTypeString);
}

void FacebookCalendarTypeSyncAdaptor::finalCleanup()
{
// commit changes to db
if (m_storageNeedsSave) {
m_storage->save();
}
m_storage->close();
}

void FacebookCalendarTypeSyncAdaptor::purgeDataForOldAccounts(const QList<int> &oldIds)
{
// We clean all the entries in the calendar
mKCal::ExtendedCalendar::Ptr calendar =
mKCal::ExtendedCalendar::Ptr(new mKCal::ExtendedCalendar(QLatin1String("UTC")));
mKCal::ExtendedStorage::Ptr storage = mKCal::ExtendedCalendar::defaultStorage(calendar);
storage->open();
foreach (int accountId, oldIds) {
QList<FacebookEvent::ConstPtr> events = m_db.events(accountId);

// Delete events from the calendar
foreach (const FacebookEvent::ConstPtr &event, events) {
QString incidenceId = event->incidenceId();
storage->load(incidenceId);
KCalCore::Event::Ptr event = calendar->event(incidenceId);
m_storage->load(incidenceId);
KCalCore::Event::Ptr event = m_calendar->event(incidenceId);
if (!event.isNull()) {
calendar->deleteEvent(event);
m_calendar->deleteEvent(event);
m_storageNeedsSave = true;
}
}

// Delete the notebook from the storage
// (we even check if there are several of them, in case of an error)
foreach (mKCal::Notebook::Ptr notebook, storage->notebooks()) {
foreach (mKCal::Notebook::Ptr notebook, m_storage->notebooks()) {
if (notebook->pluginName() == QLatin1String(FACEBOOK)
&& notebook->account() == QString::number(accountId)) {
storage->deleteNotebook(notebook);
m_storage->deleteNotebook(notebook);
m_storageNeedsSave = true;
}
}

Expand All @@ -66,9 +83,6 @@ void FacebookCalendarTypeSyncAdaptor::purgeDataForOldAccounts(const QList<int> &
m_db.sync(accountId);
m_db.wait();
}

storage->save();
storage->close();
}

void FacebookCalendarTypeSyncAdaptor::beginSync(int accountId, const QString &accessToken)
Expand Down Expand Up @@ -145,17 +159,11 @@ void FacebookCalendarTypeSyncAdaptor::finishedHandler()
TRACE(SOCIALD_DEBUG,
QString(QLatin1String("%1 events in the database")).arg(dbEvents.count()));

// We open the calendar and storage associated to it
mKCal::ExtendedCalendar::Ptr calendar =
mKCal::ExtendedCalendar::Ptr(new mKCal::ExtendedCalendar(QLatin1String("UTC")));
mKCal::ExtendedStorage::Ptr storage = mKCal::ExtendedCalendar::defaultStorage(calendar);
storage->open();

// Search for the Facebook Notebook
// Create one if not found (TODO: check if it failed)
// TODO: set a name to the notebook
mKCal::Notebook::List facebookNotebooks;
foreach (mKCal::Notebook::Ptr notebook, storage->notebooks()) {
foreach (mKCal::Notebook::Ptr notebook, m_storage->notebooks()) {
if (notebook->pluginName() == QLatin1String(FACEBOOK)
&& notebook->account() == QString::number(accountId)) {
facebookNotebooks.append(notebook);
Expand All @@ -173,17 +181,14 @@ void FacebookCalendarTypeSyncAdaptor::finishedHandler()
QString(QLatin1String("Resetting notebooks")));

foreach (mKCal::Notebook::Ptr notebook, facebookNotebooks) {
storage->loadNotebookIncidences(notebook->uid());
calendar->reload();
m_storage->loadNotebookIncidences(notebook->uid());
KCalCore::Incidence::List incidenceList;
storage->allIncidences(&incidenceList, notebook->uid());
m_storage->allIncidences(&incidenceList, notebook->uid());
foreach (KCalCore::Incidence::Ptr incidence, incidenceList) {
calendar->deleteIncidence(calendar->incidence(incidence->uid()));
m_calendar->deleteIncidence(m_calendar->incidence(incidence->uid()));
}

calendar->save();
storage->save();
storage->deleteNotebook(notebook);
m_storage->deleteNotebook(notebook);
m_storageNeedsSave = true;
}

facebookNotebooks.clear();
Expand All @@ -200,7 +205,8 @@ void FacebookCalendarTypeSyncAdaptor::finishedHandler()
notebook->setColor(QLatin1String(FACEBOOK_COLOR));
notebook->setDescription(accountManager->account(accountId)->displayName());
notebook->setIsReadOnly(true);
storage->addNotebook(notebook);
m_storage->addNotebook(notebook);
m_storageNeedsSave = true;
} else {
notebook = facebookNotebooks.first();
bool changed = false;
Expand All @@ -216,7 +222,8 @@ void FacebookCalendarTypeSyncAdaptor::finishedHandler()
}

if (changed) {
storage->updateNotebook(notebook);
m_storage->updateNotebook(notebook);
m_storageNeedsSave = true;
}
}

Expand All @@ -235,8 +242,8 @@ void FacebookCalendarTypeSyncAdaptor::finishedHandler()
// We load incidences that are associated to Facebook into memory
foreach (const FacebookEvent::ConstPtr &dbEvent, dbEvents) {
QString incidenceId = dbEvent->incidenceId();
storage->load(incidenceId);
KCalCore::Event::Ptr event = calendar->event(incidenceId);
m_storage->load(incidenceId);
KCalCore::Event::Ptr event = m_calendar->event(incidenceId);
if (!event.isNull()) {
dbEventsMap.insert(dbEvent->fbEventId(), dbEvent);
calendarEventsMap.insert(dbEvent->fbEventId(), event);
Expand Down Expand Up @@ -310,26 +317,22 @@ void FacebookCalendarTypeSyncAdaptor::finishedHandler()
if (update) {
event->endUpdates();
} else {
calendar->addEvent(event, notebook->uid());
m_calendar->addEvent(event, notebook->uid());
}
}

// Remove all other incidences
foreach (const QString &incidence, incidencesSet) {
KCalCore::Incidence::Ptr incidencePtr = calendar->incidence(incidence);
KCalCore::Incidence::Ptr incidencePtr = m_calendar->incidence(incidence);
if (incidencePtr) {
calendar->deleteIncidence(incidencePtr);
m_calendar->deleteIncidence(incidencePtr);
}
}

// Write to calendar
calendar->save();
storage->save();
storage->close();

// Perform removal and insertions
m_db.sync(accountId);
m_db.wait();
m_storageNeedsSave = true;

} else {
// error occurred during request.
Expand Down
8 changes: 8 additions & 0 deletions src/facebook/facebookcalendartypesyncadaptor.h
Expand Up @@ -11,6 +11,9 @@
#include "facebookdatatypesyncadaptor.h"
#include "internaldatabasemanipulationinterface.h"

#include <extendedcalendar.h>
#include <extendedstorage.h>

#include <socialcache/facebookcalendardatabase.h>

class FacebookCalendarTypeSyncAdaptor
Expand All @@ -23,8 +26,10 @@ class FacebookCalendarTypeSyncAdaptor
~FacebookCalendarTypeSyncAdaptor();

protected: // implementing FacebookDataTypeSyncAdaptor interface
void sync(const QString &dataTypeString);
void purgeDataForOldAccounts(const QList<int> &oldIds);
void beginSync(int accountId, const QString &accessToken);
void finalCleanup();

private:
void requestEvents(int accountId, const QString &accessToken,
Expand All @@ -34,7 +39,10 @@ private Q_SLOTS:
void finishedHandler();

private:
mKCal::ExtendedCalendar::Ptr m_calendar;
mKCal::ExtendedStorage::Ptr m_storage;
FacebookCalendarDatabase m_db;
bool m_storageNeedsSave;
};

#endif // FACEBOOKCALENDARTYPESYNCADAPTOR_H
58 changes: 29 additions & 29 deletions src/google/googlecalendarsyncadaptor.cpp
Expand Up @@ -305,6 +305,7 @@ GoogleCalendarSyncAdaptor::GoogleCalendarSyncAdaptor(SyncService *syncService, Q
: GoogleDataTypeSyncAdaptor(syncService, SyncService::Calendars, parent)
, m_calendar(mKCal::ExtendedCalendar::Ptr(new mKCal::ExtendedCalendar(QLatin1String("UTC"))))
, m_storage(mKCal::ExtendedCalendar::defaultStorage(m_calendar))
, m_storageNeedsSave(false)
{
setInitialActive(m_idDb.isValid());
}
Expand All @@ -315,10 +316,29 @@ GoogleCalendarSyncAdaptor::~GoogleCalendarSyncAdaptor()

void GoogleCalendarSyncAdaptor::sync(const QString &dataTypeString)
{
m_storageNeedsSave = false;
m_storage->open(); // we close it in finalCleanup()
GoogleDataTypeSyncAdaptor::sync(dataTypeString);
}

void GoogleCalendarSyncAdaptor::finalCleanup()
{
// commit changes to db
if (m_storageNeedsSave) {
m_storage->save();
}
m_storage->close();

// set the success status for each of our account settings.
QList<int> succeededAccounts;
Q_FOREACH (int accountId, m_syncSucceeded.keys()) {
if (m_syncSucceeded.value(accountId)) {
succeededAccounts.append(accountId);
}
}
setLastSyncSuccessful(succeededAccounts);
}

void GoogleCalendarSyncAdaptor::purgeDataForOldAccounts(const QList<int> &oldIds)
{
// We clean all the entries in the calendar
Expand All @@ -336,14 +356,13 @@ void GoogleCalendarSyncAdaptor::purgeDataForOldAccounts(const QList<int> &oldIds
m_calendar->deleteIncidence(m_calendar->incidence(incidence->uid()));
}
m_storage->deleteNotebook(notebook);
m_storageNeedsSave = true;
}
}

// Delete ids from our local->remote id mapping
m_idDb.removeEvents(accountId);
}

m_storage->save();
}

void GoogleCalendarSyncAdaptor::beginSync(int accountId, const QString &accessToken)
Expand Down Expand Up @@ -485,6 +504,7 @@ void GoogleCalendarSyncAdaptor::updateLocalCalendarNotebooks(int accountId, cons
notebook->setName(m_serverCalendarIdToSummaryAndColor[accountId].value(currDeviceCalendarId).first);
notebook->setColor(m_serverCalendarIdToSummaryAndColor[accountId].value(currDeviceCalendarId).second);
m_storage->updateNotebook(notebook);
m_storageNeedsSave = true;
}
} else {
// the calendar has been removed from the server.
Expand All @@ -500,6 +520,7 @@ void GoogleCalendarSyncAdaptor::updateLocalCalendarNotebooks(int accountId, cons
m_calendar->deleteIncidence(m_calendar->incidence(incidence->uid()));
}
m_storage->deleteNotebook(notebook);
m_storageNeedsSave = true;
}
}
}
Expand All @@ -518,14 +539,10 @@ void GoogleCalendarSyncAdaptor::updateLocalCalendarNotebooks(int accountId, cons
notebook->setPluginName(QStringLiteral("google-") + serverCalendarId);
notebook->setAccount(QString::number(accountId));
m_storage->addNotebook(notebook);
m_storageNeedsSave = true;
}
}

// commit changes to calendar backend on device.
// addNotebook/updateNotebook/deleteNotebook are all synchronous
// but deleteIncidence may not be.
m_storage->save();

// Finally, request the events for each calendar.
// If the last sync was successful, we can do a fast sync (using change deltas).
// NOTE: this "since" value was written at the completion of the previous
Expand Down Expand Up @@ -744,8 +761,8 @@ void GoogleCalendarSyncAdaptor::updateLocalCalendarNotebookEvents(int accountId,
googleNotebook->setAccount(nbAccount);
m_storage->addNotebook(googleNotebook);

m_storage->save();
m_storage->loadNotebookIncidences(googleNotebook->uid());
m_storageNeedsSave = true;

// clean the local->remote id mappings for this notebook (if they exist)
if (!nbUid.isEmpty()) {
Expand All @@ -764,6 +781,7 @@ void GoogleCalendarSyncAdaptor::updateLocalCalendarNotebookEvents(int accountId,
m_idDb.removeEvent(accountId, eventId);
if (allMap.contains(eventId)) {
m_calendar->deleteEvent(allMap.value(eventId));
m_storageNeedsSave = true;
} // else already deleted locally, can ignore.
} else if (deletedMap.contains(eventId)) {
// event was deleted locally, can ignore.
Expand All @@ -779,12 +797,14 @@ void GoogleCalendarSyncAdaptor::updateLocalCalendarNotebookEvents(int accountId,
event->startUpdates();
jsonToKCal(eventData, event, m_icalFormat);
event->endUpdates();
m_storageNeedsSave = true;
} else {
// add a new local event
remoteAdded++;
KCalCore::Event::Ptr event = KCalCore::Event::Ptr(new KCalCore::Event);
jsonToKCal(eventData, event, m_icalFormat); // direct conversion
m_calendar->addEvent(event, googleNotebook->uid());
m_storageNeedsSave = true;
m_idDb.insertEvent(accountId, eventId, googleNotebook->uid(), event->uid());
}
}
Expand Down Expand Up @@ -833,27 +853,6 @@ void GoogleCalendarSyncAdaptor::updateLocalCalendarNotebookEvents(int accountId,
.arg(googleNotebook->name()).arg(accountId)
.arg(localAdded).arg(localModified).arg(localRemoved));
}

// Write changes to local calendar.
m_storage->save();
}

void GoogleCalendarSyncAdaptor::finalCleanup()
{
// commit changes to db
m_storage->save();
m_storage->close();
m_idDb.sync();
m_idDb.wait();

// set the success status for each of our account settings.
QList<int> succeededAccounts;
Q_FOREACH (int accountId, m_syncSucceeded.keys()) {
if (m_syncSucceeded.value(accountId)) {
succeededAccounts.append(accountId);
}
}
setLastSyncSuccessful(succeededAccounts);
}

void GoogleCalendarSyncAdaptor::upsyncChanges(int accountId, const QString &accessToken,
Expand Down Expand Up @@ -1015,6 +1014,7 @@ void GoogleCalendarSyncAdaptor::upsyncFinishedHandler()
.arg(event->dtStart().toString(RFC3339_FORMAT))
.arg(event->dtEnd().toString(RFC3339_FORMAT)));
event->endUpdates();
m_storageNeedsSave = true;
m_idDb.insertEvent(accountId, gCalEventId(event), googleNotebook->uid(), kcalEventId);
}
}
Expand Down
1 change: 1 addition & 0 deletions src/google/googlecalendarsyncadaptor.h
Expand Up @@ -67,6 +67,7 @@ private Q_SLOTS:
mKCal::ExtendedCalendar::Ptr m_calendar;
mKCal::ExtendedStorage::Ptr m_storage;
mutable KCalCore::ICalFormat m_icalFormat;
bool m_storageNeedsSave;

GoogleCalendarDatabase m_idDb; // solely for local-deletion-upsync support
};
Expand Down

0 comments on commit c7529d3

Please sign in to comment.