[evolution-data-server] Bug #651446 - Implement e_book_client_get_contacts_uids()
- From: Milan Crha <mcrha src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [evolution-data-server] Bug #651446 - Implement e_book_client_get_contacts_uids()
- Date: Tue, 31 May 2011 16:12:24 +0000 (UTC)
commit 6e1a5b1257acdd503d2f3b7f298f13c1cadf466c
Author: Milan Crha <mcrha redhat com>
Date: Tue May 31 18:10:49 2011 +0200
Bug #651446 - Implement e_book_client_get_contacts_uids()
addressbook/backends/file/e-book-backend-file.c | 96 +++++++++
.../backends/google/e-book-backend-google.c | 33 +++
addressbook/backends/ldap/e-book-backend-ldap.c | 204 ++++++++++++++++++++
.../backends/webdav/e-book-backend-webdav.c | 38 ++++
addressbook/libebook/e-book-client.c | 132 +++++++++++++
addressbook/libebook/e-book-client.h | 4 +
addressbook/libedata-book/e-book-backend-sync.c | 85 ++++++++
addressbook/libedata-book/e-book-backend-sync.h | 2 +
addressbook/libedata-book/e-book-backend.c | 32 +++
addressbook/libedata-book/e-book-backend.h | 2 +
addressbook/libedata-book/e-data-book.c | 53 +++++
addressbook/libedata-book/e-data-book.h | 1 +
addressbook/libegdbus/e-gdbus-book.c | 29 +++
addressbook/libegdbus/e-gdbus-book.h | 9 +
tests/libebook/client/test-client-async.c | 38 ++++-
tests/libebook/client/test-client.c | 37 ++++
16 files changed, 794 insertions(+), 1 deletions(-)
---
diff --git a/addressbook/backends/file/e-book-backend-file.c b/addressbook/backends/file/e-book-backend-file.c
index 4fc4e0e..87f4180 100644
--- a/addressbook/backends/file/e-book-backend-file.c
+++ b/addressbook/backends/file/e-book-backend-file.c
@@ -499,6 +499,101 @@ e_book_backend_file_get_contact_list (EBookBackendSync *backend,
*contacts = contact_list;
}
+static void
+e_book_backend_file_get_contact_list_uids (EBookBackendSync *backend,
+ EDataBook *book,
+ GCancellable *cancellable,
+ const gchar *query,
+ GSList **contacts_uids,
+ GError **perror)
+{
+ EBookBackendFile *bf = E_BOOK_BACKEND_FILE (backend);
+ DB *db = bf->priv->file_db;
+ DBC *dbc;
+ gint db_error;
+ DBT id_dbt, vcard_dbt;
+ EBookBackendSExp *card_sexp = NULL;
+ gboolean search_needed;
+ const gchar *search = query;
+ GSList *uids = NULL;
+
+ d(printf ("e_book_backend_file_get_contact_list (%s)\n", search));
+ if (e_book_backend_summary_is_summary_query (bf->priv->summary, search)) {
+ /* do a summary query */
+ GPtrArray *ids = e_book_backend_summary_search (bf->priv->summary, search);
+ gint i;
+
+ if (!ids) {
+ g_propagate_error (perror, EDB_ERROR (CONTACT_NOT_FOUND));
+ return;
+ }
+
+ for (i = 0; i < ids->len; i++) {
+ gchar *id = g_ptr_array_index (ids, i);
+
+ uids = g_slist_prepend (uids, g_strdup (id));
+ }
+
+ g_ptr_array_free (ids, TRUE);
+ } else {
+ search_needed = TRUE;
+ if (!strcmp (search, "(contains \"x-evolution-any-field\" \"\")"))
+ search_needed = FALSE;
+
+ card_sexp = e_book_backend_sexp_new (search);
+ if (!card_sexp) {
+ g_propagate_error (perror, EDB_ERROR (INVALID_QUERY));
+ return;
+ }
+
+ db_error = db->cursor (db, NULL, &dbc, 0);
+
+ if (db_error != 0) {
+ g_warning (G_STRLOC ": db->cursor failed with %s", db_strerror (db_error));
+ /* XXX this needs to be some CouldNotOpen error */
+ db_error_to_gerror (db_error, perror);
+ return;
+ }
+
+ memset (&vcard_dbt, 0, sizeof (vcard_dbt));
+ vcard_dbt.flags = DB_DBT_MALLOC;
+ memset (&id_dbt, 0, sizeof (id_dbt));
+ db_error = dbc->c_get (dbc, &id_dbt, &vcard_dbt, DB_FIRST);
+
+ while (db_error == 0) {
+
+ /* don't include the version in the list of cards */
+ if (id_dbt.size != strlen (E_BOOK_BACKEND_FILE_VERSION_NAME) + 1
+ || strcmp (id_dbt.data, E_BOOK_BACKEND_FILE_VERSION_NAME)) {
+
+ if ((!search_needed) || (card_sexp != NULL && e_book_backend_sexp_match_vcard (card_sexp, vcard_dbt.data))) {
+ uids = g_slist_prepend (uids, g_strdup (id_dbt.data));
+ }
+ }
+
+ g_free (vcard_dbt.data);
+
+ db_error = dbc->c_get (dbc, &id_dbt, &vcard_dbt, DB_NEXT);
+
+ }
+ g_object_unref (card_sexp);
+
+ if (db_error == DB_NOTFOUND) {
+ /* Success */
+ } else {
+ g_warning (G_STRLOC ": dbc->c_get failed with %s", db_strerror (db_error));
+ db_error_to_gerror (db_error, perror);
+ }
+
+ db_error = dbc->c_close (dbc);
+ if (db_error != 0) {
+ g_warning (G_STRLOC ": dbc->c_close failed with %s", db_strerror (db_error));
+ }
+ }
+
+ *contacts_uids = g_slist_reverse (uids);
+}
+
typedef struct {
EBookBackendFile *bf;
GThread *thread;
@@ -1370,6 +1465,7 @@ e_book_backend_file_class_init (EBookBackendFileClass *klass)
sync_class->modify_contact_sync = e_book_backend_file_modify_contact;
sync_class->get_contact_sync = e_book_backend_file_get_contact;
sync_class->get_contact_list_sync = e_book_backend_file_get_contact_list;
+ sync_class->get_contact_list_uids_sync = e_book_backend_file_get_contact_list_uids;
sync_class->authenticate_user_sync = e_book_backend_file_authenticate_user;
object_class->dispose = e_book_backend_file_dispose;
diff --git a/addressbook/backends/google/e-book-backend-google.c b/addressbook/backends/google/e-book-backend-google.c
index 0ac563e..4f1804e 100644
--- a/addressbook/backends/google/e-book-backend-google.c
+++ b/addressbook/backends/google/e-book-backend-google.c
@@ -1151,6 +1151,38 @@ e_book_backend_google_get_contact_list (EBookBackend *backend, EDataBook *book,
g_slist_free (filtered_contacts);
}
+static void
+e_book_backend_google_get_contact_list_uids (EBookBackend *backend, EDataBook *book, guint32 opid, GCancellable *cancellable, const gchar *query)
+{
+ EBookBackendSExp *sexp;
+ GList *all_contacts;
+ GSList *filtered_uids = NULL;
+
+ __debug__ (G_STRFUNC);
+
+ /* Get all contacts */
+ sexp = e_book_backend_sexp_new (query);
+ all_contacts = cache_get_contacts (backend);
+
+ for (; all_contacts; all_contacts = g_list_delete_link (all_contacts, all_contacts)) {
+ EContact *contact = all_contacts->data;
+
+ /* If the search expression matches the contact, include it in the search results */
+ if (e_book_backend_sexp_match_contact (sexp, contact)) {
+ filtered_uids = g_slist_append (filtered_uids, e_contact_get (contact, E_CONTACT_UID));
+ }
+
+ g_object_unref (contact);
+ }
+
+ g_object_unref (sexp);
+
+ e_data_book_respond_get_contact_list_uids (book, opid, NULL, filtered_uids);
+
+ g_slist_foreach (filtered_uids, (GFunc) g_free, NULL);
+ g_slist_free (filtered_uids);
+}
+
static gboolean
on_refresh_idle (EBookBackend *backend)
{
@@ -1687,6 +1719,7 @@ e_book_backend_google_class_init (EBookBackendGoogleClass *klass)
backend_class->modify_contact = e_book_backend_google_modify_contact;
backend_class->get_contact = e_book_backend_google_get_contact;
backend_class->get_contact_list = e_book_backend_google_get_contact_list;
+ backend_class->get_contact_list_uids = e_book_backend_google_get_contact_list_uids;
backend_class->authenticate_user = e_book_backend_google_authenticate_user;
object_class->dispose = e_book_backend_google_dispose;
diff --git a/addressbook/backends/ldap/e-book-backend-ldap.c b/addressbook/backends/ldap/e-book-backend-ldap.c
index fd72bb2..ef2ccd1 100644
--- a/addressbook/backends/ldap/e-book-backend-ldap.c
+++ b/addressbook/backends/ldap/e-book-backend-ldap.c
@@ -2696,6 +2696,209 @@ e_book_backend_ldap_get_contact_list (EBookBackend *backend,
}
}
+typedef struct {
+ LDAPOp op;
+ GSList *uids;
+} LDAPGetContactListUIDsOp;
+
+static void
+contact_list_uids_handler (LDAPOp *op, LDAPMessage *res)
+{
+ LDAPGetContactListUIDsOp *contact_list_uids_op = (LDAPGetContactListUIDsOp *) op;
+ EBookBackendLDAP *bl = E_BOOK_BACKEND_LDAP (op->backend);
+ LDAPMessage *e;
+ gint msg_type;
+ GTimeVal start, end;
+ gulong diff;
+
+ if (enable_debug) {
+ printf ("contact_list_uids_handler ...\n");
+ g_get_current_time (&start);
+ }
+
+ g_static_rec_mutex_lock (&eds_ldap_handler_lock);
+ if (!bl->priv->ldap) {
+ g_static_rec_mutex_unlock (&eds_ldap_handler_lock);
+ e_data_book_respond_get_contact_list_uids (op->book, op->opid, EDB_ERROR_NOT_CONNECTED (), NULL);
+ ldap_op_finished (op);
+ if (enable_debug)
+ printf ("contact_list_uids_handler ... ldap handler is NULL \n");
+ return;
+ }
+ g_static_rec_mutex_unlock (&eds_ldap_handler_lock);
+
+ msg_type = ldap_msgtype (res);
+ if (msg_type == LDAP_RES_SEARCH_ENTRY) {
+ g_static_rec_mutex_lock (&eds_ldap_handler_lock);
+ e = ldap_first_entry (bl->priv->ldap, res);
+ g_static_rec_mutex_unlock (&eds_ldap_handler_lock);
+
+ while (NULL != e) {
+ EContact *contact;
+ gchar *uid = NULL;
+
+ contact = build_contact_from_entry (bl, e, NULL, &uid);
+ g_object_unref (contact);
+
+ if (enable_debug)
+ printf ("uid = %s\n", uid);
+
+ contact_list_uids_op->uids = g_slist_append (contact_list_uids_op->uids, uid);
+
+ g_static_rec_mutex_lock (&eds_ldap_handler_lock);
+ e = ldap_next_entry (bl->priv->ldap, e);
+ g_static_rec_mutex_unlock (&eds_ldap_handler_lock);
+ }
+ }
+ else if (msg_type == LDAP_RES_SEARCH_RESULT) {
+ gchar *ldap_error_msg;
+ gint ldap_error;
+
+ g_static_rec_mutex_lock (&eds_ldap_handler_lock);
+ ldap_parse_result (bl->priv->ldap, res, &ldap_error,
+ NULL, &ldap_error_msg, NULL, NULL, 0);
+ g_static_rec_mutex_unlock (&eds_ldap_handler_lock);
+ if (ldap_error != LDAP_SUCCESS) {
+ g_warning ("contact_list_uids_handler: %02X (%s), additional info: %s",
+ ldap_error,
+ ldap_err2string (ldap_error), ldap_error_msg);
+ }
+ ldap_memfree (ldap_error_msg);
+
+ g_warning ("search returned %d\n", ldap_error);
+
+ if (ldap_error == LDAP_TIMELIMIT_EXCEEDED)
+ e_data_book_respond_get_contact_list_uids (op->book, op->opid, EDB_ERROR (SEARCH_TIME_LIMIT_EXCEEDED), contact_list_uids_op->uids);
+ else if (ldap_error == LDAP_SIZELIMIT_EXCEEDED)
+ e_data_book_respond_get_contact_list_uids (op->book, op->opid, EDB_ERROR (SEARCH_SIZE_LIMIT_EXCEEDED), contact_list_uids_op->uids);
+ else if (ldap_error == LDAP_SUCCESS)
+ e_data_book_respond_get_contact_list_uids (op->book, op->opid, EDB_ERROR (SUCCESS), contact_list_uids_op->uids);
+ else
+ e_data_book_respond_get_contact_list_uids (op->book, op->opid, ldap_error_to_response (ldap_error), contact_list_uids_op->uids);
+
+ ldap_op_finished (op);
+ if (enable_debug) {
+ printf ("contact_list_uids_handler success ");
+ g_get_current_time (&end);
+ diff = end.tv_sec * 1000 + end.tv_usec/1000;
+ diff -= start.tv_sec * 1000 + start.tv_usec/1000;
+ printf("and took %ld.%03ld seconds\n", diff/1000, diff%1000);
+ }
+ }
+ else {
+ g_warning ("unhandled search result type %d returned", msg_type);
+ e_data_book_respond_get_contact_list_uids (op->book, op->opid,
+ e_data_book_create_error_fmt (E_DATA_BOOK_STATUS_OTHER_ERROR,
+ "%s: Unhandled search result type %d returned", G_STRFUNC, msg_type),
+ NULL);
+ ldap_op_finished (op);
+ }
+}
+
+static void
+contact_list_uids_dtor (LDAPOp *op)
+{
+ LDAPGetContactListUIDsOp *contact_list_uids_op = (LDAPGetContactListUIDsOp *) op;
+
+ g_slist_foreach (contact_list_uids_op->uids, (GFunc) g_free, NULL);
+ g_slist_free (contact_list_uids_op->uids);
+
+ g_free (contact_list_uids_op);
+}
+
+static void
+e_book_backend_ldap_get_contact_list_uids (EBookBackend *backend, EDataBook *book, guint32 opid, GCancellable *cancellable, const gchar *query)
+{
+ LDAPGetContactListUIDsOp *contact_list_uids_op;
+ EBookBackendLDAP *bl = E_BOOK_BACKEND_LDAP (backend);
+ gint contact_list_uids_msgid;
+ EDataBookView *book_view;
+ gint ldap_error;
+ gchar *ldap_query;
+ GTimeVal start, end;
+ gulong diff;
+
+ if (enable_debug) {
+ printf ("e_book_backend_ldap_get_contact_list_uids ... \n");
+ g_get_current_time (&start);
+ }
+
+ if (!bl->priv->is_online) {
+ if (bl->priv->marked_for_offline && bl->priv->cache) {
+ GList *contacts;
+ GSList *uids = NULL;
+ GList *l;
+
+ contacts = e_book_backend_cache_get_contacts (bl->priv->cache, query);
+
+ for (l = contacts; l; l = g_list_next (l)) {
+ EContact *contact = l->data;
+ uids = g_slist_prepend (uids, e_contact_get (contact, E_CONTACT_UID));
+ g_object_unref (contact);
+ }
+
+ g_list_free (contacts);
+ e_data_book_respond_get_contact_list_uids (book, opid, EDB_ERROR (SUCCESS), uids);
+ g_slist_foreach (uids, (GFunc) g_free, NULL);
+ g_slist_free (uids);
+ return;
+ }
+
+ e_data_book_respond_get_contact_list_uids (book, opid, EDB_ERROR (REPOSITORY_OFFLINE), NULL);
+ return;
+ }
+
+ g_static_rec_mutex_lock (&eds_ldap_handler_lock);
+ if (!bl->priv->ldap) {
+ g_static_rec_mutex_unlock (&eds_ldap_handler_lock);
+ e_data_book_respond_get_contact_list_uids (book, opid, EDB_ERROR_NOT_CONNECTED (), NULL);
+ if (enable_debug)
+ printf ("e_book_backend_ldap_get_contact_list_uids... ldap handler is NULL\n");
+ return;
+ }
+ g_static_rec_mutex_unlock (&eds_ldap_handler_lock);
+
+ contact_list_uids_op = g_new0 (LDAPGetContactListUIDsOp, 1);
+ book_view = find_book_view (bl);
+
+ ldap_query = e_book_backend_ldap_build_query (bl, query);
+
+ if (enable_debug)
+ printf ("getting contact list uids with filter: %s\n", ldap_query);
+
+ do {
+ g_static_rec_mutex_lock (&eds_ldap_handler_lock);
+ ldap_error = ldap_search_ext (bl->priv->ldap,
+ bl->priv->ldap_rootdn,
+ bl->priv->ldap_scope,
+ ldap_query,
+ NULL, 0, NULL, NULL,
+ NULL, /* XXX timeout */
+ LDAP_NO_LIMIT, &contact_list_uids_msgid);
+ g_static_rec_mutex_unlock (&eds_ldap_handler_lock);
+ } while (e_book_backend_ldap_reconnect (bl, book_view, ldap_error));
+
+ g_free (ldap_query);
+
+ if (ldap_error == LDAP_SUCCESS) {
+ ldap_op_add ((LDAPOp*) contact_list_uids_op, backend, book,
+ book_view, opid, contact_list_uids_msgid,
+ contact_list_uids_handler, contact_list_uids_dtor);
+ 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 ("e_book_backend_ldap_get_contact_list_uids invoked contact_list_uids_handler ");
+ printf ("and took %ld.%03ld seconds\n", diff/1000, diff%1000);
+ }
+ } else {
+ e_data_book_respond_get_contact_list_uids (book, opid, ldap_error_to_response (ldap_error), NULL);
+ contact_list_uids_dtor ((LDAPOp *) contact_list_uids_op);
+ }
+}
+
static EContactField email_ids[4] = {
E_CONTACT_EMAIL_1,
E_CONTACT_EMAIL_2,
@@ -5347,6 +5550,7 @@ e_book_backend_ldap_class_init (EBookBackendLDAPClass *klass)
parent_class->modify_contact = e_book_backend_ldap_modify_contact;
parent_class->get_contact = e_book_backend_ldap_get_contact;
parent_class->get_contact_list = e_book_backend_ldap_get_contact_list;
+ parent_class->get_contact_list_uids = e_book_backend_ldap_get_contact_list_uids;
parent_class->start_book_view = e_book_backend_ldap_start_book_view;
parent_class->stop_book_view = e_book_backend_ldap_stop_book_view;
parent_class->authenticate_user = e_book_backend_ldap_authenticate_user;
diff --git a/addressbook/backends/webdav/e-book-backend-webdav.c b/addressbook/backends/webdav/e-book-backend-webdav.c
index 7020008..4cf0d15 100644
--- a/addressbook/backends/webdav/e-book-backend-webdav.c
+++ b/addressbook/backends/webdav/e-book-backend-webdav.c
@@ -1095,6 +1095,43 @@ e_book_backend_webdav_get_contact_list (EBookBackend *backend, EDataBook *book,
}
static void
+e_book_backend_webdav_get_contact_list_uids (EBookBackend *backend, EDataBook *book, guint32 opid, GCancellable *cancellable, const gchar *query)
+{
+ EBookBackendWebdav *webdav = E_BOOK_BACKEND_WEBDAV (backend);
+ EBookBackendWebdavPrivate *priv = webdav->priv;
+ GList *contact_list;
+ GSList *uids_list;
+ GList *c;
+
+ if (priv->is_online) {
+ /* make sure the cache is up to date */
+ GError *error = download_contacts (webdav, NULL, NULL);
+
+ if (error) {
+ e_data_book_respond_get_contact_list_uids (book, opid, error, NULL);
+ return;
+ }
+ }
+
+ /* answer query from cache */
+ contact_list = e_book_backend_cache_get_contacts (priv->cache, query);
+ uids_list = NULL;
+ for (c = contact_list; c != NULL; c = g_list_next (c)) {
+ EContact *contact = c->data;
+
+ uids_list = g_slist_append (uids_list, e_contact_get (contact, E_CONTACT_UID));
+
+ g_object_unref (contact);
+ }
+ g_list_free (contact_list);
+
+ e_data_book_respond_get_contact_list_uids (book, opid, EDB_ERROR (SUCCESS), uids_list);
+
+ g_slist_foreach (uids_list, (GFunc) g_free, NULL);
+ g_slist_free (uids_list);
+}
+
+static void
e_book_backend_webdav_authenticate_user (EBookBackend *backend, GCancellable *cancellable, ECredentials *credentials)
{
EBookBackendWebdav *webdav = E_BOOK_BACKEND_WEBDAV (backend);
@@ -1377,6 +1414,7 @@ e_book_backend_webdav_class_init (EBookBackendWebdavClass *klass)
backend_class->modify_contact = e_book_backend_webdav_modify_contact;
backend_class->get_contact = e_book_backend_webdav_get_contact;
backend_class->get_contact_list = e_book_backend_webdav_get_contact_list;
+ backend_class->get_contact_list_uids = e_book_backend_webdav_get_contact_list_uids;
backend_class->start_book_view = e_book_backend_webdav_start_book_view;
backend_class->stop_book_view = e_book_backend_webdav_stop_book_view;
backend_class->authenticate_user = e_book_backend_webdav_authenticate_user;
diff --git a/addressbook/libebook/e-book-client.c b/addressbook/libebook/e-book-client.c
index 9993c31..14e50ff 100644
--- a/addressbook/libebook/e-book-client.c
+++ b/addressbook/libebook/e-book-client.c
@@ -1794,6 +1794,138 @@ e_book_client_get_contacts_sync (EBookClient *client, const gchar *sexp, GSList
}
/**
+ * e_book_client_get_contacts_uids:
+ * @client: an #EBookClient
+ * @sexp: an S-expression representing the query
+ * @cancellable: a #GCancellable; can be %NULL
+ * @callback: callback to call when a result is ready
+ * @user_data: user data for the @callback
+ *
+ * Query @client with @sexp, receiving a list of contacts UIDs which
+ * matched. The call is finished by e_book_client_get_contacts_uids_finish()
+ * from the @callback.
+ *
+ * Note: @sexp can be obtained through #EBookQuery, by converting it
+ * to a string with e_book_query_to_string().
+ *
+ * Since: 3.2
+ **/
+void
+e_book_client_get_contacts_uids (EBookClient *client, const gchar *sexp, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data)
+{
+ gchar *gdbus_sexp = NULL;
+
+ g_return_if_fail (sexp != NULL);
+
+ e_client_proxy_call_string (E_CLIENT (client), e_util_ensure_gdbus_string (sexp, &gdbus_sexp), cancellable, callback, user_data, e_book_client_get_contacts_uids,
+ e_gdbus_book_call_get_contact_list_uids,
+ NULL, NULL, NULL, e_gdbus_book_call_get_contact_list_uids_finish, NULL);
+
+ g_free (gdbus_sexp);
+}
+
+/**
+ * e_book_client_get_contacts_uids_finish:
+ * @client: an #EBookClient
+ * @result: a #GAsyncResult
+ * @contacts_uids: (out) a #GSList of matched contacts UIDs stored as strings
+ * @error: (out): a #GError to set an error, if any
+ *
+ * Finishes previous call of e_book_client_get_contacts_uids().
+ * If successful, then the @contacts_uids is set to newly allocated list
+ * of UID strings, which should be freed with e_client_util_free_string_slist().
+ *
+ * Returns: %TRUE if successful, %FALSE otherwise.
+ *
+ * Since: 3.2
+ **/
+gboolean
+e_book_client_get_contacts_uids_finish (EBookClient *client, GAsyncResult *result, GSList **contacts_uids, GError **error)
+{
+ gboolean res;
+ gchar **uids = NULL;
+
+ g_return_val_if_fail (contacts_uids != NULL, FALSE);
+
+ res = e_client_proxy_call_finish_strv (E_CLIENT (client), result, &uids, error, e_book_client_get_contacts_uids);
+
+ if (uids && res) {
+ gint ii;
+ GSList *slist = NULL;
+
+ for (ii = 0; uids[ii]; ii++) {
+ slist = g_slist_prepend (slist, g_strdup (uids[ii]));
+ }
+
+ *contacts_uids = g_slist_reverse (slist);
+ } else {
+ *contacts_uids = NULL;
+ }
+
+ g_strfreev (uids);
+
+ return res;
+}
+
+/**
+ * e_book_client_get_contacts_uids_sync:
+ * @client: an #EBookClient
+ * @sexp: an S-expression representing the query
+ * @contacts_uids: (out) a #GSList of matched contacts UIDs stored as strings
+ * @cancellable: a #GCancellable; can be %NULL
+ * @error: (out): a #GError to set an error, if any
+ *
+ * Query @client with @sexp, receiving a list of contacts UIDs which matched.
+ * If successful, then the @contacts_uids is set to newly allocated list
+ * of UID strings, which should be freed with e_client_util_free_string_slist().
+ *
+ * Note: @sexp can be obtained through #EBookQuery, by converting it
+ * to a string with e_book_query_to_string().
+ *
+ * Returns: %TRUE if successful, %FALSE otherwise.
+ *
+ * Since: 3.2
+ **/
+gboolean
+e_book_client_get_contacts_uids_sync (EBookClient *client, const gchar *sexp, GSList **contacts_uids, GCancellable *cancellable, GError **error)
+{
+ gboolean res;
+ gchar *gdbus_sexp = NULL;
+ gchar **uids = NULL;
+
+ g_return_val_if_fail (client != NULL, FALSE);
+ g_return_val_if_fail (E_IS_BOOK_CLIENT (client), FALSE);
+ g_return_val_if_fail (client->priv != NULL, FALSE);
+ g_return_val_if_fail (sexp != NULL, FALSE);
+ g_return_val_if_fail (contacts_uids != NULL, FALSE);
+
+ if (!client->priv->gdbus_book) {
+ set_proxy_gone_error (error);
+ return FALSE;
+ }
+
+ res = e_client_proxy_call_sync_string__strv (E_CLIENT (client), e_util_ensure_gdbus_string (sexp, &gdbus_sexp), &uids, cancellable, error, e_gdbus_book_call_get_contact_list_uids_sync);
+
+ if (uids && res) {
+ gint ii;
+ GSList *slist = NULL;
+
+ for (ii = 0; uids[ii]; ii++) {
+ slist = g_slist_prepend (slist, g_strdup (uids[ii]));
+ }
+
+ *contacts_uids = g_slist_reverse (slist);
+ } else {
+ *contacts_uids = NULL;
+ }
+
+ g_free (gdbus_sexp);
+ g_strfreev (uids);
+
+ return res;
+}
+
+/**
* e_book_client_get_view:
* @client: an #EBookClient
* @sexp: an S-expression representing the query
diff --git a/addressbook/libebook/e-book-client.h b/addressbook/libebook/e-book-client.h
index 92bddb9..ef6d601 100644
--- a/addressbook/libebook/e-book-client.h
+++ b/addressbook/libebook/e-book-client.h
@@ -121,6 +121,10 @@ void e_book_client_get_contacts (EBookClient *client, const gchar *sexp, GCan
gboolean e_book_client_get_contacts_finish (EBookClient *client, GAsyncResult *result, GSList **contacts, GError **error);
gboolean e_book_client_get_contacts_sync (EBookClient *client, const gchar *sexp, GSList **contacts, GCancellable *cancellable, GError **error);
+void e_book_client_get_contacts_uids (EBookClient *client, const gchar *sexp, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data);
+gboolean e_book_client_get_contacts_uids_finish (EBookClient *client, GAsyncResult *result, GSList **contacts_uids, GError **error);
+gboolean e_book_client_get_contacts_uids_sync (EBookClient *client, const gchar *sexp, GSList **contacts_uids, GCancellable *cancellable, GError **error);
+
void e_book_client_get_view (EBookClient *client, const gchar *sexp, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data);
gboolean e_book_client_get_view_finish (EBookClient *client, GAsyncResult *result, EBookClientView **view, GError **error);
gboolean e_book_client_get_view_sync (EBookClient *client, const gchar *sexp, EBookClientView **view, GCancellable *cancellable, GError **error);
diff --git a/addressbook/libedata-book/e-book-backend-sync.c b/addressbook/libedata-book/e-book-backend-sync.c
index a944554..141b234 100644
--- a/addressbook/libedata-book/e-book-backend-sync.c
+++ b/addressbook/libedata-book/e-book-backend-sync.c
@@ -304,6 +304,72 @@ e_book_backend_sync_get_contact_list (EBookBackendSync *backend,
}
/**
+ * e_book_backend_sync_get_contact_list_uids:
+ * @backend: an #EBookBackendSync
+ * @book: an #EDataBook
+ * @cancellable: a #GCancellable for the operation
+ * @query: an s-expression of the query to perform
+ * @contacts_uids: a pointer to a location to store the resulting list of UID strings
+ * @error: #GError to set, when something fails
+ *
+ * Gets a list of contact UIDS from @book. The list and its elements must be freed
+ * by the caller.
+ *
+ * Since: 3.2
+ **/
+void
+e_book_backend_sync_get_contact_list_uids (EBookBackendSync *backend,
+ EDataBook *book,
+ GCancellable *cancellable,
+ const gchar *query,
+ GSList **contacts_uids,
+ GError **error)
+{
+ e_return_data_book_error_if_fail (E_IS_BOOK_BACKEND_SYNC (backend), E_DATA_BOOK_STATUS_INVALID_ARG);
+ e_return_data_book_error_if_fail (E_IS_DATA_BOOK (book), E_DATA_BOOK_STATUS_INVALID_ARG);
+ e_return_data_book_error_if_fail (query, E_DATA_BOOK_STATUS_INVALID_ARG);
+ e_return_data_book_error_if_fail (contacts_uids, E_DATA_BOOK_STATUS_INVALID_ARG);
+
+ if (E_BOOK_BACKEND_SYNC_GET_CLASS (backend)->get_contact_list_uids_sync != NULL) {
+ (* E_BOOK_BACKEND_SYNC_GET_CLASS (backend)->get_contact_list_uids_sync) (backend, book, cancellable, query, contacts_uids, error);
+ } else {
+ /* inefficient fallback code */
+ GSList *vcards = NULL;
+ GError *local_error = NULL;
+
+ e_book_backend_sync_get_contact_list_uids (backend, book, cancellable, query, &vcards, &local_error);
+
+ if (local_error) {
+ g_propagate_error (error, local_error);
+ } else {
+ GSList *v;
+
+ *contacts_uids = NULL;
+
+ for (v = vcards; v; v = v->next) {
+ EVCard *card = e_vcard_new_from_string (v->data);
+ EVCardAttribute *attr;
+
+ if (!card)
+ continue;
+
+ attr = e_vcard_get_attribute (card, EVC_UID);
+
+ if (attr)
+ *contacts_uids = g_slist_prepend (*contacts_uids, e_vcard_attribute_get_value (attr));
+
+ g_object_unref (card);
+ }
+
+ *contacts_uids = g_slist_reverse (*contacts_uids);
+ }
+
+ g_slist_foreach (vcards, (GFunc) g_free, NULL);
+ g_slist_free (vcards);
+ }
+}
+
+/**
* e_book_backend_sync_authenticate_user:
* @backend: an #EBookBackendSync
* @cancellable: a #GCancellable for the operation
@@ -480,6 +546,24 @@ book_backend_get_contact_list (EBookBackend *backend,
}
static void
+book_backend_get_contact_list_uids (EBookBackend *backend,
+ EDataBook *book,
+ guint32 opid,
+ GCancellable *cancellable,
+ const gchar *query)
+{
+ GError *error = NULL;
+ GSList *uids = NULL;
+
+ e_book_backend_sync_get_contact_list_uids (E_BOOK_BACKEND_SYNC (backend), book, cancellable, query, &uids, &error);
+
+ e_data_book_respond_get_contact_list_uids (book, opid, error, uids);
+
+ g_slist_foreach (uids, (GFunc) g_free, NULL);
+ g_slist_free (uids);
+}
+
+static void
book_backend_authenticate_user (EBookBackend *backend,
GCancellable *cancellable,
ECredentials *credentials)
@@ -553,6 +637,7 @@ e_book_backend_sync_class_init (EBookBackendSyncClass *klass)
backend_class->modify_contact = book_backend_modify_contact;
backend_class->get_contact = book_backend_get_contact;
backend_class->get_contact_list = book_backend_get_contact_list;
+ backend_class->get_contact_list_uids = book_backend_get_contact_list_uids;
klass->get_backend_property_sync = book_backend_sync_get_backend_property;
klass->set_backend_property_sync = book_backend_sync_set_backend_property;
diff --git a/addressbook/libedata-book/e-book-backend-sync.h b/addressbook/libedata-book/e-book-backend-sync.h
index 988fa24..7ef2f51 100644
--- a/addressbook/libedata-book/e-book-backend-sync.h
+++ b/addressbook/libedata-book/e-book-backend-sync.h
@@ -38,6 +38,7 @@ struct _EBookBackendSyncClass {
void (*modify_contact_sync) (EBookBackendSync *backend, EDataBook *book, GCancellable *cancellable, const gchar *vcard, EContact **contact, GError **error);
void (*get_contact_sync) (EBookBackendSync *backend, EDataBook *book, GCancellable *cancellable, const gchar *id, gchar **vcard, GError **error);
void (*get_contact_list_sync) (EBookBackendSync *backend, EDataBook *book, GCancellable *cancellable, const gchar *query, GSList **contacts, GError **error);
+ void (*get_contact_list_uids_sync) (EBookBackendSync *backend, EDataBook *book, GCancellable *cancellable, const gchar *query, GSList **contacts_uids, GError **error);
void (*authenticate_user_sync) (EBookBackendSync *backend, GCancellable *cancellable, ECredentials *credentials, GError **error);
};
@@ -56,6 +57,7 @@ void e_book_backend_sync_remove_contacts (EBookBackendSync *backend, EDataBook
void e_book_backend_sync_modify_contact (EBookBackendSync *backend, EDataBook *book, GCancellable *cancellable, const gchar *vcard, EContact **contact, GError **error);
void e_book_backend_sync_get_contact (EBookBackendSync *backend, EDataBook *book, GCancellable *cancellable, const gchar *id, gchar **vcard, GError **error);
void e_book_backend_sync_get_contact_list (EBookBackendSync *backend, EDataBook *book, GCancellable *cancellable, const gchar *query, GSList **contacts, GError **error);
+void e_book_backend_sync_get_contact_list_uids(EBookBackendSync *backend, EDataBook *book, GCancellable *cancellable, const gchar *query, GSList **contacts_uids, GError **error);
void e_book_backend_sync_authenticate_user (EBookBackendSync *backend, GCancellable *cancellable, ECredentials *credentials, GError **error);
diff --git a/addressbook/libedata-book/e-book-backend.c b/addressbook/libedata-book/e-book-backend.c
index 72cfd01..64673d5 100644
--- a/addressbook/libedata-book/e-book-backend.c
+++ b/addressbook/libedata-book/e-book-backend.c
@@ -591,6 +591,38 @@ e_book_backend_get_contact_list (EBookBackend *backend,
}
/**
+ * e_book_backend_get_contact_list_uids:
+ * @backend: an #EBookBackend
+ * @book: an #EDataBook
+ * @opid: the ID to use for this operation
+ * @cancellable: a #GCancellable for the operation
+ * @query: the s-expression to match
+ *
+ * Executes a 'get contact list uids' request specified by @opid on @book
+ * using @backend.
+ * This might be finished with e_data_book_respond_get_contact_list_uids().
+ *
+ * Since: 3.2
+ **/
+void
+e_book_backend_get_contact_list_uids (EBookBackend *backend,
+ EDataBook *book,
+ guint32 opid,
+ GCancellable *cancellable,
+ const gchar *query)
+{
+ g_return_if_fail (E_IS_BOOK_BACKEND (backend));
+ g_return_if_fail (E_IS_DATA_BOOK (book));
+ g_return_if_fail (query);
+ g_return_if_fail (E_BOOK_BACKEND_GET_CLASS (backend)->get_contact_list_uids);
+
+ if (e_book_backend_is_opening (backend))
+ e_data_book_respond_get_contact_list_uids (book, opid, EDB_OPENING_ERROR, NULL);
+ else
+ (* E_BOOK_BACKEND_GET_CLASS (backend)->get_contact_list_uids) (backend, book, opid, cancellable, query);
+}
+
+/**
* e_book_backend_start_book_view:
* @backend: an #EBookBackend
* @book_view: the #EDataBookView to start
diff --git a/addressbook/libedata-book/e-book-backend.h b/addressbook/libedata-book/e-book-backend.h
index 52a9b39..0ee449d 100644
--- a/addressbook/libedata-book/e-book-backend.h
+++ b/addressbook/libedata-book/e-book-backend.h
@@ -74,6 +74,7 @@ struct _EBookBackendClass {
void (* modify_contact) (EBookBackend *backend, EDataBook *book, guint32 opid, GCancellable *cancellable, const gchar *vcard);
void (* get_contact) (EBookBackend *backend, EDataBook *book, guint32 opid, GCancellable *cancellable, const gchar *id);
void (* get_contact_list) (EBookBackend *backend, EDataBook *book, guint32 opid, GCancellable *cancellable, const gchar *query);
+ void (* get_contact_list_uids) (EBookBackend *backend, EDataBook *book, guint32 opid, GCancellable *cancellable, const gchar *query);
void (* start_book_view) (EBookBackend *backend, EDataBookView *book_view);
void (* stop_book_view) (EBookBackend *backend, EDataBookView *book_view);
@@ -112,6 +113,7 @@ void e_book_backend_remove_contacts (EBookBackend *backend, EDataBook *book, gu
void e_book_backend_modify_contact (EBookBackend *backend, EDataBook *book, guint32 opid, GCancellable *cancellable, const gchar *vcard);
void e_book_backend_get_contact (EBookBackend *backend, EDataBook *book, guint32 opid, GCancellable *cancellable, const gchar *id);
void e_book_backend_get_contact_list (EBookBackend *backend, EDataBook *book, guint32 opid, GCancellable *cancellable, const gchar *query);
+void e_book_backend_get_contact_list_uids(EBookBackend *backend, EDataBook *book, guint32 opid, GCancellable *cancellable, const gchar *query);
void e_book_backend_start_book_view (EBookBackend *backend, EDataBookView *view);
void e_book_backend_stop_book_view (EBookBackend *backend, EDataBookView *view);
diff --git a/addressbook/libedata-book/e-data-book.c b/addressbook/libedata-book/e-data-book.c
index 7aebda4..9e17703 100644
--- a/addressbook/libedata-book/e-data-book.c
+++ b/addressbook/libedata-book/e-data-book.c
@@ -58,6 +58,7 @@ typedef enum {
OP_REFRESH,
OP_GET_CONTACT,
OP_GET_CONTACTS,
+ OP_GET_CONTACTS_UIDS,
OP_AUTHENTICATE,
OP_ADD_CONTACT,
OP_REMOVE_CONTACTS,
@@ -90,6 +91,7 @@ typedef struct {
gchar *vcard;
/* OP_GET_BOOK_VIEW */
/* OP_GET_CONTACTS */
+ /* OP_GET_CONTACTS_UIDS */
gchar *query;
/* OP_CANCEL_OPERATION */
guint opid;
@@ -150,6 +152,10 @@ operation_thread (gpointer data, gpointer user_data)
e_book_backend_get_contact_list (backend, op->book, op->id, op->cancellable, op->d.query);
g_free (op->d.query);
break;
+ case OP_GET_CONTACTS_UIDS:
+ e_book_backend_get_contact_list_uids (backend, op->book, op->id, op->cancellable, op->d.query);
+ g_free (op->d.query);
+ break;
case OP_MODIFY_CONTACT:
e_book_backend_modify_contact (backend, op->book, op->id, op->cancellable, op->d.vcard);
g_free (op->d.vcard);
@@ -560,6 +566,28 @@ impl_Book_getContactList (EGdbusBook *object, GDBusMethodInvocation *invocation,
}
static gboolean
+impl_Book_get_contact_list_uids (EGdbusBook *object, GDBusMethodInvocation *invocation, const gchar *in_query, EDataBook *book)
+{
+ OperationData *op;
+
+ if (in_query == NULL || !*in_query) {
+ GError *error = e_data_book_create_error (E_DATA_BOOK_STATUS_INVALID_QUERY, NULL);
+ /* Translators: This is prefix to a detailed error message */
+ data_book_return_error (invocation, error, _("Empty query: "));
+ g_error_free (error);
+ return TRUE;
+ }
+
+ op = op_new (OP_GET_CONTACTS_UIDS, book);
+ op->d.query = g_strdup (in_query);
+
+ e_gdbus_book_complete_get_contact_list_uids (book->priv->gdbus_object, invocation, op->id);
+ e_operation_pool_push (ops_pool, op);
+
+ return TRUE;
+}
+
+static gboolean
impl_Book_addContact (EGdbusBook *object, GDBusMethodInvocation *invocation, const gchar *in_vcard, EDataBook *book)
{
OperationData *op;
@@ -866,6 +894,30 @@ e_data_book_respond_get_contact_list (EDataBook *book, guint32 opid, GError *err
}
void
+e_data_book_respond_get_contact_list_uids (EDataBook *book, guint32 opid, GError *error, const GSList *uids)
+{
+ if (error) {
+ /* Translators: This is prefix to a detailed error message */
+ g_prefix_error (&error, "%s", _("Cannot get contact list uids: "));
+ e_gdbus_book_emit_get_contact_list_uids_done (book->priv->gdbus_object, opid, error, NULL);
+ g_error_free (error);
+ } else {
+ gchar **array;
+ const GSList *l;
+ gint i = 0;
+
+ array = g_new0 (gchar *, g_slist_length ((GSList *) uids) + 1);
+ for (l = uids; l != NULL; l = l->next) {
+ array[i++] = e_util_utf8_make_valid (l->data);
+ }
+
+ e_gdbus_book_emit_get_contact_list_uids_done (book->priv->gdbus_object, opid, NULL, (const gchar * const *) array);
+
+ g_strfreev (array);
+ }
+}
+
+void
e_data_book_respond_create (EDataBook *book, guint32 opid, GError *error, const EContact *contact)
{
gchar *gdbus_uid = NULL;
@@ -1028,6 +1080,7 @@ e_data_book_init (EDataBook *ebook)
g_signal_connect (gdbus_object, "handle-refresh", G_CALLBACK (impl_Book_refresh), ebook);
g_signal_connect (gdbus_object, "handle-get-contact", G_CALLBACK (impl_Book_getContact), ebook);
g_signal_connect (gdbus_object, "handle-get-contact-list", G_CALLBACK (impl_Book_getContactList), ebook);
+ g_signal_connect (gdbus_object, "handle-get-contact-list-uids", G_CALLBACK (impl_Book_get_contact_list_uids), ebook);
g_signal_connect (gdbus_object, "handle-authenticate-user", G_CALLBACK (impl_Book_authenticateUser), ebook);
g_signal_connect (gdbus_object, "handle-add-contact", G_CALLBACK (impl_Book_addContact), ebook);
g_signal_connect (gdbus_object, "handle-remove-contacts", G_CALLBACK (impl_Book_removeContacts), ebook);
diff --git a/addressbook/libedata-book/e-data-book.h b/addressbook/libedata-book/e-data-book.h
index 1f6c5c6..0a1ed32 100644
--- a/addressbook/libedata-book/e-data-book.h
+++ b/addressbook/libedata-book/e-data-book.h
@@ -142,6 +142,7 @@ void e_data_book_respond_remove_contacts (EDataBook *book, guint32 opid, GErro
void e_data_book_respond_modify (EDataBook *book, guint32 opid, GError *error, const EContact *contact);
void e_data_book_respond_get_contact (EDataBook *book, guint32 opid, GError *error, const gchar *vcard);
void e_data_book_respond_get_contact_list (EDataBook *book, guint32 opid, GError *error, const GSList *cards);
+void e_data_book_respond_get_contact_list_uids (EDataBook *book, guint32 opid, GError *error, const GSList *uids);
void e_data_book_report_error (EDataBook *book, const gchar *message);
void e_data_book_report_readonly (EDataBook *book, gboolean readonly);
diff --git a/addressbook/libegdbus/e-gdbus-book.c b/addressbook/libegdbus/e-gdbus-book.c
index c6d2df5..5190d9f 100644
--- a/addressbook/libegdbus/e-gdbus-book.c
+++ b/addressbook/libegdbus/e-gdbus-book.c
@@ -50,6 +50,8 @@ enum
__GET_CONTACT_DONE_SIGNAL,
__GET_CONTACT_LIST_METHOD,
__GET_CONTACT_LIST_DONE_SIGNAL,
+ __GET_CONTACT_LIST_UIDS_METHOD,
+ __GET_CONTACT_LIST_UIDS_DONE_SIGNAL,
__ADD_CONTACT_METHOD,
__ADD_CONTACT_DONE_SIGNAL,
__REMOVE_CONTACTS_METHOD,
@@ -122,6 +124,7 @@ E_DECLARE_GDBUS_METHOD_DONE_EMISSION_HOOK_ASYNC_VOID (GDBUS_BOOK_INTERFACE_NAME,
E_DECLARE_GDBUS_METHOD_DONE_EMISSION_HOOK_ASYNC_VOID (GDBUS_BOOK_INTERFACE_NAME, refresh)
E_DECLARE_GDBUS_METHOD_DONE_EMISSION_HOOK_ASYNC_STRING (GDBUS_BOOK_INTERFACE_NAME, get_contact)
E_DECLARE_GDBUS_METHOD_DONE_EMISSION_HOOK_ASYNC_STRV (GDBUS_BOOK_INTERFACE_NAME, get_contact_list)
+E_DECLARE_GDBUS_METHOD_DONE_EMISSION_HOOK_ASYNC_STRV (GDBUS_BOOK_INTERFACE_NAME, get_contact_list_uids)
E_DECLARE_GDBUS_METHOD_DONE_EMISSION_HOOK_ASYNC_STRING (GDBUS_BOOK_INTERFACE_NAME, add_contact)
E_DECLARE_GDBUS_METHOD_DONE_EMISSION_HOOK_ASYNC_VOID (GDBUS_BOOK_INTERFACE_NAME, remove_contacts)
E_DECLARE_GDBUS_METHOD_DONE_EMISSION_HOOK_ASYNC_VOID (GDBUS_BOOK_INTERFACE_NAME, modify_contact)
@@ -151,6 +154,7 @@ e_gdbus_book_default_init (EGdbusBookIface *iface)
E_INIT_GDBUS_METHOD_ASYNC_VOID__VOID (EGdbusBookIface, "refresh", refresh, __REFRESH_METHOD, __REFRESH_DONE_SIGNAL)
E_INIT_GDBUS_METHOD_ASYNC_STRING__STRING(EGdbusBookIface, "getContact", get_contact, __GET_CONTACT_METHOD, __GET_CONTACT_DONE_SIGNAL)
E_INIT_GDBUS_METHOD_ASYNC_STRING__STRV (EGdbusBookIface, "getContactList", get_contact_list, __GET_CONTACT_LIST_METHOD, __GET_CONTACT_LIST_DONE_SIGNAL)
+ E_INIT_GDBUS_METHOD_ASYNC_STRING__STRV (EGdbusBookIface, "get_contact_list_uids", get_contact_list_uids, __GET_CONTACT_LIST_UIDS_METHOD, __GET_CONTACT_LIST_UIDS_DONE_SIGNAL)
E_INIT_GDBUS_METHOD_ASYNC_STRING__STRING(EGdbusBookIface, "addContact", add_contact, __ADD_CONTACT_METHOD, __ADD_CONTACT_DONE_SIGNAL)
E_INIT_GDBUS_METHOD_ASYNC_STRV__VOID (EGdbusBookIface, "removeContacts", remove_contacts, __REMOVE_CONTACTS_METHOD, __REMOVE_CONTACTS_DONE_SIGNAL)
E_INIT_GDBUS_METHOD_ASYNC_STRING__VOID (EGdbusBookIface, "modifyContact", modify_contact, __MODIFY_CONTACT_METHOD, __MODIFY_CONTACT_DONE_SIGNAL)
@@ -264,6 +268,26 @@ e_gdbus_book_call_get_contact_list_sync (GDBusProxy *proxy, const gchar *in_quer
}
void
+e_gdbus_book_call_get_contact_list_uids (GDBusProxy *proxy, const gchar *in_query, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data)
+{
+ e_gdbus_proxy_call_string ("get_contact_list_uids", e_gdbus_book_call_get_contact_list_uids, E_GDBUS_ASYNC_OP_KEEPER (proxy), in_query, cancellable, callback, user_data);
+}
+
+gboolean
+e_gdbus_book_call_get_contact_list_uids_finish (GDBusProxy *proxy, GAsyncResult *result, gchar ***out_uids, GError **error)
+{
+ return e_gdbus_proxy_finish_call_strv (E_GDBUS_ASYNC_OP_KEEPER (proxy), result, out_uids, error, e_gdbus_book_call_get_contact_list_uids);
+}
+
+gboolean
+e_gdbus_book_call_get_contact_list_uids_sync (GDBusProxy *proxy, const gchar *in_query, gchar ***out_uids, GCancellable *cancellable, GError **error)
+{
+ return e_gdbus_proxy_call_sync_string__strv (proxy, in_query, out_uids, cancellable, error,
+ e_gdbus_book_call_get_contact_list_uids,
+ e_gdbus_book_call_get_contact_list_uids_finish);
+}
+
+void
e_gdbus_book_call_add_contact (GDBusProxy *proxy, const gchar *in_vcard, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data)
{
e_gdbus_proxy_call_string ("addContact", e_gdbus_book_call_add_contact, E_GDBUS_ASYNC_OP_KEEPER (proxy), in_vcard, cancellable, callback, user_data);
@@ -505,6 +529,7 @@ DECLARE_EMIT_DONE_SIGNAL_0 (remove, __REMOVE_DONE_SIGNAL)
DECLARE_EMIT_DONE_SIGNAL_0 (refresh, __REFRESH_DONE_SIGNAL)
DECLARE_EMIT_DONE_SIGNAL_1 (get_contact, __GET_CONTACT_DONE_SIGNAL, const gchar *)
DECLARE_EMIT_DONE_SIGNAL_1 (get_contact_list, __GET_CONTACT_LIST_DONE_SIGNAL, const gchar * const *)
+DECLARE_EMIT_DONE_SIGNAL_1 (get_contact_list_uids, __GET_CONTACT_LIST_UIDS_DONE_SIGNAL, const gchar * const *)
DECLARE_EMIT_DONE_SIGNAL_1 (add_contact, __ADD_CONTACT_DONE_SIGNAL, const gchar *)
DECLARE_EMIT_DONE_SIGNAL_0 (remove_contacts, __REMOVE_CONTACTS_DONE_SIGNAL)
DECLARE_EMIT_DONE_SIGNAL_0 (modify_contact, __MODIFY_CONTACT_DONE_SIGNAL)
@@ -556,6 +581,7 @@ E_DECLARE_GDBUS_ASYNC_METHOD_0 (book, remove)
E_DECLARE_GDBUS_ASYNC_METHOD_0 (book, refresh)
E_DECLARE_GDBUS_ASYNC_METHOD_1_WITH_RETURN (book, getContact, uid, "s", vcard, "s")
E_DECLARE_GDBUS_ASYNC_METHOD_1_WITH_RETURN (book, getContactList, query, "s", vcards, "as")
+E_DECLARE_GDBUS_ASYNC_METHOD_1_WITH_RETURN (book, get_contact_list_uids, query, "s", uids, "as")
E_DECLARE_GDBUS_ASYNC_METHOD_1_WITH_RETURN (book, addContact, vcard, "s", uid, "s")
E_DECLARE_GDBUS_ASYNC_METHOD_1 (book, removeContacts, list, "as")
E_DECLARE_GDBUS_ASYNC_METHOD_1 (book, modifyContact, vcard, "s")
@@ -575,6 +601,7 @@ static const GDBusMethodInfo * const e_gdbus_book_method_info_pointers[] =
&E_DECLARED_GDBUS_METHOD_INFO_NAME (book, refresh),
&E_DECLARED_GDBUS_METHOD_INFO_NAME (book, getContact),
&E_DECLARED_GDBUS_METHOD_INFO_NAME (book, getContactList),
+ &E_DECLARED_GDBUS_METHOD_INFO_NAME (book, get_contact_list_uids),
&E_DECLARED_GDBUS_METHOD_INFO_NAME (book, addContact),
&E_DECLARED_GDBUS_METHOD_INFO_NAME (book, removeContacts),
&E_DECLARED_GDBUS_METHOD_INFO_NAME (book, modifyContact),
@@ -601,6 +628,7 @@ static const GDBusSignalInfo * const e_gdbus_book_signal_info_pointers[] =
&E_DECLARED_GDBUS_SIGNAL_INFO_NAME (book, refresh_done),
&E_DECLARED_GDBUS_SIGNAL_INFO_NAME (book, getContact_done),
&E_DECLARED_GDBUS_SIGNAL_INFO_NAME (book, getContactList_done),
+ &E_DECLARED_GDBUS_SIGNAL_INFO_NAME (book, get_contact_list_uids_done),
&E_DECLARED_GDBUS_SIGNAL_INFO_NAME (book, addContact_done),
&E_DECLARED_GDBUS_SIGNAL_INFO_NAME (book, removeContacts_done),
&E_DECLARED_GDBUS_SIGNAL_INFO_NAME (book, modifyContact_done),
@@ -806,6 +834,7 @@ e_gdbus_book_proxy_init (EGdbusBookProxy *proxy)
E_GDBUS_CONNECT_METHOD_DONE_SIGNAL_VOID (refresh);
E_GDBUS_CONNECT_METHOD_DONE_SIGNAL_STRING (get_contact);
E_GDBUS_CONNECT_METHOD_DONE_SIGNAL_STRV (get_contact_list);
+ E_GDBUS_CONNECT_METHOD_DONE_SIGNAL_STRV (get_contact_list_uids);
E_GDBUS_CONNECT_METHOD_DONE_SIGNAL_STRING (add_contact);
E_GDBUS_CONNECT_METHOD_DONE_SIGNAL_VOID (remove_contacts);
E_GDBUS_CONNECT_METHOD_DONE_SIGNAL_VOID (modify_contact);
diff --git a/addressbook/libegdbus/e-gdbus-book.h b/addressbook/libegdbus/e-gdbus-book.h
index ae0dd9e..4fa97da 100644
--- a/addressbook/libegdbus/e-gdbus-book.h
+++ b/addressbook/libegdbus/e-gdbus-book.h
@@ -134,6 +134,9 @@ struct _EGdbusBookIface
gboolean (*handle_get_contact_list) (EGdbusBook *object, GDBusMethodInvocation *invocation, const gchar *in_query);
void (*get_contact_list_done) (EGdbusBook *object, guint arg_opid, const GError *arg_error, gchar ***out_vcards);
+ gboolean (*handle_get_contact_list_uids)(EGdbusBook *object, GDBusMethodInvocation *invocation, const gchar *in_query);
+ void (*get_contact_list_uids_done) (EGdbusBook *object, guint arg_opid, const GError *arg_error, gchar ***out_uids);
+
gboolean (*handle_add_contact) (EGdbusBook *object, GDBusMethodInvocation *invocation, const gchar *in_vcard);
void (*add_contact_done) (EGdbusBook *object, guint arg_opid, const GError *arg_error, gchar **out_uid);
@@ -182,6 +185,10 @@ void e_gdbus_book_call_get_contact_list (GDBusProxy *proxy, const gchar *in_que
gboolean e_gdbus_book_call_get_contact_list_finish (GDBusProxy *proxy, GAsyncResult *result, gchar ***out_vcards, GError **error);
gboolean e_gdbus_book_call_get_contact_list_sync (GDBusProxy *proxy, const gchar *in_query, gchar ***out_vcards, GCancellable *cancellable, GError **error);
+void e_gdbus_book_call_get_contact_list_uids (GDBusProxy *proxy, const gchar *in_query, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data);
+gboolean e_gdbus_book_call_get_contact_list_uids_finish (GDBusProxy *proxy, GAsyncResult *result, gchar ***out_uids, GError **error);
+gboolean e_gdbus_book_call_get_contact_list_uids_sync (GDBusProxy *proxy, const gchar *in_query, gchar ***out_uids, GCancellable *cancellable, GError **error);
+
void e_gdbus_book_call_add_contact (GDBusProxy *proxy, const gchar *in_vcard, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data);
gboolean e_gdbus_book_call_add_contact_finish (GDBusProxy *proxy, GAsyncResult *result, gchar **out_uid, GError **error);
gboolean e_gdbus_book_call_add_contact_sync (GDBusProxy *proxy, const gchar *in_vcard, gchar **out_uid, GCancellable *cancellable, GError **error);
@@ -230,6 +237,7 @@ gboolean e_gdbus_book_call_close_sync (GDBusProxy *proxy, GCancellable *cancella
#define e_gdbus_book_complete_refresh e_gdbus_complete_async_method
#define e_gdbus_book_complete_get_contact e_gdbus_complete_async_method
#define e_gdbus_book_complete_get_contact_list e_gdbus_complete_async_method
+#define e_gdbus_book_complete_get_contact_list_uids e_gdbus_complete_async_method
#define e_gdbus_book_complete_add_contact e_gdbus_complete_async_method
#define e_gdbus_book_complete_remove_contacts e_gdbus_complete_async_method
#define e_gdbus_book_complete_modify_contact e_gdbus_complete_async_method
@@ -246,6 +254,7 @@ void e_gdbus_book_emit_remove_done (EGdbusBook *object, guint arg_opid, const
void e_gdbus_book_emit_refresh_done (EGdbusBook *object, guint arg_opid, const GError *arg_error);
void e_gdbus_book_emit_get_contact_done (EGdbusBook *object, guint arg_opid, const GError *arg_error, const gchar *out_vcard);
void e_gdbus_book_emit_get_contact_list_done (EGdbusBook *object, guint arg_opid, const GError *arg_error, const gchar * const *out_vcards);
+void e_gdbus_book_emit_get_contact_list_uids_done (EGdbusBook *object, guint arg_opid, const GError *arg_error, const gchar * const *out_uids);
void e_gdbus_book_emit_add_contact_done (EGdbusBook *object, guint arg_opid, const GError *arg_error, const gchar *out_uid);
void e_gdbus_book_emit_remove_contacts_done (EGdbusBook *object, guint arg_opid, const GError *arg_error);
void e_gdbus_book_emit_modify_contact_done (EGdbusBook *object, guint arg_opid, const GError *arg_error);
diff --git a/tests/libebook/client/test-client-async.c b/tests/libebook/client/test-client-async.c
index e3cc419..3e01758 100644
--- a/tests/libebook/client/test-client-async.c
+++ b/tests/libebook/client/test-client-async.c
@@ -7,9 +7,39 @@
#include "client-test-utils.h"
static void
+print_all_uids_cb (GObject *source_object, GAsyncResult *result, gpointer user_data)
+{
+ EBookClient *book_client;
+ GSList *uids = NULL, *u;
+ GError *error = NULL;
+
+ book_client = E_BOOK_CLIENT (source_object);
+ g_return_if_fail (book_client != NULL);
+
+ if (!e_book_client_get_contacts_uids_finish (book_client, result, &uids, &error)) {
+ report_error ("get contacts uids finish", &error);
+ stop_main_loop (1);
+ return;
+ }
+
+ for (u = uids; u; u = u->next) {
+ const gchar *uid = u->data;
+
+ g_print (" uid:'%s'\n", uid);
+ }
+
+ g_slist_foreach (uids, (GFunc) g_free, NULL);
+ g_slist_free (uids);
+
+ stop_main_loop (0);
+}
+
+static void
print_all_emails_cb (GObject *source_object, GAsyncResult *result, gpointer user_data)
{
EBookClient *book_client;
+ EBookQuery *query;
+ gchar *sexp;
GSList *contacts = NULL, *c;
GError *error = NULL;
@@ -31,7 +61,13 @@ print_all_emails_cb (GObject *source_object, GAsyncResult *result, gpointer user
g_slist_foreach (contacts, (GFunc) g_object_unref, NULL);
g_slist_free (contacts);
- stop_main_loop (0);
+ query = e_book_query_field_exists (E_CONTACT_FULL_NAME);
+ sexp = e_book_query_to_string (query);
+ e_book_query_unref (query);
+
+ e_book_client_get_contacts_uids (book_client, sexp, NULL, print_all_uids_cb, NULL);
+
+ g_free (sexp);
}
static void
diff --git a/tests/libebook/client/test-client.c b/tests/libebook/client/test-client.c
index 45011ab..5866bc4 100644
--- a/tests/libebook/client/test-client.c
+++ b/tests/libebook/client/test-client.c
@@ -7,6 +7,40 @@
#include "client-test-utils.h"
static void
+print_all_uids (EBookClient *book)
+{
+ GError *error = NULL;
+ EBookQuery *query;
+ gchar *sexp;
+ gboolean result;
+ GSList *uids, *u;
+
+ query = e_book_query_field_exists (E_CONTACT_FULL_NAME);
+ sexp = e_book_query_to_string (query);
+ e_book_query_unref (query);
+
+ result = e_book_client_get_contacts_uids_sync (book, sexp, &uids, NULL, &error);
+
+ g_free (sexp);
+
+ if (!result) {
+ fprintf (stderr, "Error getting uid list: %s\n", error ? error->message : "Unknown error");
+ if (error)
+ g_error_free (error);
+ exit (1);
+ }
+
+ for (u = uids; u; u = u->next) {
+ const gchar *uid = u->data;
+
+ g_print (" uid:'%s'\n", uid);
+ }
+
+ g_slist_foreach (uids, (GFunc) g_free, NULL);
+ g_slist_free (uids);
+}
+
+static void
print_all_emails (EBookClient *book)
{
GError *error = NULL;
@@ -76,6 +110,9 @@ main (gint argc, gchar **argv)
printf ("printing all contacts\n");
print_all_emails (book_client);
+ printf ("printing all uids\n");
+ print_all_uids (book_client);
+
g_object_unref (book_client);
return 0;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]