Hi Bartosz (cc @basex-talk),
if you want to cache your data in temporary files without losing synchronicity, you may take advantage of the (yet undocumented, but stable) locking options that have been introduced with BaseX 7.7. The following example query...
declare option query:write-lock "file-io"; file:write-text("x.txt", '123')
...ensures that all other queries with a read-lock or write-lock option on the (arbitrarily chosen) "file-io" string, such as e.g.…
declare option query:read-lock "file-io"; file:read-text("x.txt", '123')
…will be queued until the query has been evaluated.
Next, please note that XQuery demands that a doc() function in a query will always return the same document instance. In your example, this means that the second doc() function won’t repeatedly access the source file, but instead return the existing document node reference. You may surpass this by using fetch:text() or file:read-text() and parse-xml():
let $path := $path || '/index.xml' let $indexold := parse-xml(file:read-text($path))//index let $indexnew := <index>{ $indexold + 1 }</index> let $filewrite := file:write($path), $indexnew) let $index := parse-xml(file:read-text($path))
If you want to use pure XQuery (Update/3.0), however, you’ll have to split your query into several files, or you can use the helpful transform expression [1], which allows you to create updated main-memory instances, which can then be stored in databases or processed any other way. An example:
copy $doc := parse-xml(file:read-text($path)) modify replace value of node $doc//index with $indexold + 1 return $doc
As your problem is quite a frequent one, there’s some good chance that an upcoming version of XQuery Update will allow both updates and returned results in one query.
I hope this gives you some inspiration, Christian
[1] http://docs.basex.org/wiki/XQuery_Update#transform ___________________________
On Mon, May 27, 2013 at 12:44 PM, Bartosz Marciniak marciniak.b@gmail.com wrote:
Christan, what I mean is reading updated data from db and then binding them to a variable by let expression.
Initially, I tried to use file:write() function to store temporaty data in the external file using following solution:
let $indexold := doc(concat($path , '/index.xml'))//index let $indexnew := <index>{$indexold + 1}</index> let $filewrite := file:write(concat($path , '/index.xml'), $indexnew, ()) let $index := doc(concat($path , '/index.xml'))
but I discoverd that the file:write() function is not synchronized. So I tried to store temporary data in the db.
I hope I clearly presented the problem, if not please forget about that :-)
regards Bartosz
2013/5/27 Christian Grün christian.gruen@gmail.com
Hi Bartosz,
..what do you mean exactly with "the result"?
Best, Christian
Christian, thank you very much. This example works and explained a lot to me. But could you just explain is it possible or not to evaluate further the result?
basex-talk@mailman.uni-konstanz.de