get considerations for file I/O

In the context of file I/O that does not involve databases, the EGL get statement retrieves record data from a file.

The data that you retrieve goes into the record variable you specify in the statement, and the exact behavior of the statement depends on the way you have stereotyped your record variable.

Syntax

Syntax diagram for get with file I/O
positionOption
For relative and serial records, the only positional keyword available is next; see the "get next" sections for the specific record stereotypes in this topic. For indexed records, the previous keyword is also available. See "get previous with indexed records" in this topic.
recordVariable
Name of the record variable into which the data is copied.
forUpdate
Option to hold the record for a subsequent delete or replace.

CSV record

The only forms of the get statement that you can use when you specify a record with the CSVRecord stereotype are get next for single variables and get for arrays.

If the current record is the first you are reading from the file, EGL checks the labels property for the record. If the property does not have a null value, EGL performs the following actions:
  1. Reads the first row of data from the file.
  2. Breaks the row into strings based on the value of the delimiter property for the record. If there are more strings than fields in the record, EGL ignores the extra strings. Missing fields remain null.
  3. Clears the labels array and repopulates it with the strings from step 2.

EGL then reads the next row from the file, breaking it down into separate strings based on the value of the delimiter property. If there are more strings than fields in the record, EGL ignores the extra strings.

Finally, EGL uses the strings to update the fields in the record. EGL uses the existing conversion rules to convert the strings to the appropriate values. EGL expects "true" and "false" as values for a BOOLEAN field; case is ignored. If no string corresponds to a particular field, that field receives a null value.

You can specify an array of records with the get statement. If the array has a null value, EGL creates a new one. If the array is not null, EGL re-initializes it to an empty array. It will keep the original value of its maxSize property. While more data remains in the file and the array is not full, EGL performs the following actions:
  1. Creates a new array element (a CSVRecord).
  2. Uses the get next statement to read the next record.
  3. Converts the strings in the row and stores them in the record fields, as above.
  4. Appends the record to the end of the array.

The I/O error status of the array is set to noRecordFound if the file is empty (no rows were read, the size of the array is zero). The I/O error status is set to endOfFile if the entire file was read into the array.

EGL closes the file after it finishes reading.

Indexed record

When you issue a get statement that references a record with the IndexedRecord stereotype, the key value in the record determines the record to be retrieved from the file.

If you want to replace or delete an indexed record, you must first use a get statement to read the record, specifying the forUpdate option. Then use the replace or delete statement, with no intervening I/O operation against the same file. After you issue the get statement, the effect of the next I/O operation on the same file is as follows:
  • If the next I/O operation on the same EGL record is a replace statement, the record is changed in the file.
  • If the next I/O operation on the same EGL record is a delete statement, the record in the file is marked for deletion.
  • If the next I/O operation on the same EGL record is a get statement, and that statement includes the forUpdate option, a subsequent replace or delete statement is valid on the newly read file record.
  • If the next I/O operation on the same EGL record is a get statement (with no forUpdate option) or is a close statement on the same file, the file record is released without change.

The get statement (with the forUpdate option) prevents other programs from changing the record; for more information, see "Compatibility" in this topic.

get next with indexed records

A get next statement that specifies an indexed record reads the next record from the file, based on the current file position, which is set by either of these operations:
  • A successful input or output (I/O) operation such as a get statement, another get next statement, or a get previous statement.
  • A set statement with a position modifier.
