Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
home:pchenthill
evolution-data-server
bnc-159934-eds-CPU-spikes.patch
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File bnc-159934-eds-CPU-spikes.patch of Package evolution-data-server
--- ../temp/evolution-data-server/evolution-data-server-1.6.0/addressbook/backends/groupwise/e-book-backend-groupwise.c 2006-04-19 19:11:23.000000000 +0530 +++ addressbook/backends/groupwise/e-book-backend-groupwise.c 2006-04-19 13:13:06.000000000 +0530 @@ -22,13 +22,16 @@ */ #include <config.h> - +#include <stdio.h> +#include <stdlib.h> #include <string.h> #include <sys/types.h> #include <sys/stat.h> #include <sys/time.h> #include <time.h> #include <unistd.h> +#include <errno.h> +#include "db.h" #include <glib.h> #include <glib/gstdio.h> @@ -36,12 +39,13 @@ #include "libedataserver/e-sexp.h" #include "libedataserver/e-data-server-util.h" +#include "libedataserver/e-db3-utils.h" #include "libedataserver/e-url.h" #include "libebook/e-contact.h" #include "libedata-book/e-book-backend-sexp.h" #include "libedata-book/e-data-book.h" #include "libedata-book/e-data-book-view.h" -#include "libedata-book/e-book-backend-cache.h" +#include "libedata-book/e-book-backend-db-cache.h" #include "libedata-book/e-book-backend-summary.h" #include "e-book-backend-groupwise.h" @@ -68,15 +72,21 @@ struct _EBookBackendGroupwisePrivate { char *use_ssl; int mode; int cache_timeout; - EBookBackendCache *cache; EBookBackendSummary *summary; GMutex *update_mutex; + DB *file_db; + DB_ENV *env; /* for future use */ void *reserved1; void *reserved2; - void *reserved3; }; +static GStaticMutex global_env_lock = G_STATIC_MUTEX_INIT; +static struct { + int ref_count; + DB_ENV *env; +} global_env; + #define ELEMENT_TYPE_SIMPLE 0x01 #define ELEMENT_TYPE_COMPLEX 0x02 /* fields which require explicit functions to set values into EContact and EGwItem */ #define SUMMARY_FLUSH_TIMEOUT 5000 @@ -919,7 +929,7 @@ set_organization_in_gw_item (EGwItem *it e_contact_set (contact, E_CONTACT_FULL_NAME, organization_name); /* book uri is always set outside fill_contact_from_gw_item() */ e_contact_set (contact, E_CONTACT_BOOK_URI, egwb->priv->original_uri); - e_book_backend_cache_add_contact (egwb->priv->cache, contact); + e_book_backend_db_cache_add_contact (egwb->priv->file_db, contact); e_book_backend_summary_add_contact (egwb->priv->summary, contact); g_object_unref (contact); } @@ -1159,7 +1169,7 @@ e_book_backend_groupwise_create_contact if (status == E_GW_CONNECTION_STATUS_OK && id) { e_contact_set (contact, E_CONTACT_UID, id); g_free (id); - e_book_backend_cache_add_contact (egwb->priv->cache, contact); + e_book_backend_db_cache_add_contact (egwb->priv->file_db, contact); e_book_backend_summary_add_contact (egwb->priv->summary, contact); e_data_book_respond_create(book, opid, GNOME_Evolution_Addressbook_Success, contact); @@ -1210,7 +1220,7 @@ e_book_backend_groupwise_remove_contacts id = (char*) id_list->data; e_gw_connection_remove_item (ebgw->priv->cnc, ebgw->priv->container_id, id); deleted_ids = g_list_append (deleted_ids, id); - e_book_backend_cache_remove_contact (ebgw->priv->cache, id); + e_book_backend_db_cache_remove_contact (ebgw->priv->file_db, id); e_book_backend_summary_remove_contact (ebgw->priv->summary, id); } e_data_book_respond_remove_contacts (book, opid, @@ -1345,9 +1355,9 @@ e_book_backend_groupwise_modify_contact status = e_gw_connection_modify_item (egwb->priv->cnc, id, new_item); if (status == E_GW_CONNECTION_STATUS_OK) { e_data_book_respond_modify (book, opid, GNOME_Evolution_Addressbook_Success, contact); - e_book_backend_cache_remove_contact (egwb->priv->cache, id); + e_book_backend_db_cache_remove_contact (egwb->priv->file_db, id); e_book_backend_summary_remove_contact (egwb->priv->summary, id); - e_book_backend_cache_add_contact (egwb->priv->cache, contact); + e_book_backend_db_cache_add_contact (egwb->priv->file_db, contact); e_book_backend_summary_add_contact (egwb->priv->summary, contact); } else @@ -1381,7 +1391,7 @@ e_book_backend_groupwise_get_contact (EB switch (gwb->priv->mode) { case GNOME_Evolution_Addressbook_MODE_LOCAL : - contact = e_book_backend_cache_get_contact (gwb->priv->cache, id); + contact = e_book_backend_db_cache_get_contact (gwb->priv->file_db, id); vcard = e_vcard_to_string (E_VCARD (contact), EVC_FORMAT_VCARD_30); if (contact) { e_data_book_respond_get_contact(book, opid, GNOME_Evolution_Addressbook_Success, vcard); @@ -1836,14 +1846,14 @@ e_book_backend_groupwise_get_contact_lis char *uid = g_ptr_array_index (ids, i); EContact *contact = - e_book_backend_cache_get_contact (egwb->priv->cache, uid); + e_book_backend_db_cache_get_contact (egwb->priv->file_db, uid); contacts = g_list_append (contacts, contact); g_object_unref (contact); } g_ptr_array_free (ids, TRUE); } else - contacts = e_book_backend_cache_get_contacts (egwb->priv->cache, query); + contacts = e_book_backend_db_cache_get_contacts (egwb->priv->file_db, query); temp = contacts; for (; contacts != NULL; contacts = g_list_next(contacts)) { @@ -1882,7 +1892,7 @@ e_book_backend_groupwise_get_contact_lis int i; for (i = 0; i < ids->len; i ++) { char *uid = g_ptr_array_index (ids, i); - contact = e_book_backend_cache_get_contact (egwb->priv->cache, uid); + contact = e_book_backend_db_cache_get_contact (egwb->priv->file_db, uid); vcard_list = g_list_append (vcard_list, e_vcard_to_string (E_VCARD (contact), EVC_FORMAT_VCARD_30)); @@ -1893,7 +1903,7 @@ e_book_backend_groupwise_get_contact_lis } } else { - ids = e_book_backend_cache_search (egwb->priv->cache, query); + ids = e_book_backend_db_cache_search (egwb->priv->file_db, query); } if (ids->len > 0) { @@ -2001,7 +2011,7 @@ get_closure (EDataBookView *book_view) } static void -get_contacts_from_cache (EBookBackendGroupwisePrivate *priv, +get_contacts_from_cache (EBookBackendGroupwise *ebgw, const char *query, GPtrArray *ids, EDataBookView *book_view, @@ -2023,9 +2033,11 @@ get_contacts_from_cache (EBookBackendGro break; EContact *contact = - e_book_backend_cache_get_contact (priv->cache, uid); - e_data_book_view_notify_update (book_view, contact); - g_object_unref (contact); + e_book_backend_db_cache_get_contact (ebgw->priv->file_db, uid); + if (contact) { + e_data_book_view_notify_update (book_view, contact); + g_object_unref (contact); + } } if (!stopped) e_data_book_view_notify_complete (book_view, @@ -2067,7 +2079,7 @@ book_view_thread (gpointer data) switch (gwb->priv->mode) { case GNOME_Evolution_Addressbook_MODE_LOCAL : - if (!gwb->priv->cache) { + if (!gwb->priv->file_db) { e_data_book_view_notify_complete (book_view, GNOME_Evolution_Addressbook_Success); return NULL; } @@ -2078,7 +2090,7 @@ book_view_thread (gpointer data) printf ("reading the uids from summary \n"); ids = e_book_backend_summary_search (gwb->priv->summary, query); if (ids && ids->len > 0) { - get_contacts_from_cache (gwb->priv, query, ids, book_view, closure); + get_contacts_from_cache (gwb, query, ids, book_view, closure); g_ptr_array_free (ids, TRUE); } bonobo_object_unref (book_view); @@ -2088,7 +2100,7 @@ book_view_thread (gpointer data) /* fall back to cache */ if (enable_debug) printf ("summary not found, reading the uids from cache\n"); - contacts = e_book_backend_cache_get_contacts (gwb->priv->cache, query); + contacts = e_book_backend_db_cache_get_contacts (gwb->priv->file_db, query); temp_list = contacts; for (; contacts != NULL; contacts = g_list_next(contacts)) { g_mutex_lock (closure->mutex); @@ -2170,7 +2182,7 @@ book_view_thread (gpointer data) if (!is_auto_completion) e_data_book_view_notify_status_message (book_view, _("Searching...")); - get_contacts_from_cache (gwb->priv, query, ids, book_view, closure); + get_contacts_from_cache (gwb, query, ids, book_view, closure); g_ptr_array_free (ids, TRUE); bonobo_object_unref (book_view); if (enable_debug) { @@ -2330,11 +2342,11 @@ static EDataBookView * find_book_view (EBookBackendGroupwise *ebgw) { EList *views = e_book_backend_get_book_views (E_BOOK_BACKEND (ebgw)); - if (!views) - return NULL; + if (!views) + return NULL; EIterator *iter = e_list_get_iterator (views); EDataBookView *rv = NULL; - + if (!iter) { g_object_unref (views); return NULL; @@ -2353,35 +2365,110 @@ find_book_view (EBookBackendGroupwise *e return rv; } +static void +get_sequence_from_cache (DB *db, + gdouble *cache_first_sequence, + gdouble *cache_last_sequence, + gdouble *cache_last_po_rebuild_time) +{ + DBT uid_dbt, vcard_dbt; + int db_error; + + string_to_dbt ("firstSequence", &uid_dbt); + memset (&vcard_dbt, 0, sizeof(vcard_dbt)); + vcard_dbt.flags = DB_DBT_MALLOC; + + db_error = db->get (db, NULL, &uid_dbt, &vcard_dbt, 0); + if (db_error != 0) { + g_warning ("db->get failed with %d", db_error); + } + else { + *cache_first_sequence = strtod (g_strdup (vcard_dbt.data), NULL); + g_free (vcard_dbt.data); + } + + string_to_dbt ("lastSequence", &uid_dbt); + memset (&vcard_dbt, 0, sizeof(vcard_dbt)); + vcard_dbt.flags = DB_DBT_MALLOC; + + db_error = db->get (db, NULL, &uid_dbt, &vcard_dbt, 0); + if (db_error != 0) { + g_warning ("db->get failed with %d", db_error); + } + else { + *cache_last_sequence = strtod (g_strdup (vcard_dbt.data), NULL); + g_free (vcard_dbt.data); + } + + string_to_dbt ("lastTimePORebuild", &uid_dbt); + memset (&vcard_dbt, 0, sizeof(vcard_dbt)); + vcard_dbt.flags = DB_DBT_MALLOC; + + db_error = db->get (db, NULL, &uid_dbt, &vcard_dbt, 0); + if (db_error != 0) { + g_warning ("db->get failed with %d", db_error); + } + else { + *cache_last_po_rebuild_time = strtod (g_strdup (vcard_dbt.data), NULL); + g_free (vcard_dbt.data); + } + + if (enable_debug) { + printf("Read sequences from cache\n"); + printf("firstSequence:%lf, lastSequence:%lf, lastPoRebuildTime:%lf\n", *cache_first_sequence, *cache_last_sequence, *cache_last_po_rebuild_time); + } + +} static void -add_sequence_to_cache (EBookBackendCache *cache, - gdouble first_sequence, - gdouble last_sequence, - gdouble last_po_rebuild_time) +add_sequence_to_cache (DB *db, + gdouble first_sequence, + gdouble last_sequence, + gdouble last_po_rebuild_time) { gchar *tmp; + DBT uid_dbt, vcard_dbt; + int db_error; + + if (enable_debug) { + printf("Adding sequences to cache\n"); + printf("firstSequence:%lf, lastSequence:%lf, lastPoRebuildTime:%lf\n", first_sequence, last_sequence, last_po_rebuild_time); + } + + string_to_dbt ("firstSequence",&uid_dbt ); + tmp = g_strdup_printf("%lf", first_sequence); + string_to_dbt (tmp, &vcard_dbt); + + db_error = db->put (db, NULL, &uid_dbt, &vcard_dbt, 0); - /* This is the system address book. Let try add the sequence to maintain deltas */ - tmp = g_strdup_printf("%lf", first_sequence); - if (!e_file_cache_get_object (E_FILE_CACHE(cache), "firstSequence")) - e_file_cache_add_object (E_FILE_CACHE(cache), "firstSequence", tmp); - else - e_file_cache_replace_object (E_FILE_CACHE(cache), "firstSequence", tmp); g_free (tmp); - tmp = g_strdup_printf("%lf", last_sequence); - if (!e_file_cache_get_object (E_FILE_CACHE(cache), "lastSequence")) - e_file_cache_add_object (E_FILE_CACHE(cache), "lastSequence", tmp); - else - e_file_cache_replace_object (E_FILE_CACHE(cache), "lastSequence", tmp); + if (db_error != 0) { + g_warning ("db->put failed with %d", db_error); + } + + string_to_dbt ("lastSequence",&uid_dbt ); + tmp = g_strdup_printf("%lf", last_sequence); + string_to_dbt (tmp, &vcard_dbt); + + db_error = db->put (db, NULL, &uid_dbt, &vcard_dbt, 0); + g_free (tmp); + + if (db_error != 0) { + g_warning ("db->put failed with %d", db_error); + } - tmp = g_strdup_printf("%lf", last_po_rebuild_time); - if (!e_file_cache_get_object (E_FILE_CACHE(cache), "lastTimePORebuild")) - e_file_cache_add_object (E_FILE_CACHE(cache), "lastTimePORebuild", tmp); - else - e_file_cache_replace_object (E_FILE_CACHE(cache), "lastTimePORebuild", tmp); + string_to_dbt ("lastTimePORebuild",&uid_dbt ); + tmp = g_strdup_printf("%lf", last_po_rebuild_time); + string_to_dbt (tmp, &vcard_dbt); + + db_error = db->put (db, NULL, &uid_dbt, &vcard_dbt, 0); + g_free (tmp); + + if (db_error != 0) { + g_warning ("db->put failed with %d", db_error); + } } #define CURSOR_ITEM_LIMIT 100 @@ -2446,10 +2533,9 @@ build_cache (EBookBackendGroupwise *ebgw GTimeVal tstart, tend; unsigned long diff; - if(!ebgw) - return FALSE; + if(!ebgw) + return FALSE; - printf("build cache\n"); if (enable_debug) { g_get_current_time(&start); printf("Building the cache for %s \n", ebgw->priv->book_name); @@ -2467,14 +2553,13 @@ build_cache (EBookBackendGroupwise *ebgw if (book_view) { closure = get_closure (book_view); bonobo_object_ref (book_view); - if (closure) { - g_mutex_lock (closure->mutex); - g_cond_signal (closure->cond); - g_mutex_unlock (closure->mutex); - } + if (closure) { + g_mutex_lock (closure->mutex); + g_cond_signal (closure->cond); + g_mutex_unlock (closure->mutex); + } } - e_file_cache_freeze_changes (E_FILE_CACHE (priv->cache)); while (!done) { if (enable_debug) @@ -2496,7 +2581,7 @@ build_cache (EBookBackendGroupwise *ebgw fill_contact_from_gw_item (contact, E_GW_ITEM (l->data), ebgw->priv->categories_by_id); e_contact_set (contact, E_CONTACT_BOOK_URI, priv->original_uri); - e_book_backend_cache_add_contact (ebgw->priv->cache, contact); + e_book_backend_db_cache_add_contact (ebgw->priv->file_db, contact); e_book_backend_summary_add_contact (ebgw->priv->summary, contact); /* Since we get contacts incrementally, 100 at a time, we can not @@ -2516,7 +2601,7 @@ build_cache (EBookBackendGroupwise *ebgw } if (!gw_items) { - e_book_backend_cache_set_populated (priv->cache); + e_book_backend_db_cache_set_populated (ebgw->priv->file_db); done = TRUE; priv->is_cache_ready=TRUE; priv->is_summary_ready = TRUE; @@ -2526,7 +2611,8 @@ build_cache (EBookBackendGroupwise *ebgw gw_items = NULL; position = E_GW_CURSOR_POSITION_CURRENT; } - e_file_cache_thaw_changes (E_FILE_CACHE (priv->cache)); + + ebgw->priv->file_db->sync(ebgw->priv->file_db, 0); if (book_view) { e_data_book_view_notify_complete (book_view, @@ -2547,7 +2633,7 @@ build_cache (EBookBackendGroupwise *ebgw } static void -build_summary (EBookBackendGroupwisePrivate *priv) +build_summary (EBookBackendGroupwise *ebgw) { gchar *query_string; GList *contacts, *temp_list = NULL; @@ -2557,7 +2643,7 @@ build_summary (EBookBackendGroupwisePriv if (enable_debug) { g_get_current_time(&start); printf ("summary file not found or not up-to-date, building summary for %s\n", - priv->book_name); + ebgw->priv->book_name); } /* build summary from cache */ @@ -2565,23 +2651,23 @@ build_summary (EBookBackendGroupwisePriv " (beginswith \"full_name\" \"\") " " (beginswith \"email\" \"\") " " (beginswith \"nickname\" \"\"))"); - contacts = e_book_backend_cache_get_contacts (priv->cache, query_string); + contacts = e_book_backend_db_cache_get_contacts (ebgw->priv->file_db, query_string); g_free (query_string); temp_list = contacts; for (; contacts != NULL; contacts = g_list_next(contacts)) { - e_book_backend_summary_add_contact (priv->summary, contacts->data); + e_book_backend_summary_add_contact (ebgw->priv->summary, contacts->data); g_object_unref (contacts->data); } if (temp_list) g_list_free (temp_list); - priv->is_summary_ready = TRUE; + ebgw->priv->is_summary_ready = TRUE; if (enable_debug) { g_get_current_time(&end); diff = end.tv_sec * 1000 + end.tv_usec/1000; diff -= start.tv_sec * 1000 + start.tv_usec/1000; printf("building summary for %s took %ld.%03ld seconds \n", - priv->book_name, diff / 1000, diff % 1000); + ebgw->priv->book_name, diff / 1000, diff % 1000); } } @@ -2602,10 +2688,9 @@ update_cache (EBookBackendGroupwise *ebg GTimeVal start, end; unsigned long diff; - if (!ebgw) - return FALSE; + if (!ebgw) + return FALSE; - printf("Inside update cache\n"); if (enable_debug) { g_get_current_time(&start); printf("updating cache for %s\n", ebgw->priv->book_name); @@ -2615,14 +2700,14 @@ update_cache (EBookBackendGroupwise *ebg if (book_view) { closure = get_closure (book_view); bonobo_object_ref (book_view); - if (closure) { - g_mutex_lock (closure->mutex); - g_cond_signal (closure->cond); - g_mutex_unlock (closure->mutex); - } + if (closure) { + g_mutex_lock (closure->mutex); + g_cond_signal (closure->cond); + g_mutex_unlock (closure->mutex); + } } - cache_file_name = e_file_cache_get_filename (E_FILE_CACHE(ebgw->priv->cache)); + cache_file_name = e_book_backend_db_cache_get_filename(ebgw->priv->file_db); g_stat (cache_file_name, &buf); mod_time = buf.st_mtime; tm = gmtime (&mod_time); @@ -2631,7 +2716,7 @@ update_cache (EBookBackendGroupwise *ebg if (e_book_backend_summary_load (ebgw->priv->summary) == FALSE || e_book_backend_summary_is_up_to_date (ebgw->priv->summary, mod_time) == FALSE) { /* build summary */ - build_summary (ebgw->priv); + build_summary (ebgw); } filter = e_gw_filter_new (); @@ -2647,7 +2732,6 @@ update_cache (EBookBackendGroupwise *ebg return FALSE; } - e_file_cache_freeze_changes (E_FILE_CACHE (ebgw->priv->cache)); for (; gw_items != NULL; gw_items = g_list_next(gw_items)) { const char *id; @@ -2665,13 +2749,12 @@ update_cache (EBookBackendGroupwise *ebg g_free (status_msg); } - if (e_book_backend_cache_check_contact (ebgw->priv->cache, id)) { - e_book_backend_cache_remove_contact (ebgw->priv->cache, id); - e_book_backend_cache_add_contact (ebgw->priv->cache, contact); + if (e_book_backend_db_cache_check_contact (ebgw->priv->file_db, id)) { + e_book_backend_db_cache_add_contact (ebgw->priv->file_db, contact); e_book_backend_summary_remove_contact (ebgw->priv->summary, id); e_book_backend_summary_add_contact (ebgw->priv->summary, contact); } else { - e_book_backend_cache_add_contact (ebgw->priv->cache, contact); + e_book_backend_db_cache_add_contact (ebgw->priv->file_db, contact); e_book_backend_summary_add_contact (ebgw->priv->summary, contact); } @@ -2681,7 +2764,9 @@ update_cache (EBookBackendGroupwise *ebg ebgw->priv->is_cache_ready = TRUE; ebgw->priv->is_summary_ready = TRUE; - e_file_cache_thaw_changes (E_FILE_CACHE (ebgw->priv->cache)); + + ebgw->priv->file_db->sync(ebgw->priv->file_db, 0); + if (book_view) { e_data_book_view_notify_complete (book_view, GNOME_Evolution_Addressbook_Success); @@ -2704,23 +2789,22 @@ static gboolean update_address_book_deltas (EBookBackendGroupwise *ebgw) { int status, contact_num = 0; - gdouble server_first_sequence = -1, server_last_sequence = -1, server_last_po_rebuild_time = -1; - gdouble cache_last_sequence = -1, cache_last_po_rebuild_time = -1; - const char *cache_obj; - char *tmp, *count, *sequence, *status_msg; + gdouble server_first_sequence = -1, server_last_sequence = -1, server_last_po_rebuild_time = -1; + gdouble cache_first_sequence = -1, cache_last_sequence = -1, cache_last_po_rebuild_time = -1; + char *count, *sequence, *status_msg; + gboolean sync_required = FALSE; GList *add_list = NULL, *delete_list = NULL; EContact *contact; EDataBookView *book_view; GroupwiseBackendSearchClosure *closure; - if (!ebgw) - return FALSE; + if (!ebgw) + return FALSE; EBookBackendGroupwisePrivate *priv = ebgw->priv; - EBookBackendCache *cache = priv->cache; - - g_mutex_lock (priv->update_mutex); + g_mutex_lock (priv->update_mutex); + if (enable_debug) printf("\nupdating GroupWise system address book cache \n"); @@ -2733,7 +2817,7 @@ update_address_book_deltas (EBookBackend if (status != E_GW_CONNECTION_STATUS_OK) { if (enable_debug) printf("No connection with the server \n"); - g_mutex_unlock(priv->update_mutex); + g_mutex_unlock (priv->update_mutex); return FALSE; } @@ -2743,18 +2827,12 @@ update_address_book_deltas (EBookBackend if (enable_debug) printf ("sequence is reset, rebuilding cache...\n"); build_cache (ebgw); - g_mutex_unlock(priv->update_mutex); + g_mutex_unlock (priv->update_mutex); return TRUE; } - /* Read the last sequence and last poa rebuild time from cache */ - cache_obj = e_file_cache_get_object (E_FILE_CACHE (cache), "lastSequence"); - if (cache_obj) - cache_last_sequence = strtod (cache_obj, NULL); - - cache_obj = e_file_cache_get_object (E_FILE_CACHE (cache), "lastTimePORebuild"); - if (cache_obj) - cache_last_po_rebuild_time = strtod (cache_obj, NULL); + /* Read the last sequence and last poa rebuild time from cache */ + get_sequence_from_cache(priv->file_db, &cache_first_sequence, &cache_last_sequence, &cache_last_po_rebuild_time); /* check whether the all the sequences are available and also whether the PO is rebuilt */ if (server_first_sequence > cache_last_sequence || cache_last_sequence == -1 || @@ -2763,9 +2841,9 @@ update_address_book_deltas (EBookBackend if (enable_debug) printf ("either the sequences missing or PO is rebuilt...rebuilding the cache\n"); build_cache (ebgw); - add_sequence_to_cache (cache, server_first_sequence, + add_sequence_to_cache (priv->file_db, server_first_sequence, server_last_sequence, server_last_po_rebuild_time); - g_mutex_unlock(priv->update_mutex); + ebgw->priv->file_db->sync (ebgw->priv->file_db, 0); return TRUE; } @@ -2782,32 +2860,34 @@ update_address_book_deltas (EBookBackend if (book_view) { closure = get_closure (book_view); bonobo_object_ref (book_view); - if (closure){ - g_mutex_lock (closure->mutex); - g_cond_signal (closure->cond); - g_mutex_unlock (closure->mutex); - } + if (closure){ + g_mutex_lock (closure->mutex); + g_cond_signal (closure->cond); + g_mutex_unlock (closure->mutex); + } } /* update the cache */ - sequence = g_strdup_printf ("%lf", cache_last_sequence +1); + sequence = g_strdup_printf ("%lf", cache_last_sequence +1); count = g_strdup_printf ("%d", CURSOR_ITEM_LIMIT); /* load summary file */ - cache_file_name = e_file_cache_get_filename (E_FILE_CACHE(ebgw->priv->cache)); + cache_file_name = e_book_backend_db_cache_get_filename(ebgw->priv->file_db); g_stat (cache_file_name, &buf); mod_time = buf.st_mtime; if (e_book_backend_summary_load (ebgw->priv->summary) == FALSE || e_book_backend_summary_is_up_to_date (ebgw->priv->summary, mod_time) == FALSE) { /* build summary */ - build_summary (ebgw->priv); + build_summary (ebgw); } if (cache_last_sequence != server_last_sequence) { - e_file_cache_freeze_changes (E_FILE_CACHE (cache)); while (cache_last_sequence < server_last_sequence) { - printf("Calling get_items_delta\n"); + if (enable_debug) { + printf("cache_last_sequence:%lf, server_last_sequence:%lf\n", cache_last_sequence, server_last_sequence); + printf("Calling get_items_delta\n"); + } e_gw_connection_get_items_delta (priv->cnc, ebgw->priv->container_id, "name email sync", count, @@ -2819,9 +2899,10 @@ update_address_book_deltas (EBookBackend printf("sequence differs but no changes found !!!\n"); break; } + sync_required = TRUE; if (enable_debug) { - printf("add_list size:%d\n", g_list_length(add_list)); - printf("delete_list size:%d\n", g_list_length(delete_list)); + printf("add_list size:%d\n", g_list_length(add_list)); + printf("delete_list size:%d\n", g_list_length(delete_list)); } for (; delete_list != NULL; delete_list = g_list_next(delete_list)) { @@ -2839,7 +2920,7 @@ update_address_book_deltas (EBookBackend priv->original_uri); id = e_contact_get_const (contact, E_CONTACT_UID); - if (e_book_backend_cache_check_contact (ebgw->priv->cache, id)) { + if (e_book_backend_db_cache_check_contact (ebgw->priv->file_db, id)) { contact_num++; if (book_view) { @@ -2848,7 +2929,7 @@ update_address_book_deltas (EBookBackend book_view_notify_status (book_view, status_msg); g_free (status_msg); } - e_book_backend_cache_remove_contact (ebgw->priv->cache, id); + e_book_backend_db_cache_remove_contact (ebgw->priv->file_db, id); e_book_backend_summary_remove_contact (ebgw->priv->summary, id); } g_object_unref(contact); @@ -2863,6 +2944,9 @@ update_address_book_deltas (EBookBackend fill_contact_from_gw_item (contact, E_GW_ITEM (add_list->data), ebgw->priv->categories_by_id); + + if (enable_debug) + printf("contact email:%s, contact name:%s\n", (char *)e_contact_get(contact, E_CONTACT_EMAIL_1),(char *) e_contact_get(contact, E_CONTACT_GIVEN_NAME)); e_contact_set (contact, E_CONTACT_BOOK_URI, priv->original_uri); @@ -2875,41 +2959,32 @@ update_address_book_deltas (EBookBackend book_view_notify_status (book_view, status_msg); g_free (status_msg); } - if (e_book_backend_cache_check_contact (ebgw->priv->cache, id)) { - e_book_backend_cache_remove_contact (ebgw->priv->cache, id); + if (e_book_backend_db_cache_check_contact (ebgw->priv->file_db, id)) { + if (enable_debug) + printf("contact already there\n"); e_book_backend_summary_remove_contact (ebgw->priv->summary, id); - e_book_backend_cache_add_contact (ebgw->priv->cache, contact); + e_book_backend_db_cache_add_contact (ebgw->priv->file_db, contact); e_book_backend_summary_add_contact (ebgw->priv->summary, contact); } else { - e_book_backend_cache_add_contact (ebgw->priv->cache, contact); + if (enable_debug) + printf("contact not there\n"); + e_book_backend_db_cache_add_contact (ebgw->priv->file_db, contact); e_book_backend_summary_add_contact (ebgw->priv->summary, contact); } g_object_unref(contact); g_object_unref (add_list->data); } - cache_last_sequence += contact_num; } /* cache is updated, now adding the sequence information to the cache */ - tmp = g_strdup_printf("%lf", server_first_sequence); - e_file_cache_replace_object (E_FILE_CACHE(cache), "firstSequence", tmp); - g_free (tmp); - - tmp = g_strdup_printf("%lf", server_last_sequence); - e_file_cache_replace_object (E_FILE_CACHE(cache), "lastSequence", tmp); - g_free (tmp); - - tmp = g_strdup_printf("%lf", server_last_po_rebuild_time); - e_file_cache_replace_object (E_FILE_CACHE(cache), "lastTimePORebuild", tmp); - g_free (tmp); + add_sequence_to_cache (priv->file_db, server_first_sequence, + server_last_sequence, server_last_po_rebuild_time); g_list_free (add_list); g_list_free (delete_list); - - e_file_cache_thaw_changes (E_FILE_CACHE (cache)); } g_free (sequence); @@ -2917,6 +2992,10 @@ update_address_book_deltas (EBookBackend ebgw->priv->is_cache_ready = TRUE; ebgw->priv->is_summary_ready = TRUE; + if (sync_required) + ebgw->priv->file_db->sync(ebgw->priv->file_db, 0); + + if (book_view) { e_data_book_view_notify_complete (book_view, GNOME_Evolution_Addressbook_Success); @@ -2975,7 +3054,8 @@ e_book_backend_groupwise_authenticate_us const char *cache_refresh_interval_set; int cache_refresh_interval = CACHE_REFRESH_INTERVAL; - printf ("authenticate user ............\n"); + if (enable_debug) + printf ("authenticate user ............\n"); ebgw = E_BOOK_BACKEND_GROUPWISE (backend); priv = ebgw->priv; @@ -2996,7 +3076,7 @@ e_book_backend_groupwise_authenticate_us case GNOME_Evolution_Addressbook_MODE_REMOTE: if (priv->cnc) { /*we have already authenticated to server */ - printf("already authenticated\n"); + printf("already authenticated\n"); e_data_book_respond_authenticate_user (book, opid, GNOME_Evolution_Addressbook_Success); return; } @@ -3014,8 +3094,9 @@ e_book_backend_groupwise_authenticate_us id = NULL; is_writable = FALSE; - if(priv->book_name) - printf("book_name:%s\n", priv->book_name); + if (enable_debug) + if(priv->book_name) + printf("book_name:%s\n", priv->book_name); status = e_gw_connection_get_address_book_id (priv->cnc, priv->book_name, &id, &is_writable); if (status == E_GW_CONNECTION_STATUS_INVALID_CONNECTION) status = e_gw_connection_get_address_book_id (priv->cnc, priv->book_name, &id, &is_writable); @@ -3051,24 +3132,29 @@ e_book_backend_groupwise_authenticate_us priv->summary = e_book_backend_summary_new (priv->summary_file_name, SUMMARY_FLUSH_TIMEOUT); - if (e_book_backend_cache_is_populated (priv->cache)) { - printf("cache is populated\n"); - if (priv->is_writable){ - printf("is writable\n"); - printf("creating update_cache thread\n"); + if (e_book_backend_db_cache_is_populated (ebgw->priv->file_db)) { + if (enable_debug) + printf("cache is populated\n"); + if (priv->is_writable){ + if (enable_debug) { + printf("is writable\n"); + printf("creating update_cache thread\n"); + } g_thread_create ((GThreadFunc) update_cache, ebgw, FALSE, NULL); - } + } else if (priv->marked_for_offline) { - printf("marked for offline\n"); + if (enable_debug) + printf("marked for offline\n"); GThread *t; - printf("creating update_address_book_deltas thread\n"); + if (enable_debug) + printf("creating update_address_book_deltas thread\n"); t = g_thread_create ((GThreadFunc) update_address_book_deltas, ebgw, TRUE, NULL); /* spawn a thread to update the system address book cache * at given intervals */ - cache_refresh_interval_set = g_getenv ("BOOK_CACHE_REFRESH_INTERVAL"); + cache_refresh_interval_set = g_getenv ("BOOK_CACHE_REFRESH_INTERVAL"); if (cache_refresh_interval_set) { cache_refresh_interval = g_ascii_strtod (cache_refresh_interval_set, NULL); /* use this */ @@ -3086,16 +3172,20 @@ e_book_backend_groupwise_authenticate_us } else if (priv->is_writable) { /* for personal books we always cache */ /* Personal address book and frequent contacts */ - printf("else if is _writable"); - printf("build_cahe thread"); + if (enable_debug) { + printf("else if is _writable"); + printf("build_cahe thread"); + } g_thread_create ((GThreadFunc) build_cache, ebgw, FALSE, NULL); } else if(priv->marked_for_offline) { - printf("else if marked_for_offline\n"); + if (enable_debug) + printf("else if marked_for_offline\n"); GThread *t; /* System address book */ /* cache is not populated and book is not writable and marked for offline usage */ - printf("creating update_address_book_deltas thread\n"); + if (enable_debug) + printf("creating update_address_book_deltas thread\n"); t = g_thread_create ((GThreadFunc) update_address_book_deltas, ebgw, TRUE, NULL); g_thread_join (t); /* set the cache refresh time */ @@ -3164,6 +3254,12 @@ e_book_backend_groupwise_cancel_operatio return GNOME_Evolution_Addressbook_CouldNotCancel; } +static void +file_errcall (const char *buf1, char *buf2) +{ + g_warning ("libdb error: %s", buf2); +} + static GNOME_Evolution_Addressbook_CallStatus e_book_backend_groupwise_load_source (EBookBackend *backend, ESource *source, @@ -3171,10 +3267,14 @@ e_book_backend_groupwise_load_source (EB { EBookBackendGroupwise *ebgw; EBookBackendGroupwisePrivate *priv; + char *dirname, *filename; char *book_name; char *uri; char **tokens; const char *port; + int db_error; + DB *db; + DB_ENV *env; EUri *parsed_uri; int i; const char *use_ssl; @@ -3240,7 +3340,7 @@ e_book_backend_groupwise_load_source (EB } if (priv->mode == GNOME_Evolution_Addressbook_MODE_LOCAL) - if (!e_book_backend_cache_exists (priv->original_uri)) { + if (!e_book_backend_db_cache_exists (priv->original_uri)) { g_free (uri); e_uri_free (parsed_uri); return GNOME_Evolution_Addressbook_OfflineUnavailable; @@ -3249,15 +3349,117 @@ e_book_backend_groupwise_load_source (EB g_free (priv->summary_file_name); priv->summary_file_name = g_build_filename (g_get_home_dir(), ".evolution/addressbook" , uri, priv->book_name, NULL); priv->summary_file_name = g_strconcat (ebgw->priv->summary_file_name, ".summary", NULL); + + dirname = g_build_filename (g_get_home_dir(), ".evolution/cache/addressbook", uri, priv->book_name, NULL); + filename = g_build_filename (dirname, "cache.db", NULL); + + db_error = e_db3_utils_maybe_recover (filename); + if (db_error !=0) { + g_warning ("db recovery failed with %d", db_error); + g_free (dirname); + g_free (filename); + return GNOME_Evolution_Addressbook_OtherError; + } + + g_static_mutex_lock(&global_env_lock); + if (global_env.ref_count > 0) { + env = global_env.env; + global_env.ref_count++; + } + else { + db_error = db_env_create (&env, 0); + if (db_error != 0) { + g_warning ("db_env_create failed with %d", db_error); + g_static_mutex_unlock (&global_env_lock); + g_free (dirname); + g_free (filename); + return GNOME_Evolution_Addressbook_OtherError; + } + + db_error = env->open (env, NULL, DB_CREATE | DB_INIT_MPOOL | DB_PRIVATE | DB_THREAD, 0); + if (db_error != 0) { + env->close(env, 0); + g_warning ("db_env_open failed with %d", db_error); + g_static_mutex_unlock(&global_env_lock); + g_free(dirname); + g_free(filename); + return GNOME_Evolution_Addressbook_OtherError; + } + + env->set_errcall (env, file_errcall); + + global_env.env = env; + global_env.ref_count = 1; + } + g_static_mutex_unlock(&global_env_lock); + + ebgw->priv->env = env; + + db_error = db_create (&db, env, 0); + if (db_error != 0) { + g_warning ("db_create failed with %d", db_error); + g_free(dirname); + g_free(filename); + return GNOME_Evolution_Addressbook_OtherError; + } + + db_error = db->open (db, NULL, filename, NULL, DB_HASH, DB_THREAD, 0666); + + if (db_error == DB_OLD_VERSION) { + db_error = e_db3_utils_upgrade_format (filename); + + if (db_error != 0) { + g_warning ("db format upgrade failed with %d", db_error); + g_free(filename); + g_free(dirname); + return GNOME_Evolution_Addressbook_OtherError; + } + + db_error = db->open (db, NULL, filename, NULL, DB_HASH, DB_THREAD, 0666); + } + + ebgw->priv->file_db = db; + + if (db_error != 0) { + int rv; + + /* the databade didn't exist, so we create the + directory then the .db */ + rv = e_util_mkdir_hier (dirname, 0777); + if (rv == -1 && errno != EEXIST) { + g_warning ("failed to make directory %s: %s", dirname, strerror (errno)); + g_free (dirname); + g_free (filename); + if (errno == EACCES || errno == EPERM) + return GNOME_Evolution_Addressbook_PermissionDenied; + else + return GNOME_Evolution_Addressbook_OtherError; + } + + db_error = db->open (db, NULL, filename, NULL, DB_HASH, DB_CREATE | DB_THREAD, 0666); + if (db_error != 0) { + g_warning ("db->open (...DB_CREATE...) failed with %d", db_error); + } + + } + + if (db_error != 0) { + ebgw->priv->file_db = NULL; + g_free(filename); + g_free(dirname); + return GNOME_Evolution_Addressbook_OtherError; + } + e_book_backend_db_cache_set_filename (ebgw->priv->file_db, filename); + g_free(filename); + g_free(dirname); g_free (uri); e_uri_free (parsed_uri); - priv->cache = e_book_backend_cache_new (priv->original_uri); - if (enable_debug) { + /*if (enable_debug) { printf ("summary file name = %s\ncache file name = %s \n", priv->summary_file_name, e_file_cache_get_filename (E_FILE_CACHE(priv->cache))); - } + }*/ return GNOME_Evolution_Addressbook_Success; } @@ -3286,7 +3488,7 @@ e_book_backend_groupwise_remove (EBookBa e_data_book_respond_remove (book, opid, GNOME_Evolution_Addressbook_Success); else e_data_book_respond_remove (book, opid, GNOME_Evolution_Addressbook_OtherError); - g_unlink (e_file_cache_get_filename (E_FILE_CACHE (ebgw->priv->cache))); + g_unlink (e_book_backend_db_cache_get_filename(ebgw->priv->file_db)); } static char * @@ -3380,6 +3582,16 @@ e_book_backend_groupwise_dispose (GObjec bgw = E_BOOK_BACKEND_GROUPWISE (object); if (bgw->priv) { + if (bgw->priv->file_db) + bgw->priv->file_db->close (bgw->priv->file_db, 0); + + g_static_mutex_lock(&global_env_lock); + global_env.ref_count--; + if (global_env.ref_count == 0) { + global_env.env->close (global_env.env, 0); + global_env.env = NULL; + } + g_static_mutex_unlock(&global_env_lock); if (bgw->priv->uri) { g_free (bgw->priv->uri); bgw->priv->uri = NULL; @@ -3406,9 +3618,6 @@ e_book_backend_groupwise_dispose (GObjec g_free (bgw->priv->summary_file_name); bgw->priv->summary_file_name = NULL; } - if (bgw->priv->cache) { - g_object_unref (bgw->priv->cache); - } if (bgw->priv->summary) { e_book_backend_summary_save(bgw->priv->summary); g_object_unref (bgw->priv->summary); @@ -3422,7 +3631,7 @@ e_book_backend_groupwise_dispose (GObjec bgw->priv->cache_timeout = 0; } if (bgw->priv->update_mutex) - g_mutex_free(bgw->priv->update_mutex); + g_mutex_free (bgw->priv->update_mutex); g_free (bgw->priv); bgw->priv = NULL; @@ -3477,14 +3686,12 @@ e_book_backend_groupwise_init (EBookBack priv->is_summary_ready = FALSE; priv->marked_for_offline = FALSE; priv->use_ssl = NULL; - priv->cache=NULL; - priv->cnc = NULL; + priv->cnc = NULL; priv->original_uri = NULL; priv->cache_timeout = 0; priv->update_mutex = g_mutex_new(); priv->reserved1 = NULL; priv->reserved2 = NULL; - priv->reserved3 = NULL; backend->priv = priv; if (g_getenv ("GROUPWISE_DEBUG")) { Index: addressbook/backends/groupwise/Makefile.am =================================================================== RCS file: /cvs/gnome/evolution-data-server/addressbook/backends/groupwise/Makefile.am,v retrieving revision 1.9 diff -u -p -r1.9 Makefile.am --- addressbook/backends/groupwise/Makefile.am 22 Jun 2005 12:34:21 -0000 1.9 +++ addressbook/backends/groupwise/Makefile.am 11 Apr 2006 05:14:12 -0000 @@ -5,6 +5,7 @@ INCLUDES = \ -I$(top_srcdir)/addressbook \ -I$(top_builddir)/addressbook \ -I$(top_srcdir)/servers/groupwise \ + -I$(top_srcdir)/libdb/dist \ $(EVOLUTION_ADDRESSBOOK_CFLAGS) \ $(SOUP_CFLAGS) extension_LTLIBRARIES = libebookbackendgroupwise.la @@ -19,6 +20,7 @@ libebookbackendgroupwise_la_LIBADD = $(top_builddir)/addressbook/libebook/libebook-1.2.la \ $(top_builddir)/addressbook/libedata-book/libedata-book-1.2.la \ $(top_builddir)/libedataserver/libedataserver-1.2.la \ + $(top_builddir)/libdb/dist/libdb-4.1.la \ $(EVOLUTION_ADDRESSBOOK_LIBS) \ $(SOUP_LIBS) --- /dev/null 2006-04-11 14:30:05.384262500 +0530 +++ addressbook/libedata-book/e-book-backend-db-cache.c 2006-04-05 20:04:23.000000000 +0530 @@ -0,0 +1,416 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ +/* A class to cache address book conents on local file system + * + * Copyright (C) 2004 Novell, Inc. + * + * Authors: Devashish Sharma <sdevashish@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., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <string.h> +#include "e-book-backend-db-cache.h" +#include "e-book-backend.h" +#include "e-book-backend-sexp.h" + +void +string_to_dbt(const char *str, DBT *dbt) +{ + memset(dbt, 0, sizeof(dbt)); + dbt->data = (void *)str; + dbt->size = strlen(str) + 1; + dbt->flags = DB_DBT_USERMEM; +} + +static char * +get_filename_from_uri (const char *uri) +{ + char *mangled_uri, *filename; + int i; + + /* mangle the URI to not contain invalid characters */ + mangled_uri = g_strdup (uri); + for (i = 0; i < strlen (mangled_uri); i++) { + switch (mangled_uri[i]) { + case ':' : + case '/' : + mangled_uri[i] = '_'; + } + } + + /* generate the file name */ + filename = g_build_filename (g_get_home_dir (), ".evolution/cache/addressbook", + mangled_uri, "cache.db", NULL); + + /* free memory */ + g_free (mangled_uri); + + return filename; +} + +/** + * e_book_backend_db_cache_set_filename: + * @db: DB Handle + * @filename: filename to be set + * + * Set the filename for db cacahe file. + **/ + +void +e_book_backend_db_cache_set_filename(DB *db, const char *filename) +{ + DBT uid_dbt, vcard_dbt; + int db_error; + + string_to_dbt ("filename", &uid_dbt); + string_to_dbt (filename, &vcard_dbt); + + db_error = db->put (db, NULL, &uid_dbt, &vcard_dbt, 0); + if (db_error != 0) { + g_warning ("db->put failed with %d", db_error); + } + +} + +/** + * e_book_backend_db_cache_get_filename: + * @db: DB Handle + * + * Get the filename for db cacahe file. + **/ + +char * +e_book_backend_db_cache_get_filename(DB *db) +{ + DBT uid_dbt, vcard_dbt; + int db_error; + char *filename; + + string_to_dbt ("filename", &uid_dbt); + memset (&vcard_dbt, 0 , sizeof(vcard_dbt)); + vcard_dbt.flags = DB_DBT_MALLOC; + + db_error = db->get (db, NULL, &uid_dbt, &vcard_dbt, 0); + if (db_error != 0) { + g_warning ("db-<get failed with %d", db_error); + return NULL; + } + else { + filename = g_strdup (vcard_dbt.data); + g_free (vcard_dbt.data); + return filename; + } +} + +/** + * e_book_backend_db_cache_get_contact: + * @db: DB Handle + * @uid: a unique contact ID + * + * Get a cached contact. Note that the returned #EContact will be + * newly created, and must be unreffed by the caller when no longer + * needed. + * + * Return value: A cached #EContact, or %NULL if @uid is not cached. + **/ +EContact * +e_book_backend_db_cache_get_contact (DB *db, const char *uid) +{ + DBT uid_dbt, vcard_dbt; + int db_error; + const char *vcard_str; + + g_return_val_if_fail (uid != NULL, NULL); + + string_to_dbt (uid, &uid_dbt); + memset (&vcard_dbt, 0 , sizeof(vcard_dbt)); + vcard_dbt.flags = DB_DBT_MALLOC; + + db_error = db->get (db, NULL, &uid_dbt, &vcard_dbt,0); + if (db_error != 0) { + g_warning ("db->get failed with %d", db_error); + return NULL; + } + + vcard_str = g_strdup (vcard_dbt.data); + g_free (vcard_dbt.data); + + return e_contact_new_from_vcard (vcard_str); +} + +/** + * e_book_backend_db_cache_add_contact: + * @db: DB Handle + * @contact: an #EContact + * + * Adds @contact to @cache. + * + * Return value: %TRUE if the contact was cached successfully, %FALSE otherwise. + **/ +gboolean +e_book_backend_db_cache_add_contact (DB *db, + EContact *contact) +{ + DBT uid_dbt, vcard_dbt; + int db_error; + char *vcard_str; + const char *uid; + + uid = e_contact_get_const (contact, E_CONTACT_UID); + if (!uid) { + printf ("no uid\n"); + printf("name:%s, email:%s\n", e_contact_get (contact, E_CONTACT_GIVEN_NAME), e_contact_get (contact, E_CONTACT_EMAIL_1)); + return NULL; + } + string_to_dbt (uid, &uid_dbt); + + vcard_str = e_vcard_to_string (E_VCARD(contact), EVC_FORMAT_VCARD_30); + string_to_dbt (vcard_str, &vcard_dbt); + + //db_error = db->del (db, NULL, &uid_dbt, 0); + db_error = db->put (db, NULL, &uid_dbt, &vcard_dbt, 0); + + g_free (vcard_str); + + if (db_error != 0) { + g_warning ("db->put failed with %d", db_error); + return FALSE; + } + else + return TRUE; +} + +/** + * e_book_backend_db_cache_remove_contact: + * @db: DB Handle + * @uid: a unique contact ID + * + * Removes the contact identified by @uid from @cache. + * + * Return value: %TRUE if the contact was found and removed, %FALSE otherwise. + **/ +gboolean +e_book_backend_db_cache_remove_contact (DB *db, + const char *uid) + +{ + DBT uid_dbt; + int db_error; + + g_return_val_if_fail (uid != NULL, FALSE); + + string_to_dbt (uid, &uid_dbt); + db_error = db->del (db, NULL, &uid_dbt, 0); + + if (db_error != 0) { + g_warning ("db->del failed with %d", db_error); + return FALSE; + } + else + return TRUE; + +} + +/** + * e_book_backend_db_cache_check_contact: + * @db: DB Handle + * @uid: a unique contact ID + * + * Checks if the contact identified by @uid exists in @cache. + * + * Return value: %TRUE if the cache contains the contact, %FALSE otherwise. + **/ +gboolean +e_book_backend_db_cache_check_contact (DB *db, const char *uid) +{ + DBT uid_dbt, vcard_dbt; + int db_error; + + g_return_val_if_fail (uid != NULL, FALSE); + + string_to_dbt (uid, &uid_dbt); + memset (&vcard_dbt, 0 , sizeof(vcard_dbt)); + vcard_dbt.flags = DB_DBT_MALLOC; + + db_error = db->get (db, NULL, &uid_dbt, &vcard_dbt,0); + if (db_error != 0) + return FALSE; + else { + free (vcard_dbt.data); + return TRUE; + } +} + +/** + * e_book_backend_db_cache_get_contacts: + * @db: DB Handle + * @query: an s-expression + * + * Returns a list of #EContact elements from @cache matching @query. + * When done with the list, the caller must unref the contacts and + * free the list. + * + * Return value: A #GList of pointers to #EContact. + **/ +GList * +e_book_backend_db_cache_get_contacts (DB *db, const char *query) +{ + DBC *dbc; + DBT uid_dbt, vcard_dbt; + int db_error; + GList *list = NULL; + EBookBackendSExp *sexp = NULL; + EContact *contact; + + if (query) { + sexp = e_book_backend_sexp_new (query); + if (!sexp) + return NULL; + } + + db_error = db->cursor (db, NULL, &dbc, 0); + if (db_error != 0) { + g_warning ("db->cursor failed with %d", db_error); + return NULL; + } + + memset(&vcard_dbt, 0 , sizeof(vcard_dbt)); + memset(&uid_dbt, 0, sizeof(uid_dbt)); + db_error = dbc->c_get(dbc, &uid_dbt, &vcard_dbt, DB_FIRST); + + while(db_error == 0) { + if (vcard_dbt.data && !strncmp (vcard_dbt.data, "BEGIN:VCARD", 11)) + if (e_book_backend_sexp_match_vcard(sexp, vcard_dbt.data)) { + contact = e_contact_new_from_vcard (vcard_dbt.data); + list = g_list_append (list, contact); + } + db_error = dbc->c_get (dbc, &uid_dbt, &vcard_dbt, DB_NEXT); + } + + db_error = dbc->c_close (dbc); + if(db_error != 0) + g_warning ("db->c_close failed with %d", db_error); + + if (sexp) + g_object_unref (sexp); + + return list; +} + +/** + * e_book_backend_db_cache_search: + * @backend: an #EBookBackend + * @query: an s-expression + * + * Returns an array of pointers to unique contact ID strings for contacts + * in @cache matching @query. When done with the array, the caller must + * free the ID strings and the array. + * + * Return value: A #GPtrArray of pointers to contact ID strings. + **/ +GPtrArray * +e_book_backend_db_cache_search (DB *db, const char *query) +{ + GList *matching_contacts, *temp; + GPtrArray *ptr_array; + + matching_contacts = e_book_backend_db_cache_get_contacts (db, query); + ptr_array = g_ptr_array_new (); + + temp = matching_contacts; + for (; matching_contacts != NULL; matching_contacts = g_list_next (matching_contacts)) { + g_ptr_array_add (ptr_array, e_contact_get (matching_contacts->data, E_CONTACT_UID)); + g_object_unref (matching_contacts->data); + } + g_list_free (temp); + + return ptr_array; +} + +/** + * e_book_backend_db_cache_exists: + * @uri: URI for the cache + * + * Checks if an #EBookBackendCache exists at @uri. + * + * Return value: %TRUE if cache exists, %FALSE if not. + **/ +gboolean +e_book_backend_db_cache_exists (const char *uri) +{ + char *file_name; + gboolean exists = FALSE; + file_name = get_filename_from_uri (uri); + + if (file_name && g_file_test (file_name, G_FILE_TEST_EXISTS)) { + exists = TRUE; + g_free (file_name); + } + + return exists; +} + +/** + * e_book_backend_db_cache_set_populated: + * @backend: an #EBookBackend + * + * Flags @cache as being populated - that is, it is up-to-date on the + * contents of the book it's caching. + **/ +void +e_book_backend_db_cache_set_populated (DB *db) +{ + DBT uid_dbt, vcard_dbt; + int db_error; + + string_to_dbt ("populated", &uid_dbt); + string_to_dbt ("TRUE", &vcard_dbt); + db_error = db->put (db, NULL, &uid_dbt, &vcard_dbt, 0); + if (db_error != 0) { + g_warning ("db->put failed with %d", db_error); + } + +} + +/** + * e_book_backend_cache_is_populated: + * @db: DB Handle + * + * Checks if @cache is populated. + * + * Return value: %TRUE if @cache is populated, %FALSE otherwise. + **/ +gboolean +e_book_backend_db_cache_is_populated (DB *db) +{ + DBT uid_dbt, vcard_dbt; + int db_error; + + string_to_dbt ("populated", &uid_dbt); + memset(&vcard_dbt, 0, sizeof(vcard_dbt)); + vcard_dbt.flags = DB_DBT_MALLOC; + + db_error = db->get (db, NULL, &uid_dbt, &vcard_dbt, 0); + if (db_error != 0){ + return FALSE; + } + else { + free(vcard_dbt.data); + return TRUE; + } +} --- /dev/null 2006-04-11 14:30:05.384262500 +0530 +++ addressbook/libedata-book/e-book-backend-db-cache.h 2006-04-11 10:49:48.000000000 +0530 @@ -0,0 +1,49 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ +/* + * + * Copyright (C) 2004 Novell, Inc. + * + * Authors: Devashish Sharma <sdevashish@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., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifndef E_BOOK_BACKEND_DB_CACHE_H +#define E_BOOK_BACKEND_DB_CACHE_H + +#include <libebook/e-contact.h> +#include "db.h" + +EContact* e_book_backend_db_cache_get_contact (DB *db, const char *uid); +void string_to_dbt(const char *str, DBT *dbt); +char *e_book_backend_db_cache_get_filename(DB *db); +void e_book_backend_db_cache_set_filename(DB *db, const char *filename); +gboolean e_book_backend_db_cache_add_contact (DB *db, + EContact *contact); +gboolean e_book_backend_db_cache_remove_contact (DB *db, + const char *uid); +gboolean e_book_backend_db_cache_check_contact (DB *db, const char *uid); +GList* e_book_backend_db_cache_get_contacts (DB *db, const char *query); +gboolean e_book_backend_db_cache_exists (const char *uri); +void e_book_backend_db_cache_set_populated (DB *db); +gboolean e_book_backend_db_cache_is_populated (DB *db); +GPtrArray* e_book_backend_db_cache_search (DB *db, const char *query); + + + + +G_END_DECLS + +#endif + Index: addressbook/libedata-book/Makefile.am =================================================================== RCS file: /cvs/gnome/evolution-data-server/addressbook/libedata-book/Makefile.am,v retrieving revision 1.14 diff -u -p -r1.14 Makefile.am --- addressbook/libedata-book/Makefile.am 22 Jun 2005 12:34:23 -0000 1.14 +++ addressbook/libedata-book/Makefile.am 11 Apr 2006 05:22:41 -0000 @@ -4,6 +4,7 @@ INCLUDES = \ -I$(top_builddir) \ -I$(top_srcdir)/addressbook \ -I$(top_builddir)/addressbook \ + -I$(top_srcdir)/libdb/dist \ $(EVOLUTION_ADDRESSBOOK_CFLAGS) # The corba stubs and skels @@ -38,6 +39,7 @@ libedata_book_1_2_la_SOURCES = \ e-book-backend-sexp.c \ e-book-backend-summary.c \ e-book-backend-cache.c \ + e-book-backend-db-cache.c \ e-book-backend-sync.c \ e-book-backend.c \ e-data-book-factory.c \ @@ -48,7 +50,8 @@ libedata_book_1_2_la_SOURCES = \ libedata_book_1_2_la_LIBADD = \ $(EVOLUTION_ADDRESSBOOK_LIBS) \ $(top_builddir)/addressbook/libebook/libebook-1.2.la \ - $(top_builddir)/libedataserver/libedataserver-1.2.la + $(top_builddir)/libedataserver/libedataserver-1.2.la \ + $(top_builddir)/libdb/dist/libdb-4.1.la libedata_book_1_2_la_LDFLAGS = \ -version-info $(LIBEDATABOOK_CURRENT):$(LIBEDATABOOK_REVISION):$(LIBEDATABOOK_AGE) $(NO_UNDEFINED) @@ -66,7 +69,8 @@ libedata_bookinclude_HEADERS = \ e-data-book-types.h \ e-data-book-view.h \ e-data-book.h \ - e-book-backend-cache.h + e-book-backend-cache.h \ + e-book-backend-db-cache.h %-$(API_VERSION).pc: %.pc cp $< $@
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor