mirror of
https://github.com/t8y2/dbx.git
synced 2026-10-21 08:13:34 +00:00
fix(editor): keep object source identity for view-source saves
This commit is contained in:
@@ -272,6 +272,27 @@ describe("queryStore pending object source tab", () => {
|
||||
expect(tab.sourceLoad).toBeUndefined();
|
||||
});
|
||||
|
||||
it("keeps a routine source tab saveable when opened from the view entry", async () => {
|
||||
// 侧栏单击/双击存储过程走的是「查看源码」(initialEditing=false)。该 tab 必须
|
||||
// 仍然挂着 objectSource,否则 Ctrl+S 会退化成「保存到 SQL 库」,用户再也改不了
|
||||
// 存储过程(v0.6.18 回归)。同一次「查看」也应复用同一个 tab。
|
||||
mocks.getObjectSource.mockResolvedValue(objectSource("CREATE OR REPLACE PROCEDURE app.sp_run AS BEGIN NULL; END;"));
|
||||
const { useQueryStore } = await import("@/stores/queryStore");
|
||||
const store = useQueryStore();
|
||||
|
||||
const options = { ...pendingOptions({ name: "sp_run", objectType: "PROCEDURE" as const }), initialEditing: false };
|
||||
const id = store.openObjectSourceTabPending(options);
|
||||
await settle();
|
||||
|
||||
expect(store.tabs).toHaveLength(1);
|
||||
expect(store.tabs[0]?.sql).toBe("CREATE OR REPLACE PROCEDURE app.sp_run AS BEGIN NULL; END;");
|
||||
expect(store.tabs[0]?.objectSource).toMatchObject({ schema: SCHEMA, name: "sp_run", objectType: "PROCEDURE" });
|
||||
|
||||
expect(store.openObjectSourceTabPending(options)).toBe(id);
|
||||
await settle();
|
||||
expect(store.tabs).toHaveLength(1);
|
||||
});
|
||||
|
||||
it("keeps OceanBase sequence CREATE source for viewing and uses ALTER only for editing", async () => {
|
||||
mocks.connectionStore.dbType = "oceanbase-oracle";
|
||||
mocks.getObjectSource.mockResolvedValue(objectSource('CREATE SEQUENCE "APP"."SEQ_USERS" START WITH 10 INCREMENT BY 2'));
|
||||
|
||||
@@ -213,6 +213,17 @@ interface OpenPendingObjectSourceTabOptions {
|
||||
*/
|
||||
const OBJECT_SOURCE_READ_ONLY_TYPES: readonly ObjectSourceKind[] = ["SEQUENCE", "TRIGGER", "TYPE", "TYPE_BODY", "JOB"];
|
||||
|
||||
/**
|
||||
* 「查看」与「编辑」拿到的文本本就不同的对象类型:OceanBase Oracle 的序列在查看态
|
||||
* 展示原生 `CREATE SEQUENCE`(信息量更大),编辑态才是可执行的 `ALTER SEQUENCE`,
|
||||
* 所以查看态不能落成可保存的源码 tab —— 否则 Ctrl+S 会把 `CREATE SEQUENCE` 当增量
|
||||
* 修改执行。其余类型(存储过程/函数/视图等)查看态与编辑态文本一致,查看态沿用
|
||||
* v0.6.17 行为,仍是带 objectSource 的可保存源码 tab。
|
||||
*/
|
||||
function isViewOnlySourceWithoutEditablePayload(initialEditing: boolean | undefined, objectType: ObjectSourceKind): boolean {
|
||||
return initialEditing === false && objectType === "SEQUENCE";
|
||||
}
|
||||
|
||||
interface UpdateExecutionTargetOptions {
|
||||
persistSavedSqlTarget?: boolean;
|
||||
}
|
||||
@@ -2741,18 +2752,17 @@ export const useQueryStore = defineStore("query", () => {
|
||||
// 两条弯路都要避开 —— 再建一个 pending tab 会让界面上多出一个转圈 tab,
|
||||
// 随后又被交接逻辑关掉;而只切过去不校验,会让重开看到的是旧 DDL
|
||||
// (改动前每次打开都会重新取源,源码 tab 没有其它刷新入口)。
|
||||
const loaded =
|
||||
options.initialEditing === false
|
||||
? undefined
|
||||
: findMatchingObjectSourceTab({
|
||||
connectionId: options.connectionId,
|
||||
database: options.database,
|
||||
title: options.title,
|
||||
schema: options.schema,
|
||||
catalog: options.catalog,
|
||||
sql: "",
|
||||
objectSource: { schema: options.schema, name: options.request.name, objectType: options.request.objectType, signature: options.request.signature },
|
||||
});
|
||||
const loaded = isViewOnlySourceWithoutEditablePayload(options.initialEditing, options.request.objectType)
|
||||
? undefined
|
||||
: findMatchingObjectSourceTab({
|
||||
connectionId: options.connectionId,
|
||||
database: options.database,
|
||||
title: options.title,
|
||||
schema: options.schema,
|
||||
catalog: options.catalog,
|
||||
sql: "",
|
||||
objectSource: { schema: options.schema, name: options.request.name, objectType: options.request.objectType, signature: options.request.signature },
|
||||
});
|
||||
if (loaded) {
|
||||
loaded.sourceView = true;
|
||||
switchTab(loaded.id);
|
||||
@@ -2887,7 +2897,7 @@ export const useQueryStore = defineStore("query", () => {
|
||||
// 加载期间 tab 被关掉(用户放弃)或连接被断开:静默丢弃,不重建、不写库
|
||||
const tab = tabs.value.find((candidate) => candidate.id === id);
|
||||
if (!tab?.sourceLoad) return;
|
||||
const sourceIsEditable = loaded.initialEditing !== false && loaded.raw.editable !== false && (!OBJECT_SOURCE_READ_ONLY_TYPES.includes(loaded.resolvedType) || (loaded.databaseType === "oceanbase-oracle" && loaded.resolvedType === "SEQUENCE"));
|
||||
const sourceIsEditable = !isViewOnlySourceWithoutEditablePayload(loaded.initialEditing, loaded.resolvedType) && loaded.raw.editable !== false && (!OBJECT_SOURCE_READ_ONLY_TYPES.includes(loaded.resolvedType) || (loaded.databaseType === "oceanbase-oracle" && loaded.resolvedType === "SEQUENCE"));
|
||||
if (sourceIsEditable) {
|
||||
const options: OpenObjectSourceTabOptions = {
|
||||
connectionId: loaded.connectionId,
|
||||
|
||||
Reference in New Issue
Block a user