Re: Restricting SPARQL update to a single named graph

2022-06-13 Thread Martynas Jusevičius
On Fri, Jun 10, 2022 at 5:13 PM Martynas Jusevičius
 wrote:
>
> On Tue, Jun 7, 2022 at 9:15 PM Andy Seaborne  wrote:
> >
> > On 07/06/2022 10:47, Martynas Jusevičius wrote:
> > > Hi,
> > >
> > > I have implemented PATCH method for the Graph Store Protocol:
> > > https://www.w3.org/TR/sparql11-http-rdf-update/#http-patch
> > >
> > > The PATCH is applied to a named graph. I am missing this bit however:
> > > " If a SPARQL 1.1 Update request is used as the RDF payload for a
> > > PATCH request that makes changes to more than one graph or the graph
> > > it modifies is not the one indicated, it would be prudent for the
> > > server to respond with a 422 Unprocessable Entity status."
> >
> > I read that in the context of GSP resource naming.
> >
> > ?graph=
> >
> > and so the update does not name a graph - it'll look like the default
> > graph in the update.
> >
> > So look for GRAPH in the update.
> >
> > > What would be the way to make sure that an update only affects a
> > > single specific graph?
> >
> > A dataset of one graph and no others. c.f. DatasetGraphOne but for a
> > single named graph and read-only dft graph.
> >
> > Or a dataset which yields read-only graphs except for the target graph.
> >
> > Or analyse the update - no GRAPH in templates if the target comes from
> > the URL.
>
> It seems that it's not so easy to check for GRAPH in the update after all...
>
> What is the way to "analyse the update - no GRAPH in templates" that
> you speak of? I need to check both DELETE and INSERT templates.
>
> I thought I had found a way:
>
>   updateRequest.getOperations().get(0).getDeleteAcc().getGraph()
>
> but it returns  for the following update,
> which probably means it doesn't do what I think it does:
>
> PREFIX  rdf:  
>
> WITH 
> INSERT {
>   GRAPH ?g {
>  rdf:_2  .
>   }
> }
> WHERE
>   { GRAPH ?g
>   { ?s  ?p  ?o }
>   }

I think I figured it out. In case anyone needs it:

public class PatchUpdateVisitor extends UpdateVisitorBase
{

private boolean containsNamedGraph = false;

@Override
public void visit(UpdateModify update)
{
update.getDeleteAcc().getQuads().forEach(quad ->
{
if (!quad.getGraph().equals(Quad.defaultGraphNodeGenerated))
containsNamedGraph = true;
});
update.getInsertAcc().getQuads().forEach(quad ->
{
if (!quad.getGraph().equals(Quad.defaultGraphNodeGenerated))
containsNamedGraph = true;
});
}

public boolean containsNamedGraph()
{
return containsNamedGraph;
}

}

>
> >
> > >
> > >
> > > Martynas
> > > atomgraph.com


Re: Restricting SPARQL update to a single named graph

2022-06-10 Thread Martynas Jusevičius
On Tue, Jun 7, 2022 at 9:15 PM Andy Seaborne  wrote:
>
> On 07/06/2022 10:47, Martynas Jusevičius wrote:
> > Hi,
> >
> > I have implemented PATCH method for the Graph Store Protocol:
> > https://www.w3.org/TR/sparql11-http-rdf-update/#http-patch
> >
> > The PATCH is applied to a named graph. I am missing this bit however:
> > " If a SPARQL 1.1 Update request is used as the RDF payload for a
> > PATCH request that makes changes to more than one graph or the graph
> > it modifies is not the one indicated, it would be prudent for the
> > server to respond with a 422 Unprocessable Entity status."
>
> I read that in the context of GSP resource naming.
>
> ?graph=
>
> and so the update does not name a graph - it'll look like the default
> graph in the update.
>
> So look for GRAPH in the update.
>
> > What would be the way to make sure that an update only affects a
> > single specific graph?
>
> A dataset of one graph and no others. c.f. DatasetGraphOne but for a
> single named graph and read-only dft graph.
>
> Or a dataset which yields read-only graphs except for the target graph.
>
> Or analyse the update - no GRAPH in templates if the target comes from
> the URL.

