QueryBuilderTest.php 17KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572
  1. <?php
  2. namespace Doctrine\Tests\DBAL\Query;
  3. use Doctrine\DBAL\Query\Expression\ExpressionBuilder,
  4. Doctrine\DBAL\Query\QueryBuilder;
  5. require_once __DIR__ . '/../../TestInit.php';
  6. /**
  7. * @group DBAL-12
  8. */
  9. class QueryBuilderTest extends \Doctrine\Tests\DbalTestCase
  10. {
  11. protected $conn;
  12. public function setUp()
  13. {
  14. $this->conn = $this->getMock('Doctrine\DBAL\Connection', array(), array(), '', false);
  15. $expressionBuilder = new ExpressionBuilder($this->conn);
  16. $this->conn->expects($this->any())
  17. ->method('getExpressionBuilder')
  18. ->will($this->returnValue($expressionBuilder));
  19. }
  20. public function testSimpleSelect()
  21. {
  22. $qb = new QueryBuilder($this->conn);
  23. $qb->select('u.id')
  24. ->from('users', 'u');
  25. $this->assertEquals('SELECT u.id FROM users u', (string) $qb);
  26. }
  27. public function testSelectWithSimpleWhere()
  28. {
  29. $qb = new QueryBuilder($this->conn);
  30. $expr = $qb->expr();
  31. $qb->select('u.id')
  32. ->from('users', 'u')
  33. ->where($expr->andX($expr->eq('u.nickname', '?')));
  34. $this->assertEquals("SELECT u.id FROM users u WHERE u.nickname = ?", (string) $qb);
  35. }
  36. public function testSelectWithLeftJoin()
  37. {
  38. $qb = new QueryBuilder($this->conn);
  39. $expr = $qb->expr();
  40. $qb->select('u.*', 'p.*')
  41. ->from('users', 'u')
  42. ->leftJoin('u', 'phones', 'p', $expr->eq('p.user_id', 'u.id'));
  43. $this->assertEquals('SELECT u.*, p.* FROM users u LEFT JOIN phones p ON p.user_id = u.id', (string) $qb);
  44. }
  45. public function testSelectWithJoin()
  46. {
  47. $qb = new QueryBuilder($this->conn);
  48. $expr = $qb->expr();
  49. $qb->select('u.*', 'p.*')
  50. ->from('users', 'u')
  51. ->Join('u', 'phones', 'p', $expr->eq('p.user_id', 'u.id'));
  52. $this->assertEquals('SELECT u.*, p.* FROM users u INNER JOIN phones p ON p.user_id = u.id', (string) $qb);
  53. }
  54. public function testSelectWithInnerJoin()
  55. {
  56. $qb = new QueryBuilder($this->conn);
  57. $expr = $qb->expr();
  58. $qb->select('u.*', 'p.*')
  59. ->from('users', 'u')
  60. ->innerJoin('u', 'phones', 'p', $expr->eq('p.user_id', 'u.id'));
  61. $this->assertEquals('SELECT u.*, p.* FROM users u INNER JOIN phones p ON p.user_id = u.id', (string) $qb);
  62. }
  63. public function testSelectWithRightJoin()
  64. {
  65. $qb = new QueryBuilder($this->conn);
  66. $expr = $qb->expr();
  67. $qb->select('u.*', 'p.*')
  68. ->from('users', 'u')
  69. ->rightJoin('u', 'phones', 'p', $expr->eq('p.user_id', 'u.id'));
  70. $this->assertEquals('SELECT u.*, p.* FROM users u RIGHT JOIN phones p ON p.user_id = u.id', (string) $qb);
  71. }
  72. public function testSelectWithAndWhereConditions()
  73. {
  74. $qb = new QueryBuilder($this->conn);
  75. $expr = $qb->expr();
  76. $qb->select('u.*', 'p.*')
  77. ->from('users', 'u')
  78. ->where('u.username = ?')
  79. ->andWhere('u.name = ?');
  80. $this->assertEquals('SELECT u.*, p.* FROM users u WHERE (u.username = ?) AND (u.name = ?)', (string) $qb);
  81. }
  82. public function testSelectWithOrWhereConditions()
  83. {
  84. $qb = new QueryBuilder($this->conn);
  85. $expr = $qb->expr();
  86. $qb->select('u.*', 'p.*')
  87. ->from('users', 'u')
  88. ->where('u.username = ?')
  89. ->orWhere('u.name = ?');
  90. $this->assertEquals('SELECT u.*, p.* FROM users u WHERE (u.username = ?) OR (u.name = ?)', (string) $qb);
  91. }
  92. public function testSelectWithOrOrWhereConditions()
  93. {
  94. $qb = new QueryBuilder($this->conn);
  95. $expr = $qb->expr();
  96. $qb->select('u.*', 'p.*')
  97. ->from('users', 'u')
  98. ->orWhere('u.username = ?')
  99. ->orWhere('u.name = ?');
  100. $this->assertEquals('SELECT u.*, p.* FROM users u WHERE (u.username = ?) OR (u.name = ?)', (string) $qb);
  101. }
  102. public function testSelectWithAndOrWhereConditions()
  103. {
  104. $qb = new QueryBuilder($this->conn);
  105. $expr = $qb->expr();
  106. $qb->select('u.*', 'p.*')
  107. ->from('users', 'u')
  108. ->where('u.username = ?')
  109. ->andWhere('u.username = ?')
  110. ->orWhere('u.name = ?')
  111. ->andWhere('u.name = ?');
  112. $this->assertEquals('SELECT u.*, p.* FROM users u WHERE (((u.username = ?) AND (u.username = ?)) OR (u.name = ?)) AND (u.name = ?)', (string) $qb);
  113. }
  114. public function testSelectGroupBy()
  115. {
  116. $qb = new QueryBuilder($this->conn);
  117. $expr = $qb->expr();
  118. $qb->select('u.*', 'p.*')
  119. ->from('users', 'u')
  120. ->groupBy('u.id');
  121. $this->assertEquals('SELECT u.*, p.* FROM users u GROUP BY u.id', (string) $qb);
  122. }
  123. public function testSelectEmptyGroupBy()
  124. {
  125. $qb = new QueryBuilder($this->conn);
  126. $expr = $qb->expr();
  127. $qb->select('u.*', 'p.*')
  128. ->groupBy(array())
  129. ->from('users', 'u');
  130. $this->assertEquals('SELECT u.*, p.* FROM users u', (string) $qb);
  131. }
  132. public function testSelectEmptyAddGroupBy()
  133. {
  134. $qb = new QueryBuilder($this->conn);
  135. $expr = $qb->expr();
  136. $qb->select('u.*', 'p.*')
  137. ->addGroupBy(array())
  138. ->from('users', 'u');
  139. $this->assertEquals('SELECT u.*, p.* FROM users u', (string) $qb);
  140. }
  141. public function testSelectAddGroupBy()
  142. {
  143. $qb = new QueryBuilder($this->conn);
  144. $expr = $qb->expr();
  145. $qb->select('u.*', 'p.*')
  146. ->from('users', 'u')
  147. ->groupBy('u.id')
  148. ->addGroupBy('u.foo');
  149. $this->assertEquals('SELECT u.*, p.* FROM users u GROUP BY u.id, u.foo', (string) $qb);
  150. }
  151. public function testSelectAddGroupBys()
  152. {
  153. $qb = new QueryBuilder($this->conn);
  154. $expr = $qb->expr();
  155. $qb->select('u.*', 'p.*')
  156. ->from('users', 'u')
  157. ->groupBy('u.id')
  158. ->addGroupBy('u.foo', 'u.bar');
  159. $this->assertEquals('SELECT u.*, p.* FROM users u GROUP BY u.id, u.foo, u.bar', (string) $qb);
  160. }
  161. public function testSelectHaving()
  162. {
  163. $qb = new QueryBuilder($this->conn);
  164. $expr = $qb->expr();
  165. $qb->select('u.*', 'p.*')
  166. ->from('users', 'u')
  167. ->groupBy('u.id')
  168. ->having('u.name = ?');
  169. $this->assertEquals('SELECT u.*, p.* FROM users u GROUP BY u.id HAVING u.name = ?', (string) $qb);
  170. }
  171. public function testSelectAndHaving()
  172. {
  173. $qb = new QueryBuilder($this->conn);
  174. $expr = $qb->expr();
  175. $qb->select('u.*', 'p.*')
  176. ->from('users', 'u')
  177. ->groupBy('u.id')
  178. ->andHaving('u.name = ?');
  179. $this->assertEquals('SELECT u.*, p.* FROM users u GROUP BY u.id HAVING u.name = ?', (string) $qb);
  180. }
  181. public function testSelectHavingAndHaving()
  182. {
  183. $qb = new QueryBuilder($this->conn);
  184. $expr = $qb->expr();
  185. $qb->select('u.*', 'p.*')
  186. ->from('users', 'u')
  187. ->groupBy('u.id')
  188. ->having('u.name = ?')
  189. ->andHaving('u.username = ?');
  190. $this->assertEquals('SELECT u.*, p.* FROM users u GROUP BY u.id HAVING (u.name = ?) AND (u.username = ?)', (string) $qb);
  191. }
  192. public function testSelectHavingOrHaving()
  193. {
  194. $qb = new QueryBuilder($this->conn);
  195. $expr = $qb->expr();
  196. $qb->select('u.*', 'p.*')
  197. ->from('users', 'u')
  198. ->groupBy('u.id')
  199. ->having('u.name = ?')
  200. ->orHaving('u.username = ?');
  201. $this->assertEquals('SELECT u.*, p.* FROM users u GROUP BY u.id HAVING (u.name = ?) OR (u.username = ?)', (string) $qb);
  202. }
  203. public function testSelectOrHavingOrHaving()
  204. {
  205. $qb = new QueryBuilder($this->conn);
  206. $expr = $qb->expr();
  207. $qb->select('u.*', 'p.*')
  208. ->from('users', 'u')
  209. ->groupBy('u.id')
  210. ->orHaving('u.name = ?')
  211. ->orHaving('u.username = ?');
  212. $this->assertEquals('SELECT u.*, p.* FROM users u GROUP BY u.id HAVING (u.name = ?) OR (u.username = ?)', (string) $qb);
  213. }
  214. public function testSelectHavingAndOrHaving()
  215. {
  216. $qb = new QueryBuilder($this->conn);
  217. $expr = $qb->expr();
  218. $qb->select('u.*', 'p.*')
  219. ->from('users', 'u')
  220. ->groupBy('u.id')
  221. ->having('u.name = ?')
  222. ->orHaving('u.username = ?')
  223. ->andHaving('u.username = ?');
  224. $this->assertEquals('SELECT u.*, p.* FROM users u GROUP BY u.id HAVING ((u.name = ?) OR (u.username = ?)) AND (u.username = ?)', (string) $qb);
  225. }
  226. public function testSelectOrderBy()
  227. {
  228. $qb = new QueryBuilder($this->conn);
  229. $expr = $qb->expr();
  230. $qb->select('u.*', 'p.*')
  231. ->from('users', 'u')
  232. ->orderBy('u.name');
  233. $this->assertEquals('SELECT u.*, p.* FROM users u ORDER BY u.name ASC', (string) $qb);
  234. }
  235. public function testSelectAddOrderBy()
  236. {
  237. $qb = new QueryBuilder($this->conn);
  238. $expr = $qb->expr();
  239. $qb->select('u.*', 'p.*')
  240. ->from('users', 'u')
  241. ->orderBy('u.name')
  242. ->addOrderBy('u.username', 'DESC');
  243. $this->assertEquals('SELECT u.*, p.* FROM users u ORDER BY u.name ASC, u.username DESC', (string) $qb);
  244. }
  245. public function testSelectAddAddOrderBy()
  246. {
  247. $qb = new QueryBuilder($this->conn);
  248. $expr = $qb->expr();
  249. $qb->select('u.*', 'p.*')
  250. ->from('users', 'u')
  251. ->addOrderBy('u.name')
  252. ->addOrderBy('u.username', 'DESC');
  253. $this->assertEquals('SELECT u.*, p.* FROM users u ORDER BY u.name ASC, u.username DESC', (string) $qb);
  254. }
  255. public function testEmptySelect()
  256. {
  257. $qb = new QueryBuilder($this->conn);
  258. $qb2 = $qb->select();
  259. $this->assertSame($qb, $qb2);
  260. $this->assertEquals(QueryBuilder::SELECT, $qb->getType());
  261. }
  262. public function testSelectAddSelect()
  263. {
  264. $qb = new QueryBuilder($this->conn);
  265. $expr = $qb->expr();
  266. $qb->select('u.*')
  267. ->addSelect('p.*')
  268. ->from('users', 'u');
  269. $this->assertEquals('SELECT u.*, p.* FROM users u', (string) $qb);
  270. }
  271. public function testEmptyAddSelect()
  272. {
  273. $qb = new QueryBuilder($this->conn);
  274. $qb2 = $qb->addSelect();
  275. $this->assertSame($qb, $qb2);
  276. $this->assertEquals(QueryBuilder::SELECT, $qb->getType());
  277. }
  278. public function testSelectMultipleFrom()
  279. {
  280. $qb = new QueryBuilder($this->conn);
  281. $expr = $qb->expr();
  282. $qb->select('u.*')
  283. ->addSelect('p.*')
  284. ->from('users', 'u')
  285. ->from('phonenumbers', 'p');
  286. $this->assertEquals('SELECT u.*, p.* FROM users u, phonenumbers p', (string) $qb);
  287. }
  288. public function testUpdate()
  289. {
  290. $qb = new QueryBuilder($this->conn);
  291. $qb->update('users', 'u')
  292. ->set('u.foo', '?')
  293. ->set('u.bar', '?');
  294. $this->assertEquals(QueryBuilder::UPDATE, $qb->getType());
  295. $this->assertEquals('UPDATE users u SET u.foo = ?, u.bar = ?', (string) $qb);
  296. }
  297. public function testUpdateWithoutAlias()
  298. {
  299. $qb = new QueryBuilder($this->conn);
  300. $qb->update('users')
  301. ->set('foo', '?')
  302. ->set('bar', '?');
  303. $this->assertEquals('UPDATE users SET foo = ?, bar = ?', (string) $qb);
  304. }
  305. public function testUpdateWhere()
  306. {
  307. $qb = new QueryBuilder($this->conn);
  308. $qb->update('users', 'u')
  309. ->set('u.foo', '?')
  310. ->where('u.foo = ?');
  311. $this->assertEquals('UPDATE users u SET u.foo = ? WHERE u.foo = ?', (string) $qb);
  312. }
  313. public function testEmptyUpdate()
  314. {
  315. $qb = new QueryBuilder($this->conn);
  316. $qb2 = $qb->update();
  317. $this->assertEquals(QueryBuilder::UPDATE, $qb->getType());
  318. $this->assertSame($qb2, $qb);
  319. }
  320. public function testDelete()
  321. {
  322. $qb = new QueryBuilder($this->conn);
  323. $qb->delete('users', 'u');
  324. $this->assertEquals(QueryBuilder::DELETE, $qb->getType());
  325. $this->assertEquals('DELETE FROM users u', (string) $qb);
  326. }
  327. public function testDeleteWithoutAlias()
  328. {
  329. $qb = new QueryBuilder($this->conn);
  330. $qb->delete('users');
  331. $this->assertEquals(QueryBuilder::DELETE, $qb->getType());
  332. $this->assertEquals('DELETE FROM users', (string) $qb);
  333. }
  334. public function testDeleteWhere()
  335. {
  336. $qb = new QueryBuilder($this->conn);
  337. $qb->delete('users', 'u')
  338. ->where('u.foo = ?');
  339. $this->assertEquals('DELETE FROM users u WHERE u.foo = ?', (string) $qb);
  340. }
  341. public function testEmptyDelete()
  342. {
  343. $qb = new QueryBuilder($this->conn);
  344. $qb2 = $qb->delete();
  345. $this->assertEquals(QueryBuilder::DELETE, $qb->getType());
  346. $this->assertSame($qb2, $qb);
  347. }
  348. public function testGetConnection()
  349. {
  350. $qb = new QueryBuilder($this->conn);
  351. $this->assertSame($this->conn, $qb->getConnection());
  352. }
  353. public function testGetState()
  354. {
  355. $qb = new QueryBuilder($this->conn);
  356. $this->assertEquals(QueryBuilder::STATE_CLEAN, $qb->getState());
  357. $qb->select('u.*')->from('users', 'u');
  358. $this->assertEquals(QueryBuilder::STATE_DIRTY, $qb->getState());
  359. $sql1 = $qb->getSQL();
  360. $this->assertEquals(QueryBuilder::STATE_CLEAN, $qb->getState());
  361. $this->assertEquals($sql1, $qb->getSQL());
  362. }
  363. public function testSetMaxResults()
  364. {
  365. $qb = new QueryBuilder($this->conn);
  366. $qb->setMaxResults(10);
  367. $this->assertEquals(QueryBuilder::STATE_DIRTY, $qb->getState());
  368. $this->assertEQuals(10, $qb->getMaxResults());
  369. }
  370. public function testSetFirstResult()
  371. {
  372. $qb = new QueryBuilder($this->conn);
  373. $qb->setFirstResult(10);
  374. $this->assertEquals(QueryBuilder::STATE_DIRTY, $qb->getState());
  375. $this->assertEQuals(10, $qb->getFirstResult());
  376. }
  377. public function testResetQueryPart()
  378. {
  379. $qb = new QueryBuilder($this->conn);
  380. $qb->select('u.*')->from('users', 'u')->where('u.name = ?');
  381. $this->assertEquals('SELECT u.* FROM users u WHERE u.name = ?', (string)$qb);
  382. $qb->resetQueryPart('where');
  383. $this->assertEquals('SELECT u.* FROM users u', (string)$qb);
  384. }
  385. public function testResetQueryParts()
  386. {
  387. $qb = new QueryBuilder($this->conn);
  388. $qb->select('u.*')->from('users', 'u')->where('u.name = ?')->orderBy('u.name');
  389. $this->assertEquals('SELECT u.* FROM users u WHERE u.name = ? ORDER BY u.name ASC', (string)$qb);
  390. $qb->resetQueryParts(array('where', 'orderBy'));
  391. $this->assertEquals('SELECT u.* FROM users u', (string)$qb);
  392. }
  393. public function testCreateNamedParameter()
  394. {
  395. $qb = new QueryBuilder($this->conn);
  396. $qb->select('u.*')->from('users', 'u')->where(
  397. $qb->expr()->eq('u.name', $qb->createNamedParameter(10, \PDO::PARAM_INT))
  398. );
  399. $this->assertEquals('SELECT u.* FROM users u WHERE u.name = :dcValue1', (string)$qb);
  400. $this->assertEquals(10, $qb->getParameter('dcValue1'));
  401. }
  402. public function testCreateNamedParameterCustomPlaceholder()
  403. {
  404. $qb = new QueryBuilder($this->conn);
  405. $qb->select('u.*')->from('users', 'u')->where(
  406. $qb->expr()->eq('u.name', $qb->createNamedParameter(10, \PDO::PARAM_INT, ':test'))
  407. );
  408. $this->assertEquals('SELECT u.* FROM users u WHERE u.name = :test', (string)$qb);
  409. $this->assertEquals(10, $qb->getParameter('test'));
  410. }
  411. public function testCreatePositionalParameter()
  412. {
  413. $qb = new QueryBuilder($this->conn);
  414. $qb->select('u.*')->from('users', 'u')->where(
  415. $qb->expr()->eq('u.name', $qb->createPositionalParameter(10, \PDO::PARAM_INT))
  416. );
  417. $this->assertEquals('SELECT u.* FROM users u WHERE u.name = ?', (string)$qb);
  418. $this->assertEquals(10, $qb->getParameter(1));
  419. }
  420. /**
  421. * @group DBAL-172
  422. */
  423. public function testReferenceJoinFromJoin()
  424. {
  425. $qb = new QueryBuilder($this->conn);
  426. $qb->select("l.id", "mdsh.xcode", "mdso.xcode")
  427. ->from("location_tree", "l")
  428. ->join("l", "location_tree_pos", "p", "l.id = p.tree_id")
  429. ->rightJoin("l", "hotel", "h", "h.location_id = l.id")
  430. ->leftJoin("l", "offer_location", "ol", "l.id=ol.location_id")
  431. ->leftJoin("ol", "mds_offer", "mdso", "ol.offer_id = mdso.offer_id")
  432. ->leftJoin("h", "mds_hotel", "mdsh", "h.id = mdsh.hotel_id")
  433. ->where("p.parent_id IN (:ids)")
  434. ->andWhere("(mdso.xcode IS NOT NULL OR mdsh.xcode IS NOT NULL)");
  435. $this->setExpectedException('Doctrine\DBAL\Query\QueryException', "The given alias 'ol' is not part of any FROM clause table. The currently registered FROM-clause aliases are: l");
  436. $this->assertEquals('', $qb->getSQL());
  437. }
  438. }