1 | <?php |
||||||
2 | |||||||
3 | declare(strict_types=1); |
||||||
4 | |||||||
5 | namespace LaravelFreelancerNL\Aranguent\Query\Concerns; |
||||||
6 | |||||||
7 | use Closure; |
||||||
8 | use Illuminate\Database\Query\Expression; |
||||||
9 | use Illuminate\Support\Arr; |
||||||
10 | use InvalidArgumentException; |
||||||
11 | use LaravelFreelancerNL\Aranguent\Query\Grammar; |
||||||
12 | use LaravelFreelancerNL\FluentAQL\Exceptions\BindException; |
||||||
13 | |||||||
14 | /** |
||||||
15 | * @method applyBeforeQueryCallbacks() |
||||||
16 | */ |
||||||
17 | trait BuildsUpdates |
||||||
18 | { |
||||||
19 | /** |
||||||
20 | * @param array<mixed> $values |
||||||
21 | * @return array<mixed> |
||||||
22 | */ |
||||||
23 | 26 | protected function prepareValuesForUpdate(array $values) |
|||||
24 | { |
||||||
25 | 26 | foreach ($values as $key => $value) { |
|||||
26 | 26 | if ($value instanceof Expression) { |
|||||
27 | 5 | $values[$key] = $value->getValue($this->grammar); |
|||||
28 | |||||||
29 | 5 | continue; |
|||||
30 | } |
||||||
31 | |||||||
32 | 22 | if (is_array($value)) { |
|||||
33 | 2 | $values[$key] = $this->prepareValuesForUpdate($value); |
|||||
34 | 2 | continue; |
|||||
35 | } |
||||||
36 | |||||||
37 | 22 | $values[$key] = $this->bindValue($value, 'update'); |
|||||
0 ignored issues
–
show
Bug
introduced
by
![]() |
|||||||
38 | } |
||||||
39 | |||||||
40 | 26 | return $values; |
|||||
41 | } |
||||||
42 | |||||||
43 | /** |
||||||
44 | * Update records in the database. |
||||||
45 | * |
||||||
46 | * @param array<mixed> $values |
||||||
47 | * @return int |
||||||
48 | */ |
||||||
49 | 26 | public function update(array $values) |
|||||
50 | { |
||||||
51 | assert($this->grammar instanceof Grammar); |
||||||
52 | |||||||
53 | 26 | $this->applyBeforeQueryCallbacks(); |
|||||
54 | |||||||
55 | 26 | $values = Arr::undot($this->grammar->convertJsonFields($values)); |
|||||
56 | |||||||
57 | 26 | $values = $this->prepareValuesForUpdate($values); |
|||||
58 | |||||||
59 | 26 | $aql = $this->grammar->compileUpdate($this, $values); |
|||||
0 ignored issues
–
show
$this of type LaravelFreelancerNL\Aran...\Concerns\BuildsUpdates is incompatible with the type Illuminate\Database\Query\Builder expected by parameter $query of LaravelFreelancerNL\Aran...rammar::compileUpdate() .
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() |
|||||||
60 | |||||||
61 | 26 | return $this->connection->update($aql, $this->getBindings()); |
|||||
0 ignored issues
–
show
It seems like
getBindings() must be provided by classes using this trait. How about adding it as abstract method to this trait?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() |
|||||||
62 | } |
||||||
63 | |||||||
64 | /** |
||||||
65 | * Insert or update a record matching the attributes, and fill it with values. |
||||||
66 | * |
||||||
67 | * @param array<mixed> $attributes |
||||||
68 | * @param array<mixed>|callable $values |
||||||
69 | * @return bool |
||||||
70 | * @throws BindException |
||||||
71 | */ |
||||||
72 | 4 | public function updateOrInsert(array $attributes, array|callable $values = []) |
|||||
73 | { |
||||||
74 | 4 | $exists = $this->where($attributes)->exists(); |
|||||
0 ignored issues
–
show
It seems like
where() must be provided by classes using this trait. How about adding it as abstract method to this trait?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() |
|||||||
75 | |||||||
76 | 4 | if ($values instanceof Closure) { |
|||||
0 ignored issues
–
show
|
|||||||
77 | 1 | $values = $values($exists); |
|||||
78 | } |
||||||
79 | |||||||
80 | 4 | if (! $exists) { |
|||||
81 | 2 | $this->bindings['where'] = []; |
|||||
0 ignored issues
–
show
|
|||||||
82 | 2 | return $this->insert(array_merge($attributes, $values)); |
|||||
0 ignored issues
–
show
It seems like
insert() must be provided by classes using this trait. How about adding it as abstract method to this trait?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() |
|||||||
83 | } |
||||||
84 | |||||||
85 | 2 | if (empty($values)) { |
|||||
86 | 1 | return true; |
|||||
87 | } |
||||||
88 | |||||||
89 | 1 | return (bool) $this->limit(1)->update($values); |
|||||
0 ignored issues
–
show
It seems like
limit() must be provided by classes using this trait. How about adding it as abstract method to this trait?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() |
|||||||
90 | } |
||||||
91 | |||||||
92 | /** |
||||||
93 | * Increment the given column's values by the given amounts. |
||||||
94 | * |
||||||
95 | * @param array<string, float|int|numeric-string> $columns |
||||||
0 ignored issues
–
show
|
|||||||
96 | * @param array<string, mixed> $extra |
||||||
97 | * @return int |
||||||
98 | * |
||||||
99 | * @throws \InvalidArgumentException |
||||||
100 | */ |
||||||
101 | 3 | public function incrementEach(array $columns, array $extra = []) |
|||||
102 | { |
||||||
103 | 3 | foreach ($columns as $column => $amount) { |
|||||
104 | 3 | if (!is_numeric($amount)) { |
|||||
105 | throw new InvalidArgumentException("Non-numeric value passed as increment amount for column: '$column'."); |
||||||
106 | 3 | } elseif (!is_string($column)) { |
|||||
107 | throw new InvalidArgumentException('Non-associative array passed to incrementEach method.'); |
||||||
108 | } |
||||||
109 | |||||||
110 | 3 | $columns[$column] = new Expression($this->getTableAlias($this->from) . '.' . $column . ' + ' . $amount); |
|||||
0 ignored issues
–
show
It seems like
getTableAlias() must be provided by classes using this trait. How about adding it as abstract method to this trait?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() $this->getTableAlias($th...olumn . ' + ' . $amount of type string is incompatible with the type Illuminate\Database\Query\TValue expected by parameter $value of Illuminate\Database\Quer...pression::__construct() .
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() |
|||||||
111 | } |
||||||
112 | |||||||
113 | 3 | return $this->update(array_merge($columns, $extra)); |
|||||
114 | } |
||||||
115 | |||||||
116 | /** |
||||||
117 | * Decrement the given column's values by the given amounts. |
||||||
118 | * |
||||||
119 | * @param array<string, float|int|numeric-string> $columns |
||||||
0 ignored issues
–
show
|
|||||||
120 | * @param array<string, mixed> $extra |
||||||
121 | * @return int |
||||||
122 | * |
||||||
123 | * @throws \InvalidArgumentException |
||||||
124 | */ |
||||||
125 | 2 | public function decrementEach(array $columns, array $extra = []) |
|||||
126 | { |
||||||
127 | 2 | foreach ($columns as $column => $amount) { |
|||||
128 | 2 | if (!is_numeric($amount)) { |
|||||
129 | throw new InvalidArgumentException("Non-numeric value passed as decrement amount for column: '$column'."); |
||||||
130 | 2 | } elseif (!is_string($column)) { |
|||||
131 | throw new InvalidArgumentException('Non-associative array passed to decrementEach method.'); |
||||||
132 | } |
||||||
133 | |||||||
134 | 2 | $columns[$column] = new Expression($this->getTableAlias($this->from) . '.' . $column . ' - ' . $amount); |
|||||
0 ignored issues
–
show
$this->getTableAlias($th...olumn . ' - ' . $amount of type string is incompatible with the type Illuminate\Database\Query\TValue expected by parameter $value of Illuminate\Database\Quer...pression::__construct() .
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() |
|||||||
135 | } |
||||||
136 | |||||||
137 | 2 | return $this->update(array_merge($columns, $extra)); |
|||||
138 | } |
||||||
139 | |||||||
140 | /** |
||||||
141 | * Insert new records or update the existing ones. |
||||||
142 | * |
||||||
143 | * @param array<mixed> $values |
||||||
144 | * @param array<mixed>|string $uniqueBy |
||||||
145 | * @param array<mixed>|null $update |
||||||
146 | * @return int |
||||||
147 | * @throws BindException |
||||||
148 | */ |
||||||
149 | 7 | public function upsert(array $values, $uniqueBy, $update = null) |
|||||
150 | { |
||||||
151 | assert($this->grammar instanceof Grammar); |
||||||
152 | |||||||
153 | 7 | if (empty($values)) { |
|||||
154 | 1 | return 0; |
|||||
155 | 6 | } elseif ($update === []) { |
|||||
156 | return (int) $this->insert($values); |
||||||
157 | } |
||||||
158 | |||||||
159 | 6 | if (!is_array(reset($values))) { |
|||||
160 | 2 | $values = [$values]; |
|||||
161 | } |
||||||
162 | |||||||
163 | 6 | foreach ($values as $key => $value) { |
|||||
164 | 6 | $values[$key] = $this->grammar->convertJsonFields($value); |
|||||
165 | 6 | $values[$key] = $this->convertIdToKey($values[$key]); |
|||||
0 ignored issues
–
show
It seems like
convertIdToKey() must be provided by classes using this trait. How about adding it as abstract method to this trait?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() |
|||||||
166 | 6 | $values[$key] = Arr::undot($values[$key]); |
|||||
167 | } |
||||||
168 | |||||||
169 | 6 | foreach ($values as $key => $value) { |
|||||
170 | 6 | foreach ($value as $dataKey => $data) { |
|||||
171 | 6 | $values[$key][$dataKey] = $this->bindValue($data, 'upsert'); |
|||||
172 | } |
||||||
173 | } |
||||||
174 | |||||||
175 | 6 | $uniqueBy = $this->grammar->convertJsonFields($uniqueBy); |
|||||
176 | |||||||
177 | 6 | if (is_null($update)) { |
|||||
178 | 1 | $update = array_keys(reset($values)); |
|||||
179 | } |
||||||
180 | |||||||
181 | 6 | foreach ($update as $key => $value) { |
|||||
182 | 6 | $update[$key] = $this->convertIdToKey($value); |
|||||
183 | } |
||||||
184 | |||||||
185 | 6 | $update = $this->grammar->convertJsonFields($update); |
|||||
186 | |||||||
187 | 6 | $this->applyBeforeQueryCallbacks(); |
|||||
188 | |||||||
189 | 6 | $bindings = $this->bindings['upsert']; |
|||||
190 | |||||||
191 | 6 | $aql = $this->grammar->compileUpsert($this, $values, (array) $uniqueBy, $update); |
|||||
0 ignored issues
–
show
$this of type LaravelFreelancerNL\Aran...\Concerns\BuildsUpdates is incompatible with the type Illuminate\Database\Query\Builder expected by parameter $query of LaravelFreelancerNL\Aran...rammar::compileUpsert() .
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() |
|||||||
192 | |||||||
193 | 6 | return $this->connection->affectingStatement( |
|||||
194 | 6 | $aql, |
|||||
195 | 6 | $bindings, |
|||||
196 | 6 | ); |
|||||
197 | } |
||||||
198 | } |
||||||
199 |