DB Function Descriptions R

ReadData

Read fixed-length data record.

Short Name

REDREC()

Type

Low-Level data file function

Declaration

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

Description

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

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

Return

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

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

Example

FILNO     datno,keyno;
TEXT      recptr[1024];
LONG      part_number;

scanf("%ld",&part_number);
if (ReadData(datno, GetKey(keyno, &part_number), recptr))
    printf("\nCould not retrieve record for part #%ld", part_number);

Limitations

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

See also

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

 

ReadIsamData

ISAM read data at record position.

Short Name

REDIREC()

Type

ISAM function

Declaration

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

Description

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

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

Return

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

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

Example

FILNO     datno;
LONG      recbyt[16];
TEXT      recptr[1024];

/* fill in an array of record positions */
FillRecordByteArray(recbyt);

/* read the 10th record in the array */
if (ReadIsamData(datno,recbyt[9],recptr))
    printf("\nCould not read 10th record, error = %d",
           isam_err);
else
    printf("\nSuccessful record read at offset %ld",recbyt[9]);

Limitations

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

See also

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

 

ReadIsamVData

ISAM read variable-length data at record position.

Short Name

REDIVREC()

Type

ISAM function

Declaration

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

Description

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

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

plen acts as both an input and output parameter:

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

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

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

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

Return

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

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

Example

FILNO   datno;
LONG    recbyt[16];
TEXT    recptr[1024];
VRLEN   varlen;

/* fill in an array of record positions */
FillRecordByteArray(recbyt);

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

/* read *plen bytes of the 10th record in the array */
if (ReadIsamVData(datno,recbyt[9],recptr,&varlen))
    printf("\nCould not read 10th record, error = %d", isam_err);
else
    printf("\nSuccessful record read at offset %ld", recbyt[10]);

Limitations

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

See also

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

 

ReadVData

Read variable-length data record.

Short Name

RDVREC()

Type

Low-Level variable-length record function

Declaration

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

Description

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

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

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

Return

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

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

Example

FILNO     datno, keyno;
VRLEN     cur_bufsiz, varlen;
pTEXT     recptr, calloc();
LONG      part_number, pntr;

scanf("%ld",&part_number);
if ((pntr = GetKey(keyno,&part_number)) != DRNZERO) {
    varlen = VDataLength(datno,pntr);
    if (varlen > cur_bufsiz) {
        free(recptr);
        recptr = calloc(1,varlen));
        cur_bufsiz = varlen;
    }
    if (ReadVData(datno,pntr,recptr,varlen))
        printf>("\nError #%d reading at %ld", uerr_cod, pntr);
}

Limitations

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

See also

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

 

RebuildIFile

Incremental ISAM rebuild.

Short Name

RBLIFIL()

Type

ISAM function

Declaration

COUNT RebuildIFile(pIFIL ifilptr)  

Description

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

RebuildIFile() does the following:

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

The user data is not affected in any way.

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

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

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

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

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

Change approximately line 32 of ctsort.h from:

   #define WORK_DRIVE_OR_PATH ""

to:

   pTEXT WORK_DRIVE_OR_PATH;

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

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

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

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

Option to skip initial data file scan

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

myifil.tfilno = -(redosrlIFILoption | skipdatascanIFILoption);
RBLIFIL(&myifil);

Automatic Duplicate Purge Logic

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

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

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

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

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

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

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

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

Option Values

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

#define updateIFILoption     0x0002
#define purgeIFILoption      0x0004
#define badpartIFILoption    0x0008
#define redosrlIFILoption    0x0010

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

myifil.tfilno = setIFILoptions(redosrlIFILoption);
RBLIFIL(&myifil);

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

/* assign new serial numbers and update IFIL resource. */
myifil.tfilno = setIFILoptions(redosrlIFILoption | updateIFILoption);
RBLIFIL(&myifil);

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

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

badpartIFILoption (badpartIFIL)

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

Online Rebuild - new for V13

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

To invoke an online rebuild, use onlineIFILoption:

myifil.tfilno = setIFILoptions(onlineIFILoption);
RBLIFIL(&myifil);

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

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

Return

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

484

485

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

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

Example

extern IFIL    customer;
       COUNT   retval;

main() {

    if (retval = InitISAM(10,10,16))
        printf("\nInitISAM error = %d",retval);

    if (!(RebuildIFile(&customer)))
        printf("\nSuccessful rebuild");
    else
        printf("\nRebuildIFile isam_err = %d",isam_err);

    CloseISAM();
}

Limitations

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

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

See also

 

RebuildIFileXtd

Extended Incremental ISAM rebuild.

Short Name

RBLIFILX()

Type

Extended ISAM function

Declaration

COUNT RebuildIFileXtd(pIFIL ifilptr, cpTEXT dataextn, cpTEXT indxextn,
                      LONG permmask, cpTEXT groupid, cpTEXT fileword)

Description

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

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

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

Return

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

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

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

See also

 

RebuildIFileXtd8

Extended 8-byte Incremental ISAM rebuild.

Short Name

RBLIFILX8()

Type

Extended 8-byte ISAM function

Declaration

  COUNT RebuildIFileXtd8(pIFIL ifilptr, cpTEXT dataextn,
          cpTEXT indxextn, LONG permmask, cpTEXT groupid,
          cpTEXT fileword, pXCREblk pxcreblk)

Description

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

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

Return

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

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

See also


 

RebuildIIndex

Rebuilds a single index.

Short Name

RBLIIDX()

Type

ISAM function

Declaration

COUNT RebuildIIndex(pIFIL ifilptr)  

Description

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

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

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

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

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

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()