InsertTest.php 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211
  1. <?php
  2. namespace Drupal\KernelTests\Core\Database;
  3. /**
  4. * Tests the insert builder.
  5. *
  6. * @group Database
  7. */
  8. class InsertTest extends DatabaseTestBase {
  9. /**
  10. * Tests very basic insert functionality.
  11. */
  12. public function testSimpleInsert() {
  13. $num_records_before = db_query('SELECT COUNT(*) FROM {test}')->fetchField();
  14. $query = db_insert('test');
  15. $query->fields([
  16. 'name' => 'Yoko',
  17. 'age' => '29',
  18. ]);
  19. // Check how many records are queued for insertion.
  20. $this->assertIdentical($query->count(), 1, 'One record is queued for insertion.');
  21. $query->execute();
  22. $num_records_after = db_query('SELECT COUNT(*) FROM {test}')->fetchField();
  23. $this->assertSame($num_records_before + 1, (int) $num_records_after, 'Record inserts correctly.');
  24. $saved_age = db_query('SELECT age FROM {test} WHERE name = :name', [':name' => 'Yoko'])->fetchField();
  25. $this->assertIdentical($saved_age, '29', 'Can retrieve after inserting.');
  26. }
  27. /**
  28. * Tests that we can insert multiple records in one query object.
  29. */
  30. public function testMultiInsert() {
  31. $num_records_before = (int) db_query('SELECT COUNT(*) FROM {test}')->fetchField();
  32. $query = db_insert('test');
  33. $query->fields([
  34. 'name' => 'Larry',
  35. 'age' => '30',
  36. ]);
  37. // We should be able to specify values in any order if named.
  38. $query->values([
  39. 'age' => '31',
  40. 'name' => 'Curly',
  41. ]);
  42. // Check how many records are queued for insertion.
  43. $this->assertIdentical($query->count(), 2, 'Two records are queued for insertion.');
  44. // We should be able to say "use the field order".
  45. // This is not the recommended mechanism for most cases, but it should work.
  46. $query->values(['Moe', '32']);
  47. // Check how many records are queued for insertion.
  48. $this->assertIdentical($query->count(), 3, 'Three records are queued for insertion.');
  49. $query->execute();
  50. $num_records_after = (int) db_query('SELECT COUNT(*) FROM {test}')->fetchField();
  51. $this->assertSame($num_records_before + 3, $num_records_after, 'Record inserts correctly.');
  52. $saved_age = db_query('SELECT age FROM {test} WHERE name = :name', [':name' => 'Larry'])->fetchField();
  53. $this->assertIdentical($saved_age, '30', 'Can retrieve after inserting.');
  54. $saved_age = db_query('SELECT age FROM {test} WHERE name = :name', [':name' => 'Curly'])->fetchField();
  55. $this->assertIdentical($saved_age, '31', 'Can retrieve after inserting.');
  56. $saved_age = db_query('SELECT age FROM {test} WHERE name = :name', [':name' => 'Moe'])->fetchField();
  57. $this->assertIdentical($saved_age, '32', 'Can retrieve after inserting.');
  58. }
  59. /**
  60. * Tests that an insert object can be reused with new data after it executes.
  61. */
  62. public function testRepeatedInsert() {
  63. $num_records_before = db_query('SELECT COUNT(*) FROM {test}')->fetchField();
  64. $query = db_insert('test');
  65. $query->fields([
  66. 'name' => 'Larry',
  67. 'age' => '30',
  68. ]);
  69. // Check how many records are queued for insertion.
  70. $this->assertIdentical($query->count(), 1, 'One record is queued for insertion.');
  71. // This should run the insert, but leave the fields intact.
  72. $query->execute();
  73. // We should be able to specify values in any order if named.
  74. $query->values([
  75. 'age' => '31',
  76. 'name' => 'Curly',
  77. ]);
  78. // Check how many records are queued for insertion.
  79. $this->assertIdentical($query->count(), 1, 'One record is queued for insertion.');
  80. $query->execute();
  81. // We should be able to say "use the field order".
  82. $query->values(['Moe', '32']);
  83. // Check how many records are queued for insertion.
  84. $this->assertIdentical($query->count(), 1, 'One record is queued for insertion.');
  85. $query->execute();
  86. $num_records_after = db_query('SELECT COUNT(*) FROM {test}')->fetchField();
  87. $this->assertSame((int) $num_records_before + 3, (int) $num_records_after, 'Record inserts correctly.');
  88. $saved_age = db_query('SELECT age FROM {test} WHERE name = :name', [':name' => 'Larry'])->fetchField();
  89. $this->assertIdentical($saved_age, '30', 'Can retrieve after inserting.');
  90. $saved_age = db_query('SELECT age FROM {test} WHERE name = :name', [':name' => 'Curly'])->fetchField();
  91. $this->assertIdentical($saved_age, '31', 'Can retrieve after inserting.');
  92. $saved_age = db_query('SELECT age FROM {test} WHERE name = :name', [':name' => 'Moe'])->fetchField();
  93. $this->assertIdentical($saved_age, '32', 'Can retrieve after inserting.');
  94. }
  95. /**
  96. * Tests that we can specify fields without values and specify values later.
  97. */
  98. public function testInsertFieldOnlyDefinition() {
  99. // This is useful for importers, when we want to create a query and define
  100. // its fields once, then loop over a multi-insert execution.
  101. db_insert('test')
  102. ->fields(['name', 'age'])
  103. ->values(['Larry', '30'])
  104. ->values(['Curly', '31'])
  105. ->values(['Moe', '32'])
  106. ->execute();
  107. $saved_age = db_query('SELECT age FROM {test} WHERE name = :name', [':name' => 'Larry'])->fetchField();
  108. $this->assertIdentical($saved_age, '30', 'Can retrieve after inserting.');
  109. $saved_age = db_query('SELECT age FROM {test} WHERE name = :name', [':name' => 'Curly'])->fetchField();
  110. $this->assertIdentical($saved_age, '31', 'Can retrieve after inserting.');
  111. $saved_age = db_query('SELECT age FROM {test} WHERE name = :name', [':name' => 'Moe'])->fetchField();
  112. $this->assertIdentical($saved_age, '32', 'Can retrieve after inserting.');
  113. }
  114. /**
  115. * Tests that inserts return the proper auto-increment ID.
  116. */
  117. public function testInsertLastInsertID() {
  118. $id = db_insert('test')
  119. ->fields([
  120. 'name' => 'Larry',
  121. 'age' => '30',
  122. ])
  123. ->execute();
  124. $this->assertIdentical($id, '5', 'Auto-increment ID returned successfully.');
  125. }
  126. /**
  127. * Tests that the INSERT INTO ... SELECT (fields) ... syntax works.
  128. */
  129. public function testInsertSelectFields() {
  130. $query = db_select('test_people', 'tp');
  131. // The query builder will always append expressions after fields.
  132. // Add the expression first to test that the insert fields are correctly
  133. // re-ordered.
  134. $query->addExpression('tp.age', 'age');
  135. $query
  136. ->fields('tp', ['name', 'job'])
  137. ->condition('tp.name', 'Meredith');
  138. // The resulting query should be equivalent to:
  139. // INSERT INTO test (age, name, job)
  140. // SELECT tp.age AS age, tp.name AS name, tp.job AS job
  141. // FROM test_people tp
  142. // WHERE tp.name = 'Meredith'
  143. db_insert('test')
  144. ->from($query)
  145. ->execute();
  146. $saved_age = db_query('SELECT age FROM {test} WHERE name = :name', [':name' => 'Meredith'])->fetchField();
  147. $this->assertIdentical($saved_age, '30', 'Can retrieve after inserting.');
  148. }
  149. /**
  150. * Tests that the INSERT INTO ... SELECT * ... syntax works.
  151. */
  152. public function testInsertSelectAll() {
  153. $query = db_select('test_people', 'tp')
  154. ->fields('tp')
  155. ->condition('tp.name', 'Meredith');
  156. // The resulting query should be equivalent to:
  157. // INSERT INTO test_people_copy
  158. // SELECT *
  159. // FROM test_people tp
  160. // WHERE tp.name = 'Meredith'
  161. db_insert('test_people_copy')
  162. ->from($query)
  163. ->execute();
  164. $saved_age = db_query('SELECT age FROM {test_people_copy} WHERE name = :name', [':name' => 'Meredith'])->fetchField();
  165. $this->assertIdentical($saved_age, '30', 'Can retrieve after inserting.');
  166. }
  167. /**
  168. * Tests that we can INSERT INTO a special named column.
  169. */
  170. public function testSpecialColumnInsert() {
  171. $id = db_insert('test_special_columns')
  172. ->fields([
  173. 'id' => 2,
  174. 'offset' => 'Offset value 2',
  175. ])
  176. ->execute();
  177. $saved_value = db_query('SELECT "offset" FROM {test_special_columns} WHERE id = :id', [':id' => 2])->fetchField();
  178. $this->assertIdentical($saved_value, 'Offset value 2', 'Can retrieve special column name value after inserting.');
  179. }
  180. }