XQuery update: updating inside a closure & how to modify a node and insert it in a DB
Hi folks,
I'm trying to implement a secure RESTXQ service like this:
declare %rest:path("api/users/init")
%restxq:PUT("{$data}")
%output:method("text")
function page:init-user($data) {
sec:secure(function() {
let $profile := json:parse-ml(convert:binary-to-string($data))
return
(
insert node attribute id { sec:get-current-user-id() } into $profile,
insert node $profile as last into db:open("db")/s:root
)
})
};And I have two problems:
- when executing it like this, inside of a closure, nothing happens. No modifications of the database and no errors (%updating missing) either - which is weird. Is this construct supported in 7.5?
- when I remove the sec:secure call and leave only the rest (adding %updating to the declaration) the second insert runs but the first one doesn't - the node is saved without a "id" attribute. Does this have something to do with the PUL order? (http://docs.basex.org/wiki/Update#Example)
Thanks for your hints! I feel like I'm overlooking something obvious... Daniel
Hi Daniel,
Quoted text · Daniel Kvasnička · 4 lines
- when executing it like this, inside of a closure, nothing happens. No > modifications of the database and no errors (%updating missing) either - > which is weird. Is this construct supported in 7.5? >
I'm not exactly sure about this one - can somebody else help me out here?
- when I remove the sec:secure call and leave only the rest (adding
Quoted text · Daniel Kvasnička · 5 lines
> %updating to the declaration) the second insert runs but the first one > doesn't - the node is saved without a "id" attribute. Does this have > something to do with the PUL order? ( > http://docs.basex.org/wiki/Update#Example) >
Exactly - the example in the documentation explains it all. With the XQUF it is not at all possible to access the changes you introduced in a query within the same query. If you want to do this you could use the *[transform expression]*, which modifies a copy of a given node. Like this:
* let $profile := *
* copy $p := json:parse-ml(convert:binary-to-string($data))*
* modify **insert node attribute id { sec:get-current-user-id()
} into $p*
* return $p
return (
insert node $profile as last into db:open("db")/s:root
)*
*
*
Hope this helps a little ...Cheers, Lukas
* * *[transform expression]* http://docs.basex.org/wiki/Update#transform
Hi and thanks, I kind of thought I'd have to do it in some similar way but I wasn't sure... Doesn't it introduce performance problems though? If you do this copying with some bigger chunk of XML does it take the same amount of memory or is it somehow "delta" optimized?
Daniel
Quoted text · Lukas Kircher · 28 lines
On Nov 22, 2012, at 15:17 , Lukas Kircher <lukaskircher1 at gmail.com> wrote: > Hi Daniel, > > - when executing it like this, inside of a closure, nothing happens. No modifications of the database and no errors (%updating missing) either - which is weird. Is this construct supported in 7.5? > > I'm not exactly sure about this one - can somebody else help me out here? > > - when I remove the sec:secure call and leave only the rest (adding %updating to the declaration) the second insert runs but the first one doesn't - the node is saved without a "id" attribute. Does this have something to do with the PUL order? (http://docs.basex.org/wiki/Update#Example) > > Exactly - the example in the documentation explains it all. With the XQUF it is not at all possible to access > the changes you introduced in a query within the same query. If you want to do this you could use the > [transform expression], which modifies a copy of a given node. Like this: > > let $profile := > copy $p := json:parse-ml(convert:binary-to-string($data)) > modify insert node attribute id { sec:get-current-user-id() } into $p > return $p > return ( > insert node $profile as last into db:open("db")/s:root > ) > > Hope this helps a little ... > > Cheers, > Lukas > > > [transform expression] http://docs.basex.org/wiki/Update#transform
Hi Daniel,
Quoted text · Daniel Kvasnička · 1 line
> Doesn't it introduce performance problems though? If you do this copying with some bigger chunk of XML does it take the same amount of memory or is it somehow "delta" optimized?
Yes; this is due to the specification, btw. Whatever you copy in your XQUF spec. is supposed to be cached before it is being evaluated.
Regarding updating operations in closures: the current version of the spec. disallows updating operations, because it cannot be statically determined if a dynamic function invocation is an updating expression or not. See [1] for more details.
Best, Christian
[1] http://www.w3.org/TR/xquery-update-30/#id-dynamic-function-invocation
Interesting, thanks. Now that I think about chaining of those "atomic" update expressions I think that it probably conforms better to the functional programming paradigm (which I'm - as an avid Clojure apprentice - not against at all :))
Daniel
Quoted text · Christian Grün · 17 lines
On 22. 11. 2012, at 15:40, Christian Grün <christian.gruen at gmail.com> wrote: > Hi Daniel, > >> Doesn't it introduce performance problems though? If you do this copying with some bigger chunk of XML does it take the same amount of memory or is it somehow "delta" optimized? > > Yes; this is due to the specification, btw. Whatever you copy in your > XQUF spec. is supposed to be cached before it is being evaluated. > > Regarding updating operations in closures: the current version of the > spec. disallows updating operations, because it cannot be statically > determined if a dynamic function invocation is an updating expression > or not. See [1] for more details. > > Best, > Christian > > [1] http://www.w3.org/TR/xquery-update-30/#id-dynamic-function-invocation
From my reading: it looks like the latest version of the spec has addressed the "updating operations in closures" issue. Can we expect a BaseX implementation soon :-)
/Andy
On Thu, Nov 22, 2012 at 2:40 PM, Christian Grün <christian.gruen at gmail.com>wrote:
Quoted text · Christian Grün · 23 lines
> Hi Daniel, > > > Doesn't it introduce performance problems though? If you do this copying > with some bigger chunk of XML does it take the same amount of memory or is > it somehow "delta" optimized? > > Yes; this is due to the specification, btw. Whatever you copy in your > XQUF spec. is supposed to be cached before it is being evaluated. > > Regarding updating operations in closures: the current version of the > spec. disallows updating operations, because it cannot be statically > determined if a dynamic function invocation is an updating expression > or not. See [1] for more details. > > Best, > Christian > > [1] http://www.w3.org/TR/xquery-update-30/#id-dynamic-function-invocation > _______________________________________________ > BaseX-Talk mailing list > BaseX-Talk at mailman.uni-konstanz.de > https://mailman.uni-konstanz.de/mailman/listinfo/basex-talk >
Hi Andy,
true.. For everyone else: the latest versions of the XQuery 3.0 specs have just been made public:
http://www.w3.org/TR/xquery-30/ http://www.w3.org/TR/xquery-update-30/ http://www.w3.org/TR/xpath-full-text-30/
Quoted text · Andy Bunce · 3 lines
> From my reading: it looks like the latest version of the spec has addressed > the "updating operations in closures" issue. Can we expect a BaseX > implementation soon :-)
Could you give me a hint which section do you exactly refer to? Christian
Quoted text · Andy Bunce · 33 lines
On Wed, Jan 9, 2013 at 10:19 PM, Andy Bunce <bunce.andy at gmail.com> wrote: > > /Andy > > > > On Thu, Nov 22, 2012 at 2:40 PM, Christian Grün <christian.gruen at gmail.com> > wrote: >> >> Hi Daniel, >> >> > Doesn't it introduce performance problems though? If you do this copying >> > with some bigger chunk of XML does it take the same amount of memory or is >> > it somehow "delta" optimized? >> >> Yes; this is due to the specification, btw. Whatever you copy in your >> XQUF spec. is supposed to be cached before it is being evaluated. >> >> Regarding updating operations in closures: the current version of the >> spec. disallows updating operations, because it cannot be statically >> determined if a dynamic function invocation is an updating expression >> or not. See [1] for more details. >> >> Best, >> Christian >> >> [1] http://www.w3.org/TR/xquery-update-30/#id-dynamic-function-invocation >> _______________________________________________ >> BaseX-Talk mailing list >> BaseX-Talk at mailman.uni-konstanz.de >> https://mailman.uni-konstanz.de/mailman/listinfo/basex-talk > >
…here is the official announcement:
Quoted text · Christian Grün · 53 lines
On Wed, Jan 9, 2013 at 10:38 PM, Christian Grün <christian.gruen at gmail.com> wrote: > Hi Andy, > > true.. For everyone else: the latest versions of the XQuery 3.0 specs > have just been made > public: > > http://www.w3.org/TR/xquery-30/ > http://www.w3.org/TR/xquery-update-30/ > http://www.w3.org/TR/xpath-full-text-30/ > >> From my reading: it looks like the latest version of the spec has addressed >> the "updating operations in closures" issue. Can we expect a BaseX >> implementation soon :-) > > Could you give me a hint which section do you exactly refer to? > Christian > ___________________________ > > On Wed, Jan 9, 2013 at 10:19 PM, Andy Bunce <bunce.andy at gmail.com> wrote: >> >> /Andy >> >> >> >> On Thu, Nov 22, 2012 at 2:40 PM, Christian Grün <christian.gruen at gmail.com> >> wrote: >>> >>> Hi Daniel, >>> >>> > Doesn't it introduce performance problems though? If you do this copying >>> > with some bigger chunk of XML does it take the same amount of memory or is >>> > it somehow "delta" optimized? >>> >>> Yes; this is due to the specification, btw. Whatever you copy in your >>> XQUF spec. is supposed to be cached before it is being evaluated. >>> >>> Regarding updating operations in closures: the current version of the >>> spec. disallows updating operations, because it cannot be statically >>> determined if a dynamic function invocation is an updating expression >>> or not. See [1] for more details. >>> >>> Best, >>> Christian >>> >>> [1] http://www.w3.org/TR/xquery-update-30/#id-dynamic-function-invocation >>> _______________________________________________ >>> BaseX-Talk mailing list >>> BaseX-Talk at mailman.uni-konstanz.de >>> https://mailman.uni-konstanz.de/mailman/listinfo/basex-talk >> >>
I was thinking of http://www.w3.org/TR/xquery-update-30/#id-dynamic-function-invocation and http://www.w3.org/TR/xquery-update-30/#id-inline-function
Allowing something like:
declare updating function local:check($fn){
if(1=random:integer(2)) then db:output($fn())
else db:output("no action")
};
let $v:="good"
return local:check(%updating function(){ db:output($v)})/Andy
On Wed, Jan 9, 2013 at 9:38 PM, Christian Grün <christian.gruen at gmail.com>wrote:
Quoted text · Christian Grün · 57 lines
> Hi Andy, > > true.. For everyone else: the latest versions of the XQuery 3.0 specs > have just been made > public: > > http://www.w3.org/TR/xquery-30/ > http://www.w3.org/TR/xquery-update-30/ > http://www.w3.org/TR/xpath-full-text-30/ > > > From my reading: it looks like the latest version of the spec has > addressed > > the "updating operations in closures" issue. Can we expect a BaseX > > implementation soon :-) > > Could you give me a hint which section do you exactly refer to? > Christian > ___________________________ > > On Wed, Jan 9, 2013 at 10:19 PM, Andy Bunce <bunce.andy at gmail.com> wrote: > > > > /Andy > > > > > > > > On Thu, Nov 22, 2012 at 2:40 PM, Christian Grün < > christian.gruen at gmail.com> > > wrote: > >> > >> Hi Daniel, > >> > >> > Doesn't it introduce performance problems though? If you do this > copying > >> > with some bigger chunk of XML does it take the same amount of memory > or is > >> > it somehow "delta" optimized? > >> > >> Yes; this is due to the specification, btw. Whatever you copy in your > >> XQUF spec. is supposed to be cached before it is being evaluated. > >> > >> Regarding updating operations in closures: the current version of the > >> spec. disallows updating operations, because it cannot be statically > >> determined if a dynamic function invocation is an updating expression > >> or not. See [1] for more details. > >> > >> Best, > >> Christian > >> > >> [1] > http://www.w3.org/TR/xquery-update-30/#id-dynamic-function-invocation > >> _______________________________________________ > >> BaseX-Talk mailing list > >> BaseX-Talk at mailman.uni-konstanz.de > >> https://mailman.uni-konstanz.de/mailman/listinfo/basex-talk > > > > >
…thanks, I’ll have a look into that soon.
Quoted text · Andy Bunce · 78 lines
On Thu, Jan 10, 2013 at 12:56 PM, Andy Bunce <bunce.andy at gmail.com> wrote: > I was thinking of > http://www.w3.org/TR/xquery-update-30/#id-dynamic-function-invocation and > http://www.w3.org/TR/xquery-update-30/#id-inline-function > > Allowing something like: > > declare updating function local:check($fn){ > if(1=random:integer(2)) then db:output($fn()) > else db:output("no action") > }; > let $v:="good" > return local:check(%updating function(){ db:output($v)}) > > /Andy > > > On Wed, Jan 9, 2013 at 9:38 PM, Christian Grün <christian.gruen at gmail.com> > wrote: >> >> Hi Andy, >> >> true.. For everyone else: the latest versions of the XQuery 3.0 specs >> have just been made >> public: >> >> http://www.w3.org/TR/xquery-30/ >> http://www.w3.org/TR/xquery-update-30/ >> http://www.w3.org/TR/xpath-full-text-30/ >> >> > From my reading: it looks like the latest version of the spec has >> > addressed >> > the "updating operations in closures" issue. Can we expect a BaseX >> > implementation soon :-) >> >> Could you give me a hint which section do you exactly refer to? >> Christian >> ___________________________ >> >> On Wed, Jan 9, 2013 at 10:19 PM, Andy Bunce <bunce.andy at gmail.com> wrote: >> > >> > /Andy >> > >> > >> > >> > On Thu, Nov 22, 2012 at 2:40 PM, Christian Grün >> > <christian.gruen at gmail.com> >> > wrote: >> >> >> >> Hi Daniel, >> >> >> >> > Doesn't it introduce performance problems though? If you do this >> >> > copying >> >> > with some bigger chunk of XML does it take the same amount of memory >> >> > or is >> >> > it somehow "delta" optimized? >> >> >> >> Yes; this is due to the specification, btw. Whatever you copy in your >> >> XQUF spec. is supposed to be cached before it is being evaluated. >> >> >> >> Regarding updating operations in closures: the current version of the >> >> spec. disallows updating operations, because it cannot be statically >> >> determined if a dynamic function invocation is an updating expression >> >> or not. See [1] for more details. >> >> >> >> Best, >> >> Christian >> >> >> >> [1] >> >> http://www.w3.org/TR/xquery-update-30/#id-dynamic-function-invocation >> >> _______________________________________________ >> >> BaseX-Talk mailing list >> >> BaseX-Talk at mailman.uni-konstanz.de >> >> https://mailman.uni-konstanz.de/mailman/listinfo/basex-talk >> > >> > > >
Written for BaseX 7.3, 7.5. BaseX may have changed since: please check the current documentation.