Exemplo n.º 1
0
 /**
  * @param SegmentDescriptor[] $segmentDescriptors Description of segments in the resource path.
  * @param Url $requestUri
  * @param Version $serviceMaxVersion
  * @param $requestVersion
  * @param $maxRequestVersion
  */
 public function __construct($segmentDescriptors, Url $requestUri, Version $serviceMaxVersion, $requestVersion, $maxRequestVersion)
 {
     $this->segments = $segmentDescriptors;
     $this->_segmentCount = count($this->segments);
     $this->requestUrl = $requestUri;
     $this->lastSegment = $segmentDescriptors[$this->_segmentCount - 1];
     $this->queryType = QueryType::ENTITIES();
     //we use this for validation checks down in validateVersions...but maybe we should check that outside of this object...
     $this->maxServiceVersion = $serviceMaxVersion;
     //Per OData 1 & 2 spec we must return the smallest size
     //We start at 1.0 and move it up as features are requested
     $this->requiredMinResponseVersion = clone Version::v1();
     $this->requiredMinRequestVersion = clone Version::v1();
     //see http://www.odata.org/documentation/odata-v2-documentation/overview/#ProtocolVersioning
     //if requestVersion isn't there, use Service Max Version
     $this->requestVersion = is_null($requestVersion) ? $serviceMaxVersion : self::parseVersionHeader($requestVersion, ODataConstants::ODATAVERSIONHEADER);
     //if max version isn't there, use the request version
     $this->requestMaxVersion = is_null($maxRequestVersion) ? $this->requestVersion : self::parseVersionHeader($maxRequestVersion, ODataConstants::ODATAMAXVERSIONHEADER);
     //if it's OData v3..things change a bit
     if ($this->maxServiceVersion == Version::v3()) {
         if (is_null($maxRequestVersion)) {
             //if max request version isn't specified we use the service max version instead of the request version
             //thus we favour newer versions
             $this->requestMaxVersion = $this->maxServiceVersion;
         }
         //also we change min response version to be the max version, again favoring later things
         //note that if the request max version is specified, it is still respected
         $this->requiredMinResponseVersion = clone $this->requestMaxVersion;
     }
     $this->_containerName = null;
     $this->_skipCount = null;
     $this->_topCount = null;
     $this->_topOptionCount = null;
     $this->internalOrderByInfo = null;
     $this->_internalSkipTokenInfo = null;
     $this->_filterInfo = null;
     $this->_countValue = null;
     $this->_isExecuted = false;
 }
