Problem

  1. Trying to swap out an entity type implementation. (FWIW, User)
  2. I can easily swap out the entity type's storage controller (entirely).
  3. But the entire entity system and default DatabaseStorageController is still based on hook_schema() column definitions...?
  4. I'm stuck in determining what actually needs to be swapped out and/or altered — but hook_schema_alter() totally feels like an alien in D8.

Proposed solution

  1. Declare the database schema columns of an entity type in its storage controller (or entity info).
  2. Remove entity info's dependency on hook_schema() (entirely).

Comments

sun’s picture

WOWZA. Worse:

The entity base table SQL columns are keyed by numeric indexes:

  ["schema_fields_sql"]=> array(

    ["base_table"]=> array(
      [0]=> string(3) "uid"
      [1]=> string(4) "uuid"
      [2]=> string(4) "name"
      [3]=> string(8) "langcode"
...

...which leaves me with this fancy hack:

  public function __construct($entity_type) {
    parent::__construct($entity_type);

    $columns = &$this->entityInfo['schema_fields_sql']['base_table'];
    $columns = array_combine($columns, $columns);
    unset($columns['uuid']);
    unset($columns['langcode']);
    unset($columns['signature']);
    unset($columns['signature_format']);
    unset($columns['preferred_langcode']);
    unset($columns['preferred_admin_langcode']);
  }
plach’s picture

I am not sure this has been discussed explicitly anywhere on d.o. but I think the plan is definitely to query entities based on field definitions. The following issues should help with this, but I guess completing the NG conversion should help too.

#1893772: Move entity-type specific storage logic into entity classes
#1498720: [meta] Make the entity storage system handle changes in the entity and field schema definitions

sun’s picture

FWIW, further investigation showed that the corresponding EntityStorageController::save() operations are still using drupal_write_record(). drupal_write_record() completely relies on hook_schema().

So the current code is actually inconsistent on two fronts:

1) load() / buildQuery() uses the prepared SQL schema information, as prepared in entity info.

2) save() uses the literal information from hook_schema().

At minimum, only one of both, plz. ;-)

sun’s picture

Crell’s picture

I fully support moving Entity API to not rely on hook_schema() at all, and eliminating drupal_write_record() entirely.

fago’s picture

I fully support moving Entity API to not rely on hook_schema() at all, and eliminating drupal_write_record() entirely.

I can second that. However, I'd not say it's evil if the DatabaseStorageController relies on hook_schema(). As the controller is tight to the database, it's fine for it. Still, I'd prefer to see it working solely from field definitions.

Paul B’s picture

In DatabaseStorageController it's still using drupal_write_record() even though the class has a database field and starts a transaction in that field?
I guess I can't use that to store entities in a external database? Will this be fixed before Drupal 8 is finalized?

Paul B’s picture

Issue summary: View changes

Updated issue summary.

sun’s picture

plach’s picture

Status: Active » Fixed

This is actively being addressed in #2183231: Make ContentEntityDatabaseStorage generate static database schemas for content entities now. I guess we can call this fixed :)

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.