1 | <?php |
||||
2 | /** |
||||
3 | * KNUT7 K7F (https://marciozebedeu.com/) |
||||
4 | * KNUT7 K7F (tm) : Rapid Development Framework (https://marciozebedeu.com/) |
||||
5 | * |
||||
6 | * Licensed under The MIT License |
||||
7 | * For full copyright and license information, please see the LICENSE.txt |
||||
8 | * Redistributions of files must retain the above copyright notice. |
||||
9 | * |
||||
10 | * @link https://github.com/knut7/framework/ for the canonical source repository |
||||
11 | * @copyright (c) 2015. KNUT7 Software Technologies AO Inc. (https://marciozebedeu.com/) |
||||
12 | * @license https://marciozebedeu.com/license/new-bsd New BSD License |
||||
13 | * @author Marcio Zebedeu - [email protected] |
||||
14 | * @version 1.0.2 |
||||
15 | */ |
||||
16 | |||||
17 | |||||
18 | namespace Ballybran\Database; |
||||
19 | use Ballybran\Database\DBconnection; |
||||
20 | use Ballybran\Database\Drives\QueryBuilderInterface; |
||||
21 | |||||
22 | /** |
||||
23 | * Class QueryBuilder |
||||
24 | * @method QueryBuilder table (string $table) |
||||
25 | * @method QueryBuilder join (string $join) |
||||
26 | * @method QueryBuilder fields (array $fields) |
||||
27 | * @method QueryBuilder where (array $where) |
||||
28 | * @method QueryBuilder order (array $order) |
||||
29 | * @method QueryBuilder group (array $group) |
||||
30 | * @method QueryBuilder having (array $having) |
||||
31 | * @method QueryBuilder limit (array $join) |
||||
32 | */ |
||||
33 | class QueryBuilder extends DBconnection |
||||
34 | { |
||||
35 | /** |
||||
36 | * @var array |
||||
37 | */ |
||||
38 | private $clausules = []; |
||||
39 | |||||
40 | /** |
||||
41 | * @param $name |
||||
42 | * @param $arguments |
||||
43 | * @return $this |
||||
44 | */ |
||||
45 | function __call($name , $arguments) |
||||
46 | { |
||||
47 | $clausule = $arguments[0]; |
||||
48 | if (count( $arguments ) > 1) { |
||||
49 | $clausule = $arguments; |
||||
50 | } |
||||
51 | $this->clausules[strtolower( $name )] = $clausule; |
||||
52 | |||||
53 | return $this; |
||||
54 | } |
||||
55 | |||||
56 | /** |
||||
57 | * QueryBuilder constructor. |
||||
58 | * @param array $options |
||||
59 | */ |
||||
60 | public function __construct(array $options) |
||||
61 | { |
||||
62 | parent::__construct( $options ); |
||||
63 | $this->conn = $this->connection(); |
||||
0 ignored issues
–
show
Bug
Best Practice
introduced
by
![]() |
|||||
64 | |||||
65 | } |
||||
66 | |||||
67 | /** |
||||
68 | * @param array $values |
||||
69 | * @return string |
||||
70 | */ |
||||
71 | public function insert(array $values = [] ) |
||||
72 | { |
||||
73 | // recupera o nome da tabela |
||||
74 | // ou deixa uma marcação para mostrar que faltou informar esse campo |
||||
75 | $table = isset( $this->clausules['table'] ) ? $this->clausules['table'] : '<table>'; |
||||
76 | |||||
77 | // recupera o array dos campos |
||||
78 | // ou deixa uma marcação para mostrar que faltou informar esse campo |
||||
79 | $_fields = isset( $this->clausules['fields'] ) ? $this->clausules['fields'] : '<fields>'; |
||||
80 | // $fields = implode( ', ' , $_fields ); |
||||
81 | // |
||||
82 | // // cria uma lista de rótulos para usar "prepared statement" |
||||
83 | // $_placeholders = array_map( function () { |
||||
84 | // return '?'; |
||||
85 | // } , $_fields ); |
||||
86 | // $placeholders = implode( ', ' , $_placeholders ); |
||||
87 | |||||
88 | krsort($_fields); |
||||
0 ignored issues
–
show
It seems like
$_fields can also be of type string ; however, parameter $array of krsort() does only seem to accept array , maybe add an additional type check?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() |
|||||
89 | // |
||||
90 | $fieldName = implode('`,`', array_keys($_fields)); |
||||
91 | $fieldValues = ':' . implode(',:', array_keys($_fields)); |
||||
92 | $this->_beginTransaction(); |
||||
93 | |||||
94 | $command = []; |
||||
95 | $command[] = 'INSERT INTO'; |
||||
96 | $command[] = $table; |
||||
97 | $command[] = '(' . $fieldName . ')'; |
||||
98 | $command[] = 'VALUES'; |
||||
99 | $command[] = '(' . $fieldValues . ')'; |
||||
100 | |||||
101 | // INSERT INTO {table} ({fields}) VALUES ({values}); |
||||
102 | // junta o comando |
||||
103 | $sql = implode( ' ' , $command ); |
||||
104 | |||||
105 | return $this->executeInsert( $sql , $values ); |
||||
0 ignored issues
–
show
Are you sure the usage of
$this->executeInsert($sql, $values) targeting Ballybran\Database\QueryBuilder::executeInsert() seems to always return null.
This check looks for function or method calls that always return null and whose return value is used. class A
{
function getObject()
{
return null;
}
}
$a = new A();
if ($a->getObject()) {
The method The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes. ![]() |
|||||
106 | } |
||||
107 | |||||
108 | /** |
||||
109 | * @param $values |
||||
110 | * @return string |
||||
111 | */ |
||||
112 | public function select($values = []) |
||||
113 | { |
||||
114 | // recupera o nome da tabela |
||||
115 | // ou deixa uma marcação para mostrar que faltou informar esse campo |
||||
116 | $table = isset( $this->clausules['table'] ) ? $this->clausules['table'] : '<table>'; |
||||
117 | |||||
118 | // recupera o array dos campos |
||||
119 | // ou deixa uma marcação para mostrar que faltou informar esse campo |
||||
120 | $_fields = isset( $this->clausules['fields'] ) ? $this->clausules['fields'] : '*'; |
||||
121 | $fields = implode( ', ' , $_fields ); |
||||
0 ignored issues
–
show
It seems like
$_fields can also be of type string ; however, parameter $pieces of implode() does only seem to accept array , maybe add an additional type check?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() |
|||||
122 | |||||
123 | $join = isset( $this->clausules['join'] ) ? $this->clausules['join'] : ''; |
||||
124 | |||||
125 | $command = []; |
||||
126 | $command[] = 'SELECT'; |
||||
127 | $command[] = $fields; |
||||
128 | $command[] = 'FROM'; |
||||
129 | $command[] = $table; |
||||
130 | if ($join) { |
||||
131 | $command[] = $join; |
||||
132 | } |
||||
133 | |||||
134 | $clausules = [ |
||||
135 | 'where' => [ |
||||
136 | 'instruction' => 'WHERE' , |
||||
137 | 'separator' => ' ' , |
||||
138 | ] , |
||||
139 | 'group' => [ |
||||
140 | 'instruction' => 'GROUP BY' , |
||||
141 | 'separator' => ', ' , |
||||
142 | ] , |
||||
143 | 'order' => [ |
||||
144 | 'instruction' => 'ORDER BY' , |
||||
145 | 'separator' => ', ' , |
||||
146 | ] , |
||||
147 | 'having' => [ |
||||
148 | 'instruction' => 'HAVING' , |
||||
149 | 'separator' => ' AND ' , |
||||
150 | ] , |
||||
151 | 'limit' => [ |
||||
152 | 'instruction' => 'LIMIT' , |
||||
153 | 'separator' => ',' , |
||||
154 | ] , |
||||
155 | ]; |
||||
156 | foreach ($clausules as $key => $clausule) { |
||||
157 | if (isset( $this->clausules[$key] )) { |
||||
158 | $value = $this->clausules[$key]; |
||||
159 | if (is_array( $value )) { |
||||
160 | $value = implode( $clausule['separator'] , $this->clausules[$key] ); |
||||
161 | } |
||||
162 | $command[] = $clausule['instruction'] . ' ' . $value; |
||||
163 | } |
||||
164 | } |
||||
165 | |||||
166 | // SELECT {fields} FROM <JOIN> {table} <WHERE> <GROUP> <ORDER> <HAVING> <LIMIT>; |
||||
167 | // junta o comando |
||||
168 | $sql = implode( ' ' , $command ); |
||||
169 | var_dump($sql); |
||||
0 ignored issues
–
show
|
|||||
170 | |||||
171 | return $this->executeSelect( $sql , $values ); |
||||
172 | } |
||||
173 | |||||
174 | /** |
||||
175 | * @return int |
||||
176 | */ |
||||
177 | public function update() |
||||
178 | { |
||||
179 | // recupera o nome da tabela |
||||
180 | // ou deixa uma marcação para mostrar que faltou informar esse campo |
||||
181 | $table = isset( $this->clausules['table'] ) ? $this->clausules['table'] : '<table>'; |
||||
182 | |||||
183 | $join = isset( $this->clausules['join'] ) ? $this->clausules['join'] : ''; |
||||
184 | |||||
185 | // recupera o array dos campos |
||||
186 | // ou deixa uma marcação para mostrar que faltou informar esse campo |
||||
187 | $_fields = isset( $this->clausules['fields'] ) ? $this->clausules['fields'] : '<fields>'; |
||||
188 | |||||
189 | |||||
190 | ksort($_fields); |
||||
0 ignored issues
–
show
It seems like
$_fields can also be of type string ; however, parameter $array of ksort() does only seem to accept array , maybe add an additional type check?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() |
|||||
191 | |||||
192 | $fielDetail = null; |
||||
193 | |||||
194 | foreach ($_fields as $key => $values) { |
||||
195 | $fielDetail .= "`$key`=:$key,"; |
||||
196 | } |
||||
197 | |||||
198 | $fielDetail = trim($fielDetail, ','); |
||||
0 ignored issues
–
show
It seems like
$fielDetail can also be of type null ; however, parameter $string of trim() does only seem to accept string , maybe add an additional type check?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() |
|||||
199 | |||||
200 | $command = []; |
||||
201 | $command[] = 'UPDATE'; |
||||
202 | $command[] = $table; |
||||
203 | if ($join) { |
||||
204 | $command[] = $join; |
||||
205 | } |
||||
206 | $command[] = 'SET'; |
||||
207 | $command[] = $fielDetail; |
||||
208 | |||||
209 | $clausules = [ |
||||
210 | 'where' => [ |
||||
211 | 'instruction' => 'WHERE' , |
||||
212 | 'separator' => ' ' , |
||||
213 | ], |
||||
214 | 'limit' => [ |
||||
215 | 'instruction' => 'LIMIT' , |
||||
216 | 'separator' => ',' , |
||||
217 | ] , |
||||
218 | ]; |
||||
219 | foreach ($clausules as $key => $clausule) { |
||||
220 | if (isset( $this->clausules[$key] )) { |
||||
221 | $value = $this->clausules[$key]; |
||||
222 | if (is_array( $value )) { |
||||
223 | $value = implode( $clausule['separator'] , $this->clausules[$key] ); |
||||
224 | } |
||||
225 | $command[] = $clausule['instruction'] . ' ' . $value; |
||||
226 | } |
||||
227 | } |
||||
228 | |||||
229 | // UPDATE {table} SET {set} <WHERE> |
||||
230 | // junta o comando |
||||
231 | $sql = implode( ' ' , $command ); |
||||
232 | |||||
233 | return $this->executeUpdate( $sql , $_fields ); |
||||
234 | } |
||||
235 | |||||
236 | /** |
||||
237 | * @param $filters |
||||
238 | * @return int |
||||
239 | */ |
||||
240 | public function delete($filters = null ) |
||||
241 | { |
||||
242 | // recupera o nome da tabela |
||||
243 | // ou deixa uma marcação para mostrar que faltou informar esse campo |
||||
244 | $table = isset( $this->clausules['table'] ) ? $this->clausules['table'] : '<table>'; |
||||
245 | |||||
246 | $join = isset( $this->clausules['join'] ) ? $this->clausules['join'] : ''; |
||||
247 | |||||
248 | $command = []; |
||||
249 | $command[] = 'DELETE FROM'; |
||||
250 | $command[] = $table; |
||||
251 | if ($join) { |
||||
252 | $command[] = $join; |
||||
253 | } |
||||
254 | |||||
255 | $clausules = [ |
||||
256 | 'where' => [ |
||||
257 | 'instruction' => 'WHERE' , |
||||
258 | 'separator' => ' ' , |
||||
259 | ], |
||||
260 | 'limit' => [ |
||||
261 | 'instruction' => 'LIMIT' , |
||||
262 | 'separator' => ',' , |
||||
263 | ] , |
||||
264 | |||||
265 | ]; |
||||
266 | foreach ($clausules as $key => $clausule) { |
||||
267 | if (isset( $this->clausules[$key] )) { |
||||
268 | $value = $this->clausules[$key]; |
||||
269 | if (is_array( $value )) { |
||||
270 | $value = implode( $clausule['separator'] , $this->clausules[$key] ); |
||||
271 | } |
||||
272 | $command[] = $clausule['instruction'] . ' ' . $value; |
||||
273 | } |
||||
274 | } |
||||
275 | |||||
276 | // DELETE FROM {table} <JOIN> <USING> <WHERE> |
||||
277 | // junta o comando |
||||
278 | $sql = implode( ' ' , $command ); |
||||
279 | |||||
280 | return $this->executeDelete( $sql , $filters ); |
||||
281 | } |
||||
282 | |||||
283 | private function executeSelect($sql , $value) |
||||
284 | { |
||||
285 | |||||
286 | $stmt = $this->conn->prepare( $sql ); |
||||
287 | |||||
288 | foreach ($value as $key => $values) { |
||||
289 | return $stmt->bindValue( "$key" , $values ); |
||||
290 | } |
||||
291 | $stmt->execute(); |
||||
292 | |||||
293 | do { |
||||
0 ignored issues
–
show
DoNode is not reachable.
This check looks for unreachable code. It uses sophisticated control flow analysis techniques to find statements which will never be executed. Unreachable code is most often the result of function fx() {
try {
doSomething();
return true;
}
catch (\Exception $e) {
return false;
}
return false;
}
In the above example, the last ![]() |
|||||
294 | return $stmt->fetchAll( $fetchMode ); |
||||
295 | } while ( |
||||
296 | $stmt->nextRowset()); |
||||
297 | $stmt->close(); |
||||
298 | |||||
299 | } |
||||
300 | |||||
301 | private function executeInsert($sql , $value) |
||||
302 | { |
||||
303 | try { |
||||
304 | |||||
305 | $this->_beginTransaction(); |
||||
306 | |||||
307 | $stmt = $this->conn->prepare($sql); |
||||
308 | foreach ($value as $key => $values) { |
||||
309 | $stmt->bindValue( ":$key" , $values ); |
||||
310 | } |
||||
311 | $this->_commit(); |
||||
312 | $stmt->execute(); |
||||
313 | unset( $stmt ); |
||||
314 | } catch (\Exception $e) { |
||||
315 | $this->_Rollback(); |
||||
316 | echo 'error insert ' . $e->getMessage(); |
||||
317 | } |
||||
318 | |||||
319 | } |
||||
320 | |||||
321 | |||||
322 | private function executeUpdate($sql , $data) |
||||
323 | { |
||||
324 | $stmt = $this->conn->prepare($sql); |
||||
325 | foreach ($data as $key => $values) { |
||||
326 | $stmt->bindValue(":$key", $values); |
||||
327 | } |
||||
328 | |||||
329 | return $stmt->execute(); |
||||
330 | } |
||||
331 | |||||
332 | private function executeDelete($sql , $value) |
||||
0 ignored issues
–
show
The parameter
$value is not used and could be removed.
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
This check looks for parameters that have been defined for a function or method, but which are not used in the method body. ![]() |
|||||
333 | { |
||||
334 | return $this->conn->exec($sql); |
||||
335 | |||||
336 | } |
||||
337 | } |