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

Using Generated Code

This section contains the following subsections:

Identifying the Source of Generated Code

When BladeSmith generates source code for your DataBlade module, it uses routines and data structures from various libraries.

The following table lists common prefixes for data types and routines appearing in generated DataBlade module code and lists their sources and where they are documented.
Prefix Library More Information

mi_

DataBlade API

Almost all DataBlade API routines and data types have the mi_ prefix. See the DataBlade API Programmer's Manual for more information.

Gen_

BladeSmith

All variable names and routine names not explicitly named in the project have the Gen_ prefix. See "Utility Functions Generated by BladeSmith" for more information on utility functions.

DBDK_TRACE_

BladeSmith

BladeSmith uses four macros for error handling and tracing in generated code. See "Tracing and Error Handling" for more information.

gl_

DataBlade API

The gl_dprintf() and gl_tprintf() functions are used for internationalized tracing. See the DataBlade API Programmer's Manual for more information.

ifx_gl_

GLS API

All GLS API routines have the ifx_gl_ prefix. See the GLS API Programmer's Manual for more information.

ifx_

ESQL/C

In code generated by BladeSmith, this prefix indicates routines and data types from ESQL/C. See the INFORMIX-ESQL/C Programmer's Manual for more information.

Comments in Generated Code

BladeSmith adds comments to the code it generates. Each routine begins with a prologue that describes the purpose of the routine, its parameters, and its return value. Comments throughout the code describe variable declarations and the results of generated C statements and routine calls.

In comments at the beginning and end of each generated routine, BladeSmith stores information it uses when regenerating source code. The prologue includes a routine ID. A comment at the end of the routine contains a calculated checksum.

Warning: Do not modify either of these values; BladeSmith uses them to merge your edits into the regenerated code.
BladeSmith adds a Gen_ prefix to all variable names and routine names you did not create or explicitly define in BladeSmith: for example, utility functions and the Gen_Con connection parameter.

MI_FPARAM Function Parameter Argument

Informix Dynamic Server passes a function parameter to all user-defined routines. The parameter is a pointer to an MI_FPARAM structure.

The DataBlade API provides accessor functions for the MI_FPARAM structure. The called user-defined routine can use the accessor functions to:

BladeSmith includes an MI_FPARAM argument in all routines it generates. Do not access MI_FPARAM structure members directly, because the structure may change between versions of the DataBlade API. Instead, use DataBlade API accessor functions to set and test values in the structure.

In addition to references for each of the accessor functions, the DataBlade API Programmer's Manual includes a chapter that describes the information stored in the MI_FPARAM structure and tells you how to get values from or store values in the structure and how to use the structure for creating iterative functions.

See the ExmAmortize() function in the Business example DataBlade module for an example of using the MI_FPARAM structure in an iterative function.

Server Connection Handle

BladeSmith calls mi_open() at the beginning of many of the routines it generates. The mi_open() call obtains a database server connection handle, which is a required argument in many DataBlade API calls. If your routine does not need a connection handle, remove the mi_open() and mi_close() functions that BladeSmith adds to your code.

Tip: If the only DataBlade API call your routine makes is to mi_db_error_raise(), you do not need a connection handle. You can pass a null value to mi_db_error_raise().
For routines running in Informix Dynamic Server address space, except the large object DataBlade API routines, the connection handle enables client and database server routines to use the same DataBlade API routines.

When mi_open() is called at the beginning of a generated routine, mi_close() is called to release the handle immediately before the routine returns.

Tracing and Error Handling

BladeSmith adds tracing and error handling code throughout the generated source code if the tracing option is set to True when you generate source code in BladeSmith.

A generated utility function, Gen_Trace(), processes all tracing and error handling. Your routines must not call Gen_Trace() directly. To perform tracing and error handling tasks, use the DBDK_TRACE macros defined in the generated header file.

This section describes:

How Tracing Works

Tracing is the process of writing status messages for routines to a file. Use tracing for debugging; tracing can generate a high volume of output, which is not appropriate for production databases.

By default, tracing is disabled whenever you start a new database session.

Each tracing message has a tracing level associated with it. When you enable tracing, you set a threshold for tracing levels. Messages with a trace level less than or equal to the threshold are written to the trace file.

Tracing messages are written to a trace file, which is created with a default name and location, or with a name and location you specify. If you remove the trace file while tracing is enabled, it is automatically re-created. The default name and location of the trace file is tmp/session_id.trc, where session_id is the four-digit identifier of the current database server session. To obtain your current session ID, use the onstat -g ses command.

Messages are written to the trace file only if you:

Trace messages include the name of the executing routine, the source filename, and the line number of the call to Gen_Trace() with the embedded parameters %FUNCTION%, %FILENAME%, and %LINENO%. For example, the following example is a portion of a log file resulting from calling the "enter routine" and "exit routine" macros, DBDK_TRACE_ENTER and DBDK_TRACE_EXIT, for the Distance function:

