[evolution-data-server/openismus-work-master] Fixing sqlitedb object apis to be better usable from backends.
- From: Tristan Van Berkom <tvb src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [evolution-data-server/openismus-work-master] Fixing sqlitedb object apis to be better usable from backends.
- Date: Sat, 6 Aug 2011 23:26:19 +0000 (UTC)
commit 25b4ca9f3bfaaa11dda84dd4d9b55c67dd3b89c9
Author: Tristan Van Berkom <tristan van berkom gmail com>
Date: Sat Aug 6 19:22:55 2011 -0400
Fixing sqlitedb object apis to be better usable from backends.
This patch enhances the apis by adding 'gboolean *searched' and
'gboolean *complete_vcards' parameters to a variety of the apis.
This allows the backend to still use the sqlitedb to perform a
quick search and fall back on loading the correct full vcards
from another persistence (it also informs the caller if a search
was indeed performed on the summary but had no matches, allowing
the backends to avoid repeating the search in another persistence).
Bug: https://bugzilla.gnome.org/show_bug.cgi?id=656058
.../libedata-book/e-book-backend-sqlitedb-test.c | 4 +-
.../libedata-book/e-book-backend-sqlitedb.c | 206 +++++++++++++-------
.../libedata-book/e-book-backend-sqlitedb.h | 28 ++-
3 files changed, 150 insertions(+), 88 deletions(-)
---
diff --git a/addressbook/libedata-book/e-book-backend-sqlitedb-test.c b/addressbook/libedata-book/e-book-backend-sqlitedb-test.c
index 36df25a..16f8248 100644
--- a/addressbook/libedata-book/e-book-backend-sqlitedb-test.c
+++ b/addressbook/libedata-book/e-book-backend-sqlitedb-test.c
@@ -96,7 +96,7 @@ search_db (EBookBackendSqliteDB *ebsdb, const gchar *type, const gchar *sexp)
g_print ("%s - query: %s \n", type, sexp);
op = type;
- vcards = e_book_backend_sqlitedb_search (ebsdb, folderid, sexp, NULL, &error);
+ vcards = e_book_backend_sqlitedb_search (ebsdb, folderid, sexp, NULL, NULL, NULL, &error);
if (error)
return;
@@ -148,7 +148,7 @@ start_tests (gpointer data)
g_print ("Get Vcard string \n");
op = "get vcard string";
- vcard_str = e_book_backend_sqlitedb_get_vcard_string (ebsdb, folderid, uid, NULL, &error);
+ vcard_str = e_book_backend_sqlitedb_get_vcard_string (ebsdb, folderid, uid, NULL, NULL, &error);
if (error)
goto exit;
g_print ("VCard: %s \n", vcard_str);
diff --git a/addressbook/libedata-book/e-book-backend-sqlitedb.c b/addressbook/libedata-book/e-book-backend-sqlitedb.c
index 04a9216..e54320c 100644
--- a/addressbook/libedata-book/e-book-backend-sqlitedb.c
+++ b/addressbook/libedata-book/e-book-backend-sqlitedb.c
@@ -813,12 +813,13 @@ e_book_backend_sqlitedb_get_contact (EBookBackendSqliteDB *ebsdb,
const gchar *folderid,
const gchar *uid,
GHashTable *fields_of_interest,
- GError **error)
+ gboolean *complete,
+ GError **error)
{
GError *err = NULL;
EContact *contact = NULL;
gchar *vcard = e_book_backend_sqlitedb_get_vcard_string (ebsdb, folderid, uid,
- fields_of_interest, &err);
+ fields_of_interest, complete, &err);
if (!err) {
contact = e_contact_new_from_vcard (vcard);
g_free (vcard);
@@ -852,29 +853,56 @@ accumulate_fields_select_stmt (const gchar *field_name,
g_string_append (string, dbname);
}
+static void
+check_field_foreach (const gchar *field_name,
+ gpointer is_present,
+ gboolean *is_summary_query)
+{
+ EContactField field = e_contact_field_id (field_name);
+
+ if (!summary_dbname_from_field (field)) {
+ *is_summary_query = FALSE;
+ }
+}
+
+gboolean
+e_book_backend_sqlitedb_is_summary_fields (GHashTable *fields_of_interest)
+{
+ gboolean summary_fields = TRUE;
+
+ if (!fields_of_interest)
+ return FALSE;
+
+ g_hash_table_foreach (fields_of_interest, (GHFunc)check_field_foreach, &summary_fields);
+
+ return summary_fields;
+}
+
/* free return value with g_free */
static gchar *
summary_select_stmt (const gchar *folderid,
- GHashTable *fields_of_interest)
+ GHashTable *fields_of_interest,
+ gboolean *complete_vcards)
{
GString *string;
gchar *str;
- gint i;
string = g_string_new ("SELECT uid");
- /* If filtering by fields of interest, only query those and include the 'uid' */
- if (fields_of_interest) {
-
+ /* If filtering by fields of interest, only query those and include the 'uid'
+ *
+ */
+ if (fields_of_interest && e_book_backend_sqlitedb_is_summary_fields (fields_of_interest)) {
g_hash_table_foreach (fields_of_interest, (GHFunc)accumulate_fields_select_stmt, string);
- } else {
- /* ... Otherwise just select all the summary information */
- for (i = 1; i < G_N_ELEMENTS (summary_fields); i++) {
- g_string_append (string, ", ");
- g_string_append (string, summary_fields[i].dbname);
- }
- }
+ /* The query should return all the required information */
+ if (complete_vcards)
+ *complete_vcards = TRUE;
+ } else if (complete_vcards)
+ /* If the fields of interest is null or contains fields that are not
+ * part of the summary then only the uids are returned.
+ */
+ *complete_vcards = FALSE;
str = sqlite3_mprintf (" FROM %Q", folderid);
g_string_append (string, str);
@@ -884,22 +912,44 @@ summary_select_stmt (const gchar *folderid,
}
+/**
+ * e_book_backend_sqlitedb_get_vcard_string:
+ * @ebsdb: An #EBookBackendSqliteDB
+ * @folderid: The folder id
+ * @uid: The uid to fetch a vcard for
+ * @fields_of_interest: The required fields for this vcard, or %NULL to require all fields.
+ * @complete_vcard: (allow none) (out): Whether all the required fields are present in the returned vcard.
+ * @error: A location to store any error that may have occurred.
+ *
+ * Searches @ebsdb in the context of @folderid for @uid.
+ *
+ * If @ebsdb is configured to store the whole vcards, the whole vcard will be returned.
+ * Otherwise the summary cache will be searched and the virtual vcard will be built
+ * from the summary cache.
+ *
+ * In either case, @complete_vcard if specified, will be updated to reflect whether
+ * the returned vcard string satisfies the passed 'fields_of_interest' parameter.
+ *
+ * Returns: (transfer full): The vcard string for @uid or %NULL if @uid was not found.
+ */
gchar *
e_book_backend_sqlitedb_get_vcard_string (EBookBackendSqliteDB *ebsdb,
- const gchar *folderid,
- const gchar *uid,
- GHashTable *fields_of_interest,
- GError **error)
+ const gchar *folderid,
+ const gchar *uid,
+ GHashTable *fields_of_interest,
+ gboolean *complete_vcard,
+ GError **error)
{
gchar *stmt, *select_stmt;
gchar *vcard_str = NULL;
+ gboolean local_complete_vcard = FALSE;
READER_LOCK (ebsdb);
if (!ebsdb->priv->store_vcard) {
GSList *vcards = NULL;
- select_stmt = summary_select_stmt (folderid, fields_of_interest);
+ select_stmt = summary_select_stmt (folderid, fields_of_interest, &local_complete_vcard);
stmt = sqlite3_mprintf ("%s WHERE uid = %Q", select_stmt, uid);
book_backend_sql_exec (ebsdb->priv->db, stmt, store_data_to_vcard, &vcards, error);
@@ -922,10 +972,15 @@ e_book_backend_sqlitedb_get_vcard_string (EBookBackendSqliteDB *ebsdb,
stmt = sqlite3_mprintf ("SELECT vcard FROM %Q WHERE uid = %Q", folderid, uid);
book_backend_sql_exec (ebsdb->priv->db, stmt, get_vcard_cb , &vcard_str, error);
sqlite3_free (stmt);
+
+ local_complete_vcard = TRUE;
}
READER_UNLOCK (ebsdb);
+ if (complete_vcard)
+ *complete_vcard = local_complete_vcard;
+
return vcard_str;
}
@@ -934,7 +989,6 @@ func_check (struct _ESExp *f, gint argc, struct _ESExpResult **argv, gpointer da
{
ESExpResult *r;
gint truth = FALSE;
- gboolean fields = GPOINTER_TO_INT (data);
if (argc == 2
&& argv[0]->type == ESEXP_RES_STRING
@@ -943,15 +997,9 @@ func_check (struct _ESExp *f, gint argc, struct _ESExpResult **argv, gpointer da
gchar *query_name = argv[0]->value.string;
gint i;
- /* The "contains x-evolution-any-field" query is the standard query
- * with no query specified, in this case the query is indeed a summary
- * query if fields-of-interest have been specified as all summary fields.
- *
- * If no filtering is specified we assume that the special "any-field" means
- * that the client wants all the fields returned (thus it would not
- * be a summary query).
- */
- if (fields && !strcmp ("x-evolution-any-field", query_name))
+ /* Special case, when testing the special symbolic 'any field' we can
+ * consider it a summary query (it's similar to a 'no query'). */
+ if (!strcmp ("x-evolution-any-field", query_name))
truth = TRUE;
for (i = 0; truth == FALSE && i < G_N_ELEMENTS (summary_fields); i++) {
@@ -981,57 +1029,27 @@ static const struct {
{ "exists", func_check, 0 }
};
-static void
-check_field_foreach (const gchar *field_name,
- gpointer is_present,
- gboolean *is_summary_query)
-{
- EContactField field = e_contact_field_id (field_name);
-
- if (!summary_dbname_from_field (field)) {
- *is_summary_query = FALSE;
- }
-}
-
-static gboolean
-book_backend_sqlitedb_is_summary_fields (GHashTable *fields_of_interest)
-{
- gboolean summary_fields = TRUE;
-
- g_hash_table_foreach (fields_of_interest, (GHFunc)check_field_foreach, &summary_fields);
-
- return summary_fields;
-}
-
gboolean
-e_book_backend_sqlitedb_is_summary_query (const gchar *query, GHashTable *fields_of_interest)
+e_book_backend_sqlitedb_is_summary_query (const gchar *query)
{
ESExp *sexp;
ESExpResult *r;
- gboolean retval, fields_are_summary;
+ gboolean retval;
gint i;
gint esexp_error;
g_return_val_if_fail (query != NULL, FALSE);
g_return_val_if_fail (*query, FALSE);
- fields_are_summary =
- (fields_of_interest && book_backend_sqlitedb_is_summary_fields (fields_of_interest));
-
- if (fields_of_interest && !fields_are_summary)
- return FALSE;
-
sexp = e_sexp_new ();
for (i = 0; i < G_N_ELEMENTS (check_symbols); i++) {
if (check_symbols[i].type == 1) {
e_sexp_add_ifunction (sexp, 0, check_symbols[i].name,
- (ESExpIFunc *) check_symbols[i].func,
- GINT_TO_POINTER (fields_are_summary));
+ (ESExpIFunc *) check_symbols[i].func, NULL);
} else {
e_sexp_add_function (sexp, 0, check_symbols[i].name,
- check_symbols[i].func,
- GINT_TO_POINTER (fields_are_summary));
+ check_symbols[i].func, NULL);
}
}
@@ -1311,17 +1329,19 @@ book_backend_sqlitedb_search_query (EBookBackendSqliteDB *ebsdb,
const gchar *sql,
const gchar *folderid,
/* const */ GHashTable *fields_of_interest,
- GError **error)
+ gboolean *complete_vcards,
+ GError **error)
{
GError *err = NULL;
GSList *vcard_data = NULL;
gchar *stmt, *select_stmt;
+ gboolean local_complete = FALSE;
READER_LOCK (ebsdb);
if (!ebsdb->priv->store_vcard) {
- select_stmt = summary_select_stmt (folderid, fields_of_interest);
+ select_stmt = summary_select_stmt (folderid, fields_of_interest, &local_complete);
if (sql && sql[0]) {
stmt = sqlite3_mprintf ("%s WHERE %s", select_stmt, sql);
@@ -1344,6 +1364,7 @@ book_backend_sqlitedb_search_query (EBookBackendSqliteDB *ebsdb,
book_backend_sql_exec (ebsdb->priv->db, stmt, addto_vcard_list_cb , &vcard_data, &err);
sqlite3_free (stmt);
}
+ local_complete = TRUE;
}
READER_UNLOCK (ebsdb);
@@ -1354,6 +1375,9 @@ book_backend_sqlitedb_search_query (EBookBackendSqliteDB *ebsdb,
if (err)
g_propagate_error (error, err);
+ if (complete_vcards)
+ * complete_vcards = local_complete;
+
return vcard_data;
}
@@ -1406,13 +1430,22 @@ book_backend_sqlitedb_search_full (EBookBackendSqliteDB *ebsdb, const gchar *sex
* @fields_of_interest: a #GHashTable containing the names of fields to return, or NULL for all.
* At the moment if this is non-null, the vcard will be populated with summary fields, else it would return the
* whole vcard if its stored in the db. [not implemented fully]
+ * @searched: (allow none) (out): Whether @ebsdb was capable of searching for the provided query @sexp.
+ * @complete_vcards: (allow none) (out): Whether all the required fields are present in the returned vcards.
* @error:
- * Search on summary fields is always supported. Search expression containing
- * any other field is supported only if backend chooses to store the vcard inside the db.
*
- * Summary fields - uid, nickname, given_name, family_name, file_as email_1, email_2, email_3, email_4, is_list,
+ * Searching with summary fields is always supported. Search expressions containing
+ * any other field is supported only if backend chooses to store the vcard inside the db.
+ *
+ * Summary fields - uid, rev, nickname, given_name, family_name, file_as email_1, email_2, email_3, email_4, is_list,
* list_show_addresses, wants_html
*
+ * If @ebsdb was incapable of returning vcards with results that satisfy
+ * @fields_of_interest, then @complete_vcards will be updated to @FALSE
+ * and only uid fields will be present in the returned vcards. This can be useful
+ * when a summary query succeeds and the returned list can be used to iterate
+ * and fetch for full required data from another persistance.
+ *
* Returns: List of EbSdbSearchData.
**/
GSList *
@@ -1420,26 +1453,42 @@ e_book_backend_sqlitedb_search (EBookBackendSqliteDB *ebsdb,
const gchar *folderid,
const gchar *sexp,
/* const */ GHashTable *fields_of_interest,
+ gboolean *searched,
+ gboolean *complete_vcards,
GError **error)
{
GSList *search_contacts = NULL;
+ gboolean local_searched = FALSE;
+ gboolean local_complete_vcards = FALSE;
if (sexp && !*sexp)
sexp = NULL;
- if (!sexp || e_book_backend_sqlitedb_is_summary_query (sexp, fields_of_interest)) {
+ if (!sexp || e_book_backend_sqlitedb_is_summary_query (sexp)) {
gchar *sql_query;
sql_query = sexp ? sexp_to_sql_query (sexp) : NULL;
- search_contacts = book_backend_sqlitedb_search_query (ebsdb, sql_query, folderid, fields_of_interest, error);
+ search_contacts = book_backend_sqlitedb_search_query (ebsdb, sql_query, folderid,
+ fields_of_interest,
+ &local_complete_vcards, error);
g_free (sql_query);
- } else if (ebsdb->priv->store_vcard)
+
+ local_searched = TRUE;
+
+ } else if (ebsdb->priv->store_vcard) {
search_contacts = book_backend_sqlitedb_search_full (ebsdb, sexp, folderid, FALSE, error);
- else {
+ local_searched = TRUE;
+ local_complete_vcards = TRUE;
+ } else {
g_set_error (error, E_BOOK_SDB_ERROR,
0, "Full search_contacts are not stored in cache. Hence only summary query is supported.");
}
+ if (searched)
+ *searched = local_searched;
+ if (complete_vcards)
+ *complete_vcards = local_complete_vcards;
+
return search_contacts;
}
@@ -1447,14 +1496,16 @@ GSList *
e_book_backend_sqlitedb_search_uids (EBookBackendSqliteDB *ebsdb,
const gchar *folderid,
const gchar *sexp,
- GError **error)
+ gboolean *searched,
+ GError **error)
{
GSList *uids = NULL;
+ gboolean local_searched = FALSE;
if (sexp && !*sexp)
sexp = NULL;
- if (!sexp || e_book_backend_sqlitedb_is_summary_query (sexp, NULL)) {
+ if (!sexp || e_book_backend_sqlitedb_is_summary_query (sexp)) {
gchar *stmt;
gchar *sql_query = sexp ? sexp_to_sql_query (sexp) : NULL;
@@ -1466,9 +1517,14 @@ e_book_backend_sqlitedb_search_uids (EBookBackendSqliteDB *ebsdb,
READER_UNLOCK (ebsdb);
+ local_searched = TRUE;
+
g_free (sql_query);
- } else if (ebsdb->priv->store_vcard)
+ } else if (ebsdb->priv->store_vcard) {
uids = book_backend_sqlitedb_search_full (ebsdb, sexp, folderid, TRUE, error);
+
+ local_searched = TRUE;
+ }
else {
g_set_error (error, E_BOOK_SDB_ERROR,
0, "Full vcards are not stored in cache. Hence only summary query is supported.");
diff --git a/addressbook/libedata-book/e-book-backend-sqlitedb.h b/addressbook/libedata-book/e-book-backend-sqlitedb.h
index b41aea6..4dd1419 100644
--- a/addressbook/libedata-book/e-book-backend-sqlitedb.h
+++ b/addressbook/libedata-book/e-book-backend-sqlitedb.h
@@ -100,27 +100,33 @@ gboolean e_book_backend_sqlitedb_has_contact (EBookBackendSqliteDB *ebsdb,
const gchar *uid,
gboolean *partial_content,
GError **error);
-EContact * e_book_backend_sqlitedb_get_contact
- (EBookBackendSqliteDB *ebsdb,
- const gchar *folderid,
- const gchar *uid,
- GHashTable *fields_of_interest,
- GError **error);
-gchar * e_book_backend_sqlitedb_get_vcard_string
- (EBookBackendSqliteDB *ebsdb,
+EContact * e_book_backend_sqlitedb_get_contact (EBookBackendSqliteDB *ebsdb,
const gchar *folderid,
const gchar *uid,
GHashTable *fields_of_interest,
+ gboolean *complete,
GError **error);
+gchar * e_book_backend_sqlitedb_get_vcard_string
+ (EBookBackendSqliteDB *ebsdb,
+ const gchar *folderid,
+ const gchar *uid,
+ GHashTable *fields_of_interest,
+ gboolean *complete_vcard,
+ GError **error);
+
GSList * e_book_backend_sqlitedb_search (EBookBackendSqliteDB *ebsdb,
const gchar *folderid,
const gchar *sexp,
/* const */ GHashTable *fields_of_interest,
- GError **error);
+ gboolean *searched,
+ gboolean *complete_vcards,
+ GError **error);
+
GSList * e_book_backend_sqlitedb_search_uids
(EBookBackendSqliteDB *ebsdb,
const gchar *folderid,
const gchar *sexp,
+ gboolean *searched,
GError **error);
gboolean e_book_backend_sqlitedb_get_is_populated
(EBookBackendSqliteDB *ebsdb,
@@ -187,8 +193,8 @@ gboolean e_book_backend_sqlitedb_remove (EBookBackendSqliteDB *ebsdb,
void e_book_backend_sqlitedb_search_data_free
(EbSdbSearchData *s_data);
-gboolean e_book_backend_sqlitedb_is_summary_query (const gchar *query,
- GHashTable *fields_of_interest);
+gboolean e_book_backend_sqlitedb_is_summary_query (const gchar *query);
+gboolean e_book_backend_sqlitedb_is_summary_fields (GHashTable *fields_of_interest);
G_END_DECLS
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]