Common Functionality

FairCom DB API .NET is a high-level, easy-to-use API encapsulating two popular FairCom APIs: ISAM and Low-level. FairCom DB API .NET is intended as the new standard for c-tree programming in .NET environments. FairCom eases the developer’s task without removing the flexibility and performance of our original APIs.

The FairCom DB API .NET general architecture is presented in the figure below, organized into seven different levels: Session, Database, Table, Field, Index, Segment, and Record. These levels or layers will be used to present a group of common functionality.

c-treeDB Relationships

A Session represents a connection between a client and a FairCom DB database engine; no work can be performed before a session becomes active. The session object indicates the FairCom DB API .NET session, the server name and location, the directory where the databases are located, the user name and password.

A Database can be considered as a collection of tables, and each database has its own database dictionary that stores information about each table that belongs to that database: the table name, password and path, the active (open) tables, and the number of tables linked to the database. The database object indicates a database in the session and each session can have multiple databases.

A Table is essentially a FairCom DB data file and optional index files. There can be, and typically are, more than one table in a database, and a given table may belong to multiple databases. A table may have zero or more records.

A Field is the basic element of a table, and a collection of fields form a data record.

Often a table will have zero or more Indexes, which enhance the retrieval of records from that table.

Indexes typically have one or more Segments that describe the index key structure. The index object indicates an index associated with a particular table, while the segment links the index with the fields.

A Record is essentially a row entry in a table. A record object indicates a record instance on a particular table. A table may have one or more record objects associated with it. Each record handle may be an independent cursor into the table, or several record objects may share the same cursor into the table.

Note: It is important to note that c-tree data and index files can be manipulated directly with or without session or database dictionary support. Please refer to Working with Sessions without Dictionary Support and Creating a Table Object without Database Support for more information.


Common Functionality

FairCom DB API .NET classes CTSession, CTDatabase, CTTable, CTRecord, CTField, CTIndex and CTSegment all inherit from a common base CTBase class.

All functionality and methods described in this chapter are available when working with sessions, databases, tables, records, fields, indexes and index segments.


Objects Disposal

The .Net Garbage Collector (GC) may interfere with internal structures held by various FairCom DB API .NET objects (classes).

For this reason the automatic .Net collection has been disabled for the following classes:

  • CTSession
  • CTDatabase
  • CTTable
  • CTRecord

It is important to remember that these objects must be manually "destroyed", using the provided Dispose() method, when they are no longer referenced in applications.

Objects that are not disposed of will remain in memory resulting in a possibly significant memory Leak.

 

Error Handling

Most FairCom DB API .NET API functions return an error status to indicate if a particular function operation succeeded or not. Most FairCom DB API .NET API methods will also keep the last error status, if the function operation failed. The last error status can be manipulated with the following methods:

GetError() retrieves the last error status. If a function succeeds, the success status is not kept by the FairCom DB API .NET API.

SetError() sets the last error status, overwriting any previous error status kept by the FairCom DB API .NET API.

ClearError() clears the last error status.

// clear the error if error is INOT_ERR
// Recobj is a CTRecord object
if (Recobj.GetError() == INOT_ERR)
{
   Recobj.ClearError();
}

 

Transaction Processing

The FairCom DB API .NET API implementation of transaction processing functions follows closely the c-tree ISAM API definition. The basic difference between the FairCom DB API .NET and ISAM transaction processing API is the separation of locking mechanisms from transaction processing.

While the ISAM API also allows for locking modes to be specified when beginning a transaction, the FairCom DB API .NET API requires that locking functions be implicitly used after a transaction begins. The code fragment below shows an example using a c-tree ISAM call to start a transaction with locking:

/* start transaction enabling write locks */
TRANBEG(TRNLOG | ENABLE | LK_BLOCK);

... perform some data operations ...

/* commit the transaction and release locks */
TRANEND(FREE);

The c-tree code fragment above starts a transaction by invoking function TRANBEG. The mode ENABLE indicates that every c-tree read record operation will lock the record for writing and the mode LK_BLOCK indicates that the thread will block until the lock is acquired.

When using the FairCom DB API .NET API, developers must be aware that the transaction processing API will not start the record locking mechanism. The code fragment below shows the equivalent example using the FairCom DB API .NET API:

// Recobj is a CTRecord object
// start a transaction
Recobj.Begin();

// enable write locks
Recobj.Lock(LOCK_MODE.WRITE_BLOCK_LOCK);

... perform some data operations ...

// release locks
Recobj.Unlock();

// commit the transaction
Recobj.Commit();

The Begin() method starts a new transaction, while Commit() terminates a transaction by committing any changes. Abort() terminates a transaction and aborts any changes done during the transaction.

SetSavePoint() sets a save point in the current transaction. Once a save point is set within the current transaction, RestoreSavePoint() will reverse only changes done in between the set save point and restore the save point, without terminating the transaction.

Please refer to the chapter entitled "Data Integrity" in the c-tree Plus Programmer's Reference Guide for a detailed description of transaction processing and locking.

 

Session-Wide Locking

Session-wide locking is based on the principle that the Lock method sets the current lock mode. When locks are activated, every record read from all active tables of all active databases associated with the session are automatically locked with the current lock mode.

// start locking
// ASession is a CTSession object
try
{
   ASession.Lock(LOCK_MODE.WRITE_BLOCK_LOCK);
}
catch (CTException err)
{
   Console.Write("Session lock failed with error {0}\n", err.GetErrorCode());
}

Unlock() releases all locks acquired since the last Lock() call and clears the current lock mode. IsLockActive() indicates if a session-wide lock mode is set. GetLockMode() retrieves the current session-wide lock mode. If no session-wide locks are active, GetLockMode() returns CTLOCK_FREE.

