diff --git a/lib/postgres/index.js b/lib/postgres/index.js index bec77e0..81f1d92 100644 --- a/lib/postgres/index.js +++ b/lib/postgres/index.js @@ -51,15 +51,6 @@ module.exports = async(config) => { } } - const types = (() => { - let cache; - return async() => { - if (!cache) { - cache = (await predefinedQuery('types')).rows; - } - return cache; - }; - })(); // https://www.postgresql.org/docs/current/catalog-pg-proc.html const buildArgs = (argnames, argmodesText) => { if (!argmodesText && !argnames) { @@ -81,9 +72,14 @@ module.exports = async(config) => { }; }, {input: [], other: [], all: []}); }; - + const defaultValue = (raw) => { + // for now only 1 def val are cough + if (raw.startsWith('NULL')) { + return null; + } + return undefined; + }; const build = async() => { - const allTypes = await types(); const methods = (await predefinedQuery('methods')); return methods .filter(({schema}) => schemas.indexOf(schema) > -1) @@ -96,13 +92,20 @@ module.exports = async(config) => { inargtypes, // An array of the data types of the function arguments. This includes only input arguments (including INOUT and VARIADIC arguments), and thus represents the call signature of the function. allargtypes, // An array of the data types of the function arguments. This includes all arguments (including OUT and INOUT arguments); however, if all the arguments are IN arguments, this field will be null. Note that subscripting is 1-based, whereas for historical reasons proargtypes is subscripted from 0. argnames, // An array of the names of the function arguments. Arguments without a name are set to empty strings in the array. If none of the arguments have a name, this field will be null. Note that subscripts correspond to positions of proallargtypes not proargtypes. - argmodes // An array of the modes of the function arguments, encoded as i for IN arguments, o for OUT arguments, b for INOUT arguments, v for VARIADIC arguments, t for TABLE arguments. If all the arguments are IN arguments, this field will be null. Note that subscripts correspond to positions of proallargtypes not proargtypes. + argmodes, // An array of the modes of the function arguments, encoded as i for IN arguments, o for OUT arguments, b for INOUT arguments, v for VARIADIC arguments, t for TABLE arguments. If all the arguments are IN arguments, this field will be null. Note that subscripts correspond to positions of proallargtypes not proargtypes. + optargnames, + optargdefaults }) => { const jsName = [schema, name].join(gluePrefix); const sqlName = [`"${schema}"`, `"${name}"`].join('.'); const args = buildArgs(argnames, argmodes); const fillArgs = args.input .map((v, idx) => `$${idx + 1}`).join(','); + const oArgDefaults = (optargdefaults?.split(', ') || []); + const oArgNames = optargnames?.reduce( + (a, arg, idx) => ({...a, [arg]: defaultValue(oArgDefaults[idx])}), + {} + ) || {}; return { ...methods, /** @@ -114,6 +117,9 @@ module.exports = async(config) => { [jsName]: async(arguments, txId) => { const dynArgs = args.input.map(({name}) => { if (arguments[name] === undefined) { + if (oArgNames[name]!==undefined) { + return oArgNames[name]; + } throw SqlSe.create( 'argumentNotFound', {fn: jsName, argument: name} diff --git a/lib/postgres/sqls/methods.sql b/lib/postgres/sqls/methods.sql index 0270e5d..219e518 100644 --- a/lib/postgres/sqls/methods.sql +++ b/lib/postgres/sqls/methods.sql @@ -1,18 +1,19 @@ SELECT nspname "schema", - proname "name", - pronargs ninargs, + proname "name", + pronargs ninargs, pronargdefaults nargdefaults, prorettype rettype, proargtypes inargtypes, proallargtypes allargtypes, proargnames argnames, - proargmodes argmodes + proargmodes argmodes, + p.proargnames[pronargs-pronargdefaults+1:pronargs] optargnames, + pg_get_expr(p.proargdefaults, 0) optargdefaults FROM pg_catalog.pg_namespace n JOIN pg_catalog.pg_proc p ON p.pronamespace = n.oid WHERE - nspname not IN ('pg_catalog', 'information_schema') - + nspname not IN ('pg_catalog', 'information_schema')