summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCarlos Garnacho <carlosg@gnome.org>2018-12-24 19:11:57 +0100
committerCarlos Garnacho <carlosg@gnome.org>2018-12-26 13:21:38 +0100
commit0d5c1a65f5a1ea331d438b863e9b6fff14b2dff3 (patch)
tree82cf0a3855695ccb87ee72540402d39b2e551979
parent862b1617269f5466c658b9a01366f0a399e44a14 (diff)
downloadtracker-0d5c1a65f5a1ea331d438b863e9b6fff14b2dff3.tar.gz
libtracker-data: Implement alternative path sequences
The alternative path operator '|' allows multiplexing the ways to get a value. For example: { ?u nie:title|nfo:fileName 'foo' } will return elements whose title or filename matches the given string.
-rw-r--r--src/libtracker-data/tracker-sparql.c52
1 files changed, 47 insertions, 5 deletions
diff --git a/src/libtracker-data/tracker-sparql.c b/src/libtracker-data/tracker-sparql.c
index d2e9477c4..d123c6330 100644
--- a/src/libtracker-data/tracker-sparql.c
+++ b/src/libtracker-data/tracker-sparql.c
@@ -570,6 +570,18 @@ _prepend_path_element (TrackerSparql *sparql,
path_elem->data.composite.child1->name,
path_elem->data.composite.child2->name);
break;
+ case TRACKER_PATH_OPERATOR_ALTERNATIVE:
+ _append_string_printf (sparql,
+ "\"%s\" (ID, value, graph) AS "
+ "(SELECT ID, value, graph "
+ "FROM \"%s\" "
+ "UNION ALL "
+ "SELECT ID, value, graph "
+ "FROM \"%s\") ",
+ path_elem->name,
+ path_elem->data.composite.child1->name,
+ path_elem->data.composite.child2->name);
+ break;
case TRACKER_PATH_OPERATOR_ZEROORMORE:
_append_string_printf (sparql,
"\"%s\" (ID, value, graph) AS "
@@ -610,9 +622,6 @@ _prepend_path_element (TrackerSparql *sparql,
path_elem->data.composite.child1->name,
path_elem->data.composite.child1->name);
break;
- default:
- g_assert_not_reached ();
- break;
}
tracker_sparql_swap_builder (sparql, old);
@@ -4199,14 +4208,47 @@ static gboolean
translate_PathAlternative (TrackerSparql *sparql,
GError **error)
{
+ GPtrArray *path_elems;
+
+ path_elems = g_ptr_array_new ();
+
/* PathAlternative ::= PathSequence ( '|' PathSequence )*
*/
_call_rule (sparql, NAMED_RULE_PathSequence, error);
+ g_ptr_array_add (path_elems, sparql->current_state.path);
- if (_accept (sparql, RULE_TYPE_LITERAL, LITERAL_PATH_ALTERNATIVE)) {
- _unimplemented ("Alternative property path");
+ while (_accept (sparql, RULE_TYPE_LITERAL, LITERAL_PATH_ALTERNATIVE)) {
+ _call_rule (sparql, NAMED_RULE_PathSequence, error);
+ g_ptr_array_add (path_elems, sparql->current_state.path);
}
+ if (path_elems->len > 1) {
+ TrackerPathElement *path_elem;
+ gint i;
+
+ path_elem = tracker_path_element_operator_new (TRACKER_PATH_OPERATOR_ALTERNATIVE,
+ g_ptr_array_index (path_elems, 0),
+ g_ptr_array_index (path_elems, 1));
+ tracker_select_context_add_path_element (TRACKER_SELECT_CONTEXT (sparql->context),
+ path_elem);
+ _prepend_path_element (sparql, path_elem);
+
+ for (i = 2; i < path_elems->len; i++) {
+ TrackerPathElement *child;
+
+ child = g_ptr_array_index (path_elems, i);
+ path_elem = tracker_path_element_operator_new (TRACKER_PATH_OPERATOR_ALTERNATIVE,
+ child, path_elem);
+ tracker_select_context_add_path_element (TRACKER_SELECT_CONTEXT (sparql->context),
+ path_elem);
+ _prepend_path_element (sparql, path_elem);
+ }
+
+ sparql->current_state.path = path_elem;
+ }
+
+ g_ptr_array_unref (path_elems);
+
return TRUE;
}