@@ -233,46 +233,81 @@ protected function resetSelect()
233
233
*/
234
234
protected function _updateBatch (string $ table , array $ values , string $ index ): string
235
235
{
236
- $ keys = array_keys (current ($ values ));
236
+ // this is a work around until the rest of the platform is refactored
237
+ $ this ->QBOptions ['constraints ' ] = [$ index ];
238
+ $ keys = array_keys (current ($ values ));
237
239
238
- // make array for future use with composite keys - `field`
239
- // future: $this->QBOptions['constraints']
240
- $ constraints = [$ index ];
240
+ $ sql = $ this ->QBOptions ['sql ' ] ?? '' ;
241
241
242
- // future: $this->QBOptions['updateFields']
243
- $ updateFields = array_filter ($ keys , static fn ($ index ) => ! in_array ($ index , $ constraints , true ));
242
+ // if this is the first iteration of batch then we need to build skeleton sql
243
+ if ($ sql === '' ) {
244
+ $ constraints = $ this ->QBOptions ['constraints ' ] ?? [];
244
245
245
- // Oracle doesn't support ignore on updates so we will use MERGE
246
- $ sql = 'MERGE INTO ' . $ table . " \"t \"\n" ;
246
+ if ($ constraints === []) {
247
+ if ($ this ->db ->DBDebug ) {
248
+ throw new DatabaseException ('You must specify a constraint to match on for batch updates. ' );
249
+ }
250
+
251
+ return '' ; // @codeCoverageIgnore
252
+ }
253
+
254
+ $ updateFields = $ this ->QBOptions ['updateFields ' ] ??
255
+ $ this ->updateFields ($ keys , false , $ constraints )->QBOptions ['updateFields ' ] ??
256
+ [];
257
+
258
+ $ alias = $ this ->QBOptions ['alias ' ] ?? '"_u" ' ;
247
259
248
- $ sql .= 'USING ( ' . "\n" ;
260
+ // Oracle doesn't support ignore on updates so we will use MERGE
261
+ $ sql = 'MERGE INTO ' . $ table . "\n" ;
249
262
250
- $ sql .= implode (
251
- " UNION ALL \n" ,
252
- array_map (
253
- static fn ($ value ) => 'SELECT ' . implode (', ' , array_map (
254
- static fn ($ key , $ index ) => $ index . ' ' . $ key ,
255
- $ keys ,
256
- $ value
257
- )) . ' FROM DUAL ' ,
258
- $ values
259
- )
260
- ) . "\n" ;
263
+ $ sql .= 'USING ( ' . "\n%s " ;
261
264
262
- $ sql .= ') "u" ' . "\n" ;
265
+ $ sql .= ') ' . $ alias . "\n" ;
263
266
264
- $ sql .= 'ON ( ' . implode (
265
- ' AND ' ,
266
- array_map (static fn ($ key ) => '"t". ' . $ key . ' = "u". ' . $ key , $ constraints )
267
- ) . ") \n" ;
267
+ $ sql .= 'ON ( ' . implode (
268
+ ' AND ' ,
269
+ array_map (
270
+ static fn ($ key ) => ($ key instanceof RawSql ?
271
+ $ key :
272
+ $ table . '. ' . $ key . ' = ' . $ alias . '. ' . $ key ),
273
+ $ constraints
274
+ )
275
+ ) . ") \n" ;
268
276
269
- $ sql .= "WHEN MATCHED THEN UPDATE \n" ;
277
+ $ sql .= "WHEN MATCHED THEN UPDATE \n" ;
270
278
271
- $ sql .= 'SET ' . "\n" ;
279
+ $ sql .= 'SET ' . "\n" ;
280
+
281
+ $ sql .= implode (
282
+ ", \n" ,
283
+ array_map (
284
+ static fn ($ key , $ value ) => $ table . '. ' . $ key . ($ value instanceof RawSql ?
285
+ ' = ' . $ value :
286
+ ' = ' . $ alias . '. ' . $ value ),
287
+ array_keys ($ updateFields ),
288
+ $ updateFields
289
+ )
290
+ );
291
+
292
+ $ this ->QBOptions ['sql ' ] = $ sql ;
293
+ }
294
+
295
+ if (isset ($ this ->QBOptions ['fromQuery ' ])) {
296
+ $ data = $ this ->QBOptions ['fromQuery ' ];
297
+ } else {
298
+ $ data = implode (
299
+ " UNION ALL \n" ,
300
+ array_map (
301
+ static fn ($ value ) => 'SELECT ' . implode (', ' , array_map (
302
+ static fn ($ key , $ index ) => $ index . ' ' . $ key ,
303
+ $ keys ,
304
+ $ value
305
+ )) . ' FROM DUAL ' ,
306
+ $ values
307
+ )
308
+ ) . "\n" ;
309
+ }
272
310
273
- return $ sql .= implode (
274
- ", \n" ,
275
- array_map (static fn ($ key ) => '"t". ' . $ key . ' = "u". ' . $ key , $ updateFields )
276
- );
311
+ return sprintf ($ sql , $ data );
277
312
}
278
313
}
0 commit comments