[evolution-couchdb] Add a cache for contacts
- From: Rodrigo Moya <rodrigo src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [evolution-couchdb] Add a cache for contacts
- Date: Wed, 21 Apr 2010 14:10:25 +0000 (UTC)
commit f975ee23c372bfb8d78fba19b8c7123649d1b2b8
Author: Rodrigo Moya <rodrigo gnome-db org>
Date: Wed Apr 21 16:10:39 2010 +0200
Add a cache for contacts
addressbook/e-book-backend-couchdb.c | 209 +++++++++++++++++-----------------
addressbook/e-book-backend-couchdb.h | 2 +
2 files changed, 107 insertions(+), 104 deletions(-)
---
diff --git a/addressbook/e-book-backend-couchdb.c b/addressbook/e-book-backend-couchdb.c
index 5861462..b8718f9 100644
--- a/addressbook/e-book-backend-couchdb.c
+++ b/addressbook/e-book-backend-couchdb.c
@@ -46,8 +46,8 @@ get_current_time (gchar time_string[100])
strftime (time_string, 100, "%Y-%m-%dT%H:%M:%SZ", tm);
}
-static char *
-vcard_from_couch_document (CouchdbDocument *document)
+static EContact *
+contact_from_couch_document (CouchdbDocument *document)
{
EContact *contact;
char *str;
@@ -480,12 +480,7 @@ vcard_from_couch_document (CouchdbDocument *document)
e_contact_set (contact, E_CONTACT_REV, time_string);
}
- /* convert the contact to a VCARD string to be returned */
- str = e_vcard_to_string (E_VCARD (contact), EVC_FORMAT_VCARD_30);
-
- g_object_unref (G_OBJECT (contact));
-
- return str;
+ return contact;
}
static CouchdbStructField *
@@ -945,24 +940,22 @@ couch_document_from_contact (EBookBackendCouchDB *couchdb_backend, EContact *con
static void
document_updated_cb (CouchdbSession *couchdb, const char *dbname, CouchdbDocument *document, gpointer user_data)
{
- char *vcard;
EContact *contact;
EBookBackendCouchDB *couchdb_backend = E_BOOK_BACKEND_COUCHDB (user_data);
if (g_strcmp0 (dbname, couchdb_backend->dbname) != 0)
return;
- vcard = vcard_from_couch_document (document);
- if (!vcard)
+ contact = contact_from_couch_document (document);
+ if (!contact)
return;
- contact = e_contact_new_from_vcard (vcard);
- if (contact != NULL) {
- e_book_backend_notify_update (E_BOOK_BACKEND (couchdb_backend), contact);
- g_object_unref (G_OBJECT (contact));
- }
+ e_book_backend_notify_update (E_BOOK_BACKEND (couchdb_backend), contact);
+
+ /* Add the contact to the cache */
+ e_book_backend_cache_add_contact (couchdb_backend->cache, contact);
- g_free (vcard);
+ g_object_unref (G_OBJECT (contact));
}
static void
@@ -974,6 +967,9 @@ document_deleted_cb (CouchdbSession *couchdb, const char *dbname, const char *do
return;
e_book_backend_notify_remove (E_BOOK_BACKEND (couchdb_backend), docid);
+
+ /* Remove the contact from the cache */
+ e_book_backend_cache_remove_contact (couchdb_backend->cache, docid);
}
static GNOME_Evolution_Addressbook_CallStatus
@@ -985,14 +981,17 @@ e_book_backend_couchdb_load_source (EBookBackend *backend,
const gchar *property;
CouchdbDatabaseInfo *db_info;
GError *error = NULL;
+ GSList *doc_list, *sl;
EBookBackendCouchDB *couchdb_backend = E_BOOK_BACKEND_COUCHDB (backend);
g_return_val_if_fail (E_IS_BOOK_BACKEND_COUCHDB (couchdb_backend), GNOME_Evolution_Addressbook_OtherError);
- if (couchdb_backend->couchdb)
- g_object_unref (couchdb_backend->couchdb);
- if (couchdb_backend->dbname)
+ if (couchdb_backend->couchdb != NULL)
+ g_object_unref (G_OBJECT (couchdb_backend->couchdb));
+ if (couchdb_backend->dbname != NULL)
g_free (couchdb_backend->dbname);
+ if (couchdb_backend->cache != NULL)
+ g_object_unref (G_OBJECT (couchdb_backend->cache));
/* create CouchDB main object */
couchdb_backend->dbname = g_strdup ("contacts");
@@ -1014,7 +1013,7 @@ e_book_backend_couchdb_load_source (EBookBackend *backend,
if (! (couchdb_backend->couchdb = couchdb_session_new (uri))) {
g_free (uri);
- return GNOME_Evolution_Addressbook_OtherError;
+ return GNOME_Evolution_Addressbook_NoSuchBook;
}
g_free (uri);
@@ -1047,8 +1046,41 @@ e_book_backend_couchdb_load_source (EBookBackend *backend,
} else
couchdb_database_info_unref (db_info);
- e_book_backend_set_is_loaded (backend, TRUE);
- e_book_backend_set_is_writable (backend, TRUE);
+ /* Create cache */
+ uri = e_source_get_uri (source);
+ couchdb_backend->cache = e_book_backend_cache_new ((const gchar *) uri);
+ g_free (uri);
+
+ /* Populate the cache */
+ e_book_backend_cache_clean (couchdb_backend->cache);
+ error = NULL;
+ doc_list = couchdb_session_list_documents (couchdb_backend->couchdb,
+ couchdb_backend->dbname,
+ &error);
+ for (sl = doc_list; sl != NULL; sl = sl->next) {
+ EContact *contact;
+ CouchdbDocument *document;
+ CouchdbDocumentInfo *doc_info = (CouchdbDocumentInfo *) sl->data;
+
+ /* Retrieve this document */
+ error = NULL;
+ document = couchdb_document_get (couchdb_backend->couchdb,
+ couchdb_backend->dbname,
+ couchdb_document_info_get_docid (doc_info),
+ &error);
+ if (!document)
+ continue;
+
+ contact = contact_from_couch_document (document);
+ if (contact != NULL) {
+ e_book_backend_cache_add_contact (couchdb_backend->cache, contact);
+ g_object_unref (G_OBJECT (contact));
+ }
+
+ g_object_unref (G_OBJECT (document));
+ }
+
+ couchdb_session_free_document_list (doc_list);
/* Listen for changes on database */
g_signal_connect (G_OBJECT (couchdb_backend->couchdb), "document_created",
@@ -1059,6 +1091,9 @@ e_book_backend_couchdb_load_source (EBookBackend *backend,
G_CALLBACK (document_deleted_cb), couchdb_backend);
couchdb_session_listen_for_changes (couchdb_backend->couchdb, couchdb_backend->dbname);
+ e_book_backend_set_is_loaded (backend, TRUE);
+ e_book_backend_set_is_writable (backend, TRUE);
+
return GNOME_Evolution_Addressbook_Success;
}
@@ -1067,6 +1102,12 @@ e_book_backend_couchdb_remove (EBookBackend *backend, EDataBook *book, guint32 o
{
EBookBackendCouchDB *couchdb_backend = E_BOOK_BACKEND_COUCHDB (backend);
+ /* Remove the cache */
+ if (couchdb_backend->cache != NULL) {
+ g_object_unref (G_OBJECT (couchdb_backend->cache));
+ couchdb_backend->cache = NULL;
+ }
+
/* We don't remove data from CouchDB, since it would affect other apps,
so just report success */
e_data_book_respond_remove (book, opid, GNOME_Evolution_Addressbook_Success);
@@ -1085,13 +1126,12 @@ put_document (EBookBackendCouchDB *couchdb_backend, CouchdbDocument *document)
if (couchdb_document_put (document, couchdb_backend->dbname, &error)) {
EContact *new_contact;
- char *vcard_str;
/* couchdb_document_put sets the ID for new documents, so need to send that back */
- vcard_str = vcard_from_couch_document (document);
- new_contact = e_contact_new_from_vcard (vcard_str);
+ new_contact = contact_from_couch_document (document);
- g_free (vcard_str);
+ /* Add the new contact to the cache */
+ e_book_backend_cache_add_contact (couchdb_backend->cache, new_contact);
return new_contact;
} else {
@@ -1178,9 +1218,10 @@ e_book_backend_couchdb_remove_contacts (EBookBackend *backend,
desktopcouch_document_set_application_annotations (document, app_annotations);
/* Now put the new revision of the document */
- if (couchdb_document_put (document, couchdb_backend->dbname, &error))
+ if (couchdb_document_put (document, couchdb_backend->dbname, &error)) {
deleted_ids = g_list_append (deleted_ids, (gpointer) uid);
- else {
+ e_book_backend_cache_remove_contact (couchdb_backend->cache, uid);
+ } else {
if (error != NULL) {
g_debug ("Error deleting document: %s", error->message);
g_error_free (error);
@@ -1193,9 +1234,10 @@ e_book_backend_couchdb_remove_contacts (EBookBackend *backend,
couchdb_struct_field_unref (u1_annotations);
couchdb_struct_field_unref (private_annotations);
} else {
- if (couchdb_document_delete (document, &error))
+ if (couchdb_document_delete (document, &error)) {
deleted_ids = g_list_append (deleted_ids, (gpointer) uid);
- else {
+ e_book_backend_cache_remove_contact (couchdb_backend->cache, uid);
+ } else {
if (error != NULL) {
g_debug ("Error deleting document: %s", error->message);
g_error_free (error);
@@ -1263,18 +1305,15 @@ e_book_backend_couchdb_get_contact (EBookBackend *backend,
const char *id)
{
GError *error = NULL;
- CouchdbDocument *document;
+ EContact *contact;
EBookBackendCouchDB *couchdb_backend = E_BOOK_BACKEND_COUCHDB (backend);
- document = couchdb_document_get (couchdb_backend->couchdb,
- couchdb_backend->dbname,
- id,
- &error);
- if (document) {
- char *vcard = vcard_from_couch_document (document);
+ contact = e_book_backend_cache_get_contact (couchdb_backend->cache, id);
+ if (contact != NULL) {
+ char *vcard = e_vcard_to_string (E_VCARD (contact), EVC_FORMAT_VCARD_30);
- g_object_unref (G_OBJECT (document));
- if (vcard) {
+ g_object_unref (G_OBJECT (contact));
+ if (vcard != NULL) {
e_data_book_respond_get_contact (book,
opid,
GNOME_Evolution_Addressbook_Success,
@@ -1292,51 +1331,24 @@ e_book_backend_couchdb_get_contact_list (EBookBackend *backend,
EDataBook *book,
guint32 opid, const char *query)
{
- GSList *doc_list, *sl;
- GList *contacts = NULL;
+ GList *doc_list, *contacts = NULL;
GError *error = NULL;
- EBookBackendSExp *card_sexp = NULL;
EBookBackendCouchDB *couchdb_backend = E_BOOK_BACKEND_COUCHDB (backend);
- card_sexp = e_book_backend_sexp_new (query);
- if (!card_sexp) {
- /* XXX this needs to be an invalid query error of some sort*/
- e_data_book_respond_get_contact_list (book, opid, GNOME_Evolution_Addressbook_OtherError, NULL);
- return;
- }
-
- /* Get the list of documents from CouchDB */
- doc_list = couchdb_session_list_documents (couchdb_backend->couchdb,
- couchdb_backend->dbname,
- &error);
- for (sl = doc_list; sl != NULL; sl = sl->next) {
+ /* Get the list of documents from cache */
+ doc_list = e_book_backend_cache_get_contacts (couchdb_backend->cache, query);
+ while (doc_list != NULL) {
char *vcard;
- CouchdbDocument *document;
- CouchdbDocumentInfo *doc_info = (CouchdbDocumentInfo *) sl->data;
+ EContact *contact = E_CONTACT (doc_list->data);
- /* Retrieve this document */
- error = NULL;
- document = couchdb_document_get (couchdb_backend->couchdb,
- couchdb_backend->dbname,
- couchdb_document_info_get_docid (doc_info),
- &error);
- if (!document)
- continue;
+ vcard = e_vcard_to_string (E_VCARD (contact), EVC_FORMAT_VCARD_30);
+ if (vcard != NULL)
+ contacts = g_list_prepend (contacts, vcard);
- vcard = vcard_from_couch_document (document);
- if (vcard != NULL) {
- if (e_book_backend_sexp_match_vcard (card_sexp, vcard))
- contacts = g_list_prepend (contacts, vcard);
- else
- g_free (vcard);
- }
-
- g_object_unref (G_OBJECT (document));
+ doc_list = g_list_remove (doc_list, contact);
+ g_object_unref (G_OBJECT (contact));
}
- g_object_unref (card_sexp);
- couchdb_session_free_document_list (doc_list);
-
e_data_book_respond_get_contact_list (book, opid, GNOME_Evolution_Addressbook_Success, contacts);
}
@@ -1344,45 +1356,28 @@ static void
e_book_backend_couchdb_start_book_view (EBookBackend *backend,
EDataBookView *book_view)
{
- EBookBackendSExp *sexp;
- GError *error;
- GSList *doc_list, *sl;
+ GList *doc_list;
EBookBackendCouchDB *couchdb_backend = E_BOOK_BACKEND_COUCHDB (backend);
e_book_backend_add_book_view (backend, book_view);
- sexp = e_data_book_view_get_card_sexp (book_view);
- /* Get the list of documents from CouchDB */
- doc_list = couchdb_session_list_documents (couchdb_backend->couchdb,
- couchdb_backend->dbname,
- &error);
- for (sl = doc_list; sl != NULL; sl = sl->next) {
- CouchdbDocument *document;
+ /* Get the list of documents from cache */
+ doc_list = e_book_backend_cache_get_contacts (couchdb_backend->cache,
+ e_data_book_view_get_card_query (book_view));
+ while (doc_list != NULL) {
char *vcard;
- CouchdbDocumentInfo *doc_info = (CouchdbDocumentInfo *) sl->data;
+ EContact *contact = E_CONTACT (doc_list->data);
- /* Retrieve this document */
- error = NULL;
- document = couchdb_document_get (couchdb_backend->couchdb,
- couchdb_backend->dbname,
- couchdb_document_info_get_docid (doc_info),
- &error);
- if (!document)
- continue;
-
- vcard = vcard_from_couch_document (document);
+ vcard = e_vcard_to_string (E_VCARD (contact), EVC_FORMAT_VCARD_30);
if (!vcard)
continue;
- if (e_book_backend_sexp_match_vcard (sexp, (const gchar *) vcard))
- e_data_book_view_notify_update_vcard (book_view, vcard);
- else
- g_free (vcard);
+ e_data_book_view_notify_update_vcard (book_view, vcard);
- g_object_unref (G_OBJECT (document));
+ doc_list = g_list_remove (doc_list, contact);
+ g_object_unref (G_OBJECT (contact));
}
- couchdb_session_free_document_list (doc_list);
e_data_book_view_notify_complete (book_view, GNOME_Evolution_Addressbook_Success);
}
@@ -1555,6 +1550,11 @@ e_book_backend_couchdb_dispose (GObject *object)
couchdb_backend->couchdb = NULL;
}
+ if (couchdb_backend->cache != NULL) {
+ g_object_unref (G_OBJECT (couchdb_backend->cache));
+ couchdb_backend->cache = NULL;
+ }
+
if (couchdb_backend->dbname) {
g_free (couchdb_backend->dbname);
couchdb_backend->dbname = NULL;
@@ -1596,4 +1596,5 @@ e_book_backend_couchdb_init (EBookBackendCouchDB *backend)
{
backend->couchdb = NULL;
backend->dbname = NULL;
+ backend->cache = NULL;
}
diff --git a/addressbook/e-book-backend-couchdb.h b/addressbook/e-book-backend-couchdb.h
index 89989e3..4e1966b 100644
--- a/addressbook/e-book-backend-couchdb.h
+++ b/addressbook/e-book-backend-couchdb.h
@@ -26,6 +26,7 @@
#include <couchdb-glib.h>
#include <desktopcouch-glib.h>
#include <libedata-book/e-book-backend.h>
+#include <libedata-book/e-book-backend-cache.h>
#define E_TYPE_BOOK_BACKEND_COUCHDB (e_book_backend_couchdb_get_type ())
#define E_BOOK_BACKEND_COUCHDB(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), E_TYPE_BOOK_BACKEND_COUCHDB, EBookBackendCouchDB))
@@ -38,6 +39,7 @@ typedef struct {
EBookBackend parent_object;
CouchdbSession *couchdb;
+ EBookBackendCache *cache;
char *dbname;
gboolean using_desktopcouch;
} EBookBackendCouchDB;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]