@@ -504,10 +504,17 @@ public function __invoke( $args, $assoc_args ) {
504504 if ( $ this ->export_handle ) {
505505 fwrite ( $ this ->export_handle , "\nDROP TABLE IF EXISTS $ table_sql; \n" );
506506
507- // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared -- escaped through self::esc_sql_ident
508- $ row = $ wpdb ->get_row ( "SHOW CREATE TABLE $ table_sql " , ARRAY_N );
507+ if ( 'sqlite ' === Utils \get_db_type () ) {
508+ // sqlite_master returns a single `sql` column with the CREATE TABLE statement.
509+ $ row = $ wpdb ->get_row ( $ wpdb ->prepare ( "SELECT sql FROM sqlite_master WHERE type='table' AND name = %s " , $ table ), ARRAY_N );
510+ $ create_table = $ row [0 ];
511+ } else {
512+ // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared -- escaped through self::esc_sql_ident
513+ $ row = $ wpdb ->get_row ( "SHOW CREATE TABLE $ table_sql " , ARRAY_N );
514+ $ create_table = $ row [1 ];
515+ }
509516
510- fwrite ( $ this ->export_handle , $ row [ 1 ] . "; \n" );
517+ fwrite ( $ this ->export_handle , $ create_table . "; \n" );
511518 list ( $ table_report , $ total_rows ) = $ this ->php_export_table ( $ table , $ old , $ new );
512519 if ( $ this ->report ) {
513520 $ report = array_merge ( $ report , $ table_report );
@@ -555,12 +562,17 @@ public function __invoke( $args, $assoc_args ) {
555562 $ col_sql = self ::esc_sql_ident ( $ col );
556563 $ wpdb ->last_error = '' ;
557564
558- // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared -- escaped through self::esc_sql_ident
559- $ serial_row = $ wpdb ->get_row ( "SELECT * FROM $ table_sql WHERE $ col_sql REGEXP '^[aiO]:[1-9]' LIMIT 1 " );
560-
561- // When the regex triggers an error, we should fall back to PHP
562- if ( false !== strpos ( $ wpdb ->last_error , 'ERROR 1139 ' ) ) {
565+ if ( 'sqlite ' === Utils \get_db_type () ) {
566+ // SQLite does not support REGEXP by default, fall back to PHP processing.
563567 $ serial_row = true ;
568+ } else {
569+ // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared -- escaped through self::esc_sql_ident
570+ $ serial_row = $ wpdb ->get_row ( "SELECT * FROM $ table_sql WHERE $ col_sql REGEXP '^[aiO]:[1-9]' LIMIT 1 " );
571+
572+ // When the regex triggers an error, we should fall back to PHP
573+ if ( false !== strpos ( $ wpdb ->last_error , 'ERROR 1139 ' ) ) {
574+ $ serial_row = true ;
575+ }
564576 }
565577 }
566578
@@ -695,11 +707,13 @@ private function sql_handle_col( $col, $primary_keys, $table, $old, $new ) {
695707 }
696708 } elseif ( $ has_json ) {
697709 // Single query with OR to avoid counting rows that match both forms twice.
710+ $ like = self ::like_operator ();
698711 // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared -- escaped through self::esc_sql_ident
699- $ count = (int ) $ wpdb ->get_var ( $ wpdb ->prepare ( "SELECT COUNT( $ col_sql) FROM $ table_sql WHERE $ col_sql LIKE BINARY %s OR $ col_sql LIKE BINARY %s; " , '% ' . self ::esc_like ( $ old ) . '% ' , '% ' . self ::esc_like ( $ old_json ) . '% ' ) );
712+ $ count = (int ) $ wpdb ->get_var ( $ wpdb ->prepare ( "SELECT COUNT( $ col_sql) FROM $ table_sql WHERE $ col_sql $ like %s OR $ col_sql $ like %s; " , '% ' . self ::esc_like ( $ old ) . '% ' , '% ' . self ::esc_like ( $ old_json ) . '% ' ) );
700713 } else {
714+ $ like = self ::like_operator ();
701715 // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared -- escaped through self::esc_sql_ident
702- $ count = (int ) $ wpdb ->get_var ( $ wpdb ->prepare ( "SELECT COUNT( $ col_sql) FROM $ table_sql WHERE $ col_sql LIKE BINARY %s; " , '% ' . self ::esc_like ( $ old ) . '% ' ) );
716+ $ count = (int ) $ wpdb ->get_var ( $ wpdb ->prepare ( "SELECT COUNT( $ col_sql) FROM $ table_sql WHERE $ col_sql $ like %s; " , '% ' . self ::esc_like ( $ old ) . '% ' ) );
703717 }
704718 } else {
705719 if ( $ this ->log_handle ) {
@@ -740,10 +754,11 @@ private function php_handle_col( $col, $primary_keys, $table, $old, $new ) {
740754 $ base_key_condition = '' ;
741755 $ where_key = '' ;
742756 if ( ! $ this ->regex ) {
757+ $ like = self ::like_operator ();
743758 $ old_json = self ::json_encode_strip_quotes ( $ old );
744- $ base_key_condition = "$ col_sql " . $ wpdb ->prepare ( ' LIKE BINARY %s ' , '% ' . self ::esc_like ( $ old ) . '% ' );
759+ $ base_key_condition = "$ col_sql " . $ wpdb ->prepare ( " $ like %s " , '% ' . self ::esc_like ( $ old ) . '% ' );
745760 if ( $ old_json !== $ old ) {
746- $ base_key_condition = "( $ base_key_condition OR $ col_sql " . $ wpdb ->prepare ( ' LIKE BINARY %s ' , '% ' . self ::esc_like ( $ old_json ) . '% ' ) . ' ) ' ;
761+ $ base_key_condition = "( $ base_key_condition OR $ col_sql " . $ wpdb ->prepare ( " $ like %s " , '% ' . self ::esc_like ( $ old_json ) . '% ' ) . ' ) ' ;
747762 }
748763 $ where_key = "WHERE $ base_key_condition " ;
749764 }
@@ -953,20 +968,38 @@ private static function get_columns( $table ) {
953968 $ all_columns = array ();
954969 $ suppress_errors = $ wpdb ->suppress_errors ();
955970
956- // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared -- escaped through self::esc_sql_ident
957- $ results = $ wpdb ->get_results ( "DESCRIBE $ table_sql " );
971+ if ( 'sqlite ' === Utils \get_db_type () ) {
972+ // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared -- escaped through self::esc_sql_ident
973+ $ results = $ wpdb ->get_results ( "PRAGMA table_info( $ table_sql) " );
958974
959- if ( ! empty ( $ results ) ) {
960- foreach ( $ results as $ col ) {
961- if ( 'PRI ' === $ col ->Key ) {
962- $ primary_keys [] = $ col ->Field ;
975+ if ( ! empty ( $ results ) ) {
976+ foreach ( $ results as $ col ) {
977+ if ( $ col ->pk > 0 ) {
978+ $ primary_keys [] = $ col ->name ;
979+ }
980+ if ( self ::is_text_col ( $ col ->type ) ) {
981+ $ text_columns [] = $ col ->name ;
982+ }
983+ $ all_columns [] = $ col ->name ;
963984 }
964- if ( self ::is_text_col ( $ col ->Type ) ) {
965- $ text_columns [] = $ col ->Field ;
985+ }
986+ } else {
987+ // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared -- escaped through self::esc_sql_ident
988+ $ results = $ wpdb ->get_results ( "DESCRIBE $ table_sql " );
989+
990+ if ( ! empty ( $ results ) ) {
991+ foreach ( $ results as $ col ) {
992+ if ( 'PRI ' === $ col ->Key ) {
993+ $ primary_keys [] = $ col ->Field ;
994+ }
995+ if ( self ::is_text_col ( $ col ->Type ) ) {
996+ $ text_columns [] = $ col ->Field ;
997+ }
998+ $ all_columns [] = $ col ->Field ;
966999 }
967- $ all_columns [] = $ col ->Field ;
9681000 }
9691001 }
1002+
9701003 $ wpdb ->suppress_errors ( $ suppress_errors );
9711004 return array ( $ primary_keys , $ text_columns , $ all_columns );
9721005 }
@@ -997,6 +1030,15 @@ private static function esc_like( $old ) {
9971030 return $ old ;
9981031 }
9991032
1033+ /**
1034+ * Returns the SQL LIKE operator, using LIKE BINARY for MySQL and plain LIKE for SQLite.
1035+ *
1036+ * @return string The LIKE operator appropriate for the current database.
1037+ */
1038+ private static function like_operator () {
1039+ return 'sqlite ' === Utils \get_db_type () ? 'LIKE ' : 'LIKE BINARY ' ;
1040+ }
1041+
10001042 /**
10011043 * Returns the JSON-encoded representation of a string with the surrounding quotes stripped.
10021044 * This is used to also handle values stored as raw JSON in the database (e.g. WordPress font data).
@@ -1110,9 +1152,10 @@ private function log_sql_diff( $col, $primary_keys, $table, $old, $new ) {
11101152
11111153 $ table_sql = self ::esc_sql_ident ( $ table );
11121154 $ col_sql = self ::esc_sql_ident ( $ col );
1155+ $ like = self ::like_operator ();
11131156
11141157 // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared -- escaped through self::esc_sql_ident
1115- $ results = $ wpdb ->get_results ( $ wpdb ->prepare ( "SELECT {$ primary_keys_sql }{$ col_sql } FROM {$ table_sql } WHERE {$ col_sql } LIKE BINARY %s " , '% ' . self ::esc_like ( $ old ) . '% ' ), ARRAY_N );
1158+ $ results = $ wpdb ->get_results ( $ wpdb ->prepare ( "SELECT {$ primary_keys_sql }{$ col_sql } FROM {$ table_sql } WHERE {$ col_sql } $ like %s " , '% ' . self ::esc_like ( $ old ) . '% ' ), ARRAY_N );
11161159
11171160 if ( empty ( $ results ) ) {
11181161 return 0 ;
0 commit comments