FairCom DB Function Descriptions K-Z

LastInRange

Read the last data record in a range

Short Name

LSTRNG()

Type

ISAM function

Declaration

COUNT LastInRange(FILNO keyno, pVOID recptr)  

Description

In V12 the file number typedef was formally changed from COUNT, a two-byte value to FILNO, a four-byte value. Refer to this link for compatibility details. Four Byte File Numbering

Read the last data record in a range established by a call to AllocateRange(). If successful, the record becomes the current ISAM record for the associated data file. A successful LasttInRange() defines a current key value set, and subsequent calls to NextInRange() or PreviousInRange() will read the other records in the range.

If the data file has variable-length records, only the fixed-length portion of the record is actually read. You can use ReReadVRecord() to retrieve the whole record, including the variable-length portion. You can use LastInVRange() to read the whole variable-length record with one function call.

Return

Value Symbolic Constant Explanation
0 CTDBRET_OK Successful operation.
101 INOT_ERR

Could not satisfy and ISAM search request for index isam_fil. This error frequently indicates "End of File" reached, or "Record not Found."

The following items are the probable causes of the INOT_ERR (101).

  • Passing GetRecord() a duplicate allowed index number (keyno). GetRecord() does not support duplicate allowed indices.
  • Improper target padding. Review “Key Segment Modes” in the c-tree Plus Programmer’s Guide.
  • Not calling TransformKey() on target. Refer to “TransformKey” in the Function Reference Guide
  • Passing ctDeleteSequence() a sequence name that does not exist
  • Improper segment mode. Review “Key Segment Modes” in the c-tree Plus Programmer’s Guide.
  • ctFILBLK() is called and the file is already blocked.

See c-tree Error Codes for a complete listing of valid c-tree error values.

See also

AllocateRange(), EstimateRange(), FirstInRange(), FirstInVRange(), FreeRange(), LastInVRange(), NextInRange(), NextInVRange(), PreviousInRange(), PreviousInVRange()

 

LastInSet

Read the last data record in the set defined by a target.

Short Name

LSTSET()

Type

ISAM function

Declaration

COUNT LastInSet(FILNO keyno, pVOID target, pVOID recptr, COUNT siglen)

Description

In V12 the file number typedef was formally changed from COUNT, a two-byte value to FILNO, a four-byte value. Refer to this link for compatibility details. Four Byte File Numbering

LastInSet() reads the last data record in the set of data records whose keys match the target key in the first siglen bytes. If successful, this record becomes the current ISAM record for the associated data file. A successful LastInSet() defines a current key value set, and subsequent calls to NextInSet() and PreviousInSet() will read the other records in the set (i.e., those records whose keys also match the last siglen bytes of target). If an error occurs or no key value matches the target, the current ISAM record is not updated, and no key value set is defined.

If the data file has variable-length records, only the fixed-length portion, defined by dreclen in the original call to CreateIFile(), is actually read into the buffer pointed to by recptr. If you wish to read the entire variable-length record into the same or a different buffer, issue a call to ReReadVRecord() after the call to LastInSet(). Note that ReReadVRecord() requires the size of the buffer area so that it can check if sufficient space is available.

The target buffer must be initialized to the full length of the key to avoid memory corruption when the target is transformed to match the key.

LastInSet() can be used to perform an equality search for duplicate keys. Set target to the key value of interest, and set siglen to the key length less the 4 bytes of the suffix.

Notice that you do not directly identify the data file number involved. The ISAM parameter file described in ISAM Functions (ISAM Database Technology, /doc/ctreeplus/30841.htm) of the c-tree Programmer’s Reference Guide contains the correspondence between the index file number and the associated data file.

Return

Value Symbolic Constant Explanation
0 NO_ERROR Successful retrieval of current ISAM record.
33 DNUL_ERR recptr is NULL. No data file read performed.
42 DLOK_ERR Could not get lock on data record. No data file read performed.
101 INOT_ERR No active entries.
119 SKTY_ERR keyno must reference a non-numeric key type.

See c-tree Error Codes for a complete listing of valid c-tree error values.

Example

FILNO        keyfil;

TEXT         target[24], recbuf[320];


printf("\nEnter set value:");

scanf("%23s", target);

LastInSet(keyfil, TransformKey(keyfil,target), recbuf,

          strlen(target));

while (isam_err == NO_ERROR) {

   process_data();

   PreviousInSet(keyfil, recbuf);

}

Limitations

No check is made to determine if recptr points to a region sufficiently large to accept a data record. If the area is too small, either code or data will be clobbered.

See also

NextInSet(), PreviousInSet(), FirstInSet(), PositionSet(), ChangeSet(), CreateIFile(),
ReReadVRecord(), TransformKey()

 

LastInVRange

Read the last data record in a range

Short Name

LSTVRNG()

Type

ISAM function

Declaration

COUNT LastInRange(FILNO keyno, pVOID recptr, pVRLEN plen)  

Description

In V12 the file number typedef was formally changed from COUNT, a two-byte value to FILNO, a four-byte value. Refer to this link for compatibility details. Four Byte File Numbering

Read the last data record in a range established by a call to AllocateRange(). If successful, the record becomes the current ISAM record for the associated data file. A successful LasttInVRange() defines a current key value set, and subsequent calls to NextInVRange() or PreviousInVRange() will read the other records in the range.

plen acts as both an input and output parameter:

  • On input, plen contains the length of the output buffer.
  • On output, the contents of plen is the actual data-record length. If the length of the output buffer is less than the actual record length, a partial read is performed. If an error occurs, plen is unspecified.

Return

Value Symbolic Constant Explanation
0 CTDBRET_OK Successful operation.
101 INOT_ERR

Could not satisfy and ISAM search request for index isam_fil. This error frequently indicates "End of File" reached, or "Record not Found."

The following items are the probable causes of the INOT_ERR (101).

  • Passing GetRecord() a duplicate allowed index number (keyno). GetRecord() does not support duplicate allowed indices.
  • Improper target padding. Review “Key Segment Modes” in the c-tree Plus Programmer’s Guide.
  • Not calling TransformKey() on target. Refer to “TransformKey” in the Function Reference Guide
  • Passing ctDeleteSequence() a sequence name that does not exist
  • Improper segment mode. Review “Key Segment Modes” in the c-tree Plus Programmer’s Guide.
  • ctFILBLK() is called and the file is already blocked.

See c-tree Error Codes for a complete listing of valid c-tree error values.

See also

AllocateRange(), EstimateRange(), FirstInRange(), FirstInVRange(), FreeRange(), LastInRange(), NextInRange(), NextInVRange(), PreviousInRange(), PreviousInVRange()

 

LastInVSet

Read the last variable-length data record in the set defined by target.

Short Name

LSTVSET()

Type

ISAM function

Declaration

COUNT LastInVSet(FILNO filno, pVOID target, pVOID recptr,

                 COUNT signlen, pVRLEN plen)

Description

In V12 the file number typedef was formally changed from COUNT, a two-byte value to FILNO, a four-byte value. Refer to this link for compatibility details. Four Byte File Numbering

LastInVSet() is identical to it’s fixed-length counterpart, LastInSet(), except that it reads the last variable-length data record in the set defined by target and siglen. If successful, this record becomes the current ISAM record for the associated data file.

plen acts as both an input and output parameter:

  • On input, plen contains the length of the output buffer.
  • On output, the contents of plen is the actual data-record length. If the length of the output buffer is less than the actual record length, a partial read is performed. If an error occurs, plen is unspecified.

Read the function description for LastInSet() for additional important information.

Return

Value Symbolic Constant Explanation
0 NO_ERROR Successful retrieval of current ISAM record.
633 NPLN_ERR plen is NULL.
634 NLEN_ERR plen is negative on input.

See c-tree Error Codes for a complete listing of valid c-tree error values.

See also

LastInSet(), NextInVSet(), PreviousInVSet(), TransformKey()

 

LastKey

Find the last entry in an index file.

Short Name

LSTKEY()

Type

Low-Level index file function

Declaration

LONG LastKey(FILNO keyno, pVOID idxval) 

Description

In V12 the file number typedef was formally changed from COUNT, a two-byte value to FILNO, a four-byte value. Refer to this link for compatibility details. Four Byte File Numbering

LastKey() searches index file keyno for the last entry in the index. If successful, it copies the last index entry into the space pointed to by idxval.

Return

LastKey() returns the data record position associated with the last entry in the index file. If the index is empty or an error is detected, LastKey() returns zero. If LastKey() returns zero, check uerr_cod to see if an error occurred: if uerr_cod is also zero, then the index is empty; otherwise, an error condition was detected. See c-tree Error Codes in the c-tree Programmer’s Reference Guide for a complete listing of valid c-tree error values.

Example

TEXT     idxval[10];

FILNO    keyno;


if (LastKey(keyno,idxval))

   printf("\nLast index entry = %.10s", idxval);

else {

   printf("\nEither index is empty or an error occurred.");

   if (uerr_cod)

      printf("\Error = %d",uerr_cod);

   else

      printf("\Index is empty.);

}

Limitations

No check is made to determine if idxval points to a region sufficiently large to accept a key value from the index file. If the area is too small, either code or data will be clobbered. Use GetCtFileInfo() to determine the key length.

The key value returned by this function will be a properly formatted key value (i.e., HIGH_LOW order, forced to upper case, etc.). The main issue is if binary key values will be displayed on a LOW_HIGH machine, it will be necessary to reverse any numeric segments. Key Segment Modes (Key Segment Modes, /doc/ctreeplus/30863.htm) in the c-tree Programmer’s Reference Guide contains suggestions for manipulating the key value.

The recbyt parameter in this function is a 4-byte value capable of addressing at most 4 gigabytes. If your application supports HUGE files (greater than 4 gigabytes), you must use the ctSETHGH() and ctGETHGH() functions to set or get the high-order 4 bytes of the file offset. See also Record Offsets Under Huge File Support.

See also

GetCtFileInfo(), FirstKey(), NextKey()

 

LastRecord

Read the last data record.

Short Name

LSTREC()

Type

ISAM function

Declaration

COUNT LastRecord(FILNO filno, pVOID recptr)

Description

In V12 the file number typedef was formally changed from COUNT, a two-byte value to FILNO, a four-byte value. Refer to this link for compatibility details. Four Byte File Numbering

LastRecord() retrieves the last data record found. If filno designates an index file, LastRecord() reads the last data record based on the key sequential order of entries in index file number filno. If filno designates a data file, LastRecord() reads the last active data record, in physical sequential order. If successful, the last record becomes the current ISAM record for the associated data file. If an error occurs or there are no entries, the current ISAM record is not updated.

If LastRecord() is called with an index number, the data file number involved is not directly described. The ISAM parameters described in ISAM Functions (ISAM Database Technology, /doc/ctreeplus/30841.htm) of the c-tree Programmer’s Reference Guide contain the correspondence between the index number and the associated data file.

Return

Value Symbolic Constant Explanation
0 NO_ERROR Successful retrieval of current ISAM record.
33 DNUL_ERR recptr is NULL. No data file read performed.
42 DLOK_ERR Could not get lock on data record. No data file read performed.
48 FMOD_ERR LastRecord() called with a data file number that is: a variable-length data file; a member of a superfile; has RESOURCES enabled.
101 INOT_ERR No active entries.

See c-tree Error Codes for a complete listing of valid c-tree error values.

Example

FILNO     keyfil,datfil;

TEXT      recbuf[320];


if (LastRecord(keyfil,recbuf))

    printf("\nError %d retrieving last record.", isam_err);

else if (ReReadVRecord(datfil,recbuf,320))

    printf("\nError %d retrieving variable portion.", isam_err);

else

    printf("\nSuccessful LastRecord.");

Limitations

No check is made to determine if recptr points to a region sufficiently large to accept a data record. If the area is too small, either code or data will be clobbered.

filno cannot be a data file number if any of the following are true:

  • The data file is set up for variable-length records.
  • The data file is a member of a Superfile.
  • The data file has Resources enabled (the default state).

In any of the above cases, LastRecord() returns FMOD_ERR (48).

If filno is a key number whose associated data file has variable-length records, only the fixed-length portion, defined by dreclen in the original call to CreateIFile(), is actually read into the buffer pointed to by recptr. If you wish to read the entire variable-length record into the same or a different buffer, issue a call to ReReadVRecord() after the call to LastRecord(). Note that ReReadVRecord() requires the size of the buffer area so that it can check if sufficient space is available.

See also

NextRecord(), PreviousRecord(), FirstRecord(), CreateIFile(), ReReadVRecord()

 

LastVRecord

Read the last variable-length data record.

Short Name

LSTVREC()

Type

ISAM function

Declaration

COUNT LastVRecord(FILNO filno, pVOID recptr, pVRLEN plen)

Description

In V12 the file number typedef was formally changed from COUNT, a two-byte value to FILNO, a four-byte value. Refer to this link for compatibility details. Four Byte File Numbering

LastVRecord() is identical to it’s fixed-length counterpart, LastRecord(), except that it reads the last variable-length data record in the data file. If successful, this record becomes the current ISAM record for the associated data file.

plen acts as both an input and output parameter:

  • On input, plen contains the length of the output buffer.
  • On output, the contents of plen is the actual data-record length. If the length of the output buffer is less than the actual record length, a partial read is performed. If an error occurs, plen is unspecified.

Read the function description for LastRecord() for additional important information.

Return

Value Symbolic Constant Explanation
0 NO_ERROR Successful retrieval of current ISAM record.
633 NPLN_ERR plen is NULL.
634 NLEN_ERR plen is negative on input.

See c-tree Error Codes for a complete listing of valid c-tree error values.

See also

LastRecord(), NextVRecord(), PreviousVRecord(), TransformKey()

 

LoadFilter

Called when FairCom DB loads a filter callback DLL. This function initializes resources that are used by the filter callback DLL.

Declaration

NINT LoadFilter(pTEXT libname, ppVOID plibhandle);

Where:

  • libname is the filter callback DLL name that was passed to SetDataFilter().
  • plibhandle is a pointer to an application-defined library handle.

Description

This function is defined in the ctuserx.c module used to build a filter callback function.

LoadFilter() can allocate memory for use by the filter callback function and can return its address in this parameter.

See also

ctfiltercbAddFilter(), EvaluateFilter(), ctfiltercbRemoveFilter(), UnloadFilter(), SetDataFilter()

 

LoadKey

Add key value to index file in presorted order.

Short Name

LOADKEY()

Type

Low-Level index file function

Declaration

COUNT LoadKey(FILNO keyno, pVOID target, LONG recbyt, COUNT typadd)

Description

In V12 the file number typedef was formally changed from COUNT, a two-byte value to FILNO, a four-byte value. Refer to this link for compatibility details. Four Byte File Numbering

LoadKey() inserts the key value pointed to by target and the associated data record position recbyt into index file number keyno. Repeated calls to LoadKey() provide an exceptionally fast method to add key values which have already been sorted. The sorted keys must be added to an empty index or all of the sorted keys must be greater than the existing entries.

Calls to LoadKey() should not be intermixed for different indexes.

typadd signals the beginning, middle and end of the calls to LoadKey() as shown below:

typadd Value Symbolic Constant Sequence
0 FRSADD The first call to LoadKey() for a given index must have typadd set to zero.
1 NXTADD Subsequent calls to LoadKey() must have typadd set to one.
2 BLDADD After all the key values have been added, one additional call is made to LoadKey() with typadd set to two. This last call causes LoadKey() to complete the b-tree structure for the index. target and recbyt should be NULL.

LoadKey() is used by the RebuildIFile() to quickly build the indexes associated with a data file.

Return

Value Symbolic Constant Explanation
0 NO_ERROR Successful key value insertion.
48 FMOD_ERR LoadKey() called for a data file instead of index file.
58 KLOD_ERR LoadKey() called for index without initial FRSADD() call, or an attempt to mix calls for different indexes.
59 KLOR_ERR Key value is out of order and has not been added to index: target is less than previous entry or not greater than existing key values. Identical duplicate keys must be presented in record position order. It is permissible to continue calling LoadKey() after a KLOR_ERR.

See c-tree Error Codes for a complete listing of valid c-tree error values.

Example

TEXT      target[11];

LONG      recbyt,trials;

FILNO     name_key;

COUNT     mode;

FILE      *fp;


trials = 0L;

mode   = FRSADD;

while (fscanf(fp,"%s %ld",target,&recbyt) == 2) {

    if (LoadKey(name_key,target,recbyt,mode))

        break;

    if (trials++)

        mode = NXTADD;

}


if (uerr_cod || LoadKey(name_key,NULL,0L,BLDADD))

    printf("\nerror during LoadKey (%d) on trial #%ld", uerr_cod,trials);

Limitations

LoadKey() does not pad key values. Therefore, if you pass a key value which is not completely specified to its full length, LoadKey() will effectively pad the value with whatever “garbage” follows the key value in memory.

Key values added to an index which supports duplicate keys (keydup = 1 in CreateIndexFile() or CreateIndexMember()) have their last 4 bytes overwritten by the associated data record position. In this way, identical key values become distinguishable.

The recbyt parameter in this function is a 4-byte value capable of addressing at most 4 gigabytes. If your application supports HUGE files (greater than 4 gigabytes), you must use the ctSETHGH() and ctGETHGH() functions to set or get the high-order 4 bytes of the file offset. See Record Offsets Under Huge File Support.

See also

AddKey(), CreateIndexFile(), CreateIndexMember(), ctSETHGH(), ctGETHGH()

 

LockCtData

Lock / unlock data records or tables.

Short Name

LOKREC()

Type

Low-Level data file function

Declaration

COUNT LockCtData(FILNO datno, COUNT lokmod, LONG recbyt)

Description

LockCtData() provides Low-Level lock and unlock control over fixed- and variable-length data records. LockCtData() can also be used with ISAM files to relax the constraints of the “two-phase” protocol described in Multi-User Concepts of the c-tree Programmer’s Reference Guide. Because c-tree is based on write locks, a locked record can be read by other processes as long as they do not attempt their own write lock on the record.

lokmod specifies an action based on the following values:

Value Symbolic Constant Explanation
0 ctFREE An unlock operation.
2 ctENABLE A write lock operation. Only one process may obtain a write lock on a record.
3 ctENABLE_BLK As ctENABLE, but a process unable to get a lock sleeps until the lock is available instead of returning DLOK_ERR. However, if a dead lock is detected, DEAD_ERR is returned.
4 ctREADREC A read lock operation. Read locks may be acquired by any number of users on the same data record at the same time. A read lock ensures that no other user can acquire a write lock on the record.
11 ctREADREC_BLK Same as ctREADREC, but a process unable to get a read lock is “put to sleep” until the lock is available.
18 ctFREE_FILE Frees all locks held on file datno. Set recbyt to 0L for this lokmod. See notes below.
20 ctFREE_ISAM Frees all ISAM level locks on file datno.
21 ctCHKLOK Checks the lock status of recbyt for datno.
512 ctLK_RECR Enable recursive locking.
22 ctFREE_WRTLOKS Unlock write locks for a user for a specified data file.
23 ctLOCK_FILE Table lock request. See Table Lock Mode for LOCKREC.
24 ctUNLOCK_FILE Table unlock request. See Table Lock Mode for LOCKREC.
25 ctFREE_REDLOKS Unlock read locks for a user for a specified data file.
26 ctCHK_ANYLOK Check if the table has any user lock .
27 ctCHKLOK_OTHER Check for lock by other connection/datno
28 ctENABLE_BLKRQS Make a non-blocking write lock request on the specified record. If acquired, the force blocking lock option is set on that lock (making other connections block when requesting the lock even if they are non-blocking lock requests).

Note: Many systems do not support read locks. If read locks are not supported, c-tree returns no error condition (i.e., the read lock is not attempted, but no error is reported). The FairCom Server supports both read and write locks.

recbyt specifies the beginning byte offset for the record lock/unlock operation. c-tree automatically provides the data file record length for the number of bytes to be locked. In the case of a variable-length file, c-tree only applies the lock to the minimum, fixed-length portion of the record. In any event, c-tree always asks for at least a 1-byte lock.

Return

In single-user applications, LockCtData() always returns successfully. In other modes, check uerr_cod for the values in the following table.

Value Symbolic Constant Explanation
0 NO_ERROR Successful lock/unlock operation. Check sysiocod.
41 UDLK_ERR Could not unlock data record. Check sysiocod.
42 DLOK_ERR Record is already locked. Check sysiocod.
48 FMOD_ERR LockCtData() called for an index file.
86 DEAD_ERR Waiting for a write lock would cause a dead lock.
160 ITIM_ERR Multi-user interference: key value changed between index search and subsequent data record read.

A LockCtData() call attempting to unlock a record that is part of transaction returns NO_ERROR (0), but sets sysiocod to UDLK-TRN (-3), indicating the lock will be held until the end of the transaction.

If LockCtData(datno,ctCHKLOK,recbyt) returns NO_ERROR then sysiocod holds the lock status. If sysiocod and uerr_cod are zero, then no lock is held by the calling user. If sysiocod is non-zero and uerr_cod is zero, interpret sysiocod as follows:

  • The low-order byte contains the type of lock: ctENABLE (2) for a write lock, or ctREADREC (4) for a read lock.
  • The high-order byte is composed of one or more of the following attributes bits (left shifted 8 bits):
Value Symbolic Constant Explanation
1 ctISAMLOCK ISAM lock.
4 ctTRANLOCK Lock obtained or touched in transaction.
8 ctTRANOUT Lock obtained outside of transaction.

The higher order byte may contain other attribute bits that may be found in ctport.h where ctISAMLOCK is defined.

For an example of ctCHKLOK, a call of the form LockCtData(datno, ctCHKLOK, recbyt) might return the following values:

Value Symbolic Constant sysicod Explanation
0 NO_ERROR 0x0502 ISAM write lock at recbyt obtained inside transaction.
0 NO_ERROR 0x0000 No lock held at recbyt.

See c-tree Error Codes for a complete listing of valid c-tree error values.

Example

LONG      pntr;

FILNO     datno;

TEXT recbuf[147];


if ((pntr = NewData(datno)) == 0L ||

    fill_buffer(recbuf) != NO_ERROR ||

    WriteData(datno,pntr,recbuf) ||

    LockCtData(datno,ctFREE,pntr))

  printf("\nCould not write new record (%d)",uerr_cod);

/* NewData always acquires a lock on a new record */

Limitations

The recbyt parameter in this function is a 4-byte value capable of addressing at most 4 gigabytes. If your application supports HUGE files (greater than 4 gigabytes), you must use the ctSETHGH() and ctGETHGH() functions to set or get the high-order 4 bytes of the file offset. See also Record Offsets Under Huge File Support.

Locks on a specified record offset

ctCHKLOK_OTHER can be used to check if a lock is held on the specified offset of a data file by either another connection or by the same connection but with a different file number. The definition of "different file number" depends on the MULTIOPN mode that is in effect on the data file whose file number is specified:

  • If using MULTIOPN_NODIFUSR or MULTIOPN_DIFUSR, then a lock that was acquired on the record offset by the calling connection using a different file number (known as a co-file) is treated as though the lock was acquired by another connection.
  • If using MULTIOPN_SAMUSR_1 or MULTIOPN_SAMUSR_M, then a co-file lock is treated as though the lock was acquired by the calling connection.

To use this feature, call LOKREC() with the mode ctCHKLOK_OTHER. As with the ctCHKLOK mode, LOKREC() returns NO_ERROR to indicate success, or a non-zero error code to indicate failure. On success, c-tree's connection-level state variable sysiocod is set to indicate whether or not another connection or co-file has acquired a lock on the specified offset:

  • A sysiocod value of 0 indicates no lock is held by another connection or co-file.
  • A sysiocod value of 2 indicates a write lock is held by another connection or co-file.
  • A sysiocod value of 4 indicates a read lock is held by another connection or co-file.

Table Locking

V11 and later of FairCom DB support file-level locking on c-tree data files, which is known as a "table lock." An application can request a file lock to prevent other connections from reading from and/or writing to the file. Table Locks can be invoked using SQL or using the LockCtData() function. For information, see the sections titled Table Lock Suppor (Table Lock Support, Table Lock)t.

LOKREC() modes to unlock all records in all files of the specified type that are open by the caller

In V11, LOKREC() function's ctFREE_FILE mode now supports options to free ALL locks in ALL specified types of files that a caller has open. To use this feature, call LOKREC() with mode of ctFREE_FILE, recbyt of zero (it is ignored), and set datno to one, or a combination of the following values:

  • ctFREEALL_NOTRAN - free all non-transaction file locks
  • ctFREEALL_NOIICT - free all transaction-controlled file locks without IICT enabled
  • ctFREEALL_IICT - free all transaction-controlled file locks with IICT enabled
  • ctFREEALL_TRAN - free all transaction-controlled file locks
  • ctFREEALL_ALL - free all file locks

Example

Free all locks in all non-transaction files and all transaction-controlled files that are not using IICT that the caller has open.

rc = LOKREC( ctFREEALL_NOTRAN | ctFREEALL_NOIICT,ctFREE_FILE, 0 );

 

See also

LockISAM(), NewData(), NewVData()

 

LockDump

Dump the FairCom Server internal lock table.

Short Name

ctLOKDMP()

Type

Low-Level function

Declaration

COUNT LockDump(COUNT refno, pTEXT dumpname, COUNT mode)   

Description

LockDump() creates a diagnostic dump of the FairCom Server internal lock table. refno indicates whether locks for a particular file or user are to be dumped or whether all locks are to be dumped. mode indicates whether the dump is organized by file or by user number. dumpname is the name of a text file to which the contents of the dump will be appended.

The possible legal combinations of the mode and refno parameters are as follows:

refno mode Interpretation

ctLOKDMPallfiles

ctLOKDMPdatafiles

ctLOKDMPindexfiles

filno

ctLOKDMPfile

Dump all locks by file.

Dump all locks on data files.

Dump all locks on index files.

Dump locks for file filno.

ctLOKDMPallusers

ctLOKDMPcaller

userno

ctLOKDMPuser

Dump all locks by user.

Dump locks for user calling LockDump().

Dump locks for user userno.

In all but one case of the above combinations the caller of LockDump() does not have to have any files open, although it is no problem if the caller does have files open. In the case of ctLOKDMPfile/filno, the caller must have opened a file with file number filno. The userno referenced in the last combination is the thread ID assigned by the FairCom Server. This thread ID is listed when ctadmn is used to list users logged on to the FairCom Server. In addition to dumping the location of the lock and the type of lock, users waiting for a lock are also listed.

Lock Dump Contents

=================================================

All Files Lock Dump at Fri May 04 13:00:12 2007

 

----------------

----------------

SOMEFILE.FCS>>

        0000-013c9a16x T221 write/1: W060 W254 W740 W763 W758

        0000-002916abx T758 write/1: W774 W772 W771 W775 W773 W778 W779 W776 W071

 

cumulative lock attempts: 4002(616)  blocked: 21(0)  dead-lock: 0  denied: 0

 

Current file lock count: 0

----------------

 

cumulative I/O: read ops: 0 bytes: 0    write ops: 5 bytes: 16768

.

.

.

.

List of connected clients

-------------------------

User# 00002: (Node name not set)

User# 00012: (Node name not set)

 

=================================================

Description

In the example above, there are two records with locks held in SOMEFILE.FCS. Each record is listed with it’s locked file offset value, the thread ID of the user holding the lock, the type of lock, and a listing of thread IDs waiting for the record lock to be released. The waiting thread IDs are further delineated with a prefix indicating the type of lock they are waiting to obtain, write (W) or read (R) locks.

Types of Locks

There are several types of record locks that can be reported. The most common of these are:

  • read - A read lock requested and held by a user thread.
  • write/1 - A write lock requested and held by a user thread.
  • write/2 - An internal lock very briefly held by the FairCom Server for files under transaction control. You may occasionally observe these in a system with a high transaction volume, and these can be safely ignored.
  • forcei cmtlok - A very briefly held commit read lock enforced by the FairCom Server. These will only occur when the COMMIT_READ_LOCK option is enabled in the server configuration file. These may be occasionally observed in systems with high transaction volumes.

File Lock Info

  • cumulative lock attempts xxx (yyy) - Total number of file and (header) lock attempts. The header locks are internal FairCom Server locks required for critical updates to the file header.
  • blocked - Total number of locks and (header locks) that were blocked while another lock was held. In a high volume system, some blocked lock attempts are expected.
  • dead-lock - Total of dead-lock conditions reported for this file. These are generally not expected, and error DEAD_ERR (86) is returned to the application caller when this condition is detected. DEAD_ERR is returned when waiting for a write lock would cause a deadlock condition.
  • denied - Total number of locks denied to a caller with error DLOK_ERR (42). A lock is denied if the record is already locked. Note that blocking locks cause the thread to sleep until the lock is available, avoiding the DLOK_ERR.

Cumulative I/O

  • read ops - Total cumulative read operations for this file.
  • bytes - Total cumulative bytes read for this file.
  • write ops - Total cumulative write operations for this file.
  • bytes - Total cumulative bytes written for this file.

List of Connected Clients

A list of all connected clients is appended to the end of the lock dump output. This assists the correlation of known user threads at the application level to threads with potential blocked locks.

  • User# - The thread ID of the user as identified by the FairCom Server
  • Node Name - The node name of the thread as assigned by the application.

Note: On Windows, the list of connected clients includes the IP address in addition to the user name and node name.

Return

The common error code returns are:

Value Symbolic Constant Explanation
0 NO_ERROR Successful lock dump.
12 FNOP_ERR Could not open the dumpname text file.
22 FNUM_ERR mode is ctLOKDMPfile and refno (filno) is out of range.
26 FACS_ERR mode is ctLOKDMPfile and refno (filno) does not reference an opened file for the caller.
116 IMOD_ERR Bad mode or combination of mode and refno.
454 NSUP_ERR The call is not made to a FairCom Server; or the caller is not part of the ADMIN group; or DIAGNOSTICS LOCK_DUMP is not in the configuration file.

See c-tree Error Codes for a complete listing of valid c-tree error values.

Example

COUNT     retval;

TEXT      dumpname[20]="AllUserLocks.dmp"


retval = LockDump(ctLOKDMPallusers, dumpname, ctLOKDMPuser);

switch (retval) {

    case NO_ERROR:

        break;

    case NUSUP_ERR:

        terminate("LockDump not supported .");

    default:

        terminate("LockDump error.");

}

Limitations

Note: Dumping large quantities of locks in a very active system could affect performance.

Because of potential performance impact, a FairCom Server will ONLY support the LockDump() call if either of the following conditions is met:

  • The configuration file, ctsrvr.cfg, contains DIAGNOSTICS LOCK_DUMP.
  • The user calling LockDump() belongs to the ADMIN user group.

Related Topics

 

LockISAM

Enable, free, or suspend data record locks.

Short Name

LKISAM()

Type

ISAM function

Declaration

COUNT LockISAM(COUNT lokmod) 

Description

LockISAM() manages the data record locks during multiple-user ISAM file handling. The LockISAM() options, defined in ctport.h, are:

Value Symbolic Constant Explanation
0 ctFREE Free all data record locks held by this program and cancel the ctENABLE mode.
1 ctRESET Equivalent to first calling LockISAM() in the ctFREE mode followed by a call with the existing mode (or ctENABLE if the current mode was ctFREE).
2 ctENABLE Once LockISAM() is called with lokmod set to ctENABLE, all subsequent data record reads attempt to get a write lock before proceeding. Write locks can be used to prevent more than one process from updating the record at the same time, since only one process may acquire a write lock on a record. Any number of processes may still read the record.
3 ctENABLE_BLK Same as ctENABLE, but a process unable to get a write lock is “put to sleep” until the lock is available.
4 ctREADREC Once LockISAM() is called with lokmod set to ctREADREC, all subsequent data record reads attempt to get a read lock before proceeding. Read locks can be used to prevent another process from acquiring a write lock on the record. Any number of processes may acquire read locks on the same record. Not supported by all platforms. See the note after this table.
5 ctSUSPEND Temporarily suspend the attempt to get a lock on each ISAM record read.
6 ctRESTORE Restore the ctENABLE mode after a previous call to suspend data record locks.
7 ctRESTRED Restore the ctREADREC mode after a previous call to suspend data record locks.
8 ctRESTORE_BLK Restore the ctENABLE_BLK mode after a previous call to suspend data record locks.
11 ctREADREC_BLK Same as ctREADREC, but a process unable to get a read lock is “put to sleep” until the lock is available.
14 ctRESTRED_BLK Restore the ctREADREC_BLK mode after a previous call to suspend data record locks.
128 ctGETLKISAM Queries the current ISAM lock state. Returns the negative of the value of the current ISAM lock state. For example, if locks are enabled, -2 is returned.
512 ctLK_RECR Enables recursive locking.

To ensure multi-user systems make consistent updates, each program should ctENABLE data record locks prior to updating data, and hold these locks until the operations associated with those data records are completed. At that time, a call to LockISAM() with the ctFREE mode cancels all outstanding ISAM locks. Locks created by LockCtData() will NOT be released. ctRESET is used when traversing the data in key sequential order when, after each update, the previous locks should be released and new locks enabled for the next transaction.

ctREADREC signals that the record is under review by one or more readers, and that no update should be performed. If records are read without read, or write, locks, another process may update the record while it is under review. Usually, this is acceptable.

Note: Many systems do not support read locks. If read locks are not supported, c-tree returns a NO_ERROR condition (i.e., the read lock is not attempted, but no error is reported). The FairCom Server DOES support both read and write locks.

Five LockISAM() modes toggle locking, avoiding unnecessary data record locks in the middle of a transaction. These modes are ctSUSPEND, ctRESTORE, ctRESTORE_BLK, ctRESTRED, and ctRESTRED_BLK. Use the ctSUSPEND mode to scan one or more data records which will NOT be updated, or for which READ LOCKS ARE NOT REQUIRED, in the middle of a transaction which has already enabled data record locks. After scanning these records and before returning to your update activities, either:

  • Call LockISAM() with the ctRESTORE mode to restore ctENABLE.
  • Call LockISAM() with the ctRESTORE_BLK mode to restore ctENABLE_BLK.
  • Call LockISAM() with the ctRESTRED mode to restore ctREADREC.
  • Call LockISAM() with the ctRESTRED_BLK mode to restore ctREADREC_BLK.

Return

Value Symbolic Constant Explanation
0 NO_ERROR Successful call to LockISAM().
112 IPND_ERR A call to ctENABLE locks found some pending record locks. This error check is made to ensure that program logic has not started a new transaction before clearing the locks associated with an old transaction. However, it will also cause an error if some locks are acquired and a redundant LockISAM() call in the ctENABLE mode is issued.
113 INOL_ERR No more room left in the internal lock table maintained by LockISAM(). Insufficient system memory.

See c-tree Error Codes for a complete listing of valid c-tree error values.

In the example below, a program performing updates to customer invoices does updates involving price extension computations. To perform the computations, the program searches a separate ISAM file maintaining the prices. Since the program does not modify the price records, it calls LockISAM(ctSUSPEND) before searching the price records, and LockISAM(ctRESTORE) before continuing with the invoice updates.

Example

FILNO     inv_idx, inv_fil, price_idx, price_fil;

TEXT      target[9];


struct invd  {

    TEXT     delflg;

    TEXT     invn[8];

    TEXT     dscrp[60];

    TEXT     part[12];

    float    quant;

    float    price;

    float    exten;

} cur_info;


struct {

    TEXT     pdlflg;

    TEXT     ppart[12];

    float    pprice;

} price_rec;


main() {

    printf("\nEnter invoice number: ");

    scanf("%8s",target);

    if (LockISAM(ctENABLE) ||

       FirstInSet(inv_idx, target, &cur_info,8)) {

        printf("\n\nError starting SCAN with codes %d %d",

               isam_err,isam_fil);

        LockISAM(ctFREE);

        return;

    }

    while (!isam_err) {

        LockISAM(ctSUSPEND);      /* turn off lock acquisition */

        get_price_extension();

        LockISAM(ctRESTORE);      /* restore lock acquisition  */

        ReWriteRecord(inv_fil,&cur_info);

        ResetRecord(inv_fil,SWTCURI);

                                /* reset current ISAM record */

        LockISAM(ctRESET);

        NextInSet(inv_idx,&cur_info);

    }

    LockISAM(ctFREE);

}


void get_price_extension()

{

    if (GetRecord(price_idx,cur_info.part,&price_rec)) {

        printf("\nCould not find part# %s.",cur_info.part);

        return;

    }

    new_info.exten = (cur_info.price = price_rec.pprice) *

                     cur_info.quant;

}

Limitations

The FairCom Server supports both read and write locks on records. When not using the Server for multi-user applications, read locks may show success even if read locks are not implemented.

When using Transaction functions, refer to “Data Integrity” in the c-tree Programmer’s Reference Guide for information on how transaction processing interacts with LockISAM().

See also

LockCtDat()

 

LockList

Retrieve a list of users that own, and are waiting for, a data record lock at a specified byte offset of a data file.

Declaration

NINT LockList(FILNO datno, ctRECPT recbyt, NINT NbrUsers, pLOCKID userlist, pLONG pNbrLockers, pLONG pNbrWaiters);

Short Name

ctLOKLST

Description

In V12 the file number typedef was formally changed from COUNT, a two-byte value to FILNO, a four-byte value. Refer to this link for compatibility details. Four Byte File Numbering

LockList() information is obtained with the following parameters

  • datno is the file number of a data file opened by the calling program.
  • recbyt is the byte offset of a data record. To set the high-order word of the record offset for huge files, call ctSETHGH() immediately before calling LockList().
  • NbrUsers is the number of LOCKID structures in the array pointed to by userlist.
  • userlist may be NULL, but then NbrUsers must be zero.
  • pNbrLockers and pNbrWaiters cannot be NULL. In the event that NbrUsers is smaller than the sum of lockers and waiters, then the list returned in userlist is truncated after NbrUsers entries. LockList() returns NO_ERROR if successful.

LockList() returns the user identification information for lock owners and lock waiters in the userlist array. The lock owners are returned at the beginning of the array, and the lock waiters follow the lock owners in the array. The number of lock owners is returned in the 4-byte integer pointed to by pNbrLockers. For read locks there may be more than one lock owner. For write locks there can only be one lock owner unless strict serialization is in effect. The number of users waiting for the lock is returned in the 4-byte integer pointed to by pNbrWaiters. There are waiters for a lock only when a lock request includes the blocking attribute (e.g., ctENABLE_BLK).

Details

LOCKID is a structure defined in ctport.h that includes the internal thread ID, the login name and the node name:

typedef struct lockid {

    LONG ThrdID;        /* internal thread ID */

    TEXT UserID[32];    /* logon ID [IDZ] */

    TEXT NodeName[32];  /* optional network NodeName IDZ*/

} LOCKID, * pLOCKID;

Because an ISAM operation that fails with a lock denied error DLOK_ERR (42) does not permit the denied locker to determine the record location of the denied lock, LockList() has been enhanced to accept a pseudo datno that indicates the request is for the last denied data record lock by the caller. Use ctLastDeniedLock, defined in ctport.h, for datno and the recbyt will be ignored. Instead, the last denied record lock, across all of the data files opened by the user, if any, will be examined for current lockers and waiters.

The last denied data record lock is not cleared upon the next successful data record lock. So calling LockList(ctLastDeniedLock ...) may be referencing a denied lock from the “distant” past. If the user closes the data file which contains the last denied lock, then the last denied lock will be cleared.

Return

Value Symbolic Constant Explanation
0 NO_ERROR No error occurred.

See c-tree Error Codes for a complete listing of valid c-tree error values.

The following is an example to list all lock owner and “waiters” for a given record offset.

Example

NINT ListLockUsers(NINT datno, ctRECPT recbyt)

{

    NINT i;

    LOCKID list[128];

    LONG lockers, waiters;

    NINT eRet;

    ctSETHGH(0);

    eRet = (NINT)LockList((FILNO)datno, recbyt, 128, &list, &lockers, &waiters);

    if (eRet != NO_ERROR)

    {

        printf("LockList failed with error %d\n", eRet);

        return -1;

    }

    /* list lock owners */

    for (i = 0; i < (NINT)lockers; i++)

        printf("Lock owner %s\n", list[i].UserID);

    /* list lock waiters */

    for (i = (NINT)lockers; i < (NINT)waiters; i++)

        printf("Waiting for lock %s\n", list[i].UserID);

    return (NINT)(lockers + waiters);

}

See also

LockCtData(), LockDump(), LockISAM()

 

NbrOfKeyEntries

Number of entries in index file.

Short Name

IDXENT()

Type

Low-Level index file function

Declaration

LONG NbrOfKeyEntries(FILNO keyno)

Description

In V12 the file number typedef was formally changed from COUNT, a two-byte value to FILNO, a four-byte value. Refer to this link for compatibility details. Four Byte File Numbering

NbrOfKeyEntries() returns the number of entries in index file number keyno.

Note: A huge file may return values greater than 4 GB. This function returns the low-order 4-byte word of the 8-byte number of keys. To get the high-order 4-byte word, call ctGETHGH(). A return of zero is not necessarily an error if there are exactly a multiple 4 GB worth of key values.

Return

If an error occurs or the index file is empty, NbrOfKeyEntries() returns zero. Otherwise, NbrOfKeyEntries() returns the number of entries in the index file. When NbrOfKeyEntries() returns a zero, check uerr_cod: if uerr_cod is non-zero, an error condition was detected; otherwise, no key values are in the index. See c-tree Error Codes in the c-tree Programmer’s Reference Guide for a complete listing of valid c-tree error values.

Example

FILNO     keyno;


scanf("%d",&keyno);

printf("\nThere are %ld entries in index #%d.",

       NbrOfKeyEntries(keyno),keyno);

Limitations

With Standalone Multi-user systems, or when updates are immediately forced to disk, the time to add or delete an index entry can be reduced if the number of index entries is not maintained. By default, c-tree maintains this information. To disable this feature, add #define NO_IDXENT to the bottom of ctoptn.h/ctree.mak. By adding this define, multi-user, non-server applications may experience a performance gain. Therefore, we suggest you only use this function if it is very important to quickly determine the number of index entries.

 

NbrOfKeysInRange

Return the number of active index entries found between two targets .

Short Name

RNGENT()

Type

Low-Level index file function

Declaration

LONG NbrOfKeysInRange(FILNO keyno, pVOID idxval1, pVOID idxval2)

Description

In V12 the file number typedef was formally changed from COUNT, a two-byte value to FILNO, a four-byte value. Refer to this link for compatibility details. Four Byte File Numbering

NbrOfKeysInRange() returns the number of active index entries found between idxval1 and idxval2 for index file keyno. idxval1 and idxval2 must be properly formed keys, as is necessary with any c-tree function that retrieves data using indexes. This function is very helpful for controlling list boxes requiring “thumb operations”.

Note: A huge file may return values greater than 4 GB. This function returns the low-order 4-byte word of the 8-byte number of keys. To get the high-order 4-byte word, call ctGETHGH(). A return of zero is not necessarily an error if there are exactly a multiple 4 GB worth of key values.

Return

On success, NbrOfKeysInRange() returns the number of active index entries found between the given targets. If an error occurs or the index file is empty, NbrOfKeysInRange() returns zero. When NbrOfKeysInRange() returns zero, check uerr_cod: if uerr_cod is non-zero, an error condition was detected; otherwise, no key values are in the index. See c-tree Error Codes in the c-tree Programmer’s Reference Guide for a complete listing of valid c-tree error values.

The following example uses a duplicate allowed index over customer name. The code prompts the user for a beginning name and an ending name for the range. ActiveRange() takes the number of active index entries between the two values entered by the user.

Example

#define maxbuf 40


TEXT      idxval1[maxbuf];             /* input buffer one */

TEXT      idxval2[maxbuf];             /* input buffer two */

LONG      ActiveRange;


memset(idxval1,' ',maxbuf);

printf("\n\tEnter first name for range:");

gets(idxval1);

TransformKey(2,idxval1);      /* properly form index value 1 */


memset(idxval2,' ',maxbuf);

printf("\n\tEnter last name for range:");

gets(idxval2);

TransformKey(2,idxval2);      /* properly form index value 2 */


ActiveRange = NbrOfKeysInRange(2,idxval1,idxval2);

printf("\nRNGENT for Parent Key is %ld uerr_cod = %d", ActiveRange,uerr_cod);

See also

GetORDKey(), NbrOfKeyEntries()

 

NbrOfRecords

Get the number of active records in fixed-length data file.

Short Name

DATENT()

Type

Low-Level fixed-length data file function

Declaration

LONG NbrOfRecords(FILNO datno)

Description

In V12 the file number typedef was formally changed from COUNT, a two-byte value to FILNO, a four-byte value. Refer to this link for compatibility details. Four Byte File Numbering

NbrOfRecords() returns the number of active data records for the fixed length data file designated by datno.

Each time a new record is added to the file, the count of active records is incremented. Each time a record is deleted, the active count is decremented. A record is added by the Low-Level function NewData() or the ISAM function AddRecord(). A record is deleted by the Low-Level function ReleaseData() or the ISAM function DeleteRecord().

Note: A huge file may return values greater than 4 GB. This function returns the low-order 4-byte word of the 8-byte number of keys. To get the high-order 4-byte word, call ctGETHGH(). A return of zero is not necessarily an error if there are exactly a multiple 4 GB worth of key values.

Return

If an error occurs or if there are no active data records, NbrOfRecords() returns a value of zero. Otherwise, NbrOfRecords() returns the number of active fixed data records in the data file. After a call to NbrOfRecords() returns a zero, check the value of uerr_cod: if uerr_cod is non-zero, an error condition was detected; otherwise, no active records are in the file. See c-tree Error Codes in the c-tree Programmer’s Reference Guide for a complete listing of valid c-tree error values.

Example

FILNO   datno;


scanf("%d",&datno);

printf("\nThere are %ld active records in file #%d.",

NbrOfRecords(datno),datno);

See also

NewData(), AddRecord(), DeleteRecord(), ReleaseData()

 

NewData

Get next available fixed-length data record position.

Short Name

NEWREC()

Type

Low-Level data file function

Declaration

LONG NewData(FILNO datno)

Description

In V12 the file number typedef was formally changed from COUNT, a two-byte value to FILNO, a four-byte value. Refer to this link for compatibility details. Four Byte File Numbering

NewData() determines the next available data record position for fixed-length data file datno. If records have been deleted via ReleaseData, they are reused by NewData() before the file size is extended.

Each call to NewData() increments the serial number associated with the file. The ISAM level key segment mode of three (SRLSEG) permits this serial number to be part of a key value to enable chronologically, or reverse chronologically, ordered key values. See ISAM Functions (ISAM Database Technology, /doc/ctreeplus/30841.htm) in the c-tree Programmer’s Reference Guide.

Note: In multi-user systems, NewData() automatically acquires a data record lock on the newly acquired record. This lock should be released using LockCtData() after writing the contents of the new record.

Return

NewData() returns the data record position of the next available record. If an error occurs, NewData() returns a zero and uerr_cod is set to a non-zero value.

Value Symbolic Constant Explanation
0 NO_ERROR Successful lock/unlock operation.
31 DELFLG_ERR First byte of record about to be reused does not equal the delete flag (ff hex).
48 FMOD_ERR NewData() called for an index file.

See c-tree Error Codes for a complete listing of valid c-tree error values.

Example

LONG      recd;

FILNO     dfil;

pTEXT     recptr;


if (recd = NewData(dfil))

    if (WriteData(dfil, recd, recptr) == 0)

        if (LockCtData(dfil, ctFREE, recd) == 0)

            printf("\nSuccessful addition of new record.");

        else

            printf("\nError %d unlocking record.", uerr_cod);

    else

        printf("\nError %d writing record.", uerr_cod);

else

    printf("\nError %d getting new record pointer.", uerr_cod);

Limitations

The recbyt parameter in this function is a 4-byte value capable of addressing at most 4 gigabytes. If your application supports HUGE files (greater than 4 gigabytes), you must use the ctSETHGH() and ctGETHGH() functions to set or get the high-order 4 bytes of the file offset. See also Record Offsets Under Huge File Support.

See also

ReleaseData(), LockCtData(), NewVData()

Data File Layout

 

NewVData

Get next available variable-length data record position.

Short Name

NEWVREC()

Type

Low-Level data file function

Declaration

LONG NewVData(FILNO datno, VRLEN varlen)

Description

In V12 the file number typedef was formally changed from COUNT, a two-byte value to FILNO, a four-byte value. Refer to this link for compatibility details. Four Byte File Numbering

NewVData() determines the next available data record position for variable-length data file datno. If records have been deleted via ReleaseVData(), and if they are large enough, they are reused by NewVData() before the file size is extended.

Each call to NewVData() increments the serial number associated with the file. The ISAM level key segment mode of three (SRLSEG) permits this serial number to be part of a key value to enable chronologically, or reverse chronologically, ordered key values. See ISAM Functions (ISAM Database Technology, /doc/ctreeplus/30841.htm) in the c-tree Programmer’s Reference Guide.

Note: In multi-user systems, NewVData() automatically acquires a data record lock on the newly acquired record. This lock should be released using LockCtData() after writing the contents of the new record.

A 10-byte control block specifying the record length and the length used precedes each variable-length record whether the record is active or not.

Return

NewVData() returns the data record position of the next available record. If an error occurs, NewVData() returns a zero and uerr_cod is set to a non-zero value.

Value Symbolic Constant Explanation
0 NO_ERROR Successful lock/unlock operation.
48 FMOD_ERR NewVData() called for an index file.
147 VDLFLG_ERR The record to be reused is not marked deleted. The file is corrupt and must be rebuilt.

See c-tree Error Codes for a complete listing of valid c-tree error values.

Example

LONG      recd;

FILNO     dfil;

VRLEN     varlen;

pTEXT     recptr;


varlen = strlen(recptr);


if (recd = NewVData(dfil, varlen))

    if (WriteVData(dfil, recd, recptr, varlen) == 0)

        if (LockCtData(dfil, ctFREE, recd) == 0)

            printf("\nSuccessful addition of new record.");

        else

            printf("\nError %d unlocking record.", uerr_cod);

    else

        printf("\nError %d writing record.", uerr_cod);

else

    printf("\nError %d getting new record pointer.", uerr_cod);

Limitations

The recbyt parameter in this function is a 4-byte value capable of addressing at most 4 gigabytes. If your application supports HUGE files (greater than 4 gigabytes), you must use the ctSETHGH() and ctGETHGH() functions to set or get the high-order 4 bytes of the file offset. See also Record Offsets Under Huge File Support.

See also

ctSETHGH(), ctGETHGH(), ReleaseVData(), LockCtData(), NewData()

 

NextCtree

Change to the next registered c-tree instance.

Short Name

NXTCTREE()

Type

Low-Level function

Declaration

pTEXT NextCtree() 

Description

NextCtree() cycles to the next available c-tree instance.

When multiple instances of c-tree are established with RegisterCtree(), control blocks are connected via a link list. The last control block points back to the first. Therefore, a NextCtree() call when the last instance is current results in the first instance becoming current.

Repeated calls to NextCtree() result in continually looping through all c-tree instances. In the example program ctlxmg, the reference name of the first instance is saved to determine the “end-of-instances”.

Return

A successful NextCtree() call returns the pointer to the instance reference name. Each instance reference name, up to 31 bytes and a NULL terminator in length, is originally registered with c-tree using RegisterCtree(). If there are no active instances, a NULL will be returned.

See also

SwitchCtree(), RegisterCtree(), WhichCtree(), GetCtreePointer(), UnRegisterCtree()

 

NextInRange

Read the next data record in a range

Short Name

NXTRNG()

Type

ISAM function

Declaration

COUNT NextInRange(FILNO keyval, pVOID recptr)  

Description

In V12 the file number typedef was formally changed from COUNT, a two-byte value to FILNO, a four-byte value. Refer to this link for compatibility details. Four Byte File Numbering

Read the next data record in a range established by a call to AllocateRange(). If successful, the record becomes the current ISAM record for the associated data file. A successful NextInRange() defines a current key value set, and subsequent calls to NextInRange() or PreviousInRange() will read the other records in the range.

If the data file has variable-length records, only the fixed-length portion of the record is actually read. You can use ReReadVRecord() to retrieve the whole record, including the variable-length portion. You can use NextInVRange() to read the whole variable-length record with one function call.

Return

Value Symbolic Constant Explanation
0 CTDBRET_OK Successful operation.
101 INOT_ERR

Could not satisfy and ISAM search request for index isam_fil. This error frequently indicates "End of File" reached, or "Record not Found."

The following items are the probable causes of the INOT_ERR (101).

  • Passing GetRecord() a duplicate allowed index number (keyno). GetRecord() does not support duplicate allowed indices.
  • Improper target padding. Review “Key Segment Modes” in the c-tree Plus Programmer’s Guide.
  • Not calling TransformKey() on target. Refer to “TransformKey” in the Function Reference Guide
  • Passing ctDeleteSequence() a sequence name that does not exist
  • Improper segment mode. Review “Key Segment Modes” in the c-tree Plus Programmer’s Guide.
  • ctFILBLK() is called and the file is already blocked.

See c-tree Error Codes for a complete listing of valid c-tree error values.

See also

AllocateRange(), EstimateRange(), FirstInRange(), FirstInVRange(), FreeRange(), LastInRange(), LastInVRange(), NextInVRange(), PreviousInRange(), PreviousInVRange()

 

NextInSet

Read the next data record in the set defined by target.

Short Name

NXTSET()

Type

ISAM function

Declaration

COUNT NextInSet(FILNO keyno, pVOID recptr)  

Description

In V12 the file number typedef was formally changed from COUNT, a two-byte value to FILNO, a four-byte value. Refer to this link for compatibility details. Four Byte File Numbering

NextInSet() reads the next data record in the set of data records whose keys match the set created by an earlier set function call. If successful, this record becomes the current ISAM record for the associated data file. If an error occurs or no key value matches the target, the current ISAM record is not updated, and no key value set is defined.

If the data file has variable-length records, only the fixed-length portion, defined by dreclen in the original call to CreateIFile(), is actually read into the buffer pointed to by recptr. If you wish to read the entire variable-length record into the same or a different buffer, issue a call to ReReadVRecord() after the call to NextInSet(). Note that ReReadVRecord() requires the size of the buffer area so that it can check if sufficient space is available.

Notice that you do not directly identify the data file number involved. The ISAM parameter file described in c-tree Error Codes of the c-tree Programmer’s Reference Guide contains the correspondence between the index file number and the associated data file.

Return

Value Symbolic Constant Explanation
0 NO_ERROR Successful retrieval of current ISAM record.
33 DNUL_ERR recptr is NULL. No data file read performed.
42 DLOK_ERR Could not get lock on data record. No data file read performed.
100 ICUR_ERR No current ISAM record.
101 INOT_ERR No active entries.
118 SKEY_ERR Either FirstInSet() has not been called or the last call to FirstInSet() was not for index number keyno.

See c-tree Error Codes for a complete listing of valid c-tree error values.

Example

FILNO        keyfil;

TEXT         target[24],recbuf[320];


printf("\nEnter set value:");

scanf("%23s",target);

FirstInSet(keyfil,target,recbuf,strlen(target));

while (isam_err == NO_ERROR) {

   process_data();

   NextInSet(keyfil,recbuf);

}

Limitations

No check is made to determine if recptr points to a region sufficiently large to accept a data record. If the area is too small, either code or data will be clobbered.

See also

FirstInSet(), PreviousInSet(), LastInSet(), PositionSet(), ChangeSet(), CreateIFile(), ReReadVRecord(), TransformKey()

 

NextInVRange

Read the next data record in a range

Short Name

NXTVRNG()

Type

ISAM function

Declaration

COUNT NextInVRange(FILNO keyval, pVOID recptr, pVRLEN plen)  

Description

In V12 the file number typedef was formally changed from COUNT, a two-byte value to FILNO, a four-byte value. Refer to this link for compatibility details. Four Byte File Numbering

Read the next data record in a range established by a call to AllocateRange(). If successful, the record becomes the current ISAM record for the associated data file. A successful NextInVRange() defines a current key value set, and subsequent calls to NextInVRange() or PreviousInVRange() will read the other records in the range.

plen acts as both an input and output parameter:

  • On input, plen contains the length of the output buffer.
  • On output, the contents of plen is the actual data-record length. If the length of the output buffer is less than the actual record length, a partial read is performed. If an error occurs, plen is unspecified.

Return

Value Symbolic Constant Explanation
0 CTDBRET_OK Successful operation.
101 INOT_ERR

Could not satisfy and ISAM search request for index isam_fil. This error frequently indicates "End of File" reached, or "Record not Found."

The following items are the probable causes of the INOT_ERR (101).

  • Passing GetRecord() a duplicate allowed index number (keyno). GetRecord() does not support duplicate allowed indices.
  • Improper target padding. Review “Key Segment Modes” in the c-tree Plus Programmer’s Guide.
  • Not calling TransformKey() on target. Refer to “TransformKey” in the Function Reference Guide
  • Passing ctDeleteSequence() a sequence name that does not exist
  • Improper segment mode. Review “Key Segment Modes” in the c-tree Plus Programmer’s Guide.
  • ctFILBLK() is called and the file is already blocked.

See c-tree Error Codes for a complete listing of valid c-tree error values.

See also

AllocateRange(), EstimateRange(), FirstInRange(), FirstInVRange(), FreeRange(), LastInRange(), LastInVRange(), NextInRange(), PreviousInRange(), PreviousInVRange()

 

NextInVSet

Read the next variable-length data record in the set defined by target.

Short Name

NXTVSET()

Type

ISAM function

Declaration

COUNT NextInVSet(FILNO filno, pVOID recptr,pVRLEN plen)

Description

In V12 the file number typedef was formally changed from COUNT, a two-byte value to FILNO, a four-byte value. Refer to this link for compatibility details. Four Byte File Numbering

NextInVSet() is identical to it’s fixed-length counterpart, NextInSet(), except that it reads the next variable-length data record in the set defined by target and siglen. If successful, this record becomes the current ISAM record for the associated data file.

plen acts as both an input and output parameter:

  • On input, plen contains the length of the output buffer.
  • On output, the contents of plen is the actual data-record length. If the length of the output buffer is less than the actual record length, a partial read is performed. If an error occurs, plen is unspecified.

Read the function description for NextInSet() for additional important information.

Return

Value Symbolic Constant Explanation
0 NO_ERROR Successful retrieval of current ISAM record.
633 NPLN_ERR plen is NULL.
634 NLEN_ERR plen is negative on input.

See c-tree Error Codes for a complete listing of valid c-tree error values.

See also

NextInSet(), FirstInVSet(), PreviousInVSet(), TransformKey()

 

NextKey

Find the next entry in an index file.

Short Name

NXTKEY()

Type

Low-Level index file function

Declaration

LONG NextKey(FILNO keyno, pVOID idxval) 

Description

In V12 the file number typedef was formally changed from COUNT, a two-byte value to FILNO, a four-byte value. Refer to this link for compatibility details. Four Byte File Numbering

NextKey() searches index file keyno for the next entry in the index. If successful, it copies the index entry into the space pointed to by idxval. NextKey() fails if it is the first index search routine called after the index is opened, or if the entry found before the call to NextKey() is the last entry in the index. Repeated calls to NextKey() move through the index in ascending key value order.

Return

NextKey() returns the data record position associated with the next entry in the index file. If the index is empty or an error is detected, NextKey() returns zero. If NextKey() returns zero, check uerr_cod to see if an error occurred: if uerr_cod is also zero, then the index is empty; otherwise, an error condition was detected. See c-tree Error Codes in the c-tree Programmer’s Reference Guide for a complete listing of valid c-tree error values.

Example

LONG      recbyt;

TEXT      idxval[10];  /* 10 byte key, no duplicates */

FILNO     keyno;


recbyt = FirstKey(keyno,idxval);

while (recbyt) {

    printf("\nIndex Entry %.10s found in record #%ld",

            idxval,recbyt);

    recbyt = NextKey(keyno,idxval);

}

Limitations

No check is made to determine if idxval points to a region sufficiently large to accept a key value from the index file. If the area is too small, either code or data will be clobbered. Use GetCtFileInfo() to determine the key length.

The key value returned by this function will be a properly formatted key value (i.e., HIGH_LOW order, forced to upper case, etc.). The main issue is if binary key values will be displayed on a LOW_HIGH machine, it will be necessary to reverse any numeric segments. Key Segment Modes (Key Segment Modes, /doc/ctreeplus/30863.htm) in the c-tree Programmer’s Reference Guide contains suggestions for manipulating the key value.

The recbyt parameter in this function is a 4-byte value capable of addressing at most 4 gigabytes. If your application supports HUGE files (greater than 4 gigabytes), you must use the ctSETHGH() and ctGETHGH() functions to set or get the high-order 4 bytes of the file offset. See also Record Offsets Under Huge File Support.

See also

GetKey(), GetCtFileInfo(), LastKey(), PreviousKey()

 

NextRecord

Read the next data record.

Short Name

NXTREC()

Type

ISAM function

Declaration

COUNT NextRecord(FILNO filno, pVOID recptr)

Description

In V12 the file number typedef was formally changed from COUNT, a two-byte value to FILNO, a four-byte value. Refer to this link for compatibility details. Four Byte File Numbering

NextRecord() retrieves the next data record found. If filno designates an index file, NextRecord() reads the next data record based on the key sequential order of entries in index file number filno. If filno designates a data file, NextRecord() reads the next active data record, in physical sequential order. If successful, the next record becomes the current ISAM record for the associated data file. If an error occurs or there are no entries, the current ISAM record is not updated.

If filno designates a data file that is a member of a Superfile, NextRecord() may not reliably return the next physical active data record, though it will retrieve a record.

If the data file has variable-length records, only the fixed-length portion, defined by dreclen in the original call to CreateIFile(), is actually read into the buffer pointed to by recptr. If you wish to read the entire variable-length record into the same or a different buffer, issue a call to ReReadVRecord() after the call to NextRecord(). Note that ReReadVRecord() requires the size of the buffer area so that it can check if sufficient space is available.

If NextRecord() is called with an index number, the data file number involved is not directly described. The ISAM parameters described in ISAM Functions (ISAM Database Technology, /doc/ctreeplus/30841.htm) of the c-tree Programmer’s Reference Guide contain the correspondence between the index number and the associated data file.

NextRecord() can move sequentially through a data file based on one index then switch to another index. For example, moving through an inventory file in part number order before switching to part name order by changing the keyno parameter in the NextRecord() call.

As of c-tree V8.14, c-tree sets the current ISAM position after a record is added such that the next or previous record can be read without having to re-read the record just added. Prior to V8.14, the current ISAM position was not set to a newly-added record and an INOT_ERR (101) error would result if you tried to read either the next or previous record.

Return

Value Symbolic Constant Explanation
0 NO_ERROR Successful retrieval of current ISAM record.
33 DNUL_ERR recptr is NULL. No data file read performed.
42 DLOK_ERR Could not get lock on data record. No data file read performed.
100 ICUR_ERR No current ISAM record.
101 INOT_ERR No active entries.

See c-tree Error Codes for a complete listing of valid c-tree error values.

Example

FILNO     acct_idx, test;

TEXT      recbuf[320];


test = FirstRecord(acct_idx,recbuf);

while (test == NO_ERROR) {

    post_interest(recbuf);

    test = NextRecord(acct_idx,recbuf);

}

Limitations

No check is made to determine if recptr points to a region sufficiently large to accept a data record. If the area is too small, either code or data will be clobbered.

See also

FirstRecord(), PreviousRecord(), LastRecord(), CreateIFile(), ReReadVRecord()

 

NextVRecord

Read the next variable-length data record in the data file.

Short Name

NXTVREC()

Type

ISAM function

Declaration

COUNT NextVRecord(FILNO filno, pVOID recptr, pVRLEN plen)

Description

In V12 the file number typedef was formally changed from COUNT, a two-byte value to FILNO, a four-byte value. Refer to this link for compatibility details. Four Byte File Numbering

NextVRecord() is identical to it’s fixed-length counterpart, NextRecord(), except that it reads the next variable-length data record. If successful, this record becomes the current ISAM record for the associated data file.

plen acts as both an input and output parameter:

  • On input, plen contains the length of the output buffer.
  • On output, the contents of plen is the actual data-record length. If the length of the output buffer is less than the actual record length, a partial read is performed. If an error occurs, plen is unspecified.

Read the function description for NextRecord() for additional important information.

As of c-tree V8.14, c-tree sets the current ISAM position after a record is added such that the next or previous record can be read without having to re-read the record just added. Prior to V8.14, the current ISAM position was not set to a newly-added record and an INOT_ERR (101) error would result if you tried to read either the next or previous record.

Return

Value Symbolic Constant Explanation
0 NO_ERROR Successful retrieval of current ISAM record.
633 NPLN_ERR plen is NULL.
634 NLEN_ERR plen is negative on input.

See c-tree Error Codes for a complete listing of valid c-tree error values.

See also

NextRecord(), PreviousVRecord(), TransformKey()

 

OpenCtFile

Open a data file.

Short Name

OPNFIL()

Type

Low-Level file function

Declaration

COUNT OpenCtFile(FILNO filno, cpTEXT filnam, COUNT filmod)

Description

In V12 the file number typedef was formally changed from COUNT, a two-byte value to FILNO, a four-byte value. Refer to this link for compatibility details. Four Byte File Numbering

OpenCtFile() opens the file with the name pointed to by filnam in the mode specified by filmod. Subsequent calls to other Low-Level data file functions use filno to reference this file. filno must be in the range 0 to fils - 1, where fils is the second parameter in the initialization routine InitCTree().

The name referenced by filnam must conform to the operating system environment, and usually can include directory path names and/or disk drive identifiers. The file name should be null terminated. If filnam references an index file with additional index members, OpenCtFile() opens all indexes included in the file. The indexes are assigned file numbers equal to filno in OpenCtFile() plus their member number.

Before a file can be opened, it must be created with either CreateDataFile() or CreateIndexFile().

filmod is limited to the values shown below. Modes not listed below are reserved for creating files, and cannot be changed for an existing file. For example, you need not specify ctFIXED or ctVLENGTH when opening the file, as that is set when the file is created.

ctPERMANENT ctVIRTUAL

ctEXCLUSIVE ctSHARED ctREADFIL

ctCHECKLOCK ctCHECKREAD

ctDUPCHANEL

ctWRITETHRU

ctOPENCRPT

ctCHECKREAD and ctDUPCHANEL are available only with the FairCom Server. See filmod in the index for additional information. Some values must be used exclusively. For instance, you cannot use both ctSHARED and ctEXCLUSIVE.

SUPERFILES: Superfiles and superfile members, discussed in the chapter titled “c-tree Features” of the c-tree Programmer’s Reference Guide, must be handled differently than standard files. Form the name of the member as follows:

<name of superfile>!<name of member>

Note: This function supports EXCLUSIVE file opens. For more information, please refer to Multi-user File Mode.

Return

OpenCtFile() returns an error code from the table below. On a successful open when a differently named file matches the file ID of an open file, the error return will be NO_ERROR(0) but sysiocod will be set to MFID_COD (-586). If the files are detected to actually be different, then the file ID is changed as discussed above and sysiocod is not set to MFID_COD.

Value Symbolic Constant Explanation
0 NO_ERROR Successful open.
12 FNOP_ERR Could not open file. Most likely cause is that file does not exist. Check that filnam points to correct name. Also, FNOP_ERR will be returned in a multi-user system if the file has been locked by another process.
13 FUNK_ERR Type of file is unknown. Header record is clobbered.
14 FCRP_ERR File found corrupt at open.
20 KMIN_ERR Key length too large for node size.
22 FNUM_ERR File number is out of range.
40 KSIZ_ERR sect parameter was larger when index was created.
43 FVER_ERR Current c-tree configuration specified in ctoptn.h is incompatible with file.
45 KLEN_ERR Key length exceeds MAXLEN in ctoptn.h.
46 FUSE_ERR File number is already in use.
775 UNQK_ERR

No UNQKEY support for REPLICATION.

If a Low-Level file open call that requests write access to a c-tree data file fails with this error, it is because the data file has replication enabled. A c-tree data file that has replication enabled can only be opened for write access at the ISAM level. A read-only Low-Level call is allowed: use the ctREADFIL | ctSHARED filemodes when opening the file in addition to the other filemode options that you are using.

See c-tree Error Codes for a complete listing of valid c-tree error values.

Example

FILNO     filno = 0;

COUNT     retval=0;

TEXT      filnam[15] = "sample.dat";

 

if (retval = InitCTree(100, 10, 64))

    printf("\nCould not initialize c-tree connection. Error %d.", retval);

else {

    if (retval = OpenCtFile(filno, filnam, (ctSHARED | ctFIXED)))

        printf("\nCould not open file. Error %d.", retval);

    else if (CloseCtFile(filno, 0))

        printf("\nCould not close file.");

    if (retval = StopUser())

        printf("\nCould not close c-tree connection. Error %d.", retval);

}

Limitations

In Standalone Multi-user implementations of c-tree, the locking routines depend on the operating system, and possibly the compiler. If your operating system or compiler does not support locks, you may have to code your own locking routines. The ctclib.c files provided in each sub-directory contain locking routines and shared file opening facilities for the popular multi-user and network systems.

See also

InitCTree(), CreateDataFile(), CreateIndexFile(), OpenCtFile(), OpenCtFileXtd()

 

OpenCtFileXtd

Extended data or index file open.

Short Name

OPNFILX()

Type

Extended Low-Level file function

Declaration

COUNT OpenCtFileXtd(FILNO filno, cpTEXT filnam, COUNT filmod, cpTEXT fileword)

Description

In V12 the file number typedef was formally changed from COUNT, a two-byte value to FILNO, a four-byte value. Refer to this link for compatibility details. Four Byte File Numbering

OpenCtFileXtd() is a variation of OpenCtFile() that permits the use of the FairCom Server’s security system. This section expands on the description of OpenCtFile().

fileword is an optional file password. Set fileword to NULL if there is no password for this file. If a password is established, every user will need to use the password to be able to open the file. For more information on file passwords, review Security and Encryption (File Security and Encryption, /doc/ctreeplus/FileSecurityandEncryption.htm) in the c-tree Programmer’s Reference Guide.

Note: This function supports EXCLUSIVE file opens. For more information, please refer to Multi-user File Mode.

Return

The following error codes may be seen in addition to those for OpenCtFile():

Value Symbolic Constant Explanation
456 SACS_ERR This user does not belong to a group that can access this file.
457 SPWD_ERR Invalid password.
775 UNQK_ERR

No UNQKEY support for REPLICATION.

If a Low-Level file open call that requests write access to a c-tree data file fails with this error, it is because the data file has replication enabled. A c-tree data file that has replication enabled can only be opened for write access at the ISAM level. A read-only Low-Level call is allowed: use the ctREADFIL | ctSHARED filemodes when opening the file in addition to the other filemode options that you are using.

See c-tree Error Codes for a complete listing of valid c-tree error values.

See also

InitCTree(), CreateIndexFile(), OpenCtFile()

 

OpenFileWithResource

Incremental ISAM open, based on the IFIL Resource.

Short Name

OPNRFIL()

Type

ISAM function

Declaration

COUNT OpenFileWithResource(FILNO filno, cpTEXT filnam, COUNT filmod)  

Description

In V12 the file number typedef was formally changed from COUNT, a two-byte value to FILNO, a four-byte value. Refer to this link for compatibility details. Four Byte File Numbering

OpenFileWithResource() opens the data file with the name pointed to by filnam and optional index files referenced by the IFIL resource information stored in that file. This resource was automatically added to the file when the file was created with CreateIFile() unless Resources have been disabled for this file. All subsequent references to the file are made via the filno value. filno must be less than fils - 1, where fils is the second parameter in the initialization routine InitISAM().

The name referenced by filnam must conform to the operating system environment, and usually can include directory path names and/or disk drive identifiers. If you are trying to open a file in a subdirectory of the data folder, your path must start with "." as in ./subdir/MyFile.dat.

If OpenFileWithResource() is called with a different path than the original IFIL definition holds, an attempt is made to automatically update alternative index names with the same path modification. The file name should be null terminated. If filnam references an index file with additional index members, OpenFileWithResource() opens all indexes included in the file.

Consecutive file numbers are assigned to the data file and any associated indexes. If filno is less than zero, c-tree finds the first available block of consecutive file numbers that can accommodate the data file and its indexes. If a block of numbers is found, the first number in the block is assigned to the data file and returned. If filno is greater than or equal to zero, filno is assigned to the data file and returned provided enough consecutive file numbers are available.

filmod is limited to the values shown below. Modes not listed are reserved for file creation and cannot change for an existing file. For example, ctFIXED or ctVLENGTH are not specified when opening the file, as they are set when the file is created.

ctPERMANENT ctVIRTUAL

ctEXCLUSIVE ctSHARED ctREADFIL

ctCHECKLOCK ctCHECKREAD

ctDUPCHANEL

ctWRITETHRU

ctOPENCRPT

ctCHECKREAD and ctDUPCHANEL are available only with the FairCom Server. See filmod in the index for additional information. Some values must be used exclusively. For instance, you cannot use both ctSHARED and ctEXCLUSIVE.

Note: This function supports EXCLUSIVE file opens. For more information, please refer to Multi-user File Mode.

Return

OpenFileWithResource() returns the file number assigned to the data file. If an error occurs, the function returns a -1 and isam_err contains an error code. On a successful open when a differently named file matches the file ID of an open file, the error return will be NO_ERROR (0) but sysiocod will be set to MFID_COD (-586). If the files are detected to actually be different, then the file ID is changed as discussed above and sysiocod is not set to MFID_COD.

Value Symbolic Constant Explanation
0 NO_ERROR Successful open.
12 FNOP_ERR Could not open file. Most likely cause is that file does not exist. Check that filnam points to correct name. FNOP_ERR will be returned in a multi-user system if the file has been locked by another process. Check isam_fil for the specific file number.
14 FCRP_ERR File found corrupt at open.
20 KMIN_ERR Key length too large for node size.
22 FNUM_ERR File number is out of range.
45 KLEN_ERR Key length exceeds MAXLEN in ctoptn.h.
46 FUSE_ERR File number is already in use.
107 IDRK_ERR Too many index files for one data file. Increase MAX_DAT_KEY parameter in ctoptn.h.
109 IKRS_ERR Too many key segments. Increase MAX_KEY_SEG parameter in ctoptn.h.

See c-tree Error Codes for a complete listing of valid c-tree error values.

Example

FILNO     filno = 0;

COUNT     retval=0;

TEXT      filnam[15] = "sample.dat";


if (retval = InitISAM(6,7,4))

    printf("\nCould not initialize. Error %d.", retval);

else {

    if (OpenFileWithResource(filno, filnam, ctSHARED) < 0)

        printf("\nCould not open file (%d,%d).", isam_err, sysiocod);

    else if (CloseRFile(filno))

        printf("\nCould not close file (%d,%d).", isam_err, sysiocod);


    if (CloseISAM())

        printf("\nCould not close ISAM.");

}

Limitations

The data file must contain a resource record with the appropriate Incremental ISAM Structures (IFIL, etc.). CreateIFile() inserts a resource record and adds Incremental ISAM Structures. However, if the file was created without resource records, by either removing #define RESOURCE from ctoptn.h or by using ctDISABLERES as a file mode, resources can be enabled dynamically using EnableCtResource(). The Incremental ISAM Structures can be inserted by calling PutIFile().

See also

EnableCtResource(), PutIFile(), OpenIFile(), InitISAM(), CreateIFile(), CloseISAM(), OpenFileWithResourceXtd() and ISAM Functions (ISAM Database Technology, /doc/ctreeplus/30841.htm) in the c-tree Programmer’s Reference Guide describing the ISAM parameters.

 

OpenFileWithResourceXtd

Incremental ISAM open, based on the IFIL Resource (extended).

Short Name

OPNRFILX()

Type

Extended ISAM function

Declaration

COUNT OpenFileWithResourceXtd(FILNO filno, cpTEXT filnam,

                              COUNT filmod, cpTEXT fileword)

Description

In V12 the file number typedef was formally changed from COUNT, a two-byte value to FILNO, a four-byte value. Refer to this link for compatibility details. Four Byte File Numbering

OpenFileWithResourceXtd() is a variation of OpenFileWithResource() that permits the use of the FairCom Server’s security system. This section expands on the description of OpenFileWithResource().

fileword is an optional file password. Set fileword to NULL if there is no password for this file. If a password is established, every user will need to use the password to be able to open the file. For more information on file passwords, review Security and Encryption (File Security and Encryption, /doc/ctreeplus/FileSecurityandEncryption.htm) in the c-tree Programmer’s Reference Guide.

Note: This function supports EXCLUSIVE file opens. For more information, please refer to Multi-user File Mode.

Return

OpenFileWithResourceXtd() returns the file number assigned to the data file. If an error occurs, the function returns a -1 and isam_err contains an error code. The following error codes may be seen in addition to those for OpenFileWithResource():

Value Symbolic Constant Explanation
456 SACS_ERR This user does not belong to a group that can access this file.
457 SPWD_ERR Invalid password.

See c-tree Error Codes for a complete listing of valid c-tree error values.

Return Relative File Number

In V11.5 and later, the OPNRFILX() function has been modified so that, when it is called with a negative data file number, if the open fails, isam_fil is returned as a relative file number:

isam_fil = 0 indicates the data file open failed.
isam_fil = 1 indicates the first index open failed, etc.

Note: This feature is a Compatibility Change.

Prior to this change, OPNRFILX() set isam_fil to the file number that was not possible to open. However, it did not return useful information when it was called with a negative data file number, such as OPNRFIL(-1).

See also

InitISAM(), CreateIFile(), OpenFileWithResource()

 

OpenIFile

Incremental ISAM open.

Short Name

OPNIFIL()

Type

ISAM function

Declaration

COUNT OpenIFile(pIFIL ifilptr) 

Description

OpenIFile() opens the data file and (optional) index file referenced by the IFIL structure pointed to by ifilptr. The file name pointed to by the IFIL structure, ifilptr->pfilnam, should NOT include an extension: .dat and .idx are automatically appended to the file name for the data file and index file, respectively. The extended version of this function, OpenIFileXtd(), can change the file extensions at run time.

If you desire the files to be opened in directories that are not specified until run-time, then ifilptr->pfilnam should not be finalized until run-time.

Consecutive file numbers are assigned to the data file and any (optional) indexes associated with the data file. The IFIL structure contains two file numbers: a permanent file number (dfilno), and a temporary file number (tfilno). If dfilno is less than zero, c-tree finds the first available block of sufficient consecutive file numbers. If such a block of numbers is found, then the first number in the block is assigned to the data file and to tfilno. If dfilno is greater than or equal to zero, then dfilno is assigned to the data file and to tfilno.

Note: This function supports EXCLUSIVE file opens. For more information, please refer to Multi-user File Mode.

Return

Upon successful open, ifilptr->tfilno contains the file number assigned to the data file; and the associated indexes are assigned consecutive index numbers starting one (1) greater than the data file number.

On a successful open when a differently named file matches the file ID of an open file, the error return will be NO_ERROR (0) but sysiocod will be set to MFID_COD (-586). If the files are detected to actually be different, then the file ID is changed as discussed above and sysiocod is not set to MFID_COD.

Value Symbolic Constant Explanation
0 NO_ERROR Successful open of ISAM files.
12 FNOP_ERR Could not open file(s). Check isam_fil for the specific file number.
14 FCRP_ERR File appears corrupt at open: rebuild.
20 KMIN_ERR Key length too large for node size.
22 FNUM_ERR File number is out of range.
45 KLEN_ERR Key length exceeds MAXLEN parameter in ctoptn.h.
46 FUSE_ERR File number is already in use or no available block of numbers.
47 FINT_ERR c-tree has not been initialized. Call InitISAM() before the first call to OpenIFile().
107 IDRK_ERR Too many index files for one data file. Increase MAX_DAT_KEY parameter in ctoptn.h or keyword in ctsrvr.cfg.
109 IKRS_ERR Too many key segments. Increase MAX_KEY_SEG parameter in ctoptn.h.
115 ISLN_ERR Key segments do not equal key length.

See c-tree Error Codes for a complete listing of valid c-tree error values.

Example

extern IFIL     myfile;

       COUNT    retval;


if (retval = InitISAM(6,7,4))

    printf("\nCould not close files. Error %d.", retval);

else {

    if (CreateIFile(&myfile))

        printf( "\nCould not create %s (%d,%d)\n", 

               myfile.pfilnam, isam_err, isam_fil );

    else if (CloseIFile(&myfile))

        printf("\nCould not close files.");

   

    if (OpenIFile(&myfile))

        printf("\nCould not open files.");

    else if (CloseIFile(&myfile))

        printf("\nCould not close files.");


    if (CloseISAM())

        printf("\nCould not close ISAM.");

}

Limitations

The index files will be numbered consecutively following the data file. See “File numbering” in the index for additional information.

See also

InitISAM(), CreateIFile(), CloseISAM(), OpenIFileXtd(), OpenFileWithResource(), GetIFile() and ISAM Functions (ISAM Database Technology, /doc/ctreeplus/30841.htm) in the c-tree Programmer’s Reference Guide, which describes the ISAM parameters.

 

OpenIFileXtd

Extended Incremental ISAM open.

Short Name

OPNIFILX()

Type

Extended ISAM function

Declaration

COUNT OpenIFileXtd(pIFIL ifilptr, cpTEXT dataextn,

                   cpTEXT indxextn, cpTEXT fileword)

Description

OpenIFileXtd() is a variation of OpenIFile() that permits the use of the FairCom Server’s security system. This section expands on the description of OpenIFile().

dataextn and indxextn point to buffers specifying the data and index file name extensions, respectively. The extensions are 8-byte ASCIIZ (NULL terminated ASCII) strings. If the pointers are NULL, the default extension will be used: .dat for data files and .idx for index files. For files with no extension, pass a pointer to a buffer that contains only blanks terminated by a NULL character.

fileword is an optional file password. If fileword is null then there will be no password for this file. If a password is established, every user will need to use the password to be able to open the file.

For more information on permission masks, group id’s, and file passwords, review Security and Encryption (File Security and Encryption, /doc/ctreeplus/FileSecurityandEncryption.htm) in the c-tree Programmer’s Reference Guide.

Note: This function supports EXCLUSIVE file opens. For more information, please refer to Multi-user File Mode.

Return

The following error codes may be seen in addition to those for OpenIFile():

Value Symbolic Constant Explanation
456 SACS_ERR User is not a member of a group with access to this file.
457 SPWD_ERR Invalid password.

See c-tree Error Codes for a complete listing of valid c-tree error values.

See also

InitISAM(), OpenIFile(), CloseISAM()

 

OpenISAM

Open all the ISAM files.

Short Name

OPNISAM()

Type

ISAM function

Declaration

COUNT OpenISAM(pTEXT filnam) 

Description

OpenISAM() opens the parameter file, whose name is pointed to by filnam, and opens the data and index files specified in the parameter file. Application programs using the ISAM level functions must make a call to InitISAM() or OpenISAM() before any other c-tree functions are used. If any one of these three functions has been called, then CloseISAM() must be called before anyone of them can be invoked again. In part, this implies that no more than one ISAM parameter file may be active at one time. However, the incremental ISAM functions allow for more flexibility in file manipulations and are highly recommended.

Using virtual files, the parameter file may contain more files than available file descriptors. c-tree automatically manages the open and close of virtual files.

Although it is not recommended, it is possible to use incremental ISAM file opens and opens along with a parameter file. Increase the value of the second parameter in the parameter file, (idxs), by the total number of files used by the incremental routines. For example, if the incremental routines open two additional data files, each with five indexes, then the idxs parameter in the ISAM parameter file should be increased by 12.

Note: This function supports EXCLUSIVE file opens. For more information, please refer to Multi-user File Mode.

Return

OpenISAM() returns an error code from the table below. On a successful open when a differently named file matches the file ID of an open file, the error return will be NO_ERROR (0) but sysiocod will be set to MFID_COD (-586). If the files are detected to actually be different, then the file ID is changed as discussed above and sysiocod is not set to MFID_COD.

Value Symbolic Constant Explanation
0 NO_ERROR Successful open of ISAM files.
10 SPAC_ERR Not enough space for file structures and buffers.
11 SPRM_ERR Illegal parameters in first record of parameter file.
12 FNOP_ERR Could not open file. Check isam_fil for the specific file number.
13 FUNK_ERR Unknown file type.
14 FCRP_ERR File found corrupt at open.
20 KMIN_ERR Key length too large for node size.
21 DREC_ERR Record length is too small. File is not opened.
43 FVER_ERR Current c-tree configuration specified in ctoptn.h is incompatible with existing file.
45 KLEN_ERR Key length exceeds MAXLEN parameter in ctopt2.h.
102 INOD_ERR Could not open ISAM parameter file.
103 IGIN_ERR Could not read first record of ISAM parameter file.
104 IFIL_ERR Too many files specified. Increase ctMAXFIL in ctoptn.h and rebuild library.
106 IDRI_ERR Could not read data file description record in parameter file.
107 IDRK_ERR Too many index files for one data file. Increase MAX_DAT_KEY parameter in ctoptn.h, (and rebuild the library), or increase the ctsrvr.cfg keyword.
108 IMKY_ERR keyno for index member is out of sequence. keyno must equal the host index keyno plus the member number.
109 IKRS_ERR Too many key segments. Increase MAX_KEY_SEG parameter in ctoptn.h.
110 ISRC_ERR Could not read key segment description record in parameter file.
111 IKRI_ERR Could not read index file description record in parameter file.
115 ISLN_ERR Key segments do not equal key length.
117 IMRI_ERR Could not read index member record.
125 IINT_ERR c-tree already initialized. Call CloseISAM() before recalling OpenISAM().
182 IKSR_ERR No room for r-tree temporary files. Increase ctMAXFIL in ctoptn.h and rebuild library.

See c-tree Error Codes for a complete listing of valid c-tree error values.

Example

TEXT      isam_par[64];


printf("\nEnter ISAM parameter file name: ");

scanf("%63s",isam_par);

if (OpenISAM(isam_par))

    printf("\nCould not open ISAM.");

else   

    ProcessData()


if (CloseISAM())

    printf("\nCould not close ISAM.");

Limitations

It is not possible to open some of the files specified in the parameter file and create others. They must all be created by CreateISAM(). However, the incremental ISAM functions permit on the fly opening and closing of ISAM files. If you are adding a new index file to an established set of ISAM files, you should:

  • Update the parameter file to include the new index.
  • Use the rebuild utility to create and build the new index file. Respond no when asked to force rebuild.
  • Call OpenISAM() to actually use the files.

See also

CloseISAM(), InitISAM(), CreateISAM(), CreateIFile(), OpenIFile(), OpenISAMXtd() and ISAM Parameters in the c-tree Programmer’s Reference Guide, which describes the parameter file contents.

 

OpenISAMContext

Opens (creates) an ISAM context.

Short Name

OPNICON()

Type

ISAM function

Declaration

COUNT OpenISAMContext(FILNO datno, FILNO keyno, COUNT contextid)

Description

In V12 the file number typedef was formally changed from COUNT, a two-byte value to FILNO, a four-byte value. Refer to this link for compatibility details. Four Byte File Numbering

OpenISAMContext() returns a 2-byte integer (COUNT) which serves as the context ID. The context is maintained for the data file specified by datno. keyno is either a key for the data file or -1. If keyno is -1, then the context saves key images (values) for all the indexes associated with datno. If a specific key is specified with keyno, then the context only maintains the key value for the given index thereby conserving memory. Opening a context actually creates the context and then selects the context as the current context for the specified data file.

If contextid is passed in as “-1”, then the next available ID is assigned. If not passed as “-1”, then the value passed is taken as the desired context ID. Note that the context IDs do not have to be consecutive numbers, and both positive and negative values are allowed. However, -1 is not a legitimate value for a context ID. It is used to signify that c-tree should automatically assign the context number.

Note: FairCom DB has an internal hard limit of 65534 contexts.

To speed the location of contexts, a simple hashing scheme is used. The number of hash bins defaults to six (6) for each user. If a large number of contexts are to be maintained, then this default can be overridden as follows:

  1. Server (non-BOUND) Applications: the configuration file can contain the keyword value pair:

   CONTEXT_HASH    <# of hash bins>

  1. Bound Applications: Set the global unsigned integer ctconbins to a non-zero value before a call to initialize c-tree.

   UINT     ctconbins=12;

Note: This function supports EXCLUSIVE file opens. For more information, please refer to Multi-user File Mode.

Return

If an error occurs, OpenISAMContext() returns -1 and isam_err is set; otherwise, OpenISAMContext() returns the context ID. If datno that does not correspond to an open data file, or keyno, (when not -1), does not correspond to an open index file associated with datno, isam_err is set to FMOD_ERR (48). If no IDs are available, or if the ID is already in use, isam_err is set to ECON_ERR (592).

Value Symbolic Constant Explanation
0 NO_ERROR Successful open (creation).
48 FMOD_ERR Operation incompatible with type of file.
83 IALC_ERR No memory is available.
592 ECON_ERR Context ID exists.

See c-tree Error Codes for a complete listing of valid c-tree error values.

Example

FILNO     datno1,datno2;              /* data file numbers   */

pVOID     bufptr1,bufptr2;            /* data buffer pointer */

COUNT     contextID_1,contextID_2,contextID_3,contextID_4; /* context ID's     */


OpenFileWithResource(datno1,"data1",ctSHARED);

OpenFileWithResource(datno2,"data2",ctSHARED);

FirstRecord(datno1 + 1,bufptr1);        /* move to first record for       *

                                         * datano1 using first key        */

contextID_1 = OpenISAMContext(datno1,-1,-1);

                    /* establish first context for datno1 at first record.  *

                     * keyno == -1 saves all key positions.                 */

FirstRecord(datno2 + 3,bufptr2);        /* move to first record for       *

                                         * datano2 using third key.       */

contextID_2 = OpenISAMContext(datno2, datno2 + 3,-1);

                        /* establish first context for datno2 at first record.  *

                         * keyno != -1 saves only key value for third key.      */

NextRecord(datno1 + 1,bufptr1);

NextRecord(datno1 + 1,bufptr1);          /* position datno1 at third       *

                                          * record by first key.           */

contextID_3 = OpenISAMContext(datno1,-1,-1);

       /* Third record by first key becomes the saved position for contextID_1 *

        * and contextID_3 becomes the active context for datno1.               */

NextRecord(datno1 + 2,bufptr1);  /* move from third record by first key,       *

                                  * to the  next record using the second key.  *

                                  * Call this record 4' (4 prime).             */

ChangeISAMContext(contextID_1); /* save record 4' as contextID_3. Make the     *

                                 * 3rd record the current position for datno1, *

                                 * and contextID_1 becomes the active  context *

                                 * for datno1. contextID_2 is still the active *

                                 * context for datno2.                         */

NextRecord(datno1 + 1,bufptr1); /* move to the 4th record by key 1 for datno1.*/

contextID_4 = OpenISAMContext(datno2,datno2 + 3,-1);

         /* saves 1st record by 3rd key as the contents of contextID_2 and     *

          * makes  contextID_4 the active context for datno2. Note that only   *

          * the third key image is stored for contextID_2 and contextID_4.     *

          * Therefore, when  selecting one of these contexts, it will not make *

          * sense to continue  traversing the file with a different key.       */  

See also

CloseISAMContext(), ChangeISAMContext()

 

OpenISAMXtd

Open all the ISAM files (extended version).

Short Name

OPNISAMX()

Type

Extended ISAM function

Declaration

COUNT OpenISAMXtd(pTEXT filnam, COUNT userprof, pTEXT userid,

                pTEXT userword, pTEXT servname, pTEXT fileword)

Description

OpenISAMXtd() is a variation of OpenISAM() that permits the use of the FairCom Server’s security system. This section expands on the description of OpenISAM().

  • userprof is the user profile mask. It accepts the following values:
    • USERPRF_CLRCHK
    • USERPRF_LOCLIB
    • USERPRF_NDATA
    • USERPRF_NTKEY
    • USERPRF_PTHTMP
    • USERPRF_SAVENV
    • To use more than one value, OR the values together. Leave userprof set to zero to accept the defaults.
  • userid is a pointer to a buffer containing the user ID. If userid is null, the user is assigned the ID of GUEST
  • userword is a pointer to a buffer containing the user password.
  • servname is a pointer to a Server name if you are going to use a Server name other than the default.
  • fileword is an optional file password. If fileword is NULL then there will be no password for this file. If a password is established, every user will need to use the password to be able to open the file.

For more information on user id’s, user passwords, server names, and file passwords, review Security and Encryption (File Security and Encryption, /doc/ctreeplus/FileSecurityandEncryption.htm) in the c-tree Programmer’s Reference Guide.

Note: This function supports EXCLUSIVE file opens. For more information, please refer to Multi-user File Mode.

Return

The following error codes may be seen in addition to those for OpenISAM():

Value Symbolic Constant Explanation
453 NSRV_ERR Invalid FairCom Server name.
456 SACS_ERR User is not a member of a group with access to this file.
457 SPWD_ERR Invalid password.
1215 AUTHENTICATION_ERR Invalid authentication information.

See c-tree Error Codes for a complete listing of valid c-tree error values.

See also

InitISAM(), CreateISAM(), OpenISAM(), CloseISAM(), TransformKey(), GetCtTempFileName(), Begin()

 

PartitionAdmin

Partition file administration function.

Short Name

PTADMIN()

Type

Utility Function

Declaration

COUNT PartitionAdmin(FILNO datno, pVOID partdesc, LONG prawno, COUNT ptmode) 

Description

In V12 the file number typedef was formally changed from COUNT, a two-byte value to FILNO, a four-byte value. Refer to this link for compatibility details. Four Byte File Numbering

PartitionAdmin() manages the partitions for datno, the file number for the host data file.

  • partdesc may be either a pointer to a partition member data file name, a pointer to a key value (already transformed) representative of a partition member, or NULL.
  • prawno may either be a “raw” partition number or its value is ignored.
  • ptmode controls how to interpret partdesc and prawno as well as what action PartitionAdmin() should perform. ptmode is formed by OR-ing together the appropriate bit values from this list defined in ctport.h:

 

Value Symbolic Constant Explanation
     
Partition Identifier
0x0001 ptADMINname partdesc is a file name (ignore prawno)
0x0002 ptADMINkey partdesc is a key value (ignore prawno)
0x0004 ptADMINraw use prawno (ignore partdesc)
Operation Code
0x0010 ptADMINpurge remove partition(s)
0x0020 ptADMINadd add partition(s)
0x0040 ptADMINarchive archive partition(s)
0x0080 ptADMINbase modify lower limit on prawno
0x0100 ptADMINnumber* modify limit on number of partitions
0x0200 ptADMINreuse* reuse purged member raw #
0x0400 ptADMINactivate activate archived member(s)
0x0800 ptADMINstatus return member status in sysiocod
0x1000 ptADMINmulti* purge, archive, etc. multiple partitions
0x2000 ptADMINrule partdesc contains rule definition
0x4000 ptADMINrebuild rebuild a specific member

* The ptADMINnumber, ptADMINreuse, and ptADMINmulti options have NOT been implemented.

Note: All calls to PartitionAdmin() must specify exactly one way in which the partition will be identified (ptADMINname or ptADMINkey or ptADMINraw) and exactly one operation (for example., ptADMINpurge). If the ptmode parameter is not correctly formed, PTADMIN() will return BMOD_ERR (446, Bad mode: parameter out of range).

ptADMINstatus Option

If the ptADMINstatus option is used, then PartitionAdmin() returns either an error code (such as PLOW_ERR, 712, partition number is out of range - low) or NO_ERROR. If NO_ERROR is returned, then sysiocod contains the member status code from this list:

Value Symbolic Constant Explanation
0 pmSTATUSnone member does not exist
1 pmSTATUSexst member active
2 pmSTATUSopnd member active and physically opened
3 pmSTATUSarhv member archived
4 pmSTATUSpurg member purged
19 pmSTATUSparc member archive pending
20 pmSTATUSppnd member purge pending

There is a subtlety here concerning a return of pmSTATUSnone in sysiocod, and some possible error codes returned by PTADMIN(). For example, a NO_ERROR return from PTADMIN(.........,ptADMINstatus) and sysiocod of pmSTATUSnone means that the partition number is in the current valid range, but that no such partition member has been created. A PLOW_ERR (712, out of range - low) return means that the partition number is out of the current valid range (whether or not such a partition was ever created).

A partition that is not in use or a partition that has been opened by the host (that is, not explicitly by the application), and which is not in use by another user, can be archived or purged.

Base Partition Number

The record add and update functions attempt to increase the base partition number of the partitioned file to the first current active partition number if one exists, or to the partition number that will hold the newly-added or updated record if no current active partition exists.

Return

Value Symbolic Constant Explanation
0 NO_ERROR Successful function
712 PLOW_ERR Partition number out of range - low
713 PHST_ERR File is not partition host
714 PMBR_ERR File is not partition member
715 PNOT_ERR Raw partition does not exist
716 PXPR_ERR Bad value for partition key
717 POVR_ERR Could not overload partition number
718 PUSD_ERR Partition member in use
719 PPND_ERR Partition member pending purge
720 PPRG_ERR Partition member purged
721 PARC_ERR Partition member archived
722 PLST_ERR Bad partition host list
723 PTRY_ERR Must retry operation
724 PCRP_ERR Bad current ISAM position for host
725 PVRN_ERR Partition resource version error
-726 PPRG_COD Duplicate error caused by purged part
727 PFMD_ERR Bad partition file mode settings
728 PSUP_ERR Attempt to use partitioned file without partition support
729 PUNQ_ERR Purged unique global keys encountered
730 PHGH_ERR Partition number out of range - high
731 PRIK_ERR Illegal operation with partition key

See c-tree Error Codes for a complete listing of valid c-tree error values.

Limitations

  • A raw partition number must be 1 or greater.
  • Encryption is not supported for partitioned files.
  • To support transaction processing, a partitioned file must also support transaction-dependent file creation (TRANDEP).

 

Perform

Evaluate FairCom Server performance.

Short Name

PERFORM()

Type

Low-Level function

Declaration

COUNT Perform(COUNT status)  

Description

Perform() collects statistics on the number of times each c-tree function is called between PERFORM_ON and PERFORM_OFF. status is used to begin and end the evaluation process and to display the information collected. The values that can be used for status are:

Symbolic Constant Explanation
PERFORM_ON Begin collecting performance statistics.
PERFORM_OFF End the performance session and calculate the elapse time.
PERFORM_DUMP Print the performance statistics to the standard error device.

Return

Always returns zero (NO_ERROR).

Example

Perform(PERFORM_ON);


GetRecord(...);

ReWriteRecord(...);

NextRecord(...);


/* additional c-tree functions */


Perform(PERFORM_OFF);


Perform(PERFORM_DUMP);

 

PermIIndex

Permanent Incremental Index creation.

Short Name

PRMIIDX()

Type

ISAM function

Declaration

COUNT PermIIndex(pIFIL ifilptr) 

Description

In a single call to PermIIndex(), your application program will:

  • Add one or more additional indexes to an existing Incremental ISAM definition.
  • Automatically load the indexes from the existing data (optional).
  • Reference the new indexes with the standard ISAM level calls (e.g., the next AddRecord() call updates the new indexes along with the original indexes).
  • If resources are enabled, automatically update the stored file definition to include the new indexes.

Note: This command requires an exclusive open of the file (see PRMIIDX82() for a shared mode version of this function). c-tree attempts to open the file in exclusive mode while allowing other connections read access. If the file is already open, c-tree flushes updates to disk and sets the update flag to zero to indicate that the file is in a clean, consistent state. If c-tree cannot open the file in exclusive mode, this operation fails.

When the Incremental file is closed via CloseIFile(), CloseISAM(), or CloseRFile(), the new indexes are automatically closed. The next Incremental open automatically includes the new indexes if OpenFileWithResource() is used, or if you have updated your Incremental structures and use OpenIFile().

The key values from the existing records will be added automatically. The additional indexes created and loaded by PermIIndex() reside in a separate index file, distinct from the index file(s) already in existence for the data file. There is no extended form of this function because the new indexes are automatically assigned the security information assigned to the existing indexes.

To disable the automatic load feature, set the dxtdsiz parameter of ifilptr to ctNO_IDX_BUILD. This creates the new index without loading key values into it. This feature allows PermIIndex() to be followed by UpdateConditionalIndex(), limiting the keys the index loads to those that meet the specified condition. Once the condition is in place, call RebuildIIndex() to fill the index. Do not close the files between PermIIndex() and RebuildIIndex().

ifilptr points to a new IFIL structure in which:

  • dfilno contains the file number of the underlying Incremental data file.
  • ix points to the new index definitions.
  • tfilno is -1 if you wish the index file number to be assigned, or tfilno is set to the first desired index number.
  • dnumidx is the number of index files to create.

Note: The underlying data file is not determined by the pfilnam member of the new IFIL structure. dfilno specifies the data file involved.

The IFIL file name and location enhancement automatically locates index files created by PermIIndex() or TempIIndexXtd() in the same directory as the associated data file. With PermIIndex() only, it also allows the IFIL entry for the index file to have the same directory as the associated data file, even if the data file is not in its original directory. To activate this feature, the index file name in the aidxnam parameter of ifilptr should be in the form:

+index_name   

By placing a plus sign,‘+’s the first character of the index name, the new index automatically “follows” the data file, i.e., it is created in the same directory as the data file. c-tree can open files via OpenFileWithResource() in a directory different from the directory in the file’s internal IFIL resource. When this happens, OpenFileWithResource() expects any index that had the same directory as the data file to be in the new directory.

The plus sign is not part of the actual file name used to create the index. Mirrored file name components use this option independently. Only the name components beginning with the plus sign invoke this feature. For example, the following would all be “legal” for aidxnam entries:

+primary_index|+mirror_index

+primary_index|mirror_index

 primary_index|+mirror_index

Adding an Index to an Existing File

FairCom has always supported adding an additional index to an existing file if the index is placed in a new physical file. If you need to add an additional index to an existing file and want to store the new index in the same physical file, PermIIndex() is the preferred method. This support is available starting in V11.2.

Return

Value Symbolic Constant Explanation
0 NO_ERROR Successful creation of new permanent index.
62 LERR_ERR Underlying data file must be opened ctEXCLUSIVE.
107 IDRK_ERR Too many index files for one data file. Increase MAX_DAT_KEY parameter in ctoptn.h or keyword in ctsrvr.cfg.
197 IMEM_ERR Not enough memory.
465 IINI_ERR ifilptr->dnumidx < 1.
466 IIDT_ERR ifilptr->dfilno does not reference an ISAM data file.
467 IINM_ERR ifilptr->ix->aidxnam must point to a new index file name.
468 IITR_ERR Incremental index cannot be built inside a transaction.

See c-tree Error Codes for a complete listing of valid c-tree error values.

Example

pIFIL     newindex;

FILNO     filno;

VRLEN     bufsiz;


filno = OpenFileWithResource(-1,"test", (ctEXCLUSIVE | ctPERMANENT));

if (filno < 0) {

    printf("\nOpen  failed");

    exit(1);

}


bufsiz = GetIFile(filno, 0, newindex);

newindex = (pIFIL) mballc(1, bufsiz);

GetIFile(filno, bufsiz, newindex);


newindex->dfilno = filno;

newindex->tfilno = -1;

newindex->dnumidx = 1;

newindex->aidxnam = "testnew";


if (PermIIndex(newindex))

    printf("\nAdding Index failed (%d %d)",isam_err,isam_fil);

Limitations

The Incremental ISAM files must be opened ctEXCLUSIVE.

See also

TempIIndexXtd(), DropIndex(), RebuildIIndex(), UpdateConditionalIndex(), AddRecord(), CloseIFile(), CloseISAM(), CloseRFile(), OpenFileWithResource(), OpenIFile(), PRMIIDX82()

 

PermIIndex8

Permanent 8-byte Incremental Index creation.

Short Name

PRMIIDX8()

Type

Extended 8-byte ISAM function

Declaration

COUNT PermIIndex8(pIFIL ifilptr, pXCREblk pxcreblk)

Description

PermIIndex()8 is a variation of PermIIndex() that permits the use of huge file support. This section expands on the description of PermIIndex().

pxcreblk points to an array of XCREblk structures, the extended creation block, one for each physical file in ifilptr. For more information, review Huge File Support in the c-tree Programmer’s Reference Guide.

Return

PermIIndex8() returns error codes similar to those for PermIIndex(). See c-tree Error Codes in the c-tree Programmer’s Reference Guide for a complete listing of valid c-tree error values.

Limitations

PermIIndex8() and TempIIndexXtd8() support ctTRANDEP creates. Without ctTRANDEP creates, these routines cannot be called within a transaction. With ctTRANDEP creates, they MUST be called within a transaction.

See also

TempIIndexXtd(), RebuildIIndex(), PermIIndex(), UpdateConditionalIndex(), PRMIIDX82

 

PositionSet

Establish current ISAM record as current position in set.

Short Name

MIDSET()

Type

ISAM function

Declaration

COUNT PositionSet(FILNO keyno, pVOID recptr, COUNT siglen)

Description

In V12 the file number typedef was formally changed from COUNT, a two-byte value to FILNO, a four-byte value. Refer to this link for compatibility details. Four Byte File Numbering

PositionSet extracts the key value for index keyno from the current ISAM record, and defines a set based on the first siglen bytes of this key value. This permits an application to “jump” into the middle of a set using the current ISAM record to define the set. A successful PositionSet() defines a current key value set, and subsequent calls to NextInSet() and PreviousInSet() will read the other records in the set (i.e., those records whose keys also match the first siglen bytes of keyno). If an error occurs or no key value matches the target, no key value set is defined.

Notice that you do not directly identify the data file number involved. The ISAM parameter file described in ISAM Functions (ISAM Database Technology, /doc/ctreeplus/30841.htm) of the c-tree Programmer’s Reference Guide contains the correspondence between the index file number and the associated data file.

Return

Value Symbolic Constant Explanation
0 NO_ERROR Successful retrieval of current ISAM record.
33 DNUL_ERR recptr is NULL. No data file read performed.
42 DLOK_ERR Could not get lock on data record. No data file read performed.
100 ICUR_ERR No current ISAM record.
101 INOT_ERR No active entries.

See c-tree Error Codes for a complete listing of valid c-tree error values.

Example

FILNO        keyfil;

TEXT         target[24],recbuf[320];


printf("\nEnter set value:");

scanf("%23s",target);


LockISAM(ctENABLE);


FirstInSet(keyfil,target,recbuf,strlen(target));


while (isam_err == NO_ERROR) {

    process_data();

    LockISAM(ctRESET);


    while (NextInSet(keyfil,recbuf) == DLOK_ERR) {

        LockISAM(ctSUSPEND);

        PositionSet(keyfil,recbuf,strlen(target));

        LockISAM(ctRESTORE);

    }

}

Limitations

No check is made to determine if recptr points to a region sufficiently large to accept a data record. If the area is too small, either code or data will be clobbered.

See also

NextInSet(), PreviousInSet(), LastInSet(), FirstInSet(), ChangeSet(), TransformKey()

 

PositionVSet

Establish current variable-length ISAM record as current position in set.

Short Name

MIDVSET()

Type

ISAM function

Declaration

COUNT PositionVSet(FILNO keyno, pVOID recptr, COUNT siglen, pVRLEN plen)

Description

In V12 the file number typedef was formally changed from COUNT, a two-byte value to FILNO, a four-byte value. Refer to this link for compatibility details. Four Byte File Numbering

PositionVSet() is the same as its fixed-length counter-part, PositionSet(), except that one argument has been added: plen.

plen acts as both an input and output parameter:

  • On input, plen contains the length of the output buffer.
  • On output, the contents of plen is the actual data-record length. If the length of the output buffer is less than the actual record length, a partial read is performed. If an error occurs, plen is unspecified.

Read the function description for PositionSet() for additional important information.

Return

Value Symbolic Constant Explanation
0 NO_ERROR Successful retrieval of current ISAM record.
633 NPLN_ERR plen is NULL. No data file read performed.
634 NLEN_ERR *plen negative on input.

See c-tree Error Codes for a complete listing of valid c-tree error values.

See also

PositionSet(), NextInVSet(), PreviousInVSet(), LastInVSet(), FirstInVSet(), ChangeSet(), TransformKey()

 

PreviousInRange

Read the previous record in a range

Short Name

PRVRNG()

Type

ISAM function

Declaration

COUNT PreviousInRange(COUNT keyval, pVOID recptr)  

Description

Read the previous data record in a range established by a call to AllocateRange(). If successful, the record becomes the current ISAM record for the associated data file. A successful PreviousInRange() defines a current key value set, and subsequent calls to NextInRange() or PreviousInRange() will read the other records in the range.

If the data file has variable-length records, only the fixed-length portion of the record is actually read. You can use ReReadVRecord() to retrieve the whole record, including the variable-length portion. You can use PreviousInVRange() to read the whole variable-length record with one function call.

Return

Value Symbolic Constant Explanation
0 CTDBRET_OK Successful operation.
101 INOT_ERR

Could not satisfy and ISAM search request for index isam_fil. This error frequently indicates "End of File" reached, or "Record not Found."

The following items are the probable causes of the INOT_ERR (101).

  • Passing GetRecord() a duplicate allowed index number (keyno). GetRecord() does not support duplicate allowed indices.
  • Improper target padding. Review “Key Segment Modes” in the c-tree Plus Programmer’s Guide.
  • Not calling TransformKey() on target. Refer to “TransformKey” in the Function Reference Guide
  • Passing ctDeleteSequence() a sequence name that does not exist
  • Improper segment mode. Review “Key Segment Modes” in the c-tree Plus Programmer’s Guide.
  • ctFILBLK() is called and the file is already blocked.

See c-tree Error Codes for a complete listing of valid c-tree error values.

See also

AllocateRange(), EstimateRange(), FirstInRange(), FirstInVRange(), FreeRange(), LastInRange(), LastInVRange(), NextInRange(), NextInVRange(), PreviousInVRange()

 

PreviousInSet

Read the previous data record in the current key value set.

Short Name

PRVSET()

Type

ISAM function

Declaration

COUNT PreviousInSet(FILNO keyno, pVOID recptr)  

Description

In V12 the file number typedef was formally changed from COUNT, a two-byte value to FILNO, a four-byte value. Refer to this link for compatibility details. Four Byte File Numbering

PreviousInSet() reads the previous data record in the set of data records whose keys match the set created by an earlier set function call. If successful, this record becomes the current ISAM record for the associated data file. If an error occurs or no previous record exists in the set, the current ISAM record is not updated, and the current key value set becomes undefined.

If the data file has variable-length records, only the fixed-length portion, defined by dreclen in the original call to CreateIFile(), is actually read into the buffer pointed to by recptr. If you wish to read the entire variable-length record into the same or a different buffer, issue a call to ReReadVRecord() after the call to PreviousInSet(). Note that ReReadVRecord() requires the size of the buffer area so that it can check if sufficient space is available.

Notice that you do not directly identify the data file number involved. The ISAM parameter file described in ISAM Functions (ISAM Database Technology, /doc/ctreeplus/30841.htm) of the c-tree Programmer’s Reference Guide contains the correspondence between the index file number and the associated data file.

Return

Value Symbolic Constant Explanation
0 NO_ERROR Successful retrieval of current ISAM record.
33 DNUL_ERR recptr is NULL. No data file read performed.
42 DLOK_ERR Could not get lock on data record. No data file read performed.
100 ICUR_ERR No current ISAM record.
101 INOT_ERR No active entries.
118 SKEY_ERR Either FirstInSet() has not been called or the last call to FirstInSet() was not for index number keyno.

See c-tree Error Codes for a complete listing of valid c-tree error values.

Example

FILNO        keyfil;

TEXT         target[24],recbuf[320];


printf("\nEnter set value:");

scanf("%23s",target);

LastInSet(keyfil,target,recbuf,strlen(target));

while (isam_err == NO_ERROR) {

   process_data();

   PreviousInSet(keyfil,recbuf);

}

Limitations

No check is made to determine if recptr points to a region sufficiently large to accept a data record. If the area is too small, either code or data will be clobbered.

See also

FirstInSet(), NextInSet(), LastInSet(), PositionSet(), ChangeSet(), CreateIFile(), ReReadVRecord(), TransformKey()

 

PreviousInVRange

Read the previous record in a range

Short Name

PRVVRNG()

Type

ISAM function

Declaration

COUNT PreviousInVRange(COUNT keyval, pVOID recptr, pVRLEN plen)  

Description

Read the previous data record in a range established by a call to AllocateRange(). If successful, the record becomes the current ISAM record for the associated data file. A successful PreviousInVRange() defines a current key value set, and subsequent calls to NextInVRange() or PreviousInVRange() will read the other records in the range.

plen acts as both an input and output parameter:

  • On input, plen contains the length of the output buffer.
  • On output, the contents of plen is the actual data-record length. If the length of the output buffer is less than the actual record length, a partial read is performed. If an error occurs, plen is unspecified.

Return

Value Symbolic Constant Explanation
0 CTDBRET_OK Successful operation.
101 INOT_ERR

Could not satisfy and ISAM search request for index isam_fil. This error frequently indicates "End of File" reached, or "Record not Found."

The following items are the probable causes of the INOT_ERR (101).

  • Passing GetRecord() a duplicate allowed index number (keyno). GetRecord() does not support duplicate allowed indices.
  • Improper target padding. Review “Key Segment Modes” in the c-tree Plus Programmer’s Guide.
  • Not calling TransformKey() on target. Refer to “TransformKey” in the Function Reference Guide
  • Passing ctDeleteSequence() a sequence name that does not exist
  • Improper segment mode. Review “Key Segment Modes” in the c-tree Plus Programmer’s Guide.
  • ctFILBLK() is called and the file is already blocked.

See c-tree Error Codes for a complete listing of valid c-tree error values.

See also

AllocateRange(), EstimateRange(), FirstInRange(), FirstInVRange(), FreeRange(), LastInRange(), LastInVRange(), NextInRange(), NextInVRange(), PreviousInRange()

 

PreviousInVSet

Read the previous variable-length data record in the set defined by target.

Short Name

PRVVSET()

Type

ISAM function

Declaration

COUNT PreviousInVSet(FILNO filno, pVOID recptr, pVRLEN plen)

Description

In V12 the file number typedef was formally changed from COUNT, a two-byte value to FILNO, a four-byte value. Refer to this link for compatibility details. Four Byte File Numbering

PreviousInVSet() is identical to it’s fixed-length counterpart, PreviousInSet(), except that it reads the previous variable-length data record in the set defined by target and siglen. If successful, this record becomes the current ISAM record for the associated data file.

plen acts as both an input and output parameter:

  • On input, plen contains the length of the output buffer.
  • On output, the contents of plen is the actual data-record length. If the length of the output buffer is less than the actual record length, a partial read is performed. If an error occurs, plen is unspecified.

Read the function description for PreviousInSet() for additional important information.

Return

Value Symbolic Constant Explanation
0 NO_ERROR Successful retrieval of current ISAM record.
633 NPLN_ERR plen is NULL.
634 NLEN_ERR plen is negative on input.

See c-tree Error Codes for a complete listing of valid c-tree error values.

See also

PreviousInSet(), FirstInVSet(), NextInVSet(), TransformKey()

 

PreviousKey

Find the previous entry in an index file.

Short Name

PRVKEY()

Type

Low-Level index file function

Declaration

LONG PreviousKey(FILNO keyno, pVOID idxval) 

Description

PreviousKey() searches index file keyno for the previous entry in the index. If successful, it copies the index entry into the space pointed to by idxval. PreviousKey() fails if it is the first index search routine called after the index is opened, or if the entry found before PreviousKey() is the first entry in the index. Repeated PreviousKey() calls move through the index in descending key value order.

Return

PreviousKey() returns the data record position associated with the previous entry in the index file. If the index is empty or an error is detected, PreviousKey() returns zero. When PreviousKey() returns zero, check uerr_cod: if uerr_cod is also zero, then the index is empty; otherwise, an error condition was detected. See c-tree Error Codes in the c-tree Programmer’s Reference Guide for a complete listing of valid c-tree error values.

Example

LONG      recbyt;

TEXT      idxval[10];  /* 10 byte key, no duplicates */

FILNO     keyno;


recbyt = LastKey(keyno,idxval);

while (recbyt) {

    printf("\nIndex Entry %.10s found in record #%ld", idxval,recbyt);

    recbyt = PreviousKey(keyno,idxval);

}

Limitations

No check is made to determine if idxval points to a region sufficiently large to accept a key value from the index file. If the area is too small, either code or data will be clobbered. Use GetCtFileInfo() to determine the key length.

The key value returned by this function will be a properly formatted key value (i.e., HIGH_LOW order, forced to upper case, etc.). The main issue is if binary key values will be displayed on a LOW_HIGH machine, it will be necessary to reverse any numeric segments. Key Segment Modes (Key Segment Modes, /doc/ctreeplus/30863.htm) in the c-tree Programmer’s Reference Guide contains suggestions for manipulating the key value.

The recbyt parameter in this function is a 4-byte value capable of addressing at most 4 gigabytes. If your application supports HUGE files (greater than 4 gigabytes), you must use the ctSETHGH() and ctGETHGH() functions to set or get the high-order 4 bytes of the file offset. See also Record Offsets Under Huge File Support.

See also

ctSETHGH(), ctGETHGH(), GetKey(), GetCtFileInfo(), FirstKey(), NextKey()

 

PreviousRecord

Read the preceding data record.

Short Name

PRVREC()

Type

ISAM function

Declaration

COUNT PreviousRecord(FILNO filno, pVOID recptr)

Description

In V12 the file number typedef was formally changed from COUNT, a two-byte value to FILNO, a four-byte value. Refer to this link for compatibility details. Four Byte File Numbering

PreviousRecord() retrieves the previous data record found. If filno designates an index file, PreviousRecord() reads the previous active data record based on the key sequential order of entries in index file number filno. If filno designates a data file, PreviousRecord() reads the previous active data record, in physical sequential order. If successful, the previous record becomes the current ISAM record for the associated data file. If an error occurs or there are no entries, the current ISAM record is not updated.

Note: filno cannot be a data file number, and the error FMOD_ERR (48) will be returned, if any of the following are true:

  • The data file is set up for variable-length records;
  • The data file is a member of a Superfile;
  • The data file has Resources enabled (the default state).

If the data file has variable-length records, only the fixed-length portion, defined by dreclen in the original call to CreateIFile(), is actually read into the buffer pointed to by recptr. If you wish to read the entire variable-length record into the same or a different buffer, issue a call to ReReadVRecord() after the call to PreviousRecord(). Note that ReReadVRecord() requires the size of the buffer area so that it can check if sufficient space is available.

If PreviousRecord() is called with an index number, the data file number involved is not directly described. The ISAM parameters described in ISAM Functions (ISAM Database Technology, /doc/ctreeplus/30841.htm) of the c-tree Programmer’s Reference Guide contain the correspondence between the index number and the associated data file.

PreviousRecord() can move sequentially through a data file based on one index then switch to another index. For example, moving through an inventory file in part number order before switching to part name order by changing the keyno parameter in the PreviousRecord() call.

As of c-tree V8.14, c-tree sets the current ISAM position after a record is added such that the next or previous record can be read without having to re-read the record just added. Prior to V8.14, the current ISAM position was not set to a newly-added record and an INOT_ERR (101) error would result if you tried to read either the next or previous record.

Return

Value Symbolic Constant Explanation
0 NO_ERROR Successful retrieval of current ISAM record.
33 DNUL_ERR recptr is NULL. No data file read performed.
42 DLOK_ERR Could not get lock on data record. No data file read performed.
48 FMOD_ERR PreviousRecord() called with a data file number of a variable-length data file or superfile member, or RESOURCES are enabled.
100 ICUR_ERR No current ISAM record.
101 INOT_ERR No active entries.

See c-tree Error Codes for a complete listing of valid c-tree error values.

Example

FILNO     acct_idx, test;

TEXT      recbuf[320];


test = LastRecord(acct_idx,recbuf);

while (test == NO_ERROR) {

    post_interest(recbuf);

    test = PreviousRecord(acct_idx,recbuf);

}

Limitations

No check is made to determine if recptr points to a region sufficiently large to accept a data record. If the area is too small, either code or data will be clobbered.

See also

FirstRecord(), NextRecord(), LastRecord(), CreateIFile(), ReReadVRecord().

 

PreviousVRecord

Read the previous variable-length data record in the data file.

Short Name

PRVVREC()

Type

ISAM function

Declaration

COUNT PreviousVRecord(FILNO filno, pVOID recptr, pVRLEN plen)

Description

In V12 the file number typedef was formally changed from COUNT, a two-byte value to FILNO, a four-byte value. Refer to this link for compatibility details. Four Byte File Numbering

PreviousVRecord() is identical to it’s fixed-length counterpart, PreviousRecord(), except that it reads the previous variable-length data record. If successful, this record becomes the current ISAM record for the associated data file.

plen acts as both an input and output parameter:

  • On input, plen contains the length of the output buffer.
  • On output, the contents of plen is the actual data-record length. If the length of the output buffer is less than the actual record length, a partial read is performed. If an error occurs, plen is unspecified.

Read the function description for PreviousRecord() for additional important information.

As of c-tree V8.14, c-tree sets the current ISAM position after a record is added such that the next or previous record can be read without having to re-read the record just added. Prior to V8.14, the current ISAM position was not set to a newly-added record and an INOT_ERR (101) error would result if you tried to read either the next or previous record.

Return

Value Symbolic Constant Explanation
0 NO_ERROR Successful retrieval of current ISAM record.
633 NPLN_ERR plen is NULL.
634 NLEN_ERR plen is negative on input.

See c-tree Error Codes for a complete listing of valid c-tree error values.

See also

PreviousRecord(), NextVRecord(), TransformKey()

 

PRMIIDX82

Create an index with the data file open in shared mode.

Declaration

CTERR PRMIIDX82(pIFIL ifilptr, pXCREblk pxcreblk, ULONG numberOfExtendedCreateBlocks, ctINDEX_ATTRIBUTES *pIndexAttributes);

Description

Beginning with V13, a condition can be added to the index when creating the index with the data file open in shared mode. Use this function to add a permanent index to a data file. The function accepts ifilptr and pxcreblk parameters that are identical in usage to PRMIIDX8(). The two additional parameters indicate the number of extended create blocks in the pxcreblk array and provide the desired index attributes:

The ctINDEX_ATTRIBUTES structure contains a version so that it can be modified in future versions to support passing additional index attributes. Version 1 of the structure is defined as follows:

/* index attributes for PRMIIDX82 */

typedef struct ctIndexAttributes_t {

ULONG structureVersion;

ULONG numberOfExtendedKeySegments;

ULONG numberOfIndexConditions;

pctKSEGDEF *extendedKeySegments;

cpTEXT *indexConditions;

} ctINDEX_ATTRIBUTES;

To use the index attributes structure, set structureVersion to ctINDEX_ATTRIBUTES_VERS_V01, set numberOfExtendedKeySegments to the number of extended key segments in the extendedKeySegments array (specify zero and NULL if no extended key segments are supplied), and set numberOfIndexConditions to the number of index conditions in the indexConditions array (specify zero and NULL if no index conditions are specified).

  • extendedKeySegments is an array of pointers to key segment definitions, one for each key segment definition (ISEG structure element) specified in the array of IIDX structures specified in the ifilptr parameter. If a given key segment has no extended key segment definition, specify NULL for that array element.
  • indexConditions is an array of pointers to index conditions, one for each index definition (IIDX structure element) specified in the ifilptr parameter. If a given index has no index condition, specify NULL for that array element.

Return Values

Value Symbolic Constant Explanation
0 CTDBRET_OK Successful operation.

See c-tree Plus Error Codes for a complete listing of valid c-tree Plus error values.

 

putcndxmem

Frees memory from expression parser tree.

Declaration

VOID putcndxmem( pVOID objptr );

Description

The macros getcndxmem() and putcndxmem(), used to get and put memory required to process and store conditional index expressions, allow the proper memory allocation routines to be used on the client and server sides. (These substitute for the internal mballc() and mbfree() calls.)

Example

/* Allocate a run-time stack for the expression analyzer (first time only). */

if (!ctcidxStk)  {

    ctcidxStk = (pVOID) getcndxmem(CNDX_MAX_STACK * ctSIZE(PLEAF));

    if (!ctcidxStk)  {

        printf("Unable to allocate memory for run-time stack.\n");

        ctrt_exit(1);

    }

}

if (ctcidxStk)

putcndxmem(ctcidxStk);

See also

cndxeval(), cndxfree(), cndxparse(), ctparsedoda(), cndxrun(), putcndxmem()

 

PutDODA

Store information from a record schema as a resource.

Short Name

PUTDODA()

Type

Low-Level data file resource function

Declaration

COUNT PUTDODA(FILNO datno, pDATOBJ doda, UCOUNT numfld)

Description

In V12 the file number typedef was formally changed from COUNT, a two-byte value to FILNO, a four-byte value. Refer to this link for compatibility details. Four Byte File Numbering

PutDODA() assigns the contents of a data object definition array (DODA) to data file. The DODA is converted into a schema map and schema names as described in Record Schemas of the c-tree Programmer’s Reference Guide.

  • datno is the data file number to assign the DODA to.
  • doda points to the beginning of the DODA (i.e., the array of DATOBJ’s). The DATOBJ is discussed in Record Schemas of the c-tree Programmer’s Reference Guide.
  • The numfld parameter indicates how many data fields (number of elements) are contained in the DODA.

Return

Value Symbolic Constant Explanation
0 NO_ERROR Success
48 FMOD_ERR Only valid for data files.
62 LERR_ERR The file must be opened exclusively.
401 RNON_ERR Resources not enabled.
448 DEFP_ERR File definition permission denied.

See c-tree Error Codes for a complete listing of valid c-tree error values.

 

Limitations

The file must be opened in ctEXCLUSIVE mode.

Resources must be enabled for the data file.

See also

GetDODA()

 

PutIFile

Place an IFIL structure into a data file resource record.

Short Name

PUTIFIL()

Type

ISAM resource function

Declaration

VRLEN PutIFile(pIFIL ifilptr) 

Description

Place a new, or replace an existing file definition (consisting of IFIL, IIDX and ISEG structures) into the resource record of the data file pointed to by ifilptr.

Normally, the IFIL is placed in the file during CreateIFile(). PutIFile() allows this resource to be updated or a new IFIL structure to be placed in files created with other functions.

Return

Value Symbolic Constant Explanation
0 NO_ERROR Successful IFIL retrieval.
107 IDRK_ERR Too many keys defined for data file.
401 RNON_ERR Resources not enabled.

See c-tree Error Codes for a complete listing of valid c-tree error values.

Refer to the following sections for additional details regarding IFIL structures.

IFIL Structure

IIDX Structure

ISEG Structure

Example

IFIL vc_dat = {

. . . .

};   /* IFIL structure to be placed in resource record */


VRLEN ret=0;  /* function return work variable */


if (ret=PutIFile(&vc_dat))

    printf("\nError during PUTIFIL(), error = %d",ret);

else

    printf("\nSuccessful PUTIFIL()!");

Limitations

The file must be closed prior to calling this function. PutIFile() opens the file in ctEXCLUSIVE mode and closes the file upon return.

See also

OpenFileWithResource(), GetIFile(), CreateIFile(), PutIFileXtd()

 

PutIFileXtd

Place an IFIL structure into a data file resource record. (Extended version)

Short Name

PUTIFILX()

Type

Extended ISAM function

Declaration

COUNT PutIFileXtd(pIFIL ifilptr, cpTEXT dataextn,

                  cpTEXT indxextn, cpTEXT fileword)

Description

PutIFileXtd() is a variation of PutIFile() that permits the use of the FairCom Server’s security system. This section expands on the description of PutIFile().

fileword is an optional file password. If fileword is null then there will be no password for this file. If a password is established, every user will need to use the password to be able to open the file. For more information on file passwords, review Security and Encryption (File Security and Encryption, /doc/ctreeplus/FileSecurityandEncryption.htm) in the c-tree Programmer’s Reference Guide.

dataextn and indxextn are pointers to buffers specifying optional data and index file name extensions, respectively. The extensions can be 8-byte ASCIIZ (NULL terminated ASCII) strings. If they are NULL pointers, the default extension will be used: .dat for data files and .idx for index files. For files with no extension, pass a pointer to a buffer that contains only blanks terminated by a null character. Do not set both extensions to blanks, since the index and data file names must be distinct.

Return

The following error code may be seen in addition to those for PutIFile():

Value Symbolic Constant Explanation
455 SGRP_ERR This user does not belong to the group groupid.

See c-tree Error Codes for a complete listing of valid c-tree error values.

Limitations

The file must be closed prior to calling this function. PutIFile() opens the file in ctEXCLUSIVE mode and closes the file upon return.

See also

PutIFile()

 

PutIFileXtd8

Put an IFIL structure into a data file resource record. Extended 8-byte version.

Short Name

PUTIFILX8()

Type

Extended 8-byte ISAM Function

Declaration

COUNT PutIFileXtd8(pIFIL ifilptr, cpTEXT dataextn,

          cpTEXT indxextn, cpTEXT fileword, pXCREblk pxcreblk) 

Description

PutIFileXtd8() extends PutIFileXtd() in that it can be used on an open file. It accepts a pointer to an extended file creation block, pxcreblk, however, does not currently use that information and NULL should be passed in.

Return

Value Symbolic Constant Explanation
0 NO_ERROR IFIL resource stored successfully.

The following three points will help users avoid any error when using this function:

  • The file must be opened in exclusive mode.
  • The tfilno member of the IFIL structure must be set to the current file number.
  • The xcreblk structure must be allocated and its splval member must be set to ctFILEOPENED constant value.

See c-tree Error Codes in the c-tree Programmer’s Reference Guide for a complete listing of valid c-tree error values.

Example

IFIL      vc_dat = {

. . . .

};   /* IFIL structure to be placed in resource record */


COUNT     ret=0;  /* function return work variable */

pTEXT     fileword;


getfileword(&fileword);

if (ret = PutIFileXtd8(&vc_dat, NULL, NULL, fileword, NULL))

    printf("\nError during PUTIFILX8, error = %d",ret);

else

    printf("\nSuccessful PUTIFILX8!");

See also

PutIFile(), PutIFileXtd()

 

PutXtdKeySegmentDef

Defines an extended key segment for a Server, an application, a data file, an index file, or a particular index segment.

Short Name

PUTKSEGDEF()

Type

ISAM Data Definition

Declaration

NINT  PutXtdKeySegmentDef(FILNO filno, NINT segno, pctKSEGDEF pkdef) 

Description

PutXtdKeySegmentDef() defines an extended key segment for a Server, an application, a data file, an index file, or a particular index segment. The pkdef parameter points to a definition to be created in a call to PutXtdKeySegmentDef(). The filno and segno parameters determine where the definition is to be stored, as follows:

filno segno Interpretation
ctKSEGserver ignored Create server default definition.
ctKSEGapplic ignored Create application default definition.
datno ignored Create data file level definition.
keyno ctKSEGindex Create index file level definition.
keyno 0, 1, 2, ... Create specific segment definition.

Return

PutXtdKeySegmentDef() returns a handle for the definition if successful.

PutXtdKeySegmentDef() returns a negative value upon error, where the absolute value of the return value is the error code. The most common errors are shown below. See c-tree Error Codes in the c-tree Programmer’s Reference Guide for a complete listing of valid c-tree error values.

 

Value Symbolic Constant Explanation
62 LERR_ERR PutXtdKeySegmentDef() called for a data or index file requires the file to be opened exclusively. A just created file is in exclusive mode, regardless of the specified file mode, until it is closed and re-opened.
437 DADR_ERR NULL pkdef argument.
445 SDAT_ERR No source data to create key segment.
446 BMOD_ERR Improper filno or segno values if the handle references an extended key segment definition not supported by the executable.
589 LADM_ERR Only an ADMIN group member may set a Server default (i.e., ctKSEGserver).
694 NUNC_ERR Executable does not support ICU Unicode, but a UNCSEG modifier has been encountered.
700 OSEG_ERR Could not process key segment definition.
701 CSEG_ERR Could not process the kseg_comp options. This could occur if more than one of a set of mutually exclusive options are combined.
702 ASEG_ERR An error occurred when attempting to process one of the special attribute options.
703 HSEG_ERR Invalid key segment handle in a call to TransformXtdSegment() or in a call to GetXtdKeySegmentDef() when the ctKSEGhandle option is used and the segno parameter should be set to a valid extended key segment handle.
704 SSEG_ERR No source type provided when kseg_styp has been set to ctKSEG_STYP_PROVIDED. If this error occurs, it is likely to occur during the first use (say with an AddRecord() or AddVRecord() or OpenIFile()) of the extended key segment.
705 DSEG_ERR An extended key segment definition already exists at the level implied by the PutXtdKeySegmentDef() call.
706 NSEG_ERR Zero bytes of binary sort key were generated. Possibly an all NULL source.
707 USEG_ERR There is no extended key segment definition to use.
708 MBSP_ERR Multibyte/Unicode file names are not supported.
709 MBNM_ERR A badly formed multibyte/Unicode file name has been encountered.
710 MBFM_ERR A multibyte/Unicode variant is not supported (e.g., UTF32).

Example

See the API example in the chapter titled “Unicode Support”.

See also

AddRecord(), AddVRecord(), OpenIFile(), PutXtdKeySegmentDef(), GetXtdKeySegmentDef(), TransformXtdSegment()

 

QuietCtree

Temporarily suspends operation of the FairCom Server for specific files/actions.

Declaration

NINT QuietCtree( pTEXT filespec, LONG timeoutSEC, LONG action )

Short Name

ctQUIET()

Description

Overview

A connection can call ctQuiet() to start quiescing the database. It can set action code options to block some or all activities, such as new file opens, new logins, new transactions, and all APIs except ctQuiet(). It can call this function multiple times to unblock some or all of the previously blocked activities, such as allow new logins but not new transactions.

The typical flow is to call ctQuiet() to block all new activity. When ctQuiet() returns, the app calls it again to flush all files. When ctQuiet() returns, the app performs some action like taking a snapshot of all the files for a backup. Then lastly, the app calls ctQuiet() again to unblock everything, which returns the database back to normal.

ctQuiet() supports various types of actions related to pausing system activity. This allows, for example, a clean filesystem level copy of data and index files. External hardware snapshots are also possible when available. Placing the files in a "closed" and "clean" (that is, flushed) state allows quick recovery from these backups. Unflushed files can also be copied, and if the transaction logs are included, a server can bring the files to a current consistent state during automatic recovery.

When you quiesce the server, as long as the connection that quiesced the server remains connected, all other connections are blocked. Only if that connection goes away do we allow the ADMIN user to logon again and undo the quiesce.

When connecting to a quieted server with the intent to remove the quiet state when the original caller of ctQuiet() has disconnected, you must set the InitISAMXtd() user profile mask (userprof parameter) to USERPRF_ADMSPCL. Here is an example:

INTISAMX(bufs, file, 0,128,0,0,USERPRF_ADMSPCL,admnuser,admnword,srv_name)

Note the command-line utility ctquiet (ctquiet - Quiesce FairCom DB Utility, ctquiet Utility) sets the user profile mask (userprof parameter) to USERPRF_ADMSPCL when the -x switch is used, so this is another method for waking up the server when the quiescing client has been abandoned.

QuietCtree() returns NSUP_ERR (454) on those servers where this feature is not enabled.

  • filespec is currently ignored (file-specific quiet operations are not currently supported).
  • timeoutSEC specifies the time in seconds to wait before aborting transactions prior to blocking.
  • action is either a block or unblock code from the following tables:

Block Action Codes

Symbolic Code Value Description
ctQTblockAllFiles 0x000002 block all files, ignore filespec
ctQTblockLogons 0x000010 block new logons
ctQTblockTransactions 0x000020 block new transactions
ctQTblockLogFiles 0x000100 block server log files (requires ctQTnoActiveTran and ctQTblockTransactions, and blocked access to the log files will sleep regardless if ctQTblockError is specified.)
ctQTblockAPI 0x004000 block all API's except QuietCtree( ctQTunblockAPI )

Unblock Action codes

ctQTunblockFiles 0x000800 permit file access
ctQTunblockTransactions 0x000200 permit new transactions
ctQTunblockLogons 0x000400 permit new logons
ctQTunblockAPI 0x008000 unblock all API's

Other options can be passed into ctQUIET() for additional control. These values are OR-ed into the action parameter.

ctQUIET() Options

Symbolic Code Value Description
ctQTblockError 0x000040 return error on block instead of sleeping
ctQTnoActiveTran 0x000080 ensure no transactions are pending at the time the actions specified by the above blocking options are taken - any pending transaction are aborted
ctQTflushTranFiles 0x020000 flush before file block
ctQTflushNonTranFiles 0x040000 flush before file block
ctQTfailAfterTimeout 0x01000000 abandon the ctQUIET() call if transactions are still active after timeout period - see Timeout Notes below
ctQTwaitForReplReaders 0x02000000 (Supported in V11.5 and later) Wait for all replication readers that have registered with the server to finish processing all committed transactions. If the ctQTfailAfterTimeout option has been included, the specified timeout will apply to this option, too.
ctQTignoreInactiveReplReaders 0x04000000 (Supported in V11.5 and later) When used with ctQTwaitForReplReaders, this allows the ctQUIET() call to ignore replication readers that are not connected to the server or that have not set a log position.

The following actions and options are combinations of the above actions for convenience.

Symbolic Code Value
ctQTblockALL (ctQTblockAllFiles | ctQTblockLogFiles | ctQTblockAPI)
ctQTflushAllFiles (ctQTflushTranFiles | ctQTflushNonTranFiles)
ctQTunblockALL (ctQTunblockTransactions | ctQTunblockLogons | ctQTunblockFiles | ctQTunblockLogFiles | ctQTunblockAPI)

The action codes for ctQUIET() are defined in ctport.h.

Note: Except for ctQTblockLogFiles, all references to files imply c-tree data and/or index files.

When the blocks are set, callers that hit the blocks sleep until the block is released and then continue with their API request, except when the caller’s transaction was aborted by QuietCtree(). If the transaction was aborted, then when the caller's block is released, the current API request returns with a QTAB_ERR (817). If the transaction was aborted but the caller has not made an API call since the transaction was aborted, then the next API call will return immediately with the QTAB_ERR. QTAB_ERR is returned to alert the caller that its current transaction has been aborted. Transactions are aborted by QuietCtree() only if ctQTnoActiveTran is part of the QuietCtree() request.

QuietCtree() is designed to permit multiple calls to achieve the desired results. When the final blocking attribute is removed by a call to QuietCtree(), QuietCtree() is completed which gives ups its interlocks on other QuietCtree()/ctFILBLK() calls and dynamic dumps.

A call to ctQUIET() with mode ctQTblockALL | ctQTflushAllFiles can be used to suspend all activity within FairCom DB and flush all files so that they have all updates written to disk and the update flag in the header of the files is reset, so that they can then be copied by an external process. However, this option forces a "no active transaction" state. This means that any transactions that are active when ctQUIET() is called are aborted.

A call to ctQUIET() with mode ctQTblockAPI can be used to suspend all activity on the FairCom Server while files remain open, potentially having updated data and index cache pages that have not been written to disk. In this mode, active transactions are simply suspended and they are resumed when ctQUIET() is called with mode ctQTunblockAPI. If you use this ctQUIET() mode and then copy the data and index files and the active transaction log files, you can then run automatic recovery on the files and you will have a point in time consistent copy of the file (where the point of time is the time the ctQUIET() successfully blocked all API calls: transactions that are pending as of that time are not included in the files).

Note: QuietCtree() cannot be called with a mix of ctQTblock and ctQTunblock action codes.

Quiet vs. Blocking

There is a subtle distinction between QuietCtree() and ctFILBLK(). QuietCtree() does not "physically" close files. This has particular implications on the Windows filesystem, as files are not allowed to be removed in this case as there is an open OS file handle still maintained. Compare to ctFILBLK() where files can be deleted or otherwise replaced while in the blocked state as the OS file handle may be released. Unix systems do not impose this restriction on files, thus, care should be taken in these environments to not replace or otherwise delete a file while in a Quiet state. Always use the file block API to physically replace a file.

Timeout Notes

The quiesce mode can be set to abandon the ctQUIET() call if transactions are still active after timeout period.

The ctQUIET() option ctQTnoActiveTran causes ctQUIET() to wait for the specified timeout interval for all active transactions to complete. As soon as all active transactions have completed, ctQUIET() continues putting the server into a quiesced state. But if any transactions remain active after the specified timeout interval, c-tree Server terminates those transactions.

The ctQTfailAfterTimeout mode changes this behavior so that when the specified timeout interval has passed the ctQUIET() call fails if any transactions remain active. To use this option, OR in the ctQTfailAfterTimeout mode to the action parameter that you pass to ctQUIET(). When ctQUIET() fails because this option is used and transactions remain active after the timeout period, it returns error code QTFA_ERR (1031).

It is possible for ctQUIET() to get into an abandoned state if the calling application (or c-tree utility ctquiet or ctadmn option 8) are terminated before c-tree is taken out of the quiesce state. When in an abandoned state any new client connections that are attempted will receive the QABN_ERR (error 898). Any existing connections that were waiting before the abandoned state occurs will continue to wait.

Example:

 NINT rc;

 

 if (!(rc = ctQUIET(NULL, 2, ctQTblockALL | ctQTflushAllFiles | ctQTfailAfterTimeout))) {

  printf(""Successfully quiesced server.\n"");

 } else {

  printf(""Error: Failed to quiesce server: %d\n"", rc);

 }

Return Values

Value Symbolic Constant Explanation
0 CTDBRET_OK Successful operation.
816 QTUQ_ERR Only one QuietCtree() process at a time.
817 QTAB_ERR Transaction aborted by QuietCtree().
818 QTFB_ERR QuietCtree() / ctFILBLK() conflict.
820 QTBK_PND trying to get QUIET. leave core. ctQUIET() found a connection already in the c-tree core and it's forcing it to exit the core.
825 QTOP_ERR QuietCtree() called with files opened.
826 QBAD_ERR Improper QuietCtree() action: see sysiocod for details
440 DDDM_ERR Dynamic Dump already in progress.
70 TEXS_ERR Transaction already pending.
101 INOT_ERR

Could not satisfy and ISAM search request for index isam_fil. This error frequently indicates "End of File" reached, or "Record not Found."

The following items are the probable causes of the INOT_ERR (101).

  • Passing GetRecord() a duplicate allowed index number (keyno). GetRecord() does not support duplicate allowed indices.
  • Improper target padding. Review “Key Segment Modes” in the c-tree Plus Programmer’s Guide.
  • Not calling TransformKey() on target. Refer to “TransformKey” in the Function Reference Guide
  • Passing ctDeleteSequence() a sequence name that does not exist
  • Improper segment mode. Review “Key Segment Modes” in the c-tree Plus Programmer’s Guide.
  • ctFILBLK() is called and the file is already blocked.
454 NSUP_ERR Operation or service not supported. Using an option unavailable to this library.

Possible sysiocod Returns

Value Symbolic Constant Explanation

 

1 QBKU_COD block and unblock actions mixed
2 QBUN_COD cannot block after unblock has begun
3 QMBK_COD mixed file block types
4 QSPC_COD missing filespec
5 QMAP_COD mixed API block types
6 QBAP_COD blockAllFiles requires blockAPI
7 QBFA_COD cannotBlockAllFiles after blockFiles
8 QFAP_COD file flush requires blockAPI
9 QLAP_COD blockLogFiles requires blockAPI

 

 

See c-tree Error Codes for a complete listing of valid c-tree error values.

Example


NINT quiesce()

{

    if (!QuietCtree( NULL, 1000, ctQTblockALL | ctQTflushAllFiles )) {

printf("Successful Quiesce.\n\n");

printf("It is now safe to perform sytem administrator duties.\n");

printf("Press RETURN once the backup is completed to resume the c-tree Server\n");


getchar();

if (rc = ctQUIET( NULL, 1000, ctQTunblockALL )) {

printf("Could not resume. Error: %d\n", rc);

}


    } else {

   printf("Could not quiesce\n");

    }

 

return(0);

}

See also

ctFILBLK()

 

ReadData

Read fixed-length data record.

Short Name

REDREC()

Type

Low-Level data file function

Declaration

COUNT ReadData(FILNO datno, LONG recbyt, pVOID recptr)

Description

In V12 the file number typedef was formally changed from COUNT, a two-byte value to FILNO, a four-byte value. Refer to this link for compatibility details. Four Byte File Numbering

ReadData() reads the data record at byte position recbyt for data file datno into the buffer area pointed to by recptr. If datno refers to a variable-length file, ReadData() reads only the fixed-length portion into the buffer. Use ReReadVRecord() to read an entire variable-length record.

Return

Value Symbolic Constant Explanation
0 NO_ERROR Successful read.
29 ZREC_ERR Attempt to read at byte offset zero.
30 LEOF_ERR recbyt exceeds the logical end of file maintained in the data file header.
33 DNUL_ERR recptr is NULL.
35 SEEK_ERR lseek() failed while preparing for read.
36 READ_ERR Operating system could not execute read.

See c-tree Error Codes for a complete listing of valid c-tree error values.

Example

FILNO     datno,keyno;

TEXT      recptr[1024];

LONG      part_number;


scanf("%ld",&part_number);

if (ReadData(datno, GetKey(keyno, &part_number), recptr))

    printf("\nCould not retrieve record for part #%ld", part_number);

Limitations

The recbyt parameter in this function is a 4-byte value capable of addressing at most 4 gigabytes. If your application supports HUGE files (greater than 4 gigabytes), you must use the ctSETHGH() and ctGETHGH() functions to set or get the high-order 4 bytes of the file offset. See also Record Offsets Under Huge File Support.

See also

ctSETHGH(), ctGETHGH(), ReReadVRecord(), ReadIsamData(), WriteData()

 

ReadIsamData

ISAM read data at record position.

Short Name

REDIREC()

Type

ISAM function

Declaration

COUNT ReadIsamData(FILNO datno, LONG recbyt, pVOID recptr)

Description

In V12 the file number typedef was formally changed from COUNT, a two-byte value to FILNO, a four-byte value. Refer to this link for compatibility details. Four Byte File Numbering

ReadIsamData() is the ISAM equivalent to the Low-Level function ReadData(). ReadIsamData() reads the data at record position recbyt for data file datno into the buffer pointed to by recptr. The significance of this function is that it decreases network traffic by eliminating the need to call ReadData() and SetRecord() to update the ISAM record buffers.

Return

Value Symbolic Constant Explanation
0 NO_ERROR Successful read.
33 DNUL_ERR recptr is NULL. No data file read performed.
36 READ_ERR Operating system could not execute read.
42 DLOK_ERR Could not get lock on data record. No data file read performed.
160 ITIM_ERR Record deleted by another user.

See c-tree Error Codes for a complete listing of valid c-tree error values.

Example

FILNO     datno;

LONG      recbyt[16];

TEXT      recptr[1024];


/* fill in an array of record positions */

FillRecordByteArray(recbyt);


/* read the 10th record in the array */

if (ReadIsamData(datno,recbyt[9],recptr))

    printf("\nCould not read 10th record, error = %d",

           isam_err);

else

    printf("\nSuccessful record read at offset %ld",recbyt[9]);

Limitations

The recbyt parameter in this function is a 4-byte value capable of addressing at most 4 gigabytes. If your application supports HUGE files (greater than 4 gigabytes), you must use the ctSETHGH() and ctGETHGH() functions to set or get the high-order 4 bytes of the file offset. See also Record Offsets Under Huge File Support.

See also

ctSETHGH(), ctGETHGH(), ReadData(), SetRecord()

 

ReadIsamVData

ISAM read variable-length data at record position.

Short Name

REDIVREC()

Type

ISAM function

Declaration

COUNT ReadIsamVData(FILNO datno, LONG recbyt, pVOID recptr, pVRLEN plen)

Description

In V12 the file number typedef was formally changed from COUNT, a two-byte value to FILNO, a four-byte value. Refer to this link for compatibility details. Four Byte File Numbering

ReadIsamVData() reads a variable-length ISAM record and is the variable-length analog to ReadIsamData(). ReadIsamVData() reads the data at record position recbyt for data file datno into the buffer pointed to by recptr for plen bytes.

plen acts as both an input and output parameter:

  • On input, plen contains the length of the output buffer.
  • On output, the contents of plen is the actual data-record length. If the length of the output buffer is less than the actual record length, a partial read is performed. If an error occurs, plen is unspecified.

ReadIsamVData() decreases network traffic by eliminating the need to make two separate function calls as follows:

  • Retrieve the fixed-length portion of the record with an ISAM search routine, such as FirstRecord(),
  • Call ReReadVRecord() to retrieve the variable-length component.

As with the other variable-length ISAM functions, ReadIsamVData() can read all or a portion of the variable-length record, potentially further reducing network traffic.

Return

Value Symbolic Constant Explanation
0 NO_ERROR Successful ISAM read operation.
33 DNUL_ERR recptr is NULL. No data file read performed.
36 READ_ERR Read error occurred. Bad record byte value.
42 DLOK_ERR Could not get lock on data record. No data file read performed.
160 ITIM_ERR Record deleted by another user.
633 NPLN_ERR plen is NULL.
634 NLEN_ERR *plen is negative on input.

See c-tree Error Codes for a complete listing of valid c-tree error values.

Example

FILNO   datno;

LONG    recbyt[16];

TEXT    recptr[1024];

VRLEN   varlen;


/* fill in an array of record positions */

FillRecordByteArray(recbyt);


varlen = 64;   /* set plen to 64 bytes */


/* read *plen bytes of the 10th record in the array */

if (ReadIsamVData(datno,recbyt[9],recptr,&varlen))

    printf("\nCould not read 10th record, error = %d", isam_err);

else

    printf("\nSuccessful record read at offset %ld", recbyt[10]);

Limitations

The recbyt parameter in this function is a 4-byte value capable of addressing at most 4 gigabytes. If your application supports HUGE files (greater than 4 gigabytes), you must use the ctSETHGH() and ctGETHGH() functions to set or get the high-order 4 bytes of the file offset. See also Record Offsets Under Huge File Support.

See also

ctSETHGH(), ctGETHGH(), FirstRecord(), ReReadVRecord(), ReadData(), ReadIsamData().

 

ReadVData

Read variable-length data record.

Short Name

RDVREC()

Type

Low-Level variable-length record function

Declaration

COUNT ReadVData(FILNO datno, LONG recbyt, pVOID recptr, VRLEN varlen)

Description

ReadVData() reads the variable-length data record at byte position recbyt for data file datno into the buffer area pointed to by recptr. If varlen, the size of the buffer pointed to by recptr, is not large enough for the variable-length record, ReadVData() returns an error.

To ensure varlen is large enough, call VDataLength() before calling ReadVData(). VDataLength() returns the actual length of the record. If the existing buffer is not large enough, a new, larger buffer must be allocated before calling ReadVData().

Note: No check is actually made to be sure that the region pointed to by recptr is in fact as large as varlen indicates. It is up to the application to ensure that varlen accurately specifies the size of the area pointed to by recptr.

Return

Value Symbolic Constant Explanation
0 NO_ERROR Successful read.
29 ZREC_ERR Attempt to read at byte offset zero.
33 DNUL_ERR recptr is NULL.
35 SEEK_ERR lseek() failed while preparing for read.
36 READ_ERR Operating system could not execute read.
48 FMOD_ERR datno is not assigned to a variable-length data file.
123 RVHD_ERR Record is not preceded by a valid record mark.
153 VBSZ_ERR varlen < actual record length.
154 VRCL_ERR Variable-length record is zero bytes long.
158 VFLG_ERR Variable-length record is not marked as active.
160 ITIM_ERR Multi-user interference: key value changed between index search and subsequent data record read.

See c-tree Error Codes for a complete listing of valid c-tree error values.

Example

FILNO     datno, keyno;

VRLEN     cur_bufsiz, varlen;

pTEXT     recptr, calloc();

LONG      part_number, pntr;


scanf("%ld",&part_number);

if ((pntr = GetKey(keyno,&part_number)) != DRNZERO) {

    varlen = VDataLength(datno,pntr);

    if (varlen > cur_bufsiz) {

        free(recptr);

        recptr = calloc(1,varlen));

        cur_bufsiz = varlen;

    }

    if (ReadVData(datno,pntr,recptr,varlen))

        printf>("\nError #%d reading at %ld", uerr_cod, pntr);

}

Limitations

The recbyt parameter in this function is a 4-byte value capable of addressing at most 4 gigabytes. If your application supports HUGE files (greater than 4 gigabytes), you must use the ctSETHGH() and ctGETHGH() functions to set or get the high-order 4 bytes of the file offset. See also Record Offsets Under Huge File Support.

See also

ctSETHGH(), ctGETHGH(), ReReadVRecord(), VDataLength(), WriteVData()

 

RebuildIFile

Incremental ISAM rebuild.

Short Name

RBLIFIL()

Type

ISAM function

Declaration

COUNT RebuildIFile(pIFIL ifilptr)  

Description

RebuildIFile() rebuilds the data file and index files referenced by the IFIL structure pointed to by ifilptr. The file(s) to be rebuilt MUST be closed. RebuildIFile() opens the file(s), performs the rebuild, and closes the files upon completion.

RebuildIFile() does the following:

  1. Resets the update corrupt flag updflg in the header of the data file.
  2. Rebuilds the internal delete stack chain in fixed-length files and rebuilds the internal delete management index in variable-length files.
  3. Removes the existing index file and builds an index, optimized for both size and speed, over the existing data file.
  4. If a SRLSEG exists, RebuildIFile() finds the highest serial number in use and updates the file header with that value.

The user data is not affected in any way.

If you desire the files to be rebuilt in directories that are not specified until run-time, then ifilptr->pfilnam should not be finalized until run-time.

If RESOURCES are defined, and if ifilptr->tfilno is set to updateIFIL, RebuildIFile() automatically places the current IFIL array into a resource record in the data file - even if the data file was created without resources. After writing the IFIL structure, RebuildIFile() checks to see if the IIDX or ISEG arrays have changed. If changes are detected, the new structures replace any existing structures in the data file or will be added if no structures were previously present.

Note: Do not use RebuildIFile() to add indexes to an existing index, since the member headers are all at the front of the physical file with the key values afterward, and there is no slack space to add new member headers without recreating the physical index file. Therefore, first delete the physical index file and then do the rebuild if additional index members are added. You may also use PermIIndex() or TempIIndexXtd().

Rebuild times can be optimized by increasing the number of temporary sort files used. Increase the #define MAX_HANDLES found in ctsort.h from its default of 50 to a larger number up to the maximum of 255. The value to use is a function of the size of the index to be rebuilt and the number of available file handles and is best determined by performing timing tests on the target system. The temporary files created during rebuild are c-tree files. After changing ctsort.h, recompile the entire c-tree library, including removing the object files and library, and the rebuild application.

The path and/or drive of the temporary sort files can be modified in non-server mode with minor changes to ctsort.h and ctsort.c as follows:

Change approximately line 32 of ctsort.h from:

   #define WORK_DRIVE_OR_PATH ""

to:

   pTEXT WORK_DRIVE_OR_PATH;

Now declare WORK_DRIVE_OR_PATH as an ‘extern’ in the rebuild application and assign the desired path. See also the GetCtTempFileName() function description.

A second method for decreasing rebuild times is to link the rebuild application with a single-user c-tree library so that index caching will be used. To increase the size of the index cache, increase the number of index buffers (i.e., bufs parameter to InitISAM() or the first number of the parameter file initialization record). The index cache uses a hashing algorithm, therefore the larger the index cache the faster the rebuild will be. The size of the index cache can be calculated as follows:

memory(in bytes) = bufs *(sect * 128 + MAXLEN + 128)

MAXLEN, the maximum key length defined in ctopt2.h, defaults to 1024 bytes.

Option to skip initial data file scan

Normally the rebuild function starts by scanning the data file, checking for valid record marks if it is a variable-length data file, and checking that the logical and physical end of file values are correct. If the data file is known to be in a good state, it can be beneficial to skip this scan. OR the skipdatascanIFILoption bit into the tfilno field of the IFIL structure that you pass to the rebuild function. When using this and other options, remember to negate the tfilno value after you OR in the options. For example:

myifil.tfilno = -(redosrlIFILoption | skipdatascanIFILoption);

RBLIFIL(&myifil);

 

Automatic Duplicate Purge Logic

Prior to c-tree V6.7, rebuilding a file with duplicate key values on an index for which duplicates were not allowed terminated the rebuild completely or left the indexes in an inconsistent state. The index not supporting duplicates would not have an entry for the record while the other indexes would have an entry for the record. For consistency, this is still the default behavior, but details concerning the duplicate keys are sent to a temporary text file instead of the console. The name of the temporary file is sent to the console and to CTSTATUS.FCS. This information is not subject to the RB_OUTPUT define. It happens automatically and may not be disabled.

Records containing the unwanted duplicates are marked deleted, and none of the indexes will have an entry for this record. A copy of each deleted duplicate record is stored in a temporary file, which notes the position, length, and content of the record. CTSTATUS.FCS contains entries indicating how many duplicate keys were rejected, the name of the data file, the name of the temporary file, and a message indicating successful completion of the duplicate purge.

To implement the automatic duplicate purge behavior, where records with duplicate keys are purged from the data file and copied into a temporary file, one of the following two approaches is used:

  1. Incremental ISAM Structure Support (IFIL): Rebuilding files defined by an Incremental ISAM Structure is typically accomplished with RebuildIFile(). Setting ifilptr->tfilno to purgeIFIL, which is defined in ctport.h, instigates the new auto-purge logic. It is permissible to set ifilptr->tfilno to purgeIFIL + updateIFIL so both behaviors can be achieved.
  2. Parameter Files: For parameter files rebuilt with ctrbld.c, add #define ctRBLD_AUTO_PURGE when compiling ctrbld.c. This causes the parameter file rebuild to attempt automatic record purge if duplicate keys are rejected.

Note: If the record is longer than the operating system maximum unsigned integer (MUI), only MUI bytes are stored in the temporary file for this record. Typically, this will only be an issue with 16-bit systems where MUI will be 64K bytes.

To re-instate a deleted record, open the temporary file using c-tree open calls, retrieve the desired record, and insert it back into the data file.

If purgeIFIL is used and a binary stream file can be opened, duplicate keys and bad serial numbers are automatically purged from the indexes and the data records are deleted from the file. RebuildIFile() returns DUPJ_ERR (650) and the temporary stream file contains the deleted data records. This is an informational, not fatal, error.

If purgeIFIL is NOT used and an ASCII stream file can be opened, the duplicate keys and bad serial numbers are not added to the indexes, but the data records remain in the file. RebuildIFile() returns DUPL_ERR (652), and lists the offending keys and data records in the stream file. Before V6.7, RebuildIFile() returned NO_ERROR (0) under this condition. DUPL_ERR is an informational, not fatal, error.

Option Values

Prior to FairCom DB V9.5, several option values were defined such as updateIFIL, purgeIFIL, and badpartIFIL, that can be specified. These values are specified by adding them together. For example: myifil.tfilno = updateIFIL + purgeIFIL. A new approach simplifies checking of these options. The following option values are now specified in ctport.h:

#define updateIFILoption     0x0002

#define purgeIFILoption      0x0004

#define badpartIFILoption    0x0008

#define redosrlIFILoption    0x0010

These values can now be OR-ed together and, using the setIFILoptions() macro, assigned to the tfilno field of the IFIL structure passed to the compact or rebuild function. For example, to indicate that you want to assign new serial numbers, do the following:

myifil.tfilno = setIFILoptions(redosrlIFILoption);

RBLIFIL(&myifil);

If you want to also use more than one option when compacting or rebuilding a file, OR them in to the value. For example:

/* assign new serial numbers and update IFIL resource. */

myifil.tfilno = setIFILoptions(redosrlIFILoption | updateIFILoption);

RBLIFIL(&myifil);

If a stream file cannot be opened, RebuildIFile() returns either KDUP_ERR (2) or KSRL_ERR (605) when duplicate keys and/or bad serial numbers are encountered. Further, no more indexes are processed. That is, the rebuild does not run to completion as it does in the above two cases.

To rebuild a mirrored file, ensure the mirror is specified in ifilptr. RebuildIFile() copies the primary file to the mirrored name on successful completion.

badpartIFILoption (badpartIFIL)

The rebuild should reference the partition host. If the partition host can be opened, we attempt to open each member and rebuild only the members that get an error on open. If the partition host itself fails to open, we rebuild the host and all members.

Online Rebuild - new for V13

An online index rebuild has been implemented. It requires the target file to have the ctTRNLOG file mode (full transaction control).

To invoke an online rebuild, use onlineIFILoption:

myifil.tfilno = setIFILoptions(onlineIFILoption);

RBLIFIL(&myifil);

The file must be closed by the calling user, as for a normal rebuild, but may be open by OTHER users for update. The IFIL resource embedded in the file is used, not the IFIL definition provided by the caller. Behavior is undefined if the IFIL resource embedded in the file doesn't match the definition used to create the indexes.

NOTES: Online rebuild uses the dynamic dump and immediate restore, so it requires the ctrdmp binary exists in the server working directory. Only one dynamic dump may occur at a time, so the online rebuild will wait to begin if backups or other online rebuilds are in process. When the new index is ready, access to the file will be suspended while the index is replaced. Any active transactions that have updated this file will be aborted at this point. If an error occurs after this point, the index will need to be rebuilt in exclusive mode. The online rebuild is not supported for memory files, partition files, segmented files, or superfiles. Files with deferred indexes are not currently supported.

Return

Value Symbolic Constant Explanation
0 NO_ERROR Successful rebuild of ISAM files.
12 FNOP_ERR Could not open file(s). Check isam_fil for the specific file number.
20 KMIN_ERR Key length too large for node size.
22 FNUM_ERR File number is out of range.
45 KLEN_ERR Key length exceeds MAXLEN parameter in ctoptn.h.
46 FUSE_ERR If ifilptr->dfilno >= 0, file number (range) already in use. If ifilptr->dfilno < 0, no block of numbers available.
107 IDRK_ERR Too many index files for one data file. Increase MAX_DAT_KEY parameter in ctoptn.h.
109 IKRS_ERR Too many key segments. Increase MAX_KEY_SEG parameter in ctoptn.h.
115 ISLN_ERR Key segments do not equal key length.
120 RRLN_ERR Not enough dynamic memory for record buffer.
122 RMOD_ERR Attempt to change between fixed and variable-length records.
123 RVHD_ERR A variable-length record is not preceded by a valid record mark.
454 NSUP_ERR Mirrored file rebuilds are not supported. Rebuild the primary if necessary and then copy to the mirrored file name.

484

485

  Error opening sortwork file. Increase the number of file handles requested at c-tree initialization time (InitISAM(), InitISAMXtd() or second value in parameter file Initialization Record).
605 KSRL_ERR Bad serial number.
650 DUPJ_ERR Informational: Duplicate records successfully purged.
652 DUPL_ERR Duplicates found and listed in stream file.

See c-tree Error Codes for a complete listing of valid c-tree error values.

Example

extern IFIL    customer;

       COUNT   retval;


main() {


    if (retval = InitISAM(10,10,16))

        printf("\nInitISAM error = %d",retval);


    if (!(RebuildIFile(&customer)))

        printf("\nSuccessful rebuild");

    else

        printf("\nRebuildIFile isam_err = %d",isam_err);


    CloseISAM();

}

Limitations

RebuildIFile() can be called from applications linked with the Standalone Multi-user (FPUTFGET) mode. RebuildIFile() opens the files in ctEXCLUSIVE mode, so no processes may access the file during rebuild. For performance reasons, single-user rebuilds are recommended.

To rebuild superfiles, call SuperfilePrepassXtd() prior to RebuildIFile().

See also

 

RebuildIFileXtd

Extended Incremental ISAM rebuild.

Short Name

RBLIFILX()

Type

Extended ISAM function

Declaration

COUNT RebuildIFileXtd(pIFIL ifilptr, cpTEXT dataextn, cpTEXT indxextn,

                      LONG permmask, cpTEXT groupid, cpTEXT fileword)

Description

RebuildIFileXtd() is a variation of RebuildIFile() that permits the use of the FairCom Server’s security system. This section expands on the description of RebuildIFile().

  • dataextn and indxextn point to buffers specifying optional data and index file name extensions, respectively. The extensions are 8-byte ASCIIZ strings. If the pointers are NULL, the default extension are used: .dat for data files and .idx for index files. To use no extensions, pass a pointer to a buffer containing only blanks terminated by NULL. Do not set both extensions to blanks. The data and index files must be distinct.
  • permmask is the permission mask assigned to this data file. It is formed by OR-ing the appropriate permission constants.
  • groupid is a pointer to a buffer that contains the group id that this file is to be assigned to. The group id must be valid for the user that is creating the file. If groupid is null, the file will be assigned to the default group for the user.
  • fileword is an optional file password. If fileword is null then there will be no password for this file. If a password is established, every user will need to use the password to be able to open the file.

For more information on permission masks, group id’s, and file passwords, review Security and Encryption (File Security and Encryption, /doc/ctreeplus/FileSecurityandEncryption.htm) in the c-tree Programmer’s Reference Guide.

Return

The following error code may be seen in addition to those for RebuildIFile():

Value Symbolic Constant Explanation
455 SGRP_ERR This user does not belong to the group groupid.

See c-tree Error Codes for a complete listing of valid c-tree error values.

See also

 

RebuildIFileXtd8

Extended 8-byte Incremental ISAM rebuild.

Short Name

RBLIFILX8()

Type

Extended 8-byte ISAM function

Declaration

  COUNT RebuildIFileXtd8(pIFIL ifilptr, cpTEXT dataextn,

          cpTEXT indxextn, LONG permmask, cpTEXT groupid,

          cpTEXT fileword, pXCREblk pxcreblk)

Description

RebuildIFileXtd8() is a variation of RebuildIFile() that permits the use of huge file support. This section expands on the description of RebuildIFile() and RebuildIFileXtd().

pxcreblk points to an array of XCREblk structures, the extended creation block, one for each physical file in ifilptr. For more information, review Huge File Support in the c-tree Programmer’s Reference Guide.

Return

RebuildIFileXtd8() returns error codes similar to those for RebuildIFile() and RebuildIFileXtd().

See c-tree Error Codes in the c-tree Programmer’s Reference Guide for a complete listing of valid c-tree error values.

See also


 

RebuildIIndex

Rebuilds a single index.

Short Name

RBLIIDX()

Type

ISAM function

Declaration

COUNT RebuildIIndex(pIFIL ifilptr)  

Description

RebuildIIndex() rebuilds the indexes specified by ifilptr, starting with the file number specified in ifilptr->tfilno, producing new optimized indexes.

InitISAM() or InitISAMXtd() must be called prior to calling RebuildIIndex() and the file pointed to by ifilptr->tfilno must be open at the time of the call to RebuildIIndex().

RebuildIIndex() was created for use with PermIIndex() and TempIIndexXtd(). By default, both functions create and fill index files in one action. The ability to separate the index creation from the index build permits UpdateConditionalIndex() to set conditional expressions for the new indexes. If PermIIndex() is involved, the data file has its conditional index resource updated. If TempIIndexXtd() is involved, no permanent storage of the conditional index expression is made. The proper steps are:

  • PermIIndex() or TempIIndexXtd() with ifilptr->dxtdsiz == ctNO_IDX_BUILD.
  • UpdateConditionalIndex() for each new index with a conditional expression.
  • RebuildIIndex() for each new index.

Note: Between a call to PermIIndex() or TempIIndexXtd() and a call to RebuildIIndex(), the newly created indexes have remained opened, and have not been closed or closed and re-opened.

 

Note: The setting for SORT_MEMORY <n> in ctsrvr.cfg should be increased when rebuilding large indexes for performance. The closer SORT_MEMORY is set to the size of the index, the faster the sort phase of the rebuild will be, regardless of the index size. (There is no additional benefit in setting SORT_MEMORY larger than the size of the index.)

Return

A zero (0) return indicates successful operation. A non-zero return indicates an error, check isam_err. The error returns are similar OpenCtFile() and RebuildIFile(). See c-tree Error Codes in the c-tree Programmer’s Reference Guide for a complete listing of valid c-tree error values.

Example

extern IFIL    customer;

COUNT          retval; 

FILNO          filno;

COUNT          conditional;


main() {


    if (retval = InitISAM(10,10,16))

        printf("\nInitISAM error = %d",retval);


    filno = OpenFileWithResource(-1,"test", (ctEXCLUSIVE | ctPERMANENT));

    if (filno < 0) {

        printf("\nOpen  failed");

        exit(1);

    }


    customer->dfilno = filno

    customer->tfilno = -1

    if (conditional)

        customer->dxtdsiz = ctNO_IDX_BUILD;


    if (permIIndex(&customer))

        printf("\nAdding Index failed (%d %d)", isam_err, isam_fil);


    if (conditional && !(RebuildIIndex(&customer)))

        printf("\nSuccessful compact");

    else

        printf("\nRebuildIIndex isam_err = %d",isam_err);


    CloseISAM();

}

Limitations

RebuildIIndex() does not support superfiles, see Superfiles in the c-tree Programmer’s Reference Guide.

RebuildIIndex() is not recommended for existing indexes. If one index becomes corrupt, FairCom recommend rebuilding all indexes associated with the data file.

See also

InitISAM(), InitISAMXtd(), UpdateConditionalIndex(), OpenCtFile(), PermIIndex(), RebuildIFile(), TempIIndexXtd()

 

 

 

RegisterCtree

Register (establish) a c-tree instance.

Short Name

REGCTREE()

Type

Low-Level function

Declaration

COUNT RegisterCtree(pTEXT regid)  

Description

RegisterCtree() accepts a unique registration reference name, pointed to by regid, and establishes a unique c-tree instance. Each call allocates a new control block for the c-tree global variables. The registration reference name can be up to 31 bytes and a NULL terminator in length.

Return

Value Symbolic Constant Explanation
0 NO_ERROR Instance successfully registered.
82 UALC_ERR User allocation error (usually out of memory).
518 GEXS_ERR regid is already registered.
536 AREG_ERR Only automatic RegisterCtree() is allowed.

See c-tree Error Codes for a complete listing of valid c-tree error values.

Example

TEXT     inpbuf[32];   /* input buffer */


ctrt_printf("\nEnter Instance Name\n");

gets(inpbuf);

if (RegisterCtree(inpbuf))

{

    ctrt_printf("\nCould not register {%s} data base",inpbuf);

    ctlxmg_exit(2);

}

Limitations

File handles are not shared between instances. Virtual logic cannot close files in other instances.

See also

NextCtree(), SwitchCtree(), WhichCtree(), GetCtreePointer(), UnRegisterCtree()

 

ReleaseData

Release fixed-length data record for reuse.

Short Name

RETREC()

Type

Low-Level data file function

Declaration

COUNT ReleaseData(FILNO datno, LONG recbyt)

Description

In V12 the file number typedef was formally changed from COUNT, a two-byte value to FILNO, a four-byte value. Refer to this link for compatibility details. Four Byte File Numbering

ReleaseData() adds record position recbyt to the chain of deleted records for fixed-length file datno. ReleaseData() should be called when a data record is no longer needed so that the space can be reused. Records returned by ReleaseData() are reused by NewData() before the data file is extended. ReleaseData() is automatically called by DeleteRecord().

Return

Value Symbolic Constant Explanation
0 NO_ERROR Successful return operation.
29 ZREC_ERR recbyt is zero.
30 LEOF_ERR recbyt exceeds the logical end-of-file maintained in the data file header.
32 DDRN_ERR Attempt to return recbyt twice in a row.
48 FMOD_ERR datno is not assigned to a fixed-length data file.
57 DADV_ERR Proper lock not found by the FairCom Server.

See c-tree Error Codes for a complete listing of valid c-tree error values.

Example

FILNO     keyno,datno;

LONG      recbyt;

pTEXT     target;


if (recbyt = GetKey(keyno,target))

    if (DeleteKey(keyno,target,recbyt) == NO_ERROR)

        if (ReleaseData(datno,recbyt) == NO_ERROR)

            printf("\nSUCCESS.");

Limitations

ReleaseData() writes an 0xff byte and a 4-byte data record position starting at the first byte of the returned data record. Therefore, even if you only write ASCII information into the data records, ReleaseData() will place binary information into the beginning of deleted records.

The recbyt parameter in this function is a 4-byte value capable of addressing at most 4 gigabytes. If your application supports HUGE files (greater than 4 gigabytes), you must use the ctSETHGH() and ctGETHGH() functions to set or get the high-order 4 bytes of the file offset. See Record Offsets Under Huge File Support.

See also

ctSETHGH(), ctGETHGH(), DeleteRecord(), LockCtData(), NewData()

 

ReleaseVData

Release variable-length data record for reuse.

Short Name

RETVREC()

Type

Low-Level data file function

Declaration

COUNT ReleaseVData(FILNO datno, LONG recbyt)

Description

In V12 the file number typedef was formally changed from COUNT, a two-byte value to FILNO, a four-byte value. Refer to this link for compatibility details. Four Byte File Numbering

ReleaseVData() adds record position recbyt to the pool of deleted records for variable-length file datno. ReleaseVData() should be called when a data record is no longer needed so that the space can be reused. Records returned by ReleaseVData() are reused by NewVData() before the data file is extended. ReleaseVData() is automatically called by DeleteVRecord().

Return

Value Symbolic Constant Explanation
0 NO_ERROR Successful return operation.
2 KDUP_ERR Attempt to delete a record already in reuse list.
48 FMOD_ERR datno is not assigned to a variable-length data file.
57 DADV_ERR Proper lock not found by the FairCom Server.
159 VPNT_ERR recbyt is zero.

See c-tree Error Codes for a complete listing of valid c-tree error values.

Example

FILNO     keyno,datno;

LONG      recbyt;


pTEXT     target;

if (recbyt = GetKey(keyno,target))

    if (DeleteKey(keyno,target,recbyt) == NO_ERROR)

        if (ReleaseVData(datno,recbyt) == NO_ERROR)

            printf("\nSUCCESS.");

Limitations

The recbyt parameter in this function is a 4-byte value capable of addressing at most 4 gigabytes. If your application supports HUGE files (greater than 4 gigabytes), you must use the ctSETHGH() and ctGETHGH() functions to set or get the high-order 4 bytes of the file offset. See also Record Offsets Under Huge File Support.

See also

ctSETHGH(), ctGETHGH(), DeleteVRecord(), LockCtData(), NewVData()

 

RemoveAutoSysTimeFields

Removes the automatic system time definition from datno.

Type

ISAM Function

Declaration

NINT RemoveAutoSysTimeFields(FILNO datno);

Description

  • datno - the data file number. In V12 the file number typedef was formally changed from COUNT, a two-byte value to FILNO, a four-byte value. Refer to this link for compatibility details. Four Byte File Numbering

Return

NO_ERROR on success

 

RenameFile

Rename a file.

Short Name

ctRENFIL()

Type

Low-Level function

Declaration

COUNT RenameFile(FILNO filno, cpTEXT newname)  

Description

In V12 the file number typedef was formally changed from COUNT, a two-byte value to FILNO, a four-byte value. Refer to this link for compatibility details. Four Byte File Numbering

RenameFile() renames a file that has been opened exclusively, meaning no other processes have the file open. RenameFile() is particularly useful for allowing a client application to rename a file controlled by a FairCom Server.

A superfile host cannot have any members open when it is renamed. A superfile member must have a correct matching host name in the newname string. For example, if the file being renamed is myhost!oldname, the newname string must be of the form “myhost!newname”. A file opened as part of a mirrored pair cannot be renamed.

Note: filno corresponds to the file to rename, and which must have been open exclusively. When renaming transaction logged files, it would be wise to include SKIP_MISSING_FILES YES in the FairCom Server configuration file since the log may contain references to the old file, which will not appear present during recovery.

Return

Value Symbolic Constant Explanation
0 NO_ERROR Successful file rename.
22 FNUM_ERR Bad filno.
62 LERR_ERR File must be opened exclusively.
67 RENF_ERR Could not rename file, usually because newname already exists or newname implies an unsupported move of the file to a different directory.
70 TEXS_ERR Cannot rename a transaction logged file in the middle of a transaction in which it is updated.
418 SNAM_ERR Bad superfile member name. Old name and new name must have matching hosts.
446 BMOD_ERR Attempt to rename a superfile host directory.
454 NSUP_ERR Cannot rename a file opened as part of a mirrored pair. Open the file with ctMIRROR_SKP.

See c-tree Error Codes for a complete listing of valid c-tree error values.

 

RenameIFile

Atomically rename some or all of the files associated with the IFIL structure.

Short Name

RENIFIL()

Type

ISAM function

Declaration

COUNT RenameIFile(pIFIL ifilptr)

Description

RenameIFile() atomically renames some or all of the files associated with the IFIL structure ifilptr, and updates the internal IFIL resource. ifilptr must point to a complete IFIL structure corresponding to an exclusively opened IFIL, with the names replaced by the new names. If the “new” name is the same as the original name, no renaming takes place for that file. The tfilno member of ifilptr must contain the file number of the data file associated with the IFIL. The dataextn and indxextn parameters can be used to modify the file name suffixes of the data and/or index files.

The data file’s IFIL resource will be updated under the following conditions:

  • Resources have been enabled.
  • The ctDISABLERES bit of the dfilmod member of ifilptr is not on.

When the IFIL resource is updated, then the following protocol is used:

  • If an existing IFIL resource is found, then only the name fields are updated to reflect the renaming operations.
  • If no existing IFIL resource is found, then the IFIL information passed into RenameIFile() is used in its entirety.

The IFIL structure passed into RenameIFile() must agree with both the physical files and the existing IFIL resource (if any) on the following points:

  • The number of indexes.
  • The key length and duplicate key status of each index.
  • The specification of which indexes serve as a host index, keeping in mind that the aidxnam member of IIDX can create host indexes in addition to the “base” index.

If any of these characteristics do not match, RenameIFile() returns IAIX_ERR (608).

The first index in the IFIL may derive its name either from the data file name, or through a non-NULL aidxnam parameter. The new IFIL may change whether or not the aidxnam parameter is used for the first index. It cannot change whether aidxnam is used for any of the other indexes.

Return

Value Symbolic Constant Explanation
0 NO_ERROR Successful rename of file.
14 FCRP_ERR File updated since ctEXCLUSIVE open.
70 TEXS_ERR Transaction in progress.
608 IAIX_ERR IFIL resources too different.

See c-tree Error Codes for a complete listing of valid c-tree error values.

Example

ISEG inv_seg = {

2,25,2

};

IIDX inv_idx = {

25,            /* key length            /

0,             / key type              /

0,             / dup off               /

0,             / null off              /

32,            / empty char            /

1,             / number of key segments*/

&inv_seg,      /* pointer to segment array*/

"Itemidx",      /* pointer to symbolic index name (r-tree)/

"invent.idx"    / optional index name (if this field is omitted the

                       default index name will be used.  The default is the

                       name supplied in the IFIL pfilnam with an extension

                       of "idx".)*/

};

IFIL inv_dat = {

"invent",       /* data file name ("dat" is always assumed)/

INVENTDAT,      / data file number     /

sizeof(invent), / data record length   /

4096,           / data extension size  /

1,              / data file mode       /

1,              / number of indices    /

4096,           / index extension size /

1,              / index file mode      /

&inv_idx,       / pointer to index array*/

"Delflag",      /* pointer to first field name (r-tree)/

"Buffer"        / pointer to last field name (r-tree)*/

};

#ifdef PROTOTYPE

VOID RenameTable(void)

#else

VOID RenameIFile1()

#endif

{

if (CloseIFile(&inv_dat))  /* Close file - file must be opened in exclusive mode */

printf("\nCloseIFile error  %d",isam_err);

inv_dat.dfilmod = 0;  /* set data file mode to exclusive for RenameIFile /

inv_dat.ifilmod = 0;  / set index file mode to exclusive for RenameIFile */

if  (OpenIFile(&inv_dat)) /* Open file now that the data file AND the index are set to exclusive */

printf("\nOpenIFile error  %d",isam_err);

 

 

cpybuf(inv_dat.pfilnam,"invent2",sizeof("invent2"));  /* copy in the new file name for the data file /

cpybuf(inv_idx.aidxnam,"invent2",sizeof("invent2"));  / copy in the new file name for the index file */

 

 

if (RenameIFile(&inv_dat))

printf("\nRenameIFile error  %d",isam_err);

}

 

Limitations

Transaction Logging

If the data file supports transaction logging and it does NOT have the ctTRANDEP or ctRSTRDEL extended file attributes, two criteria must be satisfied:

  • No transaction can be active when RenameIFile() is called.
  • The files cannot be updated between the exclusive open and the renaming call.

If either of the criteria is violated, RenameIFile() returns TEXS_ERR (70) or FCRP_ERR (14), respectively.

The renaming and optional updating of the IFIL resource are performed atomically under the control of a transaction automatically managed by c-tree.

Note: Transaction dependent files that have the ctTRANDEP or ctRSTRDEL extended file attributes MUST be within an active transaction to be renamed (the exact opposite of those that do not have these attributes).

Other Limitations

The IFIL structure passed into RenameIFile() must agree with both the physical files and the existing IFIL resource (if any) on the following points:

  • The number of indexes.
  • The key length and duplicate key status of each index.
  • The specification of which indexes serve as a host index, keeping in mind that the aidxnam member of IIDX can create host indexes in addition to the “base” index.

See also

RenameIFileXtd(), RenameFile()

 

RenameIFileXtd

Rename ISAM files, extended version.

Short Name

RENIFILX()

Type

Extended ISAM function

Declaration

COUNT RenameIFileXtd(pIFIL ifilptr, cpTEXT dataextn, cpTEXT indxextn)

Description

RenameIFileXtd() is a variation of RenameIFile() permitting the file extensions to be changed. This section expands on the description of RenameIFile().

dataextn and indxextn point to buffers specifying the data and index file name extensions, respectively. The extensions are 8-byte ASCIIZ (NULL terminated ASCII) strings. If the pointers are NULL, the default extension will be used: .dat for data files and .idx for index files. For files with no extension, pass a pointer to a buffer that contains only blanks terminated by a NULL character.

Return

As with RenameIFile(). See c-tree Error Codes in the c-tree Programmer’s Reference Guide for a complete listing of valid c-tree error values.

 

ReplaceSavePoint

Maintain a moving savepoint within a transaction.

Short Name

SPCLSAV()

Type

Low-Level data file function.

Declaration

LONG SPCLSAV(VOID)

LONG ReplaceSavePoint(VOID)

Description

Call ReplaceSavePoint() to establish a savepoint while at the same time clearing the previous savepoint. ReplaceSavePoint() can be used to maintain a single “moving” savepoint within a transaction, which is useful for applications that may need to undo the work since the last savepoint but that never need to restore back to a point prior to the most recent savepoint. ReplaceSavePoint() provides this ability in the form of a single savepoint rather than multiple savepoints. Because ReplaceSavePoint() clears the previous savepoint, only the most recently established savepoint can be restored to. To restore to this savepoint, call TRANRST(-1).

Return

ReplaceSavePoint() returns a non-zero value to indicate success and a value of zero to indicate failure. If the return value is zero, uerr_cod contains the c-tree error code. If a client supports ReplaceSavePoint() but the server does not, the message:

Bad raw function #. fn: 231

will be placed in CTSTATUS.FCS and the c-tree error SFUN_ERR (170) will be returned. A RestoreSavePoint() cannot go back beyond a special save point set with SPCLSAV(). Further, ClearSavePoint() cannot clear a special save point. Either of these situations returns a SPCL_ERR (753).

Example

An example of the use of SPCLSAV() is within the c-treeSQL Server engine that must be able to undo the last update, and may involve a very large number of updates within a single transaction.

See also

SetSavePoint(), RestoreSavePoint()

 

ReReadRecord

Reread current ISAM record.

Short Name

RRDREC()

Type

ISAM function

Declaration

COUNT ReReadRecord(FILNO datno, pVOID recptr)

Description

In V12 the file number typedef was formally changed from COUNT, a two-byte value to FILNO, a four-byte value. Refer to this link for compatibility details. Four Byte File Numbering

ReReadRecord() provides a simple way to reread the current ISAM record for fixed-length data records belonging to data file number datno. The record is read into the record buffer pointed to by recptr. Use ReReadVRecord() to reread the current ISAM record for a variable-length data file, unless only the fixed-length portion of the variable-length record is needed.

As of c-tree V8.14, c-tree sets the current ISAM position after a record is added such that the next or previous record can be read without having to re-read the record just added. Prior to V8.14, the current ISAM position was not set to a newly-added record and an INOT_ERR (101) error would result if you tried to read either the next or previous record.

Return

Value Symbolic Constant Explanation
0 NO_ERROR Successful read of current ISAM record.
33 DNUL_ERR recptr is NULL. No data file read performed.
42 DLOK_ERR Could not get lock on data record. No data file read performed.
100 ICUR_ERR No current ISAM record.
160 ITIM_ERR Record deleted by another user.

See c-tree Error Codes for a complete listing of valid c-tree error values.

Example

  FILNO     datno;

  TEXT      buffer[256];


if (LockISAM(ctENABLE) || ReReadRecord(datno,buffer)) {

    printf("\nCould not reread record (%d)",isam_err);

    LockISAM(ctFREE);

    return(-1);

}

See also

ReReadVRecord(), the LOCK discussion of multi-user updates in Multi-User Concepts of the c-tree Programmer’s Reference Guide and the source code of CTIXMG.C.

 

ReReadVRecord

Reread variable-length ISAM data record.

Short Name

REDVREC()

Type

ISAM variable-length record function

Declaration

COUNT ReReadVRecord(FILNO datno,pVOID  recptr, VRLEN varlen)

Description

In V12 the file number typedef was formally changed from COUNT, a two-byte value to FILNO, a four-byte value. Refer to this link for compatibility details. Four Byte File Numbering

ReReadVRecord() reads the current variable-length ISAM record for data file datno into the buffer area pointed to by recptr. If varlen, the size of the buffer pointed to by recptr, is not large enough for the variable-length record, ReReadVRecord() returns an error. ReReadVRecord() is used to read the entire variable-length record after the fixed-length portion is read via one of the fixed-length ISAM search routines (e.g., FirstInSet() instead of FirstInVSet()).

To ensure varlen is large enough, call VRecordLength() before calling ReReadVRecord(). VRecordLength() returns the actual length of the record. If the existing buffer is not large enough, allocate a new, larger buffer before calling ReReadVRecord().

Note: No check is actually made to be sure that the region pointed to by recptr is in fact as large as varlen indicates. It is up to the application to ensure that varlen accurately specifies the size of the area pointed to by recptr.

As of c-tree V8.14, c-tree sets the current ISAM position after a record is added such that the next or previous record can be read without having to re-read the record just added. Prior to V8.14, the current ISAM position was not set to a newly-added record and an INOT_ERR (101) error would result if you tried to read either the next or previous record.

See also Record Offsets Under Huge File Support.

Return

Value Symbolic Constant Explanation
0 NO_ERROR Successful read.
33 DNUL_ERR recptr is NULL.
35 SEEK_ERR lseek() failed while preparing for read.
36 READ_ERR Operating system could not execute read.
48 FMOD_ERR datno is not assigned to a variable-length data file.
100 ICUR_ERR No current ISAM record for file datno.
153 VBSZ_ERR varlen < actual record length.
154 VRCL_ERR Variable-length record is zero bytes long.
158 VFLG_ERR Variable-length record is not marked as active.
159 VPNT_ERR recbyt is zero.

See c-tree Error Codes for a complete listing of valid c-tree error values.

Example

FILNO     datno, keyno;

VRLEN     cur_bufsiz = 128, varlen;

pTEXT     recptr;

LONG      part_number;


recptr = calloc(1, cur_bufsiz));

if (FirstRecord(keyno, recptr)) == NO_ERROR) {

    if ((varlen = VRecordLength(datno)) > cur_bufsiz) {

        free(recptr);

        recptr = calloc(1,varlen));

        cur_bufsiz = varlen;

    }

    if (ReReadVRecord(datno,recptr,varlen))

        printf>("\nCould not reread record (%d).", isam_err);

}

See also

ReadVData(), ReReadRecord(), VRecordLength(), WriteVData()

 

resetIDfield

Resets the IDENTITY value assigned to a DODA field.

Declaration

  NINT resetIDfield(FILNO datno, LONG8 nxtval)

Description

In V12 the file number typedef was formally changed from COUNT, a two-byte value to FILNO, a four-byte value. Refer to this link for compatibility details. Four Byte File Numbering

resetIDfield() resets an IDfield (IDENTITY) auto-numbering value for a numeric field in a record to a new specified value.

Where:

  • datno is the data file number
  • nxtval is the next value to be assigned on record addition

IDfield requires a DAR resource (Direct Access Resource) embedded in the file. The DAR is a specialized high-speed resource.

Return

Value Symbolic Constant Explanation
0 NO_ERROR Success

See c-tree Error Codes for a complete listing of valid c-tree error values.

Example

retval = resetIDfield(fileno, 1000);

if (retval) {

printf("\tERROR: Failed to reset ID field with error %d\n", retval);

}

Override IDENTITY Values

PUTHDR() using the ctIDfieldOverRide mode can turn on and off the ability to override the automatic IDfield values. The override is on a per user, per file basis. A nonzero hdrval turns on the override, and a zero hdrval restores the standard operation. When the override is on for a data file that supports an IDfield, then an add record operation does not fill-in the IDfield value. Whatever is passed in the record buffer is used for the IDfield. And a rewrite permits the IDfield value to change instead of generating the IDFL_CHG error. When the override is enabled, add record operations do not consume IDfield values.

See also

addIDfield(), delIDfield(), getIDfield(), wchIDfield(), IDfields - Extended support

 

ResetRecord

Updates the current ISAM record image buffers.

Short Name

UPDCURI()

Type

ISAM function

Declaration

COUNT ResetRecord(FILNO datno, COUNT mode);   

Description

In V12 the file number typedef was formally changed from COUNT, a two-byte value to FILNO, a four-byte value. Refer to this link for compatibility details. Four Byte File Numbering

ResetRecord() manipulates the internal image of the current ISAM record kept by c-tree. An image is kept of the current ISAM record’s key structure and the current ISAM record’s file address. Whenever an ISAM function changes the current ISAM record, such as an AddRecord() or ReWriteRecord(), the original current ISAM record information is copied over to a secondary buffer before the primary buffer is changed. ResetRecord() can be used to manage these two buffers.

  • datno specifies the ISAM file that is to be affected.
  • mode can be one of several values;
mode Description
SWTCURI Switches the ISAM buffers. Use SWTCURI after a rewrite to move the old buffer back to the original. This allows you to keep your position in the file as it was before the rewrite.
SAVCURI Copies the current ISAM record information to the secondary buffer.
RSTCURI Restores the primary ISAM record information from the secondary area.

Return

Value Symbolic Constant Explanation
22 FNUM_ERR File number is out of range.
26 FACS_ERR File number is not assigned to a file in use.
47 FINT_ERR c-tree has not been initialized.
48 FMOD_ERR datno is not assigned to a data file.
116 IMOD_ERR Invalid value in mode.

See c-tree Error Codes for a complete listing of valid c-tree error values.

Example

FILNO     invfil;
 

struct invd {

  TEXT      delflg[4];

  LONG      part_no;

  LONG      on_hand;

  TEXT      part_name[60];

 } recbuf;


scanf("%ld %59s %ld",&recbuf.part_no,recbuf.part_name, &recbuf.on_hand);

recbuf.delflg = '\0'; /* clear delete flag */

if (AddRecord(invfil,&recbuf) )

    printf("\nAddRecord error %d in file %d", isam_err, isam_fil);


/* after adding record, restore current ISAM to previous point */

if (ResetRecord(invfil,SWTCURI) )

    printf("\nCannot reset, error %d",isam_err);

See also

AddRecord(), ReWriteRecord(), SetRecord().

 

RestoreSavePoint

Undo transaction operations back to a savepoint.

Short Name

TRANRST()

Type

Low-Level data file function

Declaration

COUNT RestoreSavePoint(COUNT savpnt)

Description

RestoreSavePoint() rolls the current transaction back to a previously defined savepoint created with a call to SetSavePoint(). savpnt is the savepoint to roll back to, and is the value returned by the call to SetSavePoint(). This allows you to back up in a transaction to a particular point, without having to Abort() or Commit() the entire transaction. For a complete discussion of this process please see Data Integrity in the c-tree Programmer’s Reference Guide.

savpnt can also be specified as a small negative number. -1 means go back to the most current savepoint. -2 means go back one more, etc.

RestoreSavePoint() also clears errors that have occurred since the savepoint.

Return

Value Symbolic Constant Explanation
0 NO_ERROR No error occurred.
71 TNON_ERR There is no active transaction pending.

See c-tree Error Codes for a complete listing of valid c-tree error values.

Example

COUNT     savepoint;


void domaster() {

    Begin( ctENABLE | ctTRNLOG );   /* start transaction with locks  */

    while( another() ); {         /* get next record to add        */

        savepoint = SetSavePoint();

                         /* get save point at beginning of each master record */

        if ( add_master() < 0 )

            Abort();     /* RestoreSavePoint if can't add master rec          */

        dodetail();      /* process detail records                            */

    }

    if ( Commit(ctFREE) )

        printf("\nError %d in transaction",uerr_cod);

    return;

}


void dodetail() {

    while( moredetail() ); {       /*get next detail record to add */

        if ( add_detail()<0 ) {    /* add details, if possible     */

            RestoreSavePoint( savepoint ) /* with error, return to savept */

            return;

        }

    }

}

See also

Abort(), AbortXtd(), Begin(), ClearSavePoint(), Commit(), SetSavePoint(), TRANRDY()

 

ReWritePartialRecord

Rewrites a partial fixed or variable-length record.

Declaration

COUNT ReWritePartialRecord (FILNO datno, pVOID recptr, VRLEN varlen);

Short Name

RWTPREC()

Description

In V12 the file number typedef was formally changed from COUNT, a two-byte value to FILNO, a four-byte value. Refer to this link for compatibility details. Four Byte File Numbering

ReWritePartialRecord() permits a fixed or variable-length record to be updated (i.e., rewritten) without passing back an entire record image. It is only necessary to pass enough bytes to hold the fields that have been modified. As a matter of good practice, varlen should end on a field boundary. This routine is especially effective for files whose records start with status fields and end with potentially large variable-length fields. For example, for a record containing ID fields and status fields followed by a very large binary field, say a graphic image, and one desired to only change a status or ID field, it is not necessary to pass the entire record to ReWritePartialRecord() rather, only the first few bytes at the beginning of the record. This significantly reduces network traffic and improves performance.

There is a subtle difference between ReWriteVRecord() and ReWritePartialRecord() called with a varlen equal to the original record length: ReWritePartialRecord() assumes a well formed record and will permit a variable-length field to be truncated by the end of the record. ReWriteVRecord() assumes it must avoid field truncation, and would return error SDAT_ERR (445) under the same circumstance. Practically, ReWritePartialRecord() should not be used to perform a full rewrite and good practices would not permit a truncated record image for ReWriteVRecord().

ReWritePartialRecord() can only be used to rewrite with a partial record image that is less than or equal to the full record image length. An attempt to grow the existing record results in error VMAX_ERR (140). When updating records with ReWritePartialRecord() the partial record image must contain enough data to enable c-tree to construct all key segments for all indexes of the data file. ReWriteVRecord().should be used instead of ReWritePartialRecord() if any variable-length field of the record was resized, even if the resulting record length remains unchanged.

Return

Value Symbolic Constant Explanation
0 NO_ERROR No error occurred.
2 KDUP_ERR Duplicate key value detected in index file number isam_fil. Record update not performed.
22 FNUM_ERR File number is out of range.
26 FACS_ERR File number is not assigned to a file in use.
57 DADV_ERR Proper lock not found by FairCom Server.
100 ICUR_ERR No current ISAM record.
105 IUND_ERR Could not undo a rejected ISAM update.
140 VMAX_ERR Variable record length too long.
199 NSCH_ERR Key segment refers to schema, but schema not defined.
433 SSCH_ERR Segment definition inconsistent with schema.
445 SDAT_ERR Not enough data to assemble key.
446 BMOD_ERR Bad key segment mode.

See c-tree Error Codes for a complete listing of valid c-tree error values.

Example

If a data file has a record structure that contains three fields: id (CT_INT4), status (CT_INT4) and description (CT_STRING), and the id field is never updated, but the status or the description field may be updated, the ReWritePartialRecord() or ReWriteVRecord() may be used, depending on which field was updated.

Example

typedef struct

{

    LONG    id;

    LONG    status;

    TEXT    description[MAX_DESCRIPTION];

} MYRECORD;

NINT UpdateMyRecord(FILNO datno, LONG id,  LONG status, pTEXT description)

{

    NINT eRet;

    NINT partial = YES;

    VRLENvarlen = sizeof(LONG)*2;

    MYRECORD recbuf;

    /* set the fixed portion of the record */

    recbuf.id = id;

    recbuf.status  = status;

    /* check if we need to set the description field */

    if (description)

    {

        strcpy(recbuf.description, description);

        partial = NO;

        varlen += strlen(description) + 1;

    }

    /*  update/rewrite the record */

    if (partial)

        eRet = ReWritePartialRecord(datno, &recbuf, varlen);

    else

        eRet = ReWriteVRecord(datno, &recbuf, varlen);

    return eRet;

}
 

Limitations

An issue remains for how to perform the rewrite, partial or full, if the prior read of the record was itself partial (only the fixed portion of a variable-length record was read) and did not permit all of the internal key buffers to be updated. This issue remains in a pending state and you are advised to not attempt this sequence of operations. In addition, support for row level call callbacks has not been enabled for partitioned files during full or partial rewrites.

See also

ReWriteRecord(), ReWriteVRecord()

 

ReWriteRecord

Rewrite current fixed-length ISAM record.

Short Name

RWTREC()

Type

ISAM function

Declaration

COUNT ReWriteRecord(FILNO datno, pVOID recptr)

Description

In V12 the file number typedef was formally changed from COUNT, a two-byte value to FILNO, a four-byte value. Refer to this link for compatibility details. Four Byte File Numbering

ReWriteRecord() allows changes to be made in the current ISAM record for fixed-length data records belonging to data file number datno. recptr should point to the updated version of the current ISAM record. ReWriteRecord() assumes that the current ISAM record is the original version. After successful completion of ReWriteRecord(), the updated version is now stored in the data file and all necessary changes to the key values associated with the updates are automatically made.

The typical ReWriteRecord() usage is:

  • First, an ISAM retrieval function, (e.g., ReadISAMData(), GetRecord() or NextRecord()), reads the desired record, making it the current ISAM record.
  • Updates are made to the record buffer.
  • ReWriteRecord() rewrites the updated record, making the updated record the current ISAM record. If any of the key fields have been changed, the old key is removed from the appropriate indexes, and the new one is added.

Unlike c-tree version 4.3 and older, you do not have to be careful about making changes to the current record in your buffer. c-tree maintains its own copy of the current ISAM record key information and position.

Multi-user updates are more complex because of the possibility of either locking out the record for prolonged periods, or because of two users trying to update the same record at the same time. See Multi-User Concepts in the c-tree Programmer’s Reference Guide for a detailed discussion of multi-user updates.

ReWriteRecord() does not change the automatic serial number key segments, if any. If you want the serial number updated, delete the old record and add the updated record.

To make the old record the current ISAM record, so that NextRecord() will be performed relative to the position before the update, make the following call after successfully completing the record rewrite:

ResetRecord(datno,SWTCURI);

Return

Value Symbolic Constant Explanation
0 NO_ERROR Successful record update. New record becomes the current ISAM record.
2 KDUP_ERR Duplicate key value detected in index file number isam_fil. Record update not performed.
22 FNUM_ERR File number is out of range.
26 FACS_ERR File number is not assigned to a file in use.
48 FMOD_ERR datno is not assigned to a fixed length data file.
57 DADV_ERR Proper lock not found by the c-tree.
100 ICUR_ERR No current ISAM record.
105 IUND_ERR Could not undo a rejected ISAM update. Unless the files support transaction processing, this is a serious error indicating the data file must be rebuilt.
199 NSCH_ERR Key segment refers to schema, but schema not defined.
433 SSCH_ERR Segment definition inconsistent with schema.
445 SDAT_ERR Not enough data to assembly key.
446 BMOD_ERR Invalid key mode.

See c-tree Error Codes for a complete listing of valid c-tree error values.

Example

FILNO datno,keyno;

LONG  cust_no;

TEXT  buffer[128];


printf("\nEnter customer number: ");

scanf("%ld",&cust_no);

if (GetRecord(keyno,cust_no,buffer))  /* read current record */

    printf("\nCould not read customer record.");

else {

    update(buffer);           /* make your changes to buffer */

    if (ReWriteRecord(datno,buffer))

        printf("\nCould not rewrite customer record.");

    else

        printf("\nSuccessful update of customer record.");

}


   

Limitations

After a call to ReWriteRecord(), the current ISAM record is set to the new record. This may create a situation that you don’t expect when ReWriteRecord() is used inside a loop that steps over the data in key sequential order. If the key value is changed during the update, the current ISAM record position will skip to the new position, which may be before or after the original position. To avoid this situation, reset the current ISAM record after ReWriteRecord() using ResetRecord().

See also

ReadISAMData(), GetRecord(), NextRecord(), ResetRecord()

 

ReWriteVRecord

Rewrite current variable-length ISAM record.

Short Name

RWTVREC()

Type

ISAM function

Declaration

COUNT ReWriteVRecord(FILNO datno, pVOID recptr, VRLEN varlen)

Description

In V12 the file number typedef was formally changed from COUNT, a two-byte value to FILNO, a four-byte value. Refer to this link for compatibility details. Four Byte File Numbering

ReWriteVRecord() allows changes to be made in the current variable-length ISAM record for data file number datno. recptr should point to the updated version of the current ISAM record, and varlen specifies the length of the updated version. ReWriteVRecord() assumes that the current ISAM record is the original version. After successful completion of ReWriteVRecord(), the updated version is now stored in the data file and all necessary changes to the key values associated with the updates are automatically made. If the updated version does not fit into the space available for the current record, it is moved to another location in the data file. All associated indexes are updated appropriately.

The typical ReWriteVRecord() usage is:

  • First, an ISAM retrieval function, (e.g., GetRecord() or NextRecord()), reads the fixed portion of desired record, making it the current ISAM record.
  • ReReadVRecord() reads the entire record into the buffer. This buffer now contains the entire current ISAM record.

Note: Variable-length retrieval functions, such as ReadISAMVData(), GetVRecord(), and NextVRecord(), accomplish these two steps in one function call.

  • Updates are made to the record buffer.
  • ReWriteVRecord() rewrites the updated record, making the updated record the current ISAM record. If any of the key fields have been changed, the old key is removed from the appropriate indexes, and the new one is added.

Multi-user updates are more complex because of the possibility of either locking out the record for prolonged periods, or because of two users trying to update the same record at the same time. See Multi-User Concepts in the c-tree Programmer’s Reference Guide for a detailed discussion of multi-user updates.

ReWriteVRecord() does not change the automatic serial number key segments, if any. To update the serial number, delete the old record and add the updated record.

To make the old record the current ISAM record, so that NextRecord() will be performed relative to the position before the update, make the following call after successfully completing the record rewrite:

ResetRecord(datno,SWTCURI);

Return

Value Symbolic Constant Explanation
0 NO_ERROR Successful record update. New record becomes the current ISAM record.
2 KDUP_ERR Duplicate key value detected in index file number isam_fil. Record update not performed.
22 FNUM_ERR File number is out of range.
26 FACS_ERR File number is not assigned to a file in use.
48 FMOD_ERR datno is not assigned to a variable-length data file.
57 DADV_ERR Proper lock not found by the FairCom Server.
100 ICUR_ERR No current ISAM record.
105 IUND_ERR Could not undo a rejected ISAM update. Unless the files support transaction processing, this is a serious error indicating the data file must be rebuilt.
199 NSCH_ERR Key segment refers to schema, but schema not defined.
433 SSCH_ERR Segment definition inconsistent with schema.
445 SDAT_ERR Not enough data to assembly key.
446 BMOD_ERR Invalid key mode.

See c-tree Error Codes for a complete listing of valid c-tree error values.

Example

FILNO     datno, keyno;

VRLEN     newlen, varlen;

LONG      cust_no;

TEXT      buffer[512];


printf("\nEnter customer number: ");

scanf("%ld",&cust_no);

if (GetRecord(keyno,cust_no,buffer)  /* read current record */

    || ReReadVRecord(datno,buffer,512))        

    printf("\nCould not read customer record.");

else {

    newlen = update(buffer);  /* make your changes to buffer */

    if (ReWriteVRecord(datno,buffer,newlen))

        printf("\nCould not rewrite customer record.");

    else

        printf("\nSuccessful update of customer record.");

}

Limitations

After a call to ReWriteVRecord(), the current ISAM record is set to the new record. This may create a situation that you don’t expect when ReWriteVRecord() is used inside a loop that steps over the data in key sequential order. If the key value is changed during the update, the current ISAM record position will skip to the new position, which may be before or after the original position. To avoid this situation, reset the current ISAM record after ReWriteVRecord() using ResetRecord().

See also

GetRecord(), NextRecord(), ReReadVRecord(), ReadISAMVData(), GetVRecord(),
NextVRecord(), ResetRecord()

 

SA_ERRMSG

Returns an SA ADMIN associated error message.

Declaration

pTEXT SA_ERRMSG(COUNT errcode)

Description

errcode is an SA ADMIN API error code.

Return

SA_ERRMSG() returns the error message associated with an SA ADMIN API error code.

Example psuedocode

SA_LOGON("ADMIN", "ADMIN", NULL, "FAIRCOMS");

...

if ((rc = SA_FILES(...) !=0) {

/* some error occured */

ctrt_printf("SA_FILES encountered the following error code(%n):\n, %s\n",

rc, SA_ERRMSG(rc));

}

...

SA_LOGOFF();

 

SA_FILES

Performs FairCom DB file administration operations.

Short Name

SA_FILES()

Type

System Administration

Declaration

NINT SA_FILES(COUNT action, saFILINFO * filinfo)

Description

The SA_FILES() function performs FairCom DB file administration operations. SA_FILES() accepts action, indicating the operation to perform, and filinfo, a pointer to an saFILINFO structure containing the data used in carrying out the specified operation.

The following action values are described in detail below:

Value Symbolic Constant Explanation
1 ctfPASS Change file password.
2 ctfPERM Change file permission mask.
3 ctfGROUP Change file group.
4 ctfOWNER Change file owner.

filinfo points to the FILE definition structure, saFILINFO, defined below. Each action value uses specific values in the saFILINFO structure. The other values are ignored.

typedef struct

{

  TEXT    fil_pass[FILEPWZ];       // File Password

  TEXT    fil_group[IDZ];      // File Group

  TEXT    fil_name[MAX_NAME];  // File name

  TEXT    fil_mask[16];        // File Permission mask

  TEXT    fil_owner[IDZ];      // File Owner

} saFILINFO;

The operations that SA_FILES() supports are described in detail below:

CHANGE FILE PASSWORD

To change the password for a file, declare a variable of type saFILINFO, set the fil_name field to the name of the file, and set the fil_pass field to the new password. Call SA_FILES() with the fPASS action and the address of your saFILINFO structure.

Example

COUNT     rc;

saFILINFO filinfo;


ctsfill(&filinfo, 0, sizeof(saFILINFO));

strcpy(filinfo.fil_name,    "data\\custmast.dat");

strcpy(filinfo.fil_pass,    "p%9ffL2x");


if ((rc = SA_FILES(ctfPASS, &filinfo)) != 0)

    printf("Change file password failed with error %d (%d).\n",

           rc, isam_err);

else

    printf("Successfully changed file password.\n");

CHANGE FILE PERMISSIONS

To change the security permissions for a file, declare a variable of type saFILINFO, set the fil_name field to the name of the file, and set the fil_mask field to the new permission mask. The fil_mask field is interpreted as a 15-byte permission mask containing owner, group, and world permissions:

 (offset)

 0   1   2   3   4   5   6   7   8   9  10  11  12  13  14

 ------OWNER------   ------GROUP------   ------WORLD------

 r   w   f   d   p   r   w   f   d   p   r   w   f   d   p

 

r = Read  w = Write  f = define  d = Delete  p = noPass

To set a permission, set the byte at the corresponding offset of fil_mask to a value of ‘+’; to reset a specified permission, set the corresponding byte to ‘-’. In the example below, the specified mask sets all OWNER and WORLD permissions, and resets all GROUP permissions.

Call SA_FILES() with the fPERM action and the address of your saFILINFO structure.

Example

COUNT     rc;

saFILINFO filinfo;


ctsfill(&filinfo, 0, sizeof(saFILINFO));

strcpy(filinfo.fil_name,    "data\\custmast.dat");

strcpy(filinfo.fil_mask,    "+++++-----+++++");


if ((rc = SA_FILES(ctfPERM, &filinfo)) != 0)

    printf("Change file permission mask failed: Error %d (%d).\n", rc,

           isam_err);

else

    printf("Successfully changed file permission mask.\n");

CHANGE FILE GROUP

To change the group to which a file belongs, declare a variable of type saFILINFO, set the fil_name field to the name of the file, and set the fil_group field to the new group. Call SA_FILES() with the fGROUP action and the address of your saFILINFO structure.

Example

COUNT     rc;

saFILINFO filinfo;


ctsfill(&filinfo, 0, sizeof(saFILINFO));

strcpy(filinfo.fil_name,    "data\\custmast.dat");

strcpy(filinfo.fil_group,   "SUPPORT");


if ((rc = SA_FILES(ctfGROUP, &filinfo)) != 0)

    printf("Change file group failed with error %d (%d).\n", rc, isam_err);

else

    printf("Successfully changed file group.\n");

CHANGE FILE OWNER

To change the owner for a file, declare a variable of type saFILINFO, set the fil_name field to the name of the file, and set the fil_owner field to the new owner. Call SA_FILES() with the fOWNER action and the address of your saFILINFO structure.

Example

COUNT     rc;

saFILINFO filinfo;


ctsfill(&filinfo, 0, sizeof(saFILINFO));

strcpy(filinfo.fil_name,    "data\\custmast.dat");

strcpy(filinfo.fil_owner,   "ADMIN");


if ((rc = SA_FILES(ctfOWNER, &filinfo)) != 0)

    printf("Change file owner failed with error %d (%d).\n", rc, isam_err);

else

    printf("Successfully changed file owner.\n");

Return

All server administration functions return a zero value to indicate success and a non-zero value (defined in cthelp.h) to indicate failure. In the case of failure, the global variable isam_err will be set to the FairCom DB error value. See c-tree Error Codes in the FairCom DB Programmer’s Reference Guide for a complete listing of error values.

Limitations

Requires SA_LOGON() call.

See also

SA_GROUP(), SA_USERSX(), SA_LOGON(), SA_LOGOF()

 

SA_GROUP

Performs operations on FairCom DB Groups.

Short Name

SA_GROUP()

Type

System Administration

Declaration

NINT SA_GROUP(COUNT action,saGRPINFO * grpinfo) 

Description

The SA_GROUP() function performs FairCom DB group operations. SA_GROUP() accepts action, indicating the operation to perform, and grpinfo, a pointer to an saGRPINFO structure containing the data used in carrying out the specified operation.

The following action values are described in detail below:

Value Symbolic Constant Description
1 ctgNEW Add a group.
2 ctgREMOVE Remove a group.
3 ctgLIST List all groups.
4 ctgMEMBAD Add a user to a group.
5 ctgDESC Change a group description.
6 ctgMEM Change group memory setting.
7 ctgSHOW Retrieve group settings.
8 ctgMEMBRM Remove a user from a group.

grpinfo points to the GROUP definition structure, saGRPINFO, defined below. Each action value uses specific values in the saGRPINFO structure. The other values are ignored.

typedef struct _saGRPI

{

  TEXT      grp_id[IDZ];        // Group Id

  TEXT      grp_desc[DSZ];      // Group Description

  TEXT      grp_memory[32];     // Group Memory Limit

  TEXT      grp_memrule[2];     // Group Memory Rule

  TEXT      grp_user[IDZ+1];    // User id to add or remove

  struct _saGRPI   *grp_list;   // Ptr to group list

} saGRPINFO;

The operations that SA_GROUP() supports are described in detail below:

ADD GROUP

To add a group, declare a variable of type saGRPINFO and set the fields as desired. The only required field is grp_id. Specify any of the other fields as an empty string to use the default value for that option. Call SA_GROUP() with the gNEW action and the address of your saGRPINFO structure.

Example

COUNT     rc;

saGRPINFO   grpinfo;


ctsfill(&grpinfo, 0, sizeof(saGRPINFO));

strcpy(grpinfo.grp_id,      "SUPPORT");

strcpy(grpinfo.grp_desc,    "Technical support");

strcpy(grpinfo.grp_memory,  "100000");

strcpy(grpinfo.grp_memrule, "D");


if ((rc = SA_GROUP(ctgNEW, &grpinfo)) != 0)

    printf("Add group failed with error %d (%d).\n", rc, isam_err);

else

    printf("Successfully added group.\n");

REMOVE GROUP

To remove a group, declare a variable of type saGRPINFO and set the grp_id field to the group id you wish to remove. Call SA_GROUP() with the gREMOVE action and the address of your saGRPINFO structure.

Example

COUNT     rc;

saGRPINFO grpinfo;


ctsfill(&grpinfo, 0, sizeof(saGRPINFO));

strcpy(grpinfo.grp_id,      "SUPPORT");


if ((rc = SA_GROUP(ctgREMOVE, &grpinfo)) != 0)

    printf("Remove group failed with error %d (%d).\n", rc, isam_err);

else

    printf("Successfully removed group.\n");

LIST GROUPS

To retrieve a list of all defined groups, call SA_GROUP() with the gLIST action and the address of your saGRPINFO structure. Upon successful completion, SA_GROUP() sets the grp_list field of the saGRPINFO structure you passed to it to point to a linked list of saGRPINFO structures. You can traverse the list to retrieve information about each group.

Example

COUNT     rc;

saGRPINFO grpinfo;


if ((rc = SA_GROUP(ctgLIST, &grpinfo)) != 0)

    printf("List groups failed with error %d (%d)\n", rc, isam_err);

else {

    saGRPINFO *pgrp, *tp;


    pgrp = grpinfo.grp_list;

    printf("\n\n%31s  %s\n%31s  %s", "Group Id",

           "Group Description",   "------------",

           "------------------------------------");

    while (pgrp) {

        printf("\n%31s  %s",pgrp->grp_id,pgrp->grp_desc);

        tp = pgrp;

        pgrp = pgrp->grp_list;

        mbfree(tp);

    }

    printf("\n");

}

ADD USER TO GROUP

To add a user to a group, declare a variable of type saGRPINFO, set the grp_id field to the desired group id, and set the grp_user field to the user id you wish to add to the specified group. Call SA_GROUP() with the gMEMBAD action and the address of your saGRPINFO structure.

Example

COUNT     rc;

saGRPINFO grpinfo;


ctsfill(&grpinfo, 0, sizeof(saGRPINFO));

strcpy(grpinfo.grp_id,      "SUPPORT");

strcpy(grpinfo.grp_user,    "ADMIN");


if ((rc = SA_GROUP(ctgMEMBAD, &grpinfo)) != 0)

    printf("Add user to group failed with error %d (%d)\n", rc, isam_err);

else

    printf("Successfully added user to group.\n");

CHANGE GROUP Description

To change the description for a group, declare a variable of type saGRPINFO, set the grp_id field to the desired group id, and set the grp_desc field to the new description. Call SA_GROUP() with the gDESC action and the address of your saGRPINFO structure.

Example

COUNT     rc;

saGRPINFO grpinfo;


ctsfill(&grpinfo, 0, sizeof(saGRPINFO));

strcpy(grpinfo.grp_id,      "SUPPORT");

strcpy(grpinfo.grp_desc,    "Product support group");


if ((rc = SA_GROUP(ctgDESC, &grpinfo)) != 0)

    printf("Change group description failed: Error %d (%d)\n", rc, isam_err);

else

    printf("Successfully changed group description.\n");

CHANGE GROUP MEMORY

To change the memory settings for a group, declare a variable of type saGRPINFO, set the grp_id field to the desired group, set the grp_memory field to the new memory limit, and set the grp_memrule field to the new memory rule. You can specify a field as an empty string to use the current value for that option. Call SA_GROUP() with the gMEM action and the address of your saGRPINFO structure.

Example

COUNT     rc;

saGRPINFO grpinfo;


ctsfill(&grpinfo, 0, sizeof(saGRPINFO));

strcpy(grpinfo.grp_id,      "SUPPORT");

strcpy(grpinfo.grp_memory,  "300000");

strcpy(grpinfo.grp_memrule,  "A");


if ((rc = SA_GROUP(ctgMEM, &grpinfo)) != 0)

    printf("Change group memory failed with error %d (%d).\n", rc, isam_err);

else

    printf("Successfully changed group memory.\n");

RETRIEVE GROUP SETTINGS

To retrieve the settings for a group, declare a variable of type saGRPINFO and set the grp_id field to the desired group id. Call SA_GROUP() with the gSHOW action and the address of your saGRPINFO structure. Upon successful completion, SA_GROUP() fills your saGRPINFO structure with the settings for the specified group.

Example

COUNT     rc;

saUSRINFO grpinfo;


ctsfill(&grpinfo, 0, sizeof(saGRPINFO));

strcpy(grpinfo.grp_id,      "SUPPORT");


if ((rc = SA_GROUP(ctgSHOW, &grpinfo)) != 0)

    printf("Retrieve group settings failed: Error %d (%d)\n", rc, isam_err);

else

{

    printf("\nGroup Id:    %s", grpinfo.grp_id);

    printf("\nDescription: %s", grpinfo.grp_desc);

    printf("\nUser Memory: %s", grpinfo.grp_memory);

    printf("\nMemory Rule: %s", grpinfo.grp_memrule);

    printf("\n");

}

REMOVE USER FROM GROUP

To remove a user from a group, declare a variable of type saGRPINFO, set the grp_id field to the desired group id, and set the grp_user field to the user id to wish to remove from the specified group. Call SA_GROUP() with the gMEMBRM action and the address of your saGRPINFO structure.

Example

COUNT     rc;

saGRPINFO grpinfo;


ctsfill(&grpinfo, 0, sizeof(saGRPINFO));

strcpy(grpinfo.grp_id,      "SUPPORT");

strcpy(grpinfo.grp_user,    "ADMIN");


if ((rc = SA_GROUP(ctgMEMBRM, &grpinfo)) != 0)

    printf("Remove user from group failed: Error %d (%d)\n", rc, isam_err);

else

    printf("Successfully removed user from group.\n");

Return

All server administration functions return a zero value to indicate success and a non-zero value (defined in cthelp.h) to indicate failure. In the case of failure, the global variable isam_err will be set to the FairCom DB error value. See c-tree Error Codes in the FairCom DB Reference Guide for a complete listing of error values.

Limitations

Requires SA_LOGON() call.

See also

SA_USERSX(), SA_FILES(), SA_LOGON(), SA_LOGOF()

 

SA_LOGOF

Close administration files and disconnect from FairCom DB.

Short Name

SA_LOGOF()

Type

System Administration

Declaration

NINT SA_LOGOF(); 

Description

The SA_LOGOF() function closes FairCom DB administration files and disconnects from FairCom DB.

Return

All server administration functions return a zero value to indicate success and a non-zero value (defined in cthelp.h) to indicate failure. In the case of failure, the global variable isam_err will be set to the FairCom DB error value. See c-tree Error Codes in the FairCom DB Programmer’s Reference Guide for a complete listing of error values.

Example

NINT      rc;

TEXT      auid[IDZ], apwd[PWX], fpwd[FILEPWZ], svrname[25];


if ((rc = SA_LOGON(auid, apwd, fpwd, svrname)) != 0)

    printf("\nSA_LOGON error = %d", rc);

else {

    DoAdmin();

    SA_LOGOF();

}

Limitations

Requires SA_LOGON() call.

See also

SA_GROUP(), SA_FILES(), SA_LOGON(), SA_USERSX()

 

SA_LOGON

Connects to FairCom DB in preparation for administration.

Short Name

SA_LOGON()

Type

System Administration

Declaration

NINT SA_LOGON(cpTEXT admnuid, cpTEXT admnpwd, cpTEXT filepwd, cpTEXT servername) 

Description

The SA_LOGON() function is used to connect to FairCom DB and open the server’s administrative files. To use the SA_USERS(), SA_GROUP(), and SA_FILES() functions, a program must first call SA_LOGON().

Return

All server administration functions return a zero value to indicate success and a non-zero value (defined in cthelp.h) to indicate failure. In the case of failure, the global variable isam_err will be set to the FairCom DB error value. See c-tree Error Codes in the FairCom DB Programmer’s Reference Guide for a complete listing of error values.

Example

NINT      rc;

TEXT      auid[IDZ], apwd[PWZX], fpwd[FILEPWZ], svrname[25];


if ((rc = SA_LOGON(auid, apwd, fpwd, svrname)) != 0)

    printf("\nSA_LOGON error = %d", rc);

else {

    DoAdmin();

    SA_LOGOF();

}

See also

SA_GROUP(), SA_FILES(), SA_USERSX(), SA_LOGOF()

 

SA_USERS

Perform user-related Server Administration. For versions 13.1 and beyond, you can use SA_USERSX for an equivalent function that is more fully featured. 

Short Name

SA_USERS()

Type

System Administration

Declaration

NINT SA_USERS(COUNT action, saUSRINFO * userinfo) 

Description

The SA_USERS() function performs user-related FairCom Server administration operations. SA_USERS() accepts action, indicating the operation to perform, and usrinfo, a pointer to a saUSRINFO structure whose fields contain the data used in the specified operation. The following action values are described in detail below:

Value Symbolic Constant Description
1 ctuNEW Add User
2 ctuREMOVE Remove User
3 ctuLIST List Users
4 ctuWORD Change User Password (63 character limit. Nine character limit V9 and prior.)
5 ctuGROUP Add User to Group
6 ctuDESC Change User Description
7 ctuMEM Change User Memory
8 ctuXINFO Change User Extended Info
9 ctuGROUPRM Remove User From Group
10 ctuSHOW Retrieve User Settings

usrinfo points to the USER definition structure, saUSRINFO, defined below. Each action value uses specific values in the saUSRINFO structure. The other values are ignored.

typedef struct _saUSRI
{
  TEXT    usr_pass[PWZX];          // User Password
  TEXT    usr_group[MAX_NAME];    // User Group
  TEXT    usr_id[IDZ];            // User Id
  TEXT    usr_desc[DSZ];          // User Description
  TEXT    usr_memory[11];         // User Memory Limit
  TEXT    usr_memrule[2];         // User Memory Rule
  TEXT    usr_xbegdat[11];        // Begin validity period
  TEXT    usr_xenddat[11];        // End validity period
  TEXT    usr_xlgnlmt[11];        // Invalid logon limit
  TEXT    usr_xlgnrsm[11];        // Logon block time remaining
  TEXT    usr_xmstlgn[11];        // Must logon limit
  struct _saUSRI    *usr_list;    // Ptr to user list
} saUSRINFO;

The operations that SA_USERS() supports are described in detail below:

ADD USER

To add a user, declare a variable of type saUSRINFO and set the fields as desired. The usr_id field is the only required field. Specify any of the other fields as an empty string to use the default value for that option. Call SA_USERS() with the ctuNEW action and the address of your saUSRINFO structure.

Example:

COUNT     rc;
saUSRINFO usrinfo;

ctsfill(&usrinfo, 0, sizeof(saUSRINFO));
strcpy(usrinfo.usr_id,      "QATEST");
strcpy(usrinfo.usr_desc,    "QA test account");
strcpy(usrinfo.usr_pass,    "qat$145");
strcpy(usrinfo.usr_group,   "QA");
strcpy(usrinfo.usr_memory,  "100000");
strcpy(usrinfo.usr_memrule, "D");
strcpy(usrinfo.usr_xbegdat, "05/23/1999");
strcpy(usrinfo.usr_xenddat, "12/31/1999");
strcpy(usrinfo.usr_xlgnlmt, "3");

if ((rc = SA_USERS(ctuNEW, &usrinfo)) != 0)
    printf("Add user failed with error %d (%d).\n", rc, isam_err);
else
    printf("Successfully added user.\n");
REMOVE USER

To remove a user, declare a variable of type saUSRINFO and set the usr_id field to the user id to remove. Call SA_USERS() with the ctuREMOVE action and the address of your saUSRINFO structure.

Example:

COUNT     rc;
saUSRINFO usrinfo;

ctsfill(&usrinfo, 0, sizeof(saUSRINFO));
strcpy(usrinfo.usr_id,      "QATEST");

if ((rc = SA_USERS(ctuREMOVE, &usrinfo)) != 0)
    printf("Remove user failed with error %d (%d).\n", rc, isam_err);
else
    printf("Successfully removed user.\n");
LIST USERS

To retrieve a list of all defined users, call SA_USERS() with the ctuLIST action and the address of your saUSRINFO structure. Upon successful completion, SA_USERS() sets the usr_list field of the saUSRINFO structure you passed to it to point to a linked list of saUSRINFO structures. You can traverse the list to retrieve information about each user.

Example:

COUNT     rc;
saUSRINFO usrinfo;

ctsfill(&usrinfo, 0, sizeof(saUSRINFO));
if ((rc = SA_USERS(ctuLIST, &usrinfo)) != 0)
    printf("List users failed with error %d (%d)\n", rc, isam_err);
else
{
    saUSRINFO *pusr, *tp;
    pusr = usrinfo.usr_list;
    printf("\n\n%31s  %s\n%31s  %s", "User Id",
           "User Description (Groups)","------------",
           "------------------------------------");
    while (pusr) {
        printf("\n%31s  %s", pusr->usr_id, pusr->usr_desc);
        if (pusr->usr_group[0]){
            if (pusr->usr_desc[0])
                printf(" ");
            printf("( %s )", pusr->usr_group);
        }
        tp = pusr;
        pusr = pusr->usr_list;
        mbfree(tp);
    }
    printf("\n");
}

CHANGE USER PASSWORD

To change the password for a user, declare a variable of type saUSRINFO, set the usr_id field to the user id whose password to change, and set the usr_pass field to the new password. Call SA_USERS() with the ctuWORD action and the address of your saUSRINFO structure.

Example

COUNT     rc;

saUSRINFO usrinfo;


ctsfill(&usrinfo, 0, sizeof(saUSRINFO));

strcpy(usrinfo.usr_id,      "QATEST");

strcpy(usrinfo.usr_pass,    "QATEST");


if ((rc = SA_USERS(ctuWORD, &usrinfo)) != 0)

    printf("Change user password failed. Error %d (%d).\n", rc, isam_err);

else

    printf("Successfully changed user password.\n");

ADD USER TO GROUP

To add a user to a group, declare a variable of type saUSRINFO, set the usr_id field to the desired user id, and set the usr_group field to the name of the group to which the user is to be added. Call SA_USERS() with the ctuGROUP action and the address of your saUSRINFO structure.

Example

COUNT     rc;

saUSRINFO usrinfo;


ctsfill(&usrinfo, 0, sizeof(saUSRINFO));

strcpy(usrinfo.usr_id,      "QATEST");

strcpy(usrinfo.usr_group,   "ADMIN");


if ((rc = SA_USERS(ctuGROUP, &usrinfo)) != 0)

    printf("Add user to group failed with error %d (%d).\n", rc, isam_err);

else

    printf("Successfully added user to group.\n");

CHANGE USER Description

To change the description for a user, declare a variable of type saUSRINFO, set the usr_id field to the desired user id, and set the usr_desc field to the new description. Call SA_USERS() with the ctuDESC action and the address of your saUSRINFO structure.

Example

COUNT     rc;

saUSRINFO usrinfo;


ctsfill(&usrinfo, 0, sizeof(saUSRINFO));

strcpy(usrinfo.usr_id,   "QATEST");

strcpy(usrinfo.usr_desc, "QA test account for SA_ADMIN");


if ((rc = SA_USERS(ctuDESC, &usrinfo)) != 0)

    printf("Change user description failed. Error %d (%d).\n", rc, isam_err);

else

    printf("Successfully changed user description.\n");

CHANGE USER MEMORY

To change the memory settings for a user, declare a variable of type saUSRINFO, set the usr_id field to the desired user id, set the usr_memory field to the new memory limit, and set the usr_memrule field to the new memory rule. You can specify a field as an empty string to use the current value for that option. Call SA_USERS() with the ctuMEM action and the address of your saUSRINFO structure.

Example

COUNT     rc;

saUSRINFO usrinfo;


ctsfill(&usrinfo, 0, sizeof(saUSRINFO));

strcpy(usrinfo.usr_id,      "QATEST");

strcpy(usrinfo.usr_memory,  "300000");

strcpy(usrinfo.usr_memrule,  "A");


if ((rc = SA_USERS(ctuMEM, &usrinfo)) != 0)

    printf("Change user memory failed with error %d (%d).\n", rc, isam_err);

else

    printf("Successfully changed user memory.\n");

CHANGE EXTENDED USER SETTINGS

To change the extended settings for a user, declare a variable of type saUSRINFO, set the usr_id field to the desired user id, set the usr_xbegdat field to the new start valid date, set the usr_xenddat field to the new end valid date, set the usr_xlgnlmt field to the new invalid logon limit, set the usr_xmstlgn field to the new must logon period (in minutes), and set the usr_xlgnrsm field to the new remaining logon timeout value (in minutes).

Use the format “mm/dd/yyyy” for the usr_xbegdat and usr_xenddat fields. You can specify a field as an empty string to use the current value for that option. Call SA_USERS() with the ctuXINFO action and the address of your saUSRINFO structure.

To use the system default for the invalid logon limit, set usr_xlgnlmt to 0. Set the usr_xlgnlmt and usr_xmsglgn fields to -1 to disable the “logon limit” and “must logon” checks, if desired.

Example

COUNT     rc;

saUSRINFO usrinfo;


ctsfill(&usrinfo, 0, sizeof(saUSRINFO));

strcpy(usrinfo.usr_id,      "QATEST");

strcpy(usrinfo.usr_xbegdat, "05/23/1999");

strcpy(usrinfo.usr_xenddat, "12/31/1999");

strcpy(usrinfo.usr_xlgnlmt, "3");

strcpy(usrinfo.usr_xmstlgn, "3600");

strcpy(usrinfo.usr_xlgnrsm, "0");


if ((rc = SA_USERS(ctuXINFO, &usrinfo)) != 0)

    printf("Change extended user settings failed: %d (%d).\n", rc, isam_err);

else

    printf("Successfully changed extended user settings.\n");

REMOVE USER FROM GROUP

To remove a user from a group, declare a variable of type saUSRINFO, set the usr_id field to the desired user id, and set the usr_group field to the name of the group from which the user is to be removed. Call SA_USERS() with the uctGROUPRM action and the address of your saUSRINFO structure.

Example

COUNT     rc;

saUSRINFO usrinfo;


ctsfill(&usrinfo, 0, sizeof(saUSRINFO));

strcpy(usrinfo.usr_id,      "QATEST");

strcpy(usrinfo.usr_group,   "ADMIN");


if ((rc = SA_USERS(ctuGROUPRM, &usrinfo)) != 0)

    printf("Remove user from group failed. Error %d (%d).\n", rc, isam_err);

else

    printf("Successfully removed user from group.\n");

RETRIEVE USER SETTINGS

To retrieve the settings for a user, declare a variable of type saUSRINFO and set the usr_id field to the desired user id. Call SA_USERS() with the ctuSHOW action and the address of your saUSRINFO structure. Upon successful completion, SA_USERS() fills your saUSRINFO structure with the settings for the specified user.

Example

COUNT     rc;

saUSRINFO usrinfo;


ctsfill(&usrinfo, 0, sizeof(saUSRINFO));

strcpy(usrinfo.usr_id,      "QATEST");


if ((rc = SA_USERS(ctuSHOW, &usrinfo)) != 0)

    printf("Retrieve user settings failed. Error %d (%d).\n", rc, isam_err);

else {

    ctrt_printf("\nUser Id:     %s", usrinfo.usr_id);

    ctrt_printf("\nDescription: %s", usrinfo.usr_desc);

    ctrt_printf("\nPassword:    *******");

    ctrt_printf("\nUser Memory: %s", usrinfo.usr_memory);

    ctrt_printf("\nMemory Rule: %s", usrinfo.usr_memrule);

    if (!usrinfo.usr_group[0])

        ctrt_printf("\nUser Groups: (None)");

    else

        ctrt_printf("\nUser Groups: %s", usrinfo.usr_group);

    printf("\n");

}

Return

All server administration functions return a zero value to indicate success and a non-zero value (defined in cthelp.h) to indicate failure. In the case of failure, the global variable isam_err will be set to the FairCom DB error value. See c-tree Error Codes in the FairCom DB Programmer’s Reference Guide for a complete listing of error values.

Limitations

Requires SA_LOGON() call.

See also

SA_USERSX, SA_GROUP(), SA_FILES(), SA_LOGON(), SA_LOGOF()

SA_USERSX

Perform user-related Server Administration.

Short Name

SA_USERSX()

Type

System Administration

Declaration

NINT SA_USERSX(COUNT action, saUSRINFOX * userinfo, size_t infosize)

Description

The SA_USERSX() function performs user-related FairCom Server administration operations. SA_USERSX() accepts the following parameters: 

action

The action parameter indicates the operation that will be performed. It accepts the following values:  

Value

Symbolic Constant

Description

1

ctuNEW

Add User

2

ctuREMOVE

Remove User

3

ctuLIST

List Users

4

ctuWORD

Change User Password (63 character limit. Nine character limit V9 and prior.)

5

ctuGROUP

Add User to Group

6

ctuDESC

Change User Description

7

ctuMEM

Change User Memory

8

ctuXINFO

Change User Extended Info

9

ctuGROUPRM

Remove User From Group

10

ctuSHOW

Retrieve User Settings

usrinfo

The usrinfo parameter points to the USER definition structure, saUSRINFOX, as defined below. Each action value uses specific values in the saUSRINFOX structure. The other values are ignored.

typedef struct _saUSRX1

{

 TEXT    usr_pass[PWZX];          // User Password

 TEXT    usr_group[MAX_NAME];    // User Group

 TEXT    usr_id[IDZ];            // User Id

 TEXT    usr_desc[DSZ];          // User Description

 TEXT    usr_memory[11];         // User Memory Limit

 TEXT    usr_memrule[2];         // User Memory Rule

 TEXT    usr_xbegdat[11];        // Begin validity period

 TEXT    usr_xenddat[11];        // End validity period

 TEXT    usr_xlgnlmt[11];        // Invalid logon limit

 TEXT    usr_xlgnrsm[11];        // Logon block time remaining

 TEXT    usr_xmstlgn[11];        // Must logon limit

 struct _saUSRX1    *usr_list;    // Ptr to user list

 UTEXT   version;                 // structure version

 TEXT    lastPasswordChange[11]   // Date of last password change

} saUSRINFOX;

 

infosize

 

The infosize parameter indicates the size of the structure (in bytes) pointed to by usrinfo. 

 

Operations supported by SA_USERSX(): 

ADD USER

To add a user, declare a variable of type saUSRINFOX and set the fields as desired. The version and usr_id field is the only required field. Specify any of the other fields as an empty string to use the default value for that option. Call SA_USERSX() with the ctuNEW action and the address of your saUSRINFOX structure.

Example

COUNT     rc;

saUSRINFOX usrinfo;


memset(&usrinfo, 0, sizeof(saUSRINFOX));

strcpy(usrinfo.usr_id,      "QATEST");

strcpy(usrinfo.usr_desc,    "QA test account");

strcpy(usrinfo.usr_pass,    "qat$145");

strcpy(usrinfo.usr_group,   "QA");

strcpy(usrinfo.usr_memory,  "100000");

strcpy(usrinfo.usr_memrule, "D");

strcpy(usrinfo.usr_xbegdat, "05/23/1999");

strcpy(usrinfo.usr_xenddat, "12/31/1999");

strcpy(usrinfo.usr_xlgnlmt, "3");

usrinfo.version = saUSRINFOX_CURRENT_VERSION;


if ((rc = SA_USERSX(ctuNEW, &usrinfo,sizeof(usrinfo))) != 0)

   printf("Add user failed with error %d (%d).\n", rc, isam_err);

else

   printf("Successfully added user.\n");

REMOVE USER

To remove a user, declare a variable of type saUSRINFOX and set the version and usr_id field to the user id to remove. Call SA_USERSX() with the ctuREMOVE action and the address of your saUSRINFO structure.

Example

COUNT     rc;

saUSRINFOX usrinfo;


memset(&usrinfo, 0, sizeof(saUSRINFOX));

strcpy(usrinfo.usr_id,      "QATEST");

usrinfo.version = saUSRINFOX_CURRENT_VERSION;


if ((rc = SA_USERSX(ctuREMOVE, &usrinfo, sizeof(usrinfo)) != 0)

   printf("Remove user failed with error %d (%d).\n", rc, isam_err);

else

   printf("Successfully removed user.\n");

LIST USERS

To retrieve a list of all defined users, call SA_USERSX() with the ctuLIST action and the address of your saUSRINFOX structure. Upon successful completion, SA_USERSX() sets the usr_list field of the saUSRINFOX structure you passed to it to point to a linked list of saUSRINFO structures. You can traverse the list to retrieve information about each user. Each returned usr_list element must be freed with mbfree().

Example

COUNT     rc;

saUSRINFOX usrinfo;


memset(&usrinfo, 0, sizeof(saUSRINFOX));

usrinfo.version = saUSRINFOX_CURRENT_VERSION;

if ((rc = SA_USERSX(ctuLIST, &usrinfo, sizeof(usrinfo))) != 0)

   printf("List users failed with error %d (%d)\n", rc, isam_err);

else

{

   saUSRINFOX *pusr, *tp;

   pusr = usrinfo.usr_list;

   printf("\n\n%31s  %s\n%31s  %s", "User Id",

          "User Description (Groups)","------------",

          "------------------------------------");

   while (pusr) {

       printf("\n%31s  %s", pusr->usr_id, pusr->usr_desc);

       if (pusr->usr_group[0]){

           if (pusr->usr_desc[0])

               printf(" ");

           printf("( %s )", pusr->usr_group);

       }

       tp = pusr;

       pusr = pusr->usr_list;

       mbfree(tp);

   }

   printf("\n");

}

CHANGE USER PASSWORD

To change the password for a user, declare a variable of type saUSRINFOX, set the version and usr_id field to the user id whose password to change, and set the usr_pass field to the new password. Call SA_USERSX() with the ctuWORD action and the address of your saUSRINFOX structure.

Example

COUNT     rc;

saUSRINFOX usrinfo;


memset(&usrinfo, 0, sizeof(saUSRINFOX));

usrinfo.version = saUSRINFOX_CURRENT_VERSION;

strcpy(usrinfo.usr_id,      "QATEST");

strcpy(usrinfo.usr_pass,    "QATEST");


if ((rc = SA_USERSX(ctuWORD, &usrinfo, sizeof(usrinfo))) != 0)

   printf("Change user password failed. Error %d (%d).\n", rc, isam_err);

else

   printf("Successfully changed user password.\n");

ADD USER TO GROUP

To add a user to a group, declare a variable of type saUSRINFOX, set the version and usr_id field to the desired user id, and set the usr_group field to the name of the group to which the user is to be added. Call SA_USERSX() with the ctuGROUP action and the address of your saUSRINFOX structure.

Example

COUNT     rc;

saUSRINFOX usrinfo;


memset(&usrinfo, 0, sizeof(saUSRINFOX));

usrinfo.version = saUSRINFOX_CURRENT_VERSION;

strcpy(usrinfo.usr_id,      "QATEST");

strcpy(usrinfo.usr_group,   "ADMIN");


if ((rc = SA_USERSX(ctuGROUP, &usrinfo)) != 0)

   printf("Add user to group failed with error %d (%d).\n", rc, isam_err);

else

   printf("Successfully added user to group.\n");

CHANGE USER Description

To change the description for a user, declare a variable of type saUSRINFOX, set the version and usr_id field to the desired user id, and set the usr_desc field to the new description. Call SA_USERSX() with the ctuDESC action and the address of your saUSRINFOX structure.

Example

COUNT     rc;

saUSRINFOX usrinfo;


memset(&usrinfo, 0, sizeof(saUSRINFOX));

usrinfo.version = saUSRINFOX_CURRENT_VERSION;

strcpy(usrinfo.usr_id,   "QATEST");

strcpy(usrinfo.usr_desc, "QA test account for SA_ADMIN");


if ((rc = SA_USERSX(ctuDESC, &usrinfo, sizeof(usrinfo))) != 0)

   printf("Change user description failed. Error %d (%d).\n", rc, isam_err);

else

   printf("Successfully changed user description.\n");

CHANGE USER MEMORY

To change the memory settings for a user, declare a variable of type saUSRINFOX, set the version, set the usr_id field to the desired user id, set the usr_memory field to the new memory limit, and set the usr_memrule field to the new memory rule. You can specify a field as an empty string to use the current value for that option. Call SA_USERSX() with the ctuMEM action and the address of your saUSRINFOX structure.

Example

COUNT     rc;

saUSRINFOX usrinfo;


memset(&usrinfo, 0, sizeof(saUSRINFOX));

usrinfo.version = saUSRINFOX_CURRENT_VERSION;

strcpy(usrinfo.usr_id,      "QATEST");

strcpy(usrinfo.usr_memory,  "300000");

strcpy(usrinfo.usr_memrule,  "A");


if ((rc = SA_USERSX(ctuMEM, &usrinfo, sizeof(usrinfo))) != 0)

   printf("Change user memory failed with error %d (%d).\n", rc, isam_err);

else

   printf("Successfully changed user memory.\n");

CHANGE EXTENDED USER SETTINGS

To change the extended settings for a user, declare a variable of type saUSRINFOX, set the version,  set the usr_id field to the desired user id, set the usr_xbegdat field to the new start valid date, set the usr_xenddat field to the new end valid date, set the usr_xlgnlmt field to the new invalid logon limit, set the usr_xmstlgn field to the new must logon period (in minutes), and set the usr_xlgnrsm field to the new remaining logon timeout value (in minutes).

Use the format “mm/dd/yyyy” for the usr_xbegdat and usr_xenddat fields. You can specify a field as an empty string to use the current value for that option. Call SA_USERSX() with the ctuXINFO action and the address of your saUSRINFOX structure.

To use the system default for the invalid logon limit, set usr_xlgnlmt to 0. Set the usr_xlgnlmt and usr_xmsglgn fields to -1 to disable the “logon limit” and “must logon” checks, if desired.

Example

COUNT     rc;

saUSRINFOX usrinfo;


memset(&usrinfo, 0, sizeof(saUSRINFOX));

usrinfo.version = saUSRINFOX_CURRENT_VERSION;

strcpy(usrinfo.usr_id,      "QATEST");

strcpy(usrinfo.usr_xbegdat, "05/23/1999");

strcpy(usrinfo.usr_xenddat, "12/31/1999");

strcpy(usrinfo.usr_xlgnlmt, "3");

strcpy(usrinfo.usr_xmstlgn, "3600");

strcpy(usrinfo.usr_xlgnrsm, "0");


if ((rc = SA_USERSX(ctuXINFO, &usrinfo, sizeof(usrinfo))) != 0)

   printf("Change extended user settings failed: %d (%d).\n", rc, isam_err);

else

   printf("Successfully changed extended user settings.\n");

REMOVE USER FROM GROUP

To remove a user from a group, declare a variable of type saUSRINFOX, set the version, set the usr_id field to the desired user id, and set the usr_group field to the name of the group from which the user is to be removed. Call SA_USERSX() with the uctGROUPRM action and the address of your saUSRINFOX structure.

Example

COUNT     rc;

saUSRINFOX usrinfo;


memset(&usrinfo, 0, sizeof(saUSRINFOX));

usrinfo.version = saUSRINFOX_CURRENT_VERSION;

strcpy(usrinfo.usr_id,      "QATEST");

strcpy(usrinfo.usr_group,   "ADMIN");


if ((rc = SA_USERSX(ctuGROUPRM, &usrinfo, sizeof(usrinfo))) != 0)

   printf("Remove user from group failed. Error %d (%d).\n", rc, isam_err);

else

   printf("Successfully removed user from group.\n");

RETRIEVE USER SETTINGS

To retrieve the settings for a user, declare a variable of type saUSRINFOX and set the version, set the usr_id field to the desired user id. Call SA_USERSX() with the ctuSHOW action and the address of your saUSRINFOX structure. Upon successful completion, SA_USERSX() fills your saUSRINFOX structure with the settings for the specified user.

Example

COUNT     rc;

saUSRINFOX usrinfo;

time_t     utctime;


memset(&usrinfo, 0, sizeof(saUSRINFOX));

usrinfo.version = saUSRINFOX_CURRENT_VERSION;

strcpy(usrinfo.usr_id,      "QATEST");


if ((rc = SA_USERSX(ctuSHOW, &usrinfo, sizeof(usrinfo))) != 0)

   printf("Retrieve user settings failed. Error %d (%d).\n", rc, isam_err);

else {

   ctrt_printf("\nUser Id:     %s", usrinfo.usr_id);

   ctrt_printf("\nDescription: %s", usrinfo.usr_desc);

 

   if (!usrinfo.usr_group[0])

       ctrt_printf("\nUser Groups: (None)");

   else

       ctrt_printf("\nUser Groups: %s", usrinfo.usr_group);

   utctime = (time_t)atoi(usrinfo.lastPasswordChange);

   ctrt_printf("\nLast password change: %s",myformat_UTC(utctime));

   printf("\n");

}

Return

All server administration functions return a zero value to indicate success and a non-zero value (defined in cthelp.h) to indicate failure. In the case of failure, the global variable isam_err will be set to the FairCom DB error value. See c-tree Error Codes in the FairCom DB Programmer’s Reference Guide for a complete listing of error values.

Limitations

Requires SA_LOGON() call.

See also

SA_GROUP()SA_FILES()SA_LOGON()SA_LOGOF()

 

SA_WILDCARD

SA ADMIN function to find a file using a wildcard specification.

Declaration

NINT SA_WILDCARD(pTEXT infilnam, NINT mode, pTEXT outfilnam, NINT outfillen)

Description

  • infilnam is the wildcard filename
  • opcode is one of the following:
FindFileByName opcode Explanation
ctFILWCDfind start new search
ctFILWCDfindnext find next file
ctFILWCDfindclose terminate current search
  • outfilnam is the buffer to hold the found filename
  • poutfillen points to the output buffer size

Note: The wildcard logic finds all files matching the wildcard specification — there is no check that the file is a c-tree data or index file. The wildcard logic also finds memory files whose names match the specified filename.

Return

Value Symbolic Constant Explanation
0 NO_ERROR No error occurred.

See c-tree Error Codes for a complete listing of valid c-tree error values.

Example SA ADMIN API pseudocode


#define MAX_SIZE 1024 /* 1K buffer size */

pText pFilelist;

int ListLength = MAX_SIZE


pFileList = (pText) malloc (sizeOf(pText) * MAX_SIZE);

memset(pFileList, 0, MAX_SIZE);


SA_LOGON("ADMIN", "ADMIN", NULL, "FAIRCOMS");

...

if ((rc = SA_WILDCARD("jrnl*.dat", ctFILWDfindfirst, pFilelist, ListLength)) !=0 ) {

ctrt_printf("SA_WILDCARD encountered the following error code(%n):\n", rc);

}

...


SA_LOGOFF();

 

SECURITY (function)

Modifies a file’s security settings, including password, group ID, and permission mask.

Short Name

SECURITY()

Type

Server only - FairCom DB File and User Security are available only when using the client/server operational model.

Declaration

COUNT Security(FILNO filno, pVOID bufptr, VRLEN bufsiz, COUNT mode) 

Description

In V12 the file number typedef was formally changed from COUNT, a two-byte value to FILNO, a four-byte value. Refer to this link for compatibility details. Four Byte File Numbering

Security() permits the owner of a file to change a file’s security information, including the file’s password, Group ID, and permission mask. Security() permits members of the ADMIN group to change the default number of allowed consecutive logon failures or the default time to deny logon attempts after the failure limit is reached.

For file security changes to file number filno: bufptr points to the buffer containing the updated security information and bufsiz specifies the length of the buffer. The contents of the buffer will differ based on the mode. See the section below for a description of what to pass in the buffer. See the section below for a description on what to pass in the buffer.

The buffer should contain the old password, NULL terminated, immediately followed by the new information, also NULL terminated, which can be the new file password, new file group ID, new owner user ID, or the new permission mask. If you are changing the permission mask, the value following the NULL terminated old password must be a long integer containing the appropriate OR-ed permission values. To remove a password, simply pass a NULL byte for the new password. If you change the file owner, you will not be able to make additional calls to Security, only the new owner will be able to do so.

Note: FAIRCOM.FCS can be opened only by a member of the ADMIN group. ADMIN group members can read data from FAIRCOM.FCS using low-level or ISAM function calls but cannot update FAIRCOM.FCS, other than through calls through the SECURITY() API function.

mode defines the type of request. The values for mode are:

Value Symbolic Constant Interpretation
1 SEC_FILEWORD Change file password.
2 SEC_FILEGRUP Change file group.
3 SEC_FILEMASK Change file permission mask.
4 SEC_FILEOWNR Change file owner.
5 SEC_FAIL_LIMIT Set logon failure limit.
7 SEC_FAIL_TIME Set logon failure time.
8 SEC_MUST_TIME Set minimum time between logons.
9 SEC_BLOCK_NONADM Block new logons except ADMIN group members.
10 SEC_BLOCK_NONSUP Block new logons except ADMIN user ID.
11 SEC_BLOCK_OFF Stop blocking new logons.
12 SEC_BLOCK_KILL Block new logons except ADMIN user ID, suspend internal threads that might open files, and kill any current connections and dumps.
13 SEC_ADD_USER Add user account
14 SEC_REMOVE_USER Remove user account
15 SEC_CHANGE_USER_GROUPS Change user group membership
16 SEC_CHANGE_USER_DESC Change user description
17 SEC_CHANGE_USER_PASSWD Change user password
18 SEC_CHANGE_USER_MEMORY Change user memory limit
19 SEC_CHANGE_USER_XINFO Change user extended settings
20 SEC_ADD_GROUP Add group
21 SEC_REMOVE_GROUP Remove group
22 SEC_CHANGE_GROUP_DESC Change group description
23 SEC_CHANGE_GROUP_MEMORY Change group memory limit
24 SEC_CHANGE_ADVENC_PASSWD Change the master password
25 SEC_CHANGE_USER_LOGLMT Change user logon limit
26 SEC_CHANGE_GROUP_LOGLMT Change group logon limit
27 SEC_CHECK_ADVENC_PASSWD Check the master password for advanced encryption

filno is ignored when mode is SEC_FAIL_LIMIT or SEC_FAIL_TIME.

Buffer Contents

SEC_ADD_USER

2-byte extended user settings file number (FAIRCOM.FCS!UVAL.dat)

2-byte group file number (FAIRCOM.FCS!GROUP.dat)

2-byte user group file number (FAIRCOM.FCS!USER.dat)

2-byte FC_USER length

FC_USER data

2-byte FC_UVAL length

FC_UVAL data

1-byte number of groups

group 0 name, group 1 name, ... (NULL terminated strings)

 

SEC_REMOVE_USER

2-byte extended user settings file number (FAIRCOM.FCS!UVAL.dat)

2-byte user group file number (FAIRCOM.FCS!USER.dat)

null-terminated user name

 

SEC_CHANGE_USER_PASSWD

null-terminated user name

null-terminated user password

 

SEC_CHANGE_USER_GROUPS

2-byte group file number

2-byte user group file number

null-terminated user ID

1-byte number of groups

group 0 name, group 1 name, ... (NULL terminated strings)

 

SEC_CHANGE_USER_DESC

null-terminated user name

null-terminated user description

 

SEC_CHANGE_USER_MEMORY

null-terminated user name

4-byte user memory

4-byte user memory attribute

 

SEC_CHANGE_USER_XINFO

2-byte extended user settings file number

2-byte user group file number

2-byte FC_UVAL length

FC_UVAL data

 

SEC_CHANGE_USER_LOGLMT

null-terminated user name

4-byte user logon limit

 

SEC_ADD_GROUP

2-byte FC_GROUP length

 

FC_GROUP Data

SEC_CHANGE_GROUP_DESC

null-terminated group name

null-terminated group description

 

SEC_CHANGE_GROUP_MEMORY

null-terminated group name

4-byte group memory

4-byte group memory attribute

 

SEC_CHANGE_GROUP_LOGLMT

null-terminated group name

4-byte group logon limit

 

SEC_FILEWORD

null-terminated password

 

SEC_FILEMASK

1-byte set to 0

filemask

 

SEC_FILEGRUP

null-terminated group name

 

SEC_FILEOWNR

null-terminated owner name

 

SEC_CHECK_ADVENC_PASSWD

Check if the specified master encryption password matches FairCom Server's current master encryption password. This feature is only supported in client/server mode and can only be done by a user account that is a member of the ADMIN group. To use this feature, call the SECURITY() function as described below:

  • FILNO filno - Set to -1.
  • pVOID bufptr - Pass the advanced encryption password as a null-terminated string.
  • VRLEN bufsiz -Set to the length of the advanced encryption password in bytes including the null terminator.
  • COUNT mode - Set to SEC_CHECK_ADVENC_PASSWD.

If called by a user account that is not a member of the ADMIN group, the function returns error LADM_ERR (589).

If advanced encryption is not enabled, the function call returns error NSUP_ERR (454).

If the specified master password does not match the master password that FairCom Server is currently using, the function returns error BMPW_ERR (932).

 

One-Time Password

To establish a one-time password that another client can use, along with the user ID matching the caller that set the password, set bufptr to a special, (0x01 in first byte), one-time password and plen to the length of the password. filno is ignored. The password is available until it is used by the subsequent client with a matching user ID or the caller of Security logs off. The password set by the original caller MUST begin with a byte of value 0x01, otherwise it will be ignored.

To change the Logon Fail Limit in real time regardless of setting file or configuration file entries, point bufptr to a LONG holding the new LOGON_FAIL_LIMIT value. The value is stored in FAIRCOM.FCS and can only be changed by a subsequent call to Security or by replacing FAIRCOM.FCS. filno is ignored.

To change the time interval regardless of setting file or configuration file entries, point bufptr to a LONG holding the new LOGON_FAIL_TIME value in minutes. The value is stored in FAIRCOM.FCS and can only be changed by a subsequent call to Security or by replacing FAIRCOM.FCS. filno is ignored.

FC_UVAL Structure

The FC_UVAL structure holds settings used by the SECURITY() function. Some of the mode settings require setting values in this structure.

 

typedef struct {

  TEXT  userid[32];

  ULONG begstamp;      /* beginning date for valid user logon     */

  ULONG endstamp;      /* last valid date for user logon          */

  LONG  lgonover;      /* limit on consecutive logon failures     */

  LONG  reserved;

  ULONG rsmstamp;      /* temporary logon block                   */

  LONG  lgonfail;      /* current number of failed login attempts */

  ULONG lgonany;       /* last logon attempt date                 */

  ULONG lgonok;        /* last successful login date              */

  ULONG lgonbad;       /* last failed login date                  */

  LONG  lgonoknum;     /* Total number of successful logins(ever) */

  LONG  lgonbadnum;    /* Total number of failed logins(ever)     */

  ULONG disstamp;      /* when logon was disabled                 */

  LONG  lgonmust;      /* user must login within this period      */

  ULONG lastpasschg;   /* time of last change to password         */

  ULONG passvaliddays; /* number of days that password is valid   */

  TEXT  resrv[92];

} FC_UVAL;

 

When calling SECURITY() with mode of SEC_FAIL_LIMIT to set the logon failure limit, set the maximum limit in lgonover.

When calling SECURITY() with mode of SEC_FAIL_TIME to set the logon failure time, set the maximum time (in seconds) in lgonmust.

When calling SECURITY() with mode of SEC_CHANGE_USER_XINFO to set an expiration date on a user account password, set the passvaliddays field of the FC_UVAL structure to the password validity period in days. A value of zero sets no password expiration. When a user account's password has expired, attempting to log on to the user account fails with error 1116 (PWDEXP_ERR). This feature is also available in the ctadmn and sa_admin utilities.

Return

Value Symbolic Constant Explanation
0 NO_ERROR Successful open of ISAM files.
22 FNUM_ERR File number is out of range.
47 FINT_ERR c-tree has not been initialized.
48 FMOD_ERR Invalid mode value.
62 LERR_ERR File must be opened exclusively.
153 VBSZ_ERR Input does not match size of LONG.
447 BOWN_ERR Only the user/owner can change the user/file password.
448 DEFP_ERR File definition permission denied.
451 LPWD_ERR The old password is not valid.
455 SGRP_ERR The file owner does not belong to the new group.
456 SACS_ERR Group access denied.
458 SWRT_ERR Write permission not granted.
580 FSEC_ERR Negative value input.
584 LRSM_ERR Logon fail limit exceeded, wait for timeout.
589 LADM_ERR User not a member of the ADMIN group.
924 SADM_ERR Only the super administrator user account (named ADMIN) can perform this operation.
925 SCMP_ERR The FairCom DB client is attempting to use features of the SECURITY() API function that this FairCom Server does not support. Update your FairCom Server.

See c-tree Error Codes for a complete listing of valid c-tree error values.

 

API Call to Verify Server Master Password

The SECURITY() function now supports the ability to check if the specified master encryption password matches the FairCom Server's current master encryption password. It provides the ability to check that the user is able to connect as ADMIN.

This feature is only supported in client/server mode and can only be accessed by a user account that is a member of the ADMIN group. To use this feature, call the SECURITY() function as described below:

SECURITY() parameters:

  • COUNT filno: Set to -1.
  • pVOID bufptr: Pass the advanced encryption password as a null-terminated string.
  • VRLEN bufsiz: Set to the length of the advanced encryption password in bytes including the null terminator.
  • COUNT mode: Set to SEC_CHECK_ADVENC_PASSWD.

Function return values for this mode:

  • The function returns NO_ERROR(0) on success.
  • If called by a user account that is not a member of the ADMIN group, the function returns error LADM_ERR (589).
  • If advanced encryption is not enabled, the function call returns error NSUP_ERR (454).
  • If the specified master password does not match the master password that c-tree Server is currently using, the function returns error BMPW_ERR (932).

 

 

Changing the Master Password

To change the master password using the SECURITY() function:

  1. Call the SECURITY() function with the SEC_CHANGE_ADVENC_PASSWD mode.
  2. Specify filno of -1.
  3. Set bufptr to point to a buffer that holds the master password change information and set bufsiz to the size of the buffer.

    The buffer must conform to the ctENCMOD structure definition shown below:

    typedef struct ctencmod
    { LONG options; LONG numfiles; TEXT varinf[4]; }
    ctENCMOD, *pctENCMOD;
     
  4. Set options to ctENCMODlowl
  5. Set numfiles to the number of files whose names are specified in the varinf field (do not include the current and new master passwords in this count even though those values are also specified as the first two strings in the varinf field).
  6. In the varinf field, store the following values as null-terminated strings:
    • the current master password
    • the new master password
    • the first c-tree file name
    • the second c-tree file name
    • ...
    • the Nth c-tree file name (where N equals numfiles)

When using the FairCom Server master password change interface, FairCom Server attempts to change the master password for the specified files and for all active, inactive, and template transaction logs that it knows about. If any of the files cannot be changed, the entire operation is undone. When the entire operation is successful, the ctsrvr.pvf file is also updated using the new master password.

If an error happens on the transaction logs but the FairCom Server terminates before it can undo the changes, some files may be left using the new master password but the master password is still set to the old value. In this case, the ctencrypt standalone utility (see Changing the master password using the ctencrypt standalone utility) can be used to change the master password for those c-tree data, index, or transaction log files that need to be changed.

Error Codes

Two error codes have been added:

           
Value Symbolic Constant Interpretation
932 BMPW_ERR The specified encryption master password is incorrect.  
933 ICOD_ERR An encryption operation failed due to an unexpected internal error. See CTSTATUS.FCS for details.  

See c-tree Error Codes for a complete listing of valid c-tree error values.


This also requires that the ALLOW_MASTER_KEY_CHANGE configuration option is enabled, as explained in the FairCom DB Server Administrator's Guide.

See also

See Security and Encryption (File Security and Encryption, /doc/ctreeplus/FileSecurityandEncryption.htm) in the c-tree Programmer’s Reference Guide for more information.

Ability to Validate against Advanced Encryption Master Password

FairCom Server now supports the ability to check if a client-provided master encryption password matches FairCom Server's current master encryption password. The use case for this feature is an elevated level of access beyond ADMIN authentication. Knowing the master encryption password implies the calling user has elevated privileges.

The server is assumed already started with a valid master key. A new SECURITY() (SECURITY (function), Security) API mode makes this check against the current master key.

 

SetAlternateSequence

Establishes an alternative collating sequence for an index file.

Short Name

SETALTSEQ()

Type

Low-Level index file resource function

Declaration

COUNT SetAlternateSequence(FILNO keyno, pCOUNT altseq)  

Description

In V12 the file number typedef was formally changed from COUNT, a two-byte value to FILNO, a four-byte value. Refer to this link for compatibility details. Four Byte File Numbering

SetAlternateSequence() assigns an alternative collating sequence to index keyno, which has just been created and not yet closed, or has been opened exclusively. Resources must be enabled for the index file in order to complete this function successfully.

altseq points to an array of 256 short integers representing the new collating sequence. The zero’th and 255th entries in the array must be zero and 255, respectively. All other entries must be between zero and 255, inclusively. The value in the array determines where the underlying byte value will be mapped: a high value implies toward the end of the sequence.

Although this is a low level function, it ordinarily only applies to ISAM level key operations in which segment mode 32 (ALTSEG) is used to specify the use of an alternative collating sequence. See alternate collating sequence in the index for additional information.

Return

Value Symbolic Constant Explanation
22 FNUM_ERR keyno out of range.
47 FINT_ERR c-tree has not been initialized.
48 FMOD_ERR This function does not apply to data files.
62 LERR_ERR File must be opened exclusively.
401 RNON_ERR RESOURCES not enabled.
448 DEFP_ERR File definition permission denied.

See c-tree Error Codes for a complete listing of valid c-tree error values.

Example

/* The start of a full alpha sort: A, a, B, b, etc. */


  COUNT altseq[256];


    altseq['A'] = 65;

    altseq['a'] = 66;

    altseq['B'] = 67;

    altseq['b'] = 68;

/* Fill in ALL values in the array. */

See also

GetAlternateSequence()

 

SetCallbackOnRebuild

Sets up a callback function that file reconstruction functions call as progress is made during an operation.

Short Name

SETCBRBL()

Type

Low-Level function

Declaration

COUNT SetCallbackOnRebuild( pVOID funcptr, UCOUNT step ) 

Description

SetCallbackOnRebuild() sets a pointer to a callback function that is periodically called by the file reconstruction functions RebuildIFile(), RebuildIFileXtd(), CompactIFile(), and CompactIFileXtd(). The callback function can be used for progress notification and to implement a custom user interface for rebuild utility programs.

When the rebuild callback support is activated, an internal counter is incremented every time a record or key is processed during the reconstruction process. The callback function is called each time the internal counter reaches a value that is a multiple of step. If step is set to 1, the callback function is called once per record/key. The ability of setting the callback frequency, gives the user the ability to balance between speed and accuracy.

The funcptr must be a pointer to a callback function of type RBLCBFNC that accepts three parameters. The function prototype is shown below.

void (*pRBLCBFNC)(ULONG counter, TEXT event, pTEXT message);

  • counter is the current value of the internal counter.
  • event identifies the type of event that triggered the callback. event options are listed in the following table:
event Interpretation
RBLCB_DAT counter reached a multiple of step while processing data records.
RBLCB_IDX counter reached a multiple of step while processing index keys.
RBLCB_MSG A pointer to a NULL terminated string that contains information about the status of the rebuild process is passed to the message parameter.
RBLCB_LOG Flag to write to a user defined log file. counter is 1 for error, 0 for informational.
RBLCB_CNT return total number of records in file/index
RBLCB_MCT return percentage complete * 10 (of current stage of rebuild)
  • message is a text string to be returned.

Return

Always returns NO_ERROR (0).

Example CTRBLEX.C in the ctree\samples directory

IFIL my_ifil = {...};


void CallbackProc( ULONG counter, TEXT event, TEXT* message )

{

   switch(event)

   {

      case RBLCB_DAT:

         putchar('d');

         break;

      case RBLCB_IDX:

         putchar('i');

         break;

      case RBLCB_MSG:

         printf("\n%s", message);

         break;

      case RBLDB_CNT:

         printf("\n%s", counter);

         break;

      case RBLCB_LOG:

         printf("\n%s", message);

         break;

      case RBLDB_MCT:

         printf("\n%s", (double) counter / 10);

   }

}


void main()

{

   SetCallbackOnRebuild( CallbackProc, 1 );

   RebuildIFile( &my_ifil );

}

See also

RebuildIFile()

RebuildIFileXtd()

CompactIFile()

CompactIFileXtd()

GETCBRBLST

 

GETCBRBLST

Returns the current rebuild callback state.

Declaration

ctCONV pctRBCBST ctDECL GETCBRBLST (VOID)

Description

Specific rebuild callback information can be passed back to the calling client via this structure. This is a useful feature that allows canceling a rebuild from the rebuild callback function. A call to this function returns a pointer to the rebuild callback state structure ctrbcbst.

 

typedef struct ctrbcbst {

LONG rcblen; /* number of data bytes in structure */

LONG rcbhw; /* counter high word value */

COUNT rcbrc; /* rebuild callback return code */

} ctRBCBST, ctMEM * pctRBCBST;

 

/* Size of rebuild callback state structure, version 1 */

#define ctRCBLEN_V01 10

Return Values

Returns a pointer to the ctrcbst state structure.

Example

To enable a clean rebuild cancel from within a callback, consider the following.


void myRebuildCallback( LONG counter, TEXT event, pTEXT message ) {
 

    pctRBCBST state;

    extern int cancel;

 

    if( cancel ) {

        state = GETCBRBLST();

        /* stop the rebuild */

        state->rcbrc = 1;

    }

 

}

See Also

SetCallbackOnRebuild

 

SetDataFilter

Specify a data filter for a given data file.

Short Name

SETFLTR()

Type

Low-Level Data Manipulation

Declaration

COUNT SetDataFilter(FILNO datno, pTEXT condexpr)

Description

In V12 the file number typedef was formally changed from COUNT, a two-byte value to FILNO, a four-byte value. Refer to this link for compatibility details. Four Byte File Numbering

SetDataFilter() specifies that the data filter condexpr should be used for reads from data file datno until a new filter is set or the file is closed. To “turn off” a filter without closing the file, simply call SetDataFilter() with an empty string ("") for the conditional expression.

A Low-Level data record read returns FFLT_ERR (739) if the data record exists but does not satisfy the filter. ISAM level record requests, including sets and batches, skip over records failing the filter transparently to the user. In client/server, this may substantially reduce network traffic.

For partitioned files, call SetDataFilter() for the host data file and the filter automatically applies to each partition member file.

The condexpr string is similar to those used for conditional index support: it may be a logical expression involving field names from the record schema or a callback designator (e.g., “@mycallback”). See FairCom DB EXPRESSION PARSER AND GRAMMAR.

Row Level Permanent Callback Filters

Introduction

The c-tree API function SetDataFilter() can be used to establish a temporary, user-specific, filter for data record access (please see the section “Data Filters and Conditional Indexes” in the c-tree Plus Programmer’s Reference Guide). SetDataFilter() now supports establishing a new type of permanent system-wide filter.

Consider the case of requiring a customized security audit trail. Individual record reads and writes can be monitored and logged with these permanent filters in place. An application could also use this feature to restrict a user’s ability to read and/or write records based on the row from the table of interest. thereby enabling a row level security mechanism. The username, table, and operation attempted, including the record image, are all data available to your application.

System Level Callback Functions

If the conditional expression in the call to SetDataFilter() begins with either “@@?” or “@@!” then a permanent, system-wide (i.e., applies to all users) read or write filter, respectively, will be added to the file. Calling SetDataFilter() with a conditional expression that exactly matches “@@?” or “@@!” will cause the permanent read or write filter, respectively, to be deleted from the file.

To add or delete one of these filters, the file must be opened exclusively, and the calling user must have file definition permissions.

These filters are call-back filters. This is ensured with the leading ‘@’ character. A file may have at most one read and one write permanent filter.

  • ctfiltercb_rowl() is a new callback function located in module ctclbk.c where the actual callback evaluation takes place.

Two existing callback functions are also called during filter initialization and de-initialization:

  • ctfiltercb_init() - called each time a new filter is established or when a table with a permanent system wide filter is opened.
  • ctfiltercb_uninit() - called each time a new filter is deleted, or when a table with a permanent system wide filter is closed.

c-tree stores these callback expressions in a c-tree file resource. It is important that the developer take care to restrict the ability to delete or otherwise modify these important file resources. Please see the features available regarding File Definition Resource (FCRES) Security in FILEDEF_SECURITY_LEVEL in the FairCom DB Administrator's Guide.

Return

Value Symbolic Constant Explanation
0 NO_ERROR Filter applied.
48 FMOD_ERR Must be called for a data file.
596 CMIS_ERR No record schema defined for datno.
597 CINI_ERR Could not parse conditional expression.
598 CVAL_ERR Insufficient data: Condition outside of read data portion.
739 FFLT_ERR Low-Level: Data record exists but does not satisfy filter.

See c-tree Error Codes for a complete listing of valid c-tree error values.

See also

Data Filters and Conditional Indexes

ctfiltercbAddFilter(), EvaluateFilter(), LoadFilter(), ctfiltercbRemoveFilter(), UnloadFilter()

ctfiltercb_rowl(), ctfiltercb_init(), ctfiltercb_uninit()

SETFLTRN (SETFLTRN, /doc/ctreeplus/setfltrn.htm)

 

SetEncryption

Enable or disable encryption and set or reset encryption key.

Short Name

ctSETENCRYPT()

Declaration

COUNT SetEncryption(pTEXT mod, pTEXT key, VRLEN keylen)

Description

To encode index and data files without a parameter file, use SetEncryption() before the create file calls.

  • mod - use one of the symbolic constants listed below for Advanced File Encryption
  • keylen indicates the length of the key. keylen of 0 disables encryption for any files created after that point.

To stop encrypting new files, call SetEncryption() with keylen set to zero. See ctSETENCRYPT - Passing a NULL to disable encryption.

Remember: Although key is ignored when using an Advanced Encryption cipher, keylen is used to enable or disable encryption as described above.

Available Ciphers

Symbolic Constant Description
ctAES16 ctAES24 ctAES32 Advanced Encryption Standard (AES)

Ciphers available prior to V13

Symbolic Constant Description
ctENCR Advanced Encryption is not enabled; only the less-secure Data Camouflage is enabled - This mode is strongly discouraged for production systems or any place sensitive data is used. See Advanced File Encryption (Advanced File Encryption, Advanced Encryption).
ctDES8 ctDES16 ctDES24 Data Encryption Standard - DES encryption algorithm based on a description published by Bruce Schneier in “Applied Cryptography 2nd Edition.” (ISBN 0-471-12845-7)
ctBLF8 through ctBLF56 Blowfish encryption algorithm implementation based on code made public by Bruce Schneier of Counterpane Internet Security Inc. For more information regarding this standard, refer to “The Blowfish Encryption Algorithm.” According to the Counterpane web site about Blowfish: “Blowfish is unpatented and license-free, and is available free for all uses."
ctTWF16 ctTWF24 ctTWF32 Twofish encryption algorithm implementation based on code made public by Counterpane Internet Security Inc, as one of the NIST AES finalist. For more information regarding this standard, refer to the “Twofish Website”. According to the Counterpane web site about Twofish: “Twofish is unpatented, and the source code is uncopyrighted and license-free; it is free for all uses."

SetEncryption() only affects file creation operations. All files created after a given call to SetEncryption(), with a keylen greater than zero will be encrypted with the same key. Therefore, at the ISAM level, a data file and its associated indexes will be created with the same encryption key. Turning encryption on and off through calls to SetEncryption() only affects whether or not a new file is encrypted. Once a file is set for encryption, it is always encrypted.

SetEncryption Examples

The following pseudo-code encrypts the first ISAM data file and its indexes using Advanced Encryption ciphers, and does not encrypt the second ISAM data file and its indexes:

InitISAM(...)


SetEncryption (ctAES32, NULL, 1)

CreateIFile(..1..)


SetEncryption (NULL, NULL, 0)

CreateIFile(..2..)

Sample Calls to Enable or Disable Encryption

Either of these calls will enable AES encryption (if a key is specified, it is ignored):

ctSETENCRYPT(ctAES32, "mykey", 5);

ctSETENCRYPT(ctAES32, NULL, 5);

Any of these calls will disable encryption:

ctSETENCRYPT(ctENCR, NULL, 0);

ctSETENCRYPT(NULL, NULL, 0);

ctSETENCRYPT(NULL, NULL, -99);

ctSETENCRYPT(ctAES32, NULL, 0);

ctSETENCRYPT(ctAES32, NULL, -10);

Note: SetEncryption() does not enable transaction log file encryption. Use the LOG_ENCRYPT configuration option to encrypt transaction log data.

Return

Value Symbolic Constant Explanation
0 NO_ERROR Successful operation.
82 UALC_ERR No memory available to allocate.
454 NSUP_ERR Service not supported.
1210 CAMO_NSUP_ERR Camouflage not supported

See c-tree Error Codes for a complete listing of valid c-tree error values.

See Also

 

 

ctSETENCRYPT - Passing a NULL to disable encryption

Passing a NULL value for the key parameter to ctSETENCRYPT was inadvertently resetting keylen to 0, which was disabling encryption. In V10.3 and later, the code in the client library interface to ctSETENCRYPT() has been changed so that it is consistent with the following definition:

In the ctSETENCRYPT() function, keylen > 0 enables encryption for all files created after that point, and keylen <= 0 disables encryption. This is true regardless of whether key is NULL or not.

Note: A non-NULL key is required when a call to ctSETENCRYPT() is made that enables basic encryption; key is ignored when using Advanced Encryption.

 

SetFileSegments

Segmented file support configuration function.

Short Name

ctSETSEG()

Type

Low-Level function

Declaration

COUNT SetFileSegments(FILNO filno, NINT aseg, NINT tseg, pSEGMDEF pseg)

Description

In V12 the file number typedef was formally changed from COUNT, a two-byte value to FILNO, a four-byte value. Refer to this link for compatibility details. Four Byte File Numbering

SetFileSegments() configures the segments for file filno. aseg specifies the number of active segments, i.e., the segments created immediately. aseg must be at least one and less than or equal to tseg. tseg specifies the total number of segments pointed to by pseg. pseg points to an array of SEGMDEF structures.

If the first segment definition pointed to by pseg has a sgname pointing to the empty string, i.e., *sgname == ‘\0’, not sgname == NULL, the sgsize member of the structure becomes the host segment size limit. Only the last segment can have a size limit of zero, which is interpreted as no limit.

Additional segments automatically become active as needed, up to the maximum set in tseg. The segments are used in the order defined by the array of SEGMDEF structures pointed to by pseg.

The file referenced by filno must be opened in ctEXCLUSIVE mode the first time SetFileSegments() is called. Note that a file which has been created and not yet closed is always in ctEXCLUSIVE mode, regardless of the file mode specified as part of the create call.

Modifying Segment Definitions

After the segment definitions have been established by the first call to SetFileSegments(), it is possible to call SetFileSegments() to modify the segment definitions even while the file is being updated. However, it is not possible to change a segment size so that the new size is smaller than the actual physical size of the segment, nor can SetFileSegments() rename a segment that is in use. A segment is in use if data beyond the segment header information has been written to the segment. An active segment is not in use just because it is on disk; data must have been written to it. Therefore, a call to SetFileSegments() can, in real time, change where segments will reside (provided the segment is not already in use) and/or how large they are (provided the new size is not smaller than the current physical size nor is the segmented already completely full).

Changing the Number of Segments

SetFileSegments() can be used to change the number of segments for a file that uses the automatic segment feature (ctSEGAUTO). Call SetFileSegments() as follows:

  • Set aseg to zero
  • Set tseg to the new maximum number of automatic segments
  • Set pseg to point to a single SEGMDEF structure in which the sgname field is ignored and the sgsize field specifies the size of all the segments, including the host file.

Return

Value Symbolic Constant Explanation
0 NO_ERROR Successful segment configuration.
62 LERR_ERR First call requires exclusive file lock.
70 TEXS_ERR Call cannot be made within a transaction unless the file has just been created with ctTRANDEP or ctRSTRDEL (i.e., the creation has not been committed) and this is the first such call for this file.
446 BMOD_ERR Illegal value for aseg.
448 DEFP_ERR Denied permission to change file definition.
454 NSUP_ERR File requires extended header to support segments.

See c-tree Error Codes for a complete listing of valid c-tree error values.

Example

SEGMDEF segdef[2] = {

  {"d:\\data\\dataseg.2",1024}, /* 1024MB = 1GB size limit   */

  {"e:\\data\\dataseg.3",0}     /* no limit on segment size  */

};


IFIL fil = {...}


/* create files        */

if (CreateIFileXtd8( &fil, NULL, NULL, 0L, NULL, NULL,

          &creblk))  /* pointer to array of XCREblks         */

    printf("Could not create %s (%d,%d)\n", fil.pfilnam, isam_err, isam_fil);

 
/* specify definitions for the two other segments            */

if (SetFileSegments(

   fil.tfilno,  /* data file number                          */

            1,  /* one active segment (the host segment)     */

            2,  /* two segment definitions to be passed      */

      segdef))  /* pointer to the segment definitions        */

    printf("Could not set file segments (%d,%d)\n", isam_err, isam_fil);

Limitations

The fxtsiz member of the XCREblk structure cannot be set higher than the size of the first (host) segment during a file create. This results in SEGM_ERR (674) signifying the need for more segments, which do not exist yet because SetFileSegments() has not yet been called.

The file referenced by filno must be opened in ctEXCLUSIVE mode the first time SetFileSegments() is called.

See also

GetXtdCreateBlock()

 

SETFLTRN

Sets a filter having the specified filter number. Multiple filters allows advanced data filtering capability.

Type

Low-Level function

Declaration

COUNT SETFLTRN(FILNO datno, UCOUNT fltnum, UCOUNT fltopts, pTEXT expression);

Description

In V12 the file number typedef was formally changed from COUNT, a two-byte value to FILNO, a four-byte value. Refer to this link for compatibility details. Four Byte File Numbering

The function prototype for SETFLTRN() is very similar to SetDataFilter(). SETFLTRN() includes two additional parameters:

  • fltnum specifies the filter number
  • fltopts specifies filter options.

The filter number determines the order in which a filter is evaluated: filters are evaluated in ascending order by filter number. Two filters cannot have the same filter number. A call to SETFLTRN() for filter number N replaces an existing filter that has that filter number.

A call to SETFLTRN() may specify a filter number in the range 0 through 16383. The upper two bits of the filter number value are reserved for internal use. A call to SETFLTRN() with a filter number larger than 16383 fails with error PBAD_ERR (749, bad parameter value).

Currently the only supported filter option is ctDATFLT_OPTION_CURCTX, which indicates that the data filter applies only to the ISAM context in which it was created. When this filter option is not specified (that is, if the caller specifies zero for fltops), the filter applies to all ISAM contexts, and is how the current SetDataFilter() function behaves.

FairCom DB API layers use SETFLTRN() with the ctDATFLT_OPTION_CURCTX option for data filters as FairCom DB API expects a data filter to apply only to a particular context.

Return

Value Symbolic Constant Explanation
0 NO_ERROR Successful segment configuration.
116 IMOD_ERR RESETFLTR() called but server version does not support numbered filters.
454 NSUP_ERR Not supported with your server version.
749 PBAD_ERR Bad parameter value

See c-tree Error Codes for a complete listing of valid c-tree error values.

Example

rc = NXTVREC(CUSTDAT, recbuf, &reclen);

if (rc != INOT_ERR) {

ctrt_printf("Error: Failed to read record: %d\n", rc);

goto err_ret;

}


/* Set filter to read record 'b' only. */

if ((rc = SETFLTRN(CUSTDAT, 1, 0, "!strncmp(ZipCode, \"b\", 1)"))) {

ctrt_printf("Error: Failed to set data filter: %d\n", rc);

goto err_ret;

}


/* Read the record. */

reclen = bufsiz;

if ((rc = FRSVREC(CUSTDAT, recbuf, &reclen))) {

ctrt_printf("Error: Failed to read record: %d\n", rc);

goto err_ret;

}


if (recbuf[4] != 'b') {

ctrt_printf("Error: First record value (%c) does not match expected value (b)\n",

recbuf[4]);

rc = 1;

goto err_ret;


 

rc = NXTVREC(CUSTDAT, recbuf, &reclen);

if (rc != INOT_ERR) {

ctrt_printf("Error: Failed to read record: %d\n", rc);

goto err_ret;

}

ctrt_printf("Successfully read record b with filter.\n");


/* Set filter to read record 'a' only. */

if ((rc = SETFLTRN(CUSTDAT, 1, 0, "!strncmp(ZipCode, \"a\", 1)"))) {

ctrt_printf("Error: Failed to set data filter: %d\n", rc);

goto err_ret;

}


/* Read the record. */

reclen = bufsiz;

if ((rc = FRSVREC(CUSTDAT, recbuf, &reclen))) {

ctrt_printf("Error: Failed to read record: %d\n", rc);

goto err_ret;

}


if (recbuf[4] != 'a') {

ctrt_printf("Error: First record value (%c) does not match expected value (a)\n",

recbuf[4]);

rc = 1;

goto err_ret;

}


rc = NXTVREC(CUSTDAT, recbuf, &reclen);

if (rc != INOT_ERR) {

ctrt_printf("Error: Failed to read record: %d\n", rc);

goto err_ret;

}

rc = NO_ERROR;

ctrt_printf("Successfully read record a with filter.\n");


/* Set filter to read record 'a' and 'b' only. */

if ((rc = SETFLTRN(CUSTDAT, 2, 0, "!strncmp(ZipCode, \"b\", 1)"))) {

ctrt_printf("Error: Failed to set data filter: %d\n", rc);

goto err_ret;

}


/* Read the record. */

reclen = bufsiz;

rc = FRSVREC(CUSTDAT, recbuf, &reclen);


if (rc != INOT_ERR) {

ctrt_printf("Error: Expected record read to fail with INOT_ERR but return code is : %d\n",

rc);

if (!rc)

rc = 1;

goto err_ret;

}

See also

SetDataFilter()

 

SETLOGPATH

Set transaction processing control file paths for single-user applications.

Short Name

SETLOGPATH()

Type

Low-Level function

Declaration

COUNT SETLOGPATH(pTEXT path, NINT mode)  

Description

SETLOGPATH() sets the path for the transaction processing log files, start files and temporary support files for single-user transaction processing applications.

SETLOGPATH() must be called BEFORE the initialization of c-tree (i.e., before InitCTree(), InitISAM(), etc.). Therefore, it does not set uerr_cod. It returns the error code or zero if successful. If c-tree is shutdown and restarted within an application, SETLOGPATH() must be repeated just prior to each c-tree initialization.

If ctNOGLOBALS is used with instance control functions, the instance must be registered by calling RegisterCtree() before SETLOGPATH() is called. Each SETLOGPATH() call applies to only one instance of c-tree.

  • path is a pointer to the string with the path to be used. It should end with a path or device separator, and it is best if the path is absolute.
  • mode takes one of the following values:
ctlogALL Set path for all log related files.
ctlogLOG Set path for transaction log files.
ctlogSTART Set path for start files and all other related files except the log files.
ctlogLOG_EVEN Set path for even transaction log file.
ctlogLOG_ODD Set path for odd transaction log file.
ctlogSTART_EVEN Set path for even transaction start file.
ctlogSTART_ODD Set path for odd transaction start file, and all other related files except the log files.
ctlogSTATUS Sets only the path of the status log.

These modes apply only to the optional mirrored log files and start files:

  • ctlogALL_MIRROR
  • ctlogSTART_MIRROR
  • ctlogLOG_ODD_MIRROR
  • ctlogSTART_ODD_MIRROR
  • ctlogLOG_MIRROR
  • ctlogLOG_EVEN_MIRROR
  • ctlogSTART_EVEN_MIRROR

The simplest approach is to call SETLOGPATH() with the mode ctlogALL. Unless mirrored logs are desired, this is the only call required. If mirror files are desired then a second call with mode ctlogALL_MIRROR will handle all the mirrored files. The other modes are provided for unusual situations in which individual files must be placed in different locations.

If the ctlogALL mode is not used, typically more than one call to SETLOGPATH() is required.

A call made by a FairCom Server client to SETLOGPATH() returns zero, but has no effect. The FairCom Server configuration file specifies the modified names for the log and related files. However, a LOCLIB call to SETLOGPATH() sets the names for the local log files.

Return

Value Symbolic Constant Explanation
0 NO_ERROR Successful path change.
10 SPAC_ERR Could not allocate space for file names.
47 FINT_ERR ctNOGLOBALS instance not allocated yet.
116 IMOD_ERR Bad mode parameter.
454 NSUP_ERR Transaction processing not supported.

See c-tree Error Codes for a complete listing of valid c-tree error values.

Example

NINT rc;


if (rc = SETLOGPATH("/usr/logarea/",ctlogALL))

    printf("Could not setup log file names (%d)\n",rc);

 

SetNodeName

Sets a client side node name.

Short Name

SETNODE()

Type

Server only

Declaration

COUNT SetNodeName(pTEXT nodename) 

Description

SetNodeName() specifies a client side node name. The specified name appears in the ctadmn utility under the option for ‘list clients’.

The alternative method is to define the global variable ctnodnam. This variable is a null terminated, 32-byte, ASCII string hold the desired value. To set the ctnodnam to the string “Development Sun Sparc” do the following:

strcpy(ctnodnam,"Development Sun Sparc");

Note: SetNodeName() must be called after c-tree has been initialized, typically with InitISAMXtd().

Return

Always returns NO_ERROR (0).

Example

pTEXT     nodename = "Development Sun Sparc";


SetNodeName(nodename);

Limitations

Available only with the FairCom Server. A call to SetNodeName() on a non-server system results in NO_ERROR (0) error return.

See also

InitISAMXtd()

 

SetOperationState

Set operation modes for special performance-related functionality and test operational states for critical events.

Short Name

SETOPS()

Type

Low-Level function

Declaration

LONG SetOperationState( LONG status_word, VRLEN operation_code ) 

Description

SetOperationState() allows an application to set or return a 4-byte status word. The bits of the status word change default operation modes. status_word options options are listed in the following table and detailed below:

Operations Mode Description
OPS_READLOCK Enable automatic, low level, blocking read locks on each record access that does not already have a lock.
OPS_LOCKON_GET Lock next fetch only.
OPS_UNLOCK_ADD Automatic unlock on add.
OPS_UNLOCK_RWT Automatic unlock on rewrite.
OPS_UNLOCK_UPD (OPS_UNLOCK_ADD | OPS_UNLOCK_RWT)
OPS_LOCKON_BLK Blocking lock on next fetch only.
OPS_LOCKON_ADD_BLK Enable blocking write lock mode during record add call then restore original lock mode.
OPS_FUNCTION_MON Toggle function monitor. (Server)
OPS_LOCK_MON Toggle lock monitor. (Server)
OPS_TRACK_MON Toggle memory track monitor. (Server)
OPS_MIRROR_NOSWITCH Don’t continue if mirror or primary fails. (Server)
OPS_MIRROR_TRM A primary or mirror has been shutdown.
OPS_MEMORY_SWP Memory swapping active.
OPS_AUTOISAM_TRN Automatic ISAM transactions.
OPS_KEEPLOK_TRN Keep locks involved in automatic transactions on record adds and updates after commit.
OPS_SERIAL_UPD Changes GetSerialNbr() operation.
OPS_DEFER_CLOSE Defer file closes or deletes during transactions.
OPS_CONV_STRING Change all CT_STRING fields having a non-zero field length in the fixed length portion of the record buffer to CT_FSTRING fields. (Client)
OPS_DISK_IO Set sysiocod on disk reads and writes.

operation_code options are:

Operation State Description
OPS_STATE_OFF Turn a status bit off.
OPS_STATE_SET Set the entire status word.
OPS_STATE_ON Turn a status bit on.
OPS_STATE_RET Return the entire status word.

OPS_READLOCK - The set operations function, SETOPS(), enables automatic, low level, blocking read locks on each record access that does not already have a lock. The locks are released automatically as soon as the record is read. Blocking locks permit a c-tree application to be coded the same whether or not the automatic locks have been requested. But this means a read will block until the read lock is available. The locking code is in the REDREC(), iRDVREC() and REDVREC() routines.

SETOPS(OPS_READLOCK,opcode)

will turn on or off the read lock state.

If ctBEHAV_READLOCK is not enabled, the SETOPS() call will not return an error, and no automatic locking will take place. The state variable returned by SETOPS() will not have the OPS_READLOCK bit set.

OPS_UNLOCK_ADD - If on, causes automatic record unlocks on calls to AddRecord() or AddVRecord(). A loop of the form:

   while (. . .) {

    LockISAM(ctENABLE);

    AddRecord(. . .);

    LockISAM(ctFREE);

}

could be replaced with:

SetOperationState(OPS_UNLOCK_ADD,OPS_STATE_ON);

while(. . .) {

    AddRecord(. . .);

}

OPS_UNLOCK_RWT - Causes automatic record unlock on calls to ReWriteRecord() or ReWriteVRecord(). Similar to the OPS_UNLOCK_ADD, this mode eliminates the need to call LockISAM(ctFREE). If the rewrite fails, the record remains locked.

OPS_LOCKON_GET - Unlike the previous two modes, this status word mode must be set before each use. However, the OPS_STATE_ON call for OPS_LOCKON_GET is not sent to the c-tree Server, so repeated calls do not cause network overhead. OPS_LOCKON_GET should not be OR-ed with any other status_word constants.

OPS_LOCKON_GET and OPS_UNLOCK_RWT can significantly reduce the number of calls needed to lock, read, update and unlock a record. A loop of the form:

while(. . .) {

    LockISAM(ctENABLE);

    GetRecord(. . .);

    ReWriteRecord(. . .);

    LockISAM(ctFREE);

}

which requires four calls to the c-tree Server for each loop, can be replaced with:

SetOperationState(OPS_UNLOCK_RWT, OPS_STATE_ON);

while(. . .) {

    SetOperationState(OPS_LOCKON_GET, OPS_STATE_ON);

    GetRecord(. . .);

    ReWriteRecord(. . .);

}

where only two calls go to the c-tree Server for each loop.

Note: The OPS_LOCKON_GET state is cleared on the subsequent read operation, whether or not the read operation succeeds. Thus, there is no need to call OPS_STATE_OFF for this mode. In fact, doing so results in additional network calls to the server defeating any benefits gained. If the read operation fails, the lock is freed automatically on return from the read operation. Use OPS_LOCKON_GET prior to any low level or ISAM level retrieval function, such as FirstRecord() or ReadData().

OPS_LOCKON_BLK - Behaves as OPS_LOCKON_GET except the lock request is a blocking lock. If the lock is denied, the client is placed in a wait list for the lock, which is granted on a FIFO (First In First Out) basis. The application does not see the lock denial, does not have to issue retries, and waits forever for the lock. However, while waiting in the wait list, if the requesting client would cause a deadlock, the retrieval operation fails with DEAD_ERR (86). Support for this option is only guaranteed by the c-tree Server. Many non-server, multi-user systems do not support blocking locks, and OPS_LOCKON_BLK functions as a non-blocking lock.

SetOperationState(OPS_LOCKON_BLK,OPS_STATE_ON);    /* enable */

SetOperationState(OPS_LOCKON_BLK,OPS_STATE_OFF);  /* disable */

OPS_FUNCTION_MON - Toggles the c-tree Server function monitor.

OPS_MIRROR_NOSWITCH - Changes how errors related to mirrored files are handled. The default protocol is to try to continue operation with either the primary or the mirror file if the other fails. If the primary fails, all I/O continues on the mirror. If the mirror fails, all I/O continues on the primary. When operation continues with the remaining good file, either primary or mirror, the c-tree Plus function returns successfully. However, this situation causes an event to be reported via SystemMonitor(), and the OPS_MIRROR_TRM bit is set in the status_word.

Calling SetOperationState(OPS_MIRROR_NOSWITCH, OPS_STATE_ON), changes the application protocol. If either the primary or the mirror fails, the entire operation fails and returns an appropriate error code. Use SystemMonitor() to monitor for primary/mirror errors under either protocol.

OPS_AUTOISAM_TRN - Implements automatic transaction begins, commits, or aborts for the six ISAM update routines: AddRecord(), DeleteRecord(), ReWriteRecord(), AddVRecord(), DeleteVRecord(), ReWriteVRecord(). Automatic transactions reduce the network traffic for single ISAM updates. These automatic transactions can be used for both Server and single user implementations. The calls:

SetOperationState(OPS_AUTOISAM_TRN,OPS_STATE_ON);

SetOperationState(OPS_AUTOISAM_TRN,OPS_STATE_OFF);

turn on and off, respectively, automatic transaction begins, commits or aborts for the six ISAM update routines listed above. When turned on, automatic transactions start a transaction at the beginning of each of these six ISAM update routines if, and only if, no transaction is already active. Upon successful conclusion of these ISAM updates, the transaction is committed. If an error occurs, the transaction is aborted. Of course, these automatic commits or aborts are only invoked if an automatic transaction was started at the beginning of the ISAM update routine.

Assuming SetOperationState(OPS_AUTOISAM_TRN,OPS_STATE_ON) has been called and that an update on a transaction processed file is to be performed without an explicit call to Begin, then the system behavior is as follows:

  1. An automatic transaction will not free locks acquired outside the automatic transaction, unless the lock is on an item updated or locked in the transaction. This is similar to ctKEEP_OUT behavior as explained in the Begin function description.
  2. An aborted automatic transaction, which occurs when the update returns an error, always releases locks acquired in the transaction.
  3. If the LockISAM() state is ctENABLE or ctENABLE_BLK, or these states have been restored via LockISAM(ctRESTORE), or ctRESTORE_BLK, respectively, an automatic transaction will not free any locks on commit, similar to Commit(ctKEEP) or Abort(ctKEEP_OUT).

If OPS_UNLOCK_UPD is on, both commits and aborts on automatic transactions behave according to ctKEEP_OUT, regardless of the LockISAM() state.

OPS_TRACK_MON - Causes the net count of memory allocation requests to be output upon each calling of SetOperationState().

SetOperationState(OPS_TRACK_MON,OPS_STATE_ON);

SetOperationState(OPS_TRACK_MON,OPS_STATE_OFF);

Turning on the tracking via SetOperationState() uses a default threshold value of 250. Each such call to SetOperationState(), in addition to each time the threshold value is encountered, increasing or decreasing, produces a debug line of output to STDOUT, typically the c-tree Server console screen, detailing the current net allocation count. Override the threshold value by placing the keyword MEMORY_TRACK in the c-tree Server configuration file. This feature is intended for dynamically tracking the c-tree Server memory consumption.

OPS_LOCK_MON - Enables the lock monitor whether or not the configuration file contains LOCK_MONITOR. If there is no configuration entry, the threshold value is set to 100. SetOperationState(OPS_LOCK_MON,OPS_STATE_OFF) turns off the lock monitor. When SetOperationState() is called to turn the monitor on or off, and each time the threshold value is encountered, increasing or decreasing, a message specifying the current number of excess locks is sent to the c-tree Server console. The net lock count is always maintained. Therefore, if a monitor is subsequently turned on by SetOperationState(), the current lock count will be correct. There is almost no overhead to maintain this value: only a simple increment or decrement on each lock or unlock. This function is useful for assuring proper locking operation.

OPS_MIRROR_TRM - When the mirror error handling protocol is not changed via OPS_MIRROR_NOSWITCH, if a primary or mirror fails, causing the c-tree Server to go on using only one file, the OPS_MIRROR_TRM bit is set in status_word. It can be tested as follows:

if (SetOperationState((LONG)0,OPS_STATE_RET) & OPS_MIRROR_TRM)

 printf("System continuing with a primary or mirror failure.");

OPS_SERIAL_UPD - When turned on causes GetSerialNbr() to return a unique serial number. This mode allows manual serialization of the data by the application. GetSerialNbr() normally returns the current value of the file’s serial number.

Note: FairCom does not recommend this option. Corrupt files may contain an improper last-used-value in the header after a rebuild operation. When serial numbers are included in records via the serial number key segment mode, rebuild determines the highest used serial number and resets the value in the header.

For transaction controlled files, a transaction must be active to call GetSerialNbr() when OPS_SERIAL_UPD has been turned on.

OPS_DEFER_CLOSE - Defers a file closes or deletes requested during transactions. By default, a file close or delete request during a transaction returns CPND_ERR (588). Turning on the defer option allows the function to return NO_ERROR (0) and continue, while the actual close or delete is deferred until the end of the transaction.

OPS_CONV_STRING - For a data record containing CT_STRING field data in the fixed length portion of the record buffer, if the CT_STRING data is padded with null (0x0) bytes, and if a c-tree client reads the data from a c-tree Server whose system’s byte order differs from the client system’s byte ordering, the values of fields that follow the CT_STRING fields may be incorrectly reversed.

In heterogeneous environments, the c-tree client code reverses binary fields in the record buffer when reading data records. A CT_STRING field is considered to end when the first null byte is encountered. If an application pads a CT_STRING field with multiple null bytes, the c-tree client’s scanning logic stops scanning the field at the first null byte and considers the next field to begin with the second null byte. The client logic will then reverse the wrong bytes in the data record buffer.Enables the client logic to scan a c-tree data file’s field definitions when the client code reads the DODA from the data file. When enabled, the client logic will change all CT_STRING fields having a non-zero field length in the fixed length portion of the record buffer to CT_STRING fields.

OPS_DISK_IO - Uses sysiocod to indicate if the previous function call to the Server generated any read and/or write activity for data and/or index files. sysiocod is only set if the previous call did not itself cause a sysiocod return value.

A sysiocod between -1015 and -1000 indicates that the feature is on, and no other sysiocod value occurred. There are sixteen possible return values, defined as:

Value Symbolic Constant Description
1 ctDISKIO_IDXR Index read from disk.
2 ctDISKIO_DATR Data read from disk.
4 ctDISKIO_IDXW Index write to disk.
8 ctDISKIO_DATW Data write to disk.

A return of -1000 means no data or index disk activity, though there still may have been activity in transaction logs and other Server files. A return of -1015 means there were read AND writes on both data and index files.

This statement prints a message as shown:

if (sysiocod <= -ctDISKIObase && (((-sysiocod) - ctDISKIObase)& ctDISKIO_DATW))

    printf(“One or more data file writes to disk\n”);

else

    printf(“No data file write to disk\n”);

OPS_AUTOISAM_TRN - Permits individual ISAM updates to be performed within an automatically initiated transaction. The purpose of this option is to avoid the network overhead of the TRANBEG and TRANEND calls. (If a transaction has already been initiated by the application, then no automatic transaction is attempted.)

Prior to the introduction of this option, the automatic commit would free any lock involved in the transaction unless LKISAM(ENABLE) or LKISAM(ENABLE_BLK) was already in effect and OPS_UNLOCK_ADD or OPS_UNLOCK_RWT were not in effect. If an application desired to hold the lock after the automatic commit, LKISAM(ENABLE) would have to be called first; but this caused the same network overhead as the TRANBEG.

The SETOPS option, OPS_KEEPLOK_TRN, causes the locks involved in automatic transactions for adds and rewrites to be kept after the automatic commit. Delete operations still have the locks freed.

OPS_LOCLON_ADD_BLK When a table lock is in effect, a record add call by a connection that is not holding the table lock fails with error DLOK_ERR and sysiocod of DLKT_COD if that connection has not enabled the ISAM blocking write lock mode. Calling LKISAM(ctENABLE_BLK) before adding the record avoids the error, but it requires an additional call to the server, plus another call after the record add call in order to restore the original lock mode. The c-tree client library and c-tree Server now support a new SETOPS() mode that can be used to enable the blocking write lock mode during the record add call and then restore the original lock mode, all in a single call to the server.

To use this feature, call SETOPS(OPS_LOCKON_ADD_BLK, OPS_STATE_ON) before calling the record add function [ADDREC() or ADDVREC()]. The SETOPS() call sets a bit on the client side and returns to the caller without making a call to the server. This bit is passed to the server on the next record add call. The server and client library turn off this mode when the record add call completes, so it applies only to the first record add call that is made after turning on this option. For this reason, it's recommended to enable this mode right before the call to add the record to which you want this mode to apply.

The record read functions that check and turn off the OPS_LOCKON_GET and OPS_LOCKON_BLK modes ignore this new mode. And the record add functions that check and turn off the OPS_LOCKON_ADD_BLK mode ignore the OPS_LOCKON_GET and OPS_LOCKON_BLK modes.

Return

SetOperationState() returns the present state of the operation status word. On return, uerr_cod is set to one of the following

Value Symbolic Constant Explanation
0 NO_ERROR Successful operation.
116 IMOD_ERR Bad operation_code parameter or status_word contains illegal bit fields.

See c-tree Error Codes for a complete listing of valid c-tree error values.

See also

GetSerialNbr(), AddRecord(), AddVRecord(), DeleteRecord(), DeleteVRecord(), ReWriteRecord(), ReWriteVRecord(), LockISAM(), FirstRecord(), ReadData(), SystemMonitor(), Abort(), Commit(), Begin()

 

SetRecord

Resets the current ISAM record.

Short Name

SETCURI()

Type

ISAM function

Declaration

COUNT SetRecord(FILNO datno, LONG recbyt, pVOID recptr, VRLEN datlen); 

Description

In V12 the file number typedef was formally changed from COUNT, a two-byte value to FILNO, a four-byte value. Refer to this link for compatibility details. Four Byte File Numbering

c-tree maintains the record number of the current ISAM record for each data file, as well as an image of the key buffer. There may be times when you want to reset the current ISAM record. For instance, if you want to return to a particular point in the file and index in order to continue a sequential scan of the file. By calling SetRecord(), you can set the current record offset of file datno to the value in recbyt.

recptr points to a record image. If datlen is zero, recptr should point to a complete fixed-length record, or the fixed portion of a variable-length record. Otherwise, datlen indicates the size of the information pointed to by recptr.

If recptr is NULL, only the record position is updated. This is useful when SetRecord() is used to prepare for ReReadRecord(), or ReReadVRecord(), to reread the current ISAM record.

Return

Value Symbolic Constant Explanation
22 FNUM_ERR File number is out of range.
26 FACS_ERR File number is not assigned to a file in use.
47 FINT_ERR c-tree has not been initialized.
48 FMOD_ERR datno is not assigned to a data file.

See c-tree Error Codes for a complete listing of valid c-tree error values.

Example

FILNO     datno, keyno;

LONG      custno, recpos;

TEXT      savbuf[128], buffer[128];


printf("\nEnter customer number: ");

scanf("%ld",&custno);

if (FirstInSet(keyno, &custno, savbuf, 4))

    printf("\nCould not read customer record");

else{

    recpos = CurrentFileOffset(datno);

    process_more_records_in(buffer);
 

    /* restore original record as current ISAM */

    SetRecord(datno,recpos,savbuf,128L);

}

Limitations

The recbyt parameter in this function is a 4-byte value capable of addressing at most 4 gigabytes. If your application supports HUGE files (greater than 4 gigabytes), you must use the ctSETHGH() and ctGETHGH() functions to set or get the high-order 4 bytes of the file offset. See also Record Offsets Under Huge File Support.

See also

ReReadRecord(), ReReadVRecord(), ctSETHGH(), ctGETHGH(), CurrentISAMKey(), TransformKey()

 

SetSavePoint

Establish a savepoint.

Short Name

TRANSAV()

Type

Low-Level data file function

Declaration

  COUNT SetSavePoint() 

Description

SetSavePoint() creates a savepoint in the current transaction. When processing a complex transaction, you will find times when you want to back up just part way in that transaction. You do not want to use Commit(), as that commits, and ends, the entire transaction. You do not want to use Abort(), as that aborts the entire transaction.

To be able to reverse just a portion of a transaction, call SetSavePoint() to set a savepoint. There can be any number of savepoints within a transaction. SetSavePoint() returns a COUNT value that is the numerical representation of that save point. To roll back the transaction to a particular save point, issue a call to RestoreSavePoint(), passing the specific save point value as the parameter.

Return

SetSavePoint() returns the numerical representation of the save point. Use this value in a subsequent RestoreSavePoint() to reset the transaction to this save point. If an error occurs, SetSavePoint() returns zero. Check uerr_cod for the error value.

Value Symbolic Constant Explanation
0 NO_ERROR No error occurred.
71 TNON_ERR There is no active transaction pending.
94 PNDG_ERR An update error occurred during one of the previous operations, but not cleared with RestoreSavePoint().

See c-tree Error Codes for a complete listing of valid c-tree error values.

Example

COUNT     savepoint;


void domaster() {

    Begin(ctENABLE|ctTRNLOG);   /* start transaction with locks  */

    while(another()); {         /* get next record to add        */

        savepoint = SetSavePoint();

                        /* get save point at beginning of each master record */

        if (add_master() < 0)

            Abort();            /* Abort if can't add master rec */

        dodetail();             /* process detail records        */

    }

    if (Commit(ctFREE)0)

        printf("\nError %d in transaction",uerr_cod);

    return;

}


void dodetail() {

    while(moredetail()); {                /*get next detail record to add */

        if (add_detail()<0) {             /* add details, if possible */

            RestoreSavePoint(savepoint)   /* with error, return to savept */

            return;

        }

    }

}

See also

Abort(), AbortXtd(), Begin(), ClearSavePoint(), Commit(), RestoreSavePoint(), TRANRDY()

 

SetSystemConfigurationOption

SetSystemConfigurationOption() dynamically changes server configuration settings at runtime.

Declaration

NINT SetSystemConfigurationOption(NINT option, const TEXT * value);

Short Name

ctSETCFG()

Description

SetSystemConfigurationOption() allows a FairCom Server configuration to be changed at run time. This means you do not have to restart the server to operate with these specified configuration changes. This allows utilities and other diagnostic monitoring tools to directly call the server to activate or inactivate various server configuration options.


setcfgCONFIG_OPTION

setcfgCONFIG_OPTION is a general-purpose option used to set values for settings by passing a string value identical to a line in the server configuration file. Note that this option also supports the other existing options, making it possible to call ctSETCFG(setcfgCONFIG_OPTION, "CHECKPOINT_MONITOR YES").

 

Dynamic Adjustment Support

The following keywords support dynamic adjustment using setcfgCONFIG_OPTION. See the FairCom DB Configuration Options for keyword specific documentation.

  • FUNCTION_MONITOR
  • CHECKPOINT_MONITOR
  • MEMORY_MONITOR
  • REQUEST_TIME_MONITOR
  • DYNAMIC_DUMP_DEFER
  • DYNAMIC_DUMP_DEFER_INTERVAL
  • VSS_WRITER
  • VSS_WRITER_QUIESCE_TIMEOUT
  • SQL_TRACE_CTREE_ERROR
  • MAX_FILE_WAIT_SECS
  • MAX_DFRIDX_LOGS
  • MAX_REPL_LOGS
  • DELSTK_COMMIT_SEC
  • CHECKLOCK_FILE
  • AUTOTRAN_ON_CREATE
  • UNCSEG_KEYCOMPRESS
  • FILESYS_COMPRESS_UNCSEG
  • SHMEM_MAX_SPINNERS
  • SYNC_COMMIT_MAX_SPINNERS
  • READONLY_SERVER
  • LOCAL_CONNECTION_ONLY
  • REPL_NODEID
  • LEAF_NODE_READ_LOCK
  • OPEN_FILES_ALERT_THRESHOLD
  • DYNAMIC_DUMP_SYNC_INTERVAL
  • NONTRAN_FILESYS_FLUSH_OFF
  • SQL_SERVER_LOG_SIZE
  • FILE_CLOSE_FLUSH
  • PENDING_FILE_OPEN_RETRY_LIMIT
  • OPTIMIZE_FILE_OPEN
  • SYSTEM_FILE_ID_LIST
  • CLEANUP_ABLIST_ON_ABORT
  • STACK_DUMP
  • CHECK_FILENAME_VALIDITY
  • SYNC_COMMIT_TIMEOUT
  • REPL_USE_LAST_LOGPOS
  • ABANDONED_QUIET_SUSPEND_LOGON
  • MULTILINE_STATUS_LOG_MESSAGE
  • REPLICATE_ALTER_TABLE
  • BLOCKING_OPEN_RETRY_LIMIT
  • BLOCKING_OPEN_RETRY_DEFER
  • SYSCLOSE_REOPEN_CHECK_DIFF
  • SET_CACHE_OPTIONS
  • SHMEM_CONNECT_TIMEOUT
  • FLEXREC_OPTIMIZE
  • QUIET_MAX_WAIT
  • SORT_MEMORY
  • MAX_HANDLES
  • MAX_REBUILD_QUEUE

 

Partial Dynamic Adjustment Support

The following keywords have some sub-options that may be changed, see below for additional details.

  • DIAGNOSTICS
  • COMPATIBILITY
  • SUBSYSTEM

 

Disabling Binary Sub-Options

Use a tilda (~) character as a prefix to negate the sub-option to turn it off. This applies to the following keywords

  • SQL_DEBUG
  • DIAGNOSTICS
  • CTSTATUS_MASK
  • COMPATIBILITY


DIAGNOSTICS Sub-Options

Not all sub-options are changeable at runtime. Prefix the sub-option with a tilde (~) to turn it off.

The following suboptions are supported.

  • LOWL_FILE_IO
  • VSS_WRITER
  • PTADMIN
  • REPLICATE
  • FULL_DUMP
  • BACKGROUND_FLUSH
  • BACKGROUND_FLUSH_BUCKETS
  • MAX_ACTIVE_CONNECTIONS
  • DFRIDX
  • READ_ERR
  • UNOD_ERR
  • CMTLOK
  • TR_RDIF_ERR
  • TR_TRAN_ERR
  • CHECKLOCK
  • LOG_PURGE
  • LDAP
  • CHECK_KEY_MARKS
  • FALG_ERR
  • DMAP_ERR
  • POPN_ERR
  • RRED_ERR
  • RESIZE_CACHE
  • INIX_ERR
  • SYSTEM_FILE_ID_LIST
  • RECYCLE_BIN
  • SYNCREPL
  • FILE_BLOCK

 

COMPATIBILITY Sub-Options

Not all sub-options are changeable at runtime. Prefix the sub-option with a tilda (~) to turn it off.

The following sub-options are supported.

  • SQLIMPORT_ADMIN_PASSWORD
  • COPY_FILE_OPEN_SHARED

 

SUBSYSTEM details and supported Sub-Options

Keywords belonging to a SUBSYSTEM may support changes at runtime. To do so requires specific formatting like that required in the server configuration file. Multiple sub-options may be changed at once.

The following are SUBSYSTEM values with at least one supported sub-option.

  • SUBSYSTEM SQL LATTE
  • SUBSYSTEM TRNLOG AUTO_RESTORE_POINT
  • SUBSYSTEM EVENT DISK_FULL_ACTION
  • SUBSYSTEM SECURITY PASSWORD
  • SUBSYSTEM EXTERNAL_KEY_STORE AWS
  • SUBSYSTEM AUDIT LOG
  • SUBSYSTEM CTFILE RECYCLE_BIN
  • SUBSYSTEM CACHE PRIME_CACHE_AT_STARTUP


Specifying any other option value than those shown above causes ctSETCFG() to return error PBAD_ERR (749).

 

Options besides setcfgCONFIG_OPTION

Option may be one of the following FairCom Server configuration supported values (the new setting value specified as a string).

 

Option Supported Values Description
setcfgCHECKPOINT_MONITOR YES | NO | DETAIL Dynamically turn on and off the Checkpoint Monitor.
setcfgCTSTATUS_MASK

WARNING_AUTO_TRNLOG

DYNAMIC_DUMP_FILES

Dynamically turn on and off masking of messages specified by value in CTSTATUS.FCS.

A tilda (~) character prefix negates the setcfgCTSTATUS_MASK options thus turning them off.

setcfgDIAGNOSTICS

LOWL_FILE_IO

VSS_WRITER

REPLICATE

Dynamically turn on or off supported DIAGNOSTICS keywords.

A tilda (~) character prefix negates the setcfgDIAGNOSTICS options thus turning them off.

setcfgDYNAMIC_DUMP_DEFER <numeric value> Dynamically set the Dynamic Dump defer (sleep) time for enhanced on-line performance. value is in milliseconds.
setcfgDYNAMIC_DUMP_DEFER_INTERVAL <blocks> Pauses the dynamic dump for DYNAMIC_DUMP_DEFER milliseconds each time it writes specified number of 64 KB blocks of data to dynamic dump stream file.
setcfgFUNCTION_MONITOR YES | NO | <filename> Dynamically turn on and off the Function Monitor.
setcfgMAX_FILE_WAIT_SECS <seconds> | -1 | 0

Change th number of seconds a user thread waits for internal threads to close file before retrying.

-1 disables this feature.

0 (default) sets no wait limit.

setcfgMEMORY_MONITOR <numeric value> Dynamically turn on and off Memory Monitor. value is in bytes.
setcfgREQUEST_TIME_MONITOR <numeric value> Dynamically set the function monitoring time interval. value is in seconds.
setcfgVSS_WRITER YES | NO Dynamically enable VSS writer for Windows.
setcfgLOADKEY_OPTION LOADKEY_LEAF_PCT_FULL Dynamically modify rebuild options to create nodes less than 100% capacity.

 

Details

An attempt to change an option that is specified in a FairCom Server encrypted settings file (ctsrvr.set) will fail with a "SETO_ERR (804) error, cannot override option specified in settings file." ctSETCFG() can only be called by a member of the ADMIN group; otherwise it will fail with error LADM_ERR (589).

The function monitor file output now also includes a time stamp.

Return Values

Value Symbolic Constant Explanation
0 CTDBRET_OK Successful operation.
589 LADM_ERR Member of ADMIN group required.
749 PBAD_ERR

Bad parameter value. Can be caused by any of these conditions:

a) segcount is less than or equal to zero.

b) lrange is NULL.

c) invalid operator specified.

d) between operator specified but urange is NULL.

804 SETO_ERR cannot override configuration option that was specified in settings file

See c-tree Error Codes for a complete listing of valid c-tree error values.

Examples

/* Enable function monitor logging to a file. */
ctSETCFG(setcfgFUNCTION_MONITOR, "fncmon.log");


/* Dynamically set the Dynamic Dump defer time */
ctSETCFG(setcfgDYNAMIC_DUMP_DEFER, "25");

/* Dynamically turn on masking of Dynamic Dump messages */

ctSETCFG(setcfgCONFIG_OPTION, "CTSTATUS_MASK DYNAMIC_DUMP_FILES");

 

/* Dynamically disable masking of Dynamic Dump messages */

ctSETCFG(setcfgCONFIG_OPTION "CTSTATUS_MASK ~DYNAMIC_DUMP_FILES");

 

/* Dynamically set stack generation option to FULL_DUMP */

ctSETCFG(setcfgCONFIG_OPTION "STACK_DUMP FULL_DUMP");

 

/* Change the SUBSYSTEM SQL LATTE MAX_STORE option to 11 GB  */

ctSETCFG(setcfgCONFIG_OPTION,

"SUBSYSTEM SQL LATTE {\nMAX_STORE 11 GB\n}");

 

/* Change multiple SUBSYSTEM SECURITY PASSWORD options  */

const char * newconfig = "SUBSYSTEM SECURITY PASSWORD {\n" \

                      "MINIMUM_LENGTH 16\n" \

                      "REQUIRED_CLASSES 2\n" \

                      "EXPIRE_IN_DAYS 365\n}";

   

ctSETCFG(setcfgCONFIG_OPTION,newconfig);

 

History

V11.6 and later adds SQL_DEBUG configurable options.

 

SetVariableBytes

Change the values used for key padding and as a field delimiter in key construction.

Short Name

SETVARBYTS()

Type

Low-Level file resource function

Declaration

LONG SetVariableBytes(FILNO filno, pUTEXT resptr) 

Description

In V12 the file number typedef was formally changed from COUNT, a two-byte value to FILNO, a four-byte value. Refer to this link for compatibility details. Four Byte File Numbering

When called for a data file, SetVariableBytes() changes the value used to pad varying length key segments as well as the byte value used to delimit varying length string fields that are not length count delimited. When called for an index file, SetVariableBytes() changes the padding byte used during trailing padding key compression. The default values are blanks for padding and NULL for the field delimiter.

filno must be opened with an ctEXCLUSIVE file mode for it to be successful. resptr points to a 2-byte array containing the values for padding (first byte) and the field delimiter (second byte). This information will be stored in the file as a resource, therefore resources must be enabled for the file.

For a related set of data and index files, SetVariableBytes() should be called for the data and index files immediately after successful creation.

Note: When using ISAM functions, be sure to specify appropriate value in the pvbyte element of the IIDX structure in addition to calling this function.

Return

Value Symbolic Constant Explanation
0 NO_ERROR No error occurred.
63 LERR_ERR The file must be opened ctEXCLUSIVE.
401 RNON_ERR Resources are not enabled.

See c-tree Error Codes for a complete listing of valid c-tree error values.

Example

FILNO     filnum;

UTEXT     thebytes[2];


if (OpenDataFile(filnum,"test.dat", ctEXCLUSIVE | ctPERMANENT))

    printf("\nCannot open file (%d)",uerr_cod);

else {

    thebytes[0] = 00;  /*set padding byte */

    thebytes[1] = 32;  /*set delimiter byte */

    if (SetVariableBytes(filnum,thebytes)

        printf("\nByte error %d",uerr_cod);

}

 

SetXtdFileOpenMode

Pass additional file open modes to FairCom Server.

Declaration

NINT SetXtdFileOpenMode (LONG mode)

Description

Additional file open modes can be passed to FairCom DB using this function. SetXtdFileOpenMode() sets a file open mode that is used by the OPNIFIL, OPNIFILX, OPNRFIL, and OPNRFILX functions.

Note: c-tree passes the extended file open mode value to the c-tree Server on the next call to OPNIFIL, OPNIFILX, OPNRFIL, or OPNRFILX that is made after calling SetXtdFileOpenMode(). These ISAM-level file open functions always reset the extended file mode, even in case of error, so that the extended file mode only applies to the first ISAM-level file open call that is made after the call to SetXtdFileOpenMode().

Extended file open modes set by SetXtdFileOpenMode()

ctXOPN_REDSHR Open with read-only sharing.
ctXOPN_COFILE_FILELOCK Inter-thread file locking hierarchy based on most restrictive co-file open.
ctXOPN_REPLADM Read/write open of replicated file for administrative purposes.
ctXOPN_RETRYOPNFCNF

Retries opening the file if the file is opened with a conflicting access mode.

You can configure the number of retries with BLOCKING_OPEN_RETRY_LIMIT, and the delay between retries with BLOCKING_OPEN_RETRY_DEFER.

ctXOPN_NORUCB_OK Allows opening files when update callback cannot be loaded (see below).

 

Example

The following example shows a call to SetXtdFileOpenMode(ctXOPN_RETRYOPNFCNF) followed by opening a file:

 

FILNO filno = 0;

TEXT  filnam[15] = "sample.dat";

 

SetXtdFileOpenMode(ctXOPN_RETRYOPNFCNF);

if (OpenFileWithResource(filno, filnam, ctSHARED) < 0)

   printf("\nCould not open file (%d,%d).", isam_err, sysiocod);

 

Opening a data file if its record update callback resource DLL cannot be loaded

A c-tree data file that requires a record-update callback DLL would fail to open with error code 981 if the callback DLL could not be loaded. In some cases, it might be desirable to allow the data file to be opened in this situation. This is now permitted.

An extended file open mode has been added. It can be used to permit the data file to be opened for read-only access if its record-update callback DLL cannot be loaded. The new extended file mode is ctXOPN_NORUCB_OK. To use this mode when opening the file, call SetXtdFileOpenMode(ctXOPN_NORUCB_OK) before opening the file.

Note that the extended file mode set by SetXtdFileOpenMode() overwrites any previous extended file mode that was set for the connection. Upon return from the file open call, the extended file mode is reset to zero. This implies the normal usage of this function is to call it right before opening the file.

Note: Although the file open succeeds in this situation, the file open function sets sysiocod to RUCBDLL_NOT_LOADED_COD, and a message such as the following one is logged to CTSTATUS.FCS indicating the failed DLL load:

CTDLL_LOAD: Failed to load module ctuser.dll: The specified module could not be found.

 

SnapShot

Declaration

NINT SnapShot(NINT opcode, pTEXT rqstdesc, pVOID snapbufr, VRLEN buflen);

Parameters:

  • opcode specifies the action to be taken by the snapshot function.
  • rqstdesc points to an ASCII string containing the input information.
  • snapbufr points to an output buffer of length buflen.

Different opcodes require different combinations of input and output parameters ranging from using neither of them to both of them.

Description

FairCom DB tracks and reports a wealth of performance-oriented statistics. FairCom DB's Snapshot capability enables the capture of performance monitoring data using a combination of configuration file options and the SnapShot API function. The performance data can be captured automatically at specified intervals or on demand in the following ways:

  • The ctstat utility provides a command-line interface to the SNAPSHOT API function, supporting output of FairCom DB statistics at the core database engine, user, file, and function levels.
  • Configuration file options support automatic performance snapshots by specifying the interval between automatic snapshots and the contents of the snapshots. The performance data captured by automatic snapshots are written to the FairCom DB system event log (SYSLOG) files.
  • Use DIAGNOSTICS options to capture the automatic system snapshot data to the human-readable SNAPSHOT.FCS file.
  • The SnapShot() API function can control automatic snapshots, overriding configuration options (if any), and can capture on-demand performance data:
    • to either the SYSLOG files or to the human-readable SNAPSHOT.FCS file, or
    • as a return to the calling program.

For tips about monitoring system performance using this function, see Performance Monitoring Using the SnapShot API.

Snapshot Contents

Each snapshot is composed of a structure (ctGSMS for system info, ctGUMS for user info and ctGFMS for file info) followed optionally by a variable region. Each of the three snapshot structures contains information about the size of the structure and the amount of variable information, if any, following the structure. Further, if the output buffer is too small to hold all the variable information, the contents member of the main structure will have the ctSNAPSHOTtruncated bit turned on if information had to be truncated.

Note: These structure definitions may vary depending on the version of the FairCom DB and FairCom DB client versions you are using. Please consult the c-tree headers for the actual structure definition that is in use. Differences in definitions between a given ctstat client and FairCom DB may make ctstat incompatible with that server, in which case the ctstat utility displays an error message indicating structure incompatibility.

The only variable information consists of an array of function timing results for the overall system or for a user. The array is composed of ctWRKSTT structures. Function timings are described below, but these timings are only for direct calls from c-tree clients.

^ High-Resolution Timers - Most of the elapsed times accumulated in the snapshots are based on high-resolution timers that report in numbers of ticks and are stored in eight-byte integers. The description following each structure member contains a ‘^’ to indicate results based on high-resolution timers. To convert such times to seconds, divide by the ticks per second, a system dependent value stored in the scthrbastim member of each snapshot structure.

Snapshot Structures

System Snapshot Structure

File Snapshot Structure

User Snapshot Structure

SQL Snapshot Structure

Replication Snapshot Structure

Transaction Snapshot Structure

File List Snapshot Structure

CHECKLOCK List Snapshot Structure

Memory Snapshot

#define ctGMMSvern 1 /* ctGMMS (memory snapshot) version # */

#define TOTMEMLIST (24 /* NUMCTLIST */ + 1)

 

typedef struct ctgmms {

ULONG client_ver; /* client version of structure */

ULONG server_ver; /* server version of structure */

LONG8 snapshottm; /* snapshot time stamp: seconds since 70 */

 

TEXT memdsc[TOTMEMLIST][8]; /* Suballocator list description */

LONG8 memalc[TOTMEMLIST]; /* Allocated suballocator memory */

LONG8 memuse[TOTMEMLIST]; /* Used suballocator memory */

 

} ctGMMS, ctMEM * pctGMMS;

 

Snapshot Actions and Options

System Snapshot Support

The SnapShot API function supports logging FairCom DB system statistics. For a listing of the system statistics FairCom DB collects, refer to the ctGSMS structure in the Snapshot Contents section below. The supported operations include:

Snapshot action opcode rqstdesc snapbufr
On-demand system snapshot returned directly in the output buffer. No entry is made in SYSLOG. ctPSSsystem NULL Address of output buffer large enough to hold at least a ctGSMS structure
On-demand system snapshot written to the SNAPSHOT.FCS text file. ctPSStext An optional text description, or NULL NULL

 

File Snapshot Support

The SnapShot API function supports logging FairCom DB file statistics. For a listing of the file statistics the FairCom DB collects, refer to the ctGFMS structure in the Snapshot Contents section. The supported operations include:

Snapshot action opcode rqstdesc snapbufr
Activate the file with the specified file name. Use a pattern of ‘*’ to activate all files. ctPSSaddFileName File name (e.g., “cust*.*”) NULL
Activate the file with the specified file number. ctPSSaddFileNo Small integer file number (e.g., "0") NULL
On-demand file snapshot returned directly in the output buffer for the file with file number specified by rqstdesc. No entry is made in SYSLOG. ctPSSfile Small integer file number (e.g., "3") Address of output buffer large enough to hold a ctGFMS structure
Undo all file activations. ctPSSclearFiles NULL NULL
On-demand file snapshot returned directly. No entry is made in SYSLOG. ctPSSfileSystemHandle System file number ctGFMS buffer
On-demand snapshot of all open files written to SNAPFILE.FCS, a comma-delimited text file. ctPSScsvFile NULL NULL
On-demand snapshot of all open files written to SNAPFILE.FCS, a simple text file. ctPSStextFile NULL NULL
Starts collection of disk I/O timing stats. It affects the contents of a file snapshot. Disk I/O timings can also be enabled from configuration file with the entry: DIAGNOSTICS SNAPSHOT_IOTIME ctPSStimeFileIoOn NULL NULL
Turn off disk I/O timings. Disk I/O timings require a significant number of calls to the high resolution timer, and are more consistent with diagnostic or testing modes of operation. ctPSStimeFileIoOff NULL NULL

User Snapshot Support

The SnapShot API function supports logging FairCom DB user statistics. For a listing of the user statistics FairCom DB collects, refer to the ctGUMS structure in the Snapshot Contents section below. The supported operations include:

Snapshot action opcode rqstdesc snapbufr
Activate the user with the specified User ID. Use a pattern of ‘*’ to activate all users. ctPSSaddUserID User ID
(e.g., “admin”)
NULL
Activate the user with the specified thread handle. ctPSSaddUserHandle Small integer thread handle (e.g., “12”) NULL
On-demand user snapshot returned directly in the output buffer. No entry is made in SYSLOG. The snapshot is for the user calling ctSNAPSHOT(). ctPSSuser NULL Address of output buffer large enough to hold at least a ctGUMS structure
On-demand user snapshot returned directly in the output buffer. ctPSSuserHandle Small integer thread handle (e.g., “12”) Address of output buffer large enough to hold at least a ctGSMS structure
Undo all user activations. ctPSSclearUsers NULL NULL

Automatic Snapshot Support

The SnapShot API function supports starting, stopping, and resuming automatic snapshots. The following table shows the parameters to pass to SnapShot to perform these operations.

Snapshot action opcode rqstdesc snapbufr
Start automatic snapshots, or change time interval if automatic snapshots are already enabled. ctPSSstartAuto Interval in minutes
(e.g., “60”)
NULL
Stop automatic snapshots. ctPSSstopAuto NULL NULL
Resume automatic snapshots with the same interval last used. ctPSSresumeAuto NULL NULL

 

Combined Snapshot Support

The SnapShot API function supports logging combined snapshots containing FairCom Server system statistics and user and file statistics for the specified activated users and files. This ability is supported by the following operation:

Snapshot action opcode rqstdesc snapbufr
On-demand snapshot of system and activated users and files written to SYSLOG. All entries to SYSLOG share the instance ID, a 4-byte integer, returned in the output buffer. ctPSSnow An optional text description up to 128 bytes, or NULL Address of a 4-byte integer to hold instance ID

Function Timing Snapshot Support

The SnapShot API function supports profiling of FairCom DB API function calls (function timing) and timing of user-defined operations. The supported operations include:

  • Starting and stopping the collection of FairCom DB API function timing statistics.
  • Resetting the function timing statistics.
  • Accumulating timings in user-defined timing baskets. Users may define up to 8 different timing baskets. A begin mark call establishes a high resolution starting time for the specified basket. An end mark call causes the specified basket counter to be incremented, and the elapsed time is added to the timing basket. The baskets are numbered from 0 to 7.

Note: Function timings require a significant number of calls to the high-resolution timer, and are more consistent with diagnostic or testing modes of operation.

The following table shows the parameters to pass to SnapShot() to perform these operations.

Snapshot action opcode rqstdesc snapbufr
Start collecting function-timing statistics. This can be called whether or not automatic snapshots are currently active. It affects the contents of snapshots written to SYSLOG, not when or if they occur. ctPSStimeWorkOn NULL NULL
Turn off function timings. ctPSStimeWorkOff NULL NULL
Mark beginning time for one of 8 user specified timing baskets. ctPSSbegMark Small integer between 0 and 7 (e.g., "3") NULL
Mark ending time for user specified timing basket. ctPSSendMark Small integer between 0 and 7 (e.g., "3") NULL
Clear all function-timing statistics. ctPSStimeWorkClear NULL NULL
On-demand snapshot of c-tree function timings written to SNAPFUNC.FCS, a simple text file. ctPSStextFunc NULL NULL
On-demand snapshot of c-tree function timings written to SNAPFUNC.FCS, a comma-delimited text file. ctPSScsvFunc NULL NULL

 

SQL Snapshot Support

The SnapShot API function has a mode for retrieving FairCom DB SQL specific statistics.

Snapshot action opcode rqstdesc snapbufr
SQL Statement cache counters ctPSSsqlSystem NULL ctSQLS

 

File List Snapshot Support

Snapshot action opcode rqstdesc snapbufr
On demand filelist snapshot returned directly. No entry is made in SYSLOG. ctPSSfilelist NULL ctGFLS

 

CHECKLOCK List Snapshot Support

Snapshot action opcode rqstdesc snapbufr
On demand CHECKLOCK_FILE snapshot returned directly. No entry is made in SYSLOG. ctPSSchecklockfile NULL ctGCMS

 

Memory Snapshot Support

Snapshot action opcode rqstdesc snapbufr
On demand memory allocation snapshot returned directly. No entry is made in SYSLOG. ctPSSmemAlloc NULL ctGMMS
Causes the server to write information on structure sizes and compile-time constants that affect server memory use to the file MEMINFO.FCS. ctPSSmeminfo NULL NULL

 

Replication Snapshot Support

The SnapShot API function supports logging information about the FairCom Server replication state. For a listing of the transaction statistics the FairCom Server collects, refer to the ctPSSreplread structure in the Snapshot Contents section below. The supported operations include:

Snapshot action opcode rqstdesc snapbufr
Retrieve information about FairCom Server replication state. On-demand replication reader snapshot is returned directly. No entry is made in SYSLOG. ctPSSreplread    

Transaction Snapshot Support

The SnapShot API function supports logging FairCom Server transaction statistics. For a listing of the transaction statistics the FairCom Server collects, refer to the ctPSStransaction structure in the Snapshot Contents section. The supported operations include:

Snapshot action opcode rqstdesc snapbufr
Retrieve FairCom Server's transaction statistics. ctPSStransaction    


Snapshot support for FairCom Server compiled without transaction control

In V11 and later, support has been added for using the SnapShot feature when FairCom DB Server is compiled without transaction control (UNIFRMAT server, for example). (ctSNAPSHOT API and utilities such as ctstat and FairCom DB Monitor use this feature.)

Prior to this modification, FairCom DB Monitor had limited functionality on a server that did not support transaction processing: the Files Stats, System Snapshot, User Snapshot, Snapshot Favorites, and Function Timing tabs could not be used (typical error = 454, not supported).

Note: Although the snapshot API is now supported by a server, some functions (such as replication and transaction information) are not supported.

 

 

Return Values

SnapShot returns NO_ERROR (0) on success, or an error code on failure.

0 CTDBRET_OK Successful operation.

See c-tree Error Codes for a complete listing of valid c-tree error values.

Example


   ...

   ctGSMS* my_sysSnap;
   NINT rc = 0;

   my_sysSnap = (ctGSMS*) malloc(sizeof(ctGSMS));
   memset(my_sysSnap, 0, sizeof(ctGSMS));

   rc = InitISAMXtd(10, 10, 8192/128, 10, 0, "ADMIN", "ADMIN", "FAIRCOMS");

   if (rc) {
      printf("InitISAMXtd Error: %d\n", rc);
      return (rc);
   }
 

   /* Take a System SnapShot */
   rc = SnapShot(ctPSSsystem, NULL, my_sysSnap, sizeof(ctGSMS));

   if (rc) {
      printf("SnapShot Error: %d\n", rc);
      return (rc);
   }

   rc = CloseISAM();
   if (rc)
      printf("CloseISAM Error: %d\n", rc);

   /* Print Memory statistics */

   printf("High Mem: %d\n", my_sysSnap->sctmemhgh);
   printf("Current Mem: %d\n", my_sysSnap->sctmemsum);

    

 

   /* Print Disk I/O statistics */

   printf("Read ops: %d\n", my_sysSnap->sct_rdops);
   printf("Read bytes: %d\n", my_sysSnap->sct_rdbyt);
   printf("Write ops: %d\n", my_sysSnap->sct_wrops);
   printf("Write bytes: %d\n", my_sysSnap->sct_wrbyt);

   /* Print Platform Specific Server information */

   printf("Server flavor: %d\n", my_sysSnap->sflvr);
   printf("Alignment: %d\n", my_sysSnap->salgn);
   printf("Pointer size: %d\n", my_sysSnap->spntr);

   free(my_sysSnap);

   ...

See also

 

StopServer

Stop operation of the FairCom Server.

Short Name

STPSRV()

Type

Server-only function

Declaration

COUNT StopServer(pTEXT usrword, pTEXT servname, COUNT delay)

Description

StopServer() stops operation of the FairCom Server from inside an application. usrword must point to the password of the system administrator, ADMIN. servname can point to an optional FairCom Server name, or may be NULL when using the default FairCom Server name.

The application should NOT be connected to the FairCom Server when StopServer() is called. Call RegisterCtree() before and UnRegisterCtree() after the call to StopServer().

A non-zero delay specifies the number of seconds the FairCom Server should delay before beginning the shut down process. The delay allows transactions in process to complete. When a non-zero delay is specified, the FairCom Server does not accept any new users or new transactions while waiting to shut down. Logons and transactions fail with SHUT_ERR (150). After the delay expires, the FairCom Server immediately shuts down. Any users currently logged in are logged off and any incomplete transactions are aborted.

Note: If the Replication Agent is running on a server, replication should be stopped before trying to stop the server. If replication is running when you attempt to stop the server, you will see error 792 (External server shutdown disabled).

Return

Value Symbolic Constant Explanation
0 NO_ERROR Successful allocation.
133 ASKY_ERR FairCom Server cannot be found. Has it been shut down?
451 LPWD_ERR Invalid administrator password.
535 REGC_ERR No c-tree instance registered.

See c-tree Error Codes for a complete listing of valid c-tree error values.

Example

TEXT      usrword[10];

TEXT      servname[256];

COUNT     delay=10;


RegisterCtree(MYREGID);

printf("\nEnter the password: ");

scanf("%10s",usrword);

printf("\nEnter the server name:");

scanf("%255s",servname);


if (StopServer(usrword,servname,delay)

    printf("\nError on StopServer() error = %d",uerr_cod);


UnRegisterCtree(MYREGID);

See also

RegisterCtree(), UnRegisterCtree()

 

StopServerXtd

Stop operation of the FairCom Server, Extended Version

Short Name

STPSRVX()

Type

Server-only function

Declaration

COUNT StopServerXtd(pTEXT admnuser, pTEXT usrword,

                      pTEXT servname, COUNT delay)

Description

StopServerXtd() stops operation of the FairCom Server from inside an application. usrword must point to the password of the system administrator, admnuser. servname can point to an optional FairCom Server name, or may be NULL when using the default FairCom Server name.

The application should NOT be connected to the FairCom Server when StopServer() is called. Call RegisterCtree() before and UnRegisterCtree() after the call to StopServer().

A non-zero delay specifies the number of seconds the FairCom Server should delay before beginning the shut down process. The delay allows transactions in process to complete. When a non-zero delay is specified, the FairCom Server does not accept any new users or new transactions while waiting to shut down. Logons and transactions fail with SHUT_ERR (150). After the delay expires, the FairCom Server immediately shuts down. Any users currently logged in are logged off and any incomplete transactions are aborted.

Note: If the Replication Agent is running on a server, replication should be stopped before trying to stop the server. If replication is running when you attempt to stop the server, you will see error 792 (External server shutdown disabled).

Return

Value Symbolic Constant Explanation
0 NO_ERROR Successful allocation.
133 ASKY_ERR FairCom Server cannot be found. Has it been shut down?
451 LPWD_ERR Invalid administrator password.
535 REGC_ERR No c-tree instance registered.

See c-tree Error Codes for a complete listing of valid c-tree error values.

Example

TEXT      admnuser[10],usrword[10],servname[256];

COUNT     delay=10;


RegisterCtree(MYREGID);

printf("\nEnter the Admin ID: ");

scanf("%10s",admnuser);

printf("\nEnter the password: ");

scanf("%10s",usrword);

printf("\nEnter the server name:");

scanf("%255s",servname);


if (StopServerXtd(admnuser,usrword,servname,delay)

    printf("\nError on StopServerXtd() error = %d",uerr_cod);


UnRegisterCtree(MYREGID);

See also

RegisterCtree(), UnRegisterCtree()

 

StopUser

Log application off the FairCom Server.

Short Name

STPUSR()

Type

Server-only function

Declaration

COUNT StopUser() 

Description

StopUser() logs an application off a FairCom Server. It causes all the files not yet closed by the application to be closed and frees a slot on the Server for another user. StopUser() is automatically invoked by CloseISAM(). Therefore, StopUser() is only required in Low-Level applications, or in ISAM applications when a program can exit without calling CloseISAM().

Note: A c-tree application is automatically logged on to a FairCom Server whenever InitCTree(), InitISAM(), OpenISAM(), or CreateISAM() is called. There is no separate call for logging-on to the FairCom Server.

Return

StopUser() returns an error if it could not communicate with the FairCom Server. This might happen if the FairCom Server has been shut down or if the communications link has been disturbed.

Value Symbolic Constant Explanation
0 NO_ERROR Successful disconnect.
133 ASKY_ERR User cannot be found (has it been shut down?).
162 SGON_ERR Server communication link has been disturbed.
410 USTP_ERR User is not logged on when StopUser() was called.

See c-tree Error Codes for a complete listing of valid c-tree error values.

Example

pTEXT     pfname;


if (OpenISAM(pfname)) {

    printf("\nCould not OpenISAM. Error %d. File %d.", isam_err,isam_fil);

    StopUser();

    exit(2);

}

See also

CloseISAM(), InitCTree(), InitISAM(), OpenISAM(), CreateISAM()

 

StopUserAsync

Short Name

STPUSRA()

Type

Server-only function

Declaration

COUNT StopUserAsync(COUNT mode)

Description

StopUserAsync() is the same as StopUser() except that it returns immediately when called by a client without waiting for the server to complete the STPUSR() processing.

StopUserAsync() accepts a mode parameter to convey special user shutdown options. The only mode implemented affects flush operations: if a file is on the NO_SHUTDOWN_FLUSH list (see the NO_SHUTDOWN_FLUSH FairCom Server configuration keyword), and if StopUserAsync() is called with ctNOFLUSH OR-ed into mode, the file buffers will not be flushed if the StopUserAsync() causes the file closure, and the file will be marked corrupt.

Return

Value Symbolic Constant Explanation
0 NO_ERROR Successful disconnect.
133 ASKY_ERR User cannot be found (has it been shut down?).
162 SGON_ERR Server communication link has been disturbed.
410 USTP_ERR User is not logged on when StopUserAsync() was called.

See c-tree Error Codes for a complete listing of valid c-tree error values.

Example

COUNT     retval=0, buf = dbuf = 10, fil = sect = 32;

pTEXT     uid = "ADMIN", pass = "ADMIN", srv = "FAIRCOMS";


if (retval = InitISAMXtd(buf, fil, sect, dbuf, NULL, uid, pass, srv))

{

    printf("\nCould not initialize c-tree: %hd", retval);

    StopUserAsync(ctNOFLUSH);

    exit(2);

}

See also

StopUser()

 

SuperfilePrepassXtd

Preprocess superfiles to allow rebuilds.

Short Name

CTSBLDX()

Type

Low-Level function

Declaration

COUNT SuperfilePrepassXtd(pTEXT filnam, pTEXT fileword)

Description

SuperfilePrepassXtd() processes the superfile in place. Because a superfile holds numerous c-tree files in one physical file, there are complex inter-file relationships that SuperfilePrepassXtd() function cleans up.

SuperfilePrepassXtd() empties the index files. Each file in the superfile must now be processed by RebuildIFile() before it is usable.

As is the case with RebuildIFile(), the superfile must be closed prior to calling SuperfilePrepassXtd(). Both SuperfilePrepassXtd() and RebuildIFile() open and close the superfile and members.

In single user environments, the fileword parameter, file password, is ignored; i.e., you should pass both parameters, but the second one is ignored.

This operation is available as both a function and stand-alone utility. The function call can be used in single-user and client/server applications. The stand-alone implementation, ctsbld, is available only as a single-user utility.

Return

Value Symbolic Constant Explanation
0 NO_ERROR SuperfilePrepassXtd() completed successfully.
12 FNOP_ERR Could not open file. Check isam_fil for the specific file number. See c-tree Error Codes for more details.
43 FVER_ERR Current c-tree configuration is incompatible with file.
46 FUSE_ERR File number is already in use.
48 FMOD_ERR Operation is incompatible with the file type.
62 LERR_ERR Underlying data file must be opened in ctEXCLUSIVE mode.
165 SNFB_ERR No file control block is available.
418 SNAM_ERR Name inconsistency.
485   File sortwork.00x could not be created. Increase fils in c-tree initialization.

See c-tree Error Codes for a complete listing of valid c-tree error values.

Example

TEXT     filnam[64];


printf("\nEnter superfile host name: ");

scanf("%63s",filnam);

if (SuperfilePrepassXtd(filnam, NULL))

    printf("\nError on superfile pre-pass, error = %d on file

           %d", isam_err, isam_fil);

See also

Functions RebuildIFile(), RebuildIFileXtd() and the ctsbld utility.

 

SwitchCtree

Switch to a specific c-tree instance.

Short Name

SWTCTREE()

Type

Low-Level function

Declaration

COUNT SwitchCtree(pTEXT regid)  

Description

SwitchCtree() makes the instance identified by the supplied registration reference name regid active.

Note: regid is case sensitive and must be exactly the same value previously passed to RegisterCtree.

Return

Value Symbolic Constant Explanation
0 NO_ERROR Instance successfully switched.
516 GNUL_ERR ctNOGLOBALS not allocated.
517 GNOT_ERR regid is not registered.

See c-tree Error Codes for a complete listing of valid c-tree error values.

Example

TEXT     inpbuf[128] = "myInstance"; /* input buffer */


if (SwitchCtree(inpbuf)) {

    ctrt_printf("\nCould not SWITCH to {%s} instance.",inpbuf);

    ctrt_exit(2);

}

See also

NextCtree(), RegisterCtree(), WhichCtree(), GetCtreePointer(), UnRegisterCtree()

 

SystemConfiguration

Describes the configuration of the c-tree system.

Short Name

SYSCFG()

Type

Low-level function

Declaration

COUNT SystemConfiguration(pVOID bufptr)  

Description

SystemConfiguration returns an array of LONGs describing the c-tree system configuration, as well as some of the important dynamic aspects of the system, such as the memory usage and the number of files in use. The number of elements in the array is given by ctCFGLMT, which defaults to 256.

To determine if a particular system configuration option is active, check to see if its corresponding array element is non-zero. For example, to determine if TRANPROC was turned on during system compilation, check element cfgTRANPROC of the configuration array to determine if it is non-zero.

Dynamic System Resources

The following configuration array subscripts correspond to dynamic system resources and are interpreted as noted:

cfgMEMORY_USAGE

Current system memory usage.

Note: This value can overflow.

cfgMEMORY_HIGH

High-water mark of allocated memory: the largest amount of memory that has been allocated at one time since server startup.

Note: This value overflows if over 2 GB. Use system snapshot to read the 8-byte sctmemhgh counter value instead.

cfgNET_ALLOCS Current system net allocations. (Number of memory allocations minus the number of free calls.)
cfgOPEN_FILES c-tree files opened by system.
cfgPHYSICAL_FILES Physical c-tree files open. Includes superfile members omitted from cfgOPEN_FILES count.
cfgOPEN_FCBS c-tree file control blocks in use by system.
cfgLOGIDX Indicates if file mode ctLOGIDX is supported.

Server Implementations

The following array subscripts only apply to server implementations:

cfgDNODE_QLENGTH Messages in delete node queue.
cfgCHKPNT_QLENGTH Messages in checkpoint queue.
cfgSYSMON_QLENGTH Messages in system monitor queue.
cfgLOGONS Current number of logons.
cfgNET_LOCKS Current number of pending locks (system wide).
cfgUSERS Maximum number of logons.
cfgMAX_CONNECT The limit for the maximum number of logons.
cfgUSER_FILES Number of c-tree files opened by calling user.
cfgUSER_MEMORY Current user memory usage.
cfgPATH_SEPARATOR ASCII value for the file name path separator.
cfgMAX_CLIENT_NODES The maximum number of client nodes that can be connected at a time (a value of zero indicates no limit)
cfgMAX_CONN_PER_NODE The maximum number of concurrent connections per client node (a value of zero indicates no limit)
cfgLOCAL_CONN_ONLY Whether or not connections from remote systems are allowed (a value of zero indicates that remote connections are allowed)

Static Compile-Time Values

The following array subscripts are static compile-time values:

cfgFILES Maximum number of c-tree file control blocks available system wide.
cfgMAX_DAT_KEY Maximum number of indexes per data file.
cfgMAX_KEY_SEG Maximum number of key segments per index.

Client and Server Versions ("app" suffix)

The subscripts displayed in this section and the pre-initialization resources section below have client and FairCom Server versions, except for the following three subscripts:

cfgINIT_CTREEapp Determine whether c-tree has been initialized.
cfgSERIALNBR The FairCom Server serial number.
cfgTHREADapp Indicates if threading has been enabled.

Subscripts ending with ‘app’ are specific to the client side of a client/server application. To check the same system setting for the FairCom Server, use the same subscript without the app extension. For example, to determine if Conditional Index support is active on the FairCom Server, use cfgCONDIDX as the subscript and cfgCONDIDXapp for the client side. On the client side, it is assumed the argument to SystemConfiguration is an array of properly aligned LONGs.

If SystemConfiguration is called for a non-client library, use the ‘app’ versions, i.e., cfgCONDIDXapp.

cfgBOUNDapp Indicates if the application is bound to a database library. See the discussion on the different FairCom I/O models in these notes.
cfgDISKIO_MODELapp A non-zero value indicates a stand-alone multi-user I/O model i.e. FPUTFGET.
cfgLOCLIBapp A non-zero value indicates Local Library support.
cfgNOGLOBALSapp A non-zero value indicates no globals are supported i.e. indicating all globals are stored in an allocated structure. This is the default setting.
cfgUNIFRMATapp A non-zero value indicates FairCom’s automatic byte flipping (UNIFRMAT) is active.

The pre-initialization resource subscripts below may be specified prior to a c-tree initialization call, i.e., InitISAM, InitCTree, in addition to having both a client and FairCom Server version, as discussed above.

cfgANSIapp Specifies whether to use ANSI. A non-zero value indicates ANSI.
cfgCONDIDXapp A non-zero value indicates the application supports FairCom’s Conditional Index Logic.
cfgCTBATCHapp A non-zero value indicates the application supports Batch Operations.
cfgCTSUPERapp A non-zero value indicates the application supports Superfiles.
cfgCTS_ISAMapp A non-zero value indicates the application supports FairCom’s ISAM API.
cfgHISTORYapp A non-zero value indicates the application supports FairCom’s History Logic.
cfgINIT_CTREEapp A non-zero value indicates c-tree has been initialized.
cfgLOGIDXapp A non-zero value indicates the application supports the ctLOGIDX Logic.
cfgPARMFILEapp A non-zero value indicates parameter files are supported.
cfgPASCAL24app A non-zero value indicates 2-byte/4-byte length delimited strings are using the traditional pascal length convention.
cfgPASCALstapp A non-zero value indicates byte length delimited strings are using the traditional pascal length convention.
cfgPATH_SEPARATORapp Return the ASCII value for the file name path separator.
cfgPROTOTypeapp A non-zero value indicates the application supports Prototypes.
cfgRESOURCEapp A non-zero value indicates the application supports Resource Records.
cfgRTREEapp A non-zero value indicates the application supports r-tree.
cfgSERIALNBR Return FairCom Server serial number. You must display and use the returned number as a hex value.
cfgTHREADapp A non-zero value indicates the application supports FairCom’s threading API.
cfgTRANPROCapp A non-zero value indicates the application supports Transaction Processing.
cfgVARLDATAapp A non-zero value indicates the application supports Variable-length Records.
cfgVARLKEYSapp A non-zero value indicates the application supports Variable-length Keys i.e. Key compression.
cfgWORD_ORDERapp Indicates the client data order: Low_High or High_Low. A non-zero value indicates Low_High.

Pascal Length Byte

c-tree supports two different methods for specifying the length byte in a Pascal data type. The original and non-traditional approach does not include the length byte in the byte count. For example, with a 1-byte data type, CT_FPSTRING, the smallest valid length byte would be 0. The new method follows the more traditional Pascal convention of including the length byte in the byte count. For example, with the traditional approach, the smallest valid length for a 1-byte data type would be 1. Therefore, if cfgPASCALstapp or cfgPASCAL24app return a non-zero value, the new traditional approach is active.

To receive a valid return value from cfgPATH_SEPARATOR, ctPATH_SEP must be defined. The default definition found in ctopt2.h is:

#define ctPATH_SEP   '?'

This definition specifies that the system default path separator will be used. To use the same separator for all platforms, you might want to choose one of the following:

#define ctPATH_SEP   '\\'

/* define for Windows */

#define ctPATH_SEP   '/' 

/* define for most Unix systems */

#define ctPATH_SEP   ':' 

/* define for Mac OSX */

Configuration Bitmaps

The following configuration bitmaps are used with the cfgCFGCHK element of the SystemConfiguration output array. When the bit is on, the corresponding configuration is in effect. The current configuration bit mask definition is:

cfgCFGCHK This 32-bit value contains bits to indicate if particular features are enabled at runtime. See cfgCFGCHK below.
cfgCFGCHKmtclient ((LONG)0x00000002) mtclient DLL loaded (V11 and later)
cfgCFGCHKxfrfile ((LONG)0x00000004) File transfer API enabled (V11 and later)

cfgCFGCHK

The SYSCFG() function's cfgCFGCHK element is a 32-bit value that contains bits to indicate if particular features are enabled or disabled at runtime.

In V11.5 and later, a bit has been added to indicate if the advanced encryption feature is enabled:

#define cfgCFGCHKadvenc ((LONG)0x00000008) /* advanced encryption enabled */

 

The cfgCFGCHK element also indicates if REPL_MAPPINGS is in effect for FairCom Server.

Feature Bitmaps

The following feature bitmaps are used with the cfgFEACHK element of the SystemConfiguration output array. When the bit is on, the corresponding feature is available. This is useful for client applications where the availability of a feature is not known at compile/link time. The current feature bit mask definitions are:


cfgFEACHK

cfgFEACHKplusName +index name support for PermIIndex.
cfgFEACHKhugeFile Huge file support.
cfgFEACHKCLOSEInTran Close or delete of an updated file inside an active transaction does not abort the transaction: either an error is returned, or the close or delete is deferred until transaction commit or abort.
cfgFEACHKencryption Encryption is supported.
cfgFEACHKflexFile Flexible file limits are supported.
cfgFEACHKdiskFull Support disk full checks.
cfgFEACHKuniqFile Support auto reassignment of duplicated file IDs.
cfgFEACHKxtdCmp Extended key compression.
cfgFEACHK6BT Extended 6-byte tran#.
cfgFEACHKoldBCD Old BCD compatibility.
cfgFEACHKeventLogVer2 Advanced event log.
cfgFEACHKchkPntLst Adj checkpoint list counters.
cfgFEACHKnoFlushDel Suppress flush on delete.
cfgFEACHKzeroRecbyt Zero RECBYT support.
cfgFEACHKsysView System view log.
cfgFEACHKencrypTCPIP Encrypt TCPIP.
cfgFEACHKlowlCRC Common low-level CRC.
cfgFEACHKcommSUMCHK Common sum check.
cfgFEACHKpag64K 64K page size supported.
cfgFEACHKreadShare Read-only for shared files.
cfgFEACHKsplCache Dedicated cache support.
cfgFEACHKpriCache Cache priming support.
cfgFEACHKnoCache No cache data file list.
cfgFEACHKnoFlush Skip flush on close.
cfgFEACHKfpgCache Data cache FPUTFGET.
cfgFEACHKdataFilter Data filters.
cfgFEACHKdepRename TRANDEP rename support.
cfgFEACHKchannels Flexible I/O channels.
cfgFEACHKalgnchnl Aligned I/O channels.
cfgFEACHKkeepopen KEEPOPEN 4 nonMEMFILES.
cfgFEACHKiict Immediate Commit Transaction (IICT) support.


cfgFEACHK2

cfgFEACHK2copyfile File copy API enabled (V11 and later)

 

Note: An initial c-tree call (InitCTree, InitCtreeXtd, InitISAM, etc.) must be made before SystemConfiguration can check on the cfgFEACHK element. The cfgINIT_CTREEapp element can be evaluated to determine the status of the c-tree initialization.

For example:

  LONG       ca[ctCFGLMT];

 

SystemConfiguration(ca);

 

if (ca[cfgINIT_CTREEapp] == YES)

    printf("c-tree Initialized");

else

    printf("c-tree Uninitialized: %ld",

           ca(cfgINIT_CTREEapp));

 

/* where the Uninitialized value is NINT_ERR for a client or FINT_ERR for a bound application */

System-wide Cache and Buffer Statistics

SystemConfiguration returns nine values referenced with the following constants used as subscripts in the output array of LONG values an application can use to capture system-wide cache and buffer statistics, (cache pages hold data record images and buffers hold index nodes), allowing an application to track the use of these resources.

cfgCACHE_PAGES Available cache pages
cfgCACHE_PAGES_INUSE Cache pages in use
cfgCACHE_PAGES_MXUSE Maximum cache pages used
cfgCACHE_PAGES_DED Available dedicated cache pages
cfgCACHE_PAGES_DEDINUSE Dedicated cache pages in use
cfgCACHE_PAGES_DEDMXUSE Maximum dedicated cache pages used
cfgBUFFER_PAGES Available index buffers
cfgBUFFER_PAGES_INUSE Index buffers in use
cfgBUFFER_PAGES_MXUSE Maximum index buffers used

Note: The dedicated cache pages are a subset of the regular cache pages.

Please see the following example for the use of this feature.

  LONG      ctcfg[ctCFGLMT];

SystemConfiguration(ctcfg);

printf("\nAvailable Dedicated Cache Pages - %ld",

       ctcfg[cfgCACHE_PAGES_DED]);

Version Information

These values allow a client to display the same server version and build date that the FairCom Server displays.

cfgVERSIONID The version number.
cfgVERSIONID2 The mini version and build date values (V10.3 and later).
cfgVERSIONID_BASE The base build date value (V10.3 and later).

The ctdbGetProductVersion() function is a good way to get these values in a form that is more readable than these binary values.

Additional Array Elements

The following array subscripts are also returned:

cfgBROADCAST_PORT The TCP/IP port used for the broadcast (default: 5595). See https://docs.faircom.com/doc/ctserver/27902.htm
cfgBROADCAST_INTERVAL The number of seconds between broadcasts. See https://docs.faircom.com/doc/ctserver/27901.htm
cfgBROADCAST_DATA A token to be broadcast following the Server Name. See https://docs.faircom.com/doc/ctserver/27900.htm
cfgCACHE_LINE The smallest amount of memory a processor will retrieve and store in its highest speed cache. See https://docs.faircom.com/doc/ctserver/27906.htm
cfgCACHE_PAGES_SCN The number of data cache pages allowed to be used as scanner LRU pages. The configuration option SCAN_CACHE_PERCENT can be used to set this value as a percentage of the total data cache size.
cfgCACHE_PAGES_SCNINUSE The current number of data cache pages that are being used as scanner LRU pages.
cfgCACHE_PAGES_SCNMXUSE The high-water mark (maximum number at any time in the past) of data cache pages that have been used as scanner LRU pages.
cfgCACHE_STAT_ARRAY_SIZE The number of memory locations for each counter (data cache requests, data cache hits, index cache requests, index cache hits). See http://docs.faircom.com/doc/v103ace/#59144.htm and http://docs.faircom.com/doc/v103ace/#59678.htm
cfgCONNECTIONS The maximum number of connections to the FairCom Server. See https://docs.faircom.com/doc/ctserver/#27890.htm
cfgCOUNTED_LOGONS The current number of logons that count toward the connection limit if the server uses connection group support (otherwise, the value is 0).
cfgDATA_LRU_LISTS The number of LRU lists maintained for data cache pages. See https://docs.faircom.com/doc/ctserver/#49143.htm Note: The LRU algorithm is no longer used for the data cache.
cfgFIXED_LOG_SIZE Indicates if the feature to automatically adjust the size of the log files to accommodate long records has been disabled (see also cfgLOG_RECORD_LIMIT). See https://docs.faircom.com/doc/ctserver/#27928.htm
cfgFLEX_FCBS System file number high-water mark: the largest system file number that has been used since server startup.
cfgINDEX_LRU_LISTS The number of LRU lists maintained for index cache/buffer pages. See https://docs.faircom.com/doc/ctserver/#49142.htm
cfgLANGUAGE Support the r-tree language feature in an r-tree enabled server. Accepts three arguments: ENGLISH, SJIS, or EUC. See https://docs.faircom.com/doc/ctserver/#57454.htm
cfgLOG_RECORD_LIMIT The data record length limit that triggers an increase the size of the log files. Transaction controlled records longer than this limit increase the size of the log files, or cause a TLNG_ERR (error 654) if the log space is fixed. The initial record length limit is approximately one fortieth of the total log space. The limit is reset each time the log size is adjusted (increased). (See also cfgFIXED_LOG_SIZE.)
cfgLOG_SPACE The number of megabytes of disk space allocated to storing active transaction logs. See https://docs.faircom.com/doc/ctserver/#27945.htm
cfgLOGON_FAIL_LIMIT The optional limit on the number of consecutive failed logons that causes subsequent logon attempts to fail for LOGON_FAIL_TIME minutes. See https://docs.faircom.com/doc/ctserver/#27946.htm
cfgLOGON_FAIL_TIME The length of time logons are blocked after the logon limit is exceeded (see also cfgLOGON_FAIL_LIMIT). See https://docs.faircom.com/doc/ctserver/#27947.htm
cfgLOGON_MUST_TIME A non-zero value requires users to log on at-least-once within the defined time or else their profile will be deactivated. See https://docs.faircom.com/doc/ctserver/#27948.htm
cfgMAX_LOGONS High-water mark of concurrent logons: the largest number of connections that have existed at one time since server startup.
cfgMAX_PHYSICAL_FILES High-water mark of open physical files: the largest number of physically opened files that have existed at one time since server startup.
cfgMAX_VIRTUAL_FILES The maximum number of virtual files that may be opened at one time. See https://docs.faircom.com/doc/ctserver/#27949.htm
cfgMEMORY_HASH The number of internal memory suballocator lists to be created for each of 11 ranges of allocation size (an entry of N indicates 11N lists are created, with N dedicated to a particular range of allocation size). See https://docs.faircom.com/doc/ctserver/#55778.htm
cfgMEMORY_HIGH

High-water mark of allocated memory: the largest amount of memory that has been allocated at one time since server startup.

Note: This value overflows if over 2 GB. Use system snapshot to read the 8-byte sctmemhgh counter value instead. (MEMORY_USAGE can also overflow.)

cfgMONAL1_QLENGTH Not used.
cfgMONAL2_QLENGTH Not used.
cfgPROCESS_ID The process ID of the c-tree Server process
cfgRECOVER_FILES The number of files used during automatic recovery if greater than the FILES keyword. See https://docs.faircom.com/doc/ctserver/#27967.htm
cfgRSPACE_QLENGTH Current number of entries in the space reclamation queue.
cfgSRV_MODEL This value indicates whether the server supports only ISAM functionality (1) or SQL functionality (2).
cfgSYNC_DELAY The number of seconds between log flushes. See https://docs.faircom.com/doc/ctserver/#57453.htm
cfgSYSLOG_QLENGTH The current number of entries in the SYSLOG queue. This queue contains entries that the system logging thread is going to write to the SYSLOG file.

 

Return

Value Symbolic Constant Explanation
0 NO_ERROR Successful configuration return.
47 FINT_ERR c-tree not initialized.

See c-tree Error Codes for a complete listing of valid c-tree error values.

Example

LONG      ctcfg[ctCFGLMT];       /* array of 256 longs */


SystemConfiguration(ctcfg);


printf("\nMemory Use is %ld\n", ctcfg[cfgMEMORY_USAGE]);

printf("Memory Highest is %ld\n", ctcfg[cfgMEMORY_HIGH]);

printf("Net allocation is %ld\n", ctcfg[cfgNET_ALLOCS]);

printf("Open Files level is %ld\n", ctcfg[cfgOPEN_FILES]);

printf("Physical Files is %ld\n", ctcfg[cfgPHYSICAL_FILES]);

printf("Open FCB's is %ld\n", ctcfg[cfgOPEN_FCBS]);

printf("ctLOGIDX support is %ld\n", ctcfg[cfgLOGIDX]);

See also

Functions InitISAM(), InitCTree(), InitCtreeXtd() and ctport.h utility.

 

SystemLog

Manipulate a log of system events in a c-tree format file.

Short Name

SYSLOG()

Type

Low-Level function

Declaration

COUNT SystemLog(COUNT evclass, LONG event, pTEXT buffer, VRLEN buflen) 

Description

Use SystemLog() to add your own entries to the log. evclass must be ctSYSLOGapi or higher. buflen should not exceed SYSLOGvar, 8100 bytes. The contents pointed to by buffer do NOT need to be actual text. No assumptions are made about the contents of buffer.

Each entry in the system log, SYSLOGDT.FCS, is a variable-length record using the SYSLOGrec structure defined in ctport.h. Typically, the SYSLOGrec structure overlays a buffer capable of holding an entire record. A buffer of SYSLOGmax bytes will hold any entry in the system log. A DODA with the record layout below is added to SYSLOGDT.FCS when it is created:

typedef struct ctslog {

 LONG   evclass;           /* overall type of entry                    */

 LONG   event;             /* the particular event code                */

 LONG   date;              /* date measured in days: r-tree compatible */

 LONG   time;              /* seconds past midnight                    */

 LONG   rsvrd;             /* for future use                           */

 LONG   seqnm;             /* sequence number                          */

 LONG   error;             /* uerr_cod at time of entry                */

 TEXT   userid[SYSLOGidz]; /* logon user ID                            */

 TEXT   nodnam[SYSLOGidz]; /* logon node name                          */

 UCOUNT vlen;              /* length of variable region                */

 TEXT   vfld[2];           /* beginning of variable region             */

} SYSLOGrec, ctMEM * pSYSLOGrec;

 

The FairCom-defined evclass codes are:

Value (Long) Symbolic Constant Explanation
0x001 ctSYSLOGuser User logon information
0x002 ctSYSLOGddmp Dynamic dump information
0x003 ctSYSLOGstat CTSTATUS entries
0x004 ctSYSLOGtmpuser Temp user logon info
0x005 ctSYSLOGdelfil File delete information
0x006 ctSYSLOGanl Abort node list
0x007 ctSYSLOGsnap Snapshot
0x008 ctSYSLOGrstpnt Restore points
0x010 ctSYSLOGsql SQL info
0x0400 ctSYSLOGpurge Special purge request
0x0401 ctSYSLOGapi Beginning of vendor defined event classes

It is anticipated that additional evclass codes will be defined, with appropriate event codes, as additional types of FairCom Server operations are added to the system log facility.

 

The user logon info event codes are:

Value (Long) Symbolic Constant Explanation
0x001 ctSYSLOGuserLOGON Successful logon
0x002 ctSYSLOGuserLOGOFF Logoff
0x003 ctSYSLOGuserLOGFAIL Failed logon
0x004 ctSYSLOGuserADDUSER Add new user
0x005 ctSYSLOGuserCHGUSER Modify user profile
0x006 ctSYSLOGuserDELUSER Delete user
0x007 ctSYSLOGuserSQLLOGON Successful SQL logon
0x008 ctSYSLOGuserSQLLOGOFF SQL logoff
0x009 ctSYSLOGuserSQLLOGFAIL Failed SQL logon

On the ADDUSER, CHGUSER, and DELUSER entries, the variable buffer portion of the entry contains the user ID and a brief description of the type of activity. The actual details of the user profile information are not in the log.

 

The dynamic dump event codes are:

Value (Long) Symbolic Constant Explanation
0x001 ctSYSLOGddmpBEGIN Begin dynamic dump
0x002 ctSYSLOGddmpTRAN Transaction controlled file
0x003 ctSYSLOGddmpCLEAN Clean non-transaction file
0x004 ctSYSLOGddmpDIRTY Dirty non-transaction file
0x005 ctSYSLOGddmpINFO Dump information
0x006 ctSYSLOGddmpWARN Dump warning
0x007 ctSYSLOGddmpERR Fatal dump error
0x010 ctSYSLOGddmpEND End dynamic dump

The TRAN, CLEAN, and DIRTY log entries contain the name of the file dumped in the variable buffer portion of the log record.

There are no event codes for CTSTATUS entries. They are all event zero.

 

The file delete event codes are:

Value (Long) Symbolic Constant Explanation
0x001 ctSYSLOGdelfRSTR Restore of deleted file. (12-byte File ID, Original Name, Copy Name)
0x002 ctSYSLOGdelfTRAN Transaction-dependent delete. (12-byte File ID, Original Name, Copy Name)
0x003 ctSYSLOGdelfNOTRAN Non-transaction-dependent delete. (12-byte File ID, Original Name)

 

The abort node list event codes are:

Value (Long) Symbolic Constant Explanation
0x001 ctSYSLOGanlADDDEL Add / delete pair

 

The snapshot event codes are:

Value (Long) Symbolic Constant Explanation
0x001 ctSYSLOGsnapSYSTEM System snapshot
0x002 ctSYSLOGsnapFILE File snapshot
0x003 ctSYSLOGsnapUSER User snapshot

 

The restore point info event codes are:

Value (Long) Symbolic Constant Explanation
0x001 ctSYSLOGrstpntCREATE Create restore point
0x002 ctSYSLOGrstpntRECOVERY Recovery results
0x003 ctSYSLOGrstpntTRANBAK TRANBAK results
0x004 ctSYSLOGrstpntNOKEEP Create restore point but no keep

 

The SQL info event codes are:

Value (Long) Symbolic Constant Explanation
0x001 ctSYSLOGsqlSTMT SQL statement

 

The developer of the calling application assigns the user-defined event codes.

The maximum length for the variable-length portion of the log entry is given by the constant SYSLOGvar, which defaults to 8100. The fixed length user ID and node name fields are SYSLOGidz bytes, which defaults to 32.

Purging entries from the log uses a special form of the SystemLog() call: evclass is set as ctSYSLOGpurge, and event is set to zero to purge all classes, or to a particular evclass code to only purge entries from that class. The number of days of entries to keep is specified by placing the number of days to keep in an integer and passing the address of the integer in buffer and the length of the integer in buflen.

Return

SystemLog() returns an error code, NO_ERROR (0) on success.

Note: The actual writing of the log is performed by a dedicated FairCom Server thread which reads a queue fed by SystemLog() calls and internal server calls. The successful return of the SystemLog() call does not guarantee that the entry has been made in the log.

Value Symbolic Constant Explanation
0 NO_ERROR No error.
458 SWRT_ERR Attempt to write directly to system log files.

See c-tree Error Codes for a complete listing of valid c-tree error values.

This example shows how to keep the last seven days of user logon information, as well as all other entries regardless of date.

Example

NINT      days_to_keep = 7, retval;


retval = SystemLog(ctSYSLOGpurge,(LONG) ctSYSLOGuser,

                   (pTEXT) &days_to_keep,

                   (VRLEN) sizeof(NINT));

Limitations

Server configuration entries control which users, if any, can call SystemLog(). Review the FairCom Server Administrator’s Guide for complete details on server configuration and operation.

 

SystemMonitor

Monitor certain critical FairCom Server events.

Short Name

SYSMON()

Type

Server-only function

Declaration

COUNT SystemMonitor(COUNT mode, LONG timeout, pTEXT buffer, VRLEN buflen) 

Description

SystemMonitor() provides the ability for a client to monitor certain critical FairCom Server events. Each event causes a message to be written to an internal queue. Each call to SystemMonitor() reads a message from this queue. If no message is available, it waits for a message or times out.

mode can take on two values:

  • SYSMON_MAIN monitors the beginning and end of dynamic dumps and occurrence of file mirroring events.
  • SYSMON_OFF turns off the monitoring.

timeout specifies the time in seconds for a forced return of SystemMonitor() in the event that no event occurs. A value of -1L indicates an unlimited wait: SystemMonitor returns only when an event occurs or the Server stops. Note that the monitor is still in effect after a timeout return. For another process to start monitoring, the client currently monitoring must disconnect from the Server or call SystemMonitor() with the SYSMON_OFF mode.

buffer points to the buffer which receives a descriptive Server monitor message.

buflen is the length of the buffer.

Return

SystemMonitor() returns one of the following values. More events may be added in future releases.

Value Symbolic Constant Explanation
0 NO_ERROR When Server terminates.
156 NTIM_ERR Monitor timed-out without event.
454 NSUP_ERR System monitor not supported (non-server).
542 MCRE_ERR Could not create mirror file.
543 MOPN_ERR Could not open mirror file.
544 MCLS_ERR Could not close mirror file.
545 MDLT_ERR Could not delete mirror file.
546 MWRT_ERR Could not write to mirror file.
547 MSAV_ERR Could not save mirror file.
548 MRED_ERR Could not read (header) in mirror.
549 MHDR_ERR Mismatch between mirror headers.
550 MSKP_ERR Attempt to open primary w/o mirror.
551 MNOT_ERR File already opened without mirror.
555 PREA_ERR Could not read primary file, all I/O performed on mirror file only.
556 PWRT_ERR Could not write primary file, all I/O performed on mirror file only.
557 CWRT_ERR Could not write mirror file, all I/O performed on primary file only.
558 PSAV_ERR Could not save primary file, all I/O performed on mirror file only.
559 CSAV_ERR Could not save mirror file, all I/O performed on primary file only.
560 SMON_ERR Only one of each monitor at a time.
561 DDMP_BEG Dynamic dump begins.
562 DDMP_END Dynamic dump ends.
563 DDMP_ERR Dynamic dump ends with errors.

When coding the “switch” or other constructs to handle the SystemMonitor() return codes, be sure to provide a default to handle return codes which may be added in future implementations. See c-tree Error Codes in the c-tree Programmer’s Reference Guide for a complete listing of valid c-tree error values.

Example

VRLEN     buflen=128;

TEXT      buffer[128];   /* input buffer */

LONG      timeout = 10;


while(SystemMonitor(SYSMON_MAIN,timeout,buffer,buflen)) {

    switch(uerr_cod){

        case NSUP_ERR:

            printf("No monitor support\n");

            StopUser();

            exit(0);

        case NTIM_ERR:

            break;

        case PREA_ERR:

        case PWRT_ERR:

        case PSAV_ERR:

            printf("Primary file not operational (%d)\n%s\n", uerr_cod,buffer);

            break;

        case CWRT_ERR:

        case CSAV_ERR:

            printf("Mirror file not operational (%d)\n%s\n", uerr_cod,buffer);

            break;

        default:

            printf("other monitor event(%d)\n%s\n", uerr_cod, buffer);

            break;

    }    /* end of switch */

}    /* end of while */


/* if server has terminated */

StopUser();

exit(0);

Limitations

Available only with the FairCom Server. A call to SystemMonitor() on a non-server system results in error return NSUP_ERR (454).

Only one application connected to each Server may have SystemMonitor() active.

 

TempIIndexXtd

Temporary Incremental Index creation.

Short Name

TMPIIDXX()

Type

Extended ISAM function

Declaration

COUNT TempIIndexXtd(pIFIL ifilptr, LONG permmask,

                    pTEXT groupid, pTEXT fileword) 

Description

TempIIndexXtd() behaves the same as PermIIndex() except that the stored file definition is not updated, and you may be sharing the underlying Incremental data file. Each user can have separate and distinct temporary index files. Once the data file, ifilptr -> pfilnam, is closed the temporary index is no longer part of the Incremental ISAM structure. A single call:

  • Adds one or more additional indexes to an existing Incremental ISAM definition.
  • Automatically loads the indexes from the existing data (optional).
  • References the new indexes with the standard ISAM level calls (e.g., the next AddRecord() call updates the new indexes along with the original indexes).

The next time the Incremental file is opened, the new indexes will NOT be opened and used. However, the temporary file is not deleted. It should be deleted by the application using OpenCtFile() in ctEXCLUSIVE mode, followed by DeleteCtFile().

ifilptr points to a new IFIL structure in which:

  • dfilno contains the file number of the underlying Incremental data file.
  • ix points to the new index definitions.
  • tfilno is set to the first desired index number, or tfilno is -1 if you wish the index file number to be assigned, which is returned in tfilno.
  • dnumidx is the number of index files to create.

permmask is the permission mask assigned to this data file. It is formed by OR-ing the appropriate permission constants.

groupid is a pointer to a buffer that contains the group id that this file is to be assigned to. The group id must be valid for the user that is creating the file. If groupid is NULL, the file will be assigned to the default group for the user.

fileword is an optional file password. If fileword is NULL then there will be no password for this file. If a password is established, every user will need to use the password to be able to open the file. For more information on user id’s, user passwords, server names, permission masks, group id’s, and file passwords, review Security and Encryption (File Security and Encryption, /doc/ctreeplus/FileSecurityandEncryption.htm) in the c-tree Programmer’s Reference Guide.

Note: There is the potential for index/data inconsistency errors, such as RVHD_ERR (123), ITIM_ERR (160), etc., when using a temporary index in a multi-user environment. Temporary indexes are visible ONLY to the user who creates them and, therefore, any record updates and/or deletions by other users are not applied to the temporary index.

When a multiuser error occurs on a temporary index, the default server behavior is to skip the offending record and treat it as deleted. If another record satisfies the search request, that record will be returned. sysiocod is set to ITMP_COD (-832) to indicate the skipped record. This record skipping behavior can be disabled with server keyword COMPATIBILITY TEMP_INDEX_ERROR.

The ability to suspend the addition of existing data records to the newly created index creates new indexes without inserting keys for the existing records. This allows an application to have indexes containing only new entries, speeding access to newer data. Consider the following pseudocode:

  • Call TempIIndexXtd() with ifilptr -> dxtdsiz == ctNO_IDX_BUILD.
  • Do NOT call RebuildIIndex().
  • Add new data records, but no deletes or rewrites.
  • Use the temporary indexes to reference only the newly added data. The temporary indexes will not have any of the data that existed prior to the TempIIndexXtd() call.

See the ctNO_IDX_BUILD description in PermIIndex() for details.

Return

Value Symbolic Constant Explanation
0 NO_ERROR Successful creation of new temporary index.
107 IDRK_ERR Too many index files for one data file. Increase MAX_DAT_KEY in ctoptn.h or keyword in ctsrvr.cfg.
197 IMEM_ERR Not enough memory.
465 IINI_ERR ifilptr->dnumidx < 1.
466 IIDT_ERR ifilptr->dfilno does not reference an ISAM data file.
467 IINM_ERR ifilptr->ix->aidxnam must point to a new index file name.
468 IITR_ERR Incremental index cannot be built inside a transaction.

See c-tree Error Codes for a complete listing of valid c-tree error values.

See also

AddRecord(), OpenCtFile(), DeleteCtFile(), PermIIndex(), RebuildIIndex()

 

TempIIndexXtd8

Extended 8-byte temporary Incremental Index creation.

Short Name

TMPIIDXX8()

Type

Extended 8-byte ISAM function

Declaration

COUNT TempIIndexXtd8(pIFIL ifilptr, LONG permmask,

          cpTEXT groupid, cpTEXT fileword, pXCREblk pxcreblk)

Description

TempIIndexXtd8() is a variation of TempIIndexXtd() that permits the use of huge file support. This section expands on the description of TempIIndexXtd().

pxcreblk points to an array of XCREblk structures, the extended creation block, one for each physical file in ifilptr. For more information, review Huge File Support in the c-tree Programmer’s Reference Guide.

Return

TempIIndexXtd8() returns error codes similar to those for TempIIndexXtd(). See c-tree Error Codes in the c-tree Programmer’s Reference Guide for a complete listing of valid c-tree error values.

Limitations

PermIIndex8() and TempIIndexXtd8() support ctTRANDEP creates. Without ctTRANDEP creates, these routines cannot be called within a transaction. With ctTRANDEP creates, they MUST be called within a transaction.

See also

PermIIndex(), RebuildIIndex(), TempIIndexXtd()

 

TestFileNbr

Determine the status of a file number.

Short Name

TSTFILNUM()

Type

Low-Level function

Declaration

COUNT TestFileNbr(FILNO filno)

Description

In V12 the file number typedef was formally changed from COUNT, a two-byte value to FILNO, a four-byte value. Refer to this link for compatibility details. Four Byte File Numbering

TestFileNbr() returns zero if filno is not in use or returns FINT_ERR (47, c-tree not initialized), FNUM_ERR (22, filno is out of range), or FUSE_ERR (46, filno is in use). TestFileNbr() does NOT set or change uerr_cod.

Return

Value Symbolic Constant Explanation
0 NO_ERROR File number not in use.
22 FNUM_ERR filno is out of range.
46 FUSE_ERR filno is in use.
47 FINT_ERR c-tree not initialized.

See c-tree Error Codes for a complete listing of valid c-tree error values.

Example

COUNT    retval;


if (retval = InitISAM(6,7,4))

    printf("\nCould not initialize. Error %d.", retval);

else {

    if ((retval = TestFileNbr(5)) == 0) {

        if (OpenRFile(5, "MyFile.dat"))

            printf("\nCould not open files.");

    {

    else if (retval == 46)

        if (OpenRFile(-1, "MyFile.dat"))

            printf("\nCould not open files.");

    if (CloseISAM())

        printf("\nCould not close ISAM.");

}

 

TestHugeFile

Test 8-byte file status.

Short Name

TESTHUGE()

Type

Low-Level function

Declaration

  COUNT TestHugeFile(FILNO filno) 

Description

In V12 the file number typedef was formally changed from COUNT, a two-byte value to FILNO, a four-byte value. Refer to this link for compatibility details. Four Byte File Numbering

TestHugeFile() takes the file number of an opened file, filno, as its input argument to determine if the volume containing the file supports huge files.

Note: This function does NOT determine how much space is available, only if the OS logically supports such file sizes on the volume containing the open file referenced by filno.

Return

TestHugeFile() returns the following values:

Value Symbolic Constant Explanation
0 NO_ERROR Files > 4 GB supported.
26 FACS_ERR If filno is not in use.
-647 E2GB_COD Files > 2 GB NOT supported.
-648 E4GB_COD Files > 4 GB NOT supported.

See c-tree Error Codes for a complete listing of valid c-tree error values.

 

TRANRDY

Executes the first phase of a two-phase transaction commit.

Short Name

TRANRDY()

Type

Low-Level function

Declaration

COUNT TRANRDY()

Description

Two-Phase transaction support allows, for example, a transaction to span multiple servers. This is useful for updating information from a master database to remote databases in an all-or-nothing approach.

To start a transaction that supports a two-phase commit, you would include the ctTWOFASE attribute in the transaction mode passed to the Begin() function. Call the TRANRDY() function to execute the first commit phase, and finally Commit() to execute the second commit phase.

Note: You may need additional caution with regard to locking and unlocking of records as your transactions become more complex in a multi-server environment to avoid performance problems.

Caution: Two-Phase transactions can become extremely difficult to debug should there be communications problems between servers at any time during the second commit phase. This can result in out of sync data between the servers as one server may have committed while another server failed. It is always appropriate to check the return codes of the individual Commit() functions to ensure a complete successful transaction commit across multiple servers.

Return

Value Symbolic Constant Explanation
0 CTDBRET_OK Successful operation.
71 TNON_ERR No active transaction.
94 PNDG_ERR Pending error: cannot save or commit tran.

See c-tree Plus Error Codes for a complete listing of valid c-tree Plus error values.

Example

(Note that this example could also use individual threads of operation for the different c-tree Server connections, avoiding the c-tree instance calls.)

COUNT    rc1,rc2;

FILNO    filno1,filno2;

COUNT    rcc1,rcc2;

TEXT     databuf1[128],databuf2[128];

 

/* Create the connections and c-tree instances */

...

if (!RegisterCtree("server_1")) {

SwitchCtree("server_1");

InitISAMXtd(10, 10, 64, 10, 0, "ADMIN", "ADMIN", "FAIRCOMS1");

filno1 = OPNRFIL(0, "mydata.dat", ctSHARED);

FirstRecord(filno1, databuf1);

memcpy (databuf1, "new data", 8);


/* Prepare transaction on c-tree server 1 */

Begin(ctTRNLOG | ctTWOFASE | ctENABLE);

ReWriteRecord(filno1, databuf1);

rc1 = TRANRDY();

}

 

if (!RegisterCtree("server_2")) {

SwitchCtree("server_2");

InitISAMXtd(10, 10, 64, 10, 0, "ADMIN", "ADMIN", "FAIRCOMS2");

filno2 = OPNRFIL(0, "mydata.dat", ctSHARED);

FirstRecord(filno2, databuf2);

memcpy (databuf2, "new data", 8);


/* Prepare transaction on c-tree server 2 */

Begin(ctTRNLOG | ctTWOFASE | ctENABLE);

ReWriteRecord(filno2, databuf2);

rc2 = TRANRDY();

}

 

/* Commit the transactions */

if (!rc1 && !rc2) {

SwitchCtree("server_1");

rcc1 = Commit(ctFREE);

 

SwitchCtree("server_2");

rcc2 = Commit(ctFREE);

 

if (!rcc1 && !rcc2) {

printf("Transaction successfully committed across both servers.\n");

} else {

printf("One or more units of the second commit phase of the transaction failed: rcc1=%d rcc2=%d\n", rcc1, rcc2);


} else {

printf("One or more of the transactions failed to be prepared: rc1=%d rc2=%d\n", rc1, rc2);


printf("Pending transactions will be aborted.\n");

SwitchCtree("server_1");

Abort();

SwitchCtree("server_2");

Abort();

}

 

/* Done */

SwitchCtree("server_1");

CloseISAM();

SwitchCtree("server_2");

CloseISAM();

See also

Abort(), AbortXtd(), Begin(), ClearSavePoint(), Commit(), RestoreSavePoint(), SetSavePoint()

 

TransactionHistory

Permit scanning backward or forward through transaction logs.

Short Name

CTHIST()

Type

Low-Level function

Declaration

COUNT TransactionHistory(FILNO filno, pVOID target,

               pVOID bufptr, LONG recbyt, VRLEN bufsiz, UCOUNT mode)

Description

In V12 the file number typedef was formally changed from COUNT, a two-byte value to FILNO, a four-byte value. Refer to this link for compatibility details. Four Byte File Numbering

A complete single-function API to access the audit logs of transaction controlled files for the purpose of putting valuable historical capabilities in any application. Determine who deleted a record; page back through all the changes to a specific record; see who performed write operations to a specific file during a qualified time frame. These are but a few examples of this powerful feature.

The history function, TransactionHistory(), permits an application to scan backward or forward through transaction logs, returning either key values or data records and optionally the user ID and node name of the process which performed the update. When scanning backward, TransactionHistory() will look for both active log files, ending with .FCS, and for inactive log files, ending with .FCA. The information extracted from the transaction logs can be based on:

  • A particular record position of a specified data file.
  • A particular key value of a specified unique index.
  • All updates to a specified file.
  • Updates made by a particular user ID and/or node name.
  • Some combination of the above.

On the first search call, set filno to the open data or index file number, or to -1 to return any file satisfying the search criteria. When filno specifies an index file, mode indicates whether TransactionHistory() returns a key value or the associated data record.

On the first search call, target points to a key value, a user ID and/or node name, or NULL, depending on the search request. On other calls, set target to NULL.

bufptr specifies the address where a search call returns log entries satisfying the search criteria. On non-search calls, set bufptr to NULL.

Set recbyt to the starting log number on a preliminary log call, to -1L on a terminating call, to zero or a particular data record location on a first search call, or to zero on subsequent search calls. bufsiz specifies the length of bufptr, the output buffer. If the buffer is too small to hold all the output requested, only bufsiz bytes are returned. If bufsiz is less than 40, error HSIZ_ERR (620) will be returned.

mode specifies the type of call, how to interpret the search criteria, and what to return to the output buffer. The following mode constants are found in ctport.h. Each represents a bit to be OR-ed into mode.

Mode Bit Usage
ctHISTlog Signify preliminary log or terminate call.
ctHISTfirst Signify first search call.
ctHISTnext Signify subsequent search call.
ctHISTfrwd Scan logs forward (default is back).
ctHISTuser Match user ID.
ctHISTnode Match node name.
ctHISTpos Match byte offset (record position).
ctHISTkey Match key value.
ctHISTdata Return data record entries.
ctHISTindx Return key value entries.
ctHISTnet Return net change.
ctHISTinfo Return User ID and node name info.

Return

When TransactionHistory returns a non-zero value:

  1. The current history set is canceled.
  2. Memory associated with the set is freed.
  3. To make additional TransactionHistory calls, make a new first search call.
Value Symbolic Constant Explanation
0 NO_ERROR No error occurred.
610 HNUL_ERR NULL target not permitted for this request.
611 HLOG_ERR Could not access/find transaction log.
612 HSTR_ERR Must make a first search call (ctHISTfirst).
613 HONE_ERR Can only return data OR index entries.
614 HMAP_ERR Could not find ISAM map from specified index file to a data file.
615 HIDX_ERR Cannot return index entries from a specified data file.
616 HACT_ERR TransactionHistory() cannot be called during an application’s own active transaction.
617 HNOT_ERR Did not find target.
618 HENT_ERR No more transaction log entries.
619 HZRO_ERR Zero recbyt not permitted on this request.
620 HSIZ_ERR Bufsiz too small.
621 HTYP_ERR Transaction type found in log not expected.
622 HMID_ERR Must reset TransactionHistory() through a terminate call or preliminary log call.
623 HMEM_ERR Not enough memory for TransactionHistory().
624 HNET_ERR Net change only applies to specific match of key or record position.
625 HMTC_ERR Must specify exactly one matching criteria: ctHISTpos or ctHISTkey or one or both of ctHISTuser and ctHISTnode.
626 HUND_ERR Encountered an UNDTRAN (undo committed transaction) going forward: must completely restart this set of history calls. Repeat the first search call and subsequent search calls: the undone transaction will be ignored.
627 HUNK_ERR Unknown type of request.
628 HFIL_ERR Must specify filno.
629 HTFL_ERR Could not initialize internal file ID: preserve files and contact FairCom.

See c-tree Error Codes for a complete listing of valid c-tree error values.

Example

See TRNHIS.C in the \ctree\samples directory.

Limitations

When a client on a heterogeneous network calls TransactionHistory(), it only converts the history header to match the client’s byte ordering. It does not convert the optional record header or the actual data or key image from the log. It returns them in their native form as they exist on the FairCom Server.

TransactionHistory() requires transaction logs, so it only works in single-user, transaction processing applications, or in client-server applications. Files created without the ctTRNLOG file mode are not included in the transaction logs, and are not accessible to TransactionHistory().

See also Record Offsets Under Huge File Support.

 

TransformKey

TransformKey() transforms the supplied, already-assembled key value according to the ISAM key segment mode in effect for each of the key segments comprising the assembled key value.

Short Name

TFRMKEY()

Type

ISAM function

Declaration

pTEXT TransformKey(FILNO keyno, pVOID target)

Description

In V12 the file number typedef was formally changed from COUNT, a two-byte value to FILNO, a four-byte value. Refer to this link for compatibility details. Four Byte File Numbering

The ISAM parameters for your application can specify that key segments are to be translated (e.g., converted to upper case) before being concatenated and added to index files. However, c-tree does not automatically translate your target keys in the same way. TransformKey() converts a target key, pointed to by target, according to the ISAM definition for index number keyno. For example, if you have reversed the bytes of a key segment (see segment mode equal to one in ISAM Functions of the c-tree Programmer’s Reference Guide), then passing a target key to TransformKey() causes the appropriate segment of the target key to be reversed.

Since TransformKey() constructs the translated key in place, ensure the key area pointed to by target is at least as large as the key length, including suffix, defined for index number keyno. TransformKey() expects that you have concatenated all necessary segments into a target key pointed to by the target parameter. This implies all data types should be in the same contiguous buffer. See the example and notice how the LONG field int_target is copied into the TEXT buffer key_buffer.

Note: When using single entry point function calls, (see Common Entry Point Functions in the c-tree Programmer’s Reference Guide), or the extended functions CreateISAMXtd(), OpenISAMXtd(), or InitISAMXtd(), c-tree automatically invokes TransformKey() for you unless you disable this feature.

Return

TransformKey() returns a pointer to the translated target key. Since the translation is performed in place, the return value is always equal to the target parameter, unless there is an error. If an index accepts duplicate key values, TransformKey() sets the suffix to zero in the target key. A NULL value is returned if there is an error, and the value of isam_err will be:

Value Symbolic Constant Explanation
80 BKEY_ERR target is null or keyno is out of range.
199 NSCH_ERR Segment mode requires a schema map.
433 SSCH_ERR File referenced by schema-based segment is not defined.

See c-tree Error Codes for a complete listing of valid c-tree error values.

Example

TEXT      alph_target[5],key_buffer[13],rec_buffer[750];

LONG      int_target;

FILNO     keyno;


/* target is comprised of a long integer, a five byte  alphanumeric, and a 4 byte duplicate key suffix. cpybuf    copies n bytes (without regard to null bytes). */


cpybuf(key_buffer, (pTEXT) &int_target,4);

cpybuf(key_buffer + 4, alph_target,5);

if (FirstInSet(keyno, TransformKey(keyno,key_buffer), rec_buffer, 9))

    printf("\nUnsuccessful FirstInSet (%d)\n", isam_err);

Limitations

TransformKey() automatically sets the suffix of the target key to all NULL bytes if duplicates are enabled for index number keyno. To control the suffix, change it after TransformKey() is called.

If the target area pointed to by target is not at least the key length, TransformKey() clobbers the memory area following the target key.

See also

CreateISAMXtd(), OpenISAMXtd(), InitISAMXtd(), CurrentISAMKey(), BuildKey(), uTRFRMKEY()

 

TransformSegment

Low-Level key transformation.

Short Name

cttseg()

Type

Low-Level function

Declaration

NINT TransformSegment(COUNT spos, COUNT mod, COUNT slen,

                      pTEXT target, pCOUNT aq, pConvMap mp);

Description

TransformSegment() transforms keys for Low-Level functions in the same manner that TransformKey() transforms for ISAM functions.

mod is the segment mode as described in Key Segment Modes (Key Segment Modes, /doc/ctreeplus/30863.htm) in the c-tree Programmer’s Reference Guide. slen is the length of the segment to transform. tarptr points to the key value to be transformed. Note that you can do a transformation on a portion of a key. aq points to an optional alternative collating sequence. mp points to an optional record schema. aq and mp can be NULL.

spos is only used if the segment mode requires the record schema. In this case, spos specifies which field of the schema is used to define the key segment type.

Limitation: This function does not support a call with a schema-based key segment mode, such as SCHSEG, on a field that uses the CT_JSON data type. Such a call will fail with error FNUM_ERR (22). This is because, for a CT_JSON data type, the index file number and key segment number are required to transform or untransform the key segment, and this function does not accept these parameters.

Return

TransformSegment() returns zero if successful, or a Low-Level error code if not. See c-tree Error Codes in the c-tree Programmer’s Reference Guide for a complete listing of valid c-tree error values.

The following example transforms the double float key value pointed to by kvp in place.

Example

NINT      errc;

double    *kvp;


errc = TransformSegment(0,FLTSEG,8,(pTEXT) kvp,NULL,NULL);

Limitations

It is very important to note that transformations are done in place. Move the values to a buffer or structure specifically assigned to index building, rather than transforming variables in a record buffer. Taking the example code above, a mode of FLTSEG changes the format of the information stored in the double float variable so that it can be used by c-tree as a key value. The information in that variable is no longer a valid double float value usable in C language calculations. If this variable was a part of a record structure, and it is written back to the data file, that portion of the data record is trashed.

 

TransformXtdSegment

Creates a binary sort key (segment) using an extended key segment definition.

Short Name

XFMKSEGDEF()

Type

ISAM Data Definition

Declaration

NINT TransformXtdSegment(NINT seghnd, pVOID src, NINT srclen,

                         NINT srctyp, pVOID dest, NINT destlen)

Description

Most applications will not have a reason to call TransformXtdSegment() unless the application needs to create a Unicode binary sort key outside of the normal ISAM processing.

Creates a binary sort key (segment) using an extended key segment definition.

seghnd Handle returned by PutXtdKeySegmentDef() or GetXtdKeySegmentDef().
src Pointer to data used to construct segment.
srclen Size in bytes of the region pointed by src. However, srclen is ignored unless kseg_ssiz was set to ctKSEG_SSIZ_PROVIDED.
srctyp srctyp should be set to one of the c-tree field types (e.g., CT_STRING or CT_UNICODE). However, srctyp is ignored unless kseg_styp was set to ctKSEG_STYP_PROVIDED.
dest Pointer to region in which binary sort key is constructed.
destlen Size in bytes of the region pointed to by dest.

Return

If successful, it returns the number of bytes used for the binary sort key. Returns a negative value upon error, where the absolute value of the return value is the error code. The most common errors are shown below.

 

445 SDAT_ERR No source data to create key segment.
446 BMOD_ERR The handle references an extended key segment definition not supported by the executable.
694 NUNC_ERR Executable does not support ICU Unicode, but a UNCSEG modifier has been encountered.
700 OSEG_ERR Could not process key segment definition.
701 CSEG_ERR Could not process the kseg_comp options. This could occur if more than one of a set of mutually exclusive options are combined.
702 ASEG_ERR An error occurred when attempting to process one of the special attribute options.
703 HSEG_ERR Invalid key segment handle.
704 SSEG_ERR No source type provided when kseg_styp has been set to ctKSEG_STYP_PROVIDED. If this error occurs, it is likely to occur during the first use (say with an AddRecord() or AddVRecord() or OpenIFile()) of the extended key segment.
706 NSEG_ERR Zero bytes of binary sort key were generated. Possibly an all NULL source.
707 USEG_ERR There is no extended key segment definition to use.
708 MBSP_ERR Multibyte/Unicode file names are not supported.
709 MBNM_ERR A badly formed multibyte/Unicode file name has been encountered.
710 MBFM_ERR A multibyte/Unicode variant is not supported (e.g., UTF32).

See c-tree Error Codes for a complete listing of valid c-tree error values.

Example

See the API example in Unicode Support.

See also

AddRecord(), AddVRecord(), OpenIFile(), GetXtdKeySegmentDef(), PutXtdKeySegmentDef()

 

UnloadFilter

UnloadFilter() initializes resources that are used when processing the filter. The function receives the parameters passed to the filter.

Declaration

NINT UnloadFilter(pTEXT libname, pVOID libhandle)

Description

This function is defined in the ctuserx.c module used to build a filter callback function.

  • libname is the filter callback DLL name that was passed to SetDataFilter().
  • libhandle is the application-defined library handle that was set by LoadFilter().

Return Values

Value Symbolic Constant Explanation
0 CTDBRET_OK Successful operation.

See c-tree Error Codes for a complete listing of valid c-tree error values.

Example


/* 

Example Code

*/

 

See also

ctfiltercbAddFilter(), EvaluateFilter(), LoadFilter(), ctfiltercbRemoveFilter(), SetDataFilter()

 

UnRegisterCtree

Unregister a c-tree instance.

Short Name

UNRCTREE()

Type

Low-Level function

Declaration

COUNT UnRegisterCtree(pTEXT regid)  

Description

UnRegisterCtree() frees the allocated memory for the c-tree global structure belonging to the registration reference name pointed to by regid.

Return

Value Symbolic Constant Explanation
0 NO_ERROR Instance successfully unregistered.
516 GNUL_ERR ctNOGLOBALS not defined.
517 GNOT_ERR regid is not registered.

See c-tree Error Codes for a complete listing of valid c-tree error values.

Example

TEXT     inpbuf[32];   /* input buffer */


ctrt_printf("\nEnter Instance Name\n");

gets(inpbuf);

if (RegisterCtree(inpbuf))

{

    ctrt_printf("\nCould not unregister {%s} data base", inpbuf);

    ctlxmg_exit(2);

}

UnRegisterCtree(inpbuf);

Limitations

File handles are not shared between instances. Virtual logic cannot close files in other instances.

See also

NextCtree(), SwitchCtree(), RegisterCtree(), WhichCtree(), GetCtreePointer()

 

UpdateAutoSysTimeFields

Similar to AddAutoSysTimeFields, but used to update existing definitions. The definition passed in replaces an existing one.

Type

ISAM Function

Declaration

NINT UpdateAutoSysTimeFields(FILNO datno, pA_STFIELDS defs);

Description

  • datno - the data file number. In V12 the file number typedef was formally changed from COUNT, a two-byte value to FILNO, a four-byte value. Refer to this link for compatibility details. Four Byte File Numbering
  • defs - pointer to fields definition structure:
     

typedef struct astfields {

 COUNT version;                     /* Version of this structure   */

 COUNT entries;                     /* number of entries in fields array  */

 LONG pad;                          /* padding to ensure struct alignment */

 pA_STFIELD fields;                 /* fields array */

} A_STFIELDS, *pA_STFIELDS;

  • version - the version of the structure. must be set to A_STFIELDS_VERS_V01.
  • entries - the number of fields that needs to be automatically set with the system time. It must match the number of entries in the fields array.
  • fields - pointer to an array of field settings:
     

typedef struct astfield {

 LONG fieldno;                      /* field number */

 TEXT mode;                         /* set time  */

} A_STFIELD, *pA_STFIELD;
 

  • fieldno - the field number in the DODA for the field that is set to auto setting with system time stamp.
  • mode - in which condition the field gets populated. Possible values:

CT_AUTOSYSTIME_CREATE 0x01 - when the record gets added

CT_AUTOSYSTIME_UPDATE 0x02 - when the record gets rewritten/updated.

Return

NO_ERROR on success

 

UpdateConditionalIndex

Update the Conditional Index Resource in a data file.

Short Name

UPDCIDX()

Type

ISAM level function

Declaration

COUNT UpdateConditionalIndex(FILNO keyno, pTEXT condexpr)

Description

In V12 the file number typedef was formally changed from COUNT, a two-byte value to FILNO, a four-byte value. Refer to this link for compatibility details. Four Byte File Numbering

UpdateConditionalIndex() can add, delete, or change the conditional expression associated with the index. This function assumes an ISAM mapping exists between keyno and an associated data file. The NULL-terminated ASCII string pointed to by condexpr defines the conditions that must be true for an index entry to be made. The expression is stored as a resource in the associated data file.

If condexpr is NULL or points to an empty string (""), the existing conditional expression is deleted. Each index can have at most one conditional expression. If keyno already has an expression, the new expression replaces the old expression.

For existing, non-empty files, it is ordinarily necessary to call a rebuild after updating the conditional expressions.

UpdateConditionalIndex() checks the syntax of the expression before adding it to the data file resource. The syntax can fail because a name used in the expression is not found in the DODA, or because of an illegal expression.

A special case exists with indexes created by PermIIndex() and TempIIndexXtd(). By default, both functions create and fill index files in one action without allowing a condition to be set. The ability to separate the index creation from the index build permits UpdateConditionalIndex() to set conditional expressions for the new indexes. If PermIIndex() is involved, the data file has its conditional index resource updated. If TempIIndexXtd() is involved, no permanent storage of the conditional index expression is made. The proper steps are:

  • Call PermIIndex() or TempIIndexXtd() with ifilptr -> dxtdsiz == ctNO_IDX_BUILD.
  • Call UpdateConditionalIndex() for each new index with a conditional expression.
  • Call RebuildIIndex() for the new indexes.

Note: Do not close the newly created indexes between a call to PermIIndex() or TempIIndexXtd() and a call to RebuildIIndex().

UpdateConditionalIndex() creates a temporary conditional index if called for a temporary index. The data file conditional index resource is not updated. Once the temporary index closes, the conditional expression goes with it. To accomplish this:

  • Execute TempIIndexXtd() with the dxtdsiz parameter of the IFIL structure set to ctNO_IDX_BUILD to create an empty index file.
  • Call UpdateConditionalIndex() to add the condition.
  • Call RebuildIIndex() to fill the index.

Return

Value Symbolic Constant Explanation
0 NO_ERROR Successful update of condition expression resource.
401 RNON_ERR Resources not enabled.
597 CINI_ERR Failed syntax check.
614 HMAP_ERR No map to a data file exists for keyno.

See c-tree Error Codes for a complete listing of valid c-tree error values.

Example

UpdateMyIndex(pIFIL ifilptr, FILNO keyno, pTEXT condexpr)

{

/* This function updates the conditional expression of a given

   index and rebuilds the index. Requirements include proper

   c-tree ISAM initialization and IFIL file open.       */


    keyno = ifilptr->tfilno;


    if (UpdateConditionalIndex(keyno, condexpr))

        return(isam_err);


    if (RebuildIIndex(ifilptr)) {

        printf("Rebuild failed after conditional index update.");

        return(isam_err);

    }


    printf("Condition changed for index %d to %s.", keyno, condexpr);

    return();

}

See also

PermIIndex(), TempIIndexXtd(), UpdateConditionalIndex(), RebuildIndex(), GetConditionalIndex()

 

UpdateCtResource

Update the specified resource record.

Short Name

UPDRES()

Type

Low-Level file resource function

Declaration

COUNT UpdateCtResource(FILNO filno, pVOID resptr, VRLEN varlen)

Description

In V12 the file number typedef was formally changed from COUNT, a two-byte value to FILNO, a four-byte value. Refer to this link for compatibility details. Four Byte File Numbering

UpdateCtResource() updates a particular Resource in file filno. resptr points to a resource data block of length varlen. This block contains the following fields:

Byte Offset Data Type Field Name
0 - 3 unsigned long integer Resource Type
4 - 7 unsigned long integer Resource Number
8 - m null terminated character string Resource Name
(m+1) - n any collection of data types desired Resource Information

If a record lock has been placed on this resource by GetCtResource(), that lock is released by UpdateCtResource().

Return

Value Symbolic Constant Explanation
0 NO_ERROR Successful update.
57 DADV_ERR Proper lock not held.
401 RNON_ERR Resources have not been enabled for this data file.
408 RNOT_ERR Resource not found. You cannot update a resource that doesn’t exist.

See c-tree Error Codes for a complete listing of valid c-tree error values.

Example

struct {                    /* Resource Data Block structure */

  ULONG     resource_type;

  ULONG     resource_number;

  TEXT      variable_info[1016]; /* This will hold the Resource Name and Data */

} my_resource;


if (GetCtResource(datno, "MY!resource", &my_resource,

               (VRLEN)sizeof(my_resource),(RES_NAME|RES_LOCK)))

{

/*at this point you will update the information in the buffer*/

    if (UpdateCtResource(datno, &my_resource, sizeof(my_resource))

        printf("\nError %d when update resource.",uerr_cod);

    else

        printf("\nUpdate successful!");

}

else

    printf("\nCould not get resource. Error #%d",uerr_cod);

Limitations

The recbyt parameter in this function is a 4-byte value capable of addressing at most 4 gigabytes. If your application supports HUGE files (greater than 4 gigabytes), you must use the ctSETHGH() and ctGETHGH() functions to set or get the high-order 4 bytes of the file offset. See also Record Offsets Under Huge File Support.

See also

GetCtResource(), AddCtResource(), DeleteCtResource()

 

UpdateFileMode

Changes critical file mode attributes such as the level of transaction control.

Short Name

PUTFIL()

Type

Low-Level function

Declaration

COUNT UpdateFileMode(FILNO filno, COUNT mode)

Description

In V12 the file number typedef was formally changed from COUNT, a two-byte value to FILNO, a four-byte value. Refer to this link for compatibility details. Four Byte File Numbering

When creating or opening a file, the value of filmod sets the attributes for the file. Some of these attributes are permanent, assigned during the creation of the file. Others are temporary, assigned only while the file is open. UpdateFileMode() changes these attributes after the file has been opened or created.

filno specifies the file to be changed. This file must be currently open in ctEXCLUSIVE mode. filmod is the new file mode attribute. It must be perfectly formed, as it will replace the current file mode for this file.

Note: Use this function with caution! It is possible to damage a file if you are not careful. For example, changing a data file from transaction processing to no transaction processing makes automatic recovery unavailable. See the discussion of Transaction File Modes in the FairCom DB Programmer’s Reference Guide.

Some examples of changes that might make sense would be to add or delete ctCHECKLOCK, or to turn on one of the transaction modes for a data file, or to switch between ctPREIMG and ctTRNLOG for an index.

Return

Value Symbolic Constant Explanation
0 NO_ERROR No error occurred.
48 FMOD_ERR Cannot switch between fixed and variable-length records.
62 LERR_ERR File must be opened in ctEXCLUSIVE mode to modify.
99 TTYP_ERR Cannot switch an index to transaction processing.

See c-tree Error Codes for a complete listing of valid c-tree error values.

Example

FILNO     filno;


if (UpdateFileMode(filno,ctTRNLOG))

    printf("\nFile Mode Error %d",uerr_cod);

Limitations

filno must be opened in an ctEXCLUSIVE mode. No check is made to determine if the change being made will damage the file.


 

UpdateHeader

Update the header portion of a c-tree file.

Short Name

PUTHDR()

Type

Low-Level function

Declaration

COUNT UpdateHeader(FILNO filno, LONG hdrval, COUNT mode)

Description

In V12 the file number typedef was formally changed from COUNT, a two-byte value to FILNO, a four-byte value. Refer to this link for compatibility details. Four Byte File Numbering

UpdateHeader() permits an application to update certain fields in a file’s header record provided the file is opened in ctEXCLUSIVE mode.

  • filno - data or index file number. In V12 the file number typedef was formally changed from COUNT, a two-byte value to FILNO, a four-byte value. Refer to this link for compatibility details. Four Byte File Numbering
  • hdrval - is a LONG value containing the new header value.
  • mode - is one of the following header-field-ID’s:

 

Mode Description
ctSERNUMhdr Ever increasing automatic sequence number.
ctSUSSRLSEGhdr Suspend the serial segment handling for data file datno. (YES or NO).
ctTSTAMPhdr Time stamp of last close after updates.
ctNUMENThdr Number entries in file.
ctTIMEIDhdr Creation time stamp used as part of unique ID.
ctFLAVORhdr Change byte ordering.
ctADDUNQFRShdr Add unique keys before allocating space for the data record from the data file. If a unique key add fails, the operation fails immediately; if it succeeds, the operation continues.
ctALIGNhdr Change byte alignment.
ctISAMKBUFhdr Disable/enable ISAM key buffering.
ctISAMKBUFctx Disables/enable ISAM key buffering in the current context only.
ctEXTSIZhdr Reset file extension size.
ctLXTSIZhdr Change the large extent size in the XCREblk. For transaction controlled files, ctTRNLOG, this cannot be zero.
ctMXFILZhdr Maximum file size in XCREblk (only if larger than the current value.)
ctSCANCACHEhdr Toggles between the LRU cache algorithm and the scanner cache algorithm. Set hdrval to YES or NO to toggle. This mode is only valid for data files.
ctSPLREFRESHhdr Refresh the dedicated cache pages so that they may be assigned to different pages of the file.
ctSPLRESUMEhdr Restart the use of dedicated pages after a call to stop their use.
ctSPLSTOPhdr Stop using dedicated cache for this file.
ctIDfieldOverRide Turn on and off the ability to override automatic IDfield values. Override is per user, per file. Nonzero hdrval turns on; zero hdrval restores standard operation.
ctSKIPSAVEhdr

Suppresses or restores the update flag setting for the specified non-transaction-controlled file until it is physically closed and reopened.

It is intended for temporary files not requiring persistence.

ctSKIPSAVEISAMhdr Enables or disables file system cache flush calls for the specified data file and all its associated ISAM index files.
ctIFIL3hdr Enables or disables (YES/NO) the V12 default IFIL resource storage format (see also the SUPPRESS_PATH_IN_IFIL server configuration keyword). The ctIFIL3hdr format supports several new naming options for alternate indexes (IFIL.aidxnam), and improves behavior when copying or renaming files with alternative index names. Disabling the ctIFIL3hdr for files using the new naming options may lead to the indexes becoming unusable.
ctADDKYDFRhdr Toggles the deferred key add feature.
ctLOCKDFRhdr Toggles the file state for deferred closes with pending locks on a file.
ctTRNPERShdr Toggles the file state for persisted transaction unlock requests.
ctIICThdr Enables the Immediate Independent Commit Transaction (IICT). This is an auto commit ISAM update executed while a transaction is pending for the same user (thread). IICT is independent of the existing transaction: it is as if another user/thread is executing the IICT.
ctXFLSEThdr Sets extended file mode to lower-order two bytes of the hdrval parameter.
ctXFL_ONhdr Turns on the lower-order two bytes of hdrval in the extended file mode.
ctXFLOFFhdr Turns off the lower-order two bytes of hdrval in the extended file mode.
ctUNIQUIDhdr

Assigns a new unique file ID to the specified file. hdrval is ignored. File must be open in exclusive mode. Sets the file ID to a unique value using one of these methods:

  • Setting the timeid field to the current time if it has not been used yet in a call to PUTHDR() with mode of ctUNIQIDhdr.
  • Setting the fileid field to the next available value as recorded in the transaction log header.
ctMAXPARTMBRhdr Set maximum number of active partitions on a partitioned file. When a new partition is created, if the new number of active partitions exceeds the limit, the oldest partitions are purged.
ctNOISMKEYUPDhdr Restrict ISAM key updates for calling connection only. Remains in effect for that open instance of the index file until its close, or it can be turned off with an additional PUTHDR() call of NO.

 

Note: Use this function with extreme care as you are altering c-tree file headers, which can impact availability and/or integrity of your data. This function is intended more for advanced file recovery operations than for routine production use.

Automatic TRAN/noTRAN File Support

It is possible to create files in non-TRANPROC environments (e.g., FPUTFGET or single-user non-TRANPROC) which will be transaction ready, automatically, when they are opened in a TRANPROC environment. Further, they will automatically revert back to non-TRANPROC when returned to a non-TRANPROC environment.

  • To create such a file in a non-TRANPROC environment, simply set the file mode to include either TRNLOG or PREIMG at create time.
  • To create such a file in a TRANPROC environment, set the file mode to include either TRNLOG or PREIMG and after the create, but before closing the file (which ensures the file is still opened exclusively), call PUTHDR(filno,TRANMODE,ctXFL_ONhdr) or PUTHDR(filno,PIMGMODE,ctXFL_ONhdr), respectively.
  • An index file which cannot support transaction processing CANNOT be changed via a call to PUTHDR.
  • It is possible to skip the calls to PUTHDR by including TRANMODE or PIMGMODE in the x8mode member of the extended create block.

In non-TRANPROC environments, it is possible to disable this behavior by adding #define ctBEHAV_NOTRANFILE to ctoptn.h.

  • A call to PUTFIL that changes between TRNLOG and PREIMG , or PREIMG and TRNLOG , will have the TRANMODE and PIMGMODE information updated automatically. However, a call to PUTHDR which attempts to set or turn on TRANMODE or PIMGMODE, and which is incompatible with the existing file mode or auto-switch mode results in a TTYP_ERR error (99). For example, if TRANMODE is already turned on, then PIMGMODE cannot also be turned on. If the file mode is PREIMG, TRANMODE cannot be turned on. It is possible to turn off TRANMODE or PIMGMODE by using PUTHDR with ctXFLOFFhdr.
  • A superfile member cannot set TRANMODE or PIMGMODE unless the host has the same settings. If the settings do not match, a SRCV_ERR error (419) will be returned.

LOGIDX

A subtle change in how the LOGIDX file mode bit is handled has been introduced: Setting the LOGIDX bit on in the file mode used to open a file (ctXFL_ONhdr) will enable this feature (high speed index recovery) even if the file was not created with this file mode.

Mirrored Files

File mirroring status is maintained as an extended header attribute. When disabling mirroring, this bit can be permanently un-set in all physical files with the MIRRORD value with the ctXLOFFhdr mode.

Working with Temporary Files

For a temporary, non-transaction-controlled file, it may be desirable to avoid rewriting the header with the update flag set. This can be achieved for a non-transaction-controlled file by calling PUTHDR(filno, YES, ctSKIPSAVEhdr). Calling PUTHDR(filno, NO, ctSKIPSAVEhdr) restores the normal behavior for a file.

PUTHDR() called with the ctSKIPSAVEhdr fails if the file is open in shared mode and the caller does not have file definition permission on the file; or if the file is a transaction-controlled (ctTRNLOG) file.

Byte Ordering and Byte Alignment

This capability is useful for forcing different file alignment; for example, forcing byte alignment for the packing of data files. Remember, when c-tree is requested to create a data file in non-server mode, the alignment is dictated by the compiler used to create the c-tree executable. For example, Microsoft C defaults to word alignment, and most Unix systems default to double word alignment. The c-tree test utility (cttest) can be used to determine the alignment for your compiler. In non-server mode, the file flavor for the data file is dictated by the underlying CPU (i.e., Intel typically Low/High or Little Endian/Big Endian and most Motorola and RISC CPU’s are High/Low or Big Endian/Little Endian). The c-tree index file is always High/Low, regardless of the underlying CPU.

In the client/server model, the FairCom Server dictates the byte ordering of the data file (i.e., High/Low vs. Low/High) while the client application dictates the data file alignment.

The hdrval values for the ctFLAVORhdr and ctALIGNhdr modes are:

mode hdrval Explanation
ctFLAVORhdr

1

2

LOW_HIGH

HIGH_LOW

ctALIGNhdr

1

2

4

8

byte aligned

word aligned

double word aligned

quad word aligned

In addition to updating the header fields, the corresponding schema fields are also updated if the file already contains a schema (from a PutDODA() call). Typical usage would be to create a file, call PutDODA(), and call UpdateHeader() with a new alignment value. For example, if the data is byte aligned in your record, (regardless of the systems inherent alignment), calling UpdateHeader() after calling PutDODA() permits the DODA to properly reflect the field alignment. See ctalgn.c in the \ctree\source directory as an example utility.

Performance Enhancement

This ISAM access mode can be set by the UpdateHeader() function to boost performance. This mode prevents c-tree from updating the internal index buffer for every key of the current ISAM record. Especially useful if a large number of keys are defined.

Each ISAM data file is assigned, for each user, a set of key buffers containing the current key image for each index for the current ISAM position. To speed record access UpdateHeader() accepts the ctISAMKBUFhdr mode, which turns on and off the support of the key buffers for a particular ISAM data file for the calling user, (i.e., NOT all users with the file open).

UpdateHeader(datno, (LONG) 1, ctISAMKBUFhdr) turns off key buffer support, speeding access to the data records. The effect on performance will be most notable when the data file supports many indexes. (Any non-zero LONG value for the second parameter will turn off support.)

UpdateHeader(datno,(LONG) 0,ctISAMKBUFhdr) turns back on key buffer support (which is the default state of an ISAM file).

Notes

If the key buffer support is turned off, then the current ISAM position for the data file is set to zero which implies no current ISAM position. This indicates the application cannot perform updates to the file since the key buffers are required. See the limitation section below.

Unlike the previous UpdateHeader() modes, this mode does not make a permanent change to the file header and therefore does NOT require the file to be opened exclusively, and only applies to the user making the call.

With key buffer suppression is on, the file cannot be traversed by one key then by a different key. Only the key that established the ISAM position (i.e., with FirstRecord(), etc.) can be used in NextRecord() or PreviousRecord(). If the data file is traversed in physical order, then no ISAM key buffer is supported.

When a record is retrieved in this mode, it is not possible to directly do a ReWriteRecord(). ReWriteRecord() returns KBUF_ERR (121) because the ISAM buffers are not being maintained. Perform a rewrite by first calling ReadIsamData().

Immediate Independent Commit Transaction (IICT)

The Immediate Independent Commit Transaction, IICT, permits a thread with an active, pending transaction to also execute immediate commit transactions, even on the same physical file that may have been updated by the still pending (regular) transaction. An IICT is essentially an auto commit ISAM update, but with the added characteristic that an IICT can be executed even while a transaction is pending for the same user (thread).

It is important to note that the IICT is independent of the existing transaction: it is as if another user/thread is executing the IICT. The following pseudo code example demonstrates this independence:

Example

  1. Begin transaction
  2. ISAM add record R1 with unique key U to file F
  3. Switch to IICT mode
  4. ISAM add record R2 with unique key U to file F: returns error TPND_ERR (420)

If we did not switch to IICT mode, the second add would have failed with a KDUP_ERR (2); however, the IICT mode made the second add use a separate transaction and the second add found a pending add for key U, hence the TPND_ERR. Just as if another thread had a key U add pending.

A data file and it's associated indices are put into IICT mode with a call

PUTHDR(datno,1,ctIICThdr)

and are restored to regular mode with a call

PUTHDR(datno,0,ctIICThdr)

It is possible in c-tree for a thread to open the same file in shared mode more than once, each open using a different user file number. And it is possible to put one or more of these files in IICT mode while the remaining files stay in regular mode.

Note: If a file has been opened more than once by the same thread, then the updates within a (regular) transaction made to the different file numbers are treated the same as if only one open had occurred.

These special filno values enable specific IICT operations:

  • ctIICTbegin -1
  • ctIICTcommit -2
  • ctIICTabort -3

Override IDENTITY Values

PUTHDR() using the ctIDfieldOverRide mode can turn on and off the ability to override the automatic IDfield values. The override is on a per user, per file basis. A nonzero hdrval turns on the override, and a zero hdrval restores the standard operation. When the override is on for a data file that supports an IDfield, then an add record operation does not fill-in the IDfield value. Whatever is passed in the record buffer is used for the IDfield. And a rewrite permits the IDfield value to change instead of generating the IDFL_CHG error. When the override is enabled, add record operations do not consume IDfield values.

Scanner Cache Feature

The index cache pages are managed using a least-recently-used (LRU) scheme. For data files, the LRU scheme is not always effective. In particular, when data file access or updates involve many different records with little or no revisiting of records once they have been processed, the LRU scheme can result in many cache pages to be assigned to recently accessed records. But, at least from the user’s perspective, there is little chance of revisiting these pages.

The advanced FairCom DB header mode, ctSCANCACHEhdr, allows an alternative caching strategy. For details, see Scanner Cache.

File Extension Size

The stand-alone parameters dxtdsiz and ixtdsiz can be adjusted with the ctEXTSIZhdr parameter. File extensions less than 32768 bytes for superfile hosts, or less than 16KB for transaction processed files or mirrored files will not be permitted. If a smaller value is given, the minimum is used instead. No extension size may exceed 65,535 bytes for a Standard file. Use an Extended file to get much larger extension sizes.

Locking Behavior When Opening the Same File Multiple Times in the Same Connection

FairCom DB supports opening the same file multiple times in the same connection assigning a different file number to each file or, in FairCom DB API, a different file handle.

For details, see FairCom Server enhanced locking control for files opened multiple times in the same connection.

Turn on Replication for a Table

Use the PUTHDR() function to turn on replication for a table. The table must meet the following requirements:

  • It must be opened in exclusive mode and meet the requirements for replication.
  • It must use full transaction control, which is the ctTRNLOG file mode or the CTCREATE_TRNLOG FairCom DB file mode
  • It must have a unique index.

Note: If these requirements aren't met the PUTHDR() call will fail with an error such as 99 or 775.

Example

With FairCom DB, table creation and enabling replication must happen within the same transaction, as shown in this example.

  • hSession is an initialized FairCom DB session handle.
  • hTable is an initialized FairCom DB table handle.

 

/* start transaction */

ctdbBegin(hSession);

 

/* create table */

if (ctdbCreateTable(hTable, "custmast", CTCREATE_NORMAL | CTCREATE_TRNLOG)) {

/* error */

}

 

/* open table in exclusive mode */

if (ctdbOpenTable(hTable, "custmast", CTOPEN_EXCLUSIVE)) {

/* error */

}

 

/* turn on replication for the table */

if (PUTHDR(ctdbGetDatno(hTable), YES, ctREPLICATEhdr)) {

/* error */

}

 

if (ctdbCommit(hSession)) {

/* error */

}

 

ctdbCloseTable(hTable);

Verify replication

Use the ctrepd utility to verify that the creation of the table is written as replicated entries in the source server's transaction logs.

ctrepd 1 0 -inow -w -m -f SOURCE_SERVER_NAME

Where:

-inow is start at the current position

-w is wide format

-m is print file names

-f is wait for more entries (press <ctrl>-c to terminate)

Example ctrepd output

Replication log reader connected to data source.

(waiting for more log entries...)

Starting scan with log 7, position 3352334

log nbr    log pos  (in hex)     opcode        tranno   fileid      tstamp  flags  filename

       7    3350130 0x00331e72     CHKPNT            0        0           0   0x00

(waiting for more log entries...)

       7    3353817 0x00332cd9     OPNFIL        27702     1512  4294968811   0x00  custmast.dat

       7    3353054 0x003329de    BEGTRAN        27701        0  1694005047   0x00

       7    3358133 0x00333db5    CREIFIL        27701     1512           0   0x00  custmast.dat

       7    3358689 0x00333fe1  SETDEFBLK        27701     1512           0   0x00  custmast.dat

       7    3361059 0x00334923  SETDEFBLK        27701     1512           0   0x00  custmast.dat

       7    3362729 0x00334fa9     ADDRES        27701     1512           0   0x00  custmast.dat

       7    3363763 0x003353b3    ENDTRAN        27701        0  1694005055   0x00

       7    3363805 0x003353dd    SUCTRAN        27701        0           0   0x00

(waiting for more log entries...)

       7    3363847 0x00335407     CLSFIL        27703     1512  1694005064   0x00

(waiting for more log entries...)

Return

Value Symbolic Constant Explanation
0 NO_ERROR Successful update.
48 FMOD_ERR ctISAMKBUFhdr called with index file.
62 LERR_ERR File not opened exclusively.
116 IMOD_ERR Invalid mode value or called for non-server system.
463 UQID_ERR TIMEID matches existing file ID.

See c-tree Error Codes for a complete listing of valid c-tree error values.

The following arbitrary example determines the number of active records in file number 1, inflates the count by 10, and overrides the number of active records in the header of the data file with the new value.

Example

LONG      NbrRecords,i,worklong;


printf("\nNumber of records = %ld",NbrRecords = DATENT(1));

if (error = UpdateHeader(1,NbrRecords+10,ctNUMENThdr))

    printf("\nreturn from UpdateHeader is %d",error);

See also

PutDODA(), FirstRecord(), NextRecord(), PreviousRecord(), ReWriteRecord(), ReadIsamData()

 

 

UpdateRecordOffsetForKey

UpdateRecordOffsetForKey() searches the specified index for the specified key value and changes its record offset to the specified record offset.

Function Name

NINT UpdateRecordOffsetForKey(FILNO keyno, pVOID target, LONG8 recbyt);

Type

Low-Level file function

Description

  • keyno - The index file number. In V12 the file number typedef was formally changed from COUNT, a two-byte value to FILNO, a four-byte value. Refer to this link for compatibility details. Four Byte File Numbering
  • target - The key value whose record offset is to be changed.
  • recbyt8 - The new record offset.

UpdateRecordOffsetForKey() can be used with an index that allows duplicates. Notice that, in the case of duplicates, the target key value must also include the 4-byte or 8-byte record offset at the end of the key because an index that allows duplicates stores the offset as part of the key. As a low-level function, it's most useful for an index that is managed only using low-level functions. Calling UpdateRecordOffsetForKey() on a key whose index has an ISAM-level mapping with a data file (meaning the data and index file were opened at the ISAM level), the function fails with error FMOD_ERR.

Return

NO_ERROR (0) on success, or a non-zero c-tree error code on failure.

If the specified key value doesn't exist in the index, the function returns error INOT_ERR (101).

If the specified index file has an ISAM mapping to a data file, the function returns error FMOD_ERR (48).

 

USERINFOX

Track user information for each connection.

Declaration

NINT USERINFOX(pUSRINFX pusrinfx);

Description

In V11.6 and later, FairCom Server tracks the following statistics for each connection:

  • disk read operations
  • disk read bytes
  • disk write operations
  • disk write bytes
  • data cache requests
  • data cache hits
  • index cache requests
  • index cache hits

Note that USERINFOX() also returns the connection information for the calling connection.

Compatibility Note: This feature does not introduce any compatibility issues, however a new client library and new server are required to use the USERINFOX() function. If the new client library is used to connect to an old server, a call to the USERINFOX() function fails with error 170. The behavior of the existing USERINFO() function is unchanged.

USRINFX structure definition:

typedef struct userinfoxprm {

    UCOUNT  StructVersion;  /* [IN] Version of this structure. */

    UCOUNT  TaskId;         /* [IN,OUT] On input, set to the task ID of the

                               connection whose information is to be returned,

                               or set it to zero to return the information for

                               all connections. On output, this field is set to

                               the number of entries that were written to the

                               output buffer. */

    ULONG   UserInfoLength; /* [IN] Size of one connection info entry. */

    ULONG   OutBufferSize;  /* [IN,OUT] On input, set to the size of the

                               output buffer. On output, holds the number of

                               bytes written to the output buffer. If the

                               required size is too small, the function returns

                               error code VBSZ_ERR and sets OutBufferSize to

                               the size required to hold information for all

                               of the connections. */

    pTEXT   pOutBuffer;     /* [OUT] Buffer where the connection info is

                               returned. */

} USRINFX, *pUSRINFX;

 

Return Values

Value Symbolic Constant Explanation
0 CTDBRET_OK Successful operation.

See c-tree Plus Error Codes for a complete listing of valid c-tree Plus error values.

Example


int call_USERINFOX (void)

{

 pUSRPRFX pupx = NULL;

 pUSRPRFX spx;

 USRINFX uix;

 ULONG   outbuflen = 16 * sizeof(USRPRFX);

 NINT    rc,i;

 

retry:

 /* Allocate output buffer. */

 if (!(pupx = (pUSRPRFX) calloc(1,outbuflen))) {

  rc = UALC_ERR;

  goto err_ret;

 }

 

 /* Set structure version. */

 uix.StructVersion = USERINFOX_VERS_V01;

 

 /* Set size of information structure. */

 uix.UserInfoLength = sizeof(USRPRFX);

 

 /* Get info for all connections. */

 uix.TaskId = 0;

 

 /* Set output buffer. */

 uix.pOutBuffer = (pTEXT) pupx;

 

 /* Set size of output buffer. */

 uix.OutBufferSize = outbuflen;

 

 rc = USERINFOX(&uix);

 if (rc) {

  if (rc == VBSZ_ERR) {

   if (uix.OutBufferSize <= outbuflen) {

    /* Unexpected */

    rc = PBAD_ERR;

    goto err_ret;

   }

   outbuflen = uix.OutBufferSize;

   free(pupx);

   pupx = NULL;

   goto retry;

  }

  goto err_ret;

 }

 /* Loop over connection info entries: */

 for (i = 0, spx = (pUSRPRFX) uix.pOutBuffer; i < uix.TaskId; i++, spx++) {

  /* spx points to the connection info for the ith entry. */

 }

 

err_ret:

 if (pupx) {

  free(pupx);

 }

 return(rc);

}

See Also

 

USERLIST

Track user information for each connection.

Declaration

CTERR USERLIST(pCOUNT pc);

Description

pc - Pointer to an array of type COUNT. You must allocate this array. Make it large enough to hold the maximum allowed connections to your server plus 1. The function will fill this array with task IDs of connected users. The first element is set to the size of the list. I.E. if there are 27 users, there will be 28 items in the array. The first number (element 0) will be 27 followed by 27 task IDs (elements 1-27).

USERLIST() fills out a passed in array of task IDs (of type COUNT) for users connected to the server. The first element is the number of users or the length of the list. The function returns any errors it hits or 0 on success. For each task ID in the list you can call USERINFO() (USERINFOX, USERINFOX) to get additional information about that connected user.

Return Values

Value Symbolic Constant Explanation
0 CTDBRET_OK Successful operation.

See c-tree Plus Error Codes for a complete listing of valid c-tree Plus error values.

Example

#include "ctreep.h" /* c-tree Plus Application Header File */

 

#ifdef PROTOTYPE

pTEXT elapsed(LONG ct, LONG ut, pTEXT buf)

#else

pTEXT elapsed(ct, ut, buf)

LONG ct, ut;

pTEXT buf;

#endif

{

LONG sec;

 

if (ut && ut != -1L && ct >= ut) {

sec = (ct - ut) % 60;

ut = (ct - ut) / 60L;

sprintf(buf, "%3d:%02d", ut, sec);

}

else

ctrt_strcpy(buf, "  –  ");

 

return(buf);

}

 

#ifdef PROTOTYPE

NINT main(NINT argc, pTEXT argv[])

#else

NINT main(argc, argv)

NINT argc;

TEXT argv[];

#endif

{

COUNT clist[USRLSTSIZ];

USRPRF ui;

NINT i;

COUNT RetVal;

LONG curtim;

TEXT buf1[16], buf2[16];

 

if (argc != 4)

{

printf("c-treeACE Users List Utility\n");

printf("Usage:\n");

printf("%s <server_name> <user_name> <password>", argv[0]);

exit(1);

}

 

#ifdef ctTHRDS

if (ctThrdInit(3, 0L, NULL) != 0)

{

printf("Unable to initialize threading\n");

exit(1);

}

#endif

 

printf("Getting users connected to %s...\n", argv[1]);

RetVal = InitISAMXtd(16, 16, 16, 16, 0, argv[2], argv[3], argv[1]);

if (RetVal) 

{

printf("Error %d connecting to server\n", RetVal);

}

else

{

if (USERLIST(clist))

{

printf("Could not get list of attached clients\n");

}

 

if (clist[0] == 0)

{

printf("No clients attached\n");

}

 

printf("Task::UserID::NodeName::Open Files::Logon Time::Tran Time::Rqst Time::Rqst#\n");

for (i = 1; i <= clist[0]; i++)

{

if (USERINFO(clist[i], &ui) || !ui.ulogtim)

continue;

curtim = ui.ucurtim;

printf("%d::%s::%s::%d::disappointed:%s)::disappointed:%s)::disappointed:%s) %s::%d %s\n", ui.utaskid, ui.uname, ui.unodnam, ui.unbrfil, elapsed(curtim, ui.ulogtim, buf1), elapsed(curtim, ui.utrntim, buf1), elapsed(curtim, ui.urqstim, buf2), (ui.uactflg ? "InProcess" : "NoRequest"), ui.urqstfn, ui.urqst);

}

printf("\n");

CloseISAM();

printf("Session Completed.");

}

#ifdef ctTHRDS

ctThrdTerm()

#endif

}
 

See Also

 

UserLogEntry

Allows a user specified message to be written to the transaction logs.

Short Name

TRANUSR()

Declaration

The function declaration is as follows:

LONG UserLogEntry(FILNO filno, LONG poshw, LONG poslw, LONG offset, 
             LONG attribute, pVOID buffer, VRLEN bufsiz)

Description

In V12 the file number typedef was formally changed from COUNT, a two-byte value to FILNO, a four-byte value. Refer to this link for compatibility details. Four Byte File Numbering

UserLogEntry() returns the low-order word of the transaction number associated with the log entry. A return value of zero indicates an error and uerr_cod contains the error number. The high-order word of the transaction number is returned by a call to ctGETHGH() after a successful call to UserLogEntry().

  • filno specifies a user file number or -1 if no file number.
  • poshw, poslw, and offset specify three 4-byte integers to be used as desired. By convention, poshw and poslw are the high and low-order words of a file position, and offset specifies the number of bytes this file position is from the beginning of a logical record. However there is no restriction on how the user interprets these three words.
  • attribute specifies a 4-byte integer stored in the tranatr word of the TRANDSC structure. It is intended to permit the user to specify the type of user log entry. There are two restrictions:
    1. The highest order three bits of the 4-byte integer cannot be used. Error BMOD_ERR () will result otherwise.
    2. If the attribute is an even integer, then the log entry is part of the user’s existing transaction, is subject to transaction save points, and may not appear in the log unless and until TRANEND() is called.
  • buffer points to an optional variable-length portion of the log entry. Its contents are completely arbitrary.
  • bufsiz is the length of buffer. It should be zero if buffer is NULL. It is not permitted to exceed a configurable limit. If bufsiz exceeds the limit, a PBAD_ERR (749) occurs. The limit prevents a malicious program from "swamping" the log. The server configuration keyword
    MAX_USER_LOG_ENTRY_BYTES  < maximum number of bytes in variable region>
    overrides the default limit of 16KB.

 

uTFRMKEY

Undo key segment translation to target key.

Short Name

uTFRMKEY()

Type

ISAM function

Declaration

pTEXT uTFRMKEY(FILNO keyno, pVOID tarptr)

Description

In V12 the file number typedef was formally changed from COUNT, a two-byte value to FILNO, a four-byte value. Refer to this link for compatibility details. Four Byte File Numbering

uTFRMKEY() undoes reversible key transformation, meaning it can reverse the TransformKey() transformations where possible. For example, an INTSEG() transformation can be undone but an uppercase conversion such as UREGSEG() transformation cannot be undone.

Return

uTFRMKEY() returns a pointer to the translated target key. Since the translation is performed in place, the return value is always equal to the target parameter, unless there is an error. A NULL value is returned if there is an error, and the value of isam_err will be:

Value Symbolic Constant Explanation
80 BKEY_ERR tarptr is null or keyno is out of range.
199 NSCH_ERR Segment mode requires a schema map.
433 SSCH_ERR File referenced by schema-based segment is not defined.

See c-tree Error Codes for a complete listing of valid c-tree error values.

See also

CurrentISAMKey(), BuildKey(), TransformKey()

 

VDataLength

Get length of variable-length data record.

Short Name

GTVLEN()

Type

Low-Level variable-length data file function

Declaration

VRLEN VDataLength(FILNO datno, LONG recbyt) 

Description

In V12 the file number typedef was formally changed from COUNT, a two-byte value to FILNO, a four-byte value. Refer to this link for compatibility details. Four Byte File Numbering

VDataLength() returns the total length of the variable-length data record beginning at byte offset recbyt in file datno.

Return

If no error occurs, VDataLength() returns the total record length for the specified offset. When VDataLength() returns a zero, check uerr_cod. If uerr_cod is zero, the record length is zero. Otherwise, an error occurred as follows:

Value Symbolic Constant Explanation
0 CTDBRET_OK Successful operation.
29 ZREC_ERR Data file routine called with recbyt = 0.
48 FMOD_ERR

Operation incompatible with type of file. The specifics vary by function:

  • The specified keyno is not an index file number.
  • The file is not a data file or it does not contain an IFIL resource (ctFILBLK in ctFBisam mode).
  • One or more associated file (data and index files) is not TRANDEP (using RENIFIL / RENIFILX).
149 VRLN_ERR Variable-length passed to AddVRecord() is less than minimum record length established at file creation.
154 VRCL_ERR Attempt to read (R) a zero length record from a variable-length data file.
158 VFLG_ERR ReReadVRecord() record not marked active.

See c-tree Error Codes for a complete listing of valid c-tree error values.

Example

LONG      pntr;

VRLEN     vreclen;

FILNO     datno,keyno;

TEXT      key_buffer[64];


if ((pntr = FirstKey(keyno,key_buffer)) != 0L) {

    vreclen = VDataLength(datno,pntr);

    if (uerr_cod == 0) {

        if (vreclen)

            printf(

            "\nFirst variable record by key requires %d bytes",

            vreclen);

        else

            printf("\nRecord length is zero.");

    }

    else

        printf("\nError %d getting length.", uerr_cod);

}

See also

 

VRecordLength

Get length of current variable-length ISAM record.

Short Name

GETVLEN()

Type

ISAM variable-length record function

Declaration

VRLEN VRecordLength(FILNO datno) 

Description

VRecordLength() returns the length of the current ISAM record for variable-length data file datno. If an error occurs, VRecordLength() returns a zero and isam_err is set to the error code.

Ordinarily, VRecordLength() is used to determine the buffer size requirements for the entire record after a call to an ISAM function that reads only the fixed-length portion of the record. ReReadVRecord() can then be called to retrieve the full record. If you already know the maximum possible record length for the data file, it is not necessary to call VRecordLength() before ReReadVRecord().

Return

If no error occurs, VRecordLength() returns the total record length for the current ISAM record. Otherwise, VRecordLength() returns a zero and isam_err is set as follows:

Value Symbolic Content Explanation
0 NO_ERROR Successful return.
48 FMOD_ERR datno is assigned to a fixed length data file.
100 ICUR_ERR No current ISAM record for data file.

See c-tree Error Codes for a complete listing of valid c-tree error values.

Example

  COUNT     invfil,datfil;

  VRLEN     varlen;

struct invd  {

    LONG     part_no;

    TEXT     part_name[120];

} recbuf;


if (FirstRecord(invfil,&recbuf) == NO_ERROR &&

  (varlen = VRecordLength(datfil))

    printf("\nThe first record is %u bytes long.",varlen);

else

    printf("\nError #%d on file %d",isam_err,isam_fil);

See also

ReReadVRecord(), VDataLength()

 

vtclose

Close the least recently used c-tree virtual file.

Short Name

vtclose()

Type

Utility function

Declaration

  COUNT vtclose()

Description

vtclose() frees an operating system file descriptor by closing the least recently used open c-tree virtual file. In other words, the c-tree virtual file that has not been accessed for the longest period of time will be closed to the operating system, freeing up an operating system file descriptor.

Each time this function is called, c-tree attempts to free one operating system file descriptor.

Note: This function can impose a layer of overhead in Standalone Multi-user systems, especially in heavily loaded network environments. Rather than virtually closing files, it is preferable to increase the number of available operating system file descriptors. This is typically done through the C compiler run-time on non-Unix systems and in the operating system kernel for most Unix systems.

Note: This function is intended for non-server operation, including local library support. If a client side application calls this function, it is ignored so the application does not require special treatment when linking with different c-tree libraries.

Return

vtclose() returns either YES (1) or NO (0). YES signifies a file handle was made available, NO signifies a file handle could not be freed.

See also

“Virtual Files” in the index.

 

wchIDfield

Returns the DODA field with the IDENTITY attribute set.

Declaration

  whcIDfield(FILNO datno)

Description

wchIDfield() returns which DODA field has an IDfield (IDENTITY) auto-numbering attribute set.

Where:

  • datno is the data file number. In V12 the file number typedef was formally changed from COUNT, a two-byte value to FILNO, a four-byte value. Refer to this link for compatibility details. Four Byte File Numbering

IDfields requires a DAR resource (Direct Access Resource) embedded in the file. The DAR is a specialized high-speed resource.

Return

Returns the DODA index (zero based) for the IDfield (the fieldno passed into addIDfield()). On error, -1 is returned and uerr_cod is set.

Value Symbolic Constant Explanation
0 NO_ERROR Success

See c-tree Error Codes for a complete listing of valid c-tree error values.

Example

 

retval = wchIDfield(fileno);

if (retval <0 ) {

printf("\tERROR: Failed to retrieve ID column with error %d\n", uerr_cod);

}

  else

         printf("Field %d is an IDENTITY column\n", retval);

Override IDENTITY Values

PUTHDR() using the ctIDfieldOverRide mode can turn on and off the ability to override the automatic IDfield values. The override is on a per user, per file basis. A nonzero hdrval turns on the override, and a zero hdrval restores the standard operation. When the override is on for a data file that supports an IDfield, then an add record operation does not fill-in the IDfield value. Whatever is passed in the record buffer is used for the IDfield. And a rewrite permits the IDfield value to change instead of generating the IDFL_CHG error. When the override is enabled, add record operations do not consume IDfield values.

See also

addIDfield(), delIDfield(), getIDfield(), resetIDfield(), IDfields - Extended support

 

WhichAutoSysTimeFields

Retrieve in bufptr the A_STFIELDS fields definition structure.

Type

ISAM Function

Declaration

VRLEN WhichAutoSysTimeFields(FILNO datno, pVOID bufptr, VRLEN bufsiz);

Description

  • datno - the data file number. In V12 the file number typedef was formally changed from COUNT, a two-byte value to FILNO, a four-byte value. Refer to this link for compatibility details. Four Byte File Numbering
  • bufptr - pointer to a buffer where to store the definition (after successful return, it can be cast to A_STFIELDS)
  • bufsiz - size of the bufptr.

Return

The size of bufptr actually used.

  • uerr_cod needs to be checked if an error condition occurred.
  • A return value of 0 with uerr_cod 0 indicates that no field has been defined.
  • uerr_cod set to VBSZ_ERR indicates bufsiz is too small. Return value contains required size.

 

WhichCtree

Return the current c-tree instance reference name.

Short Name

WCHCTREE()

Type

Low-Level function

Declaration

  pTEXT WhichCtree()

Description

WhichCtree() returns the active instance reference name. This is useful for displaying the active instance during program execution.

Return

WhichCtree() returns the pointer to the current instance reference name. This is the same instance reference name passed to RegisterCtree(). If there are no active instances, a NULL will be returned. See c-tree Error Codes c-tree Programmer’s Reference Guide for a complete listing of valid c-tree error values.

Example

pCTGVAR     ctWNGV;


ctWNGV = GetCtreePointer(WhichCtree());

isam_err = ctWNGV->sisam_err

See also

NextCtree(), RegisterCtree(), SwitchCtree(), UnRegisterCtree(), GetCtreePointer()

 

WriteData

Write fixed-length data record.

Short Name

WRTREC()

Type

Low-Level data file function

Declaration

COUNT WriteData(FILNO datno, LONG recbyt, pVOID recptr)

Description

In V12 the file number typedef was formally changed from COUNT, a two-byte value to FILNO, a four-byte value. Refer to this link for compatibility details. Four Byte File Numbering

WriteData() writes the fixed-length data record from the buffer area pointed to by recptr into record position recbyt for data file datno.

Return

Value Symbolic Constant Explanation
0 NO_ERROR Successful write.
29 ZREC_ERR Attempt to write at byte offset zero.
30 LEOF_ERR recbyt exceeds the logical end of file maintained in the data file header.
33 DNUL_ERR recptr is NULL.
35 SEEK_ERR lseek() failed while preparing for write.
37 WRITE_ERR Operating system could not execute write. Most likely cause is a full disk or directory.
57 DADV_ERR Proper lock not held when CHKLOK specified.

See c-tree Error Codes for a complete listing of valid c-tree error values.

Example

FILNO     datno;

TEXT      recptr[1024];


if (WriteData(datno, NewData(datno), recptr))

    printf("\nCould not write record. Error #%d",uerr_cod);

Limitations

The recbyt parameter in this function is a 4-byte value capable of addressing at most 4 gigabytes. If your application supports HUGE files (greater than 4 gigabytes), you must use the ctSETHGH() and ctGETHGH() functions to set or get the high-order 4 bytes of the file offset. See also Record Offsets Under Huge File Support.

See also

ReadData(), NewData(), WriteVData()

 

WriteVData

Write variable-length data record.

Short Name

WRTVREC()

Type

Low-Level variable-length record function

Declaration

COUNT WriteVData(FILNO datno, LONG recbyt, pVOID recptr, VRLEN varlen)

Description

In V12 the file number typedef was formally changed from COUNT, a two-byte value to FILNO, a four-byte value. Refer to this link for compatibility details. Four Byte File Numbering

WriteVData() writes varlen bytes from the record buffer pointed to by recptr into the variable-length data record at record position recbyt for data file datno.

Return

WriteVData() may return the following errors, in addition to those for WriteData().

Value Symbolic Constant Explanation
0 NO_ERROR Successful write.
48 FMOD_ERR datno is not assigned to variable-length file.
148 VLEN_ERR varlen bytes will not fit into file at position recbyt.
159 VPNT_ERR recbyt is zero.

See c-tree Error Codes for a complete listing of valid c-tree error values.

Example

LONG      recbyt;

FILNO     datno;

TEXT      recptr[1024];


scanf("%1023s",recptr);

recbyt = NewVData(datno,strlen(recptr));

if (WriteVData(datno,recbyt,recptr,strlen(recptr)))

    printf("\nCould not write record. Error #%d", uerr_cod);

Limitations

The recbyt parameter in this function is a 4-byte value capable of addressing at most 4 gigabytes. If your application supports HUGE files (greater than 4 gigabytes), you must use the ctSETHGH() and ctGETHGH() functions to set or get the high-order 4 bytes of the file offset. See also Record Offsets Under Huge File Support.

See also

WriteData(), ReadVData()