Пример #1
0
        public void ProcessQuery(QueryDescriptorQueryNode query)
        {
            _sparqlModel = new SparqlModel();
            switch (query.Query.Kind)
            {
            case QueryNodeKind.EntitySet:
                ProcessNode(query.Query as EntitySetQueryNode);
                break;

            case QueryNodeKind.KeyLookup:
                ProcessRoot(query.Query as KeyLookupQueryNode);
                break;

            case QueryNodeKind.Filter:
                var entityType = (query.Query as FilterQueryNode).ItemType;
                var instances  = AssertInstancesVariable(entityType);
                _entitySetVariable = instances;
                ProcessFilter(query.Query as FilterQueryNode);
                _sparqlModel.AddSelectVariable(instances, entityType.FullName(), true);
                _sparqlModel.IsDescribe = true;
                break;

            case QueryNodeKind.Top:
            case QueryNodeKind.Skip:
                ProcessNode(query.Query);
                break;

            case QueryNodeKind.Segment:
                var navigation = query.Query as NavigationPropertyNode;
                var finalVar   = ProcessNode(navigation);
                _sparqlModel.AddSelectVariable(
                    finalVar.ToString(),
                    navigation.TypeReference.FullName(),
                    navigation.NavigationProperty.OwnMultiplicity() == EdmMultiplicity.Many);
                _sparqlModel.IsDescribe = true;
                break;

            default:
                throw new NotImplementedException("No processing implemented for " + query.Query.Kind);
            }

            // Apply page size limit
            if (!_sparqlModel.Limit.HasValue || _sparqlModel.Limit.Value > _maxPageSize)
            {
                _sparqlModel.OriginalLimit = _sparqlModel.Limit;
                _sparqlModel.Limit         = _maxPageSize;
            }
        }
Пример #2
0
        public void ProcessQuery(QueryDescriptorQueryNode query)
        {
            _sparqlModel = new SparqlModel();
            switch (query.Query.Kind)
            {
                case QueryNodeKind.EntitySet:
                    ProcessNode(query.Query as EntitySetQueryNode);
                    break;
                case QueryNodeKind.KeyLookup:
                    ProcessRoot(query.Query as KeyLookupQueryNode);
                    break;
                case QueryNodeKind.Filter:
                    var entityType = (query.Query as FilterQueryNode).ItemType;
                    var instances = AssertInstancesVariable(entityType);
                    _entitySetVariable = instances;
                    ProcessFilter(query.Query as FilterQueryNode);
                    _sparqlModel.AddSelectVariable(instances, entityType.FullName(), true);
                    _sparqlModel.IsDescribe = true;
                    break;
                case QueryNodeKind.Top:
                case QueryNodeKind.Skip:
                    ProcessNode(query.Query);
                    break;
                case QueryNodeKind.Segment:
                    var navigation = query.Query as NavigationPropertyNode;
                    var finalVar = ProcessNode(navigation);
                    _sparqlModel.AddSelectVariable(
                        finalVar.ToString(), 
                        navigation.TypeReference.FullName(),
                        navigation.NavigationProperty.OwnMultiplicity() == EdmMultiplicity.Many);
                    _sparqlModel.IsDescribe = true;
                    break;
                default:
                    throw new NotImplementedException("No processing implemented for " + query.Query.Kind);
            }

            // Apply page size limit
            if (!_sparqlModel.Limit.HasValue || _sparqlModel.Limit.Value > _maxPageSize)
            {
                _sparqlModel.OriginalLimit = _sparqlModel.Limit;
                _sparqlModel.Limit = _maxPageSize;
            }
        }
