This week's giveaway is in the Android forum.
We're giving away four copies of Android Security Essentials Live Lessons and have Godfrey Nolan on-line!
See this thread for details.
The moose likes Java Micro Edition and the fly likes strange searching Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


Win a copy of Android Security Essentials Live Lessons this week in the Android forum!
JavaRanch » Java Forums » Mobile » Java Micro Edition
Bookmark "strange searching" Watch "strange searching" New topic
Author

strange searching

david russell
Greenhorn

Joined: Feb 28, 2002
Posts: 14
hmm, this is a strange one.
ive got a bit of code that is supposed to search a database of records, comparing the records to a string, and if it matches, it should return the matched record as a string. the problem is, it will only work with the last record in the database, otherwise i get a stringindexoutofbounds exception. the search code is below:
private synchronized Object action(String s, byte[] data, int action)
throws RecordStoreNotOpenException, RecordStoreFullException,
RecordStoreException {
if ((action != 1) && (recordIDs.size() == 0)) {
throw new RecordStoreException();
}
int IDs = database.getNumRecords();
System.err.println("no of records in the database is " +IDs);

for(int index=1;index <IDs+1;index++) {
try {
System.err.println("index is "+ index);
System.err.println(s);
System.err.println("the record at position "+index+" is " + new String(database.getRecord(index)));
if (rc.compare(database.getRecord(index),s.getBytes())== RecordComparator.EQUIVALENT) {
switch (action) {
case 0:
database.deleteRecord(index);
recordIDs.removeElement(new Integer(index));
return null;
case 1:
return new String(database.getRecord(index));

case 2:
database.setRecord(index, data, 0, data.length);
return null;
default:
break;
}
}
} catch (InvalidRecordIDException iri) {
throw new RecordStoreException(iri.getMessage());
}
}//for loop ends here
return null;
}
the exception error i get and all the associated gubbins is also below:
During event handling, midlet threw java.lang.StringIndexOutOfBoundsException: String index out of range: -1
java.lang.StringIndexOutOfBoundsException: String index out of range: -1
at java.lang.String.substring(+45)
at example.stock.Stock.parse(+24)
at example.stock.Stock.getName(+14)
at example.stock.StockDatabase$StockComparator.compare(+23)
at example.stock.Database.action(+169)
at example.stock.Database.search(+7)
at example.stock.StockMIDlet.displayProduct(+8)
at example.stock.StockMIDlet.access$600(+5)
at example.stock.StockMIDlet$StockCommandListener.commandAction(+191)
at javax.microedition.lcdui.List.keyPressed(+44)
at javax.microedition.lcdui.Display$DisplayAccessor.keyEvent(+68)
at com.sun.midp.lcdui.DefaultEventHandler$2.run(+193)
i did alter this search as it originally searched using a vector of record IDs as the index, but im not sure if the way i have adapted it (ie using a for loop) is kosher. if anyone spots any glaringly obvious mistakes, please let me know, so i can bang my head off the desk.
thanks in advance
dave
Valentin Crettaz
Gold Digger
Sheriff

Joined: Aug 26, 2001
Posts: 7610
it seems to me (without knowing the rest of the code) that the problem may be located in database.getRecord(index). Could you please post the code of the class which "database" is a type of?


SCJP 5, SCJD, SCBCD, SCWCD, SCDJWS, IBM XML
[Blog] [Blogroll] [My Reviews] My Linked In
Horaci Macias
Ranch Hand

Joined: Nov 08, 2001
Posts: 74
I would try using a RecordEnumeration instead of getting the number of record (using database.getNumRecords()) and looping from 1 to getNumRecords()+1.
Hope it helps,
Horaci Macias
david russell
Greenhorn

