On Mon, Feb 25, 2013 at 4:58 PM, Joshua TAYLOR <[email protected]> wrote:
> On Mon, Feb 25, 2013 at 4:32 PM, Andy Seaborne <[email protected]> wrote:
>> On 25/02/13 20:14, Joshua TAYLOR wrote:
>>>
>>> On Mon, Feb 25, 2013 at 2:15 PM, Joshua TAYLOR <[email protected]>
>>> wrote:
>>>>
>>>> On Mon, Feb 25, 2013 at 1:43 PM, Joshua TAYLOR <[email protected]>
>>>> wrote:
>>>>>
>>>>> On Mon, Feb 25, 2013 at 11:42 AM, Joshua TAYLOR <[email protected]>
>>>>> wrote:
>>>>>>
>>>>>> I'm looking at upgrading a project to use the new 2.10.0 release, and
>>>>>> things are coming along nicely so far (some possible hitches in some
>>>>>> writing code, but can't run tests until I can build...).  I've got a
>>>>>> bunch of cases of
>>>>>>
>>>>>> UpdateAction.execute(request, getModel(), binding);
>>>>>>
>>>>>> that don't compile, though;  according to the release notes [1],
>>>>>> "SPARQL Update execution no longer supports setting an initial
>>>>>> binding".  I'm going to keep looking for the new way to do this, but
>>>>>> in case someone's got the quick answer prepared, and so that the list
>>>>>> has a recorded answer, I figured I'd ask sooner rather than later:
>>>>>> how can initial bindings be specified in Jena 2.10.0?
>>>>>>
>>>>>> [1]
>>>>>> http://svn.apache.org/repos/asf/jena/trunk/jena-arq/ReleaseNotes.txt
>>>>>
>>>>>
>>>>> After some lunch, and some searching, I've found discussion on the dev
>>>>> list about removing initial bindings [1] and that the accepted way to
>>>>> do this now is to use BIND or VALUES.   In our project, we've
>>>>> implemented a number of EnhancedResources that perform graph updates
>>>>> using an idiom where some SPARQL text refers to a ?this variable, and
>>>>> the execution uses a binding that binds ?this to the enhanced resource
>>>>> (which might not have a URI).   We'd much prefer to do the graph
>>>>> modification via SPARQL because it involves a number of operations,
>>>>> and we'd like to be able to use anonymous resources.  Here's a typical
>>>>> example:
>>>>>
>>>>>          static private final UpdateRequest setSomePropertyRequest =
>>>>> UpdateFactory.create(
>>>>>                  "DELETE {\n"+
>>>>>                   .... SPARQL code that uses variable ?this ...
>>>>>                  "} INSERT {\n"+
>>>>>                  "} WHERE {"+
>>>>>                     ...
>>>>>                  "}"
>>>>>          );
>>>>>
>>>>>          public Invocation setSomeProperty( Value value ) {
>>>>>                          final QuerySolutionMap binding = new
>>>>> QuerySolutionMap();
>>>>>                          binding.add("?this", this );
>>>>>                          UpdateAction.execute( setSomePropertyRequest,
>>>>> getModel(), binding);
>>>>>                  }
>>>>>                  return this;
>>>>>          }
>>>>>
>>>>> Is there still a way to do something like this?  If it will involve
>>>>> using VALUES or BIND, is there a way to make it work with blank nodes?
>>>>>
>>>>> Thanks in advance,
>>>>> //JT
>>>>>
>>>>> [1]
>>>>> http://mail-archives.apache.org/mod_mbox/jena-dev/201302.mbox/%3CCAPTxtVNWT1HncCLom14cTF0WcjJ04pyP8ALes5Vb5yuSDv8DWw%40mail.gmail.com%3E
>>>>
>>>>
>>>> Sorry for so much noise, but I wonder if the following is a solution.
>>>> This does depend, of course, on the model against which the update is
>>>> run being on the same machine, and such.  If "this" has a URI, then I
>>>> can use the URI in the query, and if it's anonymous, then I can use
>>>> the Jena-specific-and-depending-on-local-data id.  Then I can use
>>>> request.add( "BIND ( ... as ?this )" ) to add the binding constraints
>>>> to the request.
>>>>
>>>>                          final UpdateRequest request =
>>>> UpdateFactory.create(); // ... more
>>>> query in real example
>>>>                          if ( this.isAnon() ) {
>>>>                                  request.add( "BIND (
>>>> <_:"+this.getId()+"> as ?thisInvocation )" );
>>>>                          }
>>>>                          else {
>>>>                                  request.add( "BIND (
>>>> <_:"+this.getURI()+"> as ?thisInvocation )" );
>>>>                          }
>>>>                          UpdateAction.execute( request, model ); //
>>>> executes with the
>>>> requested binding
>>>>
>>>> If this is a solution, it's easy enough to wrap cleanly in a util
>>>> method, and I'll be content with that.  Can anyone confirm or deny
>>>> that this is a solution?  (I'm hoping that I understand the
>>>> UpdateRequest#add( String ) method correctly.  The javadoc [1] is
>>>> empty, so I'm going on a guess...)
>>>>
>>>> //JT
>>>>
>>>> [1]
>>>> http://jena.apache.org/documentation/javadoc/arq/com/hp/hpl/jena/update/UpdateRequest.html#add(java.lang.String)
>>>
>>>
>>> Sorry for all the noise and self-replies, but this doesn't work.
>>> UpdateRequest#add doesn't do what I hoped it did.  Again, the issue
>>> is, what do we do instead of initial bindings in Jena 2.10.0.  We've
>>> been using a bunch of precompiled update requests, and had been able
>>> to provide initial bindings for them.  I understand that we should now
>>> be using BIND to introduce bindings, but this will still require some
>>> sort of parameterization  (which we did before using initial
>>> bindings).  Thoughts?
>>
>>
>> What about
>>
>>     ParameterizedSparqlString
>>     .asUpdate()
>
> This may very well be the answer.  One of the reasons that we'd been
> using UpdateRequests was a (hopefully not too mistaken?) attempt at
> "pre-compiling" the queries.  If we move to parameterized SPARQL
> strings, it seems like we'll be imposing a fair amount of overhead,
> since "this class does not in any way check that your command is
> syntactically correct until such time as you try and parse it as a
> Query or UpdateRequest" [1].  Then again, maybe the parsing is much
> quicker than running a query with initial bindings?  I haven't run
> tests yet to compare this.
>
> As an aside,  the docs for ParameterizedSPARQLString state "The
> intended usage of this is where using a QuerySolutionMap as initial
> bindings is either inappropriate or not possible."  If one is doing
> updates, are there any APIs that still support initial bindings?
>
>> The technical problem with initial bindings and SPARQL update is what do
>> they apply to - your examples are one SPARQL Update operation; in general, a
>> SPARQL Update request may be several operations.
>
> (I missed this part of your message at first reading;  some email
> clients (e.g., GMail) treat everything below the double hyphen as a
> signature.)  Ah, thanks.  I haven't done much SPARQL querying/updating
> in Jena in a while, and I'm coming into code that someone else wrote.
> I can see where this is a pretty useful way of combining remote
> queries.
>
> For the moment, I'll change things to use parameterized SPARQL
> strings.  Hopefully the much more frequent parsing won't be an issue
> (we're executing some of these queries very frequently, and always
> against local models).  If I run into problems, you can be sure I'll
> be back!
>
> As always, many thanks for the help, and a great platform,
> [1] 
> http://jena.apache.org/documentation/javadoc/arq/com/hp/hpl/jena/query/ParameterizedSparqlString.html

This is pretty close, but there's still a problem.  When a blanknode
is substituted into a ParameterizedSparqlString, it's replaced by
something like "_:b0" rather than the pseudo-form <_:blank-node-id>.
That's easy enough to get around;  I can use setIri and construct the
blank node's iri from "_:"+node.getId().  This means that I can get a
ParameterizedSparqlString that looks like the update that I want.
However, asUpdate() turns those pseudo-iris back into the blank nodes
like "_:b0".  Here's an example of this (code is set up as a JUnit
test):

