SIMPOL Documentation

Object-Oriented Database Access in SIMPOL

Introduction

There are a number of different object-oriented approaches to working with databases and in general those methods are directly related to the type of database access that they attempt to model. With SQL style access the approach tends toward recordset objects, which is completely understandable since SQL is all about doing queries and doesn't really have an idea of direct table access. That is reserved to the routines that actually implement a SQL database engine. In SIMPOL the database access is based around accessing database sources (which can be files or servers) and then from that file or server accessing tables. Each table has a ring of field objects and a ring of index objects. Record objects are created as the result of selecting a record using one of the selection methods. Index objects carry a reference to the field for which they are an index. In later releases there may be a ring of objects that describe the elements of an index that is either multiple field or based on something other than field information.

One big difference between the older Superbase approach to working with tables and field names and the object-oriented version is that opening a table does not simply create a group of globally visible identifiers. This means there is a little more work involved when using objects. At the same time, there is no limit to how many times a table can be opened concurrently or how many records could be the current record. Since records are objects whenever a record object exists it is available.

Another significant difference is in the way that records are selected. The object-oriented approach takes a little getting used to, but is perfectly logical and will eventually feel quite natural and obvious. Table objects can either select the first or last record in a table in sequential order. Index objects can select either the first or last record in index order or select via a key value into the index. So what about selecting the next or previous record? That is reserved to record objects. Only a record object knows how it was selected and therefore its index position. A record can also select only the next or previous record according to the order that was used to select the record, either in index order or sequential order of the table. To change the index of a record the record can be reselected with an option to change the index.

Database Type Tags for Generic Database Functionality

In keeping with the object-oriented design of SIMPOL a set of type tags (see the section called “Value Types, Reference Types, and Type Tags”) was created for use with databases that are of a consistent form. This set of type tags is known as the db1 set. This set of tags includes the following:

  • db1table

  • db1field

  • db1index

  • db1record

By writing generic functions to use the type tags rather than the specific object type declarations it makes it very easy to switch between different database types without rewriting the functionality for each individual type.

[Note]Note

One difference between sbme1 types and ppcstype1 types is that the former have a table or tablename property where the latter have a file or filename property in addition to the tablename. This does not affect the use since when working with the db1* type tags the table can be used in most cases. A more signficant difference is that ppcstype1fields have a much greater array of properties than sbme1fields. They include help text, comments, display formats, and other things that are not provided by the more storage-oriented and lower level engine from sbme1. In general, generic database routines should not be dependent on a display format that is provided with a column (or column widths that may not exist, etc.).

A Comparison of SBL Commands and SIMPOL Methods

Comparing the two approaches should help to clarify much of the difference in approach between the command based and the object based methods. To summarize and compare the SBL commands to the SIMPOL object methods then, here is a small table:

Table 12.1. Comparison of SBL file access commands to SIMPOL methods
SBLSIMPOL
SELECT FIRST INDEX ""db1tablevar.select(lastrecord=.false)
SELECT LAST INDEX ""db1tablevar.select(lastrecord=.true)
SELECT FIRST INDEX RecNo.TESTdb1indexvar.select(lastrecord=.false)
SELECT LAST INDEX RecNo.TESTdb1indexvar.select(lastrecord=.true)
SELECT KEY 123 INDEX RecNo.TESTdb1indexvar.selectkey(123)
SELECT NEXTdb1recvar.select(previousrecord=.false)
SELECT PREVIOUSdb1recvar.select(previousrecord=.true)
SET INDEX Name.TESTdb1recvar.selectcurrent(db1indexvar_Name)
SELECT FIRST LOCK INDEX ""db1tablevar.select(lastrecord=.false, lock=.true)
SELECT FIRST LOCK INDEX RecNo.TESTdb1indexvar.select(lastrecord=.false, lock=.true)
SELECT KEY 123 LOCK INDEX RecNo.TESTdb1indexvar.selectkey(123, lock=.true)
SELECT NEXT LOCKdb1recvar.select(previousrecord=.false, lock=.true)
SELECT CURRENT LOCKdb1recvar.selectcurrent(lock=.true)
SELECT REMOVEdb1recvar.delete()


There are numerous other combinations, but the previous table should show a reasonable cross-section. One of the interesting abilities in SIMPOL is that of deleting a record but still having the record available. When the delete() method is called, the record is deleted but the record object still exists. Its stored property is set to .false and it is reset internally to appear like a new record that has been filled in. That means that the record could now be saved as a new record (possibly with some modification).

Summary

In this chapter we have looked at the generic differences between working with databases in command-oriented languages like SBL and the methods employed by SIMPOL. In the following chapters we will discuss the specific issues affecting access to PPCS and SBME databases in SIMPOL.