/// <summary> /// Processes an INSERT command /// </summary> /// <param name="cmd">Insert Command</param> public void ProcessInsertCommand(InsertCommand cmd) { this.ProcessCommand(cmd); }
/// <summary> /// Processes an INSERT command /// </summary> /// <param name="cmd">Insert Command</param> /// <remarks> /// <para> /// <strong>Note:</strong> The underlying manager must implement the <see cref="IQueryableGenericIOManager">IQueryableGenericIOManager</see> interface in order for INSERT commands to be processed /// </para> /// </remarks> public void ProcessInsertCommand(InsertCommand cmd) { if (this._manager is IUpdateableGenericIOManager) { ((IUpdateableGenericIOManager)this._manager).Update(cmd.ToString()); } else { if (this._manager is IQueryableGenericIOManager) { //Check IO Behaviour //For a insert we either need the ability to Update Add Triples or to Overwrite Graphs //Firstly check behaviour persuant to default graph if applicable if (cmd.InsertPattern.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 CanUpdateAddTriples if ((this._manager.IOBehaviour & IOBehaviour.CanUpdateAddTriples) == 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.InsertPattern.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 CanUpdateAddTriples or OverwriteNamed if ((this._manager.IOBehaviour & IOBehaviour.CanUpdateAddTriples) == 0 && (this._manager.IOBehaviour & IOBehaviour.OverwriteNamed) == 0) throw new SparqlUpdateException("The underlying store does not support the required IO Behaviour to implement this command"); } //First build and make the query to get a Result Set String queryText = "SELECT * WHERE " + cmd.WherePattern.ToString(); SparqlQueryParser parser = new SparqlQueryParser(); SparqlQuery query = parser.ParseFromString(queryText); if (cmd.GraphUri != null && !cmd.UsingUris.Any()) query.AddDefaultGraph(cmd.GraphUri); foreach (Uri u in cmd.UsingUris) { query.AddDefaultGraph(u); } foreach (Uri u in cmd.UsingNamedUris) { query.AddNamedGraph(u); } Object results = ((IQueryableGenericIOManager)this._manager).Query(query.ToString()); if (results is SparqlResultSet) { //Now need to transform the Result Set back to a Multiset Multiset mset = new Multiset((SparqlResultSet)results); //Generate the Triples for each Solution List<Triple> insertedTriples = new List<Triple>(); Dictionary<String, List<Triple>> insertedGraphTriples = new Dictionary<string, List<Triple>>(); foreach (ISet s in mset.Sets) { List<Triple> tempInsertedTriples = new List<Triple>(); try { ConstructContext context = new ConstructContext(null, s, true); foreach (IConstructTriplePattern p in cmd.InsertPattern.TriplePatterns.OfType<IConstructTriplePattern>()) { try { tempInsertedTriples.Add(p.Construct(context)); } catch (RdfQueryException) { //If we get an error here then it means we couldn't construct a specific //triple so we continue anyway } } insertedTriples.AddRange(tempInsertedTriples); } catch (RdfQueryException) { //If we get an error here this means we couldn't construct for this solution so the //solution is ignore for this graph } //Triples from GRAPH clauses foreach (GraphPattern gp in cmd.InsertPattern.ChildGraphPatterns) { tempInsertedTriples.Clear(); try { String graphUri; switch (gp.GraphSpecifier.TokenType) { case Token.URI: graphUri = gp.GraphSpecifier.Value; break; case Token.VARIABLE: if (s.ContainsVariable(gp.GraphSpecifier.Value)) { INode temp = s[gp.GraphSpecifier.Value.Substring(1)]; if (temp == null) { //If the Variable is not bound then skip continue; } else if (temp.NodeType == NodeType.Uri) { graphUri = temp.ToSafeString(); } else { //If the Variable is not bound to a URI then skip continue; } } else { //If the Variable is not bound for this solution then skip continue; } break; default: //Any other Graph Specifier we have to ignore this solution continue; } if (!insertedGraphTriples.ContainsKey(graphUri)) insertedGraphTriples.Add(graphUri, new List<Triple>()); ConstructContext context = new ConstructContext(null, s, true); foreach (IConstructTriplePattern p in gp.TriplePatterns.OfType<IConstructTriplePattern>()) { try { tempInsertedTriples.Add(p.Construct(context)); } catch (RdfQueryException) { //If we get an error here then it means we couldn't construct a specific //triple so we continue anyway } } insertedGraphTriples[graphUri].AddRange(tempInsertedTriples); } catch (RdfQueryException) { //If we get an error here this means we couldn't construct for this solution so the //solution is ignore for this graph } } } //Now decide how to apply the update if (this._manager.UpdateSupported) { this._manager.UpdateGraph(cmd.GraphUri, insertedTriples, Enumerable.Empty<Triple>()); foreach (KeyValuePair<String, List<Triple>> graphInsertion in insertedGraphTriples) { this._manager.UpdateGraph(graphInsertion.Key, graphInsertion.Value, Enumerable.Empty<Triple>()); } } else { Graph g = new Graph(); this._manager.LoadGraph(g, cmd.GraphUri); g.Assert(insertedTriples); this._manager.SaveGraph(g); foreach (KeyValuePair<String, List<Triple>> graphInsertion in insertedGraphTriples) { g = new Graph(); this._manager.LoadGraph(g, graphInsertion.Key); g.Assert(graphInsertion.Value); this._manager.SaveGraph(g); } } } else { throw new SparqlUpdateException("Cannot evaluate an INSERT Command as the underlying Store failed to answer the query for the WHERE portion of the command as expected"); } } else { throw new NotSupportedException("INSERT commands are not supported by this Update Processor as the manager for the underlying Store does not provide Query capabilities which are necessary to process this command"); } } }
/// <summary> /// Processes an INSERT command /// </summary> /// <param name="cmd">Insert Command</param> public void ProcessInsertCommand(InsertCommand cmd) { this.ProcessInsertCommandInternal(cmd, this.GetContext()); }
/// <summary> /// Processes an INSERT command /// </summary> /// <param name="cmd">Insert Command</param> /// <param name="context">SPARQL Update Evaluation Context</param> protected virtual void ProcessInsertCommandInternal(InsertCommand cmd, SparqlUpdateEvaluationContext context) { cmd.Evaluate(context); }
private SparqlUpdateCommand TryParseInsertCommand(SparqlUpdateParserContext context, bool allowData) { List<Uri> usings = new List<Uri>(); List<Uri> usingNamed = new List<Uri>(); IToken next = context.Tokens.Dequeue(); if (allowData) { //We are allowed to have an INSERT DATA command here so check for it if (next.TokenType == Token.DATA) return this.TryParseInsertDataCommand(context); } else { if (next.TokenType == Token.DATA) throw ParserHelper.Error("The DATA keyword is not permitted here as this INSERT command forms part of a modification command", next); } //Get the Modification Template GraphPattern insertions = this.TryParseModifyTemplate(context); //Then we expect a WHERE keyword next = context.Tokens.Dequeue(); if (next.TokenType == Token.USING) { foreach (KeyValuePair<Uri, bool> kvp in this.TryParseUsingStatements(context)) { if (kvp.Value) { usingNamed.Add(kvp.Key); } else { usings.Add(kvp.Key); } } next = context.Tokens.Dequeue(); } if (next.TokenType != Token.WHERE) throw ParserHelper.Error("Unexpected Token '" + next.GetType().ToString() + "' encountered, expected a WHERE keyword as part of a INSERT command", next); //Now parse the WHERE pattern 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 where = context.QueryParser.TryParseGraphPattern(subContext, context.Tokens.LastTokenType != Token.LEFTCURLYBRACKET); //And finally return the command InsertCommand cmd = new InsertCommand(insertions, where); usings.ForEach(u => cmd.AddUsingUri(u)); usingNamed.ForEach(u => cmd.AddUsingNamedUri(u)); return cmd; }