‪TYPO3CMS  11.5
Connection.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\Common\EventManager;
21 use Doctrine\DBAL\Configuration;
22 use Doctrine\DBAL\Driver;
23 use Doctrine\DBAL\Driver\ServerInfoAwareConnection;
24 use Doctrine\DBAL\Platforms\PostgreSQL94Platform as PostgreSqlPlatform;
25 use Doctrine\DBAL\Platforms\SQLServer2012Platform;
26 use Doctrine\DBAL\Result;
27 use Doctrine\DBAL\Schema\AbstractSchemaManager;
28 use Doctrine\DBAL\Types\Type;
29 use Doctrine\DBAL\VersionAwarePlatformDriver;
30 use Psr\Log\LoggerAwareInterface;
31 use Psr\Log\LoggerAwareTrait;
34 use TYPO3\CMS\Core\Database\Query\QueryBuilder;
36 
37 class ‪Connection extends \Doctrine\DBAL\Connection implements LoggerAwareInterface
38 {
39  use LoggerAwareTrait;
40 
44  public const ‪PARAM_NULL = \PDO::PARAM_NULL; // 0
45 
49  public const ‪PARAM_INT = \PDO::PARAM_INT; // 1
50 
54  public const ‪PARAM_STR = \PDO::PARAM_STR; // 2
55 
59  public const ‪PARAM_LOB = \PDO::PARAM_LOB; // 3
60 
64  public const ‪PARAM_STMT = \PDO::PARAM_STMT; // 4
65 
69  public const ‪PARAM_BOOL = \PDO::PARAM_BOOL; // 5
70 
72  protected ‪$_expr;
73 
77  private ‪$prepareConnectionCommands = [];
78 
89  public function ‪__construct(array $params, Driver $driver, ?Configuration $config = null, ?EventManager $em = null)
90  {
91  parent::__construct($params, $driver, $config, $em);
92  $this->_expr = GeneralUtility::makeInstance(ExpressionBuilder::class, $this);
93  }
94 
100  public function ‪connect(): bool
101  {
102  // Early return if the connection is already open and custom setup has been done.
103  if (!parent::connect()) {
104  return false;
105  }
106 
107  foreach ($this->prepareConnectionCommands as $command) {
108  $this->executeStatement($command);
109  }
110 
111  return true;
112  }
113 
119  public function ‪createQueryBuilder(): QueryBuilder
120  {
121  return GeneralUtility::makeInstance(QueryBuilder::class, $this);
122  }
123 
135  public function ‪quoteIdentifier($identifier): string
136  {
137  if ($identifier === '*') {
138  return $identifier;
139  }
140 
141  return parent::quoteIdentifier($identifier);
142  }
143 
153  public function ‪quoteIdentifiers(array $input): array
154  {
155  return array_map([$this, 'quoteIdentifier'], $input);
156  }
157 
168  public function ‪quoteColumnValuePairs(array $input): array
169  {
170  return array_combine($this->‪quoteIdentifiers(array_keys($input)), array_values($input));
171  }
172 
181  protected function ‪quoteColumnTypes(array $input): array
182  {
183  if (!is_string(key($input))) {
184  return $input;
185  }
186 
187  return $this->‪quoteColumnValuePairs($input);
188  }
189 
197  public function ‪escapeLikeWildcards(string $value): string
198  {
199  return addcslashes($value, '_%');
200  }
201 
213  public function ‪insert($tableName, array $data, array $types = []): int
214  {
215  return parent::insert(
216  $this->‪quoteIdentifier($tableName),
217  $this->‪quoteColumnValuePairs($data),
218  $this->‪quoteColumnTypes($types)
219  );
220  }
221 
234  public function ‪bulkInsert(string $tableName, array $data, array $columns = [], array $types = []): int
235  {
236  $query = GeneralUtility::makeInstance(BulkInsertQuery::class, $this, $tableName, $columns);
237  foreach ($data as $values) {
238  $query->addValues($values, $types);
239  }
240 
241  return $query->execute();
242  }
243 
259  public function ‪select(
260  array $columns,
261  string $tableName,
262  array $identifiers = [],
263  array $groupBy = [],
264  array $orderBy = [],
265  int $limit = 0,
266  int $offset = 0
267  ) {
268  $query = $this->‪createQueryBuilder();
269  $query->select(...$columns)
270  ->from($tableName);
271 
272  foreach ($identifiers as $identifier => $value) {
273  $query->andWhere($query->expr()->eq($identifier, $query->createNamedParameter($value)));
274  }
275 
276  foreach ($orderBy as $fieldName => $order) {
277  $query->addOrderBy($fieldName, $order);
278  }
279 
280  if (!empty($groupBy)) {
281  $query->groupBy(...$groupBy);
282  }
283 
284  if ($limit > 0) {
285  $query->setMaxResults($limit);
286  $query->setFirstResult($offset);
287  }
288 
289  return $query->executeQuery();
290  }
291 
304  public function ‪update($tableName, array $data, array $identifier, array $types = []): int
305  {
306  return parent::update(
307  $this->‪quoteIdentifier($tableName),
308  $this->‪quoteColumnValuePairs($data),
309  $this->‪quoteColumnValuePairs($identifier),
310  $this->‪quoteColumnTypes($types)
311  );
312  }
313 
325  public function delete($tableName, array $identifier, array $types = []): int
326  {
327  return parent::delete(
328  $this->‪quoteIdentifier($tableName),
329  $this->‪quoteColumnValuePairs($identifier),
330  $this->‪quoteColumnTypes($types)
331  );
332  }
333 
344  public function ‪truncate(string $tableName, bool $cascade = false): int
345  {
346  return $this->executeStatement(
347  $this->getDatabasePlatform()->getTruncateTableSQL(
348  $this->‪quoteIdentifier($tableName),
349  $cascade
350  )
351  );
352  }
353 
363  public function ‪count(string $item, string $tableName, array $identifiers): int
364  {
365  $query = $this->‪createQueryBuilder();
366  $query->count($item)
367  ->from($tableName);
368 
369  foreach ($identifiers as $identifier => $value) {
370  $query->andWhere($query->expr()->eq($identifier, $query->createNamedParameter($value)));
371  }
372 
373  return (int)$query->executeQuery()->fetchOne();
374  }
375 
385  public function ‪getServerVersion(): string
386  {
387  $version = $this->getDatabasePlatform()->getName();
388  switch ($version) {
389  case 'mysql':
390  case 'pdo_mysql':
391  case 'drizzle_pdo_mysql':
392  $version = 'MySQL';
393  break;
394  case 'postgresql':
395  case 'pdo_postgresql':
396  $version = 'PostgreSQL';
397  break;
398  case 'oci8':
399  case 'pdo_oracle':
400  $version = 'Oracle';
401  break;
402  case 'sqlsrv':
403  case 'pdo_sqlsrv':
404  $version = 'SQLServer';
405  break;
406  }
407 
408  // Driver does not support version specific platforms.
409  if (!$this->getDriver() instanceof VersionAwarePlatformDriver) {
410  return $version;
411  }
412 
413  if ($this->getWrappedConnection() instanceof ServerInfoAwareConnection
414  && !$this->getWrappedConnection()->requiresQueryForServerVersion()
415  ) {
416  $version .= ' ' . $this->getWrappedConnection()->getServerVersion();
417  }
418 
419  return $version;
420  }
421 
428  public function ‪createSchemaManager(): AbstractSchemaManager
429  {
430  return $this->_driver->getSchemaManager($this);
431  }
432 
438  public function ‪prepareConnection(string $commands)
439  {
440  if (empty($commands)) {
441  return;
442  }
443 
444  $this->prepareConnectionCommands = ‪GeneralUtility::trimExplode(
445  LF,
446  str_replace(
447  '\' . LF . \'',
448  LF,
449  $commands
450  ),
451  true
452  );
453  }
454 
465  public function ‪lastInsertId($tableName = null, string $fieldName = 'uid'): string
466  {
467  $databasePlatform = $this->getDatabasePlatform();
468  if ($databasePlatform instanceof PostgreSqlPlatform) {
469  return parent::lastInsertId(trim(implode('_', [$tableName, $fieldName, 'seq']), '_'));
470  }
471  if ($databasePlatform instanceof SQLServer2012Platform) {
472  // lastInsertId() in mssql >2012 takes a sequence name and not the table name as
473  // argument. If no argument is given, last insert id of latest table is returned.
474  // https://docs.microsoft.com/de-de/sql/connect/php/pdo-lastinsertid?view=sql-server-2017
475  return (string)parent::lastInsertId();
476  }
477 
478  return (string)parent::lastInsertId($tableName);
479  }
480 
486  public function ‪getExpressionBuilder()
487  {
488  return ‪$this->_expr;
489  }
490 }
‪TYPO3\CMS\Core\Database\Connection\truncate
‪int truncate(string $tableName, bool $cascade=false)
Definition: Connection.php:342
‪TYPO3\CMS\Core\Utility\GeneralUtility\trimExplode
‪static list< string > trimExplode($delim, $string, $removeEmptyValues=false, $limit=0)
Definition: GeneralUtility.php:999
‪TYPO3\CMS\Core\Database\Connection\PARAM_BOOL
‪const PARAM_BOOL
Definition: Connection.php:69
‪TYPO3\CMS\Core\Database\Connection\escapeLikeWildcards
‪string escapeLikeWildcards(string $value)
Definition: Connection.php:195
‪TYPO3\CMS\Core\Database\Connection\PARAM_INT
‪const PARAM_INT
Definition: Connection.php:49
‪TYPO3\CMS\Core\Database\Query\Expression\ExpressionBuilder
Definition: ExpressionBuilder.php:36
‪TYPO3\CMS\Core\Database\Connection\$_expr
‪ExpressionBuilder $_expr
Definition: Connection.php:71
‪TYPO3\CMS\Core\Database\Connection\bulkInsert
‪int bulkInsert(string $tableName, array $data, array $columns=[], array $types=[])
Definition: Connection.php:232
‪TYPO3\CMS\Core\Database\Connection\lastInsertId
‪string lastInsertId($tableName=null, string $fieldName='uid')
Definition: Connection.php:463
‪TYPO3\CMS\Core\Database\Connection\createSchemaManager
‪createSchemaManager()
Definition: Connection.php:426
‪TYPO3\CMS\Core\Database\Connection\insert
‪int insert($tableName, array $data, array $types=[])
Definition: Connection.php:211
‪TYPO3\CMS\Core\Database\Connection\quoteIdentifier
‪string quoteIdentifier($identifier)
Definition: Connection.php:133
‪TYPO3\CMS\Core\Database\Connection\PARAM_STR
‪const PARAM_STR
Definition: Connection.php:54
‪TYPO3\CMS\Core\Database\Connection\update
‪int update($tableName, array $data, array $identifier, array $types=[])
Definition: Connection.php:302
‪TYPO3\CMS\Core\Database\Connection\select
‪Result select(array $columns, string $tableName, array $identifiers=[], array $groupBy=[], array $orderBy=[], int $limit=0, int $offset=0)
Definition: Connection.php:257
‪TYPO3\CMS\Core\Database\Connection\quoteColumnValuePairs
‪array quoteColumnValuePairs(array $input)
Definition: Connection.php:166
‪TYPO3\CMS\Core\Database\Connection\PARAM_STMT
‪const PARAM_STMT
Definition: Connection.php:64
‪TYPO3\CMS\Core\Database\Connection\quoteColumnTypes
‪array quoteColumnTypes(array $input)
Definition: Connection.php:179
‪TYPO3\CMS\Core\Database\Connection\getServerVersion
‪string getServerVersion()
Definition: Connection.php:383
‪TYPO3\CMS\Core\Database\Connection\getExpressionBuilder
‪ExpressionBuilder getExpressionBuilder()
Definition: Connection.php:484
‪TYPO3\CMS\Core\Database\Connection\count
‪int count(string $item, string $tableName, array $identifiers)
Definition: Connection.php:361
‪TYPO3\CMS\Core\Database\Connection\__construct
‪__construct(array $params, Driver $driver, ?Configuration $config=null, ?EventManager $em=null)
Definition: Connection.php:87
‪TYPO3\CMS\Core\Database\Connection
Definition: Connection.php:38
‪TYPO3\CMS\Core\Database\Connection\quoteIdentifiers
‪array quoteIdentifiers(array $input)
Definition: Connection.php:151
‪TYPO3\CMS\Core\Database\Connection\prepareConnection
‪prepareConnection(string $commands)
Definition: Connection.php:436
‪TYPO3\CMS\Core\Database\Query\BulkInsertQuery
Definition: BulkInsertQuery.php:35
‪TYPO3\CMS\Core\Database\Connection\createQueryBuilder
‪TYPO3 CMS Core Database Query QueryBuilder createQueryBuilder()
Definition: Connection.php:117
‪TYPO3\CMS\Core\Database\Connection\PARAM_NULL
‪const PARAM_NULL
Definition: Connection.php:44
‪TYPO3\CMS\Core\Utility\GeneralUtility
Definition: GeneralUtility.php:50
‪TYPO3\CMS\Core\Database\Connection\connect
‪bool connect()
Definition: Connection.php:98
‪TYPO3\CMS\Core\Database
Definition: Connection.php:18
‪TYPO3\CMS\Core\Database\Connection\$prepareConnectionCommands
‪array $prepareConnectionCommands
Definition: Connection.php:75
‪TYPO3\CMS\Core\Database\Connection\PARAM_LOB
‪const PARAM_LOB
Definition: Connection.php:59