hcutl

Perform high-cooperative ISAM operations

WSupported on Windows
USupported on Unix

 

NSupported in Synergy .NET
hcutl [-option] -command filename

option

One or more of the following:

f

Force completion of potentially dangerous operations (for example, adding an autokey over existing data or deleting an integer key if the file header is full).

h or ?

Display help screen.

mlevel#

Specify a message level that defines the amount of information displayed during an operation, where level is a value from 0 to 2.

y

Answer “y” to all query prompts.

%

Display a running status (0 to 100) to indicate the percentage completed by the operation.

command

One or more of the following:

c

(optional) Convert the specified file(s) to high-cooperative.

e length

(optional) Extend record to the specified final length.

i

(optional) Provide high-cooperative information about a file.

ka key_spec

(optional) Add the specified key. (See key_spec below.)

kd key_spec

(optional) Delete the specified key. (See key_spec below.)

filename

The name of the ISAM file(s) on which you want to perform high-cooperative operations. The default extension is .ism. With the -c and - i commands only, you can use a wildcard (e.g., *.ism) to specify multiple files at once.

Hcutl performs high-cooperative operations such as initial data conversion, extending a record, adding a key, or deleting a key. Other programs can still access the file normally while these operations are executing.

Before you can use most of hcutl's options (anything besides -i), you may need to patch your file with isutl -p -qfile=hc to make it high-cooperative. See isutl -p for more information.

Hcutl changes only affect data files. File updates don't automatically update repositories, source code, or xfODBC catalogs, which may need separate updates depending on your setup.

Forcing operation completion

Do not use the -f option unless you're prompted to do so by a previous failed operation, and only use it if you're certain the operation won't harm the file. You'll only be prompted to retry with -f in the following circumstances:

Converting to high-cooperative

When ipar or hcutl -i determine a file to be an intermediate file, you can finish converting it using hcutl -c. For example,

hcutl -c intermedhc.ism

Once hcutl -c is run, ipar and hcutl -i will indicate the file is high-cooperative, without the “Intermediate file” message.

Note

Files with a page size of 512 or 1024 and no compression can't be converted to HC mode using hcutl.

Extending a record

The -e command requires a length specification as a safeguard against accidentally running the command more than once. For example,

hcutl -e 80 myfile.ism
Extended record size from 70 to 80

