[evolution-data-server/openismus-work-master: 10/16] EBookBackendSqliteDB: Added e_book_backend_new_contact[s]() APIs



commit d4726604e78fed5ede51d3455874c3a3bd23b4bd
Author: Tristan Van Berkom <tristanvb openismus com>
Date:   Fri Jan 18 15:50:04 2013 +0900

    EBookBackendSqliteDB: Added e_book_backend_new_contact[s]() APIs
    
    The new API allows control on whether or not to overwrite existing contacts
    with the same UID.
    
    Deprecated the older e_book_backend_add_contact[s]() apis which include
    the unused 'partial_contact' parameter and have no control on whether
    or not to overwrite existing contacts.
    
    Additionally this patch exposes the E_BOOK_SDB_ERROR domain and a couple
    of error codes to distinguish if an error occurred because of a constraint
    or other errors (UID conflicts at contact addition time are constraint
    errors).
    
    Conflicts:
    
    	addressbook/libedata-book/e-book-backend-sqlitedb.c
    	addressbook/libedata-book/e-book-backend-sqlitedb.h

 .../libedata-book/e-book-backend-sqlitedb.c        |  148 ++++++++++++++------
 .../libedata-book/e-book-backend-sqlitedb.h        |   43 +++++-
 2 files changed, 142 insertions(+), 49 deletions(-)
