BaseX as persistence layer

Monday, 16 August 2010 · 9 messages · last reply 18 Aug 2010
AW
Andreas Weilerin reply to chas, 16 Aug 2010, 13:4016 Aug 2010 12:00 #
Hi Chas,
Quoted text · chas · 3 lines
> QUESTION: If I rerun the above, will it overwrite the DB if it already > exists, or will it just open the existing DB? Can't find anything in the > API about that.
This will overwrite the DB.
Quoted text · chas · 3 lines
> for $x in /forum/users/User > where $x/username="Chas" > return replace node $x with " + chas
this query replaces the whole User-node with your quoted value. So in the deleting query your User-node is not there anymore. Try out the following:
for $x in /forum/users/User
where $x/username="Chas"
return replace value of node $x/username with " + chas
Then this one should work:
for $x in /forum/users/User
where $x/password="secret"
return delete nodes $x
I hope this helps, dont hesitate to ask for more. Kind regards, Andreas
Quoted text · chas · 76 lines
chas at munat.com schrieb: > I'm trying to use BaseX as a persistence layer in a project (together with > XStream). I have a few questions and I'm not having any luck with the > documentation. > > I've gotten pretty far. I have a User object (simplified for this example) > with an id (UUID), a username (String), and a password (String). XStream > turns this into: > > <User> > <id>98bdb472-97ad-4de1-b1c6-a482d7f06d94</id> > <username>Chas</username> > <password>secret</password> > </User> > > I've created a DB called "db" (clever, huh?): > > new CreateDB("cop", "<blog><users/></blog>").execute(context) > > QUESTION: If I rerun the above, will it overwrite the DB if it already > exists, or will it just open the existing DB? Can't find anything in the > API about that. > > Then I save my User like this: > > new XQuery("insert node" + chas + " into /blog/users").execute(context) > > where chas is the above XML. > > This works great! When I need to reinflate the object, I just do: > > chas = new XQuery(""" > for $x in /forum/users/User > where $x/username="Chas" > return $x > """).execute(context) > > Then I use XStream to reinflate the object. > > Any suggestions for improvement? > > So now the problem. I need to update this object in the database. The > simplest way is just to update the whole object. So I change my username > and use XStream to create the new XML: > > <User> > <id>98bdb472-97ad-4de1-b1c6-a482d7f06d94</id> > <username>Charles</username> > <password>secret</password> > </User> > > I read that one must use put() to export the changes, but maybe I'm > misunderstanding this. I'm have this: > > for $x in /forum/users/User > where $x/username="Chas" > return replace node $x with " + chas > > This and seems to work, but then when I try to delete the node thus: > > for $x in /forum/users/User > where $x/password="secret" > return delete nodes $x > > It does not work. What am I missing? > > Thanks for any help. If this thing works, I'm happy to open it up so > others can work on it, too. > > Chas. > > _______________________________________________ > BaseX-Talk mailing list > BaseX-Talk at mailman.uni-konstanz.de > https://mailman.uni-konstanz.de/mailman/listinfo/basex-talk >
LW
Leonard Wörteler16 Aug 2010 12:39 #
Hi Chas, a nice simplification would be to use XPath instead of full-blown FLWORs for your simple selections:
Quoted text · Andreas Weiler · 6 lines
Am 16.08.2010 11:41, schrieb chas at munat.com: > chas = new XQuery(""" > for $x in /forum/users/User > where $x/username="Chas" > return $x > """).execute(context)
could then be rewritten as chas = new XQuery("/forum/users/User[username='Chas']").execute(context) This can also be applied to the other queries:
Quoted text · Andreas Weiler · 4 lines
Am 16.08.2010 12:00, schrieb Andreas Weiler: > for $x in /forum/users/User > where $x/username="Chas" > return replace value of node $x/username with " + chas
replace value of node /forum/users/User/username[text() = 'Chas'] with 'Charles' (This only works if the username is unique and thus the XPath expression yields a single node.)
Quoted text · Andreas Weiler · 5 lines
> Then this one should work: > > for $x in /forum/users/User > where $x/password="secret" > return delete nodes $x
delete nodes /forum/users/User[password='secret'] XQuery is still needed if you want to transform the results in the query. Hope this helps, Cheers Leo
C
chas16 Aug 2010 13:40 #
I'm trying to use BaseX as a persistence layer in a project (together with XStream). I have a few questions and I'm not having any luck with the documentation. I've gotten pretty far. I have a User object (simplified for this example) with an id (UUID), a username (String), and a password (String). XStream turns this into:
<User>
  <id>98bdb472-97ad-4de1-b1c6-a482d7f06d94</id>
  <username>Chas</username>
  <password>secret</password>
