File control

The file control classes - IccFile, IccFileId, IccKey, IccRBA, andIccRRN - allow you to read, write, update and delete records in files.In addition, IccFileIterator class allows you to browse through all the records in a file.

An IccFile object is used to represent a file. It is convenient, but not necessary, to use an IccFileId object to identify a file by name.

An application program reads and writes its data in the form of individual records. Each read or write request is made by a method call. To access a record, the program must identify both the file and the particular record.

VSAM (or VSAM-like) files are of the following types:

KSDS
Key-sequenced: each record is identified by a key - a field in a predefined position in the record. Each key must be unique in the file.

The logical order of records within a file is determined by the key. The physical location is held in an index which is maintained by VSAM.

When browsing, records are found in their logical order.

ESDS
Entry-sequenced: each record is identified by its relative byte address (RBA).

Records are held in an ESDS in the order in which they were first loaded into the file. New records are always added at the end and records may not be deleted or have their lengths altered.

When browsing, records are found in the order in which they were originally written.

RRDS file
Relative record: records are written in fixed-length slots. A record is identified by the relative record number (RRN) of the slot which holds it.

Reading records

A read operation uses two classes - IccFile to perform the operation and one of IccKey, IccRBA, and IccRRN to identify the particular record, depending on whether the file access type is KSDS, ESDS, or RRDS.

The readRecord method of IccFile class actually reads the record.

Reading KSDS records

Before reading a record you must use the registerRecordIndex method of IccFile to associate an object of class IccKey with the file.

You must use a key, held in the IccKey object, to access records. A 'complete' key is a character string of the same length as the physical file's key. Every record can be separately identified by its complete key.

A key can also be 'generic'. A generic key is shorter than a complete key and is used for searching for a set of records.The IccKey class has methods that allow you to set and change the key.

IccFile class has methods isReadable, keyLength, keyPosition, recordIndex, and recordLength, which help you when reading KSDS records.

Reading ESDS records

You must use a relative byte address (RBA) held in an IccRBA object to access the beginning of a record.

Before reading a record you must use the registerRecordIndex method of IccFile to associate an object of class IccRBA with the file.

IccFile class has methods isReadable, recordFormat, recordIndex, and recordLength that help you when reading ESDS records.

Reading RRDS records

You must use a relative record number (RRN) held in an IccRRN object to access a record.

Before reading a record you must use registerRecordIndex method of IccFile to associate an object of class IccRRN with the file.

IccFile class has methods isReadable, recordFormat, recordIndex, and recordLength which help you when reading RRDS records.

Writing records

Writing records is also known as "adding records". This topic describes writing records that have not previously been written. Writing records that already exist is not permitted unless they have been previously been put into 'update' mode. See Updating records for more information.

Before writing a record you must use registerRecordIndex method of IccFile to associate an object of class IccKey, IccRBA, or IccRRN with the file. The writeRecord method of IccFile class actually writes the record.

A write operation uses two classes - IccFile to perform the operation and one of IccKey, IccRBA, and IccRRN to identify the particular record, depending on whether the file access type is KSDS, ESDS, or RRDS.

If you have more than one record to write, you can improve the speed of writing by using mass insertion of data. You begin and end this mass insertion by calling the beginInsert and endInsert methods of IccFile.

Writing KSDS records

You must use a key, held in an IccKey object to access records. A 'complete' key is a character string that uniquely identifies a record. Every record can be separately identified by its complete key.

The writeRecord method of IccFile class actually writes the record.

IccFile class has methods isAddable, keyLength, keyPosition, recordIndex, recordLength, and registerRecordIndex which help you when writing KSDS records.

Writing ESDS records

You must use a relative byte address (RBA) held in an IccRBA object to access the beginning of a record.

IccFile class has methods isAddable, recordFormat, recordIndex, recordLength, and registerRecordIndex that help you when writing ESDS records.

Writing RRDS records

Use the writeRecord method to add a new ESDS record. After writing the record you can use the number method on the IccRBA object to discover the assigned relative byte address for the record you have just written.

IccFile class has methods isAddable, recordFormat, recordIndex, recordLength, and registerRecordIndex that help you when writing RRDS records.

Updating records

Updating a record is also known as "rewriting a record". Before updating a record you must first read it, using readRecord method in 'update' mode. This locks the record so that nobody else can change it.

Use rewriteRecord method to actually update the record. Note that the IccFile object remembers which record is being processed and this information is not passed in again.

For an example, see code fragment: "Read record for update".

The base key in a KSDS file must not be altered when the record is modified. If the file definition allows variable-length records, the length of the record can be changed.

The length of records in an ESDS, RRDS, or fixed-length KSDS file must not be changed on update.

