mirror of https://github.com/Fabio286/antares.git
feat: scheduler edit
This commit is contained in:
parent
1e7d4ca347
commit
ceab4ef243
|
@ -676,7 +676,7 @@ export class MySQLClient extends AntaresCore {
|
|||
return results.rows.map(row => {
|
||||
const schedule = row['Create Event'].match(/(?<=ON SCHEDULE\n*?\s*?).*?(?=\n)/gs)[0];
|
||||
const execution = schedule.includes('EVERY') ? 'EVERY' : 'ONCE';
|
||||
const every = execution === 'EVERY' ? row['Create Event'].match(/(?<=EVERY )(\s*(\w+)){0,2}/gs)[0].split(' ') : [];
|
||||
const every = execution === 'EVERY' ? row['Create Event'].match(/(?<=EVERY )(\s*([^\s]+)){0,2}/gs)[0].replaceAll('\'', '').split(' ') : [];
|
||||
const starts = execution === 'EVERY' && schedule.includes('STARTS') ? schedule.match(/(?<=STARTS ').*?(?='\s)/gs)[0] : '';
|
||||
const ends = execution === 'EVERY' && schedule.includes('ENDS') ? schedule.match(/(?<=ENDS ').*?(?='\s)/gs)[0] : '';
|
||||
const at = execution === 'ONCE' && schedule.includes('AT') ? schedule.match(/(?<=AT ').*?(?='\s)/gs)[0] : '';
|
||||
|
@ -716,18 +716,22 @@ export class MySQLClient extends AntaresCore {
|
|||
*/
|
||||
async alterEvent (params) {
|
||||
const { scheduler } = params;
|
||||
const tempProcedure = Object.assign({}, scheduler);
|
||||
tempProcedure.name = `Antares_${tempProcedure.name}_tmp`;
|
||||
|
||||
try {
|
||||
await this.createEvent(tempProcedure);
|
||||
await this.dropEvent({ scheduler: tempProcedure.name });
|
||||
await this.dropEvent({ scheduler: scheduler.oldName });
|
||||
await this.createEvent(scheduler);
|
||||
}
|
||||
catch (err) {
|
||||
return Promise.reject(err);
|
||||
}
|
||||
if (scheduler.execution === 'EVERY' && scheduler.every[0].includes('-'))
|
||||
scheduler.every[0] = `'${scheduler.every[0]}'`;
|
||||
|
||||
const sql = `ALTER ${scheduler.definer ? ` DEFINER=${scheduler.definer}` : ''} EVENT \`${scheduler.oldName}\`
|
||||
ON SCHEDULE
|
||||
${scheduler.execution === 'EVERY'
|
||||
? `EVERY ${scheduler.every.join(' ')}${scheduler.starts ? ` STARTS '${scheduler.starts}'` : ''}${scheduler.ends ? ` ENDS '${scheduler.ends}'` : ''}`
|
||||
: `AT '${scheduler.at}'`}
|
||||
ON COMPLETION${!scheduler.preserve ? ' NOT' : ''} PRESERVE
|
||||
${scheduler.name !== scheduler.oldName ? `RENAME TO \`${scheduler.name}\`` : ''}
|
||||
${scheduler.state}
|
||||
COMMENT '${scheduler.comment}'
|
||||
DO ${scheduler.sql}`;
|
||||
|
||||
return await this.raw(sql);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
<form class="form-horizontal">
|
||||
<div class="form-group">
|
||||
<div class="col-3">
|
||||
<label class="form-label">{{ $t('word.user') }}:</label>
|
||||
<label class="form-label">{{ $t('word.user') }}</label>
|
||||
</div>
|
||||
<div class="col-9">
|
||||
<input
|
||||
|
@ -28,7 +28,7 @@
|
|||
</div>
|
||||
<div class="form-group">
|
||||
<div class="col-3">
|
||||
<label class="form-label">{{ $t('word.password') }}:</label>
|
||||
<label class="form-label">{{ $t('word.password') }}</label>
|
||||
</div>
|
||||
<div class="col-9">
|
||||
<input
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
<fieldset class="m-0" :disabled="isTesting">
|
||||
<div class="form-group">
|
||||
<div class="col-4 col-sm-12">
|
||||
<label class="form-label">{{ $t('word.connectionName') }}:</label>
|
||||
<label class="form-label">{{ $t('word.connectionName') }}</label>
|
||||
</div>
|
||||
<div class="col-8 col-sm-12">
|
||||
<input
|
||||
|
@ -29,7 +29,7 @@
|
|||
</div>
|
||||
<div class="form-group">
|
||||
<div class="col-4 col-sm-12">
|
||||
<label class="form-label">{{ $t('word.client') }}:</label>
|
||||
<label class="form-label">{{ $t('word.client') }}</label>
|
||||
</div>
|
||||
<div class="col-8 col-sm-12">
|
||||
<select v-model="localConnection.client" class="form-select">
|
||||
|
@ -53,7 +53,7 @@
|
|||
</div>
|
||||
<div class="form-group">
|
||||
<div class="col-4 col-sm-12">
|
||||
<label class="form-label">{{ $t('word.hostName') }}/IP:</label>
|
||||
<label class="form-label">{{ $t('word.hostName') }}/IP</label>
|
||||
</div>
|
||||
<div class="col-8 col-sm-12">
|
||||
<input
|
||||
|
@ -65,7 +65,7 @@
|
|||
</div>
|
||||
<div class="form-group">
|
||||
<div class="col-4 col-sm-12">
|
||||
<label class="form-label">{{ $t('word.port') }}:</label>
|
||||
<label class="form-label">{{ $t('word.port') }}</label>
|
||||
</div>
|
||||
<div class="col-8 col-sm-12">
|
||||
<input
|
||||
|
@ -79,7 +79,7 @@
|
|||
</div>
|
||||
<div class="form-group">
|
||||
<div class="col-4 col-sm-12">
|
||||
<label class="form-label">{{ $t('word.user') }}:</label>
|
||||
<label class="form-label">{{ $t('word.user') }}</label>
|
||||
</div>
|
||||
<div class="col-8 col-sm-12">
|
||||
<input
|
||||
|
@ -92,7 +92,7 @@
|
|||
</div>
|
||||
<div class="form-group">
|
||||
<div class="col-4 col-sm-12">
|
||||
<label class="form-label">{{ $t('word.password') }}:</label>
|
||||
<label class="form-label">{{ $t('word.password') }}</label>
|
||||
</div>
|
||||
<div class="col-8 col-sm-12">
|
||||
<input
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
<form class="form-horizontal">
|
||||
<div class="form-group">
|
||||
<div class="col-3">
|
||||
<label class="form-label">{{ $t('word.name') }}:</label>
|
||||
<label class="form-label">{{ $t('word.name') }}</label>
|
||||
</div>
|
||||
<div class="col-9">
|
||||
<input
|
||||
|
@ -30,7 +30,7 @@
|
|||
</div>
|
||||
<div class="form-group">
|
||||
<div class="col-3">
|
||||
<label class="form-label">{{ $t('word.collation') }}:</label>
|
||||
<label class="form-label">{{ $t('word.collation') }}</label>
|
||||
</div>
|
||||
<div class="col-9">
|
||||
<select
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
<fieldset class="m-0" :disabled="isTesting">
|
||||
<div class="form-group">
|
||||
<div class="col-4 col-sm-12">
|
||||
<label class="form-label">{{ $t('word.connectionName') }}:</label>
|
||||
<label class="form-label">{{ $t('word.connectionName') }}</label>
|
||||
</div>
|
||||
<div class="col-8 col-sm-12">
|
||||
<input
|
||||
|
@ -29,7 +29,7 @@
|
|||
</div>
|
||||
<div class="form-group">
|
||||
<div class="col-4 col-sm-12">
|
||||
<label class="form-label">{{ $t('word.client') }}:</label>
|
||||
<label class="form-label">{{ $t('word.client') }}</label>
|
||||
</div>
|
||||
<div class="col-8 col-sm-12">
|
||||
<select
|
||||
|
@ -57,7 +57,7 @@
|
|||
</div>
|
||||
<div class="form-group">
|
||||
<div class="col-4 col-sm-12">
|
||||
<label class="form-label">{{ $t('word.hostName') }}/IP:</label>
|
||||
<label class="form-label">{{ $t('word.hostName') }}/IP</label>
|
||||
</div>
|
||||
<div class="col-8 col-sm-12">
|
||||
<input
|
||||
|
@ -69,7 +69,7 @@
|
|||
</div>
|
||||
<div class="form-group">
|
||||
<div class="col-4 col-sm-12">
|
||||
<label class="form-label">{{ $t('word.port') }}:</label>
|
||||
<label class="form-label">{{ $t('word.port') }}</label>
|
||||
</div>
|
||||
<div class="col-8 col-sm-12">
|
||||
<input
|
||||
|
@ -83,7 +83,7 @@
|
|||
</div>
|
||||
<div class="form-group">
|
||||
<div class="col-4 col-sm-12">
|
||||
<label class="form-label">{{ $t('word.user') }}:</label>
|
||||
<label class="form-label">{{ $t('word.user') }}</label>
|
||||
</div>
|
||||
<div class="col-8 col-sm-12">
|
||||
<input
|
||||
|
@ -96,7 +96,7 @@
|
|||
</div>
|
||||
<div class="form-group">
|
||||
<div class="col-4 col-sm-12">
|
||||
<label class="form-label">{{ $t('word.password') }}:</label>
|
||||
<label class="form-label">{{ $t('word.password') }}</label>
|
||||
</div>
|
||||
<div class="col-8 col-sm-12">
|
||||
<input
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
<form class="form-horizontal">
|
||||
<div class="form-group">
|
||||
<div class="col-3">
|
||||
<label class="form-label">{{ $t('word.name') }}:</label>
|
||||
<label class="form-label">{{ $t('word.name') }}</label>
|
||||
</div>
|
||||
<div class="col-9">
|
||||
<input
|
||||
|
@ -30,7 +30,7 @@
|
|||
</div>
|
||||
<div class="form-group">
|
||||
<div class="col-3">
|
||||
<label class="form-label">{{ $t('word.collation') }}:</label>
|
||||
<label class="form-label">{{ $t('word.collation') }}</label>
|
||||
</div>
|
||||
<div class="col-9">
|
||||
<select v-model="database.collation" class="form-select">
|
||||
|
|
|
@ -56,7 +56,7 @@
|
|||
<div class="col-6 col-sm-12">
|
||||
<label class="form-label">
|
||||
<i class="mdi mdi-18px mdi-translate mr-1" />
|
||||
{{ $t('word.language') }}:
|
||||
{{ $t('word.language') }}
|
||||
</label>
|
||||
</div>
|
||||
<div class="col-6 col-sm-12">
|
||||
|
@ -78,7 +78,7 @@
|
|||
<div class="form-group">
|
||||
<div class="col-6 col-sm-12">
|
||||
<label class="form-label">
|
||||
{{ $t('message.notificationsTimeout') }}:
|
||||
{{ $t('message.notificationsTimeout') }}
|
||||
</label>
|
||||
</div>
|
||||
<div class="col-6 col-sm-12">
|
||||
|
@ -103,7 +103,7 @@
|
|||
<div class="form-group">
|
||||
<div class="col-6 col-sm-12">
|
||||
<label class="form-label">
|
||||
{{ $t('word.autoCompletion') }}:
|
||||
{{ $t('word.autoCompletion') }}
|
||||
</label>
|
||||
</div>
|
||||
<div class="col-6 col-sm-12">
|
||||
|
@ -118,7 +118,7 @@
|
|||
<div class="form-group">
|
||||
<div class="col-6 col-sm-12">
|
||||
<label class="form-label">
|
||||
{{ $t('message.wrapLongLines') }}:
|
||||
{{ $t('message.wrapLongLines') }}
|
||||
</label>
|
||||
</div>
|
||||
<div class="col-6 col-sm-12">
|
||||
|
@ -205,9 +205,9 @@
|
|||
<img :src="require('@/images/logo.svg').default" width="128">
|
||||
<h4>{{ appName }}</h4>
|
||||
<p>
|
||||
{{ $t('word.version') }}: {{ appVersion }}<br>
|
||||
{{ $t('word.version') }} {{ appVersion }}<br>
|
||||
<a class="c-hand" @click="openOutside('https://github.com/Fabio286/antares')">GitHub</a> | <a class="c-hand" @click="openOutside('https://github.com/Fabio286/antares/blob/master/CHANGELOG.md')">CHANGELOG</a><br>
|
||||
<small>{{ $t('word.author') }}: <a class="c-hand" @click="openOutside('https://github.com/Fabio286')">Fabio Di Stasio</a></small><br>
|
||||
<small>{{ $t('word.author') }} <a class="c-hand" @click="openOutside('https://github.com/Fabio286')">Fabio Di Stasio</a></small><br>
|
||||
<small>{{ $t('message.madeWithJS') }}</small>
|
||||
</p>
|
||||
</div>
|
||||
|
|
|
@ -0,0 +1,190 @@
|
|||
<template>
|
||||
<ConfirmModal
|
||||
:confirm-text="$t('word.confirm')"
|
||||
size="400"
|
||||
@confirm="confirmOptionsChange"
|
||||
@hide="$emit('hide')"
|
||||
>
|
||||
<template :slot="'header'">
|
||||
<div class="d-flex">
|
||||
<i class="mdi mdi-24px mdi-timer mr-1" /> {{ $t('word.timing') }} "{{ localOptions.name }}"
|
||||
</div>
|
||||
</template>
|
||||
<div :slot="'body'">
|
||||
<form class="form-horizontal">
|
||||
<div class="form-group">
|
||||
<label class="form-label col-4">
|
||||
{{ $t('word.execution') }}
|
||||
</label>
|
||||
<div class="column">
|
||||
<select
|
||||
ref="firstInput"
|
||||
v-model="optionsProxy.execution"
|
||||
class="form-select"
|
||||
>
|
||||
<option>EVERY</option>
|
||||
<option>ONCE</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="optionsProxy.execution === 'EVERY'">
|
||||
<div class="form-group">
|
||||
<div class="col-4" />
|
||||
<div class="column">
|
||||
<div class="input-group">
|
||||
<input
|
||||
v-model="optionsProxy.every[0]"
|
||||
class="form-input"
|
||||
type="text"
|
||||
@keypress="isNumberOrMinus($event)"
|
||||
>
|
||||
<select
|
||||
v-model="optionsProxy.every[1]"
|
||||
class="form-select text-uppercase"
|
||||
style="width: 0;"
|
||||
>
|
||||
<option>YEAR</option>
|
||||
<option>QUARTER</option>
|
||||
<option>MONTH</option>
|
||||
<option>WEEK</option>
|
||||
<option>DAY</option>
|
||||
<option>HOUR</option>
|
||||
<option>MINUTE</option>
|
||||
<option>SECOND</option>
|
||||
<option>YEAR_MONTH</option>
|
||||
<option>DAY_HOUR</option>
|
||||
<option>DAY_MINUTE</option>
|
||||
<option>DAY_SECOND</option>
|
||||
<option>HOUR_MINUTE</option>
|
||||
<option>HOUR_SECOND</option>
|
||||
<option>MINUTE_SECOND</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="form-label col-4">
|
||||
{{ $t('word.starts') }}
|
||||
</label>
|
||||
<div class="column">
|
||||
<div class="input-group">
|
||||
<label class="form-checkbox">
|
||||
<input v-model="hasStart" type="checkbox"><i class="form-icon" />
|
||||
</label>
|
||||
<input
|
||||
v-model="optionsProxy.starts"
|
||||
v-mask="'####-##-## ##:##:##'"
|
||||
type="text"
|
||||
class="form-input"
|
||||
>
|
||||
<span class="input-group-addon p-vcentered">
|
||||
<i class="form-icon mdi mdi-calendar" />
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="form-label col-4">
|
||||
{{ $t('word.ends') }}
|
||||
</label>
|
||||
<div class="column">
|
||||
<div class="input-group">
|
||||
<label class="form-checkbox">
|
||||
<input v-model="hasEnd" type="checkbox"><i class="form-icon" />
|
||||
</label>
|
||||
<input
|
||||
v-model="optionsProxy.ends"
|
||||
v-mask="'####-##-## ##:##:##'"
|
||||
type="text"
|
||||
class="form-input"
|
||||
>
|
||||
<span class="input-group-addon p-vcentered">
|
||||
<i class="form-icon mdi mdi-calendar" />
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div v-else>
|
||||
<div class="form-group">
|
||||
<div class="col-4" />
|
||||
<div class="column">
|
||||
<div class="input-group">
|
||||
<input
|
||||
v-model="optionsProxy.at"
|
||||
v-mask="'####-##-## ##:##:##'"
|
||||
type="text"
|
||||
class="form-input"
|
||||
>
|
||||
<span class="input-group-addon p-vcentered">
|
||||
<i class="form-icon mdi mdi-calendar" />
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<div class="col-4" />
|
||||
<div class="column">
|
||||
<label class="form-checkbox form-inline mt-2">
|
||||
<input v-model="optionsProxy.preserve" type="checkbox"><i class="form-icon" /> {{ $t('message.preserveOnCompletion') }}
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</ConfirmModal>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import ConfirmModal from '@/components/BaseConfirmModal';
|
||||
import { mask } from 'vue-the-mask';
|
||||
import moment from 'moment';
|
||||
|
||||
export default {
|
||||
name: 'WorkspacePropsSchedulerTimingModal',
|
||||
components: {
|
||||
ConfirmModal
|
||||
},
|
||||
directives: {
|
||||
mask
|
||||
},
|
||||
props: {
|
||||
localOptions: Object,
|
||||
workspace: Object
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
optionsProxy: {},
|
||||
isOptionsChanging: false,
|
||||
hasStart: false,
|
||||
hasEnd: false
|
||||
};
|
||||
},
|
||||
created () {
|
||||
this.optionsProxy = JSON.parse(JSON.stringify(this.localOptions));
|
||||
|
||||
this.hasStart = !!this.optionsProxy.starts;
|
||||
this.hasEnd = !!this.optionsProxy.ends;
|
||||
|
||||
if (!this.optionsProxy.at) this.optionsProxy.at = moment().format('YYYY-MM-DD HH:mm:ss');
|
||||
if (!this.optionsProxy.every.length) this.optionsProxy.every = ['1', 'DAY'];
|
||||
|
||||
setTimeout(() => {
|
||||
this.$refs.firstInput.focus();
|
||||
}, 20);
|
||||
},
|
||||
methods: {
|
||||
confirmOptionsChange () {
|
||||
if (!this.hasStart) this.optionsProxy.starts = '';
|
||||
if (!this.hasEnd) this.optionsProxy.ends = '';
|
||||
|
||||
this.$emit('options-update', this.optionsProxy);
|
||||
},
|
||||
isNumberOrMinus (event) {
|
||||
if (!/\d/.test(event.key) && event.key !== '-')
|
||||
return event.preventDefault();
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
|
@ -23,7 +23,7 @@
|
|||
</button>
|
||||
|
||||
<div class="divider-vert py-3" />
|
||||
<button class="btn btn-dark btn-sm" @click="false">
|
||||
<button class="btn btn-dark btn-sm" @click="showTimingModal">
|
||||
<span>{{ $t('word.timing') }}</span>
|
||||
<i class="mdi mdi-24px mdi-timer ml-1" />
|
||||
</button>
|
||||
|
@ -82,13 +82,6 @@
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="columns">
|
||||
<!-- <div class="column"> TODO: move in timing modal
|
||||
<label class="form-checkbox form-inline">
|
||||
<input v-model="localScheduler.preserve" type="checkbox"><i class="form-icon" /> {{ $t('message.preserveOnCompletion') }}
|
||||
</label>
|
||||
</div> -->
|
||||
</div>
|
||||
<div class="columns">
|
||||
<div class="column">
|
||||
<div class="form-group">
|
||||
|
@ -132,18 +125,27 @@
|
|||
:height="editorHeight"
|
||||
/>
|
||||
</div>
|
||||
<WorkspacePropsSchedulerTimingModal
|
||||
v-if="isTimingModal"
|
||||
:local-options="localScheduler"
|
||||
:workspace="workspace"
|
||||
@hide="hideTimingModal"
|
||||
@options-update="timingUpdate"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { mapGetters, mapActions } from 'vuex';
|
||||
import QueryEditor from '@/components/QueryEditor';
|
||||
import WorkspacePropsSchedulerTimingModal from '@/components/WorkspacePropsSchedulerTimingModal';
|
||||
import Schedulers from '@/ipc-api/Schedulers';
|
||||
|
||||
export default {
|
||||
name: 'WorkspacePropsTabScheduler',
|
||||
components: {
|
||||
QueryEditor
|
||||
QueryEditor,
|
||||
WorkspacePropsSchedulerTimingModal
|
||||
},
|
||||
props: {
|
||||
connection: Object,
|
||||
|
@ -154,6 +156,7 @@ export default {
|
|||
tabUid: 'prop',
|
||||
isQuering: false,
|
||||
isSaving: false,
|
||||
isTimingModal: false,
|
||||
originalScheduler: null,
|
||||
localScheduler: { sql: '' },
|
||||
lastScheduler: null,
|
||||
|
@ -295,6 +298,15 @@ export default {
|
|||
this.editorHeight = size;
|
||||
this.$refs.queryEditor.editor.resize();
|
||||
}
|
||||
},
|
||||
showTimingModal () {
|
||||
this.isTimingModal = true;
|
||||
},
|
||||
hideTimingModal () {
|
||||
this.isTimingModal = false;
|
||||
},
|
||||
timingUpdate (options) {
|
||||
this.localScheduler = options;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
|
@ -82,7 +82,10 @@ module.exports = {
|
|||
export: 'Export',
|
||||
returns: 'Returns',
|
||||
timing: 'Timing',
|
||||
state: 'State'
|
||||
state: 'State',
|
||||
execution: 'Execution',
|
||||
starts: 'Starts',
|
||||
ends: 'Ends'
|
||||
},
|
||||
message: {
|
||||
appWelcome: 'Welcome to Antares SQL Client!',
|
||||
|
|
Loading…
Reference in New Issue