Change record status: 
Project: 
Introduced in branch: 
8.x
Description: 

Motivation for this change

An entity type's base field definitions are to a large part duplicated in the providing module's hook_schema() implementation. The hook_schema() implementation provides the database schema for the entity type.

Since field items provide their own schema, a module's hook_schema implementation on behalf of the entity type configuration objects that it provides has become unnecessary.

Considerations for developers

  1. Do not include entries in hook_schema() for content entities provided by your module.
  2. The content entity itself can provide base fields by implementing the static baseFieldDefinitions() method of the ContentEntityInterface, for which an according schema is generated.
  3. The generated schema takes translatable and revisionable flags into account, so be sure to set them accordingly on the base field definitions.
  4. Ensure that the schema for fields that your module provides is complete. Implement the static schema() method of the FieldItemInterface.
  5. To specify additional schema information (for example, to add specific indexes or denormalization tables), override getSchema() in your entity storage class extending ContentEntityDatabaseStorage.
  6. Modules relying on the db schema of an entity should migrate to work with field definitions & the table mapping instead.

Handling field/schema changes

API changes

  • Modules shouldn't declare their entity type schemas in hook_schema() anymore. Instead the schema is generated automatically for them.
  • KernelTestBase::installSchema() no longer works for entity tables. Use KernelTestBase::installEntitySchema() instead.

API additions

  • Introduce a TableMappingInterface
  • Introduce a SqlEntityStorageInterface
    • SqlEntityStorageInterface, used for SQL-based entity storages, contains a getTableMapping() method. This method returns a TableMappingInterface object that provides a mapping of field columns to database columns per table of the entity type.
  • EntitySchemaProviderInterface is implemented by ContentEntityDatabaseStorage; thus one can retrieve an entity's db schema via ContentEntityDatabaseStorage::getSchema().
  • EntitySchemaHandlerInterface and ContentEntitySchemaHandler
    • EntitySchemaHandlerInterface extends EntitySchemaProviderInterface. It uses the entity type, the entity type's field definitions (and their respective schema arrays) and the table mapping to generate the full schema array for all of the entity type's schema in a getSchema() method.
    • The getSchema() method of ContentEntityDatabaseStorage simply forwards the call to ContentEntitySchemaHandler, which it lazy-instantiates directly (i.e. using the class name directly)
    • As part of #1498720: [meta] Make the entity storage system handle changes in the entity and field schema definitions the EntitySchemaHandlerInterface and class will be extended to handle schema changes.
  • KernelTestBase::installEntitySchema()

Altered implementations

  • drupal_get_schema()
    • Entity queries and loads are updated to use the table mapping instead of drupal_get_schema().
  • drupal_write_record()
    • Entity saves updated to use the table mapping instead of drupal_write_record().
AttachmentSize
Entity_Schema_1.png123.1 KB
Impacts: 
Module developers
Updates Done (doc team, etc.)
Online documentation: 
Not done
Theming guide: 
Not done
Module developer documentation: 
Not done
Examples project: 
Not done
Coder Review: 
Not done
Coder Upgrade: 
Not done
Other: 
Other updates done

Comments

RoySegall’s picture

So the hook_schema got deprecated? I didn't understood this one.

Anonymous’s picture

RoySegal: no, the hook_schema is still in place. You jsut don'have to write the schema definition for your content entity, if you don't want/need to.

Does this patch take care of reserved words? For example table 'order' vs 'orders'.

plach’s picture

Does this patch take care of reserved words? For example table 'order' vs 'orders'.

No, I don't think so.