BasicSyntaxTest.php 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144
  1. <?php
  2. namespace Drupal\KernelTests\Core\Database;
  3. /**
  4. * Tests SQL syntax interpretation.
  5. *
  6. * In order to ensure consistent SQL handling throughout Drupal
  7. * across multiple kinds of database systems, we test that the
  8. * database system interprets SQL syntax in an expected fashion.
  9. *
  10. * @group Database
  11. */
  12. class BasicSyntaxTest extends DatabaseTestBase {
  13. /**
  14. * Tests string concatenation.
  15. */
  16. public function testConcatLiterals() {
  17. $result = $this->connection->query('SELECT CONCAT(:a1, CONCAT(:a2, CONCAT(:a3, CONCAT(:a4, :a5))))', [
  18. ':a1' => 'This',
  19. ':a2' => ' ',
  20. ':a3' => 'is',
  21. ':a4' => ' a ',
  22. ':a5' => 'test.',
  23. ]);
  24. $this->assertIdentical($result->fetchField(), 'This is a test.', 'Basic CONCAT works.');
  25. }
  26. /**
  27. * Tests string concatenation with field values.
  28. *
  29. * We use 'job' and 'age' fields from the {test} table. Using the 'name' field
  30. * for concatenation causes issues with custom or contrib database drivers,
  31. * since its type 'varchar_ascii' may lead to using field-level collations not
  32. * compatible with the other fields.
  33. */
  34. public function testConcatFields() {
  35. $result = $this->connection->query(
  36. 'SELECT CONCAT(:a1, CONCAT(job, CONCAT(:a2, CONCAT(age, :a3)))) FROM {test} WHERE age = :age', [
  37. ':a1' => 'The age of ',
  38. ':a2' => ' is ',
  39. ':a3' => '.',
  40. ':age' => 25,
  41. ]
  42. );
  43. $this->assertSame('The age of Singer is 25.', $result->fetchField(), 'Field CONCAT works.');
  44. }
  45. /**
  46. * Tests string concatenation with separator.
  47. */
  48. public function testConcatWsLiterals() {
  49. $result = $this->connection->query("SELECT CONCAT_WS(', ', :a1, NULL, :a2, :a3, :a4)", [
  50. ':a1' => 'Hello',
  51. ':a2' => NULL,
  52. ':a3' => '',
  53. ':a4' => 'world.',
  54. ]);
  55. $this->assertIdentical($result->fetchField(), 'Hello, , world.');
  56. }
  57. /**
  58. * Tests string concatenation with separator, with field values.
  59. */
  60. public function testConcatWsFields() {
  61. $result = $this->connection->query("SELECT CONCAT_WS('-', :a1, name, :a2, age) FROM {test} WHERE age = :age", [
  62. ':a1' => 'name',
  63. ':a2' => 'age',
  64. ':age' => 25,
  65. ]);
  66. $this->assertIdentical($result->fetchField(), 'name-John-age-25');
  67. }
  68. /**
  69. * Tests escaping of LIKE wildcards.
  70. */
  71. public function testLikeEscape() {
  72. $this->connection->insert('test')
  73. ->fields([
  74. 'name' => 'Ring_',
  75. ])
  76. ->execute();
  77. // Match both "Ringo" and "Ring_".
  78. $num_matches = $this->connection->select('test', 't')
  79. ->condition('name', 'Ring_', 'LIKE')
  80. ->countQuery()
  81. ->execute()
  82. ->fetchField();
  83. $this->assertIdentical($num_matches, '2', 'Found 2 records.');
  84. // Match only "Ring_" using a LIKE expression with no wildcards.
  85. $num_matches = $this->connection->select('test', 't')
  86. ->condition('name', $this->connection->escapeLike('Ring_'), 'LIKE')
  87. ->countQuery()
  88. ->execute()
  89. ->fetchField();
  90. $this->assertIdentical($num_matches, '1', 'Found 1 record.');
  91. }
  92. /**
  93. * Tests a LIKE query containing a backslash.
  94. */
  95. public function testLikeBackslash() {
  96. $this->connection->insert('test')
  97. ->fields(['name'])
  98. ->values([
  99. 'name' => 'abcde\f',
  100. ])
  101. ->values([
  102. 'name' => 'abc%\_',
  103. ])
  104. ->execute();
  105. // Match both rows using a LIKE expression with two wildcards and a verbatim
  106. // backslash.
  107. $num_matches = $this->connection->select('test', 't')
  108. ->condition('name', 'abc%\\\\_', 'LIKE')
  109. ->countQuery()
  110. ->execute()
  111. ->fetchField();
  112. $this->assertIdentical($num_matches, '2', 'Found 2 records.');
  113. // Match only the former using a LIKE expression with no wildcards.
  114. $num_matches = $this->connection->select('test', 't')
  115. ->condition('name', $this->connection->escapeLike('abc%\_'), 'LIKE')
  116. ->countQuery()
  117. ->execute()
  118. ->fetchField();
  119. $this->assertIdentical($num_matches, '1', 'Found 1 record.');
  120. }
  121. /**
  122. * Tests \Drupal\Core\Database\Connection::getFullQualifiedTableName().
  123. */
  124. public function testGetFullQualifiedTableName() {
  125. $database = \Drupal::database();
  126. $num_matches = $database->select($database->getFullQualifiedTableName('test'), 't')
  127. ->countQuery()
  128. ->execute()
  129. ->fetchField();
  130. $this->assertIdentical($num_matches, '4', 'Found 4 records.');
  131. }
  132. }