[evolution-data-server] addressbook: Improve bulk contact removal code
- From: Christophe Dumez <cdumez src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [evolution-data-server] addressbook: Improve bulk contact removal code
- Date: Sat, 8 Oct 2011 07:10:32 +0000 (UTC)
commit 510d4c84ea9c97777ef9e804e2662bca045424cc
Author: Christophe Dumez <christophe dumez intel com>
Date: Tue Oct 4 16:26:52 2011 +0300
addressbook: Improve bulk contact removal code
The patch makes use of Berkeley DB transations in the file backend
and roll back the transaction in case of error to make the
behavior consistent with bulk addition.
This patch also makes the webdav backend behave as expected since
it does not support bulk removal and the implementation was broken.
addressbook/backends/file/e-book-backend-file.c | 68 ++++++++++++++------
.../backends/webdav/e-book-backend-webdav.c | 48 ++++++++------
2 files changed, 76 insertions(+), 40 deletions(-)
---
diff --git a/addressbook/backends/file/e-book-backend-file.c b/addressbook/backends/file/e-book-backend-file.c
index da34e5a..bcab4ce 100644
--- a/addressbook/backends/file/e-book-backend-file.c
+++ b/addressbook/backends/file/e-book-backend-file.c
@@ -438,48 +438,76 @@ e_book_backend_file_remove_contacts (EBookBackendSync *backend,
{
EBookBackendFile *bf = E_BOOK_BACKEND_FILE (backend);
DB *db = bf->priv->file_db;
- DBT id_dbt;
+ DB_ENV *env = bf->priv->env;
+ DB_TXN *txn = NULL;
gint db_error;
- const gchar *id;
- GSList *removed_cards = NULL;
+ GSList *removed_ids = NULL;
const GSList *l;
- GError *error = NULL;
if (!db) {
g_propagate_error (perror, EDB_NOT_OPENED_ERROR);
return;
}
- for (l = id_list; l; l = l->next) {
+ /* 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;
+ }
+
+ for (l = id_list; l != NULL; l = l->next) {
+ const gchar *id;
+ DBT id_dbt;
+
id = l->data;
string_to_dbt (id, &id_dbt);
- db_error = db->del (db, NULL, &id_dbt, 0);
- if (0 != db_error) {
+ db_error = db->del (db, txn, &id_dbt, 0);
+ if (db_error != 0) {
g_warning (G_STRLOC ": db->del failed with %s", db_strerror (db_error));
db_error_to_gerror (db_error, perror);
- continue;
+ /* Abort as soon as a removal fails */
+ break;
}
- removed_cards = g_slist_prepend (removed_cards, g_strdup (id));
+ removed_ids = g_slist_prepend (removed_ids, g_strdup (id));
}
- /* if we actually removed some, try to sync */
- if (removed_cards) {
- db_error = db->sync (db, 0);
- if (db_error != 0)
- g_warning (G_STRLOC ": db->sync failed with %s", db_strerror (db_error));
+ 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 {
+ /* Rollback transaction */
+ txn->abort (txn);
}
- if (!e_book_backend_sqlitedb_remove_contacts (bf->priv->sqlitedb,
+ if (db_error == 0) {
+ GError *error = NULL;
+ /* Remove from summary as well */
+ if (!e_book_backend_sqlitedb_remove_contacts (bf->priv->sqlitedb,
SQLITEDB_FOLDER_ID,
- removed_cards, &error)) {
- g_warning ("Failed to remove contacts from the summary: %s", error->message);
- g_error_free (error);
- }
+ removed_ids, &error)) {
+ g_warning ("Failed to remove contacts from the summary: %s", error->message);
+ g_error_free (error);
+ }
- *ids = removed_cards;
+ *ids = removed_ids;
+ } else {
+ *ids = NULL;
+ e_util_free_string_slist (removed_ids);
+ }
}
static void
diff --git a/addressbook/backends/webdav/e-book-backend-webdav.c b/addressbook/backends/webdav/e-book-backend-webdav.c
index 2b0fc0d..d595674 100644
--- a/addressbook/backends/webdav/e-book-backend-webdav.c
+++ b/addressbook/backends/webdav/e-book-backend-webdav.c
@@ -413,8 +413,9 @@ e_book_backend_webdav_remove_contacts (EBookBackend *backend,
{
EBookBackendWebdav *webdav = E_BOOK_BACKEND_WEBDAV (backend);
EBookBackendWebdavPrivate *priv = webdav->priv;
- GSList *deleted_ids = NULL;
- const GSList *list;
+ gchar *uid = id_list->data;
+ GSList deleted_ids = {NULL,};
+ guint status;
if (!e_backend_get_online (E_BACKEND (backend))) {
e_data_book_respond_remove_contacts (book, opid,
@@ -422,28 +423,35 @@ e_book_backend_webdav_remove_contacts (EBookBackend *backend,
return;
}
- for (list = id_list; list != NULL; list = list->next) {
- const gchar *uid = (const gchar *) list->data;
- guint status;
-
- status = delete_contact (webdav, uid);
- if (status != 204) {
- if (status == 401 || status == 407) {
- e_data_book_respond_remove_contacts (book, opid, webdav_handle_auth_request (webdav),
- deleted_ids);
- } else {
- g_warning("DELETE failed with HTTP status %d", status);
- }
- continue;
+ /* 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) {
+ e_data_book_respond_remove_contacts (book, opid,
+ EDB_ERROR_EX (NOT_SUPPORTED,
+ _("The backend does not support bulk removals")),
+ NULL);
+ return;
+ }
+
+ status = delete_contact (webdav, uid);
+ if (status != 204) {
+ if (status == 401 || status == 407) {
+ e_data_book_respond_remove_contacts (book, opid,
+ webdav_handle_auth_request (webdav), NULL);
+ } else {
+ g_warning("DELETE failed with HTTP status %d", status);
+ e_data_book_respond_remove_contacts (book, opid,
+ e_data_book_create_error_fmt (E_DATA_BOOK_STATUS_OTHER_ERROR,
+ "DELETE failed with HTTP status %d", status),
+ NULL);
}
- e_book_backend_cache_remove_contact (priv->cache, uid);
- deleted_ids = g_slist_append (deleted_ids, list->data);
+ return;
}
- e_data_book_respond_remove_contacts (book, opid,
- EDB_ERROR (SUCCESS), deleted_ids);
+ e_book_backend_cache_remove_contact (priv->cache, uid);
- g_slist_free (deleted_ids);
+ deleted_ids.data = uid;
+ e_data_book_respond_remove_contacts (book, opid, EDB_ERROR (SUCCESS), &deleted_ids);
}
static void
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]