diff --git a/src/Import.php b/src/Import.php index d9aa644..7d23723 100644 --- a/src/Import.php +++ b/src/Import.php @@ -35,7 +35,11 @@ public function run( $sql_file_path, $args ) { $is_stdin = '-' === $sql_file_path; $import_file = $is_stdin ? 'php://stdin' : $sql_file_path; - $this->execute_statements( $import_file ); + if ( method_exists( $this->driver, 'create_parser' ) ) { + $this->execute_statements_with_ast_parser( $import_file ); + } else { + $this->execute_statements( $import_file ); + } $imported_from = $is_stdin ? 'STDIN' : $sql_file_path; WP_CLI::success( sprintf( "Imported from '%s'.", $imported_from ) ); @@ -133,4 +137,39 @@ public function parse_statements( $sql_file_path ) { fclose( $handle ); } + + /** + * Execute SQL statements from an SQL dump file using the AST parser. + * + * @param $import_file + * + * @return void + * @throws Exception + */ + protected function execute_statements_with_ast_parser( $import_file ) { + $raw_queries = file_get_contents( $import_file ); + + // Detect and convert encoding to UTF-8 + $detected_encoding = mb_detect_encoding( $raw_queries, mb_list_encodings(), true ); + if ( $detected_encoding && 'UTF-8' !== $detected_encoding ) { + $raw_queries = mb_convert_encoding( $raw_queries, 'UTF-8', $detected_encoding ); + } + + $parser = $this->driver->create_parser( $raw_queries ); + while ( $parser->next_query() ) { + $ast = $parser->get_query_ast(); + $statement = substr( $raw_queries, $ast->get_start(), $ast->get_length() ); + try { + $this->driver->query( $statement ); + } catch ( Exception $e ) { + // Skip errors when executing SET comment statements + if ( 0 === strpos( $statement, 'SET ' ) && false !== strpos( $statement, '*/' ) ) { + echo 'Warning - SQLite import skipped SET comment statement: ' . $statement . PHP_EOL; + continue; + } + WP_CLI::error( 'SQLite import could not execute statement: ' . $statement ); + echo $this->driver->get_error_message(); + } + } + } }