DB Function Descriptions L

LastInRange

Read the last data record in a range

Short Name

LSTRNG()

Type

ISAM function

Declaration

COUNT LastInRange(FILNO keyno, pVOID recptr)  

Description

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

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

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

Return

Value Symbolic Constant Explanation
0 CTDBRET_OK Successful operation.
101 INOT_ERR

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

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

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

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

See also

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

 

LastInSet

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

Short Name

LSTSET()

Type

ISAM function

Declaration

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

Description

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

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

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

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

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

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

Return

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

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

Example

FILNO        keyfil;
TEXT         target[24], recbuf[320];

printf("\nEnter set value:");
scanf("%23s", target);
LastInSet(keyfil, TransformKey(keyfil,target), recbuf,
          strlen(target));
while (isam_err == NO_ERROR) {
   process_data();
   PreviousInSet(keyfil, recbuf);
}

Limitations

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

See also

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

 

LastInVRange

Read the last data record in a range

Short Name

LSTVRNG()

Type

ISAM function

Declaration

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

Description

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

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

plen acts as both an input and output parameter:

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

Return

Value Symbolic Constant Explanation
0 CTDBRET_OK Successful operation.
101 INOT_ERR

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

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

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

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

See also

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

 

LastInVSet

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

Short Name

LSTVSET()

Type

ISAM function

Declaration

COUNT LastInVSet(FILNO filno, pVOID target, pVOID recptr,
                 COUNT signlen, pVRLEN plen)

Description

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

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

plen acts as both an input and output parameter:

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

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

Return

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

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

See also

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

 

LastKey

Find the last entry in an index file.

Short Name

LSTKEY()

Type

Low-Level index file function

Declaration

LONG LastKey(FILNO keyno, pVOID idxval) 

Description

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

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

Return

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

Example

TEXT     idxval[10];
FILNO    keyno;

if (LastKey(keyno,idxval))
   printf("\nLast index entry = %.10s", idxval);
