feat: support Oracle package sources
This commit is contained in:
1 parent
76378f3a65
commit
7eca75b325
22 files changed
+429
-36
No files matched your search
@@ -24,6 +24,7 @@ import {
|
||||
PencilLine,
|
||||
PencilRuler,
|
||||
Play,
|
||||
Package,
|
||||
RefreshCw,
|
||||
Scissors,
|
||||
Search,
|
||||
@@ -89,7 +90,7 @@ import {
|
||||
type ObjectBrowserSortKey,
|
||||
} from "@/lib/objectBrowserRows";
|
||||
|
||||
type ObjectFilter = "all" | "tables" | "views" | "procedures" | "functions";
|
||||
type ObjectFilter = "all" | "tables" | "views" | "procedures" | "functions" | "packages";
|
||||
|
||||
const props = defineProps<{
|
||||
connection: ConnectionConfig;
|
||||
@@ -158,6 +159,9 @@ const tableCount = computed(() => rows.value.filter((row) => row.type === "TABLE
|
||||
const viewCount = computed(() => rows.value.filter((row) => row.type === "VIEW").length);
|
||||
const procedureCount = computed(() => rows.value.filter((row) => row.type === "PROCEDURE").length);
|
||||
const functionCount = computed(() => rows.value.filter((row) => row.type === "FUNCTION").length);
|
||||
const packageCount = computed(
|
||||
() => rows.value.filter((row) => row.type === "PACKAGE" || row.type === "PACKAGE_BODY").length,
|
||||
);
|
||||
const canOpenStructureEditor = computed(() => supportsTableStructureEditing(props.connection.db_type));
|
||||
const canOpenDiagram = computed(() => !!props.database && supportsSchemaDiagram(props.connection.db_type));
|
||||
const canOpenTableImport = computed(() => !!props.database && supportsTableImport(props.connection.db_type));
|
||||
@@ -186,6 +190,7 @@ const objectFilters = computed<ObjectFilter[]>(() =>
|
||||
["views", viewCount.value],
|
||||
["procedures", procedureCount.value],
|
||||
["functions", functionCount.value],
|
||||
["packages", packageCount.value],
|
||||
] as Array<[ObjectFilter, number]>
|
||||
)
|
||||
.filter(([filter, count]) => filter === "all" || count > 0)
|
||||
@@ -230,6 +235,7 @@ function iconFor(row: ObjectBrowserRow) {
|
||||
if (row.type === "VIEW") return Eye;
|
||||
if (row.type === "PROCEDURE") return ScrollText;
|
||||
if (row.type === "FUNCTION") return Braces;
|
||||
if (row.type === "PACKAGE" || row.type === "PACKAGE_BODY") return Package;
|
||||
return Table2;
|
||||
}
|
||||
|
||||
@@ -237,6 +243,8 @@ function typeLabel(type: ObjectBrowserRow["type"]) {
|
||||
if (type === "VIEW") return t("objects.view");
|
||||
if (type === "PROCEDURE") return t("objects.procedure");
|
||||
if (type === "FUNCTION") return t("objects.function");
|
||||
if (type === "PACKAGE") return t("objects.package");
|
||||
if (type === "PACKAGE_BODY") return t("objects.packageBody");
|
||||
return t("objects.table");
|
||||
}
|
||||
|
||||
@@ -259,6 +267,7 @@ function rowMatchesObjectFilter(row: ObjectBrowserRow) {
|
||||
if (objectFilter.value === "views") return row.type === "VIEW";
|
||||
if (objectFilter.value === "procedures") return row.type === "PROCEDURE";
|
||||
if (objectFilter.value === "functions") return row.type === "FUNCTION";
|
||||
if (objectFilter.value === "packages") return row.type === "PACKAGE" || row.type === "PACKAGE_BODY";
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -298,6 +307,7 @@ function iconClass(type: ObjectBrowserRow["type"]) {
|
||||
if (type === "VIEW") return "text-purple-500";
|
||||
if (type === "PROCEDURE") return "text-blue-500";
|
||||
if (type === "FUNCTION") return "text-amber-500";
|
||||
if (type === "PACKAGE" || type === "PACKAGE_BODY") return "text-cyan-500";
|
||||
return "text-green-500";
|
||||
}
|
||||
|
||||
@@ -314,7 +324,13 @@ function togglePartitionParent(row: ObjectBrowserRow) {
|
||||
}
|
||||
|
||||
function canOpenSource(row: ObjectBrowserRow) {
|
||||
return row.type === "VIEW" || row.type === "PROCEDURE" || row.type === "FUNCTION";
|
||||
return (
|
||||
row.type === "VIEW" ||
|
||||
row.type === "PROCEDURE" ||
|
||||
row.type === "FUNCTION" ||
|
||||
row.type === "PACKAGE" ||
|
||||
row.type === "PACKAGE_BODY"
|
||||
);
|
||||
}
|
||||
|
||||
function canRename(row: ObjectBrowserRow) {
|
||||
@@ -1063,6 +1079,7 @@ function filterCount(filter: ObjectFilter) {
|
||||
if (filter === "views") return viewCount.value;
|
||||
if (filter === "procedures") return procedureCount.value;
|
||||
if (filter === "functions") return functionCount.value;
|
||||
if (filter === "packages") return packageCount.value;
|
||||
return rows.value.length;
|
||||
}
|
||||
|
||||
@@ -1076,7 +1093,9 @@ function filterLabel(filter: ObjectFilter) {
|
||||
? "objects.procedures"
|
||||
: filter === "functions"
|
||||
? "objects.functions"
|
||||
: "objects.all";
|
||||
: filter === "packages"
|
||||
? "objects.packages"
|
||||
: "objects.all";
|
||||
return `${t(key)} ${filterCount(filter)}`;
|
||||
}
|
||||
|
||||
@@ -1224,9 +1243,18 @@ function getProcFuncMenuItems(item: ObjectBrowserRow): ContextMenuItem[] {
|
||||
];
|
||||
}
|
||||
|
||||
function getPackageMenuItems(item: ObjectBrowserRow): ContextMenuItem[] {
|
||||
return [
|
||||
{ label: t("contextMenu.viewSource"), action: () => openSource(item), icon: Code2 },
|
||||
{ label: "", separator: true },
|
||||
{ label: t("contextMenu.copyName"), action: () => copyName(item), icon: Copy },
|
||||
];
|
||||
}
|
||||
|
||||
function getObjectBrowserMenuItems(item: ObjectBrowserRow): ContextMenuItem[] {
|
||||
if (item.type === "TABLE") return getTableMenuItems(item);
|
||||
if (item.type === "VIEW") return getViewMenuItems(item);
|
||||
if (item.type === "PACKAGE" || item.type === "PACKAGE_BODY") return getPackageMenuItems(item);
|
||||
return getProcFuncMenuItems(item);
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -45,6 +45,7 @@ import {
|
||||
Braces,
|
||||
Code2,
|
||||
ListFilter,
|
||||
Package,
|
||||
} from "lucide-vue-next";
|
||||
import CustomContextMenu, { type ContextMenuItem } from "@/components/ui/CustomContextMenu.vue";
|
||||
import { useConnectionStore } from "@/stores/connectionStore";
|
||||
@@ -223,6 +224,10 @@ function getIconInfo(node: TreeNode): { icon: any; colorClass: string } | null {
|
||||
return { icon: ScrollText, colorClass: "text-blue-500" };
|
||||
case "function":
|
||||
return { icon: Braces, colorClass: "text-amber-500" };
|
||||
case "package":
|
||||
return { icon: Package, colorClass: "text-cyan-500" };
|
||||
case "package-body":
|
||||
return { icon: FileCode, colorClass: "text-cyan-400" };
|
||||
case "group-tables":
|
||||
return { icon: Table, colorClass: "text-green-500" };
|
||||
case "group-views":
|
||||
@@ -231,6 +236,8 @@ function getIconInfo(node: TreeNode): { icon: any; colorClass: string } | null {
|
||||
return { icon: ScrollText, colorClass: "text-blue-500" };
|
||||
case "group-functions":
|
||||
return { icon: Braces, colorClass: "text-amber-500" };
|
||||
case "group-packages":
|
||||
return { icon: Package, colorClass: "text-cyan-500" };
|
||||
case "group-partitions":
|
||||
return { icon: node.isExpanded ? FolderOpen : FolderClosed, colorClass: "text-green-400" };
|
||||
default:
|
||||
@@ -247,6 +254,7 @@ const groupTypes: Set<TreeNodeType> = new Set([
|
||||
"group-views",
|
||||
"group-procedures",
|
||||
"group-functions",
|
||||
"group-packages",
|
||||
"group-partitions",
|
||||
"saved-sql-root",
|
||||
"saved-sql-folder",
|
||||
@@ -307,6 +315,7 @@ async function toggle() {
|
||||
node.type === "group-views" ||
|
||||
node.type === "group-procedures" ||
|
||||
node.type === "group-functions" ||
|
||||
node.type === "group-packages" ||
|
||||
node.type === "group-partitions"
|
||||
) {
|
||||
node.isExpanded = !node.isExpanded;
|
||||
@@ -400,7 +409,12 @@ function runRowClickAction() {
|
||||
const action = treeNodeRowAction(node.type, canExpand.value, settingsStore.editorSettings.sidebarActivation);
|
||||
if (action === "open-data") {
|
||||
openData();
|
||||
} else if (node.type === "procedure" || node.type === "function") {
|
||||
} else if (
|
||||
node.type === "procedure" ||
|
||||
node.type === "function" ||
|
||||
node.type === "package" ||
|
||||
node.type === "package-body"
|
||||
) {
|
||||
void viewObjectSource();
|
||||
} else if (node.type === "saved-sql-file") {
|
||||
openSavedSqlFile();
|
||||
@@ -1628,6 +1642,8 @@ const hasTypeMenu = computed(() => {
|
||||
t === "column" ||
|
||||
t === "procedure" ||
|
||||
t === "function" ||
|
||||
t === "package" ||
|
||||
t === "package-body" ||
|
||||
t === "saved-sql-root" ||
|
||||
t === "saved-sql-folder" ||
|
||||
t === "saved-sql-file" ||
|
||||
@@ -2224,7 +2240,7 @@ function treeItemMenuItems(): ContextMenuItem[] {
|
||||
return items;
|
||||
}
|
||||
|
||||
// 8. Procedure / Function
|
||||
// 8. Procedure / Function / Package
|
||||
if (node.type === "procedure" || node.type === "function") {
|
||||
if (node.type === "procedure") {
|
||||
items.push({ label: t("contextMenu.executeProcedure"), action: openProcedureExecution, icon: Play });
|
||||
@@ -2243,6 +2259,13 @@ function treeItemMenuItems(): ContextMenuItem[] {
|
||||
return items;
|
||||
}
|
||||
|
||||
if (node.type === "package" || node.type === "package-body") {
|
||||
items.push({ label: t("contextMenu.viewSource"), action: viewObjectSource, icon: Code2 });
|
||||
items.push({ label: "", separator: true });
|
||||
items.push({ label: t("contextMenu.copyName"), action: copyName, icon: Copy });
|
||||
return items;
|
||||
}
|
||||
|
||||
// 9. Group Labels (saved-sql-root, saved-sql-folder, group-columns, etc.)
|
||||
if (isGroupLabel(node)) {
|
||||
if (node.type === "saved-sql-root") {
|
||||
@@ -2369,6 +2392,7 @@ function treeItemMenuItems(): ContextMenuItem[] {
|
||||
node.type === 'group-views' ||
|
||||
node.type === 'group-procedures' ||
|
||||
node.type === 'group-functions' ||
|
||||
node.type === 'group-packages' ||
|
||||
node.type === 'group-partitions') &&
|
||||
node.objectCount != null
|
||||
"
|
||||
|
||||
@@ -1017,6 +1017,7 @@ export default {
|
||||
views: "Views",
|
||||
procedures: "Procedures",
|
||||
functions: "Functions",
|
||||
packages: "Packages",
|
||||
partitions: "Partitions",
|
||||
objectBrowser: "Browse in Object Browser ({count})",
|
||||
},
|
||||
@@ -1026,11 +1027,14 @@ export default {
|
||||
views: "Views",
|
||||
procedures: "Procedures",
|
||||
functions: "Functions",
|
||||
packages: "Packages",
|
||||
table: "Table",
|
||||
partitions: "{count} partitions",
|
||||
view: "View",
|
||||
procedure: "Procedure",
|
||||
function: "Function",
|
||||
package: "Package",
|
||||
packageBody: "Package Body",
|
||||
name: "Name",
|
||||
type: "Type",
|
||||
createdAt: "Created",
|
||||
|
||||
@@ -911,6 +911,7 @@ export default {
|
||||
views: "Vistas",
|
||||
procedures: "Procedimientos",
|
||||
functions: "Funciones",
|
||||
packages: "Paquetes",
|
||||
partitions: "Particiones",
|
||||
objectBrowser: "Explorar en el navegador de objetos ({count})",
|
||||
},
|
||||
@@ -920,11 +921,14 @@ export default {
|
||||
views: "Vistas",
|
||||
procedures: "Procedimientos",
|
||||
functions: "Funciones",
|
||||
packages: "Paquetes",
|
||||
table: "Tabla",
|
||||
partitions: "{count} particiones",
|
||||
view: "Vista",
|
||||
procedure: "Procedimiento",
|
||||
function: "Función",
|
||||
package: "Paquete",
|
||||
packageBody: "Cuerpo del paquete",
|
||||
name: "Nombre",
|
||||
type: "Tipo",
|
||||
createdAt: "Creado",
|
||||
|
||||
@@ -993,6 +993,7 @@ export default {
|
||||
views: "视图",
|
||||
procedures: "存储过程",
|
||||
functions: "函数",
|
||||
packages: "包",
|
||||
partitions: "分区",
|
||||
objectBrowser: "在对象浏览器中查看 ({count})",
|
||||
},
|
||||
@@ -1002,11 +1003,14 @@ export default {
|
||||
views: "视图",
|
||||
procedures: "存储过程",
|
||||
functions: "函数",
|
||||
packages: "包",
|
||||
table: "表",
|
||||
partitions: "{count} 个分区",
|
||||
view: "视图",
|
||||
procedure: "存储过程",
|
||||
function: "函数",
|
||||
package: "包",
|
||||
packageBody: "包体",
|
||||
name: "名称",
|
||||
type: "类型",
|
||||
createdAt: "创建时间",
|
||||
|
||||
@@ -993,6 +993,7 @@ export default {
|
||||
views: "檢視",
|
||||
procedures: "預存程序",
|
||||
functions: "函式",
|
||||
packages: "套件",
|
||||
partitions: "分割區",
|
||||
objectBrowser: "在物件瀏覽器中檢視 ({count})",
|
||||
},
|
||||
@@ -1002,11 +1003,14 @@ export default {
|
||||
views: "檢視",
|
||||
procedures: "預存程序",
|
||||
functions: "函式",
|
||||
packages: "套件",
|
||||
table: "資料表",
|
||||
partitions: "{count} 個分割區",
|
||||
view: "檢視",
|
||||
procedure: "預存程序",
|
||||
function: "函式",
|
||||
package: "套件",
|
||||
packageBody: "套件主體",
|
||||
name: "名稱",
|
||||
type: "類型",
|
||||
createdAt: "建立時間",
|
||||
|
||||
@@ -6,7 +6,7 @@ export type ObjectBrowserRow = {
|
||||
id: string;
|
||||
name: string;
|
||||
schema?: string;
|
||||
type: "TABLE" | "VIEW" | "PROCEDURE" | "FUNCTION";
|
||||
type: "TABLE" | "VIEW" | "PROCEDURE" | "FUNCTION" | "PACKAGE" | "PACKAGE_BODY";
|
||||
comment?: string | null;
|
||||
created_at?: string | null;
|
||||
updated_at?: string | null;
|
||||
@@ -21,6 +21,8 @@ export type ObjectBrowserSortDirection = "asc" | "desc";
|
||||
|
||||
export function normalizeObjectBrowserType(type: string): ObjectBrowserRow["type"] {
|
||||
const value = type.toUpperCase();
|
||||
if (value.includes("PACKAGE BODY") || value.includes("PACKAGE_BODY")) return "PACKAGE_BODY";
|
||||
if (value.includes("PACKAGE")) return "PACKAGE";
|
||||
if (value.includes("VIEW")) return "VIEW";
|
||||
if (value.includes("PROC")) return "PROCEDURE";
|
||||
if (value.includes("FUNC")) return "FUNCTION";
|
||||
|
||||
@@ -7,6 +7,8 @@ const leafTypes: Set<TreeNodeType> = new Set([
|
||||
"trigger",
|
||||
"procedure",
|
||||
"function",
|
||||
"package",
|
||||
"package-body",
|
||||
"object-browser",
|
||||
"redis-db",
|
||||
"mongo-collection",
|
||||
|
||||
@@ -45,7 +45,7 @@ export function buildTableTreeNodes({
|
||||
|
||||
type TableTreeEntry = {
|
||||
key: string;
|
||||
objectType: "TABLE" | "VIEW" | "PROCEDURE" | "FUNCTION";
|
||||
objectType: DatabaseObjectTreeKind;
|
||||
schema?: string;
|
||||
parentSchema?: string;
|
||||
parentName?: string;
|
||||
@@ -70,7 +70,7 @@ function makeTableTreeEntry({
|
||||
schema?: string;
|
||||
includeSchemaInId?: boolean;
|
||||
name: string;
|
||||
objectType: "TABLE" | "VIEW" | "PROCEDURE" | "FUNCTION";
|
||||
objectType: DatabaseObjectTreeKind;
|
||||
comment?: string | null;
|
||||
parentSchema?: string | null;
|
||||
parentName?: string | null;
|
||||
@@ -267,6 +267,8 @@ export function hasTablePartitionGroups(node: TreeNode): boolean {
|
||||
return partitionGroupChildren(node).length > 0;
|
||||
}
|
||||
|
||||
type DatabaseObjectTreeKind = "TABLE" | "VIEW" | "PROCEDURE" | "FUNCTION" | "PACKAGE" | "PACKAGE_BODY";
|
||||
|
||||
function buildObjectTreeEntries({
|
||||
nodeId,
|
||||
connectionId,
|
||||
@@ -323,7 +325,8 @@ export function buildSimpleObjectTreeNodes({
|
||||
|
||||
for (const obj of objects) {
|
||||
const objectType = normalizeObjectType(obj.object_type);
|
||||
if (objectType !== "TABLE" && objectType !== "VIEW") continue;
|
||||
if (objectType !== "TABLE" && objectType !== "VIEW" && objectType !== "PACKAGE" && objectType !== "PACKAGE_BODY")
|
||||
continue;
|
||||
|
||||
const name = normalizeDatabaseObjectName(obj.name);
|
||||
if (!name) continue;
|
||||
@@ -346,8 +349,20 @@ export function buildSimpleObjectTreeNodes({
|
||||
});
|
||||
if (objectType === "TABLE") {
|
||||
tableEntries.push(entry);
|
||||
} else {
|
||||
} else if (objectType === "VIEW") {
|
||||
viewNodes.push(entry.node);
|
||||
} else {
|
||||
viewNodes.push({
|
||||
id: `${nodeId}:${childSchema ? `${childSchema}:` : ""}${name}:${objectType}`,
|
||||
label: name,
|
||||
type: objectType === "PACKAGE_BODY" ? "package-body" : "package",
|
||||
comment: obj.comment,
|
||||
connectionId,
|
||||
database,
|
||||
schema: childSchema,
|
||||
isExpanded: false,
|
||||
children: undefined,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -357,8 +372,10 @@ export function buildSimpleObjectTreeNodes({
|
||||
];
|
||||
}
|
||||
|
||||
function normalizeObjectType(type: string): "TABLE" | "VIEW" | "PROCEDURE" | "FUNCTION" {
|
||||
function normalizeObjectType(type: string): DatabaseObjectTreeKind {
|
||||
const v = type.toUpperCase();
|
||||
if (v.includes("PACKAGE BODY") || v.includes("PACKAGE_BODY")) return "PACKAGE_BODY";
|
||||
if (v.includes("PACKAGE")) return "PACKAGE";
|
||||
if (v.includes("VIEW")) return "VIEW";
|
||||
if (v.includes("PROC")) return "PROCEDURE";
|
||||
if (v.includes("FUNC")) return "FUNCTION";
|
||||
@@ -368,26 +385,33 @@ function normalizeObjectType(type: string): "TABLE" | "VIEW" | "PROCEDURE" | "FU
|
||||
const groupDefs: Array<{
|
||||
key: string;
|
||||
label: string;
|
||||
objectType: string;
|
||||
objectTypes: DatabaseObjectTreeKind[];
|
||||
nodeType: TreeNodeType;
|
||||
childType: TreeNodeType;
|
||||
childType: TreeNodeType | ((objectType: DatabaseObjectTreeKind) => TreeNodeType);
|
||||
}> = [
|
||||
{ key: "__tables", label: "tree.tables", objectType: "TABLE", nodeType: "group-tables", childType: "table" },
|
||||
{ key: "__views", label: "tree.views", objectType: "VIEW", nodeType: "group-views", childType: "view" },
|
||||
{ key: "__tables", label: "tree.tables", objectTypes: ["TABLE"], nodeType: "group-tables", childType: "table" },
|
||||
{ key: "__views", label: "tree.views", objectTypes: ["VIEW"], nodeType: "group-views", childType: "view" },
|
||||
{
|
||||
key: "__procedures",
|
||||
label: "tree.procedures",
|
||||
objectType: "PROCEDURE",
|
||||
objectTypes: ["PROCEDURE"],
|
||||
nodeType: "group-procedures",
|
||||
childType: "procedure",
|
||||
},
|
||||
{
|
||||
key: "__functions",
|
||||
label: "tree.functions",
|
||||
objectType: "FUNCTION",
|
||||
objectTypes: ["FUNCTION"],
|
||||
nodeType: "group-functions",
|
||||
childType: "function",
|
||||
},
|
||||
{
|
||||
key: "__packages",
|
||||
label: "tree.packages",
|
||||
objectTypes: ["PACKAGE", "PACKAGE_BODY"],
|
||||
nodeType: "group-packages",
|
||||
childType: (objectType) => (objectType === "PACKAGE_BODY" ? "package-body" : "package"),
|
||||
},
|
||||
];
|
||||
|
||||
const objectGroupNodeTypes = new Set<TreeNodeType>([
|
||||
@@ -395,6 +419,7 @@ const objectGroupNodeTypes = new Set<TreeNodeType>([
|
||||
"group-views",
|
||||
"group-procedures",
|
||||
"group-functions",
|
||||
"group-packages",
|
||||
]);
|
||||
|
||||
export function objectGroupRefreshParentId(node: TreeNode): string | null {
|
||||
@@ -434,9 +459,9 @@ export function buildGroupedObjectTreeNodes({
|
||||
|
||||
const groups: TreeNode[] = [];
|
||||
for (const def of groupDefs) {
|
||||
const items = buckets.get(def.objectType);
|
||||
const items = def.objectTypes.flatMap((objectType) => buckets.get(objectType) ?? []);
|
||||
if (!items?.length) continue;
|
||||
const isExpandable = def.childType === "table" || def.childType === "view";
|
||||
const isExpandable = def.nodeType === "group-tables" || def.nodeType === "group-views";
|
||||
const children = isExpandable
|
||||
? buildObjectTreeEntries({
|
||||
nodeId: `${nodeId}:${def.key}`,
|
||||
@@ -444,14 +469,17 @@ export function buildGroupedObjectTreeNodes({
|
||||
database,
|
||||
schema,
|
||||
objects: items,
|
||||
objectType: def.objectType as "TABLE" | "VIEW",
|
||||
objectType: def.objectTypes[0] as "TABLE" | "VIEW",
|
||||
})
|
||||
: sortDatabaseObjectsByPrefixPriority(items, (obj) => obj.name).map((obj) => {
|
||||
const childSchema = obj.schema ? normalizeDatabaseObjectName(obj.schema) : schema;
|
||||
const objectType = normalizeObjectType(obj.object_type);
|
||||
const childType = typeof def.childType === "function" ? def.childType(objectType) : def.childType;
|
||||
const objectTypeSuffix = objectType === "PACKAGE" || objectType === "PACKAGE_BODY" ? `:${objectType}` : "";
|
||||
return {
|
||||
id: `${nodeId}:${def.key}:${childSchema ? `${childSchema}:` : ""}${obj.name}`,
|
||||
id: `${nodeId}:${def.key}:${childSchema ? `${childSchema}:` : ""}${obj.name}${objectTypeSuffix}`,
|
||||
label: obj.name,
|
||||
type: def.childType,
|
||||
type: childType,
|
||||
comment: obj.comment,
|
||||
connectionId,
|
||||
database,
|
||||
|
||||
@@ -16,12 +16,14 @@ export type SidebarActivation = "single" | "double";
|
||||
const dataNodeTypes = new Set<TreeNodeType>(["table", "view"]);
|
||||
const toggleLeafNodeTypes = new Set<TreeNodeType>(["redis-db", "mongo-collection"]);
|
||||
const objectBrowserNodeTypes = new Set<TreeNodeType>(["database", "schema", "object-browser"]);
|
||||
const sourceNodeTypes = new Set<TreeNodeType>(["procedure", "function"]);
|
||||
const sourceNodeTypes = new Set<TreeNodeType>(["procedure", "function", "package", "package-body"]);
|
||||
|
||||
export function objectSourceKindForTreeNode(type: TreeNodeType): ObjectSourceKind | null {
|
||||
if (type === "view") return "VIEW";
|
||||
if (type === "procedure") return "PROCEDURE";
|
||||
if (type === "function") return "FUNCTION";
|
||||
if (type === "package") return "PACKAGE";
|
||||
if (type === "package-body") return "PACKAGE_BODY";
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
@@ -1321,6 +1321,7 @@ export const useConnectionStore = defineStore("connection", () => {
|
||||
node.type === "group-views" ||
|
||||
node.type === "group-procedures" ||
|
||||
node.type === "group-functions" ||
|
||||
node.type === "group-packages" ||
|
||||
node.type === "group-partitions"
|
||||
) {
|
||||
node.isExpanded = true;
|
||||
|
||||
@@ -172,7 +172,7 @@ export interface TableInfo {
|
||||
parent_name?: string | null;
|
||||
}
|
||||
|
||||
export type DatabaseObjectType = "TABLE" | "VIEW" | "PROCEDURE" | "FUNCTION";
|
||||
export type DatabaseObjectType = "TABLE" | "VIEW" | "PROCEDURE" | "FUNCTION" | "PACKAGE" | "PACKAGE_BODY";
|
||||
|
||||
export interface ObjectInfo {
|
||||
name: string;
|
||||
@@ -185,7 +185,7 @@ export interface ObjectInfo {
|
||||
parent_name?: string | null;
|
||||
}
|
||||
|
||||
export type ObjectSourceKind = "VIEW" | "PROCEDURE" | "FUNCTION";
|
||||
export type ObjectSourceKind = "VIEW" | "PROCEDURE" | "FUNCTION" | "PACKAGE" | "PACKAGE_BODY";
|
||||
|
||||
export interface ObjectSource {
|
||||
name: string;
|
||||
@@ -275,6 +275,8 @@ export type TreeNodeType =
|
||||
| "view"
|
||||
| "procedure"
|
||||
| "function"
|
||||
| "package"
|
||||
| "package-body"
|
||||
| "group-columns"
|
||||
| "group-indexes"
|
||||
| "group-fkeys"
|
||||
@@ -283,6 +285,7 @@ export type TreeNodeType =
|
||||
| "group-views"
|
||||
| "group-procedures"
|
||||
| "group-functions"
|
||||
| "group-packages"
|
||||
| "group-partitions"
|
||||
| "object-browser"
|
||||
| "saved-sql-root"
|
||||
|
||||
Reference in new issue
Block a user