The following rules apply:
  • When the file is not open, the get next statement reads a record with the lowest key value in the file.
  • Each subsequent get next statement reads a record that has the next highest key value in relation to the current file position. The situation for duplicate keys is also described in this topic.
  • After a get next statement reads the record with the highest key value in the file, the next get next statement results in the EGL error value endOfFile.
  • The current file position is affected by any of these operations:
    • An EGL set statement with a position modifier establishes a file position based on the set value, which is the key value in the indexed record that is referenced by the set statement. The subsequent get next statement that references the same indexed record variable reads the file record that has a key value equal to or greater than the set value. If no such record exists, the result of the get next is endOfFile.
    • A successful I/O statement other than a get next statement establishes a new file position, and the subsequent get next statement issued against the same EGL record reads the next file record. For example, after a get previous statement reads a file record, the get next statement either reads the file record with the next-highest key or returns endOfFile.
    • If a get previous statement returns endOfFile, the subsequent get next statement retrieves the first record in the file.
    • After an unsuccessful get, get next, or get previous statement, the file position is undefined and must be re-established by a set statement with a position modifier or by an I/O operation other than a get next or get previous statement.
  • When you use an alternate index and duplicate keys are in the file, the following rules apply:
    • Retrieval of a record with a higher-valued key occurs only after get next statements have read all the records that have the same key as the most recently retrieved record. The order in which duplicate-keyed records are retrieved is the order in which EGL returns the records.
    • The EGL error value duplicate is not set when your program retrieves the last record in a group of records containing the same key.
    • If a get next follows a successful I/O operation other than a get next, the get next statement skips over any duplicate-keyed records and retrieves the record with the next higher key.
Consider a file in which the keys are as follows:
  1, 2, 2, 2, 3, 4

Each of the following tables illustrates the effect of running a sequence of EGL statements on the same indexed record.

Table 1. Effect of get and get next statements on indexed records
EGL statement (in order) Key in the indexed record Key in the file record retrieved by the statement EGL error value
get 2 2 (the first of three) duplicate
get next any 3 --

Table 2. Effect of set position and get next statements on indexed records
EGL statement (in order) Key in the indexed record Key in the file record retrieved by the statement EGL error value
set position 2 no retrieval --
get next any 2 (the first of three) duplicate
get next any 2 (the second) duplicate
get next any 2 (the third) --
get next any 3 --

get previous with indexed records

When a get previous statement operates on an indexed record, the effect is based on the current file position, as with the get next statement. The following rules apply to an indexed record:
  • When the file is not open, the get previous statement reads a record with the highest key value in the file.
  • Each subsequent get previous reads a record that has the next lowest key value in relation to the current file position. The situation for duplicate keys is described later.
  • After a get previous statement reads the record with the lowest key value in the file, the next get previous statement results in the EGL error value endOfFile.
  • The current file position is affected by any of these operations:
    • An EGL set statement with a position modifier establishes a file position that is based on the set value, which is the key value in the indexed record that is referenced by the set statement. A subsequent get previous statement that references the same indexed record reads the file record that has a key value equal to or less than the set value. If no such record exists, the result of the get previous statement is endOfFile.
      If the set value is filled with hexadecimal FF, the result of a set position statement is as follows:
      • The set statement establishes a file position after the last record in the file
      • If a get previous statement is the next I/O operation, the generated code retrieves the last record in the file
    • A successful I/O statement other than a get previous statement establishes a new file position, and a subsequent get previous statement that references the same EGL record variable attempts to locate a record relative to the new position.
    • If a get next statement returns endOfFile, the subsequent get previous statement retrieves the last record in the file.
    • After an unsuccessful get, get next, or get previous statement, the file position is undefined and must be re-established by a set position statement or by an I/O operation other than a get next or get previous statement.
  • When you use an alternate index and duplicate keys are in the file, the following rules apply:
    • Retrieval of a record with a lower-valued key occurs only after get previous statements have read all the records that have the same key as the most recently retrieved record. The order in which duplicate-keyed records are retrieved is the order in which EGL returns the records.
    • The EGL error value duplicate is not set when your program retrieves the last record in a group of records that contain the same key.
    • If a get previous follows a successful I/O operation other than a get previous, the get previous statement skips over any duplicate-keyed records and retrieves the record with the next lower key.
Consider a file in which the keys in an alternate index are as follows:
  1, 2, 2, 2, 3, 4

Each of the following tables illustrates the effect of running a sequence of EGL statements on the same indexed record.

