@@ -63,15 +63,6 @@ class WP_SQLite_PDO_Engine extends PDO { // phpcs:ignore
6363 */
6464 private $ rewritten_query ;
6565
66- /**
67- * Class variable to have what kind of query to execute.
68- *
69- * @access private
70- *
71- * @var string
72- */
73- private $ query_type ;
74-
7566 /**
7667 * Class variable to store the result of the query.
7768 *
@@ -81,17 +72,6 @@ class WP_SQLite_PDO_Engine extends PDO { // phpcs:ignore
8172 */
8273 private $ results = null ;
8374
84- /**
85- * Class variable to store the results of the query.
86- *
87- * This is for the backward compatibility.
88- *
89- * @access private
90- *
91- * @var array reference to the PHP object
92- */
93- private $ _results = null ;
94-
9575 /**
9676 * Class variable to reference to the PDO instance.
9777 *
@@ -441,7 +421,6 @@ public function query( $statement, $mode = PDO::FETCH_OBJ, ...$fetch_mode_args )
441421 $ last_retval = null ;
442422 foreach ( $ translation ->queries as $ query ) {
443423 $ this ->queries [] = "Executing: {$ query ->sql } | " . ( $ query ->params ? 'parameters: ' . implode ( ', ' , $ query ->params ) : '(no parameters) ' );
444-
445424 do {
446425 $ error = null ;
447426 try {
@@ -455,21 +434,66 @@ public function query( $statement, $mode = PDO::FETCH_OBJ, ...$fetch_mode_args )
455434 } while ( $ error );
456435 }
457436
437+ if ( $ translation ->has_result ) {
438+ $ this ->results = $ translation ->result ;
439+ } else {
440+ switch ($ translation ->mysql_query_type ) {
441+ case 'DESCRIBE ' :
442+ $ this ->results = $ stmt ->fetchAll ( $ mode );
443+ if ( ! $ this ->results ) {
444+ $ this ->handle_error ( new PDOException ( 'Table not found ' ) );
445+ return ;
446+ }
447+ break ;
448+ case 'SELECT ' :
449+ case 'SHOW ' :
450+ $ this ->results = $ stmt ->fetchAll ( $ mode );
451+ break ;
452+ case 'TRUNCATE ' :
453+ $ this ->results = true ;
454+ $ this ->return_value = true ;
455+ return $ this ->return_value ;
456+ case 'SET ' :
457+ $ this ->results = 0 ;
458+ break ;
459+ default :
460+ $ this ->results = $ last_retval ;
461+ break ;
462+ }
463+ }
464+
458465 if ( $ translation ->calc_found_rows ) {
459466 $ this ->found_rows_result = $ translation ->calc_found_rows ;
460467 }
461- if ( $ stmt ) {
462- if ( 'DESCRIBE ' === $ translation ->mysql_query_type
463- || 'SELECT ' === $ translation ->mysql_query_type
464- || 'SHOW ' === $ translation ->mysql_query_type
465- ) {
466- $ this ->_results = $ stmt ->fetchAll ( $ mode );
467- } else {
468- $ this ->_results = $ last_retval ;
469- }
468+
469+ if ( is_array ( $ this ->results ) ) {
470+ $ this ->num_rows = count ( $ this ->results );
471+ $ this ->last_found_rows = count ( $ this ->results );
472+ }
473+
474+ switch ( $ translation ->sqlite_query_type ) {
475+ case 'DELETE ' :
476+ case 'UPDATE ' :
477+ case 'INSERT ' :
478+ case 'REPLACE ' :
479+ /**
480+ * SELECT CHANGES() is a workaround for the fact that
481+ * $stmt->rowCount() returns "0" (zero) with the
482+ * SQLite driver at all times.
483+ * Source: https://www.php.net/manual/en/pdostatement.rowcount.php
484+ */
485+ $ this ->affected_rows = (int ) $ this ->pdo ->query ( 'select changes() ' )->fetch ()[0 ];
486+ $ this ->return_value = $ this ->affected_rows ;
487+ $ this ->num_rows = $ this ->affected_rows ;
488+ $ this ->last_insert_id = $ this ->pdo ->lastInsertId ();
489+ if ( is_numeric ( $ this ->last_insert_id ) ) {
490+ $ this ->last_insert_id = (int ) $ this ->last_insert_id ;
491+ }
492+ break ;
493+ default :
494+ $ this ->return_value = $ this ->results ;
495+ break ;
470496 }
471-
472- $ this ->process_results ( $ stmt , $ translation );
473497
474498 return $ this ->return_value ;
475499 } catch ( Exception $ err ) {
@@ -651,28 +675,12 @@ public function get_error_message() {
651675 return $ output ;
652676 }
653677
654- /**
655- * Method to return information about query string for debugging.
656- *
657- * @return string
658- */
659- private function get_debug_info () {
660- $ output = '' ;
661- foreach ( $ this ->queries as $ q ) {
662- $ output .= $ q . "\n" ;
663- }
664-
665- return $ output ;
666- }
667-
668678 /**
669679 * Method to clear previous data.
670680 */
671681 private function flush () {
672682 $ this ->rewritten_query = '' ;
673- $ this ->query_type = '' ;
674683 $ this ->results = null ;
675- $ this ->_results = null ;
676684 $ this ->last_insert_id = null ;
677685 $ this ->affected_rows = null ;
678686 $ this ->column_data = array ();
@@ -684,73 +692,6 @@ private function flush() {
684692 $ this ->param_num = 0 ;
685693 }
686694
687- /**
688- * Method to format the queried data to that of MySQL.
689- *
690- * @param stdClass $stmt Prepared statement object.
691- * @param stdClass $translation Translation object.
692- */
693- private function process_results ( $ stmt , $ translation ) {
694- if ( 'DESCRIBE ' === $ translation ->mysql_query_type ) {
695- if ( ! $ this ->_results ) {
696- $ this ->handle_error ( new PDOException ( 'Table not found ' ) );
697- return ;
698- }
699- }
700-
701- // @TODO: Only use $translation->mysql_query_type, not $this->query_type
702- if ( $ translation ->has_result ) {
703- $ this ->_results = $ translation ->result ;
704- $ this ->results = $ translation ->result ;
705- } elseif ( in_array ( $ this ->query_type , array ( 'describe ' , 'desc ' , 'showcolumns ' ), true ) ) {
706- $ this ->convert_to_columns_object ();
707- } elseif ( 'set ' === $ this ->query_type ) {
708- $ this ->results = false ;
709- } elseif ( 'showindex ' === $ this ->query_type ) {
710- $ this ->convert_to_index_object ();
711- } elseif ( in_array ( $ this ->query_type , array ( 'check ' , 'analyze ' ), true ) ) {
712- $ this ->convert_result_check_or_analyze ();
713- } elseif ( 'SET ' === $ translation ->mysql_query_type ) {
714- $ this ->_results = 0 ;
715- $ this ->results = 0 ;
716- } else {
717- $ this ->results = $ this ->_results ;
718- }
719- $ this ->return_value = $ this ->results ;
720-
721- if ( is_array ( $ this ->results ) ) {
722- $ this ->num_rows = count ( $ this ->results );
723- $ this ->last_found_rows = count ( $ this ->results );
724- }
725-
726- switch ( $ translation ->sqlite_query_type ) {
727- case 'DELETE ' :
728- if ( 'TRUNCATE ' === $ translation ->mysql_query_type ) {
729- $ this ->_results = true ;
730- $ this ->results = true ;
731- break ;
732- }
733- case 'UPDATE ' :
734- case 'INSERT ' :
735- case 'REPLACE ' :
736- /**
737- * SELECT CHANGES() is a workaround – we can't
738- * count rows using $stmt->rowCount()
739- * This method returns "0" (zero) with the SQLite driver at
740- * all times
741- * Source: https://www.php.net/manual/en/pdostatement.rowcount.php
742- */
743- $ this ->affected_rows = (int ) $ this ->pdo ->query ( 'select changes() ' )->fetch ()[0 ];
744- $ this ->return_value = $ this ->affected_rows ;
745- $ this ->num_rows = $ this ->affected_rows ;
746- $ this ->last_insert_id = $ this ->pdo ->lastInsertId ();
747- if ( is_numeric ( $ this ->last_insert_id ) ) {
748- $ this ->last_insert_id = (int ) $ this ->last_insert_id ;
749- }
750- break ;
751- }
752- }
753-
754695 /**
755696 * Method to format the error messages and put out to the file.
756697 *
@@ -772,164 +713,6 @@ private function set_error( $line, $function, $message ) {
772713 $ this ->is_error = true ;
773714 }
774715
775- /**
776- * Method to convert the SHOW COLUMNS query data to an object.
777- *
778- * It rewrites pragma results to mysql compatible array
779- * when query_type is describe, we use sqlite pragma function.
780- *
781- * @access private
782- */
783- private function convert_to_columns_object () {
784- $ _results = array ();
785- $ _columns = array ( // Field names MySQL SHOW COLUMNS returns.
786- 'Field ' => '' ,
787- 'Type ' => '' ,
788- 'Null ' => '' ,
789- 'Key ' => '' ,
790- 'Default ' => '' ,
791- 'Extra ' => '' ,
792- );
793- if ( empty ( $ this ->_results ) ) {
794- // These messages are properly escaped in the function.
795- echo $ this ->get_error_message ();
796- } else {
797- foreach ( $ this ->_results as $ row ) {
798- if ( ! is_object ( $ row ) ) {
799- continue ;
800- }
801- if ( property_exists ( $ row , 'name ' ) ) {
802- $ _columns ['Field ' ] = $ row ->name ;
803- }
804- if ( property_exists ( $ row , 'type ' ) ) {
805- $ _columns ['Type ' ] = $ row ->type ;
806- }
807- if ( property_exists ( $ row , 'notnull ' ) ) {
808- $ _columns ['Null ' ] = $ row ->notnull ? 'NO ' : 'YES ' ;
809- }
810- if ( property_exists ( $ row , 'pk ' ) ) {
811- $ _columns ['Key ' ] = $ row ->pk ? 'PRI ' : '' ;
812- }
813- if ( property_exists ( $ row , 'dflt_value ' ) ) {
814- $ _columns ['Default ' ] = $ row ->dflt_value ;
815- }
816- $ _results [] = new WP_SQLite_Object_Array ( $ _columns );
817- }
818- }
819- $ this ->results = $ _results ;
820- }
821-
822- /**
823- * Method to convert SHOW INDEX query data to PHP object.
824- *
825- * It rewrites the result of SHOW INDEX to the Object compatible with MySQL
826- * added the WHERE clause manipulation (ver 1.3.1)
827- *
828- * @access private
829- */
830- private function convert_to_index_object () {
831- $ _results = array ();
832- $ _columns = array (
833- 'Table ' => '' ,
834- 'Non_unique ' => '' , // Unique -> 0, not unique -> 1.
835- 'Key_name ' => '' , // The name of the index.
836- 'Seq_in_index ' => '' , // Column sequence number in the index. begins at 1.
837- 'Column_name ' => '' ,
838- 'Collation ' => '' , // A(scend) or NULL.
839- 'Cardinality ' => '' ,
840- 'Sub_part ' => '' , // Set to NULL.
841- 'Packed ' => '' , // How to pack key or else NULL.
842- 'Null ' => '' , // If column contains null, YES. If not, NO.
843- 'Index_type ' => '' , // BTREE, FULLTEXT, HASH, RTREE.
844- 'Comment ' => '' ,
845- );
846- if ( 0 === count ( $ this ->_results ) ) {
847- // These messages are properly escaped in the function.
848- echo $ this ->get_error_message ();
849- } else {
850- foreach ( $ this ->_results as $ row ) {
851- if ( 'table ' === $ row ->type && ! stripos ( $ row ->sql , 'primary ' ) ) {
852- continue ;
853- }
854- if ( 'index ' === $ row ->type && stripos ( $ row ->name , 'sqlite_autoindex ' ) !== false ) {
855- continue ;
856- }
857- switch ( $ row ->type ) {
858- case 'table ' :
859- $ pattern1 = '/^ \\s*PRIMARY.*\((.*)\)/im ' ;
860- $ pattern2 = '/^ \\s*( \\w+)? \\s*.*PRIMARY.*(?!\()/im ' ;
861- if ( preg_match ( $ pattern1 , $ row ->sql , $ match ) ) {
862- $ col_name = trim ( $ match [1 ] );
863- $ _columns ['Key_name ' ] = 'PRIMARY ' ;
864- $ _columns ['Non_unique ' ] = 0 ;
865- $ _columns ['Column_name ' ] = $ col_name ;
866- } elseif ( preg_match ( $ pattern2 , $ row ->sql , $ match ) ) {
867- $ col_name = trim ( $ match [1 ] );
868- $ _columns ['Key_name ' ] = 'PRIMARY ' ;
869- $ _columns ['Non_unique ' ] = 0 ;
870- $ _columns ['Column_name ' ] = $ col_name ;
871- }
872- break ;
873-
874- case 'index ' :
875- $ _columns ['Non_unique ' ] = 1 ;
876- if ( stripos ( $ row ->sql , 'unique ' ) !== false ) {
877- $ _columns ['Non_unique ' ] = 0 ;
878- }
879- if ( preg_match ( '/^.*\((.*)\)/i ' , $ row ->sql , $ match ) ) {
880- $ col_name = str_replace ( "' " , '' , $ match [1 ] );
881- $ _columns ['Column_name ' ] = trim ( $ col_name );
882- }
883- $ _columns ['Key_name ' ] = $ row ->name ;
884- break ;
885-
886- }
887- $ _columns ['Table ' ] = $ row ->tbl_name ;
888- $ _columns ['Collation ' ] = null ;
889- $ _columns ['Cardinality ' ] = 0 ;
890- $ _columns ['Sub_part ' ] = null ;
891- $ _columns ['Packed ' ] = null ;
892- $ _columns ['Null ' ] = 'NO ' ;
893- $ _columns ['Index_type ' ] = 'BTREE ' ;
894- $ _columns ['Comment ' ] = '' ;
895- $ _results [] = new WP_SQLite_Object_Array ( $ _columns );
896- }
897- if ( stripos ( $ this ->queries [0 ], 'WHERE ' ) !== false ) {
898- preg_match ( '/WHERE \\s*(.*)$/im ' , $ this ->queries [0 ], $ match );
899- $ match_parts = explode ( '= ' , $ match [1 ] );
900- $ key = trim ( $ match_parts [0 ] );
901- $ value = trim ( preg_replace ( "/[\';]/ " , '' , $ match_parts [1 ] ) );
902- foreach ( $ _results as $ result ) {
903- if ( ! empty ( $ result ->$ key ) && is_scalar ( $ result ->$ key ) && stripos ( $ value , $ result ->$ key ) !== false ) {
904- unset( $ _results );
905- $ _results [] = $ result ;
906- break ;
907- }
908- }
909- }
910- }
911-
912- $ this ->results = $ _results ;
913- }
914-
915- /**
916- * Method to the CHECK query data to an object.
917- *
918- * @access private
919- */
920- private function convert_result_check_or_analyze () {
921- $ is_check = 'check ' === $ this ->query_type ;
922- $ _results [] = new WP_SQLite_Object_Array (
923- array (
924- 'Table ' => '' ,
925- 'Op ' => $ is_check ? 'check ' : 'analyze ' ,
926- 'Msg_type ' => 'status ' ,
927- 'Msg_text ' => $ is_check ? 'OK ' : 'Table is already up to date ' ,
928- )
929- );
930- $ this ->results = $ _results ;
931- }
932-
933716 /**
934717 * Method to call PDO::beginTransaction().
935718 *
0 commit comments