


Reading and Writing Simple Large Objects to an Optical Disc
Only Universal Server and INFORMIX-OnLine Dynamic Server, on the UNIX operating system, can use optical discs.
Within a table, rows that include simple-large-object data do not include the simple-large-object data in the row itself. Instead, the simple-large-object column contains a 56-byte simple-large-object descriptor that includes a forward pointer (rowid) to the location where the first segment of simple-large-object data is stored. The descriptor can point to a dbspace blobpage, a blobspace blobpage, or a platter in an optical storage subsystem. For details, see the Administrator's Guide for your database server and the INFORMIX-OnLine/Optical User Manual.
When a simple large object is stored on a write-once-read-many (WORM) optical-storage subsystem, you can have a single physical simple large object reside in more than one table to conserve storage space on the WORM optical disc. The LOC_DESCRIPTOR flag enables you to migrate a simple-large-object descriptor, rather than the simple large object itself, from one table to another.
When you read or write a simple-large-object column that is stored on a WORM optical disc, you can manipulate only the simple-large-object descriptor if you set the loc_oflags field of the locator structure to LOC_DESCRIPTOR.
Figure 8-20 shows a code fragment that selects the stock_num, manu_code, cat_descr, and cat_picture columns from the catalog table of the named database. The program uses the DESCR() SQL function expression to retrieve the simple-large-object descriptor, rather than to retrieve the simple large object itself, for the cat_picture column. The program then sets the loc_oflags field of the cat_picture locator structure to LOC_DESCRIPTOR to signal that the simple-large-object descriptor, rather than the simple large object, is to be inserted into the cat_picture column of the pictures table. The result is that the cat_picture columns in both the catalog and pictures tables refer to a single set of physical simple large objects.
Figure 8-20
Code Fragment to Retrieve the Simple-Large-Object Descriptor
/*
* Select row from catalog table (descr() returns TEXT descriptor
* for cat_picture. For cat_descr, the actual simple LO is returned.)
*/
EXEC SQL fetch catcurs into :stock_num, :manu_code, :cat_descr,
:cat_picture;
if(err_chk("FETCH") == SQLNOTFOUND) /* end of data */
break;
/*
* Set LOC_DESCRIPTOR in loc_oflags to indicate simple-large-object
* descriptor is being inserted rather than simple-large-object data.
*/
cat_picture.loc_oflags |= LOC_DESCRIPTOR;
/*
* Insert
*/
EXEC SQL insert into pictures values (:stock_num, :manu_code,
:cat_descr, :cat_picture);
if(err_chk("INSERT") < 0)
printf("Insert failed for stock_num %d, manu_code %s", stock_num,
manu_code);
}
/* Clean up db resources */
EXEC SQL close catcurs;
EXEC SQL free catcurs;
/* Deallocate memory buffers */
free(cat_descr.loc_buffer);
free(cat_picture.loc_buffer);
EXEC SQL disconnect current;
}
/*
* err_chk() checks sqlca.sqlcode and if an error has occurred, it uses
* rgetlmsg() to display to stderr the message for the error number in
* sqlca.sqlcode.
*/
int err_chk(stmt)
char *stmt;
{
char buffer[512];
if(sqlca.sqlcode < 0)
{
fprintf(stderr, "Error: %s\n", stmt);
rgetlmsg(sqlca.sqlcode, buffer, sizeof(buffer));
fprintf(stderr, "SQL %d: ", sqlca.sqlcode);
fprintf(stderr, buffer sqlca.sqlerrm);
if (sqlca.sqlerrd[1] != 0)
{
rgetlmsg(sqlca.sqlerrd[1], buffer, sizeof(buffer));
fprintf(stderr, "ISAM %d: ", sqlca.sqlerrd[1]);
fprintf(stderr, buffer, sqlca.sqlerrm);
}
exit(1);
}
return(sqlca.sqlcode);
}
You can also use the SQL DESCR() function to achieve the same result without a loc_oflags value of LOC_DESCRIPTOR. The SQL statement shown in Figure 8-21 accomplishes the same task as the locator structure in the preceding example.

|