Logo Море(!) аналитической информации!
IT-консалтинг Software Engineering Программирование СУБД Безопасность Internet Сети Операционные системы Hardware
Конференция «Технологии управления данными 2018»
СУБД, платформы, инструменты, реальные проекты.
29 ноября 2018 г.
2007 г.

Что дает репозитарий XML DB и как с ним работать

Владимир Пржиялковский,
Преподаватель технологий Oracle
www.ccas.ru/prz
 ... Зажгу свечу пред каждым сундуком,
И все их отопру, и стану сам
Средь них глядеть на блещущие груды.

А. С. Пушкин. Скупой рыцарь

Аннотация

Репозитарий XML DB фактически представляет из себя древовидно-организованую файловую систему внутри БД, при том что элементами ее являются ресурсы: каталоги (папки) и файлы. В статье показано, как можно работать с репозитарием XML DB.

Введение

XML DB, созданная в рамках БД Oracle, дает возможность следующего:
  • работать с репозитарием;
  • регистрировать схему XML для ее использования работе с данными XML в БД;
  • создавать внутри СУБД сервлеты для доступа к БД через интернет.

Репозитарий XML DB, фактически является древовидно-организованой файловой системой внутри БД, элементами которой выступают ресурсы: каталоги (папки) и произвольные (не обязательно текстовые) файлы. Папки можно заводить и удалять, а файлы - заводить, удалять и извлекать.

Технически ресурсы репозитария XML DB суть документы XML. Элемент Contents каждого такого документа представляет содержание ресурса, а все остальные элементы являются метаданными, описывающими ресурс.

Средствами доступа к ресурсам, составляющим репозитарий, могут служить:

  • системные таблицы RESOURCE_VIEW и PATH_VIEW
  • программы на PL/SQL (пакет DBMS_XDB) и на Java
  • протоколы HTTP, HTTPS, FTP, WebDAV.

Здесь рассматриваются две первые категории средств, а последняя оставлена для самостоятельных упражнений.

Доступ к ресурсам средствами SQL

Две производные таблицы (из исходных, в схеме XDB) позволяют узнать информацию о ресурсах XML DB: PATH_VIEW и RESOURCE_VIEW:
SQL> DESCRIBE resource_view
Name          Null?    Type
----------- -------- -----------------------------------------------
RES                  SYS.XMLTYPE(XMLSchema 
                     "http://xmlns.oracle.com/xdb/XDBResource.xsd"
                     Element "Resource")
ANY_PATH             VARCHAR2(4000)
RESID                RAW(16)

SQL> DESCRIBE path_view
Name        Null?    Type
----------- -------- -----------------------------------------------
PATH                 VARCHAR2(1024)
RES                  SYS.XMLTYPE(XMLSchema
                     "http://xmlns.oracle.com/xdb/XDBResource.xsd"
                     Element "Resource")
LINK                 SYS.XMLTYPE
RESID                RAW(16)

Обе таблицы хранят список ресурсов с путями доступа, однако благодаря возможности определять связки (links), подобно как в файловой системе, путей доступа к одному ресурсу может оказаться несколько; их-то все и покажет таблица PATH_VIEW, в отличие от RESOURCE_VIEW.

Примеры запросов.
Список ресурсов в репозитарии:
SELECT any_path FROM resource_view;

Описание первого попавшегося ресурса:

SELECT res FROM resource_view WHERE ROWNUM = 1;

Для просмотра дерева ресурсов, помимо обычных, существуют специальные функции:

  • UNDER_PATH
  • EQUALS_PATH
  • PATH
  • DEPTH

Выдать описания ресурсов, имеющихся в папке /sys/acls:

SELECT res 
FROM resource_view 
WHERE UNDER_PATH ( res, '/sys/acls' ) = 1
;

Выдать относительные имена ресурсов, имеющихся в папке /sys/acls (в данном случае это будут имена файлов), и их полные имена:

SELECT path ( 1 ), any_path 
FROM resource_view 
WHERE UNDER_PATH ( res, '/sys/acls', 1 ) = 1
;

Описание ресурса-папки /sys/acls:

SELECT res 
FROM resource_view 
WHERE EQUALS_PATH ( res, '/sys/acls' ) = 1
;

Полное описание ресурса-файла /sys/acls/all_all_acl.xml:

