@@ -2623,6 +2623,102 @@ public function delete($where = '', ?int $limit = null, bool $resetData = true)
2623
2623
return $ this ->testMode ? $ sql : $ this ->db ->query ($ sql , $ this ->binds , false );
2624
2624
}
2625
2625
2626
+ /**
2627
+ * Sets data and calls batchExecute to run queries
2628
+ *
2629
+ * @param array|object|null $set a dataset or select query
2630
+ * @param array|RawSql|string|null $constraints
2631
+ *
2632
+ * @return false|int|string[] Number of rows affected or FALSE on failure, SQL array when testMode
2633
+ */
2634
+ public function deleteBatch ($ set = null , $ constraints = null , int $ batchSize = 100 )
2635
+ {
2636
+ $ this ->onConstraint ($ constraints );
2637
+
2638
+ if ($ set !== null && $ set !== []) {
2639
+ $ this ->setData ($ set , true );
2640
+ }
2641
+
2642
+ return $ this ->batchExecute ('_deleteBatch ' , $ batchSize );
2643
+ }
2644
+
2645
+ /**
2646
+ * Generates a platform-specific batch update string from the supplied data
2647
+ */
2648
+ protected function _deleteBatch (string $ table , array $ keys , array $ values ): string
2649
+ {
2650
+ $ sql = $ this ->QBOptions ['sql ' ] ?? '' ;
2651
+
2652
+ // if this is the first iteration of batch then we need to build skeleton sql
2653
+ if ($ sql === '' ) {
2654
+ $ constraints = $ this ->QBOptions ['constraints ' ] ?? [];
2655
+
2656
+ if ($ constraints === []) {
2657
+ if ($ this ->db ->DBDebug ) {
2658
+ throw new DatabaseException ('You must specify a constraint to match on for batch deletes. ' ); // @codeCoverageIgnore
2659
+ }
2660
+
2661
+ return '' ; // @codeCoverageIgnore
2662
+ }
2663
+
2664
+ $ updateFields = $ this ->QBOptions ['updateFields ' ] ??
2665
+ $ this ->updateFields ($ keys , false , $ constraints )->QBOptions ['updateFields ' ] ??
2666
+ [];
2667
+
2668
+ $ alias = $ this ->QBOptions ['alias ' ] ?? '_u ' ;
2669
+
2670
+ $ sql = 'DELETE ' . $ table . ' FROM ' . $ table . "\n" ;
2671
+
2672
+ $ sql .= "INNER JOIN ( \n{:_table_:} " ;
2673
+
2674
+ $ sql .= ') ' . $ alias . "\n" ;
2675
+
2676
+ $ sql .= 'ON ' . implode (
2677
+ ' AND ' ,
2678
+ array_map (
2679
+ static fn ($ key ) => ($ key instanceof RawSql ?
2680
+ $ key :
2681
+ $ table . '. ' . $ key . ' = ' . $ alias . '. ' . $ key ),
2682
+ $ constraints
2683
+ )
2684
+ );
2685
+
2686
+ // convert binds in where
2687
+ foreach ($ this ->QBWhere as $ key => $ where ) {
2688
+ foreach ($ this ->binds as $ field => $ bind ) {
2689
+ $ this ->QBWhere [$ key ]['condition ' ] = str_replace (': ' . $ field . ': ' , $ bind [0 ], $ where ['condition ' ]);
2690
+ }
2691
+ }
2692
+
2693
+ // remove database prefix from alias in where
2694
+ $ sql .= ' ' . str_replace (
2695
+ $ this ->db ->DBPrefix . trim ($ alias , $ this ->db ->escapeChar ),
2696
+ trim ($ alias , $ this ->db ->escapeChar ),
2697
+ $ this ->compileWhereHaving ('QBWhere ' )
2698
+ );
2699
+
2700
+ $ this ->QBOptions ['sql ' ] = $ sql ;
2701
+ }
2702
+
2703
+ if (isset ($ this ->QBOptions ['fromQuery ' ])) {
2704
+ $ data = $ this ->QBOptions ['fromQuery ' ];
2705
+ } else {
2706
+ $ data = implode (
2707
+ " UNION ALL \n" ,
2708
+ array_map (
2709
+ static fn ($ value ) => 'SELECT ' . implode (', ' , array_map (
2710
+ static fn ($ key , $ index ) => $ index . ' ' . $ key ,
2711
+ $ keys ,
2712
+ $ value
2713
+ )),
2714
+ $ values
2715
+ )
2716
+ ) . "\n" ;
2717
+ }
2718
+
2719
+ return str_replace ('{:_table_:} ' , $ data , $ sql );
2720
+ }
2721
+
2626
2722
/**
2627
2723
* Increments a numeric column by the specified value.
2628
2724
*
0 commit comments