mirror of https://github.com/Fabio286/antares.git
feat(PostgreSQL): enable/disable triggers from contextual menu
This commit is contained in:
parent
c00fd1381f
commit
534659f9ae
|
@ -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,
|
||||||
|
|
Loading…
Reference in New Issue