‪TYPO3CMS  10.4
ConnectionPool.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\DriverManager;
21 use Doctrine\DBAL\Events;
22 use Doctrine\DBAL\Types\Type;
34 
46 {
50  const ‪DEFAULT_CONNECTION_NAME = 'Default';
51 
55  protected static ‪$connections = [];
56 
60  protected ‪$customDoctrineTypes = [
61  ‪EnumType::TYPE => EnumType::class,
62  ‪SetType::TYPE => SetType::class,
63  ];
64 
70  protected static ‪$driverMap = [
71  'pdo_mysql' => PDOMySqlDriver::class,
72  'pdo_sqlite' => PDOSqliteDriver::class,
73  'pdo_pgsql' => PDOPgSqlDriver::class,
74  'pdo_sqlsrv' => PDOSqlsrvDriver::class,
75  // TODO: not supported yet, need to be checked later
76 // 'pdo_oci' => PDOOCIDriver::class,
77 // 'drizzle_pdo_mysql' => DrizzlePDOMySQLDriver::class,
78  ];
79 
89  public function ‪getConnectionForTable(string $tableName): ‪Connection
90  {
91  if (empty($tableName)) {
92  throw new \UnexpectedValueException(
93  'ConnectionPool->getConnectionForTable() requires a table name to be provided.',
94  1459421719
95  );
96  }
97 
98  $connectionName = ‪self::DEFAULT_CONNECTION_NAME;
99  if (!empty(‪$GLOBALS['TYPO3_CONF_VARS']['DB']['TableMapping'][$tableName])) {
100  $connectionName = (string)‪$GLOBALS['TYPO3_CONF_VARS']['DB']['TableMapping'][$tableName];
101  }
102 
103  return $this->‪getConnectionByName($connectionName);
104  }
105 
116  public function ‪getConnectionByName(string $connectionName): ‪Connection
117  {
118  if (empty($connectionName)) {
119  throw new \UnexpectedValueException(
120  'ConnectionPool->getConnectionByName() requires a connection name to be provided.',
121  1459422125
122  );
123  }
124 
125  if (isset(static::$connections[$connectionName])) {
126  return static::$connections[$connectionName];
127  }
128 
129  $connectionParams = ‪$GLOBALS['TYPO3_CONF_VARS']['DB']['Connections'][$connectionName] ?? [];
130  if (empty($connectionParams)) {
131  throw new \RuntimeException(
132  'The requested database connection named "' . $connectionName . '" has not been configured.',
133  1459422492
134  );
135  }
136 
137  if (empty($connectionParams['wrapperClass'])) {
138  $connectionParams['wrapperClass'] = Connection::class;
139  }
140 
141  if (!is_a($connectionParams['wrapperClass'], Connection::class, true)) {
142  throw new \UnexpectedValueException(
143  'The "wrapperClass" for the connection name "' . $connectionName .
144  '" needs to be a subclass of "' . Connection::class . '".',
145  1459422968
146  );
147  }
148 
149  static::$connections[$connectionName] = $this->‪getDatabaseConnection($connectionParams);
150 
151  return static::$connections[$connectionName];
152  }
153 
160  protected function ‪mapCustomDriver(array $connectionParams): array
161  {
162  // if no custom driver is provided, map TYPO3 specific drivers
163  if (!isset($connectionParams['driverClass']) && isset(static::$driverMap[$connectionParams['driver']])) {
164  $connectionParams['driverClass'] = static::$driverMap[$connectionParams['driver']];
165  }
166 
167  return $connectionParams;
168  }
169 
176  protected function ‪getDatabaseConnection(array $connectionParams): Connection
177  {
178  // Default to UTF-8 connection charset
179  if (empty($connectionParams['charset'])) {
180  $connectionParams['charset'] = 'utf8';
181  }
182 
183  $connectionParams = $this->‪mapCustomDriver($connectionParams);
184 
186  $conn = DriverManager::getConnection($connectionParams);
187  $conn->setFetchMode(\PDO::FETCH_ASSOC);
188  $conn->prepareConnection($connectionParams['initCommands'] ?? '');
189 
190  // Register custom data types
191  foreach ($this->customDoctrineTypes as $type => $className) {
192  if (!Type::hasType($type)) {
193  Type::addType($type, $className);
194  }
195  }
196 
197  // Register all custom data types in the type mapping
198  foreach ($this->customDoctrineTypes as $type => $className) {
199  $conn->getDatabasePlatform()->registerDoctrineTypeMapping($type, $type);
200  }
201 
202  // Handler for building custom data type column definitions
203  // in the SchemaManager
204  $conn->getDatabasePlatform()->getEventManager()->addEventListener(
205  Events::onSchemaColumnDefinition,
206  GeneralUtility::makeInstance(SchemaColumnDefinitionListener::class)
207  );
208 
209  // Handler for enhanced index definitions in the SchemaManager
210  $conn->getDatabasePlatform()->getEventManager()->addEventListener(
211  Events::onSchemaIndexDefinition,
212  GeneralUtility::makeInstance(SchemaIndexDefinitionListener::class)
213  );
214 
215  // Handler for adding custom database platform options to ALTER TABLE
216  // requests in the SchemaManager
217  $conn->getDatabasePlatform()->getEventManager()->addEventListener(
218  Events::onSchemaAlterTable,
219  GeneralUtility::makeInstance(SchemaAlterTableListener::class)
220  );
221 
222  return $conn;
223  }
224 
232  public function ‪getQueryBuilderForTable(string $tableName): QueryBuilder
233  {
234  if (empty($tableName)) {
235  throw new \UnexpectedValueException(
236  'ConnectionPool->getQueryBuilderForTable() requires a connection name to be provided.',
237  1459423448
238  );
239  }
240 
241  return $this->‪getConnectionForTable($tableName)->‪createQueryBuilder();
242  }
243 
253  public function ‪getConnectionNames(): array
254  {
255  return array_keys(‪$GLOBALS['TYPO3_CONF_VARS']['DB']['Connections']);
256  }
257 
267  public function ‪getCustomDoctrineTypes(): array
268  {
270  }
271 
277  public function ‪resetConnections(): void
278  {
279  static::$connections = [];
280  }
281 }
‪TYPO3\CMS\Core\Database\Driver\PDOPgSql\Driver
Definition: Driver.php:31
‪TYPO3\CMS\Core\Database\Driver\PDOMySql\Driver
Definition: Driver.php:30
‪TYPO3\CMS\Core\Database\Schema\EventListener\SchemaIndexDefinitionListener
Definition: SchemaIndexDefinitionListener.php:29
‪TYPO3\CMS\Core\Database\Schema\Types\SetType
Definition: SetType.php:27
‪TYPO3\CMS\Core\Database\Driver\PDOSqlsrv\Driver
Definition: Driver.php:25
‪TYPO3\CMS\Core\Database\Schema\Types\EnumType
Definition: EnumType.php:27
‪TYPO3\CMS\Core\Database\ConnectionPool\$driverMap
‪static string[] $driverMap
Definition: ConnectionPool.php:67
‪TYPO3\CMS\Core\Database\Driver\PDOSqlite\Driver
Definition: Driver.php:30
‪TYPO3\CMS\Core\Database\Schema\Types\EnumType\TYPE
‪const TYPE
Definition: EnumType.php:28
‪TYPO3\CMS\Core\Database\ConnectionPool\DEFAULT_CONNECTION_NAME
‪const DEFAULT_CONNECTION_NAME
Definition: ConnectionPool.php:50
‪TYPO3\CMS\Core\Database\Query\QueryBuilder
Definition: QueryBuilder.php:52
‪TYPO3\CMS\Core\Database\ConnectionPool\getCustomDoctrineTypes
‪array getCustomDoctrineTypes()
Definition: ConnectionPool.php:264
‪TYPO3\CMS\Core\Database\ConnectionPool\$customDoctrineTypes
‪array $customDoctrineTypes
Definition: ConnectionPool.php:58
‪TYPO3\CMS\Core\Database\ConnectionPool\mapCustomDriver
‪array mapCustomDriver(array $connectionParams)
Definition: ConnectionPool.php:157
‪TYPO3\CMS\Core\Database\ConnectionPool\getConnectionForTable
‪Connection getConnectionForTable(string $tableName)
Definition: ConnectionPool.php:86
‪TYPO3\CMS\Core\Database\ConnectionPool\$connections
‪static Connection[] $connections
Definition: ConnectionPool.php:54
‪TYPO3\CMS\Core\Database\ConnectionPool\getConnectionByName
‪Connection getConnectionByName(string $connectionName)
Definition: ConnectionPool.php:113
‪TYPO3\CMS\Core\Database\Schema\EventListener\SchemaAlterTableListener
Definition: SchemaAlterTableListener.php:28
‪TYPO3\CMS\Core\Database\ConnectionPool\getQueryBuilderForTable
‪QueryBuilder getQueryBuilderForTable(string $tableName)
Definition: ConnectionPool.php:229
‪TYPO3\CMS\Core\Database\Connection
Definition: Connection.php:36
‪$GLOBALS
‪$GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['adminpanel']['modules']
Definition: ext_localconf.php:5
‪TYPO3\CMS\Core\Database\Connection\createQueryBuilder
‪TYPO3 CMS Core Database Query QueryBuilder createQueryBuilder()
Definition: Connection.php:117
‪TYPO3\CMS\Core\Database\ConnectionPool
Definition: ConnectionPool.php:46
‪TYPO3\CMS\Core\Utility\GeneralUtility
Definition: GeneralUtility.php:46
‪TYPO3\CMS\Core\Database\Schema\Types\SetType\TYPE
‪const TYPE
Definition: SetType.php:28
‪TYPO3\CMS\Core\Database\ConnectionPool\resetConnections
‪resetConnections()
Definition: ConnectionPool.php:274
‪TYPO3\CMS\Core\Database\ConnectionPool\getDatabaseConnection
‪Connection getDatabaseConnection(array $connectionParams)
Definition: ConnectionPool.php:173
‪TYPO3\CMS\Core\Database
Definition: Connection.php:18
‪TYPO3\CMS\Core\Database\Schema\EventListener\SchemaColumnDefinitionListener
Definition: SchemaColumnDefinitionListener.php:30
‪TYPO3\CMS\Core\Database\ConnectionPool\getConnectionNames
‪array getConnectionNames()
Definition: ConnectionPool.php:250