Skip to content

Commit 20db85d

Browse files
committed
Merge pull request #281 from rongzhj1990/master
Add insert on duplicate update method
2 parents f8d5b31 + d61612d commit 20db85d

File tree

3 files changed

+117
-1
lines changed

3 files changed

+117
-1
lines changed

MysqliDb.php

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,18 @@ class MysqliDb
112112
*/
113113
protected $isSubQuery = false;
114114

115+
/**
116+
* Name of the auto increment column
117+
*
118+
*/
119+
protected $_lastInsertId = null;
120+
121+
/**
122+
* Column names for update when using onDuplicate method
123+
*
124+
*/
125+
protected $_updateColumns = null;
126+
115127
/**
116128
* Return type: 'Array' to return results as array, 'Object' as object
117129
* 'Json' as json string
@@ -235,6 +247,8 @@ protected function reset()
235247
$this->returnType = 'Array';
236248
$this->_nestJoin = false;
237249
$this->_tableName = '';
250+
$this->_lastInsertId = null;
251+
$this->_updateColumns = null;
238252
}
239253

240254
/**
@@ -549,6 +563,19 @@ public function where($whereProp, $whereValue = 'DBNULL', $operator = '=', $cond
549563
return $this;
550564
}
551565

566+
/**
567+
* This function store update column's name and column name of the
568+
* autoincrement column
569+
*
570+
* @param Array Variable with values
571+
* @param String Variable value
572+
*/
573+
public function onDuplicate($_updateColumns, $_lastInsertId = null)
574+
{
575+
$this->_lastInsertId = $_lastInsertId;
576+
$this->_updateColumns = $_updateColumns;
577+
}
578+
552579
/**
553580
* This method allows you to specify multiple (method chaining optional) OR WHERE statements for SQL queries.
554581
*
@@ -778,6 +805,57 @@ private function _buildInsert ($tableName, $insertData, $operation)
778805
return true;
779806
}
780807

808+
/**
809+
* Helper function to add variables into the query statement
810+
*
811+
* @param Array Variable with values
812+
*/
813+
protected function _buildDuplicate($tableData)
814+
{
815+
if (is_array($this->_updateColumns) && !empty($this->_updateColumns)) {
816+
$this->_query .= " on duplicate key update ";
817+
if ($this->_lastInsertId) {
818+
$this->_lastQuery .= $this->_lastInsertId."=LAST_INSERT_ID(".$this->_lastInsertId."),";
819+
$this->_lastInsertId = null;
820+
}
821+
822+
foreach ($this->_updateColumns as $column) {
823+
$this->_query .= "`" . $column . "` = ";
824+
825+
// Simple value
826+
if (!is_array ($tableData[$column])) {
827+
$this->_bindParam($tableData[$column]);
828+
$this->_query .= '?, ';
829+
continue;
830+
}
831+
832+
// Function value
833+
$arr = $tableData[$column];
834+
$key = key($arr);
835+
$val = $arr[$key];
836+
switch ($key) {
837+
case '[I]':
838+
$this->_query .= $column . $val . ", ";
839+
break;
840+
case '[F]':
841+
$this->_query .= $val[0] . ", ";
842+
if (!empty ($val[1]))
843+
$this->_bindParams ($val[1]);
844+
break;
845+
case '[N]':
846+
if ($val == null)
847+
$this->_query .= "!" . $column . ", ";
848+
else
849+
$this->_query .= "!" . $val . ", ";
850+
break;
851+
default:
852+
die ("Wrong operation");
853+
}
854+
}
855+
$this->_query = rtrim($this->_query, ', ');
856+
}
857+
}
858+
781859
/**
782860
* Abstraction method that will compile the WHERE statement,
783861
* any passed update data, and the desired rows.
@@ -797,6 +875,7 @@ protected function _buildQuery($numRows = null, $tableData = null)
797875
$this->_buildGroupBy();
798876
$this->_buildOrderBy();
799877
$this->_buildLimit ($numRows);
878+
$this->_buildDuplicate($tableData);
800879

801880
$this->_lastQuery = $this->replacePlaceHolders ($this->_query, $this->_bindParams);
802881

readme.md

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,20 @@ else
123123
echo 'insert failed: ' . $db->getLastError();
124124
```
125125

126+
Insert with on duplicate key update
127+
```php
128+
$data = Array ("login" => "admin",
129+
"firstName" => "John",
130+
"lastName" => 'Doe',
131+
"createdAt" => $db->now(),
132+
"updatedAt" => $db->now(),
133+
);
134+
$updateColumns = Array ("updateAt");
135+
$lastInsertId = "id";
136+
$db->onDuplicate($updateColumns, $lastInsertId);
137+
$id = $db->insert ('users', $data);
138+
```
139+
126140
### Replace Query
127141
<a href='https://dev.mysql.com/doc/refman/5.0/en/replace.html'>Replace()</a> method implements same API as insert();
128142

tests/mysqliDbTests.php

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,10 @@
2929
'lastName' => 'char(10)',
3030
'password' => 'text not null',
3131
'createdAt' => 'datetime',
32+
'updatedAt' => 'datetime',
3233
'expires' => 'datetime',
33-
'loginCount' => 'int(10) default 0'
34+
'loginCount' => 'int(10) default 0',
35+
'unique key' => 'login (login)'
3436
),
3537
'products' => Array (
3638
'customerId' => 'int(10) not null',
@@ -46,6 +48,7 @@
4648
'lastName' => 'Doe',
4749
'password' => $db->func('SHA1(?)',Array ("secretpassword+salt")),
4850
'createdAt' => $db->now(),
51+
'updatedAt' => $db->now(),
4952
'expires' => $db->now('+1Y'),
5053
'loginCount' => $db->inc()
5154
),
@@ -55,6 +58,7 @@
5558
'lastName' => NULL,
5659
'password' => $db->func('SHA1(?)',Array ("secretpassword2+salt")),
5760
'createdAt' => $db->now(),
61+
'updatedAt' => $db->now(),
5862
'expires' => $db->now('+1Y'),
5963
'loginCount' => $db->inc(2)
6064
),
@@ -65,6 +69,7 @@
6569
'lastName' => 'D',
6670
'password' => $db->func('SHA1(?)',Array ("secretpassword2+salt")),
6771
'createdAt' => $db->now(),
72+
'updatedAt' => $db->now(),
6873
'expires' => $db->now('+1Y'),
6974
'loginCount' => $db->inc(3)
7075
)
@@ -136,6 +141,7 @@ function createTable ($name, $data) {
136141
'lastName' => 'Doe',
137142
'password' => 'test',
138143
'createdAt' => $db->now(),
144+
'updatedAt' => $db->now(),
139145
'expires' => $db->now('+1Y'),
140146
'loginCount' => $db->inc()
141147
);
@@ -170,6 +176,23 @@ function createTable ($name, $data) {
170176
exit;
171177
}
172178

179+
// insert with on duplicate key update
180+
$user = Array ('login' => 'user3',
181+
'active' => true,
182+
'customerId' => 11,
183+
'firstName' => 'Pete',
184+
'lastName' => 'D',
185+
'password' => $db->func('SHA1(?)',Array ("secretpassword2+salt")),
186+
'createdAt' => $db->now(),
187+
'updatedAt' => $db->now(),
188+
'expires' => $db->now('+1Y'),
189+
'loginCount' => $db->inc(3)
190+
);
191+
$updateColumns = Array ("updatedAt");
192+
$insertLastId = "id";
193+
$db->onDuplicate($updateColumns, "id");
194+
$db->insert("users", $user);
195+
173196
// order by field
174197
$db->orderBy("login","asc", Array ("user3","user2","user1"));
175198
$login = $db->getValue ("users", "login");

0 commit comments

Comments
 (0)