@@ -2653,6 +2653,102 @@ public function delete($where = '', ?int $limit = null, bool $resetData = true)
2653
2653
return $ this ->testMode ? $ sql : $ this ->db ->query ($ sql , $ this ->binds , false );
2654
2654
}
2655
2655
2656
+ /**
2657
+ * Sets data and calls batchExecute to run queries
2658
+ *
2659
+ * @param array|object|null $set a dataset or select query
2660
+ * @param array|RawSql|string|null $constraints
2661
+ *
2662
+ * @return false|int|string[] Number of rows affected or FALSE on failure, SQL array when testMode
2663
+ */
2664
+ public function deleteBatch ($ set = null , $ constraints = null , int $ batchSize = 100 )
2665
+ {
2666
+ $ this ->onConstraint ($ constraints );
2667
+
2668
+ if ($ set !== null && $ set !== []) {
2669
+ $ this ->setData ($ set , true );
2670
+ }
2671
+
2672
+ return $ this ->batchExecute ('_deleteBatch ' , $ batchSize );
2673
+ }
2674
+
2675
+ /**
2676
+ * Generates a platform-specific batch update string from the supplied data
2677
+ */
2678
+ protected function _deleteBatch (string $ table , array $ keys , array $ values ): string
2679
+ {
2680
+ $ sql = $ this ->QBOptions ['sql ' ] ?? '' ;
2681
+
2682
+ // if this is the first iteration of batch then we need to build skeleton sql
2683
+ if ($ sql === '' ) {
2684
+ $ constraints = $ this ->QBOptions ['constraints ' ] ?? [];
2685
+
2686
+ if ($ constraints === []) {
2687
+ if ($ this ->db ->DBDebug ) {
2688
+ throw new DatabaseException ('You must specify a constraint to match on for batch deletes. ' ); // @codeCoverageIgnore
2689
+ }
2690
+
2691
+ return '' ; // @codeCoverageIgnore
2692
+ }
2693
+
2694
+ $ updateFields = $ this ->QBOptions ['updateFields ' ] ??
2695
+ $ this ->updateFields ($ keys , false , $ constraints )->QBOptions ['updateFields ' ] ??
2696
+ [];
2697
+
2698
+ $ alias = $ this ->QBOptions ['alias ' ] ?? '_u ' ;
2699
+
2700
+ $ sql = 'DELETE ' . $ table . ' FROM ' . $ table . "\n" ;
2701
+
2702
+ $ sql .= "INNER JOIN ( \n{:_table_:} " ;
2703
+
2704
+ $ sql .= ') ' . $ alias . "\n" ;
2705
+
2706
+ $ sql .= 'ON ' . implode (
2707
+ ' AND ' ,
2708
+ array_map (
2709
+ static fn ($ key ) => ($ key instanceof RawSql ?
2710
+ $ key :
2711
+ $ table . '. ' . $ key . ' = ' . $ alias . '. ' . $ key ),
2712
+ $ constraints
2713
+ )
2714
+ );
2715
+
2716
+ // convert binds in where
2717
+ foreach ($ this ->QBWhere as $ key => $ where ) {
2718
+ foreach ($ this ->binds as $ field => $ bind ) {
2719
+ $ this ->QBWhere [$ key ]['condition ' ] = str_replace (': ' . $ field . ': ' , $ bind [0 ], $ where ['condition ' ]);
2720
+ }
2721
+ }
2722
+
2723
+ // remove database prefix from alias in where
2724
+ $ sql .= ' ' . str_replace (
2725
+ $ this ->db ->DBPrefix . trim ($ alias , $ this ->db ->escapeChar ),
2726
+ trim ($ alias , $ this ->db ->escapeChar ),
2727
+ $ this ->compileWhereHaving ('QBWhere ' )
2728
+ );
2729
+
2730
+ $ this ->QBOptions ['sql ' ] = $ sql ;
2731
+ }
2732
+
2733
+ if (isset ($ this ->QBOptions ['fromQuery ' ])) {
2734
+ $ data = $ this ->QBOptions ['fromQuery ' ];
2735
+ } else {
2736
+ $ data = implode (
2737
+ " UNION ALL \n" ,
2738
+ array_map (
2739
+ static fn ($ value ) => 'SELECT ' . implode (', ' , array_map (
2740
+ static fn ($ key , $ index ) => $ index . ' ' . $ key ,
2741
+ $ keys ,
2742
+ $ value
2743
+ )),
2744
+ $ values
2745
+ )
2746
+ ) . "\n" ;
2747
+ }
2748
+
2749
+ return str_replace ('{:_table_:} ' , $ data , $ sql );
2750
+ }
2751
+
2656
2752
/**
2657
2753
* Increments a numeric column by the specified value.
2658
2754
*
0 commit comments