The utility updates the record size in the header and tells you the result of the operation. If the requested size is more than a 20% increase (or the value of HC_ETHRESHOLD, if it's set), you’ll be prompted to confirm that this is okay before the operation takes effect:

hcutl -e 110 myfile.ism
You are about to extend the record size of myfile.ism by 30 bytes (>20%). Do you wish to continue (Yes/No)? y
Extended record size from 80 to 110

You can skip this prompt by including the -y option in your command. For example,

hcutl -e 80 -y myfile.ism

When you extend a file’s record size, all records are immediately treated as having the new size. Existing records retain their original data, but any newly added portion is uninitialized (filled with spaces) until the record is stored or updated, at which point it is written at the full new length. As part of this change, the file’s internal storage layout is automatically recalculated to match the new record size; you can view the updated layout using the isutl -b or isutl -vb option. This recalculation affects how space from deleted records is reused and ensures normal file operation.

Because records are considered larger even before their data changes, reading a record into a buffer sized for the old record length will result in an $ERR_TOOBIG error ("Input data size exceeds destination size"). To avoid this, use a buffer large enough for either record length and query the current record size to determine which data area to use. For example,

curlen = %isinfo(filechannel, "SIZE")
reads(filechannel,buffer(1:curlen))

Getting high-cooperative information

The -i option outputs information about whether the file is already a high-cooperative file, whether it can be converted, and what high-cooperative operations are available. The following is some sample output:

hcutl -i *.ism

[changetracking.ism]
changetracking.ism is not an HC file
It cannot be directly converted to HC, as it has change tracking enabled.
Consider transferring contents to a new file.

[intermedhc.ism]
intermedhc.ism is an intermediate HC file
To finish converting, run:
        hcutl -c intermedhc.ism

[normalfile.ism]
normalfile.ism is not an HC file
To patch to HC, run:
        isutl -p -qfile=hc normalfile.ism

[segkey.ism]
segkey.ism is a full HC file
Current record length: 50
Keys defined: 2 (56 available to add)
A key can be added with keynum 2
Current keys:
        Key0: 'start=1,length=5,keynum=0'
        Key1: 'start=1:6:11:16,length=5:5:5:4,keynum=1'

Adding a key

The -ka key_spec option adds the specified key. (See key_spec below for syntax.) For example,

hcutl -ka "start=10, length=5, type=alpha, keynum=3, dups=noqual" myfile.ism

When you add a key using hcutl, the START, LENGTH, and KEYNUM keywords (or their abbreviations) are required. All other keywords are optional. Specifying KEYNUM prevents an accidental addition of the same key multiple times. If you specify a key number that's already in use, hcutl will return an error. The only valid key number is the next key in the sequence. For example, if a file has keys 0 through 5, you can add a new key with a key_num of 6.

If you include DUPS in the key specification, it must be set to NOQUAL; only non-qualified duplicates are allowed. By default (if DUPS is not included), duplicates are not permitted, and hcutl will report an error if it encounters duplicate values while building the key.

Hcutl also reports an error if it detects invalid data for the specified key type in any segment of the new key. The following values are valid:

Key type

Valid values

ALPHA, INTEGER, UNSIGNED All values
DECIMAL Decimal values
SEQUENCE, TIMESTAMP, CTIMESTAMP Existing data must consist only of spaces, integer nulls, or decimal zeros. These values are replaced with generated autokey values when the key is added.
Note

In some cases, hcutl may write autokey values to the data file before detecting invalid existing data. Although hcutl rolls back changes to the index file and leaves the file usable with its original keys, it does not undo data file updates. Before retrying the operation, you must clear both the temporary autokey values and any invalid existing data.

Building the index for a new key can take some time, and the key is not available for read operations until indexing is completed. If hcutl encounters incompatible data or is interrupted before completion, the operation will be canceled. If an incorrect key specification caused the failure, you can correct the command and rerun it. If hcutl was interrupted, run hcutl -ka to resume the previous operation. No other hcutl operations can run while a key is being added; attempting to do so will result in an error, and you may be prompted to run hcutl -ka to complete the pending operation.

key_spec

If key_spec is a single key specification or a dimensioned argument, the number of key_spec arguments or dimensions should be equal to or greater than the number specified by num_keys. A key specification in key_spec should have the following form:

START=pos_1[:pos_n], LENGTH=len_1[:len_n], KEYNUM=key_num
&     [, NAME=key_name][, TYPE=key_type_1[:key_type_n]]
&     [, ORDER=key_order_1[:key_order_n]][, DENSITY=key_density]
&     [, DUPS=NOQUAL|NODUPS][, MODIFY|NOMODIFY][, ASCEND|NOASCEND]
&     [, NULL=null_type][, VALUE_NULL=null_val]]

START=pos_1[:pos_n]

The starting position of the key or each segment of the key, starting with the first. You can specify up to eight positions, separated by colons.

LENGTH=len_1[:len_n]

The length of the key or each segment of the key. You can specify up to eight lengths, separated by colons; the number of lengths must match the number of start positions. The combined key can be up to 254 characters, depending on file type and duplicate handling:

Duplicate type

TBYTE file

Non-TBYTE file

No duplicates allowed 254 254
Qualified duplicates 250 251
Non-qualified duplicates 248 250

KEYNUM=key_num

Indicates the number of the specified key (0 for the primary key, 1 for the first alternate key, etc.) for a high-cooperative file.

NAME=key_name

(optional) The named key of reference for Synergy ISAM access. If the name contains spaces, the key name must be enclosed in quotation marks. The maximum key name length is 15 for Synergy ISAM.

TYPE=key_type_1[:key_type_n]

(optional) The type of key or segment. You can define one type for the key and all of its segments, or you can define a type for each segment. If you define the segments individually, you must include a type for every segment. See Key type for detailed information about each type.

