Commit 2cb7a089 authored by Benni Mack's avatar Benni Mack
Browse files

[BUGFIX] Add createSchemaManager to DBAL Connection

This change adds the new createSchemaManager() to
our Doctrine DBAL Connection subclass to make it
forward-compatible with Doctrine DBAL 3.x.

createSchemaManager() is introduced with DBAL 3.x and
is replacing getSchemaManager() which will be removed
in Doctrine DBAL 4.

Since this is a very lowlevel change, the method
can be added without most notice for extension authors.

Resolves: #96286
Releases: main, 11.5
Change-Id: Ifdccc2b0dff443bfe38d23a1bd1333b5c7c5db40
Reviewed-on: https://review.typo3.org/c/Packages/TYPO3.CMS/+/72555


Tested-by: core-ci's avatarcore-ci <typo3@b13.com>
Tested-by: Benni Mack's avatarBenni Mack <benni@typo3.org>
Reviewed-by: Benni Mack's avatarBenni Mack <benni@typo3.org>
parent 88a4a857
......@@ -7263,7 +7263,7 @@ class DataHandler implements LoggerAwareInterface
$platform = $connection->getDatabasePlatform();
if ($platform instanceof SQLServerPlatform) {
// mssql needs to set proper PARAM_LOB and others to update fields
$tableDetails = $connection->getSchemaManager()->listTableDetails($table);
$tableDetails = $connection->createSchemaManager()->listTableDetails($table);
foreach ($fieldArray as $columnName => $columnValue) {
$types[$columnName] = $tableDetails->getColumn($columnName)->getType()->getBindingType();
}
......@@ -8012,7 +8012,7 @@ class DataHandler implements LoggerAwareInterface
->fetchAssociative();
// If the current record exists (which it should...), begin comparison:
if (is_array($currentRecord)) {
$tableDetails = $connection->getSchemaManager()->listTableDetails($table);
$tableDetails = $connection->createSchemaManager()->listTableDetails($table);
$columnRecordTypes = [];
foreach ($currentRecord as $columnName => $_) {
$columnRecordTypes[$columnName] = '';
......
......@@ -24,6 +24,7 @@ use Doctrine\DBAL\Driver\ServerInfoAwareConnection;
use Doctrine\DBAL\Platforms\PostgreSQL94Platform as PostgreSqlPlatform;
use Doctrine\DBAL\Platforms\SQLServer2012Platform;
use Doctrine\DBAL\Result;
use Doctrine\DBAL\Schema\AbstractSchemaManager;
use Doctrine\DBAL\VersionAwarePlatformDriver;
use Psr\Log\LoggerAwareInterface;
use Psr\Log\LoggerAwareTrait;
......@@ -413,6 +414,17 @@ class Connection extends \Doctrine\DBAL\Connection implements LoggerAwareInterfa
return $version;
}
/**
* Creates a SchemaManager that can be used to inspect or change the
* database schema through the connection.
*
* This is a copy from Doctrine DBAL 3.x, and can be removed once Doctrine DBAL 3.2 is included
*/
public function createSchemaManager(): AbstractSchemaManager
{
return $this->_driver->getSchemaManager($this);
}
/**
* Execute commands after initializing a new connection.
*
......
......@@ -215,7 +215,7 @@ class ConnectionMigrator
protected function buildSchemaDiff(bool $renameUnused = true): SchemaDiff
{
// Build the schema definitions
$fromSchema = $this->connection->getSchemaManager()->createSchema();
$fromSchema = $this->connection->createSchemaManager()->createSchema();
$toSchema = $this->buildExpectedSchemaDefinitions($this->connectionName);
// Add current table options to the fromSchema
......
......@@ -183,7 +183,7 @@ class MetaDataRepository implements SingletonInterface
$types = [];
if ($connection->getDatabasePlatform() instanceof SQLServerPlatform) {
// mssql needs to set proper PARAM_LOB and others to update fields
$tableDetails = $connection->getSchemaManager()->listTableDetails($this->tableName);
$tableDetails = $connection->createSchemaManager()->listTableDetails($this->tableName);
foreach ($updateRow as $columnName => $columnValue) {
$types[$columnName] = $tableDetails->getColumn($columnName)->getType()->getBindingType();
}
......@@ -230,7 +230,7 @@ class MetaDataRepository implements SingletonInterface
if (empty($this->tableFields)) {
$this->tableFields = GeneralUtility::makeInstance(ConnectionPool::class)
->getConnectionForTable($this->tableName)
->getSchemaManager()
->createSchemaManager()
->listTableColumns($this->tableName);
}
......
......@@ -359,7 +359,7 @@ class ProcessedFileRepository extends AbstractRepository implements LoggerAwareI
if (empty($this->tableColumns[$this->table])) {
$this->tableColumns[$this->table] = GeneralUtility::makeInstance(ConnectionPool::class)
->getConnectionForTable($this->table)
->getSchemaManager()
->createSchemaManager()
->listTableColumns($this->table);
}
......
......@@ -66,7 +66,7 @@ class SchemaMigratorTest extends FunctionalTestCase
$this->subject = GeneralUtility::makeInstance(SchemaMigrator::class);
$this->sqlReader = GeneralUtility::makeInstance(SqlReader::class);
$this->connectionPool = GeneralUtility::makeInstance(ConnectionPool::class);
$this->schemaManager = $this->connectionPool->getConnectionForTable($this->tableName)->getSchemaManager();
$this->schemaManager = $this->connectionPool->getConnectionForTable($this->tableName)->createSchemaManager();
$this->prepareTestTable();
}
......
......@@ -81,7 +81,7 @@ class Typo3DbBackend implements BackendInterface, SingletonInterface
$platform = $connection->getDatabasePlatform();
if ($platform instanceof SQLServerPlatform) {
// mssql needs to set proper PARAM_LOB and others to update fields
$tableDetails = $connection->getSchemaManager()->listTableDetails($tableName);
$tableDetails = $connection->createSchemaManager()->listTableDetails($tableName);
foreach ($fieldValues as $columnName => $columnValue) {
$types[$columnName] = $tableDetails->getColumn($columnName)->getType()->getBindingType();
}
......@@ -126,7 +126,7 @@ class Typo3DbBackend implements BackendInterface, SingletonInterface
$platform = $connection->getDatabasePlatform();
if ($platform instanceof SQLServerPlatform) {
// mssql needs to set proper PARAM_LOB and others to update fields
$tableDetails = $connection->getSchemaManager()->listTableDetails($tableName);
$tableDetails = $connection->createSchemaManager()->listTableDetails($tableName);
foreach ($fieldValues as $columnName => $columnValue) {
$columnName = (string)$columnName;
$types[$columnName] = $tableDetails->getColumn($columnName)->getType()->getBindingType();
......
......@@ -140,7 +140,7 @@ class CacheService implements SingletonInterface
if (!isset($this->hasPidColumn[$tableName])) {
$columns = $this->connectionPool
->getConnectionForTable($tableName)
->getSchemaManager()
->createSchemaManager()
->listTableColumns($tableName);
$this->hasPidColumn[$tableName] = array_key_exists('pid', $columns);
}
......
......@@ -1070,7 +1070,7 @@ class EnvironmentController extends AbstractController
'host' => $connectionParameters['host'] ?? '',
'port' => $connectionParameters['port'] ?? '',
'socket' => $connectionParameters['unix_socket'] ?? '',
'numberOfTables' => count($connection->getSchemaManager()->listTableNames()),
'numberOfTables' => count($connection->createSchemaManager()->listTableNames()),
'numberOfMappedTables' => 0,
];
if (isset($GLOBALS['TYPO3_CONF_VARS']['DB']['TableMapping'])
......
......@@ -742,7 +742,7 @@ class InstallerController
$connection = GeneralUtility::makeInstance(ConnectionPool::class)
->getConnectionByName(ConnectionPool::DEFAULT_CONNECTION_NAME);
$connection
->getSchemaManager()
->createSchemaManager()
->dropDatabase($connection->quoteIdentifier($databaseName));
}
......@@ -876,7 +876,7 @@ class InstallerController
{
$existingTables = GeneralUtility::makeInstance(ConnectionPool::class)
->getConnectionByName(ConnectionPool::DEFAULT_CONNECTION_NAME)
->getSchemaManager()
->createSchemaManager()
->listTableNames();
return new JsonResponse([
'success' => !empty($existingTables),
......@@ -1274,6 +1274,7 @@ For each website you need a TypoScript template on the main page of your website
// an invalid database name would lead to exceptions which would prevent
// changing the currently configured database.
$connection = DriverManager::getConnection($connectionParams);
// @todo: migrate to createSchemaManager() with Doctrine DBAL 3.2 requirement in TYPO3 v12.0
$databaseArray = $connection->getSchemaManager()->listDatabases();
$connection->close();
......@@ -1292,6 +1293,7 @@ For each website you need a TypoScript template on the main page of your website
$connectionParams['dbname'] = $databaseName;
$connection = DriverManager::getConnection($connectionParams);
// @todo: migrate to createSchemaManager() with Doctrine DBAL 3.2 requirement in TYPO3 v12.0
$databases[] = [
'name' => $databaseName,
'tables' => count($connection->getSchemaManager()->listTableNames()),
......@@ -1369,7 +1371,7 @@ For each website you need a TypoScript template on the main page of your website
$connection = GeneralUtility::makeInstance(ConnectionPool::class)
->getConnectionByName(ConnectionPool::DEFAULT_CONNECTION_NAME);
if (!empty($connection->getSchemaManager()->listTableNames())) {
if (!empty($connection->createSchemaManager()->listTableNames())) {
$result = new FlashMessage(
sprintf('Cannot use database "%s"', $dbName)
. ', because it already contains tables. Please select a different database or choose to create one!',
......
......@@ -213,6 +213,6 @@ class PermissionsCheck
private function getSchemaManager(): AbstractSchemaManager
{
return $this->getConnection()->getSchemaManager();
return $this->getConnection()->createSchemaManager();
}
}
......@@ -71,7 +71,7 @@ class ClearTableService
$tableStatistics = [];
foreach ($this->tableList as $table) {
$connection = GeneralUtility::makeInstance(ConnectionPool::class)->getConnectionForTable($table['name']);
if ($connection->getSchemaManager()->tablesExist([$table['name']])) {
if ($connection->createSchemaManager()->tablesExist([$table['name']])) {
$table['rowCount'] = $connection->count(
'*',
$table['name'],
......
......@@ -110,7 +110,7 @@ class CollectionsExtractionUpdate extends AbstractDownloadExtensionUpdate
// Check if database table exist
$connectionPool = GeneralUtility::makeInstance(ConnectionPool::class);
$connection = $connectionPool->getConnectionByName('Default');
$tableNames = $connection->getSchemaManager()->listTableNames();
$tableNames = $connection->createSchemaManager()->listTableNames();
if (in_array('sys_collection', $tableNames, true)) {
// table is available, now check if there are entries in it
$queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)
......
......@@ -102,7 +102,7 @@ class ShortcutRecordsMigration implements UpgradeWizardInterface
protected function columnsExistInTable(): bool
{
$schemaManager = $this->getConnectionPool()->getConnectionForTable(self::TABLE_NAME)->getSchemaManager();
$schemaManager = $this->getConnectionPool()->getConnectionForTable(self::TABLE_NAME)->createSchemaManager();
if ($schemaManager === null) {
return false;
......
......@@ -72,7 +72,7 @@ END;
}
// Ensure the level field is a varchar, otherwise we are in trouble when logging into TYPO3 Backend.
$schema = $this->sysLogTable->getSchemaManager();
$schema = $this->sysLogTable->createSchemaManager();
$table = $schema->listTableDetails('sys_log');
if (!$table->getColumn('level')->getType() instanceof StringType) {
$schema->alterTable(new TableDiff(
......
......@@ -50,7 +50,7 @@ class ShortcutRecordsMigrationTest extends FunctionalTestCase
$schemaManager = GeneralUtility::makeInstance(ConnectionPool::class)
->getConnectionForTable(self::TABLE_NAME)
->getSchemaManager();
->createSchemaManager();
$schemaManager->alterTable(
new TableDiff(
......
......@@ -409,7 +409,7 @@ class QueryGenerator
continue;
}
$connection = GeneralUtility::makeInstance(ConnectionPool::class)->getConnectionForTable($table);
$tableColumns = $connection->getSchemaManager()->listTableColumns($table);
$tableColumns = $connection->createSchemaManager()->listTableColumns($table);
$fieldsInDatabase = [];
foreach ($tableColumns as $column) {
$fieldsInDatabase[] = $column->getName();
......
......@@ -389,7 +389,7 @@ class DatabaseIntegrityCheck
$connectionPool = GeneralUtility::makeInstance(ConnectionPool::class);
foreach ($fkey_arrays as $table => $fields) {
$connection = $connectionPool->getConnectionForTable($table);
$schemaManager = $connection->getSchemaManager();
$schemaManager = $connection->createSchemaManager();
$tableColumns = $schemaManager->listTableColumns($table);
$queryBuilder = $connectionPool->getQueryBuilderForTable($table);
......
......@@ -675,7 +675,7 @@ class DataHandlerHook
$tableDetails = null;
if ($platform instanceof SQLServerPlatform) {
// mssql needs to set proper PARAM_LOB and others to update fields
$tableDetails = $connection->getSchemaManager()->listTableDetails($table);
$tableDetails = $connection->createSchemaManager()->listTableDetails($table);
}
try {
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment