QueryCompilerTest.php 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212
  1. <?php
  2. declare(strict_types=1);
  3. /**
  4. * CakePHP(tm) : Rapid Development Framework (https://cakephp.org)
  5. * Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org)
  6. *
  7. * Licensed under The MIT License
  8. * Redistributions of files must retain the above copyright notice
  9. *
  10. * @copyright Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org)
  11. * @since 5.0.0
  12. * @license https://opensource.org/licenses/mit-license.php MIT License
  13. */
  14. namespace Cake\Test\TestCase\Database;
  15. use Cake\Database\Connection;
  16. use Cake\Database\Driver\Sqlserver;
  17. use Cake\Database\Query;
  18. use Cake\Database\QueryCompiler;
  19. use Cake\Database\StatementInterface;
  20. use Cake\Database\ValueBinder;
  21. use Cake\Datasource\ConnectionInterface;
  22. use Cake\Datasource\ConnectionManager;
  23. use Cake\TestSuite\TestCase;
  24. /**
  25. * Tests Query class
  26. */
  27. class QueryCompilerTest extends TestCase
  28. {
  29. use QueryAssertsTrait;
  30. protected array $fixtures = [
  31. 'core.Articles',
  32. ];
  33. protected Connection|ConnectionInterface $connection;
  34. protected QueryCompiler $compiler;
  35. protected ValueBinder $binder;
  36. public function setUp(): void
  37. {
  38. parent::setUp();
  39. $this->connection = ConnectionManager::get('test');
  40. $this->compiler = $this->connection->getDriver()->newCompiler();
  41. $this->binder = new ValueBinder();
  42. }
  43. public function tearDown(): void
  44. {
  45. parent::tearDown();
  46. unset($this->compiler);
  47. unset($this->binder);
  48. }
  49. protected function newQuery(string $type): Query
  50. {
  51. return match ($type) {
  52. Query::TYPE_SELECT => new Query\SelectQuery($this->connection),
  53. Query::TYPE_INSERT => new Query\InsertQuery($this->connection),
  54. Query::TYPE_UPDATE => new Query\UpdateQuery($this->connection),
  55. Query::TYPE_DELETE => new Query\DeleteQuery($this->connection),
  56. };
  57. }
  58. public function testSelectFrom(): void
  59. {
  60. /** @var \Cake\Database\Query\SelectQuery $query */
  61. $query = $this->newQuery(Query::TYPE_SELECT);
  62. $query = $query->select('*')
  63. ->from('articles');
  64. $result = $this->compiler->compile($query, $this->binder);
  65. $this->assertSame('SELECT * FROM articles', $result);
  66. $result = $query->all();
  67. $this->assertCount(3, $result);
  68. }
  69. public function testSelectWhere(): void
  70. {
  71. /** @var \Cake\Database\Query\SelectQuery $query */
  72. $query = $this->newQuery(Query::TYPE_SELECT);
  73. $query = $query->select('*')
  74. ->from('articles')
  75. ->where(['author_id' => 1]);
  76. $result = $this->compiler->compile($query, $this->binder);
  77. $this->assertSame('SELECT * FROM articles WHERE author_id = :c0', $result);
  78. $result = $query->all();
  79. $this->assertCount(2, $result);
  80. }
  81. public function testSelectWithComment(): void
  82. {
  83. /** @var \Cake\Database\Query\SelectQuery $query */
  84. $query = $this->newQuery(Query::TYPE_SELECT);
  85. $query = $query->select('*')
  86. ->from('articles')
  87. ->comment('This is a test');
  88. $result = $this->compiler->compile($query, $this->binder);
  89. $this->assertSame('/* This is a test */ SELECT * FROM articles', $result);
  90. $result = $query->all();
  91. $this->assertCount(3, $result);
  92. }
  93. public function testInsert(): void
  94. {
  95. /** @var \Cake\Database\Query\InsertQuery $query */
  96. $query = $this->newQuery(Query::TYPE_INSERT);
  97. $query = $query->insert(['title'])
  98. ->into('articles')
  99. ->values(['title' => 'A new article']);
  100. $result = $this->compiler->compile($query, $this->binder);
  101. if ($this->connection->getDriver() instanceof Sqlserver) {
  102. $this->assertSame('INSERT INTO articles (title) OUTPUT INSERTED.* VALUES (:c0)', $result);
  103. } else {
  104. $this->assertSame('INSERT INTO articles (title) VALUES (:c0)', $result);
  105. }
  106. $result = $query->execute();
  107. $this->assertInstanceOf(StatementInterface::class, $result);
  108. $result->closeCursor();
  109. }
  110. public function testInsertWithComment(): void
  111. {
  112. /** @var \Cake\Database\Query\InsertQuery $query */
  113. $query = $this->newQuery(Query::TYPE_INSERT);
  114. $query = $query->insert(['title'])
  115. ->into('articles')
  116. ->values(['title' => 'A new article'])
  117. ->comment('This is a test');
  118. $result = $this->compiler->compile($query, $this->binder);
  119. if ($this->connection->getDriver() instanceof Sqlserver) {
  120. $this->assertSame('/* This is a test */ INSERT INTO articles (title) OUTPUT INSERTED.* VALUES (:c0)', $result);
  121. } else {
  122. $this->assertSame('/* This is a test */ INSERT INTO articles (title) VALUES (:c0)', $result);
  123. }
  124. $result = $query->execute();
  125. $this->assertInstanceOf(StatementInterface::class, $result);
  126. $result->closeCursor();
  127. }
  128. public function testUpdate(): void
  129. {
  130. /** @var \Cake\Database\Query\UpdateQuery $query */
  131. $query = $this->newQuery(Query::TYPE_UPDATE);
  132. $query = $query->update('articles')
  133. ->set('title', 'mark')
  134. ->where(['id' => 1]);
  135. $result = $this->compiler->compile($query, $this->binder);
  136. $this->assertSame('UPDATE articles SET title = :c0 WHERE id = :c1', $result);
  137. $result = $query->execute();
  138. $this->assertInstanceOf(StatementInterface::class, $result);
  139. $result->closeCursor();
  140. }
  141. public function testUpdateWithComment(): void
  142. {
  143. /** @var \Cake\Database\Query\UpdateQuery $query */
  144. $query = $this->newQuery(Query::TYPE_UPDATE);
  145. $query = $query->update('articles')
  146. ->set('title', 'mark')
  147. ->where(['id' => 1])
  148. ->comment('This is a test');
  149. $result = $this->compiler->compile($query, $this->binder);
  150. $this->assertSame('/* This is a test */ UPDATE articles SET title = :c0 WHERE id = :c1', $result);
  151. $result = $query->execute();
  152. $this->assertInstanceOf(StatementInterface::class, $result);
  153. $result->closeCursor();
  154. }
  155. public function testDelete(): void
  156. {
  157. /** @var \Cake\Database\Query\DeleteQuery $query */
  158. $query = $this->newQuery(Query::TYPE_DELETE);
  159. $query = $query->delete()
  160. ->from('articles')
  161. ->where(['id !=' => 1]);
  162. $result = $this->compiler->compile($query, $this->binder);
  163. $this->assertSame('DELETE FROM articles WHERE id != :c0', $result);
  164. $result = $query->execute();
  165. $this->assertInstanceOf(StatementInterface::class, $result);
  166. $result->closeCursor();
  167. }
  168. public function testDeleteWithComment(): void
  169. {
  170. /** @var \Cake\Database\Query\DeleteQuery $query */
  171. $query = $this->newQuery(Query::TYPE_DELETE);
  172. $query = $query->delete()
  173. ->from('articles')
  174. ->where(['id !=' => 1])
  175. ->comment('This is a test');
  176. $result = $this->compiler->compile($query, $this->binder);
  177. $this->assertSame('/* This is a test */ DELETE FROM articles WHERE id != :c0', $result);
  178. $result = $query->execute();
  179. $this->assertInstanceOf(StatementInterface::class, $result);
  180. $result->closeCursor();
  181. }
  182. }