ALPHA

Alphanumeric key (default)

NOCASE

Case-insensitive alphanumeric key

DECIMAL

Zoned decimal key

INTEGER

Native integer key

UNSIGNED

Native unsigned integer key

SEQUENCE

Automatically incremented i8 key

TIMESTAMP

i8 time key automatically generated on every record update

CTIMESTAMP

i8 time key automatically generated on a record’s initial STORE

Important

Using integer keys (INTEGER, UNSIGNED, SEQUENCE, TIMESTAMP, and CTIMESTAMP key types) in an ISAM file requires special handling when unloading and loading is performed. Due to the chance that one of these keys contains data that could be interpreted as a record terminator, unloading to a sequential (or text) file is not recommended. Instead, we recommend using the fconvert utility to generate a counted file (-oc). (See fconvert for more information and further restrictions on text files.)

ORDER=key_order_1[:key_order_n]

(optional) Defines the order of the key or the order of each key segment: DESCENDING (or D) or ASCENDING (or A).

You can define one key order for the key and all of its segments, or you can define a key order for each segment. If you define the segments individually, you must include a key order for every segment.

This value overrides the ASCEND | NOASCEND option.

DENSITY=key_density

(optional) Specifes a number between 50 and 100 that represents the density percentage for that key. (See Key density for more information and suggestions about setting the key density.) This value overrides the file density for each key for which it is specified.

DUPS=NOQUAL | NODUPS

(optional) Specifies whether duplicate keys are allowed. The default is no duplicates (NODUPS). Specifying DUPS=NOQUAL allows non-qualified duplicate keys. (See Non-qualified duplicate keys for more information.)

MODIFY | NOMODIFY

(optional) Specifies whether the key is modifiable. The default is not modifiable (NOMODIFY). The primary key cannot be modified.

ASCEND | NOASCEND

(optional) Specifies whether the key data will be sorted in ascending or descending order. The default is ascending order (ASCEND). This option is overridden by the ORDER option if it is specified.

NULL=null_type

(optional) Specifies that the key is a null key. In this context, a null key means that when a record is stored, and this key has a null value, no entry is placed in the index, thus saving file space, I/O, and processing. By default, a key is assumed to be null if it is filled with spaces. You can change this assumption using the VALUE_NULL option. The default null value is blank for alpha keys and 0 for numeric keys. You can specify null keys on alternate keys only, not on a primary key.

Null_type can be one of the following types. See Null keys for more information.

REPLICATE

Specifies that null_val is a single character and must match each byte of the specified key.

NOREPLICATE

If the key is alpha, specifies that null_val is a string that must match the key, from the beginning of the key, for the length of the string. If the key is numeric, specifies that null_val must match the numeric key value.

SHORT

Specifies that the key won’t be stored if the record doesn’t include the entire key on a STORE or WRITE. The file must have variable-length records.

VALUE_NULL=null_val

(optional) Indicates the null value for a null key, which can be specified as either a single character or a string. The default null value is a space. Enclosing the value in quotation marks is optional. For example:

"chr"       :       "0", " ", "\0"          ASCII representation
val         :       48,   32,   0           Binary representation
string      :       abc, "abc"              Nonreplicating string
numeric     :       100, "100"              Nonreplicating numeric string
Note

You can abbreviate all key options to their shortest unambiguous length (e.g., "S" for "START" or "DU=NOQ" for "DUPS=NOQUAL"). However, for program clarity and to eliminate confusion with options that may be added in the future, we recommend that you specify the full option name.

Deleting a key

The -kd option deletes the specified key. To avoid deleting a key accidentally, the START, LENGTH, and KEYNUM keywords (or their abbreviations) are required. Other keywords are valid, but they'll be ignored. For example,

hcutl -kd "start=10, length=5, keynum=3" myfile.ism

As an extra layer of security, you’ll be prompted to confirm the deletion with yes or no before the key is removed, unless you skip this prompt by specifying the -y option.

You can’t delete the primary key, only alternate keys. As soon as a key is deleted, it becomes unusable for any file I/O operations.