|
14 | 14 |
|
15 | 15 | use function method_exists; |
16 | 16 | use function preg_match; |
17 | | -use function strpos; |
18 | | -use function substr; |
19 | 17 |
|
20 | 18 | /** |
21 | 19 | * The DiffGenerator class is responsible for comparing two Doctrine\DBAL\Schema\Schema instances and generating a |
@@ -53,16 +51,16 @@ static function ($assetName) use ($filterExpression) { |
53 | 51 | $assetName = $assetName->getName(); |
54 | 52 | } |
55 | 53 |
|
56 | | - return preg_match($filterExpression, $assetName); |
| 54 | + return (bool) preg_match($filterExpression, $assetName); |
57 | 55 | }, |
58 | 56 | ); |
59 | 57 | } |
60 | 58 |
|
| 59 | + $toSchema = $this->createToSchema(); |
| 60 | + |
61 | 61 | $fromSchema = $fromEmptySchema |
62 | 62 | ? $this->createEmptySchema() |
63 | | - : $this->createFromSchema(); |
64 | | - |
65 | | - $toSchema = $this->createToSchema(); |
| 63 | + : $this->createFromSchema($toSchema); |
66 | 64 |
|
67 | 65 | // prior to DBAL 4.0, the schema name was set to the first element in the search path, |
68 | 66 | // which is not necessarily the default schema name |
@@ -112,42 +110,37 @@ private function createEmptySchema(): Schema |
112 | 110 | return $this->emptySchemaProvider->createSchema(); |
113 | 111 | } |
114 | 112 |
|
115 | | - private function createFromSchema(): Schema |
116 | | - { |
117 | | - return $this->schemaManager->introspectSchema(); |
118 | | - } |
119 | | - |
120 | | - private function createToSchema(): Schema |
| 113 | + /** |
| 114 | + * Creates the schema from the database, ensuring tables from the target schema are whitelisted for comparison. |
| 115 | + * |
| 116 | + * @see https://github.com/doctrine/orm/pull/7875 |
| 117 | + */ |
| 118 | + private function createFromSchema(Schema $toSchema): Schema |
121 | 119 | { |
122 | | - $toSchema = $this->schemaProvider->createSchema(); |
| 120 | + // backup schema assets filter |
| 121 | + $previousFilter = $this->dbalConfiguration->getSchemaAssetsFilter(); |
123 | 122 |
|
124 | | - $schemaAssetsFilter = $this->dbalConfiguration->getSchemaAssetsFilter(); |
| 123 | + if ($previousFilter === null) { |
| 124 | + return $this->schemaManager->introspectSchema(); |
| 125 | + } |
125 | 126 |
|
126 | | - if ($schemaAssetsFilter !== null) { |
127 | | - foreach ($toSchema->getTables() as $table) { |
128 | | - $tableName = $table->getName(); |
| 127 | + // whitelist assets we already know about in $toSchema, use the existing filter otherwise |
| 128 | + $this->dbalConfiguration->setSchemaAssetsFilter(static function ($asset) use ($previousFilter, $toSchema): bool { |
| 129 | + $assetName = $asset instanceof AbstractAsset ? $asset->getName() : $asset; |
129 | 130 |
|
130 | | - if ($schemaAssetsFilter($this->resolveTableName($tableName))) { |
131 | | - continue; |
132 | | - } |
| 131 | + return $toSchema->hasTable($assetName) || $toSchema->hasSequence($assetName) || $previousFilter($asset); |
| 132 | + }); |
133 | 133 |
|
134 | | - $toSchema->dropTable($tableName); |
135 | | - } |
| 134 | + try { |
| 135 | + return $this->schemaManager->introspectSchema(); |
| 136 | + } finally { |
| 137 | + // restore schema assets filter |
| 138 | + $this->dbalConfiguration->setSchemaAssetsFilter($previousFilter); |
136 | 139 | } |
137 | | - |
138 | | - return $toSchema; |
139 | 140 | } |
140 | 141 |
|
141 | | - /** |
142 | | - * Resolve a table name from its fully qualified name. The `$name` argument |
143 | | - * comes from Doctrine\DBAL\Schema\Table#getName which can sometimes return |
144 | | - * a namespaced name with the form `{namespace}.{tableName}`. This extracts |
145 | | - * the table name from that. |
146 | | - */ |
147 | | - private function resolveTableName(string $name): string |
| 142 | + private function createToSchema(): Schema |
148 | 143 | { |
149 | | - $pos = strpos($name, '.'); |
150 | | - |
151 | | - return $pos === false ? $name : substr($name, $pos + 1); |
| 144 | + return $this->schemaProvider->createSchema(); |
152 | 145 | } |
153 | 146 | } |
0 commit comments