create or replace package PKG_P8PANELS_SETTINGS as /* Типы данных - Настройка параметра */ type TOPTION is record ( SCODE PKG_STD.TSTRING, -- Код настройки параметра SVALUE PKG_STD.TSTRING -- Значение ); /* Типы данных - коллекция настроек параметра */ type TOPTIONS is table of TOPTION; /* Типы данных - Параметр */ type TSETTING is record ( SCODE PKG_STD.TSTRING, -- Мнемокод SNAME PKG_STD.TSTRING, -- Наименование NKIND PKG_STD.TNUMBER, -- Вид параметра SPANEL PKG_STD.TSTRING, -- Панель NCOMPANY PKG_STD.TREF, -- Рег. номер организации SAUTHID PKG_STD.TSTRING, -- Пользователь ROPTIONS TOPTIONS, -- Настройка параметра SDATA_TYPE PKG_STD.TSTRING, -- Тип данных SVALUE PKG_STD.TSTRING, -- Значение SDESC PKG_STD.TSTRING -- Описание ); /* Типы данных - Коллекция параметров */ type TSETTINGS is table of TSETTING; /* Типы данных - Панели */ type TPANEL is record ( SNAME PKG_STD.TSTRING, -- Наименование панели RSETTINGS TSETTINGS -- Настройки панели ); /* Типы данных - коллекция панелей */ type TPANELS is table of TPANEL; /* Считывание параметров */ procedure GET ( NKIND in number, -- Вид параметра SCODE in varchar2 := null, -- Мнемокод параметра (null - все) SPANEL in varchar2 := null, -- Панель NFULL in number := 0, -- Флаг включения атрибутов (0 - нет, 1 - да) COUT out clob -- Информация о параметрах ); /* Добавление параметра */ procedure PUT ( NKIND in number, -- Вид параметра CPANELS in clob -- XML-описание панелей ); /* Инициализация параметров */ procedure INIT ( NKIND in number, -- Вид параметра CPANELS in clob, -- XML-описание панелей NFULL in number := 0, -- Флаг включения в ответ атрибутов параметров (0 - нет, 1 - да) COUT out clob -- Информация о параметрах ); /* Инициализация информации о настройках панелей */ procedure PANELS_INIT ( COUT out clob -- Информация о панелях ); end PKG_P8PANELS_SETTINGS; / create or replace package body PKG_P8PANELS_SETTINGS as /* Константы - Виды параметров */ NKIND_SYSTEM constant PKG_STD.TNUMBER := 0; -- Системный NKIND_PANEL constant PKG_STD.TNUMBER := 1; -- Панельный NKIND_USER constant PKG_STD.TNUMBER := 2; -- Пользовательский /* Константы - Типы данных */ NDATA_TYPE_STR constant PKG_STD.TNUMBER := 0; -- Строковый NDATA_TYPE_NUM constant PKG_STD.TNUMBER := 1; -- Числовой NDATA_TYPE_DATE constant PKG_STD.TNUMBER := 2; -- Дата /* Константы - Теги для сериализации */ STAG_DATA constant PKG_STD.TSTRING := 'XDATA'; -- Данные STAG_PANELS constant PKG_STD.TSTRING := 'XPANELS'; -- Панели /* Константы - Атрибуты для сериализации */ SATTR_OPTIONS constant PKG_STD.TSTRING := 'options'; -- Настройки параметров SATTR_NAME constant PKG_STD.TSTRING := 'name'; -- Наименование SATTR_KIND constant PKG_STD.TSTRING := 'kind'; -- Вид параметра SATTR_PANEL constant PKG_STD.TSTRING := 'panel'; -- Панель SATTR_COMPANY constant PKG_STD.TSTRING := 'company'; -- Организация SATTR_AUTHID constant PKG_STD.TSTRING := 'authid'; -- Пользователь SATTR_DATA_TYPE constant PKG_STD.TSTRING := 'dataType'; -- Тип данных SATTR_VALUE constant PKG_STD.TSTRING := 'value'; -- Значение SATTR_DESC constant PKG_STD.TSTRING := 'desc'; -- Описание SATTR_USER_SETTINGS constant PKG_STD.TSTRING := 'userSettings'; -- Наличие пользовательских параметров /* Константы - Вспомогательные */ SPANEL_SYSTEM_NAME constant PKG_STD.TSTRING := '__P8_SYSTEM'; -- Наименование панели для системных параметров /* Конвертация типа данных в числовой формат */ function UTL_SDATA_TYPE_CONVERT ( SDATA_TYPE in varchar2 -- Тип данных (см. константы PKG_P8PANELS_VISUAL.SDATA_TYPE_*) ) return number -- Тип данных в числовом формате (см. константы NDATA_TYPE_*) is NRESULT PKG_STD.TNUMBER; -- Тип данных в числовом формате begin /* Исходим от типа данных */ case SDATA_TYPE /* Строка */ when PKG_P8PANELS_VISUAL.SDATA_TYPE_STR then NRESULT := NDATA_TYPE_STR; /* Число */ when PKG_P8PANELS_VISUAL.SDATA_TYPE_NUMB then NRESULT := NDATA_TYPE_NUM; /* Дата */ when PKG_P8PANELS_VISUAL.SDATA_TYPE_DATE then NRESULT := NDATA_TYPE_DATE; else P_EXCEPTION(0, 'Не определен тип данных параметра.'); end case; /* Возвращаем результат */ return NRESULT; end UTL_SDATA_TYPE_CONVERT; /* Конвертация типа данных в строковый формат */ function UTL_NDATA_TYPE_CONVERT ( NDATA_TYPE in number -- Тип данных в числовом формате (см. константы NDATA_TYPE_*) ) return varchar2 -- Тип данных в строковом формате (см. константы PKG_P8PANELS_VISUAL.SDATA_TYPE_*) is SRESULT PKG_STD.TSTRING; -- Тип данных в строковом формате begin /* Исходим от типа данных */ case NDATA_TYPE /* Строка */ when NDATA_TYPE_STR then SRESULT := PKG_P8PANELS_VISUAL.SDATA_TYPE_STR; /* Число */ when NDATA_TYPE_NUM then SRESULT := PKG_P8PANELS_VISUAL.SDATA_TYPE_NUMB; /* Дата */ when NDATA_TYPE_DATE then SRESULT := PKG_P8PANELS_VISUAL.SDATA_TYPE_DATE; else P_EXCEPTION(0, 'Не определен тип данных параметра.'); end case; /* Возвращаем результат */ return SRESULT; end UTL_NDATA_TYPE_CONVERT; /* Добавление информации о настройке во временную таблицу */ procedure UTL_SELECTLIST_INSERT ( NIDENT in number, -- Идентификатор процесса SAUTHID in varchar2, -- Пользователь SCONNECT_EXT in varchar2, -- Внешний идентификатор сеанса NDOCUMENT in number -- Рег. номер записи настройки ) is begin /* Добавляем настройку во временную таблицу */ insert into P8PNL_SELECTLIST (RN, IDENT, authid, SESSION_ID, CONNECT_EXT, DOCUMENT) values (GEN_ID(), NIDENT, SAUTHID, 'NULL', SCONNECT_EXT, NDOCUMENT); end UTL_SELECTLIST_INSERT; /* Очистка временной таблицы */ procedure UTL_SELECTLIST_CLEAR ( NIDENT in number -- Идентификатор процесса ) is begin /* Очищаем данные по идентификатору */ delete from P8PNL_SELECTLIST T where T.IDENT = NIDENT; end UTL_SELECTLIST_CLEAR; /* Сериализация настройки параметра */ procedure TOPTION_TO_XML ( ROPTION in TOPTION -- Настройка параметра ) is begin /* Настройка параметра */ PKG_XFAST.HERB(SNAME => ROPTION.SCODE, SVALUE => ROPTION.SVALUE); end TOPTION_TO_XML; /* Десериализация настройки параметра */ function TOPTION_FROM_XML ( CXML in clob -- XML-описание настройки параметра ) return TOPTION -- Настройка параметра is RRES TOPTION; -- Буфер для результата XDOC PKG_XPATH.TDOCUMENT; -- Документ XML XROOT PKG_XPATH.TNODE; -- Корень документа XML XNODE PKG_XPATH.TNODE; -- Буфер узла документа begin /* Если данные есть */ if (CXML is not null) then begin /* Разбираем XML */ XDOC := PKG_XPATH.PARSE_FROM_CLOB(LCXML => CXML); /* Считываем корневой узел */ XROOT := PKG_XPATH.ROOT_NODE(RDOCUMENT => XDOC); /* Считываем узел параметра */ XNODE := PKG_XPATH.FIRST_NODE(RPARENT_NODE => XROOT); /* Получаем наименование параметра */ RRES.SCODE := PKG_XPATH.NODE_NAME(RNODE => XNODE); /* Получаем значение настройки параметра */ RRES.SVALUE := PKG_XPATH.VALUE(RNODE => XNODE); /* Освободим документ */ PKG_XPATH.FREE(RDOCUMENT => XDOC); exception when others then /* Освободим документ */ PKG_XPATH.FREE(RDOCUMENT => XDOC); /* Вернем ошибку */ PKG_STATE.DIAGNOSTICS_STACKED(); P_EXCEPTION(0, PKG_STATE.SQL_ERRM()); end; end if; /* Вернём результат */ return RRES; end TOPTION_FROM_XML; /* Сериализация списка настроек параметра */ procedure TOPTIONS_TO_XML ( ROPTIONS in TOPTIONS -- Список настроек параметра ) is begin /* Открываем корень */ PKG_XFAST.DOWN_NODE(SNAME => SATTR_OPTIONS); /* Обходим параметры из коллекции */ if ((ROPTIONS is not null) and (ROPTIONS.COUNT > 0)) then for I in ROPTIONS.FIRST .. ROPTIONS.LAST loop begin /* Добавляем описание параметра */ TOPTION_TO_XML(ROPTION => ROPTIONS(I)); exception when NO_DATA_FOUND then null; end; end loop; end if; /* Закрываем корень */ PKG_XFAST.UP(); end TOPTIONS_TO_XML; /* Десериализация списка настроек параметра */ function TOPTIONS_FROM_XML ( CXML in clob -- XML-описание списка настроек параметра ) return TOPTIONS -- Коллекция настроек параметров is RRES TOPTIONS; -- Буфер для результата XDOC PKG_XPATH.TDOCUMENT; -- Документ XML XROOT PKG_XPATH.TNODE; -- Корень документа XML XOPTION_NODE PKG_XPATH.TNODE; -- Узел настройки параметра XOPTIONS_NODE PKG_XPATH.TNODE; -- Узел параметра begin /* Инициализируем результат */ RRES := TOPTIONS(); /* Если данные есть */ if (CXML is not null) then begin /* Разбираем XML */ XDOC := PKG_XPATH.PARSE_FROM_CLOB(LCXML => CXML); /* Считываем корневой узел */ XROOT := PKG_XPATH.ROOT_NODE(RDOCUMENT => XDOC); /* Считываем узел списка настроек параметра */ XOPTIONS_NODE := PKG_XPATH.SINGLE_NODE(RPARENT_NODE => XROOT, SPATTERN => SATTR_OPTIONS); /* Считываем узел настройки параметра */ XOPTION_NODE := PKG_XPATH.FIRST_NODE(RPARENT_NODE => XOPTIONS_NODE); /* Цикл по списку настройки параметров */ while not (PKG_XPATH.IS_NULL(RNODE => XOPTION_NODE)) loop /* Сериализуем и добавим его в коллекцию */ RRES.EXTEND(); RRES(RRES.LAST) := TOPTION_FROM_XML(CXML => PKG_XPATH.SERIALIZE_TO_CLOB(RNODE => XOPTION_NODE)); /* Считываем следующий параметр */ XOPTION_NODE := PKG_XPATH.NEXT_NODE(RCURRENT_NODE => XOPTION_NODE); end loop; /* Освободим документ */ PKG_XPATH.FREE(RDOCUMENT => XDOC); exception when others then /* Освободим документ */ PKG_XPATH.FREE(RDOCUMENT => XDOC); /* Вернем ошибку */ PKG_STATE.DIAGNOSTICS_STACKED(); P_EXCEPTION(0, PKG_STATE.SQL_ERRM()); end; end if; /* Вернём результат */ return RRES; end TOPTIONS_FROM_XML; /* Формирование аргумента */ function TSETTING_MAKE ( SCODE in varchar2, -- Мнемокод SNAME in varchar2, -- Наименование NKIND in number, -- Вид параметра SPANEL in varchar2, -- Панель NCOMPANY in number, -- Рег. номер организации SAUTHID in varchar2, -- Пользователь COPTIONS in clob, -- Настройка параметра SDATA_TYPE in varchar2, -- Тип данных SVALUE in varchar2, -- Значение SDESC in varchar2 -- Описание ) return TSETTING -- Описание параметра is RSETTING TSETTING; -- Буфер для результата begin /* Если мнемокод не указан */ if (SCODE is null) then P_EXCEPTION(0, 'Мнемокод параметра не указан.'); end if; /* Если наименование не указано */ if (SNAME is null) then P_EXCEPTION(0, 'Наименование параметра не указано.'); end if; /* Если вид параметра не указан */ if (NKIND is null) then P_EXCEPTION(0, 'Вид параметра не указан.'); end if; /* Если тип данные не указан */ if (SDATA_TYPE is null) then P_EXCEPTION(0, 'Тип данных параметра не указан.'); end if; /* Если тип данных не поддерживается */ if (SDATA_TYPE not in (PKG_P8PANELS_VISUAL.SDATA_TYPE_STR, PKG_P8PANELS_VISUAL.SDATA_TYPE_NUMB, PKG_P8PANELS_VISUAL.SDATA_TYPE_DATE)) then P_EXCEPTION(0, 'Параметры типа "%s" не поддерживаются.', COALESCE(TO_CHAR(SDATA_TYPE), '<НЕ УКАЗАН>')); end if; /* Собираем аргумент */ RSETTING.SCODE := SCODE; RSETTING.SNAME := SNAME; RSETTING.NKIND := NKIND; RSETTING.SPANEL := SPANEL; RSETTING.NCOMPANY := NCOMPANY; RSETTING.SAUTHID := SAUTHID; /* Если есть настройки параметра */ if (COPTIONS is not null) then RSETTING.ROPTIONS := TOPTIONS_FROM_XML(CXML => COPTIONS); end if; RSETTING.SDATA_TYPE := SDATA_TYPE; RSETTING.SVALUE := SVALUE; RSETTING.SDESC := SDESC; /* Вернем полученное */ return RSETTING; end TSETTING_MAKE; /* Сериализация списка настроек параметра */ function TSETTING_OPTIONS_TO_XML ( RSETTING in TSETTING -- Параметр ) return clob -- XML-описание is CRES clob; -- Буфер для результата begin /* Если есть настройки параметра */ if ((RSETTING.ROPTIONS is not null) and (RSETTING.ROPTIONS.COUNT > 0)) then /* Начинаем формирование XML */ PKG_XFAST.PROLOGUE(ITYPE => PKG_XFAST.CONTENT_); /* Добавляем настройки */ TOPTIONS_TO_XML(ROPTIONS => RSETTING.ROPTIONS); /* Сериализуем */ CRES := PKG_XFAST.SERIALIZE_TO_CLOB(); /* Завершаем формирование XML */ PKG_XFAST.EPILOGUE(); else CRES := null; end if; /* Возвращаем полученное */ return CRES; exception when others then /* Завершаем формирование XML */ PKG_XFAST.EPILOGUE(); /* Вернем ошибку */ PKG_STATE.DIAGNOSTICS_STACKED(); P_EXCEPTION(0, PKG_STATE.SQL_ERRM()); end TSETTING_OPTIONS_TO_XML; /* Сериализация параметра */ procedure TSETTING_TO_XML ( RSETTING in TSETTING, -- Параметр NFULL in number := 0 -- Флаг включения в ответ атрибутов параметров (0 - нет, 1 - да) ) is begin /* Открываем описание сущности */ PKG_XFAST.DOWN_NODE(SNAME => RSETTING.SCODE); /* Если не требуется включать атрибуты */ if (NFULL = 0) then /* Добавляем значение напрямую */ PKG_XFAST.VALUE(SVALUE => RSETTING.SVALUE); else /* Описываем атрибуты параметра */ PKG_XFAST.ATTR(SNAME => SATTR_NAME, SVALUE => RSETTING.SNAME); PKG_XFAST.ATTR(SNAME => SATTR_KIND, NVALUE => RSETTING.NKIND); PKG_XFAST.ATTR(SNAME => SATTR_PANEL, SVALUE => RSETTING.SPANEL); PKG_XFAST.ATTR(SNAME => SATTR_COMPANY, NVALUE => RSETTING.NCOMPANY); PKG_XFAST.ATTR(SNAME => SATTR_AUTHID, SVALUE => RSETTING.SAUTHID); PKG_XFAST.ATTR(SNAME => SATTR_DATA_TYPE, SVALUE => RSETTING.SDATA_TYPE); PKG_XFAST.ATTR(SNAME => SATTR_VALUE, SVALUE => RSETTING.SVALUE); PKG_XFAST.ATTR(SNAME => SATTR_DESC, SVALUE => RSETTING.SDESC); /* Если есть данные по настройке */ if ((RSETTING.ROPTIONS is not null) and (RSETTING.ROPTIONS.COUNT > 0)) then TOPTIONS_TO_XML(ROPTIONS => RSETTING.ROPTIONS); end if; end if; PKG_XFAST.UP(); end TSETTING_TO_XML; /* Десериализация параметра */ function TSETTING_FROM_XML ( CXML in clob -- XML-описание параметра ) return TSETTING -- Связь is RRES TSETTING; -- Буфер для результата XDOC PKG_XPATH.TDOCUMENT; -- Документ XML XROOT PKG_XPATH.TNODE; -- Корень документа XML XNODE PKG_XPATH.TNODE; -- Буфер узла документа begin /* Если данные есть */ if (CXML is not null) then begin /* Разбираем XML */ XDOC := PKG_XPATH.PARSE_FROM_CLOB(LCXML => CXML); /* Считываем корневой узел */ XROOT := PKG_XPATH.ROOT_NODE(RDOCUMENT => XDOC); /* Считываем узел параметра */ XNODE := PKG_XPATH.FIRST_NODE(RPARENT_NODE => XROOT); /* Получаем значения */ RRES.SCODE := PKG_XPATH.NODE_NAME(RNODE => XNODE); RRES.SNAME := PKG_XPATH.VALUE(RNODE => XNODE, SPATTERN => SATTR_NAME); RRES.ROPTIONS := TOPTIONS_FROM_XML(CXML => PKG_XPATH.SERIALIZE_TO_CLOB(RNODE => PKG_XPATH.SINGLE_NODE(RPARENT_NODE => XNODE, SPATTERN => SATTR_OPTIONS))); RRES.SDATA_TYPE := PKG_XPATH.VALUE(RNODE => XNODE, SPATTERN => SATTR_DATA_TYPE); RRES.SVALUE := PKG_XPATH.VALUE(RNODE => XNODE, SPATTERN => SATTR_VALUE); RRES.SDESC := PKG_XPATH.VALUE(RNODE => XNODE, SPATTERN => SATTR_DESC); /* Освободим документ */ PKG_XPATH.FREE(RDOCUMENT => XDOC); exception when others then /* Освободим документ */ PKG_XPATH.FREE(RDOCUMENT => XDOC); /* Вернем ошибку */ PKG_STATE.DIAGNOSTICS_STACKED(); P_EXCEPTION(0, PKG_STATE.SQL_ERRM()); end; end if; /* Вернём результат */ return RRES; end TSETTING_FROM_XML; /* Сериализация коллекции параметров */ function TSETTINGS_TO_XML ( RSETTINGS in TSETTINGS, -- Коллекция параметров NFULL in number := 0 -- Флаг включения в ответ атрибутов параметров (0 - нет, 1 - да) ) return clob -- Список параметров is CRES clob; -- Буфер для сериализации begin /* Начинаем формирование XML */ PKG_XFAST.PROLOGUE(ITYPE => PKG_XFAST.CONTENT_, BALINE => true, BINDENT => true); /* Открываем корень */ PKG_XFAST.DOWN_NODE(SNAME => STAG_DATA); /* Обходим параметры из коллекции */ if ((RSETTINGS is not null) and (RSETTINGS.COUNT > 0)) then for I in RSETTINGS.FIRST .. RSETTINGS.LAST loop begin /* Добавляем описание параметра */ TSETTING_TO_XML(RSETTING => RSETTINGS(I), NFULL => NFULL); exception when NO_DATA_FOUND then null; end; end loop; end if; /* Закрываем корень */ PKG_XFAST.UP(); /* Сериализуем */ CRES := PKG_XFAST.SERIALIZE_TO_CLOB(); /* Завершаем формирование XML */ PKG_XFAST.EPILOGUE(); /* Возвращаем результат */ return CRES; exception when others then /* Завершаем формирование XML */ PKG_XFAST.EPILOGUE(); /* Вернем ошибку */ PKG_STATE.DIAGNOSTICS_STACKED(); P_EXCEPTION(0, PKG_STATE.SQL_ERRM()); end TSETTINGS_TO_XML; /* Десериализация параметров */ function TSETTINGS_FROM_XML ( CXML in clob -- XML-описание параметров ) return TSETTINGS -- Параметры is RRES TSETTINGS; -- Буфер для результата XDOC PKG_XPATH.TDOCUMENT; -- Документ XML XROOT PKG_XPATH.TNODE; -- Корень документа XML XSETTINGS_NODE PKG_XPATH.TNODE; -- Узел параметров XSETTING_NODE PKG_XPATH.TNODE; -- Узел параметра begin /* Инициализируем результат */ RRES := TSETTINGS(); /* Если данные есть */ if (CXML is not null) then begin /* Разбираем XML */ XDOC := PKG_XPATH.PARSE_FROM_CLOB(LCXML => CXML); /* Считываем корневой узел */ XROOT := PKG_XPATH.ROOT_NODE(RDOCUMENT => XDOC); /* Считываем узел параметров */ XSETTINGS_NODE := PKG_XPATH.FIRST_NODE(RPARENT_NODE => XROOT); /* Считываем узел параметра */ XSETTING_NODE := PKG_XPATH.FIRST_NODE(RPARENT_NODE => XSETTINGS_NODE); /* Цикл по списку параметров */ while not (PKG_XPATH.IS_NULL(RNODE => XSETTING_NODE)) loop /* Сериализуем и добавим его в коллекцию */ RRES.EXTEND(); RRES(RRES.LAST) := TSETTING_FROM_XML(CXML => PKG_XPATH.SERIALIZE_TO_CLOB(RNODE => XSETTING_NODE)); /* Считываем следующий параметр */ XSETTING_NODE := PKG_XPATH.NEXT_NODE(RCURRENT_NODE => XSETTING_NODE); end loop; /* Освободим документ */ PKG_XPATH.FREE(RDOCUMENT => XDOC); exception when others then /* Освободим документ */ PKG_XPATH.FREE(RDOCUMENT => XDOC); /* Вернем ошибку */ PKG_STATE.DIAGNOSTICS_STACKED(); P_EXCEPTION(0, PKG_STATE.SQL_ERRM()); end; end if; /* Вернём результат */ return RRES; end TSETTINGS_FROM_XML; /* Сериализация панели */ procedure TPANEL_TO_XML ( RPANEL in TPANEL, -- Панель NFULL in number := 0 -- Флаг включения в ответ атрибутов параметров (0 - нет, 1 - да) ) is begin /* Открываем описание панели */ PKG_XFAST.DOWN_NODE(SNAME => RPANEL.SNAME); /* Если у панели есть параметры */ if ((RPANEL.RSETTINGS is not null) and (RPANEL.RSETTINGS.COUNT > 0)) then /* Добавляем параметры */ for I in RPANEL.RSETTINGS.FIRST .. RPANEL.RSETTINGS.LAST loop begin /* Добавляем описание параметра */ TSETTING_TO_XML(RSETTING => RPANEL.RSETTINGS(I), NFULL => NFULL); exception when NO_DATA_FOUND then null; end; end loop; end if; PKG_XFAST.UP(); end TPANEL_TO_XML; /* Десериализация панели */ function TPANEL_FROM_XML ( CXML in clob -- XML-описание панели ) return TPANEL -- Панель is RRES TPANEL; -- Буфер для результата XDOC PKG_XPATH.TDOCUMENT; -- Документ XML XROOT PKG_XPATH.TNODE; -- Корень документа XML XNODE PKG_XPATH.TNODE; -- Буфер узла документа begin /* Если данные есть */ if (CXML is not null) then begin /* Разбираем XML */ XDOC := PKG_XPATH.PARSE_FROM_CLOB(LCXML => CXML); /* Считываем корневой узел */ XROOT := PKG_XPATH.ROOT_NODE(RDOCUMENT => XDOC); /* Считываем узел параметра */ XNODE := PKG_XPATH.FIRST_NODE(RPARENT_NODE => XROOT); /* Получаем значения */ RRES.SNAME := PKG_XPATH.NODE_NAME(RNODE => XNODE); RRES.RSETTINGS := TSETTINGS_FROM_XML(CXML => PKG_XPATH.SERIALIZE_TO_CLOB(RNODE => XNODE)); /* Освободим документ */ PKG_XPATH.FREE(RDOCUMENT => XDOC); exception when others then /* Освободим документ */ PKG_XPATH.FREE(RDOCUMENT => XDOC); /* Вернем ошибку */ PKG_STATE.DIAGNOSTICS_STACKED(); P_EXCEPTION(0, PKG_STATE.SQL_ERRM()); end; end if; /* Вернём результат */ return RRES; end TPANEL_FROM_XML; /* Сериализация коллекции панелей */ function TPANELS_TO_XML ( RPANELS in TPANELS, -- Коллекция панелей NFULL in number := 0 -- Флаг включения в ответ атрибутов параметров (0 - нет, 1 - да) ) return clob -- Список параметров is CRES clob; -- Буфер для сериализации begin /* Начинаем формирование XML */ PKG_XFAST.PROLOGUE(ITYPE => PKG_XFAST.CONTENT_, BALINE => true, BINDENT => true); /* Открываем корень */ PKG_XFAST.DOWN_NODE(SNAME => STAG_DATA); /* Обходим параметры из коллекции */ if ((RPANELS is not null) and (RPANELS.COUNT > 0)) then for I in RPANELS.FIRST .. RPANELS.LAST loop begin /* Добавляем описание панели */ TPANEL_TO_XML(RPANEL => RPANELS(I), NFULL => NFULL); exception when NO_DATA_FOUND then null; end; end loop; end if; /* Закрываем корень */ PKG_XFAST.UP(); /* Сериализуем */ CRES := PKG_XFAST.SERIALIZE_TO_CLOB(); /* Завершаем формирование XML */ PKG_XFAST.EPILOGUE(); /* Возвращаем результат */ return CRES; exception when others then /* Завершаем формирование XML */ PKG_XFAST.EPILOGUE(); /* Вернем ошибку */ PKG_STATE.DIAGNOSTICS_STACKED(); P_EXCEPTION(0, PKG_STATE.SQL_ERRM()); end TPANELS_TO_XML; /* Десериализация панелей */ function TPANELS_FROM_XML ( CXML in clob -- XML-описание панелей ) return TPANELS -- Панели is RRES TPANELS; -- Буфер для результата XDOC PKG_XPATH.TDOCUMENT; -- Документ XML XROOT PKG_XPATH.TNODE; -- Корень документа XML XPANELS_NODE PKG_XPATH.TNODE; -- Узел панелей XPANEL_NODE PKG_XPATH.TNODE; -- Узел панели begin /* Инициализируем результат */ RRES := TPANELS(); /* Если данные есть */ if (CXML is not null) then begin /* Разбираем XML */ XDOC := PKG_XPATH.PARSE_FROM_CLOB(LCXML => CXML); /* Считываем корневой узел */ XROOT := PKG_XPATH.ROOT_NODE(RDOCUMENT => XDOC); /* Считываем узел панелей */ XPANELS_NODE := PKG_XPATH.SINGLE_NODE(RPARENT_NODE => XROOT, SPATTERN => STAG_PANELS); /* Считываем узел панели */ XPANEL_NODE := PKG_XPATH.FIRST_NODE(RPARENT_NODE => XPANELS_NODE); /* Цикл по списку панелей */ while not (PKG_XPATH.IS_NULL(RNODE => XPANEL_NODE)) loop /* Сериализуем и добавим её в коллекцию */ RRES.EXTEND(); RRES(RRES.LAST) := TPANEL_FROM_XML(CXML => PKG_XPATH.SERIALIZE_TO_CLOB(RNODE => XPANEL_NODE)); /* Считываем следующую панель */ XPANEL_NODE := PKG_XPATH.NEXT_NODE(RCURRENT_NODE => XPANEL_NODE); end loop; /* Освободим документ */ PKG_XPATH.FREE(RDOCUMENT => XDOC); exception when others then /* Освободим документ */ PKG_XPATH.FREE(RDOCUMENT => XDOC); /* Вернем ошибку */ PKG_STATE.DIAGNOSTICS_STACKED(); P_EXCEPTION(0, PKG_STATE.SQL_ERRM()); end; end if; /* Вернём результат */ return RRES; end TPANELS_FROM_XML; /* Базовое добавления параметра */ procedure SETTING_INSERT ( SCODE in varchar2, -- Мнемокод SNAME in varchar2, -- Наименование NKIND in number, -- Вид параметра SPANEL in varchar2, -- Мнемокод панели NCOMPANY in number, -- Рег. номер организации SAUTHID in varchar2, -- Пользователь COPTIONS in clob, -- Дополнительные параметры NDATA_TYPE in number, -- Тип данных SVALUE_STR in varchar2, -- Значение (строка) NVALUE_NUM in number, -- Значение (число) DVALUE_DATE in date, -- Значение (дата) SDESCRIPTION in varchar2, -- Описание NRN out number -- Рег. номер записи ) is SPANEL_TMP PKG_STD.TSTRING; -- Панель (буфер) NCOMPANY_TMP PKG_STD.TNUMBER; -- Рег. номер организации (буфер) SAUTHID_TMP PKG_STD.TSTRING; -- Пользователь (буфер) begin /* Определяем, какие поля заполнять в зависимости от NKIND */ case NKIND /* Системный */ when NKIND_SYSTEM then SPANEL_TMP := null; NCOMPANY_TMP := null; SAUTHID_TMP := null; /* Панельный */ when NKIND_PANEL then SPANEL_TMP := SPANEL; NCOMPANY_TMP := null; SAUTHID_TMP := null; /* Пользовательский */ when NKIND_USER then SPANEL_TMP := SPANEL; NCOMPANY_TMP := NCOMPANY; SAUTHID_TMP := SAUTHID; else P_EXCEPTION('Неизвестный вид параметра "%s"', NKIND); end case; /* Генерируем рег. номер записи */ NRN := GEN_ID(); /* Добавление записи в таблицу */ insert into P8PNL_SETTINGS (RN, CODE, name, KIND, PANEL, COMPANY, authid, OPTIONS, DATA_TYPE, VALUE_STR, VALUE_NUM, VALUE_DATE, DESCRIPTION) values (NRN, SCODE, SNAME, NKIND, SPANEL_TMP, NCOMPANY_TMP, SAUTHID_TMP, COPTIONS, NDATA_TYPE, SVALUE_STR, NVALUE_NUM, DVALUE_DATE, SDESCRIPTION); end SETTING_INSERT; /* Базовое обновление параметра */ procedure SETTING_UPDATE ( NRN in number, -- Рег. номер записи SCODE in varchar2, -- Мнемокод SNAME in varchar2, -- Наименование NKIND in number, -- Вид параметра SPANEL in varchar2, -- Мнемокод панели NCOMPANY in number, -- Рег. номер организации SAUTHID in varchar2, -- Пользователь COPTIONS in clob, -- Дополнительные параметры NDATA_TYPE in number, -- Тип данных SVALUE_STR in varchar2, -- Значение (строка) NVALUE_NUM in number, -- Значение (число) DVALUE_DATE in date, -- Значение (дата) SDESCRIPTION in varchar2 -- Описание ) is begin /* Исправление записи в таблице */ update P8PNL_SETTINGS set CODE = SCODE, name = SNAME, KIND = NKIND, PANEL = SPANEL, COMPANY = NCOMPANY, authid = SAUTHID, OPTIONS = COPTIONS, DATA_TYPE = NDATA_TYPE, VALUE_STR = SVALUE_STR, VALUE_NUM = NVALUE_NUM, VALUE_DATE = DVALUE_DATE, DESCRIPTION = SDESCRIPTION where RN = NRN; if (sql%notfound) then PKG_MSG.RECORD_NOT_FOUND(NDOCUMENT => NRN, SUNIT_TABLE => 'P8PNL_SETTINGS'); end if; end SETTING_UPDATE; /* Базовое удаление параметра */ procedure SETTING_DELETE ( NRN in number -- Рег. номер записи ) is begin /* Удаление записи из таблицы */ delete from P8PNL_SETTINGS where RN = NRN; /* Контроль изменения данных */ if (sql%notfound) then PKG_MSG.RECORD_NOT_FOUND(NDOCUMENT => NRN, SUNIT_TABLE => 'P8PNL_SETTINGS'); end if; end SETTING_DELETE; /* Считывание системного параметра */ function SETTINGS_SYSTEM_GET ( SCODE in varchar2 -- Мнемокод параметра ) return P8PNL_SETTINGS%rowtype -- Запись системного параметра is RRES P8PNL_SETTINGS%rowtype; -- Запись системного параметра begin /* Считываем системный параметр */ begin select T.* into RRES from P8PNL_SETTINGS T where T.CODE = SCODE and T.KIND = NKIND_SYSTEM and T.PANEL is null and T.COMPANY is null and T.AUTHID is null; exception when others then RRES := null; end; /* Возвращаем результат */ return RRES; end SETTINGS_SYSTEM_GET; /* Считывание панельного параметра */ function SETTINGS_PANEL_GET ( SCODE in varchar2, -- Мнемокод параметра SPANEL in varchar2 -- Панель ) return P8PNL_SETTINGS%rowtype -- Запись панельного параметра is RRES P8PNL_SETTINGS%rowtype; -- Запись панельного параметра begin /* Если панель не указана */ if (SPANEL is null) then P_EXCEPTION(0, 'Ошибка считывания параметра панели. Панель не определена.'); end if; /* Считываем системный параметр */ begin select T.* into RRES from P8PNL_SETTINGS T where T.CODE = SCODE and T.KIND = NKIND_PANEL and T.PANEL = SPANEL and T.COMPANY is null and T.AUTHID is null; exception when others then RRES := null; end; /* Возвращаем результат */ return RRES; end SETTINGS_PANEL_GET; /* Считывание пользовательского параметра */ function SETTINGS_USER_GET ( SCODE in varchar2, -- Мнемокод параметра SPANEL in varchar2, -- Панель NCOMPANY in number, -- Рег. номер организации SAUTHID in varchar2 -- Пользователь ) return P8PNL_SETTINGS%rowtype -- Запись пользовательского параметра is RRES P8PNL_SETTINGS%rowtype; -- Запись пользовательского параметра begin /* Если панель не указана */ if (SPANEL is null) then P_EXCEPTION(0, 'Ошибка считывания пользовательского параметра. Панель не определена.'); end if; /* Если организация не указана */ if (NCOMPANY is null) then P_EXCEPTION(0, 'Ошибка считывания пользовательского параметра. Организация не определена.'); end if; /* Если пользователь не указан */ if (SAUTHID is null) then P_EXCEPTION(0, 'Ошибка считывания пользовательского параметра. Пользователь не определен.'); end if; /* Считываем системный параметр */ begin select T.* into RRES from P8PNL_SETTINGS T where T.CODE = SCODE and T.KIND = NKIND_USER and T.PANEL = SPANEL and T.COMPANY = NCOMPANY and T.AUTHID = SAUTHID; exception when others then RRES := null; end; /* Возвращаем результат */ return RRES; end SETTINGS_USER_GET; /* Считывание записи параметра по виду */ function SETTINGS_GET_BY_KIND ( NKIND in number, -- Вид параметра SCODE in varchar2, -- Мнемокод параметра SPANEL in varchar2 := null, -- Панель NCOMPANY in number := null, -- Рег. номер организации SAUTHID in varchar2 := null -- Пользователь ) return P8PNL_SETTINGS%rowtype -- Запись параметра is RRES P8PNL_SETTINGS%rowtype; -- Запись параметра begin /* Системный параметр */ case NKIND /* Системный */ when NKIND_SYSTEM then RRES := SETTINGS_SYSTEM_GET(SCODE => SCODE); /* Панельный */ when NKIND_PANEL then RRES := SETTINGS_PANEL_GET(SCODE => SCODE, SPANEL => SPANEL); /* Пользовательский */ when NKIND_USER then RRES := SETTINGS_USER_GET(SCODE => SCODE, SPANEL => SPANEL, NCOMPANY => NCOMPANY, SAUTHID => SAUTHID); else P_EXCEPTION(0, 'Не определен вид параметра.'); end case; /* Возвращаем результат */ return RRES; end SETTINGS_GET_BY_KIND; /* Очистка параметров панели по идентификатору отмеченных записей */ procedure SETTINGS_CLEAR_BY_IDENT ( NIDENT in number, -- Идентификатор отмеченных записей SPANEL in varchar2, -- Панель NCOMPANY in number, -- Рег. номер организации SAUTHID in varchar2 -- Пользователь ) is begin /* Если определены необходимые параметры */ if ((SPANEL is not null) and (NCOMPANY is not null) and (SAUTHID is not null)) then /* Обходим неотмеченные параметры пользователя */ for REC in (select T.RN from P8PNL_SETTINGS T where T.KIND = NKIND_USER and T.PANEL = SPANEL and T.AUTHID = SAUTHID and T.COMPANY = NCOMPANY and not exists (select null from P8PNL_SELECTLIST S where S.IDENT = NIDENT and S.DOCUMENT = T.RN)) loop /* Удаляем параметр */ SETTING_DELETE(NRN => REC.RN); end loop; end if; /* Очищаем временную таблицу по идентификатору */ UTL_SELECTLIST_CLEAR(NIDENT => NIDENT); end SETTINGS_CLEAR_BY_IDENT; /* Определение значений параметра по типу данных */ procedure SETTINGS_GET_VALUES_BY_DT ( SDATA_TYPE in varchar2, -- Тип данных (см. константы PKG_P8PANELS_VISUAL.SDATA_TYPE_*) SVALUE in varchar2, -- Исходное значение SVALUE_STR out varchar2, -- Значение (строка) NVALUE_NUM out number, -- Значение (число) DVALUE_DATE out date -- Значение (дата) ) is begin /* Исходим от типа данных */ case SDATA_TYPE /* Строка */ when PKG_P8PANELS_VISUAL.SDATA_TYPE_STR then SVALUE_STR := SVALUE; /* Число */ when PKG_P8PANELS_VISUAL.SDATA_TYPE_NUMB then /* Конвертируем в число */ begin NVALUE_NUM := TO_NUMBER(SVALUE); exception when others then P_EXCEPTION(0, 'Ошибка преобразования значения "' || SVALUE || '" в число.'); end; /* Дата */ when PKG_P8PANELS_VISUAL.SDATA_TYPE_DATE then begin DVALUE_DATE := TO_DATE(SVALUE, 'yyyy-mm-dd'); exception when others then P_EXCEPTION(0, 'Ошибка преобразования значения "' || SVALUE || '" в дату.'); end; else P_EXCEPTION(0, 'Не определен тип данных параметра.'); end case; end SETTINGS_GET_VALUES_BY_DT; /* Определение значения по типу данных */ function SETTINGS_GET_VALUE_BY_DT ( SDATA_TYPE in varchar2, -- Тип данных (см. константы PKG_P8PANELS_VISUAL.SDATA_TYPE_*) SVALUE_STR in varchar2, -- Значение (строка) NVALUE_NUM in number, -- Значение (число) DVALUE_DATE in date -- Значение (дата) ) return varchar2 -- Итоговое значение is SRESULT PKG_STD.TSTRING; -- Итоговое значение begin /* Исходим от типа данных */ case SDATA_TYPE /* Строка */ when PKG_P8PANELS_VISUAL.SDATA_TYPE_STR then SRESULT := SVALUE_STR; /* Число */ when PKG_P8PANELS_VISUAL.SDATA_TYPE_NUMB then SRESULT := TO_CHAR(NVALUE_NUM); /* Дата */ when PKG_P8PANELS_VISUAL.SDATA_TYPE_DATE then SRESULT := TO_CHAR(DVALUE_DATE, 'yyyy-mm-dd'); else P_EXCEPTION(0, 'Не определен тип данных параметра.'); end case; /* Возвращаем результат */ return SRESULT; end SETTINGS_GET_VALUE_BY_DT; /* Добавление/обновление значений параметров */ procedure SETTINGS_PUT ( RSETTINGS in TSETTINGS, -- Коллекция параметров NKIND in number, -- Вид параметра SPANEL in varchar2 -- Панель ) is NCOMPANY PKG_STD.TREF := GET_SESSION_COMPANY(); -- Рег. номер организации SAUTHID PKG_STD.TSTRING := PKG_SESSION.GET_UTILIZER(); -- Пользователь RREC P8PNL_SETTINGS%rowtype; -- Запись параметра SVALUE_STR P8PNL_SETTINGS.VALUE_STR%type; -- Значение (строка) NVALUE_NUM P8PNL_SETTINGS.VALUE_NUM%type; -- Значение (число) DVALUE_DATE P8PNL_SETTINGS.VALUE_DATE%type; -- Значение (дата) NTMP PKG_STD.TREF; -- Заглушка begin /* Обходим параметры */ if ((RSETTINGS is not null) and (RSETTINGS.COUNT > 0)) then for I in RSETTINGS.FIRST .. RSETTINGS.LAST loop /* Считываем параметр */ RREC := SETTINGS_GET_BY_KIND(NKIND => NKIND, SCODE => RSETTINGS(I).SCODE, SPANEL => SPANEL, NCOMPANY => NCOMPANY, SAUTHID => SAUTHID); /* Собираем поля, которые обновляются независимо */ RREC.OPTIONS := TSETTING_OPTIONS_TO_XML(RSETTING => RSETTINGS(I)); RREC.NAME := RSETTINGS(I).SNAME; RREC.DESCRIPTION := RSETTINGS(I).SDESC; /* Определяем значения параметра */ SETTINGS_GET_VALUES_BY_DT(SDATA_TYPE => RSETTINGS(I).SDATA_TYPE, SVALUE => RSETTINGS(I).SVALUE, SVALUE_STR => SVALUE_STR, NVALUE_NUM => NVALUE_NUM, DVALUE_DATE => DVALUE_DATE); /* Если параметр не существует */ if (RREC.RN is null) then /* Добавляем параметр */ SETTING_INSERT(SCODE => RSETTINGS(I).SCODE, SNAME => RREC.NAME, NKIND => NKIND, SPANEL => SPANEL, NCOMPANY => NCOMPANY, SAUTHID => SAUTHID, COPTIONS => RREC.OPTIONS, NDATA_TYPE => UTL_SDATA_TYPE_CONVERT(SDATA_TYPE => RSETTINGS(I).SDATA_TYPE), SVALUE_STR => SVALUE_STR, NVALUE_NUM => NVALUE_NUM, DVALUE_DATE => DVALUE_DATE, SDESCRIPTION => RREC.DESCRIPTION, NRN => NTMP); else /* Обновляем параметр */ SETTING_UPDATE(NRN => RREC.RN, SCODE => RREC.CODE, SNAME => RREC.NAME, NKIND => RREC.KIND, SPANEL => RREC.PANEL, NCOMPANY => RREC.COMPANY, SAUTHID => RREC.AUTHID, COPTIONS => RREC.OPTIONS, NDATA_TYPE => UTL_SDATA_TYPE_CONVERT(SDATA_TYPE => RSETTINGS(I).SDATA_TYPE), SVALUE_STR => SVALUE_STR, NVALUE_NUM => NVALUE_NUM, DVALUE_DATE => DVALUE_DATE, SDESCRIPTION => RREC.DESCRIPTION); end if; end loop; end if; end SETTINGS_PUT; /* Считывание параметров */ procedure SETTINGS_GET ( NKIND in number, -- Вид параметра SCODE in varchar2 := null, -- Мнемокод параметра (null - все) SPANEL in varchar2 := null, -- Панель RSETTINGS out TSETTINGS -- Информация о параметрах ) is RSETTING TSETTING; -- Параметр RREC P8PNL_SETTINGS%rowtype; -- Запись параметра NCOMPANY PKG_STD.TREF := GET_SESSION_COMPANY(); -- Рег. номер организации SAUTHID PKG_STD.TSTRING := PKG_SESSION.GET_UTILIZER(); -- Пользователь SDATA_TYPE PKG_STD.TSTRING; -- Тип данных в строковом формате begin /* Если коллекция не проинициализирована */ if (RSETTINGS is null) then RSETTINGS := TSETTINGS(); end if; /* Если параметр указан - читаем только его */ if (SCODE is not null) then /* Считыаем запись параметра */ RREC := SETTINGS_GET_BY_KIND(NKIND => NKIND, SCODE => SCODE, SPANEL => SPANEL, NCOMPANY => NCOMPANY, SAUTHID => SAUTHID); /* Если запись существует */ if (RREC.RN is not null) then /* Определяем тип данных в строковом формате */ SDATA_TYPE := UTL_NDATA_TYPE_CONVERT(NDATA_TYPE => RREC.DATA_TYPE); /* Добавляем новый элемент */ RSETTINGS.EXTEND(); /* Формируем параметр */ RSETTING := TSETTING_MAKE(SCODE => RREC.CODE, SNAME => RREC.NAME, NKIND => RREC.KIND, SPANEL => RREC.PANEL, NCOMPANY => RREC.COMPANY, SAUTHID => RREC.AUTHID, COPTIONS => RREC.OPTIONS, SDATA_TYPE => SDATA_TYPE, SVALUE => SETTINGS_GET_VALUE_BY_DT(SDATA_TYPE => SDATA_TYPE, SVALUE_STR => RREC.VALUE_STR, NVALUE_NUM => RREC.VALUE_NUM, DVALUE_DATE => RREC.VALUE_DATE), SDESC => RREC.DESCRIPTION); /* Добавляем в итоговый результат */ RSETTINGS(RSETTINGS.LAST) := RSETTING; end if; else /* Обходим все подходящие параметры */ for C in (select T.* from P8PNL_SETTINGS T where T.KIND = NKIND and ((NKIND = NKIND_SYSTEM) or ((NKIND in (NKIND_PANEL, NKIND_USER)) and (T.PANEL = SPANEL))) and ((NKIND in (NKIND_SYSTEM, NKIND_PANEL)) or ((NKIND = NKIND_USER) and (T.COMPANY = NCOMPANY))) and ((NKIND in (NKIND_SYSTEM, NKIND_PANEL)) or ((NKIND_USER = NKIND_USER) and (T.AUTHID = SAUTHID)))) loop /* Определяем тип данных в строковом формате */ SDATA_TYPE := UTL_NDATA_TYPE_CONVERT(NDATA_TYPE => C.DATA_TYPE); /* Добавляем новый элемент */ RSETTINGS.EXTEND(); /* Формируем параметр */ RSETTING := TSETTING_MAKE(SCODE => C.CODE, SNAME => C.NAME, NKIND => C.KIND, SPANEL => C.PANEL, NCOMPANY => C.COMPANY, SAUTHID => C.AUTHID, COPTIONS => C.OPTIONS, SDATA_TYPE => SDATA_TYPE, SVALUE => SETTINGS_GET_VALUE_BY_DT(SDATA_TYPE => SDATA_TYPE, SVALUE_STR => C.VALUE_STR, NVALUE_NUM => C.VALUE_NUM, DVALUE_DATE => C.VALUE_DATE), SDESC => C.DESCRIPTION); /* Добавляем в итоговый результат */ RSETTINGS(RSETTINGS.LAST) := RSETTING; end loop; end if; end SETTINGS_GET; /* Инициализация параметров */ procedure SETTINGS_INIT ( SPANEL in varchar2, -- Панель NKIND in number, -- Вид параметра RSETTINGS in out TSETTINGS -- Коллекция параметров ) is RREC P8PNL_SETTINGS%rowtype; -- Запись параметра NCOMPANY PKG_STD.TREF := GET_SESSION_COMPANY(); -- Рег. номер организации SAUTHID PKG_STD.TSTRING := PKG_SESSION.GET_UTILIZER(); -- Пользователь NDATA_TYPE PKG_STD.TNUMBER; -- Тип данных в числовом формате SVALUE_STR P8PNL_SETTINGS.VALUE_STR%type; -- Значение (строка) NVALUE_NUM P8PNL_SETTINGS.VALUE_NUM%type; -- Значение (число) DVALUE_DATE P8PNL_SETTINGS.VALUE_DATE%type; -- Значение (дата) SCONNECT_EXT PKG_STD.TSTRING := PKG_SESSION.GET_CONNECT_EXT(); -- Внешний идентификатор сеанса NIDENT PKG_STD.TREF; -- Идентификатор отмеченных записей begin /* Обходим коллекцию */ if ((RSETTINGS is not null) and (RSETTINGS.COUNT > 0)) then /* Генерируем идентификатор отмеченных записей */ NIDENT := GEN_IDENT(); /* Обходим коллекцию параметров */ for I in RSETTINGS.FIRST .. RSETTINGS.LAST loop /* Считываем параметр */ RREC := SETTINGS_GET_BY_KIND(NKIND => NKIND, SCODE => RSETTINGS(I).SCODE, SPANEL => SPANEL, NCOMPANY => NCOMPANY, SAUTHID => SAUTHID); /* Определяем тип данных в числовом формате */ NDATA_TYPE := UTL_SDATA_TYPE_CONVERT(SDATA_TYPE => RSETTINGS(I).SDATA_TYPE); /* Собираем поля, которые обновляются независимо */ RREC.OPTIONS := TSETTING_OPTIONS_TO_XML(RSETTING => RSETTINGS(I)); RREC.NAME := RSETTINGS(I).SNAME; RREC.DESCRIPTION := RSETTINGS(I).SDESC; /* Определяем значения параметра */ SETTINGS_GET_VALUES_BY_DT(SDATA_TYPE => RSETTINGS(I).SDATA_TYPE, SVALUE => RSETTINGS(I).SVALUE, SVALUE_STR => SVALUE_STR, NVALUE_NUM => NVALUE_NUM, DVALUE_DATE => DVALUE_DATE); /* Если параметр не существует */ if (RREC.RN is null) then /* Добавляем параметр */ SETTING_INSERT(SCODE => RSETTINGS(I).SCODE, SNAME => RREC.NAME, NKIND => NKIND, SPANEL => SPANEL, NCOMPANY => NCOMPANY, SAUTHID => SAUTHID, COPTIONS => RREC.OPTIONS, NDATA_TYPE => NDATA_TYPE, SVALUE_STR => SVALUE_STR, NVALUE_NUM => NVALUE_NUM, DVALUE_DATE => DVALUE_DATE, SDESCRIPTION => RREC.DESCRIPTION, NRN => RREC.RN); /* Перечитываем запись */ RREC := SETTINGS_GET_BY_KIND(NKIND => NKIND, SCODE => RSETTINGS(I).SCODE, SPANEL => SPANEL, NCOMPANY => NCOMPANY, SAUTHID => SAUTHID); else /* Если тип данных не совпадает */ if (NDATA_TYPE <> RREC.DATA_TYPE) then /* Указываем новые значения параметра */ RREC.DATA_TYPE := NDATA_TYPE; RREC.VALUE_STR := SVALUE_STR; RREC.VALUE_NUM := NVALUE_NUM; RREC.VALUE_DATE := DVALUE_DATE; end if; /* Обновляем параметр */ SETTING_UPDATE(NRN => RREC.RN, SCODE => RREC.CODE, SNAME => RREC.NAME, NKIND => RREC.KIND, SPANEL => RREC.PANEL, NCOMPANY => RREC.COMPANY, SAUTHID => RREC.AUTHID, COPTIONS => RREC.OPTIONS, NDATA_TYPE => RREC.DATA_TYPE, SVALUE_STR => RREC.VALUE_STR, NVALUE_NUM => RREC.VALUE_NUM, DVALUE_DATE => RREC.VALUE_DATE, SDESCRIPTION => RREC.DESCRIPTION); end if; /* Заполняем недостающие данные для последующего наличия */ RSETTINGS(I).NKIND := RREC.KIND; RSETTINGS(I).SPANEL := RREC.PANEL; RSETTINGS(I).NCOMPANY := RREC.COMPANY; RSETTINGS(I).SAUTHID := RREC.AUTHID; /* Определяем итоговое значение параметра */ RSETTINGS(I).SVALUE := SETTINGS_GET_VALUE_BY_DT(SDATA_TYPE => RSETTINGS(I).SDATA_TYPE, SVALUE_STR => RREC.VALUE_STR, NVALUE_NUM => RREC.VALUE_NUM, DVALUE_DATE => RREC.VALUE_DATE); /* Если происходит инициализация пользовательских параметров */ if (NKIND = NKIND_USER) then /* Добавляем информацию во временную таблицу */ UTL_SELECTLIST_INSERT(NIDENT => NIDENT, SAUTHID => SAUTHID, SCONNECT_EXT => SCONNECT_EXT, NDOCUMENT => RREC.RN); end if; end loop; /* Если происходит инициализация пользовательских параметров */ if (NKIND = NKIND_USER) then /* Очищаем от лишних параметров */ SETTINGS_CLEAR_BY_IDENT(NIDENT => NIDENT, SPANEL => SPANEL, NCOMPANY => NCOMPANY, SAUTHID => SAUTHID); end if; end if; exception when others then /* Завершаем формирование XML */ PKG_XFAST.EPILOGUE(); /* Вернем ошибку */ PKG_STATE.DIAGNOSTICS_STACKED(); P_EXCEPTION(0, PKG_STATE.SQL_ERRM()); end SETTINGS_INIT; /* Считывание параметров */ procedure GET ( NKIND in number, -- Вид параметра SCODE in varchar2 := null, -- Мнемокод параметра (null - все) SPANEL in varchar2 := null, -- Панель NFULL in number := 0, -- Флаг включения атрибутов (0 - нет, 1 - да) COUT out clob -- Информация о параметрах ) is RPANELS TPANELS; -- Панели RSETTINGS TSETTINGS; -- Параметры NCOMPANY PKG_STD.TREF := GET_SESSION_COMPANY(); -- Рег. номер организации SAUTHID PKG_STD.TSTRING := PKG_SESSION.GET_UTILIZER(); -- Пользователь begin /* Инициализируем результат */ RPANELS := TPANELS(); /* Если отбор в рамках панелей */ if (NKIND in (NKIND_PANEL, NKIND_USER)) then /* Обходим все доступные панели */ for REC in (select T.PANEL from P8PNL_SETTINGS T where T.KIND = NKIND and ((SPANEL is null) or ((SPANEL is not null) and (T.PANEL = SPANEL))) and ((NKIND = NKIND_PANEL) or ((NKIND = NKIND_USER) and (T.COMPANY = NCOMPANY))) and ((NKIND = NKIND_PANEL) or ((NKIND_USER = NKIND_USER) and (T.AUTHID = SAUTHID))) and ((SCODE is null) or ((SCODE is not null) and (T.CODE = SCODE))) group by T.PANEL) loop /* Добавляем элемент панели */ RPANELS.EXTEND(); /* Инициализируем параметры */ RSETTINGS := TSETTINGS(); /* Считываем параметры панели */ SETTINGS_GET(NKIND => NKIND, SCODE => SCODE, SPANEL => REC.PANEL, RSETTINGS => RSETTINGS); /* Добавляем информацию о панели */ RPANELS(RPANELS.LAST).SNAME := REC.PANEL; RPANELS(RPANELS.LAST).RSETTINGS := RSETTINGS; end loop; else /* Добавляем элемент панели */ RPANELS.EXTEND(); /* Инициализируем параметры */ RSETTINGS := TSETTINGS(); /* Считываем параметры панели */ SETTINGS_GET(NKIND => NKIND, SCODE => SCODE, RSETTINGS => RSETTINGS); /* Добавляем информацию о системных параметрах */ RPANELS(RPANELS.LAST).SNAME := SPANEL_SYSTEM_NAME; RPANELS(RPANELS.LAST).RSETTINGS := RSETTINGS; end if; /* Считываем итоговый список панелей с параметрами */ COUT := TPANELS_TO_XML(RPANELS => RPANELS, NFULL => NFULL); exception when others then PKG_STATE.DIAGNOSTICS_STACKED(); P_EXCEPTION(0, PKG_STATE.SQL_ERRM()); end GET; /* Добавление параметра */ procedure PUT ( NKIND in number, -- Вид параметра CPANELS in clob -- XML-описание панелей ) is RPANELS TPANELS; -- Панели begin /* Десериализуем панели */ RPANELS := TPANELS_FROM_XML(CXML => BLOB2CLOB(LBDATA => BASE64_DECODE(LCSRCE => CPANELS), SCHARSET => PKG_CHARSET.CHARSET_UTF_())); /* Обходим панели */ if ((RPANELS is not null) and (RPANELS.COUNT > 0)) then for I in RPANELS.FIRST .. RPANELS.LAST loop /* Обходим параметры панели */ if ((RPANELS(I).RSETTINGS is not null) and (RPANELS(I).RSETTINGS.COUNT > 0)) then /* Добавляем/обновляем значения параметров панели */ SETTINGS_PUT(RSETTINGS => RPANELS(I).RSETTINGS, NKIND => NKIND, SPANEL => RPANELS(I).SNAME); end if; end loop; end if; exception when others then PKG_STATE.DIAGNOSTICS_STACKED(); P_EXCEPTION(0, PKG_STATE.SQL_ERRM()); end PUT; /* Инициализация параметров */ procedure INIT ( NKIND in number, -- Вид параметра CPANELS in clob, -- XML-описание панелей NFULL in number := 0, -- Флаг включения в ответ атрибутов параметров (0 - нет, 1 - да) COUT out clob -- Информация о параметрах ) is RPANELS TPANELS; -- Панели begin /* Десериализуем панели */ RPANELS := TPANELS_FROM_XML(CXML => BLOB2CLOB(LBDATA => BASE64_DECODE(LCSRCE => CPANELS), SCHARSET => PKG_CHARSET.CHARSET_UTF_())); /* Обходим панели */ if ((RPANELS is not null) and (RPANELS.COUNT > 0)) then for I in RPANELS.FIRST .. RPANELS.LAST loop /* Проверяем наличие названия панели, если соответствующий вид параметра */ if ((NKIND in (NKIND_PANEL, NKIND_USER)) and (RPANELS(I).SNAME is null)) then P_EXCEPTION(0, 'Ошибка инициализации параметров. Для вида параметра "%s" панель не может быть пустой.', NKIND); end if; /* Обходим параметры панели */ if ((RPANELS(I).RSETTINGS is not null) and (RPANELS(I).RSETTINGS.COUNT > 0)) then /* Инициализируем параметры */ SETTINGS_INIT(SPANEL => RPANELS(I).SNAME, NKIND => NKIND, RSETTINGS => RPANELS(I).RSETTINGS); end if; end loop; end if; /* Считываем итоговый список панелей с параметрами */ COUT := TPANELS_TO_XML(RPANELS => RPANELS, NFULL => NFULL); exception when others then PKG_STATE.DIAGNOSTICS_STACKED(); P_EXCEPTION(0, PKG_STATE.SQL_ERRM()); end INIT; /* Инициализация информации о настройках панелей */ procedure PANELS_INIT ( COUT out clob -- Информация о панелях ) is NCOMPANY PKG_STD.TREF := GET_SESSION_COMPANY(); -- Рег. номер организации SAUTHID PKG_STD.TSTRING := PKG_SESSION.GET_UTILIZER(); -- Пользователь begin /* Начинаем формирование XML */ PKG_XFAST.PROLOGUE(ITYPE => PKG_XFAST.CONTENT_); /* Открываем корень */ PKG_XFAST.DOWN_NODE(SNAME => STAG_DATA); /* Обходим все панели, имеющие параметры */ for REC in (select T.PANEL from P8PNL_SETTINGS T where T.KIND = NKIND_USER and T.COMPANY = NCOMPANY and T.AUTHID = SAUTHID group by T.PANEL) loop /* Открываем информацию о панели */ PKG_XFAST.DOWN_NODE(SNAME => REC.PANEL); /* Добавляем атрибут наличия пользовательских параметров панели */ PKG_XFAST.ATTR(SNAME => SATTR_USER_SETTINGS, NVALUE => 1); /* Закрываем информацию о панели */ PKG_XFAST.UP(); end loop; /* Закрываем корень */ PKG_XFAST.UP(); /* Сериализуем */ COUT := PKG_XFAST.SERIALIZE_TO_CLOB(); /* Завершаем формирование XML */ PKG_XFAST.EPILOGUE(); exception when others then /* Завершаем формирование XML */ PKG_XFAST.EPILOGUE(); /* Вернем ошибку */ PKG_STATE.DIAGNOSTICS_STACKED(); P_EXCEPTION(0, PKG_STATE.SQL_ERRM()); end PANELS_INIT; end PKG_P8PANELS_SETTINGS; /