---
diff --git a/addressbook/libedata-book/e-book-backend-sqlitedb.c b/addressbook/libedata-book/e-book-backend-sqlitedb.c
index 20cf529..fb97347 100644
--- a/addressbook/libedata-book/e-book-backend-sqlitedb.c
+++ b/addressbook/libedata-book/e-book-backend-sqlitedb.c
@@ -79,8 +79,6 @@ struct _EBookBackendSqliteDBPrivate {
 
 G_DEFINE_TYPE (EBookBackendSqliteDB, e_book_backend_sqlitedb, G_TYPE_OBJECT)
 
-#define E_BOOK_SDB_ERROR \
-	(e_book_backend_sqlitedb_error_quark ())
 
 static GHashTable *db_connections = NULL;
 static GMutex dbcon_lock;
@@ -153,7 +151,7 @@ typedef struct {
 	GSList *list;
 } StoreVCardData;
 
-static GQuark
+GQuark
 e_book_backend_sqlitedb_error_quark (void)
 {
 	static GQuark quark = 0;
@@ -297,7 +295,10 @@ book_backend_sql_exec_real (sqlite3 *db,
 	if (ret != SQLITE_OK) {
 		d (g_print ("Error in SQL EXEC statement: %s [%s].\n", stmt, errmsg));
 		g_set_error_literal (
-			error, E_BOOK_SDB_ERROR, 0, errmsg);
+			error, E_BOOK_SDB_ERROR,
+			ret == SQLITE_CONSTRAINT ?
+			E_BOOK_SDB_ERROR_CONSTRAINT : E_BOOK_SDB_ERROR_OTHER,
+			errmsg);
 		sqlite3_free (errmsg);
 		errmsg = NULL;
 		return FALSE;
@@ -738,7 +739,7 @@ introspect_summary (EBookBackendSqliteDB *ebsdb,
 		/* Check for parse error */
 		if (field == 0) {
 			g_set_error (
-				error, E_BOOK_SDB_ERROR, 0,
+				error, E_BOOK_SDB_ERROR, E_BOOK_SDB_ERROR_OTHER,
 				_("Error introspecting unknown summary field '%s'"), col);
 			success = FALSE;
 			break;
@@ -962,14 +963,15 @@ book_backend_sqlitedb_load (EBookBackendSqliteDB *ebsdb,
 	if (ret) {
 		if (!ebsdb->priv->db) {
 			g_set_error (
-				error, E_BOOK_SDB_ERROR, 0,
+				error, E_BOOK_SDB_ERROR,
+				E_BOOK_SDB_ERROR_OTHER,
 				_("Insufficient memory"));
 		} else {
 			const gchar *errmsg;
 			errmsg = sqlite3_errmsg (ebsdb->priv->db);
 			d (g_print ("Can't open database %s: %s\n", path, errmsg));
 			g_set_error_literal (
-				error, E_BOOK_SDB_ERROR, 0, errmsg);
+				error, E_BOOK_SDB_ERROR, E_BOOK_SDB_ERROR_OTHER, errmsg);
 			sqlite3_close (ebsdb->priv->db);
 		}
 		return FALSE;
@@ -1045,7 +1047,7 @@ e_book_backend_sqlitedb_new_internal (const gchar *path,
 	if (g_mkdir_with_parents (path, 0777) < 0) {
 		g_mutex_unlock (&dbcon_lock);
 		g_set_error (
-			error, E_BOOK_SDB_ERROR, 0,
+			error, E_BOOK_SDB_ERROR, E_BOOK_SDB_ERROR_OTHER,
 			"Can not make parent directory: errno %d", errno);
 		return NULL;
 	}
@@ -1097,7 +1099,7 @@ append_summary_field (GArray *array,
 
 	if (field < 1 || field >= E_CONTACT_FIELD_LAST) {
 		g_set_error (
-			error, E_BOOK_SDB_ERROR, 0,
+			error, E_BOOK_SDB_ERROR, E_BOOK_SDB_ERROR_OTHER,
 			_("Invalid contact field '%d' specified in summary"), field);
 		return FALSE;
 	}
@@ -1131,7 +1133,7 @@ append_summary_field (GArray *array,
 	    type != G_TYPE_BOOLEAN &&
 	    type != E_TYPE_CONTACT_ATTR_LIST) {
 		g_set_error (
-			error, E_BOOK_SDB_ERROR, 0,
+			error, E_BOOK_SDB_ERROR, E_BOOK_SDB_ERROR_OTHER,
 			_("Contact field '%s' of type '%s' specified in summary, "
 			"but only boolean, string and string list field types are supported"),
 			e_contact_pretty_name (field), g_type_name (type));
@@ -1371,15 +1373,16 @@ e_book_backend_sqlitedb_unlock_updates (EBookBackendSqliteDB *ebsdb,
 static gchar *
 insert_stmt_from_contact (EBookBackendSqliteDB *ebsdb,
                           EContact *contact,
-                          gboolean partial_content,
                           const gchar *folderid,
-                          gboolean store_vcard)
+                          gboolean store_vcard,
+			  gboolean replace_existing)
 {
 	GString *string;
 	gchar *str, *vcard_str;
 	gint i;
 
-	str = sqlite3_mprintf ("INSERT or REPLACE INTO %Q VALUES (", folderid);
+	str = sqlite3_mprintf ("INSERT or %s INTO %Q VALUES (",
+			       replace_existing ? "REPLACE" : "FAIL", folderid);
 	string = g_string_new (str);
 	sqlite3_free (str);
 
@@ -1444,10 +1447,10 @@ insert_stmt_from_contact (EBookBackendSqliteDB *ebsdb,
 
 static gboolean
 insert_contact (EBookBackendSqliteDB *ebsdb,
-                EContact *contact,
-                gboolean partial_content,
-                const gchar *folderid,
-                GError **error)
+		EContact *contact,
+		const gchar *folderid,
+		gboolean replace_existing,
+		GError **error)
 {
 	EBookBackendSqliteDBPrivate *priv;
 	gboolean success;
@@ -1456,7 +1459,7 @@ insert_contact (EBookBackendSqliteDB *ebsdb,
 	priv = ebsdb->priv;
 
 	/* Update main summary table */
-	stmt = insert_stmt_from_contact (ebsdb, contact, partial_content, folderid, priv->store_vcard);
+	stmt = insert_stmt_from_contact (ebsdb, contact, folderid, priv->store_vcard, replace_existing);
 	success = book_backend_sql_exec (priv->db, stmt, NULL, NULL, error);
 	g_free (stmt);
 
@@ -1519,26 +1522,25 @@ insert_contact (EBookBackendSqliteDB *ebsdb,
 }
 
 /**
- * e_book_backend_sqlitedb_add_contact
- * @ebsdb:
+ * e_book_backend_sqlitedb_new_contact
+ * @ebsdb: An #EBookBackendSqliteDB
  * @folderid: folder id
  * @contact: EContact to be added
- * @partial_content: contact does not contain full information. Used when
- * the backend cache's partial information for auto-completion.
- * @error:
+ * @replace_existing: Whether this contact should replace another contact with the same UID.
+ * @error: A location to store any error that may have occurred.
  *
- * This is a convenience wrapper for e_book_backend_sqlitedb_add_contacts,
- * which is the preferred means to add multiple contacts when possible.
+ * This is a convenience wrapper for e_book_backend_sqlitedb_new_contacts,
+ * which is the preferred means to add or modify multiple contacts when possible.
  *
  * Returns: TRUE on success.
  *
- * Since: 3.2
+ * Since: 3.8
  **/
 gboolean
-e_book_backend_sqlitedb_add_contact (EBookBackendSqliteDB *ebsdb,
+e_book_backend_sqlitedb_new_contact (EBookBackendSqliteDB *ebsdb,
                                      const gchar *folderid,
                                      EContact *contact,
-                                     gboolean partial_content,
+                                     gboolean replace_existing,
                                      GError **error)
 {
 	GSList l;
@@ -1550,30 +1552,32 @@ e_book_backend_sqlitedb_add_contact (EBookBackendSqliteDB *ebsdb,
 	l.data = contact;
 	l.next = NULL;
 
-	return e_book_backend_sqlitedb_add_contacts (
+	return e_book_backend_sqlitedb_new_contacts (
 		ebsdb, folderid, &l,
-		partial_content, error);
+		replace_existing, error);
 }
 
 /**
- * e_book_backend_sqlitedb_add_contacts
- * @ebsdb:
+ * e_book_backend_sqlitedb_new_contacts
+ * @ebsdb: An #EBookBackendSqliteDB
  * @folderid: folder id
  * @contacts: list of EContacts
- * @partial_content: contact does not contain full information. Used when
- * the backend cache's partial information for auto-completion.
- * @error:
+ * @replace_existing: Whether this contact should replace another contact with the same UID.
+ * @error: A location to store any error that may have occurred.
  *
+ * Adds or replaces contacts in @ebsdb. If @replace_existing is specified then existing
+ * contacts with the same UID will be replaced, otherwise adding an existing contact
+ * will return an error.
  *
  * Returns: TRUE on success.
  *
- * Since: 3.2
+ * Since: 3.8
  **/
 gboolean
-e_book_backend_sqlitedb_add_contacts (EBookBackendSqliteDB *ebsdb,
+e_book_backend_sqlitedb_new_contacts (EBookBackendSqliteDB *ebsdb,
                                       const gchar *folderid,
                                       GSList *contacts,
-                                      gboolean partial_content,
+                                      gboolean replace_existing,
                                       GError **error)
 {
 	GSList *l;
@@ -1588,7 +1592,7 @@ e_book_backend_sqlitedb_add_contacts (EBookBackendSqliteDB *ebsdb,
 	for (l = contacts; success && l != NULL; l = g_slist_next (l)) {
 		EContact *contact = (EContact *) l->data;
 
-		success = insert_contact (ebsdb, contact, partial_content, folderid, error);
+		success = insert_contact (ebsdb, contact, folderid, replace_existing, error);
 	}
 
 	if (success)
@@ -1601,6 +1605,60 @@ e_book_backend_sqlitedb_add_contacts (EBookBackendSqliteDB *ebsdb,
 }
 
 /**
+ * e_book_backend_sqlitedb_add_contact
+ * @ebsdb:
+ * @folderid: folder id
+ * @contact: EContact to be added
+ * @partial_content: contact does not contain full information. Used when
+ * the backend cache's partial information for auto-completion.
+ * @error:
+ *
+ * This is a convenience wrapper for e_book_backend_sqlitedb_add_contacts,
+ * which is the preferred means to add multiple contacts when possible.
+ *
+ * Returns: TRUE on success.
+ *
+ * Since: 3.2
+ *
+ * Deprecated: 3.8: Use e_book_backend_sqlitedb_new_contact() instead.
+ **/
+gboolean
+e_book_backend_sqlitedb_add_contact (EBookBackendSqliteDB *ebsdb,
+                                     const gchar *folderid,
+                                     EContact *contact,
+                                     gboolean partial_content,
+                                     GError **error)
+{
+	return e_book_backend_sqlitedb_new_contact (ebsdb, folderid, contact, TRUE, error);
+}
+
+/**
+ * e_book_backend_sqlitedb_add_contacts
+ * @ebsdb:
+ * @folderid: folder id
+ * @contacts: list of EContacts
+ * @partial_content: contact does not contain full information. Used when
+ * the backend cache's partial information for auto-completion.
+ * @error:
+ *
+ *
+ * Returns: TRUE on success.
+ *
+ * Since: 3.2
+ *
+ * Deprecated: 3.8: Use e_book_backend_sqlitedb_new_contacts() instead.
+ **/
+gboolean
+e_book_backend_sqlitedb_add_contacts (EBookBackendSqliteDB *ebsdb,
+                                      const gchar *folderid,
+                                      GSList *contacts,
+                                      gboolean partial_content,
+                                      GError **error)
+{
+	return e_book_backend_sqlitedb_new_contacts (ebsdb, folderid, contacts, TRUE, error);
+}
+
+/**
  * e_book_backend_sqlitedb_remove_contact:
  *
  * FIXME: Document me.
@@ -2066,7 +2124,7 @@ e_book_backend_sqlitedb_get_vcard_string (EBookBackendSqliteDB *ebsdb,
 		local_with_all_required_fields = TRUE;
 	} else {
 		g_set_error (
-			error, E_BOOK_SDB_ERROR, 0,
+			error, E_BOOK_SDB_ERROR, E_BOOK_SDB_ERROR_OTHER,
 			_("Full search_contacts are not stored in cache. vcards cannot be returned."));
 
 	}
@@ -2079,7 +2137,7 @@ e_book_backend_sqlitedb_get_vcard_string (EBookBackendSqliteDB *ebsdb,
 	/* Is is an error to not find a contact ?? */
 	if (!vcard_str && error && !*error)
 		g_set_error (
-			error, E_BOOK_SDB_ERROR, 0,
+			error, E_BOOK_SDB_ERROR, E_BOOK_SDB_ERROR_OTHER,
 			_("Contact '%s' not found"), uid ? uid : "NULL");
 
 	return vcard_str;
@@ -2862,7 +2920,7 @@ book_backend_sqlitedb_search_query (EBookBackendSqliteDB *ebsdb,
 		local_with_all_required_fields = TRUE;
 	} else {
 		g_set_error (
-			error, E_BOOK_SDB_ERROR, 0,
+			error, E_BOOK_SDB_ERROR, E_BOOK_SDB_ERROR_OTHER,
 			_("Full search_contacts are not stored in cache. vcards cannot be returned."));
 	}
 
@@ -3004,7 +3062,7 @@ e_book_backend_sqlitedb_search (EBookBackendSqliteDB *ebsdb,
 
 	} else {
 		g_set_error (
-			error, E_BOOK_SDB_ERROR, 0,
+			error, E_BOOK_SDB_ERROR, E_BOOK_SDB_ERROR_OTHER,
 			_("Full search_contacts are not stored in cache. "
 			"Hence only summary query is supported."));
 	}
@@ -3085,7 +3143,7 @@ e_book_backend_sqlitedb_search_uids (EBookBackendSqliteDB *ebsdb,
 
 	} else {
 		g_set_error (
-			error, E_BOOK_SDB_ERROR, 0,
+			error, E_BOOK_SDB_ERROR, E_BOOK_SDB_ERROR_OTHER,
 			_("Full vcards are not stored in cache. "
 			"Hence only summary query is supported."));
 	}
@@ -3757,7 +3815,7 @@ e_book_backend_sqlitedb_remove (EBookBackendSqliteDB *ebsdb,
 
 	if (ret == -1) {
 		g_set_error (
-			error, E_BOOK_SDB_ERROR, 0,
+			error, E_BOOK_SDB_ERROR, E_BOOK_SDB_ERROR_OTHER,
 			_("Unable to remove the db file: errno %d"), errno);
 		return FALSE;
 	}
diff --git a/addressbook/libedata-book/e-book-backend-sqlitedb.h b/addressbook/libedata-book/e-book-backend-sqlitedb.h
index f7153a4..8d6de5e 100644
--- a/addressbook/libedata-book/e-book-backend-sqlitedb.h
+++ b/addressbook/libedata-book/e-book-backend-sqlitedb.h
@@ -47,6 +47,15 @@
 	(G_TYPE_INSTANCE_GET_CLASS \
 	((obj), E_TYPE_BOOK_BACKEND_SQLITEDB, EBookBackendSqliteDBClass))
 
+/**
+ * E_BOOK_SDB_ERROR:
+ *
+ * Error domain for #EBookBackendSqliteDB operations.
+ *
+ * Since: 3.8
+ **/
+#define E_BOOK_SDB_ERROR (e_book_backend_sqlitedb_error_quark ())
+
 G_BEGIN_DECLS
 
 typedef struct _EBookBackendSqliteDB EBookBackendSqliteDB;
@@ -54,6 +63,18 @@ typedef struct _EBookBackendSqliteDBClass EBookBackendSqliteDBClass;
 typedef struct _EBookBackendSqliteDBPrivate EBookBackendSqliteDBPrivate;
 
 /**
+ * EBookSDBError:
+ * @E_BOOK_SDB_ERROR_CONSTRAINT: The error occurred due to an explicit constraint
+ * @E_BOOK_SDB_ERROR_OTHER: Another error occurred
+ *
+ * Defines the types of possible errors reported by the #EBookBackendSqliteDB
+ */
+typedef enum {
+	E_BOOK_SDB_ERROR_CONSTRAINT,
+	E_BOOK_SDB_ERROR_OTHER
+} EBookSDBError;
+
+/**
  * EBookBackendSqliteDB:
  *
  * Contains only private data that should be read and manipulated using the
@@ -85,6 +106,8 @@ typedef struct {
 
 GType		e_book_backend_sqlitedb_get_type
 						(void) G_GNUC_CONST;
+GQuark          e_book_backend_sqlitedb_error_quark
+                                                (void);
 EBookBackendSqliteDB *
 		e_book_backend_sqlitedb_new	(const gchar *path,
 						 const gchar *emailid,
@@ -108,17 +131,17 @@ gboolean	e_book_backend_sqlitedb_unlock_updates
 						(EBookBackendSqliteDB *ebsdb,
 						 gboolean do_commit,
 						 GError **error);
-gboolean	e_book_backend_sqlitedb_add_contact
+gboolean	e_book_backend_sqlitedb_new_contact
 						(EBookBackendSqliteDB *ebsdb,
 						 const gchar *folderid,
 						 EContact *contact,
-						 gboolean partial_content,
+						 gboolean replace_existing,
 						 GError **error);
-gboolean	e_book_backend_sqlitedb_add_contacts
+gboolean	e_book_backend_sqlitedb_new_contacts
 						(EBookBackendSqliteDB *ebsdb,
 						 const gchar *folderid,
 						 GSList *contacts,
-						 gboolean partial_content,
+						 gboolean replace_existing,
 						 GError **error);
 gboolean	e_book_backend_sqlitedb_remove_contact
 						(EBookBackendSqliteDB *ebsdb,
@@ -251,6 +274,18 @@ gboolean	e_book_backend_sqlitedb_is_summary_query
 						(const gchar *query);
 gboolean	e_book_backend_sqlitedb_is_summary_fields
 						(GHashTable *fields_of_interest);
+gboolean	e_book_backend_sqlitedb_add_contact
+                                                (EBookBackendSqliteDB *ebsdb,
+						 const gchar *folderid,
+						 EContact *contact,
+						 gboolean partial_content,
+						 GError **error);
+gboolean	e_book_backend_sqlitedb_add_contacts
+                                                (EBookBackendSqliteDB *ebsdb,
+						 const gchar *folderid,
+						 GSList *contacts,
+						 gboolean partial_content,
+						 GError **error);
 #endif
 
 G_END_DECLS



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]