Exemplo n.º 2
0
 /**
  * Execute queries for expansion.
  * 
  * @param array(mixed)/mixed $result Resource(s) whose navigation properties needs to be expanded.
  *
  *
  * @return void
  */
 private function _executeExpansion($result)
 {
     $expandedProjectionNodes = $this->_getExpandedProjectionNodes();
     foreach ($expandedProjectionNodes as $expandedProjectionNode) {
         $isCollection = $expandedProjectionNode->getResourceProperty()->getKind() == ResourcePropertyKind::RESOURCESET_REFERENCE;
         $expandedPropertyName = $expandedProjectionNode->getResourceProperty()->getName();
         if (is_array($result)) {
             foreach ($result as $entry) {
                 // Check for null entry
                 if ($isCollection) {
                     $currentResourceSet = $this->_getCurrentResourceSetWrapper()->getResourceSet();
                     $resourceSetOfProjectedProperty = $expandedProjectionNode->getResourceSetWrapper()->getResourceSet();
                     $projectedProperty1 = $expandedProjectionNode->getResourceProperty();
                     $result1 = $this->providers->getRelatedResourceSet(QueryType::ENTITIES(), $currentResourceSet, $entry, $resourceSetOfProjectedProperty, $projectedProperty1, null, null, null, null)->results;
                     if (!empty($result1)) {
                         $internalOrderByInfo = $expandedProjectionNode->getInternalOrderByInfo();
                         if (!is_null($internalOrderByInfo)) {
                             $orderByFunction = $internalOrderByInfo->getSorterFunction()->getReference();
                             usort($result1, $orderByFunction);
                             unset($internalOrderByInfo);
                             $takeCount = $expandedProjectionNode->getTakeCount();
                             if (!is_null($takeCount)) {
                                 $result1 = array_slice($result1, 0, $takeCount);
                             }
                         }
                         $entry->{$expandedPropertyName} = $result1;
                         $projectedProperty = $expandedProjectionNode->getResourceProperty();
                         $needPop = $this->_pushSegmentForNavigationProperty($projectedProperty);
                         $this->_executeExpansion($result1);
                         $this->_popSegment($needPop);
                     } else {
                         $entry->{$expandedPropertyName} = array();
                     }
                 } else {
                     $currentResourceSet1 = $this->_getCurrentResourceSetWrapper()->getResourceSet();
                     $resourceSetOfProjectedProperty1 = $expandedProjectionNode->getResourceSetWrapper()->getResourceSet();
                     $projectedProperty2 = $expandedProjectionNode->getResourceProperty();
                     $result1 = $this->providers->getRelatedResourceReference($currentResourceSet1, $entry, $resourceSetOfProjectedProperty1, $projectedProperty2);
                     $entry->{$expandedPropertyName} = $result1;
                     if (!is_null($result1)) {
                         $projectedProperty3 = $expandedProjectionNode->getResourceProperty();
                         $needPop = $this->_pushSegmentForNavigationProperty($projectedProperty3);
                         $this->_executeExpansion($result1);
                         $this->_popSegment($needPop);
                     }
                 }
             }
         } else {
             if ($isCollection) {
                 $currentResourceSet2 = $this->_getCurrentResourceSetWrapper()->getResourceSet();
                 $resourceSetOfProjectedProperty2 = $expandedProjectionNode->getResourceSetWrapper()->getResourceSet();
                 $projectedProperty4 = $expandedProjectionNode->getResourceProperty();
                 $result1 = $this->providers->getRelatedResourceSet(QueryType::ENTITIES(), $currentResourceSet2, $result, $resourceSetOfProjectedProperty2, $projectedProperty4, null, null, null, null)->results;
                 if (!empty($result1)) {
                     $internalOrderByInfo = $expandedProjectionNode->getInternalOrderByInfo();
                     if (!is_null($internalOrderByInfo)) {
                         $orderByFunction = $internalOrderByInfo->getSorterFunction()->getReference();
                         usort($result1, $orderByFunction);
                         unset($internalOrderByInfo);
                         $takeCount = $expandedProjectionNode->getTakeCount();
                         if (!is_null($takeCount)) {
                             $result1 = array_slice($result1, 0, $takeCount);
                         }
                     }
                     $result->{$expandedPropertyName} = $result1;
                     $projectedProperty7 = $expandedProjectionNode->getResourceProperty();
                     $needPop = $this->_pushSegmentForNavigationProperty($projectedProperty7);
                     $this->_executeExpansion($result1);
                     $this->_popSegment($needPop);
                 } else {
                     $result->{$expandedPropertyName} = array();
                 }
             } else {
                 $currentResourceSet3 = $this->_getCurrentResourceSetWrapper()->getResourceSet();
                 $resourceSetOfProjectedProperty3 = $expandedProjectionNode->getResourceSetWrapper()->getResourceSet();
                 $projectedProperty5 = $expandedProjectionNode->getResourceProperty();
                 $result1 = $this->providers->getRelatedResourceReference($currentResourceSet3, $result, $resourceSetOfProjectedProperty3, $projectedProperty5);
                 $result->{$expandedPropertyName} = $result1;
                 if (!is_null($result1)) {
                     $projectedProperty6 = $expandedProjectionNode->getResourceProperty();
                     $needPop = $this->_pushSegmentForNavigationProperty($projectedProperty6);
                     $this->_executeExpansion($result1);
                     $this->_popSegment($needPop);
                 }
             }
         }
     }
 }
Exemplo n.º 3
0
 public function testGetRelatedResourceSetReturnsArrayWhenQueryTypeIsEntities()
 {
     $orderBy = null;
     $top = 10;
     $skip = 10;
     $fakeQueryResult = new QueryResult();
     $fakeQueryResult->count = 2;
     $fakeQueryResult->results = null;
     //null is not an array
     $fakeSourceEntity = new \stdClass();
     Phockito::when($this->mockQueryProvider->getRelatedResourceSet(QueryType::ENTITIES(), $this->mockResourceSet, $fakeSourceEntity, $this->mockResourceSet2, $this->mockResourceProperty, $this->mockFilterInfo, $orderBy, $top, $skip))->return($fakeQueryResult);
     $wrapper = $this->getMockedWrapper();
     try {
         $wrapper->getRelatedResourceSet(QueryType::ENTITIES(), $this->mockResourceSet, $fakeSourceEntity, $this->mockResourceSet2, $this->mockResourceProperty, $this->mockFilterInfo, $orderBy, $top, $skip);
         $this->fail("expected exception not thrown");
     } catch (ODataException $ex) {
         $this->assertEquals(Messages::queryProviderResultsMissing("IQueryProvider::getRelatedResourceSet", QueryType::ENTITIES()), $ex->getMessage());
         $this->assertEquals(500, $ex->getStatusCode());
     }
 }
