Filtering and Ordering Records with RMS
If you’ve ever used the Record Management System mechanism in MIDP, you already know how useful the RecordStore class can be for storing persistent data. In a previous tutorial, Using RMS to Store Persistent Data, we used the RecordStore.getRecord(int) method to retrieve a record by its ID. However, sometimes you may have more complex retrieval criteria than simply the record ID. That’s where the enumerateRecords() method comes in handy. In this article we will discuss how to filter and order a subset of records in a RecordStore object using enumerateRecords()
The complete signature of the enumerateRecords() method looks like this:
public RecordEnumeration enumerateRecords(
RecordFilter, RecordComparator, boolean)
throws RecordStoreNotOpenException
This method returns an object that enumerates a set of records from the RecordStore. The RecordFilter argument allows the application to specify criteria that will used to return a subset of records. Similarly, the RecordComparator argument allows the application to define logic that will determine the order of the records that are returned.
For example, lets say we have an application with a record store containing ZIP codes.
/**
* Initializes record store with some ZIP codes.
*/
public RecordStore initRecordStore() {
try {
// Open or create RecordStore
RecordStore recordStore
= RecordStore.openRecordStore("zipCodes", true);
// Add records if this record store hasn't yet
// been initialized
if(recordStore.getNumRecords() == 0) {
recordStore.addRecord("49120".getBytes(), 0, 5);
recordStore.addRecord("90210".getBytes(), 0, 5);
recordStore.addRecord("56921".getBytes(), 0, 5);
recordStore.addRecord("10210".getBytes(), 0, 5);
recordStore.addRecord("32010".getBytes(), 0, 5);
}
return recordStore;
} catch(RecordStoreException e) {
System.err.println("Could not initialize record store");
return null;
}
}
Now, let’s say we want to be able to return only ZIP codes that appear in a specific range, and we want them returned in lexicographical order. First we will create a class that implements RecordFilter to specify the filtering. The start and end of the range will be data members of this class.
import javax.microedition.rms.*;
public class RangeRecordFilter implements RecordFilter {
/**
* Creates a new instance of RangeRecordFilter
*/
public RangeRecordFilter(String start, String end) {
setStart(start);
setEnd(end);
}
/**
* Determines if candidate is in specified range.
*/
public boolean matches(byte[] candidate) {
String candidateString = new String(candidate);
return (getStart().compareTo(candidateString) <= 0
&& getEnd().compareTo(candidateString) >= 0);
}
public String getStart() {
return start;
}
public void setStart(String start) {
this.start = start;
}
public String getEnd() {
return end;
}
public void setEnd(String end) {
this.end = end;
}
private String start;
private String end;
}
Next, we will create a class that implements RecordComparator to specify the ordering.
import javax.microedition.rms.*;
public class StringRecordComparator implements RecordComparator {
public int compare(byte[] rec1, byte[] rec2) {
// Convert to String objects
String rec1String = new String(rec1);
String rec2String = new String(rec2);
// Do a string comparison
int comparison = rec1String.compareTo(rec2String);
if(comparison < 0) {
return RecordComparator.PRECEDES;
} else if(comparison == 0) {
return RecordComparator.EQUIVALENT;
} else {
return RecordComparator.FOLLOWS;
}
}
}
Now we can use these classes to return an ordered subset of ZIP codes in a specified range from our record store. For example:
RecordStore recordStore = initRecordStore();
if(recordStore != null) {
// Create filter and comparator
RangeRecordFilter filter =
new RangeRecordFilter("40000", "60000");
StringRecordComparator comparator
= new StringRecordComparator();
// Enumerate matching records
RecordEnumeration records;
try {
records = recordStore.enumerateRecords(
filter, comparator, false);
} catch(RecordStoreNotOpenException e) {
System.err.println("Could not enumerate");
return;
}
// Output the results
while(records.hasNextElement()) {
byte[] rec;
try {
rec = records.nextRecord();
} catch(Exception e) {
System.err.println("Could not get record");
return;
}
System.out.println(new String(rec));
}
For more information about record stores, be sure to read the javax.microedition.rms Package Documentation
Bookmark this article: del.icio.us Digg Furl Reddit blogmarks Google Spurl StumbleUpon Technorati Yahoo!