Presentation is loading. Please wait.

Presentation is loading. Please wait.

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.

Similar presentations


Presentation on theme: "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."— Presentation transcript:

1 Cosc 4730 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.rms package.

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 RecordStore openRecordStore(String recordStoreName, boolean createIfNecessary) – Name of the RecordStore and True/False create it if doesn't exist. Created as a private Record Store. static RecordStore openRecordStore(String recordStoreName, boolean createIfNecessary, int authmode, 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 RecordStore rs = 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 RecordStore openRecordStore (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. 1bytes 2 3 4 5

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 – int addRecord(byte[] data, int offset, int numBytes) 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(); int rsId; 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(int recordId) – 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(int recordId, byte[] newData, int offset, int numBytes) 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(int recordId) – 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. RecordEnumeration enumerateRecords( RecordFilter filter, RecordComparator comparator, boolean keepUpdated) – 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 boolean hasNextElement() and boolean hasPreviousElement() – 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. – int numRecords() 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(RecordStore recordStore, int recordId) Called when a record has been added to a record store. – void recordChanged(RecordStore recordStore, int recordId) Called after a record in a record store has been changed. – void recordDeleted(RecordStore recordStore, int recordId) 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(int authmode, 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(int recordId) 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 &


Download ppt "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."

Similar presentations


Ads by Google