Exemplo n.º 4
0
 /**
  * For queries like http://localhost/NorthWind.svc/Customers
  */
 public function getResourceSet(QueryType $queryType, ResourceSet $resourceSet, $filterInfo = null, $orderBy = null, $top = null, $skip = null)
 {
     $result = new QueryResult();
     $entityClassName = $resourceSet->getResourceType()->getInstanceType()->name;
     $entityName = $this->getEntityName($entityClassName);
     $tableName = $this->getTableName($entityName);
     $option = null;
     if ($queryType == QueryType::ENTITIES_WITH_COUNT()) {
         //tell mysql we want to know the count prior to the LIMIT
         //$option = 'SQL_CALC_FOUND_ROWS';
     }
     $where = $filterInfo ? ' WHERE ' . $filterInfo->getExpressionAsString() : '';
     $order = $orderBy ? ' ORDER BY ' . $this->getOrderByExpressionAsString($orderBy) : '';
     $sqlCount = 'SELECT COUNT(*) FROM ' . $tableName . $where;
     if ($queryType == QueryType::ENTITIES() || $queryType == QueryType::ENTITIES_WITH_COUNT()) {
         $sql = 'SELECT ' . $option . ' * FROM ' . $tableName . $where . $order . ($top ? ' LIMIT ' . $top : '') . ($skip ? ' OFFSET ' . $skip : '');
         $data = $this->queryAll($sql);
         if ($queryType == QueryType::ENTITIES_WITH_COUNT()) {
             //get those found rows
             //$result->count = $this->queryScalar('SELECT FOUND_ROWS()');
             $result->count = $this->queryScalar($sqlCount);
         }
         $result->results = array_map($entityClassName . '::fromRecord', $data);
     } elseif ($queryType == QueryType::COUNT()) {
         $result->count = QueryResult::adjustCountForPaging($this->queryScalar($sqlCount), $top, $skip);
     }
     return $result;
 }
Exemplo n.º 5
0
 public function testProcessRequestForCollectionWithNoInlineCountWhenVersionIsTooLow()
 {
     //I'm not so sure about this test...basically $inlinecount is ignored if it's none, but maybe we should
     //be throwing an exception?
     $requestURI = new Url('http://host.com/data.svc/Collection/?$inlinecount=none');
     Phockito::when($this->mockServiceHost->getAbsoluteRequestUri())->return($requestURI);
     //mock inline count as all pages
     Phockito::when($this->mockServiceHost->getQueryStringItem(ODataConstants::HTTPQUERY_STRING_INLINECOUNT))->return("none");
     $this->fakeServiceConfig->setAcceptCountRequests(true);
     $this->fakeServiceConfig->setMaxDataServiceVersion(ProtocolVersion::V1());
     $uriProcessor = UriProcessor::process($this->mockService);
     $fakeQueryResult = new QueryResult();
     $fakeQueryResult->results = array(1, 2, 3);
     $fakeQueryResult->count = 10;
     //note this is different than the size of the array
     Phockito::when($this->mockProvidersWrapper->getResourceSet(QueryType::ENTITIES(), $this->mockCollectionResourceSetWrapper, null, null, null, null))->return($fakeQueryResult);
     //indicate that POData must perform the paging (thus it will use the count of the results in QueryResult)
     Phockito::when($this->mockProvidersWrapper->handlesOrderedPaging())->return(false);
     $uriProcessor->execute();
     $request = $uriProcessor->getRequest();
     $actual = $request->getTargetResult();
     $this->assertEquals(array(1, 2, 3), $actual);
     $this->assertNull($request->getCountValue(), 'Since $inlinecount is specified as none, there should be no count set');
 }
Exemplo n.º 6
0
 private function ValidateQueryResult($queryResult, QueryType $queryType, $methodName)
 {
     if (!$queryResult instanceof QueryResult) {
         throw ODataException::createInternalServerError(Messages::queryProviderReturnsNonQueryResult($methodName));
     }
     if ($queryType == QueryType::COUNT() || $queryType == QueryType::ENTITIES_WITH_COUNT()) {
         //and the provider is supposed to handle the ordered paging they must return a count!
         if ($this->queryProvider->handlesOrderedPaging() && !is_numeric($queryResult->count)) {
             throw ODataException::createInternalServerError(Messages::queryProviderResultCountMissing($methodName, $queryType));
         }
         //If POData is supposed to handle the ordered aging they must return results! (possibly empty)
         if (!$this->queryProvider->handlesOrderedPaging() && !is_array($queryResult->results)) {
             throw ODataException::createInternalServerError(Messages::queryProviderResultsMissing($methodName, $queryType));
         }
     }
     if (($queryType == QueryType::ENTITIES() || $queryType == QueryType::ENTITIES_WITH_COUNT()) && !is_array($queryResult->results)) {
         throw ODataException::createInternalServerError(Messages::queryProviderResultsMissing($methodName, $queryType));
     }
 }