Large Object Support

In this section:

LOB Data Types

LOB Retrieval

LOB Buffer Size (BLIM)

In the server, support for BLOBs and CLOBs has been provided. A BLOB is a market-recognized term for data that an RDBMS can store in binary format. Typically, BLOBs are image or sound representations. A CLOB is a term for a fixed or variable character string greater than 256 bytes. The CLOB data type undergoes the CCSID translation for National Language Support (NLS), which a BLOB does not.

LOB data type support:

Some restrictions may apply to the processing of LOB data types. See the iWay Server Administration manual for your specific platform for more information.


Top of page

LOB Data Types

When an EDAFETCH is issued against a row that contains LOB data types, a 16-byte handle will represent the data. Actual LOB data will not be retrieved with the EDAFETCH; instead, an EDAFIELD should be issued to retrieve the data. For more information, see EDAFETCH and EDAFIELD: Storing Fields in a Designated Data Area.

Note: Before the EDAFIELD( ) call was introduced, BLOB/CLOB write-support was done by the use of RPCs to buffer up data. This method is considered deprecated, but is still supported and documented.


Top of page

LOB Retrieval

The nature of LOB data types is such that their retrieval cannot always be completed in a single operation. Retrieval of a row containing an LOB data type will return only a handle for the LOB value.


Top of page

Procedure: How to Retrieve a LOB Value

  1. Issue an EDASET for EDA_VAR_COLINFO (148), providing the API with an address in the application buffer at which the API may store column value information for a particular row.

  1. Before you issue the request, issue an EDAINSPECT on EDA_VAR_SLIM (22) to determine if SLIM has been set at the server. If this is zero (0), an EDASET should be issued for this variable to set it to a positive value greater than zero (0). If a LOB data type column is returned for the request, the API will internally set the SLIM to one (1). This is required to ensure that both client and server are positioned on the same row. If an EDAFETCH is issued for a LOB data type while SLIM is set to zero (0), an EDA_INVALID_OPERATION status (-13) will be issued.

  2. After the request is sent, issue an EDAFETCH to retrieve a row. No data from the LOB columns will be returned at this point.

  3. Before you attempt to retrieve the data for a LOB, you should reference the ColInfo array to determine whether the value is null. If it is null, processing should continue without attempting to retrieve the data using EDAFIELD.

  1. A well-behaved application should never issue an EDAFIELD after the end of the LOB value. If this does occur, the API should return EDA_SUCCESS again to indicate the completion of retrieval; it will return no data.

Note: An EDAFIELD call to another column in the row (or an EDAFETCH or EDANEXT, which positions the cursor to the next row in the result set) will interrupt LOB retrieval. In the former case, retrieval must start at the beginning of the LOB; in the latter case, the LOB will no longer be available for retrieval. LOB retrieval from rows other than the current row is not available at this time.


Top of page

LOB Buffer Size (BLIM)

Example:

Increasing Chunk Size of LOB Data

Sending a File's Contents as a BLOB to Servers

Receiving the Contents of a BLOB or CLOB From Servers

Sending a BLOB to Transaction Adapters

Reference:

Usage Notes for Transaction Adapters

BLIM is a server parameter that can be used to control the buffer, or chunk size, used for retrieving LOB data. The current value for this is set at EDA_DEFAULT_BUFFER_SIZE. Unless otherwise set at the server, the BLIM is set to 1K.


Top of page

Example: Increasing Chunk Size of LOB Data

The following setting in a server profile will set the chunk size of LOB data returned to the client to 4K.

SET BLIM=4096

This setting is provided for tuning purposes and is transparent to the application fetches. See the iWay Server Administration manual for your specific platform for details.


Top of page

Example: Sending a File's Contents as a BLOB to Servers

No error checking is done in this example.

