Hi, Could you please review the attached patch that implements local calendar creation in KCal-EDS?
The apps need to call EStorage::localStorage(KCalCore::IncidenceBase::IncidenceType type, const QString &id, bool create) instead of defaultStorage(KCalCore::IncidenceBase::IncidenceType type) to get a local calendar storage. If the "create" parameter is set to false and the local storage identified by "id" does not exist, the method will fail and return a NULL pointer. The ECal uri is generated from the id provided by the caller as follows: "local:<id>". I have written new unit tests to check the functionality and it seems to work for me. TIA, -- Dr. Christophe Dumez Linux Software Engineer Intel Finland Oy - Open Source Technology Center
From 008928417df9c42cf709eaea2e9bbdcba2945416 Mon Sep 17 00:00:00 2001 From: Christophe Dumez <[email protected]> Date: Thu, 9 Jun 2011 15:00:05 +0300 Subject: [PATCH] eKCal::EStorage Implement local calendar creation Add localStorage() method to eKCal::EStorage that returns a local calendar storage. The storage is only created if the "create" boolean parameter is set to true. Unit tests have been written to check the functionality. --- src/eds-storage.cpp | 72 +++++++++++++++++++++++++++++ src/eds-storage.h | 15 ++++++- src/ekcal/ekcal-storage.h | 10 ++++ test/Makefile.am | 11 +++- test/ut_testlocalstorage.cpp | 104 ++++++++++++++++++++++++++++++++++++++++++ test/ut_testlocalstorage.h | 39 ++++++++++++++++ 6 files changed, 247 insertions(+), 4 deletions(-) create mode 100644 test/ut_testlocalstorage.cpp create mode 100644 test/ut_testlocalstorage.h diff --git a/src/eds-storage.cpp b/src/eds-storage.cpp index 37bfe8a..8fa4d67 100644 --- a/src/eds-storage.cpp +++ b/src/eds-storage.cpp @@ -24,6 +24,8 @@ #include <set> +const QString EDS_LOCAL_STORAGE_PREFIX = "local:"; + namespace eKCal { EStorage::Ptr EStorage::defaultStorage(KCalCore::IncidenceBase::IncidenceType type) @@ -36,6 +38,17 @@ namespace eKCal { return res; } + EStorage::Ptr EStorage::localStorage(KCalCore::IncidenceBase::IncidenceType type, + const QString &id, bool create) + { + eKCalImpl::EDSStorage::Ptr res(new eKCalImpl::EDSStorage); + if (!res->open(type, id, create)) { + EKCAL_DEBUG() << "opening local storage failed"; + res.clear(); + } + return res; + } + } // namespace eKCal namespace eKCalImpl { @@ -138,6 +151,65 @@ namespace eKCalImpl { return true; } + bool EDSStorage::open(KCalCore::IncidenceBase::IncidenceType type, + const QString &id, bool create) + { + m_type = type; + g_type_init(); + + m_calendar = KCalCore::MemoryCalendar::Ptr(new KCalCore::MemoryCalendar(KSystemTimeZones::local())); + if (!m_calendar) { + return false; + } + + switch (type) { + case KCalCore::IncidenceBase::TypeEvent: + m_database = ECalCXX::steal(e_cal_new_from_uri((EDS_LOCAL_STORAGE_PREFIX+id).toUtf8().constData(), + E_CAL_SOURCE_TYPE_EVENT)); + m_calendarDeleteAll = &KCalCore::MemoryCalendar::deleteAllEvents; + break; + case KCalCore::IncidenceBase::TypeTodo: + m_database = ECalCXX::steal(e_cal_new_from_uri((EDS_LOCAL_STORAGE_PREFIX+id).toUtf8().constData(), + E_CAL_SOURCE_TYPE_TODO)); + m_calendarDeleteAll = &KCalCore::MemoryCalendar::deleteAllTodos; + break; + case KCalCore::IncidenceBase::TypeJournal: + m_database = ECalCXX::steal(e_cal_new_from_uri((EDS_LOCAL_STORAGE_PREFIX+id).toUtf8().constData(), + E_CAL_SOURCE_TYPE_JOURNAL)); + m_calendarDeleteAll = &KCalCore::MemoryCalendar::deleteAllJournals; + break; + default: + // should be NULL, but just in case... + m_database.reset(); + } + + if (!m_database) { + EKCAL_CRITICAL() << "no system storage for type" << type; + return false; + } + + // TODO (?): define a non-blocking way of creating EStorage, + // use e_cal_open_async() here. Probably not that relevant + // for local calendars. + GErrorCXX gerror; + EKCAL_DEBUG() << "Calling e_cal_open() on database" << EDS_LOCAL_STORAGE_PREFIX+id + << "with create boolean at" << create; + if (!e_cal_open(m_database.get(), + !create, + gerror)) { + EKCAL_CRITICAL() << "e_cal_open failed" << gerror; + return false; + } + + if (!e_cal_get_static_capability(m_database.get(), + CAL_STATIC_CAPABILITY_REMOVE_ONLY_THIS)) { + EKCAL_CRITICAL() << "local storage does not support CAL_STATIC_CAPABILITY_REMOVE_ONLY_THIS, needed for KCal-EDS"; + return false; + } + + return true; + } + void EDSStorage::registerObserver(StorageObserver *observer) { m_observers.push_back(observer); diff --git a/src/eds-storage.h b/src/eds-storage.h index 32b2315..984b175 100644 --- a/src/eds-storage.h +++ b/src/eds-storage.h @@ -56,7 +56,8 @@ namespace eKCalImpl { EDSStorage(); /** - * Sets up EDSStorage instance for use. + * Sets up EDSStorage instance for use corresponding to the default system + * storage for this \a type of items. * * Must succeed before instance is ready for use via the * EStorage API. If it fails, the EDSStorage is unusable and @@ -64,6 +65,18 @@ namespace eKCalImpl { */ bool open(KCalCore::IncidenceBase::IncidenceType type); + /** + * Sets up EDSStorage instance for use corresponding to a local storage identified + * by \a id and for this \a type of items. \a create indicate if the local storage + * should be created when missing. + * + * Must succeed before instance is ready for use via the + * EStorage API. If it fails, the EDSStorage is unusable and + * should be destroyed. + */ + bool open(KCalCore::IncidenceBase::IncidenceType type, const QString &id, + bool create); + virtual KCalCore::Calendar::Ptr calendar() { return m_calendar; } virtual void registerObserver(StorageObserver *observer); diff --git a/src/ekcal/ekcal-storage.h b/src/ekcal/ekcal-storage.h index 7525108..3cbb834 100644 --- a/src/ekcal/ekcal-storage.h +++ b/src/ekcal/ekcal-storage.h @@ -145,6 +145,16 @@ namespace eKCal { static Ptr defaultStorage(KCalCore::IncidenceBase::IncidenceType type); /** + * creates a new implementation of EStorage accessing the storage identified + * by \a id and for the given \a type of items. The storage must already exist + * or \a create should be set to true. + * + * @return NULL in case of error + */ + static Ptr localStorage(KCalCore::IncidenceBase::IncidenceType type, + const QString &id, bool create); + + /** * Every storage is associated with a calendar. * * The default time zone of that calendar is the one defined diff --git a/test/Makefile.am b/test/Makefile.am index 6afab74..df69085 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -1,8 +1,8 @@ # use Qt include $(top_srcdir)/m4-repo/autotroll.mk -check_PROGRAMS = showall ut_testchanges -TESTS = ut_testchanges +check_PROGRAMS = showall ut_testchanges ut_testlocalstorage +TESTS = ut_testchanges ut_testlocalstorage # Allow Qt to set some compile flags, but not the ones normally set via configure. AM_CXXFLAGS = $(filter-out -O2 -g -W -Wall, $(QT_CXXFLAGS)) @@ -18,4 +18,9 @@ ut_testchanges_CXXFLAGS = $(AM_CXXFLAGS) $(ECAL_CFLAGS) ut_testchanges_LDADD = $(QT_LIBS) $(ECAL_LIBS) ../src/libekcal.la ut_testchanges_DEP = ../src/libekcal.la -BUILT_SOURCES = calendar-observer.moc.cpp signal-app.moc.cpp ut_testchanges.moc.cpp +ut_testlocalstorage_SOURCES = ut_testlocalstorage.cpp ut_testlocalstorage.moc.cpp +ut_testlocalstorage_CXXFLAGS = $(AM_CXXFLAGS) $(ECAL_CFLAGS) +ut_testlocalstorage_LDADD = $(QT_LIBS) $(ECAL_LIBS) ../src/libekcal.la +ut_testlocalstorage_DEP = ../src/libekcal.la + +BUILT_SOURCES = calendar-observer.moc.cpp signal-app.moc.cpp ut_testchanges.moc.cpp ut_testlocalstorage.moc.cpp diff --git a/test/ut_testlocalstorage.cpp b/test/ut_testlocalstorage.cpp new file mode 100644 index 0000000..841905c --- /dev/null +++ b/test/ut_testlocalstorage.cpp @@ -0,0 +1,104 @@ +/* + * Copyright (C) 2011 Intel Corporation + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) version 3. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA + */ + +#include <QString> +#include <QTest> +#include <QTime> +#include <QDebug> +#include "ut_testlocalstorage.h" + +const QString TEST_STORAGE_ID = "test_storage"; + +bool TestLocalStorage::addSimpleEvent(const KDateTime &t, const QString &summary) +{ + KCalCore::Event::Ptr event; + KDateTime utcstart(t); + KDateTime utcend = utcstart; + utcend.addSecs(60 * 60); + // add a minimal event + qDebug() << "=== single UTC event ==="; + event = KCalCore::Event::Ptr(new KCalCore::Event); + event->setSummary(summary); + event->setDtStart(utcstart); + event->setDtEnd(utcend); + return m_calendar->addEvent(event); +} + +void TestLocalStorage::initTestCase() +{ + m_storage = eKCal::EStorage::localStorage(KCalCore::IncidenceBase::TypeEvent, + TEST_STORAGE_ID, true); + QVERIFY(m_storage); + m_calendar = m_storage->calendar(); + QVERIFY(m_calendar); +} + +void TestLocalStorage::basicLocalStorageTest() +{ + // Add a simple event + KDateTime t(QDate(2011, 01, 01), QTime(14, 30, 0), KDateTime::Spec::UTC()); + const QString summary = "Test UTC event"; + bool ok = addSimpleEvent(t, summary); + QVERIFY(ok); + QVERIFY(m_calendar->save()); + + // Get the event back + KCalCore::Event::List events = m_calendar->events(t); + Q_ASSERT(!events.isEmpty()); + Q_ASSERT(events.first().summary() == summary); +} + +void TestLocalStorage::persistenceTest() +{ + // Add a simple event + KDateTime t(QDate(2011, 01, 01), QTime(14, 30, 0), KDateTime::Spec::UTC()); + const QString summary = "Test UTC event 2"; + bool ok = addSimpleEvent(t, summary); + QVERIFY(ok); + QVERIFY(m_calendar->save()); + + // Close the storage + m_storage.clear(); + m_calendar.clear(); + // Reopen + m_storage = eKCal::EStorage::localStorage(KCalCore::IncidenceBase::TypeEvent, + TEST_STORAGE_ID, false); + QVERIFY(m_storage); + m_calendar = m_storage->calendar(); + QVERIFY(m_calendar); + + // Get the event back + KCalCore::Event::List events = m_calendar->events(t); + Q_ASSERT(!events.isEmpty()); + Q_ASSERT(events.first().summary() == "Test UTC event"); +} + +void TestLocalStorage::cleanup() +{ + qDebug() << "=== calendar cleaning ==="; + if (m_calendar) { + m_calendar->deleteAllEvents(); + KCalCore::Event::List events = m_calendar->events(); + QVERIFY(events.isEmpty()); + m_calendar->deleteAllJournals(); + m_calendar->deleteAllTodos(); + } +} + +QTEST_MAIN(TestLocalStorage); diff --git a/test/ut_testlocalstorage.h b/test/ut_testlocalstorage.h new file mode 100644 index 0000000..6f9b893 --- /dev/null +++ b/test/ut_testlocalstorage.h @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2011 Intel Corporation + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) version 3. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA + */ + +#include <QObject> +#include <libecal/e-cal.h> +#include <ekcal/ekcal-storage.h> + +class TestLocalStorage : public QObject { + Q_OBJECT + + private slots: + void initTestCase(); + void basicLocalStorageTest(); + void persistenceTest(); + void cleanup(); + +private: + bool addSimpleEvent(const KDateTime &time, const QString &summary); + +private: + eKCal::EStorage::Ptr m_storage; + KCalCore::Calendar::Ptr m_calendar; +}; -- 1.7.4.4
_______________________________________________ MeeGo-dev mailing list [email protected] http://lists.meego.com/listinfo/meego-dev http://wiki.meego.com/Mailing_list_guidelines
