From ca1c3593bf873dcd03a8974c0785b1f6ffdbd140 Mon Sep 17 00:00:00 2001 From: JP Rosevear Date: Wed, 6 Dec 2000 20:28:10 +0000 Subject: Update so as not to conflict with calendar (next_changed_item): update to 2000-12-06 JP Rosevear * conduits/calendar/calendar-conduit.c (map_name): Update so as not to conflict with calendar (next_changed_item): update to use CalClientChange instead of CalObjChange (compute_status): ditto (pre_sync): ditto (for_each_modified): since we now have the cal component we can call local_record_from_comp directly * conduits/todo/todo-conduit.c: same as above * pcs/cal-backend.c: Remove much logging cruft (cal_backend_compute_changes): Calculate the changes based on the hashed database (cal_backend_get_changes): call cal_backend_compute_changes (cal_backend_compute_changes_foreach_key): hash callback for calculating deletions * pcs/cal-backend.h: update protype, remove logging cruft from object * pcs/cal.c (build_change_seq): dup the calobj rather than the uid now (Cal_get_changes): rename from Cal_get_changed_uids (cal_get_epv): reflect name change in epv * cal-util/cal-util.c (cal_obj_change_list_free): update assertion * cal-util/cal-util.h: CalObjChange now returns the entire ical component, update the change types. This should all go away shortly * idl/evolution-calendar.idl: getChangedUIds -> getChanges. CalObjChange now contains the calobj rather than the uid, update the change types * cal-client/cal-client.c (cal_client_get_changes): rename from cal_client_get_changed_uids to make idl and addressbook * cal-client/cal-client.h: Update prototype * cal-client/cal-client.c (build_change_list): Build a list of CalClientChange instead of CalObjChange * cal-client/cal-client-types.c (cal_client_change_list_free): Free a glist of CalClientChanges * cal-client/cal-client-types.h: New file. Declarations for CalClientChange. * cal-client/Makefile.am: Build new files svn path=/trunk/; revision=6822 --- calendar/ChangeLog | 52 ++++ calendar/cal-client/.cvsignore | 6 +- calendar/cal-client/Makefile.am | 2 + calendar/cal-client/cal-client-types.c | 52 ++++ calendar/cal-client/cal-client-types.h | 50 ++++ calendar/cal-client/cal-client.c | 43 +-- calendar/cal-client/cal-client.h | 2 +- calendar/cal-util/cal-util.c | 4 +- calendar/cal-util/cal-util.h | 7 +- calendar/conduits/calendar/calendar-conduit.c | 85 +++--- calendar/conduits/todo/todo-conduit.c | 83 +++-- calendar/idl/evolution-calendar.idl | 15 +- calendar/pcs/cal-backend.c | 416 +++++++------------------- calendar/pcs/cal-backend.h | 4 +- calendar/pcs/cal.c | 18 +- 15 files changed, 388 insertions(+), 451 deletions(-) create mode 100644 calendar/cal-client/cal-client-types.c create mode 100644 calendar/cal-client/cal-client-types.h diff --git a/calendar/ChangeLog b/calendar/ChangeLog index 11ce014358..5dcf585696 100644 --- a/calendar/ChangeLog +++ b/calendar/ChangeLog @@ -1,3 +1,55 @@ +2000-12-06 JP Rosevear + + * conduits/calendar/calendar-conduit.c (map_name): Update so as not to conflict + with calendar + (next_changed_item): update to use CalClientChange instead of CalObjChange + (compute_status): ditto + (pre_sync): ditto + (for_each_modified): since we now have the cal component we can call + local_record_from_comp directly + + * conduits/todo/todo-conduit.c: same as above + + * pcs/cal-backend.c: Remove much logging cruft + (cal_backend_compute_changes): Calculate the changes based on the + hashed database + (cal_backend_get_changes): call cal_backend_compute_changes + (cal_backend_compute_changes_foreach_key): hash callback for + calculating deletions + + * pcs/cal-backend.h: update protype, remove logging cruft from + object + + * pcs/cal.c (build_change_seq): dup the calobj rather than the uid + now + (Cal_get_changes): rename from Cal_get_changed_uids + (cal_get_epv): reflect name change in epv + + * cal-util/cal-util.c (cal_obj_change_list_free): update assertion + + * cal-util/cal-util.h: CalObjChange now returns the entire ical + component, update the change types. This should all go away shortly + + * idl/evolution-calendar.idl: getChangedUIds -> getChanges. + CalObjChange now contains the calobj rather than the uid, update + the change types + + * cal-client/cal-client.c (cal_client_get_changes): rename from + cal_client_get_changed_uids to make idl and addressbook + + * cal-client/cal-client.h: Update prototype + + * cal-client/cal-client.c (build_change_list): Build a list of + CalClientChange instead of CalObjChange + + * cal-client/cal-client-types.c (cal_client_change_list_free): Free + a glist of CalClientChanges + + * cal-client/cal-client-types.h: New file. Declarations for + CalClientChange. + + * cal-client/Makefile.am: Build new files + 2000-12-06 JP Rosevear * conduits/todo/Makefile.am: Fix my build stupidty READ THE MACRO diff --git a/calendar/cal-client/.cvsignore b/calendar/cal-client/.cvsignore index e74f322903..1537e6e01d 100644 --- a/calendar/cal-client/.cvsignore +++ b/calendar/cal-client/.cvsignore @@ -10,8 +10,6 @@ evolution-calendar.h evolution-calendar-common.lo evolution-calendar-skels.lo evolution-calendar-stubs.lo -cal-client.lo -cal-listener.lo -libcal-client.la +*.lo +*.la client-test -libcal-client-static.la diff --git a/calendar/cal-client/Makefile.am b/calendar/cal-client/Makefile.am index dd5f3e60d2..6663baeecd 100644 --- a/calendar/cal-client/Makefile.am +++ b/calendar/cal-client/Makefile.am @@ -34,11 +34,13 @@ libcal_clientincludedir = $(includedir)/evolution/cal-client libcal_client_la_SOURCES = \ $(CORBA_GENERATED) \ + cal-client-types.c \ cal-client.c \ cal-listener.c \ cal-listener.h libcal_clientinclude_HEADERS = \ + cal-client-types.h \ cal-client.h diff --git a/calendar/cal-client/cal-client-types.c b/calendar/cal-client/cal-client-types.c new file mode 100644 index 0000000000..98da8b8a6f --- /dev/null +++ b/calendar/cal-client/cal-client-types.c @@ -0,0 +1,52 @@ +/* Evolution calendar utilities and types + * + * Copyright (C) 2000 Helix Code, Inc. + * + * Authors: Federico Mena-Quintero + * JP Rosevear + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. + */ + +#include +#include +#include "cal-client-types.h" + + + +/** + * cal_client_change_list_free: + * @list: List of #CalClientChange structures. + * + * Frees a list of #CalClientChange structures. + **/ +void +cal_client_change_list_free (GList *list) +{ + CalClientChange *c; + GList *l; + + for (l = list; l; l = l->next) { + c = l->data; + + g_assert (c != NULL); + g_assert (c->comp != NULL); + + gtk_object_unref (GTK_OBJECT (c->comp)); + g_free (c); + } + + g_list_free (list); +} diff --git a/calendar/cal-client/cal-client-types.h b/calendar/cal-client/cal-client-types.h new file mode 100644 index 0000000000..5c017458ad --- /dev/null +++ b/calendar/cal-client/cal-client-types.h @@ -0,0 +1,50 @@ +/* Evolution calendar utilities and types + * + * Copyright (C) 2000 Helix Code, Inc. + * + * Authors: Federico Mena-Quintero + * JP Rosevear + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifndef CAL_CLIENT_TYPES_H +#define CAL_CLIENT_TYPES_H + +#include +#include + +BEGIN_GNOME_DECLS + + + +typedef enum { + CAL_CLIENT_CHANGE_ADDED = 1 << 0, + CAL_CLIENT_CHANGE_MODIFIED = 1 << 1, + CAL_CLIENT_CHANGE_DELETED = 1 << 2 +} CalClientChangeType; + +typedef struct +{ + CalComponent *comp; + CalClientChangeType type; +} CalClientChange; + +void cal_client_change_list_free (GList *list); + +END_GNOME_DECLS + +#endif + diff --git a/calendar/cal-client/cal-client.c b/calendar/cal-client/cal-client.c index 1eca55a2d3..99dd96710b 100644 --- a/calendar/cal-client/cal-client.c +++ b/calendar/cal-client/cal-client.c @@ -25,6 +25,7 @@ #include #include +#include "cal-client-types.h" #include "cal-client.h" #include "cal-listener.h" @@ -733,44 +734,44 @@ cal_client_get_uids (CalClient *client, CalObjType type) return uids; } -/* Builds a GList of CalObjChange structures from the CORBA sequence */ +/* Builds a GList of CalClientChange structures from the CORBA sequence */ static GList * build_change_list (GNOME_Evolution_Calendar_CalObjChangeSeq *seq) { - GList *list; + GList *list = NULL; + icalcomponent *icalcomp; int i; /* Create the list in reverse order */ - list = NULL; for (i = 0; i < seq->_length; i++) { GNOME_Evolution_Calendar_CalObjChange *corba_coc; - CalObjChange *coc; + CalClientChange *ccc; corba_coc = &seq->_buffer[i]; - coc = g_new (CalObjChange, 1); + ccc = g_new (CalClientChange, 1); + + icalcomp = icalparser_parse_string (corba_coc->calobj); + if (!icalcomp) + continue; - coc->uid = g_strdup (corba_coc->uid); - coc->type = corba_coc->type; + ccc->comp = cal_component_new (); + if (!cal_component_set_icalcomponent (ccc->comp, icalcomp)) { + icalcomponent_free (icalcomp); + gtk_object_unref (GTK_OBJECT (ccc->comp)); + continue; + } + ccc->type = corba_coc->type; - list = g_list_prepend (list, coc); + list = g_list_prepend (list, ccc); } list = g_list_reverse (list); + return list; } -/** - * cal_client_get_changed_uids: - * @client: A calendar client. - * @type: Bitmask with types of objects to return. - * - * Queries a calendar for a list of unique identifiers corresponding to calendar - * objects whose type matches one of the types specified in the @type flags. - * - * Return value: A list of strings that are the sought UIDs. - **/ GList * -cal_client_get_changed_uids (CalClient *client, CalObjType type, time_t since) +cal_client_get_changes (CalClient *client, CalObjType type, const char *change_id) { CalClientPrivate *priv; CORBA_Environment ev; @@ -787,9 +788,9 @@ cal_client_get_changed_uids (CalClient *client, CalObjType type, time_t since) t = corba_obj_type (type); CORBA_exception_init (&ev); - seq = GNOME_Evolution_Calendar_Cal_getChangedUIds (priv->cal, t, since, &ev); + seq = GNOME_Evolution_Calendar_Cal_getChanges (priv->cal, t, change_id, &ev); if (ev._major != CORBA_NO_EXCEPTION) { - g_message ("cal_client_get_changed_uids(): could not get the list of changes"); + g_message ("cal_client_get_changes(): could not get the list of changes"); CORBA_exception_free (&ev); return NULL; } diff --git a/calendar/cal-client/cal-client.h b/calendar/cal-client/cal-client.h index fd40c424d9..b30c0a7d32 100644 --- a/calendar/cal-client/cal-client.h +++ b/calendar/cal-client/cal-client.h @@ -93,7 +93,7 @@ CalClientGetStatus cal_client_get_object (CalClient *client, CalComponent **comp); GList *cal_client_get_uids (CalClient *client, CalObjType type); -GList *cal_client_get_changed_uids (CalClient *client, CalObjType type, time_t since); +GList *cal_client_get_changes (CalClient *client, CalObjType type, const char *change_id); GList *cal_client_get_objects_in_range (CalClient *client, CalObjType type, time_t start, time_t end); diff --git a/calendar/cal-util/cal-util.c b/calendar/cal-util/cal-util.c index bfb9c88fff..9365db7370 100644 --- a/calendar/cal-util/cal-util.c +++ b/calendar/cal-util/cal-util.c @@ -66,9 +66,9 @@ cal_obj_change_list_free (GList *list) c = l->data; g_assert (c != NULL); - g_assert (c->uid != NULL); + g_assert (c->calobj != NULL); - g_free (c->uid); + g_free (c->calobj); g_free (c); } diff --git a/calendar/cal-util/cal-util.h b/calendar/cal-util/cal-util.h index 243cc34105..c587be5568 100644 --- a/calendar/cal-util/cal-util.h +++ b/calendar/cal-util/cal-util.h @@ -42,13 +42,14 @@ typedef struct { void cal_obj_instance_list_free (GList *list); typedef enum { - CALOBJ_UPDATED = 1 << 0, - CALOBJ_REMOVED = 1 << 1 + CALOBJ_ADDED = 1 << 0, + CALOBJ_MODIFIED = 1 << 1, + CALOBJ_DELETED = 1 << 2 } CalObjChangeType; typedef struct { - char *uid; + char *calobj; CalObjChangeType type; } CalObjChange; diff --git a/calendar/conduits/calendar/calendar-conduit.c b/calendar/conduits/calendar/calendar-conduit.c index af514c9ada..2ded9bec6d 100644 --- a/calendar/conduits/calendar/calendar-conduit.c +++ b/calendar/conduits/calendar/calendar-conduit.c @@ -33,6 +33,7 @@ #include #include #include +#include #include #include #include @@ -203,7 +204,7 @@ map_name (ECalConduitContext *ctxt) { char *filename; - filename = g_strdup_printf ("%s/evolution/local/Calendar/pilot-map-%d.xml", g_get_home_dir (), ctxt->cfg->pilot_id); + filename = g_strdup_printf ("%s/evolution/local/Calendar/pilot-map-calendar-%d.xml", g_get_home_dir (), ctxt->cfg->pilot_id); return filename; } @@ -276,13 +277,16 @@ nth_weekday (int pos, icalrecurrencetype_weekday weekday) static GList * next_changed_item (ECalConduitContext *ctxt, GList *changes) { - CalObjChange *coc; + CalClientChange *ccc; GList *l; for (l = changes; l != NULL; l = l->next) { - coc = l->data; + const char *uid; + + ccc = l->data; - if (g_hash_table_lookup (ctxt->changed_hash, coc->uid)) + cal_component_get_uid (ccc->comp, &uid); + if (g_hash_table_lookup (ctxt->changed_hash, uid)) return l; } @@ -292,27 +296,28 @@ next_changed_item (ECalConduitContext *ctxt, GList *changes) static void compute_status (ECalConduitContext *ctxt, ECalLocalRecord *local, const char *uid) { - CalObjChange *coc; + CalClientChange *ccc; local->local.archived = FALSE; local->local.secret = FALSE; - coc = g_hash_table_lookup (ctxt->changed_hash, uid); + ccc = g_hash_table_lookup (ctxt->changed_hash, uid); - if (coc == NULL) { + if (ccc == NULL) { local->local.attr = GnomePilotRecordNothing; return; } - switch (coc->type) { - case CALOBJ_UPDATED: - if (e_pilot_map_lookup_pid (ctxt->map, coc->uid) > 0) - local->local.attr = GnomePilotRecordModified; - else - local->local.attr = GnomePilotRecordNew; + switch (ccc->type) { + case CAL_CLIENT_CHANGE_ADDED: + local->local.attr = GnomePilotRecordNew; break; - case CALOBJ_REMOVED: + case CAL_CLIENT_CHANGE_MODIFIED: + local->local.attr = GnomePilotRecordModified; + break; + + case CAL_CLIENT_CHANGE_DELETED: local->local.attr = GnomePilotRecordDeleted; break; } @@ -695,7 +700,7 @@ pre_sync (GnomePilotConduit *conduit, GList *l; int len; unsigned char *buf; - char *filename; + char *filename, *change_id; gint num_records, add_records = 0, mod_records = 0, del_records = 0; abs_conduit = GNOME_PILOT_CONDUIT_SYNC_ABS (conduit); @@ -712,36 +717,36 @@ pre_sync (GnomePilotConduit *conduit, return -1; } - /* Get the local database */ - ctxt->uids = cal_client_get_uids (ctxt->client, CALOBJ_TYPE_EVENT); - /* Load the uid <--> pilot id mapping */ filename = map_name (ctxt); e_pilot_map_read (filename, &ctxt->map); g_free (filename); + /* Get the local database */ + ctxt->uids = cal_client_get_uids (ctxt->client, CALOBJ_TYPE_EVENT); + /* Find the added, modified and deleted items */ + change_id = g_strdup_printf ("pilot-sync-evolution-calendar-%d", ctxt->cfg->pilot_id); + ctxt->changed = cal_client_get_changes (ctxt->client, CALOBJ_TYPE_EVENT, change_id); ctxt->changed_hash = g_hash_table_new (g_str_hash, g_str_equal); - ctxt->changed = cal_client_get_changed_uids (ctxt->client, - CALOBJ_TYPE_EVENT, - ctxt->map->since + 1); for (l = ctxt->changed; l != NULL; l = l->next) { - CalObjChange *coc = l->data; - - if (!e_pilot_map_uid_is_archived (ctxt->map, coc->uid)) { - - g_hash_table_insert (ctxt->changed_hash, coc->uid, coc); + CalClientChange *ccc = l->data; + const char *uid; + + cal_component_get_uid (ccc->comp, &uid); + if (!e_pilot_map_uid_is_archived (ctxt->map, uid)) { - switch (coc->type) { - case CALOBJ_UPDATED: - if (e_pilot_map_lookup_pid (ctxt->map, coc->uid) > 0) - mod_records++; - else - add_records++; + g_hash_table_insert (ctxt->changed_hash, g_strdup (uid), ccc); + + switch (ccc->type) { + case CAL_CLIENT_CHANGE_ADDED: + add_records++; + break; + case CAL_CLIENT_CHANGE_MODIFIED: + mod_records++; break; - - case CALOBJ_REMOVED: + case CAL_CLIENT_CHANGE_DELETED: del_records++; break; } @@ -893,14 +898,12 @@ for_each_modified (GnomePilotConduitSyncAbs *conduit, iterator = next_changed_item (ctxt, iterator); if (iterator != NULL) { - CalObjChange *coc = NULL; - - coc = iterator->data; + CalClientChange *ccc = iterator->data; LOG ("iterating over %d records", g_hash_table_size (ctxt->changed_hash)); *local = g_new0 (ECalLocalRecord, 1); - local_record_from_uid (*local, coc->uid, ctxt); + local_record_from_comp (*local, ccc->comp, ctxt); } else { LOG ("no events"); @@ -910,12 +913,10 @@ for_each_modified (GnomePilotConduitSyncAbs *conduit, count++; iterator = g_list_next (iterator); if (iterator && (iterator = next_changed_item (ctxt, iterator))) { - CalObjChange *coc = NULL; - - coc = iterator->data; + CalClientChange *ccc = iterator->data; *local = g_new0 (ECalLocalRecord, 1); - local_record_from_uid (*local, coc->uid, ctxt); + local_record_from_comp (*local, ccc->comp, ctxt); } else { LOG ("for_each_modified ending"); diff --git a/calendar/conduits/todo/todo-conduit.c b/calendar/conduits/todo/todo-conduit.c index 9eb0dfef61..15cb4286bb 100644 --- a/calendar/conduits/todo/todo-conduit.c +++ b/calendar/conduits/todo/todo-conduit.c @@ -33,6 +33,7 @@ #include #include #include +#include #include #include #include @@ -207,7 +208,7 @@ map_name (EToDoConduitContext *ctxt) { char *filename; - filename = g_strdup_printf ("%s/evolution/local/Calendar/pilot-map-%d.xml", g_get_home_dir (), ctxt->cfg->pilot_id); + filename = g_strdup_printf ("%s/evolution/local/Calendar/pilot-map-todo-%d.xml", g_get_home_dir (), ctxt->cfg->pilot_id); return filename; } @@ -215,13 +216,16 @@ map_name (EToDoConduitContext *ctxt) static GList * next_changed_item (EToDoConduitContext *ctxt, GList *changes) { - CalObjChange *coc; + CalClientChange *ccc; GList *l; for (l = changes; l != NULL; l = l->next) { - coc = l->data; + const char *uid; + + ccc = l->data; - if (g_hash_table_lookup (ctxt->changed_hash, coc->uid)) + cal_component_get_uid (ccc->comp, &uid); + if (g_hash_table_lookup (ctxt->changed_hash, uid)) return l; } @@ -231,27 +235,26 @@ next_changed_item (EToDoConduitContext *ctxt, GList *changes) static void compute_status (EToDoConduitContext *ctxt, EToDoLocalRecord *local, const char *uid) { - CalObjChange *coc; + CalClientChange *ccc; local->local.archived = FALSE; local->local.secret = FALSE; - coc = g_hash_table_lookup (ctxt->changed_hash, uid); + ccc = g_hash_table_lookup (ctxt->changed_hash, uid); - if (coc == NULL) { + if (ccc == NULL) { local->local.attr = GnomePilotRecordNothing; return; } - switch (coc->type) { - case CALOBJ_UPDATED: - if (e_pilot_map_lookup_pid (ctxt->map, coc->uid) > 0) - local->local.attr = GnomePilotRecordModified; - else - local->local.attr = GnomePilotRecordNew; + switch (ccc->type) { + case CAL_CLIENT_CHANGE_ADDED: + local->local.attr = GnomePilotRecordNew; + break; + case CAL_CLIENT_CHANGE_MODIFIED: + local->local.attr = GnomePilotRecordModified; break; - - case CALOBJ_REMOVED: + case CAL_CLIENT_CHANGE_DELETED: local->local.attr = GnomePilotRecordDeleted; break; } @@ -505,7 +508,7 @@ pre_sync (GnomePilotConduit *conduit, GList *l; int len; unsigned char *buf; - char *filename; + char *filename, *change_id; gint num_records, add_records = 0, mod_records = 0, del_records = 0; abs_conduit = GNOME_PILOT_CONDUIT_SYNC_ABS (conduit); @@ -522,36 +525,36 @@ pre_sync (GnomePilotConduit *conduit, return -1; } - /* Get the local database */ - ctxt->uids = cal_client_get_uids (ctxt->client, CALOBJ_TYPE_TODO); - /* Load the uid <--> pilot id map */ filename = map_name (ctxt); e_pilot_map_read (filename, &ctxt->map); g_free (filename); + /* Get the local database */ + ctxt->uids = cal_client_get_uids (ctxt->client, CALOBJ_TYPE_TODO); + /* Count and hash the changes */ + change_id = g_strdup_printf ("pilot-sync-evolution-todo-%d", ctxt->cfg->pilot_id); + ctxt->changed = cal_client_get_changes (ctxt->client, CALOBJ_TYPE_TODO, change_id); ctxt->changed_hash = g_hash_table_new (g_str_hash, g_str_equal); - ctxt->changed = cal_client_get_changed_uids (ctxt->client, - CALOBJ_TYPE_TODO, - ctxt->map->since + 1); for (l = ctxt->changed; l != NULL; l = l->next) { - CalObjChange *coc = l->data; - - if (!e_pilot_map_uid_is_archived (ctxt->map, coc->uid)) { + CalClientChange *ccc = l->data; + const char *uid; + + cal_component_get_uid (ccc->comp, &uid); + if (!e_pilot_map_uid_is_archived (ctxt->map, uid)) { - g_hash_table_insert (ctxt->changed_hash, coc->uid, coc); + g_hash_table_insert (ctxt->changed_hash, g_strdup (uid), ccc); - switch (coc->type) { - case CALOBJ_UPDATED: - if (e_pilot_map_lookup_pid (ctxt->map, coc->uid) > 0) - mod_records++; - else - add_records++; + switch (ccc->type) { + case CAL_CLIENT_CHANGE_ADDED: + add_records++; break; - - case CALOBJ_REMOVED: + case CAL_CLIENT_CHANGE_MODIFIED: + mod_records++; + break; + case CAL_CLIENT_CHANGE_DELETED: del_records++; break; } @@ -704,14 +707,12 @@ for_each_modified (GnomePilotConduitSyncAbs *conduit, iterator = next_changed_item (ctxt, iterator); if (iterator != NULL) { - CalObjChange *coc = NULL; - - coc = iterator->data; + CalClientChange *ccc = iterator->data; LOG ("iterating over %d records", g_hash_table_size (ctxt->changed_hash)); *local = g_new0 (EToDoLocalRecord, 1); - local_record_from_uid (*local, coc->uid, ctxt); + local_record_from_comp (*local, ccc->comp, ctxt); } else { LOG ("no events"); @@ -721,12 +722,10 @@ for_each_modified (GnomePilotConduitSyncAbs *conduit, count++; iterator = g_list_next (iterator); if (iterator && (iterator = next_changed_item (ctxt, iterator))) { - CalObjChange *coc = NULL; - - coc = iterator->data; + CalClientChange *ccc = iterator->data; *local = g_new0 (EToDoLocalRecord, 1); - local_record_from_uid (*local, coc->uid, ctxt); + local_record_from_comp (*local, ccc->comp, ctxt); } else { LOG ("for_each_modified ending"); diff --git a/calendar/idl/evolution-calendar.idl b/calendar/idl/evolution-calendar.idl index 7969357e9a..89926386e2 100644 --- a/calendar/idl/evolution-calendar.idl +++ b/calendar/idl/evolution-calendar.idl @@ -36,8 +36,9 @@ module Calendar { /* Types of object changes made */ typedef long CalObjChangeType; - const CalObjChangeType UPDATED = 1 << 0; - const CalObjChangeType REMOVED = 1 << 1; + const CalObjChangeType ADDED = 1 << 0; + const CalObjChangeType MODIFIED = 1 << 0; + const CalObjChangeType DELETED = 1 << 1; /* Types of alarms */ enum AlarmType { @@ -66,10 +67,12 @@ module Calendar { /* An object change */ struct CalObjChange { - CalObjUID uid; + CalObj calobj; CalObjChangeType type; }; + typedef sequence CalObjChangeSeq; + /* An alarm trigger instance */ struct CalAlarmInstance { CalObjUID uid; @@ -80,8 +83,6 @@ module Calendar { typedef sequence CalAlarmInstanceSeq; - typedef sequence CalObjChangeSeq; - interface Listener; /* Calendar client interface */ @@ -103,8 +104,8 @@ module Calendar { /* Gets a list of UIDs based on object type */ CalObjUIDSeq getUIds (in CalObjType type); - /* Gets a list of UIds that changed based on object type */ - CalObjChangeSeq getChangedUIds (in CalObjType type, in Time_t since); + /* Gets a list of objects that changed based on object type */ + CalObjChangeSeq getChanges (in CalObjType type, in string change_id); /* Gets a list of objects that occur or recur in the specified time range */ CalObjUIDSeq getObjectsInRange (in CalObjType type, diff --git a/calendar/pcs/cal-backend.c b/calendar/pcs/cal-backend.c index 43895cc554..b17b036c27 100644 --- a/calendar/pcs/cal-backend.c +++ b/calendar/pcs/cal-backend.c @@ -27,6 +27,7 @@ #include #include +#include "e-util/e-dbhash.h" #include "cal-backend.h" #include "libversit/vcc.h" @@ -41,10 +42,6 @@ enum { static void cal_backend_class_init (CalBackendClass *class); static void cal_backend_init (CalBackend *backend); static void cal_backend_destroy (GtkObject *object); -static gboolean cal_backend_log_sync (CalBackend *backend); -static GHashTable *cal_backend_get_log_entries (CalBackend *backend, - CalObjType type, - time_t since); static GtkObjectClass *parent_class; @@ -115,8 +112,6 @@ static void cal_backend_init (CalBackend *backend) { backend->uri = NULL; - backend->entries = NULL; - backend->timer = -1; } static void @@ -129,15 +124,8 @@ cal_backend_destroy (GtkObject *object) backend = CAL_BACKEND (object); - if (backend->timer != -1) { - gtk_timeout_remove (backend->timer); - backend->timer = -1; - } - - if (backend->uri) { - cal_backend_log_sync (backend); + if (backend->uri) gnome_vfs_uri_unref (backend->uri); - } if (GTK_OBJECT_CLASS (parent_class)->destroy) (* GTK_OBJECT_CLASS (parent_class)->destroy) (object); @@ -170,15 +158,8 @@ cal_backend_set_uri (CalBackend *backend, GnomeVFSURI *uri) if (backend->uri) gnome_vfs_uri_unref (backend->uri); - if (backend->timer != -1) - gtk_timeout_remove (backend->timer); - - gnome_vfs_uri_ref (uri); backend->uri = uri; - backend->timer = gtk_timeout_add (60000, - (GtkFunction)cal_backend_log_sync, - backend); } /** @@ -221,8 +202,6 @@ cal_backend_load (CalBackend *backend, GnomeVFSURI *uri) g_assert (CLASS (backend)->load != NULL); result = (* CLASS (backend)->load) (backend, uri); - /* Remember the URI for saving the log file in the same dir and add - * a timeout handler so for saving pending entries sometimes */ if (result == CAL_BACKEND_LOAD_SUCCESS) cal_backend_set_uri (backend, uri); @@ -246,8 +225,6 @@ cal_backend_create (CalBackend *backend, GnomeVFSURI *uri) g_assert (CLASS (backend)->create != NULL); (* CLASS (backend)->create) (backend, uri); - /* Remember the URI for saving the log file in the same dir and add - * a timeout handler so for saving pending entries sometimes */ cal_backend_set_uri (backend, uri); } @@ -314,40 +291,123 @@ cal_backend_get_uids (CalBackend *backend, CalObjType type) return (* CLASS (backend)->get_uids) (backend, type); } +typedef struct +{ + CalBackend *backend; + GList *changes; + GList *change_ids; +} CalBackendComputeChangesData; static void -cal_backend_foreach_changed (gpointer key, gpointer value, gpointer data) +cal_backend_compute_changes_foreach_key (const char *key, gpointer data) { - GList **list = data; + CalBackendComputeChangesData *be_data = data; + char *calobj = cal_backend_get_object (be_data->backend, key); - *list = g_list_append (*list, value); + if (calobj == NULL) { + CalObjChange *coc = g_new0 (CalObjChange, 1); + + coc->calobj = g_strdup (calobj); + coc->type = CALOBJ_DELETED; + be_data->changes = g_list_prepend (be_data->changes, coc); + be_data->change_ids = g_list_prepend (be_data->change_ids, (gpointer) key); + } +} + +static GList * +cal_backend_compute_changes (CalBackend *backend, CalObjType type, const char *change_id) +{ + char *filename; + EDbHash *ehash; + CalBackendComputeChangesData be_data; + GList *uids, *changes = NULL, *change_ids = NULL; + GList *i, *j; + + /* Find the changed ids - FIX ME, path should not be hard coded */ + filename = g_strdup_printf ("%s/evolution/local/Calendar/%s.db", g_get_home_dir (), change_id); + ehash = e_dbhash_new (filename); + g_free (filename); + + uids = cal_backend_get_uids (backend, type); + + /* Calculate adds and modifies */ + for (i = uids; i != NULL; i = i->next) { + CalObjChange *coc; + char *uid = i->data; + char *calobj = cal_backend_get_object (backend, uid); + + g_assert (calobj != NULL); + + /* check what type of change has occurred, if any */ + switch (e_dbhash_compare (ehash, uid, calobj)) { + case E_DBHASH_STATUS_SAME: + break; + case E_DBHASH_STATUS_NOT_FOUND: + coc = g_new0 (CalObjChange, 1); + coc->calobj = g_strdup (calobj); + coc->type = CALOBJ_ADDED; + changes = g_list_prepend (changes, coc); + change_ids = g_list_prepend (change_ids, uid); + break; + case E_DBHASH_STATUS_DIFFERENT: + coc = g_new0 (CalObjChange, 1); + coc->calobj = g_strdup (calobj); + coc->type = CALOBJ_MODIFIED; + changes = g_list_append (changes, coc); + change_ids = g_list_prepend (change_ids, uid); + break; + } + } + + /* Calculate deletions */ + be_data.backend = backend; + be_data.changes = changes; + be_data.change_ids = change_ids; + e_dbhash_foreach_key (ehash, (EDbHashFunc)cal_backend_compute_changes_foreach_key, &be_data); + changes = be_data.changes; + change_ids = be_data.change_ids; + + /* Update the hash */ + for (i = changes, j = change_ids; i != NULL; i = i->next, j = j->next) { + CalObjChange *coc = i->data; + char *uid = j->data; + + if (coc->type == CALOBJ_ADDED || coc->type == CALOBJ_MODIFIED) { + e_dbhash_add (ehash, uid, coc->calobj); + } else { + e_dbhash_remove (ehash, uid); + } + } + + e_dbhash_write (ehash); + e_dbhash_destroy (ehash); + + g_list_free (change_ids); + + return changes; } /** - * cal_backend_get_changed_uids: + * cal_backend_get_changes: * @backend: * @type: - * @since: + * @change_id: * * * * Return value: **/ GList * -cal_backend_get_changed_uids (CalBackend *backend, CalObjType type, time_t since) +cal_backend_get_changes (CalBackend *backend, CalObjType type, const char *change_id) { - GHashTable *hash; - GList *uids = NULL; + GList *changes = NULL; g_return_val_if_fail (backend != NULL, NULL); g_return_val_if_fail (IS_CAL_BACKEND (backend), NULL); - hash = cal_backend_get_log_entries (backend, type, since); + changes = cal_backend_compute_changes (backend, type, change_id); - if (hash) - g_hash_table_foreach (hash, cal_backend_foreach_changed, &uids); - - return uids; + return changes; } @@ -428,263 +488,6 @@ cal_backend_get_alarms_for_object (CalBackend *backend, const char *uid, return (* CLASS (backend)->get_alarms_for_object) (backend, uid, start, end, alarms); } -/* Internal logging stuff */ -typedef enum { - CAL_BACKEND_UPDATED, - CAL_BACKEND_REMOVED -} CalBackendLogEntryType; - -typedef struct { - char *uid; - CalObjType type; - - CalBackendLogEntryType event_type; - - time_t time_stamp; -} CalBackendLogEntry; - -typedef struct { - CalObjType type; - time_t since; - - gboolean in_valid_timestamp; - - GHashTable *hash; -} CalBackendParseState; - -static gchar * -cal_backend_log_name (GnomeVFSURI *uri) -{ - const gchar *path; - gchar *filename; - - path = gnome_vfs_uri_get_path (uri); - filename = g_strdup_printf ("%s.log.xml", path); - - return filename; -} - -static void -cal_backend_set_node_timet (xmlNodePtr node, const char *name, time_t t) -{ - char *tstring; - - tstring = g_strdup_printf ("%ld", t); - xmlSetProp (node, name, tstring); - g_free (tstring); -} - -static void -cal_backend_log_entry (CalBackend *backend, - const char *uid, - CalObjType cot, - CalBackendLogEntryType type) -{ - CalBackendLogEntry *entry; - - g_assert (CLASS (backend)->get_type_by_uid != NULL); - - /* Only log todos and events */ - if (cot != CALOBJ_TYPE_EVENT && cot != CALOBJ_TYPE_TODO) - return; - - entry = g_new0 (CalBackendLogEntry, 1); - entry->uid = g_strdup (uid); - entry->type = cot; - entry->event_type = type; - entry->time_stamp = time (NULL); - - /* Append so they get stored in chronological order */ - backend->entries = g_slist_append (backend->entries, entry); -} - -static gboolean -cal_backend_log_sync (CalBackend *backend) -{ - xmlDocPtr doc; - xmlNodePtr tnode; - gchar *filename; - GSList *l; - int ret; - time_t start_time = (time_t) - 1; - time_t end_time = (time_t) - 1; - - g_return_val_if_fail (backend->uri != NULL, FALSE); - - if (backend->entries == NULL) - return TRUE; - - filename = cal_backend_log_name (backend->uri); - - doc = xmlParseFile (filename); - if (doc == NULL) { - /* Create the document */ - doc = xmlNewDoc ("1.0"); - if (doc == NULL) { - g_warning ("Log file could not be created\n"); - return FALSE; - } - - - doc->root = xmlNewDocNode(doc, NULL, "CalendarLog", NULL); - } - - tnode = xmlNewChild (doc->root, NULL, "timestamp", NULL); - for (l = backend->entries; l != NULL; l = l->next) { - xmlNodePtr node; - CalBackendLogEntry *entry; - - entry = (CalBackendLogEntry *)l->data; - node = xmlNewChild (tnode, NULL, "status", NULL); - - xmlSetProp (node, "uid", entry->uid); - - switch (entry->type) { - case CALOBJ_TYPE_EVENT: - xmlSetProp (node, "type", "event"); - break; - case CALOBJ_TYPE_TODO: - xmlSetProp (node, "type", "todo"); - break; - default: - } - - switch (entry->event_type) { - case (CAL_BACKEND_UPDATED): - xmlSetProp (node, "operation", "updated"); - break; - case (CAL_BACKEND_REMOVED): - xmlSetProp (node, "operation", "removed"); - break; - } - - if (start_time == (time_t) - 1 - || entry->time_stamp < start_time) - start_time = entry->time_stamp; - - if (end_time == (time_t) - 1 - || entry->time_stamp > end_time) - end_time = entry->time_stamp; - - g_free (entry->uid); - g_free (entry); - } - cal_backend_set_node_timet (tnode, "start", start_time); - cal_backend_set_node_timet (tnode, "end", end_time); - - g_slist_free (backend->entries); - backend->entries = NULL; - - /* Write the file */ - xmlSetDocCompressMode (doc, 0); - ret = xmlSaveFile (filename, doc); - if (ret < 0) { - g_warning ("Log file could not be saved\n"); - return FALSE; - } - - xmlFreeDoc (doc); - - g_free (filename); - - return TRUE; -} - -static void -cal_backend_log_sax_start_element (CalBackendParseState *state, const CHAR *name, - const CHAR **attrs) -{ - if (!strcmp (name, "timestamp")) { - while (attrs && *attrs != NULL) { - const xmlChar **val = attrs; - - val++; - if (!strcmp (*attrs, "start")) { - time_t start = (time_t)strtoul (*val, NULL, 0); - - if (start >= state->since) - state->in_valid_timestamp = TRUE; - break; - } - attrs = ++val; - } - } - - if (state->in_valid_timestamp && !strcmp (name, "status")) { - CalObjChange *coc = g_new0 (CalObjChange, 1); - CalObjType cot = 0; - - while (attrs && *attrs != NULL) { - const xmlChar **val = attrs; - - - val++; - if (!strcmp (*attrs, "uid")) - coc->uid = g_strdup (*val); - - if (!strcmp (*attrs, "type")) { - if (!strcmp (*val, "event")) - cot = CALOBJ_TYPE_EVENT; - else if (!strcmp (*val, "todo")) - cot = CALOBJ_TYPE_TODO; - } - - if (!strcmp (*attrs, "operation")) { - if (!strcmp (*val, "updated")) - coc->type = CALOBJ_UPDATED; - else if (!strcmp (*val, "removed")) - coc->type = CALOBJ_REMOVED; - } - - attrs = ++val; - } - - if (state->type == CALOBJ_TYPE_ANY || state->type == cot) - g_hash_table_insert (state->hash, coc->uid, coc); - } -} - -static void -cal_backend_log_sax_end_element (CalBackendParseState *state, const CHAR *name) -{ - if (!strcmp (name, "timestamp")) { - state->in_valid_timestamp = FALSE; - } -} - -static GHashTable * -cal_backend_get_log_entries (CalBackend *backend, CalObjType type, time_t since) -{ - xmlSAXHandler handler; - CalBackendParseState state; - GHashTable *hash; - char *filename; - - g_return_val_if_fail (backend != NULL, NULL); - g_return_val_if_fail (backend->uri != NULL, NULL); - g_return_val_if_fail (IS_CAL_BACKEND (backend), NULL); - - if (!cal_backend_log_sync (backend)) - return NULL; - - memset (&handler, 0, sizeof (xmlSAXHandler)); - handler.startElement = (startElementSAXFunc)cal_backend_log_sax_start_element; - handler.endElement = (endElementSAXFunc)cal_backend_log_sax_end_element; - - hash = g_hash_table_new (g_str_hash, g_str_equal); - - state.type = type; - state.since = since; - state.in_valid_timestamp = FALSE; - state.hash = hash; - - filename = cal_backend_log_name (backend->uri); - if (xmlSAXUserParseFile (&handler, &state, filename) < 0) - return NULL; - - return hash; -} - /** * cal_backend_update_object: * @backend: A calendar backend. @@ -701,23 +504,13 @@ cal_backend_get_log_entries (CalBackend *backend, CalObjType type, time_t since) gboolean cal_backend_update_object (CalBackend *backend, const char *uid, const char *calobj) { - CalObjType cot; - gboolean result; - g_return_val_if_fail (backend != NULL, FALSE); g_return_val_if_fail (IS_CAL_BACKEND (backend), FALSE); g_return_val_if_fail (uid != NULL, FALSE); g_return_val_if_fail (calobj != NULL, FALSE); g_assert (CLASS (backend)->update_object != NULL); - result = (* CLASS (backend)->update_object) (backend, uid, calobj); - - if (result) { - cot = (* CLASS (backend)->get_type_by_uid) (backend, uid); - cal_backend_log_entry (backend, uid, cot, CAL_BACKEND_UPDATED); - } - - return result; + return (* CLASS (backend)->update_object) (backend, uid, calobj); } /** @@ -734,21 +527,12 @@ cal_backend_update_object (CalBackend *backend, const char *uid, const char *cal gboolean cal_backend_remove_object (CalBackend *backend, const char *uid) { - CalObjType cot; - gboolean result; - g_return_val_if_fail (backend != NULL, FALSE); g_return_val_if_fail (IS_CAL_BACKEND (backend), FALSE); g_return_val_if_fail (uid != NULL, FALSE); g_assert (CLASS (backend)->remove_object != NULL); - cot = (* CLASS (backend)->get_type_by_uid) (backend, uid); - result = (* CLASS (backend)->remove_object) (backend, uid); - - if (result) - cal_backend_log_entry (backend, uid, cot, CAL_BACKEND_REMOVED); - - return result; + return (* CLASS (backend)->remove_object) (backend, uid); } /** diff --git a/calendar/pcs/cal-backend.h b/calendar/pcs/cal-backend.h index 44262c10ca..25a60a859f 100644 --- a/calendar/pcs/cal-backend.h +++ b/calendar/pcs/cal-backend.h @@ -52,8 +52,6 @@ struct _CalBackend { GtkObject object; GnomeVFSURI *uri; - GSList *entries; - guint timer; }; struct _CalBackendClass { @@ -98,7 +96,7 @@ char *cal_backend_get_object (CalBackend *backend, const char *uid); GList *cal_backend_get_uids (CalBackend *backend, CalObjType type); -GList *cal_backend_get_changed_uids (CalBackend *backend, CalObjType type, time_t since); +GList *cal_backend_get_changes (CalBackend *backend, CalObjType type, const char *change_id); GList *cal_backend_get_objects_in_range (CalBackend *backend, CalObjType type, time_t start, time_t end); diff --git a/calendar/pcs/cal.c b/calendar/pcs/cal.c index 8383d135fb..a7f0c5dfce 100644 --- a/calendar/pcs/cal.c +++ b/calendar/pcs/cal.c @@ -300,34 +300,32 @@ build_change_seq (GList *changes) c = l->data; corba_c = &seq->_buffer[i]; - corba_c->uid = CORBA_string_dup (c->uid); + corba_c->calobj = CORBA_string_dup (c->calobj); corba_c->type = c->type; } return seq; } -/* Cal::get_changed_uids method */ +/* Cal::get_changes method */ static GNOME_Evolution_Calendar_CalObjChangeSeq * -Cal_get_changed_uids (PortableServer_Servant servant, - GNOME_Evolution_Calendar_CalObjType type, - GNOME_Evolution_Calendar_Time_t since, - CORBA_Environment *ev) +Cal_get_changes (PortableServer_Servant servant, + GNOME_Evolution_Calendar_CalObjType type, + const CORBA_char *change_id, + CORBA_Environment *ev) { Cal *cal; CalPrivate *priv; GList *changes; GNOME_Evolution_Calendar_CalObjChangeSeq *seq; int t; - time_t s; cal = CAL (bonobo_object_from_servant (servant)); priv = cal->priv; t = uncorba_obj_type (type); - s = (time_t) since; - changes = cal_backend_get_changed_uids (priv->backend, t, s); + changes = cal_backend_get_changes (priv->backend, t, change_id); seq = build_change_seq (changes); cal_obj_change_list_free (changes); @@ -564,7 +562,7 @@ cal_get_epv (void) epv->countObjects = Cal_get_n_objects; epv->getObject = Cal_get_object; epv->getUIds = Cal_get_uids; - epv->getChangedUIds = Cal_get_changed_uids; + epv->getChanges = Cal_get_changes; epv->getObjectsInRange = Cal_get_objects_in_range; epv->getAlarmsInRange = Cal_get_alarms_in_range; epv->getAlarmsForObject = Cal_get_alarms_for_object; -- cgit