/// <summary> /// Processes a DELETE DATA command /// </summary> /// <param name="cmd">DELETE Data Command</param> public void ProcessDeleteDataCommand(DeleteDataCommand cmd) { this.ProcessCommand(cmd); }
/// <summary> /// Processes a DELETE DATA command /// </summary> /// <param name="cmd">DELETE Data Command</param> public void ProcessDeleteDataCommand(DeleteDataCommand cmd) { if (this._manager is IUpdateableGenericIOManager) { ((IUpdateableGenericIOManager)this._manager).Update(cmd.ToString()); } else { //Check IO Behaviour //For a delete we either need the ability to Update Delete Triples or to Overwrite Graphs //Firstly check behaviour persuant to default graph if applicable if (cmd.DataPattern.TriplePatterns.OfType<IConstructTriplePattern>().Any()) { //Must support notion of default graph if ((this._manager.IOBehaviour & IOBehaviour.HasDefaultGraph) == 0) throw new SparqlUpdateException("The underlying store does not support the notion of an explicit unnamed Default Graph required to process this command"); //Must allow either OverwriteDefault or CanUpdateDeleteTriples if ((this._manager.IOBehaviour & IOBehaviour.CanUpdateDeleteTriples) == 0 && (this._manager.IOBehaviour & IOBehaviour.OverwriteDefault) == 0) throw new SparqlUpdateException("The underlying store does not support the required IO Behaviour to implement this command"); } //Then check behaviour persuant to named graphs if applicable if (cmd.DataPattern.HasChildGraphPatterns) { //Must support named graphs if ((this._manager.IOBehaviour & IOBehaviour.HasNamedGraphs) == 0) throw new SparqlUpdateException("The underlying store does not support the notion of named graphs required to process this command"); //Must allow either CanUpdateDeleteTriples or OverwriteNamed if ((this._manager.IOBehaviour & IOBehaviour.CanUpdateDeleteTriples) == 0 && (this._manager.IOBehaviour & IOBehaviour.OverwriteNamed) == 0) throw new SparqlUpdateException("The underlying store does not support the required IO Behaviour to implement this command"); } //Split the Pattern into the set of Graph Patterns List<GraphPattern> patterns = new List<GraphPattern>(); if (cmd.DataPattern.IsGraph) { patterns.Add(cmd.DataPattern); } else if (cmd.DataPattern.TriplePatterns.Count > 0 || cmd.DataPattern.HasChildGraphPatterns) { if (cmd.DataPattern.TriplePatterns.Count > 0) { patterns.Add(new GraphPattern()); cmd.DataPattern.TriplePatterns.ForEach(tp => patterns[0].AddTriplePattern(tp)); } cmd.DataPattern.ChildGraphPatterns.ForEach(gp => patterns.Add(gp)); } else { //If no Triple Patterns and No Child Graph Patterns nothing to do return; } foreach (GraphPattern pattern in patterns) { if (!this.IsValidDataPattern(pattern, false)) throw new SparqlUpdateException("Cannot evaluate a DELETE DATA command where any of the Triple Patterns are not concrete triples - variables are not permitted"); Uri graphUri = null; if (pattern.IsGraph) { switch (pattern.GraphSpecifier.TokenType) { case Token.QNAME: throw new NotSupportedException("Graph Specifiers as QNames for DELETE DATA Commands are not supported - please specify an absolute URI instead"); case Token.URI: graphUri = UriFactory.Create(pattern.GraphSpecifier.Value); break; default: throw new SparqlUpdateException("Cannot evaluate an DELETE DATA Command as the Graph Specifier is not a QName/URI"); } } Graph g = new Graph(); if (!this._manager.UpdateSupported) { //If the Graph to be deleted from is empty then can skip as will have no affect on the Graph this._manager.LoadGraph(g, graphUri); if (g.IsEmpty) continue; } //Note that if the Manager supports Triple Level updates we won't load the Graph //so we can't know whether it is empty or not and so can't skip the delete step //Delete the actual Triples INode subj, pred, obj; ConstructContext context = new ConstructContext(g, null, true); foreach (IConstructTriplePattern p in pattern.TriplePatterns.OfType<IConstructTriplePattern>()) { subj = p.Subject.Construct(context); pred = p.Predicate.Construct(context); obj = p.Object.Construct(context); if (!this._manager.UpdateSupported) { //If we don't support update then we'll have loaded the existing graph //so we'll use this to remove the relevant triples to get to the intended state of //the graph g.Retract(new Triple(subj, pred, obj)); } else { //If we do support update then we'll have an empty graph which we'll use to store //up the set of triples to be removed g.Assert(new Triple(subj, pred, obj)); } } if (this._manager.UpdateSupported) { this._manager.UpdateGraph(graphUri, Enumerable.Empty<Triple>(), g.Triples); } else { this._manager.SaveGraph(g); } } } }
/// <summary> /// Processes a DELETE DATA command /// </summary> /// <param name="cmd">DELETE Data Command</param> public void ProcessDeleteDataCommand(DeleteDataCommand cmd) { this.ProcessDeleteDataCommandInternal(cmd, this.GetContext()); }
/// <summary> /// Processes a DELETE DATA command /// </summary> /// <param name="cmd">Delete Data Command</param> /// <param name="context">SPARQL Update Evaluation Context</param> protected virtual void ProcessDeleteDataCommandInternal(DeleteDataCommand cmd, SparqlUpdateEvaluationContext context) { cmd.Evaluate(context); }
private SparqlUpdateCommand TryParseDeleteDataCommand(SparqlUpdateParserContext context) { DeleteDataCommand cmd; SparqlQueryParserContext subContext = new SparqlQueryParserContext(context.Tokens); subContext.Query.BaseUri = context.BaseUri; subContext.Query.NamespaceMap = context.NamespaceMap; subContext.ExpressionParser.NamespaceMap = context.NamespaceMap; subContext.ExpressionParser.ExpressionFactories = context.ExpressionFactories; subContext.ExpressionFactories = context.ExpressionFactories; GraphPattern gp = context.QueryParser.TryParseGraphPattern(subContext, context.Tokens.LastTokenType != Token.LEFTCURLYBRACKET); //Validate that the Graph Pattern is simple //Check it doesn't contain anything other than Triple Patterns or if it does it just contains a single GRAPH Pattern if (gp.IsFiltered) { throw new RdfParseException("A FILTER Clause cannot occur in a DELETE DATA Command"); } else if (gp.IsOptional) { throw new RdfParseException("An OPTIONAL Clause cannot occur in a DELETE DATA Command"); } else if (gp.IsUnion) { throw new RdfParseException("A UNION Clause cannot occur in a DELETE DATA Command"); } else if (gp.HasChildGraphPatterns) { if (!gp.ChildGraphPatterns.All(p => p.IsGraph || (!p.IsExists && !p.IsMinus && !p.IsNotExists && !p.IsOptional && !p.IsOptional && !p.IsService && !p.IsSubQuery && !p.IsUnion))) { throw new RdfParseException("A DELETE DATA Command may only contain a combination of Triple Patterns and GRAPH clauses"); } else if (gp.ChildGraphPatterns.Any(p => p.HasChildGraphPatterns)) { throw new RdfParseException("A DELETE DATA Command may not contain nested Graph Patterns"); } else if (gp.HasChildGraphPatterns && gp.TriplePatterns.Count > 0) { cmd = new DeleteDataCommand(gp); } else if (gp.ChildGraphPatterns.Count == 1 && gp.ChildGraphPatterns[0].IsGraph) { cmd = new DeleteDataCommand(gp.ChildGraphPatterns[0]); } else { throw new RdfParseException("Nested Graph Patterns cannot occur in a DELETE DATA Command"); } } else { //OK cmd = new DeleteDataCommand(gp); } return cmd; }