Skip to content

Instantly share code, notes, and snippets.

@LeKovr
Created February 7, 2019 08:43
Show Gist options
  • Save LeKovr/d05727e73846b5ce4d6787d36b759e5f to your computer and use it in GitHub Desktop.
Save LeKovr/d05727e73846b5ce4d6787d36b759e5f to your computer and use it in GitHub Desktop.
Создание postgresql функции с данными из json с помощью psql
/*
Пример создания функции postgresql средствами psql.
Функция возвращает строки по ключу без обращения к таблицам
Исходные данные размещены в файле json
*/
-- содержимое файла с данными, для логов
\! cat args.json
/*
{
"index": [
{
"arg": "a_nsp",
"type": "text",
"required": false,
"anno": "Схема БД"
}
],
"func_args": [
{
"arg": "a_code",
"type": "text",
"required": true,
"anno": "Имя функции"
}
],
"func_result": [
{
"arg": "a_code",
"type": "text",
"required": true,
"anno": "Имя функции"
}
]
}
*/
-- функция создания функции
CREATE OR REPLACE FUNCTION create_func(a_name TEXT, a_type TEXT, a_json TEXT) RETURNS VOID LANGUAGE plpgsql AS $_$
BEGIN
execute format(
$__$CREATE OR REPLACE FUNCTION %I(a_code TEXT) RETURNS SETOF %I STABLE LANGUAGE sql AS
$$ select * from jsonb_populate_recordset(null::%I, %L::JSONB -> a_code)$$;
$__$, a_name, a_type, a_type, a_json
);
END;
$_$;
-- тип возвращаемых данных
CREATE TYPE arg_def AS (
arg TEXT
, type TEXT
, required BOOL
, def_val TEXT
, anno TEXT
);
-- Загружаем json в переменную
\set CMD 'cat args.json'
\set JSON `:CMD`
-- Одной строкой и компактный вариант (если есть jq)
--\set JSON `jq -c '.' < args.json`
-- создаем функцию func_args
SELECT create_func('func_args', 'arg_def', :'JSON');
-- если функция создания уже не нужна
DROP FUNCTION create_func(a_name TEXT, a_type TEXT, a_json TEXT);
-- тесты
select * from func_args('index');
/*
arg | type | required | def_val | anno
-------+------+----------+---------+----------
a_nsp | text | f | (null) | Схема БД
(1 строка)
*/
select * from func_args('func_args');
/*
arg | type | required | def_val | anno
--------+------+----------+---------+-------------
a_code | text | t | (null) | Имя функции
(1 строка)
*/
select * from func_args('func_result');
/*
arg | type | required | def_val | anno
--------+------+----------+---------+-------------
a_code | text | t | (null) | Имя функции
(1 строка)
*/
select * from func_args('unknown');
/*
arg | type | required | def_val | anno
-----+------+----------+---------+------
(0 строк)
*/
-- очистка
DROP TYPE arg_def CASCADE;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment