Issue #2209049 by tstoeckler, lokapujya: Allow field schemas to contain unique keys.
parent
f43fb5918c
commit
c63692f769
|
@ -1454,6 +1454,14 @@ class ContentEntityDatabaseStorage extends ContentEntityStorageBase implements S
|
|||
$current['fields'][$real_name] = $attributes;
|
||||
}
|
||||
|
||||
// Add unique keys.
|
||||
foreach ($schema['unique keys'] as $unique_key_name => $columns) {
|
||||
$real_name = static::_fieldIndexName($field, $unique_key_name);
|
||||
foreach ($columns as $column_name) {
|
||||
$current['unique keys'][$real_name][] = static::_fieldColumnName($field, $column_name);
|
||||
}
|
||||
}
|
||||
|
||||
// Add indexes.
|
||||
foreach ($schema['indexes'] as $index_name => $columns) {
|
||||
$real_name = static::_fieldIndexName($field, $index_name);
|
||||
|
|
|
@ -325,13 +325,6 @@ class ContentEntitySchemaHandler implements EntitySchemaHandlerInterface {
|
|||
'foreign keys' => array(),
|
||||
);
|
||||
|
||||
if ($this->entityType->hasKey('uuid')) {
|
||||
$uuid_key = $this->entityType->getKey('uuid');
|
||||
$schema['unique keys'] = array(
|
||||
$this->getEntityIndexName($uuid_key) => array($uuid_key),
|
||||
);
|
||||
}
|
||||
|
||||
if ($this->entityType->hasKey('revision')) {
|
||||
$revision_key = $this->entityType->getKey('revision');
|
||||
$key_name = $this->getEntityIndexName($revision_key);
|
||||
|
@ -342,6 +335,8 @@ class ContentEntitySchemaHandler implements EntitySchemaHandlerInterface {
|
|||
);
|
||||
}
|
||||
|
||||
$this->addTableDefaults($schema);
|
||||
|
||||
return $schema;
|
||||
}
|
||||
|
||||
|
@ -370,6 +365,8 @@ class ContentEntitySchemaHandler implements EntitySchemaHandlerInterface {
|
|||
|
||||
$schema['indexes'][$this->getEntityIndexName($id_key)] = array($id_key);
|
||||
|
||||
$this->addTableDefaults($schema);
|
||||
|
||||
return $schema;
|
||||
}
|
||||
|
||||
|
@ -402,6 +399,8 @@ class ContentEntitySchemaHandler implements EntitySchemaHandlerInterface {
|
|||
$schema['indexes'][$this->getEntityIndexName($key)] = array($key);
|
||||
}
|
||||
|
||||
$this->addTableDefaults($schema);
|
||||
|
||||
return $schema;
|
||||
}
|
||||
|
||||
|
@ -434,9 +433,26 @@ class ContentEntitySchemaHandler implements EntitySchemaHandlerInterface {
|
|||
),
|
||||
);
|
||||
|
||||
$this->addTableDefaults($schema);
|
||||
|
||||
return $schema;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds defaults to a table schema definition.
|
||||
*
|
||||
* @param $schema
|
||||
* The schema definition array for a single table, passed by reference.
|
||||
*/
|
||||
protected function addTableDefaults(&$schema) {
|
||||
$schema += array(
|
||||
'fields' => array(),
|
||||
'unique keys' => array(),
|
||||
'indexes' => array(),
|
||||
'foreign keys' => array(),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Processes the gathered schema for a base table.
|
||||
*
|
||||
|
|
|
@ -480,6 +480,7 @@ class FieldDefinition extends ListDataDefinition implements FieldDefinitionInter
|
|||
// Fill in default values.
|
||||
$schema += array(
|
||||
'columns' => array(),
|
||||
'unique keys' => array(),
|
||||
'indexes' => array(),
|
||||
'foreign keys' => array(),
|
||||
);
|
||||
|
|
|
@ -69,6 +69,8 @@ interface FieldItemInterface extends ComplexDataInterface {
|
|||
* definitions depend on field settings when possible. No assumptions
|
||||
* should be made on how storage engines internally use the original
|
||||
* column name to structure their storage.
|
||||
* - unique keys: (optional) An array of Schema API unique key definitions.
|
||||
* Only columns that appear in the 'columns' array are allowed.
|
||||
* - indexes: (optional) An array of Schema API index definitions. Only
|
||||
* columns that appear in the 'columns' array are allowed. Those indexes
|
||||
* will be used as default indexes. Callers of field_create_field() can
|
||||
|
|
|
@ -7,6 +7,8 @@
|
|||
|
||||
namespace Drupal\Core\Field\Plugin\Field\FieldType;
|
||||
|
||||
use Drupal\Core\Field\FieldStorageDefinitionInterface;
|
||||
|
||||
/**
|
||||
* Defines the 'uuid' entity field type.
|
||||
*
|
||||
|
@ -39,4 +41,14 @@ class UuidItem extends StringItem {
|
|||
$this->setValue(array('value' => $uuid->generate()), $notify);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static function schema(FieldStorageDefinitionInterface $field_definition) {
|
||||
$schema = parent::schema($field_definition);
|
||||
$schema['unique keys']['value'] = array('value');
|
||||
return $schema;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -456,7 +456,11 @@ class FieldConfig extends ConfigEntityBase implements FieldConfigInterface {
|
|||
$class = $this->getFieldItemClass();
|
||||
$schema = $class::schema($this);
|
||||
// Fill in default values for optional entries.
|
||||
$schema += array('indexes' => array(), 'foreign keys' => array());
|
||||
$schema += array(
|
||||
'unique keys' => array(),
|
||||
'indexes' => array(),
|
||||
'foreign keys' => array(),
|
||||
);
|
||||
|
||||
// Check that the schema does not include forbidden column names.
|
||||
if (array_intersect(array_keys($schema['columns']), static::getReservedColumns())) {
|
||||
|
|
|
@ -94,6 +94,7 @@ class TestItemTest extends FieldUnitTestBase {
|
|||
'not null' => FALSE,
|
||||
),
|
||||
),
|
||||
'unique keys' => array(),
|
||||
'indexes' => array(
|
||||
'value' => array('value'),
|
||||
),
|
||||
|
|
|
@ -291,6 +291,7 @@ class ContentEntityDatabaseStorageTest extends UnitTestCase {
|
|||
),
|
||||
),
|
||||
'primary key' => array('id'),
|
||||
'unique keys' => array(),
|
||||
'indexes' => array(),
|
||||
'foreign keys' => array(),
|
||||
),
|
||||
|
@ -973,6 +974,7 @@ class ContentEntityDatabaseStorageTest extends UnitTestCase {
|
|||
'not null' => FALSE,
|
||||
),
|
||||
),
|
||||
'unique keys' => array(),
|
||||
'indexes' => array(),
|
||||
'foreign keys' => array(),
|
||||
);
|
||||
|
|
|
@ -95,13 +95,11 @@ class ContentEntitySchemaHandlerTest extends UnitTestCase {
|
|||
/**
|
||||
* Tests the schema for non-revisionable, non-translatable entities.
|
||||
*
|
||||
* @param bool $uuid_key
|
||||
* Whether or not the tested entity type should have a UUID key.
|
||||
*
|
||||
* @covers ::__construct()
|
||||
* @covers ::getSchema()
|
||||
* @covers ::getTables()
|
||||
* @covers ::initializeBaseTable()
|
||||
* @covers ::addTableDefaults()
|
||||
* @covers ::getEntityIndexName()
|
||||
* @covers ::addFieldSchema()
|
||||
* @covers ::getFieldIndexes()
|
||||
|
@ -111,16 +109,11 @@ class ContentEntitySchemaHandlerTest extends UnitTestCase {
|
|||
* @covers ::addDefaultLangcodeSchema()
|
||||
* @covers ::processBaseTable()
|
||||
* @covers ::processIdentifierSchema()
|
||||
*
|
||||
* @dataProvider providerTestGetSchemaLayoutBase
|
||||
*/
|
||||
public function testGetSchemaBase($uuid_key) {
|
||||
public function testGetSchemaBase() {
|
||||
$this->entityType = new ContentEntityType(array(
|
||||
'id' => 'entity_test',
|
||||
'entity_keys' => array(
|
||||
'id' => 'id',
|
||||
'uuid' => $uuid_key ? 'uuid' : NULL,
|
||||
),
|
||||
'entity_keys' => array('id' => 'id'),
|
||||
));
|
||||
|
||||
// Add a field with a 'length' constraint.
|
||||
|
@ -132,16 +125,6 @@ class ContentEntitySchemaHandlerTest extends UnitTestCase {
|
|||
),
|
||||
),
|
||||
));
|
||||
if ($uuid_key) {
|
||||
$this->setUpStorageDefinition('uuid', array(
|
||||
'columns' => array(
|
||||
'value' => array(
|
||||
'type' => 'varchar',
|
||||
'length' => 128,
|
||||
),
|
||||
),
|
||||
));
|
||||
}
|
||||
// Add a multi-column field.
|
||||
$this->setUpStorageDefinition('description', array(
|
||||
'columns' => array(
|
||||
|
@ -155,11 +138,51 @@ class ContentEntitySchemaHandlerTest extends UnitTestCase {
|
|||
),
|
||||
),
|
||||
));
|
||||
// Add a field with a unique key.
|
||||
$this->setUpStorageDefinition('uuid', array(
|
||||
'columns' => array(
|
||||
'value' => array(
|
||||
'type' => 'varchar',
|
||||
'length' => 128,
|
||||
),
|
||||
),
|
||||
'unique keys' => array(
|
||||
'value' => array('value'),
|
||||
),
|
||||
));
|
||||
// Add a field with a unique key, specified as column name and length.
|
||||
$this->setUpStorageDefinition('hash', array(
|
||||
'columns' => array(
|
||||
'value' => array(
|
||||
'type' => 'varchar',
|
||||
'length' => 20,
|
||||
),
|
||||
),
|
||||
'unique keys' => array(
|
||||
'value' => array(array('value', 10)),
|
||||
),
|
||||
));
|
||||
// Add a field with a multi-column unique key.
|
||||
$this->setUpStorageDefinition('email', array(
|
||||
'columns' => array(
|
||||
'username' => array(
|
||||
'type' => 'varchar',
|
||||
),
|
||||
'hostname' => array(
|
||||
'type' => 'varchar',
|
||||
),
|
||||
'domain' => array(
|
||||
'type' => 'varchar',
|
||||
)
|
||||
),
|
||||
'unique keys' => array(
|
||||
'email' => array('username', 'hostname', array('domain', 3)),
|
||||
),
|
||||
));
|
||||
// Add a field with an index.
|
||||
$this->setUpStorageDefinition('owner', array(
|
||||
'columns' => array(
|
||||
'target_id' => array(
|
||||
'description' => 'The ID of the target entity.',
|
||||
'type' => 'int',
|
||||
),
|
||||
),
|
||||
|
@ -171,7 +194,6 @@ class ContentEntitySchemaHandlerTest extends UnitTestCase {
|
|||
$this->setUpStorageDefinition('translator', array(
|
||||
'columns' => array(
|
||||
'target_id' => array(
|
||||
'description' => 'The ID of the target entity.',
|
||||
'type' => 'int',
|
||||
),
|
||||
),
|
||||
|
@ -260,6 +282,28 @@ class ContentEntitySchemaHandlerTest extends UnitTestCase {
|
|||
'description' => 'The description field.',
|
||||
'type' => 'varchar',
|
||||
),
|
||||
'uuid' => array(
|
||||
'description' => 'The uuid field.',
|
||||
'type' => 'varchar',
|
||||
'length' => 128,
|
||||
),
|
||||
'hash' => array(
|
||||
'description' => 'The hash field.',
|
||||
'type' => 'varchar',
|
||||
'length' => 20,
|
||||
),
|
||||
'email__username' => array(
|
||||
'description' => 'The email field.',
|
||||
'type' => 'varchar',
|
||||
),
|
||||
'email__hostname' => array(
|
||||
'description' => 'The email field.',
|
||||
'type' => 'varchar',
|
||||
),
|
||||
'email__domain' => array(
|
||||
'description' => 'The email field.',
|
||||
'type' => 'varchar',
|
||||
),
|
||||
'owner' => array(
|
||||
'description' => 'The owner field.',
|
||||
'type' => 'int',
|
||||
|
@ -301,6 +345,15 @@ class ContentEntitySchemaHandlerTest extends UnitTestCase {
|
|||
),
|
||||
),
|
||||
'primary key' => array('id'),
|
||||
'unique keys' => array(
|
||||
'entity_test_field__uuid__value' => array('uuid'),
|
||||
'entity_test_field__hash__value' => array(array('hash', 10)),
|
||||
'entity_test_field__email__email' => array(
|
||||
'email__username',
|
||||
'email__hostname',
|
||||
array('email__domain', 3),
|
||||
),
|
||||
),
|
||||
'indexes' => array(
|
||||
'entity_test_field__owner__target_id' => array('owner'),
|
||||
'entity_test_field__translator__target_id' => array(
|
||||
|
@ -324,35 +377,11 @@ class ContentEntitySchemaHandlerTest extends UnitTestCase {
|
|||
),
|
||||
),
|
||||
);
|
||||
if ($uuid_key) {
|
||||
$expected['entity_test']['fields']['uuid'] = array(
|
||||
'type' => 'varchar',
|
||||
'length' => 128,
|
||||
'description' => 'The uuid field.',
|
||||
'not null' => TRUE,
|
||||
);
|
||||
$expected['entity_test']['unique keys']['entity_test__uuid'] = array('uuid');
|
||||
}
|
||||
$actual = $this->schemaHandler->getSchema();
|
||||
|
||||
$this->assertEquals($expected, $actual);
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides data for testGetSchemaLayoutBase().
|
||||
*
|
||||
* @return array
|
||||
* Returns a nested array where each inner array returns a boolean,
|
||||
* indicating whether or not the tested entity type should include a UUID
|
||||
* key.
|
||||
*/
|
||||
public function providerTestGetSchemaLayoutBase() {
|
||||
return array(
|
||||
array(FALSE),
|
||||
array(TRUE),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the schema for revisionable, non-translatable entities.
|
||||
*
|
||||
|
@ -361,6 +390,7 @@ class ContentEntitySchemaHandlerTest extends UnitTestCase {
|
|||
* @covers ::getTables()
|
||||
* @covers ::initializeBaseTable()
|
||||
* @covers ::initializeRevisionTable()
|
||||
* @covers ::addTableDefaults()
|
||||
* @covers ::getEntityIndexName()
|
||||
* @covers ::processRevisionTable()
|
||||
* @covers ::processIdentifierSchema()
|
||||
|
@ -411,6 +441,9 @@ class ContentEntitySchemaHandlerTest extends UnitTestCase {
|
|||
)
|
||||
),
|
||||
'primary key' => array('id'),
|
||||
'unique keys' => array(
|
||||
'entity_test__revision_id' => array('revision_id'),
|
||||
),
|
||||
'indexes' => array(),
|
||||
'foreign keys' => array(
|
||||
'entity_test__revision' => array(
|
||||
|
@ -418,9 +451,6 @@ class ContentEntitySchemaHandlerTest extends UnitTestCase {
|
|||
'columns' => array('revision_id' => 'revision_id'),
|
||||
)
|
||||
),
|
||||
'unique keys' => array(
|
||||
'entity_test__revision_id' => array('revision_id'),
|
||||
),
|
||||
),
|
||||
'entity_test_revision' => array(
|
||||
'description' => 'The revision table for entity_test entities.',
|
||||
|
@ -436,6 +466,7 @@ class ContentEntitySchemaHandlerTest extends UnitTestCase {
|
|||
),
|
||||
),
|
||||
'primary key' => array('revision_id'),
|
||||
'unique keys' => array(),
|
||||
'indexes' => array(
|
||||
'entity_test__id' => array('id'),
|
||||
),
|
||||
|
@ -460,6 +491,7 @@ class ContentEntitySchemaHandlerTest extends UnitTestCase {
|
|||
* @covers ::getSchema()
|
||||
* @covers ::getTables()
|
||||
* @covers ::initializeDataTable()
|
||||
* @covers ::addTableDefaults()
|
||||
* @covers ::getEntityIndexName()
|
||||
* @covers ::processDataTable()
|
||||
*/
|
||||
|
@ -509,6 +541,7 @@ class ContentEntitySchemaHandlerTest extends UnitTestCase {
|
|||
)
|
||||
),
|
||||
'primary key' => array('id'),
|
||||
'unique keys' => array(),
|
||||
'indexes' => array(),
|
||||
'foreign keys' => array(),
|
||||
),
|
||||
|
@ -527,6 +560,7 @@ class ContentEntitySchemaHandlerTest extends UnitTestCase {
|
|||
),
|
||||
),
|
||||
'primary key' => array('id', 'langcode'),
|
||||
'unique keys' => array(),
|
||||
'indexes' => array(),
|
||||
'foreign keys' => array(
|
||||
'entity_test' => array(
|
||||
|
@ -549,6 +583,7 @@ class ContentEntitySchemaHandlerTest extends UnitTestCase {
|
|||
* @covers ::getSchema()
|
||||
* @covers ::getTables()
|
||||
* @covers ::initializeDataTable()
|
||||
* @covers ::addTableDefaults()
|
||||
* @covers ::getEntityIndexName()
|
||||
* @covers ::initializeRevisionDataTable()
|
||||
* @covers ::processRevisionDataTable()
|
||||
|
@ -619,10 +654,10 @@ class ContentEntitySchemaHandlerTest extends UnitTestCase {
|
|||
)
|
||||
),
|
||||
'primary key' => array('id'),
|
||||
'indexes' => array(),
|
||||
'unique keys' => array(
|
||||
'entity_test__revision_id' => array('revision_id'),
|
||||
),
|
||||
'indexes' => array(),
|
||||
'foreign keys' => array(
|
||||
'entity_test__revision' => array(
|
||||
'table' => 'entity_test_revision',
|
||||
|
@ -649,6 +684,7 @@ class ContentEntitySchemaHandlerTest extends UnitTestCase {
|
|||
),
|
||||
),
|
||||
'primary key' => array('revision_id'),
|
||||
'unique keys' => array(),
|
||||
'indexes' => array(
|
||||
'entity_test__id' => array('id'),
|
||||
),
|
||||
|
@ -678,6 +714,7 @@ class ContentEntitySchemaHandlerTest extends UnitTestCase {
|
|||
),
|
||||
),
|
||||
'primary key' => array('id', 'langcode'),
|
||||
'unique keys' => array(),
|
||||
'indexes' => array(
|
||||
'entity_test__revision_id' => array('revision_id'),
|
||||
),
|
||||
|
@ -707,6 +744,7 @@ class ContentEntitySchemaHandlerTest extends UnitTestCase {
|
|||
),
|
||||
),
|
||||
'primary key' => array('revision_id', 'langcode'),
|
||||
'unique keys' => array(),
|
||||
'indexes' => array(),
|
||||
'foreign keys' => array(
|
||||
'entity_test' => array(
|
||||
|
|
Loading…
Reference in New Issue