For a file defined to CICS® as containing fixed-length records, the length of record being updated must be the same as the original length. The length of an updated record must not be greater than the maximum defined to VSAM.

Deleting records

Records can never be deleted from an ESDS file.

Deleting normal records

The deleteRecord method of IccFile class deletes one or more records, provided they are not locked by virtue of being in 'update' mode. The records to be deleted are defined by the IccKey or IccRRN object.

Deleting locked records

The deleteLockedRecord method of IccFile class deletes a record which has been previously locked by virtue of being put in 'update' mode by the readRecord method.

Browsing records

Browsing, or sequential reading of files uses another class - IccFileIterator. An object of this class must be associated with an IccFile object and an IccKey, IccRBA, or IccRRN object. After this association has been made the IccFileIterator object can be used without further reference to the other objects.

Browsing can be done either forwards, using readNextRecord method or backwards, using readPreviousRecord method. The reset method resets the IccFileIterator object to point to the record specified by the IccKey or IccRBA object.

Examples of browsing files are shown in page Code fragment "List all records in assending order of key" .

Example of file control

This sample program demonstrates how to use the IccFile and IccFileIterator classes. The source for this sample can be found in the samples directory (see Sample source code) in file ICC$FIL. Here the code is presented without any of the terminal input and output that can be found in the source file.

#include "icceh.hpp"
#include "iccmain.hpp"

The first two lines include the header files for the Foundation Classes and the standard main function which sets up the operating environment for the application program.

const char* fileRecords[] =
{
   //NAME          KEY  PHONE     USERID
   "BACH, J S      003  00-1234   BACH      ",
   "BEETHOVEN, L   007  00-2244   BEET      ",
   "CHOPIN, F      004  00-3355   CHOPIN    ",
   "HANDEL, G F    005  00-4466   HANDEL    ",
   "MOZART, W A    008  00-5577   WOLFGANG  "
};

This defines several lines of data that are used by the sample program.

void IccUserControl::run()
{

The run method of IccUserControl class contains the user code for this example. As a terminal is to be used, the example starts by creating a terminal object and clearing the associated screen.

     short        recordsDeleted = 0;
     IccFileId    id("ICCKFILE");
     IccKey       key(3,IccKey::generic);
     IccFile      file( id );
     file.registerRecordIndex( &key );
     key = "00";
     recordsDeleted = file.deleteRecord();

The key and file objects are first created and then used to delete all the records whose key starts with "00" in the KSDS file "ICCKFILE". key is defined as a generic key having 3 bytes, only the first two of which are used in this instance.

     IccBuf       buffer(40);
     key.setKind( IccKey::complete );
     for (short j = 0; j < 5; j++)
     {
         buffer = fileRecords[j];
         key.assign(3, fileRecords[j]+15);
         file.writeRecord( buffer );
     }

This next fragment writes all the data provided into records in the file. The data is passed by means of an IccBuf object that is created for this purpose. setKind method is used to change key from 'generic' to 'complete'.

The for loop between these calls loops round all the data, passing the data into the buffer, using the operator= method of IccBuf, and thence into a record in the file, by means of writeRecord. On the way the key for each record is set, using assign, to be a character string that occurs in the data (3 characters, starting 15 characters in).

     IccFileIterator fIterator( &file, &key );
     key = "000";
     buffer = fIterator.readNextRecord();
     while (fIterator.condition() == IccCondition::NORMAL)
     {
         term->sendLine("- record read: [%s]",(const char*) buffer);  
         buffer = fIterator.readNextRecord();
     }

The loop shown here lists to the terminal, using sendLine, all the records in ascending order of key. It uses an IccFileIterator object to browse the records. It starts by setting the minimum value for the key which, as it happens, does not actually exist in this example, and relying on CICS to find the first record in key sequence.

The loop continues until any condition other than NORMAL is returned.

    key = "\xFF\xFF\xFF";
    fIterator.reset( &key );
    buffer = fIterator.readPreviousRecord();
    while (fIterator.condition() == IccCondition::NORMAL)
    {
        buffer = fIterator.readPreviousRecord();
    }

The next loop is nearly identical to the last, but lists the records in reverse order of key.

    key = "008";
    buffer = file.readRecord( IccFile::update );
    buffer.replace( 4, "5678", 23);
    file.rewriteRecord( buffer );

This fragment reads a record for update, locking it so that others cannot change it. It then modifies the record in the buffer and writes the updated record back to the file.

    buffer = file.readRecord();

The same record is read again and sent to the terminal, to show that it has indeed been updated.

    return;
}

The end of run, which returns control to CICS.

See Appendix C. Output from sample programs for the expected output from this sample.

[[ Contents Previous Page | Next Page Index ]]