summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/libtracker-data/tracker-sparql.c82
1 files changed, 79 insertions, 3 deletions
diff --git a/src/libtracker-data/tracker-sparql.c b/src/libtracker-data/tracker-sparql.c
index 011b5ab5e..600d1c776 100644
--- a/src/libtracker-data/tracker-sparql.c
+++ b/src/libtracker-data/tracker-sparql.c
@@ -37,6 +37,9 @@
#define XSD_NS "http://www.w3.org/2001/XMLSchema#"
#define FN_NS "http://www.w3.org/2005/xpath-functions#"
+/* FIXME: This should be dependent on SQLITE_LIMIT_VARIABLE_NUMBER */
+#define MAX_VARIABLES 999
+
enum {
TIME_FORMAT_SECONDS,
TIME_FORMAT_MINUTES,
@@ -57,6 +60,7 @@ static gboolean helper_translate_time (TrackerSparql *sparql,
static TrackerDBStatement * prepare_query (TrackerDBInterface *iface,
TrackerStringBuilder *str,
GPtrArray *literals,
+ gboolean cached,
GError **error);
static inline TrackerVariable * _ensure_variable (TrackerSparql *sparql,
const gchar *name);
@@ -113,6 +117,7 @@ struct _TrackerSparql
GHashTable *solution_var_map;
gboolean silent;
+ gboolean cacheable;
struct {
TrackerContext *context;
@@ -405,6 +410,32 @@ _append_placeholder (TrackerSparql *sparql)
return tracker_string_builder_append_placeholder (sparql->current_state.sql);
}
+static inline gchar *
+_escape_sql_string (const gchar *str)
+{
+ int i, j, len;
+ gchar *copy;
+
+ len = strlen (str);
+ copy = g_new (char, (len * 2) + 1);
+ i = j = 0;
+
+ while (i < len) {
+ if (str[i] == '\'') {
+ copy[j] = '\'';
+ j++;
+ }
+
+ copy[j] = str[i];
+ i++;
+ j++;
+ }
+
+ copy[j] = '\0';
+
+ return copy;
+}
+
static inline void
_append_literal_sql (TrackerSparql *sparql,
TrackerLiteralBinding *binding)
@@ -414,14 +445,53 @@ _append_literal_sql (TrackerSparql *sparql,
idx = tracker_select_context_get_literal_binding_index (TRACKER_SELECT_CONTEXT (sparql->context),
binding);
+ if (idx >= MAX_VARIABLES) {
+ sparql->cacheable = FALSE;
+ }
+
if (TRACKER_BINDING (binding)->data_type == TRACKER_PROPERTY_TYPE_RESOURCE) {
_append_string_printf (sparql,
- "COALESCE ((SELECT ID FROM Resource WHERE Uri = ?%d), 0) ",
- idx + 1);
+ "COALESCE ((SELECT ID FROM Resource WHERE Uri = ");
+ }
+
+ if (!sparql->cacheable) {
+ gchar *escaped, *full_str;
+
+ switch (TRACKER_BINDING (binding)->data_type) {
+ case TRACKER_PROPERTY_TYPE_DATE:
+ full_str = g_strdup_printf ("%sT00:00:00Z", binding->literal);
+ escaped = _escape_sql_string (full_str);
+ _append_string (sparql, escaped);
+ g_free (escaped);
+ g_free (full_str);
+ break;
+ case TRACKER_PROPERTY_TYPE_DATETIME:
+ case TRACKER_PROPERTY_TYPE_STRING:
+ case TRACKER_PROPERTY_TYPE_RESOURCE:
+ escaped = _escape_sql_string (binding->literal);
+ _append_string (sparql, escaped);
+ g_free (escaped);
+ break;
+ case TRACKER_PROPERTY_TYPE_BOOLEAN:
+ if (g_str_equal (binding->literal, "1") ||
+ g_ascii_strcasecmp (binding->literal, "true") == 0) {
+ _append_string (sparql, "1");
+ } else {
+ _append_string (sparql, "0");
+ }
+ break;
+ case TRACKER_PROPERTY_TYPE_UNKNOWN:
+ case TRACKER_PROPERTY_TYPE_INTEGER:
+ case TRACKER_PROPERTY_TYPE_DOUBLE:
+ _append_string (sparql, binding->literal);
+ break;
+ }
} else {
_append_string_printf (sparql, "?%d ", idx + 1);
}
+ if (TRACKER_BINDING (binding)->data_type == TRACKER_PROPERTY_TYPE_RESOURCE)
+ _append_string_printf (sparql, "), 0) ");
if (TRACKER_BINDING (binding)->data_type == TRACKER_PROPERTY_TYPE_STRING)
_append_string (sparql, "COLLATE " TRACKER_COLLATION_NAME " ");
}
@@ -2612,6 +2682,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,
error);
g_clear_object (&sparql->context);
@@ -6222,6 +6293,7 @@ tracker_sparql_init (TrackerSparql *sparql)
g_free, g_free);
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;
}
TrackerSparql*
@@ -6255,6 +6327,7 @@ static TrackerDBStatement *
prepare_query (TrackerDBInterface *iface,
TrackerStringBuilder *str,
GPtrArray *literals,
+ gboolean cached,
GError **error)
{
TrackerDBStatement *stmt;
@@ -6263,7 +6336,9 @@ prepare_query (TrackerDBInterface *iface,
query = tracker_string_builder_to_string (str);
stmt = tracker_db_interface_create_statement (iface,
- TRACKER_DB_STATEMENT_CACHE_TYPE_SELECT,
+ cached ?
+ TRACKER_DB_STATEMENT_CACHE_TYPE_SELECT :
+ TRACKER_DB_STATEMENT_CACHE_TYPE_NONE,
error, query);
g_free (query);
@@ -6348,6 +6423,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,
+ sparql->cacheable,
error);
if (!stmt)
return NULL;