fix: support mysql install scripts without selected database (#2356)
This commit is contained in:
1 parent
730f839e74
commit
71e618dd46
12 files changed
+975
-90
No files matched your search
@@ -39,8 +39,20 @@ describe("requiresDatabaseSelection", () => {
|
||||
expect(requiresDatabaseSelection(queryTab(), connection("mysql"), "CREATE SCHEMA `app-db` DEFAULT CHARACTER SET utf8mb4")).toBe(false);
|
||||
});
|
||||
|
||||
it("requires a database when a MySQL batch includes non-creation statements", () => {
|
||||
expect(requiresDatabaseSelection(queryTab(), connection("mysql"), "CREATE DATABASE app_db; SELECT * FROM users")).toBe(true);
|
||||
it("allows MySQL install batches that switch databases before table DDL", () => {
|
||||
expect(requiresDatabaseSelection(queryTab(), connection("mysql"), "CREATE DATABASE app_db; USE app_db; CREATE TABLE users(id INT PRIMARY KEY)")).toBe(false);
|
||||
});
|
||||
|
||||
it("allows MySQL install batches with session setup before switching databases", () => {
|
||||
expect(requiresDatabaseSelection(queryTab(), connection("mysql"), "SET NAMES utf8mb4; DROP DATABASE IF EXISTS app_db; CREATE DATABASE app_db; USE app_db; INSERT INTO users VALUES (1)")).toBe(false);
|
||||
});
|
||||
|
||||
it("requires a database when MySQL batch statements never establish database context", () => {
|
||||
expect(requiresDatabaseSelection(queryTab(), connection("mysql"), "CREATE DATABASE app_db; CREATE TABLE users(id INT)")).toBe(true);
|
||||
});
|
||||
|
||||
it("requires a database when a USE statement is not a standalone database switch", () => {
|
||||
expect(requiresDatabaseSelection(queryTab(), connection("mysql"), "CREATE DATABASE app_db; USE app_db SELECT 1; CREATE TABLE users(id INT)")).toBe(true);
|
||||
});
|
||||
|
||||
it("still requires a database for ordinary MySQL queries", () => {
|
||||
|
||||
@@ -6,6 +6,7 @@ import { useConnectionStore } from "@/stores/connectionStore";
|
||||
import { useSettingsStore } from "@/stores/settingsStore";
|
||||
import { useToast } from "@/composables/useToast";
|
||||
import { isSingleDatabase } from "@/lib/databaseCapabilities";
|
||||
import { canExecuteWithoutSelectedDatabase } from "@/lib/connectionLevelDatabaseBootstrap";
|
||||
import { classifySqlActivityKind } from "@/lib/historyActivityKind";
|
||||
import { sqlMetadataRefreshTarget } from "@/lib/sqlMetadataRefresh";
|
||||
import { classifyRedisCommandSafety, firstRedisCommandToken } from "@/lib/redisCommandSafety";
|
||||
@@ -14,7 +15,6 @@ import { extractSqlParameters } from "@/lib/sqlParameters";
|
||||
import type { ConnectionConfig, QueryTab } from "@/types/database";
|
||||
|
||||
const DANGER_RE = /^\s*(DROP|DELETE|TRUNCATE|ALTER|UPDATE|MERGE|REPLACE)\b/i;
|
||||
const CONNECTION_LEVEL_CREATE_DATABASE_RE = /^\s*CREATE\s+(?:DATABASE|SCHEMA)\s+(?:IF\s+NOT\s+EXISTS\s+)?[`"[\]\w$.-]+/i;
|
||||
|
||||
export function stripSqlComments(sql: string): string {
|
||||
return sql
|
||||
@@ -227,17 +227,6 @@ function supportsSqlTemplateParameters(connection: ConnectionConfig | undefined)
|
||||
return connection.db_type !== "redis" && connection.db_type !== "mongodb";
|
||||
}
|
||||
|
||||
function canExecuteWithoutSelectedDatabase(connection: ConnectionConfig, sql: string): boolean {
|
||||
if (connection.db_type !== "mysql") return false;
|
||||
const statements = stripSqlComments(sql)
|
||||
.split(";")
|
||||
.map((stmt) => stmt.trim())
|
||||
.filter(Boolean);
|
||||
// Only connection-level database creation may bypass the selected-database guard.
|
||||
if (statements.length !== 1) return false;
|
||||
return CONNECTION_LEVEL_CREATE_DATABASE_RE.test(statements[0]);
|
||||
}
|
||||
|
||||
export function requiresDatabaseSelection(tab: QueryTab, connection: ConnectionConfig | undefined, sql = ""): boolean {
|
||||
if (tab.mode !== "query") return false;
|
||||
if (!connection || tab.database) return false;
|
||||
|
||||
Reference in new issue
Block a user