Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
5c54007
Initial plan
Copilot Apr 2, 2026
cfe43e7
Add wpdb fallback for wp db query when mysql/mariadb binary is unavai…
Copilot Apr 2, 2026
ea5dea1
Improve wpdb fallback: add escapeshellarg and table prefix support
Copilot Apr 2, 2026
5375be8
Add load.php, extend wpdb fallback to run_query() and import command
Copilot Apr 3, 2026
47906b9
Apply suggestion from @swissspidy
swissspidy Apr 3, 2026
2d3706f
Add Behat tests for wpdb fallback in drop, reset, and import commands
Copilot Apr 3, 2026
9ea27c2
Apply suggestions from code review
swissspidy Apr 3, 2026
f85364e
Merge branch 'main' into copilot/fix-wp-db-query-fallback
swissspidy Apr 21, 2026
adc0d52
Fix split_sql_statements() to handle backslash-escaped quotes inside …
Copilot May 27, 2026
41b410d
Fix: change I run to I try in db-import fallback test to allow STDERR…
Copilot May 28, 2026
ae8b0b6
Merge branch 'main' into copilot/fix-wp-db-query-fallback
swissspidy Jul 13, 2026
72c5468
Fix issue after merge
swissspidy Jul 13, 2026
62d9d98
Fix run_query() WP 4.9 compatibility: use mysqli instead of wpdb
Copilot Jul 14, 2026
7e177ee
Address code review: fix edge cases in run_query_via_mysqli()
Copilot Jul 14, 2026
60262b5
Restore wpdb fallback in run_query() and fix WP 4.9 compatibility
Copilot Jul 14, 2026
23355d6
Fix WP 4.9: use run_query_via_mysqli() for drop/reset, keep wpdb for …
Copilot Jul 14, 2026
6414ec5
Replace maybe_load_wpdb() with direct mysqli in wpdb_query() and wpdb…
Copilot Jul 14, 2026
e1d6e78
Fix code review: remove redundant cast, handle NULL as 'NULL' in quer…
Copilot Jul 14, 2026
b6489cb
Fix split_sql_statements() to execute MySQL conditional comments (/*!…
Copilot Jul 14, 2026
ec70aa9
Improve split_sql_statements: rename $peek, clarify version-digit loo…
Copilot Jul 14, 2026
6051f7f
Merge branch 'main' into copilot/fix-wp-db-query-fallback
swissspidy Jul 21, 2026
56aa39b
Remove mysqli fallback in favor of wpdb
swissspidy Jul 22, 2026
79dd99d
Update tests for wpdb fallback
swissspidy Jul 22, 2026
6b430fb
Fix WP 4.9 functions.php require issue in maybe_load_wpdb and add deb…
swissspidy Jul 22, 2026
30dfd4f
Support wp-db.php in WP 4.9 and older releases in maybe_load_wpdb
swissspidy Jul 22, 2026
66c44fa
Improve client binary detection and wpdb fallback execution
swissspidy Jul 28, 2026
16d46e2
Add acceptance tests for multi-statement queries, zero-date imports, …
swissspidy Jul 28, 2026
1beefa6
Merge branch 'main' into copilot/fix-wp-db-query-fallback
swissspidy Jul 28, 2026
cc9efd3
Simplify is_mysql_binary_available() and remove invalid PATH scenario
swissspidy Jul 28, 2026
bd531f2
Fix binary probing and line-boundary DELIMITER parsing for wpdb fallback
swissspidy Jul 28, 2026
3958766
Include functions.php in maybe_load_wpdb() required files
swissspidy Jul 28, 2026
fbba09d
Update docblocks for all db subcommands with binary requirements and …
swissspidy Jul 28, 2026
4d1ce7a
Update readme
swissspidy Jul 28, 2026
f0eb585
Prevent infinite loop on malformed empty DELIMITER lines
swissspidy Jul 28, 2026
ece1b73
Translate --host, --user, --password, and --database options in maybe…
swissspidy Jul 28, 2026
96ad193
Merge branch 'main' into copilot/fix-wp-db-query-fallback
swissspidy Jul 29, 2026
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
24 changes: 15 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ wp db create [--dbuser=<value>] [--dbpass=<value>] [--defaults]

Runs `CREATE_DATABASE` SQL statement using `DB_HOST`, `DB_NAME`,
`DB_USER` and `DB_PASSWORD` database credentials specified in
wp-config.php.
wp-config.php. Requires MySQL/MariaDB client binaries to be available.

**OPTIONS**

Expand Down Expand Up @@ -111,7 +111,7 @@ wp db drop [--dbuser=<value>] [--dbpass=<value>] [--yes] [--defaults]

Runs `DROP_DATABASE` SQL statement using `DB_HOST`, `DB_NAME`,
`DB_USER` and `DB_PASSWORD` database credentials specified in
wp-config.php.
wp-config.php. Requires MySQL/MariaDB client binaries to be available.

**OPTIONS**

Expand Down Expand Up @@ -144,7 +144,7 @@ wp db reset [--dbuser=<value>] [--dbpass=<value>] [--yes] [--defaults]

Runs `DROP_DATABASE` and `CREATE_DATABASE` SQL statements using
`DB_HOST`, `DB_NAME`, `DB_USER` and `DB_PASSWORD` database credentials
specified in wp-config.php.
specified in wp-config.php. Requires MySQL/MariaDB client binaries to be available.

**OPTIONS**

Expand Down Expand Up @@ -177,7 +177,7 @@ wp db check [--dbuser=<value>] [--dbpass=<value>] [--<field>=<value>] [--default

Runs `mysqlcheck` utility with `--check` using `DB_HOST`,
`DB_NAME`, `DB_USER` and `DB_PASSWORD` database credentials
specified in wp-config.php.
specified in wp-config.php. Requires `mysqlcheck` or `mariadb-check` client binary.

[See docs](http://dev.mysql.com/doc/refman/5.7/en/check-table.html)
for more details on the `CHECK TABLE` statement.
Expand Down Expand Up @@ -216,7 +216,7 @@ wp db optimize [--dbuser=<value>] [--dbpass=<value>] [--<field>=<value>] [--defa

Runs `mysqlcheck` utility with `--optimize=true` using `DB_HOST`,
`DB_NAME`, `DB_USER` and `DB_PASSWORD` database credentials
specified in wp-config.php.
specified in wp-config.php. Requires `mysqlcheck` or `mariadb-check` client binary.

[See docs](http://dev.mysql.com/doc/refman/5.7/en/optimize-table.html)
for more details on the `OPTIMIZE TABLE` statement.
Expand Down Expand Up @@ -269,7 +269,7 @@ wp db repair [--dbuser=<value>] [--dbpass=<value>] [--<field>=<value>] [--defaul

Runs `mysqlcheck` utility with `--repair=true` using `DB_HOST`,
`DB_NAME`, `DB_USER` and `DB_PASSWORD` database credentials
specified in wp-config.php.
specified in wp-config.php. Requires `mysqlcheck` or `mariadb-check` client binary.

[See docs](http://dev.mysql.com/doc/refman/5.7/en/repair-table.html) for
more details on the `REPAIR TABLE` statement.
Expand Down Expand Up @@ -297,14 +297,16 @@ more details on the `REPAIR TABLE` statement.

### wp db cli

Opens a MySQL console using credentials from wp-config.php
Opens a MySQL console using credentials from wp-config.php.

~~~
wp db cli [--database=<database>] [--default-character-set=<character-set>] [--dbuser=<value>] [--dbpass=<value>] [--<field>=<value>] [--defaults]
~~~

**Alias:** `connect`

Requires `mysql` or `mariadb` client binary to be available.

**OPTIONS**

[--database=<database>]
Expand Down Expand Up @@ -342,7 +344,9 @@ wp db query [<sql>] [--dbuser=<value>] [--dbpass=<value>] [--<field>=<value>] [-
~~~

Executes an arbitrary SQL query using `DB_HOST`, `DB_NAME`, `DB_USER`
and `DB_PASSWORD` database credentials specified in wp-config.php.
and `DB_PASSWORD` database credentials specified in wp-config.php.
If MySQL/MariaDB client binaries are not available, falls back to
executing queries via WordPress's `wpdb`.

Use the `--skip-column-names` MySQL argument to exclude the headers
from a SELECT query. Pipe the output to remove the ASCII table
Expand Down Expand Up @@ -445,6 +449,7 @@ wp db export [<file>] [--dbuser=<value>] [--dbpass=<value>] [--<field>=<value>]

Runs `mysqldump` utility using `DB_HOST`, `DB_NAME`, `DB_USER` and
`DB_PASSWORD` database credentials specified in wp-config.php. Accepts any valid [`mysqldump` flags](https://dev.mysql.com/doc/en/mysqldump.html#mysqldump-option-summary).
Requires `mysqldump` or `mariadb-dump` client binary to be available.

**OPTIONS**

Expand Down Expand Up @@ -536,7 +541,8 @@ wp db import [<file>] [--dbuser=<value>] [--dbpass=<value>] [--<field>=<value>]
Runs SQL queries using `DB_HOST`, `DB_NAME`, `DB_USER` and
`DB_PASSWORD` database credentials specified in wp-config.php. This
does not create database by itself and only performs whatever tasks are
defined in the SQL.
defined in the SQL. If MySQL/MariaDB client binaries are not available,
falls back to importing via WordPress's `wpdb`.

**OPTIONS**

Expand Down
112 changes: 112 additions & 0 deletions features/db-import.feature
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,118 @@ Feature: Import a WordPress database
Success: Imported from 'wp_cli_test.sql'.
"""

@require-mysql-or-mariadb
Scenario: Database import falls back to wpdb when mysql binary is unavailable
Given a WP install
And a fake-bin/mysql file:
"""
#!/bin/sh
exit 127
"""
And a fake-bin/mariadb file:
"""
#!/bin/sh
exit 127
"""

When I try `wp db export wp_cli_test.sql`
Then the wp_cli_test.sql file should exist

When I run `chmod +x fake-bin/mysql fake-bin/mariadb`
And I try `env PATH={RUN_DIR}/fake-bin:$PATH wp db import wp_cli_test.sql --debug`
Then STDOUT should be:
"""
Success: Imported from 'wp_cli_test.sql'.
"""
And STDERR should contain:
"""
MySQL/MariaDB binary not available, falling back to wpdb for import.
"""

@require-mysql-or-mariadb
Scenario: Database import falls back to wpdb and handles zero-date column defaults
Given a WP install
And a fake-bin/mysql file:
"""
#!/bin/sh
exit 127
"""
And a fake-bin/mariadb file:
"""
#!/bin/sh
exit 127
"""
And a zero_date.sql file:
"""
CREATE TABLE IF NOT EXISTS wp_zero_date_test (
id INT AUTO_INCREMENT PRIMARY KEY,
created_at DATETIME NOT NULL DEFAULT '0000-00-00 00:00:00'
);
"""

When I run `chmod +x fake-bin/mysql fake-bin/mariadb`
And I try `env PATH={RUN_DIR}/fake-bin:$PATH wp db import zero_date.sql --debug`
Then STDOUT should be:
"""
Success: Imported from 'zero_date.sql'.
"""

@require-mysql-or-mariadb
Scenario: Database import falls back to wpdb and handles DELIMITER blocks with procedures
Given a WP install
And a fake-bin/mysql file:
"""
#!/bin/sh
exit 127
"""
And a fake-bin/mariadb file:
"""
#!/bin/sh
exit 127
"""
And a procedure.sql file:
"""
DELIMITER //
CREATE PROCEDURE wp_test_procedure()
BEGIN
SELECT 1;
END//
DELIMITER ;
"""

When I run `chmod +x fake-bin/mysql fake-bin/mariadb`
And I try `env PATH={RUN_DIR}/fake-bin:$PATH wp db import procedure.sql --debug`
Then STDOUT should be:
"""
Success: Imported from 'procedure.sql'.
"""

@require-mysql-or-mariadb
Scenario: Database import falls back to wpdb and handles malformed empty DELIMITER lines
Given a WP install
And a fake-bin/mysql file:
"""
#!/bin/sh
exit 127
"""
And a fake-bin/mariadb file:
"""
#!/bin/sh
exit 127
"""
And a malformed_delimiter.sql file:
"""
DELIMITER
SELECT 1;
"""

When I run `chmod +x fake-bin/mysql fake-bin/mariadb`
And I try `env PATH={RUN_DIR}/fake-bin:$PATH wp db import malformed_delimiter.sql --debug`
Then STDOUT should be:
"""
Success: Imported from 'malformed_delimiter.sql'.
"""

# SQLite doesn't support the --dbuser flag.
@require-mysql-or-mariadb
Scenario: Import from database name path by default with passed-in dbuser/dbpass
Expand Down
53 changes: 53 additions & 0 deletions features/db-query.feature
Original file line number Diff line number Diff line change
Expand Up @@ -155,3 +155,56 @@ Feature: Query the database with WordPress' MySQL config
"""
skip-ssl-verify-server-cert
"""

@require-mysql-or-mariadb
Scenario: Database querying falls back to wpdb when mysql binary is unavailable
Given a WP install
And a fake-bin/mysql file:
"""
#!/bin/sh
exit 127
"""
And a fake-bin/mariadb file:
"""
#!/bin/sh
exit 127
"""

When I run `chmod +x fake-bin/mysql fake-bin/mariadb`
And I try `env PATH={RUN_DIR}/fake-bin:$PATH wp db query "SELECT COUNT(ID) FROM wp_users;" --debug`
Then STDOUT should be:
"""
COUNT(ID)
1
"""
And STDERR should contain:
"""
MySQL/MariaDB binary not available, falling back to wpdb.
"""

@require-mysql-or-mariadb
Scenario: Database querying falls back to wpdb for multi-statement queries when mysql binary is unavailable
Given a WP install
And a fake-bin/mysql file:
"""
#!/bin/sh
exit 127
"""
And a fake-bin/mariadb file:
"""
#!/bin/sh
exit 127
"""

When I run `chmod +x fake-bin/mysql fake-bin/mariadb`
And I try `env PATH={RUN_DIR}/fake-bin:$PATH wp db query "SELECT 1 as num; SELECT 2 as num;" --debug`
Then STDOUT should contain:
"""
num
1
"""
And STDOUT should contain:
"""
num
2
"""
2 changes: 1 addition & 1 deletion features/db.feature
Original file line number Diff line number Diff line change
Expand Up @@ -387,8 +387,8 @@ Feature: Perform database operations
Query succeeded. Rows affected: 1
"""

@require-sqlite @skip-windows
# Skipped on Windows due to persistent file locking issues when run via Behat.
@require-sqlite @skip-windows
Scenario: SQLite DB CRUD operations
Given a WP install
And a session_yes file:
Expand Down
Loading
Loading