Skip to content

Commit e0d0cd5

Browse files
authored
feat: add migration logging required fields (#38)
1 parent f41e6ab commit e0d0cd5

File tree

120 files changed

+1742
-2048
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

120 files changed

+1742
-2048
lines changed

.gitignore

Lines changed: 27 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,32 @@
1-
.idea
2-
.vscode
3-
coverage/
4-
.phpunit.cache
5-
.phpunit.result.cache
6-
vendor
7-
node_modules
8-
phpstan.neon
1+
# ide
2+
.idea/
3+
.vscode/
4+
5+
# os
6+
.DS_Store
7+
8+
# node
9+
node_modules/
910
*.hot-update.js
10-
/var/
11+
12+
# php
13+
vendor/
14+
phpstan.neon
1115
composer.lock
12-
src/Resources/public/administration/
16+
.phpunit.cache
17+
.phpunit.result.cache
18+
19+
# tests
20+
coverage/
21+
22+
# build
1323
src/Resources/public/static/
24+
src/Resources/public/administration/
25+
src/Resources/app/administration/.tmp
26+
27+
# runtime
28+
/var/
1429
.env
30+
31+
# plugin
1532
/migration_assistant.cache

phpstan-baseline.neon

Lines changed: 420 additions & 215 deletions
Large diffs are not rendered by default.

phpstan.neon.dist

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,21 @@ parameters:
4949
- src/Profile/Shopware/Premapping/PaymentMethodReader.php
5050
- tests/Profile/Shopware/Premapping/PaymentMethodReaderTest.php
5151

52+
- # TODO remove this for 6.8 compatibility
53+
message: '#Call to deprecated method __construct\(\) of class Shopware\\Core\\Framework\\DataAbstractionLayer\\EntityDefinition:#'
54+
paths:
55+
- tests/**/*Test.php
56+
57+
- # TODO remove with #11883
58+
message: '#Strict comparison using === between SwagMigrationAssistant\\Migration\\Connection\\SwagMigrationConnectionEntity and null will always evaluate to false\.#'
59+
paths:
60+
- **/*.php
61+
62+
- # TODO remove with #11883
63+
message: '#Strict comparison using !== between SwagMigrationAssistant\\Migration\\Connection\\SwagMigrationConnectionEntity and null will always evaluate to true\.#'
64+
paths:
65+
- **/*.php
66+
5267
rules:
5368
# Shopware core rules
5469
- Shopware\Core\DevOps\StaticAnalyze\PHPStan\Rules\Deprecation\DeprecatedMethodsThrowDeprecationRule
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
<?php declare(strict_types=1);
2+
/*
3+
* (c) shopware AG <[email protected]>
4+
* For the full copyright and license information, please view the LICENSE
5+
* file that was distributed with this source code.
6+
*/
7+
8+
namespace SwagMigrationAssistant\Core\Migration;
9+
10+
use Doctrine\DBAL\Connection;
11+
use Shopware\Core\Framework\Log\Package;
12+
use Shopware\Core\Framework\Migration\MigrationStep;
13+
14+
#[Package('fundamentals@after-sales')]
15+
class Migration1754896654TruncateMigrationLogs extends MigrationStep
16+
{
17+
public function getCreationTimestamp(): int
18+
{
19+
return 1754896654;
20+
}
21+
22+
public function update(Connection $connection): void
23+
{
24+
$connection->executeStatement('TRUNCATE TABLE `swag_migration_logging`');
25+
}
26+
}
Lines changed: 172 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,172 @@
1+
<?php declare(strict_types=1);
2+
/*
3+
* (c) shopware AG <[email protected]>
4+
* For the full copyright and license information, please view the LICENSE
5+
* file that was distributed with this source code.
6+
*/
7+
8+
namespace SwagMigrationAssistant\Core\Migration;
9+
10+
use Doctrine\DBAL\Connection;
11+
use Doctrine\DBAL\Exception;
12+
use Doctrine\DBAL\Platforms\MySQLPlatform;
13+
use Doctrine\DBAL\Schema\AbstractSchemaManager;
14+
use Shopware\Core\Framework\Log\Package;
15+
use Shopware\Core\Framework\Migration\MigrationStep;
16+
17+
#[Package('fundamentals@after-sales')]
18+
class Migration1754897550AddRequiredFieldsToMigrationLogs extends MigrationStep
19+
{
20+
public const MIGRATION_LOGGING_TABLE = 'swag_migration_logging';
21+
22+
public const REQUIRED_FIELDS = [
23+
'id' => 'BINARY(16) NOT NULL',
24+
'run_id' => null,
25+
'level' => null,
26+
'code' => null,
27+
'profile_name' => 'VARCHAR(255) NOT NULL',
28+
'gateway_name' => 'VARCHAR(255) NOT NULL',
29+
'user_fixable' => 'TINYINT(1) NOT NULL DEFAULT 0',
30+
'auto_increment' => null,
31+
'created_at' => null,
32+
'updated_at' => null,
33+
];
34+
35+
public function getCreationTimestamp(): int
36+
{
37+
return 1754897550;
38+
}
39+
40+
/**
41+
* @throws \Throwable
42+
*/
43+
public function update(Connection $connection): void
44+
{
45+
$schemaManager = $connection->createSchemaManager();
46+
47+
if (!$schemaManager->tablesExist([self::MIGRATION_LOGGING_TABLE])) {
48+
return;
49+
}
50+
51+
$this->dropForeignKeyIfExists($connection, self::MIGRATION_LOGGING_TABLE, 'fk.swag_migration_logging.run_id');
52+
$this->dropIndexIfExists($connection, self::MIGRATION_LOGGING_TABLE, 'idx.swag_migration_logging.run_id_code');
53+
$this->dropConstraintIfExists($connection, 'json.swag_migration_logging.log_entry');
54+
55+
$this->dropObsoleteColumns($connection, $schemaManager);
56+
$this->addOrModifyRequiredColumns($connection, $schemaManager);
57+
$this->ensureRelations($connection, $schemaManager);
58+
}
59+
60+
/**
61+
* @param AbstractSchemaManager<MySQLPlatform> $schemaManager
62+
*/
63+
private function dropObsoleteColumns(Connection $connection, AbstractSchemaManager $schemaManager): void
64+
{
65+
$columns = $schemaManager->listTableColumns(self::MIGRATION_LOGGING_TABLE);
66+
67+
foreach ($columns as $column) {
68+
if (!\array_key_exists($column->getName(), self::REQUIRED_FIELDS)) {
69+
$connection->executeStatement(
70+
\sprintf(
71+
'ALTER TABLE `%s` DROP COLUMN `%s`;',
72+
self::MIGRATION_LOGGING_TABLE,
73+
$column->getName()
74+
)
75+
);
76+
}
77+
}
78+
}
79+
80+
/**
81+
* @param AbstractSchemaManager<MySQLPlatform> $schemaManager
82+
*/
83+
private function addOrModifyRequiredColumns(Connection $connection, AbstractSchemaManager $schemaManager): void
84+
{
85+
$columns = $schemaManager->listTableColumns(self::MIGRATION_LOGGING_TABLE);
86+
87+
foreach (self::REQUIRED_FIELDS as $name => $type) {
88+
if ($type === null) {
89+
continue;
90+
}
91+
92+
if (!isset($columns[$name])) {
93+
$connection->executeStatement(
94+
\sprintf(
95+
'ALTER TABLE `%s` ADD COLUMN `%s` %s;',
96+
self::MIGRATION_LOGGING_TABLE,
97+
$name,
98+
$type
99+
)
100+
);
101+
} else {
102+
$connection->executeStatement(
103+
\sprintf(
104+
'ALTER TABLE `%s` MODIFY COLUMN `%s` %s;',
105+
self::MIGRATION_LOGGING_TABLE,
106+
$name,
107+
$type
108+
)
109+
);
110+
}
111+
}
112+
}
113+
114+
/**
115+
* @param AbstractSchemaManager<MySQLPlatform> $schemaManager
116+
*/
117+
private function ensureRelations(Connection $connection, AbstractSchemaManager $schemaManager): void
118+
{
119+
// ensure primary key and index
120+
$indexes = $schemaManager->listTableIndexes(self::MIGRATION_LOGGING_TABLE);
121+
122+
if (isset($indexes['primary'])) {
123+
$connection->executeStatement(
124+
\sprintf(
125+
'ALTER TABLE `%s` DROP PRIMARY KEY;',
126+
self::MIGRATION_LOGGING_TABLE
127+
)
128+
);
129+
}
130+
131+
$connection->executeStatement(
132+
\sprintf(
133+
'ALTER TABLE `%s` ADD PRIMARY KEY (`id`);',
134+
self::MIGRATION_LOGGING_TABLE
135+
)
136+
);
137+
138+
$this->dropIndexIfExists(
139+
$connection,
140+
self::MIGRATION_LOGGING_TABLE,
141+
'idx.run_id'
142+
);
143+
$connection->executeStatement(
144+
\sprintf(
145+
'ALTER TABLE `%s` ADD INDEX `idx.run_id` (`run_id`);',
146+
self::MIGRATION_LOGGING_TABLE
147+
)
148+
);
149+
150+
// ensure foreign key constraint
151+
$connection->executeStatement(
152+
\sprintf(
153+
'ALTER TABLE `%s` ADD CONSTRAINT `fk.swag_migration_logging.run_id` FOREIGN KEY (`run_id`) REFERENCES `swag_migration_run` (`id`) ON DELETE RESTRICT ON UPDATE CASCADE;',
154+
self::MIGRATION_LOGGING_TABLE
155+
)
156+
);
157+
}
158+
159+
private function dropConstraintIfExists(Connection $connection, string $constraintName): void
160+
{
161+
try {
162+
$connection->executeStatement(
163+
\sprintf(
164+
'ALTER TABLE `%s` DROP CONSTRAINT `%s`;',
165+
self::MIGRATION_LOGGING_TABLE,
166+
$constraintName
167+
)
168+
);
169+
} catch (Exception) {
170+
}
171+
}
172+
}

src/Migration/History/HistoryService.php

Lines changed: 13 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -59,20 +59,8 @@ public function getGroupedLogsOfRun(
5959
null,
6060
null,
6161
new TermsAggregation(
62-
'titleSnippet',
63-
'titleSnippet',
64-
null,
65-
null,
66-
new TermsAggregation(
67-
'entity',
68-
'entity',
69-
null,
70-
null,
71-
new TermsAggregation(
72-
'level',
73-
'level'
74-
)
75-
)
62+
'level',
63+
'level'
7664
)
7765
)
7866
);
@@ -114,8 +102,8 @@ public function downloadLogsOfRun(string $runUuid, Context $context): \Closure
114102