else {
   printf("\nEither index is empty or an error occurred.");
   if (uerr_cod)
      printf("\Error = %d",uerr_cod);
   else
      printf("\Index is empty.);
}

Limitations

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

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

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

See also

GetCtFileInfo(), FirstKey(), NextKey()

 

LastRecord

Read the last data record.

Short Name

LSTREC()

Type

ISAM function

Declaration

COUNT LastRecord(FILNO filno, pVOID recptr)

Description

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

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

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

Return

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

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

Example

FILNO     keyfil,datfil;
TEXT      recbuf[320];

if (LastRecord(keyfil,recbuf))
    printf("\nError %d retrieving last record.", isam_err);
else if (ReReadVRecord(datfil,recbuf,320))
    printf("\nError %d retrieving variable portion.", isam_err);
else
    printf("\nSuccessful LastRecord.");

Limitations

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

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

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

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

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

See also

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

 

LastVRecord

Read the last variable-length data record.

Short Name

LSTVREC()

Type

ISAM function

Declaration

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

Description

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

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

plen acts as both an input and output parameter:

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

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

Return

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

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

See also

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

 

LoadFilter

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

Declaration

NINT LoadFilter(pTEXT libname, ppVOID plibhandle);

Where:

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

Description

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

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

See also

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

 

LoadKey

Add key value to index file in presorted order.

Short Name

LOADKEY()

Type

Low-Level index file function

Declaration

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

Description

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

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

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

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

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

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

Return

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

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

Example

TEXT      target[11];
LONG      recbyt,trials;
FILNO     name_key;
COUNT     mode;
FILE      *fp;

trials = 0L;
mode   = FRSADD;
while (fscanf(fp,"%s %ld",target,&recbyt) == 2) {
    if (LoadKey(name_key,target,recbyt,mode))
        break;
    if (trials++)
        mode = NXTADD;
}

if (uerr_cod || LoadKey(name_key,NULL,0L,BLDADD))
    printf("\nerror during LoadKey (%d) on trial #%ld", uerr_cod,trials);

Limitations

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

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

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

See also

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

 

LockCtData

Lock / unlock data records or tables.

Short Name

LOKREC()

Type

Low-Level data file function

Declaration

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

Description

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

lokmod specifies an action based on the following values:

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

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

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

Return

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

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

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

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

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

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

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

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

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

Example

LONG      pntr;
FILNO     datno;
TEXT recbuf[147];

if ((pntr = NewData(datno)) == 0L ||
    fill_buffer(recbuf) != NO_ERROR ||
    WriteData(datno,pntr,recbuf) ||
    LockCtData(datno,ctFREE,pntr))
  printf("\nCould not write new record (%d)",uerr_cod);
/* NewData always acquires a lock on a new record */

Limitations

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

Locks on a specified record offset

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

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

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

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

Table Locking

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

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

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

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

Example

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

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

See also

LockISAM(), NewData(), NewVData()

 

LockDump

Dump the FairCom Server internal lock table.

Short Name

ctLOKDMP()

Type

Low-Level function

Declaration

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

Description

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

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

refno mode Interpretation

ctLOKDMPallfiles

ctLOKDMPdatafiles

ctLOKDMPindexfiles

filno

ctLOKDMPfile

Dump all locks by file.

Dump all locks on data files.

Dump all locks on index files.

Dump locks for file filno.

ctLOKDMPallusers

ctLOKDMPcaller

userno

ctLOKDMPuser

Dump all locks by user.

Dump locks for user calling LockDump().

Dump locks for user userno.

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

Lock Dump Contents

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

----------------
----------------
SOMEFILE.FCS>>
        0000-013c9a16x T221 write/1: W060 W254 W740 W763 W758
        0000-002916abx T758 write/1: W774 W772 W771 W775 W773 W778 W779 W776 W071

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

Current file lock count: 0
----------------

cumulative I/O: read ops: 0 bytes: 0    write ops: 5 bytes: 16768
.
.
.
.
List of connected clients
-------------------------
User# 00002: (Node name not set)
User# 00012: (Node name not set)

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

Description

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

Types of Locks

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

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

File Lock Info

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

Cumulative I/O

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

List of Connected Clients

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

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

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

Return

The common error code returns are:

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

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

Example

COUNT     retval;
TEXT      dumpname[20]="AllUserLocks.dmp"

retval = LockDump(ctLOKDMPallusers, dumpname, ctLOKDMPuser);
switch (retval) {
    case NO_ERROR:
        break;
    case NUSUP_ERR:
        terminate("LockDump not supported .");
    default:
        terminate("LockDump error.");
}

Limitations

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

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

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

Related Topics

 

LockISAM

Enable, free, or suspend data record locks.

Short Name

LKISAM()

Type

ISAM function

Declaration

COUNT LockISAM(COUNT lokmod) 

Description

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

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

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

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

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

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

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

Return

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

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

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

Example

FILNO     inv_idx, inv_fil, price_idx, price_fil;
TEXT      target[9];

struct invd  {
    TEXT     delflg;
    TEXT     invn[8];
    TEXT     dscrp[60];
    TEXT     part[12];
    float    quant;
    float    price;
    float    exten;
} cur_info;

struct {
    TEXT     pdlflg;
    TEXT     ppart[12];
    float    pprice;
} price_rec;

main() {
    printf("\nEnter invoice number: ");
    scanf("%8s",target);
    if (LockISAM(ctENABLE) ||
       FirstInSet(inv_idx, target, &cur_info,8)) {
        printf("\n\nError starting SCAN with codes %d %d",
               isam_err,isam_fil);
        LockISAM(ctFREE);
        return;
    }
    while (!isam_err) {
        LockISAM(ctSUSPEND);      /* turn off lock acquisition */
        get_price_extension();
        LockISAM(ctRESTORE);      /* restore lock acquisition  */
        ReWriteRecord(inv_fil,&cur_info);
        ResetRecord(inv_fil,SWTCURI);
                                /* reset current ISAM record */
        LockISAM(ctRESET);
        NextInSet(inv_idx,&cur_info);
    }
    LockISAM(ctFREE);
}

void get_price_extension()
{
    if (GetRecord(price_idx,cur_info.part,&price_rec)) {
        printf("\nCould not find part# %s.",cur_info.part);
        return;
    }
    new_info.exten = (cur_info.price = price_rec.pprice) *
                     cur_info.quant;
}

Limitations

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

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

See also

LockCtDat()

 

LockList

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

Declaration

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

Short Name

ctLOKLST

Description

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

LockList() information is obtained with the following parameters

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

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

Details

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

typedef struct lockid {
    LONG ThrdID;        /* internal thread ID */
    TEXT UserID[32];    /* logon ID [IDZ] */
    TEXT NodeName[32];  /* optional network NodeName IDZ*/
} LOCKID, * pLOCKID;

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

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

Return

Value Symbolic Constant Explanation
0 NO_ERROR No error occurred.

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

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

Example

NINT ListLockUsers(NINT datno, ctRECPT recbyt)
{
    NINT i;
    LOCKID list[128];
    LONG lockers, waiters;
    NINT eRet;

    ctSETHGH(0);
    eRet = (NINT)LockList((FILNO)datno, recbyt, 128, &list, &lockers, &waiters);
    if (eRet != NO_ERROR)
    {
        printf("LockList failed with error %d\n", eRet);
        return -1;
    }

    /* list lock owners */
    for (i = 0; i < (NINT)lockers; i++)
        printf("Lock owner %s\n", list[i].UserID);

    /* list lock waiters */
    for (i = (NINT)lockers; i < (NINT)waiters; i++)
        printf("Waiting for lock %s\n", list[i].UserID);

    return (NINT)(lockers + waiters);
}

See also

LockCtData(), LockDump(), LockISAM()