SubqueryTest.php 2.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. <?php
  2. App::uses('MyCakeTestCase', 'Tools.TestSuite');
  3. App::uses('Controller', 'Controller');
  4. /**
  5. *
  6. * @link http://bakery.cakephp.org/articles/lucaswxp/2011/02/11/easy_and_simple_subquery_cakephp
  7. * @link http://www.sql-und-xml.de/sql-tutorial/subqueries-unterabfragen.html
  8. */
  9. class SubqueryTest extends MyCakeTestCase {
  10. public $fixtures = ['plugin.tools.country', 'plugin.tools.country_province'];
  11. public $Model;
  12. public function setUp() {
  13. $this->Model = ClassRegistry::init('Country');
  14. $this->db = ConnectionManager::getDataSource('test');
  15. $this->skipIf(!($this->db instanceof Mysql), 'The subquery test is only compatible with Mysql.');
  16. parent::setUp();
  17. }
  18. /**
  19. * SubqueryTest::testSubquery()
  20. *
  21. * @return void
  22. */
  23. public function testSubquery() {
  24. $res = $this->Model->find('all', ['conditions' => []]);
  25. $this->debug(count($res));
  26. $this->assertEquals(10, count($res));
  27. $res = $this->Model->subquery('count');
  28. $this->debug($res);
  29. $res = $this->Model->find('all', ['conditions' => ['lat <=' => $this->Model->subquery('count')]]);
  30. $this->debug(count($res));
  31. $this->assertEquals(0, count($res));
  32. $subqueryOptions = ['fields' => ['MAX(lat)']];
  33. $res = $this->Model->subquery('all', $subqueryOptions);
  34. $this->debug($res);
  35. $subqueryOptions = ['fields' => ['MAX(lat)']];
  36. $res = $this->Model->find('all', ['conditions' => ['lat <=' => $this->Model->subquery('first', $subqueryOptions)]]);
  37. $this->debug(count($res));
  38. $this->assertEquals(0, count($res));
  39. $subqueryOptions = ['fields' => ['id'], 'conditions' => ['id' => 1]];
  40. $res = $this->Model->subquery('first', $subqueryOptions);
  41. $this->debug($res);
  42. $res = $this->Model->find('all', ['conditions' => ['id NOT IN ' . $this->Model->subquery('all', $subqueryOptions)]]);
  43. $this->debug(count($res));
  44. $this->debug($res);
  45. $this->assertEquals(9, count($res));
  46. }
  47. /**
  48. * SubqueryTest::testSubqueryPaginated()
  49. *
  50. * @return void
  51. */
  52. public function testSubqueryPaginated() {
  53. $Controller = new CountriesTestsController(new CakeRequest(null, false), new CakeResponse());
  54. $Controller->constructClasses();
  55. $source = $Controller->Country->getDataSource();
  56. $database = $source->config['database'];
  57. $subquery = $Controller->Country->subquery('list', ['conditions' => ['NOT' => ['SubCountry.id' => [1, 2, 3]]]]);
  58. $expected = '(SELECT SubCountry.id FROM `' . $database . '`.`countries` AS `SubCountry` WHERE NOT (`SubCountry`.`id` IN (1, 2, 3)))';
  59. $this->assertEquals($expected, $subquery);
  60. $res = $Controller->Country->query($subquery);
  61. $this->assertTrue(count($res) === 7);
  62. $Controller->paginate = [
  63. 'conditions' => ['Country.id IN ' . $subquery]
  64. ];
  65. $res = $Controller->paginate();
  66. $this->assertTrue(count($res) === 7);
  67. $this->debug($res);
  68. }
  69. }
  70. class CountriesTestsController extends Controller {
  71. public $uses = ['Country'];
  72. }