diff --git a/src/common/customizations/defaults.js b/src/common/customizations/defaults.js index 1cc0fe47..062836a2 100644 --- a/src/common/customizations/defaults.js +++ b/src/common/customizations/defaults.js @@ -72,6 +72,7 @@ module.exports = { triggerTableInName: false, triggerUpdateColumns: false, triggerOnlyRename: false, + triggerEnableDisable: false, triggerFunctionSql: false, triggerFunctionlanguages: false, parametersLength: false, diff --git a/src/common/customizations/postgresql.js b/src/common/customizations/postgresql.js index 602663e4..b3547ccc 100644 --- a/src/common/customizations/postgresql.js +++ b/src/common/customizations/postgresql.js @@ -50,5 +50,6 @@ module.exports = { triggerMultipleEvents: true, triggerTableInName: true, triggerOnlyRename: false, + triggerEnableDisable: true, languages: ['sql', 'plpgsql', 'c', 'internal'] }; diff --git a/src/main/ipc-handlers/triggers.js b/src/main/ipc-handlers/triggers.js index b7edaeab..00ad9834 100644 --- a/src/main/ipc-handlers/triggers.js +++ b/src/main/ipc-handlers/triggers.js @@ -40,4 +40,19 @@ export default (connections) => { return { status: 'error', response: err.toString() }; } }); + + ipcMain.handle('toggle-trigger', async (event, params) => { + try { + if (!params.enabled) + await connections[params.uid].enableTrigger(params); + + else + await connections[params.uid].disableTrigger(params); + + return { status: 'success' }; + } + catch (err) { + return { status: 'error', response: err.toString() }; + } + }); }; diff --git a/src/main/libs/clients/PostgreSQLClient.js b/src/main/libs/clients/PostgreSQLClient.js index 7d9125e7..59272f79 100644 --- a/src/main/libs/clients/PostgreSQLClient.js +++ b/src/main/libs/clients/PostgreSQLClient.js @@ -168,19 +168,20 @@ export class PostgreSQLClient extends AntaresCore { } let { rows: triggers } = await this.raw(` - SELECT event_object_schema AS table_schema, - event_object_table AS table_name, - trigger_schema, - trigger_name, - string_agg(event_manipulation, ',') AS event, - action_timing AS activation, - action_condition AS condition, - action_statement AS definition - FROM information_schema.triggers + SELECT + pg_class.relname AS table_name, + pg_trigger.tgname AS trigger_name, + pg_namespace.nspname AS trigger_schema, + (pg_trigger.tgenabled != 'D')::bool AS enabled + FROM pg_trigger + JOIN pg_class ON pg_trigger.tgrelid = pg_class.oid + JOIN pg_namespace ON pg_namespace.oid = pg_class.relnamespace + JOIN information_schema.triggers ON information_schema.triggers.trigger_schema = pg_namespace.nspname + AND information_schema.triggers.event_object_table = pg_class.relname + AND information_schema.triggers.trigger_name = pg_trigger.tgname WHERE trigger_schema = '${db.database}' - GROUP BY 1,2,3,4,6,7,8 - ORDER BY table_schema, - table_name + GROUP BY 1, 2, 3, 4 + ORDER BY table_name `); if (triggers.length) { @@ -239,12 +240,10 @@ export class PostgreSQLClient extends AntaresCore { return { name: `${trigger.table_name}.${trigger.trigger_name}`, orgName: trigger.trigger_name, - timing: trigger.activation, definer: '', - definition: trigger.definition, - event: trigger.event, table: trigger.table_name, - sqlMode: '' + sqlMode: '', + enabled: trigger.enabled }; }); @@ -597,19 +596,25 @@ export class PostgreSQLClient extends AntaresCore { const [table, triggerName] = trigger.split('.'); const results = await this.raw(` - SELECT event_object_schema AS table_schema, - event_object_table AS table_name, - trigger_schema, - trigger_name, - string_agg(event_manipulation, ',') AS event, + SELECT + information_schema.triggers.event_object_schema AS table_schema, + information_schema.triggers.event_object_table AS table_name, + information_schema.triggers.trigger_schema, + information_schema.triggers.trigger_name, + string_agg(event_manipulation, ',') AS EVENT, action_timing AS activation, action_condition AS condition, - action_statement AS definition - FROM information_schema.triggers + action_statement AS definition, + (pg_trigger.tgenabled != 'D')::bool AS enabled + FROM pg_trigger + JOIN pg_class ON pg_trigger.tgrelid = pg_class.oid + JOIN pg_namespace ON pg_namespace.oid = pg_class.relnamespace + JOIN information_schema.triggers ON pg_namespace.nspname = information_schema.triggers.trigger_schema + AND pg_class.relname = information_schema.triggers.event_object_table WHERE trigger_schema = '${schema}' AND trigger_name = '${triggerName}' AND event_object_table = '${table}' - GROUP BY 1,2,3,4,6,7,8 + GROUP BY 1,2,3,4,6,7,8,9 ORDER BY table_schema, table_name `); @@ -619,7 +624,7 @@ export class PostgreSQLClient extends AntaresCore { sql: row.definition, name: row.trigger_name, table: row.table_name, - event: row.event.split(','), + event: [...new Set(row.event.split(','))], activation: row.activation }; })[0]; @@ -671,6 +676,18 @@ export class PostgreSQLClient extends AntaresCore { return await this.raw(sql, { split: false }); } + async enableTrigger ({ schema, trigger }) { + const [table, triggerName] = trigger.split('.'); + const sql = `ALTER TABLE "${schema}"."${table}" ENABLE TRIGGER "${triggerName}"`; + return await this.raw(sql, { split: false }); + } + + async disableTrigger ({ schema, trigger }) { + const [table, triggerName] = trigger.split('.'); + const sql = `ALTER TABLE "${schema}"."${table}" DISABLE TRIGGER "${triggerName}"`; + return await this.raw(sql, { split: false }); + } + /** * SHOW CREATE PROCEDURE * diff --git a/src/renderer/components/WorkspaceExploreBarMiscContext.vue b/src/renderer/components/WorkspaceExploreBarMiscContext.vue index 0fc6eb27..864e4221 100644 --- a/src/renderer/components/WorkspaceExploreBarMiscContext.vue +++ b/src/renderer/components/WorkspaceExploreBarMiscContext.vue @@ -10,6 +10,18 @@ > {{ $t('word.run') }} +
+ + {{ $t('word.enable') }} + + + {{ $t('word.disable') }} + +
{{ $t('word.delete') }}
@@ -78,6 +90,9 @@ export default { workspace () { return this.getWorkspace(this.selectedWorkspace); }, + customizations () { + return this.getWorkspace(this.selectedWorkspace).customizations; + }, deleteMessage () { switch (this.selectedMisc.type) { case 'trigger': @@ -273,6 +288,24 @@ export default { this.newTab({ uid: this.workspace.uid, content: sql, type: 'query', autorun: true }); this.closeContext(); + }, + async toggleTrigger () { + try { + const { status, response } = await Triggers.toggleTrigger({ + uid: this.selectedWorkspace, + schema: this.selectedSchema, + trigger: this.selectedMisc.name, + enabled: this.selectedMisc.enabled + }); + + if (status !== 'success') + this.addNotification({ status: 'error', message: response }); + } + catch (err) { + this.addNotification({ status: 'error', message: err.stack }); + } + this.closeContext(); + this.$emit('reload'); } } }; diff --git a/src/renderer/components/WorkspaceExploreBarSchema.vue b/src/renderer/components/WorkspaceExploreBarSchema.vue index 4c0fc17a..780c5838 100644 --- a/src/renderer/components/WorkspaceExploreBarSchema.vue +++ b/src/renderer/components/WorkspaceExploreBarSchema.vue @@ -71,6 +71,13 @@ +
+ +
@@ -500,7 +507,8 @@ export default { } } - .table-size { + .table-size, + .disabled-indicator { position: absolute; right: 0; top: 0; diff --git a/src/renderer/i18n/en-US.js b/src/renderer/i18n/en-US.js index 85ad58bf..de1f6d8b 100644 --- a/src/renderer/i18n/en-US.js +++ b/src/renderer/i18n/en-US.js @@ -121,7 +121,10 @@ module.exports = { history: 'History', select: 'Select', passphrase: 'Passphrase', - filter: 'Filter' + filter: 'Filter', + disabled: 'Disabled', + enable: 'Enable', + disable: 'Disable' }, message: { appWelcome: 'Welcome to Antares SQL Client!', diff --git a/src/renderer/ipc-api/Triggers.js b/src/renderer/ipc-api/Triggers.js index 98aa3316..c44c5f65 100644 --- a/src/renderer/ipc-api/Triggers.js +++ b/src/renderer/ipc-api/Triggers.js @@ -17,4 +17,8 @@ export default class { static createTrigger (params) { return ipcRenderer.invoke('create-trigger', params); } + + static toggleTrigger (params) { + return ipcRenderer.invoke('toggle-trigger', params); + } } diff --git a/src/renderer/scss/_data-types.scss b/src/renderer/scss/_data-types.scss index c4122b24..85f374ca 100644 --- a/src/renderer/scss/_data-types.scss +++ b/src/renderer/scss/_data-types.scss @@ -70,6 +70,7 @@ "bytea": $blob-color, "enum": $enum-color, "set": $enum-color, + "bool": $enum-color, "boolean": $enum-color, "interval": $array-color, "array": $array-color,