diff --git a/packages/tools/src/SqlDumper.ts b/packages/tools/src/SqlDumper.ts index 04314dfc2..d778c038a 100644 --- a/packages/tools/src/SqlDumper.ts +++ b/packages/tools/src/SqlDumper.ts @@ -18,6 +18,7 @@ import type { AlterProcessor, SqlObjectInfo, CallableObjectInfo, + SchedulerEventInfo, } from 'dbgate-types'; import _isString from 'lodash/isString'; import _isNumber from 'lodash/isNumber'; @@ -431,6 +432,14 @@ export class SqlDumper implements AlterProcessor { changeTriggerSchema(obj: TriggerInfo, newSchema: string) {} renameTrigger(obj: TriggerInfo, newSchema: string) {} + createSchedulerEvent(obj: SchedulerEventInfo) { + this.putRaw(obj.createSql); + this.endCommand(); + } + dropSchedulerEvent(obj: SchedulerEventInfo, { testIfExists = false }) { + this.putCmd('^drop ^event %f', obj); + } + dropConstraintCore(cnt: ConstraintInfo) { this.putCmd('^alter ^table %f ^drop ^constraint %i', cnt, cnt.constraintName); } diff --git a/packages/tools/src/SqlGenerator.ts b/packages/tools/src/SqlGenerator.ts index f3e1589a2..a5e3b1009 100644 --- a/packages/tools/src/SqlGenerator.ts +++ b/packages/tools/src/SqlGenerator.ts @@ -3,6 +3,7 @@ import type { EngineDriver, FunctionInfo, ProcedureInfo, + SchedulerEventInfo, TableInfo, TriggerInfo, ViewInfo, @@ -49,12 +50,16 @@ interface SqlGeneratorOptions { dropTriggers: boolean; checkIfTriggerExists: boolean; createTriggers: boolean; + + dropSchedulerEvents: boolean; + checkIfSchedulerEventExists: boolean; + createSchedulerEvents: boolean; } interface SqlGeneratorObject { schemaName: string; pureName: string; - objectTypeField: 'tables' | 'views' | 'procedures' | 'functions'; + objectTypeField: 'tables' | 'views' | 'procedures' | 'functions' | 'triggers' | 'schedulerEvents'; } export class SqlGenerator { @@ -64,6 +69,7 @@ export class SqlGenerator { private procedures: ProcedureInfo[]; private functions: FunctionInfo[]; private triggers: TriggerInfo[]; + private schedulerEvents: SchedulerEventInfo[]; public dbinfo: DatabaseInfo; public isTruncated = false; public isUnhandledException = false; @@ -83,6 +89,7 @@ export class SqlGenerator { this.procedures = this.extract('procedures'); this.functions = this.extract('functions'); this.triggers = this.extract('triggers'); + this.schedulerEvents = this.extract('schedulerEvents'); } private handleException = error => { @@ -104,6 +111,8 @@ export class SqlGenerator { if (this.checkDumper()) return; this.dropObjects(this.triggers, 'Trigger'); if (this.checkDumper()) return; + this.dropObjects(this.schedulerEvents, 'SchedulerEvent'); + if (this.checkDumper()) return; this.dropTables(); if (this.checkDumper()) return; @@ -130,6 +139,8 @@ export class SqlGenerator { if (this.checkDumper()) return; this.createObjects(this.triggers, 'Trigger'); if (this.checkDumper()) return; + this.createObjects(this.schedulerEvents, 'SchedulerEvent'); + if (this.checkDumper()) return; } finally { process.off('uncaughtException', this.handleException); } diff --git a/packages/web/src/appobj/DatabaseObjectAppObject.svelte b/packages/web/src/appobj/DatabaseObjectAppObject.svelte index d801378a6..97956891a 100644 --- a/packages/web/src/appobj/DatabaseObjectAppObject.svelte +++ b/packages/web/src/appobj/DatabaseObjectAppObject.svelte @@ -349,7 +349,34 @@ case 'functions': return [...defaultDatabaseObjectAppObjectActions['functions']]; case 'triggers': - return [...defaultDatabaseObjectAppObjectActions['triggers']]; + return [ + ...defaultDatabaseObjectAppObjectActions['triggers'], + hasPermission('dbops/model/edit') && { + label: 'Drop trigger', + isDrop: true, + requiresWriteAccess: true, + }, + { + divider: true, + }, + { + label: 'SQL generator', + submenu: [ + { + label: 'CREATE TRIGGER', + sqlGeneratorProps: { + createTriggers: true, + }, + }, + { + label: 'DROP TRIGGER', + sqlGeneratorProps: { + dropTriggers: true, + }, + }, + ], + }, + ]; case 'collections': return [ ...defaultDatabaseObjectAppObjectActions['collections'], @@ -390,10 +417,11 @@ case 'schedulerEvents': const menu: DbObjMenuItem[] = [ ...defaultDatabaseObjectAppObjectActions['schedulerEvents'], - { - divider: true, + hasPermission('dbops/model/edit') && { + label: 'Drop event', + isDrop: true, + requiresWriteAccess: true, }, - , ]; if (data?.status === 'ENABLED') { @@ -408,6 +436,29 @@ }); } + menu.push( + { + divider: true, + }, + { + label: 'SQL generator', + submenu: [ + { + label: 'CREATE SCHEDULER EVENT', + sqlGeneratorProps: { + createSchedulerEvents: true, + }, + }, + { + label: 'DROP SCHEDULER EVENT', + sqlGeneratorProps: { + dropSchedulerEvents: true, + }, + }, + ], + } + ); + return menu; } } diff --git a/packages/web/src/modals/SqlGeneratorModal.svelte b/packages/web/src/modals/SqlGeneratorModal.svelte index 632ec4447..ef4dbfa4c 100644 --- a/packages/web/src/modals/SqlGeneratorModal.svelte +++ b/packages/web/src/modals/SqlGeneratorModal.svelte @@ -74,7 +74,7 @@ $: generatePreview($valuesStore, $checkedObjectsStore); $: objectList = _.flatten( - ['tables', 'views', 'matviews', 'procedures', 'functions'].map(objectTypeField => + ['tables', 'views', 'matviews', 'procedures', 'functions', 'triggers', 'schedulerEvents'].map(objectTypeField => _.sortBy( (($dbinfo || {})[objectTypeField] || []).map(obj => ({ ...obj, objectTypeField })), ['schemaName', 'pureName'] @@ -214,8 +214,8 @@ - {#each ['View', 'Matview', 'Procedure', 'Function', 'Trigger'] as objtype} -
{getObjectTypeFieldLabel(objtype.toLowerCase() + 's')}
+ {#each ['View', 'Matview', 'Procedure', 'Function', 'Trigger', 'SchedulerEvent'] as objtype} +
{getObjectTypeFieldLabel(objtype + 's')}
{#if values[`drop${objtype}s`]}