Looking back at the thread with Joshua Taylor on initial bindings and
update, I wonder if we could do with "proper" templates.
Manipulation of the algebra for query building does not work so well
remotely as the query is sent in syntax form. Having query templates in
SPARQL syntax with template parameters seems more natural.
(read "query or update" for "query" throughout).
ParameterizedSparqlString seems to do two things - correct me if I'm
wrong Rob - it's a sort of builder of queries (the .append(..) methods)
and also a bit like JDBC prepared statements (.setXYZ(...)). But it
does not know the syntax of the query or update. They are open to
injection [1] although that's fixable.
My suggestion is to have template queries, which are like, but not
identical, to JDBC prepared statements. A template query is a superset
of SPARQL. Template parameterization is via a new parse item, not a
legal SPARQL variable (e.g. ?{abc}). They must be replaced by a node
(which could be a real variable) to use them. There would
template.asQuery(..substitutions...).
An alternative was using SPARQL variables, requiring a query/update
template to declare the template variables and checking when converting
to a query or update. But, as below, there are a couple of points where
it is desirable to parameterize a template that in SPARQL do not allow
variables. If we're tweaking the syntax anyway, we might as well have
template variable syntax.
The reason for some checking is so you can't do "SELECT * { ?s ?p ?o }"
forgetting to replace ?s with a URI, for example.
== Query
LIMIT and OFFSET take fixed integers by syntax and ideally they would
parameters.
== Update
INSERT DATA / DELETE DATA restrict
It would be good to have template data updates. But the data part of
INSERT DATA explicitly forbids variables.
To this end, I have got the machinery for transforms of Element objects
(c.f. transforms on Ops) working. By working on the AST, injection is
harder because the template parameter must be a Node to go in the right
place in the AST.
Comments and thoughts?
Rob - does this relate to jena-jdbc in some way?
Andy
[1]
public static void injection() {
String str =
"PREFIX : <http://example/>\nINSERT DATA { <s> <p> ?var2 . }" ;
ParameterizedSparqlString pss = new ParameterizedSparqlString(str) ;
pss.setIri("var2",
"hello> } ; DROP ALL ; INSERT DATA { <s> <p> <goodbye"
) ;
String x = pss.toString() ;
System.out.println(x) ;
}