Skip to content

Commit fab0f2d

Browse files
authored
Few more tests (#6)
* add manual preload tests * add EntityPreloadBlogOneHasManyAbstractTest
1 parent f93c7c1 commit fab0f2d

4 files changed

+222
-1
lines changed

tests/EntityPreloadBlogManyHasOneDeepTest.php

Lines changed: 46 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,11 @@
66
use ShipMonkTests\DoctrineEntityPreloader\Fixtures\Blog\Article;
77
use ShipMonkTests\DoctrineEntityPreloader\Fixtures\Blog\Category;
88
use ShipMonkTests\DoctrineEntityPreloader\Lib\TestCase;
9+
use function array_filter;
10+
use function array_map;
11+
use function array_unique;
12+
use function array_values;
13+
use function count;
914

1015
class EntityPreloadBlogManyHasOneDeepTest extends TestCase
1116
{
@@ -20,7 +25,47 @@ public function testManyHasOneDeepUnoptimized(): void
2025

2126
self::assertAggregatedQueries([
2227
['count' => 1, 'query' => 'SELECT * FROM article t0'],
23-
['count' => 10, 'query' => 'SELECT * FROM category t0 WHERE t0.id = ?'],
28+
['count' => 5 + 5, 'query' => 'SELECT * FROM category t0 WHERE t0.id = ?'],
29+
]);
30+
}
31+
32+
public function testManyHasOneDeepWithManualPreload(): void
33+
{
34+
$this->createDummyBlogData(categoryCount: 5, categoryParentsCount: 5, articleInEachCategoryCount: 5);
35+
36+
$articles = $this->getEntityManager()->getRepository(Article::class)->findAll();
37+
38+
$categoryIds = array_map(static fn (Article $article) => $article->getCategory()?->getId(), $articles);
39+
$categoryIds = array_filter($categoryIds, static fn (?int $id) => $id !== null);
40+
41+
if (count($categoryIds) > 0) {
42+
$categories = $this->getEntityManager()->createQueryBuilder()
43+
->select('category')
44+
->from(Category::class, 'category')
45+
->where('category.id IN (:ids)')
46+
->setParameter('ids', array_values(array_unique($categoryIds)))
47+
->getQuery()
48+
->getResult();
49+
50+
$parentCategoryIds = array_map(static fn (Category $category) => $category->getParent()?->getId(), $categories);
51+
$parentCategoryIds = array_filter($parentCategoryIds, static fn (?int $id) => $id !== null);
52+
53+
if (count($parentCategoryIds) > 0) {
54+
$this->getEntityManager()->createQueryBuilder()
55+
->select('category')
56+
->from(Category::class, 'category')
57+
->where('category.id IN (:ids)')
58+
->setParameter('ids', array_values(array_unique($parentCategoryIds)))
59+
->getQuery()
60+
->getResult();
61+
}
62+
}
63+
64+
$this->readArticleCategoryParentNames($articles);
65+
66+
self::assertAggregatedQueries([
67+
['count' => 1, 'query' => 'SELECT * FROM article t0'],
68+
['count' => 2, 'query' => 'SELECT * FROM category c0_ WHERE c0_.id IN (?, ?, ?, ?, ?)'],
2469
]);
2570
}
2671

tests/EntityPreloadBlogManyHasOneTest.php

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,13 @@
44

55
use Doctrine\ORM\Mapping\ClassMetadata;
66
use ShipMonkTests\DoctrineEntityPreloader\Fixtures\Blog\Article;
7+
use ShipMonkTests\DoctrineEntityPreloader\Fixtures\Blog\Category;
78
use ShipMonkTests\DoctrineEntityPreloader\Lib\TestCase;
9+
use function array_filter;
10+
use function array_map;
11+
use function array_unique;
12+
use function array_values;
13+
use function count;
814

915
class EntityPreloadBlogManyHasOneTest extends TestCase
1016
{
@@ -23,6 +29,33 @@ public function testManyHasOneUnoptimized(): void
2329
]);
2430
}
2531

