fix: sql_query accepts both sql and query params; describeTable handles wp_ prefix on sites with different prefix
This commit is contained in:
@@ -18,24 +18,22 @@ class RawSqlTools {
|
|||||||
throw new \RuntimeException("Raw SQL is disabled. Enable it in AskTam MCP → Settings.");
|
throw new \RuntimeException("Raw SQL is disabled. Enable it in AskTam MCP → Settings.");
|
||||||
}
|
}
|
||||||
|
|
||||||
$sql = trim($args['sql'] ?? '');
|
// Accept both 'sql' and 'query' as the parameter name
|
||||||
|
$sql = trim($args['sql'] ?? $args['query'] ?? '');
|
||||||
$limit = min((int)($args['limit'] ?? 100), 500);
|
$limit = min((int)($args['limit'] ?? 100), 500);
|
||||||
|
|
||||||
if (empty($sql)) throw new \RuntimeException("SQL query is required.");
|
if (empty($sql)) throw new \RuntimeException("SQL query is required.");
|
||||||
|
|
||||||
// Only SELECT allowed
|
|
||||||
if (!preg_match('/^\s*SELECT\b/i', $sql)) {
|
if (!preg_match('/^\s*SELECT\b/i', $sql)) {
|
||||||
throw new \RuntimeException("Only SELECT queries are allowed.");
|
throw new \RuntimeException("Only SELECT queries are allowed.");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Block dangerous patterns
|
|
||||||
foreach (self::$BLOCKED as $pattern) {
|
foreach (self::$BLOCKED as $pattern) {
|
||||||
if (preg_match($pattern, $sql)) {
|
if (preg_match($pattern, $sql)) {
|
||||||
throw new \RuntimeException("Query contains blocked pattern.");
|
throw new \RuntimeException("Query contains blocked pattern.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Inject LIMIT if not present
|
|
||||||
if (!preg_match('/\bLIMIT\b/i', $sql)) {
|
if (!preg_match('/\bLIMIT\b/i', $sql)) {
|
||||||
$sql .= " LIMIT $limit";
|
$sql .= " LIMIT $limit";
|
||||||
}
|
}
|
||||||
@@ -47,11 +45,7 @@ class RawSqlTools {
|
|||||||
throw new \RuntimeException("SQL error: " . $wpdb->last_error);
|
throw new \RuntimeException("SQL error: " . $wpdb->last_error);
|
||||||
}
|
}
|
||||||
|
|
||||||
return [
|
return ['sql' => $sql, 'rows' => $results, 'count' => count($results ?? [])];
|
||||||
'sql' => $sql,
|
|
||||||
'rows' => $results,
|
|
||||||
'count' => count($results ?? []),
|
|
||||||
];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function listTables(array $args): array {
|
public static function listTables(array $args): array {
|
||||||
@@ -72,11 +66,28 @@ class RawSqlTools {
|
|||||||
|
|
||||||
public static function describeTable(array $args): array {
|
public static function describeTable(array $args): array {
|
||||||
global $wpdb;
|
global $wpdb;
|
||||||
$table = sanitize_text_field($args['table']);
|
$table = sanitize_text_field($args['table'] ?? '');
|
||||||
// Must use allowed prefix
|
if (empty($table)) throw new \RuntimeException("table is required.");
|
||||||
|
|
||||||
|
// Accept the table name with or without the WP prefix.
|
||||||
|
// If the caller passes "wp_posts" and the actual prefix is "mwp_", try both.
|
||||||
if (strpos($table, $wpdb->prefix) !== 0) {
|
if (strpos($table, $wpdb->prefix) !== 0) {
|
||||||
throw new \RuntimeException("Table must use the WP prefix: $wpdb->prefix");
|
// Maybe they passed "wp_posts" on a site with a different prefix — strip any leading wp_ and re-add correct prefix
|
||||||
|
$stripped = preg_replace('/^wp_/', '', $table);
|
||||||
|
$candidate = $wpdb->prefix . $stripped;
|
||||||
|
// Verify the candidate exists
|
||||||
|
$exists = $wpdb->get_var($wpdb->prepare("SHOW TABLES LIKE %s", $candidate));
|
||||||
|
if ($exists) {
|
||||||
|
$table = $candidate;
|
||||||
|
} else {
|
||||||
|
// Last attempt: use exactly as given
|
||||||
|
$exists = $wpdb->get_var($wpdb->prepare("SHOW TABLES LIKE %s", $table));
|
||||||
|
if (!$exists) {
|
||||||
|
throw new \RuntimeException("Table not found: {$args['table']}. WP prefix is: {$wpdb->prefix}");
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
$columns = $wpdb->get_results("DESCRIBE `$table`", ARRAY_A);
|
$columns = $wpdb->get_results("DESCRIBE `$table`", ARRAY_A);
|
||||||
if ($wpdb->last_error) throw new \RuntimeException($wpdb->last_error);
|
if ($wpdb->last_error) throw new \RuntimeException($wpdb->last_error);
|
||||||
return ['table' => $table, 'columns' => $columns, 'count' => count($columns)];
|
return ['table' => $table, 'columns' => $columns, 'count' => count($columns)];
|
||||||
|
|||||||
Reference in New Issue
Block a user