frondoc picture

This page is
part of the
Frontier 4 site.

Frontier 5
shipped in
January 1998.

The information
on these pages
may not be
accurate for
Frontier 5.

These pages
are maintained
for archival
purposes only.

uBASE

uBASE is a fast flat-file database for script writers.

Unlike FileMaker, 4th Dimension and FoxBase, uBASE is designed to serve scripts, not users. It has almost no user interface. ItÕs a very small program that loads quickly. It has a simple scripting interface. uBASE is ideal for the data storage needs of many scripts.

In terms of its Apple Event interface, nothing as fancy as the object model here, just a few simple verbs to create a new file, open an existing file, add a record, lookup a record, close a file.

The uBASE application is shipped with Frontier 4.0, in the UserLand Utilities folder. A shared menu for uBASE is stored in system.menubars in Frontier.root, and the glue scripts table, system.verbs.apps.ubase is also pre-installed.

Creating a new file

The following sections review the scripting verbs for uBASE. If you want to follow along in Frontier, navigate to system.verbs.apps.ubase and open the examples table. Also, all of uBASEÕs verbs are documented in the DocServer database.

To create a new uBASE file, use the ubase.newFile verb. It takes a single parameter, the full path to the file it creates. The file is created initially with no fields and no records. Here's an example:


fnum = ubase.newFile ("System:States Database")

ubase.newFile returns a file refnum -- a number between 1 and 99. Save the refnum in a local variable. All subsequent calls to uBASE will use this number. This allows uBASE to manage more than a single open database, and allows scripts to move information from one database to another.

Opening an existing file; closing files

To open an existing file use ubase.openFile. It takes a full path to the file to open, and returns a file refnum:


fnum = ubase.openFile ("System:States Database")

To close a uBASE file, use ubase.closeFile:


ubase.closeFile (fnum)

Adding fields to a uBASE file

After creating a new file or opening an existing file, you can add fields to the database using the ubase.addField verb.

ubase.addField takes three parameters:

1. a file refnum indicating which file the field is to be added to.

2. fieldName, a four-character string, the name of the field. See note below.

3. fieldType, a four-character string, indicating the type of the new field.

For performance, we limited field names to four characters so that records could flow quickly between uBASE and Frontier using the Apple Event Manager.

Field types

The set of field types supported by uBASE is a subset of the types supported by Frontier.

HereÕs a list of field types:

booleanTypetrue or false.
longType32-bit signed number.
dateTypethe number of seconds since Jan 1, 1904.
stringTypea variable length text handle.
doubleTypedouble-precision floating point number.
binaryTypeunformatted data, variable-length.

Example

Here's an example that launches uBASE, creates a new file in the same folder as the Frontier application, adds two string fields to it, and then closes the file:


local (ubasefolder, fnum)

ubase.launch () «make sure uBASE is ready to talk to us

fnum = ubase.newFile (Frontier.pathstring + "States Database")

ubase.addField (fnum, 'capi', stringType) «the state's capital

ubase.addField (fnum, 'abbr', stringType) «the abbreviation for the state

ubase.closeFile (fnum) «the database has two fields, no records

Each record has a key

Every record in a uBASE file has a unique key, a string of any number of characters. In an address book application, for example, the key could be a userÕs email account name. Or in an application database, it could be the creator ID of the application.

If you add a record that has the same key as an existing record, the new record replaces the previous record. The key is unique, thatÕs an absolute rock-hard rule.

How to add a record to a uBASE file

ubase.addRecord takes three parameters:

1. a file refnum;
2. the recordÕs key;
3. the address of a Frontier table containing the values for the record.

Here's an example that opens the database created in the previous example and adds a record describing Wisconsin:


local (fnum, holder)

new (tableType, @holder)

holder.capi = "Madison"

holder.abbr = "WI"

ubase.launch ()

fnum = ubase.openFile (Frontier.pathstring + "States Database")

ubase.addRecord (fnum, "Wisconsin", @holder)

ubase.closeFile (fnum) «the database has two fields, one record

See ubase.examples.addStates for an example that adds all 50 states to the database.

ubase.lookupRecord

The flipside of ubase.addRecord is ubase.lookupRecord. It takes three parameters: a file refnum, the recordÕs key and the address of a Frontier table to receive the values for the record with the indicated key.

Here's an example that opens the database and looks up information about Wisconsin:


local (fnum, holder)

ubase.launch ()

fnum = ubase.openFile (Frontier.pathstring + "States Database")

ubase.lookupRecord (fnum, "Wisconsin", @holder)

ubase.closeFile (fnum)

dialog.alert ("Wisconsin's capital is " + holder.capi + ", abbreviation is " + holder.abbr + ".")

See ubase.examples.checkStates for another example.

Visiting all the records in a database

Use ubase.countRecords, ubase.getFirstRecord and ubase.getNextRecord.

The records are not sorted. The first record is not necessarily the first record in alphabetic order. It would be much slower to return them in sorted order. Even so, visiting all the records in a database is not a fast operation when compared to a single call to ubase.lookupRecord.

HereÕs an example that displays the names of all 50 states in FrontierÕs main window:


local (ubasefolder, fnum, count, key, i)

ubase.launch ()

fnum = ubase.openFile (Frontier.pathstring + "States Database")

count = ubase.countRecords (fnum)

key = ubase.getFirstRecord (fnum)

for i = 1 to count 

   msg (key)

key = ubase.getNextRecord (fnum, key)

ubase.closeFile (fnum)

For another example, see ubase.examples.reportStates.

How uBASE is implemented

Records are variable-length. ThereÕs no need to set a maximum length for string fields. Only the number of characters present in an individual field are stored in the database. The same is true for binary fields.

Garbage collection is incremental, when you delete a record, uBASE attempts to merge it with adjacent free blocks. uBASE will re-use space released by deleted records, but the file will never decrease in size.

uBASE is an ordinary Apple Event-aware Macintosh application.

Version 1.1b1 -- 1/4/96 DW

uBASE now flushes the default volume after every addRecord, deleteRecord and addField call. Since uBASE often runs on web servers, and web servers sometimes crash, we need to be extra careful with the databases.

People were working around this by closing and then re-opening the databases after every addRecord call. It should be faster than closing and reopening the file and safer against system crashes.


© Copyright 1996-98 UserLand Software. This page was last built on 5/9/98; 8:29:46 AM. It was originally posted on 5/6/96; 9:12:14 PM.