</User>
I've created a DB called "db" (clever, huh?): new CreateDB("cop", "<blog><users/></blog>").execute(context) QUESTION: If I rerun the above, will it overwrite the DB if it already exists, or will it just open the existing DB? Can't find anything in the API about that. Then I save my User like this: new XQuery("insert node" + chas + " into /blog/users").execute(context) where chas is the above XML. This works great! When I need to reinflate the object, I just do:
chas = new XQuery("""
  for $x in /forum/users/User
  where $x/username="Chas"
  return $x
""").execute(context)
Then I use XStream to reinflate the object. Any suggestions for improvement? So now the problem. I need to update this object in the database. The simplest way is just to update the whole object. So I change my username and use XStream to create the new XML:
<User>
  <id>98bdb472-97ad-4de1-b1c6-a482d7f06d94</id>
  <username>Charles</username>
  <password>secret</password>
</User>
I read that one must use put() to export the changes, but maybe I'm misunderstanding this. I'm have this:
for $x in /forum/users/User
where $x/username="Chas"
return replace node $x with " + chas
This and seems to work, but then when I try to delete the node thus:
for $x in /forum/users/User
where $x/password="secret"
return delete nodes $x
It does not work. What am I missing? Thanks for any help. If this thing works, I'm happy to open it up so others can work on it, too. Chas.
DG
Dave Glick16 Aug 2010 21:05 #
Hello, I think there might be a bug in Data.pre()... When you use Data.id() to get the id for a given pre, it's easy enough to check Data.meta.size to make sure you're not asking for the id of a pre value that's beyond the end of the table since pre values are contiguous and are maintained when the database is updated. However, I've noticed some crashes when asking for the pre value of a given id using Data.pre(). Specifically, if I create a large database and then remove all but a few nodes I have a very large Data.meta.lastid value but a very small Data.meta.size. If I then ask for the pre value for a very large id using Data.pre() that may or may not still be in the database, I often end up with an exception message such as "Invalid Data Access [pre:259, indexSize:3, access:3 > 2]". The expected result would simply be -1. I think the problem is that even though the id I'm asking for is still smaller than my Data.meta.lastid value, it's large enough that after the Data.table has been resized after removing most of the nodes, the call to Data.id() within Data.pre() is probing the table beyond its boundaries as it scans. Did that make sense? Dave
CG
Christian Grün17 Aug 2010 01:36 #
Dave, thanks for the hint. Yes, that absolutely made sense; I guess the following change (which will be uploaded with the next commit) should suffice to fix the problem: Data, line 275:
    for(int p = 0, ps = Math.min(meta.size, id); p < ps; ++p)
      if(id == id(p)) return p;
