TempIIndexXtd
Temporary Incremental Index creation.
Short Name
TMPIIDXX()
Type
Extended ISAM function
Declaration
COUNT TempIIndexXtd(pIFIL ifilptr, LONG permmask,
pTEXT groupid, pTEXT fileword) Description
TempIIndexXtd() behaves the same as PermIIndex() except that the stored file definition is not updated, and you may be sharing the underlying Incremental data file. Each user can have separate and distinct temporary index files. Once the data file, ifilptr -> pfilnam, is closed the temporary index is no longer part of the Incremental ISAM structure. A single call:
- Adds one or more additional indexes to an existing Incremental ISAM definition.
- Automatically loads the indexes from the existing data (optional).
- References the new indexes with the standard ISAM level calls (e.g., the next AddRecord() call updates the new indexes along with the original indexes).
The next time the Incremental file is opened, the new indexes will NOT be opened and used. However, the temporary file is not deleted. It should be deleted by the application using OpenCtFile() in ctEXCLUSIVE mode, followed by DeleteCtFile().
ifilptr points to a new IFIL structure in which:
- dfilno contains the file number of the underlying Incremental data file.
- ix points to the new index definitions.
- tfilno is set to the first desired index number, or tfilno is -1 if you wish the index file number to be assigned, which is returned in tfilno.
- dnumidx is the number of index files to create.
permmask is the permission mask assigned to this data file. It is formed by OR-ing the appropriate permission constants.
groupid is a pointer to a buffer that contains the group id that this file is to be assigned to. The group id must be valid for the user that is creating the file. If groupid is NULL, the file will be assigned to the default group for the user.
fileword is an optional file password. If fileword is NULL then there will be no password for this file. If a password is established, every user will need to use the password to be able to open the file. For more information on user id’s, user passwords, server names, permission masks, group id’s, and file passwords, review Security and Encryption (File Security and Encryption, /doc/ctreeplus/FileSecurityandEncryption.htm) in the c-tree Programmer’s Reference Guide.
Note: There is the potential for index/data inconsistency errors, such as RVHD_ERR (123), ITIM_ERR (160), etc., when using a temporary index in a multi-user environment. Temporary indexes are visible ONLY to the user who creates them and, therefore, any record updates and/or deletions by other users are not applied to the temporary index.
When a multiuser error occurs on a temporary index, the default server behavior is to skip the offending record and treat it as deleted. If another record satisfies the search request, that record will be returned. sysiocod is set to ITMP_COD (-832) to indicate the skipped record. This record skipping behavior can be disabled with server keyword COMPATIBILITY TEMP_INDEX_ERROR.
The ability to suspend the addition of existing data records to the newly created index creates new indexes without inserting keys for the existing records. This allows an application to have indexes containing only new entries, speeding access to newer data. Consider the following pseudocode:
- Call TempIIndexXtd() with ifilptr -> dxtdsiz == ctNO_IDX_BUILD.
- Do NOT call RebuildIIndex().
- Add new data records, but no deletes or rewrites.
- Use the temporary indexes to reference only the newly added data. The temporary indexes will not have any of the data that existed prior to the TempIIndexXtd() call.
See the ctNO_IDX_BUILD description in PermIIndex() for details.
Return
| Value | Symbolic Constant | Explanation |
|---|---|---|
| 0 | NO_ERROR | Successful creation of new temporary index. |
| 107 | IDRK_ERR | Too many index files for one data file. Increase MAX_DAT_KEY in ctoptn.h or keyword in ctsrvr.cfg. |
| 197 | IMEM_ERR | Not enough memory. |
| 465 | IINI_ERR | ifilptr->dnumidx < 1. |
| 466 | IIDT_ERR | ifilptr->dfilno does not reference an ISAM data file. |
| 467 | IINM_ERR | ifilptr->ix->aidxnam must point to a new index file name. |
| 468 | IITR_ERR | Incremental index cannot be built inside a transaction. |
See c-tree Error Codes for a complete listing of valid c-tree error values.
See also
AddRecord(), OpenCtFile(), DeleteCtFile(), PermIIndex(), RebuildIIndex()
TempIIndexXtd8
Extended 8-byte temporary Incremental Index creation.
Short Name
TMPIIDXX8()
Type
Extended 8-byte ISAM function
Declaration
COUNT TempIIndexXtd8(pIFIL ifilptr, LONG permmask,
cpTEXT groupid, cpTEXT fileword, pXCREblk pxcreblk)Description
TempIIndexXtd8() is a variation of TempIIndexXtd() that permits the use of huge file support. This section expands on the description of TempIIndexXtd().
pxcreblk points to an array of XCREblk structures, the extended creation block, one for each physical file in ifilptr. For more information, review Huge File Support in the c-tree Programmer’s Reference Guide.
Return
TempIIndexXtd8() returns error codes similar to those for TempIIndexXtd(). See c-tree Error Codes in the c-tree Programmer’s Reference Guide for a complete listing of valid c-tree error values.
Limitations
PermIIndex8() and TempIIndexXtd8() support ctTRANDEP creates. Without ctTRANDEP creates, these routines cannot be called within a transaction. With ctTRANDEP creates, they MUST be called within a transaction.
See also
PermIIndex(), RebuildIIndex(), TempIIndexXtd()
TestFileNbr
Determine the status of a file number.
Short Name
TSTFILNUM()
Type
Low-Level function
Declaration
COUNT TestFileNbr(FILNO filno)Description
In V12 the file number typedef was formally changed from COUNT, a two-byte value to FILNO, a four-byte value. Refer to this link for compatibility details. Four Byte File Numbering
TestFileNbr() returns zero if filno is not in use or returns FINT_ERR (47, c-tree not initialized), FNUM_ERR (22, filno is out of range), or FUSE_ERR (46, filno is in use). TestFileNbr() does NOT set or change uerr_cod.
Return
| Value | Symbolic Constant | Explanation |
|---|---|---|
| 0 | NO_ERROR | File number not in use. |
| 22 | FNUM_ERR | filno is out of range. |
| 46 | FUSE_ERR | filno is in use. |
| 47 | FINT_ERR | c-tree not initialized. |
See c-tree Error Codes for a complete listing of valid c-tree error values.
Example
COUNT retval;
if (retval = InitISAM(6,7,4))
printf("\nCould not initialize. Error %d.", retval);
else {
if ((retval = TestFileNbr(5)) == 0) {
if (OpenRFile(5, "MyFile.dat"))
printf("\nCould not open files.");
{
else if (retval == 46)
if (OpenRFile(-1, "MyFile.dat"))
printf("\nCould not open files.");
if (CloseISAM())
printf("\nCould not close ISAM.");
}
TestHugeFile
Test 8-byte file status.
Short Name
TESTHUGE()
Type
Low-Level function
Declaration
COUNT TestHugeFile(FILNO filno) Description
In V12 the file number typedef was formally changed from COUNT, a two-byte value to FILNO, a four-byte value. Refer to this link for compatibility details. Four Byte File Numbering
TestHugeFile() takes the file number of an opened file, filno, as its input argument to determine if the volume containing the file supports huge files.
Note: This function does NOT determine how much space is available, only if the OS logically supports such file sizes on the volume containing the open file referenced by filno.
Return
TestHugeFile() returns the following values:
| Value | Symbolic Constant | Explanation |
|---|---|---|
| 0 | NO_ERROR | Files > 4 GB supported. |
| 26 | FACS_ERR | If filno is not in use. |
| -647 | E2GB_COD | Files > 2 GB NOT supported. |
| -648 | E4GB_COD | Files > 4 GB NOT supported. |
See c-tree Error Codes for a complete listing of valid c-tree error values.
TRANRDY
Executes the first phase of a two-phase transaction commit.
Short Name
TRANRDY()
Type
Low-Level function
Declaration
COUNT TRANRDY()Description
Two-Phase transaction support allows, for example, a transaction to span multiple servers. This is useful for updating information from a master database to remote databases in an all-or-nothing approach.
To start a transaction that supports a two-phase commit, you would include the ctTWOFASE attribute in the transaction mode passed to the Begin() function. Call the TRANRDY() function to execute the first commit phase, and finally Commit() to execute the second commit phase.
Note: You may need additional caution with regard to locking and unlocking of records as your transactions become more complex in a multi-server environment to avoid performance problems.
Caution: Two-Phase transactions can become extremely difficult to debug should there be communications problems between servers at any time during the second commit phase. This can result in out of sync data between the servers as one server may have committed while another server failed. It is always appropriate to check the return codes of the individual Commit() functions to ensure a complete successful transaction commit across multiple servers.
Return
| Value | Symbolic Constant | Explanation |
|---|---|---|
| 0 | CTDBRET_OK | Successful operation. |
| 71 | TNON_ERR | No active transaction. |
| 94 | PNDG_ERR | Pending error: cannot save or commit tran. |
See c-tree Plus Error Codes for a complete listing of valid c-tree Plus error values.
Example
(Note that this example could also use individual threads of operation for the different c-tree Server connections, avoiding the c-tree instance calls.)
COUNT rc1,rc2;
FILNO filno1,filno2;
COUNT rcc1,rcc2;
TEXT databuf1[128],databuf2[128];
/* Create the connections and c-tree instances */
...
if (!RegisterCtree("server_1")) {
SwitchCtree("server_1");
InitISAMXtd(10, 10, 64, 10, 0, "ADMIN", "ADMIN", "FAIRCOMS1");
filno1 = OPNRFIL(0, "mydata.dat", ctSHARED);
FirstRecord(filno1, databuf1);
memcpy (databuf1, "new data", 8);
/* Prepare transaction on c-tree server 1 */
Begin(ctTRNLOG | ctTWOFASE | ctENABLE);
ReWriteRecord(filno1, databuf1);
rc1 = TRANRDY();
}
if (!RegisterCtree("server_2")) {
SwitchCtree("server_2");
InitISAMXtd(10, 10, 64, 10, 0, "ADMIN", "ADMIN", "FAIRCOMS2");
filno2 = OPNRFIL(0, "mydata.dat", ctSHARED);
FirstRecord(filno2, databuf2);
memcpy (databuf2, "new data", 8);
/* Prepare transaction on c-tree server 2 */
Begin(ctTRNLOG | ctTWOFASE | ctENABLE);
ReWriteRecord(filno2, databuf2);
rc2 = TRANRDY();
}
/* Commit the transactions */
if (!rc1 && !rc2) {
SwitchCtree("server_1");
rcc1 = Commit(ctFREE);
SwitchCtree("server_2");
rcc2 = Commit(ctFREE);
if (!rcc1 && !rcc2) {
printf("Transaction successfully committed across both servers.\n");
} else {
printf("One or more units of the second commit phase of the transaction failed: rcc1=%d rcc2=%d\n", rcc1, rcc2);
}
} else {
printf("One or more of the transactions failed to be prepared: rc1=%d rc2=%d\n", rc1, rc2);
printf("Pending transactions will be aborted.\n");
SwitchCtree("server_1");
Abort();
SwitchCtree("server_2");
Abort();
}
/* Done */
SwitchCtree("server_1");
CloseISAM();
SwitchCtree("server_2");
CloseISAM();See also
Abort(), AbortXtd(), Begin(), ClearSavePoint(), Commit(), RestoreSavePoint(), SetSavePoint()
TransactionHistory
Permit scanning backward or forward through transaction logs.
Short Name
CTHIST()
Type
Low-Level function
Declaration
COUNT TransactionHistory(FILNO filno, pVOID target,
pVOID bufptr, LONG recbyt, VRLEN bufsiz, UCOUNT mode)Description
In V12 the file number typedef was formally changed from COUNT, a two-byte value to FILNO, a four-byte value. Refer to this link for compatibility details. Four Byte File Numbering
A complete single-function API to access the audit logs of transaction controlled files for the purpose of putting valuable historical capabilities in any application. Determine who deleted a record; page back through all the changes to a specific record; see who performed write operations to a specific file during a qualified time frame. These are but a few examples of this powerful feature.
The history function, TransactionHistory(), permits an application to scan backward or forward through transaction logs, returning either key values or data records and optionally the user ID and node name of the process which performed the update. When scanning backward, TransactionHistory() will look for both active log files, ending with .FCS, and for inactive log files, ending with .FCA. The information extracted from the transaction logs can be based on:
- A particular record position of a specified data file.
- A particular key value of a specified unique index.
- All updates to a specified file.
- Updates made by a particular user ID and/or node name.
- Some combination of the above.
On the first search call, set filno to the open data or index file number, or to -1 to return any file satisfying the search criteria. When filno specifies an index file, mode indicates whether TransactionHistory() returns a key value or the associated data record.
On the first search call, target points to a key value, a user ID and/or node name, or NULL, depending on the search request. On other calls, set target to NULL.
bufptr specifies the address where a search call returns log entries satisfying the search criteria. On non-search calls, set bufptr to NULL.
Set recbyt to the starting log number on a preliminary log call, to -1L on a terminating call, to zero or a particular data record location on a first search call, or to zero on subsequent search calls. bufsiz specifies the length of bufptr, the output buffer. If the buffer is too small to hold all the output requested, only bufsiz bytes are returned. If bufsiz is less than 40, error HSIZ_ERR (620) will be returned.
mode specifies the type of call, how to interpret the search criteria, and what to return to the output buffer. The following mode constants are found in ctport.h. Each represents a bit to be OR-ed into mode.
| Mode Bit | Usage |
|---|---|
| ctHISTlog | Signify preliminary log or terminate call. |
| ctHISTfirst | Signify first search call. |
| ctHISTnext | Signify subsequent search call. |
| ctHISTfrwd | Scan logs forward (default is back). |
| ctHISTuser | Match user ID. |
| ctHISTnode | Match node name. |
| ctHISTpos | Match byte offset (record position). |
| ctHISTkey | Match key value. |
| ctHISTdata | Return data record entries. |
| ctHISTindx | Return key value entries. |
| ctHISTnet | Return net change. |
| ctHISTinfo | Return User ID and node name info. |
Return
When TransactionHistory returns a non-zero value:
- The current history set is canceled.
- Memory associated with the set is freed.
- To make additional TransactionHistory calls, make a new first search call.
| Value | Symbolic Constant | Explanation |
|---|---|---|
| 0 | NO_ERROR | No error occurred. |
| 610 | HNUL_ERR | NULL target not permitted for this request. |
| 611 | HLOG_ERR | Could not access/find transaction log. |
| 612 | HSTR_ERR | Must make a first search call (ctHISTfirst). |
| 613 | HONE_ERR | Can only return data OR index entries. |
| 614 | HMAP_ERR | Could not find ISAM map from specified index file to a data file. |
| 615 | HIDX_ERR | Cannot return index entries from a specified data file. |
| 616 | HACT_ERR | TransactionHistory() cannot be called during an application’s own active transaction. |
| 617 | HNOT_ERR | Did not find target. |
| 618 | HENT_ERR | No more transaction log entries. |
| 619 | HZRO_ERR | Zero recbyt not permitted on this request. |
| 620 | HSIZ_ERR | Bufsiz too small. |
| 621 | HTYP_ERR | Transaction type found in log not expected. |
| 622 | HMID_ERR | Must reset TransactionHistory() through a terminate call or preliminary log call. |
| 623 | HMEM_ERR | Not enough memory for TransactionHistory(). |
| 624 | HNET_ERR | Net change only applies to specific match of key or record position. |
| 625 | HMTC_ERR | Must specify exactly one matching criteria: ctHISTpos or ctHISTkey or one or both of ctHISTuser and ctHISTnode. |
| 626 | HUND_ERR | Encountered an UNDTRAN (undo committed transaction) going forward: must completely restart this set of history calls. Repeat the first search call and subsequent search calls: the undone transaction will be ignored. |
| 627 | HUNK_ERR | Unknown type of request. |
| 628 | HFIL_ERR | Must specify filno. |
| 629 | HTFL_ERR | Could not initialize internal file ID: preserve files and contact FairCom. |
See c-tree Error Codes for a complete listing of valid c-tree error values.
Example
See TRNHIS.C in the \ctree\samples directory.
Limitations
When a client on a heterogeneous network calls TransactionHistory(), it only converts the history header to match the client’s byte ordering. It does not convert the optional record header or the actual data or key image from the log. It returns them in their native form as they exist on the FairCom Server.
TransactionHistory() requires transaction logs, so it only works in single-user, transaction processing applications, or in client-server applications. Files created without the ctTRNLOG file mode are not included in the transaction logs, and are not accessible to TransactionHistory().
See also Record Offsets Under Huge File Support.
TransformKey
TransformKey() transforms the supplied, already-assembled key value according to the ISAM key segment mode in effect for each of the key segments comprising the assembled key value.
Short Name
TFRMKEY()
Type
ISAM function
Declaration
pTEXT TransformKey(FILNO keyno, pVOID target)Description
In V12 the file number typedef was formally changed from COUNT, a two-byte value to FILNO, a four-byte value. Refer to this link for compatibility details. Four Byte File Numbering
The ISAM parameters for your application can specify that key segments are to be translated (e.g., converted to upper case) before being concatenated and added to index files. However, c-tree does not automatically translate your target keys in the same way. TransformKey() converts a target key, pointed to by target, according to the ISAM definition for index number keyno. For example, if you have reversed the bytes of a key segment (see segment mode equal to one in ISAM Functions of the c-tree Programmer’s Reference Guide), then passing a target key to TransformKey() causes the appropriate segment of the target key to be reversed.
Since TransformKey() constructs the translated key in place, ensure the key area pointed to by target is at least as large as the key length, including suffix, defined for index number keyno. TransformKey() expects that you have concatenated all necessary segments into a target key pointed to by the target parameter. This implies all data types should be in the same contiguous buffer. See the example and notice how the LONG field int_target is copied into the TEXT buffer key_buffer.
Note: When using single entry point function calls, (see Common Entry Point Functions in the c-tree Programmer’s Reference Guide), or the extended functions CreateISAMXtd(), OpenISAMXtd(), or InitISAMXtd(), c-tree automatically invokes TransformKey() for you unless you disable this feature.
Return
TransformKey() returns a pointer to the translated target key. Since the translation is performed in place, the return value is always equal to the target parameter, unless there is an error. If an index accepts duplicate key values, TransformKey() sets the suffix to zero in the target key. A NULL value is returned if there is an error, and the value of isam_err will be:
| Value | Symbolic Constant | Explanation |
|---|---|---|
| 80 | BKEY_ERR | target is null or keyno is out of range. |
| 199 | NSCH_ERR | Segment mode requires a schema map. |
| 433 | SSCH_ERR | File referenced by schema-based segment is not defined. |
See c-tree Error Codes for a complete listing of valid c-tree error values.
Example
TEXT alph_target[5],key_buffer[13],rec_buffer[750];
LONG int_target;
FILNO keyno;
/* target is comprised of a long integer, a five byte alphanumeric, and a 4 byte duplicate key suffix. cpybuf copies n bytes (without regard to null bytes). */
cpybuf(key_buffer, (pTEXT) &int_target,4);
cpybuf(key_buffer + 4, alph_target,5);
if (FirstInSet(keyno, TransformKey(keyno,key_buffer), rec_buffer, 9))
printf("\nUnsuccessful FirstInSet (%d)\n", isam_err);Limitations
TransformKey() automatically sets the suffix of the target key to all NULL bytes if duplicates are enabled for index number keyno. To control the suffix, change it after TransformKey() is called.
If the target area pointed to by target is not at least the key length, TransformKey() clobbers the memory area following the target key.
See also
CreateISAMXtd(), OpenISAMXtd(), InitISAMXtd(), CurrentISAMKey(), BuildKey(), uTRFRMKEY()
TransformSegment
Low-Level key transformation.
Short Name
cttseg()
Type
Low-Level function
Declaration
NINT TransformSegment(COUNT spos, COUNT mod, COUNT slen,
pTEXT target, pCOUNT aq, pConvMap mp);Description
TransformSegment() transforms keys for Low-Level functions in the same manner that TransformKey() transforms for ISAM functions.
mod is the segment mode as described in Key Segment Modes (Key Segment Modes, /doc/ctreeplus/30863.htm) in the c-tree Programmer’s Reference Guide. slen is the length of the segment to transform. tarptr points to the key value to be transformed. Note that you can do a transformation on a portion of a key. aq points to an optional alternative collating sequence. mp points to an optional record schema. aq and mp can be NULL.
spos is only used if the segment mode requires the record schema. In this case, spos specifies which field of the schema is used to define the key segment type.
Limitation: This function does not support a call with a schema-based key segment mode, such as SCHSEG, on a field that uses the CT_JSON data type. Such a call will fail with error FNUM_ERR (22). This is because, for a CT_JSON data type, the index file number and key segment number are required to transform or untransform the key segment, and this function does not accept these parameters.
Return
TransformSegment() returns zero if successful, or a Low-Level error code if not. See c-tree Error Codes in the c-tree Programmer’s Reference Guide for a complete listing of valid c-tree error values.
The following example transforms the double float key value pointed to by kvp in place.
Example
NINT errc;
double *kvp;
errc = TransformSegment(0,FLTSEG,8,(pTEXT) kvp,NULL,NULL);Limitations
It is very important to note that transformations are done in place. Move the values to a buffer or structure specifically assigned to index building, rather than transforming variables in a record buffer. Taking the example code above, a mode of FLTSEG changes the format of the information stored in the double float variable so that it can be used by c-tree as a key value. The information in that variable is no longer a valid double float value usable in C language calculations. If this variable was a part of a record structure, and it is written back to the data file, that portion of the data record is trashed.
TransformXtdSegment
Creates a binary sort key (segment) using an extended key segment definition.
Short Name
XFMKSEGDEF()
Type
ISAM Data Definition
Declaration
NINT TransformXtdSegment(NINT seghnd, pVOID src, NINT srclen,
NINT srctyp, pVOID dest, NINT destlen)Description
Most applications will not have a reason to call TransformXtdSegment() unless the application needs to create a Unicode binary sort key outside of the normal ISAM processing.
Creates a binary sort key (segment) using an extended key segment definition.
| seghnd | Handle returned by PutXtdKeySegmentDef() or GetXtdKeySegmentDef(). |
| src | Pointer to data used to construct segment. |
| srclen | Size in bytes of the region pointed by src. However, srclen is ignored unless kseg_ssiz was set to ctKSEG_SSIZ_PROVIDED. |
| srctyp | srctyp should be set to one of the c-tree field types (e.g., CT_STRING or CT_UNICODE). However, srctyp is ignored unless kseg_styp was set to ctKSEG_STYP_PROVIDED. |
| dest | Pointer to region in which binary sort key is constructed. |
| destlen | Size in bytes of the region pointed to by dest. |
Return
If successful, it returns the number of bytes used for the binary sort key. Returns a negative value upon error, where the absolute value of the return value is the error code. The most common errors are shown below.
| 445 | SDAT_ERR | No source data to create key segment. |
| 446 | BMOD_ERR | The handle references an extended key segment definition not supported by the executable. |
| 694 | NUNC_ERR | Executable does not support ICU Unicode, but a UNCSEG modifier has been encountered. |
| 700 | OSEG_ERR | Could not process key segment definition. |
| 701 | CSEG_ERR | Could not process the kseg_comp options. This could occur if more than one of a set of mutually exclusive options are combined. |
| 702 | ASEG_ERR | An error occurred when attempting to process one of the special attribute options. |
| 703 | HSEG_ERR | Invalid key segment handle. |
| 704 | SSEG_ERR | No source type provided when kseg_styp has been set to ctKSEG_STYP_PROVIDED. If this error occurs, it is likely to occur during the first use (say with an AddRecord() or AddVRecord() or OpenIFile()) of the extended key segment. |
| 706 | NSEG_ERR | Zero bytes of binary sort key were generated. Possibly an all NULL source. |
| 707 | USEG_ERR | There is no extended key segment definition to use. |
| 708 | MBSP_ERR | Multibyte/Unicode file names are not supported. |
| 709 | MBNM_ERR | A badly formed multibyte/Unicode file name has been encountered. |
| 710 | MBFM_ERR | A multibyte/Unicode variant is not supported (e.g., UTF32). |
See c-tree Error Codes for a complete listing of valid c-tree error values.
Example
See the API example in Unicode Support.
See also
AddRecord(), AddVRecord(), OpenIFile(), GetXtdKeySegmentDef(), PutXtdKeySegmentDef()