SELECT r.res.GETCLOBVAL ( ) 
FROM resource_view r 
WHERE EQUALS_PATH ( res, '/sys/acls/all_all_acl.xml' ) = 1
;

С запросами последнего типа следует соблюдать осторожность, так как элемент Contents результирующего документа XML хранит для ресурса-файла его содержимое, а оно может оказаться очень объемистым ("большой файл").

Содержание ресурса-файла /sys/acls/all_all_acl.xml с содержимым в формате XML:

SELECT r.res.EXTRACT ( '//Contents' ) 
FROM resource_view r 
WHERE EQUALS_PATH ( res, '/sys/acls/all_all_acl.xml' ) = 1
;

Другие типы файлов могут хранить описание содержимого в элементе /Resource/Contents/text или /Resource/Contents/binary.

Работа с ресурсами в программе

Заводить, изменять свойства и удалять ресурсы в репозитарии XML DB можно с помощью пакета PL/SQL DBMS_XDB.

Примеры:

CONNECT scott/tiger

DECLARE retb BOOLEAN;
BEGIN
retb := DBMS_XDB.CREATEFOLDER ( '/public/myfolder' );

retb := DBMS_XDB.CREATERESOURCE (
  '/public/myfolder/file1.txt'
, 'First line' || CHR ( 10 ) || 'Second line'
);

retb := DBMS_XDB.CREATERESOURCE ( '/public/myfolder/file2.xml' , '<doc><line>First line</line><line>Second line</line></doc>' );

END; /

Проверка:

SQL> SELECT r.res.EXTRACT ( 'Resource/Contents' ) AS xml
  2  FROM resource_view r
  3  WHERE EQUALS_PATH ( res, '/public/myfolder/file2.xml' ) = 1;

XML
--------------------------------------------------------------
<Contents xmlns="http://xmlns.oracle.com/xdb/XDBResource.xsd">
  <doc xmlns="">
    <line>First line</line>
    <line>Second line</line>
  </doc>
</Contents>


SQL> SELECT r.res.EXTRACT ( 'Resource/Contents/text/text()' ) AS text
  2  FROM resource_view r
  3  WHERE EQUALS_PATH ( res, '/public/myfolder/file1.txt' ) = 1;

TEXT
--------------------------------------------------------------
First line
Second line

Обратите внимание, что XML DB по-разному хранит файл в зависимости от его расширения (упражнение: убедитесь, что XML DB интерпретирует содержимое именно по расширению файла, а не оттого, что внутри). Соответствие расширений файлов типам MIME устанавливается и выясняется в файле-ресурсе /xdbconfig.xml.

Создание связи (link):

BEGIN
DBMS_XDB.LINK (
  '/public/myfolder/file1.txt'
, '/public'
, 'myfolderfile1.txt'
);
END;
/

Проверка:

SQL> SELECT r.res.EXTRACT ( 'Resource/Contents/text/text()' ) AS text
  2  FROM resource_view r
  3  WHERE EQUALS_PATH ( res, '/public/myfolderfile1.txt' ) = 1
SQL> /

TEXT
----------------------------------------------------------------
First line
Second line

SQL> SELECT
  2    p.path AS path
  3  , p.link.extract('/LINK/ChildName/text()') AS link
  4  FROM path_view p
  5* WHERE UNDER_PATH ( p.res, '/public' ) = 1
SQL> /

PATH                                          LINK
--------------------------------------------- ---------------------
/public/myfolder                              myfolder
/public/myfolderfile1.txt                     file1.txt
/public/myfolder/file1.txt                    file1.txt
/public/myfolder/file2.xml                    file2.xml

Обратите внимание на два пути доступа в репозитарии к одному и тому же файлу (ресурсу).

Удаление:

CALL DBMS_XDB.DELETERESOURCE ( '/public/myfolderfile1.txt' );
CALL DBMS_XDB.DELETERESOURCE ( '/public/myfolder/file1.txt' );
CALL DBMS_XDB.DELETERESOURCE ( '/public/myfolder/file2.xml' );
CALL DBMS_XDB.DELETERESOURCE ( '/public/myfolder' );

Упражнение. Проверьте реакцию XML DB на попытку удалить несуществующий файл или непустую папку.

