Working with Catalogs
Both PalmOS and Windows CE devices allow data to be
stored in "databases" instead of using a directory-based file system.
These aren't traditional client-server
databases, they are simply sets of records containing data.
These small device databases are synchronized with an equivalent
database on a desktop PC. Changes made in either the desktop or
the small device database will appear in the other after
synchronization occurs.
In Waba, these databases are known as catalogs. The Catalog
class located in the waba.io package can be used to read
and write records in catalogs.
Background on PalmOS Databases
Before we discuss catalogs, we'll provide some background
on PalmOS databases.
Under PalmOS, all data is stored in databases. Each database is
identified by a creator (4 characters) and type (4 characters).
Even applications are stored in databases under PalmOS.
Each application has a unique creator id and a type
of "appl".
Normally, when you create a PalmOS application you need to specify
a unique creator id for it. When developing with Waba, a creator
id is automatically generated by the "warp" and "exegen"
programs based on the name of the program being created.
You can view the creator id that warp and exegen are creating if you run them without
specifying the /q (quiet) option. Here is some example output showing
warp generating a creator id of "anTW" for the Scribble program:
> warp c Scribble *.class
Wabasoft (TM) Application Resource Packager
warp files: Scribble.pdb Scribble.wrp
PalmOS PDB name: Scribble
PalmOS PDB creator: anTW
Since there are many possible creator ids, the chance of warp or
exegen choosing a creator id that is the same as one being used by an
existing program is small. However, it is possible.
Before you ship a program for the world to use, you should
check to make sure the program's creator id is unique and register
it so that someone else doesn't use the same id.
There is a central registry for PalmOS creator id's on the web on
this page where you can check to see if a creator id is in
use and register your own creator ids for programs you develop.
You need to know your application's creator id not only to
make sure it is unique, but also to assist you in naming
the databases your program creates.
In general, if your application creates a database, it
should have the same creator as the application.
For example, the PalmOS Address Book application has a creator id
of "addr" and a type of "appl". Its database, containing addresses,
has a creator id of "addr" and a type of "DATA".
The reason you should use a single creator id for both an
application and for the databases the application uses is to
allow a user to remove the application in a single step.
When an application is removed, all the databases with the same
creator id as the application are removed. So, if your application
creates 4 databases with the same creator id as the application
itself, all 4 will be removed when the main program is removed.
In contrast to the creator id, the 4 character type of a database
is rather arbitrary. Warp databases, for instance, have a type of "Wrp1".
Catalog Names
In Waba, every catalog on a device has a unique name.
Catalog names are 9 characters in length with a period in the middle.
"Test.Type" is an example of a valid catalog name.
Under PalmOS, the first 4 characters in a catalog name map to
the database creator name and the last 4 characters map to
the database type.
For example, the database for the Address Book on the PalmPilot
has a creator of "addr" and a type of "DATA". To open this
database in Waba, we would open the catalog named "addr.DATA".
Creating a Catalog
Let's say we've created an application called Scribble that
lets a user draw on the screen. The warp and exegen programs
generate a creator id of "anTW" for a program named Scribble.
Now let's say we wanted to modify the program so it stored
the drawings a user made into a catalog. We'll name the
catalog "anTW.Scrb". The creator id is the same as the
program's creator id, allowing the user to remove both in
one step.
We could write the following code to create the catalog:
Catalog c = new Catalog("anTW.Scrb", Catalog.CREATE);
if (!c.isOpen())
return; // error
In the code above, we assumed that the catalog did not already
exist when we created it. If we wanted to see if the
catalog already existed before creating it we could
write:
Catalog c = new Catalog("anTW.Scrb", Catalog.READ_ONLY);
if (!c.isOpen())
{
.. create catalog here
}
Adding Records
To make the catalog interesting, we'll need to add some
data to it. Data in catalogs is stored in records.
A record can be added to a catalog using the addRecord()
method. The addRecord() method adds a record of a given
size in bytes to the end of the catalog.
For example, the following code adds a 100 byte record
to the catalog we created:
if (c.addRecord(100) == -1)
return; // error
Records that are added are initially empty. After adding a record
you will normally use writeBytes() to write data into the record.
Writing to Records
Catalogs have the concept of a current record and also a current
position within a record, known as a cursor.
When you want to write some data into a record, you can
set the current position to the record using setRecord()
and then use writeBytes() to write data into the record.
When you use setRecord(), the cursor is set to the beginning
of the record.
Each time you write data into a record, the cursor advances to
the end of the data written. When you use writeBytes(), writing
starts at the current cursor position within the current record.
This means you'll get the same result if you write 2 bytes in one
call to writeBytes() and if you call writeBytes() twice, writing
1 byte each time.
When a record is added using addRecord(), the current position is
set to the newly added record. So, if we are writing data to a
newly created record, we don't need to call setRecord().
Here we add a 2 byte record and write 2 bytes into it:
if (c.addRecord(2) == -1)
return; // error
bytes buf[] = new bytes[2];
buf[0] = 1;
buf[1] = 2;
if (c.writeBytes(buf, 0, 2) != 2)
return; // error
Reading from Records
Reading from records is just like writing to records. To
read from a record, you can use setRecord() to set the
current record position and then use readBytes() to read
data from the record.
Each time a read occurs, the cursor within the record is
advanced the number of bytes read.
Here is an example showing how to read 4 bytes (2 reads of
2 bytes each) from the first record in a catalog:
if (!c.setRecord(0))
return; // error
byte buf1[] = new byte[2];
if (c.readBytes(buf1, 0, 2) != 2)
return; // error
byte buf2[] = new byte[2];
if (c.readBytes(buf2, 0, 2) != 2)
return; // error
Deleting Records
The deleteRecord() method is used to delete records. The following
code deletes the first record in a catalog:
if (!c.setRecord(0))
return; // error
c.deleteRecord();
When a record is deleted, it doesn't actually disappear from the
catalog. Instead, it is simply marked for deletion.
At some point later on, usually not until the database is synchronized
with a database of a desktop PC, the record will actually be removed
from the catalog.
For example, if there was only 1 record in a catalog and we deleted
it with the code above, after deleting the record, the catalog would
still contain 1 record. However, any call to setRecord() to set the
current record to the deleted record will fail since the record is deleted.
The number of records in the catalog would not actually go to 0
until the device was synchronized.
Because the setRecord() call will fail if an attempt is made to set
the current record to a delete record, you need to be careful
to check the status of setRecord() and not assume that just because
the record number is valid, you can read or write to it.
Closing the Catalog
When you are done working with a catalog you should close it.
c.close();
If you forget to close the catalog and it is freed by the
garbage collector, the catalog will be closed properly
before it is freed.
Copyright (c) 1999 - 2001 Wabasoft. Waba, WabaVM and WabaSDK are trademarks of
Wabasoft Inc.
|