HPlogo KSAM/3000 Reference Manual: HP 3000 MPE/iX Computer Systems > Chapter 4 USING KSAM FILES IN SPL PROGRAMS

FUPDATE

» 

Technical documentation

Complete book in PDF
» Feedback

 » Table of Contents

Updates the contents of a logical record in a KSAM file.

 

             IV   LA   IV 

   FUPDATE(filenum,target,tcount); 

The FUPDATE intrinsic can be used to update a logical record in a KSAM file. The entire record including primary and any alternate keys can be updated with FUPDATE. The record to be updated is the record last referenced by the intrinsics FREAD, FREADBYKEY, FFINDBYKEY, or FPOINT. The new values for the record are moved from the user's stack into this record. The file containing this record must have been opened with the aoption parameter of FOPEN set to update access. FUPDATE can be used to update both fixed-length and variable-length records. FUPDATE can be used to modify key values or to change record size, but if key values or the record size are changed, the update operation causes the entire record to be deleted and then rewritten. After an update, a subsequent call to FREAD will read the next record in ascending key sequence after the record just written.

FUPDATE checks only the logical record pointer, not the chronological pointer, in order to determine which record to update. Therefore, if you want to update a record based on its chronological position, precede the call to FUPDATE by a call to FPOINT. FPOINT locates the record by its record number and sets the logical, as well as the chronological, pointer. If you try to locate a record for FUPDATE by calling FREADDIR or FREADC, which only set the chronological pointer, the wrong record will be updated.

If the file was opened for shared access (aoptions bits 8,9 = 11), then you must call FLOCK to lock the, file before calling FUPDATE. Note that the file must also have been opened with dynamic locking allowed (aoptions bit 10 = 1).

PARAMETERS

filenum

integer by value (required)

A word identifier supplying the file number of the file to be updated.

target

logical array (required)

Contains the record to be written in the updating.

tcount

integer by value (required)

An integer specifying the number of words or bytes to be written from the record. If this value is positive, it signifies words; if it is negative, it signifies bytes. If tcount is less than the recsize parameter associated with the record, only the first tcount bytes or words are written.

CONDITION CODES

CCE

Request granted.

CCG

An end-of-file condition was encountered during updating.

CCL

Request denied because of an error, such as tcount exceeds the record size defined for the KSAM file; or tcount does not include all the keys; or a disc input/output error.

SPECIAL CONSIDERATIONS

Split stack calls permitted.

USING FUPDATE

In order to update a record in a KSAM file, you must open the file for update. This access mode is specified by setting bits 12 through 15 of the FOPEN aoptions parameter to the octal value 5 (binary value 0101). You must then access the record to be updated. Normally, you would read the record with one of the read intrinsics and then modify the record just read.

The record to be updated by FUPDATE is the last record accessed. FUPDATE writes the contents of a user buffer area (target) over the existing contents of the last record accessed. The record written by FUPDATE must contain all the key values expected by the file. If only a portion of the record is specified by a tcount parameter less than the original record size, then this portion must contain all primary and alternate key values or a CCL condition is returned and the update does not take place.

The example in Title not available shows an update of an alternate key, the telephone number located in bytes 21 through 28 of the record. In order to locate the record to be updated, FREADBYKEY is executed before FUPDATE. The data input through the standard input device contains the keylocation and keyvalue values for FREADBYKEY as well as the new value for the update:

 

   byte  | 0 1 | 2                             21 | 22          29 | 

         |-----|----------------------------------|----------------| 

         |     |                                  |                | 

         |     |             name                 | phone number   | 

         |-----|----------------------------------|----------------| 

            ^                          ^                  ^ 

            |                          |                  | 

          keylocation                 keyvalue            new value 

         (starting byte)        (primary key)       (alternate key) 

Note that bytes are numbered from zero in the standard input or output device, but bytes in the KSAM record are numbered starting from 1 for the keylocation parameter.

SHARED ACCESS.

When access is shared, it is essential to lock the file with a call to FLOCK before rewriting any records. After the update, you should unlock the file with FUNLOCK. To make sure you are updating the correct record, include both the intrinsic that locates the record and FUPDATE between the same pair of FLOCK and FUNLOCK intrinsics.

