Esempio n. 1
0
 /// <summary>
 /// Sets the Default Graph for the dataset.
 /// </summary>
 /// <param name="graphUri">Graph URI.</param>
 public virtual void SetDefaultGraph(Uri graphUri)
 {
     _dataset.SetDefaultGraph(graphUri);
 }
        /// <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();
            }
        }