wabasoft how-to papers  
Products
Overview
Downloads
Fun and Games
More VMs
More SDKs
Dev Tools
Development
FAQ
Support
Specifications
How-to Papers
Company
Overview
Contact Us
Home Page
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.