Sophie

Sophie

distrib > Fedora > 15 > i386 > by-pkgid > 2e9c43658e374d290a2de15d25134ac8 > files > 1740

db4o-doc-8.0-1.fc15.i686.rpm

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<link rel="stylesheet" type="text/css" href="docs.css">
<!--[if gte IE 5]>
     <link href="docs_ie.css" rel="stylesheet" type="text/css">
<![endif]-->
</head>
<body><div id="pagecontainer"><table><tr><td width="5">&nbsp;</td><td><a name="Evaluations"></a><br>
<a name="outline219"></a><br><h1>13. SODA Evaluations</h1><br>
In the <a href="Query.html#SODAQueryAPI">SODA API chapter</a>&nbsp;we already mentioned <em>Evaluations</em>&nbsp;as a means of providing user-defined custom constraints and as a means to run any&nbsp;arbitrary code in a SODA query. Let's have a closer look.<br>
<br>
<ul>
<a name="outline220"></a><br><h2>13.1. Evaluation API</h2><br>
The evaluation API consists of two interfaces, &nbsp;IEvaluation &nbsp;and &nbsp;ICandidate &nbsp;.&nbsp;Evaluation implementations are implemented by the user and injected into a query.&nbsp;During a query, they will be called from db4o with a candidate instance&nbsp;in order to decide whether to include it into the current (sub-)result.<br>
<br>
<br>
The&nbsp;IEvaluation &nbsp;interface contains a single method only:<br>
<br>
<br>
<table width="100%" cellpadding="3" cellspacing="0" border="0"><tr><td class="lg">
<code>public void Evaluate(ICandidate candidate);</code></td></tr></table>
<br>
<br>
This will be called by db4o to check whether the object encapsulated by this&nbsp;candidate should be included into the current candidate set.<br>
<br>
<br>
The&nbsp;ICandidate &nbsp;interface provides three methods:<br>
<br>
<br>
<br>
<table width="100%" cellpadding="3" cellspacing="0" border="0"><tr><td class="lg">
<code>public object GetObject();<br>
public void Include(bool flag);<br>
public IObjectContainer ObjectContainer();<br>
</code></td></tr></table>
<br>
<br>
An Evaluation implementation may call&nbsp;#GetObject() &nbsp;to retrieve the actual object&nbsp;instance to be evaluated, it may call&nbsp;#Include() &nbsp;to instruct db4o whether or not&nbsp;to include this object in the current candidate set, and finally it may access&nbsp;the current database directly by calling&nbsp;#ObjectContainer() .<br>
<br>
<br>
<a name="outline221"></a><br><h2>13.2. Example</h2><br>
For a simple example, let's go back to our Pilot/Car implementation from the&nbsp;<a href="Collections.html#Collections">Collections chapter</a>. Back then, we kept a history of&nbsp;SensorReadout instances in a List member inside the car. Now imagine that&nbsp;we wanted to retrieve all cars that have assembled an even number of history&nbsp;entries. A quite contrived and seemingly trivial example, however, it gets&nbsp;us into trouble: Collections are transparent to the query API, it just&nbsp;'looks through' them at their respective members.<br>
<br>
<br>
So how can we get this done? Let's implement an Evaluation that expects the&nbsp;objects passed in to be instances of type Car and checks their history size.<br>
<br>
<table width="100%" cellpadding="3" cellspacing="0" border="0"><tr><td class="lg">
<code>using Db4objects.Db4o.Query;<br>
using Db4odoc.Tutorial.F1.Chapter4;<br>
namespace Db4odoc.Tutorial.F1.Chapter7<br>
{&nbsp;&nbsp;&nbsp;&nbsp;<br>
&nbsp;&nbsp;&nbsp;&nbsp;public class EvenHistoryEvaluation : IEvaluation<br>
&nbsp;&nbsp;&nbsp;&nbsp;{<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public void Evaluate(ICandidate candidate)<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Car car=(Car)candidate.GetObject();<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;candidate.Include(car.History.Count % 2 == 0);<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br>
&nbsp;&nbsp;&nbsp;&nbsp;}<br>
}<br>
</code></td></tr></table>
<br>
<br>
To test it, let's add two cars with history sizes of one, respectively two:<br>
<br>
<table width="100%" cellpadding="3" cellspacing="0" border="0"><tr><td class="lg">
<code>// storeCars<br>
Pilot pilot1 = new Pilot("Michael Schumacher", 100);<br>
Car car1 = new Car("Ferrari");<br>
car1.Pilot = pilot1;<br>
car1.Snapshot();<br>
db.Store(car1);<br>
Pilot pilot2 = new Pilot("Rubens Barrichello", 99);<br>
Car car2 = new Car("BMW");<br>
car2.Pilot = pilot2;<br>
car2.Snapshot();<br>
car2.Snapshot();<br>
db.Store(car2);</code></td><td class="lg" align="left" valign="bottom" width=43><input type='button' class='button' value='Run' onclick='window.external.RunExample("com.db4odoc.f1.chapter7.EvaluationExample", "storeCars")' /></td></tr></table>
<br>
<br>
and run our evaluation against them:<br>
<br>
<table width="100%" cellpadding="3" cellspacing="0" border="0"><tr><td class="lg">
<code>// queryWithEvaluation<br>
IQuery query = db.Query();<br>
query.Constrain(typeof (Car));<br>
query.Constrain(new EvenHistoryEvaluation());<br>
IObjectSet result = query.Execute();<br>
Util.ListResult(result);</code></td><td class="lg" align="left" valign="bottom" width=43><input type='button' class='button' value='Run' onclick='window.external.RunExample("com.db4odoc.f1.chapter7.EvaluationExample", "queryWithEvaluation")' /></td></tr></table>
<br>
<br>
<a name="outline222"></a><br><h2>13.3. Drawbacks</h2><br>
While evaluations offer you another degree of freedom for assembling queries,&nbsp;they come at a certain cost: As you may already have noticed from the example,&nbsp;evaluations work on the fully instantiated objects, while 'normal' queries&nbsp;peek into the database file directly. So there's a certain performance penalty&nbsp;for the object instantiation, which is wasted if the object is not included&nbsp;into the candidate set.<br>
<br>
<br>
Another restriction is that, while 'normal' queries can bypass encapsulation and&nbsp;access candidates' private members directly, evaluations are bound to use their&nbsp;external API, just as in the language itself.<br>
<br>
<br>
<br>
<a name="outline223"></a><br><h2>13.4. Conclusion</h2><br>
With the introduction of evaluations we finally completed our query toolbox.&nbsp;Evaluations provide a simple way of assemble arbitrary custom query building blocks,&nbsp;however, they come at a price.<br>
<br>
<a name="outline224"></a><br><h2>13.5. Full source</h2><br>
<table width="100%" cellpadding="3" cellspacing="0" border="0"><tr><td class="lg">
<code>using System;<br>
using System.IO;<br>
using Db4objects.Db4o;<br>
using Db4objects.Db4o.Query;<br>
using Db4odoc.Tutorial.F1.Chapter4;<br>
namespace Db4odoc.Tutorial.F1.Chapter7<br>
{<br>
&nbsp;&nbsp;&nbsp;&nbsp;public class EvaluationExample : Util<br>
&nbsp;&nbsp;&nbsp;&nbsp;{<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;readonly static string YapFileName = Path.Combine(<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData),<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"formula1.yap");&nbsp;&nbsp;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public static void Main(string[] args)<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{ <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;File.Delete(YapFileName);<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;using(IObjectContainer db = Db4oEmbedded.OpenFile(YapFileName))<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;StoreCars(db);<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;QueryWithEvaluation(db);<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public static void StoreCars(IObjectContainer db)<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Pilot pilot1 = new Pilot("Michael Schumacher", 100);<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Car car1 = new Car("Ferrari");<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;car1.Pilot = pilot1;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;car1.Snapshot();<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;db.Store(car1);<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Pilot pilot2 = new Pilot("Rubens Barrichello", 99);<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Car car2 = new Car("BMW");<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;car2.Pilot = pilot2;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;car2.Snapshot();<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;car2.Snapshot();<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;db.Store(car2);<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public static void QueryWithEvaluation(IObjectContainer db)<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;IQuery query = db.Query();<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;query.Constrain(typeof (Car));<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;query.Constrain(new EvenHistoryEvaluation());<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;IObjectSet result = query.Execute();<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Util.ListResult(result);<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br>
&nbsp;&nbsp;&nbsp;&nbsp;}<br>
}<br>
</code></td></tr></table>
<br>
<br><br><div id="footer"><p align="center">Do you have any questions, suggestions or feedback? Ask your questions in the <a href="http://developer.db4o.com/Forums.aspx" target=_top>db4o forums</a>. Join the <a href="http://developer.db4o.com" target=_top>db4o community</a> for addional resources and news.<br><br><a href="http://www.db4o.com/" target=_top><small>www.db4o.com</small></a></p>.</div><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br></td></tr></table></div></body></html>