@@ -169,7 +169,7 @@ class BaseBuilder
169
169
* tableIdentity?: string,
170
170
* updateFields?: array,
171
171
* constraints?: array,
172
- * fromQuery ?: string,
172
+ * setQueryAsData ?: string,
173
173
* sql?: string,
174
174
* alias?: string
175
175
* }
@@ -1925,6 +1925,22 @@ public function upsert($set = null, ?bool $escape = null)
1925
1925
*/
1926
1926
public function upsertBatch ($ set = null , ?bool $ escape = null , int $ batchSize = 100 )
1927
1927
{
1928
+ if (isset ($ this ->QBOptions ['setQueryAsData ' ])) {
1929
+ $ sql = $ this ->_upsertBatch ($ this ->QBFrom [0 ], $ this ->QBKeys , []);
1930
+
1931
+ if ($ sql === '' ) {
1932
+ return false ; // @codeCoverageIgnore
1933
+ }
1934
+
1935
+ if ($ this ->testMode === false ) {
1936
+ $ this ->db ->query ($ sql , null , false );
1937
+ }
1938
+
1939
+ $ this ->resetWrite ();
1940
+
1941
+ return $ this ->testMode ? $ sql : $ this ->db ->affectedRows ();
1942
+ }
1943
+
1928
1944
if ($ set !== null ) {
1929
1945
$ this ->setData ($ set , $ escape );
1930
1946
}
@@ -1965,8 +1981,8 @@ protected function _upsertBatch(string $table, array $keys, array $values): stri
1965
1981
$ this ->QBOptions ['sql ' ] = $ sql ;
1966
1982
}
1967
1983
1968
- if (isset ($ this ->QBOptions ['fromQuery ' ])) {
1969
- $ data = $ this ->QBOptions ['fromQuery ' ];
1984
+ if (isset ($ this ->QBOptions ['setQueryAsData ' ])) {
1985
+ $ data = $ this ->QBOptions ['setQueryAsData ' ];
1970
1986
} else {
1971
1987
$ data = 'VALUES ' . implode (', ' , $ this ->formatValues ($ values )) . "\n" ;
1972
1988
}
@@ -2067,6 +2083,60 @@ public function onConstraint($set)
2067
2083
return $ this ;
2068
2084
}
2069
2085
2086
+ /**
2087
+ * Sets data source as a query for insertBatch()/updateBatch()/upsertBatch()/deleteBatch()
2088
+ *
2089
+ * @param BaseBuilder|RawSql $query
2090
+ * @param array|string|null $columns an array or comma delimited string of columns
2091
+ */
2092
+ public function setQueryAsData ($ query , ?string $ alias = null , $ columns = null ): BaseBuilder
2093
+ {
2094
+ if (is_string ($ query )) {
2095
+ throw new InvalidArgumentException ('$query parameter must be BaseBuilder or RawSql class. ' );
2096
+ }
2097
+
2098
+ if ($ query instanceof BaseBuilder) {
2099
+ $ query = $ query ->getCompiledSelect ();
2100
+ } elseif ($ query instanceof RawSql) {
2101
+ $ query = $ query ->__toString ();
2102
+ }
2103
+
2104
+ if (is_string ($ query )) {
2105
+ if ($ columns !== null && is_string ($ columns )) {
2106
+ $ columns = explode (', ' , $ columns );
2107
+ $ columns = array_map (static fn ($ key ) => trim ($ key ), $ columns );
2108
+ }
2109
+
2110
+ $ columns = (array ) $ columns ;
2111
+
2112
+ if ($ columns === []) {
2113
+ $ columns = $ this ->fieldsFromQuery ($ query );
2114
+ }
2115
+
2116
+ if ($ alias !== null ) {
2117
+ $ this ->setAlias ($ alias );
2118
+ }
2119
+
2120
+ foreach ($ columns as $ key => $ value ) {
2121
+ $ columns [$ key ] = $ this ->db ->escapeChar . $ value . $ this ->db ->escapeChar ;
2122
+ }
2123
+
2124
+ $ this ->QBOptions ['setQueryAsData ' ] = $ query ;
2125
+ $ this ->QBKeys = $ columns ;
2126
+ $ this ->QBSet = [];
2127
+ }
2128
+
2129
+ return $ this ;
2130
+ }
2131
+
2132
+ /**
2133
+ * Gets column names from a select query
2134
+ */
2135
+ protected function fieldsFromQuery (string $ sql ): array
2136
+ {
2137
+ return $ this ->db ->query ('SELECT * FROM ( ' . $ sql . ') _u_ LIMIT 1 ' )->getFieldNames ();
2138
+ }
2139
+
2070
2140
/**
2071
2141
* Converts value array of array to array of strings
2072
2142
*/
@@ -2084,6 +2154,22 @@ protected function formatValues(array $values): array
2084
2154
*/
2085
2155
public function insertBatch ($ set = null , ?bool $ escape = null , int $ batchSize = 100 )
2086
2156
{
2157
+ if (isset ($ this ->QBOptions ['setQueryAsData ' ])) {
2158
+ $ sql = $ this ->_insertBatch ($ this ->QBFrom [0 ], $ this ->QBKeys , []);
2159
+
2160
+ if ($ sql === '' ) {
2161
+ return false ; // @codeCoverageIgnore
2162
+ }
2163
+
2164
+ if ($ this ->testMode === false ) {
2165
+ $ this ->db ->query ($ sql , null , false );
2166
+ }
2167
+
2168
+ $ this ->resetWrite ();
2169
+
2170
+ return $ this ->testMode ? $ sql : $ this ->db ->affectedRows ();
2171
+ }
2172
+
2087
2173
if ($ set !== null && $ set !== []) {
2088
2174
$ this ->setData ($ set , $ escape );
2089
2175
}
@@ -2114,8 +2200,8 @@ protected function _insertBatch(string $table, array $keys, array $values): stri
2114
2200
$ this ->QBOptions ['sql ' ] = $ sql ;
2115
2201
}
2116
2202
2117
- if (isset ($ this ->QBOptions ['fromQuery ' ])) {
2118
- $ data = $ this ->QBOptions ['fromQuery ' ];
2203
+ if (isset ($ this ->QBOptions ['setQueryAsData ' ])) {
2204
+ $ data = $ this ->QBOptions ['setQueryAsData ' ];
2119
2205
} else {
2120
2206
$ data = 'VALUES ' . implode (', ' , $ this ->formatValues ($ values ));
2121
2207
}
@@ -2427,9 +2513,9 @@ protected function validateUpdate(): bool
2427
2513
}
2428
2514
2429
2515
/**
2430
- * Sets data and calls batchExecute to run queryies
2516
+ * Sets data and calls batchExecute to run queries
2431
2517
*
2432
- * @param array|object|null $set a dataset or select query
2518
+ * @param array|object|null $set a dataset
2433
2519
* @param array|RawSql|string|null $constraints
2434
2520
*
2435
2521
* @return false|int|string[] Number of rows affected or FALSE on failure, SQL array when testMode
@@ -2438,6 +2524,22 @@ public function updateBatch($set = null, $constraints = null, int $batchSize = 1
2438
2524
{
2439
2525
$ this ->onConstraint ($ constraints );
2440
2526
2527
+ if (isset ($ this ->QBOptions ['setQueryAsData ' ])) {
2528
+ $ sql = $ this ->_updateBatch ($ this ->QBFrom [0 ], $ this ->QBKeys , []);
2529
+
2530
+ if ($ sql === '' ) {
2531
+ return false ; // @codeCoverageIgnore
2532
+ }
2533
+
2534
+ if ($ this ->testMode === false ) {
2535
+ $ this ->db ->query ($ sql , null , false );
2536
+ }
2537
+
2538
+ $ this ->resetWrite ();
2539
+
2540
+ return $ this ->testMode ? $ sql : $ this ->db ->affectedRows ();
2541
+ }
2542
+
2441
2543
if ($ set !== null && $ set !== []) {
2442
2544
$ this ->setData ($ set , true );
2443
2545
}
@@ -2521,8 +2623,8 @@ protected function _updateBatch(string $table, array $keys, array $values): stri
2521
2623
$ this ->QBOptions ['sql ' ] = $ sql ;
2522
2624
}
2523
2625
2524
- if (isset ($ this ->QBOptions ['fromQuery ' ])) {
2525
- $ data = $ this ->QBOptions ['fromQuery ' ];
2626
+ if (isset ($ this ->QBOptions ['setQueryAsData ' ])) {
2627
+ $ data = $ this ->QBOptions ['setQueryAsData ' ];
2526
2628
} else {
2527
2629
$ data = implode (
2528
2630
" UNION ALL \n" ,
@@ -2677,7 +2779,7 @@ public function delete($where = '', ?int $limit = null, bool $resetData = true)
2677
2779
/**
2678
2780
* Sets data and calls batchExecute to run queries
2679
2781
*
2680
- * @param array|object|null $set a dataset or select query
2782
+ * @param array|object|null $set a dataset
2681
2783
* @param array|RawSql|null $constraints
2682
2784
*
2683
2785
* @return false|int|string[] Number of rows affected or FALSE on failure, SQL array when testMode
@@ -2686,6 +2788,22 @@ public function deleteBatch($set = null, $constraints = null, int $batchSize = 1
2686
2788
{
2687
2789
$ this ->onConstraint ($ constraints );
2688
2790
2791
+ if (isset ($ this ->QBOptions ['setQueryAsData ' ])) {
2792
+ $ sql = $ this ->_deleteBatch ($ this ->QBFrom [0 ], $ this ->QBKeys , []);
2793
+
2794
+ if ($ sql === '' ) {
2795
+ return false ; // @codeCoverageIgnore
2796
+ }
2797
+
2798
+ if ($ this ->testMode === false ) {
2799
+ $ this ->db ->query ($ sql , null , false );
2800
+ }
2801
+
2802
+ $ this ->resetWrite ();
2803
+
2804
+ return $ this ->testMode ? $ sql : $ this ->db ->affectedRows ();
2805
+ }
2806
+
2689
2807
if ($ set !== null && $ set !== []) {
2690
2808
$ this ->setData ($ set , true );
2691
2809
}
@@ -2757,8 +2875,8 @@ protected function _deleteBatch(string $table, array $keys, array $values): stri
2757
2875
$ this ->QBOptions ['sql ' ] = trim ($ sql );
2758
2876
}
2759
2877
2760
- if (isset ($ this ->QBOptions ['fromQuery ' ])) {
2761
- $ data = $ this ->QBOptions ['fromQuery ' ];
2878
+ if (isset ($ this ->QBOptions ['setQueryAsData ' ])) {
2879
+ $ data = $ this ->QBOptions ['setQueryAsData ' ];
2762
2880
} else {
2763
2881
$ data = implode (
2764
2882
" UNION ALL \n" ,
@@ -3156,7 +3274,7 @@ protected function isLiteral(string $str): bool
3156
3274
*
3157
3275
* @return $this
3158
3276
*/
3159
- public function resetQuery ()
3277
+ public function resetQueryAsData ()
3160
3278
{
3161
3279
$ this ->resetSelect ();
3162
3280
$ this ->resetWrite ();
@@ -3311,7 +3429,7 @@ protected function setBind(string $key, $value = null, bool $escape = true): str
3311
3429
*/
3312
3430
protected function cleanClone ()
3313
3431
{
3314
- return (clone $ this )->from ([], true )->resetQuery ();
3432
+ return (clone $ this )->from ([], true )->resetQueryAsData ();
3315
3433
}
3316
3434
3317
3435
/**
0 commit comments