// unlock if locks are active
// ARecord is a CTRecord object
try
{
   if (ARecord.GetLockMode() != LOCK_MODE.FREE_LOCK)
   {
      ARecord.Unlock();
   }
}
catch (CTException err)
{
   Console.Write ("Unlock failed with code {0}\n", err.GetErrorCode());
}

Refer to the chapter titled "Data Integrity" in the c-tree Plus Programmer's Reference Guide for a detailed description of transaction processing and locking.

 

Default Date, Time, and Float Formats

The FairCom DB API .NET record manager performs automatic data type conversions when the user reads from, or writes to, a field using a data type that is different from the field data type. For most data types, the conversion is straightforward except when converting dates and times to and from strings, as there are many different conventions for displaying dates and times.

By default FairCom DB API .NET converts date to string, and from string to date, using the standard U.S.A. convention of MM/DD/CCYY, where MM represents a two digit month with values from 01 to 12, DD represents a two digit day of the month with values from 01 to 31, depending on the number of days in the month, CC represents a two digit century and YY represents a two digit year. A date separator may be the '/', '-' and '.' characters.

The FairCom DB API .NET API converts time to string, and string to time, using the standard U.S.A. convention of HH:MM AM where HH represents the hour with values from 1 to 12, MM represents the minutes with values from1 to 59 and AM represents AM or PM values.

SetDefDateFormat() sets a new default date format. GetDefDateFormat() retrieves the current default date format. The following date formats are supported:

  • DATE_TYPE .MDCY_DATE
    Date format is MM/DD/CCYY where MM represents a two-digit month, DD represents a two-digit day of the month, CC represents a two-digit century, and YY represents a two-digit year. The date separator may be one of the following characters: '/', '-' or ','. This is the default date format. Example: 12/01/2002.
  • DATE_TYPE.MDY_DATE
    Date format is MM/DD/YY where MM represents a two-digit month, DD represents a two-digit day of the month, and YY represents a two-digit year. The date separator may be one of the following characters: '/', '-' or ','. Example: 12/01/02.
  • DATE_TYPE.DMCY_DATE
    Date format is DD/MM/CCYY where DD represents a two-digit day, MM represents a two-digit month, CC represents a two-digit century, and YY represents a two-digit year. The date separator may be one of the following characters: '/', '-' or '.'. Example: 01/12/2002.
  • DATE_TYPE.DMY_DATE
    Date format is DD/MM/YY where DD represents a two-digit day, MM represents a two-digit month, and YY represents a two-digit year. The date separator may be one of the following characters: '/', '-' or '.'. Example: 01/12/02.
  • DATE_TYPE.CYMD_DATE
    Date format is CCYYMMDD where CC is a two-digit century, YY is a two-digit date, MM is a two-digit month, and DD is a two-digit day of the month. This date format has no separators. Example: 20021201.
  • DATE_TYPE.YMD_DATE
    The date format is YYMMDD where YY represents a two-digit year, MM represents a two-digit month, and DD represents a two-digit day of the month. This date format has no separators. Example: 021201

SetDefTimeFormat() sets a new default time format. GetDefTimeFormat() retrieves the current default time format. The following time formats are supported:

  • TIME_TYPE.HMSP_TIME
    Time format is HH:MM:SS AP where HH represents an hour value between 1 and 12, MM represents a two-digit minute value between 00 and 59, SS represents a two-digit second value between 00 and 59, and AP is either AM or PM. The time separator may be ':' or '.'. Example: 1:35:45 AM.
  • TIME_TYPE.HMP_TIME
    Time format is HH:MM AP where HH represents an hour value between 1 and 12, MM represents a two-digit minute value between 00 and 59, and AP is either AM or PM. The time separator may be ':' or '.'. Example: 1:35 AM.
  • TIME_TYPE.HMS_TIME
    Time format is HH:MM:SS where HH represents an hour value between 0 and 23, MM represents a two-digit minute value between 00 and 59, and SS represents a two-digit second value between 00 and 59. The time separator may be ':' or '.'. Example: 1:35:45.
  • TIME_TYPE.HM_TIME
    Time format is HH:MM where HH represent an hour value between 0 and 23, MM represents a two-digit minute value between 00 and 59. The time separator may be ':' or '.'. Example: 1:35.
  • TIME_TYPE.MIL_TIME
    Time format is HHMM (military format). HH represents a two-digit hour value between 00 and 23 and MM represents a two-digit minute value between 00 and 59. This time format has no separator. Example: 0135.

When converting floating point type fields, such as CT_SFLOAT, CT_DFLOAT, and CT_EFLOAT, to and from strings, FairCom DB API .NET uses the float conversion format used by the standard functions Console.Write() and scanf(). By default the float conversion format is set to "%f". Use SetDefFloatFormat() set a new default float conversion format. Use GetDefFloatFormat to retrieve the current default float conversion format.

 

User-Defined Tags

Every handle allocated by the FairCom DB API .NET API has a space called user tag value reserved for holding an arbitrary user value. The user tag has no predefined meaning and is provided for the convenience of developers. It can be used for storing an additional void pointer or it can be typecast to any 32-bit value (or 64-bit value on 64-bit platforms).

Use GetUserTag() to retrieve the current user tag value associated with a handle. Use SetUserTag() to set the current user tag value associated with a handle.

When a FairCom DB API .NET object is destroyed, the user tag value is not automatically released. The user is responsible for releasing any dynamic memory controlled by pointers stored in the handle user tag space.