Product Documentation

c-treeACE V11.0 Update Guide

Previous Topic

Next Topic

Update Callback Specifications

File Open and File Close Callbacks

The file open and close callback functions are intended to allow an application to manage resources that will be used by the record update callback function. Typically an application will allocate resources in the file open function and will free the resources in the file close function. For example, initializing an alternative indexing environment on open, and freeing that environment context at close.

The file open callback function is called when the following events occur:

  1. When a connection opens a file that has a callback definition, the callback function is called at the end of the file open operation. If it is an ISAM level file open call such as OPNIFIL() or OPNRFIL(), the callback is called after the data file and its associated indexes have been successfully opened.
  2. When a connection adds a callback definition to the file, the callback function is called after the callback definition resource in the data file has been successfully updated.

A callback that is added to a data file that is open in shared mode becomes visible to other connections that already have the file open on their next record add, update, or delete operation. In that situation, the other connection finds that the new callback exists and it calls the file open callback function for the newly-added callback before calling the record update callback function.

The file close callback function is called when the following events occur:

  1. When a connection closes or deletes the file, the callback function is called right before the data file is closed, so the connection still has the data file and its associated index files open.
  2. When a connection deletes a callback definition from the file, the callback function is called after the callback definition resource in the data file has been successfully updated.

The file open and close functions have the following prototypes:

NINT rucbOpenFileCallback(pRUCBF prucbf);

NINT rucbCloseFileCallback(pRUCBF prucbf);

The record update callback function parameter structure, RUCBF, has the following definition:

/* record update callback parameters */

typedef struct rucbf {

pTEXT datnam; /* Data file name. */

pTEXT params; /* Optional callback parameter string. */

NINT calltm; /* Current context for this call. */

FILNO datno; /* User file number of data file. */

pVOID psession; /* User-defined connection-level pointer. */

pVOID ptable; /* User-defined table-level pointer. */

} RUCBF, *pRUCBF;

The two state pointers, psession and ptable, are available for use by the user-defined callback function code.

The psession state pointer is shared by all callback functions for all files in a given connection. It is appropriate for storing connection-wide state information. One way to use this pointer is to allocate memory and set psession to point to that memory on the first call to the file open callback function in a connection. The application can also maintain a connection-wide reference count, and when the file close function finds that the reference count is zero, it can free the memory.

The ptable state pointer is specific to a particular callback function for a particular file. It is appropriate for storing table-level state information.

Record Update Callback

When a user adds, updates, or deletes a record at the ISAM level, the callback is called at one of the following events:

  1. If the callback event is set to RUCBonrecupd, or if the callback time is set to RUCBontrancmt and the file is not under transaction control, the callback is called right after the record and its keys have been added, updated, or deleted.
  2. If the callback event is set to RUCBontrancmt and the file is under transaction control, the callback is called when the transaction that modified the record is committing.
  3. if the callback event is set to RUCBonqueuethrd, the callback is called after the transaction commits, when the deferred index thread has read the entry for that record modification operation from the transaction logs.
  4. if the callback event is set to RUCBonqueueapp, the callback is never called. It is up to the application to read the entry for that record modification operation from the transaction logs and take the appropriate action.

The record update callback function has the following prototype:

NINT rucbRecordUpdateCallback(pRUCBF prucbf,pDFRKY pdfrky);

The RUCBF structure is the same as mentioned above and the additional DFRKY structure contains the information about the record add, update, or delete operation and has the following definition:

typedef struct dfrky {

COUNT opcode; /* deferred index operation code */

TEXT status1; /* status bit field #1 */

TEXT status2; /* status bit field #2 */

ULONG dfrkctr; /* deferred index create counter */

LONG fid[3]; /* unique file ID of data file */

LONG oreclen; /* size of old record image (rewrite) */

LONG reclen; /* size of record image */

LONG datnamlen; /* length of data file name plus null */

LONG8 orecbyt; /* old record offset (rewrite) */

LONG8 recbyt; /* record offset */

TEXT varinf[1]; /* variable length information:

** For ctDFR_ADDKEY and ctDFR_DELKEY:

** null-terminated data file name

** old record image (rewrite)

** record image

** For ctDFR_RWTKEY and ctDFR_RWTPKEY:

** null-terminated data file name

** old record image

** record image

** For ctDFR_LOADKEY:

** null-terminated data file name

** null-terminated index file name

*/

} DFRKY, ctMEM **ppDFRKY;

Your record update callback implementation handles one of following four update operations provided in the opcode from the DFRKY structure:

  • ctDFR_ADDKEY - A record was added
  • ctDFR_RWTKEY - A record was updated
  • ctDFR_RWTPKEY - A record was partially updated
  • ctDFR_DELKEY - A record was deleted

You'll find this framework available in the ctrucbdll.c module.

First and Last Operations

An application that uses the record update callback function feature needs to know what operations are associated with a particular transaction and what are the first and last operations for that transaction. In V11.5 and later FairCom Server provides this information to the record update callback function:

  • The first operation in a transaction has the ctDFR_TRANFRS bit set in the status1 field of the pdfrky parameter that is passed to the record update callback function.

    The last operation in a transaction has the ctDFR_TRANLST bit set in the status1 field of the pdfrky parameter that is passed to the record update callback function. So, if a transaction has only one DFRKEY entry, that entry will have both the ctDFR_TRANFRS bit and the ctDFR_TRANLST bit set. If a transaction has more than one DFRKEY entry, the first entry will have the ctDFR_TRANFRS bit set and the last entry will have the ctDFR_TRANLST bit set.

  • An optional parameter of type pRUCBSTT is passed to the record update callback function. This structure has the following definition:

    typedef struct rucbstt_t {

    LONG verson; /* structure version */

    LONG avail; /* padding- available for use */

    LONG8 tranno; /* transaction number for the operation */

    } RUCBSTT, *pRUCBSTT;

Note: For FairCom Server to pass this third parameter to your record update callback function, your record update callback DLL or shared library must export the function rucbCheckVersionCallback(), which has the following function prototype:

NINT rucbCheckVersionCallback(pRUCBACB prucbacb,pNINT pversion);

prucbacb is the record update callback definition in the format of the record update callback add operation structure, RUCBACB. The function can choose to examine the record update callback definition to decide which version of the RUCB API it supports. For example, it can choose based on the callback name (prucbacb->cbname) or the name of the record update callback function (prucbacb->fncnames[2]).

The function should set pversion to the version of the record update callback API your DLL uses and return zero to indicate success. Supported versions are:

  • a) Version 1 of record update callback API. Your record update callback function must conform to the following prototype:
    NINT rucbRecordUpdateCallback (pRUCBF prucbf,pRUCBO prucbo);
  • b) Version 2 of record update callback API. Your record update callback function must conform to the following prototype:
    NINT rucbRecordUpdateCallback (pRUCBF prucbf,pRUCBO prucbo,pRUCBSTT prucbstt);

If your record update callback DLL does not export a function named rucbCheckVersionCallback(), FairCom Server uses version 1 of the record callback API.

TOCIndex