MarkLogic является сервером приложений и любая программа написанная на XQuery для него может получить доступ не только к объектам хранящимся в самой базе данных, но и к файлам находящимся непосредственно на файловой системе.
API предоставляющий доступ к файловой системе в MarkLogic Server не так уж и богат, но имеющихся средств вполне достаточно чтобы зачитывать данные с файловой системы напрямую из XQuery кода и выполнять сохранения файлов на неё.
В рамках API MarkLogic’a внешним файлом или объектом называется файл или объект хранящийся на файловой системе. Соответственно внутренний объект – это объект который хранится в самой базе данных.
Рассмотрим подробней существующий API. Функции доступа к файловой системе расположены в пространстве имен “xdmp”.
И первая функция позволяет получить доступ к binary() объекту лежащему на файловой системе
xdmp:external-binary(
$path as xs:string,
[$starting-location as xs:double],
[$length as xs:double]
) as binary()
$path – путь до файла
$starting-location – Индекс первого байта в файле равен 1. По умолчанию = 1
$length – Количество зачитываемых байт
При этом binary() объект ассоциируется с файлом на FS и вы всегда можете определить является binary() объект внутренним или внешним.
Для доступа к это функции необходимо наличие прав
“http://marklogic.com/xdmp/privileges/xdmp-external-binary”
Если файла на файловой системе не существует то выкидывается исключение XDMP-MISSINGFILE
Следующая функция принимает binary() объект файла и возвращает путь к ассоциированному с ним файлу на файловой системе.
xdmp:external-binary-path(
$source as binary()
) as xs:string?
Исключение XDMP-ARG выкидывается в случае если переданный функции binary() объект не ассоциирован с файлом на файловой системе.
Функция xdmp:binary-is-external – проверяет является ли binary() объект внешним объектом (файлом)
xdmp:binary-is-external(
$source as binary()
) as xs:boolean
С помощью следующей функции можно получить листинг директории на файловой системе.
xdmp:filesystem-directory(
$pathname as xs:string
) as element(dir:directory)
$pathname – интересующая нас директория
Для выполнения функции обязательно наличие прав
marklogic.com/xdmp/privileges/xdmp-filesystem-directory
Также системный пользователь должен иметь права на чтение указанной директории
Исключения SVC-DIROPEN или SVC-FILOPEN выбрасываются в случае если у пользователя выполняющего функцию недостаточно для этого прав.
Результатом функции является список объектов расположенных на FS. Пример
xdmp:filesystem-directory( "./" )
<dir:directory xsi:schemaLocation="http://marklogic.com/xdmp/directory directory.xsd" xmlns:dir="http://marklogic.com/xdmp/directory" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<dir:entry>
<dir:filename>Admin</dir:filename>
<dir:pathname>./Admin</dir:pathname>
<dir:type>directory</dir:type>
<dir:content-length>0</dir:content-length>
<dir:last-modified>2013-05-02T13:09:53+04:00</dir:last-modified>
</dir:entry>
<dir:entry>
<dir:filename>LEGALNOTICES.txt</dir:filename>
<dir:pathname>./LEGALNOTICES.txt</dir:pathname>
<dir:type>file</dir:type>
<dir:content-length>28343</dir:content-length>
<dir:last-modified>2013-04-19T23:06:32+04:00</dir:last-modified>
</dir:entry>
...
</dir:directory>
Для чтения текстовых данных с файловой системы можно воспользоваться такой функцией
xdmp:filesystem-file(
$pathname as xs:string
) as xs:string
Где $pathname – путь до файла, который нужно зачитать в XQuery
Для того чтобы операция чтения закончилась успешно — нужно чтобы данные в файле находились в UTF-8 кодировке. Из-за этого требования при чтении бинарных данных этой функцией возникнет исключение и MarkLogic будет ручаться на кодировку данных. Для чтения бинарных данных нужно использовать функцию xdmp:external-binary.
Для выполнения функции необходимы привилегии
marklogic.com/xdmp/privileges/xdmp-filesystem-file
Проверить существует ли файл на файловой системе можно так
xdmp:filesystem-file-exists(
$pathname as xs:string
) as xs:boolean
Где $pathname – проверяемый путь
Для выполнения функции необходимы привилегии
marklogic.com/xdmp/privileges/xdmp-filesystem-file-exists
Для того чтобы узнать размер файла существует функция xdmp:filesystem-file-length
xdmp:filesystem-file-length(
$pathname as xs:string
) as xs:unsignedLong?
Функция возвращает пустую последовательность если файл не существует
Для выполнения функции необходимы привилегии
marklogic.com/xdmp/privileges/xdmp-filesystem-file-length
Далее рассмотрим функцию сохранения
xdmp:save(
$path as xs:string,
$node as node(),
[$options as node()?]
) as empty-sequence()
Данная функция сериализует любой (xml, text, bunary) объект и сохраняет его на файловую системы под указанных именем в указанную директорию.
Опций у этой функции довольно много, например output-encoding, которая задает кодировку докумеента. Но существующие опции этой функции достаточно специфичны и для того чтобы просто сохранить документ на файловую систему достаточно выполнить такой код:
let $text := text { "hello world" }
return
xdmp:save("greeting.txt", $text)
или например так можно сохранить файл из DB на файловую систему
let $pdf := doc("/mydocs/stuff.pdf")
return
xdmp:save("mystuff.pdf", $pdf)
Для выполнения функции необходимы привилегии
marklogic.com/xdmp/privileges/xdmp-save
MarkLogic Server это в первую очередь хранение документов в базе данных и обработка этих документов запросами XQuery. Но иногда требуется прочитать или записать файл на файловую систему и для этого в MarkLogic есть все необходимое. Конечно же для сложной обработки бинарных файлов, преобразования изображений эти средства не годятся, но с задачами поставленными перед ними превосходно справляются.
Автор: SleepwalkerOne