1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
namespace CloudyCity\LaravelBuilderMacros\Library\Database\Query\Grammars; |
4
|
|
|
|
5
|
|
|
use CloudyCity\LaravelBuilderMacros\Library\Database\Query\MySqlBuilder as Builder; |
6
|
|
|
use Illuminate\Database\Query\Grammars\MySqlGrammar as Grammar; |
7
|
|
|
|
8
|
|
|
class MySqlGrammar extends Grammar |
9
|
|
|
{ |
10
|
|
|
/** |
11
|
|
|
* Compile a replace into statement into SQL. |
12
|
|
|
* |
13
|
|
|
* @link https://dev.mysql.com/doc/refman/5.5/en/replace.html |
14
|
|
|
* |
15
|
|
|
* @param \CloudyCity\LaravelBuilderMacros\Library\Database\Query\MySqlBuilder $query |
16
|
|
|
* @param array $data |
17
|
|
|
* @return string |
18
|
|
|
*/ |
19
|
|
View Code Duplication |
public function compileReplace(Builder $query, array $data) |
|
|
|
|
20
|
|
|
{ |
21
|
|
|
// Essentially we will force every insert to be treated as a batch insert which |
22
|
|
|
// simply makes creating the SQL easier for us since we can utilize the same |
23
|
|
|
// basic routine regardless of an amount of records given to us to insert. |
24
|
|
|
$table = $this->wrapTable($query->from); |
25
|
|
|
|
26
|
|
|
if (! is_array(reset($data))) { |
27
|
|
|
$data = [$data]; |
28
|
|
|
} |
29
|
|
|
|
30
|
|
|
$columns = $this->columnize(array_keys(reset($data))); |
31
|
|
|
|
32
|
|
|
// We need to build a list of parameter place-holders of values that are bound |
33
|
|
|
// to the query. Each insert should have the exact same amount of parameter |
34
|
|
|
// bindings so we will loop through the record and parameterize them all. |
35
|
|
|
$values = []; |
36
|
|
|
|
37
|
|
|
foreach ($data as $record) { |
38
|
|
|
$values[] = '('.$this->parameterize($record).')'; |
39
|
|
|
} |
40
|
|
|
|
41
|
|
|
$values = implode(', ', $values); |
42
|
|
|
|
43
|
|
|
return "REPLACE INTO {$table} ({$columns}) VALUES {$values}"; |
44
|
|
|
} |
45
|
|
|
|
46
|
|
|
/** |
47
|
|
|
* Compile an insert ignore statement into SQL. |
48
|
|
|
* |
49
|
|
|
* @link https://dev.mysql.com/doc/refman/5.5/en/insert.html |
50
|
|
|
* |
51
|
|
|
* @param \CloudyCity\LaravelBuilderMacros\Library\Database\Query\MySqlBuilder $query |
52
|
|
|
* @param array $data |
53
|
|
|
* @return string |
54
|
|
|
*/ |
55
|
|
View Code Duplication |
public function compileInsertIgnore(Builder $query, array $data) |
|
|
|
|
56
|
|
|
{ |
57
|
|
|
// Essentially we will force every insert to be treated as a batch insert which |
58
|
|
|
// simply makes creating the SQL easier for us since we can utilize the same |
59
|
|
|
// basic routine regardless of an amount of records given to us to insert. |
60
|
|
|
$table = $this->wrapTable($query->from); |
61
|
|
|
|
62
|
|
|
if (! is_array(reset($data))) { |
63
|
|
|
$data = [$data]; |
64
|
|
|
} |
65
|
|
|
|
66
|
|
|
$columns = $this->columnize(array_keys(reset($data))); |
67
|
|
|
|
68
|
|
|
// We need to build a list of parameter place-holders of values that are bound |
69
|
|
|
// to the query. Each insert should have the exact same amount of parameter |
70
|
|
|
// bindings so we will loop through the record and parameterize them all. |
71
|
|
|
$values = []; |
72
|
|
|
|
73
|
|
|
foreach ($data as $record) { |
74
|
|
|
$values[] = '('.$this->parameterize($record).')'; |
75
|
|
|
} |
76
|
|
|
|
77
|
|
|
$values = implode(', ', $values); |
78
|
|
|
|
79
|
|
|
return "INSERT IGNORE INTO {$table} ({$columns}) VALUES {$values}"; |
80
|
|
|
} |
81
|
|
|
|
82
|
|
|
/** |
83
|
|
|
* Compile an insert update statement into SQL. |
84
|
|
|
* |
85
|
|
|
* @link https://dev.mysql.com/doc/refman/8.0/en/insert-on-duplicate.html |
86
|
|
|
* @link https://gist.github.com/RuGa/5354e44883c7651fd15c |
87
|
|
|
* |
88
|
|
|
* @param \CloudyCity\LaravelBuilderMacros\Library\Database\Query\MySqlBuilder $query |
89
|
|
|
* @param array $data |
90
|
|
|
* @return string |
91
|
|
|
*/ |
92
|
|
|
public function compileInsertUpdate(Builder $query, array $data) |
93
|
|
|
{ |
94
|
|
|
// Essentially we will force every insert to be treated as a batch insert which |
95
|
|
|
// simply makes creating the SQL easier for us since we can utilize the same |
96
|
|
|
// basic routine regardless of an amount of records given to us to insert. |
97
|
|
|
$table = $this->wrapTable($query->from); |
98
|
|
|
|
99
|
|
|
$columnNames = array_keys(reset($data)); |
100
|
|
|
|
101
|
|
|
$columns = $this->columnize($columnNames); |
102
|
|
|
|
103
|
|
|
$values = implode(',', array_map(function ($row) { |
104
|
|
|
return '('.$this->parameterize($row).')'; |
105
|
|
|
}, $data)); |
106
|
|
|
|
107
|
|
|
$updates = implode(',', array_map(function ($columnName) { |
108
|
|
|
return $this->wrap($columnName).' = VALUES('.$this->wrap($columnName).')'; |
109
|
|
|
}, $columnNames)); |
110
|
|
|
|
111
|
|
|
return "INSERT INTO {$table} ({$columns}) VALUES {$values} ON DUPLICATE KEY UPDATE {$updates}"; |
112
|
|
|
} |
113
|
|
|
|
114
|
|
|
/** |
115
|
|
|
* Compile a "where in raw" clause. |
116
|
|
|
* |
117
|
|
|
* For safety, whereIntegerInRaw ensures this method is only used with integer values. |
118
|
|
|
* |
119
|
|
|
* @param \Illuminate\Database\Query\Builder $query |
120
|
|
|
* @param array $where |
121
|
|
|
* @return string |
122
|
|
|
*/ |
123
|
|
|
protected function whereInRaw(\Illuminate\Database\Query\Builder $query, $where) |
124
|
|
|
{ |
125
|
|
|
if (! empty($where['values'])) { |
126
|
|
|
return $this->wrap($where['column']).' in ('.implode(', ', $where['values']).')'; |
127
|
|
|
} |
128
|
|
|
|
129
|
|
|
return '0 = 1'; |
130
|
|
|
} |
131
|
|
|
} |
132
|
|
|
|
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.