/** * Get all foreign entities ordered by a sort column * * If you have applied a limit to the query but need to know the full size of the unfiltered set, you must set * $check_full_set_size to true to gather this information at the expense of a second database query. * * @param SortedQuery $query * @param bool $check_full_set_size * @param bool $use_cache * @return QueryResult */ public function sortedQuery(SortedQuery $query, $check_full_set_size = false, $use_cache = true) { $metadata = $this->getMapper()->getEntityMetadata($query->getClassName()); if ($query->getRelationshipName()) { // Entity relationship based query $reader = new Reader($metadata, $query->getEntity()); $relationship = $metadata->getRelationshipByName($query->getRelationshipName()); if (!$relationship) { throw new InvalidArgumentException('Relationship "' . $query->getRelationshipName() . '" does not exist'); } // Important, else the QueryResult class will try to hydrate the wrong entity $query->setClassName($relationship->getTarget()); $key = $this->getKeyScheme()->getSortIndexKey($relationship, $query->getSortBy(), $reader->getId()); } else { // Table based query $key = $this->getKeyScheme()->getTableSortKey($metadata->getTableName(), $query->getSortBy()); } $results = $this->getDriver()->getSortedIndex($key, $query->getDirection() == Direction::DESC(), $query->getStart(), $query->getEnd()); if (!$query->getStart() && !$query->getEnd()) { $full_size = count($results); } elseif ($check_full_set_size) { $full_size = $this->getDriver()->getSortedIndexSize($key); } else { $full_size = null; } return new QueryResult($this->entity_manager, $query, $results, $full_size, $use_cache); }
/** * @param object $entity Entity to retrieve relationships from * @param string $relationship_name Name of the relationship on provided entity * @param string $sort_by Sort by column * @param Direction $direction Assumes ascending if omitted * @param int $start Start index (inclusive), null/0 for beginning of set * @param int $end Stop index (inclusive), null/-1 for end of set, -2 for penultimate record */ public function __construct($entity, $relationship_name, $sort_by, Direction $direction = null, $start = null, $end = null) { parent::__construct($entity); $this->entity = $entity; $this->relationship_name = $relationship_name; $this->sort_by = $sort_by; $this->direction = $direction ?: Direction::ASC(); $this->start = $start; $this->end = $end; }
/** * @dataProvider entityManagerDataProvider * @param EntityManager $em */ public function testSortOrder(EntityManager $em) { $category = new Category(); $category->setId(600); $em->persist($category); for ($i = 0; $i < 15; $i++) { $article = new Article(); $article->setId(601 + $i); $article->setTitle('Art ' . (601 + $i)); $time = new \DateTime(); $time->modify('+' . ($i + 1) . ' minutes'); $article->setSortDate($time); $article->setCanonicalCategory($category); $em->persist($article); } $em->flush(); /** @var Article $article */ // Date sorting - $results = $em->sortedQuery(new SortedQuery($category, 'articles', 'sort_date')); $this->assertCount(15, $results); $article = $results[0]; $this->assertEquals('Art 601', $article->getTitle()); $results = $em->sortedQuery(new SortedQuery($category, 'articles', 'sort_date', Direction::DESC())); $this->assertCount(15, $results); $this->assertEquals(15, $results->getFullSize()); $article = $results[0]; $this->assertEquals('Art 615', $article->getTitle()); $results = $em->sortedQuery(new SortedQuery($category, 'articles', 'sort_date', Direction::DESC(), 5, -6), true); $this->assertCount(5, $results); $this->assertEquals(15, $results->getFullSize()); $article = $results[0]; $this->assertEquals('Art 610', $article->getTitle()); $article = $results[4]; $this->assertEquals('Art 606', $article->getTitle()); $results = $em->sortedQuery(new SortedQuery($category, 'articles', 'sort_date', Direction::ASC(), 2, 5)); $this->assertCount(4, $results); $this->assertNull($results->getFullSize()); $article = $results[0]; $this->assertEquals('Art 603', $article->getTitle()); $results = $em->sortedQuery(new SortedQuery($category, 'articles', 'sort_date', Direction::ASC(), 20, 29)); $this->assertCount(0, $results); $results = $em->sortedQuery(new SortedQuery($category, 'articles', 'title')); $this->assertCount(15, $results); $article = $results[0]; $this->assertEquals('Art 601', $article->getTitle()); // Lexicographic sorting - $results = $em->sortedQuery(new SortedQuery($category, 'articles', 'title')); $this->assertCount(15, $results); $article = $results[0]; $this->assertEquals('Art 601', $article->getTitle()); $results = $em->sortedQuery(new SortedQuery($category, 'articles', 'title', Direction::DESC())); $this->assertCount(15, $results); $article = $results[0]; $this->assertEquals('Art 615', $article->getTitle()); // Modify an entity's sort-by column $article = $em->retrieve(Article::class, 609); $time = $article->getSortDate(); $time->modify('+1 day'); $article->setSortDate($time); $em->persist($article)->flush(); $results = $em->sortedQuery(new SortedQuery($category, 'articles', 'sort_date', Direction::DESC())); $this->assertCount(15, $results); $article = $results[0]; $this->assertEquals('Art 609', $article->getTitle()); }
public function testPortation() { $mapper = new AnnotationMapper(); $src = EntityManager::build($this->getRedisDriver(), $mapper); $dest = EntityManager::build($this->getFsDriver('porter-db'), $mapper); $porter = new Porter(); $porter->registerManager('redis', $src); $porter->registerManager('tar', $dest); // Create some dummy data $category = new Category(); $category->setId(600); $src->persist($category); for ($i = 0; $i < 15; $i++) { $article = new Article(); $article->setId(601 + $i); $article->setTitle('Art ' . (601 + $i)); $time = new \DateTime(); $time->modify('+' . ($i + 1) . ' minutes'); $article->setSortDate($time); $article->setCanonicalCategory($category); $src->persist($article); } $src->flush(); // Port the database $porter->portTable(Article::class, 'redis', 'tar'); $porter->portTable(Category::class, 'redis', 'tar'); // Check entity counts $articles = $dest->indexedQuery(new IndexedQuery(Article::class, ['@id' => '*']), false); $this->assertCount(15, $articles); $categories = $dest->indexedQuery(new IndexedQuery(Category::class, ['@id' => '*']), false); $this->assertCount(1, $categories); // Test indices were preserved /** @var Article $article */ // Date sorting - $results = $dest->sortedQuery(new SortedQuery($category, 'articles', 'sort_date')); $this->assertCount(15, $results); $article = $results[0]; $this->assertEquals('Art 601', $article->getTitle()); $results = $dest->sortedQuery(new SortedQuery($category, 'articles', 'sort_date', Direction::DESC())); $this->assertCount(15, $results); $this->assertEquals(15, $results->getFullSize()); $article = $results[0]; $this->assertEquals('Art 615', $article->getTitle()); $results = $dest->sortedQuery(new SortedQuery($category, 'articles', 'sort_date', Direction::DESC(), 5, -6), true); $this->assertCount(5, $results); $this->assertEquals(15, $results->getFullSize()); $article = $results[0]; $this->assertEquals('Art 610', $article->getTitle()); $article = $results[4]; $this->assertEquals('Art 606', $article->getTitle()); $results = $dest->sortedQuery(new SortedQuery($category, 'articles', 'sort_date', Direction::ASC(), 2, 5)); $this->assertCount(4, $results); $this->assertNull($results->getFullSize()); $article = $results[0]; $this->assertEquals('Art 603', $article->getTitle()); $results = $dest->sortedQuery(new SortedQuery($category, 'articles', 'sort_date', Direction::ASC(), 20, 29)); $this->assertCount(0, $results); $results = $dest->sortedQuery(new SortedQuery($category, 'articles', 'title')); $this->assertCount(15, $results); $article = $results[0]; $this->assertEquals('Art 601', $article->getTitle()); // Lexicographic sorting - $results = $dest->sortedQuery(new SortedQuery($category, 'articles', 'title')); $this->assertCount(15, $results); $article = $results[0]; $this->assertEquals('Art 601', $article->getTitle()); $results = $dest->sortedQuery(new SortedQuery($category, 'articles', 'title', Direction::DESC())); $this->assertCount(15, $results); $article = $results[0]; $this->assertEquals('Art 615', $article->getTitle()); }