mirror of
				https://github.com/Fabio286/antares.git
				synced 2025-06-05 21:59:22 +02:00 
			
		
		
		
	feat(PostgreSQL): enable/disable triggers from contextual menu
This commit is contained in:
		| @@ -72,6 +72,7 @@ module.exports = { | |||||||
|    triggerTableInName: false, |    triggerTableInName: false, | ||||||
|    triggerUpdateColumns: false, |    triggerUpdateColumns: false, | ||||||
|    triggerOnlyRename: false, |    triggerOnlyRename: false, | ||||||
|  |    triggerEnableDisable: false, | ||||||
|    triggerFunctionSql: false, |    triggerFunctionSql: false, | ||||||
|    triggerFunctionlanguages: false, |    triggerFunctionlanguages: false, | ||||||
|    parametersLength: false, |    parametersLength: false, | ||||||
|   | |||||||
| @@ -50,5 +50,6 @@ module.exports = { | |||||||
|    triggerMultipleEvents: true, |    triggerMultipleEvents: true, | ||||||
|    triggerTableInName: true, |    triggerTableInName: true, | ||||||
|    triggerOnlyRename: false, |    triggerOnlyRename: false, | ||||||
|  |    triggerEnableDisable: true, | ||||||
|    languages: ['sql', 'plpgsql', 'c', 'internal'] |    languages: ['sql', 'plpgsql', 'c', 'internal'] | ||||||
| }; | }; | ||||||
|   | |||||||
| @@ -40,4 +40,19 @@ export default (connections) => { | |||||||
|          return { status: 'error', response: err.toString() }; |          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() }; | ||||||
|  |       } | ||||||
|  |    }); | ||||||
| }; | }; | ||||||
|   | |||||||
| @@ -168,19 +168,20 @@ export class PostgreSQLClient extends AntaresCore { | |||||||
|          } |          } | ||||||
|  |  | ||||||
|          let { rows: triggers } = await this.raw(` |          let { rows: triggers } = await this.raw(` | ||||||
|             SELECT event_object_schema AS table_schema, |             SELECT | ||||||
|                event_object_table AS table_name, |                pg_class.relname AS table_name, | ||||||
|                trigger_schema, |                pg_trigger.tgname AS trigger_name, | ||||||
|                trigger_name, |                pg_namespace.nspname AS trigger_schema, | ||||||
|                string_agg(event_manipulation, ',') AS event, |                (pg_trigger.tgenabled != 'D')::bool AS enabled | ||||||
|                action_timing AS activation, |             FROM pg_trigger | ||||||
|                action_condition AS condition, |             JOIN pg_class ON pg_trigger.tgrelid = pg_class.oid | ||||||
|                action_statement AS definition |             JOIN pg_namespace ON pg_namespace.oid = pg_class.relnamespace | ||||||
|             FROM information_schema.triggers |             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}' |             WHERE trigger_schema = '${db.database}' | ||||||
|             GROUP BY 1,2,3,4,6,7,8 |             GROUP BY 1, 2, 3, 4 | ||||||
|             ORDER BY table_schema, |             ORDER BY table_name | ||||||
|                      table_name |  | ||||||
|          `); |          `); | ||||||
|  |  | ||||||
|          if (triggers.length) { |          if (triggers.length) { | ||||||
| @@ -239,12 +240,10 @@ export class PostgreSQLClient extends AntaresCore { | |||||||
|                return { |                return { | ||||||
|                   name: `${trigger.table_name}.${trigger.trigger_name}`, |                   name: `${trigger.table_name}.${trigger.trigger_name}`, | ||||||
|                   orgName: trigger.trigger_name, |                   orgName: trigger.trigger_name, | ||||||
|                   timing: trigger.activation, |  | ||||||
|                   definer: '', |                   definer: '', | ||||||
|                   definition: trigger.definition, |  | ||||||
|                   event: trigger.event, |  | ||||||
|                   table: trigger.table_name, |                   table: trigger.table_name, | ||||||
|                   sqlMode: '' |                   sqlMode: '', | ||||||
|  |                   enabled: trigger.enabled | ||||||
|                }; |                }; | ||||||
|             }); |             }); | ||||||
|  |  | ||||||
| @@ -597,19 +596,25 @@ export class PostgreSQLClient extends AntaresCore { | |||||||
|       const [table, triggerName] = trigger.split('.'); |       const [table, triggerName] = trigger.split('.'); | ||||||
|  |  | ||||||
|       const results = await this.raw(` |       const results = await this.raw(` | ||||||
|          SELECT event_object_schema AS table_schema, |          SELECT | ||||||
|             event_object_table AS table_name, |             information_schema.triggers.event_object_schema AS table_schema, | ||||||
|             trigger_schema, |             information_schema.triggers.event_object_table AS table_name, | ||||||
|             trigger_name, |             information_schema.triggers.trigger_schema, | ||||||
|             string_agg(event_manipulation, ',') AS event, |             information_schema.triggers.trigger_name, | ||||||
|  |             string_agg(event_manipulation, ',') AS EVENT, | ||||||
|             action_timing AS activation, |             action_timing AS activation, | ||||||
|             action_condition AS condition, |             action_condition AS condition, | ||||||
|             action_statement AS definition |             action_statement AS definition, | ||||||
|          FROM information_schema.triggers |             (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}' |          WHERE trigger_schema = '${schema}' | ||||||
|          AND trigger_name = '${triggerName}' |          AND trigger_name = '${triggerName}' | ||||||
|          AND event_object_table = '${table}' |          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, |          ORDER BY table_schema, | ||||||
|                   table_name |                   table_name | ||||||
|       `); |       `); | ||||||
| @@ -619,7 +624,7 @@ export class PostgreSQLClient extends AntaresCore { | |||||||
|             sql: row.definition, |             sql: row.definition, | ||||||
|             name: row.trigger_name, |             name: row.trigger_name, | ||||||
|             table: row.table_name, |             table: row.table_name, | ||||||
|             event: row.event.split(','), |             event: [...new Set(row.event.split(','))], | ||||||
|             activation: row.activation |             activation: row.activation | ||||||
|          }; |          }; | ||||||
|       })[0]; |       })[0]; | ||||||
| @@ -671,6 +676,18 @@ export class PostgreSQLClient extends AntaresCore { | |||||||
|       return await this.raw(sql, { split: false }); |       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 |     * SHOW CREATE PROCEDURE | ||||||
|     * |     * | ||||||
|   | |||||||
| @@ -10,6 +10,18 @@ | |||||||
|       > |       > | ||||||
|          <span class="d-flex"><i class="mdi mdi-18px mdi-play text-light pr-1" /> {{ $t('word.run') }}</span> |          <span class="d-flex"><i class="mdi mdi-18px mdi-play text-light pr-1" /> {{ $t('word.run') }}</span> | ||||||
|       </div> |       </div> | ||||||
|  |       <div | ||||||
|  |          v-if="selectedMisc.type === 'trigger' && customizations.triggerEnableDisable" | ||||||
|  |          class="context-element" | ||||||
|  |          @click="toggleTrigger" | ||||||
|  |       > | ||||||
|  |          <span v-if="!selectedMisc.enabled" class="d-flex"> | ||||||
|  |             <i class="mdi mdi-18px mdi-play text-light pr-1" /> {{ $t('word.enable') }} | ||||||
|  |          </span> | ||||||
|  |          <span v-else class="d-flex"> | ||||||
|  |             <i class="mdi mdi-18px mdi-pause text-light pr-1" /> {{ $t('word.disable') }} | ||||||
|  |          </span> | ||||||
|  |       </div> | ||||||
|       <div class="context-element" @click="showDeleteModal"> |       <div class="context-element" @click="showDeleteModal"> | ||||||
|          <span class="d-flex"><i class="mdi mdi-18px mdi-table-remove text-light pr-1" /> {{ $t('word.delete') }}</span> |          <span class="d-flex"><i class="mdi mdi-18px mdi-table-remove text-light pr-1" /> {{ $t('word.delete') }}</span> | ||||||
|       </div> |       </div> | ||||||
| @@ -78,6 +90,9 @@ export default { | |||||||
|       workspace () { |       workspace () { | ||||||
|          return this.getWorkspace(this.selectedWorkspace); |          return this.getWorkspace(this.selectedWorkspace); | ||||||
|       }, |       }, | ||||||
|  |       customizations () { | ||||||
|  |          return this.getWorkspace(this.selectedWorkspace).customizations; | ||||||
|  |       }, | ||||||
|       deleteMessage () { |       deleteMessage () { | ||||||
|          switch (this.selectedMisc.type) { |          switch (this.selectedMisc.type) { | ||||||
|             case 'trigger': |             case 'trigger': | ||||||
| @@ -273,6 +288,24 @@ export default { | |||||||
|  |  | ||||||
|          this.newTab({ uid: this.workspace.uid, content: sql, type: 'query', autorun: true }); |          this.newTab({ uid: this.workspace.uid, content: sql, type: 'query', autorun: true }); | ||||||
|          this.closeContext(); |          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'); | ||||||
|       } |       } | ||||||
|    } |    } | ||||||
| }; | }; | ||||||
|   | |||||||
| @@ -71,6 +71,13 @@ | |||||||
|                               <i class="table-icon mdi mdi-table-cog mdi-18px mr-1" /> |                               <i class="table-icon mdi mdi-table-cog mdi-18px mr-1" /> | ||||||
|                               <span v-html="highlightWord(trigger.name)" /> |                               <span v-html="highlightWord(trigger.name)" /> | ||||||
|                            </a> |                            </a> | ||||||
|  |                            <div | ||||||
|  |                               v-if="trigger.enabled === false" | ||||||
|  |                               class="tooltip tooltip-left disabled-indicator" | ||||||
|  |                               :data-tooltip="$t('word.disabled')" | ||||||
|  |                            > | ||||||
|  |                               <i class="table-icon mdi mdi-pause mdi-18px mr-1" /> | ||||||
|  |                            </div> | ||||||
|                         </li> |                         </li> | ||||||
|                      </ul> |                      </ul> | ||||||
|                   </div> |                   </div> | ||||||
| @@ -500,7 +507,8 @@ export default { | |||||||
|     } |     } | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   .table-size { |   .table-size, | ||||||
|  |   .disabled-indicator { | ||||||
|     position: absolute; |     position: absolute; | ||||||
|     right: 0; |     right: 0; | ||||||
|     top: 0; |     top: 0; | ||||||
|   | |||||||
| @@ -121,7 +121,10 @@ module.exports = { | |||||||
|       history: 'History', |       history: 'History', | ||||||
|       select: 'Select', |       select: 'Select', | ||||||
|       passphrase: 'Passphrase', |       passphrase: 'Passphrase', | ||||||
|       filter: 'Filter' |       filter: 'Filter', | ||||||
|  |       disabled: 'Disabled', | ||||||
|  |       enable: 'Enable', | ||||||
|  |       disable: 'Disable' | ||||||
|    }, |    }, | ||||||
|    message: { |    message: { | ||||||
|       appWelcome: 'Welcome to Antares SQL Client!', |       appWelcome: 'Welcome to Antares SQL Client!', | ||||||
|   | |||||||
| @@ -17,4 +17,8 @@ export default class { | |||||||
|    static createTrigger (params) { |    static createTrigger (params) { | ||||||
|       return ipcRenderer.invoke('create-trigger', params); |       return ipcRenderer.invoke('create-trigger', params); | ||||||
|    } |    } | ||||||
|  |  | ||||||
|  |    static toggleTrigger (params) { | ||||||
|  |       return ipcRenderer.invoke('toggle-trigger', params); | ||||||
|  |    } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -70,6 +70,7 @@ | |||||||
|     "bytea": $blob-color, |     "bytea": $blob-color, | ||||||
|     "enum": $enum-color, |     "enum": $enum-color, | ||||||
|     "set": $enum-color, |     "set": $enum-color, | ||||||
|  |     "bool": $enum-color, | ||||||
|     "boolean": $enum-color, |     "boolean": $enum-color, | ||||||
|     "interval": $array-color, |     "interval": $array-color, | ||||||
|     "array": $array-color, |     "array": $array-color, | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user