Logo Море(!) аналитической информации!
IT-консалтинг Software Engineering Программирование СУБД Безопасность Internet Сети Операционные системы Hardware
Обучение от Mail.Ru Group.
Онлайн-университет
для программистов с
гарантией трудоустройства.
Набор открыт!
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:

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

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

Релиз ядра Linux 4.14  (9)
Среда 22.11, 19:04
Loading

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
Внимание! Любой из материалов, опубликованных на этом сервере, не может быть воспроизведен в какой бы то ни было форме и какими бы то ни было средствами без письменного разрешения владельцев авторских прав. Подробнее...