d6b0f8dd80df34993e34961c7092e40f0081bcbf
[yaffs-website] / web / core / tests / Drupal / KernelTests / Core / Database / InsertTest.php
1 <?php
2
3 namespace Drupal\KernelTests\Core\Database;
4
5 /**
6  * Tests the insert builder.
7  *
8  * @group Database
9  */
10 class InsertTest extends DatabaseTestBase {
11
12   /**
13    * Tests very basic insert functionality.
14    */
15   public function testSimpleInsert() {
16     $num_records_before = db_query('SELECT COUNT(*) FROM {test}')->fetchField();
17
18     $query = db_insert('test');
19     $query->fields([
20       'name' => 'Yoko',
21       'age' => '29',
22     ]);
23
24     // Check how many records are queued for insertion.
25     $this->assertIdentical($query->count(), 1, 'One record is queued for insertion.');
26     $query->execute();
27
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.');
32   }
33
34   /**
35    * Tests that we can insert multiple records in one query object.
36    */
37   public function testMultiInsert() {
38     $num_records_before = (int) db_query('SELECT COUNT(*) FROM {test}')->fetchField();
39
40     $query = db_insert('test');
41     $query->fields([
42       'name' => 'Larry',
43       'age' => '30',
44     ]);
45
46     // We should be able to specify values in any order if named.
47     $query->values([
48       'age' => '31',
49       'name' => 'Curly',
50     ]);
51
52     // Check how many records are queued for insertion.
53     $this->assertIdentical($query->count(), 2, 'Two records are queued for insertion.');
54
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']);
58
59     // Check how many records are queued for insertion.
60     $this->assertIdentical($query->count(), 3, 'Three records are queued for insertion.');
61     $query->execute();
62
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.');
71   }
72
73   /**
74    * Tests that an insert object can be reused with new data after it executes.
75    */
76   public function testRepeatedInsert() {
77     $num_records_before = db_query('SELECT COUNT(*) FROM {test}')->fetchField();
78
79     $query = db_insert('test');
80
81     $query->fields([
82       'name' => 'Larry',
83       'age' => '30',
84     ]);
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.
88     $query->execute();
89
90     // We should be able to specify values in any order if named.
91     $query->values([
92       'age' => '31',
93       'name' => 'Curly',
94     ]);
95     // Check how many records are queued for insertion.
96     $this->assertIdentical($query->count(), 1, 'One record is queued for insertion.');
97     $query->execute();
98
99     // We should be able to say "use the field order".
100     $query->values(['Moe', '32']);
101
102     // Check how many records are queued for insertion.
103     $this->assertIdentical($query->count(), 1, 'One record is queued for insertion.');
104     $query->execute();
105
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.');
114   }
115
116   /**
117    * Tests that we can specify fields without values and specify values later.
118    */
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.
122     db_insert('test')
123       ->fields(['name', 'age'])
124       ->values(['Larry', '30'])
125       ->values(['Curly', '31'])
126       ->values(['Moe', '32'])
127       ->execute();
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.');
134   }
135
136   /**
137    * Tests that inserts return the proper auto-increment ID.
138    */
139   public function testInsertLastInsertID() {
140     $id = db_insert('test')
141       ->fields([
142         'name' => 'Larry',
143         'age' => '30',
144       ])
145       ->execute();
146
147     $this->assertIdentical($id, '5', 'Auto-increment ID returned successfully.');
148   }
149
150   /**
151    * Tests that the INSERT INTO ... SELECT (fields) ... syntax works.
152    */
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
157     // re-ordered.
158     $query->addExpression('tp.age', 'age');
159     $query
160       ->fields('tp', ['name', 'job'])
161       ->condition('tp.name', 'Meredith');
162
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'
168     db_insert('test')
169       ->from($query)
170       ->execute();
171
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.');
174   }
175
176   /**
177    * Tests that the INSERT INTO ... SELECT * ... syntax works.
178    */
179   public function testInsertSelectAll() {
180     $query = db_select('test_people', 'tp')
181       ->fields('tp')
182       ->condition('tp.name', 'Meredith');
183
184     // The resulting query should be equivalent to:
185     // INSERT INTO test_people_copy
186     // SELECT *
187     // FROM test_people tp
188     // WHERE tp.name = 'Meredith'
189     db_insert('test_people_copy')
190       ->from($query)
191       ->execute();
192
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.');
195   }
196
197   /**
198    * Tests that we can INSERT INTO a special named column.
199    */
200   public function testSpecialColumnInsert() {
201     $this->connection->insert('test_special_columns')
202       ->fields([
203         'id' => 2,
204         'offset' => 'Offset value 2',
205         'function' => 'foobar',
206       ])
207       ->execute();
208     $result = $this->connection->select('test_special_columns')
209       ->fields('test_special_columns', ['offset', 'function'])
210       ->condition('test_special_columns.function', 'foobar')
211       ->execute();
212     $record = $result->fetch();
213     $this->assertSame('Offset value 2', $record->offset);
214     $this->assertSame('foobar', $record->function);
215   }
216
217 }