diff options
author | Chris Toshok <toshok@ximian.com> | 2003-10-23 04:50:36 +0800 |
---|---|---|
committer | Chris Toshok <toshok@src.gnome.org> | 2003-10-23 04:50:36 +0800 |
commit | cbfab681c1576d4de27d48fbd6b4b7780670494a (patch) | |
tree | 70e99033907a1f5dada728e785835a07ca6ab98c /addressbook/backend/pas/pas-backend-file.c | |
parent | f7cbb839adf3fd47aa07ca2080063acd6fff6978 (diff) | |
download | gsoc2013-evolution-cbfab681c1576d4de27d48fbd6b4b7780670494a.tar gsoc2013-evolution-cbfab681c1576d4de27d48fbd6b4b7780670494a.tar.gz gsoc2013-evolution-cbfab681c1576d4de27d48fbd6b4b7780670494a.tar.bz2 gsoc2013-evolution-cbfab681c1576d4de27d48fbd6b4b7780670494a.tar.lz gsoc2013-evolution-cbfab681c1576d4de27d48fbd6b4b7780670494a.tar.xz gsoc2013-evolution-cbfab681c1576d4de27d48fbd6b4b7780670494a.tar.zst gsoc2013-evolution-cbfab681c1576d4de27d48fbd6b4b7780670494a.zip |
use the synchronous api for this. simplifies it a bunch.
2003-10-21 Chris Toshok <toshok@ximian.com>
* tools/evolution-addressbook-abuse.c: use the synchronous api for
this. simplifies it a bunch.
2003-10-21 Chris Toshok <toshok@ximian.com>
* backend/pas/pas-book.c
(impl_GNOME_Evolution_Addressbook_Book_remove): we can ill afford
bad debug spew.
(view_listener_died_cb): implement.
(impl_GNOME_Evolution_Addressbook_Book_getBookView): hook up an
ORBit_small connection listener on the view's listener.
(pas_book_respond_create): use e_contact_get_const instead of
e_contact_get here. fixes a leak.
* backend/pas/pas-book-view.c
(impl_GNOME_Evolution_Addressbook_BookView_stop): implement, call
pas_backend_stop_book_view.
(pas_book_view_get_listener): return the book view's listener.
(pas_book_view_class_init): fill in epv->stop.
(pas_book_view_init): use a #define for THRESHOLD_MAX instead of
the constant.
* backend/pas/pas-book-view.h: add prototype for
pas_book_view_get_listener.
* backend/pas/pas-backend.c (pas_backend_stop_book_view):
implement.
(pas_backend_remove_book_view): implement.
* backend/pas/pas-backend.h: add prototype for stop_book_view and
remove_book_view.
* backend/pas/pas-backend-vcf.c (load_file): pass in the fd and
use fdopen here.
(foreach_build_list): don't creat EContacts here, because we'll
just be converting them back to vcards anyway.
(save_file): use char*'s instead of EContacts, and split entries
with 2 blank lines. Also, hold the lock over the entire function.
(do_create): hold the lock around uid generation and touching the
hash table.
(pas_backend_vcf_process_remove_contacts): same.
(pas_backend_vcf_process_modify_contact): same.
(pas_backend_vcf_stop_book_view): new function, but leave
unimplemented for now.
(pas_backend_vcf_load_uri): the uri contains the directory name,
not the filename.
(pas_backend_vcf_dispose): grab the lock here just for sanity's
sake. Also reorder things a bit, and free the hashtable and
mutex.
(pas_backend_vcf_init): init the mutex.
* backend/pas/pas-backend-summary.c
(pas_backend_summary_add_contact): don't unref the contact here.
* backend/pas/pas-backend-ldap.c
(pas_backend_ldap_process_stop_book_view): new function, but leave
unimplemented for now.
* backend/pas/pas-backend-file.c (build_summary): use an EContact
for this call.
(do_summary_query): nuke, the contents of this has been moved to
start_book_view.
(pas_backend_file_search_timeout): same.
(pas_backend_file_search): same.
(pas_backend_file_start_book_view): glom everything into here
involving searching. This function could (and should) be renamed
and reused from both this function and _get_contact_list.
(pas_backend_file_stop_book_view): new function.
(pas_backend_file_class_init): fill in backend->stop_book_view.
* backend/pas/Makefile.am (LDAP_BACKEND): libpasldap.a ->
libpasldap.la
(noinst_LTLIBRARIES): *.a -> *.la.
(libpas_la_SOURCES): same.
(libpasfile_la_SOURCES): same.
(libpasvcf_la_SOURCES): same.
(libpasldap_la_SOURCES): same.
* backend/idl/addressbook.idl: add BookView::stop.
* backend/ebook/e-vcard.c (read_attribute_value): fix GString
related leaks.
(read_attribute_params): same.
(parse): don't leak the EVCardAttributes corresponding to
BEGIN/END:vCard.
(free_gstring): new function
(e_vcard_attribute_remove_values): free the decoded_values list,
using free_gstring.
* backend/ebook/e-book.c (e_book_response_get_book_view): ref the
listener here.
* backend/ebook/e-book-view.h: add prototype for e_book_view_stop.
* backend/ebook/e-book-view.c (e_book_view_stop): new function.
* backend/ebook/e-book-async.c (_get_book_view_response_dtor):
unref the book view.
svn path=/trunk/; revision=23000
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; |