This project does not seem to handle request data directly as such no vulnerable execution paths were found.
include
, or for example
via PHP's auto-loading mechanism.
These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
1 | <?php |
||
2 | |||
3 | namespace RDV\Bundle\MigrationBundle\Migration; |
||
4 | |||
5 | use Doctrine\DBAL\Platforms\AbstractPlatform; |
||
6 | use Doctrine\DBAL\Platforms\MySqlPlatform; |
||
7 | use Doctrine\DBAL\Schema\Column; |
||
8 | use Doctrine\DBAL\Schema\ColumnDiff; |
||
9 | use Doctrine\DBAL\Schema\Comparator; |
||
10 | use Doctrine\DBAL\Schema\Index; |
||
11 | use Doctrine\DBAL\Schema\Schema; |
||
12 | use Doctrine\DBAL\Schema\SchemaConfig; |
||
13 | use Doctrine\DBAL\Schema\SchemaDiff; |
||
14 | use Doctrine\DBAL\Schema\Sequence; |
||
15 | use Doctrine\DBAL\Schema\Table; |
||
16 | use Doctrine\DBAL\Schema\TableDiff; |
||
17 | use Psr\Log\LoggerInterface; |
||
18 | use RDV\Bundle\MigrationBundle\Exception\InvalidNameException; |
||
19 | |||
20 | class MigrationExecutor |
||
21 | { |
||
22 | /** |
||
23 | * @var MigrationQueryExecutor |
||
24 | */ |
||
25 | protected $queryExecutor; |
||
26 | |||
27 | /** |
||
28 | * @var LoggerInterface |
||
29 | */ |
||
30 | protected $logger; |
||
31 | |||
32 | /** |
||
33 | * @var MigrationExtensionManager |
||
34 | */ |
||
35 | protected $extensionManager; |
||
36 | |||
37 | /** |
||
38 | * @param MigrationQueryExecutor $queryExecutor |
||
39 | */ |
||
40 | public function __construct(MigrationQueryExecutor $queryExecutor) |
||
41 | { |
||
42 | $this->queryExecutor = $queryExecutor; |
||
43 | } |
||
44 | |||
45 | /** |
||
46 | * Sets a logger |
||
47 | * |
||
48 | * @param LoggerInterface $logger |
||
49 | */ |
||
50 | public function setLogger(LoggerInterface $logger) |
||
51 | { |
||
52 | $this->logger = $logger; |
||
53 | } |
||
54 | |||
55 | /** |
||
56 | * Gets a query executor object this migration executor works with |
||
57 | * |
||
58 | * @return MigrationQueryExecutor |
||
59 | */ |
||
60 | public function getQueryExecutor() |
||
61 | { |
||
62 | return $this->queryExecutor; |
||
63 | } |
||
64 | |||
65 | /** |
||
66 | * Sets extension manager |
||
67 | * |
||
68 | * @param MigrationExtensionManager $extensionManager |
||
69 | */ |
||
70 | public function setExtensionManager(MigrationExtensionManager $extensionManager) |
||
71 | { |
||
72 | $this->extensionManager = $extensionManager; |
||
73 | $this->extensionManager->setDatabasePlatform( |
||
74 | $this->queryExecutor->getConnection()->getDatabasePlatform() |
||
75 | ); |
||
76 | } |
||
77 | |||
78 | /** |
||
79 | * Executes UP method for the given migrations |
||
80 | * |
||
81 | * @param MigrationState[] $migrations |
||
82 | * @param bool $dryRun |
||
83 | * |
||
84 | * @throws \RuntimeException if at lease one migration failed |
||
85 | */ |
||
86 | public function executeUp(array $migrations, $dryRun = false) |
||
87 | { |
||
88 | $platform = $this->queryExecutor->getConnection()->getDatabasePlatform(); |
||
89 | $sm = $this->queryExecutor->getConnection()->getSchemaManager(); |
||
90 | $schema = $this->createSchemaObject( |
||
91 | $sm->listTables(), |
||
92 | $platform->supportsSequences() ? $sm->listSequences() : [], |
||
93 | $sm->createSchemaConfig() |
||
94 | ); |
||
95 | $failedMigrations = false; |
||
96 | foreach ($migrations as $item) { |
||
97 | $migration = $item->getMigration(); |
||
98 | if (!empty($failedMigrations) && !$migration instanceof FailIndependentMigration) { |
||
99 | $this->logger->notice(sprintf('> %s - skipped', get_class($migration))); |
||
100 | continue; |
||
101 | } |
||
102 | |||
103 | if ($this->executeUpMigration($schema, $platform, $migration, $dryRun)) { |
||
104 | $item->setSuccessful(); |
||
105 | } else { |
||
106 | $item->setFailed(); |
||
107 | $failedMigrations[] = get_class($migration); |
||
108 | } |
||
109 | } |
||
110 | if (!empty($failedMigrations)) { |
||
111 | throw new \RuntimeException(sprintf('Failed migrations: %s.', implode(', ', $failedMigrations))); |
||
112 | } |
||
113 | } |
||
114 | |||
115 | /** |
||
116 | * @param Schema $schema |
||
117 | * @param AbstractPlatform $platform |
||
118 | * @param Migration $migration |
||
119 | * @param bool $dryRun |
||
120 | * |
||
121 | * @return bool |
||
122 | */ |
||
123 | public function executeUpMigration( |
||
124 | Schema &$schema, |
||
125 | AbstractPlatform $platform, |
||
126 | Migration $migration, |
||
127 | $dryRun = false |
||
128 | ) { |
||
129 | $result = true; |
||
130 | |||
131 | $this->logger->notice(sprintf('> %s', get_class($migration))); |
||
132 | $toSchema = clone $schema; |
||
133 | $this->setExtensions($migration); |
||
134 | try { |
||
135 | $queryBag = new QueryBag(); |
||
136 | $migration->up($toSchema, $queryBag); |
||
137 | |||
138 | $comparator = new Comparator(); |
||
139 | $schemaDiff = $comparator->compare($schema, $toSchema); |
||
140 | |||
141 | $this->checkTables($schemaDiff, $migration); |
||
142 | $this->checkIndexes($schemaDiff, $migration); |
||
143 | |||
144 | $queries = array_merge( |
||
145 | $queryBag->getPreQueries(), |
||
146 | $schemaDiff->toSql($platform), |
||
147 | $queryBag->getPostQueries() |
||
148 | ); |
||
149 | |||
150 | $schema = $toSchema; |
||
151 | |||
152 | foreach ($queries as $query) { |
||
153 | $this->queryExecutor->execute($query, $dryRun); |
||
154 | } |
||
155 | } catch (\Exception $ex) { |
||
156 | $result = false; |
||
157 | $this->logger->error(sprintf(' ERROR: %s', $ex->getMessage())); |
||
158 | } |
||
159 | |||
160 | return $result; |
||
161 | } |
||
162 | |||
163 | /** |
||
164 | * Creates a database schema object |
||
165 | * |
||
166 | * @param Table[] $tables |
||
167 | * @param Sequence[] $sequences |
||
168 | * @param SchemaConfig|null $schemaConfig |
||
169 | * |
||
170 | * @return Schema |
||
171 | */ |
||
172 | protected function createSchemaObject(array $tables = [], array $sequences = [], $schemaConfig = null) |
||
173 | { |
||
174 | return new Schema($tables, $sequences, $schemaConfig); |
||
175 | } |
||
176 | |||
177 | /** |
||
178 | * Sets extensions for the given migration |
||
179 | * |
||
180 | * @param Migration $migration |
||
181 | */ |
||
182 | protected function setExtensions(Migration $migration) |
||
183 | { |
||
184 | if ($this->extensionManager) { |
||
185 | $this->extensionManager->applyExtensions($migration); |
||
186 | } |
||
187 | } |
||
188 | |||
189 | /** |
||
190 | * Validates the given tables from SchemaDiff |
||
191 | * |
||
192 | * @param SchemaDiff $schemaDiff |
||
193 | * @param Migration $migration |
||
194 | * |
||
195 | * @throws InvalidNameException if invalid table or column name is detected |
||
196 | */ |
||
197 | View Code Duplication | protected function checkTables(SchemaDiff $schemaDiff, Migration $migration) |
|
0 ignored issues
–
show
|
|||
198 | { |
||
199 | foreach ($schemaDiff->newTables as $table) { |
||
200 | $this->checkTableName($table->getName(), $migration); |
||
201 | $this->checkColumnNames($table->getName(), $table->getColumns(), $migration); |
||
202 | } |
||
203 | |||
204 | foreach ($schemaDiff->changedTables as $tableName => $diff) { |
||
205 | $this->checkColumnNames( |
||
206 | $tableName, |
||
207 | array_values($diff->addedColumns), |
||
208 | $migration |
||
209 | ); |
||
210 | } |
||
211 | } |
||
212 | |||
213 | /** |
||
214 | * Validates the given columns |
||
215 | * |
||
216 | * @param string $tableName |
||
217 | * @param Column[] $columns |
||
218 | * @param Migration $migration |
||
219 | * |
||
220 | * @throws InvalidNameException if invalid column name is detected |
||
221 | */ |
||
222 | protected function checkColumnNames($tableName, $columns, Migration $migration) |
||
223 | { |
||
224 | foreach ($columns as $column) { |
||
225 | $this->checkColumnName($tableName, $column->getName(), $migration); |
||
226 | } |
||
227 | } |
||
228 | |||
229 | /** |
||
230 | * Validates table name |
||
231 | * |
||
232 | * @param string $tableName |
||
233 | * @param Migration $migration |
||
234 | * |
||
235 | * @throws InvalidNameException if table name is invalid |
||
236 | */ |
||
237 | protected function checkTableName($tableName, Migration $migration) |
||
238 | { |
||
239 | } |
||
240 | |||
241 | /** |
||
242 | * Validates column name |
||
243 | * |
||
244 | * @param string $tableName |
||
245 | * @param string $columnName |
||
246 | * @param Migration $migration |
||
247 | * |
||
248 | * @throws InvalidNameException if column name is invalid |
||
249 | */ |
||
250 | protected function checkColumnName($tableName, $columnName, Migration $migration) |
||
251 | { |
||
252 | } |
||
253 | |||
254 | /** |
||
255 | * @param SchemaDiff $schemaDiff |
||
256 | * @param Migration $migration |
||
257 | */ |
||
258 | View Code Duplication | protected function checkIndexes(SchemaDiff $schemaDiff, Migration $migration) |
|
0 ignored issues
–
show
This method seems to be duplicated in your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
|||
259 | { |
||
260 | foreach ($schemaDiff->newTables as $table) { |
||
261 | foreach ($table->getIndexes() as $index) { |
||
262 | $this->checkIndex($table, $index, $migration); |
||
263 | } |
||
264 | } |
||
265 | |||
266 | foreach ($schemaDiff->changedTables as $tableDiff) { |
||
267 | foreach (array_values($tableDiff->addedIndexes) as $index) { |
||
268 | $this->checkIndex( |
||
269 | $this->getTableFromDiff($tableDiff), |
||
270 | $index, |
||
271 | $migration |
||
272 | ); |
||
273 | } |
||
274 | } |
||
275 | } |
||
276 | |||
277 | /** |
||
278 | * @param Table $table |
||
279 | * @param Index $index |
||
280 | * @param Migration $migration |
||
281 | * |
||
282 | * @throws InvalidNameException |
||
283 | */ |
||
284 | protected function checkIndex(Table $table, Index $index, Migration $migration) |
||
285 | { |
||
286 | $columns = $index->getColumns(); |
||
287 | foreach ($columns as $columnName) { |
||
288 | if ($table->getColumn($columnName)->getLength() > MySqlPlatform::LENGTH_LIMIT_TINYTEXT) { |
||
289 | throw new InvalidNameException( |
||
290 | sprintf( |
||
291 | 'Could not create index for column with length more than %s. ' . |
||
292 | 'Please correct "%s" column length "%s" in table in "%s" migration', |
||
293 | MySqlPlatform::LENGTH_LIMIT_TINYTEXT, |
||
294 | $columnName, |
||
295 | $table->getName(), |
||
296 | get_class($migration) |
||
297 | ) |
||
298 | ); |
||
299 | } |
||
300 | } |
||
301 | } |
||
302 | |||
303 | /** |
||
304 | * @param TableDiff $diff |
||
305 | * |
||
306 | * @return Table |
||
307 | */ |
||
308 | protected function getTableFromDiff(TableDiff $diff) |
||
309 | { |
||
310 | $changedColumns = array_map( |
||
311 | function (ColumnDiff $columnDiff) { |
||
312 | return $columnDiff->column; |
||
313 | }, |
||
314 | $diff->changedColumns |
||
315 | ); |
||
316 | |||
317 | $table = new Table( |
||
318 | $diff->fromTable->getName(), |
||
319 | array_merge($diff->fromTable->getColumns(), $diff->addedColumns, $changedColumns) |
||
320 | ); |
||
321 | |||
322 | return $table; |
||
323 | } |
||
324 | } |
||
325 |
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.
You can also find more detailed suggestions in the “Code” section of your repository.