1
|
|
|
<?php |
2
|
|
|
/** |
3
|
|
|
* ActiveRecord for API |
4
|
|
|
* |
5
|
|
|
* @link https://github.com/hiqdev/yii2-hiart |
6
|
|
|
* @package yii2-hiart |
7
|
|
|
* @license BSD-3-Clause |
8
|
|
|
* @copyright Copyright (c) 2015-2017, HiQDev (http://hiqdev.com/) |
9
|
|
|
*/ |
10
|
|
|
|
11
|
|
|
namespace hiqdev\hiart; |
12
|
|
|
|
13
|
|
|
use yii\base\InvalidParamException; |
14
|
|
|
use yii\base\NotSupportedException; |
15
|
|
|
use yii\helpers\ArrayHelper; |
16
|
|
|
|
17
|
|
|
/** |
18
|
|
|
* Abstract QueryBuilder. |
19
|
|
|
* |
20
|
|
|
* QueryBuilder builds a request from the specification given as a [[Query]] object. |
21
|
|
|
*/ |
22
|
|
|
abstract class AbstractQueryBuilder extends \yii\base\Object implements QueryBuilderInterface |
|
|
|
|
23
|
|
|
{ |
24
|
|
|
/** |
25
|
|
|
* @var AbstractConnection |
26
|
|
|
*/ |
27
|
|
|
public $db; |
28
|
|
|
|
29
|
2 |
|
public function __construct($connection, $config = []) |
30
|
|
|
{ |
31
|
2 |
|
$this->db = $connection; |
32
|
2 |
|
parent::__construct($config); |
33
|
2 |
|
} |
34
|
|
|
|
35
|
|
|
/** |
36
|
|
|
* Builds config array to create Command. |
37
|
|
|
* @param Query $query |
38
|
|
|
* @throws NotSupportedException |
39
|
|
|
* @return array |
40
|
|
|
*/ |
41
|
2 |
|
public function build(Query $query) |
42
|
|
|
{ |
43
|
2 |
|
return ['request' => $this->createRequest($query)]; |
44
|
|
|
} |
45
|
|
|
|
46
|
3 |
|
public function createRequest($query) |
47
|
|
|
{ |
48
|
3 |
|
$request = new $this->db->requestClass($this, $query); |
49
|
|
|
|
50
|
3 |
|
return $request instanceof RequestCreatorInterface ? $request->createRequest() : $request; |
51
|
|
|
} |
52
|
|
|
|
53
|
|
|
/** |
54
|
|
|
* Prepares query before actual building. |
55
|
|
|
* This function for you to redefine. |
56
|
|
|
* It will be called before other build functions. |
57
|
|
|
* @param Query $query |
58
|
|
|
*/ |
59
|
2 |
|
public function prepare(Query $query) |
60
|
|
|
{ |
61
|
2 |
|
return $query->prepare($this); |
|
|
|
|
62
|
|
|
} |
63
|
|
|
|
64
|
|
|
/** |
65
|
|
|
* This function is for you to provide your authentication. |
66
|
|
|
* @param Query $query |
67
|
|
|
*/ |
68
|
|
|
abstract public function buildAuth(Query $query); |
69
|
|
|
|
70
|
|
|
abstract public function buildMethod(Query $query); |
71
|
|
|
|
72
|
|
|
abstract public function buildUri(Query $query); |
73
|
|
|
|
74
|
|
|
abstract public function buildHeaders(Query $query); |
75
|
|
|
|
76
|
|
|
abstract public function buildProtocolVersion(Query $query); |
77
|
|
|
|
78
|
|
|
abstract public function buildQueryParams(Query $query); |
79
|
|
|
|
80
|
|
|
abstract public function buildFormParams(Query $query); |
81
|
|
|
|
82
|
|
|
abstract public function buildBody(Query $query); |
83
|
|
|
|
84
|
|
|
/** |
85
|
|
|
* Creates insert request. |
86
|
|
|
* @param string $table |
87
|
|
|
* @param array $columns |
88
|
|
|
* @param array $options |
89
|
|
|
* @return AbstractRequest |
90
|
|
|
*/ |
91
|
1 |
|
public function insert($table, $columns, array $options = []) |
92
|
|
|
{ |
93
|
1 |
|
return $this->perform('insert', $table, $columns, $options); |
94
|
|
|
} |
95
|
|
|
|
96
|
|
|
/** |
97
|
|
|
* Creates update request. |
98
|
|
|
* @param string $table |
99
|
|
|
* @param array $columns |
100
|
|
|
* @param array $condition |
101
|
|
|
* @param array $options |
102
|
|
|
* @return AbstractRequest |
103
|
|
|
*/ |
104
|
|
|
public function update($table, $columns, $condition = [], array $options = []) |
105
|
|
|
{ |
106
|
|
|
$query = $this->createQuery('update', $table, $options)->body($columns)->where($condition); |
107
|
|
|
|
108
|
|
|
return $this->createRequest($query); |
109
|
|
|
} |
110
|
|
|
|
111
|
|
|
/** |
112
|
|
|
* Creates delete request. |
113
|
|
|
* @param string $table |
114
|
|
|
* @param array $condition |
115
|
|
|
* @param array $options |
116
|
|
|
* @return AbstractRequest |
117
|
|
|
*/ |
118
|
|
|
public function delete($table, $condition = [], array $options = []) |
119
|
|
|
{ |
120
|
|
|
$query = $this->createQuery('delete', $table, $options)->where($condition); |
121
|
|
|
|
122
|
|
|
return $this->createRequest($query); |
123
|
|
|
} |
124
|
|
|
|
125
|
|
|
/** |
126
|
|
|
* Creates request for given action. |
127
|
|
|
* @param string $action |
128
|
|
|
* @param string $table |
129
|
|
|
* @param mixed $body |
130
|
|
|
* @param array $options |
131
|
|
|
* @return AbstractRequest |
132
|
|
|
*/ |
133
|
1 |
|
public function perform($action, $table, $body, $options = []) |
134
|
|
|
{ |
135
|
1 |
|
$query = $this->createQuery($action, $table, $options)->body($body); |
136
|
|
|
|
137
|
1 |
|
return $this->createRequest($query); |
138
|
|
|
} |
139
|
|
|
|
140
|
1 |
|
public function createQuery($action, $table, array $options = []) |
141
|
|
|
{ |
142
|
1 |
|
$class = $this->db->queryClass; |
143
|
|
|
|
144
|
1 |
|
return $class::instantiate($action, $table, $options); |
145
|
|
|
} |
146
|
|
|
|
147
|
|
|
public function buildCondition($condition) |
148
|
|
|
{ |
149
|
|
|
static $builders = [ |
150
|
|
|
'and' => 'buildAndCondition', |
151
|
|
|
'between' => 'buildBetweenCondition', |
152
|
|
|
'eq' => 'buildEqCondition', |
153
|
|
|
'ne' => 'buildNotEqCondition', |
154
|
|
|
'in' => 'buildInCondition', |
155
|
|
|
'ni' => 'buildNotInCondition', |
156
|
|
|
'like' => 'buildLikeCondition', |
157
|
|
|
'ilike' => 'buildIlikeCondition', |
158
|
|
|
'gt' => 'buildCompareCondition', |
159
|
|
|
'ge' => 'buildCompareCondition', |
160
|
|
|
'lt' => 'buildCompareCondition', |
161
|
|
|
'le' => 'buildCompareCondition', |
162
|
|
|
]; |
163
|
|
|
if (empty($condition)) { |
164
|
|
|
return []; |
165
|
|
|
} |
166
|
|
|
if (!is_array($condition)) { |
167
|
|
|
throw new NotSupportedException('String conditions in where() are not supported by HiArt.'); |
168
|
|
|
} |
169
|
|
|
|
170
|
|
|
if (isset($condition[0])) { // operator format: operator, operand 1, operand 2, ... |
171
|
|
|
$operator = strtolower($condition[0]); |
172
|
|
|
if (isset($builders[$operator])) { |
173
|
|
|
$method = $builders[$operator]; |
174
|
|
|
array_shift($condition); // Shift build condition |
175
|
|
|
|
176
|
|
|
return $this->$method($operator, $condition); |
177
|
|
|
} else { |
178
|
|
|
throw new InvalidParamException('Found unknown operator in query: ' . $operator); |
179
|
|
|
} |
180
|
|
|
} else { |
181
|
|
|
return $this->buildHashCondition($condition); |
182
|
|
|
} |
183
|
|
|
} |
184
|
|
|
|
185
|
|
|
protected function buildHashCondition($condition) |
186
|
|
|
{ |
187
|
|
|
$parts = []; |
188
|
|
|
foreach ($condition as $attribute => $value) { |
189
|
|
|
if (is_array($value)) { // IN condition |
190
|
|
|
// $parts[] = [$attribute.'s' => join(',',$value)]; |
|
|
|
|
191
|
|
|
$parts[$attribute . 's'] = implode(',', $value); |
192
|
|
|
} else { |
193
|
|
|
$parts[$attribute] = $value; |
194
|
|
|
} |
195
|
|
|
} |
196
|
|
|
|
197
|
|
|
return $parts; |
198
|
|
|
} |
199
|
|
|
|
200
|
|
|
protected function buildLikeCondition($operator, $operands) |
|
|
|
|
201
|
|
|
{ |
202
|
|
|
return [$operands[0] . '_like' => $operands[1]]; |
203
|
|
|
} |
204
|
|
|
|
205
|
|
|
protected function buildIlikeCondition($operator, $operands) |
|
|
|
|
206
|
|
|
{ |
207
|
|
|
return [$operands[0] . '_ilike' => $operands[1]]; |
208
|
|
|
} |
209
|
|
|
|
210
|
|
|
protected function buildCompareCondition($operator, $operands) |
211
|
|
|
{ |
212
|
|
|
if (!isset($operands[0], $operands[1])) { |
213
|
|
|
throw new InvalidParamException("Operator '$operator' requires three operands."); |
214
|
|
|
} |
215
|
|
|
|
216
|
|
|
return [$operands[0] . '_' . $operator => $operands[1]]; |
217
|
|
|
} |
218
|
|
|
|
219
|
|
|
protected function buildAndCondition($operator, $operands) |
|
|
|
|
220
|
|
|
{ |
221
|
|
|
$parts = []; |
222
|
|
|
foreach ($operands as $operand) { |
223
|
|
|
if (is_array($operand)) { |
224
|
|
|
$parts = ArrayHelper::merge($this->buildCondition($operand), $parts); |
225
|
|
|
} |
226
|
|
|
} |
227
|
|
|
if (!empty($parts)) { |
228
|
|
|
return $parts; |
229
|
|
|
} else { |
230
|
|
|
return []; |
231
|
|
|
} |
232
|
|
|
} |
233
|
|
|
|
234
|
|
|
protected function buildBetweenCondition($operator, $operands) |
|
|
|
|
235
|
|
|
{ |
236
|
|
|
throw new NotSupportedException('Between condition is not supported by HiArt.'); |
237
|
|
|
} |
238
|
|
|
|
239
|
|
|
protected function buildInCondition($operator, $operands, $not = false) |
240
|
|
|
{ |
241
|
|
|
if (!isset($operands[0], $operands[1])) { |
242
|
|
|
throw new InvalidParamException("Operator '$operator' requires two operands."); |
243
|
|
|
} |
244
|
|
|
|
245
|
|
|
list($column, $values) = $operands; |
246
|
|
|
|
247
|
|
|
if (count($column) > 1) { |
248
|
|
|
return $this->buildCompositeInCondition($operator, $column, $values); |
249
|
|
|
} elseif (is_array($column)) { |
250
|
|
|
$column = reset($column); |
251
|
|
|
} |
252
|
|
|
|
253
|
|
|
foreach ((array) $values as $i => $value) { |
254
|
|
|
if (is_array($value)) { |
255
|
|
|
$values[$i] = $value = isset($value[$column]) ? $value[$column] : null; |
256
|
|
|
} |
257
|
|
|
if ($value === null) { |
258
|
|
|
unset($values[$i]); |
259
|
|
|
} |
260
|
|
|
} |
261
|
|
|
|
262
|
|
|
if ($not) { |
263
|
|
|
$key = $column . '_ni'; // not in |
264
|
|
|
} else { |
265
|
|
|
$key = $column . '_in'; |
266
|
|
|
} |
267
|
|
|
|
268
|
|
|
return [$key => $values]; |
269
|
|
|
} |
270
|
|
|
|
271
|
|
|
protected function buildNotInCondition($operator, $operands) |
272
|
|
|
{ |
273
|
|
|
return $this->buildInCondition($operator, $operands, true); |
274
|
|
|
} |
275
|
|
|
|
276
|
|
|
protected function buildEqCondition($operator, $operands) |
|
|
|
|
277
|
|
|
{ |
278
|
|
|
$key = array_shift($operands); |
279
|
|
|
|
280
|
|
|
return [$key => reset($operands)]; |
281
|
|
|
} |
282
|
|
|
|
283
|
|
|
protected function buildNotEqCondition($operator, $operands) |
284
|
|
|
{ |
285
|
|
|
$key = array_shift($operands); |
286
|
|
|
|
287
|
|
|
return [$key . '_' . $operator => reset($operands)]; |
288
|
|
|
} |
289
|
|
|
|
290
|
|
|
protected function buildCompositeInCondition($operator, $columns, $values) |
|
|
|
|
291
|
|
|
{ |
292
|
|
|
throw new NotSupportedException('composite in is not supported by HiArt.'); |
293
|
|
|
} |
294
|
|
|
} |
295
|
|
|
|
This class, trait or interface has been deprecated. The supplier of the file has supplied an explanatory message.
The explanatory message should give you some clue as to whether and when the type will be removed from the class and what other constant to use instead.