Skip to content

Commit bf741eb

Browse files
Enable --format=<format> for db search (#247)
* Enable formatter for search command * Use `value` instead of `ID` for the primary key column * Rename and reorder the columns * Update docs * Less brittle test --------- Co-authored-by: Daniel Bachhuber <[email protected]>
1 parent 41b502b commit bf741eb

File tree

3 files changed

+106
-3
lines changed

3 files changed

+106
-3
lines changed

README.md

+22-1
Original file line numberDiff line numberDiff line change
@@ -560,7 +560,7 @@ defined in the SQL.
560560
Finds a string in the database.
561561

562562
~~~
563-
wp db search <search> [<tables>...] [--network] [--all-tables-with-prefix] [--all-tables] [--before_context=<num>] [--after_context=<num>] [--regex] [--regex-flags=<regex-flags>] [--regex-delimiter=<regex-delimiter>] [--table_column_once] [--one_line] [--matches_only] [--stats] [--table_column_color=<color_code>] [--id_color=<color_code>] [--match_color=<color_code>]
563+
wp db search <search> [<tables>...] [--network] [--all-tables-with-prefix] [--all-tables] [--before_context=<num>] [--after_context=<num>] [--regex] [--regex-flags=<regex-flags>] [--regex-delimiter=<regex-delimiter>] [--table_column_once] [--one_line] [--matches_only] [--stats] [--table_column_color=<color_code>] [--id_color=<color_code>] [--match_color=<color_code>] [--fields=<fields>] [--format=<format>]
564564
~~~
565565

566566
Searches through all of the text columns in a selection of database tables for a given string, Outputs colorized references to the string.
@@ -626,6 +626,12 @@ Defaults to searching through all tables registered to $wpdb. On multisite, this
626626
[--match_color=<color_code>]
627627
Percent color code to use for the match (unless both before and after context are 0, when no color code is used). For a list of available percent color codes, see below. Default '%3%k' (black on a mustard background).
628628

629+
[--fields=<fields>]
630+
Get a specific subset of the fields.
631+
632+
[--format=<format>]
633+
Render output in a particular format.
634+
629635
The percent color codes available are:
630636

631637
| Code | Color
@@ -694,6 +700,21 @@ They can be concatenated. For instance, the default match color of black on a mu
694700
# SQL search and delete records from database table 'wp_options' where 'option_name' match 'foo'
695701
wp db query "DELETE from wp_options where option_id in ($(wp db query "SELECT GROUP_CONCAT(option_id SEPARATOR ',') from wp_options where option_name like '%foo%';" --silent --skip-column-names))"
696702

703+
# Search for a string and print the result as a table
704+
$ wp db search https://localhost:8889 --format=table --fields=table,column,match
705+
+------------+--------------+-----------------------------+
706+
| table | column | match |
707+
+------------+--------------+-----------------------------+
708+
| wp_options | option_value | https://localhost:8889 |
709+
| wp_options | option_value | https://localhost:8889 |
710+
| wp_posts | guid | https://localhost:8889/?p=1 |
711+
| wp_users | user_url | https://localhost:8889 |
712+
+------------+--------------+-----------------------------+
713+
714+
# Search for a string and get only the IDs (only works for a single table)
715+
$ wp db search https://localhost:8889 wp_options --format=ids
716+
1 2
717+
697718

698719

699720
### wp db tables

features/db-search.feature

+20
Original file line numberDiff line numberDiff line change
@@ -1066,3 +1066,23 @@ Feature: Search through the database
10661066
:aöXYXYX
10671067
"""
10681068
And STDERR should be empty
1069+
1070+
Scenario: Search for a string and output the format as a table
1071+
Given a WP install
1072+
1073+
When I run `wp db search mail.example.com --format=csv`
1074+
Then STDOUT should contain:
1075+
"""
1076+
wp_options,option_value,mail.example.com,option_id
1077+
"""
1078+
1079+
When I try `wp db search example.com --format=ids`
1080+
Then STDERR should be:
1081+
"""
1082+
Error: The "ids" format can only be used for a single table.
1083+
"""
1084+
And STDOUT should be empty
1085+
And the return code should be 1
1086+
1087+
When I run `wp db search mail.example.com wp_options --format=ids`
1088+
Then STDOUT should not be empty

src/DB_Command.php

+64-2
Original file line numberDiff line numberDiff line change
@@ -1258,6 +1258,12 @@ public function prefix() {
12581258
* [--match_color=<color_code>]
12591259
* : Percent color code to use for the match (unless both before and after context are 0, when no color code is used). For a list of available percent color codes, see below. Default '%3%k' (black on a mustard background).
12601260
*
1261+
* [--fields=<fields>]
1262+
* : Get a specific subset of the fields.
1263+
*
1264+
* [--format=<format>]
1265+
* : Render output in a particular format.
1266+
*
12611267
* The percent color codes available are:
12621268
*
12631269
* | Code | Color
@@ -1326,6 +1332,21 @@ public function prefix() {
13261332
* # SQL search and delete records from database table 'wp_options' where 'option_name' match 'foo'
13271333
* wp db query "DELETE from wp_options where option_id in ($(wp db query "SELECT GROUP_CONCAT(option_id SEPARATOR ',') from wp_options where option_name like '%foo%';" --silent --skip-column-names))"
13281334
*
1335+
* # Search for a string and print the result as a table
1336+
* $ wp db search https://localhost:8889 --format=table --fields=table,column,match
1337+
* +------------+--------------+-----------------------------+
1338+
* | table | column | match |
1339+
* +------------+--------------+-----------------------------+
1340+
* | wp_options | option_value | https://localhost:8889 |
1341+
* | wp_options | option_value | https://localhost:8889 |
1342+
* | wp_posts | guid | https://localhost:8889/?p=1 |
1343+
* | wp_users | user_url | https://localhost:8889 |
1344+
* +------------+--------------+-----------------------------+
1345+
*
1346+
* # Search for a string and get only the IDs (only works for a single table)
1347+
* $ wp db search https://localhost:8889 wp_options --format=ids
1348+
* 1 2
1349+
*
13291350
* @when after_wp_load
13301351
*/
13311352
public function search( $args, $assoc_args ) {
@@ -1365,6 +1386,8 @@ public function search( $args, $assoc_args ) {
13651386
$one_line = Utils\get_flag_value( $assoc_args, 'one_line', false );
13661387
$matches_only = Utils\get_flag_value( $assoc_args, 'matches_only', false );
13671388
$stats = Utils\get_flag_value( $assoc_args, 'stats', false );
1389+
$fields = Utils\get_flag_value( $assoc_args, 'fields' );
1390+
$format = Utils\get_flag_value( $assoc_args, 'format' );
13681391

13691392
$column_count = 0;
13701393
$row_count = 0;
@@ -1399,6 +1422,8 @@ public function search( $args, $assoc_args ) {
13991422

14001423
$tables = Utils\wp_get_table_names( $args, $assoc_args );
14011424

1425+
$search_results = [];
1426+
14021427
$start_search_time = microtime( true );
14031428

14041429
foreach ( $tables as $table ) {
@@ -1442,7 +1467,7 @@ public function search( $args, $assoc_args ) {
14421467
foreach ( $results as $result ) {
14431468
$col_val = $result->$column;
14441469
if ( preg_match_all( $search_regex, $col_val, $matches, PREG_OFFSET_CAPTURE ) ) {
1445-
if ( ! $matches_only && ( ! $table_column_once || ! $outputted_table_column_once ) && ! $one_line ) {
1470+
if ( ! $format && ! $matches_only && ( ! $table_column_once || ! $outputted_table_column_once ) && ! $one_line ) {
14461471
WP_CLI::log( $table_column_val );
14471472
$outputted_table_column_once = true;
14481473
}
@@ -1490,13 +1515,50 @@ public function search( $args, $assoc_args ) {
14901515
$match_count += $match_cnt;
14911516
$col_val = implode( ' [...] ', $bits );
14921517

1493-
WP_CLI::log( $matches_only ? $col_val : ( $one_line ? "{$table_column_val}:{$pk_val}{$col_val}" : "{$pk_val}{$col_val}" ) );
1518+
if ( $format ) {
1519+
$search_results[] = [
1520+
'table' => $table,
1521+
'column' => $column,
1522+
// Remove the colors for the format output.
1523+
'match' => str_replace(
1524+
[ $colors['match'][0], $colors['match'][1] ],
1525+
[ '','' ],
1526+
$col_val
1527+
),
1528+
'primary_key_name' => $primary_key,
1529+
'primary_key_value' => $result->$primary_key,
1530+
];
1531+
} else {
1532+
WP_CLI::log( $matches_only ? $col_val : ( $one_line ? "{$table_column_val}:{$pk_val}{$col_val}" : "{$pk_val}{$col_val}" ) );
1533+
}
14941534
}
14951535
}
14961536
}
14971537
}
14981538
}
14991539

1540+
if ( $format ) {
1541+
$formatter_args = [
1542+
'format' => $format,
1543+
];
1544+
$formatter_fields = [ 'table', 'column', 'match', 'primary_key_name', 'primary_key_value' ];
1545+
1546+
if ( $fields ) {
1547+
$fields = explode( ',', $assoc_args['fields'] );
1548+
$formatter_fields = array_values( array_intersect( $formatter_fields, $fields ) );
1549+
}
1550+
1551+
if ( in_array( $format, [ 'ids', 'count' ], true ) ) {
1552+
if ( count( $tables ) > 1 ) {
1553+
WP_CLI::error( 'The "ids" format can only be used for a single table.' );
1554+
}
1555+
$search_results = array_column( $search_results, 'primary_key_value' );
1556+
}
1557+
1558+
$formatter = new Formatter( $formatter_args, $formatter_fields );
1559+
$formatter->display_items( $search_results );
1560+
}
1561+
15001562
if ( $stats ) {
15011563
$table_count = count( $tables );
15021564
$skipped_count = count( $skipped );

0 commit comments

Comments
 (0)