1 / 37

Cosc 4730

Cosc 4730. Blackberry: Record Store & SQLite. Introduction. RecordStore Comes from JavaME , MIDP 1.0 On some phone who where you may not have a filesystem access and RecordStore was only way to store persistent data Falls very short of a Database

admon
Télécharger la présentation

Cosc 4730

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Cosc4730 Blackberry: Record Store & SQLite

  2. Introduction • RecordStore • Comes from JavaME, MIDP 1.0 • On some phone who where you may not have a filesystem access and RecordStore was only way to store persistent data • Falls very short of a Database • While this lecture will say MIDlet, it’s the same for a Blackberry Application as well. • SQLite • Introduces into Blackberry APIs at 5.0.0

  3. Record Store (2) • The record store is stored in a non-volatile place and will remain after the MIDlet/application has exited. • The stored data by default is marked private, meaning only that MIDlet can access the data • Can be set as shared, allowing any MIDlet to access it. • When the MIDlet suite is removed, all record stores (thus data stored in the Record Stores) that the MIDlet created are also removed.

  4. Record Store (3) • Record store names must be unique • The name of the MIDlet is also used as part of the name • You only need to worry about uniqueness, if you application has 2 or more Record Stores (think Database and table names here). • The name can be 32 Unicode strings (for localization) and it is case sensitive • A note, the name of a Record store is not visual to the users.

  5. Record Store (4) • Records are within the Record Store are given a unique index, which the primary key, called recordId. • The index starts with 1, the next record will be 2, etc… • When a record is deleted from the Record store, the index is NOT reused. It's set to null. • Using RecordEnumeration other indices can be created. • Records stores also store more information • a time stamped when the record store was last modified • (in long integers), in the format used by System.currentTimeMillis(); • a version, which is an integer incremented for each operation that modifies the contests of the Record Store. • Useful for synchronization engines and other things.

  6. Record Store (5) • Implementations of Record Store must guarantee atomic, synchronous, and serialized actions across a single thread, so no corruption will occur. • No locking operations provided • With multiple threads, it is the MIDlet's (programmers) responsibility. • Reader/writer problems.

  7. Using Record Store • While the code to follow will get complex, there is very little you can do • Open/close a record store • store a record in the record store • read a record from the record store • delete the record store. • get the "version" and data store of the record store. • uses RecordStore class from the javax.microedition.rmspackage.

  8. Open/create a RecordStore • openRecordStore(…) • Open or possibly create a record store associated with MIDlet suite. • Three versions: (we'll come back to the third later) • static RecordStoreopenRecordStore(String recordStoreName, booleancreateIfNecessary) • Name of the RecordStore and True/False create it if doesn't exist. Created as a private Record Store. • static RecordStoreopenRecordStore(String recordStoreName, booleancreateIfNecessary, intauthmode, boolean writable) • authmode: • AUTHMODE_ANY any MIDlet suites can access it • AUTHMODE_PRIVATE only access from current MIDlet suite

  9. Open/create a RecordStore (2) • Throws the following errors: • RecordStoreException • if a record store-related exception occurred • RecordStoreNotFoundException • if the record store could not be found • RecordStoreFullException • if the operation cannot be completed because the record store is full • IllegalArgumentException • if recordStoreName or authmode is invalid

  10. openRecordStore Example import javax.microedition.rms.*; private RecordStorers = null; try { rs = RecordStore.openRecordStore("MyStore", true); } catch (RecordStoreException ex) { //do something. } • OR rs = RecordStore.openRecordStore("MyStore", true, RecordStore.AUTHMODE_ANY, true); //Allow any MIDlet to access it, and the last true is for writeable. • Now we use rs to read/write/whatever to the RecordStore called "MyStore", which was created if it did not already exist.

  11. Open/create a RecordStore (3) • Third version is a little different. • static RecordStoreopenRecordStore(String recordStoreName, String vendorName, String suiteName) • Used to open other RecordStore created by other MIDlet suites. • Note that RecordStore must be AUTHMODE_ANY to succeed. • VendorName and suiteName are set in Application descriptor properties. • Throws same errors and adds the following: • SecurityException • if this MIDlet Suite is not allowed to open the specified RecordStore.

  12. Closing a RecordStore • rs.closeRecordStore(); • You need to close the RecordStore to ensure the resources are returned. • A note, it would seem you can open a RecordStore multiple times and you need to close it the same number of times as well, otherwise it won't be closed correctly. • Throws • RecordStoreNotOpenException • if the record store is not open • RecordStoreException • if a different record store-related exception occurred

  13. Delete a Record Store • If you need to delete a RecordStore use • deleteRecordStore(String recordStoreName) • Throws: • RecordStoreException • if a record store-related exception occurred • RecordStoreNotFoundException • if the record store could not be found • Remember a RecordStore is also removed when the MIDlet is removed.

  14. Data storage. • Since there is no serialization in JavaMe, we must do the work. • Data in a record is stored as bytes, instead of any type (ie string or integer). • Like in filesystems, we’ll use DataOutputStream and DataInputStream to do the heavy lifting.

  15. Data storage (2) • You will need to think about how you store the data, since you will also have to convert it back as well. • This is one of two places recordstore falls very short of databases • Recordstore looks like this table.

  16. String methods for bytes • You may find it easier to just create a String that is the information, instead of stream. • Example: • high score data. We need to store Name and score. • A string could be created as "Jim Ward, 3012" • String str = "Jim Ward, 3012"; • byte bytes[] = str. getBytes(); • bytes to string is as simple • String newstr = new String(bytes,0,bytes.length); • Then use the string methods to break up the string into the necessary parts.

  17. adding a record • To insert a new record • intaddRecord(byte[] data, int offset, intnumBytes) • Where offset is the index to the first relevant byte • Normally zero for us purposes. • numBytes is the length • returns the recordId number • Throws • RecordStoreNotOpenException • if the record store is not open • RecordStoreException • if a different record store-related exception occurred • RecordStoreFullException • if the operation cannot be completed because the record store has no more room • SecurityException • if the MIDlet has read-only access to the RecordStore

  18. adding a record example //data were want to insert String newdata = "Jim Ward, 3012"; //byte data variable byte bytes[] = newdata.getBytes(); intrsId; try rsId = rs.addRecord(bytes,0,bytes.length); } catch (RecordStoreException ex) { //do something about failure. }

  19. retrieving a record • The second place RecordStore fails database methods. • To get retrieve data, you need to know the index. •  byte[] getRecord(intrecordId) • Returns a copy of the data stored in the given record. • throws • RecordStoreNotOpenException • if the record store is not open • InvalidRecordIDException • if the recordId is invalid • RecordStoreException • if a general record store exception occurs

  20. retrieving a record (2) • There is no "select" method as you would think in a database. • Instead we use enumerateRecords method • We'll come back to it later on.

  21. retrieving a record example byte b[]=null; try { b = rs.getRecord(rsId); } catch (RecordStoreException ex) { //do something about failure } String str = new String(b,0,b.length); //str should have "Jim Ward, 3012"

  22. Updating a record • To change a record, use setRecord Method, which is the same as addRecord, except you specify the recordId as well. • setRecord(intrecordId, byte[] newData, int offset, intnumBytes) • throws • RecordStoreNotOpenException • if the record store is not open • InvalidRecordIDException • if the recordId is invalid • RecordStoreException • if a general record store exception occurs • RecordStoreFullException • if the operation cannot be completed because the record store has no more room • SecurityException • if the MIDlet has read-only access to the RecordStore

  23. deleting a record • deleteRecord(intrecordId) • The record is deleted from the record store. • Remember, index are never reused, instead that index will be set to null • it will return either null or throw an exception if you attempt to access it again.

  24. Counting Records • getNumRecords() • Returns the number of records currently in the record store. • Throws: • RecordStoreNotOpenException • if the record store is not open • Remember that since recordID, which are deleted are still "in use", it will count those as well.

  25. Enumerating a Record Store • Because everything is stored as bytes, there is no "simple" way to implement something like database a select statement. • Instead use the enumerateRecords method, which returns an object of type RecordEnumeration. • RecordEnumerationenumerateRecords( RecordFilter filter, RecordComparator comparator, booleankeepUpdated) • throws RecordStoreNotOpenException • Where both filter and comparator are methods • filter used to determine the subset of records • comparator used to determine the order of the records. • keepUpdated, true watches RecordStore updates and then adds them.

  26. Enumerating a Record Store (2) • If we wanted to return all the records, with no ordering, then will use the following: try { RecordEnumeration re = rs.enumerateRecords(null, null, false); } catch (RecordStoreNotOpenException ex) { //failed, RecordStore is not opened. } //now re has access to all the records. //we'll come back to RecordEnumeration class.

  27. Enumerating a Record Store (3) • Let's say we want to see only a subset of records, which starts with "Jim", with no ordering. RecordEnumeration re = rs.enumerateRecords( new RecordFilter() { //required method match. public boolean match (byte[] r) { String str = new String(r,0,r.length); if (str.startsWith("Jim") { return true; //in the subset } else { return false; //not in the subset } } }, null, false);

  28. Enumerating a Record Store (4) • Let's say we want to see all the records, but order them in alphabetic order. RecordEnumeration re = rs.enumerateRecords(null, new RecordComparator() { //compare is required public int compare ( byte[] r1, byte[] r2) { String str1 = new String(r1,0,r1.length); String str2 = new String(r2,0,r2.length); int x = str1.compareTo(str2); if (x <0) { return RecordComparator.PRECEDES; } } else if (x == 0) {return RecordComparator.EQUIVALENT; } } else {return RecordComparator.FOLLOWS; } }, false);

  29. RecordEnumeration class • So now we have the records, use the RecordEnumeration methods to access them. • Use byte[] nextRecord() to get the record • call again, to get the next record. • to go back, use byte[] previousRecord(); • To test if there is a next or previous record • booleanhasNextElement() and booleanhasPreviousElement() • To get the RecordId, use nextRecordId() //as defined by the current interator, IE call this first if you want the RecordID and then the data. • previousRecordID() if you already called nextRecord() or to find out the last recordID. • A note, nextRecordID also mores the iterator. • intnumRecords() is useful to found how many records were selected. • And very importantly, when we are done. Call destory(), so it can free up any resources in use.

  30. RecordEnumeration class example • So let's assume we wanted all records starting with Jim and they are in alphabetic order and we want to print them out. • Use the code from Enumerating a Record Store (3 and 4). • Now we have re as a variable and assume bytes and str are declared as before. while (re.hasNextElement()) { bytes = re.nextRecord(); str = new String(bytes,0,bytes.length); System.out.println("Record is "+str); } re.destroy(); • later close the RecordStore as well.

  31. Listeners • An app can listen for changes in RecordStore caused by another application or thread. • You can addRecordListener(RecordListener l) the following: • void recordAdded(RecordStorerecordStore, intrecordId) • Called when a record has been added to a record store.   • void recordChanged(RecordStorerecordStore, intrecordId) • Called after a record in a record store has been changed.   • void recordDeleted(RecordStorerecordStore, intrecordId) • Called after a record has been deleted from a record store.

  32. Other info about a RecordStore • If you don't know the names of RecordStore, you can get a list of all RecordStore for the MIDlet suite • String[] listRecordStores() • returns a string array of the names, null if no RecordStores are found. • Changing the Mode of the RecordStore • rs.setMode(intauthmode, boolean writable)

  33. Other info about a RecordStore (2) • To get the last time the record store was modified • long x = rs.getLastModified() • returns in long int, formt used by System.currentTimeMillis() • time in non-leap seconds since January 1, 1970 • get the Version number • the Version number that indicates the number of changes (by addRecord, setRecord, and deleteRecord). But since the start number is implementation-specific, so you can't count the number of changes, since it was created. • int x = rs.getVersion(); • Can be easy used in multi threads MIDlet's to determine if the data may have changed since the read.

  34. Other info about a RecordStore (3) • Size information • int x = rs.getRecordSize(intrecordId) • Returns the size (in bytes) of the MIDlet data available in the given record.   • int x = rs.getSize() • Returns the amount of space, in bytes, that the record store occupies.   • int x = getSizeAvailable() • Returns the amount of additional room (in bytes) available for this record store to grow.

  35. Other info about a RecordStore (4) • int x = getNextRecordID(); • Returns the recordId of the next record to be added to the record store. • Maybe useful if you want to add some sort of relational information in records. • example: recordID 1 has index as part of the record 5, where recordID 5 haves addition information.

  36. Limitations • Because of different implementations on different devices, you may encounter the following • Just because a device has a certain amount of space on the device, doesn't mean you can use all of it. • Some implementations of getSizeAvailable report all the space in persistent storage, not just what you can use. • The limitation of the bytes of a record. • It maybe implemented to a different size on different devices. • There is no way to predict or find the cap. Instead an error will be thrown when it is to long. • Blackberry Doc’s say 512K is the length.

  37. Q A &

More Related