mirror of
https://github.com/t8y2/dbx.git
synced 2026-10-21 04:02:15 +00:00
fix: scope query connections by client session
This commit is contained in:
@@ -89,6 +89,7 @@ export const executeScript = forward("executeScript");
|
||||
export const executeInTransaction = forward("executeInTransaction");
|
||||
export const cancelQuery = forward("cancelQuery");
|
||||
export const closeQuerySession = forward("closeQuerySession");
|
||||
export const closeClientConnectionSession = forward("closeClientConnectionSession");
|
||||
export const analyzeSqlReferences = forward("analyzeSqlReferences");
|
||||
export const findStatementAtCursor = forward("findStatementAtCursor");
|
||||
export const prepareQueryPaginationExecutionPlan = forward("prepareQueryPaginationExecutionPlan");
|
||||
|
||||
@@ -407,7 +407,13 @@ export async function executeQuery(
|
||||
sql: string,
|
||||
schema?: string,
|
||||
executionId?: string,
|
||||
options?: { maxRows?: number; fetchSize?: number; pageSize?: number; resultSessionId?: string },
|
||||
options?: {
|
||||
maxRows?: number;
|
||||
fetchSize?: number;
|
||||
pageSize?: number;
|
||||
resultSessionId?: string;
|
||||
clientSessionId?: string;
|
||||
},
|
||||
): Promise<QueryResult> {
|
||||
return post("/api/query/execute", { connectionId, database, sql, schema, executionId, ...options });
|
||||
}
|
||||
@@ -418,13 +424,32 @@ export async function executeMulti(
|
||||
sql: string,
|
||||
schema?: string,
|
||||
executionId?: string,
|
||||
options?: { maxRows?: number; fetchSize?: number; pageSize?: number; resultSessionId?: string },
|
||||
options?: {
|
||||
maxRows?: number;
|
||||
fetchSize?: number;
|
||||
pageSize?: number;
|
||||
resultSessionId?: string;
|
||||
clientSessionId?: string;
|
||||
},
|
||||
): Promise<QueryResult[]> {
|
||||
return post("/api/query/execute-multi", { connectionId, database, sql, schema, executionId, ...options });
|
||||
}
|
||||
|
||||
export async function closeQuerySession(connectionId: string, database: string, sessionId: string): Promise<boolean> {
|
||||
return post("/api/query/close-session", { connectionId, database, sessionId });
|
||||
export async function closeQuerySession(
|
||||
connectionId: string,
|
||||
database: string,
|
||||
sessionId: string,
|
||||
clientSessionId?: string,
|
||||
): Promise<boolean> {
|
||||
return post("/api/query/close-session", { connectionId, database, sessionId, clientSessionId });
|
||||
}
|
||||
|
||||
export async function closeClientConnectionSession(
|
||||
connectionId: string,
|
||||
database: string,
|
||||
clientSessionId: string,
|
||||
): Promise<boolean> {
|
||||
return post("/api/query/close-client-session", { connectionId, database, clientSessionId });
|
||||
}
|
||||
|
||||
export async function executeBatch(
|
||||
|
||||
@@ -361,7 +361,13 @@ export async function executeQuery(
|
||||
sql: string,
|
||||
schema?: string,
|
||||
executionId?: string,
|
||||
options?: { maxRows?: number; fetchSize?: number; pageSize?: number; resultSessionId?: string },
|
||||
options?: {
|
||||
maxRows?: number;
|
||||
fetchSize?: number;
|
||||
pageSize?: number;
|
||||
resultSessionId?: string;
|
||||
clientSessionId?: string;
|
||||
},
|
||||
): Promise<QueryResult> {
|
||||
return invoke("execute_query", { connectionId, database, sql, schema, executionId, ...options });
|
||||
}
|
||||
@@ -372,7 +378,13 @@ export async function executeMulti(
|
||||
sql: string,
|
||||
schema?: string,
|
||||
executionId?: string,
|
||||
options?: { maxRows?: number; fetchSize?: number; pageSize?: number; resultSessionId?: string },
|
||||
options?: {
|
||||
maxRows?: number;
|
||||
fetchSize?: number;
|
||||
pageSize?: number;
|
||||
resultSessionId?: string;
|
||||
clientSessionId?: string;
|
||||
},
|
||||
): Promise<QueryResult[]> {
|
||||
return invoke("execute_multi", { connectionId, database, sql, schema, executionId, ...options });
|
||||
}
|
||||
@@ -381,8 +393,21 @@ export async function cancelQuery(executionId: string): Promise<boolean> {
|
||||
return invoke("cancel_query", { executionId });
|
||||
}
|
||||
|
||||
export async function closeQuerySession(connectionId: string, database: string, sessionId: string): Promise<boolean> {
|
||||
return invoke("close_query_session", { connectionId, database, sessionId });
|
||||
export async function closeQuerySession(
|
||||
connectionId: string,
|
||||
database: string,
|
||||
sessionId: string,
|
||||
clientSessionId?: string,
|
||||
): Promise<boolean> {
|
||||
return invoke("close_query_session", { connectionId, database, sessionId, clientSessionId });
|
||||
}
|
||||
|
||||
export async function closeClientConnectionSession(
|
||||
connectionId: string,
|
||||
database: string,
|
||||
clientSessionId: string,
|
||||
): Promise<boolean> {
|
||||
return invoke("close_client_connection_session", { connectionId, database, clientSessionId });
|
||||
}
|
||||
|
||||
export async function executeBatch(
|
||||
|
||||
@@ -62,7 +62,7 @@ export const useQueryStore = defineStore("query", () => {
|
||||
const sessionId = tab?.resultSessionId ?? tab?.result?.session_id;
|
||||
if (!tab || !sessionId || sessionId === preserveSessionId) return;
|
||||
try {
|
||||
await api.closeQuerySession(tab.connectionId, tab.database, sessionId);
|
||||
await api.closeQuerySession(tab.connectionId, tab.database, sessionId, tab.id);
|
||||
} catch (error) {
|
||||
console.warn("[DBX][query-session:close:error]", { tabId: tab.id, sessionId, error });
|
||||
} finally {
|
||||
@@ -71,6 +71,15 @@ export const useQueryStore = defineStore("query", () => {
|
||||
}
|
||||
}
|
||||
|
||||
async function closeClientConnectionSession(tab: QueryTab | undefined) {
|
||||
if (!tab?.connectionId) return;
|
||||
try {
|
||||
await api.closeClientConnectionSession(tab.connectionId, tab.database, tab.id);
|
||||
} catch (error) {
|
||||
console.warn("[DBX][client-session:close:error]", { tabId: tab.id, error });
|
||||
}
|
||||
}
|
||||
|
||||
function clearResultPayload(tab: QueryTab, options: { evicted?: boolean } = {}) {
|
||||
tab.result = undefined;
|
||||
tab.results = undefined;
|
||||
@@ -245,6 +254,7 @@ export const useQueryStore = defineStore("query", () => {
|
||||
if (tabs.value[idx].isExecuting) void cancelTabExecution(id);
|
||||
if (tabs.value[idx].isExplaining) void cancelTabExplain(id);
|
||||
void closeResultSession(tabs.value[idx]);
|
||||
void closeClientConnectionSession(tabs.value[idx]);
|
||||
clearResultPayload(tabs.value[idx]);
|
||||
tabs.value.splice(idx, 1);
|
||||
if (activeTabId.value === id) {
|
||||
@@ -256,6 +266,7 @@ export const useQueryStore = defineStore("query", () => {
|
||||
tabs.value.filter((tab) => tab.id !== id && tab.isExecuting).forEach((tab) => void cancelTabExecution(tab.id));
|
||||
tabs.value.filter((tab) => tab.id !== id && tab.isExplaining).forEach((tab) => void cancelTabExplain(tab.id));
|
||||
tabs.value.filter((tab) => tab.id !== id).forEach((tab) => void closeResultSession(tab));
|
||||
tabs.value.filter((tab) => tab.id !== id).forEach((tab) => void closeClientConnectionSession(tab));
|
||||
const next = closeOtherTabsState(tabs.value, activeTabId.value, id);
|
||||
tabs.value = next.tabs;
|
||||
activeTabId.value = next.activeTabId;
|
||||
@@ -265,6 +276,7 @@ export const useQueryStore = defineStore("query", () => {
|
||||
tabs.value.filter((tab) => tab.isExecuting).forEach((tab) => void cancelTabExecution(tab.id));
|
||||
tabs.value.filter((tab) => tab.isExplaining).forEach((tab) => void cancelTabExplain(tab.id));
|
||||
tabs.value.forEach((tab) => void closeResultSession(tab));
|
||||
tabs.value.forEach((tab) => void closeClientConnectionSession(tab));
|
||||
const next = closeAllTabsState(tabs.value, activeTabId.value);
|
||||
tabs.value = next.tabs;
|
||||
activeTabId.value = next.activeTabId;
|
||||
@@ -325,10 +337,11 @@ export const useQueryStore = defineStore("query", () => {
|
||||
function updateDatabase(id: string, database: string) {
|
||||
const tab = tabs.value.find((t) => t.id === id);
|
||||
if (!tab || tab.database === database) return;
|
||||
void closeResultSession(tab);
|
||||
void closeClientConnectionSession(tab);
|
||||
tab.database = database;
|
||||
tab.schema = undefined;
|
||||
tab.objectBrowser = undefined;
|
||||
void closeResultSession(tab);
|
||||
clearResultPayload(tab);
|
||||
tab.lastExecutedSql = undefined;
|
||||
tab.resultBaseSql = undefined;
|
||||
@@ -347,10 +360,11 @@ export const useQueryStore = defineStore("query", () => {
|
||||
function updateConnection(id: string, connectionId: string, database = "") {
|
||||
const tab = tabs.value.find((t) => t.id === id);
|
||||
if (!tab || tab.connectionId === connectionId) return;
|
||||
void closeResultSession(tab);
|
||||
void closeClientConnectionSession(tab);
|
||||
tab.connectionId = connectionId;
|
||||
tab.database = database;
|
||||
tab.schema = undefined;
|
||||
void closeResultSession(tab);
|
||||
clearResultPayload(tab);
|
||||
tab.lastExecutedSql = undefined;
|
||||
tab.resultBaseSql = undefined;
|
||||
@@ -637,8 +651,9 @@ export const useQueryStore = defineStore("query", () => {
|
||||
fetchSize: pageLimit,
|
||||
pageSize: pageLimit,
|
||||
resultSessionId: options?.pagination?.sessionId,
|
||||
clientSessionId: tab.id,
|
||||
}
|
||||
: { maxRows: pageLimit, fetchSize: pageLimit }
|
||||
: { maxRows: pageLimit, fetchSize: pageLimit, clientSessionId: tab.id }
|
||||
: undefined;
|
||||
const results = await api.executeMulti(
|
||||
tab.connectionId,
|
||||
@@ -738,7 +753,9 @@ export const useQueryStore = defineStore("query", () => {
|
||||
tab.explainSql = built.sql;
|
||||
tab.lastExplainedSql = sql;
|
||||
try {
|
||||
const result = await api.executeQuery(tab.connectionId, tab.database, built.sql, tab.schema, executionId);
|
||||
const result = await api.executeQuery(tab.connectionId, tab.database, built.sql, tab.schema, executionId, {
|
||||
clientSessionId: tab.id,
|
||||
});
|
||||
const current = tabs.value.find((t) => t.id === id);
|
||||
if (current?.explainExecutionId === executionId) {
|
||||
current.explainPlan = parseExplainResult(databaseType as "mysql" | "postgres", result);
|
||||
|
||||
Reference in New Issue
Block a user