[tracker/wip/carlosg/portal: 2/29] libtracker-data: Add support for CONSTRAINT query prologues
- From: Carlos Garnacho <carlosg src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [tracker/wip/carlosg/portal: 2/29] libtracker-data: Add support for CONSTRAINT query prologues
- Date: Sun, 16 Feb 2020 21:39:33 +0000 (UTC)
commit 3790166c0261f37c1b413f6560f2f16497d312e1
Author: Carlos Garnacho <carlosg gnome org>
Date: Thu Jan 23 15:49:59 2020 +0100
libtracker-data: Add support for CONSTRAINT query prologues
This prologue declaration is a Tracker extension, in order to
constraint access to graphs and services within the query.
Successive CONSTRAINT calls will intersect with previous ones,
meaning that the dataset can only be shrunk and no clause will
be violated.
We allow 2 types of CONSTRAINT clauses, for graphs (CONSTRAINT
GRAPH) and services (CONSTRAINT SERVICE). These take a list of
comma-separated IRIREFs. An empty list is also accepted, resulting
in the most restrictive (empty) set. No clauses will mean access
to graphs and services is undeterred.
src/libtracker-data/tracker-sparql-grammar.h | 20 ++++++-
src/libtracker-data/tracker-sparql.c | 81 +++++++++++++++++++++++++++-
2 files changed, 97 insertions(+), 4 deletions(-)
---
diff --git a/src/libtracker-data/tracker-sparql-grammar.h b/src/libtracker-data/tracker-sparql-grammar.h
index 0372a890f..997c0f0f4 100644
--- a/src/libtracker-data/tracker-sparql-grammar.h
+++ b/src/libtracker-data/tracker-sparql-grammar.h
@@ -31,6 +31,7 @@ typedef enum {
NAMED_RULE_Prologue,
NAMED_RULE_BaseDecl,
NAMED_RULE_PrefixDecl,
+ NAMED_RULE_ConstraintDecl,
NAMED_RULE_SelectQuery,
NAMED_RULE_SubSelect,
NAMED_RULE_ConstructQuery,
@@ -191,6 +192,7 @@ typedef enum {
LITERAL_COLON,
LITERAL_CONCAT,
LITERAL_CONTAINS,
+ LITERAL_CONSTRAINT,
LITERAL_COMMA,
LITERAL_CONSTRUCT,
LITERAL_COPY,
@@ -341,6 +343,7 @@ static const gchar literals[][N_LITERALS] = {
":", /* LITERAL_COLON */
"concat", /* LITERAL_CONCAT */
"contains", /* LITERAL_CONTAINS */
+ "constraint", /* LITERAL_CONSTRAINT */
",", /* LITERAL_COMMA */
"construct", /* LITERAL_CONSTRUCT */
"copy", /* LITERAL_COPY */
@@ -1498,14 +1501,26 @@ static const TrackerGrammarRule rule_SelectQuery[] = { R(SelectClause), GTE0(hel
*/
static const TrackerGrammarRule rule_PrefixDecl[] = { L(PREFIX), T(PNAME_NS), T(IRIREF), NIL };
+/* ConstraintDecl ::= 'CONSTRAINT' ( 'GRAPH' | 'SERVICE' ) ( IRIREF (',' IRIREF)* )?
+ *
+ * TRACKER EXTENSION
+ */
+static const TrackerGrammarRule helper_ConstraintDecl_or_1[] = { L(GRAPH), L(SERVICE), NIL };
+static const TrackerGrammarRule helper_ConstraintDecl_seq_1[] = { L(COMMA), T(IRIREF), NIL };
+static const TrackerGrammarRule helper_ConstraintDecl_gte0_1[] = { S(helper_ConstraintDecl_seq_1), NIL };
+static const TrackerGrammarRule helper_ConstraintDecl_opt_1[] = { T(IRIREF),
GTE0(helper_ConstraintDecl_gte0_1), NIL };
+static const TrackerGrammarRule rule_ConstraintDecl[] = { L(CONSTRAINT), OR(helper_ConstraintDecl_or_1),
OPT(helper_ConstraintDecl_opt_1), NIL };
/* BaseDecl ::= 'BASE' IRIREF
*/
static const TrackerGrammarRule rule_BaseDecl[] = { L(BASE), T(IRIREF), NIL };
-/* Prologue ::= ( BaseDecl | PrefixDecl )*
+/* Prologue ::= ( BaseDecl | PrefixDecl | ConstraintDecl )*
+ *
+ * TRACKER EXTENSION:
+ * ConstraintDecl entirely.
*/
-static const TrackerGrammarRule helper_Prologue_or[] = { R(BaseDecl), R(PrefixDecl), NIL };
+static const TrackerGrammarRule helper_Prologue_or[] = { R(BaseDecl), R(PrefixDecl), R(ConstraintDecl), NIL
};
static const TrackerGrammarRule helper_Prologue_gte0[] = { OR(helper_Prologue_or), NIL };
static const TrackerGrammarRule rule_Prologue[] = { GTE0 (helper_Prologue_gte0), NIL };
@@ -2144,6 +2159,7 @@ static const TrackerGrammarRule *named_rules[N_NAMED_RULES] = {
rule_Prologue,
rule_BaseDecl,
rule_PrefixDecl,
+ rule_ConstraintDecl,
rule_SelectQuery,
rule_SubSelect,
rule_ConstructQuery,
diff --git a/src/libtracker-data/tracker-sparql.c b/src/libtracker-data/tracker-sparql.c
index 1f3563ddc..5b3032870 100644
--- a/src/libtracker-data/tracker-sparql.c
+++ b/src/libtracker-data/tracker-sparql.c
@@ -2524,11 +2524,16 @@ translate_Prologue (TrackerSparql *sparql,
{
TrackerGrammarNamedRule rule;
- /* Prologue ::= ( BaseDecl | PrefixDecl )*
+ /* Prologue ::= ( BaseDecl | PrefixDecl | ConstraintDecl )*
+ *
+ * TRACKER EXTENSION:
+ * ConstraintDecl entirely.
*/
rule = _current_rule (sparql);
- while (rule == NAMED_RULE_BaseDecl || rule == NAMED_RULE_PrefixDecl) {
+ while (rule == NAMED_RULE_BaseDecl ||
+ rule == NAMED_RULE_PrefixDecl ||
+ rule == NAMED_RULE_ConstraintDecl) {
_call_rule (sparql, rule, error);
rule = _current_rule (sparql);
}
@@ -2576,6 +2581,77 @@ translate_PrefixDecl (TrackerSparql *sparql,
return TRUE;
}
+static void
+intersect_set (GPtrArray *array,
+ GPtrArray *set)
+{
+ const gchar *set_graph, *graph;
+ gint i = 0, j;
+ gboolean found;
+
+ while (i < array->len) {
+ graph = g_ptr_array_index (array, i);
+ found = FALSE;
+
+ for (j = 0; j < set->len; j++) {
+ set_graph = g_ptr_array_index (set, j);
+
+ if (g_strcmp0 (set_graph, graph) == 0) {
+ found = TRUE;
+ break;
+ }
+ }
+
+ if (found) {
+ i++;
+ } else {
+ g_ptr_array_remove_index_fast (array, i);
+ }
+ }
+}
+
+static gboolean
+translate_ConstraintDecl (TrackerSparql *sparql,
+ GError **error)
+{
+ GPtrArray **previous_set, *set;
+
+ /* ConstraintDecl ::= 'CONSTRAINT' ( 'GRAPH' | 'SERVICE' ) ( IRIREF (',' IRIREF)* )?
+ *
+ * TRACKER EXTENSION
+ */
+ _expect (sparql, RULE_TYPE_LITERAL, LITERAL_CONSTRAINT);
+
+ if (_accept (sparql, RULE_TYPE_LITERAL, LITERAL_GRAPH)) {
+ previous_set = &sparql->policy.graphs;
+ } else if (_accept (sparql, RULE_TYPE_LITERAL, LITERAL_SERVICE)) {
+ previous_set = &sparql->policy.services;
+ } else {
+ g_assert_not_reached ();
+ }
+
+ set = g_ptr_array_new_with_free_func (g_free);
+
+ while (_accept (sparql, RULE_TYPE_TERMINAL, TERMINAL_TYPE_IRIREF)) {
+ gchar *elem;
+
+ elem = _dup_last_string (sparql);
+ g_ptr_array_add (set, elem);
+
+ if (!_accept (sparql, RULE_TYPE_LITERAL, LITERAL_COMMA))
+ break;
+ }
+
+ if (*previous_set) {
+ intersect_set (*previous_set, set);
+ g_ptr_array_unref (set);
+ } else {
+ *previous_set = set;
+ }
+
+ return TRUE;
+}
+
static gboolean
_check_undefined_variables (TrackerSparql *sparql,
TrackerSelectContext *context,
@@ -8415,6 +8491,7 @@ const RuleTranslationFunc rule_translation_funcs[N_NAMED_RULES] = {
translate_Prologue,
translate_BaseDecl,
translate_PrefixDecl,
+ translate_ConstraintDecl,
translate_SelectQuery,
translate_SubSelect,
translate_ConstructQuery,
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]