-
Notifications
You must be signed in to change notification settings - Fork 9
/
InsertQuery.php
140 lines (117 loc) · 4.15 KB
/
InsertQuery.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
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
<?php
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4 enc=utf8: */
/**
* @author Alexey Zakhlestin
* @package mysql-query-builder
**/
/*
MySQL Query Builder
Copyright © 2005-2009 Alexey Zakhlestin <indeyets@gmail.com>
Copyright © 2005-2006 Konstantin Sedov <kostya.online@gmail.com>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
/**
* This class contains logic of "INSERT" queries
*
* @package mysql-query-builder
* @author Alexey Zakhlestin
*/
class InsertQuery extends BasicQuery
{
private $values;
private $on_duplicate_update = false;
/**
* Constructor of INSERT query.
* WARNING: INSERT can be applied only to the single table. You can use array as the first parameter of constructor, but it should be array of 1 element
*
* @param mixed $tables
* @param bool $on_duplicate_update
* @throws InvalidArgumentException
*/
public function __construct($tables, $on_duplicate_update = false)
{
parent::__construct($tables);
if (count($this->from) != 1)
throw new InvalidArgumentException('INSERT can be used only on the single table');
$this->on_duplicate_update = $on_duplicate_update;
}
/**
* magic accessor, which lets setting parts of "SET …" clause with simple "$obj->field = 'value';" statements
*
* @param string $key
* @param mixed $value
* @return void
*/
public function __set($key, $value)
{
$this->values[$key] = new Parameter($value);
$this->reset();
}
/**
* sets "SET …" clause of query to the new value. Array is supposed to be in the following format:
* [field_name => value, field2 => value2, …]
*
* @param array $values
* @return void
*/
public function setValues(array $values)
{
$this->values = array();
foreach ($values as $key => $value) {
$this->values[$key] = new Parameter($value);
}
$this->reset();
}
protected function getSql(array &$parameters)
{
$sql = $this->getInsert($parameters);
$sql .= $this->getValues($parameters);
if (true === $this->on_duplicate_update) {
$sql .= $this->getUpdate($parameters);
}
return $sql;
}
private function getInsert(&$parameters)
{
$inserts = array();
foreach (array_keys($this->values) as $key) {
$inserts[] = '`'.$key.'`';
}
$sql = "INSERT INTO ".$this->from[0]->__toString()." (".implode(", ", $inserts).")";
return $sql;
}
private function getValues(&$parameters)
{
$values = array();
foreach ($this->values as $k => $v) {
$values[] = $v->getSql($parameters);
}
$sql = " VALUES (".implode(", ", $values).")";
return $sql;
}
private function getUpdate(&$parameters)
{
// if (!isset($this->values['id']))
// throw new LogicException("id field is required for ON DUPLICATE KEY UPDATE functionality");
$values = array();
foreach ($this->values as $k => $v) {
if ('id' == $k) { // FIXME: не всегда первичным ключом является id
$values[] = '`id` = LAST_INSERT_ID(`id`)';
} else {
$values[] = '`'.$k.'` = VALUES(`'.$k.'`)';
}
}
$sql = " ON DUPLICATE KEY UPDATE ".implode(", ", $values);
return $sql;
}
}