Important: If you want to include parameters other than %FUNCTION%, %FILENAME%, and %LINENO% in a message, you must call the gl_dprintf() function for trace messages or the mi_db_error_raise() function for error messages. For an example of calling these functions, see the Gen_Trace() function in the generated source code. See the DataBlade API Programmer's Manual for more information on using these functions.

Adding Tracing and Error Handling

To add tracing and error handling to the generated source code, edit the generated source code file and insert DBDK_TRACE macro calls.

The following table describes the tracing and error handling macros.

(1 of 2)

Macro Action (if tracing is enabled)

DBDK_TRACE_MSG()

Prints a message in the trace file.

DBDK_TRACE_ERROR()

Prints a message in the trace file and raises an error by calling mi_db_error_raise().

DBDK_TRACE_ENTER()

Prints a message in the trace file upon entering a routine.

DBDK_TRACE_EXIT()

Prints a message in the trace file upon exiting a routine.

The macros are described in the following sections. See "Setting a Trace Output File and a Trace Threshold" for information on the name and location of the trace message file.

The DBDK_TRACE_MSG() and DBDK_TRACE_ERROR() Macros
When tracing is enabled, use the DBDK_TRACE_MSG() and DBDK_TRACE_ERROR() macros to write messages to the trace message file. The DBDK_TRACE_ERROR() macro also raises an error.

If tracing is not enabled, no messages are written to the trace message file; DBDK_TRACE_ERROR() still raises an error.

The syntax for the DBDK_TRACE_MSG() and DBDK_TRACE_ERROR() macros is as follows:

For example, if you have a function called ExmAmortize and a trace message number UE001 with a trace level of 20, use the following code fragment to add tracing to the ExmAmortize function:

The DBDK_TRACE_ENTER() and DBDK_TRACE_EXIT() Macros
If you have tracing enabled and the trace threshold set to 20 or above, the DBDK_TRACE_ENTER() and DBDK_TRACE_EXIT() macros write messages to the trace file when the called routine is entered and exited, respectively. BladeSmith automatically adds these macros to generated code for every routine.

The syntax for the DBDK_TRACE_ENTER() and DBDK_TRACE_EXIT() macros is as follows:

The caller parameter specifies the name of the C routine to which you are adding the macro.

For example, if you have a routine called ExmAmortize, the following code fragment sends a message to the message file when the ExmAmortize routine is entered:

Enabling Tracing in a DataBlade Module

After you generate code with tracing and compile your code, enable tracing in your DataBlade module.

To enable tracing in your DataBlade module

    1. Create a trace class.

    2. Create the TraceSet_project procedure.

These steps are described in the following sections.

Creating a Trace Class
Tracing classes are categories of tracing that can be activated independently, allowing you to tune your tracing output to suspected problem areas.

To enable tracing in a database, you must insert the DataBlade trace class as a record in the systraceclasses system catalog.

The tracing generated by BladeSmith provides a single trace class, with the same name as your DataBlade project.

This example creates a trace class for the Business DataBlade module:

You can create your own tracing classes for customized tracing. See the DataBlade API Programmer's Manualfor more information.

Creating the TraceSet_project Procedure
The TraceSet_project procedure (where project is the name of your DataBlade module project) sets the tracing output file and the trace threshold for a database server session by calling the DataBlade API functions mi_tracefile_set() and mi_tracelevel_set().

The TraceSet_project procedure is included in generated source code by BladeSmith when you choose to generate code with tracing in the Generate DataBlade dialog box. Although the TraceSet_project procedure is included in the generated C code, the SQL statements to create it in the database are not included in the generated SQL scripts. This omission prevents end-users from accessing the TraceSet_project procedure from SQL statements.

After you install and register your DataBlade module in the database, create the TraceSet_project procedure using the following SQL statement:

project is the name of your DataBlade module.

Tip: The comments for the TraceSet_project procedure in your source code show the exact syntax to create the procedure for your DataBlade module.
The syntax for using the TraceSet_project procedure is as follows:

Enabling Tracing in a Database Session

After you enable tracing in your DataBlade module, enable tracing for the database session. By default, when you start a database server session, tracing is disabled.

To enable tracing in your DataBlade module

    1. Set the appropriate locale environment variables.

    2. Set the trace output file and the trace threshold for the current session.

These steps are described in the following sections.

Setting Your Locale
The system only displays and writes messages to your session that match the locale specified in the session environment variables. Therefore, to see your trace messages, you must set the SERVER_LOCALE environment variable to the same locale you used when you created your messages in BladeSmith.

Tip: To determine the locale for your trace message, look at its properties in BladeSmith; click the message in the project view, under the Errors folder, and choose Edit Properties. See "Error Locale" for more information.

