|
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