Skip to content

Commit 65ef54c

Browse files
Fix: Handle MariaDB sandbox mode during db import
Detects the sandbox mode directive in the SQL file and switches to a piped import to avoid MariaDB syntax errors.
1 parent 8cf2272 commit 65ef54c

2 files changed

Lines changed: 63 additions & 0 deletions

File tree

features/db-import.feature

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -178,3 +178,21 @@ Feature: Import a WordPress database
178178
"""
179179
🍣
180180
"""
181+
182+
Scenario: Import MariaDB sandbox dump
183+
Given a WP install
184+
And a sandbox.sql file:
185+
"""
186+
/*!999999\- enable the sandbox mode */
187+
INSERT INTO wp_terms (name, slug, term_group) VALUES ('Test Term', 'test-term', 0);
188+
"""
189+
190+
When I run `wp db import sandbox.sql`
191+
Then STDOUT should contain:
192+
"""
193+
MariaDB sandbox mode directive detected. Skipping it by piping the file content.
194+
"""
195+
And STDOUT should contain:
196+
"""
197+
Success: Imported from 'sandbox.sql'.
198+
"""

src/DB_Command.php

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -816,6 +816,51 @@ public function import( $args, $assoc_args ) {
816816
WP_CLI::error( sprintf( 'Import file missing or not readable: %s', $result_file ) );
817817
}
818818

819+
// Check for MariaDB sandbox mode directive in the first line.
820+
// This directive can interfere with standard imports by enabling a sandbox mode
821+
// that restricts certain operations. We skip it by piping the file content
822+
// and skipping the first line.
823+
$fp = fopen( $result_file, 'r' );
824+
if ( ! $fp ) {
825+
WP_CLI::error( sprintf( 'Unable to read import file: %s', $result_file ) );
826+
}
827+
$first_line = fgets( $fp );
828+
fclose( $fp );
829+
830+
if ( 0 === strpos( $first_line, '/*!999999\- enable the sandbox mode */' ) ) {
831+
WP_CLI::log( 'MariaDB sandbox mode directive detected. Skipping it by piping the file content.' );
832+
833+
$preamble = $this->get_sql_mode_query( $assoc_args ) . "\n";
834+
if ( ! Utils\get_flag_value( $assoc_args, 'skip-optimization' ) ) {
835+
$preamble .= "SET autocommit = 0; SET unique_checks = 0; SET foreign_key_checks = 0;\n";
836+
}
837+
838+
$postamble = Utils\get_flag_value( $assoc_args, 'skip-optimization' ) ? '' : "\nCOMMIT;\n";
839+
840+
// Use a shell pipeline to skip the first line and wrap the rest in transaction/optimizations.
841+
$command = sprintf(
842+
'sh -c \'p="$1"; f="$2"; s="$3"; shift 3; ( printf "%%s" "$p"; tail -n +2 "$f"; printf "%%s" "$s" ) | %s %s --no-auto-rehash "$@"\' sh %s %s %s',
843+
$this->get_mysql_command(),
844+
$this->get_defaults_flag_string( $assoc_args ),
845+
escapeshellarg( $preamble ),
846+
escapeshellarg( $result_file ),
847+
escapeshellarg( $postamble )
848+
);
849+
850+
// Ensure we don't pass 'execute' which would conflict with STDIN.
851+
unset( $mysql_args['execute'] );
852+
853+
$result = self::run( $command, $mysql_args );
854+
855+
if ( 0 === $result['exit_code'] ) {
856+
WP_CLI::success( sprintf( "Imported from '%s'.", $result_file ) );
857+
} else {
858+
WP_CLI::error( sprintf( "Failed to import from '%s'.", $result_file ) );
859+
}
860+
861+
return;
862+
}
863+
819864
$query = Utils\get_flag_value( $assoc_args, 'skip-optimization' )
820865
? 'SOURCE %s;'
821866
: 'SET autocommit = 0; SET unique_checks = 0; SET foreign_key_checks = 0; SOURCE %s; COMMIT;';

0 commit comments

Comments
 (0)