Пример #3
0
 private Uri GetNextPageLink(SparqlModel originalQueryModel)
 {
     if (!originalQueryModel.Limit.HasValue)
     {
         // No limit in the original query so there should be no next page
         return(null);
     }
     if (!originalQueryModel.OriginalLimit.HasValue ||
         originalQueryModel.OriginalLimit.Value > originalQueryModel.Limit.Value)
     {
         // We need a next page link
         var thisPageLink  = _request.Url.ToString();
         var queryParams   = System.Web.HttpUtility.ParseQueryString(_request.Url.Query);
         int nextPageStart = originalQueryModel.Offset.HasValue
                                    ? originalQueryModel.Offset.Value + originalQueryModel.Limit.Value
                                    : originalQueryModel.Limit.Value;
         queryParams["$skip"] = nextPageStart.ToString(CultureInfo.InvariantCulture);
         string updatedQuery = "?" + String.Join("&",
                                                 queryParams.AllKeys.Select(
                                                     k => String.Format("{0}={1}", k, queryParams[k])));
         return(new Uri(_request.Url, updatedQuery));
     }
     return(null);
 }
Пример #4
0
        /// <summary>
        /// Creates an OData feed response containing a list of entries for a particular type of entity
        /// </summary>
        /// <param name="resultsGraph">The RDF graph containing the SPARQL results</param>
        /// <param name="entityType">The fully qualified domain name for the type of entity to be written</param>
        /// <param name="resultsCount">The count of the total number of results that the server can provide</param>
        /// <param name="originalQueryModel">The SPARQL query that was executed to generate this graph</param>
        public void CreateFeedFromGraph(IGraph resultsGraph, string entityType, int resultsCount, SparqlModel originalQueryModel = null)
        {
            var msgWriter = new ODataMessageWriter(_response, _writerSettings, _map.Model);
            var feedWriter = msgWriter.CreateODataFeedWriter();
            var entries = new List<ODataEntry>();

            var typeUri = _map.GetUriForType(entityType);
            if (!String.IsNullOrEmpty(typeUri))
            {
                var predNode = resultsGraph.CreateUriNode(UriFactory.Create(RdfConstants.RdfType));
                var objNode = resultsGraph.CreateUriNode(UriFactory.Create(typeUri));
                if (originalQueryModel == null || originalQueryModel.Ordering == null)
                {
                    // No sorting required, just iterate all instances
                    foreach (var instanceTriple in resultsGraph.GetTriplesWithPredicateObject(predNode, objNode))
                    {
                        var instanceUri = (instanceTriple.Subject as IUriNode).Uri;
                        entries.Add(CreateODataEntry(resultsGraph, instanceUri.ToString(), entityType));
                    }
                }
                else
                {
                    // We need to apply the same sort criteria to this graph to ensure
                    // that the ODATA results are properly sorted.
                    // NOTE: This will only work if all the properties used in the original query
                    // are present in the graph - this could be a problem with more complex traversals
                    // and the query may instead need to be rewritten / regenerated to extract only
                    // the required sort properties.
                    originalQueryModel.IsDescribe = false;
                    var resultsTable =
                        resultsGraph.ExecuteQuery(originalQueryModel.GetSparqlRepresentation()) as SparqlResultSet;
                    var targetVariable= originalQueryModel.SelectVariables[0];
                    foreach (var result in resultsTable.Results)
                    {
                        var instanceUriNode = result[targetVariable] as IUriNode;
                        if (instanceUriNode != null)
                        {
                            entries.Add(CreateODataEntry(resultsGraph, instanceUriNode.Uri.ToString(), entityType));
                        }
                    }
                }
            }

            var feed = new ODataFeed {Id = _baseUri + _map.GetTypeSet(entityType)};
            if (_writerSettings.Version >= ODataVersion.V2)
            {
                feed.Count = resultsCount;
            }
            if (originalQueryModel != null)
            {
                feed.NextPageLink = GetNextPageLink(originalQueryModel);
            }
            feedWriter.WriteStart(feed);
            foreach (var entry in entries)
            {
                feedWriter.WriteStart(entry);
                feedWriter.WriteEnd();
            }
            feedWriter.WriteEnd();
            feedWriter.Flush();
        }
