Initial commit for calendar cache rewrite.
authorChenthill Palanisamy <pchenthill@novell.com>
Mon, 13 Jul 2009 20:32:31 +0000 (02:02 +0530)
committerChenthill Palanisamy <pchenthill@novell.com>
Mon, 13 Jul 2009 20:45:24 +0000 (02:15 +0530)
Will be migrating the backends to new cache after some testing.

calendar/libedata-cal/Makefile.am
calendar/libedata-cal/e-cal-backend-file-store.c [new file with mode: 0644]
calendar/libedata-cal/e-cal-backend-file-store.h [new file with mode: 0644]
calendar/libedata-cal/e-cal-backend-store.c [new file with mode: 0644]
calendar/libedata-cal/e-cal-backend-store.h [new file with mode: 0644]

index af88409..b3b66b8 100644 (file)
@@ -40,6 +40,8 @@ libedata_cal_1_2_la_SOURCES =         \
        e-cal-backend-sexp.c            \
        e-cal-backend-sync.c            \
        e-cal-backend-util.c            \
+       e-cal-backend-store.c           \
+       e-cal-backend-file-store.c      \
        e-data-cal.c                    \
        e-data-cal-factory.c            \
        e-data-cal-view.c
@@ -68,6 +70,8 @@ libedata_calinclude_HEADERS =                 \
        e-data-cal.h                    \
        e-data-cal-common.h             \
        e-data-cal-factory.h            \
+       e-cal-backend-store.h           \
+       e-cal-backend-file-store.h      \
        e-data-cal-view.h
 
 %-$(API_VERSION).pc: %.pc
