summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSam Thursfield <sam@afuera.me.uk>2020-12-01 14:04:41 +0000
committerSam Thursfield <sam@afuera.me.uk>2020-12-01 14:04:41 +0000
commit0072e594284416a345b9a1083a54d975edc492c5 (patch)
treefff4d2d62d70ab453acaf0b178ff22a9a69819fc
parentb217e2920efdefd8786591c0607a0e1c6ffa7a4e (diff)
parent1f0b3618e31194836e923667fe476c3c356359bf (diff)
downloadtracker-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.c142
-rw-r--r--src/libtracker-data/tracker-data-query.c10
-rw-r--r--src/libtracker-data/tracker-data-update.c324
-rw-r--r--src/libtracker-data/tracker-data-update.h7
-rw-r--r--src/libtracker-data/tracker-db-interface-sqlite.c50
-rw-r--r--src/libtracker-data/tracker-db-interface.h9
-rw-r--r--src/libtracker-data/tracker-db-manager.c12
-rw-r--r--src/libtracker-data/tracker-ontologies.h2
-rw-r--r--src/libtracker-data/tracker-sparql.c22
-rw-r--r--src/libtracker-sparql/tracker-error.c1
-rw-r--r--src/tracker/tracker-export.c2
-rw-r--r--src/tracker/tracker-sql.c2
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);