115103
foreach ($logChunk->getElements() as $logEntry) {
116104
\printf('[%s] %s%s', $logEntry->getLevel(), $logEntry->getCode(), \PHP_EOL);
117-
\printf('%s%s', $logEntry->getTitle(), \PHP_EOL);
118-
\printf('%s%s%s', $logEntry->getDescription(), \PHP_EOL, \PHP_EOL);
105+
\printf('%s%s', $logEntry->getProfileName(), \PHP_EOL);
106+
\printf('%s%s%s', $logEntry->getGatewayName(), \PHP_EOL, \PHP_EOL);
119107
}
120108

121109
$offset += self::LOG_FETCH_LIMIT;
@@ -151,31 +139,25 @@ public function isMediaProcessing(): bool
151139
'SELECT COUNT(id) FROM swag_migration_media_file WHERE processed = 0 and process_failure != 1'
152140
)->fetchOne();
153141

154-
return $unprocessedCount !== '0';
142+
return (int) $unprocessedCount !== 0;
155143
}
156144

157145
private function extractBucketInformation(Bucket $bucket): array
158146
{
159-
/** @var TermsResult $titleResult */
160-
$titleResult = $bucket->getResult();
161-
$titleBucket = $titleResult->getBuckets()[0];
162-
163-
/** @var TermsResult $entityResult */
164-
$entityResult = $titleBucket->getResult();
165-
$entityString = empty($entityResult->getBuckets()) ? '' : $entityResult->getBuckets()[0]->getKey();
166-
147+
/** @var TermsResult|null $levelResult */
148+
$levelResult = $bucket->getResult();
167149
$levelString = '';
168-
if ($entityString !== '') {
169-
/** @var TermsResult $levelResult */
170-
$levelResult = $entityResult->getBuckets()[0]->getResult();
171-
$levelString = empty($levelResult->getBuckets()) ? '' : $levelResult->getBuckets()[0]->getKey();
150+
151+
if ($levelResult !== null) {
152+
$levelBuckets = $levelResult->getBuckets();
153+
if (!empty($levelBuckets)) {
154+
$levelString = $levelBuckets[0]->getKey();
155+
}
172156
}
173157

174158
return [
175159
'code' => $bucket->getKey(),
176160
'count' => $bucket->getCount(),
177-
'titleSnippet' => $titleBucket->getKey(),
178-
'entity' => $entityString,
179161
'level' => $levelString,
180162
];
181163
}

0 commit comments

Comments
 (0)