QueryTest.php 19KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573
  1. <?php
  2. namespace Doctrine\Tests\ORM\Functional;
  3. use Doctrine\DBAL\Connection;
  4. use Doctrine\Tests\Models\CMS\CmsUser,
  5. Doctrine\Tests\Models\CMS\CmsArticle;
  6. use Doctrine\ORM\Mapping\ClassMetadata;
  7. use Doctrine\ORM\Query;
  8. require_once __DIR__ . '/../../TestInit.php';
  9. /**
  10. * Functional Query tests.
  11. *
  12. * @author robo
  13. */
  14. class QueryTest extends \Doctrine\Tests\OrmFunctionalTestCase
  15. {
  16. protected function setUp()
  17. {
  18. $this->useModelSet('cms');
  19. parent::setUp();
  20. }
  21. public function testSimpleQueries()
  22. {
  23. $user = new CmsUser;
  24. $user->name = 'Guilherme';
  25. $user->username = 'gblanco';
  26. $user->status = 'developer';
  27. $this->_em->persist($user);
  28. $this->_em->flush();
  29. $this->_em->clear();
  30. $query = $this->_em->createQuery("select u, upper(u.name) from Doctrine\Tests\Models\CMS\CmsUser u where u.username = 'gblanco'");
  31. $result = $query->getResult();
  32. $this->assertEquals(1, count($result));
  33. $this->assertTrue($result[0][0] instanceof CmsUser);
  34. $this->assertEquals('Guilherme', $result[0][0]->name);
  35. $this->assertEquals('gblanco', $result[0][0]->username);
  36. $this->assertEquals('developer', $result[0][0]->status);
  37. $this->assertEquals('GUILHERME', $result[0][1]);
  38. $resultArray = $query->getArrayResult();
  39. $this->assertEquals(1, count($resultArray));
  40. $this->assertTrue(is_array($resultArray[0][0]));
  41. $this->assertEquals('Guilherme', $resultArray[0][0]['name']);
  42. $this->assertEquals('gblanco', $resultArray[0][0]['username']);
  43. $this->assertEquals('developer', $resultArray[0][0]['status']);
  44. $this->assertEquals('GUILHERME', $resultArray[0][1]);
  45. $scalarResult = $query->getScalarResult();
  46. $this->assertEquals(1, count($scalarResult));
  47. $this->assertEquals('Guilherme', $scalarResult[0]['u_name']);
  48. $this->assertEquals('gblanco', $scalarResult[0]['u_username']);
  49. $this->assertEquals('developer', $scalarResult[0]['u_status']);
  50. $this->assertEquals('GUILHERME', $scalarResult[0][1]);
  51. $query = $this->_em->createQuery("select upper(u.name) from Doctrine\Tests\Models\CMS\CmsUser u where u.username = 'gblanco'");
  52. $this->assertEquals('GUILHERME', $query->getSingleScalarResult());
  53. }
  54. public function testJoinQueries()
  55. {
  56. $user = new CmsUser;
  57. $user->name = 'Guilherme';
  58. $user->username = 'gblanco';
  59. $user->status = 'developer';
  60. $article1 = new CmsArticle;
  61. $article1->topic = "Doctrine 2";
  62. $article1->text = "This is an introduction to Doctrine 2.";
  63. $user->addArticle($article1);
  64. $article2 = new CmsArticle;
  65. $article2->topic = "Symfony 2";
  66. $article2->text = "This is an introduction to Symfony 2.";
  67. $user->addArticle($article2);
  68. $this->_em->persist($user);
  69. $this->_em->persist($article1);
  70. $this->_em->persist($article2);
  71. $this->_em->flush();
  72. $this->_em->clear();
  73. $query = $this->_em->createQuery("select u, a from Doctrine\Tests\Models\CMS\CmsUser u join u.articles a");
  74. $users = $query->getResult();
  75. $this->assertEquals(1, count($users));
  76. $this->assertTrue($users[0] instanceof CmsUser);
  77. $this->assertEquals(2, count($users[0]->articles));
  78. $this->assertEquals('Doctrine 2', $users[0]->articles[0]->topic);
  79. $this->assertEquals('Symfony 2', $users[0]->articles[1]->topic);
  80. }
  81. public function testUsingZeroBasedQueryParameterShouldWork()
  82. {
  83. $user = new CmsUser;
  84. $user->name = 'Jonathan';
  85. $user->username = 'jwage';
  86. $user->status = 'developer';
  87. $this->_em->persist($user);
  88. $this->_em->flush();
  89. $this->_em->clear();
  90. $q = $this->_em->createQuery('SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.username = ?0');
  91. $q->setParameter(0, 'jwage');
  92. $user = $q->getSingleResult();
  93. $this->assertNotNull($user);
  94. }
  95. public function testUsingUnknownQueryParameterShouldThrowException()
  96. {
  97. $this->setExpectedException(
  98. "Doctrine\ORM\Query\QueryException",
  99. "Invalid parameter: token 2 is not defined in the query."
  100. );
  101. $q = $this->_em->createQuery('SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.name = ?1');
  102. $q->setParameter(2, 'jwage');
  103. $user = $q->getSingleResult();
  104. }
  105. public function testMismatchingParamExpectedParamCount()
  106. {
  107. $this->setExpectedException(
  108. "Doctrine\ORM\Query\QueryException",
  109. "Invalid parameter number: number of bound variables does not match number of tokens"
  110. );
  111. $q = $this->_em->createQuery('SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.name = ?1');
  112. $q->setParameter(1, 'jwage');
  113. $q->setParameter(2, 'jwage');
  114. $user = $q->getSingleResult();
  115. }
  116. public function testInvalidInputParameterThrowsException()
  117. {
  118. $this->setExpectedException("Doctrine\ORM\Query\QueryException");
  119. $q = $this->_em->createQuery('SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.name = ?');
  120. $q->setParameter(1, 'jwage');
  121. $user = $q->getSingleResult();
  122. }
  123. public function testSetParameters()
  124. {
  125. $q = $this->_em->createQuery('SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.name = ?1 AND u.status = ?2');
  126. $q->setParameters(array(1 => 'jwage', 2 => 'active'));
  127. $users = $q->getResult();
  128. }
  129. /**
  130. * @group DDC-1070
  131. */
  132. public function testIterateResultAsArrayAndParams()
  133. {
  134. $article1 = new CmsArticle;
  135. $article1->topic = "Doctrine 2";
  136. $article1->text = "This is an introduction to Doctrine 2.";
  137. $article2 = new CmsArticle;
  138. $article2->topic = "Symfony 2";
  139. $article2->text = "This is an introduction to Symfony 2.";
  140. $this->_em->persist($article1);
  141. $this->_em->persist($article2);
  142. $this->_em->flush();
  143. $this->_em->clear();
  144. $articleId = $article1->id;
  145. $query = $this->_em->createQuery("select a from Doctrine\Tests\Models\CMS\CmsArticle a WHERE a.topic = ?1");
  146. $articles = $query->iterate(array(1 => 'Doctrine 2'), Query::HYDRATE_ARRAY);
  147. $found = array();
  148. foreach ($articles AS $article) {
  149. $found[] = $article;
  150. }
  151. $this->assertEquals(1, count($found));
  152. $this->assertEquals(array(
  153. array(array('id' => $articleId, 'topic' => 'Doctrine 2', 'text' => 'This is an introduction to Doctrine 2.', 'version' => 1))
  154. ), $found);
  155. }
  156. public function testIterateResult_IterativelyBuildUpUnitOfWork()
  157. {
  158. $article1 = new CmsArticle;
  159. $article1->topic = "Doctrine 2";
  160. $article1->text = "This is an introduction to Doctrine 2.";
  161. $article2 = new CmsArticle;
  162. $article2->topic = "Symfony 2";
  163. $article2->text = "This is an introduction to Symfony 2.";
  164. $this->_em->persist($article1);
  165. $this->_em->persist($article2);
  166. $this->_em->flush();
  167. $this->_em->clear();
  168. $query = $this->_em->createQuery("select a from Doctrine\Tests\Models\CMS\CmsArticle a");
  169. $articles = $query->iterate();
  170. $iteratedCount = 0;
  171. $topics = array();
  172. foreach($articles AS $row) {
  173. $article = $row[0];
  174. $topics[] = $article->topic;
  175. $identityMap = $this->_em->getUnitOfWork()->getIdentityMap();
  176. $identityMapCount = count($identityMap['Doctrine\Tests\Models\CMS\CmsArticle']);
  177. $this->assertTrue($identityMapCount>$iteratedCount);
  178. $iteratedCount++;
  179. }
  180. $this->assertEquals(array("Doctrine 2", "Symfony 2"), $topics);
  181. $this->assertEquals(2, $iteratedCount);
  182. $this->_em->flush();
  183. $this->_em->clear();
  184. }
  185. /**
  186. * @expectedException \Doctrine\ORM\Query\QueryException
  187. */
  188. public function testIterateResult_FetchJoinedCollection_ThrowsException()
  189. {
  190. $query = $this->_em->createQuery("SELECT u, a FROM Doctrine\Tests\Models\CMS\CmsUser u JOIN u.articles a");
  191. $articles = $query->iterate();
  192. }
  193. /**
  194. * @expectedException Doctrine\ORM\NoResultException
  195. */
  196. public function testGetSingleResultThrowsExceptionOnNoResult()
  197. {
  198. $this->_em->createQuery("select a from Doctrine\Tests\Models\CMS\CmsArticle a")
  199. ->getSingleResult();
  200. }
  201. /**
  202. * @expectedException Doctrine\ORM\NoResultException
  203. */
  204. public function testGetSingleScalarResultThrowsExceptionOnNoResult()
  205. {
  206. $this->_em->createQuery("select a from Doctrine\Tests\Models\CMS\CmsArticle a")
  207. ->getSingleScalarResult();
  208. }
  209. /**
  210. * @expectedException Doctrine\ORM\NonUniqueResultException
  211. */
  212. public function testGetSingleScalarResultThrowsExceptionOnNonUniqueResult()
  213. {
  214. $user = new CmsUser;
  215. $user->name = 'Guilherme';
  216. $user->username = 'gblanco';
  217. $user->status = 'developer';
  218. $article1 = new CmsArticle;
  219. $article1->topic = "Doctrine 2";
  220. $article1->text = "This is an introduction to Doctrine 2.";
  221. $user->addArticle($article1);
  222. $article2 = new CmsArticle;
  223. $article2->topic = "Symfony 2";
  224. $article2->text = "This is an introduction to Symfony 2.";
  225. $user->addArticle($article2);
  226. $this->_em->persist($user);
  227. $this->_em->persist($article1);
  228. $this->_em->persist($article2);
  229. $this->_em->flush();
  230. $this->_em->clear();
  231. $this->_em->createQuery("select a from Doctrine\Tests\Models\CMS\CmsArticle a")
  232. ->getSingleScalarResult();
  233. }
  234. public function testModifiedLimitQuery()
  235. {
  236. for ($i = 0; $i < 5; $i++) {
  237. $user = new CmsUser;
  238. $user->name = 'Guilherme' . $i;
  239. $user->username = 'gblanco' . $i;
  240. $user->status = 'developer';
  241. $this->_em->persist($user);
  242. }
  243. $this->_em->flush();
  244. $this->_em->clear();
  245. $data = $this->_em->createQuery('SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u')
  246. ->setFirstResult(1)
  247. ->setMaxResults(2)
  248. ->getResult();
  249. $this->assertEquals(2, count($data));
  250. $this->assertEquals('gblanco1', $data[0]->username);
  251. $this->assertEquals('gblanco2', $data[1]->username);
  252. $data = $this->_em->createQuery('SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u')
  253. ->setFirstResult(3)
  254. ->setMaxResults(2)
  255. ->getResult();
  256. $this->assertEquals(2, count($data));
  257. $this->assertEquals('gblanco3', $data[0]->username);
  258. $this->assertEquals('gblanco4', $data[1]->username);
  259. $data = $this->_em->createQuery('SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u')
  260. ->setFirstResult(3)
  261. ->setMaxResults(2)
  262. ->getScalarResult();
  263. }
  264. public function testSupportsQueriesWithEntityNamespaces()
  265. {
  266. $this->_em->getConfiguration()->addEntityNamespace('CMS', 'Doctrine\Tests\Models\CMS');
  267. try {
  268. $query = $this->_em->createQuery('UPDATE CMS:CmsUser u SET u.name = ?1');
  269. $this->assertEquals('UPDATE cms_users SET name = ?', $query->getSql());
  270. $query->free();
  271. } catch (\Exception $e) {
  272. $this->fail($e->getMessage());
  273. }
  274. $this->_em->getConfiguration()->setEntityNamespaces(array());
  275. }
  276. /**
  277. * @group DDC-604
  278. */
  279. public function testEntityParameters()
  280. {
  281. $article = new CmsArticle;
  282. $article->topic = "dr. dolittle";
  283. $article->text = "Once upon a time ...";
  284. $author = new CmsUser;
  285. $author->name = "anonymous";
  286. $author->username = "anon";
  287. $author->status = "here";
  288. $article->user = $author;
  289. $this->_em->persist($author);
  290. $this->_em->persist($article);
  291. $this->_em->flush();
  292. $this->_em->clear();
  293. //$this->_em->getConnection()->getConfiguration()->setSQLLogger(new \Doctrine\DBAL\Logging\EchoSQLLogger);
  294. $q = $this->_em->createQuery("select a from Doctrine\Tests\Models\CMS\CmsArticle a where a.topic = :topic and a.user = :user")
  295. ->setParameter("user", $this->_em->getReference('Doctrine\Tests\Models\CMS\CmsUser', $author->id))
  296. ->setParameter("topic", "dr. dolittle");
  297. $result = $q->getResult();
  298. $this->assertEquals(1, count($result));
  299. $this->assertTrue($result[0] instanceof CmsArticle);
  300. $this->assertEquals("dr. dolittle", $result[0]->topic);
  301. $this->assertTrue($result[0]->user instanceof \Doctrine\ORM\Proxy\Proxy);
  302. $this->assertFalse($result[0]->user->__isInitialized__);
  303. }
  304. /**
  305. * @group DDC-952
  306. */
  307. public function testEnableFetchEagerMode()
  308. {
  309. for ($i = 0; $i < 10; $i++) {
  310. $article = new CmsArticle;
  311. $article->topic = "dr. dolittle";
  312. $article->text = "Once upon a time ...";
  313. $author = new CmsUser;
  314. $author->name = "anonymous";
  315. $author->username = "anon".$i;
  316. $author->status = "here";
  317. $article->user = $author;
  318. $this->_em->persist($author);
  319. $this->_em->persist($article);
  320. }
  321. $this->_em->flush();
  322. $this->_em->clear();
  323. $articles = $this->_em->createQuery('select a from Doctrine\Tests\Models\CMS\CmsArticle a')
  324. ->setFetchMode('Doctrine\Tests\Models\CMS\CmsArticle', 'user', ClassMetadata::FETCH_EAGER)
  325. ->getResult();
  326. $this->assertEquals(10, count($articles));
  327. foreach ($articles AS $article) {
  328. $this->assertNotInstanceOf('Doctrine\ORM\Proxy\Proxy', $article);
  329. }
  330. }
  331. /**
  332. * @group DDC-991
  333. */
  334. public function testgetOneOrNullResult()
  335. {
  336. $user = new CmsUser;
  337. $user->name = 'Guilherme';
  338. $user->username = 'gblanco';
  339. $user->status = 'developer';
  340. $this->_em->persist($user);
  341. $this->_em->flush();
  342. $this->_em->clear();
  343. $query = $this->_em->createQuery("select u from Doctrine\Tests\Models\CMS\CmsUser u where u.username = 'gblanco'");
  344. $fetchedUser = $query->getOneOrNullResult();
  345. $this->assertInstanceOf('Doctrine\Tests\Models\CMS\CmsUser', $fetchedUser);
  346. $this->assertEquals('gblanco', $fetchedUser->username);
  347. $query = $this->_em->createQuery("select u.username from Doctrine\Tests\Models\CMS\CmsUser u where u.username = 'gblanco'");
  348. $fetchedUsername = $query->getOneOrNullResult(Query::HYDRATE_SINGLE_SCALAR);
  349. $this->assertEquals('gblanco', $fetchedUsername);
  350. }
  351. /**
  352. * @group DDC-991
  353. */
  354. public function testgetOneOrNullResultSeveralRows()
  355. {
  356. $user = new CmsUser;
  357. $user->name = 'Guilherme';
  358. $user->username = 'gblanco';
  359. $user->status = 'developer';
  360. $this->_em->persist($user);
  361. $user = new CmsUser;
  362. $user->name = 'Roman';
  363. $user->username = 'romanb';
  364. $user->status = 'developer';
  365. $this->_em->persist($user);
  366. $this->_em->flush();
  367. $this->_em->clear();
  368. $query = $this->_em->createQuery("select u from Doctrine\Tests\Models\CMS\CmsUser u");
  369. $this->setExpectedException('Doctrine\ORM\NonUniqueResultException');
  370. $fetchedUser = $query->getOneOrNullResult();
  371. }
  372. /**
  373. * @group DDC-991
  374. */
  375. public function testgetOneOrNullResultNoRows()
  376. {
  377. $query = $this->_em->createQuery("select u from Doctrine\Tests\Models\CMS\CmsUser u");
  378. $this->assertNull($query->getOneOrNullResult());
  379. $query = $this->_em->createQuery("select u.username from Doctrine\Tests\Models\CMS\CmsUser u where u.username = 'gblanco'");
  380. $this->assertNull($query->getOneOrNullResult(Query::HYDRATE_SCALAR));
  381. }
  382. /**
  383. * @group DBAL-171
  384. */
  385. public function testParameterOrder()
  386. {
  387. $user1 = new CmsUser;
  388. $user1->name = 'Benjamin';
  389. $user1->username = 'beberlei';
  390. $user1->status = 'developer';
  391. $this->_em->persist($user1);
  392. $user2 = new CmsUser;
  393. $user2->name = 'Roman';
  394. $user2->username = 'romanb';
  395. $user2->status = 'developer';
  396. $this->_em->persist($user2);
  397. $user3 = new CmsUser;
  398. $user3->name = 'Jonathan';
  399. $user3->username = 'jwage';
  400. $user3->status = 'developer';
  401. $this->_em->persist($user3);
  402. $this->_em->flush();
  403. $this->_em->clear();
  404. $query = $this->_em->createQuery("SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.status = :a AND u.id IN (:b)");
  405. $query->setParameters(array(
  406. 'b' => array($user1->id, $user2->id, $user3->id),
  407. 'a' => 'developer',
  408. ));
  409. $result = $query->getResult();
  410. $this->assertEquals(3, count($result));
  411. }
  412. public function testDqlWithAutoInferOfParameters()
  413. {
  414. $user = new CmsUser;
  415. $user->name = 'Benjamin';
  416. $user->username = 'beberlei';
  417. $user->status = 'developer';
  418. $this->_em->persist($user);
  419. $user = new CmsUser;
  420. $user->name = 'Roman';
  421. $user->username = 'romanb';
  422. $user->status = 'developer';
  423. $this->_em->persist($user);
  424. $user = new CmsUser;
  425. $user->name = 'Jonathan';
  426. $user->username = 'jwage';
  427. $user->status = 'developer';
  428. $this->_em->persist($user);
  429. $this->_em->flush();
  430. $this->_em->clear();
  431. $query = $this->_em->createQuery("SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.username IN (?0)");
  432. $query->setParameter(0, array('beberlei', 'jwage'));
  433. $users = $query->execute();
  434. $this->assertEquals(2, count($users));
  435. }
  436. public function testQueryBuilderWithStringWhereClauseContainingOrAndConditionalPrimary()
  437. {
  438. $qb = $this->_em->createQueryBuilder();
  439. $qb->select('u')
  440. ->from('Doctrine\Tests\Models\CMS\CmsUser', 'u')
  441. ->innerJoin('u.articles', 'a')
  442. ->where('(u.id = 0) OR (u.id IS NULL)');
  443. $query = $qb->getQuery();
  444. $users = $query->execute();
  445. $this->assertEquals(0, count($users));
  446. }
  447. public function testQueryWithArrayOfEntitiesAsParameter()
  448. {
  449. $userA = new CmsUser;
  450. $userA->name = 'Benjamin';
  451. $userA->username = 'beberlei';
  452. $userA->status = 'developer';
  453. $this->_em->persist($userA);
  454. $userB = new CmsUser;
  455. $userB->name = 'Roman';
  456. $userB->username = 'romanb';
  457. $userB->status = 'developer';
  458. $this->_em->persist($userB);
  459. $userC = new CmsUser;
  460. $userC->name = 'Jonathan';
  461. $userC->username = 'jwage';
  462. $userC->status = 'developer';
  463. $this->_em->persist($userC);
  464. $this->_em->flush();
  465. $this->_em->clear();
  466. $query = $this->_em->createQuery("SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u IN (?0) OR u.username = ?1");
  467. $query->setParameter(0, array($userA, $userC));
  468. $query->setParameter(1, 'beberlei');
  469. $users = $query->execute();
  470. $this->assertEquals(2, count($users));
  471. }
  472. }