From: Tristan Van Berkom Date: Fri, 18 Jan 2013 06:50:04 +0000 (+0900) Subject: EBookBackendSqliteDB: Added e_book_backend_new_contact[s]() APIs X-Git-Tag: upstream/3.7.5~161 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=e51f21579c7839b6c3e15a0685c5ec37e8298fff;p=platform%2Fupstream%2Fevolution-data-server.git 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 --- diff --git a/addressbook/libedata-book/e-book-backend-sqlitedb.c b/addressbook/libedata-book/e-book-backend-sqlitedb.c index 3275017..5df68c3 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; @@ -1041,7 +1043,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; } @@ -1093,7 +1095,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; } @@ -1127,7 +1129,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)); @@ -1367,15 +1369,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); @@ -1440,10 +1443,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; @@ -1452,7 +1455,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); @@ -1515,26 +1518,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; @@ -1546,30 +1548,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; @@ -1584,7 +1588,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) @@ -1597,6 +1601,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. @@ -2062,7 +2120,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.")); } @@ -2075,7 +2133,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; @@ -2858,7 +2916,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.")); } @@ -3000,7 +3058,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.")); } @@ -3081,7 +3139,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.")); } @@ -3753,7 +3811,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 897753e..c5621af 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