Storing and reading data - migrate from exist-db

Saturday, 25 May 2013 · 3 messages · last reply 27 May 2013
BM
Bartosz Marciniak25 May 2013 17:46 #
Hello, I'm trying to rewritte XQuery prepared for exist-db into baseX. I have a problem with storing data in the database. In exist-db xmldb:store() function returns a string and there is no problem to create let/return construct. Is it possible to create a similar solution in baseX? --- exist-db ----------------------------------------- xquery version "3.0";
declare function local:indexget() as item()* {
let $index := doc('db/index.xml')
return xs:integer($index/index/text())
};

declare function local:indexset($index as xs:integer) as xs:string? {
let $newresource :=  xmldb:store('/db','index.xml', <index>{$index}</index>)
return $newresource
};

let $indexnew  :=  local:indexget() + 1
let $newresource := local:indexset($indexnew)
return local:indexget()
----------------------------------------------------
And these are baseX functions I wrote, but I don't know if is it possible to create solution similar to above? Can anyone help me solve this problem?
---- BaseX ----------------------------------------------
declare function local:indexget() as item()* {
let $index := doc('/home/index.xml')
return xs:integer($index/index/text())
};

declare %updating function local:indexset($index as xs:integer)  {
db:replace('index', 'index.xml', <index>{$index}</index>)
};
(....) ------------------------------------------------------------ Regards Bartosz Marciniak
CG
Christian Grün27 May 2013 08:37 #
Dear Bartosz,
Quoted text · Bartosz Marciniak · 2 lines
> In exist-db xmldb:store() function returns a string and there is no problem > to create let/return construct.
I must confess I know too little about the update functions of eXist-db, but as far as I see, you don’t further evaluate the result of your update operation in your FLWOR expression. Instead, you seem to want to return a value in your query. BaseX is based on the semantics of the XQuery Update Facility, in which an updating query never returns results [1], but we have included the db:output() function for that [2]. Your main expression could then look as follows:
  let $indexnew  :=  local:indexget() + 1
  return (
    local:indexset($indexnew),
    db:output($indexnew)
  )
CG
Christian Grün27 May 2013 13:44 #
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
Quoted text · Bartosz Marciniak · 45 lines
On Mon, May 27, 2013 at 12:44 PM, Bartosz Marciniak <marciniak.b at 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 at 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? > >

⚡Generated with XQuery