feat(oracle): expand package members in schema tree

This commit is contained in:
t8y2 committed 2026-08-10 18:15:47 +08:00
1 parent ad9075e18f
commit 585e2f3c50
12 files changed
+508 -75

No files matched your search

@@ -1,5 +1,5 @@
import { describe, expect, it } from "vitest";
import { normalizeSidebarObjectKind, sidebarObjectKindsForDatabase } from "@/lib/database/databaseObjectCapabilities";
import { normalizeSidebarObjectKind, sidebarObjectKindsForDatabase, supportsPackageMemberExpansion } from "@/lib/database/databaseObjectCapabilities";
describe("databaseObjectCapabilities", () => {
it("exposes supported programmable objects for Dameng", () => {
@@ -11,6 +11,13 @@ describe("databaseObjectCapabilities", () => {
expect(sidebarObjectKindsForDatabase("postgres")).not.toContain("SYNONYM");
});
it("expands package members only for implemented database paths", () => {
expect(supportsPackageMemberExpansion("oracle")).toBe(true);
expect(supportsPackageMemberExpansion("xugu")).toBe(true);
expect(supportsPackageMemberExpansion("dameng")).toBe(false);
expect(supportsPackageMemberExpansion("opengauss")).toBe(false);
});
it("exposes only tables for HBase namespaces", () => {
expect(sidebarObjectKindsForDatabase("hbase")).toEqual(["TABLE"]);
});
@@ -1,6 +1,6 @@
import { describe, expect, it } from "vitest";
import type { CompletionAssistantCandidate, TreeNode } from "@/types/database";
import { buildXuguPackageMemberNodes, markXuguPackageNodesExpandable } from "@/lib/sidebar/xuguPackageMembers";
import { buildPackageMemberNodes, markPackageNodesExpandable } from "@/lib/sidebar/packageMembers";
function packageNode(): TreeNode {
return {
@@ -15,10 +15,10 @@ function packageNode(): TreeNode {
};
}
describe("Xugu package member tree", () => {
describe("package member tree", () => {
it("marks package specifications as expandable without changing other objects", () => {
const nodes: TreeNode[] = [packageNode(), { id: "body", label: "business_api", type: "package-body" }, { id: "proc", label: "standalone", type: "procedure" }];
const result = markXuguPackageNodesExpandable(nodes);
const result = markPackageNodesExpandable(nodes);
expect(result[0]?.children).toEqual([]);
expect(result[1]?.children).toBeUndefined();
@@ -32,7 +32,7 @@ describe("Xugu package member tree", () => {
{ name: "lookup", kind: "function", signature: null, data_type: "VARCHAR" },
{ name: "ignored_table", kind: "table" },
];
const result = buildXuguPackageMemberNodes(packageNode(), candidates);
const result = buildPackageMemberNodes(packageNode(), candidates);
expect(result.map((node) => [node.type, node.label])).toEqual([
["procedure", "calculate(p_value IN INT)"],
@@ -50,7 +50,7 @@ describe("Xugu package member tree", () => {
{ name: "MIXEDCASE", kind: "function", signature: "p INT" },
{ name: "", kind: "procedure" },
];
const result = buildXuguPackageMemberNodes(packageNode(), candidates);
const result = buildPackageMemberNodes(packageNode(), candidates);
expect(result.map((node) => node.objectName)).toEqual(["MixedCase", "MIXEDCASE"]);
});
@@ -18,6 +18,7 @@ const POSTGRES_LIKE_OBJECTS: SidebarObjectKind[] = ["TABLE", "VIEW", "MATERIALIZ
const ORACLE_OBJECTS: SidebarObjectKind[] = ["TABLE", "VIEW", "MATERIALIZED_VIEW", "PROCEDURE", "FUNCTION", "PACKAGE", "PACKAGE_BODY"];
const DAMENG_OBJECTS: SidebarObjectKind[] = ["TABLE", "VIEW", "MATERIALIZED_VIEW", "PROCEDURE", "FUNCTION", "SEQUENCE", "PACKAGE", "PACKAGE_BODY"];
const XUGU_OBJECTS: SidebarObjectKind[] = ["TABLE", "VIEW", "PROCEDURE", "FUNCTION", "TRIGGER", "SEQUENCE", "SYNONYM", "PACKAGE", "PACKAGE_BODY", "TYPE", "TYPE_BODY"];
const PACKAGE_MEMBER_EXPANSION_DATABASES = new Set<DatabaseType>(["oracle", "xugu"]);
const DATABASE_TYPE_OBJECTS = new Map<DatabaseType, SidebarObjectKind[]>([
// postgres
@@ -82,6 +83,10 @@ export function sidebarObjectKindsForDatabase(dbType?: DatabaseType): SidebarObj
return DATABASE_TYPE_OBJECTS.get(dbType) ?? [...ROUTINE_OBJECTS];
}
export function supportsPackageMemberExpansion(dbType?: DatabaseType): boolean {
return !!dbType && PACKAGE_MEMBER_EXPANSION_DATABASES.has(dbType);
}
export function normalizeSidebarObjectKind(type: string): SidebarObjectKind {
const value = type.toUpperCase();
const normalized = value.replace(/[\s-]+/g, "_");
@@ -1,10 +1,10 @@
import type { CompletionAssistantCandidate, TreeNode } from "@/types/database";
export function markXuguPackageNodesExpandable(nodes: TreeNode[]): TreeNode[] {
export function markPackageNodesExpandable(nodes: TreeNode[]): TreeNode[] {
return nodes.map((node) => (node.type === "package" ? { ...node, children: node.children ?? [] } : node));
}
export function buildXuguPackageMemberNodes(packageNode: TreeNode, candidates: readonly CompletionAssistantCandidate[]): TreeNode[] {
export function buildPackageMemberNodes(packageNode: TreeNode, candidates: readonly CompletionAssistantCandidate[]): TreeNode[] {
const parentName = packageNode.objectName || packageNode.label;
const parentSchema = packageNode.schema;
const seen = new Set<string>();