Skip to content

Commit

Permalink
Error checking if DB updates fail
Browse files Browse the repository at this point in the history
  • Loading branch information
ajaydsouza committed Jan 23, 2024
1 parent 63c8e29 commit 2c4d8eb
Show file tree
Hide file tree
Showing 3 changed files with 67 additions and 61 deletions.
107 changes: 52 additions & 55 deletions includes/admin/class-activator.php
Original file line number Diff line number Diff line change
Expand Up @@ -184,100 +184,97 @@ public static function create_daily_table_sql() {
}

/**
* Recreate overall table.
* Recreate a table.
*
* This method recreates a table by creating a backup, dropping the original table,
* and then creating a new table with the original name and inserting the data from the backup.
*
* @since 3.3.0
*
* @param bool $backup Whether to backup the table or not.
* @param string $table_name The name of the table to recreate.
* @param string $create_table_sql The SQL statement to create the new table.
* @param bool $backup Whether to backup the table or not.
* @param array $fields The fields to include in the temporary table and on duplicate key code.
* @param array $group_by_fields The fields to group by in the temporary table.
*
* @return bool True if recreated, false if not.
* @return bool|\WP_Error True if recreated, error message if failed.
*/
public static function recreate_overall_table( $backup = true ) {
public static function recreate_table( $table_name, $create_table_sql, $backup = true, $fields = array( 'searchvar', 'cntaccess' ), $group_by_fields = array( 'searchvar' ) ) {
global $wpdb;

$table_name = $wpdb->prefix . 'bsearch';
$backup_table_name = $table_name . '_backup';
$success = false;

$success = false;
$fields_sql = implode( ', ', $fields );
$fields_sql_with_sum = str_replace( 'cntaccess', 'SUM(cntaccess) as cntaccess', $fields_sql );
$group_by_sql = implode( ', ', $group_by_fields );

if ( $backup ) {
$success = $wpdb->query( "CREATE TABLE $backup_table_name LIKE $table_name" ); // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.DirectDatabaseQuery.NoCaching,WordPress.DB.DirectDatabaseQuery.SchemaChange,WordPress.DB.PreparedSQL.InterpolatedNotPrepared
if ( false !== $success ) {
$success = $wpdb->query( "INSERT INTO $backup_table_name SELECT * FROM $table_name" ); // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.DirectDatabaseQuery.NoCaching,WordPress.DB.PreparedSQL.InterpolatedNotPrepared
} else {
return new \WP_Error( 'bsearch_database_backup_failed', sprintf( esc_html__( 'Database backup failed on site %1$s. Error message: %2$s', 'better-search' ), get_site_url(), $wpdb->last_error ) );
}
} else {
// Create a temporary table and store the data.
$success = $wpdb->query( // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.DirectDatabaseQuery.NoCaching
"
CREATE TEMPORARY TABLE $backup_table_name AS " . // phpcs:ignore WordPress.DB.DirectDatabaseQuery.SchemaChange,WordPress.DB.PreparedSQL.InterpolatedNotPrepared
"SELECT searchvar, SUM(cntaccess) as cntaccess
FROM $table_name " . // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared
'GROUP BY searchvar
'
);
$success = $wpdb->query( "CREATE TEMPORARY TABLE $backup_table_name AS SELECT $fields_sql_with_sum FROM $table_name GROUP BY $group_by_sql" ); // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.DirectDatabaseQuery.NoCaching,WordPress.DB.DirectDatabaseQuery.SchemaChange,WordPress.DB.PreparedSQL.InterpolatedNotPrepared
}

if ( false !== $success ) {
$wpdb->query( "DROP TABLE IF EXISTS $table_name" ); // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.DirectDatabaseQuery.NoCaching,WordPress.DB.DirectDatabaseQuery.SchemaChange,WordPress.DB.PreparedSQL.InterpolatedNotPrepared
self::maybe_create_table( $table_name, $create_table_sql );
$insert_fields_sql = 'bs.' . implode( ', bs.', $fields );

self::maybe_create_table( $table_name, self::create_full_table_sql() );

// Insert the data back into the table.
$success = $wpdb->query( "INSERT INTO $table_name (searchvar, cntaccess ) SELECT bs.searchvar, bs.cntaccess FROM $backup_table_name AS bs ON DUPLICATE KEY UPDATE $table_name.cntaccess = $table_name.cntaccess + VALUES(cntaccess);" ); // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.DirectDatabaseQuery.NoCaching,WordPress.DB.PreparedSQL.InterpolatedNotPrepared
$success = $wpdb->query( "INSERT INTO $table_name ($fields_sql) SELECT $insert_fields_sql FROM $backup_table_name AS bs ON DUPLICATE KEY UPDATE $table_name.cntaccess = $table_name.cntaccess + VALUES(cntaccess)" ); // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.DirectDatabaseQuery.NoCaching,WordPress.DB.PreparedSQL.InterpolatedNotPrepared

if ( false === $success ) {
return new \WP_Error( 'bsearch_database_insert_failed', sprintf( esc_html__( 'Database insert failed on site %1$s. Error message: %2$s', 'better-search' ), get_site_url(), $wpdb->last_error ) );
}
}

if ( ! $backup ) {
$wpdb->query( "DROP TABLE $backup_table_name" ); // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.DirectDatabaseQuery.NoCaching,WordPress.DB.DirectDatabaseQuery.SchemaChange,WordPress.DB.PreparedSQL.InterpolatedNotPrepared
}

return $success;
}

/**
* Recreate overall table.
*
* @since 3.3.0
*
* @param bool $backup Whether to backup the table or not.
*
* @return bool|\WP_Error True if recreated, error message if failed.
*/
public static function recreate_overall_table( $backup = true ) {
global $wpdb;
return self::recreate_table(
$wpdb->prefix . 'bsearch',
self::create_full_table_sql(),
$backup
);
}

/**
* Recreate daily table.
*
* @since 3.3.0
*
* @param bool $backup Whether to backup the table or not.
*
* @return bool True if recreated, false if not.
* @return bool|\WP_Error True if recreated, error message if failed.
*/
public static function recreate_daily_table( $backup = true ) {
global $wpdb;

$table_name = $wpdb->prefix . 'bsearch_daily';
$backup_table_name = $table_name . '_backup';

$success = false;

if ( $backup ) {
$success = $wpdb->query( "CREATE TABLE $backup_table_name LIKE $table_name" ); // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.DirectDatabaseQuery.NoCaching,WordPress.DB.DirectDatabaseQuery.SchemaChange,WordPress.DB.PreparedSQL.InterpolatedNotPrepared
if ( false !== $success ) {
$success = $wpdb->query( "INSERT INTO $backup_table_name SELECT * FROM $table_name" ); // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.DirectDatabaseQuery.NoCaching,WordPress.DB.PreparedSQL.InterpolatedNotPrepared
}
} else {
// Create a temporary table and store the data.
$success = $wpdb->query( // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.DirectDatabaseQuery.NoCaching
"
CREATE TEMPORARY TABLE $backup_table_name AS " . // phpcs:ignore WordPress.DB.DirectDatabaseQuery.SchemaChange,WordPress.DB.PreparedSQL.InterpolatedNotPrepared
"SELECT searchvar, SUM(cntaccess) as cntaccess, dp_date
FROM $table_name " . // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared
'GROUP BY searchvar, dp_date
'
);
}

if ( false !== $success ) {
$wpdb->query( "DROP TABLE IF EXISTS $table_name" ); // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.DirectDatabaseQuery.NoCaching,WordPress.DB.DirectDatabaseQuery.SchemaChange,WordPress.DB.PreparedSQL.InterpolatedNotPrepared

self::maybe_create_table( $table_name, self::create_daily_table_sql() );

// Insert the data back into the table.
$success = $wpdb->query( "INSERT INTO $table_name (searchvar, cntaccess, dp_date ) SELECT bs.searchvar, bs.cntaccess, bs.dp_date FROM $backup_table_name AS bs ON DUPLICATE KEY UPDATE $table_name.cntaccess = $table_name.cntaccess + VALUES(cntaccess);" ); // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.DirectDatabaseQuery.NoCaching,WordPress.DB.PreparedSQL.InterpolatedNotPrepared
}
if ( ! $backup ) {
$wpdb->query( "DROP TABLE $backup_table_name" ); // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.DirectDatabaseQuery.NoCaching,WordPress.DB.DirectDatabaseQuery.SchemaChange,WordPress.DB.PreparedSQL.InterpolatedNotPrepared
}
return $success;
return self::recreate_table(
$wpdb->prefix . 'bsearch_daily',
self::create_daily_table_sql(),
$backup,
array( 'searchvar', 'cntaccess', 'dp_date' ),
array( 'searchvar', 'dp_date' )
);
}


Expand Down
19 changes: 14 additions & 5 deletions includes/admin/class-upgrader.php
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,10 @@ public function render_page() {

<form method="post">
<p class="description">
<?php esc_html_e( 'Upgrade the Better Search Database Tables. If you are running multisite, then this will attempt the upgrade across all sites in the network.', 'better-search' ); ?>
<?php esc_html_e( 'Upgrade the Better Search Database Tables.', 'better-search' ); ?>
<?php if ( is_network_admin() ) { ?>
<strong><?php esc_html_e( 'This will upgrade the database across all sites in the network.', 'better-search' ); ?></strong>
<?php } ?>
</p>
<p>
<input name="bsearch_upgrade_db" type="submit" id="bsearch_upgrade_db" value="<?php esc_attr_e( 'Click to begin', 'better-search' ); ?>" class="button button-secondary" />
Expand Down Expand Up @@ -149,12 +152,18 @@ public static function upgrade_db() {
if ( version_compare( $current_db_version, BETTER_SEARCH_DB_VERSION, '<' ) ) {
$success_overall = Activator::recreate_overall_table();
$success_daily = Activator::recreate_daily_table();
if ( false !== $success_overall && false !== $success_daily ) {
update_option( 'bsearch_db_version', BETTER_SEARCH_DB_VERSION );
return sprintf( esc_html__( 'Database upgraded on site %s', 'better-search' ), get_admin_url() );

if ( is_wp_error( $success_overall ) ) {
return $success_overall->get_error_message();
}
if ( is_wp_error( $success_daily ) ) {
return $success_daily->get_error_message();
}

update_option( 'bsearch_db_version', BETTER_SEARCH_DB_VERSION );
return sprintf( esc_html__( 'Database upgraded on site %s', 'better-search' ), get_site_url() );
}
return sprintf( esc_html__( 'Database is already up to date on site %s', 'better-search' ), get_admin_url() );
return sprintf( esc_html__( 'Database is already up to date on site %s', 'better-search' ), get_site_url() );
}

/**
Expand Down
2 changes: 1 addition & 1 deletion readme.txt
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ This is a major release. Complete rewrite of the plugin code - Better Search now
* New Admin Dashboard will show the number of searches and the top searches for the day, week, month and all time

* Enhancements:
* The tables in the database have been changed for more optimized update queries. The plugin will attempt to automatically update the tables. If this fails, you can recreate the tables from the Tools screen.
* The tables in the database have been changed for more optimized update queries. The plugin will prompt you to run the upgrade script when you update the plugin
* Better Search Tracker doesn't use jQuery anymore
* Uninstall now uses `get_sites()` behind the scenes to delete options from all sites in a multisite install
* Blank searches will return no results
Expand Down

0 comments on commit 2c4d8eb

Please sign in to comment.