|
1
|
|
|
<?php |
|
2
|
|
|
|
|
3
|
|
|
namespace Magister\Services\Database\Query; |
|
4
|
|
|
|
|
5
|
|
|
use BadMethodCallException; |
|
6
|
|
|
use Magister\Services\Database\ConnectionInterface; |
|
7
|
|
|
use Magister\Services\Database\Query\Processors\Processor; |
|
8
|
|
|
use Magister\Services\Support\Collection; |
|
9
|
|
|
|
|
10
|
|
|
/** |
|
11
|
|
|
* Class Builder. |
|
12
|
|
|
*/ |
|
13
|
|
|
class Builder |
|
14
|
|
|
{ |
|
15
|
|
|
/** |
|
16
|
|
|
* The connection instance. |
|
17
|
|
|
* |
|
18
|
|
|
* @var \Magister\Services\Database\ConnectionInterface |
|
19
|
|
|
*/ |
|
20
|
|
|
protected $connection; |
|
21
|
|
|
|
|
22
|
|
|
/** |
|
23
|
|
|
* The processor instance. |
|
24
|
|
|
* |
|
25
|
|
|
* @var \Magister\Services\Database\Query\Processors\Processor |
|
26
|
|
|
*/ |
|
27
|
|
|
protected $processor; |
|
28
|
|
|
|
|
29
|
|
|
/** |
|
30
|
|
|
* The url which the query is targeting. |
|
31
|
|
|
* |
|
32
|
|
|
* @var string |
|
33
|
|
|
*/ |
|
34
|
|
|
protected $from; |
|
35
|
|
|
|
|
36
|
|
|
/** |
|
37
|
|
|
* The where constraints for the query. |
|
38
|
|
|
* |
|
39
|
|
|
* @var array |
|
40
|
|
|
*/ |
|
41
|
|
|
protected $bindings = []; |
|
42
|
|
|
|
|
43
|
|
|
/** |
|
44
|
|
|
* Create a new query builder instance. |
|
45
|
|
|
* |
|
46
|
|
|
* @param \Magister\Services\Database\ConnectionInterface $connection |
|
47
|
|
|
* @param \Magister\Services\Database\Query\Processors\Processor $processor |
|
48
|
|
|
*/ |
|
49
|
|
|
public function __construct(ConnectionInterface $connection, Processor $processor) |
|
50
|
|
|
{ |
|
51
|
|
|
$this->connection = $connection; |
|
52
|
|
|
$this->processor = $processor; |
|
53
|
|
|
} |
|
54
|
|
|
|
|
55
|
|
|
/** |
|
56
|
|
|
* Set the url which the query is targeting. |
|
57
|
|
|
* |
|
58
|
|
|
* @param string $query |
|
59
|
|
|
* |
|
60
|
|
|
* @return $this |
|
61
|
|
|
*/ |
|
62
|
|
|
public function from($query) |
|
63
|
|
|
{ |
|
64
|
|
|
$this->from = $query; |
|
65
|
|
|
|
|
66
|
|
|
return $this; |
|
67
|
|
|
} |
|
68
|
|
|
|
|
69
|
|
|
/** |
|
70
|
|
|
* Get an array with the values of a given column. |
|
71
|
|
|
* |
|
72
|
|
|
* @param string $column |
|
73
|
|
|
* @param string $key |
|
74
|
|
|
* |
|
75
|
|
|
* @return array |
|
76
|
|
|
*/ |
|
77
|
|
|
public function lists($column, $key = null) |
|
78
|
|
|
{ |
|
79
|
|
|
$columns = $this->getListSelect($column, $key); |
|
80
|
|
|
|
|
81
|
|
|
$results = new Collection($this->get()); |
|
|
|
|
|
|
82
|
|
|
|
|
83
|
|
|
return $results->lists($columns[0], array_get($columns, 1)); |
|
84
|
|
|
} |
|
85
|
|
|
|
|
86
|
|
|
/** |
|
87
|
|
|
* Get the columns that should be used in a lists array. |
|
88
|
|
|
* |
|
89
|
|
|
* @param string $column |
|
90
|
|
|
* @param string $key |
|
91
|
|
|
* |
|
92
|
|
|
* @return array |
|
93
|
|
|
*/ |
|
94
|
|
|
protected function getListSelect($column, $key) |
|
95
|
|
|
{ |
|
96
|
|
|
$select = is_null($key) ? [$column] : [$column, $key]; |
|
97
|
|
|
|
|
98
|
|
|
return array_map(function ($column) { |
|
99
|
|
|
$dot = strpos($column, '.'); |
|
100
|
|
|
|
|
101
|
|
|
return $dot === false ? $column : substr($column, $dot + 1); |
|
102
|
|
|
}, $select); |
|
103
|
|
|
} |
|
104
|
|
|
|
|
105
|
|
|
/** |
|
106
|
|
|
* Execute the query as a select statement. |
|
107
|
|
|
* |
|
108
|
|
|
* @return array |
|
109
|
|
|
*/ |
|
110
|
|
|
public function get() |
|
111
|
|
|
{ |
|
112
|
|
|
return $this->processor->process($this, $this->runSelect()); |
|
113
|
|
|
} |
|
114
|
|
|
|
|
115
|
|
|
/** |
|
116
|
|
|
* Run the query as a select statement against the connection. |
|
117
|
|
|
* |
|
118
|
|
|
* @return array |
|
119
|
|
|
*/ |
|
120
|
|
|
protected function runSelect() |
|
121
|
|
|
{ |
|
122
|
|
|
return $this->connection->select($this->from, $this->getBindings()); |
|
123
|
|
|
} |
|
124
|
|
|
|
|
125
|
|
|
/** |
|
126
|
|
|
* Add a basic where clause to the query. |
|
127
|
|
|
* |
|
128
|
|
|
* @param string $column |
|
129
|
|
|
* @param mixed $value |
|
130
|
|
|
* |
|
131
|
|
|
* @return $this |
|
132
|
|
|
*/ |
|
133
|
|
|
public function where($column, $value) |
|
134
|
|
|
{ |
|
135
|
|
|
$this->bindings[$column] = $value; |
|
136
|
|
|
|
|
137
|
|
|
return $this; |
|
138
|
|
|
} |
|
139
|
|
|
|
|
140
|
|
|
/** |
|
141
|
|
|
* Handles dynamic "where" clauses to the query. |
|
142
|
|
|
* |
|
143
|
|
|
* @param string $method |
|
144
|
|
|
* @param string $parameters |
|
145
|
|
|
* |
|
146
|
|
|
* @return $this |
|
147
|
|
|
*/ |
|
148
|
|
|
public function dynamicWhere($method, $parameters) |
|
149
|
|
|
{ |
|
150
|
|
|
$finder = substr($method, 5); |
|
151
|
|
|
|
|
152
|
|
|
$segments = preg_split('/(And)(?=[A-Z])/', $finder, -1, PREG_SPLIT_DELIM_CAPTURE); |
|
153
|
|
|
|
|
154
|
|
|
$parameter = array_shift($parameters); |
|
155
|
|
|
|
|
156
|
|
|
foreach ($segments as $segment) { |
|
157
|
|
|
if ($segment != 'And') { |
|
158
|
|
|
$this->where($segment, $parameter); |
|
159
|
|
|
} |
|
160
|
|
|
} |
|
161
|
|
|
|
|
162
|
|
|
return $this; |
|
163
|
|
|
} |
|
164
|
|
|
|
|
165
|
|
|
/** |
|
166
|
|
|
* Get the raw array of bindings. |
|
167
|
|
|
* |
|
168
|
|
|
* @return array |
|
169
|
|
|
*/ |
|
170
|
|
|
public function getBindings() |
|
171
|
|
|
{ |
|
172
|
|
|
return $this->bindings; |
|
173
|
|
|
} |
|
174
|
|
|
|
|
175
|
|
|
/** |
|
176
|
|
|
* Get the connection instance. |
|
177
|
|
|
* |
|
178
|
|
|
* @return \Magister\Services\Database\ConnectionInterface |
|
179
|
|
|
*/ |
|
180
|
|
|
public function getConnection() |
|
181
|
|
|
{ |
|
182
|
|
|
return $this->connection; |
|
183
|
|
|
} |
|
184
|
|
|
|
|
185
|
|
|
/** |
|
186
|
|
|
* Get the query processor instance. |
|
187
|
|
|
* |
|
188
|
|
|
* @return \Magister\Services\Database\Query\Processors\Processor |
|
189
|
|
|
*/ |
|
190
|
|
|
public function getProcessor() |
|
191
|
|
|
{ |
|
192
|
|
|
return $this->processor; |
|
193
|
|
|
} |
|
194
|
|
|
|
|
195
|
|
|
/** |
|
196
|
|
|
* Handle dynamic method calls into the method. |
|
197
|
|
|
* |
|
198
|
|
|
* @param string $method |
|
199
|
|
|
* @param array $parameters |
|
200
|
|
|
* |
|
201
|
|
|
* @throws \BadMethodCallException |
|
202
|
|
|
* |
|
203
|
|
|
* @return mixed |
|
204
|
|
|
*/ |
|
205
|
|
|
public function __call($method, $parameters) |
|
206
|
|
|
{ |
|
207
|
|
|
if (starts_with($method, 'where')) { |
|
208
|
|
|
return $this->dynamicWhere($method, $parameters); |
|
|
|
|
|
|
209
|
|
|
} |
|
210
|
|
|
|
|
211
|
|
|
$className = get_class($this); |
|
212
|
|
|
|
|
213
|
|
|
throw new BadMethodCallException("Call to undefined method {$className}::{$method}()"); |
|
214
|
|
|
} |
|
215
|
|
|
} |
|
216
|
|
|
|
This check looks at variables that are passed out again to other methods.
If the outgoing method call has stricter type requirements than the method itself, an issue is raised.
An additional type check may prevent trouble.