[evolution-data-server/openismus-work: 59/122] EBookBackendSqliteDB: Avoid errors on conflicting summaries
- From: Tristan Van Berkom <tvb src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [evolution-data-server/openismus-work: 59/122] EBookBackendSqliteDB: Avoid errors on conflicting summaries
- Date: Mon, 17 Dec 2012 09:08:16 +0000 (UTC)
commit d52a7e0415e8a78d764adf87caff6a8e78508429
Author: Tristan Van Berkom <tristanvb openismus com>
Date: Fri Nov 23 18:45:33 2012 +0900
EBookBackendSqliteDB: Avoid errors on conflicting summaries
Added function introspect_summary() to derive the summary information
from a running database.
Now the initialization of the DB is a bit safer:
o First collect configured summary
o Create Database (if it doesnt exist) with the configured summary
o Now derive the summary from the existing database
This ensures that inserts/selects run with the summary configuration
which matches the actual running database, regardless if the DB was
configured with the actual ESourceBackendSummarySetup passed or previously
configured with something else.
.../libedata-book/e-book-backend-sqlitedb.c | 455 +++++++++++++++-----
1 files changed, 343 insertions(+), 112 deletions(-)
---
diff --git a/addressbook/libedata-book/e-book-backend-sqlitedb.c b/addressbook/libedata-book/e-book-backend-sqlitedb.c
index da2dd98..f74447b 100644
--- a/addressbook/libedata-book/e-book-backend-sqlitedb.c
+++ b/addressbook/libedata-book/e-book-backend-sqlitedb.c
@@ -39,18 +39,8 @@
#define d(x)
-/* DEBUGGING QUERY PLANS */
-
-/* #define DEBUG_QUERIES */
-
-#ifdef DEBUG_QUERIES
-# define book_backend_sql_exec book_backend_sql_exec_wrap
-#else
-# define book_backend_sql_exec book_backend_sql_exec_real
-#endif
-
#define DB_FILENAME "contacts.db"
-#define FOLDER_VERSION 2
+#define FOLDER_VERSION 3
#define READER_LOCK(ebsdb) g_static_rw_lock_reader_lock (&ebsdb->priv->rwlock)
#define READER_UNLOCK(ebsdb) g_static_rw_lock_reader_unlock (&ebsdb->priv->rwlock)
@@ -66,7 +56,7 @@ typedef struct {
EContactField field; /* The EContact field */
GType type; /* The GType (only support string or gboolean) */
const gchar *dbname; /* The key for this field in the sqlite3 table */
- IndexFlags index; /* Whether this summary field should have an index in the SQLite DB */
+ IndexFlags index; /* Whether this summary field should have an index in the SQLite DB */
} SummaryField;
struct _EBookBackendSqliteDBPrivate {
@@ -125,7 +115,10 @@ static EBookIndexType default_index_types[] = {
E_BOOK_INDEX_PREFIX
};
-
+static gboolean append_summary_field (GArray *array,
+ EContactField field,
+ gboolean *have_attr_list,
+ GError **error);
static const gchar *
summary_dbname_from_field (EBookBackendSqliteDB *ebsdb, EContactField field)
@@ -245,6 +238,32 @@ e_book_backend_sqlitedb_init (EBookBackendSqliteDB *ebsdb)
ebsdb->priv->in_transaction_lock = g_mutex_new ();
}
+static gint
+get_string_cb (gpointer ref,
+ gint col,
+ gchar **cols,
+ gchar **name)
+{
+ gchar **ret = ref;
+
+ *ret = g_strdup (cols [0]);
+
+ return 0;
+}
+
+static gint
+get_bool_cb (gpointer ref,
+ gint col,
+ gchar **cols,
+ gchar **name)
+{
+ gboolean *ret = ref;
+
+ *ret = cols [0] ? strtoul (cols [0], NULL, 10) : 0;
+
+ return 0;
+}
+
/**
* e_book_sql_exec
* @db:
@@ -293,7 +312,6 @@ book_backend_sql_exec_real (sqlite3 *db,
return TRUE;
}
-#ifdef DEBUG_QUERIES
static gint
print_debug_cb (gpointer ref,
gint col,
@@ -302,34 +320,53 @@ print_debug_cb (gpointer ref,
{
gint i;
- g_print ("DEBUG BEGIN: %d results\n", col);
+ g_print (" DEBUG BEGIN: %d results\n", col);
for (i = 0; i < col; i++)
- g_print ("NAME: '%s' COL: %s\n", name[i], cols[i]);
+ g_print (" NAME: '%s' COL: %s\n", name[i], cols[i]);
- g_print ("DEBUG END\n");
+ g_print (" DEBUG END\n");
return 0;
}
-static gboolean
-book_backend_sql_exec_wrap (sqlite3 *db,
- const gchar *stmt,
- gint (*callback)(gpointer ,gint,gchar **,gchar **),
- gpointer data,
- GError **error)
+static void
+book_backend_sql_debug (sqlite3 *db,
+ const gchar *stmt,
+ gint (*callback)(gpointer ,gint,gchar **,gchar **),
+ gpointer data,
+ GError **error)
{
gchar *debug;
+ GError *local_error = NULL;
debug = g_strconcat ("EXPLAIN QUERY PLAN ", stmt, NULL);
g_print ("DEBUG STATEMENT: %s\n", stmt);
- book_backend_sql_exec_real (db, debug, print_debug_cb, NULL, NULL);
- g_print ("DEBUG STATEMENT END\n");
+ book_backend_sql_exec_real (db, debug, print_debug_cb, NULL, &local_error);
+ g_print ("DEBUG STATEMENT END: %s%s\n", local_error ? "Error: " : "", local_error ? local_error->message : "Success");
g_free (debug);
+ g_clear_error (&local_error);
+}
+
+static gboolean
+book_backend_sql_exec (sqlite3 *db,
+ const gchar *stmt,
+ gint (*callback)(gpointer ,gint,gchar **,gchar **),
+ gpointer data,
+ GError **error)
+{
+ static gint booksql_debug = -1;
+
+ if (booksql_debug == -1) {
+ booksql_debug = g_getenv ("BOOKSQL_DEBUG") != NULL ? 1 : 0;
+ }
+
+ if (booksql_debug)
+ book_backend_sql_debug (db, stmt, callback, data, error);
+
return book_backend_sql_exec_real (db, stmt, callback, data, error);
}
-#endif
/* the first caller holds the writer lock too */
static gboolean
@@ -426,16 +463,20 @@ create_folders_table (EBookBackendSqliteDB *ebsdb,
* Have not included a bdata here since the keys table should suffice any
* additional need that arises.
*/
- const gchar *stmt = "CREATE TABLE IF NOT EXISTS folders"
- "( folder_id TEXT PRIMARY KEY,"
- " folder_name TEXT,"
- " sync_data TEXT,"
- " is_populated INTEGER,"
- " partial_content INTEGER,"
- " version INTEGER,"
- " revision TEXT)";
-
- book_backend_sqlitedb_start_transaction (ebsdb, &err);
+ const gchar *stmt =
+ "CREATE TABLE IF NOT EXISTS folders"
+ "( folder_id TEXT PRIMARY KEY,"
+ " folder_name TEXT,"
+ " sync_data TEXT,"
+ " is_populated INTEGER,"
+ " partial_content INTEGER,"
+ " version INTEGER,"
+ " revision TEXT,"
+ " multivalues TEXT,"
+ " reverse_multivalues INTEGER )";
+
+ if (!book_backend_sqlitedb_start_transaction (ebsdb, error))
+ return;
if (!err)
book_backend_sql_exec (ebsdb->priv->db, stmt, NULL, NULL , &err);
@@ -459,18 +500,37 @@ create_folders_table (EBookBackendSqliteDB *ebsdb,
book_backend_sql_exec (ebsdb->priv->db, stmt, collect_versions_cb, &version, &err);
}
- /* Upgrade DB to version 2, add the 'revision' column
+ /* Upgrade DB to version 2, add revision column
*
* (version = 0 indicates that it did not exist and we just created the table)
*/
if (!err && version >= 1 && version < 2) {
stmt = "ALTER TABLE folders ADD COLUMN revision TEXT";
- book_backend_sql_exec (ebsdb->priv->db, stmt, NULL, NULL, &err);
+ book_backend_sql_exec (
+ ebsdb->priv->db, stmt, NULL, NULL, &err);
}
- if (!err && version >= 1 && version < 2) {
- stmt = "UPDATE folders SET version = 2";
- book_backend_sql_exec (ebsdb->priv->db, stmt, NULL, NULL, &err);
+ /* Upgrade DB to version 3, add multivalues introspection columns
+ */
+ if (!err && version >= 1 && version < 3) {
+
+ stmt = "ALTER TABLE folders ADD COLUMN multivalues TEXT";
+ book_backend_sql_exec (
+ ebsdb->priv->db, stmt, NULL, NULL, &err);
+
+ stmt = "ALTER TABLE folders ADD COLUMN reverse_multivalues INTEGER";
+ book_backend_sql_exec (
+ ebsdb->priv->db, stmt, NULL, NULL, &err);
+ }
+
+ if (!err && version >= 1 && version < FOLDER_VERSION) {
+ gchar *version_update_stmt =
+ sqlite3_mprintf ("UPDATE folders SET version = %d", FOLDER_VERSION);
+
+ book_backend_sql_exec (
+ ebsdb->priv->db, version_update_stmt, NULL, NULL, &err);
+
+ sqlite3_free (version_update_stmt);
}
book_backend_sqlitedb_end_transaction (ebsdb, !err, err ? NULL : &err);
@@ -483,6 +543,38 @@ create_folders_table (EBookBackendSqliteDB *ebsdb,
return;
}
+
+static gchar *
+format_multivalues (EBookBackendSqliteDB *ebsdb,
+ gboolean *reverse_multivalues)
+{
+ gint i;
+ GString *string;
+ gboolean first = TRUE;
+ gboolean has_reverse = FALSE;
+
+ string = g_string_new (NULL);
+
+ for (i = 0; i < ebsdb->priv->n_summary_fields; i++) {
+ if (ebsdb->priv->summary_fields[i].type == E_TYPE_CONTACT_ATTR_LIST) {
+ if (first)
+ first = FALSE;
+ else
+ g_string_append_c (string, ':');
+
+ g_string_append (string, ebsdb->priv->summary_fields[i].dbname);
+
+ if ((ebsdb->priv->summary_fields[i].index & INDEX_SUFFIX) != 0)
+ has_reverse = TRUE;
+ }
+ }
+
+ if (reverse_multivalues)
+ *reverse_multivalues = has_reverse;
+
+ return g_string_free (string, FALSE);
+}
+
static void
add_folder_into_db (EBookBackendSqliteDB *ebsdb,
const gchar *folderid,
@@ -491,18 +583,22 @@ add_folder_into_db (EBookBackendSqliteDB *ebsdb,
{
gchar *stmt;
GError *err = NULL;
+ gboolean has_reverse = FALSE;
+ gchar *multivalues;
book_backend_sqlitedb_start_transaction (ebsdb, &err);
- if (!err) {
- stmt = sqlite3_mprintf (
- "INSERT OR IGNORE INTO folders VALUES ( %Q, %Q, %Q, %d, %d, %d, %Q ) ",
- folderid, folder_name, NULL, 0, 0, FOLDER_VERSION, NULL);
-
- book_backend_sql_exec (ebsdb->priv->db, stmt, NULL, NULL, &err);
+ multivalues = format_multivalues (ebsdb, &has_reverse);
- sqlite3_free (stmt);
- }
+ stmt = sqlite3_mprintf (
+ "INSERT OR IGNORE INTO folders VALUES "
+ "( %Q, %Q, %Q, %d, %d, %d, %Q, %Q, %d ) ",
+ folderid, folder_name, NULL, 0, 0, FOLDER_VERSION,
+ NULL, multivalues, has_reverse);
+ book_backend_sql_exec (
+ ebsdb->priv->db, stmt, NULL, NULL, error);
+ sqlite3_free (stmt);
+ g_free (multivalues);
book_backend_sqlitedb_end_transaction (ebsdb, !err, err ? NULL : &err);
@@ -512,6 +608,171 @@ add_folder_into_db (EBookBackendSqliteDB *ebsdb,
return;
}
+static gint
+collect_columns_cb (gpointer ref,
+ gint col,
+ gchar **cols,
+ gchar **name)
+{
+ GList **columns = (GList **)ref;
+ gint i;
+
+ for (i = 0; i < col; i++) {
+
+ if (strcmp (name[i], "name") == 0) {
+
+ if (strcmp (cols[i], "vcard") != 0 &&
+ strcmp (cols[i], "bdata") != 0) {
+
+ gchar *column = g_strdup (cols[i]);
+
+ *columns = g_list_prepend (*columns, column);
+ }
+
+ break;
+ }
+ }
+
+ return 0;
+}
+
+static gboolean
+introspect_summary (EBookBackendSqliteDB *ebsdb,
+ const gchar *folderid,
+ GError **error)
+{
+ gboolean success;
+ gchar *stmt;
+ GList *summary_columns = NULL, *l;
+ GArray *summary_fields = NULL;
+ gchar *multivalues = NULL;
+ gboolean reverse_multivalues = FALSE;
+ gchar **split;
+ gint i;
+
+ stmt = sqlite3_mprintf ("PRAGMA table_info (%Q);", folderid);
+ success = book_backend_sql_exec (
+ ebsdb->priv->db, stmt, collect_columns_cb, &summary_columns, error);
+ sqlite3_free (stmt);
+
+ if (!success)
+ goto introspect_summary_finish;
+
+ summary_columns = g_list_reverse (summary_columns);
+ summary_fields = g_array_new (FALSE, FALSE, sizeof (SummaryField));
+
+ /* Introspect the normal summary fields */
+ for (l = summary_columns; l; l = l->next) {
+ EContactField field;
+ gchar *col = l->data;
+ gchar *p;
+ gboolean reverse = FALSE;
+
+ /* Check if we're parsing a reverse field */
+ p = strstr (col, "_reverse");
+ if (p) {
+ *p = '\0';
+ reverse = TRUE;
+ }
+
+ /* First check exception fields */
+ if (strcmp (col, "uid") == 0)
+ field = E_CONTACT_UID;
+ else if (strcmp (col, "is_list") == 0)
+ field = E_CONTACT_IS_LIST;
+ else
+ field = e_contact_field_id (col);
+
+ /* Check for parse error */
+ if (field == 0) {
+ g_set_error (
+ error, E_BOOK_SDB_ERROR, 0,
+ _("Error introspecting unknown summary field '%s'"), col);
+ success = FALSE;
+ break;
+ }
+
+ /* Reverse columns are always declared after the normal columns,
+ * if a reverse field is encountered we need to set the suffix
+ * index on the coresponding summary field
+ */
+ if (reverse) {
+ for (i = 0; i < summary_fields->len; i++) {
+ SummaryField *iter = &g_array_index (summary_fields, SummaryField, i);
+
+ if (iter->field == field) {
+ iter->index |= INDEX_SUFFIX;
+ break;
+ }
+ }
+ } else {
+ append_summary_field (summary_fields, field, NULL, NULL);
+ }
+ }
+
+ if (!success)
+ goto introspect_summary_finish;
+
+ /* Introspect the multivalied summary fields */
+ stmt = sqlite3_mprintf (
+ "SELECT multivalues FROM folders WHERE folder_id = %Q", folderid);
+ success = book_backend_sql_exec (
+ ebsdb->priv->db, stmt, get_string_cb, &multivalues, error);
+ sqlite3_free (stmt);
+
+ if (!success)
+ goto introspect_summary_finish;
+
+ stmt = sqlite3_mprintf (
+ "SELECT reverse_multivalues FROM folders WHERE folder_id = %Q", folderid);
+ success = book_backend_sql_exec (
+ ebsdb->priv->db, stmt, get_bool_cb, &reverse_multivalues, error);
+ sqlite3_free (stmt);
+
+ if (!success)
+ goto introspect_summary_finish;
+
+ if (multivalues) {
+ split = g_strsplit (multivalues, ":", 0);
+
+ for (i = 0; split[i] != NULL; i++) {
+ EContactField field;
+
+ field = e_contact_field_id (split[i]);
+ append_summary_field (summary_fields, field, NULL, NULL);
+ }
+ g_strfreev (split);
+ }
+
+ /* If there is a reverse multivalue column, enable lookups for every multivalue field in reverse */
+ if (reverse_multivalues) {
+
+ for (i = 0; i < summary_fields->len; i++) {
+ SummaryField *iter = &g_array_index (summary_fields, SummaryField, i);
+
+ if (iter->type == E_TYPE_CONTACT_ATTR_LIST)
+ iter->index |= INDEX_SUFFIX;
+ }
+ }
+
+ introspect_summary_finish:
+
+ g_list_free_full (summary_columns, (GDestroyNotify)g_free);
+ g_free (multivalues);
+
+ /* Apply the introspected summary fields */
+ if (success) {
+ g_free (ebsdb->priv->summary_fields);
+ ebsdb->priv->n_summary_fields = summary_fields->len;
+ ebsdb->priv->summary_fields = (SummaryField *)g_array_free (summary_fields, FALSE);
+ } else if (summary_fields) {
+ g_array_free (summary_fields, TRUE);
+ }
+
+ return success;
+}
+
+
/* The column names match the fields used in book-backend-sexp */
static gboolean
create_contacts_table (EBookBackendSqliteDB *ebsdb,
@@ -587,8 +848,7 @@ create_contacts_table (EBookBackendSqliteDB *ebsdb,
/* Construct the create statement from the attribute list summary table */
if (!err && ebsdb->priv->have_attr_list) {
-
- string = g_string_new ("CREATE TABLE IF NOT EXISTS %Q ( uid TEXT NOT NULL REFERENCES %s(uid), "
+ string = g_string_new ("CREATE TABLE IF NOT EXISTS %Q ( uid TEXT NOT NULL REFERENCES %Q(uid), "
"field TEXT, value TEXT");
if (ebsdb->priv->have_attr_list_suffix)
@@ -627,6 +887,9 @@ create_contacts_table (EBookBackendSqliteDB *ebsdb,
WRITER_UNLOCK (ebsdb);
+ if (!err)
+ ret = introspect_summary (ebsdb, folderid, &err);
+
if (err)
g_propagate_error (error, err);
@@ -811,7 +1074,7 @@ append_summary_field (GArray *array,
return FALSE;
}
- if (type == E_TYPE_CONTACT_ATTR_LIST)
+ if (type == E_TYPE_CONTACT_ATTR_LIST && have_attr_list)
*have_attr_list = TRUE;
new_field.field = field;
@@ -1067,8 +1330,9 @@ insert_stmt_from_contact (EBookBackendSqliteDB *ebsdb,
val = e_contact_get (contact, ebsdb->priv->summary_fields[i].field);
- /* Special exception, never normalize the UID string */
- if (ebsdb->priv->summary_fields[i].field != E_CONTACT_UID)
+ /* Special exception, never normalize the UID & REV string */
+ if (ebsdb->priv->summary_fields[i].field != E_CONTACT_UID &&
+ ebsdb->priv->summary_fields[i].field != E_CONTACT_REV)
normal = e_util_utf8_normalize (val);
else
normal = g_strdup (val);
@@ -1632,6 +1896,7 @@ e_book_backend_sqlitedb_get_vcard_string (EBookBackendSqliteDB *ebsdb,
if (with_all_required_fields)
*with_all_required_fields = local_with_all_required_fields;
+ /* Is is an error to not find a contact ?? */
if (!vcard_str && error && !*error)
g_set_error (
error, E_BOOK_SDB_ERROR, 0,
@@ -2033,26 +2298,31 @@ field_name_and_query_term (EBookBackendSqliteDB *ebsdb,
* o Make it a prefix search
*/
if (ebsdb->priv->summary_fields[summary_index].type == E_TYPE_CONTACT_ATTR_LIST) {
- field_name = g_strconcat (folderid, "_lists.value_reverse", NULL);
+ field_name = g_strdup ("multi.value_reverse");
list_attr = TRUE;
} else
- field_name = g_strconcat (folderid, ".",
- ebsdb->priv->summary_fields[summary_index].dbname, "_reverse", NULL);
-
- if (ebsdb->priv->summary_fields[summary_index].field == E_CONTACT_UID)
- value = convert_string_value (query_term_input, FALSE, TRUE, MATCH_BEGINS_WITH);
+ field_name = g_strconcat ("summary.",
+ ebsdb->priv->summary_fields[summary_index].dbname,
+ "_reverse", NULL);
+
+ if (ebsdb->priv->summary_fields[summary_index].field == E_CONTACT_UID ||
+ ebsdb->priv->summary_fields[summary_index].field == E_CONTACT_REV)
+ value = convert_string_value (query_term_input, FALSE, TRUE,
+ (match == MATCH_ENDS_WITH) ? MATCH_BEGINS_WITH : MATCH_IS);
else
- value = convert_string_value (query_term_input, TRUE, TRUE, MATCH_BEGINS_WITH);
+ value = convert_string_value (query_term_input, TRUE, TRUE,
+ (match == MATCH_ENDS_WITH) ? MATCH_BEGINS_WITH : MATCH_IS);
} else {
if (ebsdb->priv->summary_fields[summary_index].type == E_TYPE_CONTACT_ATTR_LIST) {
- field_name = g_strconcat (folderid, "_lists.value", NULL);
+ field_name = g_strdup ("multi.value");
list_attr = TRUE;
} else
- field_name = g_strconcat (folderid, ".",
+ field_name = g_strconcat ("summary.",
ebsdb->priv->summary_fields[summary_index].dbname, NULL);
- if (ebsdb->priv->summary_fields[summary_index].field == E_CONTACT_UID)
+ if (ebsdb->priv->summary_fields[summary_index].field == E_CONTACT_UID ||
+ ebsdb->priv->summary_fields[summary_index].field == E_CONTACT_REV)
value = convert_string_value (query_term_input, FALSE, FALSE, match);
else
value = convert_string_value (query_term_input, TRUE, FALSE, match);
@@ -2157,23 +2427,12 @@ convert_match_exp (struct _ESExp *f,
match, &is_list, &query_term);
if (is_list) {
- gchar *folder_uid, *list_folder_uid, *list_folder_field;
gchar *tmp;
- folder_uid = g_strconcat (qdata->folderid, ".uid", NULL);
- list_folder_uid = g_strconcat (qdata->folderid, "_lists.uid", NULL);
- list_folder_field = g_strconcat (qdata->folderid, "_lists.field", NULL);
-
- tmp = sqlite3_mprintf ("%s = %s AND %s = %Q",
- folder_uid, list_folder_uid,
- list_folder_field, field);
-
+ tmp = sqlite3_mprintf ("summary.uid = multi.uid AND multi.field = %Q", field);
str = g_strdup_printf ("(%s AND %s %s %s)",
tmp, field_name, oper, query_term);
sqlite3_free (tmp);
- g_free (folder_uid);
- g_free (list_folder_uid);
- g_free (list_folder_field);
} else
str = g_strdup_printf ("(%s IS NOT NULL AND %s %s %s)",
field_name, field_name, oper, query_term);
@@ -2349,14 +2608,14 @@ book_backend_sqlitedb_search_query (EBookBackendSqliteDB *ebsdb,
if (query_with_list_attrs) {
gchar *list_table = g_strconcat (folderid, "_lists", NULL);
- gchar *uid_field = g_strconcat (folderid, ".uid", NULL);
- stmt = sqlite3_mprintf ("SELECT DISTINCT %s, vcard, bdata FROM %Q, %Q WHERE %s",
- uid_field, folderid, list_table, sql);
+ stmt = sqlite3_mprintf ("SELECT DISTINCT summary.uid, vcard, bdata "
+ "FROM %Q AS summary, %Q AS multi WHERE %s",
+ folderid, list_table, sql);
g_free (list_table);
- g_free (uid_field);
- } else
- stmt = sqlite3_mprintf ("SELECT uid, vcard, bdata FROM %Q WHERE %s", folderid, sql);
+ } else {
+ stmt = sqlite3_mprintf ("SELECT uid, vcard, bdata FROM %Q as summary WHERE %s", folderid, sql);
+ }
book_backend_sql_exec (ebsdb->priv->db, stmt, addto_vcard_list_cb , &vcard_data, &err);
sqlite3_free (stmt);
@@ -2542,13 +2801,11 @@ e_book_backend_sqlitedb_search_uids (EBookBackendSqliteDB *ebsdb,
if (query_with_list_attrs) {
gchar *list_table = g_strconcat (folderid, "_lists", NULL);
- gchar *uid_field = g_strconcat (folderid, ".uid", NULL);
- stmt = sqlite3_mprintf ("SELECT DISTINCT %s FROM %Q, %Q WHERE %s",
- uid_field, folderid, list_table, sql_query);
+ stmt = sqlite3_mprintf ("SELECT DISTINCT summary.uid FROM %Q AS summary, %Q AS multi %s",
+ folderid, list_table, sql_query);
g_free (list_table);
- g_free (uid_field);
} else
stmt = sqlite3_mprintf ("SELECT uid FROM %Q WHERE %s", folderid, sql_query);
@@ -2631,19 +2888,6 @@ e_book_backend_sqlitedb_get_uids_and_rev (EBookBackendSqliteDB *ebsdb,
return uids_and_rev;
}
-static gint
-get_bool_cb (gpointer ref,
- gint col,
- gchar **cols,
- gchar **name)
-{
- gboolean *ret = ref;
-
- *ret = cols [0] ? strtoul (cols [0], NULL, 10) : 0;
-
- return 0;
-}
-
/**
* e_book_backend_sqlitedb_get_is_populated:
*
@@ -2711,19 +2955,6 @@ e_book_backend_sqlitedb_set_is_populated (EBookBackendSqliteDB *ebsdb,
return !err;
}
-static gint
-get_string_cb (gpointer ref,
- gint col,
- gchar **cols,
- gchar **name)
-{
- gchar **ret = ref;
-
- *ret = g_strdup (cols [0]);
-
- return 0;
-}
-
/**
* e_book_backend_sqlitedb_get_revision:
* @ebsdb: An #EBookBackendSqliteDB
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]