ExtraLazyCollectionTest.php 15KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418
  1. <?php
  2. namespace Doctrine\Tests\ORM\Functional;
  3. use Doctrine\ORM\Mapping\ClassMetadataInfo;
  4. require_once __DIR__ . '/../../TestInit.php';
  5. /**
  6. * Description of ExtraLazyCollectionTest
  7. *
  8. * @author beberlei
  9. */
  10. class ExtraLazyCollectionTest extends \Doctrine\Tests\OrmFunctionalTestCase
  11. {
  12. private $userId;
  13. private $groupId;
  14. private $articleId;
  15. public function setUp()
  16. {
  17. $this->useModelSet('cms');
  18. parent::setUp();
  19. $class = $this->_em->getClassMetadata('Doctrine\Tests\Models\CMS\CmsUser');
  20. $class->associationMappings['groups']['fetch'] = ClassMetadataInfo::FETCH_EXTRA_LAZY;
  21. $class->associationMappings['articles']['fetch'] = ClassMetadataInfo::FETCH_EXTRA_LAZY;
  22. $class = $this->_em->getClassMetadata('Doctrine\Tests\Models\CMS\CmsGroup');
  23. $class->associationMappings['users']['fetch'] = ClassMetadataInfo::FETCH_EXTRA_LAZY;
  24. $this->loadFixture();
  25. }
  26. public function tearDown()
  27. {
  28. parent::tearDown();
  29. $class = $this->_em->getClassMetadata('Doctrine\Tests\Models\CMS\CmsUser');
  30. $class->associationMappings['groups']['fetch'] = ClassMetadataInfo::FETCH_LAZY;
  31. $class->associationMappings['articles']['fetch'] = ClassMetadataInfo::FETCH_LAZY;
  32. $class = $this->_em->getClassMetadata('Doctrine\Tests\Models\CMS\CmsGroup');
  33. $class->associationMappings['users']['fetch'] = ClassMetadataInfo::FETCH_LAZY;
  34. }
  35. /**
  36. * @group DDC-546
  37. */
  38. public function testCountNotInitializesCollection()
  39. {
  40. $user = $this->_em->find('Doctrine\Tests\Models\CMS\CmsUser', $this->userId);
  41. $queryCount = $this->getCurrentQueryCount();
  42. $this->assertFalse($user->groups->isInitialized());
  43. $this->assertEquals(3, count($user->groups));
  44. $this->assertFalse($user->groups->isInitialized());
  45. foreach ($user->groups AS $group) { }
  46. $this->assertEquals($queryCount + 2, $this->getCurrentQueryCount(), "Expecting two queries to be fired for count, then iteration.");
  47. }
  48. /**
  49. * @group DDC-546
  50. */
  51. public function testCountWhenNewEntitysPresent()
  52. {
  53. $user = $this->_em->find('Doctrine\Tests\Models\CMS\CmsUser', $this->userId);
  54. $newGroup = new \Doctrine\Tests\Models\CMS\CmsGroup();
  55. $newGroup->name = "Test4";
  56. $user->addGroup($newGroup);
  57. $this->_em->persist($newGroup);
  58. $this->assertFalse($user->groups->isInitialized());
  59. $this->assertEquals(4, count($user->groups));
  60. $this->assertFalse($user->groups->isInitialized());
  61. }
  62. /**
  63. * @group DDC-546
  64. */
  65. public function testCountWhenInitialized()
  66. {
  67. $user = $this->_em->find('Doctrine\Tests\Models\CMS\CmsUser', $this->userId);
  68. $queryCount = $this->getCurrentQueryCount();
  69. foreach ($user->groups AS $group) { }
  70. $this->assertTrue($user->groups->isInitialized());
  71. $this->assertEquals(3, count($user->groups));
  72. $this->assertEquals($queryCount + 1, $this->getCurrentQueryCount(), "Should only execute one query to initialize colleciton, no extra query for count() more.");
  73. }
  74. /**
  75. * @group DDC-546
  76. */
  77. public function testCountInverseCollection()
  78. {
  79. $group = $this->_em->find('Doctrine\Tests\Models\CMS\CmsGroup', $this->groupId);
  80. $this->assertFalse($group->users->isInitialized(), "Pre-Condition");
  81. $this->assertEquals(4, count($group->users));
  82. $this->assertFalse($group->users->isInitialized(), "Extra Lazy collection should not be initialized by counting the collection.");
  83. }
  84. /**
  85. * @group DDC-546
  86. */
  87. public function testCountOneToMany()
  88. {
  89. $user = $this->_em->find('Doctrine\Tests\Models\CMS\CmsUser', $this->userId);
  90. $this->assertFalse($user->groups->isInitialized(), "Pre-Condition");
  91. $this->assertEquals(2, count($user->articles));
  92. }
  93. /**
  94. * @group DDC-546
  95. */
  96. public function testFullSlice()
  97. {
  98. $user = $this->_em->find('Doctrine\Tests\Models\CMS\CmsUser', $this->userId);
  99. $this->assertFalse($user->groups->isInitialized(), "Pre-Condition: Collection is not initialized.");
  100. $someGroups = $user->groups->slice(null);
  101. $this->assertEquals(3, count($someGroups));
  102. }
  103. /**
  104. * @group DDC-546
  105. */
  106. public function testSlice()
  107. {
  108. $user = $this->_em->find('Doctrine\Tests\Models\CMS\CmsUser', $this->userId);
  109. $this->assertFalse($user->groups->isInitialized(), "Pre-Condition: Collection is not initialized.");
  110. $queryCount = $this->getCurrentQueryCount();
  111. $someGroups = $user->groups->slice(0, 2);
  112. $this->assertContainsOnly('Doctrine\Tests\Models\CMS\CmsGroup', $someGroups);
  113. $this->assertEquals(2, count($someGroups));
  114. $this->assertFalse($user->groups->isInitialized(), "Slice should not initialize the collection if it wasn't before!");
  115. $otherGroup = $user->groups->slice(2, 1);
  116. $this->assertContainsOnly('Doctrine\Tests\Models\CMS\CmsGroup', $otherGroup);
  117. $this->assertEquals(1, count($otherGroup));
  118. $this->assertFalse($user->groups->isInitialized());
  119. foreach ($user->groups AS $group) { }
  120. $this->assertTrue($user->groups->isInitialized());
  121. $this->assertEquals(3, count($user->groups));
  122. $this->assertEquals($queryCount + 3, $this->getCurrentQueryCount());
  123. }
  124. /**
  125. * @group DDC-546
  126. */
  127. public function testSliceInitializedCollection()
  128. {
  129. $user = $this->_em->find('Doctrine\Tests\Models\CMS\CmsUser', $this->userId);
  130. $queryCount = $this->getCurrentQueryCount();
  131. foreach ($user->groups AS $group) { }
  132. $someGroups = $user->groups->slice(0, 2);
  133. $this->assertEquals($queryCount + 1, $this->getCurrentQueryCount());
  134. $this->assertEquals(2, count($someGroups));
  135. $this->assertTrue($user->groups->contains($someGroups[0]));
  136. $this->assertTrue($user->groups->contains($someGroups[1]));
  137. }
  138. /**
  139. * @group DDC-546
  140. */
  141. public function testSliceInverseCollection()
  142. {
  143. $group = $this->_em->find('Doctrine\Tests\Models\CMS\CmsGroup', $this->groupId);
  144. $this->assertFalse($group->users->isInitialized(), "Pre-Condition");
  145. $queryCount = $this->getCurrentQueryCount();
  146. $someUsers = $group->users->slice(0, 2);
  147. $otherUsers = $group->users->slice(2, 2);
  148. $this->assertContainsOnly('Doctrine\Tests\Models\CMS\CmsUser', $someUsers);
  149. $this->assertContainsOnly('Doctrine\Tests\Models\CMS\CmsUser', $otherUsers);
  150. $this->assertEquals(2, count($someUsers));
  151. $this->assertEquals(2, count($otherUsers));
  152. // +2 queries executed by slice
  153. $this->assertEquals($queryCount + 2, $this->getCurrentQueryCount(), "Slicing two parts should only execute two additional queries.");
  154. }
  155. /**
  156. * @group DDC-546
  157. */
  158. public function testSliceOneToMany()
  159. {
  160. $user = $this->_em->find('Doctrine\Tests\Models\CMS\CmsUser', $this->userId);
  161. $this->assertFalse($user->articles->isInitialized(), "Pre-Condition: Collection is not initialized.");
  162. $queryCount = $this->getCurrentQueryCount();
  163. $someArticle = $user->articles->slice(0, 1);
  164. $otherArticle = $user->articles->slice(1, 1);
  165. $this->assertEquals($queryCount + 2, $this->getCurrentQueryCount());
  166. }
  167. /**
  168. * @group DDC-546
  169. */
  170. public function testContainsOneToMany()
  171. {
  172. $user = $this->_em->find('Doctrine\Tests\Models\CMS\CmsUser', $this->userId);
  173. $this->assertFalse($user->articles->isInitialized(), "Pre-Condition: Collection is not initialized.");
  174. $article = $this->_em->find('Doctrine\Tests\Models\CMS\CmsArticle', $this->articleId);
  175. $queryCount = $this->getCurrentQueryCount();
  176. $this->assertTrue($user->articles->contains($article));
  177. $this->assertFalse($user->articles->isInitialized(), "Post-Condition: Collection is not initialized.");
  178. $this->assertEquals($queryCount + 1, $this->getCurrentQueryCount());
  179. $article = new \Doctrine\Tests\Models\CMS\CmsArticle();
  180. $article->topic = "Testnew";
  181. $article->text = "blub";
  182. $queryCount = $this->getCurrentQueryCount();
  183. $this->assertFalse($user->articles->contains($article));
  184. $this->assertEquals($queryCount, $this->getCurrentQueryCount(), "Checking for contains of new entity should cause no query to be executed.");
  185. $this->_em->persist($article);
  186. $this->_em->flush();
  187. $queryCount = $this->getCurrentQueryCount();
  188. $this->assertFalse($user->articles->contains($article));
  189. $this->assertEquals($queryCount+1, $this->getCurrentQueryCount(), "Checking for contains of managed entity should cause one query to be executed.");
  190. $this->assertFalse($user->articles->isInitialized(), "Post-Condition: Collection is not initialized.");
  191. }
  192. /**
  193. * @group DDC-546
  194. */
  195. public function testContainsManyToMany()
  196. {
  197. $user = $this->_em->find('Doctrine\Tests\Models\CMS\CmsUser', $this->userId);
  198. $this->assertFalse($user->groups->isInitialized(), "Pre-Condition: Collection is not initialized.");
  199. $group = $this->_em->find('Doctrine\Tests\Models\CMS\CmsGroup', $this->groupId);
  200. $queryCount = $this->getCurrentQueryCount();
  201. $this->assertTrue($user->groups->contains($group));
  202. $this->assertEquals($queryCount+1, $this->getCurrentQueryCount(), "Checking for contains of managed entity should cause one query to be executed.");
  203. $this->assertFalse($user->groups->isInitialized(), "Post-Condition: Collection is not initialized.");
  204. $group = new \Doctrine\Tests\Models\CMS\CmsGroup();
  205. $group->name = "A New group!";
  206. $queryCount = $this->getCurrentQueryCount();
  207. $this->assertFalse($user->groups->contains($group));
  208. $this->assertEquals($queryCount, $this->getCurrentQueryCount(), "Checking for contains of new entity should cause no query to be executed.");
  209. $this->assertFalse($user->groups->isInitialized(), "Post-Condition: Collection is not initialized.");
  210. $this->_em->persist($group);
  211. $this->_em->flush();
  212. $queryCount = $this->getCurrentQueryCount();
  213. $this->assertFalse($user->groups->contains($group));
  214. $this->assertEquals($queryCount+1, $this->getCurrentQueryCount(), "Checking for contains of managed entity should cause one query to be executed.");
  215. $this->assertFalse($user->groups->isInitialized(), "Post-Condition: Collection is not initialized.");
  216. }
  217. /**
  218. * @group DDC-546
  219. */
  220. public function testContainsManyToManyInverse()
  221. {
  222. $group = $this->_em->find('Doctrine\Tests\Models\CMS\CmsGroup', $this->groupId);
  223. $this->assertFalse($group->users->isInitialized(), "Pre-Condition: Collection is not initialized.");
  224. $user = $this->_em->find('Doctrine\Tests\Models\CMS\CmsUser', $this->userId);
  225. $queryCount = $this->getCurrentQueryCount();
  226. $this->assertTrue($group->users->contains($user));
  227. $this->assertEquals($queryCount+1, $this->getCurrentQueryCount(), "Checking for contains of managed entity should cause one query to be executed.");
  228. $this->assertFalse($user->groups->isInitialized(), "Post-Condition: Collection is not initialized.");
  229. $newUser = new \Doctrine\Tests\Models\CMS\CmsUser();
  230. $newUser->name = "A New group!";
  231. $queryCount = $this->getCurrentQueryCount();
  232. $this->assertFalse($group->users->contains($newUser));
  233. $this->assertEquals($queryCount, $this->getCurrentQueryCount(), "Checking for contains of new entity should cause no query to be executed.");
  234. $this->assertFalse($user->groups->isInitialized(), "Post-Condition: Collection is not initialized.");
  235. }
  236. /**
  237. * @group DDC-1399
  238. */
  239. public function testCountAfterAddThenFlush()
  240. {
  241. $user = $this->_em->find('Doctrine\Tests\Models\CMS\CmsUser', $this->userId);
  242. $newGroup = new \Doctrine\Tests\Models\CMS\CmsGroup();
  243. $newGroup->name = "Test4";
  244. $user->addGroup($newGroup);
  245. $this->_em->persist($newGroup);
  246. $this->assertFalse($user->groups->isInitialized());
  247. $this->assertEquals(4, count($user->groups));
  248. $this->assertFalse($user->groups->isInitialized());
  249. $this->_em->flush();
  250. $this->assertEquals(4, count($user->groups));
  251. }
  252. /**
  253. * @group DDC-1462
  254. */
  255. public function testSliceOnDirtyCollection()
  256. {
  257. $user = $this->_em->find('Doctrine\Tests\Models\CMS\CmsUser', $this->userId);
  258. /* @var $user CmsUser */
  259. $newGroup = new \Doctrine\Tests\Models\CMS\CmsGroup();
  260. $newGroup->name = "Test4";
  261. $user->addGroup($newGroup);
  262. $this->_em->persist($newGroup);
  263. $qc = $this->getCurrentQueryCount();
  264. $groups = $user->groups->slice(0, 10);
  265. $this->assertEquals(4, count($groups));
  266. $this->assertEquals($qc + 1, $this->getCurrentQueryCount());
  267. }
  268. private function loadFixture()
  269. {
  270. $user1 = new \Doctrine\Tests\Models\CMS\CmsUser();
  271. $user1->username = "beberlei";
  272. $user1->name = "Benjamin";
  273. $user1->status = "active";
  274. $user2 = new \Doctrine\Tests\Models\CMS\CmsUser();
  275. $user2->username = "jwage";
  276. $user2->name = "Jonathan";
  277. $user2->status = "active";
  278. $user3 = new \Doctrine\Tests\Models\CMS\CmsUser();
  279. $user3->username = "romanb";
  280. $user3->name = "Roman";
  281. $user3->status = "active";
  282. $user4 = new \Doctrine\Tests\Models\CMS\CmsUser();
  283. $user4->username = "gblanco";
  284. $user4->name = "Guilherme";
  285. $user4->status = "active";
  286. $this->_em->persist($user1);
  287. $this->_em->persist($user2);
  288. $this->_em->persist($user3);
  289. $this->_em->persist($user4);
  290. $group1 = new \Doctrine\Tests\Models\CMS\CmsGroup();
  291. $group1->name = "Test1";
  292. $group2 = new \Doctrine\Tests\Models\CMS\CmsGroup();
  293. $group2->name = "Test2";
  294. $group3 = new \Doctrine\Tests\Models\CMS\CmsGroup();
  295. $group3->name = "Test3";
  296. $user1->addGroup($group1);
  297. $user1->addGroup($group2);
  298. $user1->addGroup($group3);
  299. $user2->addGroup($group1);
  300. $user3->addGroup($group1);
  301. $user4->addGroup($group1);
  302. $this->_em->persist($group1);
  303. $this->_em->persist($group2);
  304. $this->_em->persist($group3);
  305. $article1 = new \Doctrine\Tests\Models\CMS\CmsArticle();
  306. $article1->topic = "Test";
  307. $article1->text = "Test";
  308. $article1->setAuthor($user1);
  309. $article2 = new \Doctrine\Tests\Models\CMS\CmsArticle();
  310. $article2->topic = "Test";
  311. $article2->text = "Test";
  312. $article2->setAuthor($user1);
  313. $this->_em->persist($article1);
  314. $this->_em->persist($article2);
  315. $this->_em->flush();
  316. $this->_em->clear();
  317. $this->articleId = $article1->id;
  318. $this->userId = $user1->getId();
  319. $this->groupId = $group1->id;
  320. }
  321. }