fix(kingbase): preserve query schema context
This commit is contained in:
6 files changed
+306
-49
No files matched your search
+124
@@ -7,10 +7,12 @@ import { analyzeEditableQueryEditability } from "../../apps/desktop/src/lib/sql/
|
||||
import { resultSqlForGrid } from "../../apps/desktop/src/lib/tabs/tabPresentation.ts";
|
||||
import { parseMongoCommand } from "../../apps/desktop/src/lib/mongo/mongoShellCommand.ts";
|
||||
import { useExportTracker } from "../../apps/desktop/src/composables/useExportTracker.ts";
|
||||
import { resolveHistorySqlRestoreTarget } from "../../apps/desktop/src/lib/history/historyRestoreTarget.ts";
|
||||
import { useConnectionStore } from "../../apps/desktop/src/stores/connectionStore.ts";
|
||||
import { useQueryStore } from "../../apps/desktop/src/stores/queryStore.ts";
|
||||
import { useSettingsStore } from "../../apps/desktop/src/stores/settingsStore.ts";
|
||||
import type { ConnectionConfig } from "../../apps/desktop/src/types/database.ts";
|
||||
import type { HistoryEntry } from "../../apps/desktop/src/lib/backend/tauri.ts";
|
||||
import type { QueryResult } from "../../apps/desktop/src/types/database.ts";
|
||||
|
||||
afterEach(() => {
|
||||
@@ -88,6 +90,14 @@ function sparkConn(id: string): ConnectionConfig {
|
||||
};
|
||||
}
|
||||
|
||||
function kingbaseConn(id: string): ConnectionConfig {
|
||||
return {
|
||||
...conn(id),
|
||||
db_type: "kingbase",
|
||||
port: 54321,
|
||||
};
|
||||
}
|
||||
|
||||
function withConnectionHealthMock(handler: typeof fetch): typeof fetch {
|
||||
return async (input, init) => {
|
||||
if (String(input) === "/api/connection/check-health") {
|
||||
@@ -4885,6 +4895,120 @@ test("Spark query execution applies the selected database as schema context", as
|
||||
}
|
||||
});
|
||||
|
||||
test("Kingbase query execution sends the selected schema context", async () => {
|
||||
const restoreStorage = installMemoryStorage();
|
||||
setActivePinia(createPinia());
|
||||
const connectionStore = useConnectionStore();
|
||||
const store = useQueryStore();
|
||||
const originalFetch = globalThis.fetch;
|
||||
|
||||
connectionStore.addEphemeralConnection(kingbaseConn("kingbase-1"));
|
||||
const tabId = store.createTab("kingbase-1", "qinzhou", "Query", "query", "sdy_smartsite");
|
||||
let executeBody: any;
|
||||
|
||||
globalThis.fetch = withConnectionHealthMock(async (input, init) => {
|
||||
const url = String(input);
|
||||
if (url === "/api/query/prepare-pagination-plan") {
|
||||
return new Response(JSON.stringify({ sqlToExecute: "select * from busi_sea_trip_records", useAgentResultSession: false }), {
|
||||
status: 200,
|
||||
headers: { "Content-Type": "application/json" },
|
||||
});
|
||||
}
|
||||
if (url === "/api/query/execute-multi") {
|
||||
executeBody = JSON.parse(String(init?.body ?? "{}"));
|
||||
return new Response(JSON.stringify([{ columns: ["id"], rows: [[1]], affected_rows: 0, execution_time_ms: 1 }]), {
|
||||
status: 200,
|
||||
headers: { "Content-Type": "application/json" },
|
||||
});
|
||||
}
|
||||
if (url === "/api/query/analyze-editability") {
|
||||
return new Response(JSON.stringify({ editable: false, reason: "complex-source" }), {
|
||||
status: 200,
|
||||
headers: { "Content-Type": "application/json" },
|
||||
});
|
||||
}
|
||||
return new Response("unexpected request", { status: 500 });
|
||||
});
|
||||
|
||||
try {
|
||||
await store.executeTabSql(tabId, "select * from busi_sea_trip_records");
|
||||
|
||||
assert.equal(executeBody.database, "qinzhou");
|
||||
assert.equal(executeBody.schema, "sdy_smartsite");
|
||||
} finally {
|
||||
globalThis.fetch = originalFetch;
|
||||
restoreStorage();
|
||||
}
|
||||
});
|
||||
|
||||
test("Kingbase history restore inherits schema when the history entry keeps its database", async () => {
|
||||
const restoreStorage = installMemoryStorage();
|
||||
setActivePinia(createPinia());
|
||||
const connectionStore = useConnectionStore();
|
||||
const store = useQueryStore();
|
||||
const originalFetch = globalThis.fetch;
|
||||
|
||||
connectionStore.addEphemeralConnection(kingbaseConn("kingbase-1"));
|
||||
const currentTabId = store.createTab("kingbase-1", "qinzhou", "Current", "query", "sdy_smartsite");
|
||||
const currentTab = store.tabs.find((tab) => tab.id === currentTabId);
|
||||
assert.ok(currentTab);
|
||||
const entry: HistoryEntry = {
|
||||
id: "history-1",
|
||||
connection_id: "kingbase-1",
|
||||
connection_name: "Kingbase",
|
||||
database: "qinzhou",
|
||||
sql: "select * from busi_sea_trip_records",
|
||||
executed_at: "2026-07-29T08:00:00Z",
|
||||
execution_time_ms: 12,
|
||||
success: true,
|
||||
};
|
||||
const target = resolveHistorySqlRestoreTarget({
|
||||
entry,
|
||||
activeTab: currentTab,
|
||||
firstConnectionId: connectionStore.connections[0]?.id,
|
||||
getConfig: (connectionId) => connectionStore.getConfig(connectionId),
|
||||
});
|
||||
assert.ok(target);
|
||||
assert.deepEqual(target, { connectionId: "kingbase-1", database: "qinzhou", schema: "sdy_smartsite" });
|
||||
const restoredTabId = store.createTab(target.connectionId, target.database, "SQL", "query", target.schema);
|
||||
store.updateSql(restoredTabId, entry.sql);
|
||||
let executeBody: any;
|
||||
|
||||
globalThis.fetch = withConnectionHealthMock(async (input, init) => {
|
||||
const url = String(input);
|
||||
if (url === "/api/query/prepare-pagination-plan") {
|
||||
return new Response(JSON.stringify({ sqlToExecute: entry.sql, useAgentResultSession: false }), {
|
||||
status: 200,
|
||||
headers: { "Content-Type": "application/json" },
|
||||
});
|
||||
}
|
||||
if (url === "/api/query/execute-multi") {
|
||||
executeBody = JSON.parse(String(init?.body ?? "{}"));
|
||||
return new Response(JSON.stringify([{ columns: ["id"], rows: [[1]], affected_rows: 0, execution_time_ms: 1 }]), {
|
||||
status: 200,
|
||||
headers: { "Content-Type": "application/json" },
|
||||
});
|
||||
}
|
||||
if (url === "/api/query/analyze-editability") {
|
||||
return new Response(JSON.stringify({ editable: false, reason: "complex-source" }), {
|
||||
status: 200,
|
||||
headers: { "Content-Type": "application/json" },
|
||||
});
|
||||
}
|
||||
return new Response("unexpected request", { status: 500 });
|
||||
});
|
||||
|
||||
try {
|
||||
await store.executeTabSql(restoredTabId, entry.sql);
|
||||
|
||||
assert.equal(executeBody.database, "qinzhou");
|
||||
assert.equal(executeBody.schema, "sdy_smartsite");
|
||||
} finally {
|
||||
globalThis.fetch = originalFetch;
|
||||
restoreStorage();
|
||||
}
|
||||
});
|
||||
|
||||
test("data tab execution uses a tab-scoped client session", async () => {
|
||||
const restoreStorage = installMemoryStorage();
|
||||
setActivePinia(createPinia());
|
||||
|
||||
Reference in new issue
Block a user