INFORMIX
DataBlade Developers Kit User's Guide
Chapter 5: Programming DataBlade Module Routines in C
Home Contents Index Master Index New Book

Code Generated for Opaque Type Support Routines

BladeSmith generates code for opaque type support routines, as described in the following subsections:

The following subsections describe the code BladeSmith generates for each routine and modifications you might need to make to the generated code.

Text Input/Output Functions

Text input/output functions convert between the textual representation of an opaque type and the internal format (the C structure). BladeSmith generates complete C code for these functions.

The generated code uses a default text representation, a string containing all members of the structure, delimited with spaces. Strings are enclosed in single quotation marks ('). Large objects are represented as external filenames enclosed in quotation marks. The input function calls the sscanf() C library function. Use character representations for these types that sscanf() recognizes.

For example, the Circle DataBlade module defines a Pnt data type with two mi_double_precision members, x and y. The Circ.h header file contains the following structure definition:

The default text representation for the Pnt data type is as follows:

x and y are character strings that sscanf() can convert to double-precision values. For example, the following statement inserts a Pnt value into a table, using the default text representation:

Text Input Function

The text input function has two parameters: an mi_lvarchar pointer, which points to the text that is to be converted, and an MI_FPARAM pointer, which is not used by the generated code.

The text input function returns a pointer to a filled-in C structure for the Pnt data type. The contents of this structure are written to the database table. The function allocates memory for the opaque type it returns, as follows:

The database server frees the allocated memory.

Next, the function scans the text string, obtaining a value for one structure member at a time, as follows:

This code calls the Gen_sscanf() utility function, which BladeSmith adds to each generated C source file.

Finally, the text input function returns a pointer to the completed C structure, as follows:

To use an input text format different from the default format, or if the C structure contains data types that BladeSmith cannot scan with Gen_sscanf(), you must modify the generated text input function code.

If you want an input text format that is different than the default, replace the generated code with your own. For example, you can choose to delimit values with commas instead of spaces. Your code might be able to call the Gen_sscanf() function, or you might need to write your own scanning function.

In the Circle DataBlade module, the text representation of the Pnt data type is changed from the default format:

to this format:

To support the new format, Gen_sscanf() calls in the PntInput() function are modified to include the parentheses and comma in the format string, as shown in the following code:

Text Output Function

The text output function takes a pointer to the opaque type structure and an MI_FPARAM pointer, and returns a text representation of the data type in an mi_lvarchar value. BladeSmith operates under the assumption that the text representation is a string containing character representations of all of the structure members delimited with spaces. The function encloses strings and filenames for large objects in quotation marks.

If you change the text input function to support a different text format than the default, also change the text output function. The string returned by the text input function must be a valid string for the text output function.

The generated text output function computes the maximum length of the string it returns and calls mi_new_var() to allocate an mi_lvarchar variable, Gen_RetVal. The database server frees the allocated memory later.

The function calls the C standard library function sprintf() once for each structure member to write the value and a space in the data area pointed to by the Gen_OutData parameter. The following code shows the sprintf() calls from the generated PntOutput() function in the Circle DataBlade module:

Between calls to sprintf(), the function resets Gen_OutData to point to the end of the string.

To change the text representation of the opaque type or to optimize the code, you can modify the code BladeSmith generates for the text output function. The text representation must match the representation used for the text input function.

For example, to support the new text representation for the Pnt data type, the parentheses and comma are added to the sprintf() calls in the PntOutput() function, as follows:

Binary Send/Receive Functions

The binary send/receive functions translate opaque types sent to and received from clients. The functions are needed to adjust data types for differing byte order and alignment requirements on the client and server computers. The functions call the mi_put and mi_get DataBlade API functions to transform individual members of the opaque type structure.

Binary Send Function

The database server calls the binary send function with a pointer to an mi_sendrecv type, which contains the opaque type structure and an MI_FPARAM pointer. The binary send function allocates an mi_sendrecv variable to hold another opaque data structure. Then it fills in the members of the new structure with values from the input structure, adjusted for the client machine architecture.

The function calls mi_put DataBlade API functions to store the client representation of the data type in the structure to be returned to the database server. The following code, taken from the Circle DataBlade module CircSend() function, calls mi_put_double_precision() to store values from an input Circ data type (addressed by Gen_InData) to an output Circ data type (addressed by Gen_OutData):

Binary Receive Function

The Informix database server calls the binary receive function with an mi_sendrecv pointer and an MI_FPARAM pointer. The mi_sendrecv pointer contains the address of the opaque structure. The function returns a pointer to an opaque structure, for which it allocates memory. The database server frees this memory later.

The binary receive function calls mi_get DataBlade API functions to retrieve values for each structure member from the input received from the client. The following code, from the Circle DataBlade module CircReceive() function, calls mi_get_double_precision() to retrieve three double-precision values and store them in the Circ stucture:

Text File Import/Export Functions

The Informix database server calls text file import/export functions when using bulk copy to transfer opaque type values between a database and an external file.

Text File Import Function

The database server calls the text file import function with a pointer to an mi_impexp type containing the input text, which it retrieves from an external file, and an MI_FPARAM pointer.

The text file import function converts the text to an instance of the opaque type and returns a pointer to it.

The text file import function allocates memory for the opaque structure that it returns and then calls Gen_sscanf() for each member of the structure, storing the scanned values in the allocated memory. If the data type contains a large object handle data type (MI_LO_HANDLE), the input contains the large object filename in quotation marks. The text file import function calls Gen_LoadLOFromFile() to retrieve the large object data from the external file.

The default format for imported text is the same as for the input function: a string containing each structure member, delimited with spaces. If you use a different text representation for your data type, you can modify the format strings in the Gen_sscanf() calls.

Text File Export Function

The database server calls the text file export function with a pointer to an instance of the opaque type and an MI_FPARAM pointer, which is not used by the generated code. The text file export function converts the opaque type value to a text value stored in an mi_lvarchar variable that it allocates. The generated code works the same way as the text file output function.

The function computes the maximum length of the text value it can return by adding the maximum lengths for each structure member. Then it calls mi_new_var() to allocate an mi_impexp variable large enough to hold the largest possible text value.

To create the output text, the function calls sprintf() once for each member of the opaque type structure, concatenating a text representation of the value to the string in the mi_impexp variable. Each value is followed by a space.

The default text file export function is the same text representation as the input and import functions. This format allows database users to enter values for the opaque type and enables opaque types to be displayed. For bulk copy operations, however, a user-readable format is not necessary.

To conserve space in the external file or to match the representation required by some another application that uses the export file, you can use a different text representation for bulk copy. When you modify the text representation that the text file export function uses for copy-out operations, make corresponding modifications in the text file import function.

Binary File Import/Export Functions

The Informix database server calls binary file import/export functions during bulk copy to transfer opaque type values in binary format between external files and a database.

If you define binary file import/export functions, BladeSmith generates code that calls DataBlade API mi_put and mi_get functions to build a binary image of the opaque type C structure in the client format.

Binary File Import Function

The Informix database server calls the binary file import function with an mi_bitvarying pointer containing the binary representation of an opaque type value, read from an external file. The function also receives an MI_FPARAM pointer, which is not used by the code that BladeSmith generates for this function.

The binary file import function translates the binary data in the mi_bitvarying structure into an instance of the opaque type and returns a pointer to the C structure. The BladeSmith-generated code allocates memory for the return structure and then calls DataBlade API mi_get functions to retrieve a value for each member of the structure. If the opaque type includes large objects, the function calls Gen_LoadLOFromFile() to read the large object data from a file.

Binary File Export Function

The Informix database server calls the binary file export function with a pointer to an mi_lvarchar value, which contains an instance of the opaque type, and an MI_FPARAM pointer. The function translates the opaque type value into a binary image and returns it in an mi_bitvarying variable. The Informix database server writes the returned binary value into external files.

The binary file export function calls mi_new_var() to allocate an mi_bitvarying variable and then calls an mi_put function for each element of the opaque structure to store the value. If the opaque type includes large objects, the generated code calls Gen_StoreLOToFile() to save the large object data in an external file.

Assign/Destroy Routines

The Informix database server calls an Assign function when storing an opaque type on disk. The database server calls a Destroy procedure when removing an opaque type from disk. These two routines allow you to perform special processing associated with the creation and destruction of opaque types. For example, if your opaque type includes large objects, create Assign/Destroy routines to manage the large object references.

Important: If you use text input/output functions for large objects, you must define Assign/Destroy routines to prevent runtime errors from the database server.
BladeSmith generates Assign and Destroy routines that manage large object reference counts. For other types of special processing, you must add code to the generated code.

Assign Function

The Informix database server calls the Assign function with a pointer to an instance of an opaque type and a pointer to an MI_FPARAM structure. The function returns a pointer to the opaque type to the database server. Usually, the pointer returned by the Assign function is the same one the Informix database server passed to it. If the Assign function alters the input opaque type in any way and returns a pointer to it, the database server stores the modified value in the database.

The generated Assign function manages large object reference counts. It calls mi_lo_validate() to determine if a valid large object exists and mi_lo_increfcount() to increment the reference count for the large object.

Destroy Procedure

The Informix database server calls the Destroy procedure before removing an opaque type from the database. It passes the Destroy procedure a pointer to the opaque type value that is about to be removed from the database, and an MI_FPARAM pointer. The procedure returns no value.

The Destroy procedure calls mi_lo_validate() for each large object. For valid large objects, it calls mi_lo_decrefcount() to decrement the reference count for the large object.

LOhandles Function

The Informix database server calls the LOhandles function to retrieve a list of large object handles used by an opaque type. The LOhandles function receives a pointer to the opaque type and a pointer to an MI_FPARAM structure.

The LOhandles function returns a pointer to an mi_bitvarying variable containing an MI_LO_HANDLES structure. BladeSmith defines MI_LO_HANDLES in the generated header file; it is not part of the DataBlade API. The structure holds a list of MI_LO_HANDLE structures. It has the following definition:

The LOhandles function calls mi_lo_validate() for each large object in the opaque type structure, accumulating a count of valid large objects. If there are no valid large objects in the opaque type, the function returns 0 to its caller.

If the opaque type contains valid large objects, the function:

    1. allocates an mi_bitvarying variable to hold the MI_LO_HANDLES structure.

    2. copies valid large object handles into the los array in the MI_LO_HANDLES structure.

    3. sets the MI_LO_HANDLES nlos member to the number of large objects in the array.

    4. returns a pointer to the MI_LO_HANDLES structure.

Comparison Functions

The Informix database server calls DataBlade module comparison functions to compare two opaque type values. For example, database users can compare opaque values in SQL statements. If you want to support B-tree indexes on an opaque type, you must provide an additional set of comparison functions.

Compare Function

The Compare function compares the values of the members of two opaque types. BladeSmith generates a complete Compare function for an opaque type. The generated code compares each member of the opaque type C structure, in the order defined in the structure. The Compare function returns:

For example, the Circle DataBlade module defines a Pnt data type as follows:

The Compare function generated for the Pnt type first compares the two values of x, then the two values of y.

For types such as mi_boolean, which cannot be compared for relative magnitude, the function returns +1 if the values differ. If all structure members are equal, it returns 0.

The algorithm used to generate the Compare function cannot evaluate the semantic content of an opaque type. Therefore, for many opaque types, replace the generated code with more appropriate code.

B-Tree Comparison Functions

The Informix database server calls the following additional comparison functions when constructing B-tree indexes for opaque data types:

Important: The Equal function is required if you develop a DataBlade module using Microsoft Visual Basic.
For these functions, BladeSmith generates code that calls the Compare function described in the previous section. For example, the Equal function generated for the Matrix2d type calls the Matrix2dcompare() function, as follows:

You do not have to modify these generated functions.

R-Tree Comparison Functions

Spatial data types are usually represented by opaque data types that store coordinates in k-dimensional space. An R-tree index is organized on the spatial relationships of the values. A parent node in the index stores a value that represents the union of all of the values in its child nodes.

For more information on R-tree functions, see the Informix Developer Network Web site at http://www.informix.com/idn.

If you choose to support R-tree indexes for spatial data types, BladeSmith generates the following functions:

Mathematic Functions

If you choose to support mathematic functions for an opaque type, BladeSmith generates the following functions:

The Plus, Minus, Times, Divide, and Concat functions are binary; they take two pointers to the opaque types that are to be operated upon and an MI_FPARAM pointer. The Positive, Negate, and Hash functions are unary; they take one pointer to an opaque type and an MI_FPARAM pointer. All of the functions return pointers to an opaque type structure that is the result of the operation.

BladeSmith does not generate code to perform these mathematic operations. It sets the return value to 0 in the generated code. To implement these functions, call mi_alloc() to allocate memory for the return structure, perform the necessary calculations, and return a pointer to the result structure. The database server frees the allocated memory when it has finished processing the result.

See Extending INFORMIX-Universal Server: Data Types for more information on these functions.




DataBlade Developers Kit User's Guide, version 3.6
Copyright © 1998, Informix Software, Inc. All rights reserved.