‪TYPO3CMS  10.4
BulkInsertQuery.php
Go to the documentation of this file.
1 <?php
2 
3 declare(strict_types=1);
4 
5 /*
6  * This file is part of the TYPO3 CMS project.
7  *
8  * It is free software; you can redistribute it and/or modify it under
9  * the terms of the GNU General Public License, either version 2
10  * of the License, or any later version.
11  *
12  * For the full copyright and license information, please read the
13  * LICENSE.txt file that was distributed with this source code.
14  *
15  * The TYPO3 project - inspiring people to share!
16  */
17 
19 
20 use Doctrine\DBAL\Connection;
21 
35 {
39  protected ‪$columns;
40 
44  protected ‪$connection;
45 
49  protected ‪$table;
50 
54  protected ‪$parameters = [];
55 
59  protected ‪$types = [];
60 
64  protected ‪$values = [];
65 
74  public function ‪__construct(‪Connection ‪$connection, string ‪$table, array ‪$columns = [])
75  {
76  $this->connection = ‪$connection;
78  $this->columns = ‪$columns;
79  }
80 
86  public function ‪__toString(): string
87  {
88  return $this->‪getSQL();
89  }
90 
114  public function ‪addValues(array ‪$values, array ‪$types = [])
115  {
116  $valueSet = [];
117 
118  if (empty($this->columns)) {
119  foreach (‪$values as $index => $value) {
120  $this->parameters[] = $value;
121  $this->types[] = ‪$types[$index] ?? null;
122  $valueSet[] = '?';
123  }
124 
125  $this->values[] = $valueSet;
126 
127  return;
128  }
129 
130  foreach ($this->columns as $index => $column) {
131  $namedValue = isset(‪$values[$column]) || array_key_exists($column, ‪$values);
132  $positionalValue = isset(‪$values[$index]) || array_key_exists($index, ‪$values);
133 
134  if (!$namedValue && !$positionalValue) {
135  throw new \InvalidArgumentException(
136  sprintf('No value specified for column %s (index %d).', $column, $index),
137  1476049651
138  );
139  }
140 
141  if ($namedValue && $positionalValue && ‪$values[$column] !== ‪$values[$index]) {
142  throw new \InvalidArgumentException(
143  sprintf('Multiple values specified for column %s (index %d).', $column, $index),
144  1476049652
145  );
146  }
147 
148  $this->parameters[] = $namedValue ? ‪$values[$column] : ‪$values[$index];
149  $valueSet[] = '?';
150 
151  $namedType = isset(‪$types[$column]);
152  $positionalType = isset(‪$types[$index]);
153 
154  if ($namedType && $positionalType && ‪$types[$column] !== ‪$types[$index]) {
155  throw new \InvalidArgumentException(
156  sprintf('Multiple types specified for column %s (index %d).', $column, $index),
157  1476049653
158  );
159  }
160 
161  if ($namedType) {
162  $this->types[] = ‪$types[$column];
163 
164  continue;
165  }
166 
167  if ($positionalType) {
168  $this->types[] = ‪$types[$index];
169 
170  continue;
171  }
172 
173  $this->types[] = null;
174  }
175 
176  $this->values[] = $valueSet;
177  }
178 
187  public function ‪execute(): int
188  {
189  $platform = $this->connection->getDatabasePlatform();
190  $insertMaxRows = $this->‪getInsertMaxRows();
191 
192  if ($insertMaxRows > 0 && count($this->values) > $insertMaxRows) {
193  throw new \LogicException(
194  sprintf(
195  'You can only insert %d rows in a single INSERT statement with platform "%s".',
196  $insertMaxRows,
197  $platform->getName()
198  ),
199  1476049654
200  );
201  }
202 
203  return $this->connection->executeUpdate($this->‪getSQL(), $this->parameters, $this->types);
204  }
205 
211  protected function ‪getInsertMaxRows(): int
212  {
213  $platform = $this->connection->getDatabasePlatform();
214  if ($platform->getName() === 'mssql' && $platform->getReservedKeywordsList()->isKeyword('MERGE')) {
215  return 1000;
216  }
217 
218  return 0;
219  }
220 
226  public function ‪getParameters(): array
227  {
228  return ‪$this->parameters;
229  }
230 
236  public function ‪getParameterTypes(): array
237  {
238  return ‪$this->types;
239  }
240 
248  public function ‪getSQL(): string
249  {
250  if (empty($this->values)) {
251  throw new \LogicException(
252  'You need to add at least one set of values before generating the SQL.',
253  1476049702
254  );
255  }
256 
258  $columnList = '';
259 
260  if (!empty($this->columns)) {
261  $columnList = sprintf(
262  ' (%s)',
263  implode(
264  ', ',
265  array_map(
266  function ($column) use (‪$connection) {
267  return ‪$connection->‪quoteIdentifier($column);
268  },
270  )
271  )
272  );
273  }
274 
275  return sprintf(
276  'INSERT INTO %s%s VALUES (%s)',
277  $this->table,
278  $columnList,
279  implode(
280  '), (',
281  array_map(
282  function (array $valueSet) {
283  return implode(', ', $valueSet);
284  },
286  )
287  )
288  );
289  }
290 }
‪TYPO3\CMS\Core\Database\Query\BulkInsertQuery\$columns
‪string[] $columns
Definition: BulkInsertQuery.php:38
‪TYPO3\CMS\Core\Database\Query\BulkInsertQuery\getInsertMaxRows
‪int getInsertMaxRows()
Definition: BulkInsertQuery.php:205
‪TYPO3\CMS\Core\Database\Connection\quoteIdentifier
‪string quoteIdentifier($identifier)
Definition: Connection.php:133
‪TYPO3\CMS\Core\Database\Query\BulkInsertQuery\$table
‪string $table
Definition: BulkInsertQuery.php:46
‪TYPO3\CMS\Core\Database\Query\BulkInsertQuery\execute
‪int execute()
Definition: BulkInsertQuery.php:181
‪TYPO3\CMS\Core\Database\Query\BulkInsertQuery\$values
‪array $values
Definition: BulkInsertQuery.php:58
‪TYPO3\CMS\Core\Database\Query\BulkInsertQuery\getSQL
‪string getSQL()
Definition: BulkInsertQuery.php:242
‪TYPO3\CMS\Core\Database\Query\BulkInsertQuery\getParameterTypes
‪array getParameterTypes()
Definition: BulkInsertQuery.php:230
‪TYPO3\CMS\Core\Database\Query\BulkInsertQuery\__toString
‪string __toString()
Definition: BulkInsertQuery.php:80
‪TYPO3\CMS\Core\Database\Query\BulkInsertQuery\$parameters
‪array $parameters
Definition: BulkInsertQuery.php:50
‪TYPO3\CMS\Core\Database\Connection
Definition: Connection.php:36
‪TYPO3\CMS\Core\Database\Query\BulkInsertQuery\getParameters
‪array getParameters()
Definition: BulkInsertQuery.php:220
‪TYPO3\CMS\Core\Database\Query
Definition: BulkInsertQuery.php:18
‪TYPO3\CMS\Core\Database\Query\BulkInsertQuery
Definition: BulkInsertQuery.php:35
‪TYPO3\CMS\Core\Database\Query\BulkInsertQuery\$connection
‪Connection $connection
Definition: BulkInsertQuery.php:42
‪TYPO3\CMS\Core\Database\Query\BulkInsertQuery\addValues
‪addValues(array $values, array $types=[])
Definition: BulkInsertQuery.php:108
‪TYPO3\CMS\Core\Database\Query\BulkInsertQuery\$types
‪array $types
Definition: BulkInsertQuery.php:54
‪TYPO3\CMS\Core\Database\Query\BulkInsertQuery\__construct
‪__construct(Connection $connection, string $table, array $columns=[])
Definition: BulkInsertQuery.php:68