ЦИТК-979 - Установка атрибутов сущности (сервер)

This commit is contained in:
Mikhail Chechnev 2025-08-14 14:17:25 +03:00
parent 4115961742
commit fa00940776
2 changed files with 118 additions and 37 deletions

View File

@ -72,7 +72,7 @@ create or replace package PKG_P8PANELS_QE as
(
NRN in number, -- Рег. номер запроса
SID in varchar2, -- Идентификатор сущности
CATTRS in clob -- Сериализованное описание атрибутов сущности
CATTRS in clob -- Сериализованное описание атрибутов сущности (BASE64 XML)
);
/* Добавление связи в запрос */
@ -208,7 +208,6 @@ create or replace package body PKG_P8PANELS_QE as
RENTS PKG_P8PANELS_QE_BASE.TENTS; -- Коллекция существующих сущностей
RENT PKG_P8PANELS_QE_BASE.TENT; -- Удаляемая сущность
RRLS PKG_P8PANELS_QE_BASE.TRLS; -- Коллекция существующих связей
RRLS_TMP PKG_P8PANELS_QE_BASE.TRLS; -- Буфер для коллекции удаляемых связей
begin
/* Провим права доступа */
PKG_P8PANELS_QE_BASE.QUERY_ACCESS_MODIFY(NRN => NRN, SUSER => UTILIZER());
@ -234,20 +233,8 @@ create or replace package body PKG_P8PANELS_QE as
if ((RENT.RATTRS is not null) and (RENT.RATTRS.COUNT > 0)) then
for I in RENT.RATTRS.FIRST .. RENT.RATTRS.LAST
loop
/* Если атрибут есть в связях (как источник или как приёмник) */
for J in 0 .. 1
loop
RRLS_TMP := PKG_P8PANELS_QE_BASE.TRLS_LIST_BY_ST(RRLS => RRLS,
SSOURCE_TARGET => RENT.RATTRS(I).SID,
NLIST_TYPE => J);
/* То связь должна быть удалена */
if ((RRLS_TMP is not null) and (RRLS_TMP.COUNT > 0)) then
for K in RRLS_TMP.FIRST .. RRLS_TMP.LAST
loop
PKG_P8PANELS_QE_BASE.TRLS_REMOVE(RRLS => RRLS, SID => RRLS_TMP(K).SID);
end loop;
end if;
end loop;
/* Удаляем связи в которых он задействован */
PKG_P8PANELS_QE_BASE.TRLS_CLEANUP_BY_ATTR(RRLS => RRLS, SATTR_ID => RENT.RATTRS(I).SID);
end loop;
end if;
/* Сохраняем обновленный набор сущностей */
@ -299,13 +286,57 @@ create or replace package body PKG_P8PANELS_QE as
/* Установка состава атрибутов сущности */
procedure QUERY_ENT_ATTRS_SET
(
NRN in number, -- Рег. номер запроса
SID in varchar2, -- Идентификатор сущности
CATTRS in clob -- Сериализованное описание атрибутов сущности
NRN in number, -- Рег. номер запроса
SID in varchar2, -- Идентификатор сущности
CATTRS in clob -- Сериализованное описание атрибутов сущности (BASE64 XML)
)
is
RQ P8PNL_QE_QUERY%rowtype; -- Запись запроса
RENTS PKG_P8PANELS_QE_BASE.TENTS; -- Коллекция существующих сущностей
NENT_INDEX PKG_STD.TNUMBER; -- Индекс изменяемой сущности
RATTRS PKG_P8PANELS_QE_BASE.TATTRS; -- Коллекция полученных атриубтов
RRLS PKG_P8PANELS_QE_BASE.TRLS; -- Коллекция существующих связей
begin
null;
/* Провим права доступа */
PKG_P8PANELS_QE_BASE.QUERY_ACCESS_MODIFY(NRN => NRN, SUSER => UTILIZER());
/* Читаем запись запроса */
RQ := PKG_P8PANELS_QE_BASE.QUERY_GET(NRN => NRN);
/* Читаем существующие сущности */
RENTS := PKG_P8PANELS_QE_BASE.QUERY_ENTS_GET(CENTS => RQ.ENTS);
/* Читаем свзяи */
RRLS := PKG_P8PANELS_QE_BASE.QUERY_RLS_GET(CRLS => RQ.RLS);
/* Находим изменяемую сущность */
NENT_INDEX := PKG_P8PANELS_QE_BASE.TENTS_INDEX_BY_ID(RENTS => RENTS, SID => SID);
if (NENT_INDEX is null) then
P_EXCEPTION(0,
'Сущность с идентификатором "%s" в запросе "%s" не определена.',
COALESCE(SID, '<НЕ УКАЗАН>'),
TO_CHAR(NRN));
end if;
/* Десериализуем новый набор атрибутов */
RATTRS := PKG_P8PANELS_QE_BASE.TATTRS_FROM_XML_BASE64(CXML => CATTRS,
SCHARSET => PKG_CHARSET.CHARSET_UTF_(),
BADD_ROOT => true);
/* Сбросим текущие атрибуты сущности */
RENTS(NENT_INDEX).RATTRS := PKG_P8PANELS_QE_BASE.TATTRS();
/* Наполним полученными и зачистим связи */
if (RATTRS is not null) and (RATTRS.COUNT > 0) then
for I in RATTRS.FIRST .. RATTRS.LAST
loop
/* Если атрибут используется - кладём в обновленную коллекцию атрибутов сущности */
if (RATTRS(I).NUSE = 1) then
RENTS(NENT_INDEX).RATTRS.EXTEND();
RENTS(NENT_INDEX).RATTRS(RENTS(NENT_INDEX).RATTRS.LAST) := RATTRS(I);
else
/* Атрибут не используется - необходимо очистись связи в которых он задействован */
PKG_P8PANELS_QE_BASE.TRLS_CLEANUP_BY_ATTR(RRLS => RRLS, SATTR_ID => RATTRS(I).SID);
end if;
end loop;
end if;
/* Сохраняем обновленный набор сущностей */
PKG_P8PANELS_QE_BASE.QUERY_ENTS_SET(NRN => RQ.RN, RENTS => RENTS);
/* Сохраняем обновленный набор связей */
PKG_P8PANELS_QE_BASE.QUERY_RLS_SET(NRN => RQ.RN, RRLS => RRLS);
end QUERY_ENT_ATTRS_SET;
/* Добавление связи в запрос */

