summaryrefslogtreecommitdiff
path: root/src/libtracker-data/tracker-sparql-types.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/libtracker-data/tracker-sparql-types.c')
-rw-r--r--src/libtracker-data/tracker-sparql-types.c136
1 files changed, 136 insertions, 0 deletions
diff --git a/src/libtracker-data/tracker-sparql-types.c b/src/libtracker-data/tracker-sparql-types.c
index 1c6125f0f..c3c8eae3c 100644
--- a/src/libtracker-data/tracker-sparql-types.c
+++ b/src/libtracker-data/tracker-sparql-types.c
@@ -27,6 +27,7 @@ enum {
TOKEN_TYPE_LITERAL,
TOKEN_TYPE_VARIABLE,
TOKEN_TYPE_PARAMETER,
+ TOKEN_TYPE_PATH,
};
/* Helper structs */
@@ -198,6 +199,14 @@ tracker_token_parameter_init (TrackerToken *token,
}
void
+tracker_token_path_init (TrackerToken *token,
+ TrackerPathElement *path)
+{
+ token->type = TOKEN_TYPE_PATH;
+ token->content.path = path;
+}
+
+void
tracker_token_unset (TrackerToken *token)
{
if (token->type == TOKEN_TYPE_LITERAL)
@@ -237,6 +246,14 @@ tracker_token_get_parameter (TrackerToken *token)
return NULL;
}
+TrackerPathElement *
+tracker_token_get_path (TrackerToken *token)
+{
+ if (token->type == TOKEN_TYPE_PATH)
+ return token->content.path;
+ return NULL;
+}
+
const gchar *
tracker_token_get_idstring (TrackerToken *token)
{
@@ -244,6 +261,8 @@ tracker_token_get_idstring (TrackerToken *token)
return token->content.literal;
else if (token->type == TOKEN_TYPE_VARIABLE)
return token->content.var->sql_expression;
+ else if (token->type == TOKEN_TYPE_PATH)
+ return token->content.path->name;
else
return NULL;
}
@@ -530,6 +549,86 @@ tracker_variable_binding_get_class (TrackerVariableBinding *binding)
return binding->type;
}
+/* Path element */
+static void
+tracker_path_element_free (TrackerPathElement *elem)
+{
+ g_free (elem->name);
+ g_free (elem);
+}
+
+TrackerPathElement *
+tracker_path_element_property_new (TrackerProperty *prop)
+{
+ TrackerPathElement *elem;
+
+ g_return_val_if_fail (TRACKER_IS_PROPERTY (prop), NULL);
+
+ elem = g_new0 (TrackerPathElement, 1);
+ elem->op = TRACKER_PATH_OPERATOR_NONE;
+ elem->type = tracker_property_get_data_type (prop);
+ elem->data.property = prop;
+
+ return elem;
+}
+
+TrackerPathElement *
+tracker_path_element_operator_new (TrackerPathOperator op,
+ TrackerPathElement *child1,
+ TrackerPathElement *child2)
+{
+ TrackerPathElement *elem;
+
+ g_return_val_if_fail (op != TRACKER_PATH_OPERATOR_NONE, NULL);
+ g_return_val_if_fail (child1 != NULL, NULL);
+ g_return_val_if_fail (child2 == NULL ||
+ op == TRACKER_PATH_OPERATOR_SEQUENCE ||
+ op == TRACKER_PATH_OPERATOR_ALTERNATIVE, NULL);
+
+ elem = g_new0 (TrackerPathElement, 1);
+ elem->op = op;
+ elem->data.composite.child1 = child1;
+ elem->data.composite.child2 = child2;
+ elem->type = child2 ? child2->type : child1->type;
+
+ return elem;
+}
+
+static void
+tracker_path_element_set_unique_name (TrackerPathElement *elem,
+ gint id)
+{
+ const gchar *name = NULL;
+
+ switch (elem->op) {
+ case TRACKER_PATH_OPERATOR_NONE:
+ name = tracker_property_get_name (elem->data.property);
+ break;
+ case TRACKER_PATH_OPERATOR_INVERSE:
+ name = "inv";
+ break;
+ case TRACKER_PATH_OPERATOR_SEQUENCE:
+ name = "seq";
+ break;
+ case TRACKER_PATH_OPERATOR_ALTERNATIVE:
+ name = "alt";
+ break;
+ case TRACKER_PATH_OPERATOR_ZEROORONE:
+ name = "zeroorone";
+ break;
+ case TRACKER_PATH_OPERATOR_ZEROORMORE:
+ name = "zeroormore";
+ break;
+ case TRACKER_PATH_OPERATOR_ONEORMORE:
+ name = "oneormore";
+ break;
+ default:
+ g_assert_not_reached ();
+ }
+
+ elem->name = g_strdup_printf ("p%d_%s", id, name);
+}
+
/* Context */
G_DEFINE_TYPE (TrackerContext, tracker_context, G_TYPE_INITIALLY_UNOWNED)
@@ -627,6 +726,7 @@ tracker_select_context_finalize (GObject *object)
g_clear_pointer (&context->predicate_variables, g_hash_table_unref);
g_clear_pointer (&context->generated_variables, g_ptr_array_unref);
g_clear_pointer (&context->literal_bindings, g_ptr_array_unref);
+ g_clear_pointer (&context->path_elements, g_ptr_array_unref);
G_OBJECT_CLASS (tracker_select_context_parent_class)->finalize (object);
}
@@ -759,6 +859,42 @@ tracker_select_context_get_literal_binding_index (TrackerSelectContext *context
return -1;
}
+void
+tracker_select_context_add_path_element (TrackerSelectContext *context,
+ TrackerPathElement *path_elem)
+{
+ if (!context->path_elements) {
+ context->path_elements =
+ g_ptr_array_new_with_free_func ((GDestroyNotify) tracker_path_element_free);
+ }
+
+ g_ptr_array_add (context->path_elements, path_elem);
+ tracker_path_element_set_unique_name (path_elem,
+ context->path_elements->len);
+}
+
+TrackerPathElement *
+tracker_select_context_lookup_path_element_for_property (TrackerSelectContext *context,
+ TrackerProperty *property)
+{
+ guint i;
+
+ if (!context->path_elements)
+ return NULL;
+
+ for (i = 0; i < context->path_elements->len; i++) {
+ TrackerPathElement *path_elem;
+
+ path_elem = g_ptr_array_index (context->path_elements, i);
+
+ if (path_elem->op == TRACKER_PATH_OPERATOR_NONE &&
+ path_elem->data.property == property)
+ return path_elem;
+ }
+
+ return NULL;
+}
+
/* Triple context */
G_DEFINE_TYPE (TrackerTripleContext, tracker_triple_context, TRACKER_TYPE_CONTEXT)