Custom Query Comparator

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:

MyString.java
01/* Copyright (C) 2007 db4objects Inc. http://www.db4o.com */ 02package com.db4odoc.comparing; 03 04class MyString { 05 06 private String _string; 07 08 public MyString(String string) { 09 _string = string; 10 } 11 12 public String toString() { 13 return _string; 14 } 15}

MyString class will be used for an attribute in the following class:

Record.java
01/* Copyright (C) 2007 db4objects Inc. http://www.db4o.com */ 02package com.db4odoc.comparing; 03 04public class Record { 05 private MyString _record; 06 07 08 public Record(String record) { 09 _record = new MyString(record); 10 } 11 12 public String toString(){ 13 return _record.toString(); 14 } 15}

Let's save some Record objects to the database:

CompareExample.java: storeRecords
01private static void storeRecords(Configuration configuration){ 02 new File(FILENAME).delete(); 03 ObjectContainer container = Db4o.openFile(configuration, FILENAME); 04 try { 05 Record 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 } 14 }

Selecting the query results, we need to compare string values contained in MyString objects. This can be configured with the following setting:

CompareExample.java: configure
01private static Configuration configure(){ 02 Configuration configuration = Db4o.newConfiguration(); 03 configuration.objectClass(MyString.class).compare(new ObjectAttribute() { 04 public Object attribute(Object original) { 05 if (original instanceof MyString) { 06 return ((MyString) original).toString(); 07 } 08 return original; 09 } 10 }); 11 return configuration; 12 }

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:

CompareExample.java: checkRecords
01private static void checkRecords(Configuration configuration){ 02 ObjectContainer container = Db4o.openFile(configuration, FILENAME); 03 try { 04 Query q = container.query(); 05 q.constrain(new Record("Rubens")); 06 q.descend("_record").constraints().contains(); 07 ObjectSet result = q.execute(); 08 listResult(result); 09 } finally { 10 container.close(); 11 } 12 }

Using query comparator feature we can change the standard way of selecting query results. This can be helpful for: