Let's see how simple QBE queries are expressed with SODA. A new Query object is created through the #query() method of the ObjectContainer and we can add Constraint instances to it. To find all Pilot instances, we constrain the query with the Pilot class object.
01public static void RetrieveAllPilots() 02
{ 03
IObjectContainer db = Db4oFactory.OpenFile(YapFileName); 04
try 05
{ 06
IQuery query = db.Query(); 07
query.Constrain(typeof(Pilot)); 08
IObjectSet result = query.Execute(); 09
ListResult(result); 10
} 11
finally 12
{ 13
db.Close(); 14
} 15
}
01Public Shared Sub RetrieveAllPilots() 02
Dim db As IObjectContainer = Db4oFactory.OpenFile(Db4oFileName) 03
Try 04
Dim query As IQuery = db.Query() 05
query.Constrain(GetType(Pilot)) 06
Dim result As IObjectSet = query.Execute() 07
ListResult(result) 08
Finally 09
db.Close() 10
End Try 11
End Sub
Basically, we are exchanging our 'real' prototype for a meta description of the objects we'd like to hunt down: a query graph made up of query nodes and constraints. A query node is a placeholder for a candidate object, a constraint decides whether to add or exclude candidates from the result.
Our first simple graph looks like this.
We're just asking any candidate object (here: any object in the database) to be of type Pilot to aggregate our result.
To retrieve a pilot by name, we have to further constrain the candidate pilots by descending to their name field and constraining this with the respective candidate String.
1public static void RetrievePilotByName(IObjectContainer db) 2
{ 3
IQuery query = db.Query(); 4
query.Constrain(typeof(Pilot)); 5
query.Descend("_name").Constrain("Michael Schumacher"); 6
IObjectSet result = query.Execute(); 7
ListResult(result); 8
}
1Public Shared Sub RetrievePilotByName(ByVal db As IObjectContainer) 2
Dim query As IQuery = db.Query() 3
query.Constrain(GetType(Pilot)) 4
query.Descend("_name").Constrain("Michael Schumacher") 5
Dim result As IObjectSet = query.Execute() 6
ListResult(result) 7
End Sub
What does 'descend' mean here? Well, just as we did in our 'real' prototypes, we can attach constraints to child members of our candidates.
So a candidate needs to be of type Pilot and have a member named 'name'that is equal to the given String to be accepted for the result.
Note that the class constraint is not required: If we left it out, we would query for all objects that contain a 'name' member with the given value. In most cases this will not be the desired behavior, though.
Finding a pilot by exact points is analogous.We just have to cross the Java primitive/object divide.
1public static void RetrievePilotByExactPoints(IObjectContainer db) 2
{ 3
IQuery query = db.Query(); 4
query.Constrain(typeof(Pilot)); 5
query.Descend("_points").Constrain(100); 6
IObjectSet result = query.Execute(); 7
ListResult(result); 8
}
1Public Shared Sub RetrievePilotByExactPoints(ByVal db As IObjectContainer) 2
Dim query As IQuery = db.Query() 3
query.Constrain(GetType(Pilot)) 4
query.Descend("_points").Constrain(100) 5
Dim result As IObjectSet = query.Execute() 6
ListResult(result) 7
End Sub