diff --git a/calendar/libedata-cal/e-cal-backend-file-store.c b/calendar/libedata-cal/e-cal-backend-file-store.c
new file mode 100644 (file)
index 0000000..9238adf
--- /dev/null
@@ -0,0 +1,753 @@
+/*-*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/* e-cal-backend-file-store.c
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ * Authors: Chenthill Palanisamy <pchenthill@novell.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of version 2 of the GNU Lesser General Public
+ * License as published by the Free Software Foundation.
+ *
+ * This program 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 program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include <string.h>
+#include "e-cal-backend-file-store.h"
+#include "libebackend/e-file-cache.h"
+#include <glib/gstdio.h>
+
+#define CACHE_FILE_NAME "calendar.ics"
+#define KEY_FILE_NAME "keys.xml"
+#define IDLE_SAVE_TIMEOUT 6000
+
+G_DEFINE_TYPE (ECalBackendFileStore, e_cal_backend_file_store, E_TYPE_CAL_BACKEND_STORE)
+
+#define GET_PRIVATE(o) \
+  (G_TYPE_INSTANCE_GET_PRIVATE ((o), E_TYPE_CAL_BACKEND_FILE_STORE, ECalBackendFileStorePrivate))
+
+typedef struct _ECalBackendFileStorePrivate ECalBackendFileStorePrivate;
+
+typedef struct {
+       ECalComponent *comp;
+       GHashTable *recurrences;
+} FullCompObject;
+
+struct _ECalBackendFileStorePrivate {
+       GHashTable *timezones;
+       GHashTable *comp_uid_hash;
+       EFileCache *keys_cache;
+       
+       GStaticRWLock lock;
+
+       gchar *cache_file_name;
+       gchar *key_file_name;
+
+       gboolean dirty;
+       gboolean freeze_changes;
+
+       guint save_timeout_id;
+};
+
+static void save_cache (ECalBackendFileStore *store);
+
+
+static FullCompObject *
+create_new_full_object (void)
+{
+       FullCompObject *obj;
+       
+       obj = g_new0 (FullCompObject, 1);
+       obj->recurrences = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_object_unref);
+
+       return obj;
+}
+
+static void
+destroy_full_object (FullCompObject *obj)
+{
+       if (!obj)
+               return;
+
+       if (obj->comp)
+               g_object_unref (obj->comp);
+       g_hash_table_destroy (obj->recurrences);
+
+       g_free (obj);
+       obj = NULL;
+}
+
+static gboolean
+put_component (ECalBackendFileStore *fstore, ECalComponent *comp)
+{
+       ECalBackendFileStorePrivate *priv;
+       FullCompObject *obj = NULL;
+       const gchar *uid;
+
+       g_return_val_if_fail (comp != NULL, FALSE);
+
+       priv = GET_PRIVATE (fstore);
+       e_cal_component_get_uid (comp, &uid);
+
+       if (uid == NULL) {
+               g_warning ("The component does not have a valid uid \n");
+               return FALSE;
+       }
+
+       g_static_rw_lock_writer_lock (&priv->lock);
+       
+       obj = g_hash_table_lookup (priv->comp_uid_hash, uid);
+
+       if (obj == NULL) {
+               obj = create_new_full_object ();
+       }
+
+       if (!e_cal_component_is_instance (comp)) {
+               if (obj->comp != NULL)
+                       g_object_unref (obj->comp);
+
+               obj->comp = comp;
+               g_hash_table_insert (priv->comp_uid_hash, g_strdup (uid), obj);
+       } else {
+               gchar *rid = e_cal_component_get_recurid_as_string (comp);
+
+               g_hash_table_insert (obj->recurrences, g_strdup (rid), comp);
+       }
+
+       g_static_rw_lock_writer_unlock (&priv->lock);
+
+       return TRUE;
+}
+
+static gboolean
+remove_component (ECalBackendFileStore *fstore, const gchar *uid, const gchar *rid)
+{
+       ECalBackendFileStorePrivate *priv;
+       FullCompObject *obj = NULL;
+       gboolean ret_val = TRUE;
+       gboolean remove_completely = FALSE;
+       
+       priv = GET_PRIVATE (fstore);
+
+       g_static_rw_lock_writer_lock (&priv->lock);
+
+       obj = g_hash_table_lookup (priv->comp_uid_hash, uid);
+       if (obj == NULL) {
+               ret_val = FALSE;
+               goto end;
+       }
+
+       if (rid != NULL) {
+               ret_val = g_hash_table_remove (obj->recurrences, rid);
+
+               if (ret_val && g_hash_table_size (obj->recurrences) == 0 && !obj->comp)
+                       remove_completely = TRUE;
+       } else
+               remove_completely = TRUE;
+
+       if (remove_completely)
+               destroy_full_object (obj);
+
+end:
+       g_static_rw_lock_writer_unlock (&priv->lock);
+       return ret_val;
+}
+
+static ECalComponent *
+get_component (ECalBackendFileStore *fstore, const gchar *uid, const gchar *rid)
+{
+       ECalBackendFileStorePrivate *priv;
+       FullCompObject *obj = NULL;
+       ECalComponent *comp = NULL;
+       
+       priv = GET_PRIVATE(fstore);
+
+       g_static_rw_lock_reader_lock (&priv->lock);
+
+       obj = g_hash_table_lookup (priv->comp_uid_hash, uid);
+       if (obj == NULL) 
+               goto end;
+
+       if (rid != NULL)
+               comp = g_hash_table_lookup (obj->recurrences, rid);
+       else
+               comp = obj->comp;
+
+       if (comp != NULL)
+               g_object_ref (comp);
+
+end:   
+       g_static_rw_lock_reader_unlock (&priv->lock);
+       return comp;
+}
+
+static ECalComponent *
+e_cal_backend_file_store_get_component (ECalBackendStore *store, const gchar *uid, const gchar *rid)
+{
+       ECalBackendFileStore *fstore = E_CAL_BACKEND_FILE_STORE (store);
+       ECalBackendFileStorePrivate *priv;
+
+       priv = GET_PRIVATE (fstore);
+
+       return get_component (fstore, uid, rid);
+}
+
+static gboolean
+e_cal_backend_file_store_put_component (ECalBackendStore *store, ECalComponent *comp)
+{
+       ECalBackendFileStore *fstore = E_CAL_BACKEND_FILE_STORE (store);
+       ECalBackendFileStorePrivate *priv;
+       gboolean ret_val = FALSE;
+
+       priv = GET_PRIVATE (fstore);
+
+       ret_val = put_component (fstore, comp);
+       
+       if (ret_val) {
+               priv->dirty = TRUE;
+
+               if (!priv->freeze_changes)
+                       save_cache (fstore);
+       }
+
+       return ret_val;
+}
+
+static gboolean
+e_cal_backend_file_store_remove_component (ECalBackendStore *store, const gchar *uid, const gchar *rid)
+{
+       ECalBackendFileStore *fstore = E_CAL_BACKEND_FILE_STORE (store);
+       ECalBackendFileStorePrivate *priv;
+       gboolean ret_val = FALSE;
+       
+       priv = GET_PRIVATE (fstore);
+       
+       ret_val = remove_component (fstore, uid, rid);
+       
+       if (ret_val) {
+               priv->dirty = TRUE;
+               
+               if (!priv->freeze_changes)
+                       save_cache (fstore);
+       }
+       
+       return ret_val;
+}
+
+static const icaltimezone *
+e_cal_backend_file_store_get_timezone (ECalBackendStore *store, const gchar *tzid)
+{
+       ECalBackendFileStore *fstore = E_CAL_BACKEND_FILE_STORE (store);
+       ECalBackendFileStorePrivate *priv;
+       const icaltimezone *zone = NULL;
+       
+       priv = GET_PRIVATE (fstore);
+       
+       g_static_rw_lock_reader_lock (&priv->lock);
+       zone = g_hash_table_lookup (priv->timezones, tzid);
+       g_static_rw_lock_reader_unlock (&priv->lock);
+       
+       return zone;    
+}
+
+static gboolean
+e_cal_backend_file_store_put_timezone (ECalBackendStore *store, const icaltimezone *zone)
+{
+       ECalBackendFileStore *fstore = E_CAL_BACKEND_FILE_STORE (store);
+       ECalBackendFileStorePrivate *priv;
+       gboolean ret_val = FALSE;
+
+       priv = GET_PRIVATE (fstore);
+       
+       g_static_rw_lock_writer_lock (&priv->lock);
+       g_hash_table_insert (priv->timezones, g_strdup (icaltimezone_get_tzid ((icaltimezone *) zone)), (icaltimezone *) zone);
+       g_static_rw_lock_writer_unlock (&priv->lock);
+
+       if (ret_val) {
+               priv->dirty = TRUE;
+               
+               if (!priv->freeze_changes)
+                       save_cache (fstore);
+       }
+
+       return ret_val;
+}
+
+static gboolean
+e_cal_backend_file_store_remove_timezone (ECalBackendStore *store, const gchar *tzid)
+{
+       ECalBackendFileStore *fstore = E_CAL_BACKEND_FILE_STORE (store);
+       ECalBackendFileStorePrivate *priv;
+       gboolean ret_val = FALSE;
+       
+       priv = GET_PRIVATE (fstore);
+       
+       g_static_rw_lock_writer_lock (&priv->lock);
+       ret_val = g_hash_table_remove (priv->timezones, tzid);
+       g_static_rw_lock_writer_unlock (&priv->lock);
+
+       if (ret_val) {
+               priv->dirty = TRUE;
+               
+               if (!priv->freeze_changes)
+                       save_cache (fstore);
+       }
+
+       return ret_val; 
+}
+
+static const gchar *
+e_cal_backend_file_store_get_key_value (ECalBackendStore *store, const gchar *key)
+{
+       ECalBackendFileStore *fstore = E_CAL_BACKEND_FILE_STORE (store);
+       ECalBackendFileStorePrivate *priv;
+       const gchar *value;
+
+       priv = GET_PRIVATE (fstore);
+
+       g_static_rw_lock_reader_lock (&priv->lock);
+       value = e_file_cache_get_object (priv->keys_cache, key);
+       g_static_rw_lock_reader_unlock (&priv->lock);
+
+       return value;
+}
+
+static gboolean
+e_cal_backend_file_store_put_key_value (ECalBackendStore *store, const gchar *key, const gchar *value)
+{
+       ECalBackendFileStore *fstore = E_CAL_BACKEND_FILE_STORE (store);
+       ECalBackendFileStorePrivate *priv;
+       gboolean ret_val = FALSE;
+
+       priv = GET_PRIVATE (fstore);
+       
+       g_static_rw_lock_writer_lock (&priv->lock);
+       ret_val = e_file_cache_replace_object (priv->keys_cache, key, value);
+       g_static_rw_lock_writer_unlock (&priv->lock);
+
+       return ret_val; 
+}
+
+static const icaltimezone *
+e_cal_backend_file_store_get_default_timezone (ECalBackendStore *store)
+{
+       ECalBackendFileStore *fstore = E_CAL_BACKEND_FILE_STORE (store);
+       ECalBackendFileStorePrivate *priv;
+       const gchar *tzid;
+       const icaltimezone *zone = NULL;
+
+       priv = GET_PRIVATE (fstore);
+
+       g_static_rw_lock_reader_lock (&priv->lock);
+
+       tzid = e_file_cache_get_object (priv->keys_cache, "default-zone");
+       if (tzid)
+               zone = g_hash_table_lookup (priv->timezones, tzid);
+
+       g_static_rw_lock_reader_unlock (&priv->lock);
+
+       return zone;
+}
+
+static gboolean
+e_cal_backend_file_store_set_default_timezone (ECalBackendStore *store, const icaltimezone *zone)
+{
+       ECalBackendFileStore *fstore = E_CAL_BACKEND_FILE_STORE (store);
+       ECalBackendFileStorePrivate *priv;
+       const gchar *tzid;
+       
+       priv = GET_PRIVATE (fstore);
+
+       g_static_rw_lock_writer_lock (&priv->lock);
+       
+       tzid = icaltimezone_get_tzid ((icaltimezone*) zone);
+       g_hash_table_insert (priv->timezones, g_strdup (tzid), (icaltimezone *) zone);
+       e_file_cache_replace_object (priv->keys_cache, "default-zone", tzid);
+
+       g_static_rw_lock_writer_unlock (&priv->lock);
+
+       return TRUE;
+}
+
+static void
+e_cal_backend_file_store_thaw_changes (ECalBackendStore *store)
+{
+       ECalBackendFileStore *fstore = E_CAL_BACKEND_FILE_STORE (store);
+       ECalBackendFileStorePrivate *priv;
+
+       priv = GET_PRIVATE (fstore);
+
+       priv->freeze_changes = FALSE;
+       
+       e_file_cache_thaw_changes (priv->keys_cache);
+       if (priv->dirty) {
+               save_cache (fstore);
+       }
+}
+
+static void
+e_cal_backend_file_store_freeze_changes (ECalBackendStore *store)
+{
+       ECalBackendFileStore *fstore = E_CAL_BACKEND_FILE_STORE (store);
+       ECalBackendFileStorePrivate *priv;
+
+       priv = GET_PRIVATE (fstore);
+
+       priv->freeze_changes = TRUE;
+       e_file_cache_freeze_changes (priv->keys_cache);
+}
+
+static void
+add_comp_to_slist (gpointer key, gpointer value, gpointer user_data)
+{
+       GSList **slist = (GSList **) user_data;
+       ECalComponent *comp = (ECalComponent *) value;
+
+       g_object_ref (comp);
+       *slist = g_slist_prepend (*slist, comp);
+}
+
+static GSList *
+e_cal_backend_file_store_get_components_by_uid (ECalBackendStore *store, const gchar *uid)
+{
+       ECalBackendFileStore *fstore = E_CAL_BACKEND_FILE_STORE (store);
+       ECalBackendFileStorePrivate *priv;
+       FullCompObject *obj = NULL;
+       GSList *comps = NULL;
+
+       priv = GET_PRIVATE (fstore);
+       
+       g_static_rw_lock_reader_lock (&priv->lock);
+
+       obj = g_hash_table_lookup (priv->comp_uid_hash, uid);
+       if (obj == NULL) {
+               goto end;
+       }
+
+       if (obj->comp) {
+               g_object_ref (obj->comp);
+               comps = g_slist_append (comps, obj->comp);
+       }
+
+       g_hash_table_foreach (obj->recurrences, (GHFunc) add_comp_to_slist, &comps);
+end:   
+       g_static_rw_lock_reader_unlock (&priv->lock);
+       return comps;
+}
+
+static void
+add_timezone (ECalBackendFileStore *fstore, icalcomponent *vtzcomp)
+{
+       ECalBackendFileStorePrivate *priv;
+       icalproperty *prop;
+       icaltimezone *zone;
+       const char *tzid;
+
+       prop = icalcomponent_get_first_property (vtzcomp, ICAL_TZID_PROPERTY);
+       if (!prop)
+               return;
+
+       tzid = icalproperty_get_tzid (prop);
+       if (g_hash_table_lookup (priv->timezones, tzid))
+               return;
+
+       zone = icaltimezone_new ();
+       if (!icaltimezone_set_component (zone, icalcomponent_new_clone (vtzcomp))) {
+               icaltimezone_free (zone, TRUE);
+               return;
+       }
+
+       g_static_rw_lock_writer_lock (&priv->lock);
+       g_hash_table_insert (priv->timezones, g_strdup (tzid), zone);
+       g_static_rw_lock_writer_unlock (&priv->lock);
+}
+
+static void 
+scan_vcalendar (ECalBackendFileStore *fstore, icalcomponent *top_icalcomp)
+{
+       ECalBackendFileStorePrivate *priv;
+       icalcompiter iter;
+
+       priv = GET_PRIVATE(fstore);
+
+       for (iter = icalcomponent_begin_component (top_icalcomp, ICAL_ANY_COMPONENT);
+            icalcompiter_deref (&iter) != NULL;
+            icalcompiter_next (&iter)) {
+               icalcomponent *icalcomp;
+               icalcomponent_kind kind;
+               ECalComponent *comp;
+
+               icalcomp = icalcompiter_deref (&iter);
+
+               kind = icalcomponent_isa (icalcomp);
+
+               if (!(kind == ICAL_VEVENT_COMPONENT
+                     || kind == ICAL_VTODO_COMPONENT
+                     || kind == ICAL_VJOURNAL_COMPONENT
+                     || kind == ICAL_VTIMEZONE_COMPONENT))
+                       continue;
+
+               if (kind == ICAL_VTIMEZONE_COMPONENT) {
+                       add_timezone (fstore, icalcomp);
+                       continue;
+               }
+
+               comp = e_cal_component_new ();
+
+               if (!e_cal_component_set_icalcomponent (comp, icalcomp))
+                       continue;
+
+               put_component (fstore, comp);
+       }
+}
+
+static gboolean
+e_cal_backend_file_store_load (ECalBackendStore *store)
+{
+       ECalBackendFileStore *fstore = E_CAL_BACKEND_FILE_STORE (store);
+       ECalBackendFileStorePrivate *priv;
+       icalcomponent *icalcomp;
+
+       priv = GET_PRIVATE(fstore);
+
+       if (!priv->cache_file_name || !priv->key_file_name)
+               return FALSE;
+
+       /* Parse keys */
+       priv->keys_cache = e_file_cache_new (priv->key_file_name);
+
+       /* Parse components */
+       icalcomp = e_cal_util_parse_ics_file (priv->cache_file_name);
+       if (!icalcomp)
+               return FALSE;
+
+       if (icalcomponent_isa (icalcomp) != ICAL_VCALENDAR_COMPONENT) {
+               icalcomponent_free (icalcomp);
+       
+               return FALSE;
+       }
+
+       scan_vcalendar (fstore, icalcomp);
+
+       return TRUE;
+}
+
+static void
+save_instance (gpointer key, gpointer value, gpointer user_data)
+{
+       icalcomponent *vcalcomp = user_data;
+       icalcomponent *icalcomp;
+       ECalComponent *comp = value;
+
+       icalcomp = icalcomponent_new_clone (e_cal_component_get_icalcomponent (comp));
+       icalcomponent_add_component (vcalcomp, icalcomp);
+}
+
+static void
+save_object (gpointer key, gpointer value, gpointer user_data)
+{
+       FullCompObject *obj = value;
+       icalcomponent *icalcomp, *vcalcomp = user_data;
+
+       if (obj->comp) {
+               icalcomp = icalcomponent_new_clone (e_cal_component_get_icalcomponent (obj->comp));
+               icalcomponent_add_component (vcalcomp, icalcomp);
+       }
+
+       g_hash_table_foreach (obj->recurrences, save_instance, vcalcomp);
+}
+       
+static void
+save_timezone (gpointer key, gpointer tz, gpointer vcalcomp)
+{
+       icalcomponent *tzcomp;
+
+       tzcomp = icalcomponent_new_clone (icaltimezone_get_component (tz));
+       icalcomponent_add_component (vcalcomp, tzcomp);
+}
+
+static gboolean
+timeout_save_cache (gpointer user_data)
+{
+       ECalBackendFileStore *fstore = user_data;
+       ECalBackendFileStorePrivate *priv;
+       icalcomponent *vcalcomp;
+       gchar *data = NULL, *tmpfile;
+       gsize len, nwrote;
+       FILE *f;
+
+       priv = GET_PRIVATE(fstore);
+
+       g_static_rw_lock_reader_lock (&priv->lock);
+
+       priv->save_timeout_id = 0;
+       
+       vcalcomp = e_cal_util_new_top_level ();
+       g_hash_table_foreach (priv->timezones, save_timezone, vcalcomp);
+       g_hash_table_foreach (priv->comp_uid_hash, save_object, vcalcomp);
+       data = icalcomponent_as_ical_string_r (vcalcomp);
+       icalcomponent_free (vcalcomp);
+
+       tmpfile = g_strdup_printf ("%s~", priv->cache_file_name);
+       f = g_fopen (tmpfile, "wb");
+       if (!f)
+               goto error;
+
+       len = strlen (data);
+       nwrote = fwrite (data, 1, len, f);
+       if (fclose (f) != 0 || nwrote != len)
+               goto error;
+
+       if (g_rename (tmpfile, priv->cache_file_name) != 0)
+               g_unlink (tmpfile);
+
+       e_file_cache_thaw_changes (priv->keys_cache);
+
+error:
+       g_static_rw_lock_reader_unlock (&priv->lock);
+       g_free (tmpfile);
+       g_free (data);
+       return FALSE;
+}
+
+static void
+save_cache (ECalBackendFileStore *store)
+{
+       ECalBackendFileStorePrivate *priv;
+
+       priv = GET_PRIVATE(store);
+
+       if (priv->save_timeout_id) {
+               g_source_remove (priv->save_timeout_id);
+       }
+
+       priv->save_timeout_id = g_timeout_add (IDLE_SAVE_TIMEOUT, timeout_save_cache, store);
+}
+
+static void
+e_cal_backend_file_store_construct (ECalBackendFileStore *fstore)
+{
+       ECalBackendFileStorePrivate *priv;
+       ECalBackendStore *store = E_CAL_BACKEND_STORE (fstore);
+       const gchar *path;
+
+       priv = GET_PRIVATE(store);
+
+       path = e_cal_backend_store_get_path (store);
+       priv->cache_file_name = g_build_filename (path, CACHE_FILE_NAME, NULL);
+       priv->key_file_name = g_build_filename (path, KEY_FILE_NAME, NULL);
+}
+
+static void
+e_cal_backend_file_store_dispose (GObject *object)
+{
+       G_OBJECT_CLASS (e_cal_backend_file_store_parent_class)->dispose (object);
+}
+
+static void
+e_cal_backend_file_store_finalize (GObject *object)
+{
+       ECalBackendFileStore *fstore = (ECalBackendFileStore *) object;
+       ECalBackendFileStorePrivate *priv;
+
+       priv = GET_PRIVATE(fstore);
+
+       if (priv->save_timeout_id) {
+               g_source_remove (priv->save_timeout_id);
+               timeout_save_cache (fstore);
+               priv->save_timeout_id = 0;
+       }
+
+       if (priv->timezones) {
+               g_hash_table_destroy (priv->timezones);
+               priv->timezones = NULL;
+       }
+
+       if (priv->comp_uid_hash) {
+               g_hash_table_destroy (priv->comp_uid_hash);
+               priv->comp_uid_hash = NULL;
+       }
+
+       if (priv->keys_cache) {
+               g_object_unref (priv->keys_cache);
+               priv->keys_cache = NULL;
+       }
+
+       if (priv->cache_file_name) {
+               g_free (priv->cache_file_name);
+               priv->cache_file_name = NULL;
+       }
+
+       if (priv->key_file_name) {
+               g_free (priv->key_file_name);
+               priv->key_file_name = NULL;
+       }
+
+       priv->dirty = FALSE;
+       priv->freeze_changes = FALSE;
+
+       G_OBJECT_CLASS (e_cal_backend_file_store_parent_class)->finalize (object);
+}
+
+static void
+e_cal_backend_file_store_class_init (ECalBackendFileStoreClass *klass)
+{
+       GObjectClass *object_class = G_OBJECT_CLASS (klass);
+       ECalBackendStoreClass *store_class = E_CAL_BACKEND_STORE_CLASS (klass);
+
+       g_type_class_add_private (klass, sizeof (ECalBackendFileStorePrivate));
+
+       object_class->dispose = e_cal_backend_file_store_dispose;
+       object_class->finalize = e_cal_backend_file_store_finalize;
+
+       store_class->load = e_cal_backend_file_store_load;
+       store_class->get_component = e_cal_backend_file_store_get_component;
+       store_class->put_component = e_cal_backend_file_store_put_component;
+       store_class->remove_component = e_cal_backend_file_store_remove_component;
+       store_class->get_timezone = e_cal_backend_file_store_get_timezone;
+       store_class->put_timezone = e_cal_backend_file_store_put_timezone;
+       store_class->remove_timezone = e_cal_backend_file_store_remove_timezone;
+       store_class->get_default_timezone = e_cal_backend_file_store_get_default_timezone;
+       store_class->set_default_timezone = e_cal_backend_file_store_set_default_timezone;
+       store_class->get_components_by_uid = e_cal_backend_file_store_get_components_by_uid;
+       store_class->get_key = e_cal_backend_file_store_get_key_value;
+       store_class->put_key = e_cal_backend_file_store_put_key_value;
+       store_class->thaw_changes = e_cal_backend_file_store_thaw_changes;
+       store_class->freeze_changes = e_cal_backend_file_store_freeze_changes;
+}
+
+static void
+e_cal_backend_file_store_init (ECalBackendFileStore *self)
+{
+       ECalBackendFileStorePrivate *priv;
+
+       priv = GET_PRIVATE(self);
+
+       priv->timezones = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
+       priv->comp_uid_hash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, (GDestroyNotify) destroy_full_object);
+       priv->keys_cache = NULL;
+       g_static_rw_lock_init (&priv->lock);
+       priv->cache_file_name = NULL;
+       priv->key_file_name = NULL;
+       priv->dirty = FALSE;
+       priv->freeze_changes = FALSE;
+       priv->save_timeout_id = 0;
+}
+
+ECalBackendFileStore*
+e_cal_backend_file_store_new (const gchar *uri, ECalSourceType source_type)
+{
+       ECalBackendFileStore *fstore;
+
+       fstore =  g_object_new (E_TYPE_CAL_BACKEND_FILE_STORE, "source_type", source_type, "uri", uri);
+       e_cal_backend_file_store_construct (fstore);
+
+       return fstore;
+}
diff --git a/calendar/libedata-cal/e-cal-backend-file-store.h b/calendar/libedata-cal/e-cal-backend-file-store.h
new file mode 100644 (file)
index 0000000..9548c99
--- /dev/null
@@ -0,0 +1,61 @@
+/*-*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/* e-cal-backend-file-store.h
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ * Authors: Chenthill Palanisamy <pchenthill@novell.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of version 2 of the GNU Lesser General Public
+ * License as published by the Free Software Foundation.
+ *
+ * This program 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 program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifndef _E_CAL_BACKEND_FILE_STORE
+#define _E_CAL_BACKEND_FILE_STORE
+
+#include <glib-object.h>
+#include "e-cal-backend-store.h"
+
+G_BEGIN_DECLS
+
+#define E_TYPE_CAL_BACKEND_FILE_STORE e_cal_backend_file_store_get_type()
+
+#define E_CAL_BACKEND_FILE_STORE(obj) \
+  (G_TYPE_CHECK_INSTANCE_CAST ((obj), E_TYPE_CAL_BACKEND_FILE_STORE, ECalBackendFileStore))
+
+#define E_CAL_BACKEND_FILE_STORE_CLASS(klass) \
+  (G_TYPE_CHECK_CLASS_CAST ((klass), E_TYPE_CAL_BACKEND_FILE_STORE, ECalBackendFileStoreClass))
+
+#define E_IS_CAL_BACKEND_FILE_STORE(obj) \
+  (G_TYPE_CHECK_INSTANCE_TYPE ((obj), E_TYPE_CAL_BACKEND_FILE_STORE))
+
+#define E_IS_CAL_BACKEND_FILE_STORE_CLASS(klass) \
+  (G_TYPE_CHECK_CLASS_TYPE ((klass), E_TYPE_CAL_BACKEND_FILE_STORE))
+
+#define E_CAL_BACKEND_FILE_STORE_GET_CLASS(obj) \
+  (G_TYPE_INSTANCE_GET_CLASS ((obj), E_TYPE_CAL_BACKEND_FILE_STORE, ECalBackendFileStoreClass))
+
+typedef struct {
+  ECalBackendStore parent;
+} ECalBackendFileStore;
+
+typedef struct {
+  ECalBackendStoreClass parent_class;
+} ECalBackendFileStoreClass;
+
+GType e_cal_backend_file_store_get_type (void);
+
+ECalBackendFileStore* e_cal_backend_file_store_new (const gchar *uri, ECalSourceType source_type);
+
+G_END_DECLS
+
+#endif /* _E_CAL_BACKEND_FILE_STORE */
diff --git a/calendar/libedata-cal/e-cal-backend-store.c b/calendar/libedata-cal/e-cal-backend-store.c
new file mode 100644 (file)
index 0000000..0d6d86f
--- /dev/null
@@ -0,0 +1,350 @@
+/*-*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/* e-cal-backend-store.c
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ * Authors: Chenthill Palanisamy <pchenthill@novell.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of version 2 of the GNU Lesser General Public
+ * License as published by the Free Software Foundation.
+ *
+ * This program 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 program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include "e-cal-backend-store.h"
+
+G_DEFINE_TYPE (ECalBackendStore, e_cal_backend_store, G_TYPE_OBJECT)
+
+#define GET_PRIVATE(o) \
+  (G_TYPE_INSTANCE_GET_PRIVATE ((o), E_TYPE_CAL_BACKEND_STORE, ECalBackendStorePrivate))
+
+typedef struct _ECalBackendStorePrivate ECalBackendStorePrivate;
+
+struct _ECalBackendStorePrivate {
+       ECalSourceType source_type;
+       gchar *uri;
+       gchar *path;
+};
+
+/* Property IDs */
+enum {
+       PROP_0,
+       PROP_SOURCE_TYPE,
+       PROP_URI
+};
+
+static const gchar *
+get_component (ECalSourceType source_type)
+{
+       switch (source_type) {
+               case E_CAL_SOURCE_TYPE_EVENT :
+                       return "calendar";
+               case E_CAL_SOURCE_TYPE_TODO :
+                       return "tasks";
+               case E_CAL_SOURCE_TYPE_JOURNAL :
+                       return "journal";
+               case E_CAL_SOURCE_TYPE_LAST :
+               default :
+                       return "invalid";
+       }
+
+}
+
+static void
+set_store_path (ECalBackendStore *store)
+{
+       ECalBackendStorePrivate *priv;
+
+       priv = GET_PRIVATE(store);
+
+       if (priv->uri)
+       {
+               const gchar *component = get_component (priv->source_type);
+               char *mangled_uri = NULL;
+
+               mangled_uri = g_strdup (priv->uri);
+               mangled_uri = g_strdelimit (mangled_uri, ":/",'_');
+
+               if (priv->path)
+                       g_free (priv->path);
+
+               priv->path = g_build_filename (g_get_home_dir (), ".evolution/cache/",
+                               component, mangled_uri, NULL);  
+       }
+}
+
+static void
+set_uri (ECalBackendStore *store, gchar *uri)
+{
+       ECalBackendStorePrivate *priv;
+
+       priv = GET_PRIVATE(store);
+
+       if (priv->uri)
+               g_free (priv->uri);
+
+       priv->uri = uri;
+}
+
+static void
+e_cal_backend_store_set_property (GObject *object, guint property_id, const GValue *value, GParamSpec *spec)
+{
+       ECalBackendStore *store;
+       ECalBackendStorePrivate *priv;
+
+       store = E_CAL_BACKEND_STORE (object);
+       priv = GET_PRIVATE(store);
+
+       switch (property_id) {
+       case PROP_SOURCE_TYPE:
+               priv->source_type = g_value_get_enum (value);
+       case PROP_URI:
+               set_uri (store, g_value_dup_string (value));
+               set_store_path (store);
+       default:
+               G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, spec);
+       }
+}
+
+static void
+e_cal_backend_store_get_property (GObject *object, guint property_id, GValue *value, GParamSpec *spec)
+{
+       ECalBackendStore *store;
+       ECalBackendStorePrivate *priv;
+
+       store = E_CAL_BACKEND_STORE (object);
+       priv = GET_PRIVATE(store);
+
+       switch (property_id) 
+       {
+       case PROP_SOURCE_TYPE:
+               g_value_set_enum (value, priv->source_type);
+       case PROP_URI :
+               g_value_set_string (value, priv->uri);
+               break;
+       default :
+               G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, spec);
+       }
+}
+
+static void
+e_cal_backend_store_dispose (GObject *object)
+{
+       G_OBJECT_CLASS (e_cal_backend_store_parent_class)->dispose (object);
+}
+
+static void
+e_cal_backend_store_finalize (GObject *object)
+{
+       ECalBackendStore *store = (ECalBackendStore *) object;
+       ECalBackendStorePrivate *priv;
+
+       priv = GET_PRIVATE(store);
+
+       if (priv->uri) {
+               g_free (priv->uri);
+               priv->uri = NULL;
+       }
+
+       if (priv->path) {
+               g_free (priv->path);
+               priv->uri = NULL;
+       }
+
+       G_OBJECT_CLASS (e_cal_backend_store_parent_class)->finalize (object);
+}
+
+static void
+e_cal_backend_store_class_init (ECalBackendStoreClass *klass)
+{
+       GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+       g_type_class_add_private (klass, sizeof (ECalBackendStorePrivate));
+
+       object_class->dispose = e_cal_backend_store_dispose;
+       object_class->finalize = e_cal_backend_store_finalize;
+       object_class->set_property = e_cal_backend_store_set_property;
+       object_class->get_property = e_cal_backend_store_get_property;
+
+       klass->load = NULL;
+       klass->get_component = NULL;
+       klass->put_component = NULL;
+       klass->remove_component = NULL;
+       klass->get_timezone = NULL;
+       klass->put_timezone = NULL;
+       klass->remove_timezone = NULL;
+       klass->get_default_timezone = NULL;
+       klass->set_default_timezone = NULL;
+       klass->get_components_by_uid = NULL;
+       klass->get_key = NULL;
+       klass->put_key = NULL;
+
+       g_object_class_install_property (object_class, PROP_SOURCE_TYPE, 
+                               g_param_spec_enum ("source_type", NULL, NULL,
+                               e_cal_source_type_enum_get_type (),
+                               E_CAL_SOURCE_TYPE_EVENT,
+                               G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY));
+       g_object_class_install_property (object_class, PROP_URI,
+                                       g_param_spec_string ("uri", NULL, NULL, "",
+                                       G_PARAM_READABLE | G_PARAM_WRITABLE
+                                       | G_PARAM_CONSTRUCT_ONLY));
+}
+
+static void
+e_cal_backend_store_init (ECalBackendStore *store)
+{
+       ECalBackendStorePrivate *priv;
+
+       priv = GET_PRIVATE(store);
+
+       priv->uri = NULL;
+       priv->path = NULL;
+       priv->source_type = E_CAL_SOURCE_TYPE_EVENT;
+}
+
+gboolean
+e_cal_backend_store_load (ECalBackendStore *store)
+{
+       g_return_val_if_fail (store != NULL, FALSE);
+       g_return_val_if_fail (E_IS_CAL_BACKEND_STORE (store), FALSE);
+       
+       return (E_CAL_BACKEND_STORE_GET_CLASS (store))->load (store);
+}
+
+ECalComponent *
+e_cal_backend_store_get_component (ECalBackendStore *store, const gchar *uid, const gchar *rid)
+{
+       g_return_val_if_fail (store != NULL, NULL);
+       g_return_val_if_fail (E_IS_CAL_BACKEND_STORE (store), NULL);
+       g_return_val_if_fail (uid != NULL, NULL);
+       g_return_val_if_fail (rid != NULL, NULL);
+
+       return (E_CAL_BACKEND_STORE_GET_CLASS (store))->get_component (store, uid, rid);
+}
+
+gboolean
+e_cal_backend_store_put_component (ECalBackendStore *store, ECalComponent *comp)
+{
+       g_return_val_if_fail (store != NULL, FALSE);
+       g_return_val_if_fail (E_IS_CAL_BACKEND_STORE (store), FALSE);
+       g_return_val_if_fail (comp != NULL, FALSE);
+       g_return_val_if_fail (E_IS_CAL_COMPONENT (comp) != FALSE, FALSE);
+       
+       return (E_CAL_BACKEND_STORE_GET_CLASS (store))->put_component (store, comp);
+}
+
+gboolean
+e_cal_backend_store_remove_component (ECalBackendStore *store, const gchar *uid, const gchar *rid)
+{
+       g_return_val_if_fail (store != NULL, FALSE);
+       g_return_val_if_fail (E_IS_CAL_BACKEND_STORE (store), FALSE);
+       g_return_val_if_fail (uid != NULL, FALSE);
+       g_return_val_if_fail (rid != NULL, FALSE);
+       
+       return (E_CAL_BACKEND_STORE_GET_CLASS (store))->remove_component (store, uid, rid);
+}
+
+const icaltimezone *
+e_cal_backend_store_get_timezone (ECalBackendStore *store, const gchar *tzid)
+{
+       g_return_val_if_fail (store != NULL, NULL);
+       g_return_val_if_fail (E_IS_CAL_BACKEND_STORE (store), NULL);
+       g_return_val_if_fail (tzid != NULL, NULL);
+       
+       return (E_CAL_BACKEND_STORE_GET_CLASS (store))->get_timezone (store, tzid);
+}
+
+gboolean
+e_cal_backend_store_put_timezone (ECalBackendStore *store, const icaltimezone *zone)
+{
+       g_return_val_if_fail (store != NULL, FALSE);
+       g_return_val_if_fail (E_IS_CAL_BACKEND_STORE (store), FALSE);
+       g_return_val_if_fail (zone != NULL, FALSE);
+       
+       return (E_CAL_BACKEND_STORE_GET_CLASS (store))->put_timezone (store, zone);
+}
+
+gboolean
+e_cal_backend_store_remove_timezone (ECalBackendStore *store, const gchar *tzid)
+{
+       g_return_val_if_fail (store != NULL, FALSE);
+       g_return_val_if_fail (E_IS_CAL_BACKEND_STORE (store), FALSE);
+       g_return_val_if_fail (tzid != NULL, FALSE);
+       
+       return (E_CAL_BACKEND_STORE_GET_CLASS (store))->remove_timezone (store, tzid);
+}
+
+const icaltimezone *
+e_cal_backend_store_get_default_timezone (ECalBackendStore *store)
+{
+       g_return_val_if_fail (store != NULL, NULL);
+       g_return_val_if_fail (E_IS_CAL_BACKEND_STORE (store), NULL);
+       
+       return (E_CAL_BACKEND_STORE_GET_CLASS (store))->get_default_timezone (store);
+}
+
+gboolean
+e_cal_backend_store_set_default_timezone (ECalBackendStore *store, const icaltimezone *zone)
+{
+       g_return_val_if_fail (store != NULL, FALSE);
+       g_return_val_if_fail (E_IS_CAL_BACKEND_STORE (store), FALSE);
+       g_return_val_if_fail (zone != NULL, FALSE);
+       
+       return (E_CAL_BACKEND_STORE_GET_CLASS (store))->set_default_timezone (store, zone);
+}
+
+GSList *
+e_cal_backend_store_get_components_by_uid (ECalBackendStore *store, const gchar *uid)
+{
+       g_return_val_if_fail (store != NULL, NULL);
+       g_return_val_if_fail (E_IS_CAL_BACKEND_STORE (store), NULL);
+       g_return_val_if_fail (uid != NULL, NULL);
+       
+       return (E_CAL_BACKEND_STORE_GET_CLASS (store))->get_components_by_uid (store, uid);
+}
+
+const gchar *
+e_cal_backend_store_get_key (ECalBackendStore *store, const gchar *key)
+{
+       g_return_val_if_fail (store != NULL, NULL);
+       g_return_val_if_fail (E_IS_CAL_BACKEND_STORE (store), NULL);
+       g_return_val_if_fail (key != NULL, NULL);
+       
+       return (E_CAL_BACKEND_STORE_GET_CLASS (store))->get_key (store, key);
+}
+
+gboolean
+e_cal_backend_store_put_key (ECalBackendStore *store, const gchar *key, const gchar *value)
+{
+       g_return_val_if_fail (store != NULL, FALSE);
+       g_return_val_if_fail (E_IS_CAL_BACKEND_STORE (store), FALSE);
+       g_return_val_if_fail (key != NULL, FALSE);
+       
+       return (E_CAL_BACKEND_STORE_GET_CLASS (store))->put_key (store, key, value);
+}
+
+void
+e_cal_backend_store_thaw_changes (ECalBackendStore *store)
+{
+       g_return_if_fail (store != NULL);
+       g_return_if_fail (E_IS_CAL_BACKEND_STORE (store));
+       
+       (E_CAL_BACKEND_STORE_GET_CLASS (store))->thaw_changes (store);
+}
+
+void
+e_cal_backend_store_freeze_changes (ECalBackendStore *store)
+{
+       g_return_if_fail (store != NULL);
+       g_return_if_fail (E_IS_CAL_BACKEND_STORE (store));
+       
+       (E_CAL_BACKEND_STORE_GET_CLASS (store))->freeze_changes (store);
+}
diff --git a/calendar/libedata-cal/e-cal-backend-store.h b/calendar/libedata-cal/e-cal-backend-store.h
new file mode 100644 (file)
index 0000000..cea1bf1
--- /dev/null
@@ -0,0 +1,101 @@
+/*-*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/* e-cal-backend-store.h
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ * Authors: Chenthill Palanisamy <pchenthill@novell.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of version 2 of the GNU Lesser General Public
+ * License as published by the Free Software Foundation.
+ *
+ * This program 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 program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifndef _E_CAL_BACKEND_STORE
+#define _E_CAL_BACKEND_STORE
+
+#include <glib-object.h>
+#include <libecal/e-cal-component.h>
+#include <libecal/e-cal.h>
+
+G_BEGIN_DECLS
+
+#define E_TYPE_CAL_BACKEND_STORE e_cal_backend_store_get_type()
+
+#define E_CAL_BACKEND_STORE(obj) \
+  (G_TYPE_CHECK_INSTANCE_CAST ((obj), E_TYPE_CAL_BACKEND_STORE, ECalBackendStore))
+
+#define E_CAL_BACKEND_STORE_CLASS(klass) \
+  (G_TYPE_CHECK_CLASS_CAST ((klass), E_TYPE_CAL_BACKEND_STORE, ECalBackendStoreClass))
+
+#define E_IS_CAL_BACKEND_STORE(obj) \
+  (G_TYPE_CHECK_INSTANCE_TYPE ((obj), E_TYPE_CAL_BACKEND_STORE))
+
+#define E_IS_CAL_BACKEND_STORE_CLASS(klass) \
+  (G_TYPE_CHECK_CLASS_TYPE ((klass), E_TYPE_CAL_BACKEND_STORE))
+
+#define E_CAL_BACKEND_STORE_GET_CLASS(obj) \
+  (G_TYPE_INSTANCE_GET_CLASS ((obj), E_TYPE_CAL_BACKEND_STORE, ECalBackendStoreClass))
+
+typedef struct {
+  GObject parent;
+} ECalBackendStore;
+
+typedef struct {
+  GObjectClass parent_class;
+
+  /* virtual methods */
+  gboolean (* load) (ECalBackendStore *store);
+  
+  ECalComponent *(* get_component) (ECalBackendStore *store, const gchar *uid, const gchar *rid);
+  gboolean (* put_component) (ECalBackendStore *store, ECalComponent *comp);
+  gboolean (* remove_component) (ECalBackendStore *store, const gchar *uid, const gchar *rid);
+  GSList *(* get_components_by_uid) (ECalBackendStore *store, const gchar *uid);
+  
+  const icaltimezone *(* get_timezone) (ECalBackendStore *store, const gchar *tzid);
+  gboolean (* put_timezone) (ECalBackendStore *store, const icaltimezone *zone);
+  gboolean (* remove_timezone) (ECalBackendStore *store, const gchar *tzid);
+
+  const icaltimezone *(* get_default_timezone) (ECalBackendStore *store);
+  gboolean (* set_default_timezone) (ECalBackendStore *store, const icaltimezone *zone);
+
+  void (* thaw_changes) (ECalBackendStore *store);
+  void (* freeze_changes) (ECalBackendStore *store);
+
+  const gchar *(* get_key) (ECalBackendStore *store, const gchar *key);
+  gboolean (* put_key) (ECalBackendStore *store, const gchar *key, const gchar *value);
+
+} ECalBackendStoreClass;
+
+GType e_cal_backend_store_get_type (void);
+
+const char *e_cal_backend_store_get_path (ECalBackendStore *store);
+
+gboolean e_cal_backend_store_load (ECalBackendStore *store);
+ECalComponent *e_cal_backend_store_get_component (ECalBackendStore *store, const gchar *uid, const gchar *rid);
+gboolean e_cal_backend_store_put_component (ECalBackendStore *store, ECalComponent *comp);
+gboolean e_cal_backend_store_remove_component (ECalBackendStore *store, const gchar *uid, const gchar *rid);
+const icaltimezone *e_cal_backend_store_get_timezone (ECalBackendStore *store, const gchar *tzid);
+gboolean e_cal_backend_store_put_timezone (ECalBackendStore *store, const icaltimezone *zone);
+gboolean e_cal_backend_store_remove_timezone (ECalBackendStore *store, const gchar *tzid);
+const icaltimezone *e_cal_backend_store_get_default_timezone (ECalBackendStore *store);
+gboolean e_cal_backend_store_set_default_timezone (ECalBackendStore *store, const icaltimezone *zone);
+GSList *e_cal_backend_store_get_components_by_uid (ECalBackendStore *store, const gchar *uid);
+GSList *e_cal_backend_store_get_objects_list (ECalBackendStore *store, const gchar *sexp);
+const gchar *e_cal_backend_store_get_key (ECalBackendStore *store, const gchar *key);
+gboolean e_cal_backend_store_put_key (ECalBackendStore *store, const gchar *key, const gchar *value);
+void   e_cal_backend_store_thaw_changes (ECalBackendStore *store);
+void   e_cal_backend_store_freeze_changes (ECalBackendStore *store);
+
+
+G_END_DECLS
+
+#endif /* _E_CAL_BACKEND_STORE */