ISAM #ch, code, key
ch (Num) [in]
Channel number specified in the OPEN statement for the file. Note that a single channel is used for the combination of the IDA and the primary IDX. Secondary IDX files have their own channels.
key (String) [in/out]
A symbolic key
code (Num) [in]
A numeric code 1-8 indicating the operation to perform.
Code |
Operation |
Description |
1 |
Lookup |
Searches the IDX file associated with CH for the specified KEY. If not found, returns ERF(ch) = 33. Else returns ERF(ch) = 0 and sets the relative record number variable (from the OPEN statement) to match the found record. |
2 |
Get Next |
Performs a get-next operation based on index position left by the previous 1, 2, or 7 statement. Sets the relative record number variable to match the fund record. Sets ERF(ch) to 38 if no more keys in sequence. KEY is not used. Generally superseded by code 7. |
3 |
Add Key |
Adds the specified key to the index, associating it with the record number currently stored in the record number variable. |
4 |
Delete Key |
Deletes the specified key from the index. |
5 |
Add Record |
Allocates/assigns a new record in the IDA file, returning its relative record number in the record number variable. Must be followed by a WRITE{L} #ch, rec statement to actually write the record data to the file. |
6 |
Delete Record |
Deletes the record specified by the relative record number variable from the IDA file (adding it back to the deleted record chain so that it may be reused). |
7 |
Get Next |
Same as code 2 except returns the found next key in the KEY variable. |
8 |
Get Previous |
A-Shell extension, added in 6.1.1344.0. Reverse of code 7. Returns ERF(ch) = 38 if no more keys (i.e. when you hit the start of the index). |
Each of the ISAM statements returns a status which you should check using the ERF(ch) function. The range of values is given in the table below:
ERF(ch) value |
Meaning |
32 |
Illegal ISAM statement code |
33 |
Key not found during key lookup |
34 |
Duplicate key during attempt to add key. Note that duplicate keys not supported by ISAM 1.x. |
35 |
IDX is corrupted and must be recreated. |
36 |
IDX file full. You've disabled the auto-expand feature (see NOAUTOX option), the disk is full, or you've reached the maximum limit of 4 billion IDX blocks. |
37 |
IDA file full. You've disabled the auto-expand feature (see NOAUTOX), the disk is full, or you've reached the maximum limit of 4 billion records.) |
38 |
End of file reached during get-next key operation, or start of file reached during get-previous key operation |
39 |
Illegal ISAM sequence. See File Locking below. |
You must employ some kind of file locking system when allowing multi-user access to ISAM files (i.e. when the files are opened in INDEXED rather than INDEXED'EXCLUSIVE mode). Unlike ISAM-A, ISAM 1.x provides you the latitude (and responsibility) to implement the locking system. However, when LOKSER is enabled, it will be used and certain rules will be enforced (with violations resulting in ERF(ch) returning error 39). The following table summarizes the ISAM /LOKSER behavior and rules:
Stmt Code |
Operation |
Primary IDX |
Secondary IDX |
1, 2, 7, 8 |
Locate record by key |
Locked automatically and remains locked on return |
Locked automatically during operation but unlocked on return |
3 |
Add key |
Must be locked initially (typically from a previous locate record operation). Unlocked on return |
Locked automatically during operation; unlocked on return |
4 |
Delete Key |
Must be locked initially and remains locked on return |
Locked automatically during operation; unlocked on return |
5 |
Add Data Rec |
Must be locked initially; remains locked on return |
N/A |
6 |
Delete Data Rec |
Must be locked initially; remains locked on return |
N/A |
READ |
read data |
Must be locked initially; unlocked on return |
N/A |
READL |
read/lock (for update) |
Must be locked initially; remains locked on return |
N/A |
WRITE |
write/update data |
Must be locked initially; unlocked on return. |
N/A |
WRITEL |
write new data |
Must be locked initially; remains locked on return. (Normally followed by Add Key which unlocks) |
N/A |
LOCK |
Lock primary index |
Locked by operation |
N/A |
UNLOKR |
Unlock record and/or index |
Unlocked by operation (no harm if already unlocked) |
N/A |
The following samples illustrate some typical operations on an ISAM file with a single primary IDX. For simplicity, all the examples use a generic routine called ISAM'ERROR for any unexpected errors. The routine should always start with an UNLOKR #CH to make sure the file isn't left in a locked state.
Add Record:
ISAM #CH, 1, KEY ! lookup key
IF ERF(CH) = 0 THEN
? "Record already exists"
UNLOKR #CH
ELSEIF ERF(CH) # 33 THEN ! any state other than not-found
GOTO ISAM'ERROR
ELSE
ISAM #CH, 5, KEY ! add a data record
IF ERF(CH) # 0 THEN
GOTO ISAM'ERROR
ELSE
WRITEL #CH, REC ! write the data
ISAM #CH, 3, KEY ! add the key
IF ERF(CH) # 0 THEN
GOTO ISAM'ERROR
ENDIF
ENDIF
ENDIF
Delete Record:
ISAM #CH, 1, KEY ! lookup key
IF ERF(CH) = 33 THEN
? "Record doesn't exist"
UNLOKR #CH
ELSEIF ERF(CH) # 0 THEN
GOTO ISAM'ERROR
ELSE
READL #CH, REC ! read/lock the record
ISAM #CH, 4, KEY ! delete key
IF ERF(CH) # 0 THEN
GOTO ISAM'ERROR
ELSE
ISAM #CH, 6, KEY ! delete the data record
IF ERF(CH) # 0 THEN
GOTO ISAM'ERROR
ENDIF
ENDIF
ENDIF
Read Record:
ISAM #CH, 1, KEY ! lookup key
IF ERF(CH) = 0 THEN ! if found ...
READ #CH, REC ! read rec (unlocks index)
ELSE ! else
? "Key ";KEY;" not found" !
UNLOKR #CH ! manually unlock index
ENDIF
History
2013 March, A-Shell 6.1.1344: Add new get'previous statement: ISAM #CH, 8, KEY.
2011 April, A-Shell 1211: ISAM 7 statements (get next key and return it) now support dynamic variables. They do not, however, support auto-extension of arrays. So if you want to use an auto-extend array variable, you must first initialize each element; for example,
DIMX IKEY(1),S,0,AUTO_EXTEND
...
! load ISAM keys into an auto-extending array of dynamic elements
DO WHILE ERF(CH)=0
I = I + 1
IKEY(I) = "" ! must initialize element to get auto-extension!
ISAM #CH, 7, IKEY(I)
LOOP