Skip to content

Commit aeae871

Browse files
authored
Merge pull request #6072 from wp-cli/try/mariadb-detection
Detect MariaDB vs MySQL
2 parents 366764f + 8dc58a3 commit aeae871

File tree

2 files changed

+115
-23
lines changed

2 files changed

+115
-23
lines changed

features/utils.feature

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ Feature: Utilities that do NOT depend on WordPress code
3131

3232
@require-mysql
3333
Scenario: Check that `Utils\run_mysql_command()` uses STDOUT and STDERR by default
34-
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;" ] );'`
34+
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;" ] );'`
3535
Then STDOUT should contain:
3636
"""
3737
Database
@@ -42,7 +42,7 @@ Feature: Utilities that do NOT depend on WordPress code
4242
"""
4343
And STDERR should be empty
4444

45-
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" ]);'`
45+
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" ]);'`
4646
Then STDOUT should be empty
4747
And STDERR should contain:
4848
"""
@@ -51,7 +51,7 @@ Feature: Utilities that do NOT depend on WordPress code
5151

5252
@require-mysql
5353
Scenario: Check that `Utils\run_mysql_command()` can return data and errors if requested
54-
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 ) );'`
54+
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 ) );'`
5555
Then STDOUT should not contain:
5656
"""
5757
Database
@@ -70,7 +70,7 @@ Feature: Utilities that do NOT depend on WordPress code
7070
"""
7171
And STDERR should be empty
7272

73-
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 ) );'`
73+
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 ) );'`
7474
Then STDOUT should be empty
7575
And STDERR should not contain:
7676
"""
@@ -149,19 +149,19 @@ Feature: Utilities that do NOT depend on WordPress code
149149
"""
150150
And save STDOUT as {DB_HOST_STRING}
151151
152-
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;"`
152+
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;"`
153153
Then the return code should be 0
154154
155155
# This throws a warning because of the password.
156-
When I try `mysql --database={DB_NAME} --user={DB_USER} --password={DB_PASSWORD} {DB_HOST_STRING} < test_db.sql`
156+
When I try `{MYSQL_BINARY} --database={DB_NAME} --user={DB_USER} --password={DB_PASSWORD} {DB_HOST_STRING} < test_db.sql`
157157
Then the return code should be 0
158158
159159
# The --skip-column-statistics flag is not always present.
160-
When I try `mysqldump --help | grep -q 'column-statistics' && echo '--skip-column-statistics'`
160+
When I try `{SQL_DUMP_COMMAND} --help | grep -q 'column-statistics' && echo '--skip-column-statistics'`
161161
Then save STDOUT as {SKIP_COLUMN_STATISTICS_FLAG}
162162
163163
# This throws a warning because of the password.
164-
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);'`
164+
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);'`
165165
Then the return code should be 0
166166
And STDOUT should not be empty
167167
And STDOUT should contain:

php/utils.php

Lines changed: 107 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1818,37 +1818,103 @@ function pluralize( $noun, $count = null ) {
18181818
}
18191819

18201820
/**
1821-
* Get the path to the mysql binary.
1821+
* Return the detected database type.
18221822
*
1823-
* @return string Path to the mysql binary, or an empty string if not found.
1823+
* Can be either 'sqlite' (if in a WordPress installation with the SQLite drop-in),
1824+
* 'mysql', or 'mariadb'.
1825+
*
1826+
* @return string Database type.
1827+
*/
1828+
function get_db_type() {
1829+
static $db_type = null;
1830+
1831+
if ( defined( 'SQLITE_DB_DROPIN_VERSION' ) ) {
1832+
return 'sqlite';
1833+
}
1834+
1835+
if ( null !== $db_type ) {
1836+
return $db_type;
1837+
}
1838+
1839+
$db_type = 'mysql';
1840+
1841+
$binary = get_mysql_binary_path();
1842+
1843+
if ( '' !== $binary ) {
1844+
$result = Process::create( "$binary --version", null, null )->run();
1845+
1846+
if ( 0 === $result->return_code ) {
1847+
$db_type = ( false !== strpos( $result->stdout, 'MariaDB' ) ) ? 'mariadb' : 'mysql';
1848+
}
1849+
}
1850+
1851+
return $db_type;
1852+
}
1853+
1854+
/**
1855+
* Get the path to the MySQL or MariaDB binary.
1856+
*
1857+
* If the MySQL binary is provided by MariaDB (as determined by the version string),
1858+
* prefers the actual MariaDB binary.
1859+
*
1860+
* @since 2.12.0 Now also checks for MariaDB.
1861+
*
1862+
* @return string Path to the MySQL/MariaDB binary, or an empty string if not found.
18241863
*/
18251864
function get_mysql_binary_path() {
18261865
static $path = null;
18271866

1828-
if ( null === $path ) {
1829-
$result = Process::create( '/usr/bin/env which mysql', null, null )->run();
1867+
if ( null !== $path ) {
1868+
return $path;
1869+
}
18301870

1831-
if ( 0 !== $result->return_code ) {
1832-
$path = '';
1833-
} else {
1834-
$path = trim( $result->stdout );
1871+
$path = '';
1872+
$mysql = Process::create( '/usr/bin/env which mysql', null, null )->run();
1873+
$mariadb = Process::create( '/usr/bin/env which mariadb', null, null )->run();
1874+
1875+
$mysql_binary = trim( $mysql->stdout );
1876+
$mariadb_binary = trim( $mariadb->stdout );
1877+
1878+
if ( 0 === $mysql->return_code ) {
1879+
if ( '' !== $mysql_binary ) {
1880+
$path = $mysql_binary;
1881+
$result = Process::create( "$mysql_binary --version", null, null )->run();
1882+
1883+
// It's actually MariaDB disguised as MySQL.
1884+
if ( 0 === $result->return_code && false !== strpos( $result->stdout, 'MariaDB' ) && 0 === $mariadb->return_code ) {
1885+
$path = $mariadb_binary;
1886+
}
18351887
}
1888+
} elseif ( 0 === $mariadb->return_code ) {
1889+
$path = $mariadb_binary;
1890+
}
1891+
1892+
if ( '' === $path ) {
1893+
WP_CLI::Error( 'Could not find mysql binary' );
18361894
}
18371895

18381896
return $path;
18391897
}
18401898

18411899
/**
1842-
* Get the version of the MySQL database.
1900+
* Get the version of the MySQL or MariaDB database.
1901+
*
1902+
* @since 2.12.0 Now also checks for MariaDB.
18431903
*
1844-
* @return string Version of the MySQL database, or an empty string if not
1845-
* found.
1904+
* @return string Version of the MySQL/MariaDB database,
1905+
* or an empty string if not found.
18461906
*/
18471907
function get_mysql_version() {
18481908
static $version = null;
18491909

1850-
if ( null === $version ) {
1851-
$result = Process::create( '/usr/bin/env mysql --version', null, null )->run();
1910+
if ( null !== $version ) {
1911+
return $version;
1912+
}
1913+
1914+
$db_type = get_db_type();
1915+
1916+
if ( 'sqlite' !== $db_type ) {
1917+
$result = Process::create( "/usr/bin/env $db_type --version", null, null )->run();
18521918

18531919
if ( 0 !== $result->return_code ) {
18541920
$version = '';
@@ -1860,6 +1926,24 @@ function get_mysql_version() {
18601926
return $version;
18611927
}
18621928

1929+
/**
1930+
* Returns the correct `dump` command based on the detected database type.
1931+
*
1932+
* @return string The appropriate dump command.
1933+
*/
1934+
function get_sql_dump_command() {
1935+
return 'mariadb' === get_db_type() ? 'mariadb-dump' : 'mysqldump';
1936+
}
1937+
1938+
/**
1939+
* Returns the correct `check` command based on the detected database type.
1940+
*
1941+
* @return string The appropriate check command.
1942+
*/
1943+
function get_sql_check_command() {
1944+
return 'mariadb' === get_db_type() ? 'mariadb-check' : 'mysqlcheck';
1945+
}
1946+
18631947
/**
18641948
* Get the SQL modes of the MySQL session.
18651949
*
@@ -1869,8 +1953,16 @@ function get_mysql_version() {
18691953
function get_sql_modes() {
18701954
static $sql_modes = null;
18711955

1872-
if ( null === $sql_modes ) {
1873-
$result = Process::create( '/usr/bin/env mysql --no-auto-rehash --batch --skip-column-names --execute="SELECT @@SESSION.sql_mode"', null, null )->run();
1956+
if ( null !== $sql_modes ) {
1957+
return $sql_modes;
1958+
}
1959+
1960+
$binary = get_mysql_binary_path();
1961+
1962+
if ( '' === $binary ) {
1963+
$sql_modes = [];
1964+
} else {
1965+
$result = Process::create( "$binary --no-auto-rehash --batch --skip-column-names --execute=\"SELECT @@SESSION.sql_mode\"", null, null )->run();
18741966

18751967
if ( 0 !== $result->return_code ) {
18761968
$sql_modes = [];

0 commit comments

Comments
 (0)