UnloadFilter
UnloadFilter() initializes resources that are used when processing the filter. The function receives the parameters passed to the filter.
Declaration
NINT UnloadFilter(pTEXT libname, pVOID libhandle)Description
This function is defined in the ctuserx.c module used to build a filter callback function.
- libname is the filter callback DLL name that was passed to SetDataFilter().
- libhandle is the application-defined library handle that was set by LoadFilter().
Return Values
| Value | Symbolic Constant | Explanation |
|---|---|---|
| 0 | CTDBRET_OK | Successful operation. |
See c-tree Error Codes for a complete listing of valid c-tree error values.
Example
/*
Example Code
*/
See also
ctfiltercbAddFilter(), EvaluateFilter(), LoadFilter(), ctfiltercbRemoveFilter(), SetDataFilter()
UnRegisterCtree
Unregister a c-tree instance.
Short Name
UNRCTREE()
Type
Low-Level function
Declaration
COUNT UnRegisterCtree(pTEXT regid) Description
UnRegisterCtree() frees the allocated memory for the c-tree global structure belonging to the registration reference name pointed to by regid.
Return
| Value | Symbolic Constant | Explanation |
|---|---|---|
| 0 | NO_ERROR | Instance successfully unregistered. |
| 516 | GNUL_ERR | ctNOGLOBALS not defined. |
| 517 | GNOT_ERR | regid is not registered. |
See c-tree Error Codes for a complete listing of valid c-tree error values.
Example
TEXT inpbuf[32]; /* input buffer */
ctrt_printf("\nEnter Instance Name\n");
gets(inpbuf);
if (RegisterCtree(inpbuf))
{
ctrt_printf("\nCould not unregister {%s} data base", inpbuf);
ctlxmg_exit(2);
}
UnRegisterCtree(inpbuf);Limitations
File handles are not shared between instances. Virtual logic cannot close files in other instances.
See also
NextCtree(), SwitchCtree(), RegisterCtree(), WhichCtree(), GetCtreePointer()
UpdateAutoSysTimeFields
Similar to AddAutoSysTimeFields, but used to update existing definitions. The definition passed in replaces an existing one.
Type
ISAM Function
Declaration
NINT UpdateAutoSysTimeFields(FILNO datno, pA_STFIELDS defs);Description
- datno - the data file number. In V12 the file number typedef was formally changed from COUNT, a two-byte value to FILNO, a four-byte value. Refer to this link for compatibility details. Four Byte File Numbering
-
defs - pointer to fields definition structure:
typedef struct astfields { COUNT version; /* Version of this structure */ COUNT entries; /* number of entries in fields array */ LONG pad; /* padding to ensure struct alignment */ pA_STFIELD fields; /* fields array */ } A_STFIELDS, *pA_STFIELDS;
- version - the version of the structure. must be set to A_STFIELDS_VERS_V01.
- entries - the number of fields that needs to be automatically set with the system time. It must match the number of entries in the fields array.
-
fields - pointer to an array of field settings:
typedef struct astfield { LONG fieldno; /* field number */ TEXT mode; /* set time */ } A_STFIELD, *pA_STFIELD;
- fieldno - the field number in the DODA for the field that is set to auto setting with system time stamp.
- mode - in which condition the field gets populated. Possible values:
CT_AUTOSYSTIME_CREATE 0x01 - when the record gets added
CT_AUTOSYSTIME_UPDATE 0x02 - when the record gets rewritten/updated.
Return
NO_ERROR on success
UpdateConditionalIndex
Update the Conditional Index Resource in a data file.
Short Name
UPDCIDX()
Type
ISAM level function
Declaration
COUNT UpdateConditionalIndex(FILNO keyno, pTEXT condexpr)Description
In V12 the file number typedef was formally changed from COUNT, a two-byte value to FILNO, a four-byte value. Refer to this link for compatibility details. Four Byte File Numbering
UpdateConditionalIndex() can add, delete, or change the conditional expression associated with the index. This function assumes an ISAM mapping exists between keyno and an associated data file. The NULL-terminated ASCII string pointed to by condexpr defines the conditions that must be true for an index entry to be made. The expression is stored as a resource in the associated data file.
If condexpr is NULL or points to an empty string (""), the existing conditional expression is deleted. Each index can have at most one conditional expression. If keyno already has an expression, the new expression replaces the old expression.
For existing, non-empty files, it is ordinarily necessary to call a rebuild after updating the conditional expressions.
UpdateConditionalIndex() checks the syntax of the expression before adding it to the data file resource. The syntax can fail because a name used in the expression is not found in the DODA, or because of an illegal expression.
A special case exists with indexes created by PermIIndex() and TempIIndexXtd(). By default, both functions create and fill index files in one action without allowing a condition to be set. The ability to separate the index creation from the index build permits UpdateConditionalIndex() to set conditional expressions for the new indexes. If PermIIndex() is involved, the data file has its conditional index resource updated. If TempIIndexXtd() is involved, no permanent storage of the conditional index expression is made. The proper steps are:
- Call PermIIndex() or TempIIndexXtd() with ifilptr -> dxtdsiz == ctNO_IDX_BUILD.
- Call UpdateConditionalIndex() for each new index with a conditional expression.
- Call RebuildIIndex() for the new indexes.
Note: Do not close the newly created indexes between a call to PermIIndex() or TempIIndexXtd() and a call to RebuildIIndex().
UpdateConditionalIndex() creates a temporary conditional index if called for a temporary index. The data file conditional index resource is not updated. Once the temporary index closes, the conditional expression goes with it. To accomplish this:
- Execute TempIIndexXtd() with the dxtdsiz parameter of the IFIL structure set to ctNO_IDX_BUILD to create an empty index file.
- Call UpdateConditionalIndex() to add the condition.
- Call RebuildIIndex() to fill the index.
Return
| Value | Symbolic Constant | Explanation |
|---|---|---|
| 0 | NO_ERROR | Successful update of condition expression resource. |
| 401 | RNON_ERR | Resources not enabled. |
| 597 | CINI_ERR | Failed syntax check. |
| 614 | HMAP_ERR | No map to a data file exists for keyno. |
See c-tree Error Codes for a complete listing of valid c-tree error values.
Example
UpdateMyIndex(pIFIL ifilptr, FILNO keyno, pTEXT condexpr)
{
/* This function updates the conditional expression of a given
index and rebuilds the index. Requirements include proper
c-tree ISAM initialization and IFIL file open. */
keyno = ifilptr->tfilno;
if (UpdateConditionalIndex(keyno, condexpr))
return(isam_err);
if (RebuildIIndex(ifilptr)) {
printf("Rebuild failed after conditional index update.");
return(isam_err);
}
printf("Condition changed for index %d to %s.", keyno, condexpr);
return();
}See also
PermIIndex(), TempIIndexXtd(), UpdateConditionalIndex(), RebuildIndex(), GetConditionalIndex()
UpdateCtResource
Update the specified resource record.
Short Name
UPDRES()
Type
Low-Level file resource function
Declaration
COUNT UpdateCtResource(FILNO filno, pVOID resptr, VRLEN varlen)Description
In V12 the file number typedef was formally changed from COUNT, a two-byte value to FILNO, a four-byte value. Refer to this link for compatibility details. Four Byte File Numbering
UpdateCtResource() updates a particular Resource in file filno. resptr points to a resource data block of length varlen. This block contains the following fields:
| Byte Offset | Data Type | Field Name |
|---|---|---|
| 0 - 3 | unsigned long integer | Resource Type |
| 4 - 7 | unsigned long integer | Resource Number |
| 8 - m | null terminated character string | Resource Name |
| (m+1) - n | any collection of data types desired | Resource Information |
If a record lock has been placed on this resource by GetCtResource(), that lock is released by UpdateCtResource().
Return
| Value | Symbolic Constant | Explanation |
|---|---|---|
| 0 | NO_ERROR | Successful update. |
| 57 | DADV_ERR | Proper lock not held. |
| 401 | RNON_ERR | Resources have not been enabled for this data file. |
| 408 | RNOT_ERR | Resource not found. You cannot update a resource that doesn’t exist. |
See c-tree Error Codes for a complete listing of valid c-tree error values.
Example
struct { /* Resource Data Block structure */
ULONG resource_type;
ULONG resource_number;
TEXT variable_info[1016]; /* This will hold the Resource Name and Data */
} my_resource;
if (GetCtResource(datno, "MY!resource", &my_resource,
(VRLEN)sizeof(my_resource),(RES_NAME|RES_LOCK)))
{
/*at this point you will update the information in the buffer*/
if (UpdateCtResource(datno, &my_resource, sizeof(my_resource))
printf("\nError %d when update resource.",uerr_cod);
else
printf("\nUpdate successful!");
}
else
printf("\nCould not get resource. Error #%d",uerr_cod);Limitations
The recbyt parameter in this function is a 4-byte value capable of addressing at most 4 gigabytes. If your application supports HUGE files (greater than 4 gigabytes), you must use the ctSETHGH() and ctGETHGH() functions to set or get the high-order 4 bytes of the file offset. See also Record Offsets Under Huge File Support.
See also
GetCtResource(), AddCtResource(), DeleteCtResource()
UpdateFileMode
Changes critical file mode attributes such as the level of transaction control.
Short Name
PUTFIL()
Type
Low-Level function
Declaration
COUNT UpdateFileMode(FILNO filno, COUNT mode)Description
In V12 the file number typedef was formally changed from COUNT, a two-byte value to FILNO, a four-byte value. Refer to this link for compatibility details. Four Byte File Numbering
When creating or opening a file, the value of filmod sets the attributes for the file. Some of these attributes are permanent, assigned during the creation of the file. Others are temporary, assigned only while the file is open. UpdateFileMode() changes these attributes after the file has been opened or created.
filno specifies the file to be changed. This file must be currently open in ctEXCLUSIVE mode. filmod is the new file mode attribute. It must be perfectly formed, as it will replace the current file mode for this file.
Note: Use this function with caution! It is possible to damage a file if you are not careful. For example, changing a data file from transaction processing to no transaction processing makes automatic recovery unavailable. See the discussion of Transaction File Modes in the FairCom DB Programmer’s Reference Guide.
Some examples of changes that might make sense would be to add or delete ctCHECKLOCK, or to turn on one of the transaction modes for a data file, or to switch between ctPREIMG and ctTRNLOG for an index.
Return
| Value | Symbolic Constant | Explanation |
|---|---|---|
| 0 | NO_ERROR | No error occurred. |
| 48 | FMOD_ERR | Cannot switch between fixed and variable-length records. |
| 62 | LERR_ERR | File must be opened in ctEXCLUSIVE mode to modify. |
| 99 | TTYP_ERR | Cannot switch an index to transaction processing. |
See c-tree Error Codes for a complete listing of valid c-tree error values.
Example
FILNO filno;
if (UpdateFileMode(filno,ctTRNLOG))
printf("\nFile Mode Error %d",uerr_cod);Limitations
filno must be opened in an ctEXCLUSIVE mode. No check is made to determine if the change being made will damage the file.
UpdateHeader
Update the header portion of a c-tree file.
Short Name
PUTHDR()
Type
Low-Level function
Declaration
COUNT UpdateHeader(FILNO filno, LONG hdrval, COUNT mode)Description
In V12 the file number typedef was formally changed from COUNT, a two-byte value to FILNO, a four-byte value. Refer to this link for compatibility details. Four Byte File Numbering
UpdateHeader() permits an application to update certain fields in a file’s header record provided the file is opened in ctEXCLUSIVE mode.
- filno - data or index file number. In V12 the file number typedef was formally changed from COUNT, a two-byte value to FILNO, a four-byte value. Refer to this link for compatibility details. Four Byte File Numbering
- hdrval - is a LONG value containing the new header value.
- mode - is one of the following header-field-ID’s:
| Mode | Description |
|---|---|
| ctSERNUMhdr | Ever increasing automatic sequence number. |
| ctSUSSRLSEGhdr | Suspend the serial segment handling for data file datno. (YES or NO). |
| ctTSTAMPhdr | Time stamp of last close after updates. |
| ctNUMENThdr | Number entries in file. |
| ctTIMEIDhdr | Creation time stamp used as part of unique ID. |
| ctFLAVORhdr | Change byte ordering. |
| ctADDUNQFRShdr | Add unique keys before allocating space for the data record from the data file. If a unique key add fails, the operation fails immediately; if it succeeds, the operation continues. |
| ctALIGNhdr | Change byte alignment. |
| ctISAMKBUFhdr | Disable/enable ISAM key buffering. |
| ctISAMKBUFctx | Disables/enable ISAM key buffering in the current context only. |
| ctEXTSIZhdr | Reset file extension size. |
| ctLXTSIZhdr | Change the large extent size in the XCREblk. For transaction controlled files, ctTRNLOG, this cannot be zero. |
| ctMXFILZhdr | Maximum file size in XCREblk (only if larger than the current value.) |
| ctSCANCACHEhdr | Toggles between the LRU cache algorithm and the scanner cache algorithm. Set hdrval to YES or NO to toggle. This mode is only valid for data files. |
| ctSPLREFRESHhdr | Refresh the dedicated cache pages so that they may be assigned to different pages of the file. |
| ctSPLRESUMEhdr | Restart the use of dedicated pages after a call to stop their use. |
| ctSPLSTOPhdr | Stop using dedicated cache for this file. |
| ctIDfieldOverRide | Turn on and off the ability to override automatic IDfield values. Override is per user, per file. Nonzero hdrval turns on; zero hdrval restores standard operation. |
| ctSKIPSAVEhdr |
Suppresses or restores the update flag setting for the specified non-transaction-controlled file until it is physically closed and reopened. It is intended for temporary files not requiring persistence. |
| ctSKIPSAVEISAMhdr | Enables or disables file system cache flush calls for the specified data file and all its associated ISAM index files. |
| ctIFIL3hdr | Enables or disables (YES/NO) the V12 default IFIL resource storage format (see also the SUPPRESS_PATH_IN_IFIL server configuration keyword). The ctIFIL3hdr format supports several new naming options for alternate indexes (IFIL.aidxnam), and improves behavior when copying or renaming files with alternative index names. Disabling the ctIFIL3hdr for files using the new naming options may lead to the indexes becoming unusable. |
| ctADDKYDFRhdr | Toggles the deferred key add feature. |
| ctLOCKDFRhdr | Toggles the file state for deferred closes with pending locks on a file. |
| ctTRNPERShdr | Toggles the file state for persisted transaction unlock requests. |
| ctIICThdr | Enables the Immediate Independent Commit Transaction (IICT). This is an auto commit ISAM update executed while a transaction is pending for the same user (thread). IICT is independent of the existing transaction: it is as if another user/thread is executing the IICT. |
| ctXFLSEThdr | Sets extended file mode to lower-order two bytes of the hdrval parameter. |
| ctXFL_ONhdr | Turns on the lower-order two bytes of hdrval in the extended file mode. |
| ctXFLOFFhdr | Turns off the lower-order two bytes of hdrval in the extended file mode. |
| ctUNIQUIDhdr |
Assigns a new unique file ID to the specified file. hdrval is ignored. File must be open in exclusive mode. Sets the file ID to a unique value using one of these methods:
|
| ctMAXPARTMBRhdr | Set maximum number of active partitions on a partitioned file. When a new partition is created, if the new number of active partitions exceeds the limit, the oldest partitions are purged. |
| ctNOISMKEYUPDhdr | Restrict ISAM key updates for calling connection only. Remains in effect for that open instance of the index file until its close, or it can be turned off with an additional PUTHDR() call of NO. |
Note: Use this function with extreme care as you are altering c-tree file headers, which can impact availability and/or integrity of your data. This function is intended more for advanced file recovery operations than for routine production use.
Automatic TRAN/noTRAN File Support
It is possible to create files in non-TRANPROC environments (e.g., FPUTFGET or single-user non-TRANPROC) which will be transaction ready, automatically, when they are opened in a TRANPROC environment. Further, they will automatically revert back to non-TRANPROC when returned to a non-TRANPROC environment.
- To create such a file in a non-TRANPROC environment, simply set the file mode to include either TRNLOG or PREIMG at create time.
- To create such a file in a TRANPROC environment, set the file mode to include either TRNLOG or PREIMG and after the create, but before closing the file (which ensures the file is still opened exclusively), call PUTHDR(filno,TRANMODE,ctXFL_ONhdr) or PUTHDR(filno,PIMGMODE,ctXFL_ONhdr), respectively.
- An index file which cannot support transaction processing CANNOT be changed via a call to PUTHDR.
- It is possible to skip the calls to PUTHDR by including TRANMODE or PIMGMODE in the x8mode member of the extended create block.
- In non-TRANPROC environments, it is possible to disable this behavior by adding #define ctBEHAV_NOTRANFILE to ctoptn.h.
- A call to PUTFIL that changes between TRNLOG and PREIMG, or PREIMG and TRNLOG, will have the TRANMODE and PIMGMODE information updated automatically. However, a call to PUTHDR which attempts to set or turn on TRANMODE or PIMGMODE, and which is incompatible with the existing file mode or auto-switch mode results in a TTYP_ERR error (99). For example, if TRANMODE is already turned on, then PIMGMODE cannot also be turned on. If the file mode is PREIMG, TRANMODE cannot be turned on. It is possible to turn off TRANMODE or PIMGMODE by using PUTHDR with ctXFLOFFhdr.
- A superfile member cannot set TRANMODE or PIMGMODE unless the host has the same settings. If the settings do not match, a SRCV_ERR error (419) will be returned.
LOGIDX
A subtle change in how the LOGIDX file mode bit is handled has been introduced: Setting the LOGIDX bit on in the file mode used to open a file (ctXFL_ONhdr) will enable this feature (high speed index recovery) even if the file was not created with this file mode.
Mirrored Files
File mirroring status is maintained as an extended header attribute. When disabling mirroring, this bit can be permanently un-set in all physical files with the MIRRORD value with the ctXLOFFhdr mode.
Working with Temporary Files
For a temporary, non-transaction-controlled file, it may be desirable to avoid rewriting the header with the update flag set. This can be achieved for a non-transaction-controlled file by calling PUTHDR(filno, YES, ctSKIPSAVEhdr). Calling PUTHDR(filno, NO, ctSKIPSAVEhdr) restores the normal behavior for a file.
PUTHDR() called with the ctSKIPSAVEhdr fails if the file is open in shared mode and the caller does not have file definition permission on the file; or if the file is a transaction-controlled (ctTRNLOG) file.
Byte Ordering and Byte Alignment
This capability is useful for forcing different file alignment; for example, forcing byte alignment for the packing of data files. Remember, when c-tree is requested to create a data file in non-server mode, the alignment is dictated by the compiler used to create the c-tree executable. For example, Microsoft C defaults to word alignment, and most Unix systems default to double word alignment. The c-tree test utility (cttest) can be used to determine the alignment for your compiler. In non-server mode, the file flavor for the data file is dictated by the underlying CPU (i.e., Intel typically Low/High or Little Endian/Big Endian and most Motorola and RISC CPU’s are High/Low or Big Endian/Little Endian). The c-tree index file is always High/Low, regardless of the underlying CPU.
In the client/server model, the FairCom Server dictates the byte ordering of the data file (i.e., High/Low vs. Low/High) while the client application dictates the data file alignment.
The hdrval values for the ctFLAVORhdr and ctALIGNhdr modes are:
| mode | hdrval | Explanation |
|---|---|---|
| ctFLAVORhdr |
1 2 |
LOW_HIGH HIGH_LOW |
| ctALIGNhdr |
1 2 4 8 |
byte aligned word aligned double word aligned quad word aligned |
In addition to updating the header fields, the corresponding schema fields are also updated if the file already contains a schema (from a PutDODA() call). Typical usage would be to create a file, call PutDODA(), and call UpdateHeader() with a new alignment value. For example, if the data is byte aligned in your record, (regardless of the systems inherent alignment), calling UpdateHeader() after calling PutDODA() permits the DODA to properly reflect the field alignment. See ctalgn.c in the \ctree\source directory as an example utility.
Performance Enhancement
This ISAM access mode can be set by the UpdateHeader() function to boost performance. This mode prevents c-tree from updating the internal index buffer for every key of the current ISAM record. Especially useful if a large number of keys are defined.
Each ISAM data file is assigned, for each user, a set of key buffers containing the current key image for each index for the current ISAM position. To speed record access UpdateHeader() accepts the ctISAMKBUFhdr mode, which turns on and off the support of the key buffers for a particular ISAM data file for the calling user, (i.e., NOT all users with the file open).
UpdateHeader(datno, (LONG) 1, ctISAMKBUFhdr) turns off key buffer support, speeding access to the data records. The effect on performance will be most notable when the data file supports many indexes. (Any non-zero LONG value for the second parameter will turn off support.)
UpdateHeader(datno,(LONG) 0,ctISAMKBUFhdr) turns back on key buffer support (which is the default state of an ISAM file).
Notes
If the key buffer support is turned off, then the current ISAM position for the data file is set to zero which implies no current ISAM position. This indicates the application cannot perform updates to the file since the key buffers are required. See the limitation section below.
Unlike the previous UpdateHeader() modes, this mode does not make a permanent change to the file header and therefore does NOT require the file to be opened exclusively, and only applies to the user making the call.
With key buffer suppression is on, the file cannot be traversed by one key then by a different key. Only the key that established the ISAM position (i.e., with FirstRecord(), etc.) can be used in NextRecord() or PreviousRecord(). If the data file is traversed in physical order, then no ISAM key buffer is supported.
When a record is retrieved in this mode, it is not possible to directly do a ReWriteRecord(). ReWriteRecord() returns KBUF_ERR (121) because the ISAM buffers are not being maintained. Perform a rewrite by first calling ReadIsamData().
Immediate Independent Commit Transaction (IICT)
The Immediate Independent Commit Transaction, IICT, permits a thread with an active, pending transaction to also execute immediate commit transactions, even on the same physical file that may have been updated by the still pending (regular) transaction. An IICT is essentially an auto commit ISAM update, but with the added characteristic that an IICT can be executed even while a transaction is pending for the same user (thread).
It is important to note that the IICT is independent of the existing transaction: it is as if another user/thread is executing the IICT. The following pseudo code example demonstrates this independence:
Example
- Begin transaction
- ISAM add record R1 with unique key U to file F
- Switch to IICT mode
- ISAM add record R2 with unique key U to file F: returns error TPND_ERR (420)
If we did not switch to IICT mode, the second add would have failed with a KDUP_ERR (2); however, the IICT mode made the second add use a separate transaction and the second add found a pending add for key U, hence the TPND_ERR. Just as if another thread had a key U add pending.
A data file and it's associated indices are put into IICT mode with a call
PUTHDR(datno,1,ctIICThdr)and are restored to regular mode with a call
PUTHDR(datno,0,ctIICThdr)It is possible in c-tree for a thread to open the same file in shared mode more than once, each open using a different user file number. And it is possible to put one or more of these files in IICT mode while the remaining files stay in regular mode.
Note: If a file has been opened more than once by the same thread, then the updates within a (regular) transaction made to the different file numbers are treated the same as if only one open had occurred.
These special filno values enable specific IICT operations:
- ctIICTbegin -1
- ctIICTcommit -2
- ctIICTabort -3
Override IDENTITY Values
PUTHDR() using the ctIDfieldOverRide mode can turn on and off the ability to override the automatic IDfield values. The override is on a per user, per file basis. A nonzero hdrval turns on the override, and a zero hdrval restores the standard operation. When the override is on for a data file that supports an IDfield, then an add record operation does not fill-in the IDfield value. Whatever is passed in the record buffer is used for the IDfield. And a rewrite permits the IDfield value to change instead of generating the IDFL_CHG error. When the override is enabled, add record operations do not consume IDfield values.
Scanner Cache Feature
The index cache pages are managed using a least-recently-used (LRU) scheme. For data files, the LRU scheme is not always effective. In particular, when data file access or updates involve many different records with little or no revisiting of records once they have been processed, the LRU scheme can result in many cache pages to be assigned to recently accessed records. But, at least from the user’s perspective, there is little chance of revisiting these pages.
The advanced FairCom DB header mode, ctSCANCACHEhdr, allows an alternative caching strategy. For details, see Scanner Cache.
File Extension Size
The stand-alone parameters dxtdsiz and ixtdsiz can be adjusted with the ctEXTSIZhdr parameter. File extensions less than 32768 bytes for superfile hosts, or less than 16KB for transaction processed files or mirrored files will not be permitted. If a smaller value is given, the minimum is used instead. No extension size may exceed 65,535 bytes for a Standard file. Use an Extended file to get much larger extension sizes.
Locking Behavior When Opening the Same File Multiple Times in the Same Connection
FairCom DB supports opening the same file multiple times in the same connection assigning a different file number to each file or, in FairCom DB API, a different file handle.
For details, see FairCom Server enhanced locking control for files opened multiple times in the same connection.
Turn on Replication for a Table
Use the PUTHDR() function to turn on replication for a table. The table must meet the following requirements:
- It must be opened in exclusive mode and meet the requirements for replication.
- It must use full transaction control, which is the ctTRNLOG file mode or the CTCREATE_TRNLOG FairCom DB file mode
- It must have a unique index.
Note: If these requirements aren't met the PUTHDR() call will fail with an error such as 99 or 775.
Example
With FairCom DB, table creation and enabling replication must happen within the same transaction, as shown in this example.
- hSession is an initialized FairCom DB session handle.
- hTable is an initialized FairCom DB table handle.
/* start transaction */
ctdbBegin(hSession);
/* create table */
if (ctdbCreateTable(hTable, "custmast", CTCREATE_NORMAL | CTCREATE_TRNLOG)) {
/* error */
}
/* open table in exclusive mode */
if (ctdbOpenTable(hTable, "custmast", CTOPEN_EXCLUSIVE)) {
/* error */
}
/* turn on replication for the table */
if (PUTHDR(ctdbGetDatno(hTable), YES, ctREPLICATEhdr)) {
/* error */
}
if (ctdbCommit(hSession)) {
/* error */
}
ctdbCloseTable(hTable);Verify replication
Use the ctrepd utility to verify that the creation of the table is written as replicated entries in the source server's transaction logs.
ctrepd 1 0 -inow -w -m -f SOURCE_SERVER_NAMEWhere:
-inow is start at the current position
-w is wide format
-m is print file names
-f is wait for more entries (press <ctrl>-c to terminate)Example ctrepd output
Replication log reader connected to data source.
(waiting for more log entries...)
Starting scan with log 7, position 3352334
log nbr log pos (in hex) opcode tranno fileid tstamp flags filename
7 3350130 0x00331e72 CHKPNT 0 0 0 0x00
(waiting for more log entries...)
7 3353817 0x00332cd9 OPNFIL 27702 1512 4294968811 0x00 custmast.dat
7 3353054 0x003329de BEGTRAN 27701 0 1694005047 0x00
7 3358133 0x00333db5 CREIFIL 27701 1512 0 0x00 custmast.dat
7 3358689 0x00333fe1 SETDEFBLK 27701 1512 0 0x00 custmast.dat
7 3361059 0x00334923 SETDEFBLK 27701 1512 0 0x00 custmast.dat
7 3362729 0x00334fa9 ADDRES 27701 1512 0 0x00 custmast.dat
7 3363763 0x003353b3 ENDTRAN 27701 0 1694005055 0x00
7 3363805 0x003353dd SUCTRAN 27701 0 0 0x00
(waiting for more log entries...)
7 3363847 0x00335407 CLSFIL 27703 1512 1694005064 0x00
(waiting for more log entries...)Return
| Value | Symbolic Constant | Explanation |
|---|---|---|
| 0 | NO_ERROR | Successful update. |
| 48 | FMOD_ERR | ctISAMKBUFhdr called with index file. |
| 62 | LERR_ERR | File not opened exclusively. |
| 116 | IMOD_ERR | Invalid mode value or called for non-server system. |
| 463 | UQID_ERR | TIMEID matches existing file ID. |
See c-tree Error Codes for a complete listing of valid c-tree error values.
The following arbitrary example determines the number of active records in file number 1, inflates the count by 10, and overrides the number of active records in the header of the data file with the new value.
Example
LONG NbrRecords,i,worklong;
printf("\nNumber of records = %ld",NbrRecords = DATENT(1));
if (error = UpdateHeader(1,NbrRecords+10,ctNUMENThdr))
printf("\nreturn from UpdateHeader is %d",error);See also
PutDODA(), FirstRecord(), NextRecord(), PreviousRecord(), ReWriteRecord(), ReadIsamData()
UpdateRecordOffsetForKey
UpdateRecordOffsetForKey() searches the specified index for the specified key value and changes its record offset to the specified record offset.
Function Name
NINT UpdateRecordOffsetForKey(FILNO keyno, pVOID target, LONG8 recbyt);Type
Low-Level file function
Description
- keyno - The index file number. In V12 the file number typedef was formally changed from COUNT, a two-byte value to FILNO, a four-byte value. Refer to this link for compatibility details. Four Byte File Numbering
- target - The key value whose record offset is to be changed.
- recbyt8 - The new record offset.
UpdateRecordOffsetForKey() can be used with an index that allows duplicates. Notice that, in the case of duplicates, the target key value must also include the 4-byte or 8-byte record offset at the end of the key because an index that allows duplicates stores the offset as part of the key. As a low-level function, it's most useful for an index that is managed only using low-level functions. Calling UpdateRecordOffsetForKey() on a key whose index has an ISAM-level mapping with a data file (meaning the data and index file were opened at the ISAM level), the function fails with error FMOD_ERR.
Return
NO_ERROR (0) on success, or a non-zero c-tree error code on failure.
If the specified key value doesn't exist in the index, the function returns error INOT_ERR (101).
If the specified index file has an ISAM mapping to a data file, the function returns error FMOD_ERR (48).
USERINFOX
Track user information for each connection.
Declaration
NINT USERINFOX(pUSRINFX pusrinfx);Description
In V11.6 and later, FairCom Server tracks the following statistics for each connection:
- disk read operations
- disk read bytes
- disk write operations
- disk write bytes
- data cache requests
- data cache hits
- index cache requests
- index cache hits
Note that USERINFOX() also returns the connection information for the calling connection.
Compatibility Note: This feature does not introduce any compatibility issues, however a new client library and new server are required to use the USERINFOX() function. If the new client library is used to connect to an old server, a call to the USERINFOX() function fails with error 170. The behavior of the existing USERINFO() function is unchanged.
USRINFX structure definition:
typedef struct userinfoxprm {
UCOUNT StructVersion; /* [IN] Version of this structure. */
UCOUNT TaskId; /* [IN,OUT] On input, set to the task ID of the
connection whose information is to be returned,
or set it to zero to return the information for
all connections. On output, this field is set to
the number of entries that were written to the
output buffer. */
ULONG UserInfoLength; /* [IN] Size of one connection info entry. */
ULONG OutBufferSize; /* [IN,OUT] On input, set to the size of the
output buffer. On output, holds the number of
bytes written to the output buffer. If the
required size is too small, the function returns
error code VBSZ_ERR and sets OutBufferSize to
the size required to hold information for all
of the connections. */
pTEXT pOutBuffer; /* [OUT] Buffer where the connection info is
returned. */
} USRINFX, *pUSRINFX;
Return Values
| Value | Symbolic Constant | Explanation |
|---|---|---|
| 0 | CTDBRET_OK | Successful operation. |
See c-tree Plus Error Codes for a complete listing of valid c-tree Plus error values.
Example
int call_USERINFOX (void)
{
pUSRPRFX pupx = NULL;
pUSRPRFX spx;
USRINFX uix;
ULONG outbuflen = 16 * sizeof(USRPRFX);
NINT rc,i;
retry:
/* Allocate output buffer. */
if (!(pupx = (pUSRPRFX) calloc(1,outbuflen))) {
rc = UALC_ERR;
goto err_ret;
}
/* Set structure version. */
uix.StructVersion = USERINFOX_VERS_V01;
/* Set size of information structure. */
uix.UserInfoLength = sizeof(USRPRFX);
/* Get info for all connections. */
uix.TaskId = 0;
/* Set output buffer. */
uix.pOutBuffer = (pTEXT) pupx;
/* Set size of output buffer. */
uix.OutBufferSize = outbuflen;
rc = USERINFOX(&uix);
if (rc) {
if (rc == VBSZ_ERR) {
if (uix.OutBufferSize <= outbuflen) {
/* Unexpected */
rc = PBAD_ERR;
goto err_ret;
}
outbuflen = uix.OutBufferSize;
free(pupx);
pupx = NULL;
goto retry;
}
goto err_ret;
}
/* Loop over connection info entries: */
for (i = 0, spx = (pUSRPRFX) uix.pOutBuffer; i < uix.TaskId; i++, spx++) {
/* spx points to the connection info for the ith entry. */
}
err_ret:
if (pupx) {
free(pupx);
}
return(rc);
}See Also
- ctstat -userinfox option
USERLIST
Track user information for each connection.
Declaration
CTERR USERLIST(pCOUNT pc);Description
pc - Pointer to an array of type COUNT. You must allocate this array. Make it large enough to hold the maximum allowed connections to your server plus 1. The function will fill this array with task IDs of connected users. The first element is set to the size of the list. I.E. if there are 27 users, there will be 28 items in the array. The first number (element 0) will be 27 followed by 27 task IDs (elements 1-27).
USERLIST() fills out a passed in array of task IDs (of type COUNT) for users connected to the server. The first element is the number of users or the length of the list. The function returns any errors it hits or 0 on success. For each task ID in the list you can call USERINFO() (USERINFOX, USERINFOX) to get additional information about that connected user.
Return Values
| Value | Symbolic Constant | Explanation |
|---|---|---|
| 0 | CTDBRET_OK | Successful operation. |
See c-tree Plus Error Codes for a complete listing of valid c-tree Plus error values.
Example
#include "ctreep.h" /* c-tree Plus Application Header File */
#ifdef PROTOTYPE
pTEXT elapsed(LONG ct, LONG ut, pTEXT buf)
#else
pTEXT elapsed(ct, ut, buf)
LONG ct, ut;
pTEXT buf;
#endif
{
LONG sec;
if (ut && ut != -1L && ct >= ut) {
sec = (ct - ut) % 60;
ut = (ct - ut) / 60L;
sprintf(buf, "%3d:%02d", ut, sec);
}
else
ctrt_strcpy(buf, " – ");
return(buf);
}
#ifdef PROTOTYPE
NINT main(NINT argc, pTEXT argv[])
#else
NINT main(argc, argv)
NINT argc;
TEXT argv[];
#endif
{
COUNT clist[USRLSTSIZ];
USRPRF ui;
NINT i;
COUNT RetVal;
LONG curtim;
TEXT buf1[16], buf2[16];
if (argc != 4)
{
printf("c-treeACE Users List Utility\n");
printf("Usage:\n");
printf("%s <server_name> <user_name> <password>", argv[0]);
exit(1);
}
#ifdef ctTHRDS
if (ctThrdInit(3, 0L, NULL) != 0)
{
printf("Unable to initialize threading\n");
exit(1);
}
#endif
printf("Getting users connected to %s...\n", argv[1]);
RetVal = InitISAMXtd(16, 16, 16, 16, 0, argv[2], argv[3], argv[1]);
if (RetVal)
{
printf("Error %d connecting to server\n", RetVal);
}
else
{
if (USERLIST(clist))
{
printf("Could not get list of attached clients\n");
}
if (clist[0] == 0)
{
printf("No clients attached\n");
}
printf("Task::UserID::NodeName::Open Files::Logon Time::Tran Time::Rqst Time::Rqst#\n");
for (i = 1; i <= clist[0]; i++)
{
if (USERINFO(clist[i], &ui) || !ui.ulogtim)
continue;
curtim = ui.ucurtim;
printf("%d::%s::%s::%d::disappointed:%s)::disappointed:%s)::disappointed:%s) %s::%d %s\n", ui.utaskid, ui.uname, ui.unodnam, ui.unbrfil, elapsed(curtim, ui.ulogtim, buf1), elapsed(curtim, ui.utrntim, buf1), elapsed(curtim, ui.urqstim, buf2), (ui.uactflg ? "InProcess" : "NoRequest"), ui.urqstfn, ui.urqst);
}
printf("\n");
CloseISAM();
printf("Session Completed.");
}
#ifdef ctTHRDS
ctThrdTerm()
#endif
}
See Also
- ctstat -userinfox option
UserLogEntry
Allows a user specified message to be written to the transaction logs.
Short Name
TRANUSR()
Declaration
The function declaration is as follows:
LONG UserLogEntry(FILNO filno, LONG poshw, LONG poslw, LONG offset,
LONG attribute, pVOID buffer, VRLEN bufsiz)Description
In V12 the file number typedef was formally changed from COUNT, a two-byte value to FILNO, a four-byte value. Refer to this link for compatibility details. Four Byte File Numbering
UserLogEntry() returns the low-order word of the transaction number associated with the log entry. A return value of zero indicates an error and uerr_cod contains the error number. The high-order word of the transaction number is returned by a call to ctGETHGH() after a successful call to UserLogEntry().
- filno specifies a user file number or -1 if no file number.
- poshw, poslw, and offset specify three 4-byte integers to be used as desired. By convention, poshw and poslw are the high and low-order words of a file position, and offset specifies the number of bytes this file position is from the beginning of a logical record. However there is no restriction on how the user interprets these three words.
-
attribute specifies a 4-byte integer stored in the tranatr word of the TRANDSC structure. It is intended to permit the user to specify the type of user log entry. There are two restrictions:
- The highest order three bits of the 4-byte integer cannot be used. Error BMOD_ERR () will result otherwise.
- If the attribute is an even integer, then the log entry is part of the user’s existing transaction, is subject to transaction save points, and may not appear in the log unless and until TRANEND() is called.
- If the integer is odd, then the log entry is not part of a transaction, and it is assigned its own "transaction" number and is written immediately into the log buffer.
- buffer points to an optional variable-length portion of the log entry. Its contents are completely arbitrary.
-
bufsiz is the length of buffer. It should be zero if buffer is NULL. It is not permitted to exceed a configurable limit. If bufsiz exceeds the limit, a PBAD_ERR (749) occurs. The limit prevents a malicious program from "swamping" the log. The server configuration keyword
MAX_USER_LOG_ENTRY_BYTES < maximum number of bytes in variable region>
overrides the default limit of 16KB.
uTFRMKEY
Undo key segment translation to target key.
Short Name
uTFRMKEY()
Type
ISAM function
Declaration
pTEXT uTFRMKEY(FILNO keyno, pVOID tarptr)Description
In V12 the file number typedef was formally changed from COUNT, a two-byte value to FILNO, a four-byte value. Refer to this link for compatibility details. Four Byte File Numbering
uTFRMKEY() undoes reversible key transformation, meaning it can reverse the TransformKey() transformations where possible. For example, an INTSEG() transformation can be undone but an uppercase conversion such as UREGSEG() transformation cannot be undone.
Return
uTFRMKEY() returns a pointer to the translated target key. Since the translation is performed in place, the return value is always equal to the target parameter, unless there is an error. A NULL value is returned if there is an error, and the value of isam_err will be:
| Value | Symbolic Constant | Explanation |
|---|---|---|
| 80 | BKEY_ERR | tarptr is null or keyno is out of range. |
| 199 | NSCH_ERR | Segment mode requires a schema map. |
| 433 | SSCH_ERR | File referenced by schema-based segment is not defined. |
See c-tree Error Codes for a complete listing of valid c-tree error values.
See also
CurrentISAMKey(), BuildKey(), TransformKey()