fix(2meet-data-optimizer): add declared flat-table indexes from WP-CLI or WP-Cron only, one process at a time

- ensure_group_indexes() runs the ALTER only under WP-CLI or WP-Cron (filter
  tmdo_schema_ddl_allowed); web requests, including /wp-admin/ before
  auth_redirect() and admin-post.php, schedule tmdo_ensure_group_indexes instead
- MySQL GET_LOCK keeps it to one process (add_option() is INSERT ... ON
  DUPLICATE KEY UPDATE and cannot serve as a lock); released by MySQL if the
  process dies
- the applied signature is recorded only when every ALTER succeeds; failures
  log schema.index_failed and stay in pending_indexes(), which doctor reports
- new tables get their declared cidx_ indexes in CREATE TABLE
- test stub wpdb::query()/insert() return false on SQL errors like wpdb
- Verify: GroupCompositeIndexTest 7/7, unit 698, integration 576, phpcs, stan
- PR: PR-090a
This commit is contained in:
2026-09-27 16:07:23 +08:00
parent 28ac6e3cad
commit ec8d69a6f4
6 changed files with 214 additions and 13 deletions
+13 -3
View File
@@ -168,7 +168,12 @@ $wpdb = new class( $_mysqli ) {
fn( $v ) => $v === null ? 'NULL' : "'" . $this->db->real_escape_string( (string) $v ) . "'",
array_values( $data )
) );
$ok = $this->db->query( "INSERT INTO `{$table}` ({$cols}) VALUES ({$vals})" );
try {
$ok = $this->db->query( "INSERT INTO `{$table}` ({$cols}) VALUES ({$vals})" );
} catch ( mysqli_sql_exception $e ) { // Like wpdb::insert(): an SQL error returns false.
$this->last_error = $e->getMessage();
return false;
}
if ( $ok ) { $this->insert_id = (int) $this->db->insert_id; return $this->insert_id; }
$this->last_error = (string) $this->db->error;
return false;
@@ -200,7 +205,12 @@ $wpdb = new class( $_mysqli ) {
public function flush(): void {}
public function query( string $sql ): int|bool {
$result = $this->db->query( $sql );
try {
$result = $this->db->query( $sql );
} catch ( mysqli_sql_exception $e ) { // Like wpdb::query(): an SQL error returns false.
$this->last_error = $e->getMessage();
return false;
}
if ( $result instanceof mysqli_result ) { $result->free(); return true; }
if ( false === $result ) { return false; }
return $this->db->affected_rows;
@@ -291,7 +301,7 @@ if ( ! function_exists( 'is_singular' ) ) { function is_singular( $t = '' ):
if ( ! function_exists( 'wp_doing_ajax' ) ) { function wp_doing_ajax(): bool { return false; } }
if ( ! function_exists( 'wp_next_scheduled' ) ) { function wp_next_scheduled( string $hook ): int|false { return false; } }
if ( ! function_exists( 'wp_schedule_event' ) ) { function wp_schedule_event( int $t, string $r, string $h ): bool { return true; } }
if ( ! function_exists( 'wp_schedule_single_event' ) ) { function wp_schedule_single_event( int $ts, string $hook ): bool { return true; } }
if ( ! function_exists( 'wp_schedule_single_event' ) ) { function wp_schedule_single_event( int $ts, string $hook ): bool { $GLOBALS['_wp_scheduled_single'][] = $hook; return true; } }
if ( ! function_exists( 'wp_clear_scheduled_hook' ) ) { function wp_clear_scheduled_hook( string $hook ): int|false { return 0; } }
if ( ! function_exists( 'sanitize_text_field' ) ) { function sanitize_text_field( string $s ): string { return trim( strip_tags( $s ) ); } }
if ( ! function_exists( '__' ) ) { function __( string $text, string $domain = 'default' ): string { return $text; } }