Db4o is a native java/C# database framework. In a db4o database, you can easily
store and retieve java objects. This all seems rather nice, but when using db4o
with Scala, there is a snag.
Db4o allows easy construction of querys by implementing their Predicate interface. Example, from their tutorial:
List <Pilot> pilots = db.query(new Predicate <Pilot>() {
public boolean match(Pilot pilot) {
return pilot.getPoints() == 100;
}
});
The idea is that, rather than running every object in the database past the
filter .getPoints()==100, db4o parses the bytecode and looks for
objects that match using the database index. However, this doesn’t seem to work for Scala bytecode.
Maybe at some point this will be fixed. But for now, Scala’s syntax comes to the rescue. Db4o converts Predicate implementations into something called a SODA query. The code for constructing a SODA query from scratch in Java, looks like:
Query query=db.query();
query.constrain(Pilot.class);
Query pointQuery=query.descend("points");
query.descend("name").constrain("Rubens Barrichello")
.or(pointQuery.constrain(new Integer(99)).greater()
.and(pointQuery.constrain(new Integer(199)).smaller()));
ObjectSet result=query.execute();
listResult(result);
(Again, this is from the tutorial).
Pretty ugly, huh? However, a Scala version is not too bad:
val query = db query
query constrain classOf[Pilot]
query descend "name" constrain "Rubens Barrichello" or
(query descend "points" constrain 99 greater) and
(query descend "points" constrain 199 smaller)
result = query execute
listResult result
From a few minutes play, it seems that things work like they should – you can use parentheses to surround subqueries and connect with and or or.
For example:
(
(query descend "name" constrain "Rubens Barrichello") or
(query descend "points" constrain 99 greater)
) and
(query descend "points" constrain 199 smaller)
Means (“Reubens Barrichello” OR > 99 points ) AND < 199 points, while:
query descend "name" constrain "Rubens Barrichello" or
(
(query descend "points" constrain 99 greater) and
(query descend "points" constrain 199 smaller)
)
means “Reubens Barrichello” OR (> 99 points AND < 199 points).
This actually isn’t too bad to work with, after all!