From 19abf86418d263ca18935a08784b4f64fb7a416c Mon Sep 17 00:00:00 2001 From: rongzhj Date: Mon, 3 Aug 2015 18:18:12 +0800 Subject: [PATCH 1/3] add on dulplicate update --- MysqliDb.php | 51 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) diff --git a/MysqliDb.php b/MysqliDb.php index 42dc34a8..5ca4071a 100644 --- a/MysqliDb.php +++ b/MysqliDb.php @@ -112,6 +112,18 @@ class MysqliDb */ protected $isSubQuery = false; + /** + * Name of the auto increment column + * + */ + protected $lastInsertId = null; + + /** + * Column names for update when using onDuplicate method + * + */ + protected $updateColumns = null; + /** * Return type: 'Array' to return results as array, 'Object' as object * 'Json' as json string @@ -550,6 +562,19 @@ public function where($whereProp, $whereValue = 'DBNULL', $operator = '=', $cond return $this; } + /** + * This function store update column's name and column name of the + * autoincrement column + * + * @param Array Variable with values + * @param String Variable value + */ + public function onDuplicate($updateColumns, $lastInsertId = null) + { + $this->lastInsertId = $lastInsertId; + $this->updateColumns = $updateColumns; + } + /** * This method allows you to specify multiple (method chaining optional) OR WHERE statements for SQL queries. * @@ -779,6 +804,31 @@ private function _buildInsert ($tableName, $insertData, $operation) return true; } + /** + * Helper function to add variables into the query statement + * + * @param Array Variable with values + */ + protected function _buildDuplicate($tableData) + { + if (is_array($this->updateColumns) && !empty($this->updateColumns)) { + $this->_query .= " on duplicate key update "; + if ($this->lastInsertId) { + $this->_lastQuery .= $this->lastInsertId."=LAST_INSERT_ID(".$this->lastInsertId."),"; + $this->lastInsertId = null; + } + + foreach ($this->updateColumns as $value) { + $this->_bindParam($tableData[$value]); + $this->_query .= "`" . $value . "` = ?, "; + } + + $this->_query = rtrim($this->_query, ', '); + $this->lastInsertId = null; + $this->updateColumns = null; + } + } + /** * Abstraction method that will compile the WHERE statement, * any passed update data, and the desired rows. @@ -798,6 +848,7 @@ protected function _buildQuery($numRows = null, $tableData = null) $this->_buildGroupBy(); $this->_buildOrderBy(); $this->_buildLimit ($numRows); + $this->_buildDuplicate($tableData); $this->_lastQuery = $this->replacePlaceHolders ($this->_query, $this->_bindParams); From 75030a1e26e477321223a39f6acd3eb8c0b540dc Mon Sep 17 00:00:00 2001 From: rongzhj Date: Tue, 4 Aug 2015 00:43:22 +0800 Subject: [PATCH 2/3] fixed _buildDuplicate() method unable to handle array arguments --- MysqliDb.php | 80 +++++++++++++++++++++++++++-------------- readme.md | 14 ++++++++ tests/mysqliDbTests.php | 25 ++++++++++++- 3 files changed, 92 insertions(+), 27 deletions(-) diff --git a/MysqliDb.php b/MysqliDb.php index 5ca4071a..f115a72d 100644 --- a/MysqliDb.php +++ b/MysqliDb.php @@ -112,17 +112,17 @@ class MysqliDb */ protected $isSubQuery = false; - /** - * Name of the auto increment column - * - */ - protected $lastInsertId = null; + /** + * Name of the auto increment column + * + */ + protected $_lastInsertId = null; - /** - * Column names for update when using onDuplicate method - * - */ - protected $updateColumns = null; + /** + * Column names for update when using onDuplicate method + * + */ + protected $_updateColumns = null; /** * Return type: 'Array' to return results as array, 'Object' as object @@ -247,6 +247,8 @@ protected function reset() $this->returnType = 'Array'; $this->_nestJoin = false; $this->_tableName = ''; + $this->_lastInsertId = null; + $this->_updateColumns = null; } /** @@ -562,17 +564,17 @@ public function where($whereProp, $whereValue = 'DBNULL', $operator = '=', $cond return $this; } - /** + /** * This function store update column's name and column name of the * autoincrement column * * @param Array Variable with values * @param String Variable value */ - public function onDuplicate($updateColumns, $lastInsertId = null) + public function onDuplicate($_updateColumns, $_lastInsertId = null) { - $this->lastInsertId = $lastInsertId; - $this->updateColumns = $updateColumns; + $this->_lastInsertId = $_lastInsertId; + $this->_updateColumns = $_updateColumns; } /** @@ -804,28 +806,54 @@ private function _buildInsert ($tableName, $insertData, $operation) return true; } - /** + /** * Helper function to add variables into the query statement * * @param Array Variable with values */ protected function _buildDuplicate($tableData) { - if (is_array($this->updateColumns) && !empty($this->updateColumns)) { + if (is_array($this->_updateColumns) && !empty($this->_updateColumns)) { $this->_query .= " on duplicate key update "; - if ($this->lastInsertId) { - $this->_lastQuery .= $this->lastInsertId."=LAST_INSERT_ID(".$this->lastInsertId."),"; - $this->lastInsertId = null; + if ($this->_lastInsertId) { + $this->_lastQuery .= $this->_lastInsertId."=LAST_INSERT_ID(".$this->_lastInsertId."),"; + $this->_lastInsertId = null; } - - foreach ($this->updateColumns as $value) { - $this->_bindParam($tableData[$value]); - $this->_query .= "`" . $value . "` = ?, "; + + foreach ($this->_updateColumns as $column) { + $this->_query .= "`" . $column . "` = "; + + // Simple value + if (!is_array ($tableData[$column])) { + $this->_bindParam($tableData[$column]); + $this->_query .= '?, '; + continue; + } + + // Function value + $arr = $tableData[$column]; + $key = key($arr); + $val = $arr[$key]; + switch ($key) { + case '[I]': + $this->_query .= $column . $val . ", "; + break; + case '[F]': + $this->_query .= $val[0] . ", "; + if (!empty ($val[1])) + $this->_bindParams ($val[1]); + break; + case '[N]': + if ($val == null) + $this->_query .= "!" . $column . ", "; + else + $this->_query .= "!" . $val . ", "; + break; + default: + die ("Wrong operation"); + } } - $this->_query = rtrim($this->_query, ', '); - $this->lastInsertId = null; - $this->updateColumns = null; } } diff --git a/readme.md b/readme.md index dfd9a9de..299f2f3c 100644 --- a/readme.md +++ b/readme.md @@ -123,6 +123,20 @@ else echo 'insert failed: ' . $db->getLastError(); ``` +Insert with on duplicate key update +```php +$data = Array ("login" => "admin", + "firstName" => "John", + "lastName" => 'Doe', + "createdAt" => $db->now(), + "updatedAt" => $db->now(), +); +$updateColumns = Array ("updateAt"); +$lastInsertId = "id"; +$db->onDuplicate($updateColumns, $lastInsertId); +$id = $db->insert ('users', $data); +``` + ### Replace Query Replace() method implements same API as insert(); diff --git a/tests/mysqliDbTests.php b/tests/mysqliDbTests.php index 0cdcd34e..44b17417 100644 --- a/tests/mysqliDbTests.php +++ b/tests/mysqliDbTests.php @@ -29,8 +29,10 @@ 'lastName' => 'char(10)', 'password' => 'text not null', 'createdAt' => 'datetime', + 'updatedAt' => 'datetime', 'expires' => 'datetime', - 'loginCount' => 'int(10) default 0' + 'loginCount' => 'int(10) default 0', + 'unique key' => 'login (login)' ), 'products' => Array ( 'customerId' => 'int(10) not null', @@ -46,6 +48,7 @@ 'lastName' => 'Doe', 'password' => $db->func('SHA1(?)',Array ("secretpassword+salt")), 'createdAt' => $db->now(), + 'updatedAt' => $db->now(), 'expires' => $db->now('+1Y'), 'loginCount' => $db->inc() ), @@ -55,6 +58,7 @@ 'lastName' => NULL, 'password' => $db->func('SHA1(?)',Array ("secretpassword2+salt")), 'createdAt' => $db->now(), + 'updatedAt' => $db->now(), 'expires' => $db->now('+1Y'), 'loginCount' => $db->inc(2) ), @@ -65,6 +69,7 @@ 'lastName' => 'D', 'password' => $db->func('SHA1(?)',Array ("secretpassword2+salt")), 'createdAt' => $db->now(), + 'updatedAt' => $db->now(), 'expires' => $db->now('+1Y'), 'loginCount' => $db->inc(3) ) @@ -136,6 +141,7 @@ function createTable ($name, $data) { 'lastName' => 'Doe', 'password' => 'test', 'createdAt' => $db->now(), + 'updatedAt' => $db->now(), 'expires' => $db->now('+1Y'), 'loginCount' => $db->inc() ); @@ -170,6 +176,23 @@ function createTable ($name, $data) { exit; } +// insert with on duplicate key update +$user = Array ('login' => 'user3', + 'active' => true, + 'customerId' => 11, + 'firstName' => 'Pete', + 'lastName' => 'D', + 'password' => $db->func('SHA1(?)',Array ("secretpassword2+salt")), + 'createdAt' => $db->now(), + 'updatedAt' => $db->now(), + 'expires' => $db->now('+1Y'), + 'loginCount' => $db->inc(3) + ); +$updateColumns = Array ("updatedAt"); +$insertLastId = "id"; +$db->onDuplicate($updateColumns, "id"); +$db->insert("users", $user); + // order by field $db->orderBy("login","asc", Array ("user3","user2","user1")); $login = $db->getValue ("users", "login"); From d61612df44e52244872ea117de9c5a36618a66ea Mon Sep 17 00:00:00 2001 From: rongzhj Date: Tue, 4 Aug 2015 01:04:53 +0800 Subject: [PATCH 3/3] re-formatted code --- MysqliDb.php | 30 +++++++++++++++--------------- tests/mysqliDbTests.php | 22 +++++++++++----------- 2 files changed, 26 insertions(+), 26 deletions(-) diff --git a/MysqliDb.php b/MysqliDb.php index f115a72d..ff4832d3 100644 --- a/MysqliDb.php +++ b/MysqliDb.php @@ -821,20 +821,20 @@ protected function _buildDuplicate($tableData) } foreach ($this->_updateColumns as $column) { - $this->_query .= "`" . $column . "` = "; - - // Simple value - if (!is_array ($tableData[$column])) { - $this->_bindParam($tableData[$column]); - $this->_query .= '?, '; - continue; - } - - // Function value - $arr = $tableData[$column]; - $key = key($arr); - $val = $arr[$key]; - switch ($key) { + $this->_query .= "`" . $column . "` = "; + + // Simple value + if (!is_array ($tableData[$column])) { + $this->_bindParam($tableData[$column]); + $this->_query .= '?, '; + continue; + } + + // Function value + $arr = $tableData[$column]; + $key = key($arr); + $val = $arr[$key]; + switch ($key) { case '[I]': $this->_query .= $column . $val . ", "; break; @@ -851,7 +851,7 @@ protected function _buildDuplicate($tableData) break; default: die ("Wrong operation"); - } + } } $this->_query = rtrim($this->_query, ', '); } diff --git a/tests/mysqliDbTests.php b/tests/mysqliDbTests.php index 44b17417..6a83b668 100644 --- a/tests/mysqliDbTests.php +++ b/tests/mysqliDbTests.php @@ -32,7 +32,7 @@ 'updatedAt' => 'datetime', 'expires' => 'datetime', 'loginCount' => 'int(10) default 0', - 'unique key' => 'login (login)' + 'unique key' => 'login (login)' ), 'products' => Array ( 'customerId' => 'int(10) not null', @@ -178,16 +178,16 @@ function createTable ($name, $data) { // insert with on duplicate key update $user = Array ('login' => 'user3', - 'active' => true, - 'customerId' => 11, - 'firstName' => 'Pete', - 'lastName' => 'D', - 'password' => $db->func('SHA1(?)',Array ("secretpassword2+salt")), - 'createdAt' => $db->now(), - 'updatedAt' => $db->now(), - 'expires' => $db->now('+1Y'), - 'loginCount' => $db->inc(3) - ); + 'active' => true, + 'customerId' => 11, + 'firstName' => 'Pete', + 'lastName' => 'D', + 'password' => $db->func('SHA1(?)',Array ("secretpassword2+salt")), + 'createdAt' => $db->now(), + 'updatedAt' => $db->now(), + 'expires' => $db->now('+1Y'), + 'loginCount' => $db->inc(3) + ); $updateColumns = Array ("updatedAt"); $insertLastId = "id"; $db->onDuplicate($updateColumns, "id");