/**
  * Tests getTableMapping() with a complex entity type with fields.
  *
  * @param string[] $entity_keys
  *   A map of entity keys to use for the mocked entity type.
  *
  * @covers ::__construct()
  * @covers ::getTableMapping()
  *
  * @dataProvider providerTestGetTableMappingSimple()
  */
 public function testGetTableMappingRevisionableTranslatableWithFields(array $entity_keys)
 {
     // This allows to re-use the data provider.
     $entity_keys = array('id' => $entity_keys['id'], 'revision' => 'test_revision', 'bundle' => $entity_keys['bundle'], 'uuid' => $entity_keys['uuid'], 'langcode' => 'langcode');
     // PHPUnit does not allow for multiple data providers.
     $test_cases = array(array(), array('revision_timestamp'), array('revision_uid'), array('revision_log'), array('revision_timestamp', 'revision_uid'), array('revision_timestamp', 'revision_log'), array('revision_uid', 'revision_log'), array('revision_timestamp', 'revision_uid', 'revision_log'));
     foreach ($test_cases as $revision_metadata_field_names) {
         $this->setUp();
         $base_field_names = array('title');
         $field_names = array_merge(array_values(array_filter($entity_keys)), $base_field_names);
         $definition = $this->getMock('Drupal\\Core\\Field\\FieldStorageDefinitionInterface');
         $this->fieldDefinitions = array_fill_keys($field_names, $definition);
         $revisionable_field_names = array('description', 'owner');
         $definition = $this->getMock('Drupal\\Core\\Field\\FieldStorageDefinitionInterface');
         // isRevisionable() is only called once, but we re-use the same definition
         // for all revisionable fields.
         $definition->expects($this->any())->method('isRevisionable')->will($this->returnValue(TRUE));
         $this->fieldDefinitions += array_fill_keys(array_merge($revisionable_field_names, $revision_metadata_field_names), $definition);
         $this->entityType->expects($this->exactly(2))->method('isRevisionable')->will($this->returnValue(TRUE));
         $this->entityType->expects($this->exactly(2))->method('isTranslatable')->will($this->returnValue(TRUE));
         $this->entityType->expects($this->exactly(3))->method('getDataTable')->will($this->returnValue('entity_test_field_data'));
         $this->entityType->expects($this->any())->method('getKey')->will($this->returnValueMap(array(array('id', $entity_keys['id']), array('uuid', $entity_keys['uuid']), array('bundle', $entity_keys['bundle']), array('revision', $entity_keys['revision']))));
         $this->setUpEntityStorage();
         $mapping = $this->entityStorage->getTableMapping();
         $expected = array('entity_test', 'entity_test_field_data', 'entity_test_revision', 'entity_test_field_revision');
         $this->assertEquals($expected, $mapping->getTableNames());
         $expected = array('entity_test', 'entity_test_field_data', 'entity_test_revision', 'entity_test_field_revision');
         $this->assertEquals($expected, $mapping->getTableNames());
         // The language code is not stored on the base table, but on the revision
         // table.
         $expected = array_values(array_filter(array($entity_keys['id'], $entity_keys['revision'], $entity_keys['bundle'], $entity_keys['uuid'])));
         $actual = $mapping->getFieldNames('entity_test');
         $this->assertEquals($expected, $actual);
         // The revision table on the other hand does not store the bundle and the
         // UUID.
         $expected = array_merge(array_filter(array($entity_keys['id'], $entity_keys['revision'], $entity_keys['langcode'])), $revision_metadata_field_names);
         $actual = $mapping->getFieldNames('entity_test_revision');
         $this->assertEquals($expected, $actual);
         // The UUID is not stored on the data table.
         $expected = array_merge(array_filter(array($entity_keys['id'], $entity_keys['revision'], $entity_keys['bundle'], $entity_keys['langcode'])), $base_field_names, $revisionable_field_names);
         $actual = $mapping->getFieldNames('entity_test_field_data');
         $this->assertEquals($expected, $actual);
         // The data revision also does not store the bundle.
         $expected = array_merge(array_filter(array($entity_keys['id'], $entity_keys['revision'], $entity_keys['langcode'])), $revisionable_field_names);
         $actual = $mapping->getFieldNames('entity_test_field_revision');
         $this->assertEquals($expected, $actual);
         $expected = array();
         $actual = $mapping->getExtraColumns('entity_test');
         $this->assertEquals($expected, $actual);
         $actual = $mapping->getExtraColumns('entity_test_revision');
         $this->assertEquals($expected, $actual);
         $expected = array('default_langcode');
         $actual = $mapping->getExtraColumns('entity_test_field_data');
         $this->assertEquals($expected, $actual);
         $actual = $mapping->getExtraColumns('entity_test_field_revision');
         $this->assertEquals($expected, $actual);
     }
 }
 /**
  * {@inheritdoc}
  */
 public function getSchema()
 {
     // Prepare basic information about the entity type.
     $tables = $this->getTables();
     if (!isset($this->schema[$this->entityType->id()])) {
         // Initialize the table schema.
         $schema[$tables['base_table']] = $this->initializeBaseTable();
         if (isset($tables['revision_table'])) {
             $schema[$tables['revision_table']] = $this->initializeRevisionTable();
         }
         if (isset($tables['data_table'])) {
             $schema[$tables['data_table']] = $this->initializeDataTable();
         }
         if (isset($tables['revision_data_table'])) {
             $schema[$tables['revision_data_table']] = $this->initializeRevisionDataTable();
         }
         $table_mapping = $this->storage->getTableMapping();
         foreach ($table_mapping->getTableNames() as $table_name) {
             // Add the schema from field definitions.
             foreach ($table_mapping->getFieldNames($table_name) as $field_name) {
                 $column_names = $table_mapping->getColumnNames($field_name);
                 $this->addFieldSchema($schema[$table_name], $field_name, $column_names);
             }
             // Add the schema for extra fields.
             foreach ($table_mapping->getExtraColumns($table_name) as $column_name) {
                 if ($column_name == 'default_langcode') {
                     $this->addDefaultLangcodeSchema($schema[$table_name]);
                 }
             }
         }
         // Process tables after having gathered field information.
         $this->processBaseTable($schema[$tables['base_table']]);
         if (isset($tables['revision_table'])) {
             $this->processRevisionTable($schema[$tables['revision_table']]);
         }
         if (isset($tables['data_table'])) {
             $this->processDataTable($schema[$tables['data_table']]);
         }
         if (isset($tables['revision_data_table'])) {
             $this->processRevisionDataTable($schema[$tables['revision_data_table']]);
         }
         $this->schema[$this->entityType->id()] = $schema;
     }
     return $this->schema[$this->entityType->id()];
 }