Db4o allows using a custom comparator for query processing. This can be useful for replacing the standard way of selecting query results, for example, when a non-standard attribute type should be compared as string or integer
The usage is best shown on an example.
Let's create a custom class containing string information:
01/* Copyright (C) 2007 db4objects Inc. http://www.db4o.com */ 02
namespace Db4objects.Db4odoc.Comparing 03
{ 04
class MyString 05
{ 06
private string _string; 07
08
public MyString(string str){ 09
_string = str; 10
} 11
12
public override string ToString(){ 13
return _string; 14
} 15
} 16
}
01' Copyright (C) 2007 db4objects Inc. http://www.db4o.com 02
Namespace Db4objects.Db4odoc.Comparing 03
04
Class MyString 05
Private _string As String 06
07
Public Sub New(ByVal str As String) 08
_string = str 09
End Sub 10
11
Public Overloads Overrides Function ToString() As String 12
Return _string 13
End Function 14
End Class 15
End Namespace
MyString class will be used for an attribute in the following class:
01/* Copyright (C) 2007 db4objects Inc. http://www.db4o.com */ 02
namespace Db4objects.Db4odoc.Comparing 03
{ 04
class Record 05
{ 06
private MyString _record; 07
08
09
public Record(string record) 10
{ 11
_record = new MyString(record); 12
} 13
14
public override string ToString() 15
{ 16
return _record.ToString(); 17
} 18
} 19
}
01' Copyright (C) 2007 db4objects Inc. http://www.db4o.com 02
Namespace Db4objects.Db4odoc.Comparing 03
04
Class Record 05
Private _record As MyString 06
07
Public Sub New(ByVal record As String) 08
_record = New MyString(record) 09
End Sub 10
11
Public Overloads Overrides Function ToString() As String 12
Return _record.ToString 13
End Function 14
End Class 15
End Namespace
Let's save some Record objects to the database:
01private static void StoreRecords(IConfiguration configuration) 02
{ 03
File.Delete(FileName); 04
IObjectContainer container = Db4oFactory.OpenFile(configuration, FileName); 05
try 06
{ 07
Record record = new Record("Michael Schumacher, points: 100"); 08
container.Set(record); 09
record = new Record("Rubens Barrichello, points: 98"); 10
container.Set(record); 11
record = new Record("Kimi Raikonnen, points: 55"); 12
container.Set(record); 13
} 14
finally 15
{ 16
container.Close(); 17
} 18
}
01Public Shared Sub StoreRecords(ByVal configuration As IConfiguration) 02
File.Delete(FileName) 03
Dim container As IObjectContainer = Db4oFactory.OpenFile(configuration, FileName) 04
Try 05
Dim record As Record = New Record("Michael Schumacher, points: 100") 06
container.Set(record) 07
record = New Record("Rubens Barrichello, points: 98") 08
container.Set(record) 09
record = New Record("Kimi Raikonnen, points: 55") 10
container.Set(record) 11
Finally 12
container.Close() 13
End Try 14
End Sub
Selecting the query results, we need to compare string values contained in MyString objects. This can be configured with the following setting:
1private static IConfiguration Configure() 2
{ 3
IConfiguration configuration = Db4oFactory.NewConfiguration(); 4
configuration.ObjectClass(typeof(MyString)).Compare(new MyStringAttribute()); 5
return configuration; 6
}
01private class MyStringAttribute : IObjectAttribute 02
{ 03
public object Attribute(object original) 04
{ 05
if (original is MyString) 06
{ 07
return ((MyString)original).ToString(); 08
} 09
return original; 10
} 11
}
1Public Shared Function Configure() As IConfiguration 2
Dim configuration As IConfiguration = Db4oFactory.NewConfiguration() 3
configuration.ObjectClass(GetType(MyString)).Compare(New MyStringAttribute) 4
Return configuration 5
End Function
01Private Class MyStringAttribute 02
Implements IObjectAttribute 03
04
Public Function Attribute(ByVal original As Object) As Object Implements IObjectAttribute.Attribute 05
If TypeOf original Is MyString Then 06
Return CType(original, MyString).ToString 07
End If 08
Return original 09
End Function 10
End Class
This piece of code registers an attribute provider for special query behavior.
The query processor will compare the object returned by the attribute provider instead of the actual object, both for the constraint and the candidate persistent object.
The querying code will look like this:
01private static void CheckRecords(IConfiguration configuration) 02
{ 03
IObjectContainer container = Db4oFactory.OpenFile(configuration, FileName); 04
try 05
{ 06
IQuery q = container.Query(); 07
q.Constrain(new Record("Rubens")); 08
q.Descend("_record").Constraints().Contains(); 09
IObjectSet result = q.Execute(); 10
ListResult(result); 11
} 12
finally 13
{ 14
container.Close(); 15
} 16
}
01Public Shared Sub CheckRecords(ByVal configuration As IConfiguration) 02
Dim container As IObjectContainer = Db4oFactory.OpenFile(configuration, FileName) 03
Try 04
Dim q As IQuery = container.Query 05
q.Constrain(New Record("Rubens")) 06
q.Descend("_record").Constraints.Contains() 07
Dim result As IObjectSet = q.Execute 08
ListResult(result) 09
Finally 10
container.Close() 11
End Try 12
End Sub
Using query comparator feature we can change the standard way of selecting query results. This can be helpful for: