Re: Restricting SPARQL update to a single named graph
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
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
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