Teaching an old dog new tricks

RDM was first introduced in the mid 1980’s under the name of dbVista. That original version of the RDM software, designed for the hardware and operating systems available in those times, has relatively little in common with the current version of RDM. Over the years the product has been enhanced with functionality needed by the ever changing software market. Multi-user capability has been added, the engine was made thread-safe and then reentrant, new programming interfaces have been added (SQL, ODBC, ADO.Net, Objective-C, C++), but the one thing that has remained constant through RDM’s nearly 30 years of life is the core C API.

Odds are that the database access code of a dbVista program developed in the 1980’s could compile with RDM 12.0 with minimal updates. Things have been added, but the core interface has stayed consistent for all of those years.

The primary of the reasons that RDM’s core API has stayed constant over the years is that it was is designed to meet the needs of developers both then and now.  However we recently decided to go through an exercise to figure out what the RDM Core interface would look like if we were designing for the first time today.  The parameters of our design were the new API had to be compatible with our current file format and it should have nothing to do with SQL.  A team of two was tasked with this exercise one an engineer with 15 years experience working on and with the RDM engine, the other a senior engineer that had never worked on or with RDM.  The result of the collaboration is the new Cursor based interface that is being introduced with the release of RDM 12.0.  This new Cursor interface is not replacing the original interface, which is still available and will be maintained.  It is an alternative interface that is able to do anything the original interface can do in a manner that is clean and intuitive.

As can be guessed by the name our new interface is based on the concept of Cursors or collections of records.  These cursors are accessed using an iterator style interface.  You request a cursor on a table and then iterate through the records in that cursor.  The cursor may contain every record in the table or it may contain just a subset of the records.  The power of the interface is that a while a cursor can be based on several things, we support five distinct types of cursors, all cursors accessed with the exact same set of APIs.

The five types of cursor available in RDM 12.0 are

  • Record Scan Cursor – a collection of all the records of a single type in raw database order
  • Key Scan Cursor – a collection of all the records of a single type  in index order
  • Key Range Cursor – a collection of the records of a single type within an index value range ordered by index value
  • Set Scan Cursor – a collection of related records (the many size of a one-to-many set relationship)
  • Singleton Cursor – a cursor containing a single record

When you request a Cursor you have the option of specifying where the cursor will be initially positioned.  A cursor can be initially positioned to a particular database address, a particular index value, or at a location before any of the records in the collection (‘BeforeFirst’).  Once the cursor has been created there are iterator functions to position yourself throughout the collection of records in the cursor (dc_fist, dc_next, dc_prev, and dc_last).  If you don’t wish to navigate serially through a cursor you can position the cursor by database address (dc_findByDBA) or index/hash value (dc_findByKey).  Once the cursor is positioned you can perform the typical database CRUD operations (Creation, Deletion, Update, and Retrieval) on the record the cursor is positioned to.  The cursor API being based on the RDM engine there are also cursor functions for managing network model sets.  You can add a member to a set (dc_addMember/dc_connect) and remove members from sets (dc_removeMember/dc_disconnect).  Anything that is possible with the core API can be done with the cursor API and in many cases it can be done in fewer API calls.  In addition to these operations, all of which are possible with the core API, the cursor API adds a powerful set of new operations.  The ability to determine the position of a cursor and to compare the position of one cursor with another cursor.

Whether you are new to RDM or looking at it for the first time, I suggest you take a look at the Cursor API in RDM 12.0.  It is a powerful and intuitive interface to the best embedded data engine on the market.