32+
public function testManyHasOneWithManualPreload(): void
33+
{
34+
$this->createDummyBlogData(categoryCount: 5, articleInEachCategoryCount: 5);
35+
36+
$articles = $this->getEntityManager()->getRepository(Article::class)->findAll();
37+
38+
$categoryIds = array_map(static fn (Article $article) => $article->getCategory()?->getId(), $articles);
39+
$categoryIds = array_filter($categoryIds, static fn (?int $id) => $id !== null);
40+
41+
if (count($categoryIds) > 0) {
42+
$this->getEntityManager()->createQueryBuilder()
43+
->select('category')
44+
->from(Category::class, 'category')
45+
->where('category.id IN (:ids)')
46+
->setParameter('ids', array_values(array_unique($categoryIds)))
47+
->getQuery()
48+
->getResult();
49+
}
50+
51+
$this->readArticleCategoryNames($articles);
52+
53+
self::assertAggregatedQueries([
54+
['count' => 1, 'query' => 'SELECT * FROM article t0'],
55+
['count' => 1, 'query' => 'SELECT * FROM category c0_ WHERE c0_.id IN (?, ?, ?, ?, ?)'],
56+
]);
57+
}
58+
2659
public function testManyHasOneWithFetchJoin(): void
2760
{
2861
$this->createDummyBlogData(categoryCount: 5, articleInEachCategoryCount: 5);
Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
<?php declare(strict_types = 1);
2+
3+
namespace ShipMonkTests\DoctrineEntityPreloader;
4+
5+
use Doctrine\ORM\Mapping\ClassMetadata;
6+
use ShipMonkTests\DoctrineEntityPreloader\Fixtures\Blog\Article;
7+
use ShipMonkTests\DoctrineEntityPreloader\Fixtures\Blog\Comment;
8+
use ShipMonkTests\DoctrineEntityPreloader\Lib\TestCase;
9+
10+
class EntityPreloadBlogOneHasManyAbstractTest extends TestCase
11+
{
12+
13+
public function testOneHasManyAbstractUnoptimized(): void
14+
{
15+
$this->createDummyBlogData(categoryCount: 1, articleInEachCategoryCount: 5, commentForEachArticleCount: 5);
16+
17+
$articles = $this->getEntityManager()->getRepository(Article::class)->findAll();
18+
19+
$this->readComments($articles);
20+
21+
self::assertAggregatedQueries([
22+
['count' => 1, 'query' => 'SELECT * FROM article t0'],
23+
['count' => 5, 'query' => 'SELECT * FROM comment t0 WHERE t0.article_id = ?'],
24+
['count' => 25, 'query' => 'SELECT * FROM contributor t0 WHERE t0.id = ? AND t0.dtype IN (?)'],
25+
]);
26+
}
27+
28+
public function testOneHasManyAbstractWithFetchJoin(): void
29+
{
30+
$this->createDummyBlogData(categoryCount: 1, articleInEachCategoryCount: 5, commentForEachArticleCount: 5);
31+
32+
$articles = $this->getEntityManager()->createQueryBuilder()
33+
->select('article', 'comment', 'author')
34+
->from(Article::class, 'article')
35+
->leftJoin('article.comments', 'comment')
36+
->leftJoin('comment.author', 'author')
37+
->getQuery()
38+
->getResult();
39+
40+
$this->readComments($articles);
41+
42+
self::assertAggregatedQueries([
43+
['count' => 1, 'query' => 'SELECT * FROM article a0_ LEFT JOIN comment c1_ ON a0_.id = c1_.article_id LEFT JOIN contributor c2_ ON c1_.author_id = c2_.id AND c2_.dtype IN (?)'],
44+
]);
45+
}
46+
47+
public function testOneHasManyAbstractWithEagerFetchMode(): void
48+
{
49+
$this->createDummyBlogData(categoryCount: 1, articleInEachCategoryCount: 5, commentForEachArticleCount: 5);
50+
51+
$articles = $this->getEntityManager()->createQueryBuilder()
52+
->select('article')
53+
->from(Article::class, 'article')
54+
->getQuery()
55+
->setFetchMode(Article::class, 'comments', ClassMetadata::FETCH_EAGER)
56+
->setFetchMode(Comment::class, 'author', ClassMetadata::FETCH_EAGER)
57+
->getResult();
58+
59+
$this->readComments($articles);
60+
61+
self::assertAggregatedQueries([
62+
['count' => 1, 'query' => 'SELECT * FROM article a0_'],
63+
['count' => 1, 'query' => 'SELECT * FROM comment t0 WHERE t0.article_id IN (?, ?, ?, ?, ?)'],
64+
['count' => 25, 'query' => 'SELECT * FROM contributor t0 WHERE t0.id = ? AND t0.dtype IN (?)'],
65+
]);
66+
}
67+
68+
public function testOneHasManyAbstractWithPreload(): void
69+
{
70+
$this->createDummyBlogData(categoryCount: 1, articleInEachCategoryCount: 5, commentForEachArticleCount: 5);
71+
72+
$articles = $this->getEntityManager()->getRepository(Article::class)->findAll();
73+
$this->getEntityPreloader()->preload($articles, 'comments');
74+
75+
$this->readComments($articles);
76+
77+
self::assertAggregatedQueries([
78+
['count' => 1, 'query' => 'SELECT * FROM article t0'],
79+
['count' => 1, 'query' => 'SELECT * FROM comment c0_ LEFT JOIN contributor c1_ ON c0_.author_id = c1_.id AND c1_.dtype IN (?) WHERE c0_.article_id IN (?, ?, ?, ?, ?)'],
80+
]);
81+
}
82+
83+
/**
84+
* @param array<Article> $articles
85+
*/
86+
private function readComments(array $articles): void
87+
{
88+
foreach ($articles as $article) {
89+
foreach ($article->getComments() as $comment) {
90+
$comment->getContent();
91+
}
92+
}
93+
}
94+
95+
}

tests/EntityPreloadBlogOneHasManyTest.php

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
namespace ShipMonkTests\DoctrineEntityPreloader;
44

55
use Doctrine\ORM\Mapping\ClassMetadata;
6+
use Doctrine\ORM\Query\QueryException;
7+
use ShipMonkTests\DoctrineEntityPreloader\Fixtures\Blog\Article;
68
use ShipMonkTests\DoctrineEntityPreloader\Fixtures\Blog\Category;
79
use ShipMonkTests\DoctrineEntityPreloader\Lib\TestCase;
810

@@ -23,6 +25,52 @@ public function testOneHasManyUnoptimized(): void
2325
]);
2426
}
2527

