1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
namespace Napp\Core\Dbal\Builder; |
4
|
|
|
|
5
|
|
|
use Illuminate\Database\Grammar; |
6
|
|
|
use Illuminate\Database\Query\Builder; |
7
|
|
|
|
8
|
|
|
/** |
9
|
|
|
* Class ReplaceIntoBuilder. |
10
|
|
|
*/ |
11
|
|
|
class ReplaceIntoBuilder |
12
|
|
|
{ |
13
|
|
|
/** |
14
|
|
|
* @return \Closure |
15
|
|
|
*/ |
16
|
|
|
public function replace() |
17
|
|
|
{ |
18
|
|
|
return function (array $values) { |
19
|
|
|
|
20
|
|
|
/* @var Builder $this */ |
21
|
|
|
|
22
|
|
|
if (empty($values)) { |
23
|
|
|
return true; |
24
|
|
|
} |
25
|
|
|
|
26
|
|
|
// Since every insert gets treated like a batch insert, we will make sure the |
27
|
|
|
// bindings are structured in a way that is convenient for building these |
28
|
|
|
// inserts statements by verifying the elements are actually an array. |
29
|
|
View Code Duplication |
if (!\is_array(reset($values))) { |
|
|
|
|
30
|
|
|
$values = [$values]; |
31
|
|
|
} |
32
|
|
|
|
33
|
|
|
// Since every insert gets treated like a batch insert, we will make sure the |
34
|
|
|
// bindings are structured in a way that is convenient for building these |
35
|
|
|
// inserts statements by verifying the elements are actually an array. |
36
|
|
|
else { |
37
|
|
|
foreach ($values as $key => $value) { |
38
|
|
|
ksort($value); |
39
|
|
|
$values[$key] = $value; |
40
|
|
|
} |
41
|
|
|
} |
42
|
|
|
// We'll treat every insert like a batch insert so we can easily insert each |
43
|
|
|
// of the records into the database consistently. This will make it much |
44
|
|
|
// easier on the grammars to just handle one type of record insertion. |
45
|
|
|
$bindings = []; |
46
|
|
|
|
47
|
|
|
foreach ($values as $record) { |
48
|
|
|
foreach ($record as $value) { |
49
|
|
|
$bindings[] = $value; |
50
|
|
|
} |
51
|
|
|
} |
52
|
|
|
|
53
|
|
|
$sql = $this->compileReplace($values); |
|
|
|
|
54
|
|
|
|
55
|
|
|
// Once we have compiled the insert statement's SQL we can execute it on the |
56
|
|
|
// connection and return a result as a boolean success indicator as that |
57
|
|
|
// is the same type of result returned by the raw connection instance. |
58
|
|
|
$bindings = $this->cleanBindings($bindings); |
|
|
|
|
59
|
|
|
|
60
|
|
|
return $this->connection->insert($sql, $bindings); |
|
|
|
|
61
|
|
|
}; |
62
|
|
|
} |
63
|
|
|
|
64
|
|
|
/** |
65
|
|
|
* @param Builder $query |
|
|
|
|
66
|
|
|
* @param Grammar $grammar |
|
|
|
|
67
|
|
|
* @param array $values |
|
|
|
|
68
|
|
|
* |
69
|
|
|
* @return string |
70
|
|
|
*/ |
71
|
|
|
public static function compileReplace() |
72
|
|
|
{ |
73
|
|
|
return function (array $values) { |
74
|
|
|
$grammar = $this->getGrammar(); |
|
|
|
|
75
|
|
|
// Essentially we will force every insert to be treated as a batch insert which |
76
|
|
|
// simply makes creating the SQL easier for us since we can utilize the same |
77
|
|
|
// basic routine regardless of an amount of records given to us to insert. |
78
|
|
|
$table = $grammar->wrapTable($this->from); |
|
|
|
|
79
|
|
|
|
80
|
|
|
if (!\is_array(reset($values))) { |
81
|
|
|
$values = [$values]; |
82
|
|
|
} |
83
|
|
|
|
84
|
|
|
$columns = $grammar->columnize(array_keys(reset($values))); |
85
|
|
|
|
86
|
|
|
// We need to build a list of parameter place-holders of values that are bound |
87
|
|
|
// to the query. Each insert should have the exact same amount of parameter |
88
|
|
|
// bindings so we will loop through the record and parameterize them all. |
89
|
|
|
$parameters = []; |
90
|
|
|
|
91
|
|
|
foreach ($values as $record) { |
92
|
|
|
$parameters[] = '('.$grammar->parameterize($record).')'; |
93
|
|
|
} |
94
|
|
|
|
95
|
|
|
$parameters = implode(', ', $parameters); |
96
|
|
|
|
97
|
|
|
return "replace into {$table} ({$columns}) values {$parameters}"; |
98
|
|
|
}; |
99
|
|
|
} |
100
|
|
|
} |
101
|
|
|
|
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.