В отличие от производных таблиц (view) словаря-стправочника в Oracle, производные таблицы RESOURCE_VIEW и PATH_VIEW обновляемы (на деле это "объектно-реляционные" таблицы). Это позвляет, например, удалить связь также и командой DELETE, или переместить существующий ресурс в другую папку обычной операцией UPDATE:

UPDATE path_view 
SET путь = новый_путь 
WHERE equals_path ( res, путь ) = 1
;

Пример помещения в репозитарий файла ОС:

CONNECT / AS SYSDBA

CREATE DIRECTORY courses AS 'c:\crs';

GRANT READ ON DIRECTORY courses TO scott;

CONNECT scott/tiger

DECLARE retb BOOLEAN;
BEGIN 
retb := 
DBMS_XDB.CREATERESOURCE (
  '/public/OracleXML.doc'
, BFILENAME ( 'COURSES', 'OracleXML.doc' )
);
END;
/

Проверка:

SQL> SELECT res AS resource_description
  2  FROM resource_view
  3  WHERE EQUALS_PATH ( res, '/public/OracleXML.doc' ) = 1
  4  ;

RESOURCE_DESCRIPTION
-----------------------------------------------------------------
<Resource xmlns="http://xmlns.oracle.com/xdb/XDBResource.xsd">
  <CreationDate>2006-09-05T12:47:57.547000</CreationDate>
  <ModificationDate>2006-09-05T12:47:57.547000</ModificationDate>
  <DisplayName>OracleXML.doc</DisplayName>
  <Language>en-US</Language>
  <CharacterSet>WINDOWS-1251</CharacterSet>
  <ContentType>application/msword</ContentType>
  <RefCount>1</RefCount>
</Resource>

Технически файлы репозитария размещаются служебных таблицах БД (документы XML) или в объектах LOB (файлы всех остальных типов). Использование формата MIME для хранения двоичных файлов не является самым экономным, что относится к издержкам метода.

Разграничение доступа