28+
public function testOneHasManyWithWithManualPreload(): void
29+
{
30+
$this->createDummyBlogData(categoryCount: 5, articleInEachCategoryCount: 5);
31+
32+
$categories = $this->getEntityManager()->getRepository(Category::class)->findAll();
33+
34+
$this->getEntityManager()->createQueryBuilder()
35+
->select('article')
36+
->from(Article::class, 'article')
37+
->where('article.category IN (:categories)')
38+
->setParameter('categories', $categories)
39+
->getQuery()
40+
->getResult();
41+
42+
$this->readArticleTitles($categories);
43+
44+
self::assertAggregatedQueries([
45+
['count' => 1, 'query' => 'SELECT * FROM category t0'],
46+
['count' => 1, 'query' => 'SELECT * FROM article a0_ WHERE a0_.category_id IN (?, ?, ?, ?, ?)'],
47+
['count' => 5, 'query' => 'SELECT * FROM article t0 WHERE t0.category_id = ?'],
48+
]);
49+
}
50+
51+
public function testOneHasManyWithWithManualPreloadUsingPartial(): void
52+
{
53+
$this->createDummyBlogData(categoryCount: 5, articleInEachCategoryCount: 5);
54+
55+
$categories = $this->getEntityManager()->getRepository(Category::class)->findAll();
56+
57+
// partial no longer works in doctrine 3.0
58+
self::assertException(
59+
QueryException::class,
60+
null,
61+
function () use ($categories): void {
62+
$this->getEntityManager()->createQueryBuilder()
63+
->select('PARTIAL category.{id}', 'article')
64+
->from(Category::class, 'category')
65+
->leftJoin('category.articles', 'article')
66+
->where('category IN (:categories)')
67+
->setParameter('categories', $categories)
68+
->getQuery()
69+
->getResult();
70+
},
71+
);
72+
}
73+
2674
public function testOneHasManyWithFetchJoin(): void
2775
{
2876
$this->createDummyBlogData(categoryCount: 5, articleInEachCategoryCount: 5);

0 commit comments

Comments
 (0)