From c7c173f4c231c797b2eddebc1cf1a601b08c2e26 Mon Sep 17 00:00:00 2001 From: Carlos Garnacho Date: Sun, 14 Oct 2018 11:23:35 +0200 Subject: libtracker-data: Support parameter bindings Those relate to PARAMETERIZED_VAR, and allow binding values through it at query preparation time. --- src/libtracker-data/tracker-data-query.c | 2 +- src/libtracker-data/tracker-sparql-types.c | 69 ++++++++++++++++- src/libtracker-data/tracker-sparql-types.h | 31 +++++++- src/libtracker-data/tracker-sparql.c | 114 +++++++++++++++++++++++++---- src/libtracker-data/tracker-sparql.h | 1 + src/libtracker-direct/tracker-direct.c | 2 +- 6 files changed, 199 insertions(+), 20 deletions(-) diff --git a/src/libtracker-data/tracker-data-query.c b/src/libtracker-data/tracker-data-query.c index aebfacf61..2694d6d0b 100644 --- a/src/libtracker-data/tracker-data-query.c +++ b/src/libtracker-data/tracker-data-query.c @@ -176,7 +176,7 @@ tracker_data_query_sparql_cursor (TrackerDataManager *manager, sparql_query = tracker_sparql_new (manager, query); - cursor = tracker_sparql_execute_cursor (sparql_query, error); + cursor = tracker_sparql_execute_cursor (sparql_query, NULL, error); g_object_unref (sparql_query); diff --git a/src/libtracker-data/tracker-sparql-types.c b/src/libtracker-data/tracker-sparql-types.c index d48ed886e..1c6125f0f 100644 --- a/src/libtracker-data/tracker-sparql-types.c +++ b/src/libtracker-data/tracker-sparql-types.c @@ -25,7 +25,8 @@ enum { TOKEN_TYPE_NONE, TOKEN_TYPE_LITERAL, - TOKEN_TYPE_VARIABLE + TOKEN_TYPE_VARIABLE, + TOKEN_TYPE_PARAMETER, }; /* Helper structs */ @@ -188,11 +189,21 @@ tracker_token_variable_init (TrackerToken *token, token->content.var = variable; } +void +tracker_token_parameter_init (TrackerToken *token, + const gchar *parameter) +{ + token->type = TOKEN_TYPE_PARAMETER; + token->content.parameter = g_strdup (parameter); +} + void tracker_token_unset (TrackerToken *token) { if (token->type == TOKEN_TYPE_LITERAL) g_clear_pointer (&token->content.literal, g_free); + else if (token->type == TOKEN_TYPE_PARAMETER) + g_clear_pointer (&token->content.parameter, g_free); token->type = TOKEN_TYPE_NONE; } @@ -218,6 +229,14 @@ tracker_token_get_variable (TrackerToken *token) return NULL; } +const gchar * +tracker_token_get_parameter (TrackerToken *token) +{ + if (token->type == TOKEN_TYPE_PARAMETER) + return token->content.parameter; + return NULL; +} + const gchar * tracker_token_get_idstring (TrackerToken *token) { @@ -419,6 +438,45 @@ tracker_literal_binding_new (const gchar *literal, return binding; } +/* Parameter binding */ +G_DEFINE_TYPE (TrackerParameterBinding, tracker_parameter_binding, TRACKER_TYPE_LITERAL_BINDING) + +static void +tracker_parameter_binding_finalize (GObject *object) +{ + TrackerParameterBinding *binding = TRACKER_PARAMETER_BINDING (object); + + g_free (binding->name); + + G_OBJECT_CLASS (tracker_parameter_binding_parent_class)->finalize (object); +} + +static void +tracker_parameter_binding_class_init (TrackerParameterBindingClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + object_class->finalize = tracker_parameter_binding_finalize; +} + +static void +tracker_parameter_binding_init (TrackerParameterBinding *binding) +{ +} + +TrackerBinding * +tracker_parameter_binding_new (const gchar *name, + TrackerDataTable *table) +{ + TrackerBinding *binding; + + binding = g_object_new (TRACKER_TYPE_PARAMETER_BINDING, NULL); + binding->table = table; + TRACKER_PARAMETER_BINDING (binding)->name = g_strdup (name); + + return binding; +} + /* Variable binding */ G_DEFINE_TYPE (TrackerVariableBinding, tracker_variable_binding, TRACKER_TYPE_BINDING) @@ -592,6 +650,15 @@ tracker_select_context_new (void) return g_object_new (TRACKER_TYPE_SELECT_CONTEXT, NULL); } +TrackerVariable * +tracker_select_context_lookup_variable (TrackerSelectContext *context, + const gchar *name) +{ + if (!context->variables) + return NULL; + return g_hash_table_lookup (context->variables, name); +} + TrackerVariable * tracker_select_context_ensure_variable (TrackerSelectContext *context, const gchar *name) diff --git a/src/libtracker-data/tracker-sparql-types.h b/src/libtracker-data/tracker-sparql-types.h index 6fdd0cbe7..1df06764c 100644 --- a/src/libtracker-data/tracker-sparql-types.h +++ b/src/libtracker-data/tracker-sparql-types.h @@ -31,6 +31,10 @@ #define TRACKER_LITERAL_BINDING(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), TRACKER_TYPE_LITERAL_BINDING, TrackerLiteralBinding)) #define TRACKER_IS_LITERAL_BINDING(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), TRACKER_TYPE_LITERAL_BINDING)) +#define TRACKER_TYPE_PARAMETER_BINDING (tracker_parameter_binding_get_type ()) +#define TRACKER_PARAMETER_BINDING(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), TRACKER_TYPE_PARAMETER_BINDING, TrackerParameterBinding)) +#define TRACKER_IS_PARAMETER_BINDING(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), TRACKER_TYPE_PARAMETER_BINDING)) + #define TRACKER_TYPE_VARIABLE_BINDING (tracker_variable_binding_get_type ()) #define TRACKER_VARIABLE_BINDING(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), TRACKER_TYPE_VARIABLE_BINDING, TrackerVariableBinding)) #define TRACKER_IS_VARIABLE_BINDING(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), TRACKER_TYPE_VARIABLE_BINDING)) @@ -51,6 +55,8 @@ typedef struct _TrackerBinding TrackerBinding; typedef struct _TrackerBindingClass TrackerBindingClass; typedef struct _TrackerLiteralBinding TrackerLiteralBinding; typedef struct _TrackerLiteralBindingClass TrackerLiteralBindingClass; +typedef struct _TrackerParameterBinding TrackerParameterBinding; +typedef struct _TrackerParameterBindingClass TrackerParameterBindingClass; typedef struct _TrackerVariableBinding TrackerVariableBinding; typedef struct _TrackerVariableBindingClass TrackerVariableBindingClass; typedef struct _TrackerContext TrackerContext; @@ -95,6 +101,16 @@ struct _TrackerLiteralBindingClass { TrackerBindingClass parent_class; }; +/* Represents a mapping of a SPARQL parameter variable to a user-provided value */ +struct _TrackerParameterBinding { + TrackerLiteralBinding parent_instance; + gchar *name; +}; + +struct _TrackerParameterBindingClass { + TrackerLiteralBindingClass parent_class; +}; + /* Represents a mapping of a SPARQL variable to a SQL table and column */ struct _TrackerVariableBinding { TrackerBinding parent_instance; @@ -117,6 +133,7 @@ struct _TrackerToken { guint type; union { gchar *literal; + gchar *parameter; TrackerVariable *var; } content; }; @@ -225,6 +242,11 @@ GType tracker_literal_binding_get_type (void) G_GNUC_CONST; TrackerBinding * tracker_literal_binding_new (const gchar *literal, TrackerDataTable *table); +/* Parameter binding */ +GType tracker_parameter_binding_get_type (void) G_GNUC_CONST; +TrackerBinding * tracker_parameter_binding_new (const gchar *name, + TrackerDataTable *table); + /* Variable binding */ GType tracker_variable_binding_get_type (void) G_GNUC_CONST; TrackerBinding * tracker_variable_binding_new (TrackerVariable *variable, @@ -249,15 +271,18 @@ TrackerVariableBinding * tracker_variable_get_sample_binding (TrackerVariable *v /* Token */ void tracker_token_literal_init (TrackerToken *token, - const gchar *literal); + const gchar *literal); void tracker_token_variable_init (TrackerToken *token, TrackerVariable *variable); -void tracker_token_unset (TrackerToken *token); +void tracker_token_parameter_init (TrackerToken *token, + const gchar *pameter); +void tracker_token_unset (TrackerToken *token); gboolean tracker_token_is_empty (TrackerToken *token); const gchar * tracker_token_get_literal (TrackerToken *token); TrackerVariable * tracker_token_get_variable (TrackerToken *token); const gchar * tracker_token_get_idstring (TrackerToken *token); +const gchar * tracker_token_get_parameter (TrackerToken *token); /* Predicate variable */ TrackerPredicateVariable *tracker_predicate_variable_new (void); @@ -298,6 +323,8 @@ gboolean tracker_context_lookup_variable_ref (TrackerContext *context, /* Select context */ GType tracker_select_context_get_type (void) G_GNUC_CONST; TrackerContext * tracker_select_context_new (void); +TrackerVariable * tracker_select_context_lookup_variable (TrackerSelectContext *context, + const gchar *name); TrackerVariable * tracker_select_context_ensure_variable (TrackerSelectContext *context, const gchar *name); TrackerVariable * tracker_select_context_add_generated_variable (TrackerSelectContext *context); diff --git a/src/libtracker-data/tracker-sparql.c b/src/libtracker-data/tracker-sparql.c index 600d1c776..54e48a1d2 100644 --- a/src/libtracker-data/tracker-sparql.c +++ b/src/libtracker-data/tracker-sparql.c @@ -60,6 +60,7 @@ static gboolean helper_translate_time (TrackerSparql *sparql, static TrackerDBStatement * prepare_query (TrackerDBInterface *iface, TrackerStringBuilder *str, GPtrArray *literals, + GHashTable *parameters, gboolean cached, GError **error); static inline TrackerVariable * _ensure_variable (TrackerSparql *sparql, @@ -119,6 +120,8 @@ struct _TrackerSparql gboolean silent; gboolean cacheable; + GHashTable *parameters; + struct { TrackerContext *context; TrackerContext *select_context; @@ -151,6 +154,7 @@ tracker_sparql_finalize (GObject *object) g_object_unref (sparql->data_manager); g_hash_table_destroy (sparql->prefix_map); + g_hash_table_destroy (sparql->parameters); if (sparql->sql) tracker_string_builder_free (sparql->sql); @@ -555,6 +559,7 @@ _extract_node_string (TrackerParserNode *node, switch (rule->data.terminal) { case TERMINAL_TYPE_VAR1: case TERMINAL_TYPE_VAR2: + case TERMINAL_TYPE_PARAMETERIZED_VAR: add_start = 1; break; case TERMINAL_TYPE_STRING_LITERAL1: @@ -618,14 +623,22 @@ _dup_last_string (TrackerSparql *sparql) static inline TrackerBinding * _convert_terminal (TrackerSparql *sparql) { + const TrackerGrammarRule *rule; TrackerBinding *binding; gchar *str; str = _dup_last_string (sparql); g_assert (str != NULL); - binding = tracker_literal_binding_new (str, NULL); - tracker_binding_set_data_type (binding, sparql->current_state.expression_type); + rule = tracker_parser_node_get_rule (sparql->current_state.prev_node); + + if (tracker_grammar_rule_is_a (rule, RULE_TYPE_TERMINAL, TERMINAL_TYPE_PARAMETERIZED_VAR)) { + binding = tracker_parameter_binding_new (str, NULL); + } else { + binding = tracker_literal_binding_new (str, NULL); + tracker_binding_set_data_type (binding, sparql->current_state.expression_type); + } + g_free (str); return binding; @@ -669,18 +682,18 @@ _ensure_variable (TrackerSparql *sparql, TrackerVariable *var; var = tracker_select_context_ensure_variable (TRACKER_SELECT_CONTEXT (sparql->context), - name); + name); tracker_context_add_variable_ref (sparql->current_state.context, var); return var; } static inline TrackerVariable * -_extract_node_variable (TrackerParserNode *node, - TrackerSparql *sparql) +_extract_node_variable (TrackerParserNode *node, + TrackerSparql *sparql) { const TrackerGrammarRule *rule = tracker_parser_node_get_rule (node); - TrackerVariable *variable; + TrackerVariable *variable = NULL; gchar *str; if (!tracker_grammar_rule_is_a (rule, RULE_TYPE_TERMINAL, TERMINAL_TYPE_VAR1) && @@ -722,6 +735,8 @@ _init_token (TrackerToken *token, value = g_hash_table_lookup (sparql->solution_var_map, str); tracker_token_literal_init (token, value); } + } else if (tracker_grammar_rule_is_a (rule, RULE_TYPE_TERMINAL, TERMINAL_TYPE_PARAMETERIZED_VAR)) { + tracker_token_parameter_init (token, str); } else { tracker_token_literal_init (token, str); } @@ -911,7 +926,7 @@ _add_quad (TrackerSparql *sparql, triple_context = TRACKER_TRIPLE_CONTEXT (sparql->current_state.context); ontologies = tracker_data_manager_get_ontologies (sparql->data_manager); - if (!tracker_token_get_variable (predicate)) { + if (tracker_token_get_literal (predicate)) { gboolean share_table = TRUE; const gchar *db_table; @@ -1030,7 +1045,7 @@ _add_quad (TrackerSparql *sparql, db_table); new_table = TRUE; } - } else { + } else if (tracker_token_get_variable (predicate)) { TrackerPredicateVariable *pred_var; /* Variable in predicate */ @@ -1061,15 +1076,23 @@ _add_quad (TrackerSparql *sparql, tracker_binding_set_db_column_name (binding, "predicate"); _add_binding (sparql, binding); g_object_unref (binding); + } else { + /* The parser disallows parameter predicates */ + g_assert_not_reached (); } if (new_table) { if (tracker_token_get_variable (subject)) { variable = tracker_token_get_variable (subject); binding = tracker_variable_binding_new (variable, subject_type, table); - } else { + } else if (tracker_token_get_literal (subject)) { binding = tracker_literal_binding_new (tracker_token_get_literal (subject), table); + } else if (tracker_token_get_parameter (subject)) { + binding = tracker_parameter_binding_new (tracker_token_get_parameter (subject), + table); + } else { + g_assert_not_reached (); } tracker_binding_set_data_type (binding, TRACKER_PROPERTY_TYPE_RESOURCE); @@ -1134,7 +1157,14 @@ _add_quad (TrackerSparql *sparql, _add_binding (sparql, binding); g_object_unref (binding); } else if (is_fts) { - binding = tracker_literal_binding_new (tracker_token_get_literal (object), table); + if (tracker_token_get_literal (object)) { + binding = tracker_literal_binding_new (tracker_token_get_literal (object), table); + } else if (tracker_token_get_parameter (object)) { + binding = tracker_parameter_binding_new (tracker_token_get_parameter (object), table); + } else { + g_assert_not_reached (); + } + tracker_binding_set_db_column_name (binding, "fts5"); _add_binding (sparql, binding); g_object_unref (binding); @@ -1175,8 +1205,13 @@ _add_quad (TrackerSparql *sparql, } } } else { - binding = tracker_literal_binding_new (tracker_token_get_literal (object), - table); + if (tracker_token_get_literal (object)) { + binding = tracker_literal_binding_new (tracker_token_get_literal (object), table); + } else if (tracker_token_get_parameter (object)) { + binding = tracker_parameter_binding_new (tracker_token_get_parameter (object), table); + } else { + g_assert_not_reached (); + } if (tracker_token_get_variable (predicate)) { tracker_binding_set_db_column_name (binding, "object"); @@ -1195,8 +1230,12 @@ _add_quad (TrackerSparql *sparql, variable = tracker_token_get_variable (graph); binding = tracker_variable_binding_new (variable, NULL, table); tracker_variable_binding_set_nullable (TRACKER_VARIABLE_BINDING (binding), TRUE); - } else { + } else if (tracker_token_get_literal (graph)) { binding = tracker_literal_binding_new (tracker_token_get_literal (graph), table); + } else if (tracker_token_get_parameter (graph)) { + binding = tracker_parameter_binding_new (tracker_token_get_parameter (graph), table); + } else { + g_assert_not_reached (); } tracker_binding_set_data_type (binding, TRACKER_PROPERTY_TYPE_RESOURCE); @@ -2682,7 +2721,7 @@ get_solution_for_pattern (TrackerSparql *sparql, iface = tracker_data_manager_get_writable_db_interface (sparql->data_manager); stmt = prepare_query (iface, sparql->sql, TRACKER_SELECT_CONTEXT (sparql->context)->literal_bindings, - FALSE, + NULL, FALSE, error); g_clear_object (&sparql->context); @@ -5916,12 +5955,17 @@ translate_NumericLiteralUnsigned (TrackerSparql *sparql, GError **error) { /* NumericLiteralUnsigned ::= INTEGER | DECIMAL | DOUBLE + * + * TRACKER EXTENSION: + * The terminal PARAMETERIZED_VAR is additionally accepted */ if (_accept (sparql, RULE_TYPE_TERMINAL, TERMINAL_TYPE_INTEGER)) { sparql->current_state.expression_type = TRACKER_PROPERTY_TYPE_INTEGER; } else if (_accept (sparql, RULE_TYPE_TERMINAL, TERMINAL_TYPE_DOUBLE) || _accept (sparql, RULE_TYPE_TERMINAL, TERMINAL_TYPE_DECIMAL)) { sparql->current_state.expression_type = TRACKER_PROPERTY_TYPE_DOUBLE; + } else if (_accept (sparql, RULE_TYPE_TERMINAL, TERMINAL_TYPE_PARAMETERIZED_VAR)) { + sparql->current_state.expression_type = TRACKER_PROPERTY_TYPE_UNKNOWN; } else { g_assert_not_reached (); } @@ -5934,12 +5978,17 @@ translate_NumericLiteralPositive (TrackerSparql *sparql, GError **error) { /* NumericLiteralPositive ::= INTEGER_POSITIVE | DECIMAL_POSITIVE | DOUBLE_POSITIVE + * + * TRACKER EXTENSION: + * The terminal PARAMETERIZED_VAR is additionally accepted */ if (_accept (sparql, RULE_TYPE_TERMINAL, TERMINAL_TYPE_INTEGER_POSITIVE)) { sparql->current_state.expression_type = TRACKER_PROPERTY_TYPE_INTEGER; } else if (_accept (sparql, RULE_TYPE_TERMINAL, TERMINAL_TYPE_DECIMAL_POSITIVE) || _accept (sparql, RULE_TYPE_TERMINAL, TERMINAL_TYPE_DOUBLE_POSITIVE)) { sparql->current_state.expression_type = TRACKER_PROPERTY_TYPE_DOUBLE; + } else if (_accept (sparql, RULE_TYPE_TERMINAL, TERMINAL_TYPE_PARAMETERIZED_VAR)) { + sparql->current_state.expression_type = TRACKER_PROPERTY_TYPE_UNKNOWN; } else { g_assert_not_reached (); } @@ -5952,12 +6001,17 @@ translate_NumericLiteralNegative (TrackerSparql *sparql, GError **error) { /* NumericLiteralNegative ::= INTEGER_NEGATIVE | DECIMAL_NEGATIVE | DOUBLE_NEGATIVE + * + * TRACKER EXTENSION: + * The terminal PARAMETERIZED_VAR is additionally accepted */ if (_accept (sparql, RULE_TYPE_TERMINAL, TERMINAL_TYPE_INTEGER_NEGATIVE)) { sparql->current_state.expression_type = TRACKER_PROPERTY_TYPE_INTEGER; } else if (_accept (sparql, RULE_TYPE_TERMINAL, TERMINAL_TYPE_DECIMAL_NEGATIVE) || _accept (sparql, RULE_TYPE_TERMINAL, TERMINAL_TYPE_DOUBLE_NEGATIVE)) { sparql->current_state.expression_type = TRACKER_PROPERTY_TYPE_DOUBLE; + } else if (_accept (sparql, RULE_TYPE_TERMINAL, TERMINAL_TYPE_PARAMETERIZED_VAR)) { + sparql->current_state.expression_type = TRACKER_PROPERTY_TYPE_UNKNOWN; } else { g_assert_not_reached (); } @@ -5970,11 +6024,16 @@ translate_BooleanLiteral (TrackerSparql *sparql, GError **error) { /* BooleanLiteral ::= 'true' | 'false' + * + * TRACKER EXTENSION: + * The terminal PARAMETERIZED_VAR is additionally accepted */ if (_accept (sparql, RULE_TYPE_LITERAL, LITERAL_TRUE) || _accept (sparql, RULE_TYPE_LITERAL, LITERAL_FALSE)) { sparql->current_state.expression_type = TRACKER_PROPERTY_TYPE_BOOLEAN; return TRUE; + } else if (_accept (sparql, RULE_TYPE_TERMINAL, TERMINAL_TYPE_PARAMETERIZED_VAR)) { + sparql->current_state.expression_type = TRACKER_PROPERTY_TYPE_UNKNOWN; } else { g_assert_not_reached (); } @@ -5987,6 +6046,9 @@ translate_String (TrackerSparql *sparql, GError **error) { /* String ::= STRING_LITERAL1 | STRING_LITERAL2 | STRING_LITERAL_LONG1 | STRING_LITERAL_LONG2 + * + * TRACKER EXTENSION: + * The terminal PARAMETERIZED_VAR is additionally accepted */ if (_accept (sparql, RULE_TYPE_TERMINAL, TERMINAL_TYPE_STRING_LITERAL1) || _accept (sparql, RULE_TYPE_TERMINAL, TERMINAL_TYPE_STRING_LITERAL2) || @@ -5994,6 +6056,8 @@ translate_String (TrackerSparql *sparql, _accept (sparql, RULE_TYPE_TERMINAL, TERMINAL_TYPE_STRING_LITERAL_LONG2)) { sparql->current_state.expression_type = TRACKER_PROPERTY_TYPE_STRING; return TRUE; + } else if (_accept (sparql, RULE_TYPE_TERMINAL, TERMINAL_TYPE_PARAMETERIZED_VAR)) { + sparql->current_state.expression_type = TRACKER_PROPERTY_TYPE_UNKNOWN; } else { g_assert_not_reached (); } @@ -6291,6 +6355,7 @@ tracker_sparql_init (TrackerSparql *sparql) { sparql->prefix_map = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free); + sparql->parameters = g_hash_table_new (g_str_hash, g_str_equal); sparql->var_names = g_ptr_array_new_with_free_func (g_free); sparql->var_types = g_array_new (FALSE, FALSE, sizeof (TrackerPropertyType)); sparql->cacheable = TRUE; @@ -6327,6 +6392,7 @@ static TrackerDBStatement * prepare_query (TrackerDBInterface *iface, TrackerStringBuilder *str, GPtrArray *literals, + GHashTable *parameters, gboolean cached, GError **error) { @@ -6352,7 +6418,23 @@ prepare_query (TrackerDBInterface *iface, binding = g_ptr_array_index (literals, i); prop_type = TRACKER_BINDING (binding)->data_type; - if (prop_type == TRACKER_PROPERTY_TYPE_BOOLEAN) { + if (TRACKER_IS_PARAMETER_BINDING (binding)) { + const gchar *name; + GValue *value = NULL; + + name = TRACKER_PARAMETER_BINDING (binding)->name; + + if (parameters) + value = g_hash_table_lookup (parameters, name); + + if (value) { + tracker_db_statement_bind_value (stmt, i, value); + } else { + g_set_error (error, TRACKER_SPARQL_ERROR, + TRACKER_SPARQL_ERROR_TYPE, + "Parameter '%s' has no given value", name); + } + } else if (prop_type == TRACKER_PROPERTY_TYPE_BOOLEAN) { if (g_str_equal (binding->literal, "1") || g_ascii_strcasecmp (binding->literal, "true") == 0) { tracker_db_statement_bind_int (stmt, i, 1); @@ -6403,6 +6485,7 @@ prepare_query (TrackerDBInterface *iface, TrackerSparqlCursor * tracker_sparql_execute_cursor (TrackerSparql *sparql, + GHashTable *parameters, GError **error) { TrackerDBStatement *stmt; @@ -6423,6 +6506,7 @@ tracker_sparql_execute_cursor (TrackerSparql *sparql, iface = tracker_data_manager_get_db_interface (sparql->data_manager); stmt = prepare_query (iface, sparql->sql, TRACKER_SELECT_CONTEXT (sparql->context)->literal_bindings, + parameters, sparql->cacheable, error); if (!stmt) diff --git a/src/libtracker-data/tracker-sparql.h b/src/libtracker-data/tracker-sparql.h index bf0b3b137..e86665c51 100644 --- a/src/libtracker-data/tracker-sparql.h +++ b/src/libtracker-data/tracker-sparql.h @@ -36,6 +36,7 @@ TrackerSparql * tracker_sparql_new (TrackerDataManager *manager, const gchar *sparql); TrackerSparqlCursor * tracker_sparql_execute_cursor (TrackerSparql *sparql, + GHashTable *parameters, GError **error); TrackerSparql * tracker_sparql_new_update (TrackerDataManager *manager, diff --git a/src/libtracker-direct/tracker-direct.c b/src/libtracker-direct/tracker-direct.c index b7e2a8449..9bec7429b 100644 --- a/src/libtracker-direct/tracker-direct.c +++ b/src/libtracker-direct/tracker-direct.c @@ -438,7 +438,7 @@ tracker_direct_connection_query (TrackerSparqlConnection *self, g_mutex_lock (&priv->mutex); query = tracker_sparql_new (priv->data_manager, sparql); - cursor = tracker_sparql_execute_cursor (query, error); + cursor = tracker_sparql_execute_cursor (query, NULL, error); g_object_unref (query); if (cursor) -- cgit v1.2.1