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).
|
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).
|
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
- The command-line utility ctstat -filelocks and -userlocks modes provide an alternate way to retrieve lock table information. That utility provides a more granular method of inspecting locks. See File and User Lock Example in the FairCom DB Server Administrator's Guide.
- LockDump Output
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).
|
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).
|
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:
- Server (non-BOUND) Applications: the configuration file can contain the keyword value pair:
CONTEXT_HASH <# of hash bins>
- 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).
|
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).
|
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.
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).
|
| 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:
- Resets the update corrupt flag updflg in the header of the data file.
- Rebuilds the internal delete stack chain in fixed-length files and rebuilds the internal delete management index in variable-length files.
- Removes the existing index file and builds an index, optimized for both size and speed, over the existing data file.
- 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:
- 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.
- 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
- Preventing Possible Data Loss with Compact & Rebuild Operations
- PermIIndex()
- TempIIndexXtd()
- GetCtTempFileName()
- RebuildIFileXtd()
- InitISAM()
- CompactIFile()
- SuperfilePrepassXtd()
- ISAM Functions (ISAM Database Technology, /doc/ctreeplus/30841.htm) in the c-tree Programmer’s Reference Guide (describes the ISAM parameters)
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
- Preventing Possible Data Loss with Compact & Rebuild Operations
- InitISAM()
- RebuildIFile()
- CloseISAM()
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
- Preventing Possible Data Loss with Compact & Rebuild Operations
- InitISAM()
- RebuildIFile()
- CloseISAM()
- RebuildIFileXtd()
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 USERTo 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 USERSTo 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:
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:
- Call the SECURITY() function with the SEC_CHANGE_ADVENC_PASSWD mode.
- Specify filno of -1.
- 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;
- Set options to ctENCMODlowl
- 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).
- 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
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
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
- Encryption (Advanced File Encryption, Advanced Encryption)
- ctSETENCRYPT - Passing a NULL to disable encryption
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
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:
- 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.
- An aborted automatic transaction, which occurs when the update returns an error, always releases locks acquired in the transaction.
- 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
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:
- The current history set is canceled.
- Memory associated with the set is freed.
- 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:
|
| 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
- Begin transaction
- ISAM add record R1 with unique key U to file F
- Switch to IICT mode
- 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
- ctstat -userinfox option
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
- ctstat -userinfox option
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:
- The highest order three bits of the 4-byte integer cannot be used. Error BMOD_ERR () will result otherwise.
- 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:
|
| 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()
- Record Offsets Under Huge File Support
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()