Skip to content

Commit d78d246

Browse files
committed
🐛 issue #3540 and add test database migration
1 parent e36aa17 commit d78d246

File tree

8 files changed

+1291
-14
lines changed

8 files changed

+1291
-14
lines changed
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
name: Test MySQL Database migration
2+
3+
on:
4+
pull_request:
5+
6+
7+
jobs:
8+
db_migration:
9+
strategy:
10+
matrix:
11+
php-version: [ '8.1' ]
12+
db-source-version: ['4.2', '5.0', '5.1']
13+
# db-source-version: ['4.2']
14+
fail-fast: false
15+
services:
16+
mysql:
17+
image: mysql:5.7
18+
ports:
19+
- "3306:3306"
20+
env:
21+
MYSQL_DATABASE: bolt
22+
MYSQL_USER: bolt
23+
MYSQL_PASSWORD: bolt
24+
MYSQL_ROOT_PASSWORD: bolt
25+
options: --health-cmd="mysqladmin ping" --health-interval=10s --health-timeout=5s --health-retries=3
26+
27+
name: MySQL DB Migration test from ${{ matrix.db-source-version }}
28+
runs-on: ubuntu-latest
29+
steps:
30+
- uses: actions/checkout@v4
31+
32+
- name: restore database
33+
run: mysql -h 127.0.0.1 -u root --password=bolt bolt < tests/assets/database_dump_mysql/bolt-${{ matrix.db-source-version }}_database.sql
34+
35+
- uses: shivammathur/setup-php@v2
36+
with:
37+
# test the lowest version, to make sure checks pass on it
38+
php-version: ${{ matrix.php-version }}
39+
extensions: json, mbstring, pdo, curl, pdo_mysql
40+
coverage: none
41+
env:
42+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
43+
- name: Install composer dependencies
44+
run: composer install --prefer-dist --no-progress
45+
env:
46+
DATABASE_URL: mysql://bolt:[email protected]/bolt?serverVersion=5.7&charset=utf8mb4
47+
48+
- name: upgrade
49+
run: bin/console doctrine:migrations:migrate -n
50+
env:
51+
DATABASE_URL: mysql://bolt:[email protected]/bolt?serverVersion=5.7&charset=utf8mb4
52+
53+
- name: list migration
54+
run: |
55+
bin/console doctrine:migration:status -n
56+
bin/console doctrine:migration:list -n
57+
env:
58+
DATABASE_URL: mysql://bolt:[email protected]/bolt?serverVersion=5.7&charset=utf8mb4
59+
- name: Check DB DIFF
60+
run: |
61+
set +e
62+
bin/console doctrine:migrations:diff -n
63+
result=$?
64+
if [ $result -eq 0 ]; then
65+
migration_file=migrations/$(ls -1 migrations | tail -n 1)
66+
# The `$this->addSql('ALTER TABLE bolt_field_translation CHANGE value value JSON NOT NULL');` change is due doctrine/migration and database server misconfiguration
67+
count=$(grep -c 'ALTER TABLE bolt_field_translation CHANGE value value JSON NOT NULL' $migration_file || true)
68+
# count all `addSql` method call
69+
countAddSql=$(grep -c 'addSql' $migration_file || true)
70+
if (( $countAddSql - $count > 0 )); then
71+
echo ' '
72+
echo '**************************** CHANGE ****************************'
73+
echo ' '
74+
cat $migration_file
75+
echo ' '
76+
echo '********************* MISSING A MIGRATION *********************'
77+
echo ' '
78+
exit 1
79+
else
80+
echo 'Great Job! No unexpected change!'
81+
fi
82+
fi
83+
exit 0
84+
env:
85+
DATABASE_URL: mysql://bolt:[email protected]/bolt?serverVersion=5.7&charset=utf8mb4

compose.yml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,10 @@ services:
2121
ports:
2222
- 3306
2323
environment:
24-
MYSQL_ROOT_PASSWORD: ${DATABASE_PASSWORD}
25-
MYSQL_PASSWORD: ${DATABASE_PASSWORD}
26-
MYSQL_USER: ${DATABASE_USER}
27-
MYSQL_DATABASE: ${DATABASE_NAME}
24+
MYSQL_ROOT_PASSWORD: ${DATABASE_PASSWORD:-bolt}
25+
MYSQL_PASSWORD: ${DATABASE_PASSWORD:-bolt}
26+
MYSQL_USER: ${DATABASE_USER:-bolt}
27+
MYSQL_DATABASE: ${DATABASE_NAME:-bolt}
2828
MYSQL_INITDB_SKIP_TZINFO: 0
2929

3030
web:

migrations/Version20201210105836.php

Lines changed: 48 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
use Doctrine\DBAL\Connection;
88
use Doctrine\DBAL\Schema\Schema;
9+
use Doctrine\DBAL\Schema\SchemaConfig;
910
use Doctrine\Migrations\AbstractMigration;
1011
use Psr\Log\LoggerInterface;
1112
use Symfony\Component\DependencyInjection\ContainerAwareInterface;
@@ -23,31 +24,68 @@ public function __construct(Connection $connection, LoggerInterface $logger)
2324
$this->tablePrefix = 'bolt';
2425
}
2526

26-
public function getDescription() : string
27+
public function getDescription(): string
2728
{
2829
return 'Bolt 4.2 Migration: bolt_reset_password and bolt_column.avatar';
2930
}
3031