Table 3. Effect of get and get previous statements on indexed records
EGL statement (in order) Key in the indexed record Key in the file record retrieved by the statement EGL error value
get 3 3 --
get previous any 2 (the first of three) duplicate
get previous any 2 (the second) duplicate
get previous any 2 (the third) --
get previous any 1 --
get previous any -- endOfFile

Table 4. Effect of set position and get previous statements on indexed records
EGL statement (in order) Key in the indexed record Key in the file record retrieved by the statement EGL error value
set position 2 -- --
get next any 2 (the first) duplicate
get next any 2 (the second) duplicate
get previous any 1 --
get previous any -- endOfFile

Table 5. Effect of set position and get previous statements on indexed records
EGL statement (in order) Key in the indexed record Key in the file record retrieved by the statement EGL error value
set position 1 -- --
get previous any 1 --
get previous any -- endOfFile

get with relative records

When you use a get statement with a relative record variable, the record number field that is associated with the record determines the record to be retrieved from the file. The record number field must be available to any function that uses the record and can be any of the following fields:
  • A field in the same record.
  • A field in a record that is global to the program or is local to the function that runs the get statement.
  • A variable that is global to the program or is local to the function that runs the get statement.
If you want to replace or delete a relative record, you must issue a get statement for the record that includes the forUpdate option, and then issue the replace or delete statement, with no intervening I/O operation against the same file. After you issue the get statement, the effect of the next I/O operation on the same file is as follows:
  • If the next I/O operation on the same EGL record is a replace statement, the record is changed in the file.
  • If the next I/O operation on the same EGL record is a delete statement, the record in the file is marked for deletion.
  • If the next I/O operation on the same EGL record is a get statement, and that statement includes the forUpdate option, a subsequent replace or delete is valid on the newly read file record.
  • If the next I/O operation is a get statement on the same EGL record (with no forUpdate option) or is a close statement on the same file, the file or record is released without change.

get next with relative records

When you use a get next statement with a relative record, the effect is based on the current file position, which is set by a successful input or output (I/O) operation such as a get statement or another get next statement. The following rules apply:
  • When the file is not open, the get next statement reads the first record in the file.
  • Each subsequent get next reads a record that has the next highest record number value in relation to the current file position.
  • A get next does not return noRecordFound if the next record is deleted. Instead, the get next skips deleted records and retrieves the next record in the file.
  • The current file position is affected by any of these operations:
    • A successful I/O statement other than a get next establishes a new file position, and a subsequent get next that references the same EGL record attempts to locate a record based on the new file position.
    • After an unsuccessful get or get next statement, the file position is undefined and must be re-established by an I/O operation other than a get next statement.
  • After a get next statement reads the last record in the file, the next get next statement results in the EGL error values endOfFile and noRecordFound.

get next with serial records

The get statement is not available for serial records.

When a get next statement operates on a serial record, the effect is based on the current file position, which is set by another get next statement. The following rules apply:
  • When the file is not open, the get next statement reads the first record in the file.
  • Each subsequent get next statement reads the next record.
  • After a get next statement reads the last record, the subsequent get next statement results in the EGL error value endOfFile.
  • EGL closes and reopens the file whenever the program changes from writing to reading or from reading to writing the file. For example, EGL closes the file if you use an add statement to write to a serial record and then use a get next statement to read data from the same file. An add that follows a get next statement adds a record to the beginning of the file. A get next statement that follows an add statement reads the first record in the file. This behavior also occurs when the get next and add statements are in different programs, and one program calls another.
It is recommended that you avoid having the same file open in more than one program at the same time.

Example

The following example shows how to read a record from an indexed file:
  myCustomer CustomerRecord;          // create record variable
  myCustomer.customerNumber = 1001;   // set key in record variable

  try
    get myCustomer;
  onException(fileErr FileIOException)
    myErrorHandler(fileErr);  // exits the program
  end

Feedback