Skip to content

Instantly share code, notes, and snippets.

@line-o
Forked from joewiz/chmod-recursive.xq
Last active November 20, 2022 06:06
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save line-o/c8fa604aee8e9159e98ca307755acc55 to your computer and use it in GitHub Desktop.
Save line-o/c8fa604aee8e9159e98ca307755acc55 to your computer and use it in GitHub Desktop.
[WIP] change user, group, mode on resources and collections in eXist-db recursively
xquery version "3.1";
import module namespace sm="http://exist-db.org/xquery/securitymanager";
import module namespace xmldb="http://exist-db.org/xquery/xmldb";
(: these variables need to be set by the caller :)
declare variable $collection as xs:string external;
declare variable $group as xs:string? external;
declare variable $user as xs:string? external;
declare variable $mode as xs:string external;
declare variable $collection-mode as xs:string? external;
declare variable $match as xs:string? external;
(:~ Scan a collection tree recursively starting at $root. Call $func once for each collection found :)
declare function local:scan-collections($root as xs:anyURI, $func as function(xs:anyURI) as item()*) {
$func($root),
if (sm:has-access($root, "rx")) then
for $child in xmldb:get-child-collections($root)
return
local:scan-collections(xs:anyURI($root || "/" || $child), $func)
else
()
};
(:~
: List all resources contained in a collection and call the supplied function once for each
: resource with the complete path to the resource as parameter.
:)
declare function local:scan-resources($collection as xs:anyURI, $func as function(xs:anyURI) as item()*) {
if (sm:has-access($collection, "rx")) then
for $child in xmldb:get-child-resources($collection)
return
$func(xs:anyURI($collection || "/" || $child))
else
()
};
(:~
: Scan a collection tree recursively starting at $root. Call the supplied function once for each
: resource encountered. The first parameter to $func is the collection URI, the second the resource
: path (including the collection part).
:)
declare function local:scan($root as xs:anyURI, $func as function(xs:anyURI, xs:anyURI?) as item()*) {
local:scan-collections($root, function($collection as xs:anyURI) {
$func($collection, ()),
(: scan-resources expects a function with one parameter, so we use a partial application
to fill in the collection parameter :)
local:scan-resources($collection, $func($collection, ?))
})
};
declare variable $matcher as function(*) :=
if ($match)
then function ($subject) { matches($subject, $match) }
else function ($subject) { true() }
;
declare function local:set-permissions ($subject as xs:string, $mode as xs:string) {
if (exists($user)) then sm:chown($subject, $user) else (),
if (exists($group)) then sm:chgrp($subject, $group) else (),
sm:chmod($subject, $mode) else (),
};
declare function local:cb ($collection as xs:string, $resource as xs:string?) {
let $is-resource := exists($resource)
let $subject :=
if ($is-resource)
then $resource
else $collection
let $_mode :=
if ($is-resource or empty($collection-mode))
then $mode
else $collection-mode
return
if ($does-match($subject))
then local:set-permissions($subject, $_mode)
else ()
};
local:scan(xs:anyURI($collection), local:cb#2)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment