vendor/doctrine/dbal/src/Schema/AbstractSchemaManager.php line 352

Open in your IDE?
  1. <?php
  2. namespace Doctrine\DBAL\Schema;
  3. use Doctrine\DBAL\Connection;
  4. use Doctrine\DBAL\Event\SchemaColumnDefinitionEventArgs;
  5. use Doctrine\DBAL\Event\SchemaIndexDefinitionEventArgs;
  6. use Doctrine\DBAL\Events;
  7. use Doctrine\DBAL\Exception;
  8. use Doctrine\DBAL\Exception\DatabaseRequired;
  9. use Doctrine\DBAL\Platforms\AbstractPlatform;
  10. use Doctrine\DBAL\Result;
  11. use Doctrine\Deprecations\Deprecation;
  12. use Throwable;
  13. use function array_filter;
  14. use function array_intersect;
  15. use function array_map;
  16. use function array_values;
  17. use function assert;
  18. use function call_user_func_array;
  19. use function count;
  20. use function func_get_args;
  21. use function is_callable;
  22. use function is_string;
  23. use function preg_match;
  24. use function str_replace;
  25. use function strtolower;
  26. /**
  27.  * Base class for schema managers. Schema managers are used to inspect and/or
  28.  * modify the database schema/structure.
  29.  *
  30.  * @template-covariant T of AbstractPlatform
  31.  */
  32. abstract class AbstractSchemaManager
  33. {
  34.     /**
  35.      * Holds instance of the Doctrine connection for this schema manager.
  36.      *
  37.      * @var Connection
  38.      */
  39.     protected $_conn;
  40.     /**
  41.      * Holds instance of the database platform used for this schema manager.
  42.      *
  43.      * @var T
  44.      */
  45.     protected $_platform;
  46.     /** @param T $platform */
  47.     public function __construct(Connection $connectionAbstractPlatform $platform)
  48.     {
  49.         $this->_conn     $connection;
  50.         $this->_platform $platform;
  51.     }
  52.     /**
  53.      * Returns the associated platform.
  54.      *
  55.      * @deprecated Use {@link Connection::getDatabasePlatform()} instead.
  56.      *
  57.      * @return T
  58.      */
  59.     public function getDatabasePlatform()
  60.     {
  61.         Deprecation::trigger(
  62.             'doctrine/dbal',
  63.             'https://github.com/doctrine/dbal/pull/5387',
  64.             'AbstractSchemaManager::getDatabasePlatform() is deprecated.'
  65.                 ' Use Connection::getDatabasePlatform() instead.',
  66.         );
  67.         return $this->_platform;
  68.     }
  69.     /**
  70.      * Tries any method on the schema manager. Normally a method throws an
  71.      * exception when your DBMS doesn't support it or if an error occurs.
  72.      * This method allows you to try and method on your SchemaManager
  73.      * instance and will return false if it does not work or is not supported.
  74.      *
  75.      * <code>
  76.      * $result = $sm->tryMethod('dropView', 'view_name');
  77.      * </code>
  78.      *
  79.      * @deprecated
  80.      *
  81.      * @return mixed
  82.      */
  83.     public function tryMethod()
  84.     {
  85.         Deprecation::triggerIfCalledFromOutside(
  86.             'doctrine/dbal',
  87.             'https://github.com/doctrine/dbal/pull/4897',
  88.             'AbstractSchemaManager::tryMethod() is deprecated.',
  89.         );
  90.         $args   func_get_args();
  91.         $method $args[0];
  92.         unset($args[0]);
  93.         $args array_values($args);
  94.         $callback = [$this$method];
  95.         assert(is_callable($callback));
  96.         try {
  97.             return call_user_func_array($callback$args);
  98.         } catch (Throwable $e) {
  99.             return false;
  100.         }
  101.     }
  102.     /**
  103.      * Lists the available databases for this connection.
  104.      *
  105.      * @return string[]
  106.      *
  107.      * @throws Exception
  108.      */
  109.     public function listDatabases()
  110.     {
  111.         $sql $this->_platform->getListDatabasesSQL();
  112.         $databases $this->_conn->fetchAllAssociative($sql);
  113.         return $this->_getPortableDatabasesList($databases);
  114.     }
  115.     /**
  116.      * Returns a list of all namespaces in the current database.
  117.      *
  118.      * @deprecated Use {@see listSchemaNames()} instead.
  119.      *
  120.      * @return string[]
  121.      *
  122.      * @throws Exception
  123.      */
  124.     public function listNamespaceNames()
  125.     {
  126.         Deprecation::triggerIfCalledFromOutside(
  127.             'doctrine/dbal',
  128.             'https://github.com/doctrine/dbal/issues/4503',
  129.             'AbstractSchemaManager::listNamespaceNames() is deprecated,'
  130.                 ' use AbstractSchemaManager::listSchemaNames() instead.',
  131.         );
  132.         $sql $this->_platform->getListNamespacesSQL();
  133.         $namespaces $this->_conn->fetchAllAssociative($sql);
  134.         return $this->getPortableNamespacesList($namespaces);
  135.     }
  136.     /**
  137.      * Returns a list of the names of all schemata in the current database.
  138.      *
  139.      * @return list<string>
  140.      *
  141.      * @throws Exception
  142.      */
  143.     public function listSchemaNames(): array
  144.     {
  145.         throw Exception::notSupported(__METHOD__);
  146.     }
  147.     /**
  148.      * Lists the available sequences for this connection.
  149.      *
  150.      * @param string|null $database
  151.      *
  152.      * @return Sequence[]
  153.      *
  154.      * @throws Exception
  155.      */
  156.     public function listSequences($database null)
  157.     {
  158.         if ($database === null) {
  159.             $database $this->getDatabase(__METHOD__);
  160.         } else {
  161.             Deprecation::trigger(
  162.                 'doctrine/dbal',
  163.                 'https://github.com/doctrine/dbal/issues/5284',
  164.                 'Passing $database to AbstractSchemaManager::listSequences() is deprecated.',
  165.             );
  166.         }
  167.         $sql $this->_platform->getListSequencesSQL($database);
  168.         $sequences $this->_conn->fetchAllAssociative($sql);
  169.         return $this->filterAssetNames($this->_getPortableSequencesList($sequences));
  170.     }
  171.     /**
  172.      * Lists the columns for a given table.
  173.      *
  174.      * In contrast to other libraries and to the old version of Doctrine,
  175.      * this column definition does try to contain the 'primary' column for
  176.      * the reason that it is not portable across different RDBMS. Use
  177.      * {@see listTableIndexes($tableName)} to retrieve the primary key
  178.      * of a table. Where a RDBMS specifies more details, these are held
  179.      * in the platformDetails array.
  180.      *
  181.      * @param string      $table    The name of the table.
  182.      * @param string|null $database
  183.      *
  184.      * @return Column[]
  185.      *
  186.      * @throws Exception
  187.      */
  188.     public function listTableColumns($table$database null)
  189.     {
  190.         if ($database === null) {
  191.             $database $this->getDatabase(__METHOD__);
  192.         } else {
  193.             Deprecation::triggerIfCalledFromOutside(
  194.                 'doctrine/dbal',
  195.                 'https://github.com/doctrine/dbal/issues/5284',
  196.                 'Passing $database to AbstractSchemaManager::listTableColumns() is deprecated.',
  197.             );
  198.         }
  199.         $sql $this->_platform->getListTableColumnsSQL($table$database);
  200.         $tableColumns $this->_conn->fetchAllAssociative($sql);
  201.         return $this->_getPortableTableColumnList($table$database$tableColumns);
  202.     }
  203.     /**
  204.      * @param string      $table
  205.      * @param string|null $database
  206.      *
  207.      * @return Column[]
  208.      *
  209.      * @throws Exception
  210.      */
  211.     protected function doListTableColumns($table$database null): array
  212.     {
  213.         if ($database === null) {
  214.             $database $this->getDatabase(__METHOD__);
  215.         } else {
  216.             Deprecation::triggerIfCalledFromOutside(
  217.                 'doctrine/dbal',
  218.                 'https://github.com/doctrine/dbal/issues/5284',
  219.                 'Passing $database to AbstractSchemaManager::doListTableColumns() is deprecated.',
  220.             );
  221.         }
  222.         return $this->_getPortableTableColumnList(
  223.             $table,
  224.             $database,
  225.             $this->selectTableColumns($database$this->normalizeName($table))
  226.                 ->fetchAllAssociative(),
  227.         );
  228.     }
  229.     /**
  230.      * Lists the indexes for a given table returning an array of Index instances.
  231.      *
  232.      * Keys of the portable indexes list are all lower-cased.
  233.      *
  234.      * @param string $table The name of the table.
  235.      *
  236.      * @return Index[]
  237.      *
  238.      * @throws Exception
  239.      */
  240.     public function listTableIndexes($table)
  241.     {
  242.         $sql $this->_platform->getListTableIndexesSQL($table$this->_conn->getDatabase());
  243.         $tableIndexes $this->_conn->fetchAllAssociative($sql);
  244.         return $this->_getPortableTableIndexesList($tableIndexes$table);
  245.     }
  246.     /**
  247.      * @param string $table
  248.      *
  249.      * @return Index[]
  250.      *
  251.      * @throws Exception
  252.      */
  253.     protected function doListTableIndexes($table): array
  254.     {
  255.         $database $this->getDatabase(__METHOD__);
  256.         $table    $this->normalizeName($table);
  257.         return $this->_getPortableTableIndexesList(
  258.             $this->selectIndexColumns(
  259.                 $database,
  260.                 $table,
  261.             )->fetchAllAssociative(),
  262.             $table,
  263.         );
  264.     }
  265.     /**
  266.      * Returns true if all the given tables exist.
  267.      *
  268.      * The usage of a string $tableNames is deprecated. Pass a one-element array instead.
  269.      *
  270.      * @param string|string[] $names
  271.      *
  272.      * @return bool
  273.      *
  274.      * @throws Exception
  275.      */
  276.     public function tablesExist($names)
  277.     {
  278.         if (is_string($names)) {
  279.             Deprecation::trigger(
  280.                 'doctrine/dbal',
  281.                 'https://github.com/doctrine/dbal/issues/3580',
  282.                 'The usage of a string $tableNames in AbstractSchemaManager::tablesExist() is deprecated. ' .
  283.                 'Pass a one-element array instead.',
  284.             );
  285.         }
  286.         $names array_map('strtolower', (array) $names);
  287.         return count($names) === count(array_intersect($namesarray_map('strtolower'$this->listTableNames())));
  288.     }
  289.     /**
  290.      * Returns a list of all tables in the current database.
  291.      *
  292.      * @return string[]
  293.      *
  294.      * @throws Exception
  295.      */
  296.     public function listTableNames()
  297.     {
  298.         $sql $this->_platform->getListTablesSQL();
  299.         $tables     $this->_conn->fetchAllAssociative($sql);
  300.         $tableNames $this->_getPortableTablesList($tables);
  301.         return $this->filterAssetNames($tableNames);
  302.     }
  303.     /**
  304.      * @return list<string>
  305.      *
  306.      * @throws Exception
  307.      */
  308.     protected function doListTableNames(): array
  309.     {
  310.         $database $this->getDatabase(__METHOD__);
  311.         return $this->filterAssetNames(
  312.             $this->_getPortableTablesList(
  313.                 $this->selectTableNames($database)
  314.                     ->fetchAllAssociative(),
  315.             ),
  316.         );
  317.     }
  318.     /**
  319.      * Filters asset names if they are configured to return only a subset of all
  320.      * the found elements.
  321.      *
  322.      * @param mixed[] $assetNames
  323.      *
  324.      * @return mixed[]
  325.      */
  326.     protected function filterAssetNames($assetNames)
  327.     {
  328.         $filter $this->_conn->getConfiguration()->getSchemaAssetsFilter();
  329.         if ($filter === null) {
  330.             return $assetNames;
  331.         }
  332.         return array_values(array_filter($assetNames$filter));
  333.     }
  334.     /**
  335.      * Lists the tables for this connection.
  336.      *
  337.      * @return list<Table>
  338.      *
  339.      * @throws Exception
  340.      */
  341.     public function listTables()
  342.     {
  343.         $tableNames $this->listTableNames();
  344.         $tables = [];
  345.         foreach ($tableNames as $tableName) {
  346.             $tables[] = $this->introspectTable($tableName);
  347.         }
  348.         return $tables;
  349.     }
  350.     /**
  351.      * @return list<Table>
  352.      *
  353.      * @throws Exception
  354.      */
  355.     protected function doListTables(): array
  356.     {
  357.         $database $this->getDatabase(__METHOD__);
  358.         $tableColumnsByTable      $this->fetchTableColumnsByTable($database);
  359.         $indexColumnsByTable      $this->fetchIndexColumnsByTable($database);
  360.         $foreignKeyColumnsByTable $this->fetchForeignKeyColumnsByTable($database);
  361.         $tableOptionsByTable      $this->fetchTableOptionsByTable($database);
  362.         $filter $this->_conn->getConfiguration()->getSchemaAssetsFilter();
  363.         $tables = [];
  364.         foreach ($tableColumnsByTable as $tableName => $tableColumns) {
  365.             if ($filter !== null && ! $filter($tableName)) {
  366.                 continue;
  367.             }
  368.             $tables[] = new Table(
  369.                 $tableName,
  370.                 $this->_getPortableTableColumnList($tableName$database$tableColumns),
  371.                 $this->_getPortableTableIndexesList($indexColumnsByTable[$tableName] ?? [], $tableName),
  372.                 [],
  373.                 $this->_getPortableTableForeignKeysList($foreignKeyColumnsByTable[$tableName] ?? []),
  374.                 $tableOptionsByTable[$tableName] ?? [],
  375.             );
  376.         }
  377.         return $tables;
  378.     }
  379.     /**
  380.      * @deprecated Use {@see introspectTable()} instead.
  381.      *
  382.      * @param string $name
  383.      *
  384.      * @return Table
  385.      *
  386.      * @throws Exception
  387.      */
  388.     public function listTableDetails($name)
  389.     {
  390.         Deprecation::triggerIfCalledFromOutside(
  391.             'doctrine/dbal',
  392.             'https://github.com/doctrine/dbal/pull/5595',
  393.             '%s is deprecated. Use introspectTable() instead.',
  394.             __METHOD__,
  395.         );
  396.         $columns     $this->listTableColumns($name);
  397.         $foreignKeys = [];
  398.         if ($this->_platform->supportsForeignKeyConstraints()) {
  399.             $foreignKeys $this->listTableForeignKeys($name);
  400.         }
  401.         $indexes $this->listTableIndexes($name);
  402.         return new Table($name$columns$indexes, [], $foreignKeys);
  403.     }
  404.     /**
  405.      * @param string $name
  406.      *
  407.      * @throws Exception
  408.      */
  409.     protected function doListTableDetails($name): Table
  410.     {
  411.         $database $this->getDatabase(__METHOD__);
  412.         $normalizedName $this->normalizeName($name);
  413.         $tableOptionsByTable $this->fetchTableOptionsByTable($database$normalizedName);
  414.         if ($this->_platform->supportsForeignKeyConstraints()) {
  415.             $foreignKeys $this->listTableForeignKeys($name);
  416.         } else {
  417.             $foreignKeys = [];
  418.         }
  419.         return new Table(
  420.             $name,
  421.             $this->listTableColumns($name$database),
  422.             $this->listTableIndexes($name),
  423.             [],
  424.             $foreignKeys,
  425.             $tableOptionsByTable[$normalizedName] ?? [],
  426.         );
  427.     }
  428.     /**
  429.      * An extension point for those platforms where case sensitivity of the object name depends on whether it's quoted.
  430.      *
  431.      * Such platforms should convert a possibly quoted name into a value of the corresponding case.
  432.      */
  433.     protected function normalizeName(string $name): string
  434.     {
  435.         $identifier = new Identifier($name);
  436.         return $identifier->getName();
  437.     }
  438.     /**
  439.      * Selects names of tables in the specified database.
  440.      *
  441.      * @throws Exception
  442.      *
  443.      * @abstract
  444.      */
  445.     protected function selectTableNames(string $databaseName): Result
  446.     {
  447.         throw Exception::notSupported(__METHOD__);
  448.     }
  449.     /**
  450.      * Selects definitions of table columns in the specified database. If the table name is specified, narrows down
  451.      * the selection to this table.
  452.      *
  453.      * @throws Exception
  454.      *
  455.      * @abstract
  456.      */
  457.     protected function selectTableColumns(string $databaseName, ?string $tableName null): Result
  458.     {
  459.         throw Exception::notSupported(__METHOD__);
  460.     }
  461.     /**
  462.      * Selects definitions of index columns in the specified database. If the table name is specified, narrows down
  463.      * the selection to this table.
  464.      *
  465.      * @throws Exception
  466.      */
  467.     protected function selectIndexColumns(string $databaseName, ?string $tableName null): Result
  468.     {
  469.         throw Exception::notSupported(__METHOD__);
  470.     }
  471.     /**
  472.      * Selects definitions of foreign key columns in the specified database. If the table name is specified,
  473.      * narrows down the selection to this table.
  474.      *
  475.      * @throws Exception
  476.      */
  477.     protected function selectForeignKeyColumns(string $databaseName, ?string $tableName null): Result
  478.     {
  479.         throw Exception::notSupported(__METHOD__);
  480.     }
  481.     /**
  482.      * Fetches definitions of table columns in the specified database and returns them grouped by table name.
  483.      *
  484.      * @return array<string,list<array<string,mixed>>>
  485.      *
  486.      * @throws Exception
  487.      */
  488.     protected function fetchTableColumnsByTable(string $databaseName): array
  489.     {
  490.         return $this->fetchAllAssociativeGrouped($this->selectTableColumns($databaseName));
  491.     }
  492.     /**
  493.      * Fetches definitions of index columns in the specified database and returns them grouped by table name.
  494.      *
  495.      * @return array<string,list<array<string,mixed>>>
  496.      *
  497.      * @throws Exception
  498.      */
  499.     protected function fetchIndexColumnsByTable(string $databaseName): array
  500.     {
  501.         return $this->fetchAllAssociativeGrouped($this->selectIndexColumns($databaseName));
  502.     }
  503.     /**
  504.      * Fetches definitions of foreign key columns in the specified database and returns them grouped by table name.
  505.      *
  506.      * @return array<string, list<array<string, mixed>>>
  507.      *
  508.      * @throws Exception
  509.      */
  510.     protected function fetchForeignKeyColumnsByTable(string $databaseName): array
  511.     {
  512.         if (! $this->_platform->supportsForeignKeyConstraints()) {
  513.             return [];
  514.         }
  515.         return $this->fetchAllAssociativeGrouped(
  516.             $this->selectForeignKeyColumns($databaseName),
  517.         );
  518.     }
  519.     /**
  520.      * Fetches table options for the tables in the specified database and returns them grouped by table name.
  521.      * If the table name is specified, narrows down the selection to this table.
  522.      *
  523.      * @return array<string,array<string,mixed>>
  524.      *
  525.      * @throws Exception
  526.      */
  527.     protected function fetchTableOptionsByTable(string $databaseName, ?string $tableName null): array
  528.     {
  529.         throw Exception::notSupported(__METHOD__);
  530.     }
  531.     /**
  532.      * Introspects the table with the given name.
  533.      *
  534.      * @throws Exception
  535.      */
  536.     public function introspectTable(string $name): Table
  537.     {
  538.         $table $this->listTableDetails($name);
  539.         if ($table->getColumns() === []) {
  540.             throw SchemaException::tableDoesNotExist($name);
  541.         }
  542.         return $table;
  543.     }
  544.     /**
  545.      * Lists the views this connection has.
  546.      *
  547.      * @return View[]
  548.      *
  549.      * @throws Exception
  550.      */
  551.     public function listViews()
  552.     {
  553.         $database $this->_conn->getDatabase();
  554.         $sql      $this->_platform->getListViewsSQL($database);
  555.         $views    $this->_conn->fetchAllAssociative($sql);
  556.         return $this->_getPortableViewsList($views);
  557.     }
  558.     /**
  559.      * Lists the foreign keys for the given table.
  560.      *
  561.      * @param string      $table    The name of the table.
  562.      * @param string|null $database
  563.      *
  564.      * @return ForeignKeyConstraint[]
  565.      *
  566.      * @throws Exception
  567.      */
  568.     public function listTableForeignKeys($table$database null)
  569.     {
  570.         if ($database === null) {
  571.             $database $this->getDatabase(__METHOD__);
  572.         } else {
  573.             Deprecation::trigger(
  574.                 'doctrine/dbal',
  575.                 'https://github.com/doctrine/dbal/issues/5284',
  576.                 'Passing $database to AbstractSchemaManager::listTableForeignKeys() is deprecated.',
  577.             );
  578.         }
  579.         $sql              $this->_platform->getListTableForeignKeysSQL($table$database);
  580.         $tableForeignKeys $this->_conn->fetchAllAssociative($sql);
  581.         return $this->_getPortableTableForeignKeysList($tableForeignKeys);
  582.     }
  583.     /**
  584.      * @param string      $table
  585.      * @param string|null $database
  586.      *
  587.      * @return ForeignKeyConstraint[]
  588.      *
  589.      * @throws Exception
  590.      */
  591.     protected function doListTableForeignKeys($table$database null): array
  592.     {
  593.         if ($database === null) {
  594.             $database $this->getDatabase(__METHOD__);
  595.         } else {
  596.             Deprecation::trigger(
  597.                 'doctrine/dbal',
  598.                 'https://github.com/doctrine/dbal/issues/5284',
  599.                 'Passing $database to AbstractSchemaManager::listTableForeignKeys() is deprecated.',
  600.             );
  601.         }
  602.         return $this->_getPortableTableForeignKeysList(
  603.             $this->selectForeignKeyColumns(
  604.                 $database,
  605.                 $this->normalizeName($table),
  606.             )->fetchAllAssociative(),
  607.         );
  608.     }
  609.     /* drop*() Methods */
  610.     /**
  611.      * Drops a database.
  612.      *
  613.      * NOTE: You can not drop the database this SchemaManager is currently connected to.
  614.      *
  615.      * @param string $database The name of the database to drop.
  616.      *
  617.      * @return void
  618.      *
  619.      * @throws Exception
  620.      */
  621.     public function dropDatabase($database)
  622.     {
  623.         $this->_conn->executeStatement(
  624.             $this->_platform->getDropDatabaseSQL($database),
  625.         );
  626.     }
  627.     /**
  628.      * Drops a schema.
  629.      *
  630.      * @throws Exception
  631.      */
  632.     public function dropSchema(string $schemaName): void
  633.     {
  634.         $this->_conn->executeStatement(
  635.             $this->_platform->getDropSchemaSQL($schemaName),
  636.         );
  637.     }
  638.     /**
  639.      * Drops the given table.
  640.      *
  641.      * @param string $name The name of the table to drop.
  642.      *
  643.      * @return void
  644.      *
  645.      * @throws Exception
  646.      */
  647.     public function dropTable($name)
  648.     {
  649.         $this->_conn->executeStatement(
  650.             $this->_platform->getDropTableSQL($name),
  651.         );
  652.     }
  653.     /**
  654.      * Drops the index from the given table.
  655.      *
  656.      * @param Index|string $index The name of the index.
  657.      * @param Table|string $table The name of the table.
  658.      *
  659.      * @return void
  660.      *
  661.      * @throws Exception
  662.      */
  663.     public function dropIndex($index$table)
  664.     {
  665.         if ($index instanceof Index) {
  666.             Deprecation::trigger(
  667.                 'doctrine/dbal',
  668.                 'https://github.com/doctrine/dbal/issues/4798',
  669.                 'Passing $index as an Index object to %s is deprecated. Pass it as a quoted name instead.',
  670.                 __METHOD__,
  671.             );
  672.             $index $index->getQuotedName($this->_platform);
  673.         }
  674.         if ($table instanceof Table) {
  675.             Deprecation::trigger(
  676.                 'doctrine/dbal',
  677.                 'https://github.com/doctrine/dbal/issues/4798',
  678.                 'Passing $table as an Table object to %s is deprecated. Pass it as a quoted name instead.',
  679.                 __METHOD__,
  680.             );
  681.             $table $table->getQuotedName($this->_platform);
  682.         }
  683.         $this->_conn->executeStatement(
  684.             $this->_platform->getDropIndexSQL($index$table),
  685.         );
  686.     }
  687.     /**
  688.      * Drops the constraint from the given table.
  689.      *
  690.      * @deprecated Use {@see dropIndex()}, {@see dropForeignKey()} or {@see dropUniqueConstraint()} instead.
  691.      *
  692.      * @param Table|string $table The name of the table.
  693.      *
  694.      * @return void
  695.      *
  696.      * @throws Exception
  697.      */
  698.     public function dropConstraint(Constraint $constraint$table)
  699.     {
  700.         if ($table instanceof Table) {
  701.             Deprecation::trigger(
  702.                 'doctrine/dbal',
  703.                 'https://github.com/doctrine/dbal/issues/4798',
  704.                 'Passing $table as a Table object to %s is deprecated. Pass it as a quoted name instead.',
  705.                 __METHOD__,
  706.             );
  707.             $table $table->getQuotedName($this->_platform);
  708.         }
  709.         $this->_conn->executeStatement($this->_platform->getDropConstraintSQL(
  710.             $constraint->getQuotedName($this->_platform),
  711.             $table,
  712.         ));
  713.     }
  714.     /**
  715.      * Drops a foreign key from a table.
  716.      *
  717.      * @param ForeignKeyConstraint|string $foreignKey The name of the foreign key.
  718.      * @param Table|string                $table      The name of the table with the foreign key.
  719.      *
  720.      * @return void
  721.      *
  722.      * @throws Exception
  723.      */
  724.     public function dropForeignKey($foreignKey$table)
  725.     {
  726.         if ($foreignKey instanceof ForeignKeyConstraint) {
  727.             Deprecation::trigger(
  728.                 'doctrine/dbal',
  729.                 'https://github.com/doctrine/dbal/issues/4798',
  730.                 'Passing $foreignKey as a ForeignKeyConstraint object to %s is deprecated.'
  731.                 ' Pass it as a quoted name instead.',
  732.                 __METHOD__,
  733.             );
  734.             $foreignKey $foreignKey->getQuotedName($this->_platform);
  735.         }
  736.         if ($table instanceof Table) {
  737.             Deprecation::trigger(
  738.                 'doctrine/dbal',
  739.                 'https://github.com/doctrine/dbal/issues/4798',
  740.                 'Passing $table as a Table object to %s is deprecated. Pass it as a quoted name instead.',
  741.                 __METHOD__,
  742.             );
  743.             $table $table->getQuotedName($this->_platform);
  744.         }
  745.         $this->_conn->executeStatement(
  746.             $this->_platform->getDropForeignKeySQL($foreignKey$table),
  747.         );
  748.     }
  749.     /**
  750.      * Drops a sequence with a given name.
  751.      *
  752.      * @param string $name The name of the sequence to drop.
  753.      *
  754.      * @return void
  755.      *
  756.      * @throws Exception
  757.      */
  758.     public function dropSequence($name)
  759.     {
  760.         $this->_conn->executeStatement(
  761.             $this->_platform->getDropSequenceSQL($name),
  762.         );
  763.     }
  764.     /**
  765.      * Drops the unique constraint from the given table.
  766.      *
  767.      * @throws Exception
  768.      */
  769.     public function dropUniqueConstraint(string $namestring $tableName): void
  770.     {
  771.         $this->_conn->executeStatement(
  772.             $this->_platform->getDropUniqueConstraintSQL($name$tableName),
  773.         );
  774.     }
  775.     /**
  776.      * Drops a view.
  777.      *
  778.      * @param string $name The name of the view.
  779.      *
  780.      * @return void
  781.      *
  782.      * @throws Exception
  783.      */
  784.     public function dropView($name)
  785.     {
  786.         $this->_conn->executeStatement(
  787.             $this->_platform->getDropViewSQL($name),
  788.         );
  789.     }
  790.     /* create*() Methods */
  791.     /** @throws Exception */
  792.     public function createSchemaObjects(Schema $schema): void
  793.     {
  794.         $this->_execSql($schema->toSql($this->_platform));
  795.     }
  796.     /**
  797.      * Creates a new database.
  798.      *
  799.      * @param string $database The name of the database to create.
  800.      *
  801.      * @return void
  802.      *
  803.      * @throws Exception
  804.      */
  805.     public function createDatabase($database)
  806.     {
  807.         $this->_conn->executeStatement(
  808.             $this->_platform->getCreateDatabaseSQL($database),
  809.         );
  810.     }
  811.     /**
  812.      * Creates a new table.
  813.      *
  814.      * @return void
  815.      *
  816.      * @throws Exception
  817.      */
  818.     public function createTable(Table $table)
  819.     {
  820.         $createFlags AbstractPlatform::CREATE_INDEXES AbstractPlatform::CREATE_FOREIGNKEYS;
  821.         $this->_execSql($this->_platform->getCreateTableSQL($table$createFlags));
  822.     }
  823.     /**
  824.      * Creates a new sequence.
  825.      *
  826.      * @param Sequence $sequence
  827.      *
  828.      * @return void
  829.      *
  830.      * @throws Exception
  831.      */
  832.     public function createSequence($sequence)
  833.     {
  834.         $this->_conn->executeStatement(
  835.             $this->_platform->getCreateSequenceSQL($sequence),
  836.         );
  837.     }
  838.     /**
  839.      * Creates a constraint on a table.
  840.      *
  841.      * @deprecated Use {@see createIndex()}, {@see createForeignKey()} or {@see createUniqueConstraint()} instead.
  842.      *
  843.      * @param Table|string $table
  844.      *
  845.      * @return void
  846.      *
  847.      * @throws Exception
  848.      */
  849.     public function createConstraint(Constraint $constraint$table)
  850.     {
  851.         $this->_conn->executeStatement(
  852.             $this->_platform->getCreateConstraintSQL($constraint$table),
  853.         );
  854.     }
  855.     /**
  856.      * Creates a new index on a table.
  857.      *
  858.      * @param Table|string $table The name of the table on which the index is to be created.
  859.      *
  860.      * @return void
  861.      *
  862.      * @throws Exception
  863.      */
  864.     public function createIndex(Index $index$table)
  865.     {
  866.         $this->_conn->executeStatement(
  867.             $this->_platform->getCreateIndexSQL($index$table),
  868.         );
  869.     }
  870.     /**
  871.      * Creates a new foreign key.
  872.      *
  873.      * @param ForeignKeyConstraint $foreignKey The ForeignKey instance.
  874.      * @param Table|string         $table      The name of the table on which the foreign key is to be created.
  875.      *
  876.      * @return void
  877.      *
  878.      * @throws Exception
  879.      */
  880.     public function createForeignKey(ForeignKeyConstraint $foreignKey$table)
  881.     {
  882.         $this->_conn->executeStatement(
  883.             $this->_platform->getCreateForeignKeySQL($foreignKey$table),
  884.         );
  885.     }
  886.     /**
  887.      * Creates a unique constraint on a table.
  888.      *
  889.      * @throws Exception
  890.      */
  891.     public function createUniqueConstraint(UniqueConstraint $uniqueConstraintstring $tableName): void
  892.     {
  893.         $this->_conn->executeStatement(
  894.             $this->_platform->getCreateUniqueConstraintSQL($uniqueConstraint$tableName),
  895.         );
  896.     }
  897.     /**
  898.      * Creates a new view.
  899.      *
  900.      * @return void
  901.      *
  902.      * @throws Exception
  903.      */
  904.     public function createView(View $view)
  905.     {
  906.         $this->_conn->executeStatement(
  907.             $this->_platform->getCreateViewSQL(
  908.                 $view->getQuotedName($this->_platform),
  909.                 $view->getSql(),
  910.             ),
  911.         );
  912.     }
  913.     /* dropAndCreate*() Methods */
  914.     /** @throws Exception */
  915.     public function dropSchemaObjects(Schema $schema): void
  916.     {
  917.         $this->_execSql($schema->toDropSql($this->_platform));
  918.     }
  919.     /**
  920.      * Drops and creates a constraint.
  921.      *
  922.      * @deprecated Use {@see dropIndex()} and {@see createIndex()},
  923.      *             {@see dropForeignKey()} and {@see createForeignKey()}
  924.      *             or {@see dropUniqueConstraint()} and {@see createUniqueConstraint()} instead.
  925.      *
  926.      * @see dropConstraint()
  927.      * @see createConstraint()
  928.      *
  929.      * @param Table|string $table
  930.      *
  931.      * @return void
  932.      *
  933.      * @throws Exception
  934.      */
  935.     public function dropAndCreateConstraint(Constraint $constraint$table)
  936.     {
  937.         Deprecation::trigger(
  938.             'doctrine/dbal',
  939.             'https://github.com/doctrine/dbal/pull/4897',
  940.             'AbstractSchemaManager::dropAndCreateConstraint() is deprecated.'
  941.                 ' Use AbstractSchemaManager::dropIndex() and AbstractSchemaManager::createIndex(),'
  942.                 ' AbstractSchemaManager::dropForeignKey() and AbstractSchemaManager::createForeignKey()'
  943.                 ' or AbstractSchemaManager::dropUniqueConstraint()'
  944.                 ' and AbstractSchemaManager::createUniqueConstraint() instead.',
  945.         );
  946.         $this->tryMethod('dropConstraint'$constraint$table);
  947.         $this->createConstraint($constraint$table);
  948.     }
  949.     /**
  950.      * Drops and creates a new index on a table.
  951.      *
  952.      * @deprecated Use {@see dropIndex()} and {@see createIndex()} instead.
  953.      *
  954.      * @param Table|string $table The name of the table on which the index is to be created.
  955.      *
  956.      * @return void
  957.      *
  958.      * @throws Exception
  959.      */
  960.     public function dropAndCreateIndex(Index $index$table)
  961.     {
  962.         Deprecation::trigger(
  963.             'doctrine/dbal',
  964.             'https://github.com/doctrine/dbal/pull/4897',
  965.             'AbstractSchemaManager::dropAndCreateIndex() is deprecated.'
  966.             ' Use AbstractSchemaManager::dropIndex() and AbstractSchemaManager::createIndex() instead.',
  967.         );
  968.         $this->tryMethod('dropIndex'$index->getQuotedName($this->_platform), $table);
  969.         $this->createIndex($index$table);
  970.     }
  971.     /**
  972.      * Drops and creates a new foreign key.
  973.      *
  974.      * @deprecated Use {@see dropForeignKey()} and {@see createForeignKey()} instead.
  975.      *
  976.      * @param ForeignKeyConstraint $foreignKey An associative array that defines properties
  977.      *                                         of the foreign key to be created.
  978.      * @param Table|string         $table      The name of the table on which the foreign key is to be created.
  979.      *
  980.      * @return void
  981.      *
  982.      * @throws Exception
  983.      */
  984.     public function dropAndCreateForeignKey(ForeignKeyConstraint $foreignKey$table)
  985.     {
  986.         Deprecation::trigger(
  987.             'doctrine/dbal',
  988.             'https://github.com/doctrine/dbal/pull/4897',
  989.             'AbstractSchemaManager::dropAndCreateForeignKey() is deprecated.'
  990.             ' Use AbstractSchemaManager::dropForeignKey() and AbstractSchemaManager::createForeignKey() instead.',
  991.         );
  992.         $this->tryMethod('dropForeignKey'$foreignKey$table);
  993.         $this->createForeignKey($foreignKey$table);
  994.     }
  995.     /**
  996.      * Drops and create a new sequence.
  997.      *
  998.      * @deprecated Use {@see dropSequence()} and {@see createSequence()} instead.
  999.      *
  1000.      * @return void
  1001.      *
  1002.      * @throws Exception
  1003.      */
  1004.     public function dropAndCreateSequence(Sequence $sequence)
  1005.     {
  1006.         Deprecation::trigger(
  1007.             'doctrine/dbal',
  1008.             'https://github.com/doctrine/dbal/pull/4897',
  1009.             'AbstractSchemaManager::dropAndCreateSequence() is deprecated.'
  1010.             ' Use AbstractSchemaManager::dropSequence() and AbstractSchemaManager::createSequence() instead.',
  1011.         );
  1012.         $this->tryMethod('dropSequence'$sequence->getQuotedName($this->_platform));
  1013.         $this->createSequence($sequence);
  1014.     }
  1015.     /**
  1016.      * Drops and creates a new table.
  1017.      *
  1018.      * @deprecated Use {@see dropTable()} and {@see createTable()} instead.
  1019.      *
  1020.      * @return void
  1021.      *
  1022.      * @throws Exception
  1023.      */
  1024.     public function dropAndCreateTable(Table $table)
  1025.     {
  1026.         Deprecation::trigger(
  1027.             'doctrine/dbal',
  1028.             'https://github.com/doctrine/dbal/pull/4897',
  1029.             'AbstractSchemaManager::dropAndCreateTable() is deprecated.'
  1030.             ' Use AbstractSchemaManager::dropTable() and AbstractSchemaManager::createTable() instead.',
  1031.         );
  1032.         $this->tryMethod('dropTable'$table->getQuotedName($this->_platform));
  1033.         $this->createTable($table);
  1034.     }
  1035.     /**
  1036.      * Drops and creates a new database.
  1037.      *
  1038.      * @deprecated Use {@see dropDatabase()} and {@see createDatabase()} instead.
  1039.      *
  1040.      * @param string $database The name of the database to create.
  1041.      *
  1042.      * @return void
  1043.      *
  1044.      * @throws Exception
  1045.      */
  1046.     public function dropAndCreateDatabase($database)
  1047.     {
  1048.         Deprecation::trigger(
  1049.             'doctrine/dbal',
  1050.             'https://github.com/doctrine/dbal/pull/4897',
  1051.             'AbstractSchemaManager::dropAndCreateDatabase() is deprecated.'
  1052.             ' Use AbstractSchemaManager::dropDatabase() and AbstractSchemaManager::createDatabase() instead.',
  1053.         );
  1054.         $this->tryMethod('dropDatabase'$database);
  1055.         $this->createDatabase($database);
  1056.     }
  1057.     /**
  1058.      * Drops and creates a new view.
  1059.      *
  1060.      * @deprecated Use {@see dropView()} and {@see createView()} instead.
  1061.      *
  1062.      * @return void
  1063.      *
  1064.      * @throws Exception
  1065.      */
  1066.     public function dropAndCreateView(View $view)
  1067.     {
  1068.         Deprecation::trigger(
  1069.             'doctrine/dbal',
  1070.             'https://github.com/doctrine/dbal/pull/4897',
  1071.             'AbstractSchemaManager::dropAndCreateView() is deprecated.'
  1072.             ' Use AbstractSchemaManager::dropView() and AbstractSchemaManager::createView() instead.',
  1073.         );
  1074.         $this->tryMethod('dropView'$view->getQuotedName($this->_platform));
  1075.         $this->createView($view);
  1076.     }
  1077.     /**
  1078.      * Alters an existing schema.
  1079.      *
  1080.      * @throws Exception
  1081.      */
  1082.     public function alterSchema(SchemaDiff $schemaDiff): void
  1083.     {
  1084.         $this->_execSql($this->_platform->getAlterSchemaSQL($schemaDiff));
  1085.     }
  1086.     /**
  1087.      * Migrates an existing schema to a new schema.
  1088.      *
  1089.      * @throws Exception
  1090.      */
  1091.     public function migrateSchema(Schema $toSchema): void
  1092.     {
  1093.         $schemaDiff $this->createComparator()
  1094.             ->compareSchemas($this->introspectSchema(), $toSchema);
  1095.         $this->alterSchema($schemaDiff);
  1096.     }
  1097.     /* alterTable() Methods */
  1098.     /**
  1099.      * Alters an existing tables schema.
  1100.      *
  1101.      * @return void
  1102.      *
  1103.      * @throws Exception
  1104.      */
  1105.     public function alterTable(TableDiff $tableDiff)
  1106.     {
  1107.         $this->_execSql($this->_platform->getAlterTableSQL($tableDiff));
  1108.     }
  1109.     /**
  1110.      * Renames a given table to another name.
  1111.      *
  1112.      * @param string $name    The current name of the table.
  1113.      * @param string $newName The new name of the table.
  1114.      *
  1115.      * @return void
  1116.      *
  1117.      * @throws Exception
  1118.      */
  1119.     public function renameTable($name$newName)
  1120.     {
  1121.         $this->_execSql($this->_platform->getRenameTableSQL($name$newName));
  1122.     }
  1123.     /**
  1124.      * Methods for filtering return values of list*() methods to convert
  1125.      * the native DBMS data definition to a portable Doctrine definition
  1126.      */
  1127.     /**
  1128.      * @param mixed[] $databases
  1129.      *
  1130.      * @return string[]
  1131.      */
  1132.     protected function _getPortableDatabasesList($databases)
  1133.     {
  1134.         $list = [];
  1135.         foreach ($databases as $value) {
  1136.             $list[] = $this->_getPortableDatabaseDefinition($value);
  1137.         }
  1138.         return $list;
  1139.     }
  1140.     /**
  1141.      * Converts a list of namespace names from the native DBMS data definition to a portable Doctrine definition.
  1142.      *
  1143.      * @deprecated Use {@see listSchemaNames()} instead.
  1144.      *
  1145.      * @param array<int, array<string, mixed>> $namespaces The list of namespace names
  1146.      *                                                     in the native DBMS data definition.
  1147.      *
  1148.      * @return string[]
  1149.      */
  1150.     protected function getPortableNamespacesList(array $namespaces)
  1151.     {
  1152.         Deprecation::triggerIfCalledFromOutside(
  1153.             'doctrine/dbal',
  1154.             'https://github.com/doctrine/dbal/issues/4503',
  1155.             'AbstractSchemaManager::getPortableNamespacesList() is deprecated,'
  1156.                 ' use AbstractSchemaManager::listSchemaNames() instead.',
  1157.         );
  1158.         $namespacesList = [];
  1159.         foreach ($namespaces as $namespace) {
  1160.             $namespacesList[] = $this->getPortableNamespaceDefinition($namespace);
  1161.         }
  1162.         return $namespacesList;
  1163.     }
  1164.     /**
  1165.      * @param mixed $database
  1166.      *
  1167.      * @return mixed
  1168.      */
  1169.     protected function _getPortableDatabaseDefinition($database)
  1170.     {
  1171.         return $database;
  1172.     }
  1173.     /**
  1174.      * Converts a namespace definition from the native DBMS data definition to a portable Doctrine definition.
  1175.      *
  1176.      * @deprecated Use {@see listSchemaNames()} instead.
  1177.      *
  1178.      * @param array<string, mixed> $namespace The native DBMS namespace definition.
  1179.      *
  1180.      * @return mixed
  1181.      */
  1182.     protected function getPortableNamespaceDefinition(array $namespace)
  1183.     {
  1184.         Deprecation::triggerIfCalledFromOutside(
  1185.             'doctrine/dbal',
  1186.             'https://github.com/doctrine/dbal/issues/4503',
  1187.             'AbstractSchemaManager::getPortableNamespaceDefinition() is deprecated,'
  1188.                 ' use AbstractSchemaManager::listSchemaNames() instead.',
  1189.         );
  1190.         return $namespace;
  1191.     }
  1192.     /**
  1193.      * @param mixed[][] $sequences
  1194.      *
  1195.      * @return Sequence[]
  1196.      *
  1197.      * @throws Exception
  1198.      */
  1199.     protected function _getPortableSequencesList($sequences)
  1200.     {
  1201.         $list = [];
  1202.         foreach ($sequences as $value) {
  1203.             $list[] = $this->_getPortableSequenceDefinition($value);
  1204.         }
  1205.         return $list;
  1206.     }
  1207.     /**
  1208.      * @param mixed[] $sequence
  1209.      *
  1210.      * @return Sequence
  1211.      *
  1212.      * @throws Exception
  1213.      */
  1214.     protected function _getPortableSequenceDefinition($sequence)
  1215.     {
  1216.         throw Exception::notSupported('Sequences');
  1217.     }
  1218.     /**
  1219.      * Independent of the database the keys of the column list result are lowercased.
  1220.      *
  1221.      * The name of the created column instance however is kept in its case.
  1222.      *
  1223.      * @param string    $table        The name of the table.
  1224.      * @param string    $database
  1225.      * @param mixed[][] $tableColumns
  1226.      *
  1227.      * @return Column[]
  1228.      *
  1229.      * @throws Exception
  1230.      */
  1231.     protected function _getPortableTableColumnList($table$database$tableColumns)
  1232.     {
  1233.         $eventManager $this->_platform->getEventManager();
  1234.         $list = [];
  1235.         foreach ($tableColumns as $tableColumn) {
  1236.             $column           null;
  1237.             $defaultPrevented false;
  1238.             if ($eventManager !== null && $eventManager->hasListeners(Events::onSchemaColumnDefinition)) {
  1239.                 Deprecation::trigger(
  1240.                     'doctrine/dbal',
  1241.                     'https://github.com/doctrine/dbal/issues/5784',
  1242.                     'Subscribing to %s events is deprecated. Use a custom schema manager instead.',
  1243.                     Events::onSchemaColumnDefinition,
  1244.                 );
  1245.                 $eventArgs = new SchemaColumnDefinitionEventArgs($tableColumn$table$database$this->_conn);
  1246.                 $eventManager->dispatchEvent(Events::onSchemaColumnDefinition$eventArgs);
  1247.                 $defaultPrevented $eventArgs->isDefaultPrevented();
  1248.                 $column           $eventArgs->getColumn();
  1249.             }
  1250.             if (! $defaultPrevented) {
  1251.                 $column $this->_getPortableTableColumnDefinition($tableColumn);
  1252.             }
  1253.             if ($column === null) {
  1254.                 continue;
  1255.             }
  1256.             $name        strtolower($column->getQuotedName($this->_platform));
  1257.             $list[$name] = $column;
  1258.         }
  1259.         return $list;
  1260.     }
  1261.     /**
  1262.      * Gets Table Column Definition.
  1263.      *
  1264.      * @param mixed[] $tableColumn
  1265.      *
  1266.      * @return Column
  1267.      *
  1268.      * @throws Exception
  1269.      */
  1270.     abstract protected function _getPortableTableColumnDefinition($tableColumn);
  1271.     /**
  1272.      * Aggregates and groups the index results according to the required data result.
  1273.      *
  1274.      * @param mixed[][]   $tableIndexes
  1275.      * @param string|null $tableName
  1276.      *
  1277.      * @return Index[]
  1278.      *
  1279.      * @throws Exception
  1280.      */
  1281.     protected function _getPortableTableIndexesList($tableIndexes$tableName null)
  1282.     {
  1283.         $result = [];
  1284.         foreach ($tableIndexes as $tableIndex) {
  1285.             $indexName $keyName $tableIndex['key_name'];
  1286.             if ($tableIndex['primary']) {
  1287.                 $keyName 'primary';
  1288.             }
  1289.             $keyName strtolower($keyName);
  1290.             if (! isset($result[$keyName])) {
  1291.                 $options = [
  1292.                     'lengths' => [],
  1293.                 ];
  1294.                 if (isset($tableIndex['where'])) {
  1295.                     $options['where'] = $tableIndex['where'];
  1296.                 }
  1297.                 $result[$keyName] = [
  1298.                     'name' => $indexName,
  1299.                     'columns' => [],
  1300.                     'unique' => ! $tableIndex['non_unique'],
  1301.                     'primary' => $tableIndex['primary'],
  1302.                     'flags' => $tableIndex['flags'] ?? [],
  1303.                     'options' => $options,
  1304.                 ];
  1305.             }
  1306.             $result[$keyName]['columns'][]            = $tableIndex['column_name'];
  1307.             $result[$keyName]['options']['lengths'][] = $tableIndex['length'] ?? null;
  1308.         }
  1309.         $eventManager $this->_platform->getEventManager();
  1310.         $indexes = [];
  1311.         foreach ($result as $indexKey => $data) {
  1312.             $index            null;
  1313.             $defaultPrevented false;
  1314.             if ($eventManager !== null && $eventManager->hasListeners(Events::onSchemaIndexDefinition)) {
  1315.                 Deprecation::trigger(
  1316.                     'doctrine/dbal',
  1317.                     'https://github.com/doctrine/dbal/issues/5784',
  1318.                     'Subscribing to %s events is deprecated. Use a custom schema manager instead.',
  1319.                     Events::onSchemaColumnDefinition,
  1320.                 );
  1321.                 $eventArgs = new SchemaIndexDefinitionEventArgs($data$tableName$this->_conn);
  1322.                 $eventManager->dispatchEvent(Events::onSchemaIndexDefinition$eventArgs);
  1323.                 $defaultPrevented $eventArgs->isDefaultPrevented();
  1324.                 $index            $eventArgs->getIndex();
  1325.             }
  1326.             if (! $defaultPrevented) {
  1327.                 $index = new Index(
  1328.                     $data['name'],
  1329.                     $data['columns'],
  1330.                     $data['unique'],
  1331.                     $data['primary'],
  1332.                     $data['flags'],
  1333.                     $data['options'],
  1334.                 );
  1335.             }
  1336.             if ($index === null) {
  1337.                 continue;
  1338.             }
  1339.             $indexes[$indexKey] = $index;
  1340.         }
  1341.         return $indexes;
  1342.     }
  1343.     /**
  1344.      * @param mixed[][] $tables
  1345.      *
  1346.      * @return string[]
  1347.      */
  1348.     protected function _getPortableTablesList($tables)
  1349.     {
  1350.         $list = [];
  1351.         foreach ($tables as $value) {
  1352.             $list[] = $this->_getPortableTableDefinition($value);
  1353.         }
  1354.         return $list;
  1355.     }
  1356.     /**
  1357.      * @param mixed $table
  1358.      *
  1359.      * @return string
  1360.      */
  1361.     protected function _getPortableTableDefinition($table)
  1362.     {
  1363.         return $table;
  1364.     }
  1365.     /**
  1366.      * @param mixed[][] $views
  1367.      *
  1368.      * @return View[]
  1369.      */
  1370.     protected function _getPortableViewsList($views)
  1371.     {
  1372.         $list = [];
  1373.         foreach ($views as $value) {
  1374.             $view $this->_getPortableViewDefinition($value);
  1375.             if ($view === false) {
  1376.                 continue;
  1377.             }
  1378.             $viewName        strtolower($view->getQuotedName($this->_platform));
  1379.             $list[$viewName] = $view;
  1380.         }
  1381.         return $list;
  1382.     }
  1383.     /**
  1384.      * @param mixed[] $view
  1385.      *
  1386.      * @return View|false
  1387.      */
  1388.     protected function _getPortableViewDefinition($view)
  1389.     {
  1390.         return false;
  1391.     }
  1392.     /**
  1393.      * @param mixed[][] $tableForeignKeys
  1394.      *
  1395.      * @return ForeignKeyConstraint[]
  1396.      */
  1397.     protected function _getPortableTableForeignKeysList($tableForeignKeys)
  1398.     {
  1399.         $list = [];
  1400.         foreach ($tableForeignKeys as $value) {
  1401.             $list[] = $this->_getPortableTableForeignKeyDefinition($value);
  1402.         }
  1403.         return $list;
  1404.     }
  1405.     /**
  1406.      * @param mixed $tableForeignKey
  1407.      *
  1408.      * @return ForeignKeyConstraint
  1409.      *
  1410.      * @abstract
  1411.      */
  1412.     protected function _getPortableTableForeignKeyDefinition($tableForeignKey)
  1413.     {
  1414.         return $tableForeignKey;
  1415.     }
  1416.     /**
  1417.      * @internal
  1418.      *
  1419.      * @param string[]|string $sql
  1420.      *
  1421.      * @return void
  1422.      *
  1423.      * @throws Exception
  1424.      */
  1425.     protected function _execSql($sql)
  1426.     {
  1427.         foreach ((array) $sql as $query) {
  1428.             $this->_conn->executeStatement($query);
  1429.         }
  1430.     }
  1431.     /**
  1432.      * Creates a schema instance for the current database.
  1433.      *
  1434.      * @deprecated Use {@link introspectSchema()} instead.
  1435.      *
  1436.      * @return Schema
  1437.      *
  1438.      * @throws Exception
  1439.      */
  1440.     public function createSchema()
  1441.     {
  1442.         Deprecation::triggerIfCalledFromOutside(
  1443.             'doctrine/dbal',
  1444.             'https://github.com/doctrine/dbal/pull/5613',
  1445.             '%s is deprecated. Use introspectSchema() instead.',
  1446.             __METHOD__,
  1447.         );
  1448.         $schemaNames = [];
  1449.         if ($this->_platform->supportsSchemas()) {
  1450.             $schemaNames $this->listNamespaceNames();
  1451.         }
  1452.         $sequences = [];
  1453.         if ($this->_platform->supportsSequences()) {
  1454.             $sequences $this->listSequences();
  1455.         }
  1456.         $tables $this->listTables();
  1457.         return new Schema($tables$sequences$this->createSchemaConfig(), $schemaNames);
  1458.     }
  1459.     /**
  1460.      * Returns a {@see Schema} instance representing the current database schema.
  1461.      *
  1462.      * @throws Exception
  1463.      */
  1464.     public function introspectSchema(): Schema
  1465.     {
  1466.         return $this->createSchema();
  1467.     }
  1468.     /**
  1469.      * Creates the configuration for this schema.
  1470.      *
  1471.      * @return SchemaConfig
  1472.      *
  1473.      * @throws Exception
  1474.      */
  1475.     public function createSchemaConfig()
  1476.     {
  1477.         $schemaConfig = new SchemaConfig();
  1478.         $schemaConfig->setMaxIdentifierLength($this->_platform->getMaxIdentifierLength());
  1479.         $searchPaths $this->getSchemaSearchPaths();
  1480.         if (isset($searchPaths[0])) {
  1481.             $schemaConfig->setName($searchPaths[0]);
  1482.         }
  1483.         $params $this->_conn->getParams();
  1484.         if (! isset($params['defaultTableOptions'])) {
  1485.             $params['defaultTableOptions'] = [];
  1486.         }
  1487.         if (! isset($params['defaultTableOptions']['charset']) && isset($params['charset'])) {
  1488.             $params['defaultTableOptions']['charset'] = $params['charset'];
  1489.         }
  1490.         $schemaConfig->setDefaultTableOptions($params['defaultTableOptions']);
  1491.         return $schemaConfig;
  1492.     }
  1493.     /**
  1494.      * The search path for namespaces in the currently connected database.
  1495.      *
  1496.      * The first entry is usually the default namespace in the Schema. All
  1497.      * further namespaces contain tables/sequences which can also be addressed
  1498.      * with a short, not full-qualified name.
  1499.      *
  1500.      * For databases that don't support subschema/namespaces this method
  1501.      * returns the name of the currently connected database.
  1502.      *
  1503.      * @deprecated
  1504.      *
  1505.      * @return string[]
  1506.      *
  1507.      * @throws Exception
  1508.      */
  1509.     public function getSchemaSearchPaths()
  1510.     {
  1511.         Deprecation::triggerIfCalledFromOutside(
  1512.             'doctrine/dbal',
  1513.             'https://github.com/doctrine/dbal/pull/4821',
  1514.             'AbstractSchemaManager::getSchemaSearchPaths() is deprecated.',
  1515.         );
  1516.         $database $this->_conn->getDatabase();
  1517.         if ($database !== null) {
  1518.             return [$database];
  1519.         }
  1520.         return [];
  1521.     }
  1522.     /**
  1523.      * Given a table comment this method tries to extract a typehint for Doctrine Type, or returns
  1524.      * the type given as default.
  1525.      *
  1526.      * @internal This method should be only used from within the AbstractSchemaManager class hierarchy.
  1527.      *
  1528.      * @param string|null $comment
  1529.      * @param string      $currentType
  1530.      *
  1531.      * @return string
  1532.      */
  1533.     public function extractDoctrineTypeFromComment($comment$currentType)
  1534.     {
  1535.         if ($this->_conn->getConfiguration()->getDisableTypeComments()) {
  1536.             return $currentType;
  1537.         }
  1538.         if ($comment !== null && preg_match('(\(DC2Type:(((?!\)).)+)\))'$comment$match) === 1) {
  1539.             return $match[1];
  1540.         }
  1541.         return $currentType;
  1542.     }
  1543.     /**
  1544.      * @internal This method should be only used from within the AbstractSchemaManager class hierarchy.
  1545.      *
  1546.      * @param string|null $comment
  1547.      * @param string|null $type
  1548.      *
  1549.      * @return string|null
  1550.      */
  1551.     public function removeDoctrineTypeFromComment($comment$type)
  1552.     {
  1553.         if ($this->_conn->getConfiguration()->getDisableTypeComments()) {
  1554.             return $comment;
  1555.         }
  1556.         if ($comment === null) {
  1557.             return null;
  1558.         }
  1559.         return str_replace('(DC2Type:' $type ')'''$comment);
  1560.     }
  1561.     /** @throws Exception */
  1562.     private function getDatabase(string $methodName): string
  1563.     {
  1564.         $database $this->_conn->getDatabase();
  1565.         if ($database === null) {
  1566.             throw DatabaseRequired::new($methodName);
  1567.         }
  1568.         return $database;
  1569.     }
  1570.     public function createComparator(): Comparator
  1571.     {
  1572.         return new Comparator($this->_platform);
  1573.     }
  1574.     /**
  1575.      * @return array<string,list<array<string,mixed>>>
  1576.      *
  1577.      * @throws Exception
  1578.      */
  1579.     private function fetchAllAssociativeGrouped(Result $result): array
  1580.     {
  1581.         $data = [];
  1582.         foreach ($result->fetchAllAssociative() as $row) {
  1583.             $tableName          $this->_getPortableTableDefinition($row);
  1584.             $data[$tableName][] = $row;
  1585.         }
  1586.         return $data;
  1587.     }
  1588. }