1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
namespace League\Database\BulkSql; |
4
|
|
|
|
5
|
|
|
use PDOStatement; |
6
|
|
|
use League\Database\Traits\BulkSqlTrait; |
7
|
|
|
use League\Database\Exceptions\LogicException; |
8
|
|
|
|
9
|
|
|
class BulkInsert extends Base |
10
|
|
|
{ |
11
|
|
|
use BulkSqlTrait; |
12
|
|
|
|
13
|
|
|
private $onDuplicateUpdate = []; |
14
|
|
|
|
15
|
|
|
const QUERY_TEMPLATE = 'INSERT %s INTO %s (%s) VALUES %s %s'; |
16
|
|
|
|
17
|
|
View Code Duplication |
protected function buildQuery() : string |
|
|
|
|
18
|
|
|
{ |
19
|
|
|
$this->resetFields(); |
20
|
|
|
$this->resetPreparedItems(); |
21
|
|
|
|
22
|
|
|
$queryParams = $this->iterateOverItems($this->getPreparedItems(), function ($iteration) { |
23
|
|
|
$prepared = array_map(function ($field, $key) use ($iteration) { |
24
|
|
|
if (in_array($field, $this->getIgnoredColumn(), true)) { |
25
|
|
|
return $this->getPreparedItems()[$iteration][$field] ?? $this->getPreparedItems()[$iteration][$key]; |
26
|
|
|
} |
27
|
|
|
|
28
|
|
|
return ':'.$field.'_'.$iteration; |
29
|
|
|
}, $this->getFields(), array_keys($this->getFields())); |
30
|
|
|
|
31
|
|
|
return '('.implode(',', $prepared).')'; |
32
|
|
|
}); |
33
|
|
|
|
34
|
|
|
$fields = array_map(function ($field) { |
35
|
|
|
return "`{$field}`"; |
36
|
|
|
}, $this->getFields()); |
37
|
|
|
|
38
|
|
|
return sprintf( |
39
|
|
|
self::QUERY_TEMPLATE, |
40
|
|
|
($this->isIgnoreUsed() ? 'IGNORE' : ''), |
41
|
|
|
$this->getTable(), |
42
|
|
|
implode(',', $fields), |
43
|
|
|
implode(',', $queryParams), |
44
|
|
|
$this->getOnDuplicateUpdateRow() |
45
|
|
|
); |
46
|
|
|
} |
47
|
|
|
|
48
|
|
View Code Duplication |
protected function bindValues(PDOStatement $statement) |
|
|
|
|
49
|
|
|
{ |
50
|
|
|
$this->resetFields(); |
51
|
|
|
$this->resetPreparedItems(); |
52
|
|
|
|
53
|
|
|
$this->iterateOverItems($this->getPreparedItems(), function ($iteration) use ($statement) { |
54
|
|
|
foreach ($this->getFields() as $key => $field) { |
55
|
|
|
if (in_array($field, $this->getIgnoredColumn(), true)) { |
56
|
|
|
return; |
57
|
|
|
} |
58
|
|
|
$value = $this->getPreparedItems()[$iteration][$field] ?? $this->getPreparedItems()[$iteration][$key]; |
59
|
|
|
$statement->bindValue(':'.$field.'_'.$iteration, $value); |
60
|
|
|
} |
61
|
|
|
}); |
62
|
|
|
} |
63
|
|
|
|
64
|
|
|
public function addOnDuplicateUpdateStatement(array $array) |
65
|
|
|
{ |
66
|
|
|
if (!array_is_assoc($array)) { |
67
|
|
|
throw new LogicException('ON DUPLICATE UPDATE setter should take associative array'); |
68
|
|
|
} elseif (array_depth($array) !== 1) { |
69
|
|
|
throw new LogicException('ON DUPLICATE UPDATE setter should take one depth array'); |
70
|
|
|
} |
71
|
|
|
|
72
|
|
|
$this->onDuplicateUpdate += $array; |
73
|
|
|
} |
74
|
|
|
|
75
|
|
|
public function resetOnDuplicateUpdateStatement() : self |
76
|
|
|
{ |
77
|
|
|
$this->onDuplicateUpdate = []; |
78
|
|
|
|
79
|
|
|
return $this; |
80
|
|
|
} |
81
|
|
|
|
82
|
|
|
private function getOnDuplicateUpdateRow() : string |
83
|
|
|
{ |
84
|
|
|
if (!$this->onDuplicateUpdate) { |
|
|
|
|
85
|
|
|
return ''; |
86
|
|
|
} |
87
|
|
|
|
88
|
|
|
return ' ON DUPLICATE KEY UPDATE ' . implode(', ', array_map(function ($key, $value) { |
89
|
|
|
return "$key = $value"; |
90
|
|
|
}, array_keys($this->onDuplicateUpdate), $this->onDuplicateUpdate)); |
91
|
|
|
} |
92
|
|
|
} |
93
|
|
|
|
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.