TYPO3 CMS  TYPO3_8-7
Connection.php
Go to the documentation of this file.
1 <?php
2 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 
26 
27 class Connection extends \Doctrine\DBAL\Connection
28 {
32  const PARAM_NULL = \PDO::PARAM_NULL; // 0
33 
37  const PARAM_INT = \PDO::PARAM_INT; // 1
38 
42  const PARAM_STR = \PDO::PARAM_STR; // 2
43 
47  const PARAM_LOB = \PDO::PARAM_LOB; // 3
48 
52  const PARAM_STMT = \PDO::PARAM_STMT; // 4
53 
57  const PARAM_BOOL = \PDO::PARAM_BOOL; // 5
58 
63 
74  public function __construct(array $params, Driver $driver, Configuration $config = null, EventManager $em = null)
75  {
76  parent::__construct($params, $driver, $config, $em);
77  $this->_expr = GeneralUtility::makeInstance(ExpressionBuilder::class, $this);
78  }
79 
85  public function connect(): bool
86  {
87  // Early return if the connection is already open and custom setup has been done.
88  if (!parent::connect()) {
89  return false;
90  }
91 
92  foreach ($this->prepareConnectionCommands as $command) {
93  if ($this->executeUpdate($command) === false) {
94  GeneralUtility::sysLog(
95  'Could not initialize DB connection with query "' . $command . '": ' . $this->errorInfo(),
96  'core',
98  );
99  }
100  }
101 
102  return true;
103  }
104 
110  public function createQueryBuilder(): QueryBuilder
111  {
112  return GeneralUtility::makeInstance(QueryBuilder::class, $this);
113  }
114 
126  public function quoteIdentifier($identifier): string
127  {
128  if ($identifier === '*') {
129  return $identifier;
130  }
131 
132  return parent::quoteIdentifier($identifier);
133  }
134 
144  public function quoteIdentifiers(array $input): array
145  {
146  return array_map([$this, 'quoteIdentifier'], $input);
147  }
148 
159  public function quoteColumnValuePairs(array $input): array
160  {
161  return array_combine($this->quoteIdentifiers(array_keys($input)), array_values($input));
162  }
163 
172  protected function quoteColumnTypes(array $input): array
173  {
174  if (!is_string(key($input))) {
175  return $input;
176  }
177 
178  return $this->quoteColumnValuePairs($input);
179  }
180 
193  public function insert($tableName, array $data, array $types = []): int
194  {
195  return parent::insert(
196  $this->quoteIdentifier($tableName),
197  $this->quoteColumnValuePairs($data),
198  $this->quoteColumnTypes($types)
199  );
200  }
201 
215  public function bulkInsert(string $tableName, array $data, array $columns = [], array $types = []): int
216  {
217  $query = GeneralUtility::makeInstance(Query\BulkInsertQuery::class, $this, $tableName, $columns);
218  foreach ($data as $values) {
219  $query->addValues($values, $types);
220  }
221 
222  return $query->execute();
223  }
224 
241  public function select(
242  array $columns,
243  string $tableName,
244  array $identifiers = [],
245  array $groupBy = [],
246  array $orderBy = [],
247  int $limit = 0,
248  int $offset = 0
249  ): Statement {
250  $query = $this->createQueryBuilder();
251  $query->select(...$columns)
252  ->from($tableName);
253 
254  foreach ($identifiers as $identifier => $value) {
255  $query->andWhere($query->expr()->eq($identifier, $query->createNamedParameter($value)));
256  }
257 
258  foreach ($orderBy as $fieldName => $order) {
259  $query->addOrderBy($fieldName, $order);
260  }
261 
262  if (!empty($groupBy)) {
263  $query->groupBy(...$groupBy);
264  }
265 
266  if ($limit > 0) {
267  $query->setMaxResults($limit);
268  $query->setFirstResult($offset);
269  }
270 
271  return $query->execute();
272  }
273 
287  public function update($tableName, array $data, array $identifier, array $types = []): int
288  {
289  return parent::update(
290  $this->quoteIdentifier($tableName),
291  $this->quoteColumnValuePairs($data),
292  $this->quoteColumnValuePairs($identifier),
293  $this->quoteColumnTypes($types)
294  );
295  }
296 
309  public function delete($tableName, array $identifier, array $types = []): int
310  {
311  return parent::delete(
312  $this->quoteIdentifier($tableName),
313  $this->quoteColumnValuePairs($identifier),
314  $this->quoteColumnTypes($types)
315  );
316  }
317 
329  public function truncate(string $tableName, bool $cascade = false): int
330  {
331  return $this->executeUpdate(
332  $this->getDatabasePlatform()->getTruncateTableSQL(
333  $this->quoteIdentifier($tableName),
334  $cascade
335  )
336  );
337  }
338 
348  public function count(string $item, string $tableName, array $identifiers): int
349  {
350  $query = $this->createQueryBuilder();
351  $query->count($item)
352  ->from($tableName);
353 
354  foreach ($identifiers as $identifier => $value) {
355  $query->andWhere($query->expr()->eq($identifier, $query->createNamedParameter($value)));
356  }
357 
358  return (int)$query->execute()->fetchColumn(0);
359  }
360 
370  public function getServerVersion(): string
371  {
372  $version = $this->getDatabasePlatform()->getName();
373  switch ($version) {
374  case 'mysql':
375  case 'pdo_mysql':
376  case 'drizzle_pdo_mysql':
377  $version = 'MySQL';
378  break;
379  case 'postgresql':
380  case 'pdo_postgresql':
381  $version = 'PostgreSQL';
382  break;
383  case 'oci8':
384  case 'pdo_oracle':
385  $version = 'Oracle';
386  break;
387  case 'sqlsrv':
388  case 'pdo_sqlsrv':
389  $version = 'SQLServer';
390  break;
391  }
392 
393  // Driver does not support version specific platforms.
394  if (!$this->getDriver() instanceof \Doctrine\DBAL\VersionAwarePlatformDriver) {
395  return $version;
396  }
397 
398  if ($this->getWrappedConnection() instanceof \Doctrine\DBAL\Driver\ServerInfoAwareConnection
399  && !$this->getWrappedConnection()->requiresQueryForServerVersion()
400  ) {
401  $version .= ' ' . $this->getWrappedConnection()->getServerVersion();
402  }
403 
404  return $version;
405  }
406 
412  public function prepareConnection(string $commands)
413  {
414  if (empty($commands)) {
415  return;
416  }
417 
418  $this->prepareConnectionCommands = GeneralUtility::trimExplode(
419  LF,
420  str_replace(
421  '\' . LF . \'',
422  LF,
423  $commands
424  ),
425  true
426  );
427  }
428 
439  public function lastInsertId($tableName = null, string $fieldName = 'uid'): string
440  {
441  if ($this->getDatabasePlatform() instanceof PostgreSqlPlatform) {
442  return parent::lastInsertId(trim(implode('_', [$tableName, $fieldName, 'seq']), '_'));
443  }
444 
445  return (string)parent::lastInsertId($tableName);
446  }
447 }
insert($tableName, array $data, array $types=[])
Definition: Connection.php:193
update($tableName, array $data, array $identifier, array $types=[])
Definition: Connection.php:287
lastInsertId($tableName=null, string $fieldName='uid')
Definition: Connection.php:439
static trimExplode($delim, $string, $removeEmptyValues=false, $limit=0)
static makeInstance($className,... $constructorArguments)
select(array $columns, string $tableName, array $identifiers=[], array $groupBy=[], array $orderBy=[], int $limit=0, int $offset=0)
Definition: Connection.php:241
count(string $item, string $tableName, array $identifiers)
Definition: Connection.php:348
truncate(string $tableName, bool $cascade=false)
Definition: Connection.php:329
bulkInsert(string $tableName, array $data, array $columns=[], array $types=[])
Definition: Connection.php:215
prepareConnection(string $commands)
Definition: Connection.php:412
__construct(array $params, Driver $driver, Configuration $config=null, EventManager $em=null)
Definition: Connection.php:74