Hi Graydon,

> What I want is something similar to transform() but for a main query module, so I'm going to call it query().

Did you have a look at xquery:eval? [1] It allows you to supply a query as string or URI and pass on a context or variables:

(: main.xq :)
let $db := db:open('x')
return xquery:eval(xs:anyURI('query.xq', map { '': $db })

(: query.xq :)
.//names

fn:load-xquery-module($module-uri as xs:string, $options as map(*)) as map(*)

The function is not available in BaseX, but inspect:functions works similarly [2]: The functions of the module at the specified URI will be returned as a sequence (back then when the function was added, maps were not available yet).

If you have read-only and updating queries, Eliot’s approach of chaining queries is definitely worth looking at. It uses the Job Module [3] for running queries in a new context, i.e. as independent 'jobs'. If you write tests, the Unit Module [4] allows you to:

a) initialize a test or a set of tests (e.g., create a database);
b) run the test;
c) clean up your setup (e.g., drop the database).

Best,
Christian



 
  I want this because I
frequently find myself using XQuery to test XML content sets, and
keeping the individual tests to an individual query module is much
simpler than trying to stuff everything into an eventually enormous set
of functions.  But then they all have to be run individually and the
specific results aggregated together somehow to get the overall result.

It's possible to do this with the scripting functionality but I find
that gets hard to maintain and I'd really like an XQuery layer that
allows using multiple modules in a single at-least-notional query.

(The quality improvement I've experienced in XSLT from using transform()
and keeping every step of the transformation small and comprehensible
has been large; such an improvement may not generalize well, but if it
does, being able to treat a query module as a function seems highly
worthwhile for implementing anything complex in XQuery.)

I am not sure if my hypothetical query() function would be equivalent to

fn:load-xquery-module($module-uri as xs:string, $options as map(*)) as map(*)

from the 4.0 version of the functions spec at https://www.saxonica.com/qt4specs/FO/Overview-diff.html#func-load-xquery-module

My idea would be

fn:query($module-uri as xs:string, $context as item()*, $options as
map(*)) as map(*)

where a db is explicitly available as a value for $context.  (I realize
that document-node()* is not the type of a BaseX db, but given the
optimizer will substitute db:get() for collection() I figure it's
close...)

So it would be possible to do:

let $contentSet as xs:string :=
    fn:query('load-set.xq', (), $options)?db-name

let $test1Result as map(*) :=
    fn:query('test1.xq', $contentSet, $test-options)

let $test2Result as map(*) :=
    fn:query('test2.xq', $contentSet, $test-options)

And so on.

I emphatically don't want to be able to update a DB and then query it
further in a single query module; I am sharply aware I'm not smart
enough not to mess that up!

Does that make any more sense?

Thanks!


--
Graydon Saunders  | graydonish@gmail.com
Þæs oferéode, ðisses swá mæg.
-- Deor  ("That passed, so may this.")