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
16 changes: 8 additions & 8 deletions features/utils.feature
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ Feature: Utilities that do NOT depend on WordPress code

@require-mysql
Scenario: Check that `Utils\run_mysql_command()` uses STDOUT and STDERR by default
When I run `wp --skip-wordpress eval 'WP_CLI\Utils\run_mysql_command( "/usr/bin/env mysql --no-defaults", [ "user" => "{DB_USER}", "pass" => "{DB_PASSWORD}", "host" => "{DB_HOST}", "execute" => "SHOW DATABASES;" ] );'`
When I run `wp --skip-wordpress eval 'WP_CLI\Utils\run_mysql_command( "{MYSQL_BINARY} --no-defaults", [ "user" => "{DB_USER}", "pass" => "{DB_PASSWORD}", "host" => "{DB_HOST}", "execute" => "SHOW DATABASES;" ] );'`
Then STDOUT should contain:
"""
Database
Expand All @@ -42,7 +42,7 @@ Feature: Utilities that do NOT depend on WordPress code
"""
And STDERR should be empty

When I try `wp --skip-wordpress eval 'WP_CLI\Utils\run_mysql_command( "/usr/bin/env mysql --no-defaults", [ "user" => "{DB_USER}", "pass" => "{DB_PASSWORD}", "host" => "{DB_HOST}", "execute" => "broken query" ]);'`
When I try `wp --skip-wordpress eval 'WP_CLI\Utils\run_mysql_command( "{MYSQL_BINARY} --no-defaults", [ "user" => "{DB_USER}", "pass" => "{DB_PASSWORD}", "host" => "{DB_HOST}", "execute" => "broken query" ]);'`
Then STDOUT should be empty
And STDERR should contain:
"""
Expand All @@ -51,7 +51,7 @@ Feature: Utilities that do NOT depend on WordPress code

@require-mysql
Scenario: Check that `Utils\run_mysql_command()` can return data and errors if requested
When I run `wp --skip-wordpress eval 'list( $stdout, $stderr, $exit_code ) = WP_CLI\Utils\run_mysql_command( "/usr/bin/env mysql --no-defaults", [ "user" => "{DB_USER}", "pass" => "{DB_PASSWORD}", "host" => "{DB_HOST}", "execute" => "SHOW DATABASES;" ], null, false ); fwrite( STDOUT, strtoupper( $stdout ) ); fwrite( STDERR, strtoupper( $stderr ) );'`
When I run `wp --skip-wordpress eval 'list( $stdout, $stderr, $exit_code ) = WP_CLI\Utils\run_mysql_command( "{MYSQL_BINARY} --no-defaults", [ "user" => "{DB_USER}", "pass" => "{DB_PASSWORD}", "host" => "{DB_HOST}", "execute" => "SHOW DATABASES;" ], null, false ); fwrite( STDOUT, strtoupper( $stdout ) ); fwrite( STDERR, strtoupper( $stderr ) );'`
Then STDOUT should not contain:
"""
Database
Expand All @@ -70,7 +70,7 @@ Feature: Utilities that do NOT depend on WordPress code
"""
And STDERR should be empty

When I try `wp --skip-wordpress eval 'list( $stdout, $stderr, $exit_code ) = WP_CLI\Utils\run_mysql_command( "/usr/bin/env mysql --no-defaults", [ "user" => "{DB_USER}", "pass" => "{DB_PASSWORD}", "host" => "{DB_HOST}", "execute" => "broken query" ], null, false ); fwrite( STDOUT, strtoupper( $stdout ) ); fwrite( STDERR, strtoupper( $stderr ) );'`
When I try `wp --skip-wordpress eval 'list( $stdout, $stderr, $exit_code ) = WP_CLI\Utils\run_mysql_command( "{MYSQL_BINARY} --no-defaults", [ "user" => "{DB_USER}", "pass" => "{DB_PASSWORD}", "host" => "{DB_HOST}", "execute" => "broken query" ], null, false ); fwrite( STDOUT, strtoupper( $stdout ) ); fwrite( STDERR, strtoupper( $stderr ) );'`
Then STDOUT should be empty
And STDERR should not contain:
"""
Expand Down Expand Up @@ -149,19 +149,19 @@ Feature: Utilities that do NOT depend on WordPress code
"""
And save STDOUT as {DB_HOST_STRING}

When I try `mysql --database={DB_NAME} --user={DB_ROOT_USER} --password={DB_ROOT_PASSWORD} {DB_HOST_STRING} -e "SET GLOBAL max_allowed_packet=64*1024*1024;"`
When I try `{MYSQL_BINARY} --database={DB_NAME} --user={DB_ROOT_USER} --password={DB_ROOT_PASSWORD} {DB_HOST_STRING} -e "SET GLOBAL max_allowed_packet=64*1024*1024;"`
Then the return code should be 0

# This throws a warning because of the password.
When I try `mysql --database={DB_NAME} --user={DB_USER} --password={DB_PASSWORD} {DB_HOST_STRING} < test_db.sql`
When I try `{MYSQL_BINARY} --database={DB_NAME} --user={DB_USER} --password={DB_PASSWORD} {DB_HOST_STRING} < test_db.sql`
Then the return code should be 0

# The --skip-column-statistics flag is not always present.
When I try `mysqldump --help | grep -q 'column-statistics' && echo '--skip-column-statistics'`
When I try `{SQL_DUMP_COMMAND} --help | grep -q 'column-statistics' && echo '--skip-column-statistics'`
Then save STDOUT as {SKIP_COLUMN_STATISTICS_FLAG}

# This throws a warning because of the password.
When I try `{INVOKE_WP_CLI_WITH_PHP_ARGS--dmemory_limit=50M -ddisable_functions=ini_set} eval '\WP_CLI\Utils\run_mysql_command("/usr/bin/env mysqldump {SKIP_COLUMN_STATISTICS_FLAG} --no-tablespaces {DB_NAME}", [ "user" => "{DB_USER}", "pass" => "{DB_PASSWORD}", "host" => "{DB_HOST}" ], null, true);'`
When I try `{INVOKE_WP_CLI_WITH_PHP_ARGS--dmemory_limit=50M -ddisable_functions=ini_set} eval '\WP_CLI\Utils\run_mysql_command("/usr/bin/env {SQL_DUMP_COMMAND} {SKIP_COLUMN_STATISTICS_FLAG} --no-tablespaces {DB_NAME}", [ "user" => "{DB_USER}", "pass" => "{DB_PASSWORD}", "host" => "{DB_HOST}" ], null, true);'`
Then the return code should be 0
And STDOUT should not be empty
And STDOUT should contain:
Expand Down
122 changes: 107 additions & 15 deletions php/utils.php
Original file line number Diff line number Diff line change
Expand Up @@ -1818,37 +1818,103 @@
}

/**
* Get the path to the mysql binary.
* Return the detected database type.
*
* @return string Path to the mysql binary, or an empty string if not found.
* Can be either 'sqlite' (if in a WordPress installation with the SQLite drop-in),
* 'mysql', or 'mariadb'.
*
* @return string Database type.
*/
function get_db_type() {
static $db_type = null;

Check warning on line 1829 in php/utils.php

View check run for this annotation

Codecov / codecov/patch

php/utils.php#L1829

Added line #L1829 was not covered by tests

if ( defined( 'SQLITE_DB_DROPIN_VERSION' ) ) {
return 'sqlite';

Check warning on line 1832 in php/utils.php

View check run for this annotation

Codecov / codecov/patch

php/utils.php#L1831-L1832

Added lines #L1831 - L1832 were not covered by tests
}

if ( null !== $db_type ) {
return $db_type;

Check warning on line 1836 in php/utils.php

View check run for this annotation

Codecov / codecov/patch

php/utils.php#L1835-L1836

Added lines #L1835 - L1836 were not covered by tests
}

$db_type = 'mysql';

Check warning on line 1839 in php/utils.php

View check run for this annotation

Codecov / codecov/patch

php/utils.php#L1839

Added line #L1839 was not covered by tests

$binary = get_mysql_binary_path();

Check warning on line 1841 in php/utils.php

View check run for this annotation

Codecov / codecov/patch

php/utils.php#L1841

Added line #L1841 was not covered by tests

if ( '' !== $binary ) {
$result = Process::create( "$binary --version", null, null )->run();

Check warning on line 1844 in php/utils.php

View check run for this annotation

Codecov / codecov/patch

php/utils.php#L1843-L1844

Added lines #L1843 - L1844 were not covered by tests

if ( 0 === $result->return_code ) {
$db_type = ( false !== strpos( $result->stdout, 'MariaDB' ) ) ? 'mariadb' : 'mysql';

Check warning on line 1847 in php/utils.php

View check run for this annotation

Codecov / codecov/patch

php/utils.php#L1846-L1847

Added lines #L1846 - L1847 were not covered by tests
}
}

return $db_type;

Check warning on line 1851 in php/utils.php

View check run for this annotation

Codecov / codecov/patch

php/utils.php#L1851

Added line #L1851 was not covered by tests
}

/**
* Get the path to the MySQL or MariaDB binary.
*
* If the MySQL binary is provided by MariaDB (as determined by the version string),
* prefers the actual MariaDB binary.
*
* @since 2.12.0 Now also checks for MariaDB.
*
* @return string Path to the MySQL/MariaDB binary, or an empty string if not found.
*/
function get_mysql_binary_path() {
static $path = null;

if ( null === $path ) {
$result = Process::create( '/usr/bin/env which mysql', null, null )->run();
if ( null !== $path ) {
return $path;

Check warning on line 1868 in php/utils.php

View check run for this annotation

Codecov / codecov/patch

php/utils.php#L1867-L1868

Added lines #L1867 - L1868 were not covered by tests
}

if ( 0 !== $result->return_code ) {
$path = '';
} else {
$path = trim( $result->stdout );
$path = '';
$mysql = Process::create( '/usr/bin/env which mysql', null, null )->run();
$mariadb = Process::create( '/usr/bin/env which mariadb', null, null )->run();

Check warning on line 1873 in php/utils.php

View check run for this annotation

Codecov / codecov/patch

php/utils.php#L1871-L1873

Added lines #L1871 - L1873 were not covered by tests

$mysql_binary = trim( $mysql->stdout );
$mariadb_binary = trim( $mariadb->stdout );

Check warning on line 1876 in php/utils.php

View check run for this annotation

Codecov / codecov/patch

php/utils.php#L1875-L1876

Added lines #L1875 - L1876 were not covered by tests

if ( 0 === $mysql->return_code ) {
if ( '' !== $mysql_binary ) {
$path = $mysql_binary;
$result = Process::create( "$mysql_binary --version", null, null )->run();

Check warning on line 1881 in php/utils.php

View check run for this annotation

Codecov / codecov/patch

php/utils.php#L1878-L1881

Added lines #L1878 - L1881 were not covered by tests

// It's actually MariaDB disguised as MySQL.
if ( 0 === $result->return_code && false !== strpos( $result->stdout, 'MariaDB' ) && 0 === $mariadb->return_code ) {
$path = $mariadb_binary;

Check warning on line 1885 in php/utils.php

View check run for this annotation

Codecov / codecov/patch

php/utils.php#L1884-L1885

Added lines #L1884 - L1885 were not covered by tests
}
}
} elseif ( 0 === $mariadb->return_code ) {
$path = $mariadb_binary;

Check warning on line 1889 in php/utils.php

View check run for this annotation

Codecov / codecov/patch

php/utils.php#L1888-L1889

Added lines #L1888 - L1889 were not covered by tests
}

if ( '' === $path ) {
WP_CLI::Error( 'Could not find mysql binary' );

Check warning on line 1893 in php/utils.php

View check run for this annotation

Codecov / codecov/patch

php/utils.php#L1892-L1893

Added lines #L1892 - L1893 were not covered by tests
}

return $path;
}

/**
* Get the version of the MySQL database.
* Get the version of the MySQL or MariaDB database.
*
* @since 2.12.0 Now also checks for MariaDB.
*
* @return string Version of the MySQL database, or an empty string if not
* found.
* @return string Version of the MySQL/MariaDB database,
* or an empty string if not found.
*/
function get_mysql_version() {
static $version = null;

if ( null === $version ) {
$result = Process::create( '/usr/bin/env mysql --version', null, null )->run();
if ( null !== $version ) {
return $version;

Check warning on line 1911 in php/utils.php

View check run for this annotation

Codecov / codecov/patch

php/utils.php#L1910-L1911

Added lines #L1910 - L1911 were not covered by tests
}

$db_type = get_db_type();

Check warning on line 1914 in php/utils.php

View check run for this annotation

Codecov / codecov/patch

php/utils.php#L1914

Added line #L1914 was not covered by tests

if ( 'sqlite' !== $db_type ) {
$result = Process::create( "/usr/bin/env $db_type --version", null, null )->run();

Check warning on line 1917 in php/utils.php

View check run for this annotation

Codecov / codecov/patch

php/utils.php#L1916-L1917

Added lines #L1916 - L1917 were not covered by tests

if ( 0 !== $result->return_code ) {
$version = '';
Expand All @@ -1860,6 +1926,24 @@
return $version;
}

/**
* Returns the correct `dump` command based on the detected database type.
*
* @return string The appropriate dump command.
*/
function get_sql_dump_command() {
return 'mariadb' === get_db_type() ? 'mariadb-dump' : 'mysqldump';

Check warning on line 1935 in php/utils.php

View check run for this annotation

Codecov / codecov/patch

php/utils.php#L1935

Added line #L1935 was not covered by tests
}

/**
* Returns the correct `check` command based on the detected database type.
*
* @return string The appropriate check command.
*/
function get_sql_check_command() {
return 'mariadb' === get_db_type() ? 'mariadb-check' : 'mysqlcheck';

Check warning on line 1944 in php/utils.php

View check run for this annotation

Codecov / codecov/patch

php/utils.php#L1944

Added line #L1944 was not covered by tests
}

/**
* Get the SQL modes of the MySQL session.
*
Expand All @@ -1869,8 +1953,16 @@
function get_sql_modes() {
static $sql_modes = null;

if ( null === $sql_modes ) {
$result = Process::create( '/usr/bin/env mysql --no-auto-rehash --batch --skip-column-names --execute="SELECT @@SESSION.sql_mode"', null, null )->run();
if ( null !== $sql_modes ) {
return $sql_modes;

Check warning on line 1957 in php/utils.php

View check run for this annotation

Codecov / codecov/patch

php/utils.php#L1956-L1957

Added lines #L1956 - L1957 were not covered by tests
}

$binary = get_mysql_binary_path();

Check warning on line 1960 in php/utils.php

View check run for this annotation

Codecov / codecov/patch

php/utils.php#L1960

Added line #L1960 was not covered by tests

if ( '' === $binary ) {
$sql_modes = [];

Check warning on line 1963 in php/utils.php

View check run for this annotation

Codecov / codecov/patch

php/utils.php#L1962-L1963

Added lines #L1962 - L1963 were not covered by tests
} else {
$result = Process::create( "$binary --no-auto-rehash --batch --skip-column-names --execute=\"SELECT @@SESSION.sql_mode\"", null, null )->run();

Check warning on line 1965 in php/utils.php

View check run for this annotation

Codecov / codecov/patch

php/utils.php#L1965

Added line #L1965 was not covered by tests

if ( 0 !== $result->return_code ) {
$sql_modes = [];
Expand Down
Loading