feat(xugu): expose table child metadata
This commit is contained in:
1 parent
6ddfa8bd24
commit
0362fef273
33 files changed
+1269
-33
No files matched your search
@@ -158,6 +158,9 @@ export const listDataTypes = forward("listDataTypes");
|
||||
export const listIndexes = forward("listIndexes");
|
||||
export const listForeignKeys = forward("listForeignKeys");
|
||||
export const listTriggers = forward("listTriggers");
|
||||
export const listConstraints = forward("listConstraints");
|
||||
export const listPartitions = forward("listPartitions");
|
||||
export const listSubpartitions = forward("listSubpartitions");
|
||||
export const getTableDdl = forward("getTableDdl");
|
||||
export const listFunctions = forward("listFunctions");
|
||||
export const listSequences = forward("listSequences");
|
||||
|
||||
@@ -19,6 +19,9 @@ import type {
|
||||
IndexInfo,
|
||||
ForeignKeyInfo,
|
||||
TriggerInfo,
|
||||
ConstraintInfo,
|
||||
PartitionInfo,
|
||||
SubpartitionInfo,
|
||||
ExtensionInfo,
|
||||
FunctionInfo,
|
||||
SequenceInfo,
|
||||
@@ -685,6 +688,18 @@ export async function listTriggers(connectionId: string, database: string, schem
|
||||
return get(`/api/schema/triggers?${qs({ connection_id: connectionId, database, schema, table, catalog })}`);
|
||||
}
|
||||
|
||||
export async function listConstraints(connectionId: string, database: string, schema: string, table: string, catalog?: string): Promise<ConstraintInfo[]> {
|
||||
return get(`/api/schema/constraints?${qs({ connection_id: connectionId, database, schema, table, catalog })}`);
|
||||
}
|
||||
|
||||
export async function listPartitions(connectionId: string, database: string, schema: string, table: string, catalog?: string): Promise<PartitionInfo[]> {
|
||||
return get(`/api/schema/partitions?${qs({ connection_id: connectionId, database, schema, table, catalog })}`);
|
||||
}
|
||||
|
||||
export async function listSubpartitions(connectionId: string, database: string, schema: string, table: string, catalog?: string): Promise<SubpartitionInfo[]> {
|
||||
return get(`/api/schema/subpartitions?${qs({ connection_id: connectionId, database, schema, table, catalog })}`);
|
||||
}
|
||||
|
||||
export async function getTableDdl(connectionId: string, database: string, schema: string, table: string, objectType?: ObjectSourceKind, catalog?: string): Promise<string> {
|
||||
return get(`/api/schema/ddl?${qs({ connection_id: connectionId, database, schema, table, object_type: objectType, catalog })}`);
|
||||
}
|
||||
|
||||
@@ -22,6 +22,9 @@ import type {
|
||||
IndexInfo,
|
||||
ForeignKeyInfo,
|
||||
TriggerInfo,
|
||||
ConstraintInfo,
|
||||
PartitionInfo,
|
||||
SubpartitionInfo,
|
||||
FunctionInfo,
|
||||
SequenceInfo,
|
||||
RuleInfo,
|
||||
@@ -1177,6 +1180,18 @@ export async function listTriggers(connectionId: string, database: string, schem
|
||||
return invoke("list_triggers", { connectionId, database, schema, table, catalog });
|
||||
}
|
||||
|
||||
export async function listConstraints(connectionId: string, database: string, schema: string, table: string, catalog?: string): Promise<ConstraintInfo[]> {
|
||||
return invoke("list_constraints", { connectionId, database, schema, table, catalog });
|
||||
}
|
||||
|
||||
export async function listPartitions(connectionId: string, database: string, schema: string, table: string, catalog?: string): Promise<PartitionInfo[]> {
|
||||
return invoke("list_partitions", { connectionId, database, schema, table, catalog });
|
||||
}
|
||||
|
||||
export async function listSubpartitions(connectionId: string, database: string, schema: string, table: string, catalog?: string): Promise<SubpartitionInfo[]> {
|
||||
return invoke("list_subpartitions", { connectionId, database, schema, table, catalog });
|
||||
}
|
||||
|
||||
export async function getTableDdl(connectionId: string, database: string, schema: string, table: string, objectType?: ObjectSourceKind, catalog?: string): Promise<string> {
|
||||
return invoke("get_table_ddl", { connectionId, database, schema, table, objectType, catalog });
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
import { driverStoreFocusForInstallError } from "@/lib/connection/agentDriverInstallHint";
|
||||
import { driverStoreFocusForInstallError, hasInstalledAgentVersion } from "@/lib/connection/agentDriverInstallHint";
|
||||
|
||||
describe("driverStoreFocusForInstallError", () => {
|
||||
it("focuses the missing agent driver for driver-not-installed errors", () => {
|
||||
@@ -38,3 +38,11 @@ describe("driverStoreFocusForInstallError", () => {
|
||||
expect(driverStoreFocusForInstallError("No reachable ZooKeeper server within 2000ms: zk:2181", "zookeeper", undefined)).toBeNull();
|
||||
});
|
||||
});
|
||||
|
||||
describe("hasInstalledAgentVersion", () => {
|
||||
it("requires an installed Agent at or above the requested release", () => {
|
||||
expect(hasInstalledAgentVersion([{ db_type: "xugu", installed: true, installed_version: "0.1.23" }], "xugu", "0.1.23")).toBe(true);
|
||||
expect(hasInstalledAgentVersion([{ db_type: "xugu", installed: true, installed_version: "0.1.22" }], "xugu", "0.1.23")).toBe(false);
|
||||
expect(hasInstalledAgentVersion([{ db_type: "xugu", installed: true, installed_version: null }], "xugu", "0.1.23")).toBe(false);
|
||||
});
|
||||
});
|
||||
@@ -4,9 +4,25 @@ import { supportsDriverManagement } from "@/lib/database/databaseCapabilities";
|
||||
export interface AgentDriverInstallState {
|
||||
db_type: string;
|
||||
installed: boolean;
|
||||
installed_version?: string | null;
|
||||
update_available?: boolean;
|
||||
}
|
||||
|
||||
/** Returns whether a locally installed native Agent meets a required release. */
|
||||
export function hasInstalledAgentVersion(drivers: readonly AgentDriverInstallState[], driverKey: string, minimumVersion: string): boolean {
|
||||
const installedVersion = drivers.find((driver) => driver.db_type === driverKey && driver.installed)?.installed_version;
|
||||
if (!installedVersion) return false;
|
||||
|
||||
const parse = (version: string): number[] | null => {
|
||||
const match = version.trim().match(/^(\d+)\.(\d+)\.(\d+)$/);
|
||||
return match ? match.slice(1).map(Number) : null;
|
||||
};
|
||||
const installed = parse(installedVersion);
|
||||
const minimum = parse(minimumVersion);
|
||||
if (!installed || !minimum) return false;
|
||||
return installed[0] > minimum[0] || (installed[0] === minimum[0] && (installed[1] > minimum[1] || (installed[1] === minimum[1] && installed[2] >= minimum[2])));
|
||||
}
|
||||
|
||||
export function agentDriverInstallKey(dbType: DatabaseType | undefined, driverProfile?: string): string | undefined {
|
||||
if (dbType === "oracle") return "oracle";
|
||||
if (dbType === "mongodb") return "mongodb";
|
||||
|
||||
@@ -12,7 +12,7 @@ const toggleLeafNodeTypes = new Set<TreeNodeType>(["redis-db", "mq-tenant", "etc
|
||||
const objectBrowserNodeTypes = new Set<TreeNodeType>(["database", "schema", "object-browser"]);
|
||||
const sourceNodeTypes = new Set<TreeNodeType>(["materialized_view", "procedure", "function", "trigger", "sequence", "package", "package-body", "type", "type-body"]);
|
||||
const savedSqlNodeTypes = new Set<TreeNodeType>(["saved-sql-file"]);
|
||||
const tableChildGroupNodeTypes = new Set<TreeNodeType>(["group-columns", "group-indexes", "group-fkeys", "group-triggers", "group-partitions"]);
|
||||
const tableChildGroupNodeTypes = new Set<TreeNodeType>(["group-columns", "group-indexes", "group-fkeys", "group-triggers", "group-constraints", "group-partitions", "group-table-partitions", "group-table-subpartitions"]);
|
||||
const databaseChildGroupNodeTypes = new Set<TreeNodeType>(["group-tables", "group-views", "group-materialized-views", "group-procedures", "group-functions", "group-triggers", "group-sequences", "group-packages", "group-types"]);
|
||||
|
||||
export function objectSourceKindForTreeNode(type: TreeNodeType): ObjectSourceKind | null {
|
||||
|
||||
@@ -53,6 +53,15 @@ export function getTreeNodeIconInfo(node: TreeNode): TreeNodeIconInfo | null {
|
||||
return { icon: Zap, colorClass: "text-orange-400" };
|
||||
case "trigger":
|
||||
return { icon: Zap, colorClass: "text-orange-300" };
|
||||
case "group-constraints":
|
||||
case "constraint":
|
||||
return { icon: Key, colorClass: "text-amber-500" };
|
||||
case "group-table-partitions":
|
||||
case "group-table-subpartitions":
|
||||
return { icon: node.isExpanded ? FolderOpen : FolderClosed, colorClass: "text-green-400" };
|
||||
case "partition":
|
||||
case "subpartition":
|
||||
return { icon: TableProperties, colorClass: "text-green-400" };
|
||||
case "object-browser":
|
||||
return { icon: TableProperties, colorClass: "text-primary" };
|
||||
case "user-admin":
|
||||
|
||||
Reference in new issue
Block a user