diff options
Diffstat (limited to 'addressbook/backend/pas/pas-backend-file.c')
-rw-r--r-- | addressbook/backend/pas/pas-backend-file.c | 288 |
1 files changed, 140 insertions, 148 deletions
diff --git a/addressbook/backend/pas/pas-backend-file.c b/addressbook/backend/pas/pas-backend-file.c index 06923d7b08..923c7e907d 100644 --- a/addressbook/backend/pas/pas-backend-file.c +++ b/addressbook/backend/pas/pas-backend-file.c @@ -90,8 +90,9 @@ build_summary (PASBackendFilePrivate *bfpriv) /* don't include the version in the list of cards */ if (id_dbt.size != strlen(PAS_BACKEND_FILE_VERSION_NAME) + 1 || strcmp (id_dbt.data, PAS_BACKEND_FILE_VERSION_NAME)) { - - pas_backend_summary_add_contact (bfpriv->summary, vcard_dbt.data); + EContact *contact = e_contact_new_from_vcard (vcard_dbt.data); + pas_backend_summary_add_contact (bfpriv->summary, contact); + g_object_unref (contact); } db_error = dbc->c_get(dbc, &id_dbt, &vcard_dbt, DB_NEXT); @@ -99,52 +100,6 @@ build_summary (PASBackendFilePrivate *bfpriv) } } -static void -do_summary_query (PASBackendFile *bf, - PASBookView *view) -{ - GPtrArray *ids = pas_backend_summary_search (bf->priv->summary, pas_book_view_get_card_query (view)); - int db_error = 0; - DB *db = bf->priv->file_db; - DBT id_dbt, vcard_dbt; - int i; - - for (i = 0; i < ids->len; i ++) { - char *id = g_ptr_array_index (ids, i); - -#if SUMMARY_STORES_ENOUGH_INFO - /* this is disabled for the time being because lists - can have more than 3 email addresses and the - summary only stores 3. */ - - if (completion_search) { - vcard = pas_backend_summary_get_summary_vcard (bf->priv->summary, - id); - if (vcard) { - EContact *contact = e_contact_new_from_vcard (vcard_dbt.data); - pas_book_view_notify_update (view, contact); - g_object_unref (contact); - } - } - else { -#endif - string_to_dbt (id, &id_dbt); - memset (&vcard_dbt, 0, sizeof (vcard_dbt)); - - db_error = db->get (db, NULL, &id_dbt, &vcard_dbt, 0); - - if (db_error == 0) - pas_book_view_notify_update (view, vcard_dbt.data); -#if SUMMARY_STORES_ENOUGH_INFO - } -#endif - } - - g_ptr_array_free (ids, TRUE); - - pas_book_view_notify_complete (view, GNOME_Evolution_Addressbook_Success); -} - static char * pas_backend_file_create_unique_id (void) { @@ -155,105 +110,6 @@ pas_backend_file_create_unique_id (void) return g_strdup_printf (PAS_ID_PREFIX "%08lX%08X", time(NULL), c++); } -typedef struct { - PASBackendFile *bf; - PASBook *book; - PASBookView *view; - DBC *dbc; - - gboolean done_first; -} FileBackendSearchClosure; - -static void -free_search_closure (FileBackendSearchClosure *closure) -{ - g_free (closure); -} - -static gboolean -pas_backend_file_search_timeout (gpointer data) -{ - FileBackendSearchClosure *closure = data; - int db_error = 0; - DBT id_dbt, vcard_dbt; - int file_version_name_len; - DBC *dbc = closure->dbc; - - file_version_name_len = strlen (PAS_BACKEND_FILE_VERSION_NAME); - - memset (&id_dbt, 0, sizeof (id_dbt)); - memset (&vcard_dbt, 0, sizeof (vcard_dbt)); - - if (closure->done_first) { - db_error = dbc->c_get(dbc, &id_dbt, &vcard_dbt, DB_NEXT); - } - else { - db_error = dbc->c_get(dbc, &id_dbt, &vcard_dbt, DB_FIRST); - closure->done_first = TRUE; - } - - while (db_error == 0) { - - /* don't include the version in the list of cards */ - if (strcmp (id_dbt.data, PAS_BACKEND_FILE_VERSION_NAME)) { - char *vcard_string = vcard_dbt.data; - EContact *contact = e_contact_new_from_vcard (vcard_string); - - /* notify_update will check if it matches for us */ - pas_book_view_notify_update (closure->view, contact); - g_object_unref (contact); - } - - db_error = dbc->c_get(dbc, &id_dbt, &vcard_dbt, DB_NEXT); - } - - dbc->c_close (dbc); - - if (db_error != DB_NOTFOUND) { - g_warning ("pas_backend_file_search: error building list\n"); - free_search_closure (closure); - } - - pas_book_view_notify_complete (closure->view, GNOME_Evolution_Addressbook_Success); - - free_search_closure (closure); - - return FALSE; -} - - -static void -pas_backend_file_search (PASBackendFile *bf, - PASBookView *book_view) -{ - const char *query = pas_book_view_get_card_query (book_view); - - if ( ! strcmp (query, "(contains \"x-evolution-any-field\" \"\")")) - pas_book_view_notify_status_message (book_view, _("Loading...")); - else - pas_book_view_notify_status_message (book_view, _("Searching...")); - - if (pas_backend_summary_is_summary_query (bf->priv->summary, query)) { - do_summary_query (bf, book_view); - } - else { - FileBackendSearchClosure *closure = g_new0 (FileBackendSearchClosure, 1); - DB *db = bf->priv->file_db; - int db_error; - - closure->view = book_view; - closure->bf = bf; - - db_error = db->cursor (db, NULL, &closure->dbc, 0); - - if (db_error != 0) { - g_warning ("pas_backend_file_search: error building list\n"); - } else { - g_idle_add (pas_backend_file_search_timeout, closure); - } - } -} - static EContact * do_create(PASBackendFile *bf, const char *vcard_req) @@ -509,11 +365,146 @@ pas_backend_file_get_contact_list (PASBackendSync *backend, : GNOME_Evolution_Addressbook_Success; } +typedef struct { + GMutex *mutex; + gboolean stopped; +} FileBackendSearchClosure; + static void pas_backend_file_start_book_view (PASBackend *backend, PASBookView *book_view) { - pas_backend_file_search (PAS_BACKEND_FILE (backend), book_view); + FileBackendSearchClosure *closure = g_new0 (FileBackendSearchClosure, 1); + PASBackendFile *bf = PAS_BACKEND_FILE (backend); + const char *query; + DB *db; + DBT id_dbt, vcard_dbt; + int db_error; + gboolean stopped = FALSE; + + printf ("starting initial population of book view\n"); + + /* ref the book view because it'll be removed and unrefed + when/if it's stopped */ + g_object_ref (book_view); + + db = bf->priv->file_db; + query = pas_book_view_get_card_query (book_view); + + closure->mutex = g_mutex_new(); + closure->stopped = FALSE; + g_object_set_data (G_OBJECT (book_view), "PASBackendFile.BookView::closure", closure); + + if ( ! strcmp (query, "(contains \"x-evolution-any-field\" \"\")")) + pas_book_view_notify_status_message (book_view, _("Loading...")); + else + pas_book_view_notify_status_message (book_view, _("Searching...")); + + if (pas_backend_summary_is_summary_query (bf->priv->summary, query)) { + /* do a summary query */ + GPtrArray *ids = pas_backend_summary_search (bf->priv->summary, pas_book_view_get_card_query (book_view)); + int i; + + for (i = 0; i < ids->len; i ++) { + char *id = g_ptr_array_index (ids, i); + + g_mutex_lock (closure->mutex); + stopped = closure->stopped; + g_mutex_unlock (closure->mutex); + + if (stopped) { + g_mutex_free (closure->mutex); + g_free (closure); + break; + } + + string_to_dbt (id, &id_dbt); + memset (&vcard_dbt, 0, sizeof (vcard_dbt)); + + db_error = db->get (db, NULL, &id_dbt, &vcard_dbt, 0); + + if (db_error == 0) { + EContact *contact = e_contact_new_from_vcard (vcard_dbt.data); + pas_book_view_notify_update (book_view, contact); + g_object_unref (contact); + } + } + + g_ptr_array_free (ids, TRUE); + } + else { + /* iterate over the db and do the query there */ + DBC *dbc; + + memset (&id_dbt, 0, sizeof (id_dbt)); + memset (&vcard_dbt, 0, sizeof (vcard_dbt)); + + db_error = db->cursor (db, NULL, &dbc, 0); + + db_error = dbc->c_get(dbc, &id_dbt, &vcard_dbt, DB_FIRST); + while (db_error == 0) { + + g_mutex_lock (closure->mutex); + stopped = closure->stopped; + g_mutex_unlock (closure->mutex); + + if (stopped) { + g_mutex_free (closure->mutex); + g_free (closure); + break; + } + + /* don't include the version in the list of cards */ + if (strcmp (id_dbt.data, PAS_BACKEND_FILE_VERSION_NAME)) { + char *vcard_string = vcard_dbt.data; + EContact *contact = e_contact_new_from_vcard (vcard_string); + + /* notify_update will check if it matches for us */ + pas_book_view_notify_update (book_view, contact); + g_object_unref (contact); + } + + db_error = dbc->c_get(dbc, &id_dbt, &vcard_dbt, DB_NEXT); + } + + dbc->c_close (dbc); + + if (db_error != DB_NOTFOUND) + g_warning ("pas_backend_file_search: error building list\n"); + + } + + g_mutex_lock (closure->mutex); + stopped = closure->stopped; + g_mutex_unlock (closure->mutex); + if (!stopped) + pas_book_view_notify_complete (book_view, GNOME_Evolution_Addressbook_Success); + + g_mutex_free (closure->mutex); + g_free (closure); + + g_object_set_data (G_OBJECT (book_view), "PASBackendFile.BookView::closure", NULL); + + /* unref the */ + g_object_unref (book_view); + + printf ("finished initial population of book view\n"); +} + +static void +pas_backend_file_stop_book_view (PASBackend *backend, + PASBookView *book_view) +{ + FileBackendSearchClosure *closure = g_object_get_data (G_OBJECT (book_view), "PASBackendFile.BookView::closure"); + if (!closure) { + printf ("book view is already done populating\n"); + return; + } + + printf ("stopping book view!\n"); + g_mutex_lock (closure->mutex); + closure->stopped = TRUE; + g_mutex_lock (closure->mutex); } typedef struct { @@ -1108,6 +1099,7 @@ pas_backend_file_class_init (PASBackendFileClass *klass) backend_class->load_uri = pas_backend_file_load_uri; backend_class->get_static_capabilities = pas_backend_file_get_static_capabilities; backend_class->start_book_view = pas_backend_file_start_book_view; + backend_class->stop_book_view = pas_backend_file_stop_book_view; backend_class->cancel_operation = pas_backend_file_cancel_operation; sync_class->remove_sync = pas_backend_file_remove; |