diff --git a/packages/types/dbinfo.d.ts b/packages/types/dbinfo.d.ts index 680bbb236..1b9776a12 100644 --- a/packages/types/dbinfo.d.ts +++ b/packages/types/dbinfo.d.ts @@ -121,6 +121,7 @@ export interface ViewInfo extends SqlObjectInfo { export interface ParameterInfo { objectId?: string | number; parentObjectId?: string | number; + routineName?: string; pureName: string; dataType: string; fullDataType: string; diff --git a/plugins/dbgate-plugin-postgres/src/backend/Analyser.js b/plugins/dbgate-plugin-postgres/src/backend/Analyser.js index 84b67a858..a7633fc61 100644 --- a/plugins/dbgate-plugin-postgres/src/backend/Analyser.js +++ b/plugins/dbgate-plugin-postgres/src/backend/Analyser.js @@ -144,6 +144,8 @@ class Analyser extends DatabaseAnalyser { this.feedback({ analysingMessage: 'Loading routines' }); const routines = await this.analyserQuery('routines', ['procedures', 'functions']); + const routineParametersRows = await this.analyserQuery('proceduresParameters'); + this.feedback({ analysingMessage: 'Loading indexes' }); const indexes = this.driver.__analyserInternals.skipIndexes ? { rows: [] } @@ -191,6 +193,42 @@ class Analyser extends DatabaseAnalyser { columnName: x.column_name, })); + const procedurePerameters = routineParametersRows.rows + .filter(i => i.routine_type == 'PROCEDURE') + .map(i => ({ + objectId: 'procedures:' + i.specific_schema + '.' + i.routine_name + '@' + i.pure_name, + routineName: i.routine_name, + pureName: i.pure_name, + dataType: i.data_type, + fullDataType: i.data_type, + isOutputParameter: i.is_output_parameter, + })); + + const procedureNameToParameters = procedurePerameters.reduce((acc, row) => { + if (!acc[row.routineName]) acc[row.routineName] = []; + acc[row.routineName].push(row); + + return acc; + }, {}); + + const fucntionPerameters = routineParametersRows.rows + .filter(i => i.routine_type == 'FUNCTION') + .map(i => ({ + objectId: 'functions:' + i.specific_schema + '.' + i.routine_name + '@' + i.pure_name, + routineName: i.routine_name, + pureName: i.pure_name, + dataType: i.data_type, + fullDataType: i.data_type, + isOutputParameter: i.is_output_parameter, + })); + + const functionNameToParameters = fucntionPerameters.reduce((acc, row) => { + if (!acc[row.routineName]) acc[row.routineName] = []; + acc[row.routineName].push(row); + + return acc; + }, {}); + const res = { tables: tables.rows.map(table => { const newTable = { @@ -281,6 +319,7 @@ class Analyser extends DatabaseAnalyser { schemaName: proc.schema_name, createSql: `CREATE PROCEDURE "${proc.schema_name}"."${proc.pure_name}"() LANGUAGE ${proc.language}\nAS\n$$\n${proc.definition}\n$$`, contentHash: proc.hash_code, + parameters: procedureNameToParameters[proc.pure_name], })), functions: routines.rows .filter(x => x.object_type == 'FUNCTION') @@ -290,6 +329,7 @@ class Analyser extends DatabaseAnalyser { pureName: func.pure_name, schemaName: func.schema_name, contentHash: func.hash_code, + parameters: functionNameToParameters[func.pure_name], })), }; diff --git a/plugins/dbgate-plugin-postgres/src/backend/sql/index.js b/plugins/dbgate-plugin-postgres/src/backend/sql/index.js index 53a858ab5..b3f338646 100644 --- a/plugins/dbgate-plugin-postgres/src/backend/sql/index.js +++ b/plugins/dbgate-plugin-postgres/src/backend/sql/index.js @@ -14,6 +14,7 @@ const indexcols = require('./indexcols'); const uniqueNames = require('./uniqueNames'); const geometryColumns = require('./geometryColumns'); const geographyColumns = require('./geographyColumns'); +const proceduresParameters = require('./proceduresParameters'); const fk_keyColumnUsage = require('./fk_key_column_usage'); const fk_referentialConstraints = require('./fk_referential_constraints'); @@ -39,4 +40,5 @@ module.exports = { uniqueNames, geometryColumns, geographyColumns, + proceduresParameters, }; diff --git a/plugins/dbgate-plugin-postgres/src/backend/sql/proceduresParameters.js b/plugins/dbgate-plugin-postgres/src/backend/sql/proceduresParameters.js new file mode 100644 index 000000000..7a275e6e9 --- /dev/null +++ b/plugins/dbgate-plugin-postgres/src/backend/sql/proceduresParameters.js @@ -0,0 +1,27 @@ +module.exports = ` +SELECT + proc.specific_schema AS specific_schema, + proc.routine_name AS routine_name, + proc.routine_type as routine_type, + args.parameter_name AS pure_name, + args.parameter_mode, + args.data_type AS data_type, + args.ordinal_position AS parameter_index, + CASE + WHEN args.parameter_mode IN ('OUT', 'INOUT') THEN TRUE + ELSE FALSE + END AS is_output_paramter +FROM + information_schema.routines proc +LEFT JOIN + information_schema.parameters args + ON proc.specific_schema = args.specific_schema + AND proc.specific_name = args.specific_name +WHERE + proc.routine_schema NOT IN ('pg_catalog', 'information_schema') -- Exclude system schemas + AND proc.routine_type IN ('PROCEDURE', 'FUNCTION') -- Filter for procedures +ORDER BY + specific_schema, + routine_name, + args.ordinal_position; +`;