For example, suppose you use FREADBYKEY to examine the record to be updated, you should lock the file before calling the intrinsic that locates the record to be updated and unlock if after the update:

 

   FLOCK 

   FREADBYKEY (or FFINDBYKEY) <----------- locate record to be updated

   .

   .

   .

   FUPDATE <------- update record 

   FUNLOCK <----------- all key buffers, data buffers and control information written to disc 

If you perform operations on a record between locating it and updating it, and you do not want to lock the file during this process (between the read and the update), then you can use the following code sequence:

 

   FLOCK 

   FREADBYKEY (or FFINDBYKEY) <----- locate record 

   FUNLOCK 

   . 

   . <----------------- while you decide whether to update record, 

   .                           other users can modify or delete it 

   (decide to update) 

   FLOCK 

   FREADBYKEY (or FFINDBYKEY) <----------- reread record 

   FUPDATE 

   FUNLOCK 

UPDATING RECORDS WITH DUPLICATE KEYS.

If you want to sequentially update all the records in a chain of records with duplicate keys, locate the first record in the chain with FFINDBYKEY, FREADBYKEY, or FPOINT. Then call FUPDATE to modify this record. If no key value (the selected key or any other) is modified, subsequent calls to FUPDATE will modify the next sequential records in the chain of records with duplicate keys. If, however, any key has been changed, the modified key is written to the end of the chain and the next sequential record is one with the next higher key value. In this case, to update all records with duplicate keys, precede each call to FUPDATE with a call to FFINDBYKEY, FREADBYKEY, or FPOINT to position to the beginning of the chain.

If you are in the middle of a duplicate key chain and FUPDATE modifies a key value, you can position back to the next duplicate key in the chain with the following sequence of calls:

 

   FSPACE(FILNUM,1); <-------- position to next sequential record 

   FGETINFO(FILNUM,,,,,,,,,RECPTR); <--------------- retrieve current record number 

   FSPACE(FILNUM,-1); <--------------- backspace to current record 

   FUPDATE(FILNUM,OUTPUT,-72); <------------ modify key, positioning to end of key chain 

   . 

   . 

   . 

   FPOINT(FILNUM,RECPTR); <-------- position to next duplicate key using record number 

                        retrieved by FGETINFO 

Note that if the KSAM file has fixed-length records or if the updated record is the samesize as the old record, the space in the data file is reused. Otherwise, the updated record is written to the end of the data file.

Figure 4-13 FUPDATE Example

 



$CONTROL MAIN=JEXAMPL8 

<<******************************************************>> 

<<*                                                    *>> 

<<*                     EXAMPLE 8                      *>> 

<<*        UPDATE A RECORD IN A KSAM FILE              *>> 

<<*                                                    *>> 

<<******************************************************>> 

INTEGER FILUM; 

INTEGER ERRORCODE; 

INTEGER LENGTH; 

BYTE ARRAY FILNAME (0:9);="JEXAMPLE "; 

ARRAY MESSAGE(0:35); 

ARRAY INPUT(0:39); 

ARRAY OUTPUT(*)=INPUT; 

BYTE ARRAY OUTPUTB(*)=OUTPUT; 

BYTE ARRAY INFO(0:35); 

ARRAY INFOW(*)=INFO; 

BYTE ARRAY KEYVALUE(*)=INFO(2); 

INTEGER KEYLOCATION; 

INTRINSIC FOPEN,FCLOSE,FUPDATE,FREADBYKEY,READ,PRINT, 

          BINARY,FCHECK,FERRMSG,TERMINATE; 

<<************************>> 

<<* OPEN THF KSAM FILE   *>> 

<<************************>> 

FILNUM:=FOPEN(FILNAME,3,5); <<OPEN THE KSAM FILE FOR UPDATE>> 

IF FILNUM=0 

