NativeQueryTest.php 13KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334
  1. <?php
  2. namespace Doctrine\Tests\ORM\Functional;
  3. use Doctrine\ORM\Query\ResultSetMapping;
  4. use Doctrine\ORM\Query\ResultSetMappingBuilder;
  5. use Doctrine\Tests\Models\CMS\CmsUser;
  6. use Doctrine\Tests\Models\CMS\CmsPhonenumber;
  7. use Doctrine\Tests\Models\CMS\CmsAddress;
  8. use Doctrine\Tests\Models\Company\CompanyFixContract;
  9. use Doctrine\Tests\Models\Company\CompanyEmployee;
  10. require_once __DIR__ . '/../../TestInit.php';
  11. /**
  12. * NativeQueryTest
  13. *
  14. * @author robo
  15. */
  16. class NativeQueryTest extends \Doctrine\Tests\OrmFunctionalTestCase
  17. {
  18. private $platform = null;
  19. protected function setUp() {
  20. $this->useModelSet('cms');
  21. parent::setUp();
  22. $this->platform = $this->_em->getConnection()->getDatabasePlatform();
  23. }
  24. public function testBasicNativeQuery()
  25. {
  26. $user = new CmsUser;
  27. $user->name = 'Roman';
  28. $user->username = 'romanb';
  29. $user->status = 'dev';
  30. $this->_em->persist($user);
  31. $this->_em->flush();
  32. $this->_em->clear();
  33. $rsm = new ResultSetMapping;
  34. $rsm->addEntityResult('Doctrine\Tests\Models\CMS\CmsUser', 'u');
  35. $rsm->addFieldResult('u', $this->platform->getSQLResultCasing('id'), 'id');
  36. $rsm->addFieldResult('u', $this->platform->getSQLResultCasing('name'), 'name');
  37. $query = $this->_em->createNativeQuery('SELECT id, name FROM cms_users WHERE username = ?', $rsm);
  38. $query->setParameter(1, 'romanb');
  39. $users = $query->getResult();
  40. $this->assertEquals(1, count($users));
  41. $this->assertTrue($users[0] instanceof CmsUser);
  42. $this->assertEquals('Roman', $users[0]->name);
  43. }
  44. public function testBasicNativeQueryWithMetaResult()
  45. {
  46. $user = new CmsUser;
  47. $user->name = 'Roman';
  48. $user->username = 'romanb';
  49. $user->status = 'dev';
  50. $addr = new CmsAddress;
  51. $addr->country = 'germany';
  52. $addr->zip = 10827;
  53. $addr->city = 'Berlin';
  54. $user->setAddress($addr);
  55. $this->_em->persist($user);
  56. $this->_em->flush();
  57. $this->_em->clear();
  58. $rsm = new ResultSetMapping;
  59. $rsm->addEntityResult('Doctrine\Tests\Models\CMS\CmsAddress', 'a');
  60. $rsm->addFieldResult('a', $this->platform->getSQLResultCasing('id'), 'id');
  61. $rsm->addFieldResult('a', $this->platform->getSQLResultCasing('country'), 'country');
  62. $rsm->addFieldResult('a', $this->platform->getSQLResultCasing('zip'), 'zip');
  63. $rsm->addFieldResult('a', $this->platform->getSQLResultCasing('city'), 'city');
  64. $rsm->addMetaResult('a', $this->platform->getSQLResultCasing('user_id'), 'user_id');
  65. $query = $this->_em->createNativeQuery('SELECT a.id, a.country, a.zip, a.city, a.user_id FROM cms_addresses a WHERE a.id = ?', $rsm);
  66. $query->setParameter(1, $addr->id);
  67. $addresses = $query->getResult();
  68. $this->assertEquals(1, count($addresses));
  69. $this->assertTrue($addresses[0] instanceof CmsAddress);
  70. $this->assertEquals($addr->country, $addresses[0]->country);
  71. $this->assertEquals($addr->zip, $addresses[0]->zip);
  72. $this->assertEquals($addr->city, $addresses[0]->city);
  73. $this->assertEquals($addr->street, $addresses[0]->street);
  74. $this->assertTrue($addresses[0]->user instanceof CmsUser);
  75. }
  76. public function testJoinedOneToManyNativeQuery()
  77. {
  78. $user = new CmsUser;
  79. $user->name = 'Roman';
  80. $user->username = 'romanb';
  81. $user->status = 'dev';
  82. $phone = new CmsPhonenumber;
  83. $phone->phonenumber = 424242;
  84. $user->addPhonenumber($phone);
  85. $this->_em->persist($user);
  86. $this->_em->flush();
  87. $this->_em->clear();
  88. $rsm = new ResultSetMapping;
  89. $rsm->addEntityResult('Doctrine\Tests\Models\CMS\CmsUser', 'u');
  90. $rsm->addFieldResult('u', $this->platform->getSQLResultCasing('id'), 'id');
  91. $rsm->addFieldResult('u', $this->platform->getSQLResultCasing('name'), 'name');
  92. $rsm->addFieldResult('u', $this->platform->getSQLResultCasing('status'), 'status');
  93. $rsm->addJoinedEntityResult('Doctrine\Tests\Models\CMS\CmsPhonenumber', 'p', 'u', 'phonenumbers');
  94. $rsm->addFieldResult('p', $this->platform->getSQLResultCasing('phonenumber'), 'phonenumber');
  95. $query = $this->_em->createNativeQuery('SELECT id, name, status, phonenumber FROM cms_users INNER JOIN cms_phonenumbers ON id = user_id WHERE username = ?', $rsm);
  96. $query->setParameter(1, 'romanb');
  97. $users = $query->getResult();
  98. $this->assertEquals(1, count($users));
  99. $this->assertTrue($users[0] instanceof CmsUser);
  100. $this->assertEquals('Roman', $users[0]->name);
  101. $this->assertTrue($users[0]->getPhonenumbers() instanceof \Doctrine\ORM\PersistentCollection);
  102. $this->assertTrue($users[0]->getPhonenumbers()->isInitialized());
  103. $this->assertEquals(1, count($users[0]->getPhonenumbers()));
  104. $phones = $users[0]->getPhonenumbers();
  105. $this->assertEquals(424242, $phones[0]->phonenumber);
  106. $this->assertTrue($phones[0]->getUser() === $users[0]);
  107. }
  108. public function testJoinedOneToOneNativeQuery()
  109. {
  110. $user = new CmsUser;
  111. $user->name = 'Roman';
  112. $user->username = 'romanb';
  113. $user->status = 'dev';
  114. $addr = new CmsAddress;
  115. $addr->country = 'germany';
  116. $addr->zip = 10827;
  117. $addr->city = 'Berlin';
  118. $user->setAddress($addr);
  119. $this->_em->persist($user);
  120. $this->_em->flush();
  121. $this->_em->clear();
  122. $rsm = new ResultSetMapping;
  123. $rsm->addEntityResult('Doctrine\Tests\Models\CMS\CmsUser', 'u');
  124. $rsm->addFieldResult('u', $this->platform->getSQLResultCasing('id'), 'id');
  125. $rsm->addFieldResult('u', $this->platform->getSQLResultCasing('name'), 'name');
  126. $rsm->addFieldResult('u', $this->platform->getSQLResultCasing('status'), 'status');
  127. $rsm->addJoinedEntityResult('Doctrine\Tests\Models\CMS\CmsAddress', 'a', 'u', 'address');
  128. $rsm->addFieldResult('a', $this->platform->getSQLResultCasing('a_id'), 'id');
  129. $rsm->addFieldResult('a', $this->platform->getSQLResultCasing('country'), 'country');
  130. $rsm->addFieldResult('a', $this->platform->getSQLResultCasing('zip'), 'zip');
  131. $rsm->addFieldResult('a', $this->platform->getSQLResultCasing('city'), 'city');
  132. $query = $this->_em->createNativeQuery('SELECT u.id, u.name, u.status, a.id AS a_id, a.country, a.zip, a.city FROM cms_users u INNER JOIN cms_addresses a ON u.id = a.user_id WHERE u.username = ?', $rsm);
  133. $query->setParameter(1, 'romanb');
  134. $users = $query->getResult();
  135. $this->assertEquals(1, count($users));
  136. $this->assertTrue($users[0] instanceof CmsUser);
  137. $this->assertEquals('Roman', $users[0]->name);
  138. $this->assertTrue($users[0]->getPhonenumbers() instanceof \Doctrine\ORM\PersistentCollection);
  139. $this->assertFalse($users[0]->getPhonenumbers()->isInitialized());
  140. $this->assertTrue($users[0]->getAddress() instanceof CmsAddress);
  141. $this->assertTrue($users[0]->getAddress()->getUser() == $users[0]);
  142. $this->assertEquals('germany', $users[0]->getAddress()->getCountry());
  143. $this->assertEquals(10827, $users[0]->getAddress()->getZipCode());
  144. $this->assertEquals('Berlin', $users[0]->getAddress()->getCity());
  145. }
  146. public function testFluentInterface()
  147. {
  148. $rsm = new ResultSetMapping;
  149. $q = $this->_em->createNativeQuery('SELECT id, name, status, phonenumber FROM cms_users INNER JOIN cms_phonenumbers ON id = user_id WHERE username = ?', $rsm);
  150. $q2 = $q->setSql('foo', $rsm)
  151. ->setResultSetMapping($rsm)
  152. ->expireResultCache(true)
  153. ->setHint('foo', 'bar')
  154. ->setParameter(1, 'foo')
  155. ->setParameters(array(2 => 'bar'))
  156. ->setResultCacheDriver(null)
  157. ->setResultCacheLifetime(3500);
  158. $this->assertSame($q, $q2);
  159. }
  160. public function testJoinedOneToManyNativeQueryWithRSMBuilder()
  161. {
  162. $user = new CmsUser;
  163. $user->name = 'Roman';
  164. $user->username = 'romanb';
  165. $user->status = 'dev';
  166. $phone = new CmsPhonenumber;
  167. $phone->phonenumber = 424242;
  168. $user->addPhonenumber($phone);
  169. $this->_em->persist($user);
  170. $this->_em->flush();
  171. $this->_em->clear();
  172. $rsm = new ResultSetMappingBuilder($this->_em);
  173. $rsm->addRootEntityFromClassMetadata('Doctrine\Tests\Models\CMS\CmsUser', 'u');
  174. $rsm->addJoinedEntityFromClassMetadata('Doctrine\Tests\Models\CMS\CmsPhonenumber', 'p', 'u', 'phonenumbers');
  175. $query = $this->_em->createNativeQuery('SELECT u.*, p.* FROM cms_users u LEFT JOIN cms_phonenumbers p ON u.id = p.user_id WHERE username = ?', $rsm);
  176. $query->setParameter(1, 'romanb');
  177. $users = $query->getResult();
  178. $this->assertEquals(1, count($users));
  179. $this->assertTrue($users[0] instanceof CmsUser);
  180. $this->assertEquals('Roman', $users[0]->name);
  181. $this->assertTrue($users[0]->getPhonenumbers() instanceof \Doctrine\ORM\PersistentCollection);
  182. $this->assertTrue($users[0]->getPhonenumbers()->isInitialized());
  183. $this->assertEquals(1, count($users[0]->getPhonenumbers()));
  184. $phones = $users[0]->getPhonenumbers();
  185. $this->assertEquals(424242, $phones[0]->phonenumber);
  186. $this->assertTrue($phones[0]->getUser() === $users[0]);
  187. $this->_em->clear();
  188. $rsm = new ResultSetMappingBuilder($this->_em);
  189. $rsm->addRootEntityFromClassMetadata('Doctrine\Tests\Models\CMS\CmsPhonenumber', 'p');
  190. $query = $this->_em->createNativeQuery('SELECT p.* FROM cms_phonenumbers p WHERE p.phonenumber = ?', $rsm);
  191. $query->setParameter(1, $phone->phonenumber);
  192. $phone = $query->getSingleResult();
  193. $this->assertNotNull($phone->getUser());
  194. $this->assertEquals($user->name, $phone->getUser()->getName());
  195. }
  196. public function testJoinedOneToOneNativeQueryWithRSMBuilder()
  197. {
  198. $user = new CmsUser;
  199. $user->name = 'Roman';
  200. $user->username = 'romanb';
  201. $user->status = 'dev';
  202. $addr = new CmsAddress;
  203. $addr->country = 'germany';
  204. $addr->zip = 10827;
  205. $addr->city = 'Berlin';
  206. $user->setAddress($addr);
  207. $this->_em->persist($user);
  208. $this->_em->flush();
  209. $this->_em->clear();
  210. $rsm = new ResultSetMappingBuilder($this->_em);
  211. $rsm->addRootEntityFromClassMetadata('Doctrine\Tests\Models\CMS\CmsUser', 'u');
  212. $rsm->addJoinedEntityFromClassMetadata('Doctrine\Tests\Models\CMS\CmsAddress', 'a', 'u', 'address', array('id' => 'a_id'));
  213. $query = $this->_em->createNativeQuery('SELECT u.*, a.*, a.id AS a_id FROM cms_users u INNER JOIN cms_addresses a ON u.id = a.user_id WHERE u.username = ?', $rsm);
  214. $query->setParameter(1, 'romanb');
  215. $users = $query->getResult();
  216. $this->assertEquals(1, count($users));
  217. $this->assertTrue($users[0] instanceof CmsUser);
  218. $this->assertEquals('Roman', $users[0]->name);
  219. $this->assertTrue($users[0]->getPhonenumbers() instanceof \Doctrine\ORM\PersistentCollection);
  220. $this->assertFalse($users[0]->getPhonenumbers()->isInitialized());
  221. $this->assertTrue($users[0]->getAddress() instanceof CmsAddress);
  222. $this->assertTrue($users[0]->getAddress()->getUser() == $users[0]);
  223. $this->assertEquals('germany', $users[0]->getAddress()->getCountry());
  224. $this->assertEquals(10827, $users[0]->getAddress()->getZipCode());
  225. $this->assertEquals('Berlin', $users[0]->getAddress()->getCity());
  226. $this->_em->clear();
  227. $rsm = new ResultSetMappingBuilder($this->_em);
  228. $rsm->addRootEntityFromClassMetadata('Doctrine\Tests\Models\CMS\CmsAddress', 'a');
  229. $query = $this->_em->createNativeQuery('SELECT a.* FROM cms_addresses a WHERE a.id = ?', $rsm);
  230. $query->setParameter(1, $addr->getId());
  231. $address = $query->getSingleResult();
  232. $this->assertNotNull($address->getUser());
  233. $this->assertEquals($user->name, $address->getUser()->getName());
  234. }
  235. /**
  236. * @expectedException \InvalidArgumentException
  237. */
  238. public function testRSMBuilderThrowsExceptionOnColumnConflict()
  239. {
  240. $rsm = new ResultSetMappingBuilder($this->_em);
  241. $rsm->addRootEntityFromClassMetadata('Doctrine\Tests\Models\CMS\CmsUser', 'u');
  242. $rsm->addJoinedEntityFromClassMetadata('Doctrine\Tests\Models\CMS\CmsAddress', 'a', 'u', 'address');
  243. }
  244. /**
  245. * @group PR-39
  246. */
  247. public function testUnknownParentAliasThrowsException()
  248. {
  249. $rsm = new ResultSetMappingBuilder($this->_em);
  250. $rsm->addRootEntityFromClassMetadata('Doctrine\Tests\Models\CMS\CmsUser', 'u');
  251. $rsm->addJoinedEntityFromClassMetadata('Doctrine\Tests\Models\CMS\CmsAddress', 'a', 'un', 'address', array('id' => 'a_id'));
  252. $query = $this->_em->createNativeQuery('SELECT u.*, a.*, a.id AS a_id FROM cms_users u INNER JOIN cms_addresses a ON u.id = a.user_id WHERE u.username = ?', $rsm);
  253. $query->setParameter(1, 'romanb');
  254. $this->setExpectedException(
  255. "Doctrine\ORM\Internal\Hydration\HydrationException",
  256. "The parent object of entity result with alias 'a' was not found. The parent alias is 'un'."
  257. );
  258. $users = $query->getResult();
  259. }
  260. }