Currently, due to its inefficiency, the method in question isn't used anywhere in the code. We're working on an ID-Pre mapping, which will allow us to keep on using existing index structures after update operations. This is work in progress, though; just stay tuned! Christian
Quoted text · Dave Glick · 12 lines
On Mon, Aug 16, 2010 at 7:06 PM, Dave Glick <dglick at dracorp.com> wrote: > Hello, > > I think there might be a bug in Data.pre()... > > When you use Data.id() to get the id for a given pre, it's easy enough to check Data.meta.size to make sure you're not asking for the id of a pre value that's beyond the end of the table since pre values are contiguous and are maintained when the database is updated. > > However, I've noticed some crashes when asking for the pre value of a given id using Data.pre(). Specifically, if I create a large database and then remove all but a few nodes I have a very large Data.meta.lastid value but a very small Data.meta.size. If I then ask for the pre value for a very large id using Data.pre() that may or may not still be in the database, I often end up with an exception message such as "Invalid Data Access [pre:259, indexSize:3, access:3 > 2]". The expected result would simply be -1. I think the problem is that even though the id I'm asking for is still smaller than my Data.meta.lastid value, it's large enough that after the Data.table has been resized after removing most of the nodes, the call to Data.id() within Data.pre() is probing the table beyond its boundaries as it scans. > > Did that make sense? > > Dave
DG
Dave Glick17 Aug 2010 16:17 #
Excellent, thanks. I know a lot of people are using BaseX through the server and other APIs, but we use it directly and are thankful for the continued development on that front. We also make heavy use of the pre-to-id mapping and are especially grateful for any performance improvements you plan on making there.
Quoted text · Christian Grün · 30 lines
-----Original Message----- From: Christian Grün [mailto:christian.gruen at gmail.com] Sent: Monday, August 16, 2010 7:36 PM To: Dave Glick Cc: BaseX-Talk at mailman.uni-konstanz.de Subject: Re: [basex-talk] Possible bug in Data.pre()? Dave, thanks for the hint. Yes, that absolutely made sense; I guess the following change (which will be uploaded with the next commit) should suffice to fix the problem: Data, line 275: for(int p = 0, ps = Math.min(meta.size, id); p < ps; ++p) if(id == id(p)) return p; Currently, due to its inefficiency, the method in question isn't used anywhere in the code. We're working on an ID-Pre mapping, which will allow us to keep on using existing index structures after update operations. This is work in progress, though; just stay tuned! Christian On Mon, Aug 16, 2010 at 7:06 PM, Dave Glick <dglick at dracorp.com> wrote: > Hello, > > I think there might be a bug in Data.pre()... > > When you use Data.id() to get the id for a given pre, it's easy enough to check Data.meta.size to make sure you're not asking for the id of a pre value that's beyond the end of the table since pre values are contiguous and are maintained when the database is updated. > > However, I've noticed some crashes when asking for the pre value of a given id using Data.pre(). Specifically, if I create a large database and then remove all but a few nodes I have a very large Data.meta.lastid value but a very small Data.meta.size. If I then ask for the pre value for a very large id using Data.pre() that may or may not still be in the database, I often end up with an exception message such as "Invalid Data Access [pre:259, indexSize:3, access:3 > 2]". The expected result would simply be -1. I think the problem is that even though the id I'm asking for is still smaller than my Data.meta.lastid value, it's large enough that after the Data.table has been resized after removing most of the nodes, the call to Data.id() within Data.pre() is probing the table beyond its boundaries as it scans. > > Did that make sense? > > Dave
LW
Leonard Wörtelerin reply to Dave Glick, 18 Aug 2010, 16:4718 Aug 2010 15:00 #
Hi Dave,
Quoted text · Dave Glick · 4 lines
Am 18.08.2010 14:48, schrieb Dave Glick: > By the way, I did notice the IDPREMAPON flag and that it's currently > set to false. Is that ready for use yet, or is it mostly for > internal testing right now?
these data structures are still in an early state of development and aren't safe to use yet. Sorry for that... Cheers, Leo
DG
Dave Glickin reply to Christian Grün, 17 Aug 2010, 01:3618 Aug 2010 16:47 #
By the way, I did notice the IDPREMAPON flag and that it's currently set to false. Is that ready for use yet, or is it mostly for internal testing right now?
Quoted text · Christian Grün · 37 lines
-----Original Message----- From: Dave Glick Sent: Tuesday, August 17, 2010 8:18 AM To: 'Christian Grün' Cc: 'BaseX-Talk at mailman.uni-konstanz.de' Subject: RE: [basex-talk] Possible bug in Data.pre()? Excellent, thanks. I know a lot of people are using BaseX through the server and other APIs, but we use it directly and are thankful for the continued development on that front. We also make heavy use of the pre-to-id mapping and are especially grateful for any performance improvements you plan on making there. -----Original Message----- From: Christian Grün [mailto:christian.gruen at gmail.com] Sent: Monday, August 16, 2010 7:36 PM To: Dave Glick Cc: BaseX-Talk at mailman.uni-konstanz.de Subject: Re: [basex-talk] Possible bug in Data.pre()? Dave, thanks for the hint. Yes, that absolutely made sense; I guess the following change (which will be uploaded with the next commit) should suffice to fix the problem: Data, line 275: for(int p = 0, ps = Math.min(meta.size, id); p < ps; ++p) if(id == id(p)) return p; Currently, due to its inefficiency, the method in question isn't used anywhere in the code. We're working on an ID-Pre mapping, which will allow us to keep on using existing index structures after update operations. This is work in progress, though; just stay tuned! Christian On Mon, Aug 16, 2010 at 7:06 PM, Dave Glick <dglick at dracorp.com> wrote: > Hello, > > I think there might be a bug in Data.pre()... > > When you use Data.id() to get the id for a given pre, it's easy enough to check Data.meta.size to make sure you're not asking for the id of a pre value that's beyond the end of the table since pre values are contiguous and are maintained when the database is updated. > > However, I've noticed some crashes when asking for the pre value of a given id using Data.pre(). Specifically, if I create a large database and then remove all but a few nodes I have a very large Data.meta.lastid value but a very small Data.meta.size. If I then ask for the pre value for a very large id using Data.pre() that may or may not still be in the database, I often end up with an exception message such as "Invalid Data Access [pre:259, indexSize:3, access:3 > 2]". The expected result would simply be -1. I think the problem is that even though the id I'm asking for is still smaller than my Data.meta.lastid value, it's large enough that after the Data.table has been resized after removing most of the nodes, the call to Data.id() within Data.pre() is probing the table beyond its boundaries as it scans. > > Did that make sense? > > Dave
DG
Dave Glickin reply to Leonard Wörteler, 18 Aug 2010, 15:0018 Aug 2010 17:00 #
Leo - no problem. I'm just glad some work is being done in the area and looking forward to when it's more stable.
Quoted text · Leonard Wörteler · 15 lines
-----Original Message----- From: Leonard Wörteler [mailto:leonard.woerteler at uni-konstanz.de] Sent: Wednesday, August 18, 2010 9:01 AM To: basex-talk at mailman.uni-konstanz.de Cc: Dave Glick Subject: Re: [basex-talk] Possible bug in Data.pre()? Hi Dave, Am 18.08.2010 14:48, schrieb Dave Glick: > By the way, I did notice the IDPREMAPON flag and that it's currently > set to false. Is that ready for use yet, or is it mostly for > internal testing right now? these data structures are still in an early state of development and aren't safe to use yet. Sorry for that... Cheers, Leo

⚡Generated with XQuery