mirror of
https://github.com/Fabio286/antares.git
synced 2025-06-05 21:59:22 +02:00
feat(PostgreSQL): views management
This commit is contained in:
@ -43,6 +43,10 @@ module.exports = {
|
|||||||
autoIncrement: false,
|
autoIncrement: false,
|
||||||
comment: false,
|
comment: false,
|
||||||
collation: false,
|
collation: false,
|
||||||
|
definer: false,
|
||||||
arrays: false,
|
arrays: false,
|
||||||
onUpdate: false
|
onUpdate: false,
|
||||||
|
viewAlgorithm: false,
|
||||||
|
viewSqlSecurity: false,
|
||||||
|
viewUpdateOption: false
|
||||||
};
|
};
|
||||||
|
@ -42,5 +42,9 @@ module.exports = {
|
|||||||
autoIncrement: true,
|
autoIncrement: true,
|
||||||
comment: true,
|
comment: true,
|
||||||
collation: true,
|
collation: true,
|
||||||
onUpdate: true
|
definer: true,
|
||||||
|
onUpdate: true,
|
||||||
|
viewAlgorithm: true,
|
||||||
|
viewSqlSecurity: true,
|
||||||
|
viewUpdateOption: true
|
||||||
};
|
};
|
||||||
|
@ -12,16 +12,17 @@ module.exports = {
|
|||||||
processesList: true,
|
processesList: true,
|
||||||
// Structure
|
// Structure
|
||||||
tables: true,
|
tables: true,
|
||||||
views: false,
|
views: true,
|
||||||
triggers: false,
|
triggers: false,
|
||||||
routines: false,
|
routines: false,
|
||||||
functions: false,
|
functions: false,
|
||||||
schedulers: false,
|
schedulers: false,
|
||||||
// Settings
|
// Settings
|
||||||
tableAdd: true,
|
tableAdd: true,
|
||||||
|
viewAdd: true,
|
||||||
databaseEdit: false,
|
databaseEdit: false,
|
||||||
tableSettings: true,
|
tableSettings: true,
|
||||||
viewSettings: false,
|
viewSettings: true,
|
||||||
triggerSettings: false,
|
triggerSettings: false,
|
||||||
routineSettings: false,
|
routineSettings: false,
|
||||||
functionSettings: false,
|
functionSettings: false,
|
||||||
|
@ -454,17 +454,17 @@ export class PostgreSQLClient extends AntaresCore {
|
|||||||
* @memberof PostgreSQLClient
|
* @memberof PostgreSQLClient
|
||||||
*/
|
*/
|
||||||
async getViewInformations ({ schema, view }) {
|
async getViewInformations ({ schema, view }) {
|
||||||
const sql = `SHOW CREATE VIEW \`${schema}\`.\`${view}\``;
|
const sql = `SELECT "definition" FROM "pg_views" WHERE "viewname"='${view}' AND "schemaname"='${schema}'`;
|
||||||
const results = await this.raw(sql);
|
const results = await this.raw(sql);
|
||||||
|
|
||||||
return results.rows.map(row => {
|
return results.rows.map(row => {
|
||||||
return {
|
return {
|
||||||
algorithm: row['Create View'].match(/(?<=CREATE ALGORITHM=).*?(?=\s)/gs)[0],
|
algorithm: '',
|
||||||
definer: row['Create View'].match(/(?<=DEFINER=).*?(?=\s)/gs)[0],
|
definer: '',
|
||||||
security: row['Create View'].match(/(?<=SQL SECURITY ).*?(?=\s)/gs)[0],
|
security: '',
|
||||||
updateOption: row['Create View'].match(/(?<=WITH ).*?(?=\s)/gs) ? row['Create View'].match(/(?<=WITH ).*?(?=\s)/gs)[0] : '',
|
updateOption: '',
|
||||||
sql: row['Create View'].match(/(?<=AS ).*?$/gs)[0],
|
sql: row.definition,
|
||||||
name: row.View
|
name: view
|
||||||
};
|
};
|
||||||
})[0];
|
})[0];
|
||||||
}
|
}
|
||||||
@ -476,7 +476,7 @@ export class PostgreSQLClient extends AntaresCore {
|
|||||||
* @memberof PostgreSQLClient
|
* @memberof PostgreSQLClient
|
||||||
*/
|
*/
|
||||||
async dropView (params) {
|
async dropView (params) {
|
||||||
const sql = `DROP VIEW \`${params.view}\``;
|
const sql = `DROP VIEW ${params.view}`;
|
||||||
return await this.raw(sql);
|
return await this.raw(sql);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -488,10 +488,10 @@ export class PostgreSQLClient extends AntaresCore {
|
|||||||
*/
|
*/
|
||||||
async alterView (params) {
|
async alterView (params) {
|
||||||
const { view } = params;
|
const { view } = params;
|
||||||
let sql = `ALTER ALGORITHM = ${view.algorithm}${view.definer ? ` DEFINER=${view.definer}` : ''} SQL SECURITY ${view.security} VIEW \`${view.oldName}\` AS ${view.sql} ${view.updateOption ? `WITH ${view.updateOption} CHECK OPTION` : ''}`;
|
let sql = `CREATE OR REPLACE VIEW ${view.oldName} AS ${view.sql}`;
|
||||||
|
|
||||||
if (view.name !== view.oldName)
|
if (view.name !== view.oldName)
|
||||||
sql += `; RENAME TABLE \`${view.oldName}\` TO \`${view.name}\``;
|
sql += `; ALTER VIEW ${view.oldName} RENAME TO ${view.name}`;
|
||||||
|
|
||||||
return await this.raw(sql);
|
return await this.raw(sql);
|
||||||
}
|
}
|
||||||
@ -503,7 +503,7 @@ export class PostgreSQLClient extends AntaresCore {
|
|||||||
* @memberof PostgreSQLClient
|
* @memberof PostgreSQLClient
|
||||||
*/
|
*/
|
||||||
async createView (view) {
|
async createView (view) {
|
||||||
const sql = `CREATE ALGORITHM = ${view.algorithm} ${view.definer ? `DEFINER=${view.definer} ` : ''}SQL SECURITY ${view.security} VIEW \`${view.name}\` AS ${view.sql} ${view.updateOption ? `WITH ${view.updateOption} CHECK OPTION` : ''}`;
|
const sql = `CREATE VIEW ${view.name} AS ${view.sql}`;
|
||||||
return await this.raw(sql);
|
return await this.raw(sql);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -823,33 +823,33 @@ export class PostgreSQLClient extends AntaresCore {
|
|||||||
* @returns {Array.<Object>} view informations
|
* @returns {Array.<Object>} view informations
|
||||||
* @memberof PostgreSQLClient
|
* @memberof PostgreSQLClient
|
||||||
*/
|
*/
|
||||||
async getEventInformations ({ schema, scheduler }) {
|
// async getEventInformations ({ schema, scheduler }) {
|
||||||
const sql = `SHOW CREATE EVENT \`${schema}\`.\`${scheduler}\``;
|
// const sql = `SHOW CREATE EVENT \`${schema}\`.\`${scheduler}\``;
|
||||||
const results = await this.raw(sql);
|
// const results = await this.raw(sql);
|
||||||
|
|
||||||
return results.rows.map(row => {
|
// return results.rows.map(row => {
|
||||||
const schedule = row['Create Event'];
|
// const schedule = row['Create Event'];
|
||||||
const execution = schedule.includes('EVERY') ? 'EVERY' : 'ONCE';
|
// const execution = schedule.includes('EVERY') ? 'EVERY' : 'ONCE';
|
||||||
const every = execution === 'EVERY' ? row['Create Event'].match(/(?<=EVERY )(\s*([^\s]+)){0,2}/gs)[0].replaceAll('\'', '').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 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 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] : '';
|
// const at = execution === 'ONCE' && schedule.includes('AT') ? schedule.match(/(?<=AT ').*?(?='\s)/gs)[0] : '';
|
||||||
|
|
||||||
return {
|
// return {
|
||||||
definer: row['Create Event'].match(/(?<=DEFINER=).*?(?=\s)/gs)[0],
|
// definer: row['Create Event'].match(/(?<=DEFINER=).*?(?=\s)/gs)[0],
|
||||||
sql: row['Create Event'].match(/(?<=DO )(.*)/gs)[0],
|
// sql: row['Create Event'].match(/(?<=DO )(.*)/gs)[0],
|
||||||
name: row.Event,
|
// name: row.Event,
|
||||||
comment: row['Create Event'].match(/(?<=COMMENT ').*?(?=')/gs) ? row['Create Event'].match(/(?<=COMMENT ').*?(?=')/gs)[0] : '',
|
// comment: row['Create Event'].match(/(?<=COMMENT ').*?(?=')/gs) ? row['Create Event'].match(/(?<=COMMENT ').*?(?=')/gs)[0] : '',
|
||||||
state: row['Create Event'].includes('ENABLE') ? 'ENABLE' : row['Create Event'].includes('DISABLE ON SLAVE') ? 'DISABLE ON SLAVE' : 'DISABLE',
|
// state: row['Create Event'].includes('ENABLE') ? 'ENABLE' : row['Create Event'].includes('DISABLE ON SLAVE') ? 'DISABLE ON SLAVE' : 'DISABLE',
|
||||||
preserve: row['Create Event'].includes('ON COMPLETION PRESERVE'),
|
// preserve: row['Create Event'].includes('ON COMPLETION PRESERVE'),
|
||||||
execution,
|
// execution,
|
||||||
every,
|
// every,
|
||||||
starts,
|
// starts,
|
||||||
ends,
|
// ends,
|
||||||
at
|
// at
|
||||||
};
|
// };
|
||||||
})[0];
|
// })[0];
|
||||||
}
|
// }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* DROP EVENT
|
* DROP EVENT
|
||||||
@ -857,10 +857,10 @@ export class PostgreSQLClient extends AntaresCore {
|
|||||||
* @returns {Array.<Object>} parameters
|
* @returns {Array.<Object>} parameters
|
||||||
* @memberof PostgreSQLClient
|
* @memberof PostgreSQLClient
|
||||||
*/
|
*/
|
||||||
async dropEvent (params) {
|
// async dropEvent (params) {
|
||||||
const sql = `DROP EVENT \`${params.scheduler}\``;
|
// const sql = `DROP EVENT \`${params.scheduler}\``;
|
||||||
return await this.raw(sql);
|
// return await this.raw(sql);
|
||||||
}
|
// }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ALTER EVENT
|
* ALTER EVENT
|
||||||
@ -868,25 +868,25 @@ export class PostgreSQLClient extends AntaresCore {
|
|||||||
* @returns {Array.<Object>} parameters
|
* @returns {Array.<Object>} parameters
|
||||||
* @memberof PostgreSQLClient
|
* @memberof PostgreSQLClient
|
||||||
*/
|
*/
|
||||||
async alterEvent (params) {
|
// async alterEvent (params) {
|
||||||
const { scheduler } = params;
|
// const { scheduler } = params;
|
||||||
|
|
||||||
if (scheduler.execution === 'EVERY' && scheduler.every[0].includes('-'))
|
// if (scheduler.execution === 'EVERY' && scheduler.every[0].includes('-'))
|
||||||
scheduler.every[0] = `'${scheduler.every[0]}'`;
|
// scheduler.every[0] = `'${scheduler.every[0]}'`;
|
||||||
|
|
||||||
const sql = `ALTER ${scheduler.definer ? ` DEFINER=${scheduler.definer}` : ''} EVENT \`${scheduler.oldName}\`
|
// const sql = `ALTER ${scheduler.definer ? ` DEFINER=${scheduler.definer}` : ''} EVENT \`${scheduler.oldName}\`
|
||||||
ON SCHEDULE
|
// ON SCHEDULE
|
||||||
${scheduler.execution === 'EVERY'
|
// ${scheduler.execution === 'EVERY'
|
||||||
? `EVERY ${scheduler.every.join(' ')}${scheduler.starts ? ` STARTS '${scheduler.starts}'` : ''}${scheduler.ends ? ` ENDS '${scheduler.ends}'` : ''}`
|
// ? `EVERY ${scheduler.every.join(' ')}${scheduler.starts ? ` STARTS '${scheduler.starts}'` : ''}${scheduler.ends ? ` ENDS '${scheduler.ends}'` : ''}`
|
||||||
: `AT '${scheduler.at}'`}
|
// : `AT '${scheduler.at}'`}
|
||||||
ON COMPLETION${!scheduler.preserve ? ' NOT' : ''} PRESERVE
|
// ON COMPLETION${!scheduler.preserve ? ' NOT' : ''} PRESERVE
|
||||||
${scheduler.name !== scheduler.oldName ? `RENAME TO \`${scheduler.name}\`` : ''}
|
// ${scheduler.name !== scheduler.oldName ? `RENAME TO \`${scheduler.name}\`` : ''}
|
||||||
${scheduler.state}
|
// ${scheduler.state}
|
||||||
COMMENT '${scheduler.comment}'
|
// COMMENT '${scheduler.comment}'
|
||||||
DO ${scheduler.sql}`;
|
// DO ${scheduler.sql}`;
|
||||||
|
|
||||||
return await this.raw(sql, { split: false });
|
// return await this.raw(sql, { split: false });
|
||||||
}
|
// }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* CREATE EVENT
|
* CREATE EVENT
|
||||||
@ -894,19 +894,19 @@ export class PostgreSQLClient extends AntaresCore {
|
|||||||
* @returns {Array.<Object>} parameters
|
* @returns {Array.<Object>} parameters
|
||||||
* @memberof PostgreSQLClient
|
* @memberof PostgreSQLClient
|
||||||
*/
|
*/
|
||||||
async createEvent (scheduler) {
|
// async createEvent (scheduler) {
|
||||||
const sql = `CREATE ${scheduler.definer ? ` DEFINER=${scheduler.definer}` : ''} EVENT \`${scheduler.name}\`
|
// const sql = `CREATE ${scheduler.definer ? ` DEFINER=${scheduler.definer}` : ''} EVENT \`${scheduler.name}\`
|
||||||
ON SCHEDULE
|
// ON SCHEDULE
|
||||||
${scheduler.execution === 'EVERY'
|
// ${scheduler.execution === 'EVERY'
|
||||||
? `EVERY ${scheduler.every.join(' ')}${scheduler.starts ? ` STARTS '${scheduler.starts}'` : ''}${scheduler.ends ? ` ENDS '${scheduler.ends}'` : ''}`
|
// ? `EVERY ${scheduler.every.join(' ')}${scheduler.starts ? ` STARTS '${scheduler.starts}'` : ''}${scheduler.ends ? ` ENDS '${scheduler.ends}'` : ''}`
|
||||||
: `AT '${scheduler.at}'`}
|
// : `AT '${scheduler.at}'`}
|
||||||
ON COMPLETION${!scheduler.preserve ? ' NOT' : ''} PRESERVE
|
// ON COMPLETION${!scheduler.preserve ? ' NOT' : ''} PRESERVE
|
||||||
${scheduler.state}
|
// ${scheduler.state}
|
||||||
COMMENT '${scheduler.comment}'
|
// COMMENT '${scheduler.comment}'
|
||||||
DO ${scheduler.sql}`;
|
// DO ${scheduler.sql}`;
|
||||||
|
|
||||||
return await this.raw(sql, { split: false });
|
// return await this.raw(sql, { split: false });
|
||||||
}
|
// }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* SELECT * FROM pg_collation
|
* SELECT * FROM pg_collation
|
||||||
|
@ -25,7 +25,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="column col-6">
|
<div class="column col-6">
|
||||||
<div class="form-group">
|
<div v-if="workspace.customizations.definer" class="form-group">
|
||||||
<label class="form-label">{{ $t('word.definer') }}</label>
|
<label class="form-label">{{ $t('word.definer') }}</label>
|
||||||
<select v-model="localView.definer" class="form-select">
|
<select v-model="localView.definer" class="form-select">
|
||||||
<option value="">
|
<option value="">
|
||||||
@ -44,7 +44,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="columns">
|
<div class="columns">
|
||||||
<div class="column col-4">
|
<div class="column col-4">
|
||||||
<div class="form-group">
|
<div v-if="workspace.customizations.viewSqlSecurity" class="form-group">
|
||||||
<label class="form-label">{{ $t('message.sqlSecurity') }}</label>
|
<label class="form-label">{{ $t('message.sqlSecurity') }}</label>
|
||||||
<label class="form-radio">
|
<label class="form-radio">
|
||||||
<input
|
<input
|
||||||
@ -67,7 +67,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="column col-4">
|
<div class="column col-4">
|
||||||
<div class="form-group">
|
<div v-if="workspace.customizations.viewAlgorithm" class="form-group">
|
||||||
<label class="form-label">{{ $t('word.algorithm') }}</label>
|
<label class="form-label">{{ $t('word.algorithm') }}</label>
|
||||||
<label class="form-radio">
|
<label class="form-radio">
|
||||||
<input
|
<input
|
||||||
@ -99,7 +99,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="column col-4">
|
<div class="column col-4">
|
||||||
<div class="form-group">
|
<div v-if="workspace.customizations.viewUpdateOption" class="form-group">
|
||||||
<label class="form-label">{{ $t('message.updateOption') }}</label>
|
<label class="form-label">{{ $t('message.updateOption') }}</label>
|
||||||
<label class="form-radio">
|
<label class="form-radio">
|
||||||
<input
|
<input
|
||||||
|
@ -37,7 +37,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="column col-auto">
|
<div class="column col-auto">
|
||||||
<div class="form-group">
|
<div v-if="workspace.customizations.definer" class="form-group">
|
||||||
<label class="form-label">{{ $t('word.definer') }}</label>
|
<label class="form-label">{{ $t('word.definer') }}</label>
|
||||||
<select
|
<select
|
||||||
v-if="workspace.users.length"
|
v-if="workspace.users.length"
|
||||||
@ -68,7 +68,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="columns">
|
<div class="columns">
|
||||||
<div class="column col-auto mr-2">
|
<div class="column col-auto mr-2">
|
||||||
<div class="form-group">
|
<div v-if="workspace.customizations.viewSqlSecurity" class="form-group">
|
||||||
<label class="form-label">{{ $t('message.sqlSecurity') }}</label>
|
<label class="form-label">{{ $t('message.sqlSecurity') }}</label>
|
||||||
<label class="form-radio">
|
<label class="form-radio">
|
||||||
<input
|
<input
|
||||||
@ -91,7 +91,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="column col-auto mr-2">
|
<div class="column col-auto mr-2">
|
||||||
<div class="form-group">
|
<div v-if="workspace.customizations.viewAlgorithm" class="form-group">
|
||||||
<label class="form-label">{{ $t('word.algorithm') }}</label>
|
<label class="form-label">{{ $t('word.algorithm') }}</label>
|
||||||
<label class="form-radio">
|
<label class="form-radio">
|
||||||
<input
|
<input
|
||||||
@ -122,7 +122,7 @@
|
|||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="column col-auto mr-2">
|
<div v-if="workspace.customizations.viewUpdateOption" class="column col-auto mr-2">
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label class="form-label">{{ $t('message.updateOption') }}</label>
|
<label class="form-label">{{ $t('message.updateOption') }}</label>
|
||||||
<label class="form-radio">
|
<label class="form-radio">
|
||||||
|
Reference in New Issue
Block a user