View File

@ -1,9 +1,5 @@
create or replace package PKG_P8PANELS_QE_BASE as
/* Константы - Типы сущностей */
SENT_TYPE_TABLE constant PKG_STD.TSTRING := 'TABLE'; -- Таблица
SENT_TYPE_VIEW constant PKG_STD.TSTRING := 'VIEW'; -- Представление
/* Типы данных - Атрибут сущности */
type TATTR is record
(
@ -46,6 +42,14 @@ create or replace package PKG_P8PANELS_QE_BASE as
/* Типы данных - Коллекция отношений */
type TRLS is table of TRL;
/* Десериализация коллекции атрибутов сущности (из BASE64) */
function TATTRS_FROM_XML_BASE64
(
CXML in clob, -- XML-описание коллекции атрибутов сущности (BASE64)
SCHARSET in varchar2, -- Кодировка, в которой XML-данные были упакованы в BASE64
BADD_ROOT in boolean := false -- Флаг необходимости добавления корневого тэга (false - нет, true - да)
) return TATTRS; -- Коллекция атрибутов сущности
/* Поиск индекса сущности по идентификатору */
function TENTS_INDEX_BY_ID
(
@ -77,14 +81,6 @@ create or replace package PKG_P8PANELS_QE_BASE as
NY in number -- Координата по оси ординат
);
/* Формирование коллекции связей по источнику/приёмнику */
function TRLS_LIST_BY_ST
(
RRLS in TRLS, -- Коллекция связей
SSOURCE_TARGET in varchar2, -- Идентификатор источника/приёмкника
NLIST_TYPE in number -- Тип формирования коллекции (0 - по источнику, 1 - по приёмнику
) return TRLS; -- Сформированная коллекция
/* Добавление связи в коллекцию */
procedure TRLS_APPEND
(
@ -100,6 +96,13 @@ create or replace package PKG_P8PANELS_QE_BASE as
SID in varchar2 -- Идентификатор удялемой связи
);
/* Подчистка коллекции связей по атрибуту */
procedure TRLS_CLEANUP_BY_ATTR
(
RRLS in out nocopy TRLS, -- Изменяемая коллекция
SATTR_ID in varchar2 -- Идентификатор атрибута
);
/* Считывание записи запроса */
function QUERY_GET
(
@ -220,6 +223,10 @@ end PKG_P8PANELS_QE_BASE;
/
create or replace package body PKG_P8PANELS_QE_BASE as
/* Константы - Типы сущностей */
SENT_TYPE_TABLE constant PKG_STD.TSTRING := 'TABLE'; -- Таблица
SENT_TYPE_VIEW constant PKG_STD.TSTRING := 'VIEW'; -- Представление
/* Константы - Теги для сериализации */
STAG_DATA constant PKG_STD.TSTRING := 'XDATA'; -- Данные
STAG_QUERIES constant PKG_STD.TSTRING := 'XQUERIES'; -- Запросы
@ -378,7 +385,7 @@ create or replace package body PKG_P8PANELS_QE_BASE as
RRES.NDATA_TYPE := PKG_XPATH.ATTRIBUTE_NUM(RNODE => XNODE, SNAME => SATTR_DATA_TYPE);
RRES.SAGG := PKG_XPATH.ATTRIBUTE(RNODE => XNODE, SNAME => SATTR_AGG);
RRES.SALIAS := PKG_XPATH.ATTRIBUTE(RNODE => XNODE, SNAME => SATTR_ALIAS);
RRES.NUSE := PKG_XPATH.ATTRIBUTE_NUM(RNODE => XNODE, SNAME => SATTR_SHOW);
RRES.NUSE := PKG_XPATH.ATTRIBUTE_NUM(RNODE => XNODE, SNAME => SATTR_USE);
RRES.NSHOW := PKG_XPATH.ATTRIBUTE_NUM(RNODE => XNODE, SNAME => SATTR_SHOW);
/* Освободим документ */
PKG_XPATH.FREE(RDOCUMENT => XDOC);
@ -453,8 +460,8 @@ create or replace package body PKG_P8PANELS_QE_BASE as
end if;
/* Инициализируем результат */
RRES := TATTRS();
/* Установим флаг инициализации */
if ((RENT.RATTRS is null) or (RENT.RATTRS.COUNT = 0)) then
/* Установим флаг инициализации - в сущности нет атрибутов и нас просили ограничить количество */
if (((RENT.RATTRS is null) or (RENT.RATTRS.COUNT = 0)) and (NCOUNT is not null)) then
BINIT := true;
end if;
/* Если сущность это представление */
@ -483,14 +490,14 @@ create or replace package body PKG_P8PANELS_QE_BASE as
RRES(RRES.LAST).STITLE := DMSCLVIEWSATTRS_TITLE_GET(SVIEW_NAME => RENT.SNAME,
SATTR_NAME => RRES(RRES.LAST).SNAME);
RRES(RRES.LAST).NDATA_TYPE := RVIEW_FIELD.DATA_TYPE;
/* Если ранее в сущности вообще не было атрибутов - установим флаг применения в запросе (тогда атрибут будет отображен в диаграмме) */
/* Если это инициализиция сущности - установим флаг применения в запросе (тогда атрибут будет отображен в диаграмме) */
if (BINIT) then
RRES(RRES.LAST).NUSE := 1;
RRES(RRES.LAST).NSHOW := 1;
else
RRES(RRES.LAST).NUSE := 0;
RRES(RRES.LAST).NSHOW := 0;
end if;
end if;
end if;
/* Ограничим объем коллекции если необходимо */
if (NCOUNT is not null) then
@ -576,6 +583,26 @@ create or replace package body PKG_P8PANELS_QE_BASE as
return RRES;
end TATTRS_FROM_XML;
/* Десериализация коллекции атрибутов сущности (из BASE64) */
function TATTRS_FROM_XML_BASE64
(
CXML in clob, -- XML-описание коллекции атрибутов сущности (BASE64)
SCHARSET in varchar2, -- Кодировка, в которой XML-данные были упакованы в BASE64
BADD_ROOT in boolean := false -- Флаг необходимости добавления корневого тэга (false - нет, true - да)
) return TATTRS -- Коллекция атрибутов сущности
is
CTMP clob; -- Буфер для преобразований
begin
/* Избавимся от BASE64 */
CTMP := BLOB2CLOB(LBDATA => BASE64_DECODE(LCSRCE => CXML), SCHARSET => SCHARSET);
/* Если надо - добавим корень */
if (BADD_ROOT) then
CTMP := '<' || STAG_ATTRS || '>' || CTMP || '</' || STAG_ATTRS || '>';
end if;
/* Десериализуем */
return TATTRS_FROM_XML(CXML => CTMP);
end TATTRS_FROM_XML_BASE64;
/* Формирование идентификатора сущности */
function TENT_ID_MAKE
(
@ -1063,6 +1090,29 @@ create or replace package body PKG_P8PANELS_QE_BASE as
end if;
end TRLS_REMOVE;
/* Подчистка коллекции связей по атрибуту */
procedure TRLS_CLEANUP_BY_ATTR
(
RRLS in out nocopy TRLS, -- Изменяемая коллекция
SATTR_ID in varchar2 -- Идентификатор атрибута
)
is
RRLS_TMP PKG_P8PANELS_QE_BASE.TRLS; -- Буфер для коллекции удаляемых связей
begin
/* Если атрибут есть в связях (как источник или как приёмник) */
for J in 0 .. 1
loop
RRLS_TMP := TRLS_LIST_BY_ST(RRLS => RRLS, SSOURCE_TARGET => SATTR_ID, NLIST_TYPE => J);
/* То связь должна быть удалена */
if ((RRLS_TMP is not null) and (RRLS_TMP.COUNT > 0)) then
for K in RRLS_TMP.FIRST .. RRLS_TMP.LAST
loop
TRLS_REMOVE(RRLS => RRLS, SID => RRLS_TMP(K).SID);
end loop;
end if;
end loop;
end TRLS_CLEANUP_BY_ATTR;
/* Сериализация коллекции связей */
procedure TRLS_TO_XML
(