Large Object field processing for non-FILEORG X'100' files

From m204wiki
Revision as of 18:10, 23 July 2014 by Alan (talk | contribs)
Jump to navigation Jump to search

Overview

Model 204 Version 7.5 introduced the X'0100' switch on the FILEORG parameter which provides for a variety of extended features, including a simpler syntax for ADDing, CHANGEing and DELETEing Large Object fields (fields with a BLOB or CLOB attribute). Prior to FILEORG=X'0100', working with Large Objects requires the use of a 'universal buffer'. This page describes the universal buffer syntax, which is deprecated for X'0100' files, but required for earlier-version files that use BLOB or CLOB fields.

Data maintenance statements

Special processing necessary for pre-FILEORG X'0100' files with LOB fields is needed for:

Statement Action
ADD Place a new field-value pair on a record.
CHANGE Alter the value of fields in a record.
STORE RECORD Add a new record to a Model 204 file.

Using FOR EACH RECORD loops

The User Language data maintenance statements handle one record at a time, therefore the data maintenance statements are always part of a FOR EACH RECORD loop. The data maintenance may involve a field-value pair for the field.

Data used in examples in this topic

Each statement is discussed separately on the pages that follow. To illustrate their usage, assume that the following two records have been stored:

VIN = A99999998E VIN = X99999999Z MAKE = FORD MAKE = FORD COLOR = GREEN COLOR = RED YEAR = 88 YEAR = 04 MODEL = FOCUS MODEL = MUSTANG

ADD statement

The ADD statement adds a new occurrence of a field and/or value to a record.

Syntax

The basic format of the ADD statement is:

ADD fieldname = {value | (expression)}

Where:

fieldname identifies the field in a record.

value specifies the value you want to store.

(expression) can be used in place of value to specify the resolved value at the time of evaluation. (expression) can be a function call, string concatenation, arithmetic operation, User Language construct, or Boolean expression. The expression must be enclosed in parentheses to invoke the expression compiler; otherwise the value will be treated as a literal string.

Large Object field syntax

ADD lob-name=BUFFER,position,length [RESERVE n [BYTES]]

Where:

  • lob-name specifies the field name of the Large Object data.

    Note: you cannot use subscripts on ADD statements.

  • BUFFER specifies the Universal Buffer
  • position is a positive number specifying the offset of the first character in the buffer or Large Object data. If the position is set to a negative value, an error occurs. The position can be a %variable or a constant.
  • length is a positive number specifying the length to move. The length can be a %variable or a constant.
  • RESERVE n specifies a positive number of bytes to reserve for the Large Object field value. The number of RESERVE bytes is always greater than or equal to maximum length of Large Object.
  • BYTES, optional, specifies that n applies to bytes.

Example

BEGIN IMAGE XYZ BUFF_DATA IS STRING LEN 200 END IMAGE IDENTIFY IMAGE XYZ * add LOB field with "CURRECn" to the records: FOR EACH RECORD * enter data into image item: %XYZ:BUFF_DATA = 'CURREC' WITH $CURREC * write image on the buffer: WRITE IMAGE XYZ ON BUFFER POSITION=1 MAXLEN=200 * add LOB field from buffer contents: ADD MY.LOB.FIELD=BUFFER,1,10 RESERVE 200 BYTES END FOR * print LOB data: FOR EACH RECORD * place LOB data into the buffer: BUFFER,1,200=MY.LOB.FIELD,1,200 * place contents of the buffer into image: READ IMAGE XYZ FROM BUFFER * print LOB data that has been placed into the buffer: PRINT VIN AND %XYZ:BUFF_DATA END

This code would result in adding a large object field to each record containing the text "CURREC" followed by the internal record number and this output:

A99999998E CURREC0 X99999999Z CURREC1

Usage

For Large Object data, a compiler error is issued for ADD (and STORE) statements if the context to the right of the equal sign (=) is not a BUFFER reference.

M204.0037: INVALID SYNTAX

Large Object field syntax for CHANGE

To change large object fields with the CHANGE statement use the following syntax:

CHANGE lob-fieldname,position1,length TO BUFFER position2,length

  • lob-fieldname specifies the name of the field
  • position, position1 and position2 are positive numbers specifying the offset of the first character in the buffer or Large Object data. If position, position1, or position2 is set to a negative value, an error occurs. Any positions can be a %variable or a constant.
  • length is a positive number specifying the length to move. The length can be a %variable or a constant. The source and target lengths must be equal.

    If position plus length minus one exceeds the current length of the LOB field, the intervening bytes are filled with binary 0. If the file has FILEORG X'100' on, then any final length of the LOB field is allowed. Otherwise extending a LOB field requires that the final length must fit within the RESERVE clause length specified when the LOB field was added.

    For example, if the buffer contains "ABCDEFGHIJKL" and the field is initially stored with:

    ADD LOB.FLD=BUFFER,1,3 RESERVE 500 BYTES

    The field would contain "ABC". If it was subsequently changed as follows:

    CHANGE LOB.FLD,5,10 TO BUFFER,1,10

    The field would then contain "ABC ABCDEFGHIJ" with position 4 being a binary zero.

  • TO BUFFER specifies the Universal Buffer. You can use BUFFER only in conjunction with a Large Object field.

