This introduces the Database Schema Definition to replace the current way of defining a table's structure via a nested array, with a structure of value objects defined in the Drupal\Core\Database\SchemaDefinition namespace.
This structure is immutable and database abstract.
In the future, the db-specific field types in the existing array-based schema definition will no longer be defined here and database drivers will be able to implement db-specific features such as GIN and GIST indexes. It will also allow for better introspection of database schema, and validation of properties.
Schema definition changes
Before
$schema = [
'description' => 'The base table for configuration data.',
'fields' => [
'collection' => [
'description' => 'Primary Key: Config object collection.',
'type' => 'varchar_ascii',
'length' => 255,
'not null' => TRUE,
'default' => '',
],
'name' => [
'description' => 'Primary Key: Config object name.',
'type' => 'varchar_ascii',
'length' => 255,
'not null' => TRUE,
'default' => '',
],
'data' => [
'description' => 'A serialized configuration object data.',
'type' => 'blob',
'not null' => FALSE,
'size' => 'big',
],
],
'primary key' => ['collection', 'name'],
];
After
Note the usage of named parameters. In the future, these could allow more flexibility when it comes to adding, changing, deprecating, and removing function arguments.
new Table(
name: 'config',
description: 'The base table for configuration data.',
columns: [
new Column(
name: 'collection',
description: 'Primary Key: Config object collection.',
type: ColumnType::VarcharAscii,
length: 255,
notNull: TRUE,
default: new StringValue(''),
),
new Column(
name: 'name',
description: 'Primary Key: Config object name.',
type: ColumnType::VarcharAscii,
length: 255,
notNull: TRUE,
default: new StringValue(''),
),
new Column(
name: 'data',
description: 'A serialized configuration object data.',
type: ColumnType::Blob,
notNull: FALSE,
size: ColumnSize::Big,
),
],
primaryKey: new PrimaryKey(['collection', 'name']),
);
hook_schema() changes
Refer to database.api.php for a full example.
Before
/**
* Implements hook_schema().
*/
function system_schema(): array {
$schema['my_table'] = [
...
];
return $schema;
}
After
/**
* Implements hook_schema().
*/
function system_schema(): Schema {
$tables[] = new Table(
name: 'my_table',
...
);
return new Schema(
type: SchemaDefinitionType::Module,
name: 'system',
tables: $tables,
);
}
Storage handlers
Before
/**
* Check if the table exists and create it if not.
*/
protected function ensureTableExists() {
try {
$database_schema = $this->connection->schema();
$schema_definition = $this->schemaDefinition();
$database_schema->createTable(static::TABLE_NAME, $schema_definition);
}
// If another process has already created the batch table, attempting to
// recreate it will throw an exception. In this case just catch the
// exception and do nothing.
catch (DatabaseException) {
}
catch (\Exception) {
return FALSE;
}
return TRUE;
}
public function schemaDefinition() {
return [
...
];
}
After
/**
* Check if the table exists and create it if not.
*/
protected function ensureTableExists() {
try {
$this->connection->schema()->createSchemaFromDefinition($this->schemaDefinition());
}
// If another process has already created the batch table, attempting to
// recreate it will throw an exception. In this case just catch the
// exception and do nothing.
catch (DatabaseException) {
}
catch (\Exception) {
return FALSE;
}
return TRUE;
}
public function schemaDefinition(): Schema {
$tables[] = new Table(
name: 'my_storage_table',
...
);
return new Schema(
type: SchemaDefinitionType::Storage,
name: 'my_storage',
tables: $tables,
);
}