/** * {@inheritdoc} */ public function onFieldStorageDefinitionUpdate(FieldStorageDefinitionInterface $storage_definition, FieldStorageDefinitionInterface $original) { if (!$storage_definition->hasData()) { // There is no data. Re-create the tables completely. if ($this->database->supportsTransactionalDDL()) { // If the database supports transactional DDL, we can go ahead and rely // on it. If not, we will have to rollback manually if something fails. $transaction = $this->database->startTransaction(); } try { $original_schema = $this->_fieldSqlSchema($original); foreach ($original_schema as $name => $table) { $this->database->schema()->dropTable($name, $table); } $schema = $this->_fieldSqlSchema($storage_definition); foreach ($schema as $name => $table) { $this->database->schema()->createTable($name, $table); } } catch (\Exception $e) { if ($this->database->supportsTransactionalDDL()) { $transaction->rollback(); } else { // Recreate tables. $original_schema = $this->_fieldSqlSchema($original); foreach ($original_schema as $name => $table) { if (!$this->database->schema()->tableExists($name)) { $this->database->schema()->createTable($name, $table); } } } throw $e; } } else { if ($storage_definition->getColumns() != $original->getColumns()) { throw new FieldStorageDefinitionUpdateForbiddenException("The SQL storage cannot change the schema for an existing field with data."); } // There is data, so there are no column changes. Drop all the prior // indexes and create all the new ones, except for all the priors that // exist unchanged. $table = static::_fieldTableName($original); $revision_table = static::_fieldRevisionTableName($original); $schema = $storage_definition->getSchema(); $original_schema = $original->getSchema(); foreach ($original_schema['indexes'] as $name => $columns) { if (!isset($schema['indexes'][$name]) || $columns != $schema['indexes'][$name]) { $real_name = static::_fieldIndexName($storage_definition, $name); $this->database->schema()->dropIndex($table, $real_name); $this->database->schema()->dropIndex($revision_table, $real_name); } } $table = static::_fieldTableName($storage_definition); $revision_table = static::_fieldRevisionTableName($storage_definition); foreach ($schema['indexes'] as $name => $columns) { if (!isset($original_schema['indexes'][$name]) || $columns != $original_schema['indexes'][$name]) { $real_name = static::_fieldIndexName($storage_definition, $name); $real_columns = array(); foreach ($columns as $column_name) { // Indexes can be specified as either a column name or an array with // column name and length. Allow for either case. if (is_array($column_name)) { $real_columns[] = array(static::_fieldColumnName($storage_definition, $column_name[0]), $column_name[1]); } else { $real_columns[] = static::_fieldColumnName($storage_definition, $column_name); } } $this->database->schema()->addIndex($table, $real_name, $real_columns); $this->database->schema()->addIndex($revision_table, $real_name, $real_columns); } } } }