This project does not seem to handle request data directly as such no vulnerable execution paths were found.
include
, or for example
via PHP's auto-loading mechanism.
These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
1 | <?php |
||
2 | namespace Fwlib\Db; |
||
3 | |||
4 | use Fwlib\Bridge\Adodb; |
||
5 | use Fwlib\Util\UtilContainerAwareTrait; |
||
6 | |||
7 | /** |
||
8 | * Compare db data before and after write |
||
9 | * |
||
10 | * Diff data array format: |
||
11 | * {table: [{mode, 'pk': pk, 'column': column}]} |
||
12 | * |
||
13 | * mode is one of INSERT, DELETE, UPDATE. |
||
14 | * |
||
15 | * pk is array of primary key and their new/old value, format: |
||
16 | * {pk: {new, old}}. |
||
17 | * |
||
18 | * column is array of other columns changed, format: |
||
19 | * {column: {new, old}}. |
||
20 | * |
||
21 | * @deprecated |
||
22 | * |
||
23 | * @copyright Copyright 2012-2015 Fwolf |
||
24 | * @license http://www.gnu.org/licenses/lgpl.html LGPL-3.0+ |
||
25 | */ |
||
26 | class DbDiff |
||
27 | { |
||
28 | use UtilContainerAwareTrait; |
||
29 | |||
30 | |||
31 | /** |
||
32 | * Counter of DbDiff changed rows |
||
33 | * |
||
34 | * @var int |
||
35 | */ |
||
36 | protected $rowCount = 0; |
||
37 | |||
38 | /** |
||
39 | * @var Adodb |
||
40 | */ |
||
41 | protected $db = null; |
||
42 | |||
43 | /** |
||
44 | * Diff data array |
||
45 | * |
||
46 | * @var array |
||
47 | */ |
||
48 | protected $diff = []; |
||
49 | |||
50 | /** |
||
51 | * DbDiff execute status |
||
52 | * |
||
53 | * 0 not executed |
||
54 | * 100 committed |
||
55 | * -100 rollbacked |
||
56 | * |
||
57 | * @var int |
||
58 | */ |
||
59 | protected $executeStatus = 0; |
||
60 | |||
61 | |||
62 | /** |
||
63 | * Constructor |
||
64 | * |
||
65 | * @param Adodb $db |
||
66 | */ |
||
67 | public function __construct($db) |
||
68 | { |
||
69 | $this->db = $db; |
||
70 | } |
||
71 | |||
72 | |||
73 | /** |
||
74 | * Check PK array is valid or throw exception |
||
75 | * |
||
76 | * @param string $table |
||
77 | * @param array $pkArray |
||
78 | * @param array &$rowArray |
||
79 | */ |
||
80 | protected function checkPkArray($table, array $pkArray, array &$rowArray) |
||
81 | { |
||
82 | if (empty($pkArray)) { |
||
83 | throw new \Exception( |
||
84 | "Table $table must have PK defined" |
||
85 | ); |
||
86 | } |
||
87 | |||
88 | // array_intersect() is less loop than array_key_exist() check. |
||
89 | // Can't use isset when do array_key_exist(), bcs isset(null) == false |
||
90 | foreach ($rowArray as $index => &$row) { |
||
91 | if (count($pkArray) != |
||
92 | count(array_intersect($pkArray, array_keys($row))) |
||
93 | ) { |
||
94 | throw new \Exception( |
||
95 | "PK not all assigned in new array," . |
||
96 | " table $table index $index" |
||
97 | ); |
||
98 | } |
||
99 | } |
||
100 | unset($row); |
||
101 | } |
||
102 | |||
103 | |||
104 | /** |
||
105 | * Commit diff result, change db |
||
106 | * |
||
107 | * @return DbDiff |
||
108 | */ |
||
109 | View Code Duplication | public function commit() |
|
0 ignored issues
–
show
|
|||
110 | { |
||
111 | if (empty($this->diff)) { |
||
112 | throw new \Exception('No diff data'); |
||
113 | } |
||
114 | |||
115 | if ($this->isCommitted()) { |
||
116 | throw new \Exception( |
||
117 | 'Committed DbDiff can\'t commit again' |
||
118 | ); |
||
119 | } |
||
120 | |||
121 | $sqlArray = $this->generateCommitSql(); |
||
122 | |||
123 | $this->db->BeginTrans(); |
||
0 ignored issues
–
show
The method
BeginTrans does not exist on object<Fwlib\Bridge\Adodb> ? Since you implemented __call , maybe consider adding a @method annotation.
If you implement This is often the case, when class ParentClass {
private $data = array();
public function __call($method, array $args) {
if (0 === strpos($method, 'get')) {
return $this->data[strtolower(substr($method, 3))];
}
throw new \LogicException(sprintf('Unsupported method: %s', $method));
}
}
/**
* If this class knows which fields exist, you can specify the methods here:
*
* @method string getName()
*/
class SomeClass extends ParentClass { }
![]() |
|||
124 | |||
125 | try { |
||
126 | foreach ((array)$sqlArray as $sql) { |
||
127 | $this->db->execute($sql); |
||
128 | |||
129 | if (0 != $this->db->getErrorCode()) { |
||
130 | throw new \Exception($this->db->getErrorMessage()); |
||
131 | } |
||
132 | } |
||
133 | |||
134 | $this->db->CommitTrans(); |
||
0 ignored issues
–
show
The method
CommitTrans does not exist on object<Fwlib\Bridge\Adodb> ? Since you implemented __call , maybe consider adding a @method annotation.
If you implement This is often the case, when class ParentClass {
private $data = array();
public function __call($method, array $args) {
if (0 === strpos($method, 'get')) {
return $this->data[strtolower(substr($method, 3))];
}
throw new \LogicException(sprintf('Unsupported method: %s', $method));
}
}
/**
* If this class knows which fields exist, you can specify the methods here:
*
* @method string getName()
*/
class SomeClass extends ParentClass { }
![]() |
|||
135 | $this->rowCount = count($sqlArray); |
||
136 | $this->executeStatus = 100; |
||
137 | |||
138 | } catch (\Exception $e) { |
||
139 | $this->db->RollbackTrans(); |
||
0 ignored issues
–
show
The method
RollbackTrans does not exist on object<Fwlib\Bridge\Adodb> ? Since you implemented __call , maybe consider adding a @method annotation.
If you implement This is often the case, when class ParentClass {
private $data = array();
public function __call($method, array $args) {
if (0 === strpos($method, 'get')) {
return $this->data[strtolower(substr($method, 3))];
}
throw new \LogicException(sprintf('Unsupported method: %s', $method));
}
}
/**
* If this class knows which fields exist, you can specify the methods here:
*
* @method string getName()
*/
class SomeClass extends ParentClass { }
![]() |
|||
140 | |||
141 | throw new \Exception($e->getMessage()); |
||
142 | } |
||
143 | |||
144 | return $this; |
||
145 | } |
||
146 | |||
147 | |||
148 | /** |
||
149 | * Compare new data with old data in db |
||
150 | * |
||
151 | * New/old array are all assoc, index by table column. PK column must |
||
152 | * included in new array, but its value can be null. |
||
153 | * |
||
154 | * In new array, null PK value means DELETE operate. |
||
155 | * In old array, null PK value means INSERT operate. |
||
156 | * |
||
157 | * Multi table and row supported. |
||
158 | * |
||
159 | * New/old array format: |
||
160 | * {table: [{column: value}]} |
||
161 | * If only need to change a single row, can use simple format: |
||
162 | * {table: {column: value}} |
||
163 | * |
||
164 | * If old array is null, will read its value from db by Pk in new array. |
||
165 | * |
||
166 | * Row index in new/old array must match, it is used to connect same row |
||
167 | * in new and old data, so either use a meaningful row index, or use default |
||
168 | * integer index and keep same data order in new and old. |
||
169 | * |
||
170 | * @param array $dataNew |
||
171 | * @param array $dataOld |
||
172 | * @return DbDiff |
||
173 | */ |
||
174 | public function compare(array $dataNew, array $dataOld = null) |
||
175 | { |
||
176 | if (empty($dataNew)) { |
||
177 | throw new \Exception('New data array can\'t be empty'); |
||
178 | } |
||
179 | |||
180 | |||
181 | $diff = []; |
||
182 | foreach ($dataNew as $table => &$rowArrayNew) { |
||
183 | // Convert row array to 2-dim array |
||
184 | if (!is_array(current($rowArrayNew))) { |
||
185 | $rowArrayNew = [$rowArrayNew]; |
||
186 | } |
||
187 | |||
188 | $pkArray = (array)$this->db->getMetaPrimaryKey($table); |
||
189 | $this->checkPkArray($table, $pkArray, $rowArrayNew); |
||
190 | |||
191 | $diffOfTable = $this->compareTable( |
||
192 | $table, |
||
193 | $pkArray, |
||
194 | $rowArrayNew, |
||
195 | $dataOld |
||
196 | ); |
||
197 | |||
198 | if (!empty($diffOfTable)) { |
||
199 | $diff[$table] = $diffOfTable; |
||
200 | } |
||
201 | } |
||
202 | unset($rowArrayNew); |
||
203 | |||
204 | $this->diff = $diff; |
||
205 | |||
206 | return $this; |
||
207 | } |
||
208 | |||
209 | |||
210 | /** |
||
211 | * Compare different of a single row |
||
212 | * |
||
213 | * $rowNew MUST contain all PK columns. |
||
214 | * |
||
215 | * @param array &$rowNew |
||
216 | * @param array $pkArray |
||
217 | * @param array &$rowOld |
||
218 | * @return array |
||
219 | */ |
||
220 | protected function compareRow( |
||
221 | array &$rowNew, |
||
222 | array $pkArray, |
||
223 | array &$rowOld = null |
||
224 | ) { |
||
225 | $mode = $this->compareRowMode($rowNew, $pkArray, $rowOld); |
||
226 | |||
227 | $pkDiff = $this->compareRowPk($rowNew, $pkArray, $rowOld); |
||
228 | |||
229 | $columnArray = array_keys($rowNew); |
||
230 | if (!is_null($rowOld)) { |
||
231 | $columnArray = array_merge(array_keys($rowOld)); |
||
232 | } |
||
233 | $columnDiff = $this->compareRowColumn( |
||
234 | $mode, |
||
235 | $rowNew, |
||
236 | $columnArray, |
||
237 | $rowOld |
||
238 | ); |
||
239 | |||
240 | // UPDATE with no column change will be skipped |
||
241 | if ('UPDATE' == $mode && empty($columnDiff)) { |
||
242 | return null; |
||
243 | |||
244 | } else { |
||
245 | return [ |
||
246 | 'mode' => $mode, |
||
247 | 'pk' => $pkDiff, |
||
248 | 'column' => $columnDiff, |
||
249 | ]; |
||
250 | } |
||
251 | } |
||
252 | |||
253 | |||
254 | /** |
||
255 | * Compare column values, return diff array |
||
256 | * |
||
257 | * Pk column should be removed already. |
||
258 | * |
||
259 | * @param string $mode |
||
260 | * @param array &$rowNew |
||
261 | * @param array $columnArray |
||
262 | * @param array &$rowOld |
||
263 | * @return array |
||
264 | */ |
||
265 | protected function compareRowColumn( |
||
266 | $mode, |
||
267 | array &$rowNew, |
||
268 | array $columnArray, |
||
269 | array &$rowOld = null |
||
270 | ) { |
||
271 | $diff = []; |
||
272 | |||
273 | foreach ((array)$columnArray as $column) { |
||
274 | $valueNew = isset($rowNew[$column]) ? $rowNew[$column] : null; |
||
275 | $valueOld = isset($rowOld[$column]) ? $rowOld[$column] : null; |
||
276 | |||
277 | // Set useless column data to null. New value in DELETE mode is |
||
278 | // useless, and old value in INSERT mode is useless too. |
||
279 | if ('DELETE' == $mode) { |
||
280 | $valueNew = null; |
||
281 | } |
||
282 | if ('INSERT' == $mode) { |
||
283 | $valueOld = null; |
||
284 | } |
||
285 | |||
286 | // Skip equal value, they are not included in result diff array. |
||
287 | // Change between null and non-null value (include '' and 0, |
||
288 | // although they == null) will be kept. But 1 == '1' will be |
||
289 | // skipped, so not using === and check equal only if both value |
||
290 | // are not null. |
||
291 | if ((is_null($valueNew) && is_null($valueOld)) || |
||
292 | (!is_null($valueNew) && !is_null($valueOld) && |
||
293 | $valueNew == $valueOld) |
||
294 | ) { |
||
295 | continue; |
||
296 | } |
||
297 | |||
298 | $diff[$column] = [ |
||
299 | 'new' => $valueNew, |
||
300 | 'old' => $valueOld, |
||
301 | ]; |
||
302 | } |
||
303 | |||
304 | return $diff; |
||
305 | } |
||
306 | |||
307 | |||
308 | |||
309 | |||
310 | /** |
||
311 | * Get compare mode of a single row |
||
312 | * |
||
313 | * Mode: INSERT/UPDATE/DELETE |
||
314 | * |
||
315 | * Empty PK value are allowed, but null PK value will change mode flag and |
||
316 | * ignore other non-null pk column values. |
||
317 | * |
||
318 | * @param array &$rowNew |
||
319 | * @param array $pkArray |
||
320 | * @param array &$rowOld |
||
321 | * @return string |
||
322 | */ |
||
323 | protected function compareRowMode( |
||
324 | array &$rowNew, |
||
325 | array $pkArray, |
||
326 | array &$rowOld = null |
||
327 | ) { |
||
328 | $nullPkInNew = false; |
||
329 | $nullPkInOld = false; |
||
330 | |||
331 | foreach ($pkArray as $pk) { |
||
332 | if (is_null($rowNew[$pk])) { |
||
333 | $nullPkInNew = true; |
||
334 | } |
||
335 | if (!isset($rowOld[$pk]) || is_null($rowOld[$pk])) { |
||
336 | $nullPkInOld = true; |
||
337 | } |
||
338 | } |
||
339 | |||
340 | if ($nullPkInNew && !$nullPkInOld) { |
||
341 | $mode = 'DELETE'; |
||
342 | } elseif (!$nullPkInNew && $nullPkInOld) { |
||
343 | $mode = 'INSERT'; |
||
344 | } elseif (!$nullPkInNew && !$nullPkInOld) { |
||
345 | $mode = 'UPDATE'; |
||
346 | } else { |
||
347 | throw new \Exception( |
||
348 | 'Pk in new and old array are all null' |
||
349 | ); |
||
350 | } |
||
351 | |||
352 | return $mode; |
||
353 | } |
||
354 | |||
355 | |||
356 | /** |
||
357 | * Compare and extract PK values, return diff array |
||
358 | * |
||
359 | * Pk column are removed from new and old row columns. |
||
360 | * |
||
361 | * @param array &$rowNew |
||
362 | * @param array $pkArray |
||
363 | * @param array &$rowOld |
||
364 | * @return array |
||
365 | */ |
||
366 | protected function compareRowPk( |
||
367 | array &$rowNew, |
||
368 | array $pkArray, |
||
369 | array &$rowOld = null |
||
370 | ) { |
||
371 | $diff = []; |
||
372 | |||
373 | foreach ($pkArray as $pk) { |
||
374 | $diff[$pk] = [ |
||
375 | 'new' => $rowNew[$pk], |
||
376 | 'old' => isset($rowOld[$pk]) ? $rowOld[$pk] : null, |
||
377 | ]; |
||
378 | |||
379 | unset($rowNew[$pk]); |
||
380 | unset($rowOld[$pk]); |
||
381 | } |
||
382 | |||
383 | return $diff; |
||
384 | } |
||
385 | |||
386 | |||
387 | /** |
||
388 | * Compare different for a single table |
||
389 | * |
||
390 | * @param string $table |
||
391 | * @param array $pkArray |
||
392 | * @param array &$rowArrayNew |
||
393 | * @param array &$dataOld |
||
394 | * @return array |
||
395 | */ |
||
396 | protected function compareTable( |
||
397 | $table, |
||
398 | array $pkArray, |
||
399 | array &$rowArrayNew, |
||
400 | array &$dataOld = null |
||
401 | ) { |
||
402 | $diff = []; |
||
403 | foreach ($rowArrayNew as $index => &$rowNew) { |
||
404 | $columnArray = array_keys($rowNew); |
||
405 | $pkValueArray = array_intersect_key( |
||
406 | $rowNew, |
||
407 | array_fill_keys($pkArray, null) |
||
408 | ); |
||
409 | |||
410 | $rowOld = $this->prepareRowOld( |
||
411 | $table, |
||
412 | $index, |
||
413 | $pkValueArray, |
||
414 | $columnArray, |
||
415 | $pkArray, |
||
416 | $dataOld |
||
417 | ); |
||
418 | |||
419 | $diffOfRow = $this->compareRow($rowNew, $pkArray, $rowOld); |
||
420 | if (!empty($diffOfRow)) { |
||
421 | $diff[] = $diffOfRow; |
||
422 | } |
||
423 | } |
||
424 | unset($rowOld); |
||
425 | |||
426 | return $diff; |
||
427 | } |
||
428 | |||
429 | |||
430 | /** |
||
431 | * Compare and commit diff result |
||
432 | * |
||
433 | * If $dataNew is null, will use internal stored $diff. |
||
434 | * |
||
435 | * @param array $dataNew |
||
436 | * @param array $dataOld |
||
437 | * @return DbDiff |
||
438 | */ |
||
439 | public function execute(array $dataNew = null, array $dataOld = null) |
||
440 | { |
||
441 | if (!is_null($dataNew)) { |
||
442 | $this->reset(); |
||
443 | $this->compare($dataNew, $dataOld); |
||
444 | } |
||
445 | |||
446 | if (!$this->isExecuted()) { |
||
447 | $this->commit(); |
||
448 | |||
449 | } else { |
||
450 | throw new \Exception( |
||
451 | 'Committed or rollbacked DbDiff can\'t execute again' |
||
452 | ); |
||
453 | } |
||
454 | |||
455 | return $this; |
||
456 | } |
||
457 | |||
458 | |||
459 | /** |
||
460 | * Export to json string |
||
461 | * |
||
462 | * @return string |
||
463 | */ |
||
464 | public function export() |
||
465 | { |
||
466 | $json = $this->getUtilContainer()->getJson(); |
||
467 | |||
468 | return $json->encodeUnicode( |
||
469 | [ |
||
470 | 'rowCount' => $this->rowCount, |
||
471 | 'executeStatus' => $this->executeStatus, |
||
472 | 'diff' => $this->diff, |
||
473 | ] |
||
474 | ); |
||
475 | } |
||
476 | |||
477 | |||
478 | /** |
||
479 | * Generate commit sql array from diff result |
||
480 | * |
||
481 | * @return array |
||
482 | */ |
||
483 | View Code Duplication | protected function generateCommitSql() |
|
0 ignored issues
–
show
This method seems to be duplicated in your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
|||
484 | { |
||
485 | $sqlArray = []; |
||
486 | $db = $this->db; |
||
487 | |||
488 | foreach ($this->diff as $table => $rowArray) { |
||
489 | foreach ((array)$rowArray as $index => $row) { |
||
490 | $sqlConfig = []; |
||
491 | |||
492 | switch ($row['mode']) { |
||
493 | case 'INSERT': |
||
494 | $sqlConfig['INSERT'] = $table; |
||
495 | |||
496 | $columnArray = $row['pk'] + $row['column']; |
||
497 | foreach ($columnArray as $k => $v) { |
||
498 | $sqlConfig['VALUES'][$k] = $v['new']; |
||
499 | } |
||
500 | |||
501 | break; |
||
502 | |||
503 | case 'DELETE': |
||
504 | $sqlConfig['DELETE'] = $table; |
||
505 | // Limit row count to 1 for safety |
||
506 | $sqlConfig['LIMIT'] = 1; |
||
507 | |||
508 | foreach ($row['pk'] as $k => $v) { |
||
509 | $sqlConfig['WHERE'][] = $k . ' = ' . |
||
510 | $db->quoteValue($table, $k, $v['old']); |
||
511 | } |
||
512 | |||
513 | break; |
||
514 | |||
515 | case 'UPDATE': |
||
516 | $sqlConfig['UPDATE'] = $table; |
||
517 | // Limit row count to 1 for safety |
||
518 | $sqlConfig['LIMIT'] = 1; |
||
519 | |||
520 | foreach ($row['column'] as $k => $v) { |
||
521 | $sqlConfig['SET'][$k] = $v['new']; |
||
522 | } |
||
523 | |||
524 | foreach ($row['pk'] as $k => $v) { |
||
525 | $sqlConfig['WHERE'][] = $k . ' = ' . |
||
526 | $db->quoteValue($table, $k, $v['new']); |
||
527 | } |
||
528 | |||
529 | break; |
||
530 | |||
531 | default: |
||
532 | throw new \Exception("Invalid mode {$row['mode']}"); |
||
533 | } |
||
534 | |||
535 | $sqlArray[] = $db->generateSql($sqlConfig); |
||
536 | } |
||
537 | } |
||
538 | |||
539 | return $sqlArray; |
||
540 | } |
||
541 | |||
542 | |||
543 | /** |
||
544 | * Generate rollback sql array from diff result |
||
545 | * |
||
546 | * @return array |
||
547 | */ |
||
548 | View Code Duplication | protected function generateRollbackSql() |
|
0 ignored issues
–
show
This method seems to be duplicated in your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
|||
549 | { |
||
550 | $sqlArray = []; |
||
551 | $db = $this->db; |
||
552 | |||
553 | foreach ($this->diff as $table => $rowArray) { |
||
554 | foreach ((array)$rowArray as $index => $row) { |
||
555 | $sqlConfig = []; |
||
556 | |||
557 | switch ($row['mode']) { |
||
558 | case 'INSERT': |
||
559 | $sqlConfig['DELETE'] = $table; |
||
560 | // Limit row count to 1 for safety |
||
561 | $sqlConfig['LIMIT'] = 1; |
||
562 | |||
563 | foreach ($row['pk'] as $k => $v) { |
||
564 | $sqlConfig['WHERE'][] = $k . ' = ' . |
||
565 | $db->quoteValue($table, $k, $v['new']); |
||
566 | } |
||
567 | |||
568 | break; |
||
569 | |||
570 | case 'DELETE': |
||
571 | $sqlConfig['INSERT'] = $table; |
||
572 | |||
573 | $columnArray = $row['pk'] + $row['column']; |
||
574 | foreach ($columnArray as $k => $v) { |
||
575 | $sqlConfig['VALUES'][$k] = $v['old']; |
||
576 | } |
||
577 | |||
578 | break; |
||
579 | |||
580 | case 'UPDATE': |
||
581 | $sqlConfig['UPDATE'] = $table; |
||
582 | // Limit row count to 1 for safety |
||
583 | $sqlConfig['LIMIT'] = 1; |
||
584 | |||
585 | foreach ($row['column'] as $k => $v) { |
||
586 | $sqlConfig['SET'][$k] = $v['old']; |
||
587 | } |
||
588 | |||
589 | foreach ($row['pk'] as $k => $v) { |
||
590 | $sqlConfig['WHERE'][] = $k . ' = ' . |
||
591 | $db->quoteValue($table, $k, $v['old']); |
||
592 | } |
||
593 | |||
594 | break; |
||
595 | |||
596 | default: |
||
597 | throw new \Exception("Invalid mode {$row['mode']}"); |
||
598 | } |
||
599 | |||
600 | $sqlArray[] = $db->generateSql($sqlConfig); |
||
601 | } |
||
602 | } |
||
603 | |||
604 | return $sqlArray; |
||
605 | } |
||
606 | |||
607 | |||
608 | /** |
||
609 | * Getter of $diff |
||
610 | * |
||
611 | * @return array |
||
612 | */ |
||
613 | public function getDiff() |
||
614 | { |
||
615 | return $this->diff; |
||
616 | } |
||
617 | |||
618 | |||
619 | /** |
||
620 | * Getter of $rowCount |
||
621 | * |
||
622 | * @return int |
||
623 | */ |
||
624 | public function getRowCount() |
||
625 | { |
||
626 | return $this->rowCount; |
||
627 | } |
||
628 | |||
629 | |||
630 | /** |
||
631 | * Import from a json string |
||
632 | * |
||
633 | * Notice: Import empty string will report error. |
||
634 | * |
||
635 | * @param string $json |
||
636 | * @return DbDiff |
||
637 | */ |
||
638 | public function import($json) |
||
639 | { |
||
640 | $this->reset(); |
||
641 | |||
642 | $info = $this->getUtilContainer()->getJson() |
||
643 | ->decode($json, true); |
||
644 | |||
645 | try { |
||
646 | $this->rowCount = $info['rowCount']; |
||
647 | $this->executeStatus = $info['executeStatus']; |
||
648 | $this->diff = $info['diff']; |
||
649 | |||
650 | } catch (\Exception $e) { |
||
651 | throw new \Exception( |
||
652 | 'Invalid json string to import: ' . $e->getMessage() |
||
653 | ); |
||
654 | } |
||
655 | |||
656 | return $this; |
||
657 | } |
||
658 | |||
659 | |||
660 | /** |
||
661 | * Is DbDiff executed/committed ? |
||
662 | * |
||
663 | * @return bool |
||
664 | */ |
||
665 | public function isCommitted() |
||
666 | { |
||
667 | return 100 == $this->executeStatus; |
||
668 | } |
||
669 | |||
670 | |||
671 | /** |
||
672 | * Is DbDiff executed ? |
||
673 | * |
||
674 | * Return true when committed or rollbacked. |
||
675 | * |
||
676 | * @return bool |
||
677 | */ |
||
678 | public function isExecuted() |
||
679 | { |
||
680 | return 0 != $this->executeStatus; |
||
681 | } |
||
682 | |||
683 | |||
684 | /** |
||
685 | * Is DbDiff rollbacked ? |
||
686 | * |
||
687 | * @return bool |
||
688 | */ |
||
689 | public function isRollbacked() |
||
690 | { |
||
691 | return -100 == $this->executeStatus; |
||
692 | } |
||
693 | |||
694 | |||
695 | /** |
||
696 | * Prepare a single old row for compare |
||
697 | * |
||
698 | * If old row are not set, will query db using pk value from new row, |
||
699 | * return null for not exists(INSERT mode). |
||
700 | * |
||
701 | * Also convert old row array to 2-dim. |
||
702 | * |
||
703 | * @param string $table |
||
704 | * @param int|string $index |
||
705 | * @param array $pkValueArray |
||
0 ignored issues
–
show
There is no parameter named
$pkValueArray . Was it maybe removed?
This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function. Consider the following example. The parameter /**
* @param array $germany
* @param array $island
* @param array $italy
*/
function finale($germany, $island) {
return "2:1";
}
The most likely cause is that the parameter was removed, but the annotation was not. ![]() |
|||
706 | * @param array $columnArray |
||
707 | * @param array $pkArray |
||
0 ignored issues
–
show
There is no parameter named
$pkArray . Was it maybe removed?
This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function. Consider the following example. The parameter /**
* @param array $germany
* @param array $island
* @param array $italy
*/
function finale($germany, $island) {
return "2:1";
}
The most likely cause is that the parameter was removed, but the annotation was not. ![]() |
|||
708 | * @param array &$dataOld |
||
709 | * @return array |
||
710 | */ |
||
711 | protected function prepareRowOld( |
||
712 | $table, |
||
713 | $index, |
||
714 | array $keyValueArray, |
||
715 | array $columnArray, |
||
716 | array $keyArray, |
||
717 | array &$dataOld = null |
||
718 | ) { |
||
719 | // Convert to 2-dim array |
||
720 | if (isset($dataOld[$table]) && !is_array(current($dataOld[$table]))) { |
||
721 | $dataOld[$table] = [$dataOld[$table]]; |
||
722 | } |
||
723 | |||
724 | if (isset($dataOld[$table][$index])) { |
||
725 | return $dataOld[$table][$index]; |
||
726 | } |
||
727 | |||
728 | // Need query from db |
||
729 | $rs = $this->db->getByKey( |
||
730 | $table, |
||
731 | $keyValueArray, |
||
0 ignored issues
–
show
$keyValueArray is of type array , but the function expects a integer|string .
It seems like the type of the argument is not accepted by the function/method which you are calling. In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug. We suggest to add an explicit type cast like in the following example: function acceptsInteger($int) { }
$x = '123'; // string "123"
// Instead of
acceptsInteger($x);
// we recommend to use
acceptsInteger((integer) $x);
![]() |
|||
732 | $columnArray, |
||
733 | $keyArray |
||
734 | ); |
||
735 | |||
736 | // If row only have one column, convert back to array |
||
737 | $rs = is_null($rs) ? $rs : (array)$rs; |
||
738 | |||
739 | return $rs; |
||
740 | } |
||
741 | |||
742 | |||
743 | /** |
||
744 | * Reset code, message and flag |
||
745 | * |
||
746 | * @return DbDiff |
||
747 | */ |
||
748 | public function reset() |
||
749 | { |
||
750 | $this->rowCount = 0; |
||
751 | $this->executeStatus = 0; |
||
752 | $this->diff = []; |
||
753 | |||
754 | return $this; |
||
755 | } |
||
756 | |||
757 | |||
758 | /** |
||
759 | * Rollback committed diff result |
||
760 | * |
||
761 | * @return DbDiff |
||
762 | */ |
||
763 | View Code Duplication | public function rollback() |
|
0 ignored issues
–
show
This method seems to be duplicated in your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
|||
764 | { |
||
765 | if (empty($this->diff)) { |
||
766 | throw new \Exception('No diff data'); |
||
767 | } |
||
768 | |||
769 | if ($this->isRollbacked()) { |
||
770 | throw new \Exception( |
||
771 | 'Rollbacked DbDiff can\'t rollback again' |
||
772 | ); |
||
773 | } |
||
774 | |||
775 | $sqlArray = $this->generateRollbackSql(); |
||
776 | |||
777 | $this->db->BeginTrans(); |
||
0 ignored issues
–
show
The method
BeginTrans does not exist on object<Fwlib\Bridge\Adodb> ? Since you implemented __call , maybe consider adding a @method annotation.
If you implement This is often the case, when class ParentClass {
private $data = array();
public function __call($method, array $args) {
if (0 === strpos($method, 'get')) {
return $this->data[strtolower(substr($method, 3))];
}
throw new \LogicException(sprintf('Unsupported method: %s', $method));
}
}
/**
* If this class knows which fields exist, you can specify the methods here:
*
* @method string getName()
*/
class SomeClass extends ParentClass { }
![]() |
|||
778 | |||
779 | try { |
||
780 | foreach ((array)$sqlArray as $sql) { |
||
781 | $this->db->execute($sql); |
||
782 | |||
783 | if (0 != $this->db->getErrorCode()) { |
||
784 | throw new \Exception($this->db->getErrorMessage()); |
||
785 | } |
||
786 | } |
||
787 | |||
788 | $this->db->CommitTrans(); |
||
0 ignored issues
–
show
The method
CommitTrans does not exist on object<Fwlib\Bridge\Adodb> ? Since you implemented __call , maybe consider adding a @method annotation.
If you implement This is often the case, when class ParentClass {
private $data = array();
public function __call($method, array $args) {
if (0 === strpos($method, 'get')) {
return $this->data[strtolower(substr($method, 3))];
}
throw new \LogicException(sprintf('Unsupported method: %s', $method));
}
}
/**
* If this class knows which fields exist, you can specify the methods here:
*
* @method string getName()
*/
class SomeClass extends ParentClass { }
![]() |
|||
789 | // Rollback operate doesn't change $rowCount |
||
790 | $this->executeStatus = -100; |
||
791 | |||
792 | } catch (\Exception $e) { |
||
793 | $this->db->RollbackTrans(); |
||
0 ignored issues
–
show
The method
RollbackTrans does not exist on object<Fwlib\Bridge\Adodb> ? Since you implemented __call , maybe consider adding a @method annotation.
If you implement This is often the case, when class ParentClass {
private $data = array();
public function __call($method, array $args) {
if (0 === strpos($method, 'get')) {
return $this->data[strtolower(substr($method, 3))];
}
throw new \LogicException(sprintf('Unsupported method: %s', $method));
}
}
/**
* If this class knows which fields exist, you can specify the methods here:
*
* @method string getName()
*/
class SomeClass extends ParentClass { }
![]() |
|||
794 | |||
795 | throw new \Exception($e->getMessage()); |
||
796 | } |
||
797 | |||
798 | return $this; |
||
799 | } |
||
800 | } |
||
801 |
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.
You can also find more detailed suggestions in the “Code” section of your repository.