evolution-data-server/bnc-159934-eds-CPU-spikes.patch

1609 lines
53 KiB
Diff

--- ../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 $< $@