Exemple #1
0
 /**
  * Applies the query options to the resource(s) retrieved from the data source.
  * 
  * @param SegmentDescriptor $segment The descriptor which holds resource(s) on which query options to be applied.
  *
  */
 private function applyQueryOptions(SegmentDescriptor $segment)
 {
     //TODO: I'm not really happy with this..i think i'd rather keep the result the QueryResult
     //not even bother with the setCountValue stuff (shouldn't counts be on segments?)
     //and just work with the QueryResult in the object model serializer
     $result = $segment->getResult();
     if (!$result instanceof QueryResult) {
         //If the segment isn't a query result, then there's no paging or counting to be done
         return;
     }
     // Note $inlinecount=allpages means include the total count regardless of paging..so we set the counts first
     // regardless if POData does the paging or not.
     if ($this->request->queryType == QueryType::ENTITIES_WITH_COUNT()) {
         if ($this->providers->handlesOrderedPaging()) {
             $this->request->setCountValue($result->count);
         } else {
             $this->request->setCountValue(count($result->results));
         }
     }
     //Have POData perform paging if necessary
     if (!$this->providers->handlesOrderedPaging() && !empty($result->results)) {
         $result->results = $this->performPaging($result->results);
     }
     //a bit surprising, but $skip and $top affects $count so update it here, not above
     //IE  data.svc/Collection/$count?$top=10 returns 10 even if Collection has 11+ entries
     if ($this->request->queryType == QueryType::COUNT()) {
         if ($this->providers->handlesOrderedPaging()) {
             $this->request->setCountValue($result->count);
         } else {
             $this->request->setCountValue(count($result->results));
         }
     }
     $segment->setResult($result->results);
 }
 /**
  * Write top level url collection.
  * 
  * @param array $entryObjects Array of entry resources
  * whose url to be written.
  * 
  * @return ODataURLCollection
  */
 public function writeUrlElements($entryObjects)
 {
     $urls = new ODataURLCollection();
     if (!empty($entryObjects)) {
         $i = 0;
         foreach ($entryObjects as $entryObject) {
             $urls->urls[$i] = $this->writeUrlElement($entryObject);
             $i++;
         }
         if ($i > 0 && $this->needNextPageLink(count($entryObjects))) {
             $urls->nextPageLink = $this->getNextLinkUri($entryObjects[$i - 1], $this->request->getRequestUrl()->getUrlAsString());
         }
     }
     if ($this->request->queryType == QueryType::ENTITIES_WITH_COUNT()) {
         $urls->count = $this->request->getCountValue();
     }
     return $urls;
 }
 public function testGetRelatedResourceSetReturnsArrayWhenQueryTypeIsEntitiesWithCount()
 {
     $orderBy = null;
     $top = 10;
     $skip = 10;
     $fakeQueryResult = new QueryResult();
     $fakeQueryResult->count = 4;
     $fakeQueryResult->results = null;
     //null is not an array
     $fakeSourceEntity = new \stdClass();
     Phockito::when($this->mockQueryProvider->getRelatedResourceSet(QueryType::ENTITIES_WITH_COUNT(), $this->mockResourceSet, $fakeSourceEntity, $this->mockResourceSet2, $this->mockResourceProperty, $this->mockFilterInfo, $orderBy, $top, $skip))->return($fakeQueryResult);
     $wrapper = $this->getMockedWrapper();
     try {
         $wrapper->getRelatedResourceSet(QueryType::ENTITIES_WITH_COUNT(), $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_WITH_COUNT()), $ex->getMessage());
         $this->assertEquals(500, $ex->getStatusCode());
     }
 }
 /**
  * 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;
 }
 public function testProcessRequestForCollectionWithInlineCountProviderHandlesPaging()
 {
     $requestURI = new Url('http://host.com/data.svc/Collection/?$inlinecount=allpages');
     Phockito::when($this->mockServiceHost->getAbsoluteRequestUri())->return($requestURI);
     //mock inline count as all pages
     Phockito::when($this->mockServiceHost->getQueryStringItem(ODataConstants::HTTPQUERY_STRING_INLINECOUNT))->return("allpages");
     $this->fakeServiceConfig->setAcceptCountRequests(true);
     $this->fakeServiceConfig->setMaxDataServiceVersion(ProtocolVersion::V2());
     $uriProcessor = UriProcessor::process($this->mockService);
     $fakeQueryResult = new QueryResult();
     $fakeQueryResult->results = array(1, 2, 3);
     $fakeQueryResult->count = 10;
     Phockito::when($this->mockProvidersWrapper->getResourceSet(QueryType::ENTITIES_WITH_COUNT(), $this->mockCollectionResourceSetWrapper, null, null, null, null))->return($fakeQueryResult);
     //indicate that the Provider performs the paging (thus it will use the count in the QueryResult)
     Phockito::when($this->mockProvidersWrapper->handlesOrderedPaging())->return(true);
     $uriProcessor->execute();
     $request = $uriProcessor->getRequest();
     $actual = $request->getTargetResult();
     $this->assertEquals(array(1, 2, 3), $actual);
     $this->assertEquals(10, $request->getCountValue());
 }
Exemple #6
0
 /**
  * Process the $inlinecount option and update the request description.
  *
  * @return void
  * 
  * @throws ODataException Throws bad request error in the following cases
  *                          (1) If $inlinecount is disabled by the developer
  *                          (2) If both $count and $inlinecount specified
  *                          (3) If $inlinecount value is unknown
  *                          (4) If capability negotiation over version fails
  */
 private function _processCount()
 {
     $inlineCount = $this->service->getHost()->getQueryStringItem(ODataConstants::HTTPQUERY_STRING_INLINECOUNT);
     //If it's not specified, we're done
     if (is_null($inlineCount)) {
         return;
     }
     //If the service doesn't allow count requests..then throw an exception
     if (!$this->service->getConfiguration()->getAcceptCountRequests()) {
         throw ODataException::createBadRequestError(Messages::configurationCountNotAccepted());
     }
     $inlineCount = trim($inlineCount);
     //if it's set to none, we don't do inline counts
     if ($inlineCount === ODataConstants::URI_ROWCOUNT_OFFOPTION) {
         return;
     }
     //You can't specify $count & $inlinecount together
     //TODO: ensure there's a test for this case see #55
     if ($this->request->queryType == QueryType::COUNT()) {
         throw ODataException::createBadRequestError(Messages::queryProcessorInlineCountWithValueCount());
     }
     $this->_checkSetQueryApplicable();
     //TODO: why do we do this check?
     if ($inlineCount === ODataConstants::URI_ROWCOUNT_ALLOPTION) {
         $this->request->queryType = QueryType::ENTITIES_WITH_COUNT();
         $this->request->raiseMinVersionRequirement(2, 0);
         $this->request->raiseResponseVersion(2, 0);
     } else {
         throw ODataException::createBadRequestError(Messages::queryProcessorInvalidInlineCountOptionError());
     }
 }
 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));
     }
 }