diff --git a/core/lib/Drupal/Core/Database/Driver/mysql/Schema.php b/core/lib/Drupal/Core/Database/Driver/mysql/Schema.php index 107495bea6c9316b169c8ad99378aa860c2ccf4b..6fd999e2802522ee46bb42c990bce05b6193bd53 100644 --- a/core/lib/Drupal/Core/Database/Driver/mysql/Schema.php +++ b/core/lib/Drupal/Core/Database/Driver/mysql/Schema.php @@ -411,6 +411,11 @@ public function addField($table, $field, $spec, $keys_new = array()) { ->fields(array($field => $spec['initial'])) ->execute(); } + if (isset($spec['initial_from_field'])) { + $this->connection->update($table) + ->expression($field, $spec['initial_from_field']) + ->execute(); + } if ($fixnull) { $spec['not null'] = TRUE; $this->changeField($table, $field, $field, $spec); diff --git a/core/lib/Drupal/Core/Database/Driver/pgsql/Schema.php b/core/lib/Drupal/Core/Database/Driver/pgsql/Schema.php index 4cd660b4b42bcb2499a231d8dfa518d4a7a83b90..c0775c914aff89fdcf6198e0c02c83db2faeedb2 100644 --- a/core/lib/Drupal/Core/Database/Driver/pgsql/Schema.php +++ b/core/lib/Drupal/Core/Database/Driver/pgsql/Schema.php @@ -531,6 +531,11 @@ public function addField($table, $field, $spec, $new_keys = array()) { ->fields(array($field => $spec['initial'])) ->execute(); } + if (isset($spec['initial_from_field'])) { + $this->connection->update($table) + ->expression($field, $spec['initial_from_field']) + ->execute(); + } if ($fixnull) { $this->connection->query("ALTER TABLE {" . $table . "} ALTER $field SET NOT NULL"); } diff --git a/core/lib/Drupal/Core/Database/Driver/sqlite/Schema.php b/core/lib/Drupal/Core/Database/Driver/sqlite/Schema.php index a3c001cc846ed8d6b19f99ecd2bfa04f1806d2bb..4b954ed35dfe8cc858e1513bdfe929d3378896e5 100644 --- a/core/lib/Drupal/Core/Database/Driver/sqlite/Schema.php +++ b/core/lib/Drupal/Core/Database/Driver/sqlite/Schema.php @@ -316,6 +316,11 @@ public function addField($table, $field, $specification, $keys_new = array()) { ->fields(array($field => $specification['initial'])) ->execute(); } + if (isset($specification['initial_from_field'])) { + $this->connection->update($table) + ->expression($field, $specification['initial_from_field']) + ->execute(); + } } else { // We cannot add the field directly. Use the slower table alteration @@ -335,6 +340,13 @@ public function addField($table, $field, $specification, $keys_new = array()) { 'arguments' => array(':newfieldinitial' => $specification['initial']), ); } + elseif (isset($specification['initial_from_field'])) { + // If we have a initial value, copy it over. + $mapping[$field] = array( + 'expression' => $specification['initial_from_field'], + 'arguments' => [], + ); + } else { // Else use the default of the field. $mapping[$field] = NULL; diff --git a/core/lib/Drupal/Core/Database/Schema.php b/core/lib/Drupal/Core/Database/Schema.php index 1a2141575ac73e6e77096fb7cab17f6b38f77c07..8b9eb7e129ddd8a1678c9d90e2f775eccc1adef9 100644 --- a/core/lib/Drupal/Core/Database/Schema.php +++ b/core/lib/Drupal/Core/Database/Schema.php @@ -305,6 +305,8 @@ abstract public function dropTable($table); * created field will be set to the value of the key in all rows. * This is most useful for creating NOT NULL columns with no default * value in existing tables. + * Alternatively, the 'initial_form_field' key may be used, which will + * auto-populate the new field with values from the specified field. * @param $keys_new * (optional) Keys and indexes specification to be created on the * table along with adding the field. The format is the same as a diff --git a/core/tests/Drupal/KernelTests/Core/Database/SchemaTest.php b/core/tests/Drupal/KernelTests/Core/Database/SchemaTest.php index 7866146f90b8b0eb918504f5840329056d842e54..8641fd3c9cc4e196015a084a321412997179c0b8 100644 --- a/core/tests/Drupal/KernelTests/Core/Database/SchemaTest.php +++ b/core/tests/Drupal/KernelTests/Core/Database/SchemaTest.php @@ -505,6 +505,7 @@ function testSchemaAddField() { array('not null' => FALSE, 'default' => 7), array('not null' => TRUE, 'initial' => 1), array('not null' => TRUE, 'initial' => 1, 'default' => 7), + array('not null' => TRUE, 'initial_from_field' => 'serial_column'), ); foreach ($variations as $variation) { @@ -532,6 +533,7 @@ function testSchemaAddField() { array('not null' => FALSE, 'default' => 7), array('not null' => TRUE, 'initial' => 1), array('not null' => TRUE, 'initial' => 1, 'default' => 7), + array('not null' => TRUE, 'initial_from_field' => 'serial_column'), ); foreach ($variations as $variation) { @@ -620,6 +622,19 @@ protected function assertFieldCharacteristics($table_name, $field_name, $field_s $this->assertEqual($count, 0, 'Initial values filled out.'); } + // Check that the initial value from another field has been registered. + if (isset($field_spec['initial_from_field'])) { + // There should be no row with a value different than + // $field_spec['initial_from_field']. + $count = db_select($table_name) + ->fields($table_name, array('serial_column')) + ->where($table_name . '.' . $field_spec['initial_from_field'] . ' <> ' . $table_name . '.' . $field_name) + ->countQuery() + ->execute() + ->fetchField(); + $this->assertEqual($count, 0, 'Initial values from another field filled out.'); + } + // Check that the default value has been registered. if (isset($field_spec['default'])) { // Try inserting a row, and check the resulting value of the new column.