Skip to content

Commit fcd5a54

Browse files
committed
Merge remote-tracking branch 'WordPress/lexer-translation' into lexer-translation
2 parents 6411003 + 3efdc7c commit fcd5a54

1 file changed

Lines changed: 56 additions & 273 deletions

File tree

wp-includes/sqlite/class-wp-sqlite-pdo-engine.php

Lines changed: 56 additions & 273 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)