fix(mysql): show scheduled events in the sidebar
This commit is contained in:
1 parent
5011468a9a
commit
2b11af94ba
26 files changed
+137
-33
No files matched your search
@@ -39,8 +39,8 @@ describe("databaseObjectCapabilities", () => {
|
||||
});
|
||||
|
||||
it("exposes triggers only for native MySQL among MySQL-compatible paths", () => {
|
||||
expect(sidebarObjectKindsForDatabase("mysql")).toEqual(["TABLE", "VIEW", "PROCEDURE", "FUNCTION", "TRIGGER"]);
|
||||
expect(databaseObjectCapabilities("mysql").sourceReadable).toEqual(["VIEW", "PROCEDURE", "FUNCTION", "TRIGGER"]);
|
||||
expect(sidebarObjectKindsForDatabase("mysql")).toEqual(["TABLE", "VIEW", "PROCEDURE", "FUNCTION", "TRIGGER", "EVENT"]);
|
||||
expect(databaseObjectCapabilities("mysql").sourceReadable).toEqual(["VIEW", "PROCEDURE", "FUNCTION", "TRIGGER", "EVENT"]);
|
||||
|
||||
expect(sidebarObjectKindsForDatabase("doris")).toEqual(["TABLE", "VIEW"]);
|
||||
expect(sidebarObjectKindsForDatabase("starrocks")).toEqual(["TABLE", "VIEW", "MATERIALIZED_VIEW"]);
|
||||
|
||||
@@ -248,6 +248,16 @@ describe("programmable database objects", () => {
|
||||
]);
|
||||
});
|
||||
|
||||
it("groups MySQL scheduled events under a dedicated Events group", () => {
|
||||
const objects: ObjectInfo[] = [{ name: "event_daily_middle_db_sync", object_type: "EVENT", schema: "shop" }];
|
||||
|
||||
const groups = buildGroupedObjectTreeNodes({ ...context, schema: "shop", objects, databaseType: "mysql" });
|
||||
const eventGroup = groups.find((node) => node.type === "group-events");
|
||||
|
||||
expect(eventGroup).toEqual(expect.objectContaining({ objectCount: 1, label: "tree.events" }));
|
||||
expect(eventGroup?.children).toEqual([expect.objectContaining({ type: "event", objectName: "event_daily_middle_db_sync" })]);
|
||||
});
|
||||
|
||||
it("keeps table-scoped Kingbase triggers distinct and source-addressable", () => {
|
||||
const objects: ObjectInfo[] = [
|
||||
{ name: "audit_before", object_type: "TRIGGER", schema: "public", parent_schema: "public", parent_name: "items" },
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import type { DatabaseType } from "@/types/database";
|
||||
|
||||
export type SidebarObjectKind = "TABLE" | "VIEW" | "MATERIALIZED_VIEW" | "PROCEDURE" | "FUNCTION" | "TRIGGER" | "SEQUENCE" | "SYNONYM" | "PACKAGE" | "PACKAGE_BODY" | "TYPE" | "TYPE_BODY";
|
||||
export type SidebarObjectKind = "TABLE" | "VIEW" | "MATERIALIZED_VIEW" | "PROCEDURE" | "FUNCTION" | "TRIGGER" | "EVENT" | "SEQUENCE" | "SYNONYM" | "PACKAGE" | "PACKAGE_BODY" | "TYPE" | "TYPE_BODY";
|
||||
|
||||
export interface DatabaseObjectCapabilities {
|
||||
sidebarObjects: SidebarObjectKind[];
|
||||
@@ -12,7 +12,7 @@ const TABLE_VIEW_OBJECTS: SidebarObjectKind[] = ["TABLE", "VIEW"];
|
||||
const TABLE_VIEW_MV_OBJECTS: SidebarObjectKind[] = ["TABLE", "VIEW", "MATERIALIZED_VIEW"];
|
||||
|
||||
const ROUTINE_OBJECTS: SidebarObjectKind[] = ["TABLE", "VIEW", "PROCEDURE", "FUNCTION"];
|
||||
const MYSQL_OBJECTS: SidebarObjectKind[] = ["TABLE", "VIEW", "PROCEDURE", "FUNCTION", "TRIGGER"];
|
||||
const MYSQL_OBJECTS: SidebarObjectKind[] = ["TABLE", "VIEW", "PROCEDURE", "FUNCTION", "TRIGGER", "EVENT"];
|
||||
|
||||
// PostgreSQL-family databases with a verified pg_type listing path. TYPE only
|
||||
// covers user-created types (enum/domain/composite/range/multirange/base);
|
||||
@@ -157,6 +157,7 @@ export function normalizeSidebarObjectKind(type: string): SidebarObjectKind {
|
||||
if (normalized.includes("TYPE_BODY")) return "TYPE_BODY";
|
||||
if (normalized.includes("PACKAGE")) return "PACKAGE";
|
||||
if (normalized.includes("TRIGGER")) return "TRIGGER";
|
||||
if (normalized.includes("EVENT")) return "EVENT";
|
||||
if (normalized.includes("TYPE")) return "TYPE";
|
||||
if (normalized.includes("MATERIALIZED_VIEW")) return "MATERIALIZED_VIEW";
|
||||
if (value.includes("VIEW")) return "VIEW";
|
||||
|
||||
@@ -54,11 +54,11 @@ const objectBrowserNodeTypes = new Set<TreeNodeType>(["database", "schema", "obj
|
||||
export function shouldOpenObjectBrowserOnSingleClick(type: TreeNodeType, enabled: boolean): boolean {
|
||||
return enabled && objectBrowserNodeTypes.has(type);
|
||||
}
|
||||
const sourceNodeTypes = new Set<TreeNodeType>(["materialized_view", "procedure", "function", "trigger", "sequence", "synonym", "package", "package-body", "type", "type-body"]);
|
||||
const sourceNodeTypes = new Set<TreeNodeType>(["materialized_view", "procedure", "function", "trigger", "event", "sequence", "synonym", "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-constraints", "group-partitions", "group-table-partitions", "group-table-subpartitions"]);
|
||||
const databaseChildGroupNodeTypes = new Set<TreeNodeType>(["group-tables", "group-dolt-system-tables", "group-views", "group-materialized-views", "group-procedures", "group-functions", "group-triggers", "group-sequences", "group-synonyms", "group-packages", "group-types"]);
|
||||
const displayPathObjectNodeTypes = new Set<TreeNodeType>(["table", "view", "materialized_view", "procedure", "function", "trigger"]);
|
||||
const databaseChildGroupNodeTypes = new Set<TreeNodeType>(["group-tables", "group-dolt-system-tables", "group-views", "group-materialized-views", "group-procedures", "group-functions", "group-triggers", "group-events", "group-sequences", "group-synonyms", "group-packages", "group-types"]);
|
||||
const displayPathObjectNodeTypes = new Set<TreeNodeType>(["table", "view", "materialized_view", "procedure", "function", "trigger", "event"]);
|
||||
|
||||
export function objectSourceKindForTreeNode(type: TreeNodeType): ObjectSourceKind | null {
|
||||
if (type === "view") return "VIEW";
|
||||
@@ -66,6 +66,7 @@ export function objectSourceKindForTreeNode(type: TreeNodeType): ObjectSourceKin
|
||||
if (type === "procedure") return "PROCEDURE";
|
||||
if (type === "function") return "FUNCTION";
|
||||
if (type === "trigger") return "TRIGGER";
|
||||
if (type === "event") return "EVENT";
|
||||
if (type === "sequence") return "SEQUENCE";
|
||||
if (type === "synonym") return "SYNONYM";
|
||||
if (type === "package") return "PACKAGE";
|
||||
|
||||
@@ -5,6 +5,7 @@ const treeGroupNodeTypes = new Set<TreeNodeType>([
|
||||
"group-indexes",
|
||||
"group-fkeys",
|
||||
"group-triggers",
|
||||
"group-events",
|
||||
"group-constraints",
|
||||
"group-table-partitions",
|
||||
"group-table-subpartitions",
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import type { Component } from "vue";
|
||||
import { Archive, Braces, Columns3, Database, Eye, FileCode, FolderClosed, FolderOpen, Gauge, Key, Link, Link2, ListTree, Network, Package, Plus, ScrollText, Server, ShieldCheck, Table, TableProperties, UsersRound, Zap } from "@lucide/vue";
|
||||
import { Archive, Braces, Clock, Columns3, Database, Eye, FileCode, FolderClosed, FolderOpen, Gauge, Key, Link, Link2, ListTree, Network, Package, Plus, ScrollText, Server, ShieldCheck, Table, TableProperties, UsersRound, Zap } from "@lucide/vue";
|
||||
import type { ColumnInfo, TreeNode } from "@/types/database";
|
||||
|
||||
export type TreeNodeIconInfo = {
|
||||
@@ -68,6 +68,10 @@ 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-events":
|
||||
return { icon: Clock, colorClass: "text-orange-400" };
|
||||
case "event":
|
||||
return { icon: Clock, colorClass: "text-orange-300" };
|
||||
case "group-constraints":
|
||||
case "constraint":
|
||||
return { icon: Key, colorClass: "text-amber-500" };
|
||||
|
||||
@@ -634,7 +634,7 @@ export function buildSimpleObjectTreeNodes({ nodeId, connectionId, database, sch
|
||||
|
||||
for (const obj of coalesceXuguPackageObjects(objects, databaseType)) {
|
||||
const objectType = normalizeObjectType(obj.object_type);
|
||||
if (!["TABLE", "VIEW", "MATERIALIZED_VIEW", "PROCEDURE", "FUNCTION", "TRIGGER", "SEQUENCE", "SYNONYM", "PACKAGE", "PACKAGE_BODY", "TYPE", "TYPE_BODY"].includes(objectType)) {
|
||||
if (!["TABLE", "VIEW", "MATERIALIZED_VIEW", "PROCEDURE", "FUNCTION", "TRIGGER", "EVENT", "SEQUENCE", "SYNONYM", "PACKAGE", "PACKAGE_BODY", "TYPE", "TYPE_BODY"].includes(objectType)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -700,6 +700,7 @@ function simpleObjectNodeType(objectType: DatabaseObjectTreeKind): TreeNodeType
|
||||
if (objectType === "PROCEDURE") return "procedure";
|
||||
if (objectType === "FUNCTION") return "function";
|
||||
if (objectType === "TRIGGER") return "trigger";
|
||||
if (objectType === "EVENT") return "event";
|
||||
if (objectType === "SEQUENCE") return "sequence";
|
||||
if (objectType === "SYNONYM") return "synonym";
|
||||
if (objectType === "PACKAGE_BODY") return "package-body";
|
||||
@@ -752,6 +753,13 @@ const groupDefs: Array<{
|
||||
nodeType: "group-triggers",
|
||||
childType: "trigger",
|
||||
},
|
||||
{
|
||||
key: "__events",
|
||||
label: "tree.events",
|
||||
objectTypes: ["EVENT"],
|
||||
nodeType: "group-events",
|
||||
childType: "event",
|
||||
},
|
||||
{
|
||||
key: "__sequences",
|
||||
label: "tree.sequences",
|
||||
@@ -782,7 +790,7 @@ const groupDefs: Array<{
|
||||
},
|
||||
];
|
||||
|
||||
const objectGroupNodeTypes = new Set<TreeNodeType>(["group-tables", "group-dolt-system-tables", "group-views", "group-materialized-views", "group-procedures", "group-functions", "group-triggers", "group-sequences", "group-synonyms", "group-packages", "group-types"]);
|
||||
const objectGroupNodeTypes = new Set<TreeNodeType>(["group-tables", "group-dolt-system-tables", "group-views", "group-materialized-views", "group-procedures", "group-functions", "group-triggers", "group-events", "group-sequences", "group-synonyms", "group-packages", "group-types"]);
|
||||
|
||||
export function buildObjectGroupPlaceholderNodes({
|
||||
nodeId,
|
||||
|
||||
Reference in new issue
Block a user