From 9d6182d8d00b99a608b49ae47a5ccd03187802fe Mon Sep 17 00:00:00 2001
From: Dries Buytaert <dries@buytaert.net>
Date: Sun, 11 Oct 2009 13:43:37 +0000
Subject: [PATCH] - Patch #597556 by Berdir: return status to indicate executed
 query in MergeQuery::execute().

---
 includes/database/mysql/query.inc           |  9 +++++++--
 includes/database/query.inc                 | 19 +++++++++++++++++++
 modules/simpletest/tests/database_test.test |  8 ++++++--
 3 files changed, 32 insertions(+), 4 deletions(-)

diff --git a/includes/database/mysql/query.inc b/includes/database/mysql/query.inc
index 09878f96dc8e..7ea48c8acd7c 100644
--- a/includes/database/mysql/query.inc
+++ b/includes/database/mysql/query.inc
@@ -133,9 +133,14 @@ public function execute() {
       $values[':db_update_placeholder_' . ($max_placeholder++)] = $value;
     }
 
-    $last_insert_id = $this->connection->query((string)$this, $values, $this->queryOptions);
 
-    return $last_insert_id;
+    // MySQL's INSERT ... ON DUPLICATE KEY UPDATE queries return 1
+    // (MergeQuery::STATUS_INSERT) for an INSERT operation or 2
+    // (MergeQuery::STATUS_UPDATE) for an UPDATE operation.
+    //
+    // @link http ://dev.mysql.com/doc/refman/5.0/en/mysql-affected-rows.html
+    $this->queryOptions['return'] = Database::RETURN_AFFECTED;
+    return $this->connection->query((string)$this, $values, $this->queryOptions);
   }
 
 
diff --git a/includes/database/query.inc b/includes/database/query.inc
index 87b903d96b8d..98723496d990 100644
--- a/includes/database/query.inc
+++ b/includes/database/query.inc
@@ -548,6 +548,15 @@ public function preExecute() {
  * General class for an abstracted MERGE operation.
  */
 class MergeQuery extends Query {
+  /**
+   * Returned by execute() if an INSERT query has been executed.
+   */
+  const STATUS_INSERT = 1;
+
+  /**
+   * Returned by execute() if an UPDATE query has been executed.
+   */
+  const STATUS_UPDATE = 2;
 
   /**
    * The table on which to insert.
@@ -761,6 +770,14 @@ public function preExecute() {
     return TRUE;
   }
 
+  /**
+   * Run the MERGE query against the database.
+   *
+   * @return
+   *   A status indicating the executed operation:
+   *   - MergeQuery::STATUS_INSERT for an INSERT operation.
+   *   - MergeQuery::STATUS_UPDATE for an UPDATE operation.
+   */
   public function execute() {
     // If validation fails, simply return NULL.
     // Note that validation routines in preExecute() may throw exceptions instead.
@@ -813,12 +830,14 @@ public function execute() {
           $update->expression($field, $expression['expression'], $expression['arguments']);
         }
         $update->execute();
+        return MergeQuery::STATUS_UPDATE;
       }
     }
     else {
       // If there is no existing record, run an insert query.
       $insert_fields = $this->insertFields + $this->keyFields;
       $this->connection->insert($this->table, $this->queryOptions)->fields($insert_fields)->execute();
+      return MergeQuery::STATUS_INSERT;
     }
 
     // Transaction commits here where $transaction looses scope.
diff --git a/modules/simpletest/tests/database_test.test b/modules/simpletest/tests/database_test.test
index 5499cee43545..8d400e68c153 100644
--- a/modules/simpletest/tests/database_test.test
+++ b/modules/simpletest/tests/database_test.test
@@ -990,7 +990,7 @@ class DatabaseMergeTestCase extends DatabaseTestCase {
   function testMergeInsert() {
     $num_records_before = db_query('SELECT COUNT(*) FROM {test_people}')->fetchField();
 
-    db_merge('test_people')
+    $result = db_merge('test_people')
       ->key(array('job' => 'Presenter'))
       ->fields(array(
         'age' => 31,
@@ -998,6 +998,8 @@ class DatabaseMergeTestCase extends DatabaseTestCase {
       ))
       ->execute();
 
+    $this->assertEqual($result, MergeQuery::STATUS_INSERT, t('Insert status returned.'));
+
     $num_records_after = db_query('SELECT COUNT(*) FROM {test_people}')->fetchField();
     $this->assertEqual($num_records_before + 1, $num_records_after, t('Merge inserted properly.'));
 
@@ -1013,7 +1015,7 @@ class DatabaseMergeTestCase extends DatabaseTestCase {
   function testMergeUpdate() {
     $num_records_before = db_query('SELECT COUNT(*) FROM {test_people}')->fetchField();
 
-    db_merge('test_people')
+    $result = db_merge('test_people')
       ->key(array('job' => 'Speaker'))
       ->fields(array(
         'age' => 31,
@@ -1021,6 +1023,8 @@ class DatabaseMergeTestCase extends DatabaseTestCase {
       ))
       ->execute();
 
+    $this->assertEqual($result, MergeQuery::STATUS_UPDATE, t('Update status returned.'));
+
     $num_records_after = db_query('SELECT COUNT(*) FROM {test_people}')->fetchField();
     $this->assertEqual($num_records_before, $num_records_after, t('Merge updated properly.'));
 
-- 
GitLab