Frontier website on www.scripting.com
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:
booleanType true or false. longType 32-bit signed number. dateType the number of seconds since Jan 1, 1904. stringType a variable length text handle. doubleType double-precision floating point number. binaryType unformatted 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 recordsEach 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 recordSee 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-97 UserLand Software. This page was last built on Wed, Jan 22, 1997 at 2:32:46 PM with Frontier. Thanks for checking it out! Dave