|
| ||||||||||||
| ||||||||||||
|
2007 г.
Что дает репозитарий XML DB и как с ним работатьВладимир Пржиялковский,Преподаватель технологий Oracle www.ccas.ru/prz
АннотацияРепозитарий XML DB фактически представляет из себя древовидно-организованую файловую систему внутри БД, при том что элементами ее являются ресурсы: каталоги (папки) и файлы. В статье показано, как можно работать с репозитарием XML DB. ВведениеXML DB, созданная в рамках БД Oracle, дает возможность следующего:
Репозитарий XML DB, фактически является древовидно-организованой файловой системой внутри БД, элементами которой выступают ресурсы: каталоги (папки) и произвольные (не обязательно текстовые) файлы. Папки можно заводить и удалять, а файлы - заводить, удалять и извлекать. Технически ресурсы репозитария XML DB суть документы XML. Элемент Contents каждого такого документа представляет содержание ресурса, а все остальные элементы являются метаданными, описывающими ресурс. Средствами доступа к ресурсам, составляющим репозитарий, могут служить:
Здесь рассматриваются две первые категории средств, а последняя оставлена для самостоятельных упражнений. Доступ к ресурсам средствами 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; Для просмотра дерева ресурсов, помимо обычных, существуют специальные функции:
Выдать описания ресурсов, имеющихся в папке /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' ); Проверка: 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 являются:
В XML DB имеются несколько встроенных ACL, заданных следующими ресурсами: >/sys/acls/all_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 ("системное") свои элементы. Для этой цели можно использовать разные средства:
Подробности имеются в документации по Oracle. |
|
CITForum © 1997–2025