Репозитарий XML DB в БД Oracle использует собственную схему защиты доступа, access control list (ACL), созданную в рамках модели ACL для WebDAV (http://greenbytes.de/tech/webdav/rfc3744.html). Основными понятиями ACL являются:

  • Участник безопасности (principal). В XML DB это пользователь БД, роль БД или пользователь/роль справочника каталогов LDAP.
  • Привилегия. Может быть атомарной (atomic; например read-contents, update или dav:lock) и составной (aggregate, состоящей из других привилегий; например all, dav:all или dav:read-acl). (Полный перечень имеющихся в XML DB привилегий имеется в документации).
  • Access control entry (ACE). Запись о предоставлении или запрету привилегии участнику. Делается в тексте ACL.

В XML DB имеются несколько встроенных ACL, заданных следующими ресурсами: >/sys/acls/all_all_acl.xml
/sys/acls/all_owner_acl.xml
/sys/acls/bootstrap_acl.xml
/sys/acls/ro_all_acl.xml

ACL файла /public/OracleXML.doc в программе можно узнать так:

SELECT r.res.EXTRACT ( 'Resource/ACL' ) AS text
FROM resource_view r
WHERE EQUALS_PATH ( res, '/public/OracleXML.doc' ) = 1;

Пример замены ACL ресурса:

BEGIN DBMS_XDB.SETACL (
  '/public/OracleXML.doc'
, '/sys/acls/all_all_acl.xml' 
);
END;
/

Создадим в БД роль и создадим в XML DB соответствующий ей файл ACL:

CONNECT / AS SYSDBA

CREATE ROLE mygroup;

CONNECT xdb/xdb

DECLARE 
aclxml VARCHAR2 ( 4000 ) := 
'
<acl description="All privileges to MYGROUP, no to others" 
     xmlns="http://xmlns.oracle.com/xdb/acl.xsd"  
     xmlns:dav="DAV:" 
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
     xsi:schemaLocation="http://xmlns.oracle.com/xdb/acl.xsd
                         http://xmlns.oracle.com/xdb/acl.xsd" 
>
  <ace>
    <principal>MYGROUP</principal>
    <grant>true</grant>
    <privilege>
      <all/>
    </privilege>
  </ace>
</acl>
'
;
retb BOOLEAN;

BEGIN
retb := 
DBMS_XDB.CREATERESOURCE ( '/sys/acls/all_mygroup_acl.xml', aclxml )
;
END;
/

Защитим файл /public/OracleXML.doc созданым ACL:

CONNECT scott/tiger

BEGIN 
DBMS_XDB.SETACL (
  '/public/OracleXML.doc'
, '/sys/acls/all_mygroup_acl.xml' 
);
END;
/

COMMIT;

Проверим видимость ресурса пользователем SCOTT. Для удобства создадим сначала файл с запросом:

SELECT any_path 
FROM resource_view 
WHERE UNDER_PATH ( res, '/public' ) = 1
.
SAVE publicpaths

Проверка:

SQL> CONNECT scott/tiger
Connected.
SQL> @publicpaths

no rows selected

SQL> CONNECT / as sysdba
Connected.
SQL> GRANT mygroup TO scott;

Grant succeeded.

SQL> CONNECT scott/tiger
Connected.
SQL> @publicpaths

ANY_PATH
------------------------------------------
/public/OracleXML.doc

При включении пользователя в группу ранее невидимый ресурс стал виден.

Тип XDBURITYPE для работы с ресурсами

Для работы с ресурсами репозитария можно использовать системный подтип XDBURITYPE абстрактного типа URITYPE. В частности, методы типа XDBURITYPE позволяют извлекать из репозитария содержимое ресурсов.

Пример определения длины файла /public/OracleXML.doc:

SELECT
  DBMS_LOB.GETLENGTH (
    XDBURITYPE ( '/public/OracleXML.doc' ).GETBLOB ( )
  ) AS bytes
FROM dual
;

Результат:

     BYTES
----------
    504320

Таким же образом можно извлечь большой файл (содержимое, а не длину) в переменную программы.

Одно из применений типа XDBURITYPE - дать возможность ссылаться на данные в репозитарии XBM DB из полей обычных таблиц.

Пример:

CREATE TABLE projects AS
  SELECT
    1 AS pid
  , XDBURITYPE ( '/public/OracleXML.doc' ) AS description
  FROM dual
;
SELECT
  DBMS_LOB.GETLENGTH ( p.description.GETBLOB ( ) ) AS bytes
FROM projects p;

Получим:

     BYTES
----------
    504320

Обратите внимание, что сослаться на файл в репозитарии из БД можно и через тип HTTPURITYPE, однако в этом случае в ссылке появится имя компьютера и номер порта - признаки, внешние по отношению в содержимому БД, неконтролируемые средствами БД и, в отличие от ссылок извне, по сути ненужные.

Другие возможности

Любой ресурс репозитария можно перевести в режим версионного доступа (version control resource, VCR). С этой целью, и с целью самого доступа, следует использовать особый пакет DBMS_XDB_VERSION.

Любой ресурс репозитария можно снабдить собственным описанием (метаданными; в дополнение к "системным" метаданным), добавив в его описание XML ("системное") свои элементы. Для этой цели можно использовать разные средства:

  • в PL/SQL - процедуры пакета DBMS_XDB: APPENDRESOURCEMETADATA, UPDATERESOURCEMETADATA, DELETERESOURCEMETADATA, PURGERESOURCEMETADATA;

  • в SQL - операции INSERT, UPDATE, DELETE применительно к полю RES (производной) таблицы RESOURCE_VIEW;

  • методом PROPPATCH протокола WebDAV.

Подробности имеются в документации по Oracle.

Новости мира IT:

Архив новостей

Последние комментарии:

IT-консалтинг Software Engineering Программирование СУБД Безопасность Internet Сети Операционные системы Hardware

Информация для рекламодателей PR-акции, размещение рекламы — adv@citforum.ru,
тел. +7 985 1945361
Пресс-релизы — pr@citforum.ru
Обратная связь
Информация для авторов
Rambler's Top100 TopList liveinternet.ru: показано число просмотров за 24 часа, посетителей за 24 часа и за сегодня This Web server launched on February 24, 1997
Copyright © 1997-2000 CIT, © 2001-2015 CIT Forum
Внимание! Любой из материалов, опубликованных на этом сервере, не может быть воспроизведен в какой бы то ни было форме и какими бы то ни было средствами без письменного разрешения владельцев авторских прав. Подробнее...