Joined: Feb 28, 2002
Posts: 14
here is the database class.
public abstract class Database {
/**
* The database storing all the records and the last
* used recordID in position 1
*/
protected volatile RecordStore database = null;
/**
* The <code>Vector</code> of used recordIDs that are in the database
*/
protected volatile Vector recordIDs = null;
/**
* The last used ID in the database
*/
protected int lastID = 1;
/**
* The object used to compare two records and see if they are equal
*/
protected RecordComparator rc = null;
/**
* <p>Initializes the database and if it's not a new database, loads the
* recordID of the last record out of the first position in the
* <code>RecordStore</code>. We have stored it there when we closed the
* database, then checks each ID from 1 to lastID to see if they exist in
* the database and then add the IDs that exist to the recordIDs
* <code>Vector</code></p>
*
* @param fileName The name of the <code>RecordStore</code> to open
* @throws <code>RecordStoreNotFoundException</code> is thrown if the
* <code>RecordStore</code> indicated with <code>fileName</code>
* cannot be found
* @throws <code>RecordStoreException</code> is thrown when a general
* exception occurs in a <code>RecordStore</code> operation
* @throws <code>RecordStoreFullException</code> is thrown when the
* storage system is is full
*/
public void open(String fileName) throws RecordStoreNotFoundException,
RecordStoreException,
RecordStoreFullException {
database = RecordStore.openRecordStore(fileName, true);
recordIDs = new Vector();
try {
if (database.getNumRecords() != 0) {
try {
lastID =
Integer.valueOf(
new String(database.getRecord(1))).intValue();
for (int i = 1; i <= lastID; i++) {
try {
database.getRecord(i);
recordIDs.addElement(new Integer(i));
} catch (RecordStoreException rs) {}
}
} catch (InvalidRecordIDException iri) {
throw new RecordStoreException(iri.getMessage());
}
}
} catch (RecordStoreNotOpenException rsno) {
throw new RecordStoreException(rsno.getMessage());
}
}
/**
* <p>Close the database and remove it from persistant
* storage if it is empty</p>
*
* @throws <code>RecordStoreNotOpenException</code> is thrown when trying
* to close a <code>RecordStore</code> that is not open
* @throws <code>RecordStoreException</code> is thrown when a general
* exception occurs in a <code>RecordStore</code> operation
*/
public void close() throws RecordStoreNotOpenException,
RecordStoreException {
if (database.getNumRecords() == 0) {
String fileName = database.getName();
database.closeRecordStore();
database.deleteRecordStore(fileName);
} else {
database.closeRecordStore();
}
}
/**
* <p>Remove the database from persistant storage</p>
*
* @param fileName the name of the <code>RecordStore</code> to remove
*/
public void cleanUp(String fileName) throws RecordStoreNotFoundException,
RecordStoreException {
RecordStore.deleteRecordStore(fileName);
open(fileName);
}
/**
* <p>Add the record to the database<BR>
* Add the recordID to our vector<BR>
* Update the database's last ID counter</p>
*
* @param record The record data to be added to the database
* @throws <code>RecordStoreNotOpenException</code> is thrown when
* trying to close a <code>RecordStore</code> that is not open
* @throws <code>RecordStoreFullException</code> is thrown when the storage
* system is is full
* @throws <code>RecordStoreException</code> is thrown when a general
* exception occurs in a <code>RecordStore</code> operation
*/
/* public synchronized void add(String record)
throws RecordStoreNotOpenException,
RecordStoreFullException,
RecordStoreException {
if (database.getNumRecords() != 0) {
database.addRecord(record.getBytes(), 0, record.getBytes().length);
recordIDs.addElement(new Integer(++lastID));
database.setRecord(1, (String.valueOf(lastID)).getBytes(),
0, (String.valueOf(lastID)).length());
} else {
recordIDs.addElement(new Integer(++lastID));
database.addRecord((String.valueOf(lastID)).getBytes(),
0, (String.valueOf(lastID)).length());
try {
database.addRecord(record.getBytes(), 0,
record.getBytes().length);
} catch (RecordStoreException rs) {
recordIDs.removeElement(new Integer(lastID--));
database.setRecord(1, (String.valueOf(lastID)).getBytes(),
0, (String.valueOf(lastID)).length());
throw rs;
}
}
}
*/

public synchronized void add(String record)
throws RecordStoreNotOpenException,
RecordStoreFullException,
RecordStoreException {
database.addRecord(record.getBytes(), 0, record.getBytes().length);}

/**
* <p>Delete the record from the database and remove that recordID from the
* vector of used recordIDs</p>
*
* @param s The name of the record to delete from the database
* @throws <code>RecordStoreNotOpenException</code> is thrown when trying
* to close a <code>RecordStore</code> that is not open
* @throws <code>RecordStoreException</code> is thrown when a general
* exception occurs in a <code>RecordStore</code> operation
*/
public synchronized void delete(String s)
throws RecordStoreNotOpenException,
RecordStoreException {
action(s, null, 0);
}
/**
* <p>Find and return a record</p>
*
* @return The record that we're looking for or
* <code>null</code> if not found
* @param s The name of the record to search for
* @throws <code>RecordStoreNotOpenException</code> is thrown when trying
* to close a <code>RecordStore</code> that is not open
* @throws <code>RecordStoreException</code> is thrown when a general
* exception occurs in a <code>RecordStore</code> operation
*/
public synchronized String search(String s)
throws RecordStoreNotOpenException, RecordStoreException {
return (String) action(s, null, 1);
}
/**
* <p>Update the record with the name <code>s</code> with the data
* in the byte[] array</p>
*
* @param s The name of the record to update
* @param data the new data to update the record with
* @throws <code>RecordStoreNotOpenException</code> is thrown when trying
* to close a <code>RecordStore</code> that is not open
* @throws <code>RecordStoreFullException</code> is thrown when the storage
* system is is full
* @throws <code>RecordStoreException</code> is thrown when a general
* exception occurs in a <code>RecordStore</code> operation
*/
public synchronized void update(String s, byte[] data)
throws RecordStoreNotOpenException, RecordStoreFullException,
RecordStoreException {
action(s, data, 2);
}
/**
* <p>Go to the index of the record specified by <code>s</code> and perform
* an action. Either an update, search or deletion. This method is for
* code compaction as the process for updating, searching and
* deleting varies only slightly.</p>
*
* @param s The name of the record to perform the action on
* @param data Data to use in the action
* @param action What to do. 0 = delete, 1 = search, 2 = update
* @throws <code>RecordStoreNotOpenException</code> is thrown when trying
* to close a <code>RecordStore</code> that is not open
* @throws <code>RecordStoreFullException</code> is thrown when the storage
* system is is full
* @throws <code>RecordStoreException</code> is thrown when a general
* exception occurs in a <code>RecordStore</code> operation
*/
private synchronized Object action(String s, byte[] data, int action)
throws RecordStoreNotOpenException, RecordStoreFullException,
RecordStoreException {
if ((action != 1) && (recordIDs.size() == 0)) {
throw new RecordStoreException();
}
int IDs = database.getNumRecords();
System.err.println("no of records in the database is " +IDs);

for(int index=1;index <IDs+1;index++) {
try {
System.err.println("index is "+ index);
System.err.println(s);
System.err.println("the record at position "+index+" is " + new String(database.getRecord(index)));
if (rc.compare(database.getRecord(index),s.getBytes())== RecordComparator.EQUIVALENT) {
switch (action) {
case 0:
database.deleteRecord(index);
recordIDs.removeElement(new Integer(index));
return null;
case 1:
return new String(database.getRecord(index));

case 2:
database.setRecord(index, data, 0, data.length);
return null;
default:
break;
}
}
} catch (InvalidRecordIDException iri) {
throw new RecordStoreException(iri.getMessage());
}
}//for loop ends here
return null;
}
/**
* <p>Return the number of records in the database</p>
*
* @return the number of records in the database
* @throws <code>RecordStoreNotOpenException</code> is thrown when trying
* to close a <code>RecordStore</code> that is not open
*/
public int getNumRecords() throws RecordStoreNotOpenException {
return database.getNumRecords();
}
}
its a bit of a mish mash, i changed the add method because i didnt want it sticking record ids in the database. i was doing some work on the midlet last night and i know for sure that the data is held correctly in the records, i also know that it definitely is searching the record using the correct parameter (the name of the list component clicked) and the comparator compares the records based on the name of the record. i can post that code too if its any help.
dave
david russell
Greenhorn

Joined: Feb 28, 2002
Posts: 14
sorry folks, ive figured out the problem.
my search was calling a record comparator to compare the record names and see if they matched. i was passing in a record and a record name to the comparator. unfortunately my comparator was then trying to go and get a get a record name by passing in the variable given. i was only passing in the record name, so thats why it was going mad.
thanks to everyone who helped though, and im still having problems with my list component if ur interested
cheers
dave
 
It is sorta covered in the JavaRanch Style Guide.
 
subject: strange searching
 
Similar Threads
calculate the amount values stored form recordstore in J2ME midlet
Palm + Database = ??
suncertify.db.Data
JUnit Test Cases
Help Parsing a file