Skip to content

IBX-12603: Resolved Ibexa DB platform when generating test database schema - #52

Merged
alongosz merged 3 commits into
6.0from
ibx-12603-sqlite-composite-pk
Sep 15, 2026
Merged

alongosz merged 3 commits into
6.0from
ibx-12603-sqlite-composite-pk

Conversation

@alongosz

@alongosz alongosz commented Sep 15, 2026

Copy link
Copy Markdown
Member
🎫 Issue IBX-12603

Related PRs:

Description:

DatabaseSchemaHook generates DDL with $connection->getDatabasePlatform(), which since the DBAL 4 upgrade returns vanilla Doctrine\DBAL\Platforms\SQLitePlatform instead of our SqliteDbPlatform. Vanilla SQLitePlatform drops the table-level PRIMARY KEY (...) clause as soon as a table has an autoincrement column, so composite keys silently degrade to a single column:

SQLitePlatform:   CREATE TABLE ibexa_content_field (id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, version ...)
SqliteDbPlatform: CREATE TABLE ibexa_content_field (id INTEGER NOT NULL, version ..., PRIMARY KEY (id, version))

ibexa_content_field is keyed on (id, version), one row per content version, so the fixture repeats id on purpose and the import dies in bootstrap with UNIQUE constraint failed: ibexa_content_field.id. ibexa_content_type and ibexa_content_type_field_definition lose their (id, status) key the same way. This is what makes ibexa/core 6.0 red: run 34885080403.

SQLite only, 6.0 only. It took two changes to get here:

  • Resolved the platform via DbPlatformFactoryInterface instead of taking it off the connection, the same way CoreInstaller and LegacySchemaImporter already do
  • [Tests] Added DatabaseSchemaHookTest - builds a schema shaped like ibexa_content_field and asserts the emitted DDL keeps PRIMARY KEY (id, version). Confirmed it fails against the previous code.
  • [CS] Overrode php_unit_test_case_static_method_calls for createStub only - it is not static in PHPUnit 9, so $this-> is the accurate form and PHPStorm flags self::. Bumped ibexa/code-style to ~2.3.0 while at it.
  • 🟢 composer integration on ibexa/core 6.0 with this branch symlinked in: legacy suite 11417 tests green, phpunit-integration.xml 79 tests green (was dying in bootstrap)
  • 🟢 composer check-cs, composer test, composer phpstan green here

The test is deliberately a tripwire for the note below rather than broad coverage - it fails if this call site ever goes back to the connection's platform. Real integration coverage of SqliteDbPlatform DDL generation belongs in ibexa/doctrine-schema, not here.

Note

ibexa/doctrine-schema#49 moves this call site onto a new SchemaApplier, which carries the same $connection->getDatabasePlatform(), plus Connection::getSchemaManager() and getDropTableSQL(Table) - both gone in DBAL 4. That chain is based on 4.6, so all three need handling when it merges up into 6.0, otherwise this comes back.

For QA:

No QA required. CI covers it:

Documentation:

No documentation required.

🤖 Generated with Claude Code

DatabaseSchemaHook generated DDL with $connection->getDatabasePlatform(),
which returns vanilla Doctrine SQLitePlatform. That platform drops the
table-level PRIMARY KEY clause whenever a table has an autoincrement
column, so composite keys degraded to a single column and fixture import
failed on ibexa_content_field(id, version).

DBAL 4 removed doctrine-bundle's platform_service, so the connection no
longer carries Ibexa's platform subclasses. Resolve them explicitly via
DbPlatformFactoryInterface, the same way CoreInstaller and
LegacySchemaImporter already do.

Affects 6.0 only. 4.6 and 5.0 are on DBAL 3 and still wire
platform_service.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
alongosz added a commit to ibexa/core that referenced this pull request Sep 15, 2026
6.0 integration test bootstrap fails on SQLite because DatabaseSchemaHook
generates DDL with the vanilla Doctrine platform, losing composite primary
keys. The fix lives in ibexa/test-core, nothing in this repository changes.

dependencies.json makes CI install that branch, so the fix can be proven
here before it merges. Generated with ci dependencies:link, must be dropped
once ibexa/test-core#52 is merged.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
alongosz and others added 2 commits September 15, 2026 14:15
Builds a schema with a composite primary key over an autoincrement column,
the shape ibexa_content_field has, and asserts the emitted DDL keeps
PRIMARY KEY (id, version). Fails against the previous code, which took the
platform off the connection.

This is the guard for the SchemaApplier work on 4.6: if that call site goes
back to $connection->getDatabasePlatform() when the chain merges up, this
test fails instead of the bug returning silently.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
php_unit_test_case_static_method_calls rewrites $this->createStub() to
self::, which contradicts PHPStorm's EA inspection. createStub is a
non-static method in PHPUnit 9, so $this-> is the accurate form here. The
fixer matches on method name across PHPUnit versions and assumes PHPUnit 10+,
where createStub did become static, hence the disagreement.

Overriding the call type for that one method keeps the rest of the suite on
self::. Revisit when moving to PHPUnit 10+, where the override stops being
correct.

Bumped ibexa/code-style to ~2.3.0 while at it.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Comment thread .php-cs-fixer.php
'inline_constructor_arguments' => false,
],
'php_unit_test_case_static_method_calls' => ['call_type' => 'self'],
'php_unit_test_case_static_method_calls' => ['call_type' => 'self', 'methods' => ['createStub' => 'this']],

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note

Well... That fixer is of... questionable quality. It hard-codes list of method it thinks should be static rather than inferring from the installed source (maybe can't?). PHPUnit methods' signatures change across different PHPUnit version. Right now createStub is not static (PHPUnit 9).

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe that should be delegated to phpstan? tbh, fixer saying that something is static or not seems kinda too much.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe that should be delegated to phpstan? tbh, fixer saying that something is static or not seems kinda too much.

Yeah, not sure why it was enabled here. It belongs to the @PhpCsFixer:risky rule set, not enabled by default.
I can drop it completely.

POV ping @Steveb-p

Comment thread composer.json
"require-dev": {
"phpunit/phpunit": "^9",
"ibexa/code-style": "^2.0",
"ibexa/code-style": "~2.3.0",

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bumped while at it, causes no CS drifts.

Comment thread .php-cs-fixer.php
'inline_constructor_arguments' => false,
],
'php_unit_test_case_static_method_calls' => ['call_type' => 'self'],
'php_unit_test_case_static_method_calls' => ['call_type' => 'self', 'methods' => ['createStub' => 'this']],

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe that should be delegated to phpstan? tbh, fixer saying that something is static or not seems kinda too much.

@Steveb-p Steveb-p left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good enough to unblock.

@alongosz
alongosz merged commit d78ca95 into 6.0 Sep 15, 2026
18 checks passed
@alongosz
alongosz deleted the ibx-12603-sqlite-composite-pk branch September 15, 2026 12:59
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants