diff options
author | Sam Thursfield <sam@afuera.me.uk> | 2020-12-01 14:04:41 +0000 |
---|---|---|
committer | Sam Thursfield <sam@afuera.me.uk> | 2020-12-01 14:04:41 +0000 |
commit | 0072e594284416a345b9a1083a54d975edc492c5 (patch) | |
tree | fff4d2d62d70ab453acaf0b178ff22a9a69819fc | |
parent | b217e2920efdefd8786591c0607a0e1c6ffa7a4e (diff) | |
parent | 1f0b3618e31194836e923667fe476c3c356359bf (diff) | |
download | tracker-0072e594284416a345b9a1083a54d975edc492c5.tar.gz |
Merge branch 'wip/carlosg/insert-perf' into 'master'
Improve insert performance
See merge request GNOME/tracker!348
-rw-r--r-- | src/libtracker-data/tracker-data-manager.c | 142 | ||||
-rw-r--r-- | src/libtracker-data/tracker-data-query.c | 10 | ||||
-rw-r--r-- | src/libtracker-data/tracker-data-update.c | 324 | ||||
-rw-r--r-- | src/libtracker-data/tracker-data-update.h | 7 | ||||
-rw-r--r-- | src/libtracker-data/tracker-db-interface-sqlite.c | 50 | ||||
-rw-r--r-- | src/libtracker-data/tracker-db-interface.h | 9 | ||||
-rw-r--r-- | src/libtracker-data/tracker-db-manager.c | 12 | ||||
-rw-r--r-- | src/libtracker-data/tracker-ontologies.h | 2 | ||||
-rw-r--r-- | src/libtracker-data/tracker-sparql.c | 22 | ||||
-rw-r--r-- | src/libtracker-sparql/tracker-error.c | 1 | ||||
-rw-r--r-- | src/tracker/tracker-export.c | 2 | ||||
-rw-r--r-- | src/tracker/tracker-sql.c | 2 |
12 files changed, 276 insertions, 307 deletions
diff --git a/src/libtracker-data/tracker-data-manager.c b/src/libtracker-data/tracker-data-manager.c index bea674b3e..4a2bee58d 100644 --- a/src/libtracker-data/tracker-data-manager.c +++ b/src/libtracker-data/tracker-data-manager.c @@ -706,7 +706,6 @@ tracker_data_ontology_load_statement (TrackerDataManager *manager, const gchar *subject, const gchar *predicate, const gchar *object, - gint *max_id, gboolean in_update, GHashTable *classes, GHashTable *properties, @@ -735,8 +734,8 @@ tracker_data_ontology_load_statement (TrackerDataManager *manager, return; } - subject_id = ++(*max_id); - + subject_id = tracker_data_update_ensure_resource (manager->data_update, + subject, NULL); class = tracker_class_new (FALSE); tracker_class_set_ontologies (class, manager->ontologies); tracker_class_set_is_new (class, in_update); @@ -779,8 +778,9 @@ tracker_data_ontology_load_statement (TrackerDataManager *manager, return; } - subject_id = ++(*max_id); - + subject_id = tracker_data_update_ensure_resource (manager->data_update, + subject, + NULL); property = tracker_property_new (FALSE); tracker_property_set_ontologies (property, manager->ontologies); tracker_property_set_is_new (property, in_update); @@ -1756,7 +1756,6 @@ tracker_data_ontology_free_seen (GPtrArray *seen) static void load_ontology_file (TrackerDataManager *manager, GFile *file, - gint *max_id, gboolean in_update, GPtrArray *seen_classes, GPtrArray *seen_properties, @@ -1786,7 +1785,7 @@ load_ontology_file (TrackerDataManager *manager, tracker_data_ontology_load_statement (manager, ontology_uri, subject, predicate, object, - max_id, in_update, NULL, NULL, + in_update, NULL, NULL, seen_classes, seen_properties, &ontology_error); if (ontology_error) { @@ -3333,9 +3332,9 @@ query_table_exists (TrackerDBInterface *iface, TrackerDBStatement *stmt; gboolean exists = FALSE; - stmt = tracker_db_interface_create_statement (iface, TRACKER_DB_STATEMENT_CACHE_TYPE_SELECT, error, - "SELECT 1 FROM sqlite_master WHERE tbl_name=\"%s\" AND type=\"table\"", - table_name); + stmt = tracker_db_interface_create_vstatement (iface, TRACKER_DB_STATEMENT_CACHE_TYPE_SELECT, error, + "SELECT 1 FROM sqlite_master WHERE tbl_name=\"%s\" AND type=\"table\"", + table_name); if (stmt) { cursor = tracker_db_statement_start_cursor (stmt, error); g_object_unref (stmt); @@ -3539,39 +3538,6 @@ get_ontologies (TrackerDataManager *manager, return sorted; } - -static gint -get_new_service_id (TrackerDBInterface *iface) -{ - TrackerDBCursor *cursor = NULL; - TrackerDBStatement *stmt; - gint max_service_id = 0; - GError *error = NULL; - - /* Don't intermix this thing with tracker_data_update_get_new_service_id, - * if you use this, know what you are doing! */ - stmt = tracker_db_interface_create_statement (iface, TRACKER_DB_STATEMENT_CACHE_TYPE_SELECT, &error, - "SELECT MAX(ID) AS A FROM Resource WHERE ID <= %d", TRACKER_ONTOLOGIES_MAX_ID); - - if (stmt) { - cursor = tracker_db_statement_start_cursor (stmt, &error); - g_object_unref (stmt); - } - - if (cursor) { - if (tracker_db_cursor_iter_next (cursor, NULL, &error)) { - max_service_id = tracker_db_cursor_get_int (cursor, 0); - } - g_object_unref (cursor); - } - - if (error) { - g_error ("Unable to get max ID, aborting: %s", error->message); - } - - return ++max_service_id; -} - static void tracker_data_manager_update_status (TrackerDataManager *manager, const gchar *status) @@ -4021,7 +3987,6 @@ tracker_data_manager_initable_init (GInitable *initable, GHashTable *ontos_table; GHashTable *graphs; GList *sorted = NULL, *l; - gint max_id = 0; gboolean read_only; GError *internal_error = NULL; @@ -4100,6 +4065,16 @@ tracker_data_manager_initable_init (GInitable *initable, return FALSE; } + tracker_data_begin_ontology_transaction (manager->data_update, &internal_error); + if (internal_error) { + g_propagate_error (error, internal_error); + return FALSE; + } + + if (!create_base_tables (manager, iface, error)) { + return FALSE; + } + for (l = sorted; l; l = l->next) { GError *ontology_error = NULL; GFile *ontology_file = l->data; @@ -4108,7 +4083,6 @@ tracker_data_manager_initable_init (GInitable *initable, TRACKER_NOTE (ONTOLOGY_CHANGES, g_message ("Loading ontology %s", uri)); load_ontology_file (manager, ontology_file, - &max_id, FALSE, NULL, NULL, @@ -4121,16 +4095,6 @@ tracker_data_manager_initable_init (GInitable *initable, g_free (uri); } - tracker_data_begin_ontology_transaction (manager->data_update, &internal_error); - if (internal_error) { - g_propagate_error (error, internal_error); - return FALSE; - } - - if (!create_base_tables (manager, iface, error)) { - return FALSE; - } - tracker_data_ontology_setup_db (manager, iface, "main", FALSE, &internal_error); @@ -4352,14 +4316,9 @@ tracker_data_manager_initable_init (GInitable *initable, transaction_started = TRUE; } - if (max_id == 0) { - /* In case of first-time, this wont start at zero */ - max_id = get_new_service_id (iface); - } /* load ontology from files into memory, set all new's * is_new to TRUE */ load_ontology_file (manager, ontology_file, - &max_id, TRUE, seen_classes, seen_properties, @@ -4414,14 +4373,9 @@ tracker_data_manager_initable_init (GInitable *initable, transaction_started = TRUE; } - if (max_id == 0) { - /* In case of first-time, this wont start at zero */ - max_id = get_new_service_id (iface); - } /* load ontology from files into memory, set all new's * is_new to TRUE */ load_ontology_file (manager, ontology_file, - &max_id, TRUE, seen_classes, seen_properties, @@ -4664,15 +4618,13 @@ data_manager_perform_cleanup (TrackerDataManager *manager, g_string_append (str, ") "); g_string_append_printf (str, "DELETE FROM Resource " - "WHERE Resource.ID > %d " - "AND Resource.ID NOT IN (SELECT ID FROM referencedElements) " - "AND Resource.ID NOT IN (SELECT ID FROM Graph)", - TRACKER_ONTOLOGIES_MAX_ID); + "WHERE Resource.ID NOT IN (SELECT ID FROM referencedElements) " + "AND Resource.ID NOT IN (SELECT ID FROM Graph)"); stmt = tracker_db_interface_create_statement (iface, TRACKER_DB_STATEMENT_CACHE_TYPE_UPDATE, &internal_error, - "%s", str->str); + str->str); g_string_free (str, TRUE); if (!stmt) @@ -4967,10 +4919,10 @@ tracker_data_manager_clear_graph (TrackerDataManager *manager, if (g_str_has_prefix (tracker_class_get_name (classes[i]), "xsd:")) continue; - stmt = tracker_db_interface_create_statement (iface, TRACKER_DB_STATEMENT_CACHE_TYPE_NONE, &inner_error, - "DELETE FROM \"%s\".\"%s\" WHERE ID > 100000", - graph, - tracker_class_get_name (classes[i])); + stmt = tracker_db_interface_create_vstatement (iface, TRACKER_DB_STATEMENT_CACHE_TYPE_NONE, &inner_error, + "DELETE FROM \"%s\".\"%s\"", + graph, + tracker_class_get_name (classes[i])); if (!stmt) break; @@ -4985,11 +4937,11 @@ tracker_data_manager_clear_graph (TrackerDataManager *manager, continue; service = tracker_property_get_domain (properties[i]); - stmt = tracker_db_interface_create_statement (iface, TRACKER_DB_STATEMENT_CACHE_TYPE_NONE, &inner_error, - "DELETE FROM \"%s\".\"%s_%s\" WHERE ID > 100000", - graph, - tracker_class_get_name (service), - tracker_property_get_name (properties[i])); + stmt = tracker_db_interface_create_vstatement (iface, TRACKER_DB_STATEMENT_CACHE_TYPE_NONE, &inner_error, + "DELETE FROM \"%s\".\"%s_%s\"", + graph, + tracker_class_get_name (service), + tracker_property_get_name (properties[i])); if (!stmt) break; @@ -5035,13 +4987,13 @@ tracker_data_manager_copy_graph (TrackerDataManager *manager, if (g_str_has_prefix (tracker_class_get_name (classes[i]), "xsd:")) continue; - stmt = tracker_db_interface_create_statement (iface, TRACKER_DB_STATEMENT_CACHE_TYPE_NONE, &inner_error, - "INSERT OR REPLACE INTO \"%s\".\"%s\" " - "SELECT * from \"%s\".\"%s\" WHERE ID > 100000", - destination, - tracker_class_get_name (classes[i]), - source, - tracker_class_get_name (classes[i])); + stmt = tracker_db_interface_create_vstatement (iface, TRACKER_DB_STATEMENT_CACHE_TYPE_NONE, &inner_error, + "INSERT OR REPLACE INTO \"%s\".\"%s\" " + "SELECT * from \"%s\".\"%s\"", + destination, + tracker_class_get_name (classes[i]), + source, + tracker_class_get_name (classes[i])); if (!stmt) break; @@ -5056,15 +5008,15 @@ tracker_data_manager_copy_graph (TrackerDataManager *manager, continue; service = tracker_property_get_domain (properties[i]); - stmt = tracker_db_interface_create_statement (iface, TRACKER_DB_STATEMENT_CACHE_TYPE_NONE, &inner_error, - "INSERT OR REPLACE INTO \"%s\".\"%s_%s\" " - "SELECT * from \"%s\".\"%s_%s\" WHERE ID > 100000", - destination, - tracker_class_get_name (service), - tracker_property_get_name (properties[i]), - source, - tracker_class_get_name (service), - tracker_property_get_name (properties[i])); + stmt = tracker_db_interface_create_vstatement (iface, TRACKER_DB_STATEMENT_CACHE_TYPE_NONE, &inner_error, + "INSERT OR REPLACE INTO \"%s\".\"%s_%s\" " + "SELECT * from \"%s\".\"%s_%s\"", + destination, + tracker_class_get_name (service), + tracker_property_get_name (properties[i]), + source, + tracker_class_get_name (service), + tracker_property_get_name (properties[i])); if (!stmt) break; diff --git a/src/libtracker-data/tracker-data-query.c b/src/libtracker-data/tracker-data-query.c index ddde295e8..7ff062f58 100644 --- a/src/libtracker-data/tracker-data-query.c +++ b/src/libtracker-data/tracker-data-query.c @@ -48,11 +48,11 @@ tracker_data_query_rdf_type (TrackerDataManager *manager, iface = tracker_data_manager_get_writable_db_interface (manager); ontologies = tracker_data_manager_get_ontologies (manager); - stmt = tracker_db_interface_create_statement (iface, TRACKER_DB_STATEMENT_CACHE_TYPE_SELECT, &error, - "SELECT (SELECT Uri FROM Resource WHERE ID = \"rdf:type\") " - "FROM \"%s\".\"rdfs:Resource_rdf:type\" " - "WHERE ID = ?", - graph ? graph : "main"); + stmt = tracker_db_interface_create_vstatement (iface, TRACKER_DB_STATEMENT_CACHE_TYPE_SELECT, &error, + "SELECT (SELECT Uri FROM Resource WHERE ID = \"rdf:type\") " + "FROM \"%s\".\"rdfs:Resource_rdf:type\" " + "WHERE ID = ?", + graph ? graph : "main"); if (stmt) { tracker_db_statement_bind_int (stmt, 0, id); diff --git a/src/libtracker-data/tracker-data-update.c b/src/libtracker-data/tracker-data-update.c index 378f434bc..e97006631 100644 --- a/src/libtracker-data/tracker-data-update.c +++ b/src/libtracker-data/tracker-data-update.c @@ -37,6 +37,7 @@ #include "tracker-property.h" #include "tracker-sparql.h" #include "tracker-turtle-reader.h" +#include "tracker-uuid.h" typedef struct _TrackerDataUpdateBuffer TrackerDataUpdateBuffer; typedef struct _TrackerDataUpdateBufferGraph TrackerDataUpdateBufferGraph; @@ -50,10 +51,10 @@ typedef struct _TrackerCommitDelegate TrackerCommitDelegate; struct _TrackerDataUpdateBuffer { /* string -> integer */ GHashTable *resource_cache; + /* set of string, key is same pointer than resource_cache, and owned there */ + GHashTable *new_resources; /* string -> TrackerDataUpdateBufferGraph */ GPtrArray *graphs; - - gboolean fts_ever_updated; }; struct _TrackerDataUpdateBufferGraph { @@ -127,8 +128,6 @@ struct _TrackerData { GPtrArray *delete_callbacks; GPtrArray *commit_callbacks; GPtrArray *rollback_callbacks; - gint max_service_id; - gint max_ontology_id; }; struct _TrackerDataClass { @@ -142,9 +141,6 @@ enum { G_DEFINE_TYPE (TrackerData, tracker_data, G_TYPE_OBJECT); -static gint ensure_resource_id (TrackerData *data, - const gchar *uri, - gboolean *create); static void cache_insert_value (TrackerData *data, const gchar *table_name, const gchar *field_name, @@ -162,7 +158,6 @@ static gboolean delete_metadata_decomposed (TrackerData *data, static gboolean resource_buffer_switch (TrackerData *data, const gchar *graph, const gchar *subject, - gint subject_id, GError **error); static gboolean update_resource_single (TrackerData *data, const gchar *graph, @@ -417,78 +412,6 @@ tracker_data_dispatch_delete_statement_callbacks (TrackerData *data, } static gint -tracker_data_update_get_new_service_id (TrackerData *data, - GError **error) -{ - TrackerDBCursor *cursor = NULL; - TrackerDBInterface *iface; - TrackerDBStatement *stmt; - GError *inner_error = NULL; - - if (data->in_ontology_transaction) { - if (G_LIKELY (data->max_ontology_id != 0)) { - return ++data->max_ontology_id; - } - - iface = tracker_data_manager_get_writable_db_interface (data->manager); - - stmt = tracker_db_interface_create_statement (iface, TRACKER_DB_STATEMENT_CACHE_TYPE_SELECT, &inner_error, - "SELECT MAX(ID) AS A FROM Resource WHERE ID <= %d", TRACKER_ONTOLOGIES_MAX_ID); - - if (stmt) { - cursor = tracker_db_statement_start_cursor (stmt, &inner_error); - g_object_unref (stmt); - } - - if (cursor) { - if (tracker_db_cursor_iter_next (cursor, NULL, &inner_error)) { - data->max_ontology_id = MAX (tracker_db_cursor_get_int (cursor, 0), data->max_ontology_id); - } - - g_object_unref (cursor); - } - - if (G_UNLIKELY (inner_error)) { - g_propagate_error (error, inner_error); - return 0; - } - - return ++data->max_ontology_id; - } else { - if (G_LIKELY (data->max_service_id != 0)) { - return ++data->max_service_id; - } - - data->max_service_id = TRACKER_ONTOLOGIES_MAX_ID; - - iface = tracker_data_manager_get_writable_db_interface (data->manager); - - stmt = tracker_db_interface_create_statement (iface, TRACKER_DB_STATEMENT_CACHE_TYPE_SELECT, &inner_error, - "SELECT MAX(ID) AS A FROM Resource"); - - if (stmt) { - cursor = tracker_db_statement_start_cursor (stmt, &inner_error); - g_object_unref (stmt); - } - - if (cursor) { - if (tracker_db_cursor_iter_next (cursor, NULL, &inner_error)) { - data->max_service_id = MAX (tracker_db_cursor_get_int (cursor, 0), data->max_service_id); - } - - g_object_unref (cursor); - } - - if (G_UNLIKELY (inner_error)) { - g_propagate_error (error, inner_error); - return 0; - } - - return ++data->max_service_id; - } -} - -static gint tracker_data_update_get_next_modseq (TrackerData *data) { TrackerDBCursor *cursor = NULL; @@ -775,48 +698,65 @@ query_resource_id (TrackerData *data, return id; } -static gint -ensure_resource_id (TrackerData *data, - const gchar *uri, - gboolean *create) +gint +tracker_data_update_ensure_resource (TrackerData *data, + const gchar *uri, + gboolean *create) { TrackerDBInterface *iface; TrackerDBStatement *stmt = NULL; GError *error = NULL; + gchar *key; gint id; - id = query_resource_id (data, uri); + id = GPOINTER_TO_INT (g_hash_table_lookup (data->update_buffer.resource_cache, uri)); - if (create) { - *create = (id == 0); + if (id != 0) { + if (create) + *create = FALSE; + return id; } - if (id == 0) { - iface = tracker_data_manager_get_writable_db_interface (data->manager); + iface = tracker_data_manager_get_writable_db_interface (data->manager); - id = tracker_data_update_get_new_service_id (data, &error); + stmt = tracker_db_interface_create_statement (iface, TRACKER_DB_STATEMENT_CACHE_TYPE_UPDATE, &error, + "INSERT INTO Resource (Uri, BlankNode) VALUES (?, ?)"); - if (id > 0) { - stmt = tracker_db_interface_create_statement (iface, TRACKER_DB_STATEMENT_CACHE_TYPE_UPDATE, &error, - "INSERT INTO Resource (ID, Uri, BlankNode) VALUES (?, ?, ?)"); - } + if (stmt) { + tracker_db_statement_bind_text (stmt, 0, uri); + tracker_db_statement_bind_int (stmt, 1, g_str_has_prefix (uri, "urn:bnode:")); + tracker_db_statement_execute (stmt, &error); + g_object_unref (stmt); + } - if (stmt) { - tracker_db_statement_bind_int (stmt, 0, id); - tracker_db_statement_bind_text (stmt, 1, uri); - tracker_db_statement_bind_int (stmt, 2, g_str_has_prefix (uri, "urn:bnode:")); - tracker_db_statement_execute (stmt, &error); - g_object_unref (stmt); - } + if (error) { + if (g_error_matches (error, + TRACKER_DB_INTERFACE_ERROR, + TRACKER_DB_CONSTRAINT)) { + id = query_resource_id (data, uri); - if (error) { - g_error ("Could not ensure resource existence: %s", error->message); - g_error_free (error); + if (id != 0) { + if (create) + *create = FALSE; + + g_hash_table_insert (data->update_buffer.resource_cache, g_strdup (uri), GINT_TO_POINTER (id)); + g_error_free (error); + return id; + } } - g_hash_table_insert (data->update_buffer.resource_cache, g_strdup (uri), GINT_TO_POINTER (id)); + g_error ("Could not ensure resource existence: %s", error->message); + g_error_free (error); } + if (create) + *create = TRUE; + + id = tracker_db_interface_sqlite_get_last_insert_id (iface); + key = g_strdup (uri); + g_hash_table_insert (data->update_buffer.resource_cache, key, GINT_TO_POINTER (id)); + g_hash_table_add (data->update_buffer.new_resources, key); + return id; } @@ -901,23 +841,23 @@ tracker_data_resource_buffer_flush (TrackerData *data, property = &g_array_index (table->properties, TrackerDataUpdateBufferProperty, i); if (table->delete_value && property->delete_all_values) { - stmt = tracker_db_interface_create_statement (iface, TRACKER_DB_STATEMENT_CACHE_TYPE_UPDATE, &actual_error, - "DELETE FROM \"%s\".\"%s\" WHERE ID = ?", - database, - table_name); + stmt = tracker_db_interface_create_vstatement (iface, TRACKER_DB_STATEMENT_CACHE_TYPE_UPDATE, &actual_error, + "DELETE FROM \"%s\".\"%s\" WHERE ID = ?", + database, + table_name); } else if (table->delete_value) { /* delete rows for multiple value properties */ - stmt = tracker_db_interface_create_statement (iface, TRACKER_DB_STATEMENT_CACHE_TYPE_UPDATE, &actual_error, - "DELETE FROM \"%s\".\"%s\" WHERE ID = ? AND \"%s\" = ?", - database, - table_name, - property->name); + stmt = tracker_db_interface_create_vstatement (iface, TRACKER_DB_STATEMENT_CACHE_TYPE_UPDATE, &actual_error, + "DELETE FROM \"%s\".\"%s\" WHERE ID = ? AND \"%s\" = ?", + database, + table_name, + property->name); } else { - stmt = tracker_db_interface_create_statement (iface, TRACKER_DB_STATEMENT_CACHE_TYPE_UPDATE, &actual_error, - "INSERT OR IGNORE INTO \"%s\".\"%s\" (ID, \"%s\") VALUES (?, ?)", - database, - table_name, - property->name); + stmt = tracker_db_interface_create_vstatement (iface, TRACKER_DB_STATEMENT_CACHE_TYPE_UPDATE, &actual_error, + "INSERT OR IGNORE INTO \"%s\".\"%s\" (ID, \"%s\") VALUES (?, ?)", + database, + table_name, + property->name); } if (actual_error) { @@ -945,13 +885,13 @@ tracker_data_resource_buffer_flush (TrackerData *data, if (table->delete_row) { /* remove entry from rdf:type table */ - stmt = tracker_db_interface_create_statement (iface, TRACKER_DB_STATEMENT_CACHE_TYPE_UPDATE, &actual_error, - "DELETE FROM \"%s\".\"rdfs:Resource_rdf:type\" WHERE ID = ? AND \"rdf:type\" = ?", - database); + stmt = tracker_db_interface_create_vstatement (iface, TRACKER_DB_STATEMENT_CACHE_TYPE_UPDATE, &actual_error, + "DELETE FROM \"%s\".\"rdfs:Resource_rdf:type\" WHERE ID = ? AND \"rdf:type\" = ?", + database); if (stmt) { tracker_db_statement_bind_int (stmt, 0, resource->id); - tracker_db_statement_bind_int (stmt, 1, ensure_resource_id (data, tracker_class_get_uri (table->class), NULL)); + tracker_db_statement_bind_int (stmt, 1, tracker_class_get_id (table->class)); tracker_db_statement_execute (stmt, &actual_error); g_object_unref (stmt); } @@ -962,9 +902,9 @@ tracker_data_resource_buffer_flush (TrackerData *data, } /* remove row from class table */ - stmt = tracker_db_interface_create_statement (iface, TRACKER_DB_STATEMENT_CACHE_TYPE_UPDATE, &actual_error, - "DELETE FROM \"%s\".\"%s\" WHERE ID = ?", - database, table_name); + stmt = tracker_db_interface_create_vstatement (iface, TRACKER_DB_STATEMENT_CACHE_TYPE_UPDATE, &actual_error, + "DELETE FROM \"%s\".\"%s\" WHERE ID = ?", + database, table_name); if (stmt) { tracker_db_statement_bind_int (stmt, 0, resource->id); @@ -1019,15 +959,15 @@ tracker_data_resource_buffer_flush (TrackerData *data, g_string_append (sql, ")"); g_string_append (values_sql, ")"); - stmt = tracker_db_interface_create_statement (iface, TRACKER_DB_STATEMENT_CACHE_TYPE_UPDATE, &actual_error, - "%s %s", sql->str, values_sql->str); + stmt = tracker_db_interface_create_vstatement (iface, TRACKER_DB_STATEMENT_CACHE_TYPE_UPDATE, &actual_error, + "%s %s", sql->str, values_sql->str); g_string_free (sql, TRUE); g_string_free (values_sql, TRUE); } else { g_string_append (sql, " WHERE ID = ?"); stmt = tracker_db_interface_create_statement (iface, TRACKER_DB_STATEMENT_CACHE_TYPE_UPDATE, &actual_error, - "%s", sql->str); + sql->str); g_string_free (sql, TRUE); } @@ -1112,7 +1052,6 @@ tracker_data_resource_buffer_flush (TrackerData *data, resource->id, (const gchar **) properties->pdata, (const gchar **) text->pdata); - data->update_buffer.fts_ever_updated = TRUE; g_ptr_array_free (properties, TRUE); g_ptr_array_free (text, TRUE); } @@ -1164,6 +1103,7 @@ tracker_data_update_buffer_flush (TrackerData *data, out: g_ptr_array_set_size (data->update_buffer.graphs, 0); + g_hash_table_remove_all (data->update_buffer.new_resources); data->resource_buffer = NULL; } @@ -1189,10 +1129,9 @@ static void tracker_data_update_buffer_clear (TrackerData *data) { g_ptr_array_set_size (data->update_buffer.graphs, 0); + g_hash_table_remove_all (data->update_buffer.new_resources); g_hash_table_remove_all (data->update_buffer.resource_cache); data->resource_buffer = NULL; - - data->update_buffer.fts_ever_updated = FALSE; } static void @@ -1225,9 +1164,6 @@ cache_create_service_decomposed (TrackerData *data, cache_insert_row (data, cl); - /* This is the original, no idea why tracker_class_get_id wasn't used here: - * class_id = ensure_resource_id (tracker_class_get_uri (cl), NULL); */ - class_id = tracker_class_get_id (cl); ontologies = tracker_data_manager_get_ontologies (data->manager); @@ -1413,9 +1349,9 @@ get_property_values (TrackerData *data, iface = tracker_data_manager_get_writable_db_interface (data->manager); - stmt = tracker_db_interface_create_statement (iface, TRACKER_DB_STATEMENT_CACHE_TYPE_SELECT, &error, - "SELECT \"%s\" FROM \"%s\".\"%s\" WHERE ID = ?", - field_name, database, table_name); + stmt = tracker_db_interface_create_vstatement (iface, TRACKER_DB_STATEMENT_CACHE_TYPE_SELECT, &error, + "SELECT \"%s\" FROM \"%s\".\"%s\" WHERE ID = ?", + field_name, database, table_name); if (stmt) { tracker_db_statement_bind_int (stmt, 0, data->resource_buffer->id); @@ -1551,8 +1487,6 @@ get_old_property_values (TrackerData *data, g_ptr_array_unref (fts_props); g_ptr_array_unref (fts_text); - data->update_buffer.fts_ever_updated = TRUE; - old_values = g_hash_table_lookup (data->resource_buffer->predicates, property); } else { old_values = get_property_values (data, property); @@ -1614,7 +1548,7 @@ bytes_to_gvalue (GBytes *bytes, tracker_date_time_set_from_string (gvalue, value, error); break; case TRACKER_PROPERTY_TYPE_RESOURCE: - object_id = ensure_resource_id (data, value, NULL); + object_id = tracker_data_update_ensure_resource (data, value, NULL); g_value_init (gvalue, G_TYPE_INT64); g_value_set_int64 (gvalue, object_id); break; @@ -1638,8 +1572,7 @@ get_bnode_for_resource (GHashTable *bnodes, return bnode; iface = tracker_data_manager_get_writable_db_interface (data->manager); - bnode = tracker_data_query_unused_uuid (data->manager, - iface); + bnode = tracker_data_update_ensure_new_bnode (data, iface, NULL); identifier = tracker_resource_get_identifier (resource); g_hash_table_insert (bnodes, g_strdup (identifier), bnode); @@ -1687,8 +1620,7 @@ bytes_from_gvalue (GValue *gvalue, TrackerDBInterface *iface; iface = tracker_data_manager_get_writable_db_interface (data->manager); - bnode = tracker_data_query_unused_uuid (data->manager, - iface); + bnode = tracker_data_update_ensure_new_bnode (data, iface, NULL); g_hash_table_insert (bnodes, g_strdup (uri), bnode); } @@ -1999,11 +1931,11 @@ cache_delete_resource_type_full (TrackerData *data, /* retrieve all subclasses we need to remove from the subject * before we can remove the class specified as object of the statement */ - stmt = tracker_db_interface_create_statement (iface, TRACKER_DB_STATEMENT_CACHE_TYPE_SELECT, &error, - "SELECT (SELECT Uri FROM Resource WHERE ID = subclass.ID) " - "FROM \"%s\".\"rdfs:Resource_rdf:type\" AS type INNER JOIN \"%s\".\"rdfs:Class_rdfs:subClassOf\" AS subclass ON (type.\"rdf:type\" = subclass.ID) " - "WHERE type.ID = ? AND subclass.\"rdfs:subClassOf\" = (SELECT ID FROM Resource WHERE Uri = ?)", - database, database); + stmt = tracker_db_interface_create_vstatement (iface, TRACKER_DB_STATEMENT_CACHE_TYPE_SELECT, &error, + "SELECT (SELECT Uri FROM Resource WHERE ID = subclass.ID) " + "FROM \"%s\".\"rdfs:Resource_rdf:type\" AS type INNER JOIN \"%s\".\"rdfs:Class_rdfs:subClassOf\" AS subclass ON (type.\"rdf:type\" = subclass.ID) " + "WHERE type.ID = ? AND subclass.\"rdfs:subClassOf\" = (SELECT ID FROM Resource WHERE Uri = ?)", + database, database); if (stmt) { tracker_db_statement_bind_int (stmt, 0, data->resource_buffer->id); @@ -2145,7 +2077,6 @@ static gboolean resource_buffer_switch (TrackerData *data, const gchar *graph, const gchar *subject, - gint subject_id, GError **error) { TrackerDataUpdateBufferGraph *graph_buffer; @@ -2181,11 +2112,15 @@ resource_buffer_switch (TrackerData *data, subject_dup = g_strdup (subject); resource_buffer->subject = subject_dup; } - if (subject_id > 0) { - resource_buffer->id = subject_id; - } else { - resource_buffer->id = ensure_resource_id (data, resource_buffer->subject, &resource_buffer->create); - } + + resource_buffer->id = + tracker_data_update_ensure_resource (data, + resource_buffer->subject, + NULL); + resource_buffer->create = + g_hash_table_contains (data->update_buffer.new_resources, + resource_buffer->subject); + resource_buffer->fts_updated = FALSE; if (resource_buffer->create) { resource_buffer->types = g_ptr_array_new (); @@ -2230,7 +2165,7 @@ tracker_data_delete_statement (TrackerData *data, return; } - if (!resource_buffer_switch (data, graph, subject, subject_id, error)) + if (!resource_buffer_switch (data, graph, subject, error)) return; ontologies = tracker_data_manager_get_ontologies (data->manager); @@ -2295,7 +2230,7 @@ tracker_data_delete_all (TrackerData *data, return; } - if (!resource_buffer_switch (data, graph, subject, subject_id, error)) + if (!resource_buffer_switch (data, graph, subject, error)) return; ontologies = tracker_data_manager_get_ontologies (data->manager); @@ -2459,7 +2394,7 @@ tracker_data_insert_statement_with_uri (TrackerData *data, data->has_persistent = TRUE; - if (!resource_buffer_switch (data, graph, subject, 0, error)) + if (!resource_buffer_switch (data, graph, subject, error)) return; object_str = g_bytes_get_data (object, NULL); @@ -2541,7 +2476,7 @@ tracker_data_insert_statement_with_string (TrackerData *data, data->has_persistent = TRUE; - if (!resource_buffer_switch (data, graph, subject, 0, error)) + if (!resource_buffer_switch (data, graph, subject, error)) return; /* add value to metadata database */ @@ -2599,9 +2534,7 @@ tracker_data_update_statement (TrackerData *data, return; } - if (!resource_buffer_switch (data, graph, subject, - ensure_resource_id (data, subject, NULL), - error)) + if (!resource_buffer_switch (data, graph, subject, error)) return; cache_delete_all_values (data, @@ -2610,9 +2543,7 @@ tracker_data_update_statement (TrackerData *data, tracker_property_get_fulltext_indexed (property), tracker_property_get_data_type (property) == TRACKER_PROPERTY_TYPE_DATETIME); } else { - if (!resource_buffer_switch (data, graph, subject, - ensure_resource_id (data, subject, NULL), - error)) + if (!resource_buffer_switch (data, graph, subject, error)) return; if (!delete_single_valued (data, graph, subject, predicate, @@ -2666,6 +2597,7 @@ tracker_data_begin_transaction (TrackerData *data, if (data->update_buffer.resource_cache == NULL) { data->update_buffer.resource_cache = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL); + data->update_buffer.new_resources = g_hash_table_new (g_str_hash, g_str_equal); /* used for normal transactions */ data->update_buffer.graphs = g_ptr_array_new_with_free_func ((GDestroyNotify) graph_buffer_free); } @@ -2725,10 +2657,6 @@ tracker_data_commit_transaction (TrackerData *data, data->in_transaction = FALSE; data->in_ontology_transaction = FALSE; - if (data->update_buffer.fts_ever_updated) { - data->update_buffer.fts_ever_updated = FALSE; - } - tracker_data_manager_commit_graphs (data->manager); tracker_db_interface_execute_query (iface, NULL, "PRAGMA cache_size = %d", TRACKER_DB_CACHE_SIZE_DEFAULT); @@ -2901,7 +2829,7 @@ tracker_data_ensure_graph (TrackerData *data, TrackerDBStatement *stmt; gint id; - id = ensure_resource_id (data, uri, NULL); + id = tracker_data_update_ensure_resource (data, uri, NULL); iface = tracker_data_manager_get_writable_db_interface (data->manager); stmt = tracker_db_interface_create_statement (iface, TRACKER_DB_STATEMENT_CACHE_TYPE_UPDATE, error, "INSERT OR IGNORE INTO Graph (ID) VALUES (?)"); @@ -3123,3 +3051,57 @@ tracker_data_update_resource (TrackerData *data, return retval; } + +gchar * +tracker_data_update_ensure_new_bnode (TrackerData *data, + TrackerDBInterface *iface, + GError **error) +{ + TrackerDBStatement *stmt = NULL; + GError *inner_error = NULL; + gchar *uuid, *key; + gint id; + + iface = tracker_data_manager_get_writable_db_interface (data->manager); + + stmt = tracker_db_interface_create_statement (iface, TRACKER_DB_STATEMENT_CACHE_TYPE_UPDATE, + &inner_error, + "INSERT INTO Resource (Uri, BlankNode) VALUES (?, ?)"); + if (!stmt) { + g_propagate_error (error, inner_error); + return NULL; + } + + while (TRUE) { + uuid = tracker_generate_uuid ("urn:bnode:"); + + tracker_db_statement_bind_text (stmt, 0, uuid); + tracker_db_statement_bind_int (stmt, 1, 1); + tracker_db_statement_execute (stmt, &inner_error); + + if (!inner_error || + !g_error_matches (inner_error, + TRACKER_DB_INTERFACE_ERROR, + TRACKER_DB_CONSTRAINT)) { + break; + } + + /* Constraint error, retry */ + g_clear_error (&inner_error); + g_free (uuid); + } + + g_object_unref (stmt); + + if (inner_error) { + g_propagate_error (error, inner_error); + return NULL; + } + + id = tracker_db_interface_sqlite_get_last_insert_id (iface); + key = g_strdup (uuid); + g_hash_table_insert (data->update_buffer.resource_cache, key, GINT_TO_POINTER (id)); + g_hash_table_add (data->update_buffer.new_resources, key); + + return uuid; +} diff --git a/src/libtracker-data/tracker-data-update.h b/src/libtracker-data/tracker-data-update.h index 26fc3d971..8df34e213 100644 --- a/src/libtracker-data/tracker-data-update.h +++ b/src/libtracker-data/tracker-data-update.h @@ -143,6 +143,13 @@ gboolean tracker_data_update_resource (TrackerData *data, GHashTable *bnodes, GError **error); +gint tracker_data_update_ensure_resource (TrackerData *data, + const gchar *uri, + gboolean *create); +gchar * tracker_data_update_ensure_new_bnode (TrackerData *data, + TrackerDBInterface *iface, + GError **error); + GType tracker_data_get_type (void) G_GNUC_CONST; TrackerData * tracker_data_new (TrackerDataManager *manager); diff --git a/src/libtracker-data/tracker-db-interface-sqlite.c b/src/libtracker-data/tracker-db-interface-sqlite.c index 18a174e26..260b81d87 100644 --- a/src/libtracker-data/tracker-db-interface-sqlite.c +++ b/src/libtracker-data/tracker-db-interface-sqlite.c @@ -2341,7 +2341,7 @@ tracker_db_interface_sqlite_fts_update_text (TrackerDBInterface *db_interface, stmt = tracker_db_interface_create_statement (db_interface, TRACKER_DB_STATEMENT_CACHE_TYPE_UPDATE, &error, - "%s", query); + query); g_free (query); if (!stmt || error) { @@ -2395,7 +2395,7 @@ tracker_db_interface_sqlite_fts_delete_text (TrackerDBInterface *db_interface, stmt = tracker_db_interface_create_statement (db_interface, TRACKER_DB_STATEMENT_CACHE_TYPE_UPDATE, &error, - "%s", query); + query); g_free (query); if (!stmt || error) { @@ -2434,7 +2434,7 @@ tracker_db_interface_sqlite_fts_delete_id (TrackerDBInterface *db_interface, stmt = tracker_db_interface_create_statement (db_interface, TRACKER_DB_STATEMENT_CACHE_TYPE_UPDATE, &error, - "%s", query); + query); g_free (query); if (!stmt || error) { @@ -2785,35 +2785,27 @@ TrackerDBStatement * tracker_db_interface_create_statement (TrackerDBInterface *db_interface, TrackerDBStatementCacheType cache_type, GError **error, - const gchar *query, - ...) + const gchar *query) { TrackerDBStatement *stmt = NULL; - va_list args; - gchar *full_query; g_return_val_if_fail (TRACKER_IS_DB_INTERFACE (db_interface), NULL); - va_start (args, query); - full_query = g_strdup_vprintf (query, args); - va_end (args); - tracker_db_interface_lock (db_interface); if (cache_type != TRACKER_DB_STATEMENT_CACHE_TYPE_NONE) { stmt = tracker_db_interface_lru_lookup (db_interface, &cache_type, - full_query); + query); } if (!stmt) { sqlite3_stmt *sqlite_stmt; sqlite_stmt = tracker_db_interface_prepare_stmt (db_interface, - full_query, + query, error); if (!sqlite_stmt) { tracker_db_interface_unlock (db_interface); - g_free (full_query); return NULL; } @@ -2831,13 +2823,36 @@ tracker_db_interface_create_statement (TrackerDBInterface *db_interfac } stmt->stmt_is_owned = TRUE; - g_free (full_query); tracker_db_interface_unlock (db_interface); return g_object_ref_sink (stmt); } +TrackerDBStatement * +tracker_db_interface_create_vstatement (TrackerDBInterface *db_interface, + TrackerDBStatementCacheType cache_type, + GError **error, + const gchar *query, + ...) +{ + TrackerDBStatement *stmt; + va_list args; + gchar *full_query; + + g_return_val_if_fail (TRACKER_IS_DB_INTERFACE (db_interface), NULL); + + va_start (args, query); + full_query = g_strdup_vprintf (query, args); + va_end (args); + + stmt = tracker_db_interface_create_statement (db_interface, cache_type, + error, full_query); + g_free (full_query); + + return stmt; +} + static gboolean execute_stmt (TrackerDBInterface *interface, sqlite3_stmt *stmt, @@ -2916,6 +2931,11 @@ execute_stmt (TrackerDBInterface *interface, TRACKER_DB_INTERFACE_ERROR, TRACKER_DB_INTERRUPTED, "Interrupted"); + } else if (result == SQLITE_CONSTRAINT) { + g_set_error (error, + TRACKER_DB_INTERFACE_ERROR, + TRACKER_DB_CONSTRAINT, + "Constraint would be broken"); } else { g_set_error (error, TRACKER_DB_INTERFACE_ERROR, diff --git a/src/libtracker-data/tracker-db-interface.h b/src/libtracker-data/tracker-db-interface.h index 28fe5c7e9..07f370139 100644 --- a/src/libtracker-data/tracker-db-interface.h +++ b/src/libtracker-data/tracker-db-interface.h @@ -64,7 +64,8 @@ typedef enum { TRACKER_DB_QUERY_ERROR, TRACKER_DB_INTERRUPTED, TRACKER_DB_OPEN_ERROR, - TRACKER_DB_NO_SPACE + TRACKER_DB_NO_SPACE, + TRACKER_DB_CONSTRAINT, } TrackerDBInterfaceError; typedef enum { @@ -97,7 +98,11 @@ void tracker_db_interface_set_user_data (TrackerDBI gpointer tracker_db_interface_get_user_data (TrackerDBInterface *interface); /* Functions to create queries/procedures */ -TrackerDBStatement * tracker_db_interface_create_statement (TrackerDBInterface *interface, +TrackerDBStatement * tracker_db_interface_create_statement (TrackerDBInterface *db_interface, + TrackerDBStatementCacheType cache_type, + GError **error, + const gchar *query); +TrackerDBStatement * tracker_db_interface_create_vstatement (TrackerDBInterface *interface, TrackerDBStatementCacheType cache_type, GError **error, const gchar *query, diff --git a/src/libtracker-data/tracker-db-manager.c b/src/libtracker-data/tracker-db-manager.c index 5e98337de..9f4e89101 100644 --- a/src/libtracker-data/tracker-db-manager.c +++ b/src/libtracker-data/tracker-db-manager.c @@ -198,9 +198,9 @@ db_set_params (TrackerDBInterface *iface, tracker_db_interface_execute_query (iface, NULL, "PRAGMA \"%s\".auto_vacuum = 0", database); if (enable_wal) { - stmt = tracker_db_interface_create_statement (iface, TRACKER_DB_STATEMENT_CACHE_TYPE_NONE, - &internal_error, - "PRAGMA \"%s\".journal_mode = WAL", database); + stmt = tracker_db_interface_create_vstatement (iface, TRACKER_DB_STATEMENT_CACHE_TYPE_NONE, + &internal_error, + "PRAGMA \"%s\".journal_mode = WAL", database); if (internal_error) { g_info ("Can't set journal mode to WAL: '%s'", @@ -324,9 +324,9 @@ tracker_db_manager_update_version (TrackerDBManager *db_manager) GError *error = NULL; iface = tracker_db_manager_get_writable_db_interface (db_manager); - stmt = tracker_db_interface_create_statement (iface, TRACKER_DB_STATEMENT_CACHE_TYPE_NONE, - &error, "PRAGMA user_version = %d", - TRACKER_DB_VERSION_NOW); + stmt = tracker_db_interface_create_vstatement (iface, TRACKER_DB_STATEMENT_CACHE_TYPE_NONE, + &error, "PRAGMA user_version = %d", + TRACKER_DB_VERSION_NOW); if (stmt) { tracker_db_statement_execute (stmt, &error); g_object_unref (stmt); diff --git a/src/libtracker-data/tracker-ontologies.h b/src/libtracker-data/tracker-ontologies.h index 36857df8a..c984b7a2e 100644 --- a/src/libtracker-data/tracker-ontologies.h +++ b/src/libtracker-data/tracker-ontologies.h @@ -34,8 +34,6 @@ G_BEGIN_DECLS #error "only <libtracker-data/tracker-data.h> must be included directly." #endif -#define TRACKER_ONTOLOGIES_MAX_ID 100000 - #define TRACKER_TYPE_ONTOLOGIES (tracker_ontologies_get_type ()) #define TRACKER_ONTOLOGIES(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), TRACKER_TYPE_ONTOLOGIES, TrackerOntologies)) #define TRACKER_ONTOLOGIES_CLASS(k) (G_TYPE_CHECK_CLASS_CAST ((k), TRACKER_TYPE_ONTOLOGIES, TrackerOntologiesClass)) diff --git a/src/libtracker-data/tracker-sparql.c b/src/libtracker-data/tracker-sparql.c index 45caa02df..42bed5907 100644 --- a/src/libtracker-data/tracker-sparql.c +++ b/src/libtracker-data/tracker-sparql.c @@ -68,7 +68,6 @@ static gboolean helper_translate_time (TrackerSparql *sparql, GError **error); static TrackerDBStatement * prepare_query (TrackerSparql *sparql, TrackerDBInterface *iface, - TrackerStringBuilder *str, GPtrArray *literals, GHashTable *parameters, gboolean cached, @@ -164,6 +163,7 @@ struct _TrackerSparql TrackerContext *context; TrackerStringBuilder *sql; + gchar *sql_string; GHashTable *prefix_map; GList *filter_clauses; @@ -225,6 +225,7 @@ tracker_sparql_finalize (GObject *object) g_hash_table_destroy (sparql->parameters); g_hash_table_destroy (sparql->cached_bindings); + g_clear_pointer (&sparql->sql_string, g_free); if (sparql->sql) tracker_string_builder_free (sparql->sql); @@ -2027,6 +2028,7 @@ tracker_sparql_init_string_builder (TrackerSparql *sparql) TrackerStringBuilder *str; g_clear_pointer (&sparql->sql, tracker_string_builder_free); + g_clear_pointer (&sparql->sql_string, g_free); sparql->sql = sparql->current_state->sql = tracker_string_builder_new (); sparql->current_state->with_clauses = _prepend_placeholder (sparql); @@ -4362,7 +4364,7 @@ get_solution_for_pattern (TrackerSparql *sparql, } iface = tracker_data_manager_get_writable_db_interface (sparql->data_manager); - stmt = prepare_query (sparql, iface, sparql->sql, + stmt = prepare_query (sparql, iface, TRACKER_SELECT_CONTEXT (sparql->context)->literal_bindings, NULL, TRUE, error); @@ -9330,23 +9332,24 @@ tracker_sparql_new (TrackerDataManager *manager, static TrackerDBStatement * prepare_query (TrackerSparql *sparql, TrackerDBInterface *iface, - TrackerStringBuilder *str, GPtrArray *literals, - GHashTable *parameters, + GHashTable *parameters, gboolean cached, GError **error) { TrackerDBStatement *stmt; - gchar *query; guint i; - query = tracker_string_builder_to_string (str); + if (!sparql->sql_string) { + sparql->sql_string = tracker_string_builder_to_string (sparql->sql); + g_clear_pointer (&sparql->sql, tracker_string_builder_free); + } + stmt = tracker_db_interface_create_statement (iface, cached ? TRACKER_DB_STATEMENT_CACHE_TYPE_SELECT : TRACKER_DB_STATEMENT_CACHE_TYPE_NONE, - error, "%s", query); - g_free (query); + error, sparql->sql_string); if (!stmt || !literals) return stmt; @@ -9496,12 +9499,13 @@ tracker_sparql_execute_cursor (TrackerSparql *sparql, sparql->current_state = NULL; tracker_sparql_state_clear (&state); + if (!retval) goto error; } iface = tracker_data_manager_get_db_interface (sparql->data_manager); - stmt = prepare_query (sparql, iface, sparql->sql, + stmt = prepare_query (sparql, iface, TRACKER_SELECT_CONTEXT (sparql->context)->literal_bindings, parameters, sparql->cacheable, diff --git a/src/libtracker-sparql/tracker-error.c b/src/libtracker-sparql/tracker-error.c index 89e42c023..849aa87db 100644 --- a/src/libtracker-sparql/tracker-error.c +++ b/src/libtracker-sparql/tracker-error.c @@ -87,6 +87,7 @@ _translate_internal_error (GError *error) /* This should never happen as we don't call sqlite3_interrupt() * anywhere, so it doesn't get its own public error code. */ case TRACKER_DB_INTERRUPTED: new_code = TRACKER_SPARQL_ERROR_INTERNAL; break; + case TRACKER_DB_CONSTRAINT: new_code = TRACKER_SPARQL_ERROR_CONSTRAINT; break; default: g_warn_if_reached (); } diff --git a/src/tracker/tracker-export.c b/src/tracker/tracker-export.c index 900fc411b..ead5de036 100644 --- a/src/tracker/tracker-export.c +++ b/src/tracker/tracker-export.c @@ -406,7 +406,7 @@ export_2to3_with_query (const gchar *query, stmt = tracker_db_interface_create_statement (iface, TRACKER_DB_STATEMENT_CACHE_TYPE_NONE, &inner_error, - "%s", query); + query); if (!stmt) { g_propagate_prefixed_error (error, inner_error, "%s: ", _("Could not run query")); diff --git a/src/tracker/tracker-sql.c b/src/tracker/tracker-sql.c index 493e09f33..6803813d0 100644 --- a/src/tracker/tracker-sql.c +++ b/src/tracker/tracker-sql.c @@ -124,7 +124,7 @@ sql_by_query (void) iface = tracker_data_manager_get_db_interface (data_manager); - stmt = tracker_db_interface_create_statement (iface, TRACKER_DB_STATEMENT_CACHE_TYPE_NONE, &error, "%s", query); + stmt = tracker_db_interface_create_statement (iface, TRACKER_DB_STATEMENT_CACHE_TYPE_NONE, &error, query); if (stmt) { cursor = tracker_db_statement_start_cursor (stmt, &error); |