Рекурсивная копия папки с XQuery
Мне нужно скопировать всю папку проекта на сервере MarkLogic, и вместо того, чтобы делать это вручную, я решил сделать это с помощью рекурсивной функции, но это становится худшей идеей, которую я когда-либо имел. У меня проблемы с транзакциями и с синтаксисом, но, поскольку я новичок, я не могу найти верный способ их решить. Вот мой код, спасибо за помощь!
import module namespace dls = "http://marklogic.com/xdmp/dls" at "/MarkLogic/dls.xqy";
declare option xdmp:set-transaction-mode "update";
declare function local:recursive-copy($filesystem as xs:string, $uri as xs:string)
{
for $e in xdmp:filesystem-directory($filesystem)/dir:entry
return
if($e/dir:type/text() = "file")
then dls:document-insert-and-manage($e/dir:filename, fn:false(), $e/dir:pathname)
else
(
xdmp:directory-create(concat(concat($uri, data($e/dir:filename)), "/")),
local:recursive-copy($e/dir:pathname, $uri)
)
};
let $filesystemfolder := 'C:\Users\WB523152\Downloads\expath-ml-console-0.4.0\src'
let $uri := "/expath_console/"
return local:recursive-copy($filesystemfolder, $uri)
1 ответ
Решение
MLCP было бы неплохо использовать. Тем не менее, вот моя версия:
declare option xdmp:set-transaction-mode "update";
declare variable $prefix-replace := ('C:/', '/expath_console/');
declare function local:recursive-copy($filesystem as xs:string){
for $e in xdmp:filesystem-directory($filesystem)/dir:entry
return
if($e/dir:type/text() = "file")
then
let $source := $e/dir:pathname/text()
let $dest := fn:replace($source, $prefix-replace[1], $prefix-replace[2])
let $_ := xdmp:document-insert($source,
<options xmlns="xdmp:document-load">
<uri>{$dest}</uri>
</options>)
return <record>
<from>{$source}</from>
<to>{$dest}</to>
</record>
else
local:recursive-copy($e/dir:pathname)
};
let $filesystemfolder := 'C:\Temp'
return <results>{local:recursive-copy($filesystemfolder)}</results>
Пожалуйста, обратите внимание на следующее:
- Я изменил мой образец на C:\Temp dir
- Вывод - только XML, потому что по соглашению я пытаюсь сделать это на случай, если захочу проанализировать результаты. Это на самом деле, как я нашел ошибку, связанную с конфликтующими обновлениями.
- Я решил определить простой префикс заменить на URI
- Я не видел необходимости DLS в вашем описании
- Я не видел необходимости явного создания каталогов в вашем случае использования
- Причина, по которой вы получали конфликтующие обновления, потому что вы использовали только имя файла в качестве URI. Во всей структуре каталогов эти имена не были уникальными - отсюда и конфликтующее обновление при двойных вставках одного и того же URI.
- Это не сплошной код:
- Вы должны убедиться, что URI действителен. Не все пути / имена файловых систем подходят для URI, поэтому вы можете проверить это и, если необходимо, экранировать символы.
- У больших файловых систем будет тайм-аут, поэтому порождение в пакетах может быть полезным.
- Например, я мог бы собрать список документов, как в моем XML, а затем обработать этот список, создав новую задачу для каждых 100 документов. Это может быть выполнено с помощью простого цикла над xdmp:spawn-function или с помощью библиотеки, такой как taskbot от @mblakele