Хост Postgres
ХНазначение: Обеспечивает работу с PostgreSQL через Oracle-совмест Postgres построен на базимые интерфреймворкасы. @morphcluster/core и пПредоставляет доступ к базе данных PostgreSQL в стиле, совместимом с Oracle (через адаптер). Он состоит из нескольких внутренних сервисов, каждый из которых выполняет свою роль: загрузкау метаданных функций, выполнение запросов, управление пуломы соединений, пкоддроткиержка и длинныхе транзакцийи, нотификации и утилиты генерации обёрток. Включает адаптеры, скрывающие различия между Oracle и PostgreSQL.
Пакет предназначен для работы в составед MorphCluster‑приломлжения (например, Supervisor) и использует общие сервисы: DbServices, RegistryHelper, GlobalServices и тестовые инструменты.д.
Точка входа (src/index.mjs)
export default {
name: "Postgres",
config,
clients: {},
services: {
DbServices, PgFunctions, OraFunctions, PgPool, OraQueries,
PgTransactions, PgTools, PgNotify, OraLongTransactions,
OraQueriesPool, OLTTest, OraAdpTest
}
}
Все сервисы наследуют ServiceRequire и регистрируются в ServiceHost с именем . "Postgres"Конфигурация по умолчаОнию определенбща в src/config.mjs и можеют быть переопределенася через механизм зависимостей () и прямые вызовы методов друг друга.CommonRegistryrequirements
СОсновные сервисы
1. PgFunctions
НФазначениейл: src/pg-queries/pg-functions/index.mjs
Загружает и хранит метаданные о всех функциях и /процедурах PostgreSQL из системногоых таблиц PostgreSQL и каталога (pg_proc). Пэширедоставляует мих. Используетося дыругими сервисами для поиска функций по имени и пространству имён.
НЗависледуимости: нет
Ключевые методы:
-
reload()– перечитывает функции из БД (вызывается при старте). -
find({namespace, name})– поиск функции по схеме и имени. -
findByName({name})– поиск только по имени (менее точно).
2. OraFunctions
Файл: ServiceRequiresrc/ora-adapter/ora-functions/index.mjs
Представляет функции PostgreSQL в «оракул-подобном» виде: пакеты и процедуры. Использует PgFunctions для получения сырых метаданных и конвертирует их в формат, привычный для Oracle-клиентов.
Зависимости (requirements): отсутстPgFunctions
Ключевуютые (использумет только config.common)
Конфигурацияды:
-
–common.postgresUrilist()строка подключения к PostgreSQL common.timeZone– часовой пояс (например,'Europe/Moscow')
Методы (запросы):
| | | getPackage({packageName}) – список функций |
| – | | |
| | |
Структура FuncRec:
{
oid: number; // OID функции name:(параметры, string;типы, //направления).
reload() – обновляет данные, перезагружая PgFunctions.
3. PgPool
Файл: src/pg-queries/pg-pool/index.mjs
Пул «коротких» соединений с PostgreSQL. Каждый запрос выполняется в отдельной транзакции (BEGIN → COMMIT/ROLLBACK). Используется сервисами OraQueries для быстрых запросов.
Зависимости: PgFunctions, RegistryHelper
Управление через CommonRegistry:
-
pgQueryPool.connectionCount – размер пула (по умолчанию 0 = отключен).
Методы:
-
execSql({sql, values, session}) – выполнить SQL.
-
execFunc({namespace, funcName, params, session}) – выполнить функцию.
-
reconnectAll() – пересоздать все соединения.
-
state() – текущий статус соединений (для OraQueriesPool).
-
reload() – инициализация ссылок на служебные функции kind: string; // 'f' - функция(set_user_id, 'p' - процедура
nsp: string; // Пространство имён (схемаwrite_error_log)
result: string|null; // Тип возвращаемого значения
args: Array<{
name: string;
isOut: boolean;
hasDefault: boolean;
type: string | null;
}>;
}
Жизненный цикл:
При старте автоматически вызываетreload().При вызовеreload()подключается к БД, запрашиваетpg_typeи список функций, разбирает аргументы с помощью.ArgumentParser
Особенности:
ИУстанавливает контекст пользователя черезaccounts.set_user_id.- Лог
норируетсхемыошибки в таблицуpg_catalogи.information_schemalogs.write_error_log Для разбора аргуменАвтовматическииспереподкльзуючаетсявстпроенный парсерArgumentParser, которыйи обрабатываетхс(тандаймертный вывод).pg_get_function_arguments
4. Сервис OraFunctions
PgTransactions
НФазначениейл: Пsrc/pg-queries/pg-transactions/index.mjs
Упредоставляет длинфоными трмацию о фунзакцияхми. PostgreSQLВ в нотацличие Oracle (адаптируеот типыPgPool, соедимнение удержива, параметры). Используется отклирытым ментжду вызовами, поддержидвающется ручное управлениме (BEGIN, выполнение Oracle-нескольких запросовместимый, интерфейсCOMMIT/ROLLBACK).
Зависимости: ["PgFunctions"]
Конфигурация:
disableAutoload – если , trueRegistryHelperне вызываетDbServices, reload()PgFunctions
Упри старте (по умолчанию false).
Методы (запросы):
| | | |
| | | |
| | | |
| | |
Структура параметра функции в ответе getFunc:
{
pos: number; // Позиция параметра
name: string|null; // Имя
type: string; // Oracle-тип (VARCHAR2, NUMBER, CURSOR и т.д.)
out: boolean; // Является ли OUT-параметром
IN_OUT: "IN"|"OUT";// Строковое представление направления
required: boolean; // Обязательность (нет значения по умолчанию)
}
Особенности:
Преобразует PG-типы в Oracle-типы с помощьюoraUtils.convertType.Игнорирует функции из служебных схем.Все имена схем и функций приводятся к верхнему регистру.
Сервис PgPool
Назначение: Управляет пулом простых (не транзакционных) соединений с PostgreSQL. Выполняет SQL-запросы и вызовы функций/процедур. Поддерживает очередьз запросов с автоматическим переподключением и записью ошибок в лог.
Зависимости: ["PgFunctions", "RegistryHelper"]
Конфигурация:CommonRegistry:
-
–common.postgresUriPgTransactions.idleTimeoutстрока подключения common.timeZone– часовой поясpgQueryPool.connectionCount– количество соединений в пуле (изCommonRegistry, схемаregistrySchema)
Методы (запросы):
| | | |
| | | |
| | | |
Дополнительно:
getState()– не запрос, а метод для получения состояния пула (возвращает массив объектов сidиstatusкаждого соединения).
Жизненный цикл:
Приstart()создаёт подписку на изменения реестра черезRegistryHelper.onDataChanged, при изменении пересоздаёт пул.Приstop()отключает все соединения и очищаеттаймер переподключения.
Внаутр беннздее устройство:
Пул состоит из объектовPgConnection.Запросы помещаются в очередьqueueи обрабатываются последовательно с помощьюprocessQueue().При ошибке соединение переподключается автоматически (до 3 попыток).Для установки контекста пользователя вызываетсяcarabimeta.set_user_id(userId)перед каждым запросом.Ошибки запросов логируются в БД через функциюlogs.write_error_log.
Формат возвращаемых данных:
PgConnectionвозвращает результаты в виде массива{paramName, type, value}.Типы данных преобразуются черезPgFormats.formatValue().
Сервис PgTransactions
Назначение: Предоставляет механизм длинных транзакций (long transactions) с состоянием, возможностью выполнения нескольких запросов в одной транзакции, коммитом/откатом и фетчем курсоров.
Зависимости: ["RegistryHelper", "DbServices", "PgFunctions"]
Конфигурация (из мс)CommonRegistry:
- .
-
PgTransactions.cleanTimeout–время в мс,через сколько очищатороеь закрытые транзакции (мс).
Внудаляютсяренний из пукла (по умолчанию 600000)
PgTransactions.idleTimeoutPGTPool PGTransaction. Каждая транзакция имеет created умолчанию→ 60000)Методы (внешние черезапросы OraLongTransactions):
| | | trxId.
|
| execFunc({ | | |
| | | – в транзакции | .
| | | getExecResult({trxId}) – получи |
| | | |
| | | |
| | | |
| | |
Внутреннее устройство:
Использует пулPGTPool, который управляет наборомPGTransaction.Каждая транзакция (PGTransaction) проходит через состояния: created → connecting → ready → executing → executed → (fetching) → closing → closed.Транзакция начинается сBEGIN, выполняет запросы, и завершаетсяCOMMITилиROLLBACK.Поддерживается работа с курсорами (refcursor):после выполнения (блокирующий).-
fetch({trxId, count})– дочитать строки курсора. -
commit({trxId})/rollback({trxId})– завершить транзакцию. -
poolStatus()– состояние всех транзакций.
5. PgTools
Файл: src/pg-queries/pg-tools/index.mjs
Вспомогательный сервис, создающий функциию, возвращающей курсор, можно вызыватью TABLE(.fetch
errorgetExecResult.logs.write_error_logФормат результата getExecResult:
[
{
paramName: string;
type: string; // PG-тип
value: any; // для скалярных
columns?: [string, string][]; // для курсоров
}
]
Важно: Все методы, изменяющие состояние транзакции, являются асинхронными и не блокируют вызывающий поток (кроме getExecResult и fetch, которые ожидают готовности результата).
Сервис PgTools
Назначение: Утилита для генерации заготовки функции, возвращающей , на основе существующей функции, возвращающей TABLE.refcursorREFCURSOR
ЗУпрощависимости: отсутствуюет (толькомиграцию config)с Oracle.
Методы (запросы):
| funcTableFromRefcursor({funcFrom, funcTo}) | |
Параметры:
funcFrom– строкаё видаschema.func_name(args)(например,public.my_func(123))funcTo– полное имя новой функции (по умолчаниюschema.func_name_table)
Пример использования:
{
"funcFrom": "public.my_cursor_func(42)",
"funcTo": "public.my_table_func"
}
Создаст функцию public.my_table_func(...) RETURNS TABLE(...) на основе структуры курсора.
Особенности:
ВыполняетFETCH 0для получения структуры курсора без перемещения.Автоматически преобразует типы черезpg_type.Требует прав администратора (needAdmin: true)БД.
Сервис6. PgNotify
НФазначениейл: Обsrc/pg-queries/pg-notify/index.mjs
Респечаливазует механизм подписки на асинхронныех уведомленияй PostgreSQL (LISTEN/NOTIFY). УПоддерживает подписку на каналы, перепомдключенияе и единоставляются через событие onNotify.
Зависимости: []
Конфигурация:
common.postgresUri – строка подключения.
Методы (запросы):
| | | |
| | | |
| | | |
| | |
События:
onNotify | | (полезная нагру | JSON).
ЖизнМеннтодый цикл:
При старте подключается к PostgreSQL черезPgNotifyConnectionsubscribe({channelName})и/восстанавливает все активные подпискиunsubscribe({channelName}).ПриостановкеisConnected()корректно отключается.Встроенный таймер (ReconnectTimer) каждые 5 секунд– проверяетка соединениея.-
getSubscriptions()– списокпереактивных подписоключается при обрыве.
7. OraQueries
Файл: src/ora-adapter/ora-queries/index.mjs
Особенносвной адапти:
Идентификаторы каналов экранируютсядлябезопасного исвыпользования в SQL.Уведомленияав«коротоматических»парсятся из JSON (если возможно), иначе передаётся строка.
Сервис OraQueries
Назначение: ВыOracle-полдобняетых запросов. Принимает вызовы квида PostgreSQL вpackage.func с именованными параметрамиле, Oracle. Ппреобразует именованные параметры в позиционные, конвертирует типы результатов, валидирует вызовых через DbServices в реальные вызовы PostgreSQL и исполняет через PgPool.
Зависимости: , ["PgPool"PgPool"DbServices"]DbServices
Методы (запросы):
execFunc(...) – явное указание пакета и функции.execSql({sql, params, session}) – выпо | лнение :param на поз | ||
|---|---|---|---|
| | | .
resetUser() |
| | | |
| | | |
| | | |
| | (не реализованы) | |
| |
Возвращаемое значение:
{
results: Array<{
paramName: string; // имя выходного параметра (в верхнем регистре)
type: string; // Oracle-тип: "VARCHAR2", "NUMBER", "CURSOR", "CLOB", "DATE"...
value: any; // значение, для курсоров - {columns, list}
}>
}
Особенности:
Автоматически преобразует именованные параметры (:name) в позиционные ($1) с помощьюoraUtils.convertNameToPos.Конвертирует PG-типы в Oracle-типы (convertType).Для курсоров преобразует структуру черезconvertColumns.Логирует результат с ограничением размера (если заданlimitLogger).В случае отсутствия функции вPgFunctions, записывает информацию о недостающем вызове вlogs.write_error_logи выбрасывает.ComplexError
Сервис8. OraLongTransactions
НФазначениейл: Предsrc/ora-adapter/ora-long-transactions/index.mjs
Аналоставляетг Oracle-сOraQueries, новместимый интерфейс для длинных транзакций. ЯвИсполяьзуется обёрткой над PgTransactions, адаптируля удержания соединения. Поддерживает многошаговые сценарии: мсоздать транзакцию, выполнить нетскодлько запросов и, получить результаты, зафиксироваметрыь.
Зависимости: , ["PgTransactions"PgTransactions"DbServices"]DbServices
Методы:
-
create({session})– создать транзакцию (возвращаетoltId). -
execFunc({oltId, package, func, params, session})/execSql(...). -
getExecResult({oltId})– получить результат выполненного запроса. -
fetch({oltId, count})– получить строки из открытого курсора. -
commit({oltId})/rollback({oltId}). -
poolStatus()– состояние пула длинных транзакций.
9. OraQueriesPool
Файл: src/ora-adapter/ora-queries-pool/index.mjs
Административный интерфейс для просмотра состояния пула PgPool.
Зависимости: PgPool, DbServices
Методы:
-
state()– возвращает детализацию по соединениям (количество, статусы).
Тестовые сервисы
OLTTest (src/ora-adapter/ora-long-transactions/test/index.mjs)
OraAdpTest (src/ora-adapter/test/index.mjs)
Предназначены для ручного тестирования длинных транзакций и обычных SQL-запросов. Содержат примеры вызовов и могут быть удалены в продуктовой среде.
Вспомогательные классы и утилиты
ArgumentParser
Распарсивает строку аргументов функции PostgreSQL (из pg_get_function_arguments) в структурированный вид: { name, type, isOut, hasDefault }.
PgFormats
Отвечает за:
- Конвертацию типов полей при чтении из БД (числа, даты).
- Формирование SQL-вызова функции с именованными параметрами (
"arg" => $1). - Проверку кодов ошибок PostgreSQL (отделение логических ошибок от проблем соединения).
PgConnection
Управляет одним подключением для «коротких» запросов (PgPool). Выполняет SQL в транзакции (BEGIN → запрос → COMMIT/ROLLBACK). Обрабатывает refcursor, загружая данные из курсора.
PGTransaction
Класс одной длинной транзакции. Хранит состояние, управляет жизненным циклом, поддерживает выполнение SQL и функций, фетч курсора. Используется внутри PGTPool.
PGTPool
Менеджер пула PGTransaction. Создаёт транзакции по требованию, отслеживает таймауты, автоматически подчищает закрытые соединения, пишет ошибки в лог БД.
PgNotifyConnection
Подключение для LISTEN/NOTIFY. Инкапсулирует логику переподключения и подписки.
Конфигурация
Файл config.mjs содержит параметры по умолчанию:
-
NatsConnection.queue="pgqueries",timeout= 60000 -
NatsPublisher.interval= 60000
Остальные настройки берутся из config.common и CommonRegistry:
| Параметр | Описание | ||
|---|---|---|---|
| | |
С |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | |
Особенности:
ПараметрыexecFuncпринимаютpackageиfuncвместоnamespace/funcName.При выполнении SQL черезexecSql, параметры могут быть переданы в нотации Oracle (:paramName), они автоматически конвертируются в позиционные черезoraUtils.convertNameToPos.Все выходные параметры и курсоры приводятся к Oracle-типам.
Сервис OraQueriesPool
Назначение: Управление пулом обычных (не транзакционных) сессий OraQueries. Предоставляет административные методы для мониторинга и управления.
Зависимости: ["PgPool", "DbServices"]
Методы (запросы):
| | | |
| | ||
| |
Формат state:
{
"result": [
{
"name": "main",
"pid": 0,
"sessionsCount": 4,
"workedSessions": [{"id": "pool_0", "status": "exec"}, ...],
"queryQueue": [],
"killerSession": null,
"usage": { ... }
}
]
}
Особенности:
Фактически является административной панелью дляPgPool.МетодыrecreateиbrakeQueryпока не реализованы (выбрасывают ошибку).
Общая архитектура и зависимости
graph TD
subgraph "Внешние сервисы"
DbServices[DbServices]
CommonRegistry[CommonRegistry]
RegistryHelper[RegistryHelper]
end
subgraph "Сервисы PostgreSQL"
PgFunctions --> |загрузка метаданных| PostgreSQL
OraFunctions --> PgFunctions
PgPool --> PgFunctions
PgPool --> RegistryHelper
PgTransactions --> PgFunctions
PgTransactions --> RegistryHelper
PgTransactions --> DbServices
PgTools --> PostgreSQL
PgNotify --> PgNotifyConnection --> PostgreSQL
OraQueries --> PgPool
OraQueries --> DbServices
OraLongTransactions --> PgTransactions
OraLongTransactions --> DbServices
OraQueriesPool --> PgPool
OraQueriesPool --> DbServices
end
RegistryHelper --> CommonRegistry
Все соединения с PostgreSQL используют строку подключения из конфигурации common.postgresUri. Настройки пулов и таймаутов управляются через CommonRegistry, изменения вступают в силу после перезагрузки пула (для PgPool — автоматически при изменении схемы).
Конфигурация по умолчанию
Файл config.mjs:
{
"NatsConnection": {
"queue": "pgqueries",
"timeout": 60000
},
"NatsPublisher": {
"interval": 60000
}
}
Дополнительные параметры (из config.common):
postgresUri– строка подключения кPostgreSQL.PostgreSQL
-
common.timeZone– чЧасовой пояс для сессий (нБДpgQueryPool.connectionCountРазмер пула коротких запросов (в CommonRegistry)PgTransactions.idleTimeoutТаймаут простоя транзакции (мс) PgTransactions.cleanTimeoutИнтервал очистки закрытых транзакций (мс) Все сервисы получают конфигурацию через стандартный механизм
Configи могут динамически обновляться через подписку наCommonRegistry.
Схема взаимодействия
-
Загрузка метаданных
PgFunctionsпри старте загружает список всех функций PostgreSQL.OraFunctionsна его основе строит «оракул-подобное» представление. -
Регистрация в DbServices Сер
,вис(из внешнего пакета) хранит каталог всех доступных вызовов (жёсткие и мягкие).'Europe/Moscow'DbServicesOraQueriesиOraLongTransactionsиспользуютDbServices.getOraSql()для генерации PL/SQL‑блока с подстановкой параметров. -
Выполнение запросов
-
Короткие запросы:
OraQueries.exec→DbServices.getOraSql→ формирование вызова →PgPool.execFunc→PgConnection. -
Длинные транзакции:
OraLongTransactions.create→PgTransactions.create(создаётсяPGTransaction) → далееexecFunc/execSql→ по окончанииgetExecResult+commit/rollback.
-
Короткие запросы:
-
Нотификации
PgNotifyслушает каналы PostgreSQL и генерирует событиеonNotify, на которое могут подписываться другие сервисы. -
Администрирование
OraQueriesPoolи методpoolStatusу длинных транзакций дают мониторинг соединений.
Примечания
по использованиюБольшинство сервисов требуют наличияDbServicesдДляпроверки и выполнения хранимогокода.DbServices– это внешний сервис, который должен быть доступен в кластере(предктноставляет запросыgetOraSqlи др.).Дляй работыснеобходлинными транзакциями используйтеOraLongTransactions,а неастройкаи наPgTransactionscommon.postgresUriпряличие в БД схемую, чтобыобеспечить совместимость с Oracle-клиентами.Административные методы защищены флагомneedAdmin: truecarabimeta, который требует аутентифицированной сессиис правоцедурамиадминистратора.Все ошибки базы данных логируются вset_user_id,logs.write_error_log(если функция доступна и не отключена флагомnoLog).
Данный хост является ключевым компонентом для миграции с Oracle на PostgreSQL, обеспечивая прозрачную работу приложений, написанных под Oracle. -