@@ -229,13 +229,14 @@ public function __call($name, array $arguments)
229229 /**
230230 * @var array
231231 */
232- protected static $ queryNodes = [
232+ const SELECT_NODES = [
233233 // string: 'id, name'; array: ['id', 'name']
234234 'select ' ,
235235 'from ' ,
236236 // string: full join clause; array: [$table, $condition, $type = 'LEFT']
237237 'join ' ,
238238
239+ /** @see handleWheres() */
239240 'where ' ,
240241
241242 'having ' , // [$conditions, $glue = 'AND']
@@ -247,7 +248,17 @@ public function __call($name, array $arguments)
247248 /**
248249 * @var array
249250 */
250- protected static $ queryOptions = [
251+ const UPDATE_NODES = ['update ' , 'set ' , 'where ' , 'order ' , 'limit ' ];
252+
253+ /**
254+ * @var array
255+ */
256+ const DELETE_NODES = ['from ' , 'join ' , 'where ' , 'order ' , 'limit ' ];
257+
258+ /**
259+ * @var array
260+ */
261+ const SELECT_OPTIONS = [
251262 /* data index column. */
252263 'indexKey ' => null ,
253264
@@ -280,7 +291,11 @@ public function find(string $from, $wheres = 1, $select = '*', array $options =
280291
281292 $ statement = $ this ->compileSelect ($ options );
282293
283- return $ this ->fetchOne ($ statement , $ bindings ?: []);
294+ if (isset ($ options ['dumpSql ' ])) {
295+ return [$ statement , $ bindings ];
296+ }
297+
298+ return $ this ->fetchOne ($ statement , $ bindings );
284299 }
285300
286301 /**
@@ -306,42 +321,95 @@ public function findAll(string $from, $wheres = 1, $select = '*', array $options
306321
307322 $ statement = $ this ->compileSelect ($ options );
308323
309- return $ this ->fetchAll ($ statement , $ bindings ?: []);
324+ if (isset ($ options ['dumpSql ' ])) {
325+ return [$ statement , $ bindings ];
326+ }
327+
328+ return $ this ->fetchAll ($ statement , $ bindings );
310329 }
311330
312331 /**
313- * Run a insert statement
332+ * Run a statement for insert a row
314333 * @param string $statement
315- * @param array $bindings
316- * @param null|string $sequence For special driver, like PgSQL
334+ * @param array $data <column => value>
335+ * @param array $options
317336 * @return int
318337 */
319- public function insert ($ statement , array $ bindings = [], $ sequence = null )
338+ public function insert (string $ from , array $ data , array $ options = [] )
320339 {
340+ list ($ statement , $ bindings ) = $ this ->compileInsert ($ from , $ data );
341+
342+ if (isset ($ options ['dumpSql ' ])) {
343+ return [$ statement , $ bindings ];
344+ }
345+
321346 $ this ->fetchAffected ($ statement , $ bindings );
322347
323- return $ this ->lastInsertId ($ sequence );
348+ // 'sequence' For special driver, like PgSQL
349+ return isset ($ options ['sequence ' ]) ? $ this ->lastInsertId ($ options ['sequence ' ]) : $ this ->lastInsertId ();
324350 }
325351
326352 /**
327- * Run a update statement
353+ * Run a statement for insert multi row
328354 * @param string $statement
329- * @param array $bindings
355+ * @param array $data <column => value>
356+ * @param array $options
330357 * @return int
331358 */
332- public function update ( $ statement , array $ bindings = [])
359+ public function insertBatch ( string $ from , array $ dataSet , array $ options = [])
333360 {
361+ list ($ statement , $ bindings ) = $ this ->compileInsert ($ from , $ dataSet , $ options ['columns ' ] ?? [], true );
362+
363+ if (isset ($ options ['dumpSql ' ])) {
364+ return [$ statement , $ bindings ];
365+ }
366+
367+ return $ this ->fetchAffected ($ statement , $ bindings );
368+ }
369+
370+ /**
371+ * Run a update statement
372+ * @param string $from
373+ * @param array|string $wheres
374+ * @param array $values
375+ * @return int
376+ */
377+ public function update (string $ from , $ wheres , array $ values , array $ options = [])
378+ {
379+ list ($ where , $ bindings ) = $ this ->handleWheres ($ wheres );
380+
381+ $ options ['update ' ] = $ this ->qn ($ from );
382+ $ options ['where ' ] = $ where ;
383+
384+ $ statement = $ this ->compileUpdate ($ values , $ bindings , $ options );
385+
386+ if (isset ($ options ['dumpSql ' ])) {
387+ return [$ statement , $ bindings ];
388+ }
389+
334390 return $ this ->fetchAffected ($ statement , $ bindings );
335391 }
336392
337393 /**
338394 * Run a delete statement
339- * @param string $statement
340- * @param array $bindings
395+ * @param string $from
396+ * @param array|string $wheres
397+ * @param array $options
341398 * @return int
342399 */
343- public function delete ($ statement , array $ bindings = [])
400+ public function delete (string $ from , $ wheres , array $ options = [])
344401 {
402+ list ($ where , $ bindings ) = $ this ->handleWheres ($ wheres );
403+
404+ $ options ['from ' ] = $ this ->qn ($ from );
405+ $ options ['where ' ] = $ where ;
406+
407+ $ statement = $ this ->compileDelete ($ options );
408+
409+ if (isset ($ options ['dumpSql ' ])) {
410+ return [$ statement , $ bindings ];
411+ }
412+
345413 return $ this ->fetchAffected ($ statement , $ bindings );
346414 }
347415
@@ -810,11 +878,11 @@ public function handleWheres($wheres)
810878 }
811879
812880 if (!$ wheres || $ wheres === 1 ) {
813- return [1 , null ];
881+ return [1 , [] ];
814882 }
815883
816884 if (is_string ($ wheres )) {
817- return [$ wheres , null ];
885+ return [$ wheres , [] ];
818886 }
819887
820888 $ nodes = $ bindings = [];
@@ -858,16 +926,95 @@ public function handleWheres($wheres)
858926 * @param array $opts
859927 * @return string
860928 */
861- public function compileSelect (array $ opts )
929+ public function compileSelect (array $ options )
930+ {
931+ return $ this ->compileNodes (self ::SELECT_NODES , $ options );
932+ }
933+
934+ /**
935+ * @param array $updates
936+ * @param array $bindings
937+ * @param array $options
938+ * @return string
939+ */
940+ public function compileInsert ($ from , array $ data , array $ columns = [], $ isBatch = false )
941+ {
942+ $ names = $ bindings = [];
943+ $ table = $ this ->qn ($ from );
944+
945+ if (!$ isBatch ) {
946+ $ bindings = array_values ($ data );
947+ $ nameStr = $ this ->qns (array_keys ($ data ));
948+ $ valueStr = '( ' . rtrim (str_repeat ('?, ' , count ($ data )), ', ' ) . ') ' ;
949+ } else {
950+ if ($ columns ) {
951+ $ columnNum = count ($ columns );
952+ $ nameStr = $ this ->qns ($ columns );
953+ } else {
954+ $ columnNum = count ($ data [0 ]);
955+ $ nameStr = $ this ->qns (array_keys ($ data [0 ]));
956+ }
957+
958+ $ valueStr = '' ;
959+ $ rowTpl = '( ' . rtrim (str_repeat ('?, ' , $ columnNum ), ', ' ) . '), ' ;
960+
961+ foreach ($ data as $ row ) {
962+ $ bindings = array_merge ($ bindings , array_values ($ row ));
963+ $ valueStr .= $ rowTpl ;
964+ }
965+
966+ $ valueStr = rtrim ($ valueStr , ', ' );
967+ }
968+
969+ return ["INSERT INTO $ table ( $ nameStr) VALUES $ valueStr " , $ bindings ];
970+ }
971+
972+ /**
973+ *
974+ * @param array $updates
975+ * @param array $bindings
976+ * @param array $options
977+ * @return string
978+ */
979+ public function compileUpdate (array $ updates , array &$ bindings , array $ options )
980+ {
981+ $ nodes = $ vlaues = [];
982+
983+ foreach ($ updates as $ column => $ value ) {
984+ if (is_int ($ column )) {
985+ contiune;
986+ }
987+
988+ $ nodes [] = $ this ->qn ($ column ) . '= ? ' ;
989+ $ vlaues [] = $ value ;
990+ }
991+
992+ $ options ['set ' ] = \implode (', ' , $ nodes );
993+ $ bindings = array_merge ($ vlaues , $ bindings );
994+
995+ return $ this ->compileNodes (self ::UPDATE_NODES , $ options );
996+ }
997+
998+ public function compileDelete (array $ options )
999+ {
1000+ return 'DELETE ' . $ this ->compileNodes (self ::DELETE_NODES , $ options );;
1001+ }
1002+
1003+ /**
1004+ * @param array $commandNodes
1005+ * @param array $data
1006+ * @return string
1007+ */
1008+ public function compileNodes (array $ commandNodes , array $ data )
8621009 {
8631010 $ nodes = [];
8641011
865- foreach (self :: $ queryNodes as $ node ) {
866- if (!isset ($ opts [$ node ])) {
1012+ foreach ($ commandNodes as $ node ) {
1013+ if (!isset ($ data [$ node ])) {
8671014 continue ;
8681015 }
8691016
870- $ val = $ opts [$ node ];
1017+ $ val = $ data [$ node ];
8711018 if ($ isString = is_string ($ val )) {
8721019 $ val = trim ($ val );
8731020 }
0 commit comments