From 8fa692388b29979c56ff6d0229d20e09e8ecba65 Mon Sep 17 00:00:00 2001
From: Joas Schilling <nickvergessen@owncloud.com>
Date: Mon, 9 Mar 2015 17:25:02 +0100
Subject: [PATCH] Allow specifying the compare-array for insertIfNotExists()

---
 lib/private/allconfig.php          | 15 +++++++++++----
 lib/private/appframework/db/db.php |  4 ++--
 lib/private/db.php                 |  4 ++--
 lib/private/db/adapter.php         | 11 +++++++----
 lib/private/db/adaptersqlite.php   | 11 +++++++----
 lib/private/db/connection.php      |  4 ++--
 lib/public/db.php                  |  4 ++--
 lib/public/idbconnection.php       |  2 +-
 8 files changed, 34 insertions(+), 21 deletions(-)

diff --git a/lib/private/allconfig.php b/lib/private/allconfig.php
index 00defd920d..b8bba7986e 100644
--- a/lib/private/allconfig.php
+++ b/lib/private/allconfig.php
@@ -189,11 +189,18 @@ class AllConfig implements \OCP\IConfig {
 			return;
 		}
 
-		$data = array($value, $userId, $appName, $key);
+		$affectedRows = 0;
 		if (!$exists && $preCondition === null) {
-			$sql  = 'INSERT INTO `*PREFIX*preferences` (`configvalue`, `userid`, `appid`, `configkey`)'.
-					'VALUES (?, ?, ?, ?)';
+			$this->connection->insertIfNotExist('*PREFIX*preferences', [
+				'configvalue'	=> $value,
+				'userid'		=> $userId,
+				'appid'			=> $appName,
+				'configkey'		=> $key,
+			], ['configvalue', 'userid', 'appid']);
+			$affectedRows = 1;
 		} elseif ($exists) {
+			$data = array($value, $userId, $appName, $key);
+
 			$sql  = 'UPDATE `*PREFIX*preferences` SET `configvalue` = ? '.
 					'WHERE `userid` = ? AND `appid` = ? AND `configkey` = ? ';
 
@@ -206,8 +213,8 @@ class AllConfig implements \OCP\IConfig {
 				}
 				$data[] = $preCondition;
 			}
+			$affectedRows = $this->connection->executeUpdate($sql, $data);
 		}
