ISAM File Statements

ISAM #ch, code, key

Parameters

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

 

Error processing

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.

 

File Locking

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

 

Examples

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