get_results($sql, ARRAY_A); if ($wpdb->last_error) { throw new \RuntimeException("SQL error: " . $wpdb->last_error); } return [ 'sql' => $sql, 'rows' => $results, 'count' => count($results ?? []), ]; } public static function listTables(array $args): array { global $wpdb; $prefix = $args['prefix'] ?? $wpdb->prefix; $tables = $wpdb->get_col("SHOW TABLES LIKE '{$wpdb->esc_like($prefix)}%'"); $result = []; foreach ($tables as $t) { $info = $wpdb->get_row("SELECT TABLE_ROWS, DATA_LENGTH+INDEX_LENGTH as SIZE FROM information_schema.TABLES WHERE TABLE_SCHEMA=DATABASE() AND TABLE_NAME='$t'", ARRAY_A); $result[] = [ 'table' => $t, 'rows' => (int)($info['TABLE_ROWS'] ?? 0), 'size' => size_format((int)($info['SIZE'] ?? 0)), ]; } return ['tables'=>$result,'count'=>count($result),'prefix'=>$prefix]; } public static function describeTable(array $args): array { global $wpdb; $table = sanitize_text_field($args['table']); // Must use allowed prefix if (strpos($table, $wpdb->prefix) !== 0) { throw new \RuntimeException("Table must use the WP prefix: $wpdb->prefix"); } $columns = $wpdb->get_results("DESCRIBE `$table`", ARRAY_A); if ($wpdb->last_error) throw new \RuntimeException($wpdb->last_error); return ['table'=>$table,'columns'=>$columns,'count'=>count($columns)]; } }