1
1
mirror of https://github.com/Fabio286/antares.git synced 2025-06-05 21:59:22 +02:00

perf(MySQL): improved the way to get routine and functions parameters

This commit is contained in:
2021-04-14 18:06:20 +02:00
parent c0f54b9514
commit 90fd9db917
5 changed files with 82 additions and 75 deletions

View File

@ -581,7 +581,7 @@ export class MySQLClient extends AntaresCore {
const sql = `SHOW CREATE PROCEDURE \`${schema}\`.\`${routine}\``; const sql = `SHOW CREATE PROCEDURE \`${schema}\`.\`${routine}\``;
const results = await this.raw(sql); const results = await this.raw(sql);
return results.rows.map(row => { return results.rows.map(async row => {
if (!row['Create Procedure']) { if (!row['Create Procedure']) {
return { return {
definer: null, definer: null,
@ -595,22 +595,23 @@ export class MySQLClient extends AntaresCore {
}; };
} }
const parameters = row['Create Procedure'] const sql = `SELECT *
.match(/(\([^()]*(?:(?:\([^()]*\))[^()]*)*\)\s*)/s)[0] FROM information_schema.parameters
.replaceAll('\r', '') WHERE SPECIFIC_NAME = '${routine}'
.replaceAll('\t', '') AND SPECIFIC_SCHEMA = '${schema}'
.slice(1, -1) ORDER BY ORDINAL_POSITION
.split(',') `;
.map(el => {
const param = el.split(' '); const results = await this.raw(sql);
const type = param[2] ? param[2].replace(')', '').split('(') : ['', null];
return { const parameters = results.rows.map(row => {
name: param[1] ? param[1].replaceAll('`', '') : '', return {
type: type[0].replaceAll('\n', ''), name: row.PARAMETER_NAME,
length: +type[1] ? +type[1].replace(/\D/g, '') : '', type: row.DATA_TYPE.toUpperCase(),
context: param[0] ? param[0].replace('\n', '') : '' length: row.NUMERIC_PRECISION || row.DATETIME_PRECISION || row.CHARACTER_MAXIMUM_LENGTH || '',
}; context: row.PARAMETER_MODE
}).filter(el => el.name); };
});
let dataAccess = 'CONTAINS SQL'; let dataAccess = 'CONTAINS SQL';
if (row['Create Procedure'].includes('NO SQL')) if (row['Create Procedure'].includes('NO SQL'))
@ -701,7 +702,7 @@ export class MySQLClient extends AntaresCore {
const sql = `SHOW CREATE FUNCTION \`${schema}\`.\`${func}\``; const sql = `SHOW CREATE FUNCTION \`${schema}\`.\`${func}\``;
const results = await this.raw(sql); const results = await this.raw(sql);
return results.rows.map(row => { return results.rows.map(async row => {
if (!row['Create Function']) { if (!row['Create Function']) {
return { return {
definer: null, definer: null,
@ -717,22 +718,23 @@ export class MySQLClient extends AntaresCore {
}; };
} }
const parameters = row['Create Function'] const sql = `SELECT *
.match(/(\([^()]*(?:(?:\([^()]*\))[^()]*)*\)\s*)/s)[0] FROM information_schema.parameters
.replaceAll('\r', '') WHERE SPECIFIC_NAME = '${func}'
.replaceAll('\t', '') AND SPECIFIC_SCHEMA = '${schema}'
.slice(1, -1) ORDER BY ORDINAL_POSITION
.split(',') `;
.map(el => {
const param = el.split(' ');
const type = param[1] ? param[1].replace(')', '').split('(') : ['', null];
return { const results = await this.raw(sql);
name: param[0] ? param[0].replaceAll('`', '') : '',
type: type[0], const parameters = results.rows.filter(row => row.PARAMETER_MODE).map(row => {
length: +type[1] ? +type[1].replace(/\D/g, '') : '' return {
}; name: row.PARAMETER_NAME,
}).filter(el => el.name); type: row.DATA_TYPE.toUpperCase(),
length: row.NUMERIC_PRECISION || row.DATETIME_PRECISION || row.CHARACTER_MAXIMUM_LENGTH || '',
context: row.PARAMETER_MODE
};
});
let dataAccess = 'CONTAINS SQL'; let dataAccess = 'CONTAINS SQL';
if (row['Create Function'].includes('NO SQL')) if (row['Create Function'].includes('NO SQL'))
@ -804,13 +806,15 @@ export class MySQLClient extends AntaresCore {
return acc; return acc;
}, []).join(','); }, []).join(',');
const sql = `CREATE ${func.definer ? `DEFINER=${func.definer} ` : ''}FUNCTION \`${func.name}\`(${parameters}) RETURNS ${func.returns}${func.returnsLength ? `(${func.returnsLength})` : ''} const body = func.returns ? func.sql : 'BEGIN\n RETURN 0;\nEND';
const sql = `CREATE ${func.definer ? `DEFINER=${func.definer} ` : ''}FUNCTION \`${func.name}\`(${parameters}) RETURNS ${func.returns || 'SMALLINT'}${func.returnsLength ? `(${func.returnsLength})` : ''}
LANGUAGE SQL LANGUAGE SQL
${func.deterministic ? 'DETERMINISTIC' : 'NOT DETERMINISTIC'} ${func.deterministic ? 'DETERMINISTIC' : 'NOT DETERMINISTIC'}
${func.dataAccess} ${func.dataAccess}
SQL SECURITY ${func.security} SQL SECURITY ${func.security}
COMMENT '${func.comment}' COMMENT '${func.comment}'
${func.sql}`; ${body}`;
return await this.raw(sql, { split: false }); return await this.raw(sql, { split: false });
} }

View File

@ -577,25 +577,25 @@ export class PostgreSQLClient extends AntaresCore {
} }
const sql = `SELECT proc.specific_schema AS procedure_schema, const sql = `SELECT proc.specific_schema AS procedure_schema,
proc.specific_name, proc.specific_name,
proc.routine_name AS procedure_name, proc.routine_name AS procedure_name,
proc.external_language, proc.external_language,
args.parameter_name, args.parameter_name,
args.parameter_mode, args.parameter_mode,
args.data_type args.data_type
FROM information_schema.routines proc FROM information_schema.routines proc
LEFT JOIN information_schema.parameters args LEFT JOIN information_schema.parameters args
ON proc.specific_schema = args.specific_schema ON proc.specific_schema = args.specific_schema
AND proc.specific_name = args.specific_name AND proc.specific_name = args.specific_name
WHERE proc.routine_schema not in ('pg_catalog', 'information_schema') WHERE proc.routine_schema not in ('pg_catalog', 'information_schema')
AND proc.routine_type = 'PROCEDURE' AND proc.routine_type = 'PROCEDURE'
AND proc.routine_name = '${routine}' AND proc.routine_name = '${routine}'
AND proc.specific_schema = '${schema}' AND proc.specific_schema = '${schema}'
ORDER BY procedure_schema, ORDER BY procedure_schema,
specific_name, specific_name,
procedure_name, procedure_name,
args.ordinal_position args.ordinal_position
`; `;
const results = await this.raw(sql); const results = await this.raw(sql);
@ -705,25 +705,25 @@ export class PostgreSQLClient extends AntaresCore {
} }
const sql = `SELECT proc.specific_schema AS procedure_schema, const sql = `SELECT proc.specific_schema AS procedure_schema,
proc.specific_name, proc.specific_name,
proc.routine_name AS procedure_name, proc.routine_name AS procedure_name,
proc.external_language, proc.external_language,
args.parameter_name, args.parameter_name,
args.parameter_mode, args.parameter_mode,
args.data_type args.data_type
FROM information_schema.routines proc FROM information_schema.routines proc
LEFT JOIN information_schema.parameters args LEFT JOIN information_schema.parameters args
ON proc.specific_schema = args.specific_schema ON proc.specific_schema = args.specific_schema
AND proc.specific_name = args.specific_name AND proc.specific_name = args.specific_name
WHERE proc.routine_schema not in ('pg_catalog', 'information_schema') WHERE proc.routine_schema not in ('pg_catalog', 'information_schema')
AND proc.routine_type = 'FUNCTION' AND proc.routine_type = 'FUNCTION'
AND proc.routine_name = '${func}' AND proc.routine_name = '${func}'
AND proc.specific_schema = '${schema}' AND proc.specific_schema = '${schema}'
ORDER BY procedure_schema, ORDER BY procedure_schema,
specific_name, specific_name,
procedure_name, procedure_name,
args.ordinal_position args.ordinal_position
`; `;
const results = await this.raw(sql); const results = await this.raw(sql);

View File

@ -227,7 +227,7 @@
<h4>{{ appName }}</h4> <h4>{{ appName }}</h4>
<p> <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> <a class="c-hand" @click="openOutside('https://github.com/Fabio286/antares')">GitHub</a> | <a class="c-hand" @click="openOutside('https://antares-sql.app/')">Website</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> <small>{{ $t('message.madeWithJS') }}</small>
</p> </p>

View File

@ -77,6 +77,9 @@
class="form-select text-uppercase" class="form-select text-uppercase"
style="width: 0;" style="width: 0;"
> >
<option v-if="localOptions.returns === 'VOID'">
VOID
</option>
<optgroup <optgroup
v-for="group in workspace.dataTypes" v-for="group in workspace.dataTypes"
:key="group.group" :key="group.group"

View File

@ -47,7 +47,7 @@
<BaseLoader v-if="isLoading" /> <BaseLoader v-if="isLoading" />
<label class="form-label ml-2">{{ $t('message.functionBody') }}</label> <label class="form-label ml-2">{{ $t('message.functionBody') }}</label>
<QueryEditor <QueryEditor
v-if="isSelected" v-show="isSelected"
ref="queryEditor" ref="queryEditor"
:value.sync="localFunction.sql" :value.sync="localFunction.sql"
:workspace="workspace" :workspace="workspace"