[evolution-data-server] e-book-client: add e_book_client_add_contacts*() methods
- From: Christophe Dumez <cdumez src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [evolution-data-server] e-book-client: add e_book_client_add_contacts*() methods
- Date: Sat, 8 Oct 2011 07:10:22 +0000 (UTC)
commit e91992d774039224aceef2dd5c7d2d0f2baf366b
Author: Christophe Dumez <christophe dumez intel com>
Date: Tue Sep 27 13:35:36 2011 +0300
e-book-client: add e_book_client_add_contacts*() methods
Enables optimizations for batch additions of contacts such as
less DBus round trips and use of database transactions in file
backend.
addressbook/backends/file/e-book-backend-file.c | 185 +++++++++++-----
.../backends/google/e-book-backend-google.c | 42 +++-
addressbook/backends/ldap/e-book-backend-ldap.c | 61 +++--
addressbook/backends/vcf/e-book-backend-vcf.c | 35 +++-
.../backends/webdav/e-book-backend-webdav.c | 51 +++--
addressbook/libebook/e-book-client.c | 233 ++++++++++++++++----
addressbook/libebook/e-book-client.h | 4 +
addressbook/libebook/e-book.c | 40 +++--
addressbook/libedata-book/e-book-backend-sync.c | 50 ++--
addressbook/libedata-book/e-book-backend-sync.h | 4 +-
addressbook/libedata-book/e-book-backend.c | 22 +-
addressbook/libedata-book/e-book-backend.h | 4 +-
addressbook/libedata-book/e-data-book.c | 58 +++--
addressbook/libedata-book/e-data-book.h | 2 +-
addressbook/libegdbus/e-gdbus-book.c | 48 ++--
addressbook/libegdbus/e-gdbus-book.h | 14 +-
16 files changed, 587 insertions(+), 266 deletions(-)
---
diff --git a/addressbook/backends/file/e-book-backend-file.c b/addressbook/backends/file/e-book-backend-file.c
index 38652b8..da34e5a 100644
--- a/addressbook/backends/file/e-book-backend-file.c
+++ b/addressbook/backends/file/e-book-backend-file.c
@@ -296,79 +296,133 @@ set_revision (EContact *contact)
}
+/**
+ * This method will return TRUE if all the contacts were properly created.
+ * If at least one contact fails, the method will return FALSE, all
+ * changes will be reverted (the @contacts list will stay empty) and
+ * @perror will be set.
+ */
static gboolean
do_create (EBookBackendFile *bf,
- const gchar *vcard_req,
- EContact **contact,
+ const GSList *vcards_req,
+ GSList **contacts,
GError **perror)
{
- DB *db = bf->priv->file_db;
- DBT id_dbt, vcard_dbt;
- gint db_error;
- gchar *id;
- gchar *vcard;
- const gchar *rev;
+ DB *db = bf->priv->file_db;
+ DB_ENV *env = bf->priv->env;
+ DB_TXN *txn = NULL;
+ GSList *slist = NULL;
+ const GSList *l;
+ gint db_error = 0;
g_assert (bf);
- g_assert (vcard_req);
- g_assert (contact);
+ g_assert (vcards_req);
if (!db) {
g_propagate_error (perror, EDB_NOT_OPENED_ERROR);
return FALSE;
}
- id = e_book_backend_file_create_unique_id ();
+ /* Begin transaction */
+ db_error = env->txn_begin(env, NULL, &txn, 0);
+ if (db_error != 0) {
+ g_warning (G_STRLOC ": env->txn_begin failed with %s", db_strerror (db_error));
+ db_error_to_gerror (db_error, perror);
+ return FALSE;
+ }
+
+ for (l = vcards_req; l != NULL; l = l->next) {
+ DBT id_dbt, vcard_dbt;
+ gchar *id;
+ gchar *vcard;
+ const gchar *rev;
+ const gchar *vcard_req;
+ EContact *contact;
- string_to_dbt (id, &id_dbt);
+ vcard_req = (const gchar*) l->data;
- *contact = e_contact_new_from_vcard_with_uid (vcard_req, id);
- rev = e_contact_get_const (*contact, E_CONTACT_REV);
- if (!(rev && *rev))
- set_revision (*contact);
+ id = e_book_backend_file_create_unique_id ();
- vcard = e_vcard_to_string (E_VCARD (*contact), EVC_FORMAT_VCARD_30);
+ string_to_dbt (id, &id_dbt);
- string_to_dbt (vcard, &vcard_dbt);
+ contact = e_contact_new_from_vcard_with_uid (vcard_req, id);
- db_error = db->put (db, NULL, &id_dbt, &vcard_dbt, 0);
+ rev = e_contact_get_const (contact, E_CONTACT_REV);
+ if (!(rev && *rev))
+ set_revision (contact);
- g_free (vcard);
+ vcard = e_vcard_to_string (E_VCARD (contact), EVC_FORMAT_VCARD_30);
- if (0 == db_error) {
- db_error = db->sync (db, 0);
- if (db_error != 0) {
- g_warning ("db->sync failed with %s", db_strerror (db_error));
+ string_to_dbt (vcard, &vcard_dbt);
+
+ db_error = db->put (db, txn, &id_dbt, &vcard_dbt, 0);
+
+ g_free (vcard);
+ g_free (id);
+
+ if (db_error == 0) {
+ /* Contact was added successfully, add it to the return list */
+ if (contacts != NULL)
+ slist = g_slist_prepend (slist, contact);
+ } else {
+ /* Contact could not be added */
+ g_warning (G_STRLOC ": db->put failed with %s", db_strerror (db_error));
+ g_object_unref (contact);
+ db_error_to_gerror (db_error, perror);
+
+ /* Abort as soon as an error occurs */
+ break;
+ }
+ }
+
+ if (db_error == 0) {
+ /* Commit transaction */
+ db_error = txn->commit (txn, 0);
+ if (db_error == 0) {
+ /* Flush cache information to disk */
+ if (db->sync (db, 0) != 0) {
+ g_warning ("db->sync failed with %s", db_strerror (db_error));
+ }
+ } else {
+ g_warning (G_STRLOC ": txn->commit failed with %s", db_strerror (db_error));
+ db_error_to_gerror (db_error, perror);
}
} else {
- g_warning (G_STRLOC ": db->put failed with %s", db_strerror (db_error));
- g_object_unref (*contact);
- *contact = NULL;
+ /* Rollback transaction */
+ txn->abort (txn);
}
- g_free (id);
- db_error_to_gerror (db_error, perror);
+ if (db_error == 0) {
+ if (contacts != NULL)
+ *contacts = g_slist_reverse (slist);
+
+ return TRUE;
+ } else {
+ if (contacts != NULL)
+ *contacts = NULL;
- return db_error == 0;
+ e_util_free_object_slist (slist);
+ return FALSE;
+ }
}
static void
-e_book_backend_file_create_contact (EBookBackendSync *backend,
- EDataBook *book,
- GCancellable *cancellable,
- const gchar *vcard,
- EContact **contact,
- GError **perror)
+e_book_backend_file_create_contacts (EBookBackendSync *backend,
+ EDataBook *book,
+ GCancellable *cancellable,
+ const GSList *vcards,
+ GSList **added_contacts,
+ GError **perror)
{
EBookBackendFile *bf = E_BOOK_BACKEND_FILE (backend);
- if (do_create (bf, vcard, contact, perror)) {
+ if (do_create (bf, vcards, added_contacts, perror)) {
GError *error = NULL;
- if (!e_book_backend_sqlitedb_add_contact (bf->priv->sqlitedb,
+ if (!e_book_backend_sqlitedb_add_contacts (bf->priv->sqlitedb,
SQLITEDB_FOLDER_ID,
- *contact, FALSE, &error)) {
- g_warning ("Failed to add contact to summary: %s", error->message);
+ *added_contacts, FALSE, &error)) {
+ g_warning ("Failed to add contacts to summary: %s", error->message);
g_error_free (error);
}
}
@@ -1219,18 +1273,31 @@ e_book_backend_file_open (EBookBackendSync *backend,
(gpointer (*)(gpointer , gsize)) g_try_realloc,
g_free);
+ /* Make sure the database directory is created
+ or env->open will fail */
+ if (!only_if_exists) {
+ if (!create_directory (dirname, perror)) {
+ g_warning ("failed to create directory at %s", dirname);
+ G_UNLOCK (global_env);
+ g_free (dirname);
+ g_free (filename);
+ return;
+ }
+ }
+
/*
- * We need either DB_INIT_CDB or DB_INIT_LOCK, because we will have
- * multiple threads reading and writing concurrently without
- * any locking above libdb.
+ * DB_INIT_TXN enables transaction support. It requires DB_INIT_LOCK to
+ * initialize the locking subsystem and DB_INIT_LOG for the logging
+ * subsystem.
+ *
+ * DB_INIT_MPOOL enables the in-memory cache.
*
- * DB_INIT_CDB enforces multiple reader/single writer by locking inside
- * the database. It is used instead of DB_INIT_LOCK because DB_INIT_LOCK
- * may deadlock, which would have to be called in a separate thread.
- * Considered too complicated for not enough gain (= concurrent writes)
- * at this point.
+ * Note that we need either DB_INIT_CDB or DB_INIT_LOCK, because we will
+ * have multiple threads reading and writing concurrently without
+ * any locking above libdb. Right now DB_INIT_LOCK is used because
+ * DB_INIT_TXN conflicts with DB_INIT_CDB.
*/
- db_error = (*env->open) (env, NULL, DB_INIT_CDB | DB_CREATE | DB_INIT_MPOOL | DB_PRIVATE | DB_THREAD, 0);
+ db_error = (*env->open) (env, dirname, DB_INIT_LOCK | DB_INIT_TXN | DB_INIT_LOG | 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 %s", db_strerror (db_error));
@@ -1257,7 +1324,7 @@ e_book_backend_file_open (EBookBackendSync *backend,
return;
}
- db_error = (*db->open) (db, NULL, filename, NULL, DB_HASH, DB_THREAD, 0666);
+ db_error = (*db->open) (db, NULL, filename, NULL, DB_HASH, DB_THREAD | DB_AUTO_COMMIT, 0666);
if (db_error == DB_OLD_VERSION) {
db_error = e_db3_utils_upgrade_format (filename);
@@ -1280,7 +1347,7 @@ e_book_backend_file_open (EBookBackendSync *backend,
return;
}
- db_error = (*db->open) (db, NULL, filename, NULL, DB_HASH, DB_THREAD, 0666);
+ db_error = (*db->open) (db, NULL, filename, NULL, DB_HASH, DB_THREAD | DB_AUTO_COMMIT, 0666);
}
if (db_error == 0) {
@@ -1296,7 +1363,7 @@ e_book_backend_file_open (EBookBackendSync *backend,
return;
}
- db_error = (*db->open) (db, NULL, filename, NULL, DB_HASH, DB_RDONLY | DB_THREAD, 0666);
+ db_error = (*db->open) (db, NULL, filename, NULL, DB_HASH, DB_RDONLY | DB_THREAD | DB_AUTO_COMMIT, 0666);
if (db_error != 0 && !only_if_exists) {
@@ -1319,7 +1386,7 @@ e_book_backend_file_open (EBookBackendSync *backend,
return;
}
- db_error = (*db->open) (db, NULL, filename, NULL, DB_HASH, DB_CREATE | DB_THREAD, 0666);
+ db_error = (*db->open) (db, NULL, filename, NULL, DB_HASH, DB_CREATE | DB_THREAD | DB_AUTO_COMMIT, 0666);
if (db_error != 0) {
db->close (db, 0);
g_warning ("db->open (... %s ... DB_CREATE ...) failed with %s", filename, db_strerror (db_error));
@@ -1346,12 +1413,12 @@ e_book_backend_file_open (EBookBackendSync *backend,
#ifdef CREATE_DEFAULT_VCARD
if (create_default_vcard) {
- EContact *contact = NULL;
+ GSList l;
+ l.data = XIMIAN_VCARD;
+ l.next = NULL;
- if (!do_create (bf, XIMIAN_VCARD, &contact, NULL))
+ if (!do_create (bf, &l, NULL, NULL))
g_warning ("Cannot create default contact");
- if (contact)
- g_object_unref (contact);
}
#endif
@@ -1474,7 +1541,7 @@ e_book_backend_file_get_backend_property (EBookBackendSync *backend,
g_return_val_if_fail (prop_value != NULL, FALSE);
if (g_str_equal (prop_name, CLIENT_BACKEND_PROPERTY_CAPABILITIES)) {
- *prop_value = g_strdup ("local,do-initial-query,bulk-removes,contact-lists");
+ *prop_value = g_strdup ("local,do-initial-query,bulk-adds,bulk-removes,contact-lists");
} else if (g_str_equal (prop_name, BOOK_BACKEND_PROPERTY_REQUIRED_FIELDS)) {
*prop_value = g_strdup (e_contact_field_name (E_CONTACT_FILE_AS));
} else if (g_str_equal (prop_name, BOOK_BACKEND_PROPERTY_SUPPORTED_FIELDS)) {
@@ -1680,7 +1747,7 @@ e_book_backend_file_class_init (EBookBackendFileClass *klass)
sync_class->open_sync = e_book_backend_file_open;
sync_class->remove_sync = e_book_backend_file_remove;
sync_class->get_backend_property_sync = e_book_backend_file_get_backend_property;
- sync_class->create_contact_sync = e_book_backend_file_create_contact;
+ sync_class->create_contacts_sync = e_book_backend_file_create_contacts;
sync_class->remove_contacts_sync = e_book_backend_file_remove_contacts;
sync_class->modify_contact_sync = e_book_backend_file_modify_contact;
sync_class->get_contact_sync = e_book_backend_file_get_contact;
diff --git a/addressbook/backends/google/e-book-backend-google.c b/addressbook/backends/google/e-book-backend-google.c
index 1438959..c6f490d 100644
--- a/addressbook/backends/google/e-book-backend-google.c
+++ b/addressbook/backends/google/e-book-backend-google.c
@@ -1203,22 +1203,24 @@ create_contact_finish (CreateContactData *data,
GDataContactsContact *new_contact,
const GError *gdata_error)
{
- EContact *e_contact;
-
__debug__ (G_STRFUNC);
if (gdata_error == NULL) {
/* Add the new contact to the cache. If uploading the photo was successful, the photo's data is stored on the contact as the "photo"
* key, which the cache will pick up and store. */
+ EContact *e_contact;
+ GSList added_contacts = {NULL,};
e_contact = cache_add_contact (data->backend, GDATA_ENTRY (new_contact));
- e_data_book_respond_create (data->book, data->opid, NULL, e_contact);
+
+ added_contacts.data = e_contact;
+ e_data_book_respond_create_contacts (data->book, data->opid, NULL, &added_contacts);
g_object_unref (e_contact);
} else {
GError *book_error = NULL;
/* Report the error. */
data_book_error_from_gdata_error (&book_error, gdata_error);
- e_data_book_respond_create (data->book, data->opid, book_error, NULL);
+ e_data_book_respond_create_contacts (data->book, data->opid, book_error, NULL);
}
finish_operation (data->backend, data->opid, gdata_error);
@@ -1367,24 +1369,35 @@ finish:
* operation responded to in create_contact_photo_query_cb().
*/
static void
-e_book_backend_google_create_contact (EBookBackend *backend,
- EDataBook *book,
- guint32 opid,
- GCancellable *cancellable,
- const gchar *vcard_str)
+e_book_backend_google_create_contacts (EBookBackend *backend,
+ EDataBook *book,
+ guint32 opid,
+ GCancellable *cancellable,
+ const GSList *vcards)
{
EBookBackendGooglePrivate *priv = E_BOOK_BACKEND_GOOGLE (backend)->priv;
EContact *contact;
GDataEntry *entry;
gchar *xml;
CreateContactData *data;
+ const gchar *vcard_str = (const gchar *) vcards->data;
+
+ /* We make the assumption that the vCard list we're passed is always exactly one element long, since we haven't specified "bulk-adds"
+ * in our static capability list. This simplifies a lot of the logic, especially around asynchronous results. */
+ if (vcards->next != NULL) {
+ e_data_book_respond_create_contacts (book, opid,
+ EDB_ERROR_EX (NOT_SUPPORTED,
+ _("The backend does not support bulk additions")),
+ NULL);
+ return;
+ }
__debug__ (G_STRFUNC);
__debug__ ("Creating: %s", vcard_str);
if (!e_backend_get_online (E_BACKEND (backend))) {
- e_data_book_respond_create (book, opid, EDB_ERROR (OFFLINE_UNAVAILABLE), NULL);
+ e_data_book_respond_create_contacts (book, opid, EDB_ERROR (OFFLINE_UNAVAILABLE), NULL);
return;
}
@@ -1487,6 +1500,13 @@ e_book_backend_google_remove_contacts (EBookBackend *backend,
/* We make the assumption that the ID list we're passed is always exactly one element long, since we haven't specified "bulk-removes"
* in our static capability list. This simplifies a lot of the logic, especially around asynchronous results. */
+ if (id_list->next != NULL) {
+ e_data_book_respond_remove_contacts (book, opid,
+ EDB_ERROR_EX (NOT_SUPPORTED,
+ _("The backend does not support bulk removals")),
+ NULL);
+ return;
+ }
g_return_if_fail (!id_list->next);
/* Get the contact and associated GDataEntry from the cache */
@@ -2542,7 +2562,7 @@ e_book_backend_google_class_init (EBookBackendGoogleClass *klass)
backend_class->start_book_view = e_book_backend_google_start_book_view;
backend_class->stop_book_view = e_book_backend_google_stop_book_view;
backend_class->remove = e_book_backend_google_remove;
- backend_class->create_contact = e_book_backend_google_create_contact;
+ backend_class->create_contacts = e_book_backend_google_create_contacts;
backend_class->remove_contacts = e_book_backend_google_remove_contacts;
backend_class->modify_contact = e_book_backend_google_modify_contact;
backend_class->get_contact = e_book_backend_google_get_contact;
diff --git a/addressbook/backends/ldap/e-book-backend-ldap.c b/addressbook/backends/ldap/e-book-backend-ldap.c
index 1412cfd..f10a294 100644
--- a/addressbook/backends/ldap/e-book-backend-ldap.c
+++ b/addressbook/backends/ldap/e-book-backend-ldap.c
@@ -1553,24 +1553,25 @@ create_contact_handler (LDAPOp *op,
EBookBackendLDAP *bl = E_BOOK_BACKEND_LDAP (op->backend);
gchar *ldap_error_msg;
gint ldap_error;
+ GSList added_contacts = {NULL,};
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_create (op->book,
- op->opid,
- EDB_ERROR_NOT_CONNECTED (),
- NULL);
+ e_data_book_respond_create_contacts (op->book,
+ op->opid,
+ EDB_ERROR_NOT_CONNECTED (),
+ NULL);
ldap_op_finished (op);
return;
}
g_static_rec_mutex_unlock (&eds_ldap_handler_lock);
if (LDAP_RES_ADD != ldap_msgtype (res)) {
- e_data_book_respond_create (op->book,
- op->opid,
- EDB_ERROR_MSG_TYPE (ldap_msgtype (res)),
- NULL);
+ e_data_book_respond_create_contacts (op->book,
+ op->opid,
+ EDB_ERROR_MSG_TYPE (ldap_msgtype (res)),
+ NULL);
ldap_op_finished (op);
return;
}
@@ -1590,10 +1591,11 @@ create_contact_handler (LDAPOp *op,
ldap_memfree (ldap_error_msg);
/* and lastly respond */
- e_data_book_respond_create (op->book,
- op->opid,
- ldap_error_to_response (ldap_error),
- create_op->new_contact);
+ added_contacts.data = create_op->new_contact;
+ e_data_book_respond_create_contacts (op->book,
+ op->opid,
+ ldap_error_to_response (ldap_error),
+ &added_contacts);
ldap_op_finished (op);
}
@@ -1609,11 +1611,11 @@ create_contact_dtor (LDAPOp *op)
}
static void
-e_book_backend_ldap_create_contact (EBookBackend *backend,
- EDataBook *book,
- guint32 opid,
- GCancellable *cancellable,
- const gchar *vcard)
+e_book_backend_ldap_create_contacts (EBookBackend *backend,
+ EDataBook *book,
+ guint32 opid,
+ GCancellable *cancellable,
+ const GSList *vcards)
{
LDAPCreateOp *create_op = g_new0 (LDAPCreateOp, 1);
EBookBackendLDAP *bl = E_BOOK_BACKEND_LDAP (backend);
@@ -1623,16 +1625,27 @@ e_book_backend_ldap_create_contact (EBookBackend *backend,
GPtrArray *mod_array;
LDAPMod **ldap_mods;
gchar *new_uid;
+ const gchar *vcard = (const gchar *) vcards->data;
+
+ /* We make the assumption that the vCard list we're passed is always exactly one element long, since we haven't specified "bulk-adds"
+ * in our static capability list. This is because there is no clean way to roll back changes in case of an error. */
+ if (vcards->next != NULL) {
+ e_data_book_respond_create_contacts (book, opid,
+ EDB_ERROR_EX (NOT_SUPPORTED,
+ _("The backend does not support bulk additions")),
+ NULL);
+ return;
+ }
if (!e_backend_get_online (E_BACKEND (backend))) {
- e_data_book_respond_create (book, opid, EDB_ERROR (REPOSITORY_OFFLINE), NULL);
+ e_data_book_respond_create_contacts (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_create (book, opid, EDB_ERROR_NOT_CONNECTED (), NULL);
+ e_data_book_respond_create_contacts (book, opid, EDB_ERROR_NOT_CONNECTED (), NULL);
return;
}
g_static_rec_mutex_unlock (&eds_ldap_handler_lock);
@@ -1730,10 +1743,10 @@ e_book_backend_ldap_create_contact (EBookBackend *backend,
free_mods (mod_array);
if (LDAP_SUCCESS != err) {
- e_data_book_respond_create (create_op->op.book,
- opid,
- ldap_error_to_response (err),
- NULL);
+ e_data_book_respond_create_contacts (create_op->op.book,
+ opid,
+ ldap_error_to_response (err),
+ NULL);
create_contact_dtor ((LDAPOp *) create_op);
return;
} else {
@@ -5669,7 +5682,7 @@ e_book_backend_ldap_class_init (EBookBackendLDAPClass *klass)
parent_class->remove = e_book_backend_ldap_remove;
parent_class->get_backend_property = e_book_backend_ldap_get_backend_property;
- parent_class->create_contact = e_book_backend_ldap_create_contact;
+ parent_class->create_contacts = e_book_backend_ldap_create_contacts;
parent_class->remove_contacts = e_book_backend_ldap_remove_contacts;
parent_class->modify_contact = e_book_backend_ldap_modify_contact;
parent_class->get_contact = e_book_backend_ldap_get_contact;
diff --git a/addressbook/backends/vcf/e-book-backend-vcf.c b/addressbook/backends/vcf/e-book-backend-vcf.c
index fb84ec6..9318409 100644
--- a/addressbook/backends/vcf/e-book-backend-vcf.c
+++ b/addressbook/backends/vcf/e-book-backend-vcf.c
@@ -56,6 +56,7 @@
#define d(x)
#define EDB_ERROR(_code) e_data_book_create_error (E_DATA_BOOK_STATUS_ ## _code, NULL)
+#define EDB_ERROR_EX(_code, _msg) e_data_book_create_error (E_DATA_BOOK_STATUS_ ## _code, _msg)
G_DEFINE_TYPE (EBookBackendVCF, e_book_backend_vcf, E_TYPE_BOOK_BACKEND_SYNC)
@@ -271,17 +272,30 @@ do_create (EBookBackendVCF *bvcf,
}
static void
-e_book_backend_vcf_create_contact (EBookBackendSync *backend,
+e_book_backend_vcf_create_contacts (EBookBackendSync *backend,
EDataBook *book,
GCancellable *cancellable,
- const gchar *vcard,
- EContact **contact,
+ const GSList *vcards,
+ GSList **added_contacts,
GError **perror)
{
+ EContact *contact = NULL;
EBookBackendVCF *bvcf = E_BOOK_BACKEND_VCF (backend);
+ const gchar *vcard = vcards->data;
+
+ /* We make the assumption that the vCard list we're passed is always exactly one element long, since we haven't specified "bulk-adds"
+ * in our static capability list. */
+ if (vcards->next != NULL) {
+ g_propagate_error (perror,
+ EDB_ERROR_EX (NOT_SUPPORTED,
+ _("The backend does not support bulk additions")));
+ return;
+ }
- *contact = do_create(bvcf, vcard, TRUE);
- if (!*contact) {
+ contact = do_create(bvcf, vcard, TRUE);
+ if (added_contacts) {
+ *added_contacts = g_slist_append (*added_contacts, contact);
+ } else {
/* XXX need a different call status for this case, i
* think */
g_propagate_error (perror, EDB_ERROR (CONTACT_NOT_FOUND));
@@ -301,6 +315,15 @@ e_book_backend_vcf_remove_contacts (EBookBackendSync *backend,
const gchar *id = id_list->data;
GList *elem;
+ /* We make the assumption that the ID list we're passed is always exactly one element long, since we haven't specified "bulk-removes"
+ * in our static capability list. */
+ if (id_list->next != NULL) {
+ g_propagate_error (perror,
+ EDB_ERROR_EX (NOT_SUPPORTED,
+ _("The backend does not support bulk removals")));
+ return;
+ }
+
g_mutex_lock (bvcf->priv->mutex);
elem = g_hash_table_lookup (bvcf->priv->contacts, id);
if (!elem) {
@@ -734,7 +757,7 @@ e_book_backend_vcf_class_init (EBookBackendVCFClass *klass)
sync_class->open_sync = e_book_backend_vcf_open;
sync_class->get_backend_property_sync = e_book_backend_vcf_get_backend_property;
- sync_class->create_contact_sync = e_book_backend_vcf_create_contact;
+ sync_class->create_contacts_sync = e_book_backend_vcf_create_contacts;
sync_class->remove_contacts_sync = e_book_backend_vcf_remove_contacts;
sync_class->modify_contact_sync = e_book_backend_vcf_modify_contact;
sync_class->get_contact_sync = e_book_backend_vcf_get_contact;
diff --git a/addressbook/backends/webdav/e-book-backend-webdav.c b/addressbook/backends/webdav/e-book-backend-webdav.c
index a399441..2b0fc0d 100644
--- a/addressbook/backends/webdav/e-book-backend-webdav.c
+++ b/addressbook/backends/webdav/e-book-backend-webdav.c
@@ -301,21 +301,33 @@ webdav_handle_auth_request (EBookBackendWebdav *webdav)
}
static void
-e_book_backend_webdav_create_contact (EBookBackend *backend,
- EDataBook *book,
- guint32 opid,
- GCancellable *cancellable,
- const gchar *vcard)
+e_book_backend_webdav_create_contacts (EBookBackend *backend,
+ EDataBook *book,
+ guint32 opid,
+ GCancellable *cancellable,
+ const GSList *vcards)
{
EBookBackendWebdav *webdav = E_BOOK_BACKEND_WEBDAV (backend);
EBookBackendWebdavPrivate *priv = webdav->priv;
EContact *contact;
gchar *uid;
guint status;
- gchar *status_reason = NULL;
+ gchar *status_reason = NULL;
+ const gchar *vcard = (const gchar *) vcards->data;
+ GSList added_contacts = {NULL,};
+
+ /* We make the assumption that the vCard list we're passed is always exactly one element long, since we haven't specified "bulk-adds"
+ * in our static capability list. This is because there is no clean way to roll back changes in case of an error. */
+ if (vcards->next != NULL) {
+ e_data_book_respond_create_contacts (book, opid,
+ EDB_ERROR_EX (NOT_SUPPORTED,
+ _("The backend does not support bulk additions")),
+ NULL);
+ return;
+ }
if (!e_backend_get_online (E_BACKEND (backend))) {
- e_data_book_respond_create (book, opid, EDB_ERROR (REPOSITORY_OFFLINE), NULL);
+ e_data_book_respond_create_contacts (book, opid, EDB_ERROR (REPOSITORY_OFFLINE), NULL);
return;
}
@@ -323,7 +335,7 @@ e_book_backend_webdav_create_contact (EBookBackend *backend,
* good enough for us */
uid = g_strdup_printf("%s%08X-%08X-%08X.vcf", priv->uri, rand(), rand(),
rand ());
-
+
contact = e_contact_new_from_vcard_with_uid (vcard, uid);
/* kill revision field (might have been set by some other backend) */
@@ -333,12 +345,12 @@ e_book_backend_webdav_create_contact (EBookBackend *backend,
if (status != 201 && status != 204) {
g_object_unref (contact);
if (status == 401 || status == 407) {
- e_data_book_respond_create (book, opid, webdav_handle_auth_request (webdav), NULL);
+ e_data_book_respond_create_contacts (book, opid, webdav_handle_auth_request (webdav), NULL);
} else {
- e_data_book_respond_create (book, opid,
- e_data_book_create_error_fmt (E_DATA_BOOK_STATUS_OTHER_ERROR,
- _("Create resource '%s' failed with HTTP status: %d (%s)"), uid, status, status_reason),
- NULL);
+ e_data_book_respond_create_contacts (book, opid,
+ e_data_book_create_error_fmt (E_DATA_BOOK_STATUS_OTHER_ERROR,
+ _("Create resource '%s' failed with HTTP status: %d (%s)"), uid, status, status_reason),
+ NULL);
}
g_free (uid);
g_free (status_reason);
@@ -358,7 +370,7 @@ e_book_backend_webdav_create_contact (EBookBackend *backend,
g_object_unref (contact);
if (new_contact == NULL) {
- e_data_book_respond_create (book, opid,
+ e_data_book_respond_create_contacts (book, opid,
EDB_ERROR (OTHER_ERROR), NULL);
g_free (uid);
return;
@@ -367,10 +379,11 @@ e_book_backend_webdav_create_contact (EBookBackend *backend,
}
e_book_backend_cache_add_contact (priv->cache, contact);
- e_data_book_respond_create (book, opid, EDB_ERROR (SUCCESS), contact);
- if (contact)
- g_object_unref (contact);
+ added_contacts.data = contact;
+ e_data_book_respond_create_contacts (book, opid, EDB_ERROR (SUCCESS), &added_contacts);
+
+ g_object_unref (contact);
g_free (uid);
}
@@ -449,7 +462,7 @@ e_book_backend_webdav_modify_contact (EBookBackend *backend,
gchar *status_reason = NULL;
if (!e_backend_get_online (E_BACKEND (backend))) {
- e_data_book_respond_create (book, opid,
+ e_data_book_respond_create_contacts (book, opid,
EDB_ERROR (REPOSITORY_OFFLINE), NULL);
g_object_unref (contact);
return;
@@ -1444,7 +1457,7 @@ e_book_backend_webdav_class_init (EBookBackendWebdavClass *klass)
backend_class->open = e_book_backend_webdav_open;
backend_class->get_backend_property = e_book_backend_webdav_get_backend_property;
- backend_class->create_contact = e_book_backend_webdav_create_contact;
+ backend_class->create_contacts = e_book_backend_webdav_create_contacts;
backend_class->remove_contacts = e_book_backend_webdav_remove_contacts;
backend_class->modify_contact = e_book_backend_webdav_modify_contact;
backend_class->get_contact = e_book_backend_webdav_get_contact;
diff --git a/addressbook/libebook/e-book-client.c b/addressbook/libebook/e-book-client.c
index 90df80e..9d6acfd 100644
--- a/addressbook/libebook/e-book-client.c
+++ b/addressbook/libebook/e-book-client.c
@@ -1273,15 +1273,18 @@ e_book_client_add_contact (EBookClient *client,
gpointer user_data)
{
gchar *vcard, *gdbus_vcard = NULL;
+ const gchar *strv[2];
g_return_if_fail (contact != NULL);
g_return_if_fail (E_IS_CONTACT (contact));
vcard = e_vcard_to_string (E_VCARD (contact), EVC_FORMAT_VCARD_30);
+ strv[0] = e_util_ensure_gdbus_string (vcard, &gdbus_vcard);
+ strv[1] = NULL;
- e_client_proxy_call_string (E_CLIENT (client), e_util_ensure_gdbus_string (vcard, &gdbus_vcard), cancellable, callback, user_data, e_book_client_add_contact,
- e_gdbus_book_call_add_contact,
- NULL, NULL, e_gdbus_book_call_add_contact_finish, NULL, NULL);
+ e_client_proxy_call_strv (E_CLIENT (client), strv, cancellable, callback, user_data, e_book_client_add_contact,
+ e_gdbus_book_call_add_contacts,
+ NULL, NULL, NULL, e_gdbus_book_call_add_contacts_finish, NULL);
g_free (vcard);
g_free (gdbus_vcard);
@@ -1311,17 +1314,17 @@ e_book_client_add_contact_finish (EBookClient *client,
GError **error)
{
gboolean res;
- gchar *out_uid = NULL;
+ gchar **out_uids = NULL;
- res = e_client_proxy_call_finish_string (E_CLIENT (client), result, &out_uid, error, e_book_client_add_contact);
+ res = e_client_proxy_call_finish_strv (E_CLIENT (client), result, &out_uids, error, e_book_client_add_contact);
- if (res && out_uid && added_uid) {
- *added_uid = out_uid;
+ if (res && out_uids && added_uid) {
+ *added_uid = g_strdup (out_uids[0]);
} else {
- g_free (out_uid);
if (added_uid)
*added_uid = NULL;
}
+ g_strfreev (out_uids);
return res;
}
@@ -1353,7 +1356,8 @@ e_book_client_add_contact_sync (EBookClient *client,
GError **error)
{
gboolean res;
- gchar *vcard, *gdbus_vcard = NULL, *out_uid = NULL;
+ gchar *vcard, *gdbus_vcard = NULL, **out_uids = NULL;
+ const gchar *strv[2];
g_return_val_if_fail (client != NULL, FALSE);
g_return_val_if_fail (E_IS_BOOK_CLIENT (client), FALSE);
@@ -1365,17 +1369,19 @@ e_book_client_add_contact_sync (EBookClient *client,
}
vcard = e_vcard_to_string (E_VCARD (contact), EVC_FORMAT_VCARD_30);
+ strv[0] = e_util_ensure_gdbus_string (vcard, &gdbus_vcard);
+ strv[1] = NULL;
- res = e_client_proxy_call_sync_string__string (E_CLIENT (client), e_util_ensure_gdbus_string (vcard, &gdbus_vcard), &out_uid, cancellable, error, e_gdbus_book_call_add_contact_sync);
+ res = e_client_proxy_call_sync_strv__strv (E_CLIENT (client), strv, &out_uids, cancellable, error, e_gdbus_book_call_add_contacts_sync);
- if (res && out_uid && added_uid) {
- *added_uid = out_uid;
+ if (res && out_uids && added_uid) {
+ *added_uid = g_strdup (out_uids[0]);
} else {
- g_free (out_uid);
if (added_uid)
*added_uid = NULL;
}
+ g_strfreev (out_uids);
g_free (vcard);
g_free (gdbus_vcard);
@@ -1383,6 +1389,155 @@ e_book_client_add_contact_sync (EBookClient *client,
}
/**
+ * e_book_client_add_contacts:
+ * @client: an #EBookClient
+ * @contacts: a #GSList of #EContact objects to add
+ * @cancellable: a #GCancellable; can be %NULL
+ * @callback: callback to call when a result is ready
+ * @user_data: user data for the @callback
+ *
+ * Adds @contacts to @client.
+ * The call is finished by e_book_client_add_contacts_finish()
+ * from the @callback.
+ *
+ * Since: 3.4
+ **/
+void
+e_book_client_add_contacts (EBookClient *client,
+ /* const */ GSList *contacts,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ gchar **array;
+ const GSList *l;
+ gint i = 0;
+
+ g_return_if_fail (contacts != NULL);
+
+ array = g_new0 (gchar *, g_slist_length (contacts) + 1);
+ for (l = contacts; l != NULL; l = l->next) {
+ gchar *vcard = e_vcard_to_string (E_VCARD (l->data), EVC_FORMAT_VCARD_30);
+ array[i++] = e_util_utf8_make_valid (vcard);
+ g_free (vcard);
+ }
+
+ e_client_proxy_call_strv (E_CLIENT (client), (const gchar * const *) array, cancellable, callback, user_data, e_book_client_add_contacts,
+ e_gdbus_book_call_add_contacts,
+ NULL, NULL, NULL, e_gdbus_book_call_add_contacts_finish, NULL);
+
+ g_strfreev (array);
+}
+
+/**
+ * e_book_client_add_contacts_finish:
+ * @client: an #EBookClient
+ * @result: a #GAsyncResult
+ * @added_uids: (out): UIDs of newly added contacts; can be %NULL
+ * @error: (out): a #GError to set an error, if any
+ *
+ * Finishes previous call of e_book_client_add_contacts() and
+ * sets @added_uids to the UIDs of newly added contacts if successful.
+ * This #GSList should be freed with e_client_util_free_string_slist().
+ *
+ * If any of the contacts cannot be inserted, all of the insertions will be
+ * reverted and this method will return %FALSE.
+ *
+ * Note: This is not modifying original #EContact objects.
+ *
+ * Returns: %TRUE if successful, %FALSE otherwise.
+ *
+ * Since: 3.4
+ **/
+gboolean
+e_book_client_add_contacts_finish (EBookClient *client,
+ GAsyncResult *result,
+ GSList **added_uids,
+ GError **error)
+{
+ gboolean res;
+ gchar **out_uids = NULL;
+
+ res = e_client_proxy_call_finish_strv (E_CLIENT (client), result, &out_uids, error, e_book_client_add_contacts);
+
+ if (res && out_uids && added_uids) {
+ *added_uids = e_client_util_strv_to_slist ((const gchar * const*) out_uids);
+ } else {
+ if (added_uids)
+ *added_uids = NULL;
+ }
+
+ g_strfreev (out_uids);
+
+ return res;
+}
+
+/**
+ * e_book_client_add_contacts_sync:
+ * @client: an #EBookClient
+ * @contacts: a #GSList of #EContact objects to add
+ * @added_uids: (out): UIDs of newly added contacts; can be %NULL
+ * @cancellable: a #GCancellable; can be %NULL
+ * @error: (out): a #GError to set an error, if any
+ *
+ * Adds @contacts to @client and
+ * sets @added_uids to the UIDs of newly added contacts if successful.
+ * This #GSList should be freed with e_client_util_free_string_slist().
+ *
+ * If any of the contacts cannot be inserted, all of the insertions will be
+ * reverted and this method will return %FALSE.
+ *
+ * Note: This is not modifying original @contacts, thus if it's needed,
+ * then use e_contact_set (contact, E_CONTACT_UID, new_uid).
+ *
+ * Returns: %TRUE if successful, %FALSE otherwise.
+ *
+ * Since: 3.4
+ **/
+gboolean
+e_book_client_add_contacts_sync (EBookClient *client,
+ /* const */ GSList *contacts,
+ GSList **added_uids,
+ GCancellable *cancellable,
+ GError **error)
+{
+ gboolean res;
+ gint i = 0;
+ gchar **array, **out_uids = NULL;
+ const GSList *l;
+
+ 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);
+
+ if (!client->priv->gdbus_book) {
+ set_proxy_gone_error (error);
+ return FALSE;
+ }
+
+ array = g_new0 (gchar *, g_slist_length (contacts) + 1);
+ for (l = contacts; l != NULL; l = l->next) {
+ gchar *vcard = e_vcard_to_string (E_VCARD (l->data), EVC_FORMAT_VCARD_30);
+ array[i++] = e_util_utf8_make_valid (vcard);
+ g_free (vcard);
+ }
+
+ res = e_client_proxy_call_sync_strv__strv (E_CLIENT (client), (const gchar * const*) array, &out_uids, cancellable, error, e_gdbus_book_call_add_contacts_sync);
+
+ if (res && out_uids && added_uids) {
+ *added_uids = e_client_util_strv_to_slist ((const gchar * const*) out_uids);
+ } else {
+ if (added_uids)
+ *added_uids = NULL;
+ }
+
+ g_strfreev (out_uids);
+ g_strfreev (array);
+
+ return res;
+}
+
+/**
* e_book_client_modify_contact:
* @client: an #EBookClient
* @contact: an #EContact
@@ -1501,7 +1656,7 @@ e_book_client_remove_contact (EBookClient *client,
gpointer user_data)
{
gchar *uid;
- const gchar *lst[2];
+ const gchar *strv[2];
g_return_if_fail (contact != NULL);
g_return_if_fail (E_IS_CONTACT (contact));
@@ -1509,10 +1664,10 @@ e_book_client_remove_contact (EBookClient *client,
uid = e_util_utf8_make_valid (e_contact_get_const ((EContact *) contact, E_CONTACT_UID));
g_return_if_fail (uid != NULL);
- lst[0] = uid;
- lst[1] = NULL;
+ strv[0] = uid;
+ strv[1] = NULL;
- e_client_proxy_call_strv (E_CLIENT (client), lst, cancellable, callback, user_data, e_book_client_remove_contact,
+ e_client_proxy_call_strv (E_CLIENT (client), strv, cancellable, callback, user_data, e_book_client_remove_contact,
e_gdbus_book_call_remove_contacts,
e_gdbus_book_call_remove_contacts_finish, NULL, NULL, NULL, NULL);
@@ -1560,7 +1715,7 @@ e_book_client_remove_contact_sync (EBookClient *client,
{
gboolean res;
gchar *uid;
- const gchar *lst[2];
+ const gchar *strv[2];
g_return_val_if_fail (client != NULL, FALSE);
g_return_val_if_fail (E_IS_BOOK_CLIENT (client), FALSE);
@@ -1576,10 +1731,10 @@ e_book_client_remove_contact_sync (EBookClient *client,
uid = e_util_utf8_make_valid (e_contact_get_const ((EContact *) contact, E_CONTACT_UID));
g_return_val_if_fail (uid != NULL, 0);
- lst[0] = uid;
- lst[1] = NULL;
+ strv[0] = uid;
+ strv[1] = NULL;
- res = e_client_proxy_call_sync_strv__void (E_CLIENT (client), lst, cancellable, error, e_gdbus_book_call_remove_contacts_sync);
+ res = e_client_proxy_call_sync_strv__void (E_CLIENT (client), strv, cancellable, error, e_gdbus_book_call_remove_contacts_sync);
g_free (uid);
@@ -1608,17 +1763,17 @@ e_book_client_remove_contact_by_uid (EBookClient *client,
gpointer user_data)
{
gchar *safe_uid;
- const gchar *lst[2];
+ const gchar *strv[2];
g_return_if_fail (uid != NULL);
safe_uid = e_util_utf8_make_valid (uid);
g_return_if_fail (safe_uid != NULL);
- lst[0] = safe_uid;
- lst[1] = NULL;
+ strv[0] = safe_uid;
+ strv[1] = NULL;
- e_client_proxy_call_strv (E_CLIENT (client), lst, cancellable, callback, user_data, e_book_client_remove_contact_by_uid,
+ e_client_proxy_call_strv (E_CLIENT (client), strv, cancellable, callback, user_data, e_book_client_remove_contact_by_uid,
e_gdbus_book_call_remove_contacts,
e_gdbus_book_call_remove_contacts_finish, NULL, NULL, NULL, NULL);
@@ -1666,7 +1821,7 @@ e_book_client_remove_contact_by_uid_sync (EBookClient *client,
{
gboolean res;
gchar *safe_uid;
- const gchar *lst[2];
+ const gchar *strv[2];
g_return_val_if_fail (client != NULL, FALSE);
g_return_val_if_fail (E_IS_BOOK_CLIENT (client), FALSE);
@@ -1681,10 +1836,10 @@ e_book_client_remove_contact_by_uid_sync (EBookClient *client,
safe_uid = e_util_utf8_make_valid (uid);
g_return_val_if_fail (safe_uid != NULL, FALSE);
- lst[0] = safe_uid;
- lst[1] = NULL;
+ strv[0] = safe_uid;
+ strv[1] = NULL;
- res = e_client_proxy_call_sync_strv__void (E_CLIENT (client), lst, cancellable, error, e_gdbus_book_call_remove_contacts_sync);
+ res = e_client_proxy_call_sync_strv__void (E_CLIENT (client), strv, cancellable, error, e_gdbus_book_call_remove_contacts_sync);
g_free (safe_uid);
@@ -1715,18 +1870,18 @@ e_book_client_remove_contacts (EBookClient *client,
GAsyncReadyCallback callback,
gpointer user_data)
{
- gchar **lst;
+ gchar **strv;
g_return_if_fail (uids != NULL);
- lst = e_client_util_slist_to_strv (uids);
- g_return_if_fail (lst != NULL);
+ strv = e_client_util_slist_to_strv (uids);
+ g_return_if_fail (strv != NULL);
- e_client_proxy_call_strv (E_CLIENT (client), (const gchar * const *) lst, cancellable, callback, user_data, e_book_client_remove_contacts,
+ e_client_proxy_call_strv (E_CLIENT (client), (const gchar * const *) strv, cancellable, callback, user_data, e_book_client_remove_contacts,
e_gdbus_book_call_remove_contacts,
e_gdbus_book_call_remove_contacts_finish, NULL, NULL, NULL, NULL);
- g_strfreev (lst);
+ g_strfreev (strv);
}
/**
@@ -1772,7 +1927,7 @@ e_book_client_remove_contacts_sync (EBookClient *client,
GError **error)
{
gboolean res;
- gchar **lst;
+ gchar **strv;
g_return_val_if_fail (client != NULL, FALSE);
g_return_val_if_fail (E_IS_BOOK_CLIENT (client), FALSE);
@@ -1784,12 +1939,12 @@ e_book_client_remove_contacts_sync (EBookClient *client,
return FALSE;
}
- lst = e_client_util_slist_to_strv (uids);
- g_return_val_if_fail (lst != NULL, FALSE);
+ strv = e_client_util_slist_to_strv (uids);
+ g_return_val_if_fail (strv != NULL, FALSE);
- res = e_client_proxy_call_sync_strv__void (E_CLIENT (client), (const gchar * const *) lst, cancellable, error, e_gdbus_book_call_remove_contacts_sync);
+ res = e_client_proxy_call_sync_strv__void (E_CLIENT (client), (const gchar * const *) strv, cancellable, error, e_gdbus_book_call_remove_contacts_sync);
- g_strfreev (lst);
+ g_strfreev (strv);
return res;
}
diff --git a/addressbook/libebook/e-book-client.h b/addressbook/libebook/e-book-client.h
index 1435ce8..5482bde 100644
--- a/addressbook/libebook/e-book-client.h
+++ b/addressbook/libebook/e-book-client.h
@@ -140,6 +140,10 @@ void e_book_client_add_contact (EBookClient *client, /* const */ EContact *co
gboolean e_book_client_add_contact_finish (EBookClient *client, GAsyncResult *result, gchar **added_uid, GError **error);
gboolean e_book_client_add_contact_sync (EBookClient *client, /* const */ EContact *contact, gchar **added_uid, GCancellable *cancellable, GError **error);
+void e_book_client_add_contacts (EBookClient *client, /* const */ GSList *contacts, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data);
+gboolean e_book_client_add_contacts_finish (EBookClient *client, GAsyncResult *result, GSList **added_uids, GError **error);
+gboolean e_book_client_add_contacts_sync (EBookClient *client, /* const */ GSList *contacts, GSList **added_uids, GCancellable *cancellable, GError **error);
+
void e_book_client_modify_contact (EBookClient *client, /* const */ EContact *contact, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data);
gboolean e_book_client_modify_contact_finish (EBookClient *client, GAsyncResult *result, GError **error);
gboolean e_book_client_modify_contact_sync (EBookClient *client, /* const */ EContact *contact, GCancellable *cancellable, GError **error);
diff --git a/addressbook/libebook/e-book.c b/addressbook/libebook/e-book.c
index 5f4f525..6598177 100644
--- a/addressbook/libebook/e-book.c
+++ b/addressbook/libebook/e-book.c
@@ -423,7 +423,8 @@ e_book_add_contact (EBook *book,
GError **error)
{
GError *err = NULL;
- gchar *vcard, *uid = NULL, *gdbus_vcard = NULL;
+ gchar *vcard, **uids = NULL, *gdbus_vcard = NULL;
+ const gchar *strv[2];
g_return_val_if_fail (E_IS_BOOK (book), FALSE);
g_return_val_if_fail (E_IS_CONTACT (contact), FALSE);
@@ -432,13 +433,16 @@ e_book_add_contact (EBook *book,
book->priv->gdbus_book, E_BOOK_ERROR_REPOSITORY_OFFLINE);
vcard = e_vcard_to_string (E_VCARD (contact), EVC_FORMAT_VCARD_30);
- e_gdbus_book_call_add_contact_sync (book->priv->gdbus_book, e_util_ensure_gdbus_string (vcard, &gdbus_vcard), &uid, NULL, &err);
+ strv[0] = e_util_ensure_gdbus_string (vcard, &gdbus_vcard);
+ strv[1] = NULL;
+
+ e_gdbus_book_call_add_contacts_sync (book->priv->gdbus_book, strv, &uids, NULL, &err);
g_free (vcard);
g_free (gdbus_vcard);
- if (uid) {
- e_contact_set (contact, E_CONTACT_UID, uid);
- g_free (uid);
+ if (uids) {
+ e_contact_set (contact, E_CONTACT_UID, uids[0]);
+ g_strfreev (uids);
}
return unwrap_gerror (err, error);
@@ -450,12 +454,12 @@ add_contact_reply (GObject *gdbus_book,
gpointer user_data)
{
GError *err = NULL, *error = NULL;
- gchar *uid = NULL;
+ gchar *uid = NULL, **uids = NULL;
AsyncData *data = user_data;
EBookIdAsyncCallback excb = data->excallback;
EBookIdCallback cb = data->callback;
- e_gdbus_book_call_add_contact_finish (G_DBUS_PROXY (gdbus_book), res, &uid, &error);
+ e_gdbus_book_call_add_contacts_finish (G_DBUS_PROXY (gdbus_book), res, &uids, &error);
unwrap_gerror (error, &err);
@@ -463,6 +467,8 @@ add_contact_reply (GObject *gdbus_book,
* for the OUT values. This is bad. */
if (error)
uid = NULL;
+ else
+ uid = uids[0];
if (cb)
cb (data->book, err ? err->code : E_BOOK_ERROR_OK, uid, data->closure);
@@ -472,8 +478,8 @@ add_contact_reply (GObject *gdbus_book,
if (err)
g_error_free (err);
- if (uid)
- g_free (uid);
+ if (uids)
+ g_strfreev (uids);
g_object_unref (data->book);
g_slice_free (AsyncData, data);
@@ -500,6 +506,7 @@ e_book_async_add_contact (EBook *book,
{
gchar *vcard, *gdbus_vcard = NULL;
AsyncData *data;
+ const gchar *strv[2];
g_return_val_if_fail (E_IS_BOOK (book), FALSE);
g_return_val_if_fail (E_IS_CONTACT (contact), FALSE);
@@ -508,13 +515,15 @@ e_book_async_add_contact (EBook *book,
book->priv->gdbus_book, E_BOOK_ERROR_REPOSITORY_OFFLINE);
vcard = e_vcard_to_string (E_VCARD (contact), EVC_FORMAT_VCARD_30);
+ strv[0] = e_util_ensure_gdbus_string (vcard, &gdbus_vcard);
+ strv[1] = NULL;
data = g_slice_new0 (AsyncData);
data->book = g_object_ref (book);
data->callback = cb;
data->closure = closure;
- e_gdbus_book_call_add_contact (book->priv->gdbus_book, e_util_ensure_gdbus_string (vcard, &gdbus_vcard), NULL, add_contact_reply, data);
+ e_gdbus_book_call_add_contacts (book->priv->gdbus_book, strv, NULL, add_contact_reply, data);
g_free (vcard);
g_free (gdbus_vcard);
@@ -545,6 +554,7 @@ e_book_add_contact_async (EBook *book,
{
gchar *vcard, *gdbus_vcard = NULL;
AsyncData *data;
+ const gchar *strv[2];
g_return_val_if_fail (E_IS_BOOK (book), FALSE);
g_return_val_if_fail (E_IS_CONTACT (contact), FALSE);
@@ -553,13 +563,15 @@ e_book_add_contact_async (EBook *book,
book->priv->gdbus_book, E_BOOK_ERROR_REPOSITORY_OFFLINE);
vcard = e_vcard_to_string (E_VCARD (contact), EVC_FORMAT_VCARD_30);
+ strv[0] = e_util_ensure_gdbus_string (vcard, &gdbus_vcard);
+ strv[1] = NULL;
data = g_slice_new0 (AsyncData);
data->book = g_object_ref (book);
data->excallback = cb;
data->closure = closure;
- e_gdbus_book_call_add_contact (book->priv->gdbus_book, e_util_ensure_gdbus_string (vcard, &gdbus_vcard), NULL, add_contact_reply, data);
+ e_gdbus_book_call_add_contacts (book->priv->gdbus_book, strv, NULL, add_contact_reply, data);
g_free (vcard);
g_free (gdbus_vcard);
@@ -3755,13 +3767,13 @@ array_to_stringlist (gchar **list)
}
static EList *
-array_to_elist (gchar **list)
+array_to_elist (gchar **strv)
{
EList *elst = NULL;
- gchar **i = list;
+ gchar **i = strv;
elst = e_list_new (NULL, (EListFreeFunc) g_free, NULL);
- if (!list)
+ if (!strv)
return elst;
while (*i != NULL) {
diff --git a/addressbook/libedata-book/e-book-backend-sync.c b/addressbook/libedata-book/e-book-backend-sync.c
index ecb386d..7ee5635 100644
--- a/addressbook/libedata-book/e-book-backend-sync.c
+++ b/addressbook/libedata-book/e-book-backend-sync.c
@@ -11,6 +11,7 @@
#endif
#include "e-book-backend-sync.h"
+#include "libedataserver/e-data-server-util.h"
G_DEFINE_TYPE (EBookBackendSync, e_book_backend_sync, E_TYPE_BOOK_BACKEND)
@@ -61,31 +62,31 @@ e_book_backend_sync_open (EBookBackendSync *backend,
}
/**
- * e_book_backend_sync_create_contact:
+ * e_book_backend_sync_create_contacts:
* @backend: an #EBookBackendSync
* @book: an #EDataBook
* @cancellable: a #GCancellable for the operation
- * @vcard: a VCard representation of a contact
- * @contact: a pointer to a location to store the resulting #EContact
+ * @vcards: a #GSList of vCard representations of contacts
+ * @added_contacts: a pointer to a location to store the resulting #EContact list
* @error: #GError to set, when something fails
*
- * Creates a new contact with the contents of @vcard in @backend.
+ * Creates new contacts with the contents of @vcards in @backend.
**/
void
-e_book_backend_sync_create_contact (EBookBackendSync *backend,
- EDataBook *book,
- GCancellable *cancellable,
- const gchar *vcard,
- EContact **contact,
- GError **error)
+e_book_backend_sync_create_contacts (EBookBackendSync *backend,
+ EDataBook *book,
+ GCancellable *cancellable,
+ const GSList *vcards,
+ GSList **added_contacts,
+ 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 (vcard, E_DATA_BOOK_STATUS_INVALID_ARG);
- e_return_data_book_error_if_fail (contact, E_DATA_BOOK_STATUS_INVALID_ARG);
- e_return_data_book_error_if_fail (E_BOOK_BACKEND_SYNC_GET_CLASS (backend)->create_contact_sync, E_DATA_BOOK_STATUS_NOT_SUPPORTED);
+ e_return_data_book_error_if_fail (vcards, E_DATA_BOOK_STATUS_INVALID_ARG);
+ e_return_data_book_error_if_fail (added_contacts, E_DATA_BOOK_STATUS_INVALID_ARG);
+ e_return_data_book_error_if_fail (E_BOOK_BACKEND_SYNC_GET_CLASS (backend)->create_contacts_sync, E_DATA_BOOK_STATUS_NOT_SUPPORTED);
- (* E_BOOK_BACKEND_SYNC_GET_CLASS (backend)->create_contact_sync) (backend, book, cancellable, vcard, contact, error);
+ (* E_BOOK_BACKEND_SYNC_GET_CLASS (backend)->create_contacts_sync) (backend, book, cancellable, vcards, added_contacts, error);
}
/**
@@ -481,21 +482,20 @@ book_backend_set_backend_property (EBookBackend *backend,
}
static void
-book_backend_create_contact (EBookBackend *backend,
- EDataBook *book,
- guint32 opid,
- GCancellable *cancellable,
- const gchar *vcard)
+book_backend_create_contacts (EBookBackend *backend,
+ EDataBook *book,
+ guint32 opid,
+ GCancellable *cancellable,
+ const GSList *vcards)
{
GError *error = NULL;
- EContact *contact = NULL;
+ GSList *added_contacts = NULL;
- e_book_backend_sync_create_contact (E_BOOK_BACKEND_SYNC (backend), book, cancellable, vcard, &contact, &error);
+ e_book_backend_sync_create_contacts (E_BOOK_BACKEND_SYNC (backend), book, cancellable, vcards, &added_contacts, &error);
- e_data_book_respond_create (book, opid, error, contact);
+ e_data_book_respond_create_contacts (book, opid, error, added_contacts);
- if (contact)
- g_object_unref (contact);
+ e_util_free_object_slist (added_contacts);
}
static void
@@ -668,7 +668,7 @@ e_book_backend_sync_class_init (EBookBackendSyncClass *klass)
backend_class->refresh = book_backend_refresh;
backend_class->get_backend_property = book_backend_get_backend_property;
backend_class->set_backend_property = book_backend_set_backend_property;
- backend_class->create_contact = book_backend_create_contact;
+ backend_class->create_contacts = book_backend_create_contacts;
backend_class->remove_contacts = book_backend_remove_contacts;
backend_class->modify_contact = book_backend_modify_contact;
backend_class->get_contact = book_backend_get_contact;
diff --git a/addressbook/libedata-book/e-book-backend-sync.h b/addressbook/libedata-book/e-book-backend-sync.h
index ec45ac2..621cdb3 100644
--- a/addressbook/libedata-book/e-book-backend-sync.h
+++ b/addressbook/libedata-book/e-book-backend-sync.h
@@ -33,7 +33,7 @@ struct _EBookBackendSyncClass {
void (* refresh_sync) (EBookBackendSync *backend, EDataBook *book, GCancellable *cancellable, GError **error);
gboolean (*get_backend_property_sync) (EBookBackendSync *backend, EDataBook *book, GCancellable *cancellable, const gchar *prop_name, gchar **prop_value, GError **error);
gboolean (*set_backend_property_sync) (EBookBackendSync *backend, EDataBook *book, GCancellable *cancellable, const gchar *prop_name, const gchar *prop_value, GError **error);
- void (*create_contact_sync) (EBookBackendSync *backend, EDataBook *book, GCancellable *cancellable, const gchar *vcard, EContact **contact, GError **error);
+ void (*create_contacts_sync) (EBookBackendSync *backend, EDataBook *book, GCancellable *cancellable, const GSList *vcards, GSList **added_contacts, GError **error);
void (*remove_contacts_sync) (EBookBackendSync *backend, EDataBook *book, GCancellable *cancellable, const GSList *id_list, GSList **removed_ids, GError **error);
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);
@@ -52,7 +52,7 @@ void e_book_backend_sync_remove (EBookBackendSync *backend, EDataBook *book, G
void e_book_backend_sync_refresh (EBookBackendSync *backend, EDataBook *book, GCancellable *cancellable, GError **error);
gboolean e_book_backend_sync_get_backend_property (EBookBackendSync *backend, EDataBook *book, GCancellable *cancellable, const gchar *prop_name, gchar **prop_value, GError **error);
gboolean e_book_backend_sync_set_backend_property (EBookBackendSync *backend, EDataBook *book, GCancellable *cancellable, const gchar *prop_name, const gchar *prop_value, GError **error);
-void e_book_backend_sync_create_contact (EBookBackendSync *backend, EDataBook *book, GCancellable *cancellable, const gchar *vcard, EContact **contact, GError **error);
+void e_book_backend_sync_create_contacts (EBookBackendSync *backend, EDataBook *book, GCancellable *cancellable, const GSList *vcards, GSList **added_contacts, GError **error);
void e_book_backend_sync_remove_contacts (EBookBackendSync *backend, EDataBook *book, GCancellable *cancellable, const GSList *id_list, GSList **removed_ids, GError **error);
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);
diff --git a/addressbook/libedata-book/e-book-backend.c b/addressbook/libedata-book/e-book-backend.c
index cb68604..5b69194 100644
--- a/addressbook/libedata-book/e-book-backend.c
+++ b/addressbook/libedata-book/e-book-backend.c
@@ -429,35 +429,35 @@ e_book_backend_refresh (EBookBackend *backend,
}
/**
- * e_book_backend_create_contact:
+ * e_book_backend_create_contacts
* @backend: an #EBookBackend
* @book: an #EDataBook
* @opid: the ID to use for this operation
* @cancellable: a #GCancellable for the operation
- * @vcard: the VCard to add
+ * @vcards: a #GSList of vCards to add
*
- * Executes a 'create contact' request specified by @opid on @book
+ * Executes a 'create contacts' request specified by @opid on @book
* using @backend.
- * This might be finished with e_data_book_respond_create().
+ * This might be finished with e_data_book_respond_create_contacts().
**/
void
-e_book_backend_create_contact (EBookBackend *backend,
+e_book_backend_create_contacts (EBookBackend *backend,
EDataBook *book,
guint32 opid,
GCancellable *cancellable,
- const gchar *vcard)
+ const GSList *vcards)
{
g_return_if_fail (E_IS_BOOK_BACKEND (backend));
g_return_if_fail (E_IS_DATA_BOOK (book));
- g_return_if_fail (vcard);
- g_return_if_fail (E_BOOK_BACKEND_GET_CLASS (backend)->create_contact);
+ g_return_if_fail (vcards);
+ g_return_if_fail (E_BOOK_BACKEND_GET_CLASS (backend)->create_contacts);
if (e_book_backend_is_opening (backend))
- e_data_book_respond_create (book, opid, EDB_OPENING_ERROR, NULL);
+ e_data_book_respond_create_contacts (book, opid, EDB_OPENING_ERROR, NULL);
else if (!e_book_backend_is_opened (backend))
- e_data_book_respond_create (book, opid, EDB_NOT_OPENED_ERROR, NULL);
+ e_data_book_respond_create_contacts (book, opid, EDB_NOT_OPENED_ERROR, NULL);
else
- (* E_BOOK_BACKEND_GET_CLASS (backend)->create_contact) (backend, book, opid, cancellable, vcard);
+ (* E_BOOK_BACKEND_GET_CLASS (backend)->create_contacts) (backend, book, opid, cancellable, vcards);
}
/**
diff --git a/addressbook/libedata-book/e-book-backend.h b/addressbook/libedata-book/e-book-backend.h
index fd209f1..7e047d9 100644
--- a/addressbook/libedata-book/e-book-backend.h
+++ b/addressbook/libedata-book/e-book-backend.h
@@ -140,7 +140,7 @@ struct _EBookBackendClass {
void (* authenticate_user) (EBookBackend *backend, GCancellable *cancellable, ECredentials *credentials);
void (* refresh) (EBookBackend *backend, EDataBook *book, guint32 opid, GCancellable *cancellable);
- void (* create_contact) (EBookBackend *backend, EDataBook *book, guint32 opid, GCancellable *cancellable, const gchar *vcard);
+ void (* create_contacts) (EBookBackend *backend, EDataBook *book, guint32 opid, GCancellable *cancellable, const GSList *vcards);
void (* remove_contacts) (EBookBackend *backend, EDataBook *book, guint32 opid, GCancellable *cancellable, const GSList *id_list);
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);
@@ -177,7 +177,7 @@ void e_book_backend_set_backend_property (EBookBackend *backend, EDataBook *boo
void e_book_backend_open (EBookBackend *backend, EDataBook *book, guint32 opid, GCancellable *cancellable, gboolean only_if_exists);
void e_book_backend_remove (EBookBackend *backend, EDataBook *book, guint32 opid, GCancellable *cancellable);
void e_book_backend_refresh (EBookBackend *backend, EDataBook *book, guint32 opid, GCancellable *cancellable);
-void e_book_backend_create_contact (EBookBackend *backend, EDataBook *book, guint32 opid, GCancellable *cancellable, const gchar *vcard);
+void e_book_backend_create_contacts (EBookBackend *backend, EDataBook *book, guint32 opid, GCancellable *cancellable, const GSList *vcards);
void e_book_backend_remove_contacts (EBookBackend *backend, EDataBook *book, guint32 opid, GCancellable *cancellable, const GSList *id_list);
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);
diff --git a/addressbook/libedata-book/e-data-book.c b/addressbook/libedata-book/e-data-book.c
index 35c8420..3c0b5d2 100644
--- a/addressbook/libedata-book/e-data-book.c
+++ b/addressbook/libedata-book/e-data-book.c
@@ -66,7 +66,7 @@ typedef enum {
OP_GET_CONTACTS,
OP_GET_CONTACTS_UIDS,
OP_AUTHENTICATE,
- OP_ADD_CONTACT,
+ OP_ADD_CONTACTS,
OP_REMOVE_CONTACTS,
OP_MODIFY_CONTACT,
OP_GET_BACKEND_PROPERTY,
@@ -93,6 +93,7 @@ typedef struct {
/* OP_REMOVE_CONTACTS */
GSList *ids;
/* OP_ADD_CONTACT */
+ GSList *vcards;
/* OP_MODIFY_CONTACT */
gchar *vcard;
/* OP_GET_VIEW */
@@ -153,9 +154,9 @@ operation_thread (gpointer data,
case OP_OPEN:
e_book_backend_open (backend, op->book, op->id, op->cancellable, op->d.only_if_exists);
break;
- case OP_ADD_CONTACT:
- e_book_backend_create_contact (backend, op->book, op->id, op->cancellable, op->d.vcard);
- g_free (op->d.vcard);
+ case OP_ADD_CONTACTS:
+ e_book_backend_create_contacts (backend, op->book, op->id, op->cancellable, op->d.vcards);
+ e_util_free_string_slist (op->d.vcards);
break;
case OP_GET_CONTACT:
e_book_backend_get_contact (backend, op->book, op->id, op->cancellable, op->d.uid);
@@ -175,8 +176,7 @@ operation_thread (gpointer data,
break;
case OP_REMOVE_CONTACTS:
e_book_backend_remove_contacts (backend, op->book, op->id, op->cancellable, op->d.ids);
- g_slist_foreach (op->d.ids, (GFunc) g_free, NULL);
- g_slist_free (op->d.ids);
+ e_util_free_string_slist (op->d.ids);
break;
case OP_REMOVE:
e_book_backend_remove (backend, op->book, op->id, op->cancellable);
@@ -614,14 +614,14 @@ impl_Book_get_contact_list_uids (EGdbusBook *object,
}
static gboolean
-impl_Book_add_contact (EGdbusBook *object,
+impl_Book_add_contacts (EGdbusBook *object,
GDBusMethodInvocation *invocation,
- const gchar *in_vcard,
+ const gchar * const *in_vcards,
EDataBook *book)
{
OperationData *op;
- if (in_vcard == NULL || !*in_vcard) {
+ if (in_vcards == NULL || !*in_vcards) {
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, _("Cannot add contact: "));
@@ -629,10 +629,10 @@ impl_Book_add_contact (EGdbusBook *object,
return TRUE;
}
- op = op_new (OP_ADD_CONTACT, book);
- op->d.vcard = g_strdup (in_vcard);
+ op = op_new (OP_ADD_CONTACTS, book);
+ op->d.vcards = e_util_strv_to_slist (in_vcards);
- e_gdbus_book_complete_add_contact (book->priv->gdbus_object, invocation, op->id);
+ e_gdbus_book_complete_add_contacts (book->priv->gdbus_object, invocation, op->id);
e_operation_pool_push (ops_pool, op);
return TRUE;
@@ -1013,25 +1013,39 @@ e_data_book_respond_get_contact_list_uids (EDataBook *book,
}
void
-e_data_book_respond_create (EDataBook *book,
- guint32 opid,
- GError *error,
- const EContact *contact)
+e_data_book_respond_create_contacts (EDataBook *book,
+ guint32 opid,
+ GError *error,
+ const GSList *contacts)
{
- gchar *gdbus_uid = NULL;
+ gchar **array = NULL;
+ const GSList *l;
+ gint i = 0;
op_complete (book, opid);
+ array = g_new0 (gchar *, g_slist_length ((GSList *) contacts) + 1);
+ for (l = contacts; l != NULL; l = l->next) {
+ EContact *contact = E_CONTACT (l->data);
+
+ array[i++] = e_util_utf8_make_valid (e_contact_get_const (contact, E_CONTACT_UID));
+ }
+
/* Translators: This is prefix to a detailed error message */
g_prefix_error (&error, "%s", _("Cannot add contact: "));
- e_gdbus_book_emit_add_contact_done (book->priv->gdbus_object, opid, error, e_util_ensure_gdbus_string (e_contact_get_const ((EContact *) contact, E_CONTACT_UID), &gdbus_uid));
+ e_gdbus_book_emit_add_contacts_done (book->priv->gdbus_object, opid, error, (const gchar * const *) array);
- g_free (gdbus_uid);
+ g_strfreev (array);
if (error) {
g_error_free (error);
} else {
- e_book_backend_notify_update (e_data_book_get_backend (book), contact);
+ for (l = contacts; l != NULL; l = l->next) {
+ EContact *contact = E_CONTACT (l->data);
+
+ e_book_backend_notify_update (e_data_book_get_backend (book), contact);
+ }
+
e_book_backend_notify_complete (e_data_book_get_backend (book));
}
}
@@ -1376,8 +1390,8 @@ e_data_book_init (EDataBook *ebook)
gdbus_object, "handle-authenticate-user",
G_CALLBACK (impl_Book_authenticate_user), ebook);
g_signal_connect (
- gdbus_object, "handle-add-contact",
- G_CALLBACK (impl_Book_add_contact), ebook);
+ gdbus_object, "handle-add-contacts",
+ G_CALLBACK (impl_Book_add_contacts), ebook);
g_signal_connect (
gdbus_object, "handle-remove-contacts",
G_CALLBACK (impl_Book_remove_contacts), ebook);
diff --git a/addressbook/libedata-book/e-data-book.h b/addressbook/libedata-book/e-data-book.h
index 001f797..0b900c5 100644
--- a/addressbook/libedata-book/e-data-book.h
+++ b/addressbook/libedata-book/e-data-book.h
@@ -136,7 +136,7 @@ void e_data_book_respond_remove (EDataBook *book, guint32 opid, GError *error
void e_data_book_respond_refresh (EDataBook *book, guint32 opid, GError *error);
void e_data_book_respond_get_backend_property (EDataBook *book, guint32 opid, GError *error, const gchar *prop_value);
void e_data_book_respond_set_backend_property (EDataBook *book, guint32 opid, GError *error);
-void e_data_book_respond_create (EDataBook *book, guint32 opid, GError *error, const EContact *contact);
+void e_data_book_respond_create_contacts (EDataBook *book, guint32 opid, GError *error, const GSList *contacts);
void e_data_book_respond_remove_contacts (EDataBook *book, guint32 opid, GError *error, const GSList *ids);
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);
diff --git a/addressbook/libegdbus/e-gdbus-book.c b/addressbook/libegdbus/e-gdbus-book.c
index 04bf496..7b0f5fa 100644
--- a/addressbook/libegdbus/e-gdbus-book.c
+++ b/addressbook/libegdbus/e-gdbus-book.c
@@ -53,8 +53,8 @@ enum
__GET_CONTACT_LIST_DONE_SIGNAL,
__GET_CONTACT_LIST_UIDS_METHOD,
__GET_CONTACT_LIST_UIDS_DONE_SIGNAL,
- __ADD_CONTACT_METHOD,
- __ADD_CONTACT_DONE_SIGNAL,
+ __ADD_CONTACTS_METHOD,
+ __ADD_CONTACTS_DONE_SIGNAL,
__REMOVE_CONTACTS_METHOD,
__REMOVE_CONTACTS_DONE_SIGNAL,
__MODIFY_CONTACT_METHOD,
@@ -139,8 +139,8 @@ 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_STRV (GDBUS_BOOK_INTERFACE_NAME,
+ add_contacts)
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,
@@ -176,7 +176,7 @@ e_gdbus_book_default_init (EGdbusBookIface *iface)
E_INIT_GDBUS_METHOD_ASYNC_STRING__STRING(EGdbusBookIface, "get_contact", get_contact, __GET_CONTACT_METHOD, __GET_CONTACT_DONE_SIGNAL)
E_INIT_GDBUS_METHOD_ASYNC_STRING__STRV (EGdbusBookIface, "get_contact_list", 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, "add_contact", add_contact, __ADD_CONTACT_METHOD, __ADD_CONTACT_DONE_SIGNAL)
+ E_INIT_GDBUS_METHOD_ASYNC_STRV__STRV (EGdbusBookIface, "add_contacts", add_contacts, __ADD_CONTACTS_METHOD, __ADD_CONTACTS_DONE_SIGNAL)
E_INIT_GDBUS_METHOD_ASYNC_STRV__VOID (EGdbusBookIface, "remove_contacts", remove_contacts, __REMOVE_CONTACTS_METHOD, __REMOVE_CONTACTS_DONE_SIGNAL)
E_INIT_GDBUS_METHOD_ASYNC_STRING__VOID (EGdbusBookIface, "modify_contact", modify_contact, __MODIFY_CONTACT_METHOD, __MODIFY_CONTACT_DONE_SIGNAL)
E_INIT_GDBUS_METHOD_ASYNC_STRING__STRING(EGdbusBookIface, "get_backend_property", get_backend_property, __GET_BACKEND_PROPERTY_METHOD, __GET_BACKEND_PROPERTY_DONE_SIGNAL)
@@ -365,34 +365,34 @@ e_gdbus_book_call_get_contact_list_uids_sync (GDBusProxy *proxy,
}
void
-e_gdbus_book_call_add_contact (GDBusProxy *proxy,
- const gchar *in_vcard,
+e_gdbus_book_call_add_contacts (GDBusProxy *proxy,
+ const gchar * const *in_vcards,
GCancellable *cancellable,
GAsyncReadyCallback callback,
gpointer user_data)
{
- e_gdbus_proxy_call_string ("add_contact", e_gdbus_book_call_add_contact, E_GDBUS_ASYNC_OP_KEEPER (proxy), in_vcard, cancellable, callback, user_data);
+ e_gdbus_proxy_call_strv ("add_contacts", e_gdbus_book_call_add_contacts, E_GDBUS_ASYNC_OP_KEEPER (proxy), in_vcards, cancellable, callback, user_data);
}
gboolean
-e_gdbus_book_call_add_contact_finish (GDBusProxy *proxy,
+e_gdbus_book_call_add_contacts_finish (GDBusProxy *proxy,
GAsyncResult *result,
- gchar **out_uid,
+ gchar ***out_uids,
GError **error)
{
- return e_gdbus_proxy_finish_call_string (E_GDBUS_ASYNC_OP_KEEPER (proxy), result, out_uid, error, e_gdbus_book_call_add_contact);
+ return e_gdbus_proxy_finish_call_strv (E_GDBUS_ASYNC_OP_KEEPER (proxy), result, out_uids, error, e_gdbus_book_call_add_contacts);
}
gboolean
-e_gdbus_book_call_add_contact_sync (GDBusProxy *proxy,
- const gchar *in_vcard,
- gchar **out_uid,
+e_gdbus_book_call_add_contacts_sync (GDBusProxy *proxy,
+ const gchar * const *in_vcards,
+ gchar ***out_uids,
GCancellable *cancellable,
GError **error)
{
- return e_gdbus_proxy_call_sync_string__string (proxy, in_vcard, out_uid, cancellable, error,
- e_gdbus_book_call_add_contact,
- e_gdbus_book_call_add_contact_finish);
+ return e_gdbus_proxy_call_sync_strv__strv (proxy, in_vcards, out_uids, cancellable, error,
+ e_gdbus_book_call_add_contacts,
+ e_gdbus_book_call_add_contacts_finish);
}
void
@@ -694,9 +694,9 @@ DECLARE_EMIT_DONE_SIGNAL_1 (get_contact_list,
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_1 (add_contacts,
+ __ADD_CONTACTS_DONE_SIGNAL,
+ const gchar * const *)
DECLARE_EMIT_DONE_SIGNAL_0 (remove_contacts,
__REMOVE_CONTACTS_DONE_SIGNAL)
DECLARE_EMIT_DONE_SIGNAL_0 (modify_contact,
@@ -770,7 +770,7 @@ E_DECLARE_GDBUS_ASYNC_METHOD_0 (book,
E_DECLARE_GDBUS_ASYNC_METHOD_1_WITH_RETURN (book, get_contact, uid, "s", vcard, "s")
E_DECLARE_GDBUS_ASYNC_METHOD_1_WITH_RETURN (book, get_contact_list, 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, add_contact, vcard, "s", uid, "s")
+E_DECLARE_GDBUS_ASYNC_METHOD_1_WITH_RETURN (book, add_contacts, vcards, "as", uids, "as")
E_DECLARE_GDBUS_ASYNC_METHOD_1 (book, remove_contacts, list, "as")
E_DECLARE_GDBUS_ASYNC_METHOD_1 (book, modify_contact, vcard, "s")
E_DECLARE_GDBUS_ASYNC_METHOD_1_WITH_RETURN (book, get_backend_property, prop_name, "s", prop_value, "s")
@@ -792,7 +792,7 @@ static const GDBusMethodInfo * const e_gdbus_book_method_info_pointers[] =
&E_DECLARED_GDBUS_METHOD_INFO_NAME (book, get_contact),
&E_DECLARED_GDBUS_METHOD_INFO_NAME (book, get_contact_list),
&E_DECLARED_GDBUS_METHOD_INFO_NAME (book, get_contact_list_uids),
- &E_DECLARED_GDBUS_METHOD_INFO_NAME (book, add_contact),
+ &E_DECLARED_GDBUS_METHOD_INFO_NAME (book, add_contacts),
&E_DECLARED_GDBUS_METHOD_INFO_NAME (book, remove_contacts),
&E_DECLARED_GDBUS_METHOD_INFO_NAME (book, modify_contact),
&E_DECLARED_GDBUS_METHOD_INFO_NAME (book, get_backend_property),
@@ -820,7 +820,7 @@ static const GDBusSignalInfo * const e_gdbus_book_signal_info_pointers[] =
&E_DECLARED_GDBUS_SIGNAL_INFO_NAME (book, get_contact_done),
&E_DECLARED_GDBUS_SIGNAL_INFO_NAME (book, get_contact_list_done),
&E_DECLARED_GDBUS_SIGNAL_INFO_NAME (book, get_contact_list_uids_done),
- &E_DECLARED_GDBUS_SIGNAL_INFO_NAME (book, add_contact_done),
+ &E_DECLARED_GDBUS_SIGNAL_INFO_NAME (book, add_contacts_done),
&E_DECLARED_GDBUS_SIGNAL_INFO_NAME (book, remove_contacts_done),
&E_DECLARED_GDBUS_SIGNAL_INFO_NAME (book, modify_contact_done),
&E_DECLARED_GDBUS_SIGNAL_INFO_NAME (book, get_backend_property_done),
@@ -1042,7 +1042,7 @@ e_gdbus_book_proxy_init (EGdbusBookProxy *proxy)
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_STRV (add_contacts);
E_GDBUS_CONNECT_METHOD_DONE_SIGNAL_VOID (remove_contacts);
E_GDBUS_CONNECT_METHOD_DONE_SIGNAL_VOID (modify_contact);
E_GDBUS_CONNECT_METHOD_DONE_SIGNAL_STRING (get_backend_property);
diff --git a/addressbook/libegdbus/e-gdbus-book.h b/addressbook/libegdbus/e-gdbus-book.h
index aea23ef..417c1f1 100644
--- a/addressbook/libegdbus/e-gdbus-book.h
+++ b/addressbook/libegdbus/e-gdbus-book.h
@@ -138,8 +138,8 @@ struct _EGdbusBookIface
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);
+ gboolean (*handle_add_contacts) (EGdbusBook *object, GDBusMethodInvocation *invocation, const gchar * const *in_vcards);
+ void (*add_contacts_done) (EGdbusBook *object, guint arg_opid, const GError *arg_error, gchar ***out_uids);
gboolean (*handle_remove_contacts) (EGdbusBook *object, GDBusMethodInvocation *invocation, const gchar * const *in_list);
void (*remove_contacts_done) (EGdbusBook *object, guint arg_opid, const GError *arg_error);
@@ -190,9 +190,9 @@ void e_gdbus_book_call_get_contact_list_uids (GDBusProxy *proxy, const gchar *i
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);
+void e_gdbus_book_call_add_contacts (GDBusProxy *proxy, const gchar * const *in_vcards, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data);
+gboolean e_gdbus_book_call_add_contacts_finish (GDBusProxy *proxy, GAsyncResult *result, gchar ***out_uids, GError **error);
+gboolean e_gdbus_book_call_add_contacts_sync (GDBusProxy *proxy, const gchar * const *in_vcards, gchar ***out_uids, GCancellable *cancellable, GError **error);
void e_gdbus_book_call_remove_contacts (GDBusProxy *proxy, const gchar * const *in_list, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data);
gboolean e_gdbus_book_call_remove_contacts_finish (GDBusProxy *proxy, GAsyncResult *result, GError **error);
@@ -239,7 +239,7 @@ gboolean e_gdbus_book_call_close_sync (GDBusProxy *proxy, GCancellable *cancella
#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_add_contacts 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
#define e_gdbus_book_complete_get_backend_property e_gdbus_complete_async_method
@@ -256,7 +256,7 @@ void e_gdbus_book_emit_refresh_done (EGdbusBook *object, guint arg_opid, const
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_add_contacts_done (EGdbusBook *object, guint arg_opid, const GError *arg_error, const gchar *const *out_uids);
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);
void e_gdbus_book_emit_get_backend_property_done (EGdbusBook *object, guint arg_opid, const GError *arg_error, const gchar *out_prop_value);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]