feat(desktop): drop tree schema objects
This commit is contained in:
1 parent
17504be027
commit
ac7a5b7576
15 files changed
+466
-13
No files matched your search
@@ -102,15 +102,19 @@ import {
|
||||
buildDropObjectSql,
|
||||
buildDropSchemaSql,
|
||||
buildDropTableSql,
|
||||
buildDropTableChildObjectSql,
|
||||
buildDuplicateTableStructureSql,
|
||||
buildEmptyTableSql,
|
||||
buildTruncateTableSql,
|
||||
type DropTableChildObjectSqlOptions,
|
||||
type DropObjectSqlOptions,
|
||||
type TableChildObjectType,
|
||||
type TableAdminSqlOptions,
|
||||
} from "@/lib/dbAdminSql";
|
||||
import { buildRenameObjectSql, supportsObjectRename, type RenameableObjectType } from "@/lib/objectRenameSql";
|
||||
import { buildRoutineRenameObjectSourceStatements, supportsSourceBackedRoutineRename } from "@/lib/objectSourceEditor";
|
||||
import { buildViewDdl } from "@/lib/viewDdl";
|
||||
import { getTableStructureCapabilities } from "@/lib/tableStructureCapabilities";
|
||||
import { hexToRgba } from "@/lib/color";
|
||||
import { focusSidebarRenameInput } from "@/lib/sidebarRenameFocus";
|
||||
import { hasTreeNodeDatabaseContext } from "@/lib/treeNodeContext";
|
||||
@@ -450,6 +454,12 @@ function isEditableShortcutTarget(target: EventTarget | null): boolean {
|
||||
|
||||
function onKeydown(event: KeyboardEvent) {
|
||||
if (!isSelected.value || isEditableShortcutTarget(event.target)) return;
|
||||
if (!event.metaKey && !event.ctrlKey && !event.altKey && !event.shiftKey && isDeleteTreeNodeShortcut(event)) {
|
||||
if (!requestDropSelectedNode()) return;
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
return;
|
||||
}
|
||||
const action = sidebarSelectionCopyAction(event);
|
||||
if (action !== "copy-name") return;
|
||||
event.preventDefault();
|
||||
@@ -457,6 +467,10 @@ function onKeydown(event: KeyboardEvent) {
|
||||
copyName();
|
||||
}
|
||||
|
||||
function isDeleteTreeNodeShortcut(event: KeyboardEvent): boolean {
|
||||
return event.key === "Delete" || event.key === "Backspace";
|
||||
}
|
||||
|
||||
function onDoubleClick() {
|
||||
const action = treeNodeRowDoubleClickAction(
|
||||
props.node.type,
|
||||
@@ -704,6 +718,7 @@ async function duplicateConnection() {
|
||||
|
||||
// --- Table Management Operations ---
|
||||
const showDropTableConfirm = ref(false);
|
||||
const showDropTableChildObjectConfirm = ref(false);
|
||||
const showEmptyTableConfirm = ref(false);
|
||||
const showTruncateTableConfirm = ref(false);
|
||||
const showRenameObjectDialog = ref(false);
|
||||
@@ -714,6 +729,7 @@ const dropTablePreviewSql = ref("");
|
||||
const emptyTablePreviewSql = ref("");
|
||||
const truncateTablePreviewSql = ref("");
|
||||
const dropObjectPreviewSql = ref("");
|
||||
const dropTableChildObjectPreviewSql = ref("");
|
||||
const dropDatabasePreviewSql = ref("");
|
||||
const dropSchemaPreviewSql = ref("");
|
||||
const showDuplicateDialog = ref(false);
|
||||
@@ -735,21 +751,114 @@ const showProcedureExecutionConfirm = ref(false);
|
||||
|
||||
function dropObjectSqlOptions(): DropObjectSqlOptions | null {
|
||||
const node = props.node;
|
||||
if (node.type !== "procedure" && node.type !== "function") return null;
|
||||
if (node.type !== "view" && node.type !== "procedure" && node.type !== "function") return null;
|
||||
return {
|
||||
databaseType: currentDatabaseType(),
|
||||
objectType: node.type === "procedure" ? "PROCEDURE" : "FUNCTION",
|
||||
objectType: node.type === "view" ? "VIEW" : node.type === "procedure" ? "PROCEDURE" : "FUNCTION",
|
||||
schema: node.schema,
|
||||
name: node.label,
|
||||
};
|
||||
}
|
||||
|
||||
function tableChildDropObjectType(type: TreeNodeType): TableChildObjectType | null {
|
||||
if (type === "column") return "COLUMN";
|
||||
if (type === "index") return "INDEX";
|
||||
if (type === "fkey") return "FOREIGN_KEY";
|
||||
if (type === "trigger") return "TRIGGER";
|
||||
return null;
|
||||
}
|
||||
|
||||
function tableChildDropObjectName(node: TreeNode): string {
|
||||
if (node.type === "column")
|
||||
return node.meta && "name" in node.meta ? node.meta.name : node.label.replace(/\s+\(.+\)$/, "");
|
||||
if (node.type === "index")
|
||||
return node.meta && "name" in node.meta ? node.meta.name : node.label.replace(/\s+\(.+\)$/, "");
|
||||
if (node.type === "fkey") return node.meta && "name" in node.meta ? node.meta.name : node.label;
|
||||
if (node.type === "trigger")
|
||||
return node.meta && "name" in node.meta ? node.meta.name : node.label.replace(/\s+\(.+\)$/, "");
|
||||
return node.label;
|
||||
}
|
||||
|
||||
function dropTableChildObjectSqlOptions(): DropTableChildObjectSqlOptions | null {
|
||||
const node = props.node;
|
||||
const objectType = tableChildDropObjectType(node.type);
|
||||
if (!objectType || !node.tableName) return null;
|
||||
const name = tableChildDropObjectName(node).trim();
|
||||
if (!name) return null;
|
||||
return {
|
||||
databaseType: currentDatabaseType(),
|
||||
objectType,
|
||||
schema: node.schema,
|
||||
tableName: node.tableName,
|
||||
name,
|
||||
};
|
||||
}
|
||||
|
||||
const canDropTableChildObject = computed(() => {
|
||||
const options = dropTableChildObjectSqlOptions();
|
||||
if (!options) return false;
|
||||
const capabilities = getTableStructureCapabilities(currentDatabaseType());
|
||||
if (options.objectType === "COLUMN") return capabilities.dropColumn;
|
||||
if (options.objectType === "INDEX") return capabilities.dropIndex;
|
||||
return true;
|
||||
});
|
||||
|
||||
function dropObjectMenuLabel(): string {
|
||||
if (props.node.type === "view") return t("contextMenu.dropView");
|
||||
if (props.node.type === "procedure") return t("contextMenu.dropProcedure");
|
||||
if (props.node.type === "function") return t("contextMenu.dropFunction");
|
||||
return t("contextMenu.dropObject");
|
||||
}
|
||||
|
||||
function dropObjectConfirmTitle(): string {
|
||||
if (props.node.type === "view") return t("contextMenu.confirmDropViewTitle");
|
||||
if (props.node.type === "procedure") return t("contextMenu.confirmDropProcedureTitle");
|
||||
if (props.node.type === "function") return t("contextMenu.confirmDropFunctionTitle");
|
||||
return t("contextMenu.confirmDropObjectTitle");
|
||||
}
|
||||
|
||||
function dropObjectConfirmMessage(): string {
|
||||
if (props.node.type === "view") return t("contextMenu.confirmDropViewMessage", { name: props.node.label });
|
||||
if (props.node.type === "procedure") return t("contextMenu.confirmDropProcedureMessage", { name: props.node.label });
|
||||
if (props.node.type === "function") return t("contextMenu.confirmDropFunctionMessage", { name: props.node.label });
|
||||
return t("contextMenu.confirmDropObjectMessage", { name: props.node.label });
|
||||
}
|
||||
|
||||
function dropTableChildObjectMenuLabel(): string {
|
||||
if (props.node.type === "column") return t("contextMenu.dropColumn");
|
||||
if (props.node.type === "index") return t("contextMenu.dropIndex");
|
||||
if (props.node.type === "fkey") return t("contextMenu.dropForeignKey");
|
||||
if (props.node.type === "trigger") return t("contextMenu.dropTrigger");
|
||||
return t("contextMenu.dropObject");
|
||||
}
|
||||
|
||||
function dropTableChildObjectConfirmTitle(): string {
|
||||
if (props.node.type === "column") return t("contextMenu.confirmDropColumnTitle");
|
||||
if (props.node.type === "index") return t("contextMenu.confirmDropIndexTitle");
|
||||
if (props.node.type === "fkey") return t("contextMenu.confirmDropForeignKeyTitle");
|
||||
if (props.node.type === "trigger") return t("contextMenu.confirmDropTriggerTitle");
|
||||
return t("contextMenu.confirmDropObjectTitle");
|
||||
}
|
||||
|
||||
function dropTableChildObjectConfirmMessage(): string {
|
||||
return t("contextMenu.confirmDropTableChildObjectMessage", {
|
||||
name: tableChildDropObjectName(props.node),
|
||||
table: props.node.tableName || "",
|
||||
});
|
||||
}
|
||||
|
||||
async function refreshDropObjectPreviewSql() {
|
||||
const options = dropObjectSqlOptions();
|
||||
dropObjectPreviewSql.value = "";
|
||||
dropObjectPreviewSql.value = options ? await buildDropObjectSql(options).catch(() => "") : "";
|
||||
}
|
||||
|
||||
async function refreshDropTableChildObjectPreviewSql() {
|
||||
const options = dropTableChildObjectSqlOptions();
|
||||
dropTableChildObjectPreviewSql.value = "";
|
||||
dropTableChildObjectPreviewSql.value = options ? await buildDropTableChildObjectSql(options).catch(() => "") : "";
|
||||
}
|
||||
|
||||
function viewObjectSource() {
|
||||
const node = props.node;
|
||||
if (!node.connectionId || !node.database) return;
|
||||
@@ -828,6 +937,28 @@ function requestDropObject() {
|
||||
showDropObjectConfirm.value = true;
|
||||
}
|
||||
|
||||
function requestDropTableChildObject() {
|
||||
if (!canDropTableChildObject.value) return;
|
||||
void refreshDropTableChildObjectPreviewSql();
|
||||
showDropTableChildObjectConfirm.value = true;
|
||||
}
|
||||
|
||||
function requestDropSelectedNode(): boolean {
|
||||
if (props.node.type === "table") {
|
||||
dropTable();
|
||||
return true;
|
||||
}
|
||||
if (props.node.type === "view" || props.node.type === "procedure" || props.node.type === "function") {
|
||||
requestDropObject();
|
||||
return true;
|
||||
}
|
||||
if (canDropTableChildObject.value) {
|
||||
requestDropTableChildObject();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function nodeRenameObjectType(): RenameableObjectType | null {
|
||||
if (props.node.type === "table") return "TABLE";
|
||||
if (props.node.type === "view") return "VIEW";
|
||||
@@ -944,9 +1075,34 @@ async function confirmDropObject() {
|
||||
await connectionStore.ensureConnected(node.connectionId);
|
||||
const sql = dropObjectPreviewSql.value || (await buildDropObjectSql(options));
|
||||
await api.executeQuery(node.connectionId, node.database, sql, node.schema);
|
||||
const msgKey = node.type === "procedure" ? "contextMenu.dropProcedureSuccess" : "contextMenu.dropFunctionSuccess";
|
||||
const msgKey =
|
||||
node.type === "view"
|
||||
? "contextMenu.dropViewSuccess"
|
||||
: node.type === "procedure"
|
||||
? "contextMenu.dropProcedureSuccess"
|
||||
: "contextMenu.dropFunctionSuccess";
|
||||
toast(t(msgKey, { name: node.label }), 3000);
|
||||
await refreshTableList(node);
|
||||
if (node.type === "view") {
|
||||
connectionStore.removeTreeNode(node.id);
|
||||
} else {
|
||||
await refreshTableList(node);
|
||||
}
|
||||
} catch (e: any) {
|
||||
toast(t("contextMenu.tableOperationFailed", { message: e?.message || String(e) }), 5000);
|
||||
}
|
||||
}
|
||||
|
||||
async function confirmDropTableChildObject() {
|
||||
const node = props.node;
|
||||
if (!node.connectionId || !node.database) return;
|
||||
const options = dropTableChildObjectSqlOptions();
|
||||
if (!options) return;
|
||||
try {
|
||||
await connectionStore.ensureConnected(node.connectionId);
|
||||
const sql = dropTableChildObjectPreviewSql.value || (await buildDropTableChildObjectSql(options));
|
||||
await api.executeQuery(node.connectionId, node.database, sql, node.schema);
|
||||
toast(t("contextMenu.dropTableChildObjectSuccess", { name: options.name }), 3000);
|
||||
connectionStore.removeTreeNode(node.id);
|
||||
} catch (e: any) {
|
||||
toast(t("contextMenu.tableOperationFailed", { message: e?.message || String(e) }), 5000);
|
||||
}
|
||||
@@ -2190,6 +2346,14 @@ function treeItemMenuItems(): ContextMenuItem[] {
|
||||
if (canRenameObject.value) {
|
||||
items.push({ label: t("contextMenu.renameObject"), action: openRenameObjectDialog, icon: Pencil });
|
||||
}
|
||||
if (node.type === "view") {
|
||||
items.push({
|
||||
label: t("contextMenu.dropView"),
|
||||
action: requestDropObject,
|
||||
icon: Trash2,
|
||||
variant: "destructive" as const,
|
||||
});
|
||||
}
|
||||
items.push({ label: t("contextMenu.newQuery"), action: newQuery, icon: TerminalSquare });
|
||||
if (canOpenDiagram.value) {
|
||||
items.push({ label: t("diagram.open"), action: openDiagram, icon: Network });
|
||||
@@ -2236,9 +2400,34 @@ function treeItemMenuItems(): ContextMenuItem[] {
|
||||
|
||||
// 7. Column
|
||||
if (node.type === "column") {
|
||||
items.push({ label: t("contextMenu.copyName"), action: copyName, icon: Copy });
|
||||
if (canOpenFieldLineage.value) {
|
||||
items.push({ label: "", separator: true });
|
||||
items.push({ label: t("lineage.open"), action: openFieldLineage, icon: Network });
|
||||
}
|
||||
if (canDropTableChildObject.value) {
|
||||
items.push({ label: "", separator: true });
|
||||
items.push({
|
||||
label: dropTableChildObjectMenuLabel(),
|
||||
action: requestDropTableChildObject,
|
||||
icon: Trash2,
|
||||
variant: "destructive" as const,
|
||||
});
|
||||
}
|
||||
return items;
|
||||
}
|
||||
|
||||
if (node.type === "index" || node.type === "fkey" || node.type === "trigger") {
|
||||
items.push({ label: t("contextMenu.copyName"), action: copyName, icon: Copy });
|
||||
if (canDropTableChildObject.value) {
|
||||
items.push({ label: "", separator: true });
|
||||
items.push({
|
||||
label: dropTableChildObjectMenuLabel(),
|
||||
action: requestDropTableChildObject,
|
||||
icon: Trash2,
|
||||
variant: "destructive" as const,
|
||||
});
|
||||
}
|
||||
return items;
|
||||
}
|
||||
|
||||
@@ -2611,19 +2800,22 @@ function treeItemMenuItems(): ContextMenuItem[] {
|
||||
|
||||
<DangerConfirmDialog
|
||||
v-model:open="showDropObjectConfirm"
|
||||
:title="
|
||||
node.type === 'procedure' ? t('contextMenu.confirmDropProcedureTitle') : t('contextMenu.confirmDropFunctionTitle')
|
||||
"
|
||||
:message="
|
||||
node.type === 'procedure'
|
||||
? t('contextMenu.confirmDropProcedureMessage', { name: node.label })
|
||||
: t('contextMenu.confirmDropFunctionMessage', { name: node.label })
|
||||
"
|
||||
:title="dropObjectConfirmTitle()"
|
||||
:message="dropObjectConfirmMessage()"
|
||||
:sql="dropObjectPreviewSql"
|
||||
:confirm-label="node.type === 'procedure' ? t('contextMenu.dropProcedure') : t('contextMenu.dropFunction')"
|
||||
:confirm-label="dropObjectMenuLabel()"
|
||||
@confirm="confirmDropObject"
|
||||
/>
|
||||
|
||||
<DangerConfirmDialog
|
||||
v-model:open="showDropTableChildObjectConfirm"
|
||||
:title="dropTableChildObjectConfirmTitle()"
|
||||
:message="dropTableChildObjectConfirmMessage()"
|
||||
:sql="dropTableChildObjectPreviewSql"
|
||||
:confirm-label="dropTableChildObjectMenuLabel()"
|
||||
@confirm="confirmDropTableChildObject"
|
||||
/>
|
||||
|
||||
<ProcedureExecutionDialog
|
||||
v-if="node.type === 'procedure' && node.connectionId && node.database"
|
||||
v-model:open="showProcedureExecutionConfirm"
|
||||
|
||||
@@ -938,7 +938,12 @@ export default {
|
||||
editView: "Edit View",
|
||||
viewSource: "View Source",
|
||||
viewDdl: "View DDL",
|
||||
dropObject: "Drop Object",
|
||||
dropView: "Drop View",
|
||||
dropColumn: "Drop Column",
|
||||
dropIndex: "Drop Index",
|
||||
dropForeignKey: "Drop Foreign Key",
|
||||
dropTrigger: "Drop Trigger",
|
||||
executeProcedure: "Execute Procedure",
|
||||
confirmExecuteProcedureTitle: "Execute Procedure",
|
||||
confirmExecuteProcedureMessage: 'Execute procedure "{name}"? You can fill or adjust parameter values first.',
|
||||
@@ -965,6 +970,13 @@ export default {
|
||||
dropFunction: "Drop Function",
|
||||
confirmDropViewTitle: "Drop View",
|
||||
confirmDropViewMessage: 'Are you sure you want to drop view "{name}"?',
|
||||
confirmDropObjectTitle: "Drop Object",
|
||||
confirmDropObjectMessage: 'Are you sure you want to drop "{name}"?',
|
||||
confirmDropColumnTitle: "Drop Column",
|
||||
confirmDropIndexTitle: "Drop Index",
|
||||
confirmDropForeignKeyTitle: "Drop Foreign Key",
|
||||
confirmDropTriggerTitle: "Drop Trigger",
|
||||
confirmDropTableChildObjectMessage: 'Are you sure you want to drop "{name}" from "{table}"?',
|
||||
confirmDropProcedureTitle: "Drop Procedure",
|
||||
confirmDropProcedureMessage: 'Are you sure you want to drop procedure "{name}"?',
|
||||
confirmDropFunctionTitle: "Drop Function",
|
||||
@@ -972,6 +984,7 @@ export default {
|
||||
dropViewSuccess: 'View "{name}" dropped',
|
||||
dropProcedureSuccess: 'Procedure "{name}" dropped',
|
||||
dropFunctionSuccess: 'Function "{name}" dropped',
|
||||
dropTableChildObjectSuccess: '"{name}" dropped',
|
||||
emptyTableSuccess: 'All data deleted from "{name}"',
|
||||
truncateTableSuccess: 'Table "{name}" truncated',
|
||||
duplicateStructureSuccess: 'Table structure duplicated as "{name}"',
|
||||
|
||||
@@ -830,7 +830,12 @@ export default {
|
||||
editView: "Editar vista",
|
||||
viewSource: "Ver código fuente",
|
||||
viewDdl: "Ver DDL",
|
||||
dropObject: "Eliminar objeto",
|
||||
dropView: "Eliminar vista",
|
||||
dropColumn: "Eliminar columna",
|
||||
dropIndex: "Eliminar índice",
|
||||
dropForeignKey: "Eliminar clave foránea",
|
||||
dropTrigger: "Eliminar disparador",
|
||||
executeProcedure: "Ejecutar procedimiento",
|
||||
confirmExecuteProcedureTitle: "Ejecutar procedimiento",
|
||||
confirmExecuteProcedureMessage:
|
||||
@@ -858,6 +863,13 @@ export default {
|
||||
dropFunction: "Eliminar función",
|
||||
confirmDropViewTitle: "Eliminar vista",
|
||||
confirmDropViewMessage: '¿Seguro que deseas eliminar la vista "{name}"?',
|
||||
confirmDropObjectTitle: "Eliminar objeto",
|
||||
confirmDropObjectMessage: '¿Seguro que deseas eliminar "{name}"?',
|
||||
confirmDropColumnTitle: "Eliminar columna",
|
||||
confirmDropIndexTitle: "Eliminar índice",
|
||||
confirmDropForeignKeyTitle: "Eliminar clave foránea",
|
||||
confirmDropTriggerTitle: "Eliminar disparador",
|
||||
confirmDropTableChildObjectMessage: '¿Seguro que deseas eliminar "{name}" de "{table}"?',
|
||||
confirmDropProcedureTitle: "Eliminar procedimiento",
|
||||
confirmDropProcedureMessage: '¿Seguro que deseas eliminar el procedimiento "{name}"?',
|
||||
confirmDropFunctionTitle: "Eliminar función",
|
||||
@@ -865,6 +877,7 @@ export default {
|
||||
dropViewSuccess: 'Vista "{name}" eliminada',
|
||||
dropProcedureSuccess: 'Procedimiento "{name}" eliminado',
|
||||
dropFunctionSuccess: 'Función "{name}" eliminada',
|
||||
dropTableChildObjectSuccess: '"{name}" eliminado',
|
||||
emptyTableSuccess: 'Todos los datos eliminados de "{name}"',
|
||||
truncateTableSuccess: 'Tabla "{name}" truncada',
|
||||
duplicateStructureSuccess: 'Estructura de tabla duplicada como "{name}"',
|
||||
|
||||
@@ -918,7 +918,12 @@ export default {
|
||||
editView: "编辑视图",
|
||||
viewSource: "查看源码",
|
||||
viewDdl: "查看 DDL",
|
||||
dropObject: "删除对象",
|
||||
dropView: "删除视图",
|
||||
dropColumn: "删除字段",
|
||||
dropIndex: "删除索引",
|
||||
dropForeignKey: "删除外键",
|
||||
dropTrigger: "删除触发器",
|
||||
executeProcedure: "执行过程",
|
||||
confirmExecuteProcedureTitle: "执行存储过程",
|
||||
confirmExecuteProcedureMessage: "确认执行存储过程「{name}」?可先补充或调整参数值。",
|
||||
@@ -943,6 +948,13 @@ export default {
|
||||
dropFunction: "删除函数",
|
||||
confirmDropViewTitle: "删除视图",
|
||||
confirmDropViewMessage: "确定要删除视图「{name}」吗?",
|
||||
confirmDropObjectTitle: "删除对象",
|
||||
confirmDropObjectMessage: "确定要删除「{name}」吗?",
|
||||
confirmDropColumnTitle: "删除字段",
|
||||
confirmDropIndexTitle: "删除索引",
|
||||
confirmDropForeignKeyTitle: "删除外键",
|
||||
confirmDropTriggerTitle: "删除触发器",
|
||||
confirmDropTableChildObjectMessage: "确定要从「{table}」删除「{name}」吗?",
|
||||
confirmDropProcedureTitle: "删除存储过程",
|
||||
confirmDropProcedureMessage: "确定要删除存储过程「{name}」吗?",
|
||||
confirmDropFunctionTitle: "删除函数",
|
||||
@@ -950,6 +962,7 @@ export default {
|
||||
dropViewSuccess: "视图「{name}」已删除",
|
||||
dropProcedureSuccess: "存储过程「{name}」已删除",
|
||||
dropFunctionSuccess: "函数「{name}」已删除",
|
||||
dropTableChildObjectSuccess: "「{name}」已删除",
|
||||
emptyTableSuccess: "已清空「{name}」的所有数据",
|
||||
truncateTableSuccess: "表「{name}」已截断",
|
||||
duplicateStructureSuccess: "已复制表结构为「{name}」",
|
||||
|
||||
@@ -918,7 +918,12 @@ export default {
|
||||
editView: "編輯檢視",
|
||||
viewSource: "檢視原始碼",
|
||||
viewDdl: "檢視 DDL",
|
||||
dropObject: "刪除物件",
|
||||
dropView: "刪除檢視",
|
||||
dropColumn: "刪除欄位",
|
||||
dropIndex: "刪除索引",
|
||||
dropForeignKey: "刪除外鍵",
|
||||
dropTrigger: "刪除觸發器",
|
||||
executeProcedure: "執行預存程序",
|
||||
confirmExecuteProcedureTitle: "執行預存程序",
|
||||
confirmExecuteProcedureMessage: "確認執行預存程序「{name}」?可先補充或調整參數值。",
|
||||
@@ -943,6 +948,13 @@ export default {
|
||||
dropFunction: "刪除函式",
|
||||
confirmDropViewTitle: "刪除檢視",
|
||||
confirmDropViewMessage: "確定要刪除檢視「{name}」嗎?",
|
||||
confirmDropObjectTitle: "刪除物件",
|
||||
confirmDropObjectMessage: "確定要刪除「{name}」嗎?",
|
||||
confirmDropColumnTitle: "刪除欄位",
|
||||
confirmDropIndexTitle: "刪除索引",
|
||||
confirmDropForeignKeyTitle: "刪除外鍵",
|
||||
confirmDropTriggerTitle: "刪除觸發器",
|
||||
confirmDropTableChildObjectMessage: "確定要從「{table}」刪除「{name}」嗎?",
|
||||
confirmDropProcedureTitle: "刪除預存程序",
|
||||
confirmDropProcedureMessage: "確定要刪除預存程序「{name}」嗎?",
|
||||
confirmDropFunctionTitle: "刪除函式",
|
||||
@@ -950,6 +962,7 @@ export default {
|
||||
dropViewSuccess: "檢視「{name}」已刪除",
|
||||
dropProcedureSuccess: "預存程序「{name}」已刪除",
|
||||
dropFunctionSuccess: "函式「{name}」已刪除",
|
||||
dropTableChildObjectSuccess: "「{name}」已刪除",
|
||||
emptyTableSuccess: "已清空「{name}」的所有資料",
|
||||
truncateTableSuccess: "資料表「{name}」已截斷",
|
||||
duplicateStructureSuccess: "已複製資料表結構為「{name}」",
|
||||
|
||||
@@ -106,6 +106,7 @@ export const buildCreateDatabaseSql = forward("buildCreateDatabaseSql");
|
||||
export const buildDuckDbAttachDatabaseSql = forward("buildDuckDbAttachDatabaseSql");
|
||||
export const buildDropObjectSql = forward("buildDropObjectSql");
|
||||
export const buildDropTableSql = forward("buildDropTableSql");
|
||||
export const buildDropTableChildObjectSql = forward("buildDropTableChildObjectSql");
|
||||
export const buildEmptyTableSql = forward("buildEmptyTableSql");
|
||||
export const buildTruncateTableSql = forward("buildTruncateTableSql");
|
||||
export const buildDropDatabaseSql = forward("buildDropDatabaseSql");
|
||||
|
||||
@@ -14,6 +14,16 @@ export interface TableAdminSqlOptions {
|
||||
tableName: string;
|
||||
}
|
||||
|
||||
export type TableChildObjectType = "COLUMN" | "INDEX" | "FOREIGN_KEY" | "TRIGGER";
|
||||
|
||||
export interface DropTableChildObjectSqlOptions {
|
||||
databaseType?: DatabaseType;
|
||||
objectType: TableChildObjectType;
|
||||
schema?: string | null;
|
||||
tableName: string;
|
||||
name: string;
|
||||
}
|
||||
|
||||
export interface DatabaseNameSqlOptions {
|
||||
databaseType?: DatabaseType;
|
||||
name: string;
|
||||
@@ -39,6 +49,10 @@ export function buildDropTableSql(options: TableAdminSqlOptions): Promise<string
|
||||
return api.buildDropTableSql(options);
|
||||
}
|
||||
|
||||
export function buildDropTableChildObjectSql(options: DropTableChildObjectSqlOptions): Promise<string> {
|
||||
return api.buildDropTableChildObjectSql(options);
|
||||
}
|
||||
|
||||
export function buildEmptyTableSql(options: TableAdminSqlOptions): Promise<string> {
|
||||
return api.buildEmptyTableSql(options);
|
||||
}
|
||||
|
||||
@@ -81,6 +81,7 @@ import type { BuildRenameObjectSqlOptions } from "@/lib/objectRenameSql";
|
||||
import type { CreateDatabaseSqlOptions } from "@/lib/createDatabaseSql";
|
||||
import type {
|
||||
DatabaseNameSqlOptions,
|
||||
DropTableChildObjectSqlOptions,
|
||||
DropObjectSqlOptions,
|
||||
DuplicateTableStructureSqlOptions,
|
||||
SchemaNameSqlOptions,
|
||||
@@ -588,6 +589,10 @@ export async function buildDropTableSql(options: TableAdminSqlOptions): Promise<
|
||||
return post("/api/query/build-drop-table-sql", { options });
|
||||
}
|
||||
|
||||
export async function buildDropTableChildObjectSql(options: DropTableChildObjectSqlOptions): Promise<string> {
|
||||
return post("/api/query/build-drop-table-child-object-sql", { options });
|
||||
}
|
||||
|
||||
export async function buildEmptyTableSql(options: TableAdminSqlOptions): Promise<string> {
|
||||
return post("/api/query/build-empty-table-sql", { options });
|
||||
}
|
||||
|
||||
@@ -54,6 +54,7 @@ import type { BuildRenameObjectSqlOptions } from "@/lib/objectRenameSql";
|
||||
import type { CreateDatabaseSqlOptions } from "@/lib/createDatabaseSql";
|
||||
import type {
|
||||
DatabaseNameSqlOptions,
|
||||
DropTableChildObjectSqlOptions,
|
||||
DropObjectSqlOptions,
|
||||
DuplicateTableStructureSqlOptions,
|
||||
SchemaNameSqlOptions,
|
||||
@@ -580,6 +581,10 @@ export async function buildDropTableSql(options: TableAdminSqlOptions): Promise<
|
||||
return invoke("build_drop_table_sql", { options });
|
||||
}
|
||||
|
||||
export async function buildDropTableChildObjectSql(options: DropTableChildObjectSqlOptions): Promise<string> {
|
||||
return invoke("build_drop_table_child_object_sql", { options });
|
||||
}
|
||||
|
||||
export async function buildEmptyTableSql(options: TableAdminSqlOptions): Promise<string> {
|
||||
return invoke("build_empty_table_sql", { options });
|
||||
}
|
||||
|
||||
@@ -1170,6 +1170,7 @@ export const useConnectionStore = defineStore("connection", () => {
|
||||
connectionId,
|
||||
database,
|
||||
schema,
|
||||
tableName: table,
|
||||
meta: idx,
|
||||
})),
|
||||
);
|
||||
@@ -1210,6 +1211,7 @@ export const useConnectionStore = defineStore("connection", () => {
|
||||
connectionId,
|
||||
database,
|
||||
schema,
|
||||
tableName: table,
|
||||
meta: fk,
|
||||
})),
|
||||
);
|
||||
@@ -1244,6 +1246,7 @@ export const useConnectionStore = defineStore("connection", () => {
|
||||
connectionId,
|
||||
database,
|
||||
schema,
|
||||
tableName: table,
|
||||
meta: tr,
|
||||
})),
|
||||
);
|
||||
|
||||
Reference in new issue
Block a user