TYPO3CMS  8
 All Classes Namespaces Files Functions Variables Pages
Connection.php
Go to the documentation of this file.
1 <?php
2 declare(strict_types=1);
3 namespace TYPO3\CMS\Core\Database;
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 
18 use Doctrine\Common\EventManager;
19 use Doctrine\DBAL\Configuration;
20 use Doctrine\DBAL\Driver;
21 use Doctrine\DBAL\Driver\Statement;
22 use Doctrine\DBAL\Platforms\PostgreSqlPlatform;
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 
69  public function __construct(array $params, Driver $driver, Configuration $config = null, EventManager $em = null)
70  {
71  parent::__construct($params, $driver, $config, $em);
72  $this->_expr = GeneralUtility::makeInstance(ExpressionBuilder::class, $this);
73  }
74 
80  public function createQueryBuilder(): QueryBuilder
81  {
82  return GeneralUtility::makeInstance(QueryBuilder::class, $this);
83  }
84 
96  public function quoteIdentifier($identifier): string
97  {
98  if ($identifier === '*') {
99  return $identifier;
100  }
101 
102  return parent::quoteIdentifier($identifier);
103  }
104 
114  public function quoteIdentifiers(array $input): array
115  {
116  return array_map([$this, 'quoteIdentifier'], $input);
117  }
118 
129  public function quoteColumnValuePairs(array $input): array
130  {
131  return array_combine($this->quoteIdentifiers(array_keys($input)), array_values($input));
132  }
133 
146  public function insert($tableName, array $data, array $types = []): int
147  {
148  return parent::insert(
149  $this->quoteIdentifier($tableName),
150  $this->quoteColumnValuePairs($data),
151  $types
152  );
153  }
154 
168  public function bulkInsert(string $tableName, array $data, array $columns = [], array $types = []): int
169  {
170  $query = GeneralUtility::makeInstance(Query\BulkInsertQuery::class, $this, $tableName, $columns);
171  foreach ($data as $values) {
172  $query->addValues($values, $types);
173  }
174 
175  return $query->execute();
176  }
177 
194  public function select(
195  array $columns,
196  string $tableName,
197  array $identifiers = [],
198  array $groupBy = [],
199  array $orderBy = [],
200  int $limit = 0,
201  int $offset = 0
202  ): Statement {
203  $query = $this->createQueryBuilder();
204  $query->select(...$columns)
205  ->from($tableName);
206 
207  foreach ($identifiers as $identifier => $value) {
208  $query->andWhere($query->expr()->eq($identifier, $query->createNamedParameter($value)));
209  }
210 
211  foreach ($orderBy as $fieldName => $order) {
212  $query->addOrderBy($fieldName, $order);
213  }
214 
215  if (!empty($groupBy)) {
216  $query->groupBy(...$groupBy);
217  }
218 
219  if ($limit > 0) {
220  $query->setMaxResults($limit);
221  $query->setFirstResult($offset);
222  }
223 
224  return $query->execute();
225  }
226 
240  public function update($tableName, array $data, array $identifier, array $types = []): int
241  {
242  return parent::update(
243  $this->quoteIdentifier($tableName),
244  $this->quoteColumnValuePairs($data),
245  $this->quoteColumnValuePairs($identifier),
246  $types
247  );
248  }
249 
262  public function delete($tableName, array $identifier, array $types = []): int
263  {
264  return parent::delete(
265  $this->quoteIdentifier($tableName),
266  $this->quoteColumnValuePairs($identifier),
267  $types
268  );
269  }
270 
282  public function truncate(string $tableName, bool $cascade = false): int
283  {
284  return $this->executeUpdate(
285  $this->getDatabasePlatform()->getTruncateTableSQL(
286  $this->quoteIdentifier($tableName),
287  $cascade
288  )
289  );
290  }
291 
301  public function count(string $item, string $tableName, array $identifiers): int
302  {
303  $query = $this->createQueryBuilder();
304  $query->count($item)
305  ->from($tableName);
306 
307  foreach ($identifiers as $identifier => $value) {
308  $query->andWhere($query->expr()->eq($identifier, $query->createNamedParameter($value)));
309  }
310 
311  return (int)$query->execute()->fetchColumn(0);
312  }
313 
323  public function getServerVersion(): string
324  {
325  $version = $this->getDatabasePlatform()->getName();
326  switch ($version) {
327  case 'mysql':
328  case 'pdo_mysql':
329  case 'drizzle_pdo_mysql':
330  $version = 'MySQL';
331  break;
332  case 'postgresql':
333  case 'pdo_postgresql':
334  $version = 'PostgreSQL';
335  break;
336  case 'oci8':
337  case 'pdo_oracle':
338  $version = 'Oracle';
339  break;
340  case 'sqlsrv':
341  case 'pdo_sqlsrv':
342  $version = 'SQLServer';
343  break;
344  }
345 
346  // Driver does not support version specific platforms.
347  if (!$this->getDriver() instanceof \Doctrine\DBAL\VersionAwarePlatformDriver) {
348  return $version;
349  }
350 
351  if ($this->getWrappedConnection() instanceof \Doctrine\DBAL\Driver\ServerInfoAwareConnection
352  && !$this->getWrappedConnection()->requiresQueryForServerVersion()
353  ) {
354  $version .= ' ' . $this->getWrappedConnection()->getServerVersion();
355  }
356 
357  return $version;
358  }
359 
365  public function prepareConnection(string $commands)
366  {
367  if (empty($commands)) {
368  return;
369  }
370 
371  $commandsToPerform = GeneralUtility::trimExplode(
372  LF,
373  str_replace(
374  '\' . LF . \'',
375  LF,
376  $commands
377  ),
378  true
379  );
380 
381  foreach ($commandsToPerform as $command) {
382  if ($this->executeUpdate($command) === false) {
383  GeneralUtility::sysLog(
384  'Could not initialize DB connection with query "' . $command . '": ' . $this->errorInfo(),
385  'core',
387  );
388  }
389  }
390  }
391 
402  public function lastInsertId($tableName = null, string $fieldName = 'uid'): string
403  {
404  if ($this->getDatabasePlatform() instanceof PostgreSqlPlatform) {
405  return parent::lastInsertId(trim(implode('_', [$tableName, $fieldName, 'seq']), '_'));
406  }
407 
408  return (string)parent::lastInsertId($tableName);
409  }
410 }
insert($tableName, array $data, array $types=[])
Definition: Connection.php:146
static trimExplode($delim, $string, $removeEmptyValues=false, $limit=0)
truncate(string $tableName, bool $cascade=false)
Definition: Connection.php:282
count(string $item, string $tableName, array $identifiers)
Definition: Connection.php:301
prepareConnection(string $commands)
Definition: Connection.php:365
select(array $columns, string $tableName, array $identifiers=[], array $groupBy=[], array $orderBy=[], int $limit=0, int $offset=0)
Definition: Connection.php:194
lastInsertId($tableName=null, string $fieldName= 'uid')
Definition: Connection.php:402
static makeInstance($className,...$constructorArguments)
__construct(array $params, Driver $driver, Configuration $config=null, EventManager $em=null)
Definition: Connection.php:69
update($tableName, array $data, array $identifier, array $types=[])
Definition: Connection.php:240
bulkInsert(string $tableName, array $data, array $columns=[], array $types=[])
Definition: Connection.php:168