FUPDATE [ KSAM/3000 Reference Manual ] MPE/iX 5.0 Documentation
KSAM/3000 Reference Manual
FUPDATE
INTRINSIC NUMBER 4
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 Figure 4-13 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 same size 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.
_____________________________________________________________________
| |
| $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); |
_____________________________________________________________________
Figure 4-13. FUPDATE Example
________________________________________________________________________________
| |
| 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; |
________________________________________________________________________________
Figure 4-13. FUPDATE Example (continued)
__________________________________________________________________________
| |
| <<***********************************************>> |
| <<* 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|
__________________________________________________________________________
Figure 4-13. FUPDATE Example (continued)
MPE/iX 5.0 Documentation