Пример #5
0
 private Uri GetNextPageLink(SparqlModel originalQueryModel)
 {
     if (!originalQueryModel.Limit.HasValue)
     {
         // No limit in the original query so there should be no next page
         return null;
     }
     if (!originalQueryModel.OriginalLimit.HasValue ||
         originalQueryModel.OriginalLimit.Value > originalQueryModel.Limit.Value)
     {
         // We need a next page link
         var thisPageLink = _request.Url.ToString();
         var queryParams = System.Web.HttpUtility.ParseQueryString(_request.Url.Query);
         int nextPageStart = originalQueryModel.Offset.HasValue
                                    ? originalQueryModel.Offset.Value + originalQueryModel.Limit.Value
                                    : originalQueryModel.Limit.Value;
         queryParams["$skip"] = nextPageStart.ToString(CultureInfo.InvariantCulture);
         string updatedQuery = "?" + String.Join("&",
                                           queryParams.AllKeys.Select(
                                               k => String.Format("{0}={1}", k, queryParams[k])));
         return new Uri(_request.Url, updatedQuery);
     }
     return null;
 }
Пример #6
0
        /// <summary>
        /// Creates an OData feed response containing a list of entries for a particular type of entity
        /// </summary>
        /// <param name="resultsGraph">The RDF graph containing the SPARQL results</param>
        /// <param name="entityType">The fully qualified domain name for the type of entity to be written</param>
        /// <param name="resultsCount">The count of the total number of results that the server can provide</param>
        /// <param name="originalQueryModel">The SPARQL query that was executed to generate this graph</param>
        public void CreateFeedFromGraph(IGraph resultsGraph, string entityType, int resultsCount, SparqlModel originalQueryModel = null)
        {
            var msgWriter  = new ODataMessageWriter(_response, _writerSettings, _map.Model);
            var feedWriter = msgWriter.CreateODataFeedWriter();
            var entries    = new List <ODataEntry>();

            var typeUri = _map.GetUriForType(entityType);

            if (!String.IsNullOrEmpty(typeUri))
            {
                var predNode = resultsGraph.CreateUriNode(UriFactory.Create(RdfConstants.RdfType));
                var objNode  = resultsGraph.CreateUriNode(UriFactory.Create(typeUri));
                if (originalQueryModel == null || originalQueryModel.Ordering == null)
                {
                    // No sorting required, just iterate all instances
                    foreach (var instanceTriple in resultsGraph.GetTriplesWithPredicateObject(predNode, objNode))
                    {
                        var instanceUri = (instanceTriple.Subject as IUriNode).Uri;
                        entries.Add(CreateODataEntry(resultsGraph, instanceUri.ToString(), entityType));
                    }
                }
                else
                {
                    // We need to apply the same sort criteria to this graph to ensure
                    // that the ODATA results are properly sorted.
                    // NOTE: This will only work if all the properties used in the original query
                    // are present in the graph - this could be a problem with more complex traversals
                    // and the query may instead need to be rewritten / regenerated to extract only
                    // the required sort properties.
                    originalQueryModel.IsDescribe = false;
                    var resultsTable =
                        resultsGraph.ExecuteQuery(originalQueryModel.GetSparqlRepresentation()) as SparqlResultSet;
                    var targetVariable = originalQueryModel.SelectVariables[0];
                    foreach (var result in resultsTable.Results)
                    {
                        var instanceUriNode = result[targetVariable] as IUriNode;
                        if (instanceUriNode != null)
                        {
                            entries.Add(CreateODataEntry(resultsGraph, instanceUriNode.Uri.ToString(), entityType));
                        }
                    }
                }
            }

            var feed = new ODataFeed {
                Id = _baseUri + _map.GetTypeSet(entityType)
            };

            if (_writerSettings.Version >= ODataVersion.V2)
            {
                feed.Count = resultsCount;
            }
            if (originalQueryModel != null)
            {
                feed.NextPageLink = GetNextPageLink(originalQueryModel);
            }
            feedWriter.WriteStart(feed);
            foreach (var entry in entries)
            {
                feedWriter.WriteStart(entry);
                feedWriter.WriteEnd();
            }
            feedWriter.WriteEnd();
            feedWriter.Flush();
        }