It seems that it's not so easy to check for GRAPH in the update after all...

What is the way to "analyse the update - no GRAPH in templates" that
you speak of? I need to check both DELETE and INSERT templates.

I thought I had found a way:

  updateRequest.getOperations().get(0).getDeleteAcc().getGraph()

but it returns  for the following update,
which probably means it doesn't do what I think it does:

PREFIX  rdf:  

WITH 
INSERT {
  GRAPH ?g {
 rdf:_2  .
  }
}
WHERE
  { GRAPH ?g
  { ?s  ?p  ?o }
  }

>
> >
> >
> > Martynas
> > atomgraph.com


Re: Restricting SPARQL update to a single named graph

2022-06-09 Thread Martynas Jusevičius
That was a naive implementation... This one based on regex is somewhat
more robust:
https://github.com/AtomGraph/LinkedDataHub/blob/develop/src/main/java/com/atomgraph/linkeddatahub/server/model/impl/GraphStoreImpl.java#L322

If anyone has examples of how to do a similar thing without string
manipulation, that would be appreciated.

On Thu, Jun 9, 2022 at 12:21 PM Martynas Jusevičius
 wrote:
>
> On Thu, Jun 9, 2022 at 11:03 AM Martynas Jusevičius
>  wrote:
> >
> > On Wed, Jun 8, 2022 at 12:22 PM Andy Seaborne  wrote:
> > >
> > >
> > >
> > > On 08/06/2022 09:22, Martynas Jusevičius wrote:
> > > > On Tue, Jun 7, 2022 at 9:15 PM Andy Seaborne  wrote:
> > > >>
> > > >> On 07/06/2022 10:47, Martynas Jusevičius wrote:
> > > >>> Hi,
> > > >>>
> > > >>> I have implemented PATCH method for the Graph Store Protocol:
> > > >>> https://www.w3.org/TR/sparql11-http-rdf-update/#http-patch
> > > >>>
> > > >>> The PATCH is applied to a named graph. I am missing this bit however:
> > > >>> " If a SPARQL 1.1 Update request is used as the RDF payload for a
> > > >>> PATCH request that makes changes to more than one graph or the graph
> > > >>> it modifies is not the one indicated, it would be prudent for the
> > > >>> server to respond with a 422 Unprocessable Entity status."
> > > >>
> > > >> I read that in the context of GSP resource naming.
> > > >>
> > > >> ?graph=
> > > >>
> > > >> and so the update does not name a graph - it'll look like the default
> > > >> graph in the update.
> > > >>
> > > >> So look for GRAPH in the update.
> > > >
> > > > Thanks, that makes sense. GRAPH is also easy to check.
> > > >
> > > > But then I need to forward the update to a triplestore that does not
> > > > support PATCH.
> > >
> > > It's the GSP naming that matters.
> > >
> > > > Which means I would need to wrap INSERT/DELETE/WHERE templates into
> > > > GRAPH  { }.
> > >
> > > WITH  DELETE {} INSERT {} WHERE {}
> > >
> > > Also: USING. And protocol.
> >
> > Thanks, forgot about those. I could definitely use WITH.
> >
> > And re. SPARQL protocol, would ?using-named-graph-uri=uri have the
> > same effect as WITH  in this case?
>
> I realized ?using-named-graph-uri=uri would restrict the dataset but
> still require GRAPH  in the update string.
>
> WITH  on the other hand does what I need. I add it by string
> manipulation -- the current code is ugly but seems to do the job:
>
> String updateString = updateRequest.toString();
> // append WITH  before DELETE or INSERT
> if (updateString.toUpperCase().contains("DELETE"))
>updateString = updateString.replaceAll("(?i)" +
> Pattern.quote("DELETE"), "WITH <" + graphUri + ">\nDELETE");
> else
> {
> if (updateString.toUpperCase().contains("INSERT"))
> updateString = updateString.replaceAll("(?i)" +
> Pattern.quote("INSERT"), "WITH <" + graphUri + ">\nINSERT");
> else throw new BadRequestException("SPARQL update contains
> no DELETE or INSERT?"); // cannot happen
> }
> updateRequest = UpdateFactory.create(updateString);
>
> >
> > >
> > > > Is there some builder code that can help with that?
> > >
> > > Have you looked at UpdateBuilder?
> > >
> >
> > I looked at the Javadoc, it seems quite complicated. I'll see if I can
> > avoid modifying the update string.
> >
> >
> > > >
> > > >>
> > > >>> What would be the way to make sure that an update only affects a
> > > >>> single specific graph?
> > > >>
> > > >> A dataset of one graph and no others. c.f. DatasetGraphOne but for a
> > > >> single named graph and read-only dft graph.
> > > >>
> > > >> Or a dataset which yields read-only graphs except for the target graph.
> > > >>
> > > >> Or analyse the update - no GRAPH in templates if the target comes from
> > > >> the URL.
> > > >>
> > > >>>
> > > >>>
> > > >>> Martynas
> > > >>> atomgraph.com


Re: Restricting SPARQL update to a single named graph

2022-06-09 Thread Martynas Jusevičius
On Thu, Jun 9, 2022 at 11:03 AM Martynas Jusevičius
 wrote:
>
> On Wed, Jun 8, 2022 at 12:22 PM Andy Seaborne  wrote:
> >
> >
> >
> > On 08/06/2022 09:22, Martynas Jusevičius wrote:
> > > On Tue, Jun 7, 2022 at 9:15 PM Andy Seaborne  wrote:
> > >>
> > >> On 07/06/2022 10:47, Martynas Jusevičius wrote:
> > >>> Hi,
> > >>>
> > >>> I have implemented PATCH method for the Graph Store Protocol:
> > >>> https://www.w3.org/TR/sparql11-http-rdf-update/#http-patch
> > >>>
> > >>> The PATCH is applied to a named graph. I am missing this bit however:
> > >>> " If a SPARQL 1.1 Update request is used as the RDF payload for a
> > >>> PATCH request that makes changes to more than one graph or the graph
> > >>> it modifies is not the one indicated, it would be prudent for the
> > >>> server to respond with a 422 Unprocessable Entity status."
> > >>
> > >> I read that in the context of GSP resource naming.
> > >>
> > >> ?graph=
> > >>
> > >> and so the update does not name a graph - it'll look like the default
> > >> graph in the update.
> > >>
> > >> So look for GRAPH in the update.
> > >
> > > Thanks, that makes sense. GRAPH is also easy to check.
> > >
> > > But then I need to forward the update to a triplestore that does not
> > > support PATCH.
> >
> > It's the GSP naming that matters.
> >
> > > Which means I would need to wrap INSERT/DELETE/WHERE templates into
> > > GRAPH  { }.
> >
> > WITH  DELETE {} INSERT {} WHERE {}
> >
> > Also: USING. And protocol.
>
> Thanks, forgot about those. I could definitely use WITH.
>
> And re. SPARQL protocol, would ?using-named-graph-uri=uri have the
> same effect as WITH  in this case?

I realized ?using-named-graph-uri=uri would restrict the dataset but
still require GRAPH  in the update string.

WITH  on the other hand does what I need. I add it by string
manipulation -- the current code is ugly but seems to do the job:

String updateString = updateRequest.toString();
// append WITH  before DELETE or INSERT
if (updateString.toUpperCase().contains("DELETE"))
   updateString = updateString.replaceAll("(?i)" +
Pattern.quote("DELETE"), "WITH <" + graphUri + ">\nDELETE");
else
{
if (updateString.toUpperCase().contains("INSERT"))
updateString = updateString.replaceAll("(?i)" +
Pattern.quote("INSERT"), "WITH <" + graphUri + ">\nINSERT");
else throw new BadRequestException("SPARQL update contains
no DELETE or INSERT?"); // cannot happen
}
updateRequest = UpdateFactory.create(updateString);

>
> >
> > > Is there some builder code that can help with that?
> >
> > Have you looked at UpdateBuilder?
> >
>
> I looked at the Javadoc, it seems quite complicated. I'll see if I can
> avoid modifying the update string.
>
>
> > >
> > >>
> > >>> What would be the way to make sure that an update only affects a
> > >>> single specific graph?
> > >>
> > >> A dataset of one graph and no others. c.f. DatasetGraphOne but for a
> > >> single named graph and read-only dft graph.
> > >>
> > >> Or a dataset which yields read-only graphs except for the target graph.
> > >>
> > >> Or analyse the update - no GRAPH in templates if the target comes from
> > >> the URL.
> > >>
> > >>>
> > >>>
> > >>> Martynas
> > >>> atomgraph.com


Re: Restricting SPARQL update to a single named graph

2022-06-09 Thread Martynas Jusevičius
On Wed, Jun 8, 2022 at 12:22 PM Andy Seaborne  wrote:
>
>
>
> On 08/06/2022 09:22, Martynas Jusevičius wrote:
> > On Tue, Jun 7, 2022 at 9:15 PM Andy Seaborne  wrote:
> >>
> >> On 07/06/2022 10:47, Martynas Jusevičius wrote:
> >>> Hi,
> >>>
> >>> I have implemented PATCH method for the Graph Store Protocol:
> >>> https://www.w3.org/TR/sparql11-http-rdf-update/#http-patch
> >>>
> >>> The PATCH is applied to a named graph. I am missing this bit however:
> >>> " If a SPARQL 1.1 Update request is used as the RDF payload for a
> >>> PATCH request that makes changes to more than one graph or the graph
> >>> it modifies is not the one indicated, it would be prudent for the
> >>> server to respond with a 422 Unprocessable Entity status."
> >>
> >> I read that in the context of GSP resource naming.
> >>
> >> ?graph=
> >>
> >> and so the update does not name a graph - it'll look like the default
> >> graph in the update.
> >>
> >> So look for GRAPH in the update.
> >
> > Thanks, that makes sense. GRAPH is also easy to check.
> >
> > But then I need to forward the update to a triplestore that does not
> > support PATCH.
>
> It's the GSP naming that matters.
>
> > Which means I would need to wrap INSERT/DELETE/WHERE templates into
> > GRAPH  { }.
>
> WITH  DELETE {} INSERT {} WHERE {}
>
> Also: USING. And protocol.

Thanks, forgot about those. I could definitely use WITH.

And re. SPARQL protocol, would ?using-named-graph-uri=uri have the
same effect as WITH  in this case?

>
> > Is there some builder code that can help with that?
>
> Have you looked at UpdateBuilder?
>

I looked at the Javadoc, it seems quite complicated. I'll see if I can
avoid modifying the update string.


> >
> >>
> >>> What would be the way to make sure that an update only affects a
> >>> single specific graph?
> >>
> >> A dataset of one graph and no others. c.f. DatasetGraphOne but for a
> >> single named graph and read-only dft graph.
> >>
> >> Or a dataset which yields read-only graphs except for the target graph.
> >>
> >> Or analyse the update - no GRAPH in templates if the target comes from
> >> the URL.
> >>
> >>>
> >>>
> >>> Martynas
> >>> atomgraph.com


Re: Restricting SPARQL update to a single named graph

2022-06-08 Thread Andy Seaborne




On 08/06/2022 09:22, Martynas Jusevičius wrote:

On Tue, Jun 7, 2022 at 9:15 PM Andy Seaborne  wrote:


On 07/06/2022 10:47, Martynas Jusevičius wrote:

Hi,

I have implemented PATCH method for the Graph Store Protocol:
https://www.w3.org/TR/sparql11-http-rdf-update/#http-patch

The PATCH is applied to a named graph. I am missing this bit however:
" If a SPARQL 1.1 Update request is used as the RDF payload for a
PATCH request that makes changes to more than one graph or the graph
it modifies is not the one indicated, it would be prudent for the
server to respond with a 422 Unprocessable Entity status."


I read that in the context of GSP resource naming.

?graph=

and so the update does not name a graph - it'll look like the default
graph in the update.

So look for GRAPH in the update.


Thanks, that makes sense. GRAPH is also easy to check.

But then I need to forward the update to a triplestore that does not
support PATCH.


It's the GSP naming that matters.


Which means I would need to wrap INSERT/DELETE/WHERE templates into
GRAPH  { }.


WITH  DELETE {} INSERT {} WHERE {}

Also: USING. And protocol.


Is there some builder code that can help with that?


Have you looked at UpdateBuilder?






What would be the way to make sure that an update only affects a
single specific graph?


A dataset of one graph and no others. c.f. DatasetGraphOne but for a
single named graph and read-only dft graph.

Or a dataset which yields read-only graphs except for the target graph.

Or analyse the update - no GRAPH in templates if the target comes from
the URL.




Martynas
atomgraph.com


Re: Restricting SPARQL update to a single named graph

2022-06-08 Thread Martynas Jusevičius
On Tue, Jun 7, 2022 at 9:15 PM Andy Seaborne  wrote:
>
> On 07/06/2022 10:47, Martynas Jusevičius wrote:
> > Hi,
> >
> > I have implemented PATCH method for the Graph Store Protocol:
> > https://www.w3.org/TR/sparql11-http-rdf-update/#http-patch
> >
> > The PATCH is applied to a named graph. I am missing this bit however:
> > " If a SPARQL 1.1 Update request is used as the RDF payload for a
> > PATCH request that makes changes to more than one graph or the graph
> > it modifies is not the one indicated, it would be prudent for the
> > server to respond with a 422 Unprocessable Entity status."
>
> I read that in the context of GSP resource naming.
>
> ?graph=
>
> and so the update does not name a graph - it'll look like the default
> graph in the update.
>
> So look for GRAPH in the update.

Thanks, that makes sense. GRAPH is also easy to check.

But then I need to forward the update to a triplestore that does not
support PATCH.
Which means I would need to wrap INSERT/DELETE/WHERE templates into
GRAPH  { }.
Is there some builder code that can help with that?

>
> > What would be the way to make sure that an update only affects a
> > single specific graph?
>
> A dataset of one graph and no others. c.f. DatasetGraphOne but for a
> single named graph and read-only dft graph.
>
> Or a dataset which yields read-only graphs except for the target graph.
>
> Or analyse the update - no GRAPH in templates if the target comes from
> the URL.
>
> >
> >
> > Martynas
> > atomgraph.com


Re: Restricting SPARQL update to a single named graph

2022-06-07 Thread Andy Seaborne
On 07/06/2022 10:47, Martynas Jusevičius wrote:
> Hi,
>
> I have implemented PATCH method for the Graph Store Protocol:
> https://www.w3.org/TR/sparql11-http-rdf-update/#http-patch
>
> The PATCH is applied to a named graph. I am missing this bit however:
> " If a SPARQL 1.1 Update request is used as the RDF payload for a
> PATCH request that makes changes to more than one graph or the graph
> it modifies is not the one indicated, it would be prudent for the
> server to respond with a 422 Unprocessable Entity status."

I read that in the context of GSP resource naming.

?graph=

and so the update does not name a graph - it'll look like the default
graph in the update.

So look for GRAPH in the update.

> What would be the way to make sure that an update only affects a
> single specific graph?

A dataset of one graph and no others. c.f. DatasetGraphOne but for a
single named graph and read-only dft graph.

Or a dataset which yields read-only graphs except for the target graph.

Or analyse the update - no GRAPH in templates if the target comes from
the URL.

>
>
> Martynas
> atomgraph.com


Restricting SPARQL update to a single named graph

2022-06-07 Thread Martynas Jusevičius
Hi,

I have implemented PATCH method for the Graph Store Protocol:
https://www.w3.org/TR/sparql11-http-rdf-update/#http-patch

The PATCH is applied to a named graph. I am missing this bit however:
" If a SPARQL 1.1 Update request is used as the RDF payload for a
PATCH request that makes changes to more than one graph or the graph
it modifies is not the one indicated, it would be prudent for the
server to respond with a 422 Unprocessable Entity status."

What would be the way to make sure that an update only affects a
single specific graph?


Martynas
atomgraph.com