From 962eb36a66363c6b2dd242748f82001af7465b59 Mon Sep 17 00:00:00 2001 From: Lorenz Schori Date: Thu, 16 Aug 2012 09:48:36 +0200 Subject: [PATCH] Issue #1266572 by znerol, Damien Tournoud: workaround in SQLite causes some update to be missed. --- .../Drupal/Core/Database/Driver/sqlite/Update.php | 29 +++----------------- .../Drupal/system/Tests/Database/UpdateTest.php | 15 ++++++++++ 2 files changed, 19 insertions(+), 25 deletions(-) diff --git a/core/lib/Drupal/Core/Database/Driver/sqlite/Update.php b/core/lib/Drupal/Core/Database/Driver/sqlite/Update.php index 18332e7..b6c2bdf 100644 --- a/core/lib/Drupal/Core/Database/Driver/sqlite/Update.php +++ b/core/lib/Drupal/Core/Database/Driver/sqlite/Update.php @@ -19,39 +19,18 @@ use Drupal\Core\Database\Query\Update as QueryUpdate; * we don't select those rows. * * A query like this one: - * UPDATE test SET name = 'newname' WHERE tid = 1 + * UPDATE test SET col1 = 'newcol1', col2 = 'newcol2' WHERE tid = 1 * will become: - * UPDATE test SET name = 'newname' WHERE tid = 1 AND name <> 'newname' + * UPDATE test SET col1 = 'newcol1', col2 = 'newcol2' WHERE tid = 1 AND (col1 <> 'newcol1' OR col2 <> 'newcol2') */ class Update extends QueryUpdate { - /** - * Helper function that removes the fields that are already in a condition. - * - * @param $fields - * The fields. - * @param QueryConditionInterface $condition - * A database condition. - */ - protected function removeFieldsInCondition(&$fields, ConditionInterface $condition) { - foreach ($condition->conditions() as $child_condition) { - if ($child_condition['field'] instanceof ConditionInterface) { - $this->removeFieldsInCondition($fields, $child_condition['field']); - } - else { - unset($fields[$child_condition['field']]); - } - } - } - public function execute() { if (!empty($this->queryOptions['sqlite_return_matched_rows'])) { return parent::execute(); } - // Get the fields used in the update query, and remove those that are already - // in the condition. + // Get the fields used in the update query. $fields = $this->expressionFields + $this->fields; - $this->removeFieldsInCondition($fields, $this->condition); // Add the inverse of the fields to the condition. $condition = new Condition('OR'); @@ -77,4 +56,4 @@ class Update extends QueryUpdate { return parent::execute(); } -} \ No newline at end of file +} diff --git a/core/modules/system/lib/Drupal/system/Tests/Database/UpdateTest.php b/core/modules/system/lib/Drupal/system/Tests/Database/UpdateTest.php index a428383..ecca79a 100644 --- a/core/modules/system/lib/Drupal/system/Tests/Database/UpdateTest.php +++ b/core/modules/system/lib/Drupal/system/Tests/Database/UpdateTest.php @@ -125,4 +125,19 @@ class UpdateTest extends DatabaseTestBase { ->execute(); $this->assertIdentical($num_rows, 3, t('Number of affected rows are returned.')); } + + /** + * Confirm that we can update the primary key of a record successfully. + * Bug: http://drupal.org/node/1266572 + */ + function testPrimaryKeyUpdate() { + $num_updated = db_update('test') + ->fields(array('id' => 42, 'name' => 'John')) + ->condition('id', 1) + ->execute(); + $this->assertIdentical($num_updated, 1, t('Updated 1 record.')); + + $saved_name= db_query('SELECT name FROM {test} WHERE id = :id', array(':id' => 42))->fetchField(); + $this->assertIdentical($saved_name, 'John', t('Updated primary key successfully.')); + } } -- 1.7.2.5