3 namespace Drupal\KernelTests\Core\Database;
6 * Tests the insert builder.
10 class InsertTest extends DatabaseTestBase {
13 * Tests very basic insert functionality.
15 public function testSimpleInsert() {
16 $num_records_before = db_query('SELECT COUNT(*) FROM {test}')->fetchField();
18 $query = db_insert('test');
24 // Check how many records are queued for insertion.
25 $this->assertIdentical($query->count(), 1, 'One record is queued for insertion.');
28 $num_records_after = db_query('SELECT COUNT(*) FROM {test}')->fetchField();
29 $this->assertSame($num_records_before + 1, (int) $num_records_after, 'Record inserts correctly.');
30 $saved_age = db_query('SELECT age FROM {test} WHERE name = :name', [':name' => 'Yoko'])->fetchField();
31 $this->assertIdentical($saved_age, '29', 'Can retrieve after inserting.');
35 * Tests that we can insert multiple records in one query object.
37 public function testMultiInsert() {
38 $num_records_before = (int) db_query('SELECT COUNT(*) FROM {test}')->fetchField();
40 $query = db_insert('test');
46 // We should be able to specify values in any order if named.
52 // Check how many records are queued for insertion.
53 $this->assertIdentical($query->count(), 2, 'Two records are queued for insertion.');
55 // We should be able to say "use the field order".
56 // This is not the recommended mechanism for most cases, but it should work.
57 $query->values(['Moe', '32']);
59 // Check how many records are queued for insertion.
60 $this->assertIdentical($query->count(), 3, 'Three records are queued for insertion.');
63 $num_records_after = (int) db_query('SELECT COUNT(*) FROM {test}')->fetchField();
64 $this->assertSame($num_records_before + 3, $num_records_after, 'Record inserts correctly.');
65 $saved_age = db_query('SELECT age FROM {test} WHERE name = :name', [':name' => 'Larry'])->fetchField();
66 $this->assertIdentical($saved_age, '30', 'Can retrieve after inserting.');
67 $saved_age = db_query('SELECT age FROM {test} WHERE name = :name', [':name' => 'Curly'])->fetchField();
68 $this->assertIdentical($saved_age, '31', 'Can retrieve after inserting.');
69 $saved_age = db_query('SELECT age FROM {test} WHERE name = :name', [':name' => 'Moe'])->fetchField();
70 $this->assertIdentical($saved_age, '32', 'Can retrieve after inserting.');
74 * Tests that an insert object can be reused with new data after it executes.
76 public function testRepeatedInsert() {
77 $num_records_before = db_query('SELECT COUNT(*) FROM {test}')->fetchField();
79 $query = db_insert('test');
85 // Check how many records are queued for insertion.
86 $this->assertIdentical($query->count(), 1, 'One record is queued for insertion.');
87 // This should run the insert, but leave the fields intact.
90 // We should be able to specify values in any order if named.
95 // Check how many records are queued for insertion.
96 $this->assertIdentical($query->count(), 1, 'One record is queued for insertion.');
99 // We should be able to say "use the field order".
100 $query->values(['Moe', '32']);
102 // Check how many records are queued for insertion.
103 $this->assertIdentical($query->count(), 1, 'One record is queued for insertion.');
106 $num_records_after = db_query('SELECT COUNT(*) FROM {test}')->fetchField();
107 $this->assertSame((int) $num_records_before + 3, (int) $num_records_after, 'Record inserts correctly.');
108 $saved_age = db_query('SELECT age FROM {test} WHERE name = :name', [':name' => 'Larry'])->fetchField();
109 $this->assertIdentical($saved_age, '30', 'Can retrieve after inserting.');
110 $saved_age = db_query('SELECT age FROM {test} WHERE name = :name', [':name' => 'Curly'])->fetchField();
111 $this->assertIdentical($saved_age, '31', 'Can retrieve after inserting.');
112 $saved_age = db_query('SELECT age FROM {test} WHERE name = :name', [':name' => 'Moe'])->fetchField();
113 $this->assertIdentical($saved_age, '32', 'Can retrieve after inserting.');
117 * Tests that we can specify fields without values and specify values later.
119 public function testInsertFieldOnlyDefinition() {
120 // This is useful for importers, when we want to create a query and define
121 // its fields once, then loop over a multi-insert execution.
123 ->fields(['name', 'age'])
124 ->values(['Larry', '30'])
125 ->values(['Curly', '31'])
126 ->values(['Moe', '32'])
128 $saved_age = db_query('SELECT age FROM {test} WHERE name = :name', [':name' => 'Larry'])->fetchField();
129 $this->assertIdentical($saved_age, '30', 'Can retrieve after inserting.');
130 $saved_age = db_query('SELECT age FROM {test} WHERE name = :name', [':name' => 'Curly'])->fetchField();
131 $this->assertIdentical($saved_age, '31', 'Can retrieve after inserting.');
132 $saved_age = db_query('SELECT age FROM {test} WHERE name = :name', [':name' => 'Moe'])->fetchField();
133 $this->assertIdentical($saved_age, '32', 'Can retrieve after inserting.');
137 * Tests that inserts return the proper auto-increment ID.
139 public function testInsertLastInsertID() {
140 $id = db_insert('test')
147 $this->assertIdentical($id, '5', 'Auto-increment ID returned successfully.');
151 * Tests that the INSERT INTO ... SELECT (fields) ... syntax works.
153 public function testInsertSelectFields() {
154 $query = db_select('test_people', 'tp');
155 // The query builder will always append expressions after fields.
156 // Add the expression first to test that the insert fields are correctly
158 $query->addExpression('tp.age', 'age');
160 ->fields('tp', ['name', 'job'])
161 ->condition('tp.name', 'Meredith');
163 // The resulting query should be equivalent to:
164 // INSERT INTO test (age, name, job)
165 // SELECT tp.age AS age, tp.name AS name, tp.job AS job
166 // FROM test_people tp
167 // WHERE tp.name = 'Meredith'
172 $saved_age = db_query('SELECT age FROM {test} WHERE name = :name', [':name' => 'Meredith'])->fetchField();
173 $this->assertIdentical($saved_age, '30', 'Can retrieve after inserting.');
177 * Tests that the INSERT INTO ... SELECT * ... syntax works.
179 public function testInsertSelectAll() {
180 $query = db_select('test_people', 'tp')
182 ->condition('tp.name', 'Meredith');
184 // The resulting query should be equivalent to:
185 // INSERT INTO test_people_copy
187 // FROM test_people tp
188 // WHERE tp.name = 'Meredith'
189 db_insert('test_people_copy')
193 $saved_age = db_query('SELECT age FROM {test_people_copy} WHERE name = :name', [':name' => 'Meredith'])->fetchField();
194 $this->assertIdentical($saved_age, '30', 'Can retrieve after inserting.');
198 * Tests that we can INSERT INTO a special named column.
200 public function testSpecialColumnInsert() {
201 $this->connection->insert('test_special_columns')
204 'offset' => 'Offset value 2',
205 'function' => 'foobar',
208 $result = $this->connection->select('test_special_columns')
209 ->fields('test_special_columns', ['offset', 'function'])
210 ->condition('test_special_columns.function', 'foobar')
212 $record = $result->fetch();
213 $this->assertSame('Offset value 2', $record->offset);
214 $this->assertSame('foobar', $record->function);