From bae3e31e1fc1fb8e546edd6ccea108dc9689c000 Mon Sep 17 00:00:00 2001 From: Alex Pott <alex.a.pott@googlemail.com> Date: Fri, 24 Jun 2016 18:26:50 +0200 Subject: [PATCH] Issue #2753475 by amateescu, timmillwood: Support using the values of another field as initial values when adding a new field --- .../Drupal/Core/Database/Driver/mysql/Schema.php | 5 +++++ .../Drupal/Core/Database/Driver/pgsql/Schema.php | 5 +++++ .../Drupal/Core/Database/Driver/sqlite/Schema.php | 12 ++++++++++++ core/lib/Drupal/Core/Database/Schema.php | 2 ++ .../KernelTests/Core/Database/SchemaTest.php | 15 +++++++++++++++ 5 files changed, 39 insertions(+) diff --git a/core/lib/Drupal/Core/Database/Driver/mysql/Schema.php b/core/lib/Drupal/Core/Database/Driver/mysql/Schema.php index 107495bea6c9..6fd999e28025 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 4cd660b4b42b..c0775c914aff 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 a3c001cc846e..4b954ed35dfe 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 1a2141575ac7..8b9eb7e129dd 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 7866146f90b8..8641fd3c9cc4 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. -- GitLab