Setting a Trace Output File and a Trace Threshold
To set the trace output file and the trace threshold, use the TraceSet_project procedure. The DBDK_TRACE_ENTER() and DBDK_TRACE_EXIT() macros provided by BladeSmith use the trace level 20.

The following example sets the filename to Business.trc in the /tmp directory and sets the threshold to 20 without changing the trace threshold:

To change the trace output file without altering the trace threshold, specify the trace threshold as -1. To change the trace threshold without altering the trace output file, do not put a filename between the quotation marks.

Standard Error Messages

BladeSmith uses a standard set of messages in the code that it generates. These messages are shared by all DataBlade modules created with BladeSmith and cannot be changed. BladeManager adds the error messages to the syserrors system catalog and the systracemsgs system catalog when a DataBlade module is registered in a database.

The messages have the same text and error numbers in the two system tables, except that messages in the systracemsgs system table include the text "(%FILENAME%, %LINENO%)" after the %FUNCTION% parameter to ensure that the source filename and line number appear in the trace file.

The following table lists the standard U.S. English DataBlade module error messages.

Error Number Message Text

UGEN1

Connection has failed in %FUNCTION%.

UGEN2

Memory allocation has failed in %FUNCTION%.

UGEN3

Error creating large object from client file in %FUNCTION%.

UGEN4

Large object handle is invalid in %FUNCTION%.

UGEN5

Error creating large object from client file in %FUNCTION%.

UGEN6

Error saving large object to client file in %FUNCTION%.

UGEN7

Double-quoted string expected in %FUNCTION%.

UGEN8

Interval format conversion has failed in %FUNCTION%.

UGEN9

Input string is not terminated with double-quote in %FUNCTION%.

UGENA

Input string is too long in %FUNCTION%.

UGENB

Input data format error in %FUNCTION%.

UGENC

Output LO file creation has failed in %FUNCTION%.

UGEND

Entering function %FUNCTION%.

UGENE

Successfully existing function %FUNCTION%.

UGENF

The collection could not be created in %FUNCTION%.

UGENG

Insertion into the collection has failed in %FUNCTION%.

UGENH

Invalid iterator state used in %FUNCTION%.

The generated header file defines constants ERRORMSG1 through ERRORMSG17 for these error numbers.

You can define additional messages used in your DataBlade module. Define them in the BladeSmith project to ensure that they are loaded into the database when your DataBlade module is registered. See "Contacting the Informix Registry" for information about reserving error codes for your DataBlade module.

Utility Functions Generated by BladeSmith

BladeSmith generates support functions that it calls from other generated code. These functions include:

Most of the generated utility functions are called by code that BladeSmith generates, and you typically do not use them in your code. The Gen_sscanf() utility function, however, can be useful in your input/output functions. You can use the Gen_IsMMXMachine() function if you use Intel MMX instructions in your code.

The Gen_sscanf() Utility Function

The Gen_sscanf() utility function scans one value from an input string and stores it at a given address. Gen_sscanf() returns a pointer that points just past the value it scanned from the input string.

Gen_sscanf() takes the following parameters:
Gen_Con

The database connection handle

Gen_Caller

The name of the calling function

Gen_InData

A pointer to the text to be scanned

Gen_InDataLen

An integer containing the length of the text (mi_lvarchar strings are not null-terminated)

Gen_Width

An integer containing the maximum data length for text data

Gen_Format

A string containing a sscanf() format string for the structure member to be scanned

Gen_Result

A pointer to the member in the structure where Gen_sscanf() stores the scanned value

The generated input and import functions call Gen_sscanf() once for each structure member. Gen_sscanf() requires an input string in the current locale and uses the Informix GLS routines to scan the string.

The Gen_IsMMXMachine() Utility Function

The Gen_IsMMXMachine() utility function can be used when you include Intel MMX media enhancement technology in your DataBlade module. The function tests the processor in the database server computer to determine if it has MMX technology support. If MMX technology support is found, Gen_IsMMXMachine() returns 1.

If the database server machine does not have MMX technology support, or if the FORCE_NO_MMX environment variable is set in the database server environment, Gen_IsMMXMachine() returns 0. On UNIX machines, Gen_IsMMXMachine() always returns 0.

To execute MMX instructions when possible and to execute portable C code on computers that do not have MMX technology support, call Gen_IsMMXMachine() in an IF statement.

Gen_IsMMXMachine() declares a static INT flag, MMXType. It first looks for the FORCE_NO_MMX environment variable, which must be set in the environment before the database server is started.

If FORCE_NO_MMX is found, the function sets MMXType to 0 without testing the CPU. If FORCE_NO_MMX is not found, the function tests the processor and sets the MMXType variable to 1 if MMX technology support is found, or 0 if not. After the value of MMXType is set, Gen_IsMMXMachine() returns its value immediately, so that tests are performed once after the DataBlade module object file is loaded.




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