Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 15 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@ $ wp sqlite import <file>
<file>
The path to the MySQL compatible dump file to import. When passing `-` as the file argument, the SQL commands are read from standard input.

[--enable-ast-driver]
Enables new AST driver for full MySQL compatibility.

### wp sqlite export

Exports an SQLite database to a MySQL compatible file.
Expand All @@ -42,6 +45,9 @@ $ wp sqlite export [<file>] [--tables=<tables>] [--exclude-tables] [--porcelain]
[--porcelain]
Output filename for the exported database.

[--enable-ast-driver]
Enables new AST driver for full MySQL compatibility.

### wp sqlite tables

Lists the SQLite database tables.
Expand All @@ -61,23 +67,26 @@ $ wp sqlite tables [--format=<list|csv>]
- csv
---

[--enable-ast-driver]
Enables new AST driver for full MySQL compatibility.

**EXAMPLES**

```
# List all tables
$ wp sqlite tables
wp_users
wp_usermeta
wp_termmeta
wp_terms
wp_term_taxonomy
wp_term_relationships
wp_commentmeta
wp_comments
wp_links
wp_options
wp_postmeta
wp_posts
wp_term_relationships
wp_term_taxonomy
wp_termmeta
wp_terms
wp_usermeta
wp_users

* List all tables in CSV format
$ wp sqlite tables --format=csv
Expand Down
2 changes: 1 addition & 1 deletion features/pass.feature
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
Feature: Always Passing Test
Scenario: Evaluate true expression
Scenario: Evaluate true expression
Given a WP install

When I run `wp eval "var_export(true);"`
Expand Down
File renamed without changes.
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -11,32 +11,32 @@ Feature: WP-CLI SQLite Tables Command
When I run `wp sqlite tables`
Then STDOUT should contain:
"""
wp_users
wp_usermeta
wp_termmeta
wp_terms
wp_term_taxonomy
wp_term_relationships
wp_commentmeta
wp_comments
wp_links
wp_options
wp_postmeta
wp_posts
wp_term_relationships
wp_term_taxonomy
wp_termmeta
wp_terms
wp_usermeta
wp_users
"""

@require-sqlite
Scenario: Successfully list the tables in the SQLite database in a CSV format
When I run `wp sqlite tables --format=csv`
Then STDOUT should contain:
"""
wp_users,wp_usermeta,wp_termmeta,wp_terms,wp_term_taxonomy,wp_term_relationships,wp_commentmeta,wp_comments,wp_links,wp_options,wp_postmeta,wp_posts
wp_commentmeta,wp_comments,wp_links,wp_options,wp_postmeta,wp_posts,wp_term_relationships,wp_term_taxonomy,wp_termmeta,wp_terms,wp_usermeta,wp_users
"""

@require-sqlite
Scenario: Successfully list the tables in the SQLite database in a CSV format
When I run `wp sqlite tables --format=json`
Then STDOUT should contain:
"""
["wp_users","wp_usermeta","wp_termmeta","wp_terms","wp_term_taxonomy","wp_term_relationships","wp_commentmeta","wp_comments","wp_links","wp_options","wp_postmeta","wp_posts"]
["wp_commentmeta","wp_comments","wp_links","wp_options","wp_postmeta","wp_posts","wp_term_relationships","wp_term_taxonomy","wp_termmeta","wp_terms","wp_usermeta","wp_users"]
"""
58 changes: 46 additions & 12 deletions src/Export.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,23 @@
use Exception;
use PDO;
use WP_CLI;
use WP_SQLite_Driver;
use WP_SQLite_Translator;

class Export {
/**
* The SQLite driver instance.
*
* @var WP_SQLite_Driver|WP_SQLite_Translator
*/
protected $driver;

protected $translator;
protected $args = array();
protected $is_stdout = false;

public function __construct() {
SQLiteDatabaseIntegrationLoader::load_plugin();
$this->translator = new WP_SQLite_Translator();
$this->driver = SQLiteDriverFactory::create_driver();
}

/**
Expand Down Expand Up @@ -79,19 +85,27 @@ protected function close_output_stream( $handle ) {
protected function write_sql_statements( $handle ) {
$include_tables = $this->get_include_tables();
$exclude_tables = $this->get_exclude_tables();
foreach ( $this->translator->query( 'SHOW TABLES' ) as $table ) {
foreach ( $this->driver->query( 'SHOW TABLES' ) as $row ) {
$table_name = array_values( (array) $row )[0];

// Skip tables that are not in the include_tables list if the list is defined
if ( ! empty( $include_tables ) && ! in_array( $table->name, $include_tables, true ) ) {
if ( ! empty( $include_tables ) && ! in_array( $table_name, $include_tables, true ) ) {
continue;
}

// Skip internal tables used by the new SQLite driver
// (This is only needed when exporting with the legacy driver.)
if ( 0 === strpos( $table_name, '_wp_sqlite_' ) ) {
continue;
}

// Skip tables that are in the exclude_tables list
if ( in_array( $table->name, $exclude_tables, true ) ) {
if ( in_array( $table_name, $exclude_tables, true ) ) {
continue;
}

$this->write_create_table_statement( $handle, $table->name );
$this->write_insert_statements( $handle, $table->name );
$this->write_create_table_statement( $handle, $table_name );
$this->write_insert_statements( $handle, $table_name );
}

fwrite( $handle, sprintf( '-- Dump completed on %s', gmdate( 'c' ) ) );
Expand Down Expand Up @@ -144,8 +158,14 @@ protected function write_insert_statements( $handle, $table_name ) {
* @throws Exception
*/
protected function get_create_statement( $table_name ) {
$create = $this->translator->query( 'SHOW CREATE TABLE ' . $table_name );
return $create[0]->{'Create Table'} . "\n";
$table_name = $this->driver instanceof WP_SQLite_Driver
? $this->driver->get_connection()->quote_identifier( $table_name )
: $table_name;

$create = $this->driver->query( 'SHOW CREATE TABLE ' . $table_name );
$sql = $create[0]->{'Create Table'};
$sql = rtrim( $sql, ';' ); // The old SQLite driver appends a semicolon.
return $sql . ";\n";
}

/**
Expand All @@ -156,7 +176,7 @@ protected function get_create_statement( $table_name ) {
* @return \Generator
*/
protected function get_insert_statements( $table_name ) {
$pdo = $this->translator->get_pdo();
$pdo = $this->get_pdo();
$stmt = $pdo->prepare( 'SELECT * FROM ' . $table_name );
$stmt->execute();
// phpcs:ignore
Expand All @@ -175,6 +195,8 @@ protected function get_exclude_tables() {
return array_merge(
$exclude_tables,
[
// This list is only needed when exporting with the legacy driver.
// In the new SQLite driver, SHOW TABLES never returns these tables.
'_mysql_data_types_cache',
'sqlite_master',
'sqlite_sequence',
Expand Down Expand Up @@ -235,7 +257,7 @@ protected function escape_values( PDO $pdo, $values ) {
* @return string
*/
protected function escape_string( $value ) {
$pdo = $this->translator->get_pdo();
$pdo = $this->get_pdo();
return addcslashes( $pdo->quote( $value ), "\\\n" );
}

Expand All @@ -261,9 +283,21 @@ protected function get_dump_comment( $comment ) {
* @return bool
*/
protected function table_has_records( $table_name ) {
$pdo = $this->translator->get_pdo();
$pdo = $this->get_pdo();
$stmt = $pdo->prepare( 'SELECT COUNT(*) FROM ' . $table_name );
$stmt->execute();
return $stmt->fetchColumn() > 0;
}

/**
* Get the PDO instance.
*
* @return PDO
*/
protected function get_pdo() {
if ( $this->driver instanceof WP_SQLite_Translator ) {
return $this->driver->get_pdo();
}
return $this->driver->get_connection()->get_pdo();
}
}
13 changes: 9 additions & 4 deletions src/Import.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,18 @@
use WP_SQLite_Translator;

class Import {
/**
* The SQLite driver instance.
*
* @var WP_SQLite_Driver|WP_SQLite_Translator
*/
protected $driver;

protected $translator;
protected $args;

public function __construct() {
SQLiteDatabaseIntegrationLoader::load_plugin();
$this->translator = new WP_SQLite_Translator();
$this->driver = SQLiteDriverFactory::create_driver();
}

/**
Expand Down Expand Up @@ -46,10 +51,10 @@ public function run( $sql_file_path, $args ) {
*/
protected function execute_statements( $import_file ) {
foreach ( $this->parse_statements( $import_file ) as $statement ) {
$result = $this->translator->query( $statement );
$result = $this->driver->query( $statement );
if ( false === $result ) {
WP_CLI::warning( 'Could not execute statement: ' . $statement );
echo $this->translator->get_error_message();
echo $this->driver->get_error_message();
}
}
}
Expand Down
32 changes: 27 additions & 5 deletions src/SQLiteDatabaseIntegrationLoader.php
Original file line number Diff line number Diff line change
Expand Up @@ -85,10 +85,32 @@ public static function load_plugin() {
// We also need to selectively load the necessary classes from the plugin.
require_once $plugin_directory . '/php-polyfills.php';
require_once $plugin_directory . '/constants.php';
require_once $plugin_directory . '/wp-includes/sqlite/class-wp-sqlite-lexer.php';
require_once $plugin_directory . '/wp-includes/sqlite/class-wp-sqlite-query-rewriter.php';
require_once $plugin_directory . '/wp-includes/sqlite/class-wp-sqlite-translator.php';
require_once $plugin_directory . '/wp-includes/sqlite/class-wp-sqlite-token.php';
require_once $plugin_directory . '/wp-includes/sqlite/class-wp-sqlite-pdo-user-defined-functions.php';

$new_driver_enabled = defined( 'WP_SQLITE_AST_DRIVER' ) && WP_SQLITE_AST_DRIVER;

if ( $new_driver_enabled ) {
require_once $plugin_directory . '/version.php';
require_once $plugin_directory . '/wp-includes/parser/class-wp-parser-grammar.php';
require_once $plugin_directory . '/wp-includes/parser/class-wp-parser.php';
require_once $plugin_directory . '/wp-includes/parser/class-wp-parser-node.php';
require_once $plugin_directory . '/wp-includes/parser/class-wp-parser-token.php';
require_once $plugin_directory . '/wp-includes/mysql/class-wp-mysql-token.php';
require_once $plugin_directory . '/wp-includes/mysql/class-wp-mysql-lexer.php';
require_once $plugin_directory . '/wp-includes/mysql/class-wp-mysql-parser.php';
require_once $plugin_directory . '/wp-includes/sqlite/class-wp-sqlite-pdo-user-defined-functions.php';
require_once $plugin_directory . '/wp-includes/sqlite-ast/class-wp-sqlite-connection.php';
require_once $plugin_directory . '/wp-includes/sqlite-ast/class-wp-sqlite-configurator.php';
require_once $plugin_directory . '/wp-includes/sqlite-ast/class-wp-sqlite-driver.php';
require_once $plugin_directory . '/wp-includes/sqlite-ast/class-wp-sqlite-driver-exception.php';
require_once $plugin_directory . '/wp-includes/sqlite-ast/class-wp-sqlite-information-schema-builder.php';
require_once $plugin_directory . '/wp-includes/sqlite-ast/class-wp-sqlite-information-schema-exception.php';
require_once $plugin_directory . '/wp-includes/sqlite-ast/class-wp-sqlite-information-schema-reconstructor.php';
} else {
require_once $plugin_directory . '/wp-includes/sqlite/class-wp-sqlite-lexer.php';
require_once $plugin_directory . '/wp-includes/sqlite/class-wp-sqlite-query-rewriter.php';
require_once $plugin_directory . '/wp-includes/sqlite/class-wp-sqlite-translator.php';
require_once $plugin_directory . '/wp-includes/sqlite/class-wp-sqlite-token.php';
require_once $plugin_directory . '/wp-includes/sqlite/class-wp-sqlite-pdo-user-defined-functions.php';
}
}
}
29 changes: 29 additions & 0 deletions src/SQLiteDriverFactory.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<?php

namespace Automattic\WP_CLI\SQLite;

use WP_SQLite_Connection;
use WP_SQLite_Driver;
use WP_SQLite_Translator;

class SQLiteDriverFactory {
/**
* Create an instance of the SQLite driver.
*
* @return WP_SQLite_Driver|WP_SQLite_Translator
*/
public static function create_driver() {
$new_driver_enabled = defined( 'WP_SQLITE_AST_DRIVER' ) && WP_SQLITE_AST_DRIVER;

if ( $new_driver_enabled ) {
$connection = new WP_SQLite_Connection(
array(
'path' => FQDB,
)
);
return new WP_SQLite_Driver( $connection, DB_NAME );
}

return new WP_SQLite_Translator();
}
}
Loading