:
:
FILE * fh;
long size;
long prec;
long scale=0L;
char * buffer;
long one=1L;
long zero=0L;
long sth; /* previously filled in by EDAPREPARE as statement handle */ long dtype = EDA_BLOB_TYPE_CODE;
fh = fopen("myblob","rb");
fseek(fh,0L,SEEK_END);
size = ftell(fh); /* how big? */
buffer = malloc(size); /* get space for the file */
fread(buffer,1,size,fh); /* load the entire file */
fclose(fh); /* release resources */
prec = size;
EDAUSING(&scb,&sth,&one,
buffer, /* point to start of data */
&size, /* length opf data to send */
&dtype, /* this is a blob */
&prec,
&scale,
&one); /* this is the last parameter */
...check and process any errors...
EDAEXECUTE(&scb,&sth,&zero,&zero,NULL,&zero);
...check and process any errors...
free(buffer); /* don't free until after the execute */
:
:

Top of page

Example: Receiving the Contents of a BLOB or CLOB From Servers

   /****** routine to retrieve a blob or clob from a server *******/ 

#define MAXLOBBUF 32000

long getEdaLob(
EDA_ID *plEid, // eda context id
EDA_scb *pScb, // session control block
long lColno, // column number of lob
EDA_INFO_AREA *pInfoArea, // saved eda info area
EDA_COLINFO *pColInfo) // retrieval info area used to store
information about column

{
long lFmt,
lSize,
lRetBytes =0;
char szLobTemp[MAXLOBBUF];
EDA_INFO_AREA *edacol;
EDA_COLINFO *colinf;

edacol=pInfoArea+lColno-1;
colinf=pColInfo+lColno;

if(colinf->colInfo==EDA_COLINFO_NULL)
return(0);

/* set lob type retrieval format according to lob type */
switch(edacol->type)
{
case EDA_CLOB_TYPE_CODE:
lFmt=EDA_ALPHANUM;
break;
case EDA_BLOB_TYPE_CODE:
lFmt=EDA_BINARY;
break;
default:
printf("ERROR: Column is not of type BLOB or CLOB\n");
return(-1);
break;
}

/* if the lob size is known set it, not to exceed programs lob buffer area */
if(colinf->colAvailable)
lSize=colinf->colAvailable;
else
lSize=edacol->length;

if(lSize > MAXLOBBUF)
{
printf("LOB size %ld exceeds the maximum chuck size\n",lSize);
lSize=MAXLOBBUF;
}
else
if(lSize == 0)
{
printf("Unknown LOB size %ld\n",lSize);
lSize=MAXLOBBUF;
}

...open output stream or file...

/* get lob, may take a number of iteration, the number of iteration will */
/* depend on the lob buffer size */
do
{
memset(szLobTemp,' ',lSize); /* clear buffer */
EDAFIELD(pScb,&lColno,szLobTemp,&lSize,&lFmt);
if(pScb->status<EDA_SUCCESS) /* error */
printf("(ERR) Error Occured in EDAFIELD,status=%ld\n",pScb->status);
else
{
lRetBytes+=colinf->colRetrieved;
...send to output stream or file...
}
}while(pScb->status==EDA_TRUNCATED);

...close output stream or file...

return(lRetBytes);
}

:
:
/****** supporting routines used by getEdaLob ********/


long InitInfoArea(
EDA_ID *plEid, // eda context id
EDA_scb *pScb // session control block
:
:
{
long lStatus,
lColNo=0,
lEdaVarColinfoPtr=EDA_VAR_COLINFO_PTR;
:
:

/* save eda column metadata information */
pInfoArea=calloc((size_t)pScb->nbrcols,sizeof(EDA_INFO_AREA)));

for(lColNo=1;lColNo<=pScb->nbrcols;lColNo++,pInfoArea++)
EDAINFO(pSscb,&lColNo,pInfoArea);

:
:

/* setup colinfo area, needed for lob retrieval usage */
/* allocate memory for all columns in request in request */
/* ***PLEASE NOTE: the colinfo array must be number of columns plus 1 */
/* since colinfo is populated at offset 1 not 0 */

pColInfo=calloc((size_t)pScb->nbrcols+1,sizeof(EDA_COLINFO)));

