Hi, I am having issues with updating functions in BaseX 7.5 (official release).
When I update a document, its content is updated with the content of another document.
I even perform the db:optimized in a separate function after a forward to ensure that the db:replace is in fact completed before indexes are optimized.
* *
To replicate: you'll need a db named 'en-us' with the 3 following documents (file names don't matter):
<menu id="devicehelp"/> <menu id="smbonly"/> <menu id="ptt-help"/>
Then use these functions:
* *
*declare* %rest:path("/admin/refresh-menu-headings") %rest:GET %rest:query-param("menu-id", "{$menu-id}", "devicehelp") *updating* *function* *admin:refresh-menu-headings*(*$menu-id* *as ** xs:string*){
(:Get the content:) *let* *$raw-menu* := *app:open-db*('en-us')/*menu*[*@id* = *$menu-id* ]
(:Get the file location:) *let* *$menu-uri* := *substring-after*(*$raw-menu*/*base-uri*(), 'en-us/')
(:Copy the content:) *let* *$menu* := *$raw-menu*
* (:Output the content in a file to ensure you have the right one:)*
* **let* *$debug* := *file:write*('debug-ouch.xml', *document*{*$menu* })
(:Output the file uri to ensure you have the right one:)
*let* *$debug-uri* := *file:write*('debug-uri.xml', *$menu-uri*)
(:Replace the content of the file with the same content that was outputted in debug-ouch:) *return *(*db:replace*('en-us', *$menu-uri*, *$menu*), *db:output*(restxq:forward /restxq/admin/success/heading-refresh</restxq:forward>))
};
*declare* %rest:path('/admin/success/heading-refresh') *updating* *function* *admin:success-heading-refresh*(){ *let **$result* := <html *xmlns*=*"http://www.w3.org/1999/xhtml%22*%3E <head><title>Add headings to menu topicrefs </title></head> <body> <h2>Add headings to menu topicrefs</h2> <ul> <li *style*=*"color:green"*>Menus were updated successfully.</li> </ul> </body> </html> *return *(*db:optimize*('en-us'), *db:output*(*$result*))
RESULT: The result after optimize if your query for a list of the /menu/data(@id) should be devicehelp, smbonly, ptt-help, but it's ptt-help, smbonly, ptt-help.
debug-ouch.xml shows the correct content (content of menu devicehelp), debug-uri shows the right file path (path of menu ptt-help), yet the content of menu with @id devicehelp gets replaced by the content of menu with @id=ptt-help after db:replace.
Note: If I use db:optimize('en-us', true()), I get 'unexpected error: 0'
;) ..hi France,
it may take us a while to reproduce what’s going on in your code, so.. do you think you could further simplify your example? Or, ideally, minimize it to a simple db:replace() function?
Note: If I use db:optimize('en-us', true()), I get 'unexpected error: 0'
You could check the consistency of your database via the INSPECT command [1] before and after running your query.
Thanks, Christian
[1] http://docs.basex.org/wiki/Commands#INSPECT ___________________________________
To replicate: you'll need a db named 'en-us' with the 3 following documents (file names don't matter):
<menu id="devicehelp"/> <menu id="smbonly"/> <menu id="ptt-help"/>
Then use these functions:
declare %rest:path("/admin/refresh-menu-headings") %rest:GET %rest:query-param("menu-id", "{$menu-id}", "devicehelp") updating function admin:refresh-menu-headings($menu-id as xs:string){
(:Get the content:) let $raw-menu := app:open-db('en-us')/menu[@id = $menu-id] (:Get the file location:) let $menu-uri := substring-after($raw-menu/base-uri(), 'en-us/') (:Copy the content:) let $menu := $raw-menu (:Output the content in a file to ensure you have the right one:) let $debug := file:write('debug-ouch.xml', document{$menu}) (:Output the file uri to ensure you have the right one:) let $debug-uri := file:write('debug-uri.xml', $menu-uri) (:Replace the content of the file with the same content that was
outputted in debug-ouch:)
return (db:replace('en-us', $menu-uri, $menu),
db:output(restxq:forward/restxq/admin/success/heading-refresh</restxq:forward>))
};
declare %rest:path('/admin/success/heading-refresh') updating function admin:success-heading-refresh(){ let $result := <html xmlns="http://www.w3.org/1999/xhtml"> <head><title>Add headings to menu topicrefs</title></head> <body> <h2>Add headings to menu topicrefs</h2> <ul> <li style="color:green">Menus were updated successfully.</li> </ul> </body> </html> return (db:optimize('en-us'), db:output($result))
RESULT: The result after optimize if your query for a list of the /menu/data(@id) should be devicehelp, smbonly, ptt-help, but it's ptt-help, smbonly, ptt-help.
debug-ouch.xml shows the correct content (content of menu devicehelp), debug-uri shows the right file path (path of menu ptt-help), yet the content of menu with @id devicehelp gets replaced by the content of menu with @id=ptt-help after db:replace.
Note: If I use db:optimize('en-us', true()), I get 'unexpected error: 0'
-- France Baril Architecte documentaire / Documentation architect france.baril@architextus.com (514) 572-0341 _______________________________________________ BaseX-Talk mailing list BaseX-Talk@mailman.uni-konstanz.de https://mailman.uni-konstanz.de/mailman/listinfo/basex-talk
You'll get the same error without the forward, without the debug lines and without the second function. The error is that the content of the file with menu-id=devicehelp is going to be replaced by the content of an other menu.
The example becomes:
You'll need a db named 'en-us' with the 3 following documents (file names don't matter):
<menu id="devicehelp"/> <menu id="smbonly"/> <menu id="ptt-help"/>
Then use this functions:
* *
*declare* %rest:path("/admin/refresh-menu-headings") %rest:GET %rest:query-param("menu-id", "{$menu-id}", "devicehelp") *updating* *function* *admin:refresh-menu-headings*(*$menu-id* *as ** xs:string*){ *let* *$raw-menu* := *app:open-db*('en-us')/*menu*[*@id* = *$menu-id* ]
*let* *$menu-uri* := *substring-after*(*$raw-menu*/*base-uri*(), 'en-us/')
*let* *$menu* := *$raw-menu* *return *(*db:replace*('en-us', *$menu-uri*, *$menu*), *db:output*(<html *xmlns*=*" http://www.w3.org/1999/xhtml%22*%3E <head><title>Add headings to menu topicrefs </title></head> <body> <h2>Add headings to menu topicrefs</h2> <ul> <li *style*=*"color:green"*>Menus were updated successfully.</li> </ul> </body> </html>))
};
On Wed, Jan 2, 2013 at 3:43 PM, Christian Grün christian.gruen@gmail.comwrote:
;) ..hi France,
it may take us a while to reproduce what’s going on in your code, so.. do you think you could further simplify your example? Or, ideally, minimize it to a simple db:replace() function?
Note: If I use db:optimize('en-us', true()), I get 'unexpected error: 0'
You could check the consistency of your database via the INSPECT command [1] before and after running your query.
Thanks, Christian
[1] http://docs.basex.org/wiki/Commands#INSPECT ___________________________________
To replicate: you'll need a db named 'en-us' with the 3 following
documents
(file names don't matter):
<menu id="devicehelp"/> <menu id="smbonly"/> <menu id="ptt-help"/>
Then use these functions:
declare %rest:path("/admin/refresh-menu-headings") %rest:GET %rest:query-param("menu-id", "{$menu-id}", "devicehelp") updating function admin:refresh-menu-headings($menu-id as xs:string){
(:Get the content:) let $raw-menu := app:open-db('en-us')/menu[@id = $menu-id] (:Get the file location:) let $menu-uri := substring-after($raw-menu/base-uri(), 'en-us/') (:Copy the content:) let $menu := $raw-menu (:Output the content in a file to ensure you have the right one:) let $debug := file:write('debug-ouch.xml', document{$menu}) (:Output the file uri to ensure you have the right one:) let $debug-uri := file:write('debug-uri.xml', $menu-uri) (:Replace the content of the file with the same content that was
outputted in debug-ouch:)
return (db:replace('en-us', $menu-uri, $menu),
db:output(restxq:forward/restxq/admin/success/heading-refresh</restxq:forward>))
};
declare %rest:path('/admin/success/heading-refresh') updating function admin:success-heading-refresh(){ let $result := <html xmlns="http://www.w3.org/1999/xhtml"> <head><title>Add headings to menu topicrefs</title></head> <body> <h2>Add headings to menu topicrefs</h2> <ul> <li style="color:green">Menus were updated successfully.</li> </ul> </body> </html> return (db:optimize('en-us'), db:output($result))
RESULT: The result after optimize if your query for a list of the /menu/data(@id) should be devicehelp, smbonly, ptt-help, but it's ptt-help, smbonly, ptt-help.
debug-ouch.xml shows the correct content (content of menu devicehelp), debug-uri shows the right file path (path of menu ptt-help), yet the
content
of menu with @id devicehelp gets replaced by the content of menu with @id=ptt-help after db:replace.
Note: If I use db:optimize('en-us', true()), I get 'unexpected error: 0'
-- France Baril Architecte documentaire / Documentation architect france.baril@architextus.com (514) 572-0341 _______________________________________________ BaseX-Talk mailing list BaseX-Talk@mailman.uni-konstanz.de https://mailman.uni-konstanz.de/mailman/listinfo/basex-talk
Baril,
sorry, but I’m still not sure how to reproduce your use case.
let $raw-menu := app:open-db('en-us')/menu[@id = $menu-id]
Is app:open-db(...) equivalent to db:open(...) ?
Do you think that the following script is equivalent to what you do via RESTXQ?
<commands> <create-db name='en-us'/> <add path='devicehelp.xml'><menu id="devicehelp"/></add> <add path='smbonly.xml'><menu id="smbonly"/></add> <add path='ptt-help.xml'><menu id="ptt-help"/></add> <xquery><![CDATA[ db:replace('en-us', 'devicehelp.xml', <menu id="devicehelp"/>) ]]></xquery> <list name='en-us'/> </commands>
You can save this script using the ".bxs" suffix, and open and run it via the GUI or on command-line (basex script.bxs).
Christian
Yes it is somewhat equivalent.
I modified it a little bit, to test the update. Devicehelp doesn't seem get updated with this command.
<commands> <create-db name="en-us"/> <add path="devicehelp.xml"> <menu id="devicehelp"/> </add> <add path="smbonly.xml"> <menu id="smbonly"/> </add> <add path="ptt-help.xml"> <menu id="ptt-help"/> </add> <xquery><![CDATA[ db:replace('en-us', 'devicehelp.xml', <menu id="new"/>) ]]></xquery> <list name="en-us"/> </commands>
for $x in /*
return $x/data(@id)
gets me: devicehelp smbonly ptt-help
On Sat, Jan 5, 2013 at 4:33 AM, Christian Grün christian.gruen@gmail.comwrote:
Baril,
sorry, but I’m still not sure how to reproduce your use case.
let $raw-menu := app:open-db('en-us')/menu[@id = $menu-id]
Is app:open-db(...) equivalent to db:open(...) ?
Do you think that the following script is equivalent to what you do via RESTXQ?
<commands> <create-db name='en-us'/> <add path='devicehelp.xml'><menu id="devicehelp"/></add> <add path='smbonly.xml'><menu id="smbonly"/></add> <add path='ptt-help.xml'><menu id="ptt-help"/></add> <xquery><![CDATA[ db:replace('en-us', 'devicehelp.xml', <menu id="devicehelp"/>) ]]></xquery> <list name='en-us'/> </commands>
You can save this script using the ".bxs" suffix, and open and run it via the GUI or on command-line (basex script.bxs).
Christian
I wonder what this could be. The script below gives me "smbonly ptt-help new" as result; what do you get?
<commands> <create-db name="en-us"/> <add path="devicehelp.xml"> <menu id="devicehelp"/> </add> <add path="smbonly.xml"> <menu id="smbonly"/> </add> <add path="ptt-help.xml"> <menu id="ptt-help"/> </add> <xquery> <![CDATA[ db:replace('en-us', 'devicehelp.xml', <menu id="new"/>) ]]></xquery> <xquery> for $x in /* return $x/data(@id) </xquery> </commands>
Never mind, I still had the terminal opened when I ran this in the GUI… probably was interfering.
I'm back to 7.4 to be able to develop on something that works for my team. As soon as I can get back to 7.5, I'll test the command again. The two of them don't seem to work well in parallel.
This is more like what was failing in RESTXQ. You want doc #2 to replace the content of doc #2 with its own content, but instead it updated the file with the content from one of the other 2 documents.
<commands> <create-db name="en-us"/> <add path="devicehelp.xml"> <menu id="devicehelp"/> </add> <add path="smbonly.xml"> <menu id="smbonly"/> </add> <add path="ptt-help.xml"> <menu id="ptt-help"/> </add> <xquery><![CDATA[ let $x := db:open('en-us')/*[@id='smbonly'] let $x-uri := substring-after($x/base-uri(), 'en-us') return db:replace('en-us', $x-uri, document{$x}) ]]></xquery> <list name="en-us"/> </commands>
On Tue, Jan 8, 2013 at 12:48 PM, Christian Grün christian.gruen@gmail.comwrote:
I wonder what this could be. The script below gives me "smbonly ptt-help new" as result; what do you get?
<commands> <create-db name="en-us"/> <add path="devicehelp.xml"> <menu id="devicehelp"/> </add> <add path="smbonly.xml"> <menu id="smbonly"/> </add> <add path="ptt-help.xml"> <menu id="ptt-help"/> </add> <xquery> <![CDATA[ db:replace('en-us', 'devicehelp.xml', <menu id="new"/>) ]]></xquery> <xquery> for $x in /* return $x/data(@id) </xquery> </commands>
basex-talk@mailman.uni-konstanz.de