ClassTableInheritanceTest.php 16KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452
  1. <?php
  2. namespace Doctrine\Tests\ORM\Functional;
  3. require_once __DIR__ . '/../../TestInit.php';
  4. use Doctrine\Tests\Models\Company\CompanyPerson,
  5. Doctrine\Tests\Models\Company\CompanyEmployee,
  6. Doctrine\Tests\Models\Company\CompanyManager,
  7. Doctrine\Tests\Models\Company\CompanyOrganization,
  8. Doctrine\Tests\Models\Company\CompanyEvent,
  9. Doctrine\Tests\Models\Company\CompanyAuction,
  10. Doctrine\Tests\Models\Company\CompanyRaffle,
  11. Doctrine\Tests\Models\Company\CompanyCar;
  12. /**
  13. * Functional tests for the Class Table Inheritance mapping strategy.
  14. *
  15. * @author robo
  16. */
  17. class ClassTableInheritanceTest extends \Doctrine\Tests\OrmFunctionalTestCase
  18. {
  19. protected function setUp() {
  20. $this->useModelSet('company');
  21. parent::setUp();
  22. //$this->_em->getConnection()->getConfiguration()->setSQLLogger(new \Doctrine\DBAL\Logging\EchoSQLLogger);
  23. }
  24. public function testCRUD()
  25. {
  26. $person = new CompanyPerson;
  27. $person->setName('Roman S. Borschel');
  28. $this->_em->persist($person);
  29. $employee = new CompanyEmployee;
  30. $employee->setName('Roman S. Borschel');
  31. $employee->setSalary(100000);
  32. $employee->setDepartment('IT');
  33. $this->_em->persist($employee);
  34. $employee->setName('Guilherme Blanco');
  35. $this->_em->flush();
  36. $this->_em->clear();
  37. $query = $this->_em->createQuery("select p from Doctrine\Tests\Models\Company\CompanyPerson p order by p.name desc");
  38. $entities = $query->getResult();
  39. $this->assertEquals(2, count($entities));
  40. $this->assertTrue($entities[0] instanceof CompanyPerson);
  41. $this->assertTrue($entities[1] instanceof CompanyEmployee);
  42. $this->assertTrue(is_numeric($entities[0]->getId()));
  43. $this->assertTrue(is_numeric($entities[1]->getId()));
  44. $this->assertEquals('Roman S. Borschel', $entities[0]->getName());
  45. $this->assertEquals('Guilherme Blanco', $entities[1]->getName());
  46. $this->assertEquals(100000, $entities[1]->getSalary());
  47. $this->_em->clear();
  48. $query = $this->_em->createQuery("select p from Doctrine\Tests\Models\Company\CompanyEmployee p");
  49. $entities = $query->getResult();
  50. $this->assertEquals(1, count($entities));
  51. $this->assertTrue($entities[0] instanceof CompanyEmployee);
  52. $this->assertTrue(is_numeric($entities[0]->getId()));
  53. $this->assertEquals('Guilherme Blanco', $entities[0]->getName());
  54. $this->assertEquals(100000, $entities[0]->getSalary());
  55. $this->_em->clear();
  56. $guilherme = $this->_em->getRepository(get_class($employee))->findOneBy(array('name' => 'Guilherme Blanco'));
  57. $this->assertTrue($guilherme instanceof CompanyEmployee);
  58. $this->assertEquals('Guilherme Blanco', $guilherme->getName());
  59. $this->_em->clear();
  60. $query = $this->_em->createQuery("update Doctrine\Tests\Models\Company\CompanyEmployee p set p.name = ?1, p.department = ?2 where p.name='Guilherme Blanco' and p.salary = ?3");
  61. $query->setParameter(1, 'NewName', 'string');
  62. $query->setParameter(2, 'NewDepartment');
  63. $query->setParameter(3, 100000);
  64. $query->getSql();
  65. $numUpdated = $query->execute();
  66. $this->assertEquals(1, $numUpdated);
  67. $query = $this->_em->createQuery("delete from Doctrine\Tests\Models\Company\CompanyPerson p");
  68. $numDeleted = $query->execute();
  69. $this->assertEquals(2, $numDeleted);
  70. }
  71. public function testMultiLevelUpdateAndFind() {
  72. $manager = new CompanyManager;
  73. $manager->setName('Roman S. Borschel');
  74. $manager->setSalary(100000);
  75. $manager->setDepartment('IT');
  76. $manager->setTitle('CTO');
  77. $this->_em->persist($manager);
  78. $this->_em->flush();
  79. $manager->setName('Roman B.');
  80. $manager->setSalary(119000);
  81. $manager->setTitle('CEO');
  82. $this->_em->persist($manager);
  83. $this->_em->flush();
  84. $this->_em->clear();
  85. $manager = $this->_em->find('Doctrine\Tests\Models\Company\CompanyManager', $manager->getId());
  86. $this->assertTrue($manager instanceof CompanyManager);
  87. $this->assertEquals('Roman B.', $manager->getName());
  88. $this->assertEquals(119000, $manager->getSalary());
  89. $this->assertEquals('CEO', $manager->getTitle());
  90. $this->assertTrue(is_numeric($manager->getId()));
  91. }
  92. public function testFindOnBaseClass() {
  93. $manager = new CompanyManager;
  94. $manager->setName('Roman S. Borschel');
  95. $manager->setSalary(100000);
  96. $manager->setDepartment('IT');
  97. $manager->setTitle('CTO');
  98. $this->_em->persist($manager);
  99. $this->_em->flush();
  100. $this->_em->clear();
  101. $person = $this->_em->find('Doctrine\Tests\Models\Company\CompanyPerson', $manager->getId());
  102. $this->assertTrue($person instanceof CompanyManager);
  103. $this->assertEquals('Roman S. Borschel', $person->getName());
  104. $this->assertEquals(100000, $person->getSalary());
  105. $this->assertEquals('CTO', $person->getTitle());
  106. $this->assertTrue(is_numeric($person->getId()));
  107. //$this->assertTrue($person->getCar() instanceof CompanyCar);
  108. }
  109. public function testSelfReferencingOneToOne() {
  110. $manager = new CompanyManager;
  111. $manager->setName('John Smith');
  112. $manager->setSalary(100000);
  113. $manager->setDepartment('IT');
  114. $manager->setTitle('CTO');
  115. $wife = new CompanyPerson;
  116. $wife->setName('Mary Smith');
  117. $wife->setSpouse($manager);
  118. $this->assertSame($manager, $wife->getSpouse());
  119. $this->assertSame($wife, $manager->getSpouse());
  120. $this->_em->persist($manager);
  121. $this->_em->persist($wife);
  122. $this->_em->flush();
  123. //var_dump($this->_em->getConnection()->fetchAll('select * from company_persons'));
  124. //var_dump($this->_em->getConnection()->fetchAll('select * from company_employees'));
  125. //var_dump($this->_em->getConnection()->fetchAll('select * from company_managers'));
  126. $this->_em->clear();
  127. $query = $this->_em->createQuery('select p, s from Doctrine\Tests\Models\Company\CompanyPerson p join p.spouse s where p.name=\'Mary Smith\'');
  128. $result = $query->getResult();
  129. $this->assertEquals(1, count($result));
  130. $this->assertTrue($result[0] instanceof CompanyPerson);
  131. $this->assertEquals('Mary Smith', $result[0]->getName());
  132. $this->assertTrue($result[0]->getSpouse() instanceof CompanyEmployee);
  133. $this->assertEquals('John Smith', $result[0]->getSpouse()->getName());
  134. $this->assertSame($result[0], $result[0]->getSpouse()->getSpouse());
  135. }
  136. public function testSelfReferencingManyToMany()
  137. {
  138. $person1 = new CompanyPerson;
  139. $person1->setName('Roman');
  140. $person2 = new CompanyPerson;
  141. $person2->setName('Jonathan');
  142. $person1->addFriend($person2);
  143. $this->assertEquals(1, count($person1->getFriends()));
  144. $this->assertEquals(1, count($person2->getFriends()));
  145. $this->_em->persist($person1);
  146. $this->_em->persist($person2);
  147. $this->_em->flush();
  148. $this->_em->clear();
  149. $query = $this->_em->createQuery('select p, f from Doctrine\Tests\Models\Company\CompanyPerson p join p.friends f where p.name=?1');
  150. $query->setParameter(1, 'Roman');
  151. $result = $query->getResult();
  152. $this->assertEquals(1, count($result));
  153. $this->assertEquals(1, count($result[0]->getFriends()));
  154. $this->assertEquals('Roman', $result[0]->getName());
  155. $friends = $result[0]->getFriends();
  156. $this->assertEquals('Jonathan', $friends[0]->getName());
  157. }
  158. public function testLazyLoading1()
  159. {
  160. $org = new CompanyOrganization;
  161. $event1 = new CompanyAuction;
  162. $event1->setData('auction');
  163. $org->addEvent($event1);
  164. $event2 = new CompanyRaffle;
  165. $event2->setData('raffle');
  166. $org->addEvent($event2);
  167. $this->_em->persist($org);
  168. $this->_em->flush();
  169. $this->_em->clear();
  170. $orgId = $org->getId();
  171. $q = $this->_em->createQuery('select a from Doctrine\Tests\Models\Company\CompanyOrganization a where a.id = ?1');
  172. $q->setParameter(1, $orgId);
  173. $result = $q->getResult();
  174. $this->assertEquals(1, count($result));
  175. $this->assertTrue($result[0] instanceof CompanyOrganization);
  176. $this->assertNull($result[0]->getMainEvent());
  177. $events = $result[0]->getEvents();
  178. $this->assertTrue($events instanceof \Doctrine\ORM\PersistentCollection);
  179. $this->assertFalse($events->isInitialized());
  180. $this->assertEquals(2, count($events));
  181. if ($events[0] instanceof CompanyAuction) {
  182. $this->assertTrue($events[1] instanceof CompanyRaffle);
  183. } else {
  184. $this->assertTrue($events[0] instanceof CompanyRaffle);
  185. $this->assertTrue($events[1] instanceof CompanyAuction);
  186. }
  187. }
  188. public function testLazyLoading2()
  189. {
  190. $org = new CompanyOrganization;
  191. $event1 = new CompanyAuction;
  192. $event1->setData('auction');
  193. $org->setMainEvent($event1);
  194. $this->_em->persist($org);
  195. $this->_em->flush();
  196. $this->_em->clear();
  197. $q = $this->_em->createQuery('select a from Doctrine\Tests\Models\Company\CompanyEvent a where a.id = ?1');
  198. $q->setParameter(1, $event1->getId());
  199. $result = $q->getResult();
  200. $this->assertEquals(1, count($result));
  201. $this->assertTrue($result[0] instanceof CompanyAuction, sprintf("Is of class %s",get_class($result[0])));
  202. $this->_em->clear();
  203. $q = $this->_em->createQuery('select a from Doctrine\Tests\Models\Company\CompanyOrganization a where a.id = ?1');
  204. $q->setParameter(1, $org->getId());
  205. $result = $q->getResult();
  206. $this->assertEquals(1, count($result));
  207. $this->assertTrue($result[0] instanceof CompanyOrganization);
  208. $mainEvent = $result[0]->getMainEvent();
  209. // mainEvent should have been loaded because it can't be lazy
  210. $this->assertTrue($mainEvent instanceof CompanyAuction);
  211. $this->assertFalse($mainEvent instanceof \Doctrine\ORM\Proxy\Proxy);
  212. }
  213. /**
  214. * @group DDC-368
  215. */
  216. public function testBulkUpdateIssueDDC368()
  217. {
  218. $dql = 'UPDATE Doctrine\Tests\Models\Company\CompanyEmployee AS p SET p.salary = 1';
  219. $this->_em->createQuery($dql)->execute();
  220. $this->assertTrue(count($this->_em->createQuery(
  221. 'SELECT count(p.id) FROM Doctrine\Tests\Models\Company\CompanyEmployee p WHERE p.salary = 1')
  222. ->getResult()) > 0);
  223. }
  224. /**
  225. * @group DDC-1341
  226. */
  227. public function testBulkUpdateNonScalarParameterDDC1341()
  228. {
  229. $dql = 'UPDATE Doctrine\Tests\Models\Company\CompanyEmployee AS p SET p.startDate = ?0 WHERE p.department = ?1';
  230. $query = $this->_em->createQuery($dql)
  231. ->setParameter(0, new \DateTime())
  232. ->setParameter(1, 'IT');
  233. $result = $query->execute();
  234. }
  235. /**
  236. * @group DDC-130
  237. */
  238. public function testDeleteJoinTableRecords()
  239. {
  240. #$this->markTestSkipped('Nightmare! friends adds both ID 6-7 and 7-6 into two rows of the join table. How to detect this?');
  241. $employee1 = new CompanyEmployee();
  242. $employee1->setName('gblanco');
  243. $employee1->setSalary(0);
  244. $employee1->setDepartment('IT');
  245. $employee2 = new CompanyEmployee();
  246. $employee2->setName('jwage');
  247. $employee2->setSalary(0);
  248. $employee2->setDepartment('IT');
  249. $employee1->addFriend($employee2);
  250. $this->_em->persist($employee1);
  251. $this->_em->persist($employee2);
  252. $this->_em->flush();
  253. $employee1Id = $employee1->getId();
  254. $this->_em->remove($employee1);
  255. $this->_em->flush();
  256. $this->assertNull($this->_em->find(get_class($employee1), $employee1Id));
  257. }
  258. /**
  259. * @group DDC-728
  260. */
  261. public function testQueryForInheritedSingleValuedAssociation()
  262. {
  263. $manager = new CompanyManager();
  264. $manager->setName('gblanco');
  265. $manager->setSalary(1234);
  266. $manager->setTitle('Awesome!');
  267. $manager->setDepartment('IT');
  268. $person = new CompanyPerson();
  269. $person->setName('spouse');
  270. $manager->setSpouse($person);
  271. $this->_em->persist($manager);
  272. $this->_em->persist($person);
  273. $this->_em->flush();
  274. $this->_em->clear();
  275. $dql = "SELECT m FROM Doctrine\Tests\Models\Company\CompanyManager m WHERE m.spouse = ?1";
  276. $dqlManager = $this->_em->createQuery($dql)->setParameter(1, $person->getId())->getSingleResult();
  277. $this->assertEquals($manager->getId(), $dqlManager->getId());
  278. $this->assertEquals($person->getId(), $dqlManager->getSpouse()->getId());
  279. }
  280. /**
  281. * @group DDC-817
  282. */
  283. public function testFindByAssociation()
  284. {
  285. $manager = new CompanyManager();
  286. $manager->setName('gblanco');
  287. $manager->setSalary(1234);
  288. $manager->setTitle('Awesome!');
  289. $manager->setDepartment('IT');
  290. $person = new CompanyPerson();
  291. $person->setName('spouse');
  292. $manager->setSpouse($person);
  293. $this->_em->persist($manager);
  294. $this->_em->persist($person);
  295. $this->_em->flush();
  296. $this->_em->clear();
  297. $repos = $this->_em->getRepository('Doctrine\Tests\Models\Company\CompanyManager');
  298. $pmanager = $repos->findOneBy(array('spouse' => $person->getId()));
  299. $this->assertEquals($manager->getId(), $pmanager->getId());
  300. $repos = $this->_em->getRepository('Doctrine\Tests\Models\Company\CompanyPerson');
  301. $pmanager = $repos->findOneBy(array('spouse' => $person->getId()));
  302. $this->assertEquals($manager->getId(), $pmanager->getId());
  303. }
  304. /**
  305. * @group DDC-834
  306. */
  307. public function testGetReferenceEntityWithSubclasses()
  308. {
  309. $manager = new CompanyManager();
  310. $manager->setName('gblanco');
  311. $manager->setSalary(1234);
  312. $manager->setTitle('Awesome!');
  313. $manager->setDepartment('IT');
  314. $this->_em->persist($manager);
  315. $this->_em->flush();
  316. $this->_em->clear();
  317. $ref = $this->_em->getReference('Doctrine\Tests\Models\Company\CompanyPerson', $manager->getId());
  318. $this->assertNotInstanceOf('Doctrine\ORM\Proxy\Proxy', $ref, "Cannot Request a proxy from a class that has subclasses.");
  319. $this->assertInstanceOf('Doctrine\Tests\Models\Company\CompanyPerson', $ref);
  320. $this->assertInstanceOf('Doctrine\Tests\Models\Company\CompanyEmployee', $ref, "Direct fetch of the reference has to load the child class Emplyoee directly.");
  321. $this->_em->clear();
  322. $ref = $this->_em->getReference('Doctrine\Tests\Models\Company\CompanyManager', $manager->getId());
  323. $this->assertInstanceOf('Doctrine\ORM\Proxy\Proxy', $ref, "A proxy can be generated only if no subclasses exists for the requested reference.");
  324. }
  325. /**
  326. * @group DDC-992
  327. */
  328. public function testGetSubClassManyToManyCollection()
  329. {
  330. $manager = new CompanyManager();
  331. $manager->setName('gblanco');
  332. $manager->setSalary(1234);
  333. $manager->setTitle('Awesome!');
  334. $manager->setDepartment('IT');
  335. $person = new CompanyPerson();
  336. $person->setName('friend');
  337. $manager->addFriend($person);
  338. $this->_em->persist($manager);
  339. $this->_em->persist($person);
  340. $this->_em->flush();
  341. $this->_em->clear();
  342. $manager = $this->_em->find('Doctrine\Tests\Models\Company\CompanyManager', $manager->getId());
  343. $this->assertEquals(1, count($manager->getFriends()));
  344. }
  345. }