Example

BEGIN IMAGE XYZ BUFF_DATA IS STRING LEN 200 END IMAGE IDENTIFY IMAGE XYZ IN JUNK FOR EACH RECORD * place LOB data into the buffer: %XYZ:BUFF_DATA = 'This is the data for VIN ' WITH VIN * write image on the buffer: WRITE IMAGE XYZ ON BUFFER POSITION=1 MAXLEN=200 * change the LOB field to the contents of the buffer: CHANGE MY.LOB.FIELD,1,50 TO BUFFER,1,50 END FOR * print LOB data: FOR EACH RECORD * place LOB data into the buffer: BUFFER,1,200=MY.LOB.FIELD,1,200 * place contents of the buffer into image: READ IMAGE XYZ FROM BUFFER * print LOB data that has been placed into the buffer: PRINT VIN AND %XYZ:BUFF_DATA END

This code results in changing the large object field in each record to the text "This is the data for VIN" followed by the VIN field and this output.

A99999998E This is the data for VIN A99999998E X99999999Z This is the data for VIN X99999999Z

Usage

If you issue a CHANGE statement on a Large Object field to a record that does not contain the field, nothing happens. Unlike a non-Large Object field, a new occurrence of the field is not added to the record.

Extending a LOB field requires that the final length must fit within the RESERVE clause length specified when the LOB field was added.

Note: You cannot change the number of RESERVE bytes. Furthermore, facilities are not available to delete a portion of data or to insert data: for example, to replace 10 bytes with 25 bytes within Large Object data. When an attempt to insert or delete data is made the following error message is issued:

M204.2693: SOURCE AND TARGET LENGTH MUST BE EQUAL

All Large Object data implicitly has the contiguous characteristic. A User Language procedure can store some amount of initial data and then extend the data up to the RESERVE number of bytes with subsequent CHANGE statements. For example:

FR * add initial 10 bytes: ADD LOB.FLD=BUFFER,1,10 RESERVE 200 BYTES * add increments of 10 bytes at * positions 11, 21, 31, 41 * moving data from the buffer to the field FOR %X FROM 1 TO 4 %Y = %X WITH '1' CHANGE LOB.FLD,%Y,10 TO BUFFER,%Y,10 END FOR PAI PRINT 'LOBLEN' AND $LOBLEN(LOB.FLD) END


STORE RECORD syntax for Large Object fields

Binary Large Objects — fields defined with a BLOB or CLOB attribute (often referred to collectively as LOBs) — are stored in Table E, and they can hold content longer than the 255 limit of regular Model 204 fields. They are useful for holding blocks of text, images, documents, etc. Prior to the Model 204 Version 7.5 introduction of X'0100' files (see the FILEORG parameter for more information), LOB fields required a special STORE syntax referencing the "universal buffer".

As of Model 204 V7.5, LOB fields can be stored using normal STORE syntax, typically with a Longstring variable holding the content:

%myImage is longString ... store record rectype="IMAGE" name="sunset.jpg" image=%myImage end store

Prior to Model 204 V7.5, or in lieu of the X'0100' FILEORG bit being set, LOB fields require the use of the universal buffer, and special syntax to access the buffer.

STORE RECORD lob-name=BUFFER,position,length [RESERVE n [BYTES]] . . . END_STORE [label]

Where:

  • lob-name specifies the field name of the Large Object field.

    Note: you cannot use subscripts on statements for any field type.

  • BUFFER specifies the Universal Buffer
  • position is a positive number specifying the offset of the first character in the buffer. If the position is less than one, an error occurs. The position can be a %variable or a constant.
  • length is a positive number specifying the length to move. The length can be a %variable or a constant.
  • RESERVE >n specifies a positive number of bytes to reserve for the Large Object field value. The number of bytes is always greater than or equal to $LOBLEN.
  • BYTES, optional, specifies that n applies to bytes.

Examples

BEGIN STORE RECORD NAME = JEAN ANDERSON SALARY = 30000 POSITION = CHEMIST END STORE END

Using the THEN CONTINUE statement

%COLOR = 'BLUE' STORE RECORD MODEL = %MODEL THEN CONTINUE FR WHERE RECTYPE = 'TABLE' AND COLOR = %COLOR %CODE = COLOR_CODE END FOR ADD COLOR_CODE=%CODE PAI END STORE

Storing Large Object data

STORE RECORD NOVEL=BUFFER,%POSITION,%LENGTH [RESERVE n [BYTES]] AUTHOR_PIC=BUFFER,%POSITION2,%LENGTH2 END STORE

Handling Large Object data

When you store an instance of a Large Object field, the value of the data is stored in the file's Table E. Additionally, a LOB descriptor containing a pointer to the value in Table E, as well as other items, are stored in the record data in a Table B entry. The LOB descriptor is 27 bytes in length, plus the 1-byte length and 2-byte field code that apply to all fields — unless the field is preallocated. See Building a Large Object descriptor for a description of how to build a Large Object data descriptor.

The following compiler error is issued when the right side of the equal sign is expected to contain a BUFFER expression and it does not.

M204.0037: INVALID SYNTAX