The update declaration looks right. I think that will work, as long as you
don't need to use sequence arguments or handle multiple arguments. The built-in
xdmp:apply actually takes varargs, and user-defined XQuery functions can't do
that. It's also tough to pass a sequence or an empty sequence via xdmp:invoke,
but we can handle that with a map. In fact we can handle varargs through the
same map. The implementation is ugly, but only has to be done once:
declare function map-apply(
$fn as xdmp:function,
$m as map:map?)
as item()*
{
if (empty($m)) then xdmp:apply($fn)
else
let $count := map:get($m, 'count')
let $count := if (exists($count)) then $count else map:count($m)
return if ($count eq 0) then xdmp:apply($fn)
else if ($count eq 1) then xdmp:apply(
$fn, map:get($m, 'arg1'))
else if ($count eq 2) then xdmp:apply(
$fn, map:get($m, 'arg1'), map:get($m, 'arg2'))
else if ($count eq 3) then xdmp:apply(
$fn, map:get($m, 'arg1'), map:get($m, 'arg2'), map:get($m, 'arg3'))
(: etc :)
else error((), 'UNIMPLEMENTED', $count)
};
declare function map-apply(
$fn as xdmp:function,
$m as map:map?)
as item()*
{
map:apply($fn, ())
};
The caller would have to fill out that map beforehand, knowing the convention
for the map keys. Empty keys will pass the empty sequence to $fn, by design.
Every time you hit the 'UNIMPLEMENTED' error, add another level of arguments:
probably seven would be enough for most purposes, but I didn't feel like typing
it all out.
-- Mike
On 29 Jul 2011, at 14:48 , [email protected] wrote:
> Ok, this is what I did and it seems to give me what I need. I use it like
> xdmp:apply, eg aint:apply($function, $params)
>
> Any peer reviews appreciated. Two files, the first is called, which then uses
> the invoker to xdmp:invoke back on itself in a new update transaction:
>
>
> apply-in-new-transaction.xqy:
> -----------------------------------
> module namespace aint = "apply-in-new-transaction";
>
> declare option xdmp:mapping "false";
>
> declare function apply($function) {
> apply($function, ())
> };
>
> declare function apply($function, $params) {
> xdmp:invoke("apply-in-new-transaction-invoker.xqy",
> ((xs:QName("aint:function"), $function),
> (xs:QName("aint:params"), $params)),
> <options xmlns="xdmp:eval">
> <isolation>different-transaction</isolation>
> </options>)
> };
>
>
>
> apply-in-new-transaction-invoker.xqy:
> ---------------------------------------------
> declare namespace aint = "apply-in-new-transaction";
> declare option xdmp:update "true";
>
> declare variable $aint:function as xdmp:function external;
> declare variable $aint:params as item()* external;
>
> xdmp:apply($aint:function, $aint:params)
>
>
>
>
>
>
> > From: [email protected]
> > To: [email protected]
> > Date: Fri, 29 Jul 2011 14:27:21 -0700
> > Subject: Re: [MarkLogic Dev General] Cannot apply an update function from a
> > query
> >
> > Yes.
> >
> > If you want to force update mode, you can use this option in the prolog of
> > your calling module:
> >
> > declare option xdmp:update "true";
> >
> > But that doesn't help you if you want to run in query mode when updates are
> > not involved.
> >
> > --Colleen
> >
> > Colleen Whitney
> > MarkLogic Corporation
> >
> > Phone +1 650 655 2366
> > email [email protected]
> > web www.marklogic.com
> >
> > This e-mail and any accompanying attachments are confidential. The
> > information is intended solely for the use of the individual to whom it is
> > addressed. Any review, disclosure, copying, distribution, or use of this
> > e-mail communication by others is strictly prohibited. If you are not the
> > intended recipient, please notify us immediately by returning this message
> > to the sender and delete all copies. Thank you for your cooperation.
> >
> > ________________________________________
> > From: [email protected]
> > [[email protected]] On Behalf [email protected]
> > [[email protected]]
> > Sent: Friday, July 29, 2011 2:27 PM
> > To: [email protected]
> > Subject: Re: [MarkLogic Dev General] Cannot apply an update function from a
> > query
> >
> > Ok. So did static analysis not detect that the code should run as an update
> > query because the xdmp:document-insert call was on the other side of the
> > xdmp:apply call? I'm thinking this is a new thing I've got to be on the
> > lookout for.
> >
> > ________________________________
> > From: [email protected]
> > Date: Fri, 29 Jul 2011 14:19:32 -0700
> > To: [email protected]
> > Subject: Re: [MarkLogic Dev General] Cannot apply an update function from a
> > query
> >
> > On Jul 29, 2011, at 2:08 PM,
> > [email protected]<mailto:[email protected]> wrote:
> >
> > Am I going to have to xdmp:eval or xdmp:invoke the function and declare it
> > to be in a separate transaction?
> >
> > Yes. You can eval or invoke the function or the apply of the function.
> >
> > -jh-
> >
> >
> > _______________________________________________ General mailing list
> > [email protected]http://developer.marklogic.com/mailman/listinfo/general
> > _______________________________________________
> > General mailing list
> > [email protected]
> > http://developer.marklogic.com/mailman/listinfo/general
> _______________________________________________
> General mailing list
> [email protected]
> http://developer.marklogic.com/mailman/listinfo/general
_______________________________________________
General mailing list
[email protected]
http://developer.marklogic.com/mailman/listinfo/general