Problem/Motivation

The Database Schema API supports defining and managing database tables, but it has no equivalent support for SQL views.

Modules that need an SQL view must currently execute DDL directly and manage database portability, lifecycle, dependencies, and test cleanup themselves.

Core would benefit from this with at least a couple of use cases:

  • Deprecating/renaming database tables. For example, Workspaces would like to rename the workspace_association table to workspace_tracker. BC could be provided for this rename by creating a virtual workspace_association table that matches the data of the new one.
  • After #3343634: Add "json" as core data type to Schema and Database API is done, we can extract data from JSON columns into table structures, for example to match the structure of dedicated entity field tables.

Proposed resolution

Extend the Database Schema API so modules can define, create, discover, replace, and remove SQL views in a database-independent way.

Modules can declare views alongside tables in hook_schema(). Tables are created before their views and views are removed before their underlying tables.

Example:

$views[] = new View(
  name: 'example_active_items',
  query: new ViewQuery(
    'SELECT [id], [label] FROM {example_item} WHERE [active] = 1'
  ),
  description: 'Active example items.',
);

return new Schema(
  type: SchemaDefinitionType::Module,
  name: 'example',
  tables: $tables,
  views: $views,
);

API changes

New schema definition classes:

  • Drupal\Core\Database\SchemaDefinition\View
  • Drupal\Core\Database\SchemaDefinition\ViewQuery

New methods on Drupal\Core\Database\Schema:

public function createView(
  string $name,
  string $query,
  bool $replace = FALSE,
): void;

public function createViewFromDefinition(View $view): void;

public function dropView(string $name): bool;

public function dropViews(array $views): void;

public function viewExists(
  string $name,
  bool $add_prefix = TRUE,
): bool;

public function findViews(string $view_expression): array;

SchemaDefinition\Schema receives a new optional views constructor argument and provides:

  • viewNames()
  • getViewDefinition()

Schema definitions containing views cannot be converted to the legacy array representation because that format has no representation for SQL views.

Data model changes

Modules can create SQL views alongside their tables. No existing table schemas or stored data are changed.

User interface changes

None.

Remaining tasks

  • Review the new API and database-driver implementations.

Release notes snippet

TBD.

Issue fork drupal-3618770

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

amateescu created an issue. See original summary.

amateescu’s picture

Issue summary: View changes
Status: Active » Needs review

Here we go :) A LLM was used to assist with this work.

mondrake’s picture

Nice to see the new Schema Definition API getting traction!

#3557481: Convert hook_schema() implementations to SchemaDefinition - regular modules would probably have to be done first.
#3567335: (experiment) Introduce a registry to store the abstract definitions of the tables created might help in the process of re-creating views without having to look into each db definition tables.

Added some comments inline, NW for some of them

amateescu’s picture

Status: Needs work » Needs review

Thanks for the review, @mondrake! I've addressed most points, and kept only 3 open with my opinion on them.

mondrake’s picture

This is large enough to require subsystem and FM reviews.

mondrake’s picture

What will happen on a created view when we drop/rename a table or a column via schema operations? Do we need to conceive a process so that the view is dropped and rebuilt? I’ve been doing something as such in #3620121: Introduce SchemaDefinition-based alternatives to Schema::addField and ::changeField.

needs-review-queue-bot’s picture

Status: Needs review » Needs work
StatusFileSize
new98 bytes

The Needs Review Queue Bot tested this issue. The merge request has merge conflicts and cannot be merged. Therefore, this issue status is now "Needs work".

This does not mean that the patch necessarily needs to be re-rolled or the MR rebased. Read the Issue Summary, the issue tags and the latest discussion here to determine what needs to be done.

Consult the Drupal Contributor Guide to find step-by-step guides for working with issues.