This repository has been archived by the owner on Jul 15, 2020. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
/
InsertUpdateCommandBehavior.php
108 lines (100 loc) · 3.98 KB
/
InsertUpdateCommandBehavior.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
<?php
/**
* InsertUpdateCommandBehavior class file.
*
* @package InsertUpdateCommandBehavior
* @version 1.0
* @author dotzero <[email protected]>
* @link http://www.dotzero.ru/
* @link https://github.com/dotzero/yii-insertupdate-behavior
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
/**
* The InsertUpdateCommandBehavior extension adds up some functionality to the default
* possibilites of yii´s CDbCommand implementation. Creates and executes an
* INSERT with ON DUPLICATE KEY UPDATE MySQL statement.
*
* Requirements:
* Yii Framework 1.1.14 or above
*
* Basic usage:
* $command = Yii::app()->db->createCommand();
* $command->attachBehavior('InsertUpdateCommandBehavior', new InsertUpdateCommandBehavior);
* $command->insertUpdate('tbl_user', array(
* 'name'=>'Tester',
* 'email'=>'[email protected]',
* 'counter'=>'1'
* ), array(
* 'name'=>'Tester',
* 'email'=>'[email protected]'
* ));
*
* Creates and executes an INSERT SQL with ON DUPLICATE KEY UPDATE MySQL statement
* INSERT INTO `tbl_user` (`name`, `email`, `counter`) VALUES ('Tester', '[email protected]', 1)
* ON DUPLICATE KEY UPDATE `name`='Tester', `email`='[email protected]';
*
* Advanced usage:
* $command = Yii::app()->db->createCommand();
* $command->attachBehavior('InsertUpdateCommandBehavior', new InsertUpdateCommandBehavior);
* $command->insertUpdate('tbl_user', array(
* 'name'=>'Tester',
* 'email'=>'[email protected]',
* 'counter'=>'1'
* ), array(
* 'name'=>'Tester',
* 'email'=>'[email protected]'
* 'counter'=>new CDbExpression('LAST_INSERT_ID(counter)');
* ));
*
* Creates and executes an INSERT SQL with ON DUPLICATE KEY UPDATE MySQL statement
* INSERT INTO `tbl_user` (`name`, `email`, `counter`) VALUES ('Tester', '[email protected]', 1)
* ON DUPLICATE KEY UPDATE `name`='Tester', `email`='[email protected]', `counter`=LAST_INSERT_ID(counter);
*/
class InsertUpdateCommandBehavior extends CBehavior
{
/**
* Creates and executes an INSERT with ON DUPLICATE KEY UPDATE SQL statement.
* The method will properly escape the column names, and bind the values to be inserted or updated
* @param string $table the table that new rows will be inserted into.
* @param array $columns the column data (name=>value) to be inserted into the table.
* @param array $update the column data (name=>value) to be updated in the table.
* @return integer number of rows affected by the execution.
*/
public function insertUpdate($table, $columns, $update)
{
$params = array();
$names = array();
$placeholders = array();
$lines = array();
foreach ($columns as $name => $value) {
$names[] = $this->owner->connection->quoteColumnName($name);
if ($value instanceof CDbExpression) {
$placeholders[] = $value->expression;
foreach ($value->params as $n => $v) {
$params[$n] = $v;
}
} else {
$placeholders[] = ':' . $name;
$params[':' . $name] = $value;
}
}
foreach ($update as $name => $value) {
if ($value instanceof CDbExpression) {
$lines[] = $this->owner->connection->quoteColumnName($name) . '=' . $value->expression;
foreach ($value->params as $n => $v) {
$params[$n] = $v;
}
} else {
$lines[] = $this->owner->connection->quoteColumnName($name) . '=:' . $name;
$params[':' . $name] = $value;
}
}
$sql = 'INSERT INTO ' . $this->owner->connection->quoteTableName($table)
. ' (' . implode(', ', $names) . ') VALUES ('
. implode(', ', $placeholders) . ')'
. ' ON DUPLICATE KEY UPDATE ' . implode(', ', $lines);
return $this->owner->setText($sql)->execute($params);
}
}