Skip to content

IBX-11939: [Doctrine Migrations] Added Doctrine Migrations-based schema and data install path (inlined SQL) - #787

Open
Steveb-p wants to merge 12 commits into
base/ibx-11939-4.6-merged-5.0from
feature/fix-schema-rename-migration-5.0-postgres
Open

Steveb-p wants to merge 12 commits into
base/ibx-11939-4.6-merged-5.0from
feature/fix-schema-rename-migration-5.0-postgres

Conversation

@Steveb-p

@Steveb-p Steveb-p commented Jul 20, 2026 •

Copy link
Copy Markdown
Contributor

Warning

Stacked on the 4.6 → 5.0 merge-up #863. Its base branch (base/ibx-11939-4.6-merged-5.0) is the merge-up's branch — 5.0 with 4.6 merged in, including #785 and #856 — so this PR shows only what 5.0 needs on top. Fast-forward #863 into 5.0 first, then retarget this PR to 5.0.

Warning

This is the 5.0 follow-up to #785 (4.6). It carries the same migration forward onto this branch.

Warning

MariaDB schema drift between upgraded and fresh installs, fixed here by a new migration. On MariaDB, 4.6 creates ibexa_setting.value as LONGTEXT … COMMENT '(DC2Type:json)', and 5.0 as JSON, which MariaDB stores as LONGTEXT in utf8mb4_bin with a json_valid() check. InstallSchemaMigration doesn't run again on upgrade, and ibexa/installer's ibexa-4.6.latest-to-5.0.0.sql doesn't convert it either, so a 4.6 database upgraded to 5.0 kept the 4.6 form. ConvertMariaDbJsonColumnsMigration converts it, and fails if a row holds invalid JSON. On MariaDB 10.11 an upgraded 4.6 database ends up identical to a fresh 5.0 install, data included; on a fresh install, on a re-run and on other databases it does nothing.

🎫 Issue IBX-11939

Note

Test-side companion — ibexa/test-core#57.
Moves the baseline fixture import into its own BaseFixtureHook (priority 950, between the
schema hooks and FixtureHook), switchable with a load_base_fixture option.
It matters here because under the Doctrine Migrations path the baseline repository content
arrives as core's ImportDataMigration rather than as a loaded fixture, and FixtureImporter
truncates every table a fixture touches before inserting — so a package's own fixture writing
into those tables would take the baseline's rows with it unless it implements AppendOnlyFixture.
Packages whose integration tests load their own fixtures depend on it; the rest are unaffected.

Note

Shared library — ibexa/doctrine-migrations.
Every migration in the table below extends the AbstractSqlMigration / SqlPlatform base it provides.
It is already merged on all three branches, so nothing in this effort is blocked on it:
#1 (4.6 baseline) · #3 (6.0 baseline) · #4 (enable_service_migrations fix) · #6 (DBAL 4).
The fix reached 5.0 and 6.0 via merge-ups #9 and #10 — which is why #5 was closed rather than merged.

Related PRs:

Package 4.6 5.0 6.0
ibexa/activity-log #166 #167 #168
ibexa/cart #172 #173 🔄 #174
ibexa/collaboration – #115 #116
ibexa/connector-ai – #198 #199
ibexa/connector-payum ⚠️ #39 #40 #41 🩹
ibexa/core #785 🩹 this PR 🔄 🩹 #788 🩹
ibexa/corporate-account #369 #370 🔄 #371
ibexa/discounts – #341 🩹 #342 🩹
ibexa/discounts-codes – #50 #51
ibexa/doctrine-schema #41 #42 #43
ibexa/fieldtype-page #208 🩹 #209 🔄 🩹 #210 🩹
ibexa/form-builder #240 🩹 #241 🔄 🩹 #242 🩹
ibexa/measurement #133 #134 🔄 #135
ibexa/messenger – #22 #23
ibexa/migrations #438 #439 #440 ⏭️
ibexa/oauth2-server 🔄 #48 #49 #50
ibexa/order-management #188 #189 🔄 #190
ibexa/payment #204 #205 🔄 #206
ibexa/product-catalog #1543 #1544 🔄 #1545
ibexa/product-catalog-date-time-attribute – #53 #54
ibexa/product-catalog-symbol-attribute – #17 #18 ⏭️
ibexa/scheduler #168 #169 🔄 #170
ibexa/segmentation #186 #187 🔄 #188 🩹
ibexa/share – #190 #191 ⏭️
ibexa/shipping #154 #155 🔄 #156
ibexa/shopping-list – #66 #67
ibexa/site-context – – #121
ibexa/site-factory #172 #173 🔄 🩹 #174 🩹
ibexa/taxonomy ⚠️ #431 🩹 #432 🩹 #433 🩹
ibexa/translations-management – #174 #175
ibexa/user #128 #129 🔄 #130
ibexa/workflow #191 🩹 #192 🔄 🩹 #193 🩹