public class ParameterizedSparqlStrings {
        @Test
        public void showResults() {
                OntModel model = ModelFactory.createOntologyModel( 
OntModelSpec.OWL_DL_MEM );
                Individual a = model.createIndividual( OWL.Thing );
                Individual b = model.createIndividual(
"http://example.org/individual";, OWL.Thing );
                String sparqlString = "INSERT {\n"+
                  "  ?aByNode a ?ignore . \n"+
                  "  ?aByIri  a ?ignore . \n"+
                  "  ?bByNode a ?ignore . \n"+
                  "  ?bByIri  a ?ignore . \n"+
                  "} WHERE {}";
                ParameterizedSparqlString pss = new ParameterizedSparqlString( 
sparqlString );

                pss.setParam( "?aByNode", a );
                pss.setIri( "?aByIri", "_:"+a.getId() );
                pss.setParam( "?bByNode", b );
                pss.setIri( "?bByIri", b.getURI() );
                
                System.out.println( "\n* Parameterized Sparql String with 
Ids:\n" + pss );
                System.out.println( "\n* Parameterized Sparql String as 
Update:\n" +
pss.asUpdate() );
        }
}

and here's the output:  (In the parameterized string, ?aByIRI is what
I'd like to have for the update, but it gets clobbered by asUpdate().)

* Parameterized Sparql String with Ids:
INSERT {
  _:b0 a ?ignore .
  <_:-570c0f1c:13d1389a5a3:-7ffc>  a ?ignore .
  <http://example.org/individual> a ?ignore .
  <http://example.org/individual>  a ?ignore .
} WHERE {}

* Parameterized Sparql String as Update:
INSERT {
  _:b0 <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> ?ignore .
  _:b1 <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> ?ignore .
  <http://example.org/individual>
<http://www.w3.org/1999/02/22-rdf-syntax-ns#type> ?ignore .
  <http://example.org/individual>
<http://www.w3.org/1999/02/22-rdf-syntax-ns#type> ?ignore .
}
WHERE
  {  }

Thoughts?
//JT

-- 
Joshua Taylor, http://www.cs.rpi.edu/~tayloj/

Reply via email to