Problem/Motivation

Schema::addField() and ::changeField() are a bit weird in the sense that they require in input parts of the schema definition, duplicating information that is already present in the schema definition itself. With the new SchemaDefinition structure, we could just pass the target structure and determine the operations needed.

Proposed resolution

Introduce two new methods to Schema:

  • addTableColumnFromDefinition(SchemaDefinition $targetSchema, string $tableName, string $targetColumnName, ?Expression $initializationExpression = NULL): void
  • changeTableColumnFromDefinition(SchemaDefinition $targetSchema, string $tableName, string $targetColumnName, ?string $currentColumnName = NULL): void

Also do some additional ancillary changes:

  • Support an initialization SQL expression when adding a column, useful for populating existing rows.
  • Automatically handle dropping and rebuilding of indexes, unique keys, and primary keys affected by column addtion/changes.
  • Add ::columnNames() helpers to Table and KeyBase.
  • Strengthen Table validation to ensure keys reference existing columns.
  • Add Schema::uniqueKeyExists() to the schema API, filling a surprising gap.
  • Improve PostgreSQL handling of transformed index/constraint names.
  • Add MySQL handling for failures when dropping primary keys.
  • Adjust SQLite table rebuild logic to preserve keys/indexes.

And add relative tests.

In the future, these methods could potentially replace :addField() and ::changeField() once all the conversions to SchemaDefinition will have been made.

Remaining tasks

User interface changes

Introduced terminology

API changes

Data model changes

Release notes snippet

Issue fork drupal-3620121

Command icon Show commands

Start within a Git clone of the project using the version control instructions.

Or, if you do not have SSH keys set up on git.drupalcode.org:

Comments

mondrake created an issue. See original summary.

mondrake’s picture

Status: Active » Needs review
mondrake’s picture

Category: Task » Feature request
mondrake’s picture

Issue summary: View changes

Used a bit of AI to summarize the changes and updated the proposed resultion in the IS accordingly. The MR is all human brain, though.

mondrake’s picture

Issue summary: View changes
amateescu’s picture

Status: Needs review » Needs work

Posted a comment on the MR which is a hard blocker, so I haven't reviewed past it.

mondrake’s picture

Status: Needs work » Needs review

Can you make an example? In my (maybe simplistic, ok) view, the target schema is the lighthouse: we need to get there. ‘How’ we get there and the intermediate states are implementation details. So with a case we can discuss what the solution could be?

mondrake’s picture

Gotcha. It's about the intermediate state between update functions, i.e. the schema version. If we just rely on the latest version, update functions that change between earlier versions will not have the data. I think at this point we could have versioned schema definitions too; it would be a bit verbose but we would also have all the intermediate versions clearly described, which is a bonus, to me.

mondrake’s picture

Made the simplest change I could think of

mondrake’s picture

Let's revert the changes to the update function from here. I've filed #3621166: Introduce a VersionedSchema object to hold multiple versions of a database Schema to enable schema versioning.

mondrake’s picture

Assigned: mondrake » Unassigned
Status: Needs work » Needs review
mondrake’s picture