31-
public function up(Schema $schema) : void
32+
public function up(Schema $schema): void
3233
{
34+
$schemaConfig = new SchemaConfig();
35+
$options = [
36+
'charset' => 'utf8',
37+
];
38+
if ($this->connection->getDatabasePlatform()->getName() === 'mysql') {
39+
$options = [
40+
'engine' => 'InnoDB',
41+
'charset' => 'utf8mb4',
42+
'collate' => 'utf8mb4_unicode_ci'
43+
];
44+
}
45+
$schemaConfig->setDefaultTableOptions($options);
46+
3347
// Create the user avatar. See https://github.com/bolt/core/pull/2114
3448
$userTable = $schema->getTable($this->tablePrefix . '_user');
3549

36-
if (! $userTable->hasColumn('avatar')) {
50+
if (!$userTable->hasColumn('avatar')) {
3751
$userTable->addColumn('avatar', 'string', ['notnull' => false, 'length' => 250]);
3852
}
3953

4054
// Create the reset password table. See https://github.com/bolt/core/pull/2131
41-
if (!$schema->hasTable($this->tablePrefix . '_password_request')) {
42-
$resetPaswordTable = $schema->createTable($this->tablePrefix . '_password_request');
43-
$resetPaswordTable->addColumn('id', 'integer', ['autoincrement' => true]);
44-
$resetPaswordTable->setPrimaryKey(["id"]); // MySQL / MariaDB needs autoincrement column to be the primary key
45-
$resetPaswordTable->addColumn('user_id', 'integer', ['notnull' => true, '', 'default' => 0]);
46-
$resetPaswordTable->addForeignKeyConstraint($this->tablePrefix . '_user', ['user_id'], ['id'], ['onUpdate' => 'CASCADE']);
55+
if ($schema->hasTable($this->tablePrefix . '_reset_password_request') === false) {
56+
57+
$table = $schema->createTable($this->tablePrefix . '_reset_password_request');
58+
$table->addColumn('id', 'integer', ['autoincrement' => true, 'notnull' => true]);
59+
$table->addColumn('user_id', 'integer', ['notnull' => true]);
60+
$table->addColumn('selector', 'string', ['notnull' => true, 'length' => 20]);
61+
$table->addColumn('hashed_token', 'string', ['notnull' => true, 'length' => 100]);
62+
$table->addColumn('requested_at', 'datetime',
63+
['notnull' => true, 'comment' => '(DC2Type:datetime_immutable)']);
64+
$table->addColumn('expires_at', 'datetime',
65+
['notnull' => true, 'comment' => '(DC2Type:datetime_immutable)']);
66+
67+
$table->setPrimaryKey(['id']);
68+
$table->addIndex(['user_id'], 'IDX_D04070DCA76ED395');
69+
$table->setSchemaConfig($schemaConfig);
70+
$table->addForeignKeyConstraint(
71+
$this->tablePrefix . '_user',
72+
['user_id'],
73+
['id'],
74+
[],
75+
'FK_D04070DCA76ED395'
76+
);
77+
}
78+
79+
$fieldTranstationTable = $schema->getTable($this->tablePrefix . '_field_translation');
80+
foreach ($fieldTranstationTable->getIndexes() as $index) {
81+
if ($index->getName() === 'bolt_field_translation_unique_translation') {
82+
$fieldTranstationTable->renameIndex('bolt_field_translation_unique_translation',
83+
'field_translation_unique_translation');
84+
}
4785
}
4886
}
4987

50-
public function down(Schema $schema) : void
88+
public function down(Schema $schema): void
5189
{
5290
}
5391
}

migrations/Version20211123103530.php

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,20 @@ public function up(Schema $schema): void
3232
$userTable = $schema->getTable($this->tablePrefix . '_user_auth_token');
3333
$indexes = $userTable->getIndexes();
3434

35+
// Add index needed by foreign key before remove unique index
36+
$hasIndex = false;
37+
foreach ($indexes as $index) {
38+
if (strtoupper($index->getName()) === 'IDX_8B90D313A76ED395') {
39+
$hasIndex = true;
40+
}
41+
}
42+
43+
// If no index found, add it
44+
if (!$hasIndex) {
45+
$userTable->addIndex(['user_id'], 'IDX_8B90D313A76ED395');
46+
}
47+
48+
// Remove unique index if found
3549
foreach($indexes as $index) {
3650
if ($index->getColumns() === [0 => 'user_id'] && $index->isUnique()) {
3751
$userTable->dropIndex($index->getName());

migrations/Version20221004090755.php

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,12 +34,28 @@ public function up(Schema $schema): void
3434
if (! $userTable->hasColumn('about')) {
3535
$userTable->addColumn('about', 'string', ['notnull' => false, 'length' => 1024]);
3636
}
37+
38+
$contentTable = $schema->getTable($this->tablePrefix . '_content');
39+
40+
if (! $contentTable->hasColumn('title')) {
41+
$contentTable->addColumn('title', 'string', ['notnull' => false, 'length' => 191]);
42+
}
43+
if (! $contentTable->hasColumn('list_format')) {
44+
$contentTable->addColumn('list_format', 'string', ['notnull' => false, 'length' => 191]);
45+
}
46+
3747
}
3848

3949
public function down(Schema $schema): void
4050
{
4151
$userTable = $schema->getTable($this->tablePrefix . '_user');
4252

4353
$userTable->dropColumn('about');
54+
55+
$contentTable = $schema->getTable($this->tablePrefix . '_content');
56+
57+
$contentTable->dropColumn('title');
58+
$contentTable->dropColumn('list_format');
59+
4460
}
4561
}

0 commit comments

Comments
 (0)