THEN BEGIN <<CANNOT OPEN KSAM FILE>> 

       MOVE MESSAGE:="CANNOT OPEN KSAM FILE"; 

       PRINT(MESSAGE,-21,0); 

       FCHECK (FILNUM,ERRORCODE); <<GET ERROR NUMBER>> 

       FERRMSG(ERRORCODE,MESSAGE,LENGTH);<<CONVERT TO STRING>> 

       PRINT(MESSAGE,-LENGTH,0); <<PRINTOUT ERROR MESSAGE>> 

       TERMINATE; 

     END; 

<<***********************************************>> 

<<* READ IN KEYVALUE AND KEYLOCATION INFOMATION *>> 

<<***********************************************>> 

L1: 

READ(INFOW,-36); 

IF > 

THEN BEGIN 

       FCLOSE(FILNUM,0,0,); <<CLOSE THE KSAM FILE>> 

       IF <> THEN 

          BEGIN 

            MOVE MESSAGE:="CANNOT CLOSE THE KSAM FILE"; 

            PRINT (MESSAGE,-26,0); 

            FCHECK(FILNUM,ERRORCODE); <<GET ERROR NUMBER>> 

            FERRMSG(ERRORCODE,MESSAGE,LENGTH);<<CONVERT TO STRING>> 

            PRINT(MESSAGE,-LENGTH,0); <<PRINTOUT ERROR MESSAGE>> 

          END 

       TERMINATE; 

     END; 

IF < 

THEN BEGIN 

       MOVE MESSAGE:="ERROR OCCURRED WHILE READING INPUT"; 

                  PRINT(MESSAGE,-34,0); 

                  TERMINATE; 

               END;

PRINT(INFOW,-36,0); <<TEST READ>> 

KEYLOCATION:=BINARY(INFO,2); <<CONVERT FROM ASCII TO BINARY>> 

<<*****************************************************>> 

<<* READ KSAM ACCORDING TO KEYVALUE AND KEYLOCATION   *>> 

<<*****************************************************>> 

FREADBYKEY(FTLNUM,INPUT,-72,KEYVALUE,KEYLOCATION); 

IF <> 

THEN BEGIN <<ERROR OCCUPRED IN FREADBYKEY>> 

       MOVE MESSAGE:="ERROR OCCUPRED IN FREADBYKEY"; 

       PRINT(MESSAGE,-28,0); 

       FCHECK(FILNUM,ERRORCODE); <<GET ERROR NUMBER>> 

       FERRMSG(ERRORCODE,MESSAGE,LENGTH);<<CONVERT TO STRING>> 

       PRINT(MESSAGE,-LENGTH,0); <<PRINTOUT ERROR MESSAGE>> 

       GO TO L1; 

     END; 

<<**********************************************>> 

<<*       UPDATE THE RECORD JUST READ          *>> 

<<**********************************************>> 

MOVE OUTPUTB(20):=INFO(22),(8); 

FUPUATE(FILNUM,OUTPUT,-72); 

IF <> 

THEN BEGIN 

       MOVE MESSAGE:="ERROR OCCURRED DURING UPDATE"; 

       PRINT(MESSAGE,-28,0); 

       FCHECK(FILNUM,ERRORCODE); <<GET ERROR NUMBER>> 

       FERRMSG(ERRORCODE,MESSAGE,LENGTH);<<CONVERT TO STRING>> 

       PRINT(MESSAGE,-LENGTH,0); <<PRINTOUT ERROR MESSAGE>> 

       TERMINATE; 

     END; 



<<***********************************************>> 

<<* PRINT THE RECORD JUST UPDATED               *>> 

<<***********************************************>> 

PRINT(OUTPUT,-72,0); 

<<***********************************>> 

<<* GO BACK TO GET ANOTHER RECORD   *>> 

<<***********************************>> 

GO TO L1; 

END; 



Output from Program Execution: 





           read from $STDIN 

          /  

         /                     /updated record

        /                     / 

01WHITE GORDON 428-2498      / 

WHITE GORDON 428-2498 4350 ASHBY AVE. BERKELEY CA. 91234 

01ECKSTEIN LEO 263-2464 

ECKSTEIN LEO 263-2464 5303 STEVENS CREEK SANTA CLARA CA. 95050 
Feedback to webmaster