/** * Test search InternalSkipToeknInfo::GetIndexOfFirstEntryInNextPage function */ public function testGetIndexOfFirstEntryInNextPage2() { try { $northWindMetadata = CreateNorthWindMetadata1::Create(); $configuration = new DataServiceConfiguration($northWindMetadata); $configuration->setEntitySetAccessRule('*', EntitySetRights::ALL); $metaQueryProverWrapper = new MetadataQueryProviderWrapper($northWindMetadata, null, $configuration, false); $resourceSetWrapper = $metaQueryProverWrapper->resolveResourceSet('Orders'); $resourceType = $resourceSetWrapper->getResourceType(); $orderBy = 'ShipName asc, Freight'; //Note: library will add prim key as last sort key $orderBy .= ', OrderID'; $qp = new NorthWindQueryProvider1(); $orders = $qp->getResourceSet($resourceSetWrapper->getResourceSet()); $internalOrderByInfo = OrderByParser::parseOrderByClause($resourceSetWrapper, $resourceType, $orderBy, $metaQueryProverWrapper); $compFun = $internalOrderByInfo->getSorterFunction(); $fun = $compFun->getReference(); usort($orders, $fun); $numRecords = count($orders); //----------------------------------------------------------------- //Search with a key that exactly matches $skipToken = utf8_decode(urldecode("'Antonio%20Moreno%20Taquer%C3%ADa',22.0000M,10365")); $skipToken = urldecode($skipToken); $internalSkipTokenInfo = SkipTokenParser::parseSkipTokenClause($resourceType, $internalOrderByInfo, $skipToken); $nextIndex = $internalSkipTokenInfo->getIndexOfFirstEntryInTheNextPage($orders); $this->assertTrue($nextIndex > 1); $this->assertTrue($nextIndex < $numRecords); //$nextIndex is the index of order record next to the searched record $this->assertEquals($orders[$nextIndex - 1]->OrderID, 10365); $this->assertEquals($orders[$nextIndex - 1]->Freight, 22.0); //----------------------------------------------------------------- //Search with a key that partially matches, in the DB there is no //order with ShipName 'An', but there are records start with //'An', so partial match, since its a parial match other two //key wont be used for comparsion $skipToken = "'An',22.0000M,10365"; $internalSkipTokenInfo = SkipTokenParser::parseSkipTokenClause($resourceType, $internalOrderByInfo, $skipToken); $nextIndex = $internalSkipTokenInfo->getIndexOfFirstEntryInTheNextPage($orders); $this->assertTrue($nextIndex > 1); $this->assertTrue($nextIndex < $numRecords); //Make sure this is the most matching record by comparing with previous record $prevOrder = $orders[$nextIndex - 1]; $r = strcmp($prevOrder->ShipName, $orders[$nextIndex]->ShipName); $this->assertTrue($r < 0); //Make sure this is the most matching record by comparing with next record $nextOrder = $orders[$nextIndex + 1]; $r = strcmp($nextOrder->ShipName, $orders[$nextIndex]->ShipName); $this->assertTrue($r >= 0); //----------------------------------------------------------------- //Search with a key that does not exists $skipToken = "'XXX',11,10365"; $internalSkipTokenInfo = SkipTokenParser::parseSkipTokenClause($resourceType, $internalOrderByInfo, $skipToken); $nextIndex = $internalSkipTokenInfo->getIndexOfFirstEntryInTheNextPage($orders); $this->assertTrue($nextIndex == -1); //----------------------------------------------------------------- } catch (\Exception $exception) { $this->fail('An unexpected Exception has been raised.' . $exception->getMessage()); } }
public function testWriteMetadata() { $northWindMetadata = CreateNorthWindMetadata1::Create(); $configuration = new DataServiceConfiguration($northWindMetadata); $configuration->setEntitySetAccessRule("*", EntitySetRights::ALL); $configuration->setMaxDataServiceVersion(DataServiceProtocolVersion::V3); $northWindQuery = new NorthWindQueryProvider1(); $metaQueryProverWrapper = new MetadataQueryProviderWrapper($northWindMetadata, $northWindQuery, $configuration, false); $metadataWriter = new MetadataWriter($metaQueryProverWrapper); $metadata = $metadataWriter->writeMetadata(); $this->assertNotNull($metadata); $this->assertEquals($metaQueryProverWrapper->getContainerName(), 'NorthWindEntities'); $this->assertEquals($metaQueryProverWrapper->getContainerNamespace(), 'NorthWind'); $this->assertStringStartsWith('<edmx:Edmx Version="1.0"', $metadata); $customerResourceSet = $metaQueryProverWrapper->resolveResourceSet('Customers'); $this->assertEquals($customerResourceSet->getName(), 'Customers'); $this->assertEquals($customerResourceSet->getResourceType()->getName(), 'Customer'); $customerEntityType = $metaQueryProverWrapper->resolveResourceType('Customer'); $this->assertEquals($customerEntityType->getResourceTypeKind(), ResourceTypeKind::ENTITY); }
/** * Create SegmentDescriptor for the first segment * * @param string $segmentIdentifier The identifier part of the * first segment * @param string $keyPredicate The predicate part of the first * segment if any else NULL * @param boolean $checkRights Whether to check the rights on * this segment * * @return SegmentDescriptor Descriptor for the first segment * * @throws ODataException Exception if any validation fails */ private function _createFirstSegmentDescriptor($segmentIdentifier, $keyPredicate, $checkRights) { $descriptor = new SegmentDescriptor(); $descriptor->setIdentifier($segmentIdentifier); if ($segmentIdentifier === ODataConstants::URI_METADATA_SEGMENT) { $this->_assertion(is_null($keyPredicate)); $descriptor->setTargetKind(RequestTargetKind::METADATA); return $descriptor; } if ($segmentIdentifier === ODataConstants::URI_BATCH_SEGMENT) { $this->_assertion(is_null($keyPredicate)); $descriptor->setTargetKind(RequestTargetKind::BATCH); return $descriptor; } if ($segmentIdentifier === ODataConstants::URI_COUNT_SEGMENT) { ODataException::createBadRequestError(Messages::segmentParserSegmentNotAllowedOnRoot(ODataConstants::URI_COUNT_SEGMENT)); } if ($segmentIdentifier === ODataConstants::URI_LINK_SEGMENT) { ODataException::createBadRequestError(Messages::segmentParserSegmentNotAllowedOnRoot(ODataConstants::URI_LINK_SEGMENT)); } $resourceSetWrapper = $this->_providerWrapper->resolveResourceSet($segmentIdentifier); if ($resourceSetWrapper === null) { ODataException::createResourceNotFoundError($segmentIdentifier); } $descriptor->setTargetResourceSetWrapper($resourceSetWrapper); $descriptor->setTargetResourceType($resourceSetWrapper->getResourceType()); $descriptor->setTargetSource(RequestTargetSource::ENTITY_SET); $descriptor->setTargetKind(RequestTargetKind::RESOURCE); if ($keyPredicate !== null) { $keyDescriptor = $this->_createKeyDescriptor($segmentIdentifier . '(' . $keyPredicate . ')', $resourceSetWrapper->getResourceType(), $keyPredicate); $descriptor->setKeyDescriptor($keyDescriptor); if (!$keyDescriptor->isEmpty()) { $descriptor->setSingleResult(true); } } if ($checkRights) { $resourceSetWrapper->checkResourceSetRightsForRead($descriptor->isSingleResult()); } return $descriptor; }
/** * Test whether order by parser identify and remove path duplication */ public function testOrderByWithPathDuplication() { try { $northWindMetadata = CreateNorthWindMetadata3::Create(); $configuration = new DataServiceConfiguration($northWindMetadata); $configuration->setEntitySetAccessRule('*', EntitySetRights::ALL); $metaQueryProverWrapper = new MetadataQueryProviderWrapper($northWindMetadata, null, $configuration, false); $resourceSetWrapper = $metaQueryProverWrapper->resolveResourceSet('Order_Details'); $resourceType = $resourceSetWrapper->getResourceType(); $orderBy = 'Order/Price desc, Product/ProductName asc, Order/Price asc'; $internalOrderInfo = OrderByParser::parseOrderByClause($resourceSetWrapper, $resourceType, $orderBy, $metaQueryProverWrapper); //The orderby path Order/Price appears twice, but parser will consider only first path $orderByInfo = $internalOrderInfo->getOrderByInfo(); //There are navigation (resource reference) properties in the orderby path so getNavigationPropertiesUsed should //not be null $naviUsed = $orderByInfo->getNavigationPropertiesUsed(); $this->assertFalse(is_null($naviUsed)); //3 path segment are there, but last one is duplicate of first one, so parser removes last one $this->assertEquals(count($naviUsed), 2); $this->assertTrue(is_array($naviUsed[0])); $this->assertTrue(is_array($naviUsed[1])); //one navgations used in first orderby 'Order' $this->assertEquals(count($naviUsed[0]), 1); //one navgations used in second orderby 'Prodcut' $this->assertEquals(count($naviUsed[1]), 1); $this->assertEquals($naviUsed[0][0]->getName(), 'Order'); $this->assertEquals($naviUsed[1][0]->getName(), 'Product'); $orderByPathSegments = $orderByInfo->getOrderByPathSegments(); $this->assertEquals(count($orderByPathSegments), 2); } catch (\Exception $exception) { $this->fail('An unexpected Exception has been raised' . $exception->getMessage()); } }
/** * If last sub path segment specified in the select clause does not appear in the prjection tree, * then parser will create 'ProjectionNode' for them */ public function testPrjectionNodeCreation() { try { $northWindMetadata = CreateNorthWindMetadata3::Create(); $queryProvider = new NorthWindQueryProvider2(); $configuration = new DataServiceConfiguration($northWindMetadata); $configuration->setEntitySetAccessRule('*', EntitySetRights::ALL); $metaQueryProverWrapper = new MetadataQueryProviderWrapper($northWindMetadata, $queryProvider, $configuration, false); $ordersResourceSetWrapper = $metaQueryProverWrapper->resolveResourceSet('Orders'); $orderResourceType = $ordersResourceSetWrapper->getResourceType(); //test selection of properties which is not included in expand clause //1 primitve ('Order_Details/UnitPrice') and 1 link to navigation 'Customer' $projectionTreeRoot = ExpandProjectionParser::parseExpandAndSelectClause($ordersResourceSetWrapper, $orderResourceType, null, null, null, 'Order_Details', 'Order_Details/UnitPrice, Customer', $metaQueryProverWrapper); //expand option is absent $this->assertTrue($projectionTreeRoot->isExpansionSpecified()); //select is applied $this->assertTrue($projectionTreeRoot->isSelectionSpecified()); $this->assertFalse($projectionTreeRoot->canSelectAllImmediateProperties()); $this->assertFalse($projectionTreeRoot->canSelectAllProperties()); //there are 2 child nodes for the root $this->assertEquals(count($projectionTreeRoot->getChildNodes()), 2); //The child nodes one 'ProjectionNode' Customer and one 'ExpandedProjectionNode' for 'Order' $childNodes = $projectionTreeRoot->getChildNodes(); $this->assertTrue(array_key_exists('Order_Details', $childNodes)); $this->assertTrue(array_key_exists('Customer', $childNodes)); $this->assertTrue($childNodes['Order_Details'] instanceof ExpandedProjectionNode); $this->assertTrue($childNodes['Customer'] instanceof ProjectionNode); //'Order_Detials' has a child node $childNodes = $childNodes['Order_Details']->getChildNodes(); $this->assertEquals(count($childNodes), 1); $this->assertTrue(array_key_exists('UnitPrice', $childNodes)); $this->assertTrue($childNodes['UnitPrice'] instanceof ProjectionNode); } catch (\Exception $exception) { $this->fail('An unexpected Exception has been raised' . $exception->getMessage()); } }
/** * test the creation of nextlink from an object. * Test building of link with guid sub-value */ public function testCreationOfNextLink4() { try { $northWindMetadata = CreateNorthWindMetadata3::Create(); $configuration = new DataServiceConfiguration($northWindMetadata); $configuration->setEntitySetAccessRule('*', EntitySetRights::ALL); $metaQueryProverWrapper = new MetadataQueryProviderWrapper($northWindMetadata, null, $configuration, false); $resourceSetWrapper = $metaQueryProverWrapper->resolveResourceSet('Customers'); $resourceType = $resourceSetWrapper->getResourceType(); $orderBy = 'CustomerID, CustomerGuid'; $internalOrderByInfo = OrderByParser::parseOrderByClause($resourceSetWrapper, $resourceType, $orderBy, $metaQueryProverWrapper); $skipToken = "null, guid'05b242e752eb46bd8f0e6568b72cd9a5'"; $internalSkipTokenInfo = SkipTokenParser::parseSkipTokenClause($resourceType, $internalOrderByInfo, $skipToken); $keyObject = $internalSkipTokenInfo->getKeyObject(); $lastObject = new Customer2(); $lastObject->CustomerID = 'ABC'; $lastObject->CustomerGuid = '{05b242e7-52eb-46bd-8f0e-6568b72cd9a5}'; $nextLink = $internalSkipTokenInfo->buildNextPageLink($lastObject); $this->assertEquals($nextLink, "'ABC', guid'%7B05b242e7-52eb-46bd-8f0e-6568b72cd9a5%7D'"); } catch (\Exception $exception) { $this->fail('An unexpected Exception has been raised.' . $exception->getMessage()); } }
public function testGetResourceAssociationSet1() { try { //Get the association set where resource set in both ends are visible $configuration = null; $metadataProvider = $this->_createMetadataAndConfiguration1($configuration); $metaQueryProverWrapper = new MetadataQueryProviderWrapper($metadataProvider, null, $configuration, false); $configuration->setEntitySetAccessRule('Customers', EntitySetRights::ALL); $configuration->setEntitySetAccessRule('Orders', EntitySetRights::ALL); $customersEntitySetWrapper = $metaQueryProverWrapper->resolveResourceSet('Customers'); $this->assertNotNull($customersEntitySetWrapper); $customerEntityType = $metaQueryProverWrapper->resolveResourceType('Customer'); $this->assertNotNull($customerEntityType); $ordersProperty = $customerEntityType->tryResolvePropertyTypeByName('Orders'); $this->assertNotNull($ordersProperty); $associationSet = $metaQueryProverWrapper->getResourceAssociationSet($customersEntitySetWrapper, $customerEntityType, $ordersProperty); $this->assertNotNull($associationSet); $associationSetEnd1 = $associationSet->getEnd1(); $this->assertNotNull($associationSetEnd1); $associationSetEnd2 = $associationSet->getEnd2(); $this->assertNotNull($associationSetEnd2); $this->assertEquals($associationSetEnd1->getResourceSet()->getName(), 'Customers'); $this->assertEquals($associationSetEnd2->getResourceSet()->getName(), 'Orders'); $this->assertEquals($associationSetEnd1->getResourceType()->getName(), 'Customer'); $this->assertEquals($associationSetEnd2->getResourceType()->getName(), 'Order'); //Try to get the association set where resource set in one end is invisible $configuration = null; $metadataProvider = $this->_createMetadataAndConfiguration1($configuration); $metaQueryProverWrapper = new MetadataQueryProviderWrapper($metadataProvider, null, $configuration, false); $configuration->setEntitySetAccessRule('Customers', EntitySetRights::ALL); //Set orders entity set as invisible $configuration->setEntitySetAccessRule('Orders', EntitySetRights::NONE); $customersEntitySetWrapper = $metaQueryProverWrapper->resolveResourceSet('Customers'); $this->assertNotNull($customersEntitySetWrapper); $customerEntityType = $metaQueryProverWrapper->resolveResourceType('Customer'); $this->assertNotNull($customerEntityType); $ordersProperty = $customerEntityType->tryResolvePropertyTypeByName('Orders'); $this->assertNotNull($ordersProperty); $associationSet = $metaQueryProverWrapper->getResourceAssociationSet($customersEntitySetWrapper, $customerEntityType, $ordersProperty); $this->assertNull($associationSet); } catch (\Exception $exception) { $this->fail('An unexpected Exception has been raised' . $exception->getMessage()); } }
/** * One can expand a navigation property only if corrosponding resource set is visible * */ public function testExpandWithNonVisibleResourceSet() { try { $northWindMetadata = CreateNorthWindMetadata3::Create(); $queryProvider = new NorthWindQueryProvider2(); $configuration = new DataServiceConfiguration($northWindMetadata); //Make 'Customers' and 'Orders' visible, make 'Order_Details' invisible $configuration->setEntitySetAccessRule('Customers', EntitySetRights::ALL); $configuration->setEntitySetAccessRule('Orders', EntitySetRights::ALL); $metaQueryProverWrapper = new MetadataQueryProviderWrapper($northWindMetadata, $queryProvider, $configuration, false); $customersResourceSetWrapper = $metaQueryProverWrapper->resolveResourceSet('Customers'); $customerResourceType = $customersResourceSetWrapper->getResourceType(); $exceptionThrown = false; try { $projectionTree = ExpandProjectionParser::parseExpandAndSelectClause($customersResourceSetWrapper, $customerResourceType, null, null, null, 'Orders/Order_Details', null, $metaQueryProverWrapper); } catch (ODataException $odataException) { $exceptionThrown = true; $this->assertStringEndsWith("(Check the resource set of the navigation property 'Order_Details' is visible)", $odataException->getMessage()); } if (!$exceptionThrown) { $this->fail('An expected ODataException for navigation to invisible resource set has not been thrown'); } } catch (\Exception $exception) { $this->fail('An unexpected Exception has been raised' . $exception->getMessage()); } }