-		$affectedRows = $this->connection->executeUpdate($sql, $data);
 
 		// only add to the cache if we already loaded data for the user
 		if ($affectedRows > 0 && isset($this->userCache[$userId])) {
diff --git a/lib/private/appframework/db/db.php b/lib/private/appframework/db/db.php
index 5387e36d62..18c32c948c 100644
--- a/lib/private/appframework/db/db.php
+++ b/lib/private/appframework/db/db.php
@@ -138,8 +138,8 @@ class Db implements IDb {
 	 * @return bool
 	 *
 	 */
-	public function insertIfNotExist($table, $input) {
-		return $this->connection->insertIfNotExist($table, $input);
+	public function insertIfNotExist($table, $input, $compare = null) {
+		return $this->connection->insertIfNotExist($table, $input, $compare);
 	}
 
 	/**
diff --git a/lib/private/db.php b/lib/private/db.php
index dc25092e27..3993ae2774 100644
--- a/lib/private/db.php
+++ b/lib/private/db.php
@@ -172,8 +172,8 @@ class OC_DB {
 	 * @param array $input An array of fieldname/value pairs
 	 * @return boolean number of updated rows
 	 */
-	public static function insertIfNotExist($table, $input) {
-		return \OC::$server->getDatabaseConnection()->insertIfNotExist($table, $input);
+	public static function insertIfNotExist($table, $input, $compare = null) {
+		return \OC::$server->getDatabaseConnection()->insertIfNotExist($table, $input, $compare);
 	}
 
 	/**
diff --git a/lib/private/db/adapter.php b/lib/private/db/adapter.php
index 58b3514b92..ee6898dde8 100644
--- a/lib/private/db/adapter.php
+++ b/lib/private/db/adapter.php
@@ -46,19 +46,22 @@ class Adapter {
 	 * @throws \OC\HintException
 	 * @return int count of inserted rows
 	 */
-	public function insertIfNotExist($table, $input) {
+	public function insertIfNotExist($table, $input, $compare = null) {
+		if ($compare === null) {
+			$compare = array_keys($input);
+		}
 		$query = 'INSERT INTO `' .$table . '` (`'
 			. implode('`,`', array_keys($input)) . '`) SELECT '
 			. str_repeat('?,', count($input)-1).'? ' // Is there a prettier alternative?
 			. 'FROM `' . $table . '` WHERE ';
 
 		$inserts = array_values($input);
-		foreach($input as $key => $value) {
+		foreach($compare as $key) {
 			$query .= '`' . $key . '`';
-			if (is_null($value)) {
+			if (is_null($input[$key])) {
 				$query .= ' IS NULL AND ';
 			} else {
-				$inserts[] = $value;
+				$inserts[] = $input[$key];
 				$query .= ' = ? AND ';
 			}
 		}
diff --git a/lib/private/db/adaptersqlite.php b/lib/private/db/adaptersqlite.php
index df4a804feb..8b3c4ebc83 100644
--- a/lib/private/db/adaptersqlite.php
+++ b/lib/private/db/adaptersqlite.php
@@ -18,19 +18,22 @@ class AdapterSqlite extends Adapter {
 		return $statement;
 	}
 
-	public function insertIfNotExist($table, $input) {
+	public function insertIfNotExist($table, $input, $compare = null) {
+		if ($compare === null) {
+			$compare = array_keys($input);
+		}
 		$fieldList = '`' . implode('`,`', array_keys($input)) . '`';
 		$query = "INSERT INTO `$table` ($fieldList) SELECT "
 			. str_repeat('?,', count($input)-1).'? '
 			. " WHERE NOT EXISTS (SELECT 1 FROM `$table` WHERE ";
 
 		$inserts = array_values($input);
-		foreach($input as $key => $value) {
+		foreach($compare as $key) {
 			$query .= '`' . $key . '`';
-			if (is_null($value)) {
+			if (is_null($input[$key])) {
 				$query .= ' IS NULL AND ';
 			} else {
-				$inserts[] = $value;
+				$inserts[] = $input[$key];
 				$query .= ' = ? AND ';
 			}
 		}
diff --git a/lib/private/db/connection.php b/lib/private/db/connection.php
index 6ba29fc2cc..cc94c862b8 100644
--- a/lib/private/db/connection.php
+++ b/lib/private/db/connection.php
@@ -164,8 +164,8 @@ class Connection extends \Doctrine\DBAL\Connection implements IDBConnection {
 	 * @throws \OC\HintException
 	 * @return bool The return value from execute()
 	 */
-	public function insertIfNotExist($table, $input) {
-		return $this->adapter->insertIfNotExist($table, $input);
+	public function insertIfNotExist($table, $input, $compare = null) {
+		return $this->adapter->insertIfNotExist($table, $input, $compare);
 	}
 
 	/**
diff --git a/lib/public/db.php b/lib/public/db.php
index e8fc817106..50e519bbe9 100644
--- a/lib/public/db.php
+++ b/lib/public/db.php
@@ -64,8 +64,8 @@ class DB {
 	 * @return bool
 	 *
 	 */
-	public static function insertIfNotExist($table, $input) {
-		return(\OC_DB::insertIfNotExist($table, $input));
+	public static function insertIfNotExist($table, $input, $compare = null) {
+		return(\OC_DB::insertIfNotExist($table, $input, $compare));
 	}
 
 	/**
diff --git a/lib/public/idbconnection.php b/lib/public/idbconnection.php
index 0d3274d90e..3cc7ff3248 100644
--- a/lib/public/idbconnection.php
+++ b/lib/public/idbconnection.php
@@ -94,7 +94,7 @@ interface IDBConnection {
 	 * @return bool
 	 *
 	 */
-	public function insertIfNotExist($table, $input);
+	public function insertIfNotExist($table, $input, $compare = null);
 
 	/**
 	 * Start a transaction
-- 
GitLab