feat: 支持 SQL 参数查询
* Fix: 支持 SQL 参数查询 * Fix: 修复前端格式检查 --------- Co-authored-by: staff <staff@qimaos-MacBook-Pro.local> Co-authored-by: t8y2 <1156263951@qq.com>
This commit is contained in:
15 files changed
+681
-2
No files matched your search
@@ -10,6 +10,7 @@ import { classifySqlActivityKind } from "@/lib/historyActivityKind";
|
||||
import { sqlMetadataRefreshTarget } from "@/lib/sqlMetadataRefresh";
|
||||
import { classifyRedisCommandSafety, firstRedisCommandToken } from "@/lib/redisCommandSafety";
|
||||
import { isSqlExecutionSnapshot, resolveExecutableSql, type SqlExecutionOverride, type SqlExecutionSnapshot } from "@/lib/sqlExecutionTarget";
|
||||
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;
|
||||
@@ -56,6 +57,9 @@ export function useSqlExecution(deps: {
|
||||
const showDangerDialog = ref(false);
|
||||
const suppressDangerConfirm = ref(false);
|
||||
const explainMode = ref<"explain" | "autotrace">("explain");
|
||||
const showSqlParameterDialog = ref(false);
|
||||
const sqlParameterSourceSql = ref("");
|
||||
const sqlParameterNames = ref<string[]>([]);
|
||||
|
||||
async function resolvedExecutableSql(source?: SqlExecutionOverride): Promise<string> {
|
||||
if (typeof source === "string") return source;
|
||||
@@ -72,6 +76,11 @@ export function useSqlExecution(deps: {
|
||||
deps.onMissingDatabase?.();
|
||||
return;
|
||||
}
|
||||
if (supportsSqlTemplateParameters(deps.activeConnection.value) && prepareSqlParameterDialog(sql)) return;
|
||||
await continueExecute(sql);
|
||||
}
|
||||
|
||||
async function continueExecute(sql: string) {
|
||||
// Redis: block dangerous commands when toggle is on (check each line for multi-line input)
|
||||
if (deps.activeConnection.value?.db_type === "redis" && deps.blockDangerousRedisCommands?.value !== false) {
|
||||
const commands = sql
|
||||
@@ -92,10 +101,19 @@ export function useSqlExecution(deps: {
|
||||
suppressDangerConfirm.value = false;
|
||||
showDangerDialog.value = true;
|
||||
} else {
|
||||
doExecute(sql);
|
||||
await doExecute(sql);
|
||||
}
|
||||
}
|
||||
|
||||
function prepareSqlParameterDialog(sql: string): boolean {
|
||||
const parameters = extractSqlParameters(sql);
|
||||
if (!parameters.length) return false;
|
||||
sqlParameterSourceSql.value = sql;
|
||||
sqlParameterNames.value = parameters;
|
||||
showSqlParameterDialog.value = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
async function doExecute(sql?: string) {
|
||||
sql ??= await resolvedExecutableSql();
|
||||
const tab = deps.activeTab.value;
|
||||
@@ -178,6 +196,13 @@ export function useSqlExecution(deps: {
|
||||
await doExecute(sql);
|
||||
}
|
||||
|
||||
async function onSqlParametersConfirm(sql: string) {
|
||||
showSqlParameterDialog.value = false;
|
||||
sqlParameterSourceSql.value = "";
|
||||
sqlParameterNames.value = [];
|
||||
await continueExecute(sql);
|
||||
}
|
||||
|
||||
return {
|
||||
dangerSql,
|
||||
pendingDangerSql,
|
||||
@@ -188,10 +213,19 @@ export function useSqlExecution(deps: {
|
||||
cancelActiveExecution,
|
||||
tryExplain,
|
||||
onDangerConfirm,
|
||||
showSqlParameterDialog,
|
||||
sqlParameterSourceSql,
|
||||
sqlParameterNames,
|
||||
onSqlParametersConfirm,
|
||||
explainMode,
|
||||
};
|
||||
}
|
||||
|
||||
function supportsSqlTemplateParameters(connection: ConnectionConfig | undefined): boolean {
|
||||
if (!connection) return false;
|
||||
return connection.db_type !== "redis" && connection.db_type !== "mongodb";
|
||||
}
|
||||
|
||||
function requiresDatabaseSelection(tab: QueryTab, connection: ConnectionConfig | undefined): boolean {
|
||||
if (tab.mode !== "query") return false;
|
||||
if (!connection || tab.database) return false;
|
||||
|
||||
Reference in new issue
Block a user