EDASET(plEid,pScb,&lEdaVarColinfoPtr,(EDALPTR)pColInfo,&lStatus);

:
:
}

Top of page

Reference: Usage Notes for Transaction Adapters

Transaction adapters do not support EDAPREPARE. EDAUSING, however, requires a prepare statement handle (STH).

EDAUSING must use EDA_VAR_BLOB_TP (-4) for the statement handle. Only a BLOB or a CLOB may be sent as part of a transaction.

The BLOB should not be included in the EDARPC parameter buffer.


Top of page

Example: Sending a BLOB to Transaction Adapters

               :   
:
EDA_ID lEid;
EDA_scb scb;
long lStatus,
lNts=EDA_NULL_DELIM,
lParmNo=1,
lEndParm=EDA_END_PARM_LIST,
lSth=EDA_VAR_BLOB_TP,
lDbType=EDA_BLOB_TYPE_CODE,
lScale=0,
lLobSize,
char *pszRpc ="ETPBLOB";
*pszPar ="";
*pLobData ="";
:
:
...load lob data into buffer...
/* store blob */
EDAUSING(&scb,&lSth,&lParmNo,pLobData,&lLobSize,&lDbType,&lLobSize,&lScale,
&lEndParm);
/* send blob and any other non-blob parameters to EDA TP */
EDARPC(&scb,pszRpc,&lNts,pszPar,&lParSize);
:
:

Top of page

LOB Write Support via RPCs (Deprecated)

Before BLOB/CLOB support using EDAFIELD( ) existed, BLOB/CLOB support was done by using server Remote Procedure routines to buffer data for use in PREPARE and USING steps. These routines are available in Direct Passthru and Automatic Passthru modes only. They are internal server routines and are not found in any library or directory available to the server. While this method is considered deprecated, it is still supported and documented here for reference. The routine names are as follows:

BLOB
Remote Procedure Routines

 
Description

EDABS

Used to send binary image data to the server.

EDABE

Used to mark the end of the binary image.

EDABK

Used to purge the binary image from server storage.

CLOB
Remote Procedure Routines

 
Description

EDACS

Used to send character data to the server.

EDACE

Used to mark the end of the character data.

EDACK

Used to purge the character data from server storage.

For any given database, see that adapter manual as to specifics of BLOB/CLOB support.

In order to insert or update a binary image or a variable character data type, the following steps should be taken.

  1. For BLOB data only, each byte of the binary image should be converted into two bytes of hexadecimal data and stored within the client application. If the image is large, this process should be apportioned into manageable sections.

  1. The EDABS or EDACS stored procedure can be used to send sections of data to the server using the EDARPC function. On receipt of this procedure call, the server will store the data in an internal buffer. For BLOB data only, the server will convert the hexadecimal data back to binary format.

  1. When all the data from the column has been sent, the EDABE or EDACE remote procedure should be called to indicate the end of transmission. (This also marks the end of the internal buffer on the server).

  1. A statement must be prepared for the INSERT or UPDATE request using parameter markers to indicate the values to be inserted or updated.

  1. The values to be inserted or updated must be described and provided with the EDAUSING function.

  1. After the using call, the prepared statement can be executed using EDAEXECUTE as follows:

    EDAEXECUTE (scb1, 1, 0, 0, '', 0)
  2. Once the insert or update has been successfully completed and the transaction committed, the data buffer on the server should be purged using the EDABK or EDACK procedure call. For example,

    EDARPC (scb, {EDABK|EDACK}, 5, '', 0)

Note: To retrieve BLOB/CLOB data types for some databases, a SET CONVERSION LONGCHAR BLOB/CLOB must be issued before any CLOB EDACS, EDACE, or EDACIS, or BLOB EDABS, EDABE, or EDABIS usage. The set may be issued as a EDAFOCUS call, part of an EDARPC to a "set-up" procedure, or in a server profile. See the relevant adapter manual for requirements.


iWay Software