🔄 = this branch adds an upgrade migration (renames/FK-retargets existing schema), not just a fresh baseline.
🩹 = this branch also received a backported delta migration, converted from a legacy ibexa/installer upgrade/db/*.sql script (4.6.0 or later) that the original baseline-only migration didn't cover. See IBX-11939 upgrade-scripts backport report or that package's own PR description for details.
⚠️ = fixes a different, related problem (missing SchemaBuilderEvent support for a plain Doctrine ORM entity/table) — not a Doctrine Migrations baseline/upgrade migration like the rest of this table. See that package's own PR description for details.
⏭️ = struck through and closed as unnecessary — that tier needs no changes of its own. Everything it requires arrives through the normal merge-up from the tier below; the branch is kept, so the PR can be reopened if genuinely tier-specific work turns up.

Description:

Fixes a gap in #785's Doctrine Migrations installer path. On the 5.0 and 6.0 branches, InstallSchemaMigration/ImportDataMigration had been independently rewritten to create the already-renamed (ibexa_*) schema from scratch — instead of replaying the real 4.6→5.0 rename. This meant a project already running 4.6 (with legacy ez* table names) had no actual migration path to 5.0/6.0 via this mechanism, only a fresh-install script.

This PR:

IbexaMigrationComparator orders migrations by getTargetVersion() then getCreationDate(), so TaggedMigrationsRunner replays these correctly both for a fresh 6.0 install (both migrations run) and for an existing 4.6→6.0 upgrade (only the 5.0.0 rename runs; already-applied migrations are skipped via the standard Doctrine Migrations metadata table).

Verification caught two real gaps in the installer's own shipped SQL, both fixed here:

  • A stray FK-backing index (ezcontentclass_attribute_ml_lang_fk) needed renaming, not just the FK constraint itself.
  • An index-name mismatch: the installer script renames to ibexa_content_type_field_definition_ct_id, but the live schema.yaml actually expects ..._ctid (no underscore) — used the live schema as ground truth.

For QA:

Ran both migrations end-to-end against a real SQLite connection and diffed the resulting table/index names against a fresh bin/console ibexa:doctrine:schema:dump-sql src/bundle/Core/Resources/config/storage/legacy/schema.yaml --force-platform=sqlite — they match exactly.

To verify manually: set ibexa.installer.schema_builder_event.enabled: false, run ibexa:install, and confirm the resulting schema matches an install with the flag left at its default true.

Documentation:

N/A — internal installer implementation detail.

@Steveb-p Steveb-p changed the title IBX-11939: [Doctrine Migrations] Fixed schema rename migration to replay 4.6→5.0 history IBX-11939: [Doctrine Migrations] Added Doctrine Migrations-based schema and data install path (inlined SQL) Jul 21, 2026
@Steveb-p
Steveb-p force-pushed the feature/fix-schema-rename-migration-5.0-postgres branch 2 times, most recently from 2e5073b to be5d0a0 Compare July 24, 2026 11:37
@Steveb-p
Steveb-p changed the base branch from 5.0 to base/ibx-11939-4.6-merged-5.0 July 24, 2026 11:37
@Steveb-p
Steveb-p marked this pull request as ready for review July 24, 2026 12:14
Steveb-p added a commit that referenced this pull request Jul 28, 2026
…for PR #787)

# Conflicts:
#	composer.json
#	phpstan-baseline.neon
#	src/bundle/RepositoryInstaller/Command/InstallPlatformCommand.php
#	src/bundle/RepositoryInstaller/DependencyInjection/Compiler/InstallerTagPass.php
#	src/bundle/RepositoryInstaller/Installer/CoreInstaller.php
#	tests/bundle/RepositoryInstaller/DependencyInjection/Compiler/InstallerTagPassTest.php
#	tests/bundle/RepositoryInstaller/DependencyInjection/IbexaInstallerExtensionTest.php
#	tests/bundle/RepositoryInstaller/IbexaRepositoryInstallerBundleTest.php
@Steveb-p
Steveb-p force-pushed the base/ibx-11939-4.6-merged-5.0 branch from 4e1d96a to 42fc503 Compare July 28, 2026 14:51
@Steveb-p
Steveb-p force-pushed the feature/fix-schema-rename-migration-5.0-postgres branch from 648a27c to 402fbc2 Compare July 28, 2026 16:28
@sonarqubecloud

Copy link
Copy Markdown

@Steveb-p
Steveb-p force-pushed the base/ibx-11939-4.6-merged-5.0 branch from d071e3d to ecc0e95 Compare September 18, 2026 23:09
@Steveb-p
Steveb-p force-pushed the feature/fix-schema-rename-migration-5.0-postgres branch from 58bc2fb to b9778ac Compare September 18, 2026 23:11
Steveb-p added a commit that referenced this pull request Sep 25, 2026
@Steveb-p
Steveb-p force-pushed the base/ibx-11939-4.6-merged-5.0 branch from aeecd6f to efe6338 Compare September 25, 2026 16:16
@Steveb-p
Steveb-p force-pushed the feature/fix-schema-rename-migration-5.0-postgres branch from a1d6729 to 3e897ff Compare September 25, 2026 16:16
…ma and data install path (inlined SQL)

Rebuilt as a single commit on the refreshed base; replaces these 2 commits:

- IBX-11939: [Doctrine Migrations] Added the 5.0 schema rename and legacy identifier migrations
- IBX-11939: Removed the deprecated InstallerTagPass
Uses 5.0's readonly class / promoted constructor style, passes array_values() of the foreign key
columns (DBAL 4 requires a list), and the test uses APIs present in both DBAL 3 and 4
(getCreateTablesSQL(), connection-provided SQLite platform) with XSD validation enabled, so it
carries over to 6.0 unchanged.
…Command

#785 replaced InstallerTagPass with a !tagged_locator for the command's $installers argument,
and both of those reached this branch through the base - but InstallPlatformCommand kept 5.0's
array-typed constructor, so ibexa:install failed with a TypeError before doing anything. Ported
the matching change from #785: ServiceLocator in, has()/get() for the lookup, and
getProvidedServices() for listing the available types.
Declares the installers ServiceLocator's value type on the constructor, drops the baseline
entry for the old array-typed parameter, and removes a stray blank line in CoreInstaller that
the code style check flagged.
…on_ml's language FK

The 5.0 rename replaced the ezcontentclass_attribute_ml_lang_fk foreign key, but on MySQL and
PostgreSQL the index behind it kept its old name - MySQL reuses the leftover index for the new
constraint, and PostgreSQL's was created explicitly by the install schema. schema.yaml expects
ibexa_content_type_field_definition_ml_lang_fk for both. SQLite already dropped and recreated it.
DBAL 3 no longer includes the SQL in its exception message, so the runner now
takes it from DriverException::getQuery() and puts it in its own message.
doctrine-migrations 5.0 takes SqlPlatform now, so the migrations that only exist on this
branch list SqlPlatform::MARIADB and run their MySQL SQL there too, like the ones from 4.6.
@Steveb-p
Steveb-p force-pushed the base/ibx-11939-4.6-merged-5.0 branch from f801939 to fbac366 Compare October 5, 2026 12:31
@Steveb-p
Steveb-p force-pushed the feature/fix-schema-rename-migration-5.0-postgres branch from 7d77111 to 4ac802f Compare October 5, 2026 12:31
…XT on MariaDB

On MariaDB, 4.6's InstallSchemaMigration creates JSON columns as LONGTEXT, as Doctrine DBAL 2.13
does, and 5.0's creates them as JSON, as DBAL 3 does: MariaDB stores that as LONGTEXT in
utf8mb4_bin, with a json_valid() check. It's the same migration, so it doesn't run again on a 4.6
database upgraded to 5.0, and those columns kept their 4.6 form. ConvertMariaDbJsonColumnsMigration
converts them. It skips columns that already have the check, so a fresh 5.0 install is unaffected.

ibexa/installer's 4.6 to 5.0 upgrade script doesn't convert these columns either. A database
upgraded through it gets them converted once it runs the Doctrine Migrations.
The column definitions were a constant in the migration class, and the
statements were built in PHP. They're plain SQL in sql/ now, so they can be
read or run by hand; the class only checks whether the last column is
converted yet and loads the file if it isn't.
@sonarqubecloud

sonarqubecloud Bot commented Oct 6, 2026

Copy link
Copy Markdown

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant