/// <summary> /// Sets the Active Graph for the dataset. /// </summary> /// <param name="graphUris">Graph URIs.</param> public virtual void SetActiveGraph(IEnumerable <Uri> graphUris) { _dataset.SetActiveGraph(graphUris); }
/// <summary> /// Processes a SPARQL Query sending the results to a RDF/SPARQL Results handler as appropriate. /// </summary> /// <param name="rdfHandler">RDF Handler.</param> /// <param name="resultsHandler">Results Handler.</param> /// <param name="query">SPARQL Query.</param> public void ProcessQuery(IRdfHandler rdfHandler, ISparqlResultsHandler resultsHandler, SparqlQuery query) { // Do Handler null checks before evaluating the query if (query == null) { throw new ArgumentNullException("query", "Cannot evaluate a null query"); } if (rdfHandler == null && (query.QueryType == SparqlQueryType.Construct || query.QueryType == SparqlQueryType.Describe || query.QueryType == SparqlQueryType.DescribeAll)) { throw new ArgumentNullException("rdfHandler", "Cannot use a null RDF Handler when the Query is a CONSTRUCT/DESCRIBE"); } if (resultsHandler == null && (query.QueryType == SparqlQueryType.Ask || SparqlSpecsHelper.IsSelectQuery(query.QueryType))) { throw new ArgumentNullException("resultsHandler", "Cannot use a null resultsHandler when the Query is an ASK/SELECT"); } // Handle the Thread Safety of the Query Evaluation ReaderWriterLockSlim currLock = (_dataset is IThreadSafeDataset) ? ((IThreadSafeDataset)_dataset).Lock : _lock; try { currLock.EnterReadLock(); // Reset Query Timers query.QueryExecutionTime = null; bool datasetOk = false, defGraphOk = false; try { // Set up the Default and Active Graphs if (query.DefaultGraphs.Any()) { // Call HasGraph() on each Default Graph but ignore the results, we just do this // in case a dataset has any kind of load on demand behaviour foreach (Uri defGraphUri in query.DefaultGraphs) { _dataset.HasGraph(defGraphUri); } _dataset.SetDefaultGraph(query.DefaultGraphs); defGraphOk = true; } else if (query.NamedGraphs.Any()) { // No FROM Clauses but one/more FROM NAMED means the Default Graph is the empty graph _dataset.SetDefaultGraph(Enumerable.Empty <Uri>()); } _dataset.SetActiveGraph(_dataset.DefaultGraphUris); datasetOk = true; // Convert to Algebra and execute the Query SparqlEvaluationContext context = GetContext(query); BaseMultiset result; try { context.StartExecution(); ISparqlAlgebra algebra = query.ToAlgebra(); result = context.Evaluate(algebra); context.EndExecution(); query.QueryExecutionTime = new TimeSpan(context.QueryTimeTicks); } catch (RdfQueryException) { context.EndExecution(); query.QueryExecutionTime = new TimeSpan(context.QueryTimeTicks); throw; } catch { context.EndExecution(); query.QueryExecutionTime = new TimeSpan(context.QueryTimeTicks); throw; } // Return the Results switch (query.QueryType) { case SparqlQueryType.Ask: case SparqlQueryType.Select: case SparqlQueryType.SelectAll: case SparqlQueryType.SelectAllDistinct: case SparqlQueryType.SelectAllReduced: case SparqlQueryType.SelectDistinct: case SparqlQueryType.SelectReduced: // For SELECT and ASK can populate a Result Set directly from the Evaluation Context // return new SparqlResultSet(context); resultsHandler.Apply(context); break; case SparqlQueryType.Construct: // Create a new Empty Graph for the Results try { rdfHandler.StartRdf(); foreach (String prefix in query.NamespaceMap.Prefixes) { if (!rdfHandler.HandleNamespace(prefix, query.NamespaceMap.GetNamespaceUri(prefix))) { ParserHelper.Stop(); } } // Construct the Triples for each Solution if (context.OutputMultiset is IdentityMultiset) { context.OutputMultiset = new SingletonMultiset(); } foreach (ISet s in context.OutputMultiset.Sets) { // List<Triple> constructedTriples = new List<Triple>(); try { ConstructContext constructContext = new ConstructContext(rdfHandler, s, false); foreach (IConstructTriplePattern p in query.ConstructTemplate.TriplePatterns.OfType <IConstructTriplePattern>()) { try { if (!rdfHandler.HandleTriple(p.Construct(constructContext))) { ParserHelper.Stop(); } // constructedTriples.Add(((IConstructTriplePattern)p).Construct(constructContext)); } catch (RdfQueryException) { // If we get an error here then we could not construct a specific triple // so we continue anyway } } } catch (RdfQueryException) { // If we get an error here this means we couldn't construct for this solution so the // entire solution is discarded continue; } // h.Assert(constructedTriples); } rdfHandler.EndRdf(true); } catch (RdfParsingTerminatedException) { rdfHandler.EndRdf(true); } catch { rdfHandler.EndRdf(false); throw; } break; case SparqlQueryType.Describe: case SparqlQueryType.DescribeAll: // For DESCRIBE we retrieve the Describe algorithm and apply it ISparqlDescribe describer = query.Describer; describer.Describe(rdfHandler, context); break; default: throw new RdfQueryException("Unknown query types cannot be processed by Leviathan"); } } finally { if (defGraphOk) { _dataset.ResetDefaultGraph(); } if (datasetOk) { _dataset.ResetActiveGraph(); } } } finally { currLock.ExitReadLock(); } }