API Function Reference

This is the online version of the API Function Reference that is in the API Guide. The functions are listed alphabetically. However, they are gouped by category in the Function categories tables that at the beginning of this document. In these tabes, you can click a function name to jump directly to it. For each function, the document provides a description, syntax, arguments, examples of use, and cross references to related calls. Please note that in this HTML version, links to other chapters in the API Guide do not work.

This chapter is also available in HTML format in <ib_home>/HtmlRef/ApiFunctionRef.html.

Function categories

There are twelve classes of InterBase API function calls:

• Array functions for handling arrays of data

• Blob functions for handling the InterBase Blob datatype

• Database functions for handling database requests

• Conversion functions for translating dates between InterBase format and UNIX format, and for reversing the byte-order of integers

• DSQL functions for handling SQL statements entered by users at run time

• Error-handling functions

• Event functions for registering interest in events posted by triggers and stored procedures in applications and for processing the event queue

• Information functions for retrieving information about databases, transactions, Blob data, and events

• Install functions for writing silent embedded installs of InterBase.

• Security functions for adding, deleting, and modifying user records in the password database

• Services functions for administering server and database properties

• Transaction functions for handling transactions in an application

Some functions, such as information calls, occur in more than one class.

Array functions

The following table summarizes the InterBase API functions available for handling array data in an application:

Table 15.1 Array functions

Function name | Purpose
isc_array_get_slice2() | Retrieve a specified part of an array field
isc_array_lookup_bounds2() | Determine the dimensions of an array field
isc_array_lookup_desc2() | Retrieve an array description
isc_array_put_slice2() | Write a specified part of an array field
isc_array_set_desc2() | Set an array description

u Back to top

Blob functions

The following table summarizes the InterBase API functions available for handling Blob data in an application:

Table 15.2 Blob functions

Function name | Purpose
isc_blob_default_desc2() | Set a default Blob description for dynamic access
isc_blob_gen_bpb2() | Generate a Blob parameter buffer (BPB) for dynamic access
isc_blob_info() | Request information about a Blob field
isc_blob_lookup_desc2() | Retrieve a Blob description
isc_blob_set_desc2() | Set a Blob description
isc_cancel_blob() | Discard a Blob
isc_close_blob() | Close a Blob
isc_create_blob2() | Create a new Blob
isc_get_segment() | Retrieve a segment of Blob data
isc_open_blob2() | Open a Blob for read access
isc_put_segment() | Write a segment of Blob data

Database functions

The following table summarizes the InterBase API functions available for handling database requests in an application:

Table 15.3 Database functions

Function name | Purpose
isc_attach_database() | Connect to an existing database
isc_database_info() | Request information about an attached database
isc_detach_database() | Disconnect from a database
isc_drop_database() | Delete an attached database and its associated files
isc_expand_dpb() | Build a database parameter buffer (DPB) dynamically
isc_version() | Retrieve database implementation number and on-disk structure (ODS) major and minor version numbers

u Back to top

Conversion functions

The following table summarizes the InterBase API functions available for translating between InterBase DATE, TIME, and TIMESTAMP format and the UNIX date format, and for reversing the byte-order of an integer:

Table 15.4 Date and conversion functions

Function name | Purpose
isc_decode_sql_date() | Translate a date from InterBase format to C struct tm format
isc_encode_sql_date() | Translate a date from C struct tm format to InterBase format
isc_decode_sql_time() | Translate a time from InterBase format to C struct tm format
isc_encode_sql_time() | Translate a time from C tm format to InterBase format
isc_decode_timestamp() | Translate a date and time from InterBase format to C struct tm format
isc_encode_timestamp() | Translate a date and time from C struct tm format to InterBase format
isc_portable_integer() | Reverse the byte-order of an integer

Note To provide backward compatibility, the isc_encode_date() and isc_decode_date() functions are still available. They behave exactly like isc_encode_timestamp() and isc_decode_timestamp().

u Back to top

DSQL functions

The following table summarizes the InterBase API functions available for handling DSQL statements built or entered by users at run time:

Table 15.5 DSQL functions

Function name | Purpose
isc_dsql_allocate_statement() | Allocate a statement handle
isc_dsql_alloc_statement2() | Allocate a statement handle that is automatically freed on database detachment
isc_dsql_describe() | Fill in an XSQLDA with information about values returned by a statement
isc_dsql_describe_bind() | Fill in an XSQLDA with information about a statement’s input parameters
isc_dsql_execute() | Execute a prepared statement
isc_dsql_execute2() | Execute a prepared statement returning a single set of values
isc_dsql_execute_immediate() | Prepare and execute a statement without return values for one-time use
isc_dsql_exec_immed2() | Prepare and execute a statement with a single set of return values for one-time use
isc_dsql_fetch() | Retrieve data returned by a previously prepared and executed statement
isc_dsql_free_statement() | Free a statement handle, or close a cursor associated with a statement handle
isc_dsql_prepare() | Prepare a statement for execution
isc_dsql_set_cursor_name() | Define a cursor name and associate it with a statement handle
isc_dsql_sql_info() | Request information about a prepared statement

u Back to top

Error-handling functions

The following table summarizes the InterBase API functions available for handling database error conditions an application:

Table 15.6 Error-handling functions

Function name | Purpose
isc_interprete() | Capture InterBase error messages to a buffer
isc_print_sqlerror() | Display a SQL error message
isc_print_status() | Display InterBase error messages
isc_sqlcode() | Set the value of SQLCODE
isc_sql_interprete() | Capture a SQL error message to a buffer

Event functions

The following table summarizes the InterBase API functions available for handling events in an application:

Table 15.7 Event functions

Function name | Purpose
isc_cancel_events() | Cancel interest in an event
isc_event_block() | Allocate event parameter buffers
isc_event_counts() | Get the change in values of event counters in the event array
isc_que_events() | Wait asynchronously until an event is posted
isc_wait_for_event() | Wait synchronously until an event is posted

u Back to top

Information functions

The following table summarizes the InterBase API functions available for reporting information about databases, transactions, and Blob data to a client application that requests it:

Table 15.8 Information functions

Function name | Purpose
isc_blob_info() | Request information about a Blob field
isc_database_info() | Request information about an attached database
isc_dsql_sql_info() | Request information about a prepared DSQL statement
isc_transaction_info() | Request information about a specified transaction
isc_version() | Retrieve database implementation number and on-disk structure (ODS) major and minor version numbers

u Back to top

Install functions

The following table summarizes the InterBase API functions available for creating an application install routine:

Table 15.9 Install functions

Function name | Purpose
isc_install_clear_options() | Clear all options set by isc_install_set_option()
isc_install_execute() | Perform the install
isc_install_get_info() | Return requested information
isc_install_get_message() | Return the text of the requested error or warning message
isc_install_load_external_text() | Load messages from the specified file
isc_install_precheck() | Perform checks on the install environment
isc_install_set_option() | Create a handle to a list of selected install options
isc_install_unset_option() | Remove an option from a list of selected options
isc_uninstall_execute() | Remove previously installed files
isc_uninstall_precheck() | Check current system and the validity of the uninstall file

u Back to top

Licensing functions

The following table summarizes the InterBase API functions available for adding, removing, and viewing certificate ID and key pairs (authorization codes). The fifth function retrieves and displays messages associated with the return values from the other four functions.

Table 15.10 Licensing functions

Function name | Purpose
isc_license_add() | Adds a certificate ID and key pair to the InterBase license file
isc_license_check() | Checks whether the supplied ID/key pair is valid
isc_license_remove() | Removes the specified line from the InterBase license file
isc_license_display() | Copies ID/key pairs from the InterBase license file into a buffer
isc_license_get_msg() | Returns the text of an error code

u Back to top

Services functions

The following table summarizes the InterBase API functions available for programmatic control of server and database administration tasks:

Table 15.11 Service functions

Function name | Purpose
isc_service_attach() | Attach to the InterBase Services Manager facility; required before using any of the InterBase services
isc_service_detach() | End the attachment to the InterBase Services Manager
isc_service_query() | Request and retrieve information about the InterBase server to which the client is attached
isc_service_start() | Perform a service task on the InterBase server to which the client is attached

u Back to top

Transaction control functions

The following table summarizes the InterBase API functions available for controlling transactions in an application:

Table 15.12 Transaction control functions

Function name | Purpose
isc_commit_retaining() | Commit a transaction, and start a new one using the original transaction’s context
isc_commit_transaction() | Save a transaction’s database changes, and end the transaction
isc_prepare_transaction() | Execute the first phase of a two-phase commit
isc_prepare_transaction2() | Execute the second phase of a two-phase commit
isc_rollback_transaction() | Undo a transaction’s database changes, and end the transaction
isc_rollback_retaining() | Undo changes made by a transaction and retain the transaction context after the rollback
isc_start_multiple() | Begin new transactions (used on systems that do not support a variable number of input arguments)
isc_start_transaction() | Begin new transactions
isc_transaction_info() | Request information about a specified transaction

u Back to top

isc_add_user()

Adds a user record to the InterBase security database (admin.ib by default).

Note Use of this function is deprecated. It is replaced by a full featured Services API. See Chapter 12, “Working with Services” on page 12-1 and the reference entry for “isc_service_start()” on page 15-148.

    Syntax  ISC_STATUS isc_add_user(
                     ISC_STATUS *status
                     USER_SEC_DATA *user_sec_data);

Parameter | Type | Description
status vector | ISC_STATUS * | Pointer to the error status vector
user_sec_data | USER_SEC_DATA * | Pointer to a struct that is defined in ibase.h

Description The three security functions, isc_add_user(), isc_delete_user(), and isc_modify_user() mirror functionality that is available in the gsec command-line utility. isc_add_user() adds a record to the InterBase security database (admin.ib by default).

At a minimum, you must provide the user name and password. If the server is not local, you must also provide a server name and protocol. Valid choices for the protocol field are sec_protocol_tcpip, sec_protocol_netbeui, and sec_protocol_local.

InterBase reads the settings for the ISC_USER and ISC_PASSWORD environment variables if you do not provide a DBA user name and password.

The definition for the USER_SEC_DATA structure in ibase.h is as follows:

    typedef struct {
      short  sec_flags;       /* which fields are specified */
      int    uid;              /* the user's id */
      int    gid;              /* the user's group id */
      int    protocol;         /* protocol to use for connection */
      char   *server;          /* server to administer */
      char   *user_name;      /* the user's name */
      char   *password;       /* the user's password */
      char   *group_name;     /* the group name */
      char   *first_name;     /* the user's first name */
      char   *middle_name;    /* the user's middle name */
      char   *last_name;      /* the user's last name */
      char   *dba_user_name;  /* the dba user name */
      char   *dba_password;   /* the dba password */
    } USER_SEC_DATA;

When you pass this structure to one of the three security functions, you can tell it which fields you have specified by doing a bitwise OR of the following values, which are defined in ibase.h:

    sec_uid_spec                0x01
    sec_gid_spec                0x02
    sec_server_spec             0x04
    sec_password_spec           0x08
    sec_group_name_spec         0x10
    sec_first_name_spec         0x20
    sec_middle_name_spec        0x40
    sec_last_name_spec          0x80
    sec_dba_user_name_spec      0x100
    sec_dba_password_spec        0x200

No bit values are available for user name and password, since they are required.

The following error messages exist for this function:

Table 15.13 Error messages for isc_adduser()

Code | Value | Description
isc_usrname_too_long | 335544747 | The user name passed in is greater than 31 bytes
isc_password_too_long | 335544748 | The password passed in is longer than 8 bytes
isc_usrname_required | 335544749 | The operation requires a user name
isc_password_required | 335544750 | The operation requires a password
isc_bad_protocol | 335544751 | The protocol specified is invalid
isc_dup_usrname_found | 335544752 | The user name being added already exists in the security database
isc_usrname_not_found | 335544753 | The user name was not found in the security database
isc_error_adding_sec_record | 335544754 | An unknown error occurred while adding a user
isc_error_deleting_sec_record | 335544755 | An unknown error occurred while deleting a user
isc_error_modifying_sec_record | 335544756 | An unknown error occurred while modifying a user
isc_error_updating_sec_db | 335544757 | An unknown error occurred while updating the security database

Example The following example adds a user (“Socks”) to the password database, using the bitwise OR technique for passing values from the USER_SEC_DATA structure.

    {
      ISC_STATUS status[20];
      USER_SEC_DATA sec;

      sec.server      = "kennel";
      sec.dba_user_name = "sysdba";
      sec.dba_password = "masterkey";
      sec.protocol    = sec_protocol_tcpip;
      sec.first_name  = "Socks";
      sec.last_name   = "Clinton";
      sec.user_name   = "socks";
      sec.password    = "2meow!"; /* Note: do not hardcode passwords */
      sec.sec_flags   = sec_server_spec
                      | sec_password_spec
                      | sec_dba_user_name_spec
                      | sec_dba_password_spec
                      | sec_first_name_spec
                      | sec_last_name_spec;
      isc_add_user(status, &sec);
      /* check status for errors */
      if (status[0] == 1 && status[1])
      {
         switch (status[1]) {
         case isc_usrname_too_long:
            printf("Security database cannot accept long user names\n");
            break;
         ...
         }
      }
    }

Return Value isc_add_user() returns the second element of the status vector. Zero indicates success. A nonzero value indicates an error.

See also isc_delete_user(),

u Back to top

isc_array_get_slice()

Deprecated; like isc_array_get_slice2(), but does not support metadata names longer than 32 bytes.

isc_array_get_slice2()

Retrieves data from an array column in a row returned by a SELECT.

    Syntax  ISC_STATUS isc_array_get_slice2(
                     ISC_STATUS *status_vector,
                     isc_db_handle *db_handle,
                     isc_tr_handle *trans_handle,
                     ISC_QUAD *array_id,
                     ISC_ARRAY_DESC_V2 *desc,
                     void *dest_array,
                     ISC_LONG *slice_length);

Parameter | Type | Description
status_vector | ISC_STATUS * | Pointer to the error status vector
db_handle | isc_db_handle * | Pointer to a database handle set by a previous call to isc_attach_database(); the handle identifies the database containing the array column db_handle returns an error in status_vector if it is NULL
trans_handle | isc_tr_handle * | Pointer to a transaction handle whose value has been set by a previous isc_start_transaction() call; trans_handle returns an error if NULL
array_id | ISC_QUAD * | Internal identifier for the array; the array ID must be previously retrieved through API DSQL functions
desc | ISC_ARRAY_DESC _V2* | Descriptor defining the array slice (entire array or subset) to be retrieved
dest_array | void * | Pointer to a buffer of length slice_length into which the array slice will be copied by this function
slice_length | ISC_LONG * | Length, in bytes, of the dest_array buffer

isc_array_get_slice2() retrieves data from an array column of a table row using an array ID. You can either retrieve all the array elements in that column, or a subset of contiguous array elements, called a slice. The upper and lower boundaries in the desc structure specify which elements are to be retrieved.

InterBase copies the elements into the buffer, dest_array, whose size is specified by slice_length. This should be at least the expected length required for the elements retrieved. Before returning from isc_array_get_slice2(), InterBase sets slice_length to the actual number of bytes copied.

Before calling isc_array_get_slice2(), there are many operations you must do in order to fill in the array descriptor, desc, determine the appropriate internal array identifier, array_id, and fetch the rows whose array columns you want to access. For complete step-by-step instructions for setting up an array descriptor and retrieving array information, see Chapter 8, “Working with Array Data.”

Note Never execute a DSQL statement that tries to access array column data directly unless you are fetching only a single element. The way to access slices of array column data is to call isc_array_get_slice2() or isc_array_put_slice2(). The only supported array references in DSQL statements are ones that specify an entire array column (that is, just the column name) in order to get the internal identifier for the array, which is required by isc_array_get_slice2() and isc_array_put_slice2(), or single element references.

Example The following program operates on a table named PROJ_DEPT_BUDGET.
This table contains the quarterly head counts allocated for each project in each department of an organization. Each row of the table applies to a particular department and project. The quarterly head counts are contained in an array column named QUARTERLY_HEAD_CNT. Each row has four elements in this column, one per quarter. Each element of the array is a number of type long.

The example below selects the rows containing 1994 information for the project named VBASE. For each such row, it retrieves and prints the department number and the data in the array column (that is, the quarterly head counts).

In addition to illustrating the usage of isc_array_lookup_bounds2() and isc_array_get_slice2(), the program shows data structure initializations and calls to the DSQL functions required to prepare and execute the SELECT statement, to obtain the array_id needed by isc_array_get_slice2(), and to fetch the selected rows one by one.

    #include <ibase.h>
    #define Return_if_Error(stat) if (stat[0] == 1 && stat[1]) \
                    { \
                    isc_print_status(stat); \
                    return(1); \
                    }
    char *sel_str =
      "SELECT dept_no, quarterly_head_cnt FROM proj_dept_budget \
         WHERE year = 1994 AND proj_id = 'VBASE'";
    char dept_no[6];
    long hcnt[4], tr_handle, database_handle, SQLCODE;
    short len, i, flag0, flag1;
    ISC_QUAD array_id;
    ISC_ARRAY_DESC_V2 desc;
    ISC_STATUS status_vector[20], fetch_stat;
    isc_stmt_handle stmt = NULL;
    XSQLDA *osqlda;
    tr_handle = database_handle = 0L;
    /* Attach to a database here--this code omitted for brevity */
    /* Start a transaction here--this code omitted for brevity */
    /* Set up the SELECT statement. */
    /* Allocate the output XSQLDA for holding the array data. */
    osqlda = (XSQLDA *)malloc(XSQLDA_LENGTH(2));
    osqlda->sqln = 2;
    osqlda->version = 1;
    /* Allocate a statement handle. */
    isc_dsql_allocate_statement(
      status_vector,
      &database_handle,
      &stmt);
    Return_if_Error(status_vector);
    /* Prepare the query for execution. */
    isc_dsql_prepare(
      status_vector,
      &tr_handle,
      &stmt,
      0,
      sel_str,
      1,
      osqlda);
    Return_if_Error(status_vector);
    /* Set up an XSQLVAR structure to allocate space for each item
      to be retrieved. */
    osqlda->sqlvar[0].sqldata = (char *) dept_no;
    osqlda->sqlvar[0].sqltype = SQL_TEXT + 1;
    osqlda->sqlvar[0].sqlind = &flag0;
    osqlda->sqlvar[1].sqldata = (char *) &array_id;
    osqlda->sqlvar[1].sqltype = SQL_ARRAY + 1;
    osqlda->sqlvar[1].sqlind = &flag1;
    /* Execute the SELECT statement. */
    isc_dsql_execute(
      status_vector,
      &tr_handle,
      &stmt,
      1,
      NULL);
    Return_if_Error(status_vector);
    /* Set up the array descriptor. */
    isc_array_lookup_bounds2(
      status_vector,
      &database_handle,          /* Set by previous isc_attach_database() call. */
      &tr_handle,                /* Set by previous isc_start_transaction() call. */
      "PROJ_DEPT_BUDGET",        /* Table name. */
      "QUARTERLY_HEAD_CNT",      /* Array column name. */
      &desc);
    Return_if_Error(status_vector);

    /* Fetch the head count for each department's four quarters. */
    while ((fetch_stat = isc_dsql_fetch(
      status_vector,
      &stmt,
      1,
      osqlda)) == 0)
    {
      if (!flag1)
      {
         /* There is array data; get the current values. */
         len = sizeof(hcnt);
         /* Fetch the data from the array column into hcnt array. */
         isc_array_get_slice2(
            status_vector,
            &database_handle,
            &tr_handle,
            &array_id,
            &desc,
            hcnt,
            &len);
         Return_if_Error(status_vector);

         /* Print department number and head counts. */
         dept_no[osqlda->sqlvar[0].sqllen] = '\0';
         printf("Department #: %s\n\n", dept_no);
         printf("\tCurrent counts: %d %d %d %d\n",
            hcnt[0], hcnt[1], hcnt[2], hcnt[3]);
      };
    }
    if (fetch_stat != 100L)
    {
      SQLCODE = isc_sqlcode(status_vector);
      isc_print_sqlerror(SQLCODE, status_vector);
      return(1);
    }

Return Value isc_array_get_slice2() returns the second element of the status vector. Zero indicates success. A nonzero value indicates an error. For InterBase errors, the first element of the status vector is set to 1, and the second element is set to isc_bad_stmt_handle, isc_bad_trans_handle, or another InterBase error code.

To check for an InterBase error, examine the first two elements of the status vector directly.

See also isc_array_lookup_bounds2(), isc_array_lookup_desc2(), isc_array_put_slice2(), isc_array_set_desc2(), isc_dsql_fetch(), isc_dsql_prepare()

u Back to top

isc_array_lookup_bounds()

Deprecated; like isc_array_lookup_bounds2(), but does not support metadata names longer than 32 bytes.

isc_array_lookup_bounds2()

Determines the datatype, length, scale, dimensions, and array boundaries for the specified array column in the specified table.

    Syntax  ISC_STATUS isc_array_lookup_bounds2(
                     ISC_STATUS *status_vector,
                     isc_db_handle *db_handle,
                     isc_tr_handle *trans_handle,
                     char *table_name,
                     char *column_name,
                     ISC_ARRAY_DESC_V2 *desc);

Parameter | Type | Description
status_vector | ISC_STATUS * | Pointer to the error status vector
db_handle | isc_db_handle * | Pointer to a database handle set by a previous call to isc_attach_database(); the handle identifies the database containing the array column db_handle returns an error in status_vector if it is NULL
trans_handle | isc_tr_handle * | Pointer to a transaction handle whose value has been set by a previous isc_start_transaction() call; trans_handle returns an error if NULL
table_name | char * | Name of the table containing the array column, column_name; can be either null-terminated or blank-terminated
column_name | char * | Name of the array column; can be either null-terminated or blank-terminated
desc | ISC_ARRAY_DESC_V2 * | Pointer to a descriptor for the arrays that will be filled in by this function

Description isc_array_lookup_bounds2() determines the datatype, length, scale, dimensions, and array boundaries for the elements in an array column, column_name in the table, table_name. It stores this information in the array descriptor, desc.

isc_array_lookup_bounds2() sets a flag in the descriptor to zero. This specifies that the array should be accessed in future function calls in row-major order, the default. If an application requires column-major access, reset this flag to 1.

The array descriptor is used in subsequent calls to isc_array_get_slice2() or isc_array_put_slice2().

For a detailed description of the array descriptor, see Chapter 8, “Working with Array Data.”

Note There are ways to fill in an array descriptor other than by calling isc_array_lookup_bounds2(). You can also:

• Call isc_array_lookup_desc2(). This is exactly the same as calling isc_array_lookup_bounds2(), except that the former does not fill in information about the upper and lower bounds of each dimension.

• Call isc_array_set_desc2() to initialize the descriptor from parameters you call it with, rather than accessing the database metadata.

• Set the descriptor fields directly. Note that array_desc_dtype must be expressed as one of the datatypes in the following table, and the parameters, array_desc_field_name, and array_desc_relation_name, must be null-terminated:

Table 15.14 Datatypes for array descriptor fields

array_desc_dtype | Corresponding InterBase datatype
blr_boolean_dtype | BOOLEAN
blr_text | CHAR
blr_text2 | CHAR
blr_short | SMALLINT
blr_long | INTEGER
blr_quad | ISC_QUAD structure
blr_float | FLOAT
blr_double | DOUBLE PRECISION
blr_sql_date | DATE
blr_sql_time | TIME
blr_timestamp | TIMESTAMP
blr_varying | VARCHAR
blr_varying2 | VARCHAR
blr_blob_id | ISC_QUAD structure
blr_cstring | NULL-terminated string
blr_cstring2 | NULL-terminated string

Example The following illustrates a sample call to isc_array_lookup_bounds2(). More complete examples of accessing arrays are found in the example programs for isc_array_get_slice2() and isc_array_put_slice2().

    #include <ibase.h>

    ISC_STATUS status_vector[20];
    ISC_ARRAY_DESC_V2 desc;
    char *str1 = "PROJ_DEPT_BUDGET";
    char *str2 = "QUARTERLY_HEAD_CNT";

    isc_array_lookup_bounds2(
      status_vector,
      &database_handle, /* Set in previous isc_attach_database() call. */
      &tr_handle, /* Set in previous isc_start_transaction() call. */
      str1,
      str2,
      &desc);
    if (status_vector[0] == 1 && status_vector[1])
    {
      /* Process error. */
      isc_print_status(status_vector);
      return(1);
    }

Return Value isc_array_lookup_bounds2() returns the second element of the status vector. Zero indicates success. A nonzero value indicates an error. For InterBase errors, the first element of the status vector is set to 1, and the second element is set to isc_bad_stmt_handle, isc_bad_trans_handle, isc_fld_not_def, or another InterBase error code.

To check for an InterBase error, examine the first two elements of the status vector directly. For more information about examining the status vector, see Chapter 10, “Handling Error Conditions.”

See also isc_array_get_slice2(), isc_array_lookup_desc2(), isc_array_put_slice2(), isc_array_set_desc2()

u Back to top

isc_array_lookup_desc()

Deprecated; like isc_array_lookup_desc2(), but does not support metadata names longer than 32 bytes.

isc_array_lookup_desc2()

Determines the datatype, length, scale, and dimensions for all elements in the specified array column in the specified table.

    Syntax  ISC_STATUS isc_array_lookup_desc2(
                     ISC_STATUS *status_vector,
                     isc_db_handle *db_handle,
                     isc_tr_handle *trans_handle,
                     char *table_name,
                     char *column_name,
                     ISC_ARRAY_DESC_V2 *desc);

Parameter | Type | Description
status_vector | ISC_STATUS * | Pointer to the error status vector
db_handle | isc_db_handle * | Pointer to a database handle set by a previous call to isc_attach_database(); the handle identifies the database containing the array column db_handle returns an error in status_vector if it is NULL
trans_handle | isc_tr_handle * | Pointer to a transaction handle whose value has been set by a previous isc_start_transaction() call; trans_handle returns an error if NULL
table_name | char * | Name of the table containing the array column column_name; can be either null-terminated or blank-terminated
column_name | char * | Name of the array column; can be either null-terminated or blank-terminated
desc | ISC_ARRAY_DESC_V2 * | Pointer to an array descriptor that will be filled in by this function

Description isc_array_lookup_desc2() determines the datatype, length, scale, and dimensions for the array column, column_name, in the table, table_name. It stores this information in the array descriptor, desc.

It also sets to 0 a flag in the descriptor. This specifies that the array is accessed in future function calls in row-major order, the default. If an application requires column-major access, reset this flag to 1.

The array descriptor is used in subsequent calls to isc_array_get_slice2() or isc_array_put_slice2().

For a detailed description of the array descriptor, see Chapter 8, “Working with Array Data.”

Note There are ways to fill in an array descriptor other than by calling isc_array_lookup_desc2(). You can also:

• Call isc_array_lookup_bounds2(). This is like isc_array_lookup_desc2(), except that isc_array_lookup_bounds2() also fills in information about the upper and lower bounds of each dimension.

• Call isc_array_set_desc2(), to initialize the descriptor from parameters you call it with, rather than accessing the database metadata.

• Set the descriptor fields directly. Note that array_desc_dtype must be expressed as one of the datatypes in the following table, and the parameters, array_desc_field_name, and array_desc_relation_name, must be null-terminated:

Table 15.15 Datatypes for array descriptor fields

array_desc_dtype | Corresponding InterBase datatype
blr_boolean_dtype | BOOLEAN
blr_text | CHAR
blr_text2 | CHAR
blr_short | SMALLINT
blr_long | INTEGER
blr_quad | ISC_QUAD structure
blr_float | FLOAT
blr_double | DOUBLE PRECISION
blr_sql_date | DATE
blr_sql_time | TIME
blr_timestamp | TIMESTAMP
blr_varying | VARCHAR
blr_varying2 | VARCHAR
blr_blob_id | ISC_QUAD structure
blr_cstring | NULL-terminated string
blr_cstring2 | NULL-terminated string

Example The following illustrates a sample call to isc_array_lookup_desc2(). More complete examples of accessing arrays are found in the example programs for isc_array_get_slice2() and isc_array_put_slice2().

    #include <ibase.h>
    ISC_STATUS status_vector[20];
    ISC_ARRAY_DESC_V2 desc;
    char str1 = "PROJ_DEPT_BUDGET";
    char str2 = "QUARTERLY_HEAD_CNT";

    isc_array_lookup_desc2(
      status_vector,
      &database_handle, /* Set in previous isc_attach_database() call. */
      &tr_handle, /* Set in previous isc_start_transaction() call. */
      str1,
      str2,
      &desc);
    if (status_vector[0] == 1 && status_vector[1])
    {
      /* Process error. */
      isc_print_status(status_vector);
      return(1);
    };

Return Value isc_array_lookup_desc2() returns the second element of the status vector. Zero indicates success. A nonzero value indicates an error. For InterBase errors, the first element of the status vector is set to 1, and the second element is set to isc_bad_stmt_handle, isc_bad_trans_handle, isc_fld_not_def, or another InterBase error code.

To check for an InterBase error, examine the first two elements of the status vector directly. For more information about examining the status vector, see Chapter 10, “Handling Error Conditions.”

See also isc_array_get_slice2(), isc_array_lookup_bounds2(), isc_array_put_slice2(), isc_array_set_desc2()

u Back to top

isc_array_put_slice()

Deprecated; like isc_array_put_slice2(), but does not support metadata names longer than 32 bytes.

isc_array_put_slice2()

Writes data into an array column.

    Syntax  ISC_STATUS isc_array_put_slice2(
                     ISC_STATUS *status_vector,
                     isc_db_handle *db_handle,
                     isc_tr_handle *trans_handle,
                     ISC_QUAD *array_id,
                     ISC_ARRAY_DESC_V2 *desc,
                     void *source_array,
                     ISC_LONG *slice_length);

Parameter | Type | Description
status_vector | ISC_STATUS * | Pointer to the error status vector
db_handle | isc_db_handle * | Pointer to a database handle set by a previous call to isc_attach_database(); the handle identifies the database containing the array column db_handle returns an error in status_vector if it is NULL
trans_handle | isc_tr_handle * | Pointer to a transaction handle whose value has been set by a previous isc_start_transaction() call; trans_handle returns an error if NULL
array_id | ISC_QUAD * | On input, NULL (if you are creating a new array), or the internal identifier for an array to be modified, as assigned by the InterBase engine. This internal identifier must have been determined by previous calls to DSQL functions. This function changes array_id to be the identifier for the array it creates or modifies (see below).
desc | ISC_ARRAY_DESC _V2* | Descriptor defining the array slice (entire array or subset) to be written to
source_array | void * | Pointer to a buffer of length slice_length, that contains the slice of data that will be copied to the array by this function
slice_length | ISC_LONG * | Length, in bytes, of the source_array buffer

Description isc_array_put_slice2() writes data into an array column. You can either store into all the array elements in that column, or into an array slice, a subset of contiguous array elements. The boundaries passed to the function in the array descriptor, desc, specify which elements are to be stored into.

InterBase copies the elements from the buffer, source_array, whose size is specified by slice_length.

The array identifier (array ID), array_id, should be passed as NULL if you are calling isc_array_put_slice2() to create a new array. If you are calling it to modify an existing array, then array_id should be the identifier of the array to be modified. This must have been determined by previous calls to DSQL functions.

When isc_array_put_slice2() is called with an array ID of an existing array, it:

1 Creates a new array with the same dimensions, bounds, etc., as the specified array, and copies the existing array data to the new array.

2 Writes the data from the array buffer, source_array, to the new array (or slice of the array), per the bounds specified in the array descriptor, desc.

3 Returns in the same array_id variable the array ID of the new array.

When isc_array_put_slice2() is called with a NULL array ID, it:

1 Creates a new empty array with dimensions, bounds, etc., as declared for the array column whose name and table name are specified in the array descriptor, desc.

2 Writes the data from the array buffer, source_array, to the new array (or slice of the array)

3 Returns in the array_id variable the array ID of the new array.

Note that in both cases, a new array is created, and its array ID is returned in the array_id variable. The array is temporary until an UPDATE or INSERT statement is executed to associate the array with a particular column of a particular row.

You can make a single call to isc_array_put_slice2() to write all the data you wish to the array. Or, you can call isc_array_put_slice2() multiple times
to store data into various slices of the array. In this case, each call to isc_array_put_slice2() after the first call should pass the array ID of the temporary array. When isc_array_put_slice2() is called with the array ID of a temporary array, it copies the specified data to the specified slice of the temporary array (it will not create a new array), and it doesn’t modify array_id.

Before calling isc_array_put_slice2(), there are many operations you must do in order to fill in the array descriptor, desc, determine the appropriate internal array identifier, array_id, and fetch the rows whose array columns you want to access.

For complete step-by-step instructions for setting up an array descriptor and writing array information, see Chapter 8, “Working with Array Data.”

Note Never execute a DSQL statement that tries to directly store data into an array column. The only way to access array column data is by calling isc_array_get_slice2() or isc_array_put_slice2(). The only supported array references in DSQL statements are ones that specify an entire array column (that is, just the column name) in order to get the internal identifier for the array, which is required by isc_array_get_slice2() and isc_array_put_slice2().

Example The following program operates on a table named PROJ_DEPT_BUDGET. This table contains the quarterly head counts allocated for each project in each department of an organization. Each row of the table applies to a particular department and project. The quarterly head counts are contained in an array column named QUARTERLY_HEAD_CNT. Each table row has four elements in this column, one per quarter. Each element is a number of type long.

This program selects the rows containing 1994 information for the project named VBASE. For each such row, it calls isc_array_get_slice2() to retrieve a slice of the array, the quarterly head counts for the last two quarters. It then increments each, and calls isc_array_put_slice2() to store the updated values.

In addition to illustrating the usage of isc_array_lookup_desc2(), isc_array_get_slice2(), and isc_array_put_slice2(), the program shows data structure initializations and calls to the DSQL functions required to prepare and execute the SELECT and UPDATE statements, to obtain the array_id needed by isc_array_get_slice2() and isc_array_put_slice2(), to fetch the selected rows one by one, and to update the array ID.

    #include <ibase.h>

    #define Return_if_Error(stat) if (stat[0] == 1 && stat[1]) \
                    { \
                    isc_print_status(stat); \
                    return(1); \
                    }

    char *sel_str =
      "SELECT dept_no, quarterly_head_cnt FROM proj_dept_budget \
         WHERE year = 1994 AND proj_id = 'VBASE'";
    char *upd_str =
      "UPDATE proj_dept_budget SET quarterly_head_count = ? \
      WHERE CURRENT OF S";

    char dept_no[6];
    long fetch_stat, SQLCODE, hcnt[2];
    short len, i, flag0, flag1, flag2;
    ISC_QUAD array_id;
    ISC_ARRAY_DESC_V2 desc;
    ISC_STATUS status_vector[20];
    isc_stmt_handle stmt = NULL;
    isc_stmt_handle ustmt = NULL;
    char *cursor = "S";
    XSQLDA *osqlda, *isqlda;

    /* Set up the SELECT statement. */

    /* Allocate the output XSQLDA for holding the array data. */
    osqlda = (XSQLDA *)malloc(XSQLDA_LENGTH(2));
    osqlda->sqln = 2;
    osqlda->version = SQLDA_CURRENT_VERSION;

    /* Allocate a statement handle for the SELECT statement. */
    isc_dsql_allocate_statement(
      status_vector, &database_handle, &stmt);
    Return_if_Error(status_vector);

    /* Prepare the query for execution. */
    isc_dsql_prepare(
      status_vector,
      &tr_handle,
      &stmt,
      0,
      sel_str,
      1,
      osqlda);
    Return_if_Error(status_vector);

    /* Set up an XSQLVAR structure to allocate space for each item
      to be retrieved. */

    osqlda->sqlvar[0].sqldata = (char *) dept_no;
    osqlda->sqlvar[0].sqltype = SQL_TEXT + 1;
    osqlda->sqlvar[0].sqlind = &flag0;

    osqlda->sqlvar[1].sqldata = (char *) &array_id;
    osqlda->sqlvar[1].sqltype = SQL_ARRAY + 1;
    osqlda->sqlvar[1].sqlind = &flag1;

    /* Execute the SELECT statement. */
    isc_dsql_execute(
      status_vector,
      &tr_handle,
      &stmt,
      1,
      NULL);
    Return_if_Error(status_vector);

    /* Declare a cursor. */
    isc_dsql_set_cursor_name(
      status_vector, &stmt, cursor, 0);
    Return_if_Error(status_vector);

    /* Set up the UPDATE statement. */

    /* Allocate a statement handle for the UPDATE statement. */
    isc_dsql_allocate_statement(
      status_vector, &database_handle, &ustmt);
    Return_if_Error(status_vector);

    /* Allocate the input XSQLDA. */
    isqlda = (XSQLDA *)malloc(XSQLDA_LENGTH(2));
    isqlda->sqln = 1;
    1sqlda->version = SQLDA_CURRENT_VERSION;

    /* Prepare the UPDATE statement for execution. */
    isc_dsql_prepare(
      status_vector,
      &tr_handle,
      &ustmt,
      0,
      upd_str,
      1,
      NULL);
    Return_if_Error(status_vector);

    /* Initialize the input XSQLDA. */
    isc_dsql_describe_bind(
      status_vector, &ustmt, 1, isqlda);
    Return_if_Error(status_vector);

    /* Set up the input sqldata and sqlind fields. */
    isqlda->sqlvar[0].sqldata = (char *) &array_id;
    isqlda->sqlvar[0].sqlind = &flag2;

    /* Set up the array descriptor. */
    isc_array_lookup_desc2(
      status_vector,
      &database_handle, /* Set by previous isc_attach_database() call. */
      &tr_handle, /* Set by previous isc_start_transaction() call. */
      "PROJ_DEPT_BUDGET", /* Table name. */
      "QUARTERLY_HEAD_CNT", /* Array column name. */
      &desc);
    Return_if_Error(status_vector);

    /* Set the descriptor bounds to those of the slice to be updated, that is, to
    those of the last two elements. Assuming the array column was defined to contain 4
    elements, with a lower bound (subscript) of 1 and an upper bound of 4, the last
    two elements are at subscripts 3 and 4. */
    desc->array_desc_bounds[0].array_bound_lower = 3;
    desc->array_desc_bounds[0].array_bound_upper = 4;

    /* Fetch and process the rows of interest. */
    while ((fetch_stat = isc_dsql_fetch(
      status_vector, &stmt, 1, osqlda)) == 0)
    {
      if (!flag1)
      {
         /* There is array data; get values for last two quarters. */
         len = sizeof(hcnt);
         /* Fetch the data from the array slice into hcnt array. */
         isc_array_get_slice2(
            status_vector,
            &database_handle,
            &tr_handle,
            &array_id,
            &desc,
            hcnt,
            &len);
         Return_if_Error(status_vector);

              /* Add 1 to each count. */
         for (i = 0; i < 2; i++)
            hcnt[i] = hcnt[i] + 1;

         /* Save new values. */
         isc_array_put_slice2(
            status_vector,
            &database_handle,
            &tr_handle,
            &array_id,
            &desc,
            hcnt,
            &len);
         Return_if_Error(status_vector);

              /* Update the array ID. */
         isc_dsql_execute(
              status_vector, &tr_handle, &ustmt, 1, isqlda);
         Return_if_Error(status_vector);

      };
    };
    if (fetch_stat != 100L)
    {
      SQLCODE = isc_sqlcode(status_vector);
      isc_print_sqlerror(SQLCODE, status_vector);
      return(1);
    }

Return Value isc_array_put_slice2() returns the second element of the status vector. Zero indicates success. A nonzero value indicates an error. For InterBase errors, the first element of the status vector is set to 1, and the second element is set to isc_bad_stmt_handle, isc_bad_trans_handle, or another InterBase error code.

To check for an InterBase error, examine the first two elements of the status vector directly. For more information about examining the status vector, see Chapter 10, “Handling Error Conditions.”

See also isc_array_get_slice2(), isc_array_lookup_bounds2(), isc_array_lookup_desc2(), isc_array_set_desc2(), isc_dsql_allocate_statement(), isc_dsql_describe_bind(), isc_dsql_execute(), isc_dsql_fetch(), isc_dsql_prepare(), isc_dsql_set_cursor_name()

u Back to top

isc_array_set_desc()

Deprecated; like isc_array_set_desc2(), but does not support metadata names longer than 32 bytes.

isc_array_set_desc2()

Initializes an array descriptor.

    Syntax  ISC_STATUS isc_array_set_desc2(
                     ISC_STATUS *status_vector,
                     char *table_name,
                     char *column_name,
                     short *sql_dtype,
                     short *sql_length,
                     short *dimensions,
                     ISC_ARRAY_DESC_V2 *desc);

Parameter | Type | Description
status_vector | ISC_STATUS * | Pointer to the error status vector
table_name | char * | Blank- or null-terminated name of the table containing the array column, column_name
column_name | char * | Name of the array column; this may be either null-terminated or blank-terminated
sql_dtype | short * | Pointer to SQL datatype of the array elements
sql_length | short * | Pointer to length of each array element
dimensions | short * | Pointer to number of array dimensions
desc | ISC_ARRAY_DESC_V2 * | Array descriptor to be filled in by this function

Description isc_array_set_desc2() initializes the array descriptor, desc, from the function parameters, table_name, column_name, sql_dtype, sql_length, and dimensions.

isc_array_set_desc2() also sets to 0 a flag in the descriptor. This specifies that the array is accessed in future function calls in row-major order, the default. If an application requires column-major access, reset this flag to 1.

table_name and column_name can be either null-terminated or blank-terminated. The names stored in the descriptor will be null-terminated.

sql_dtype must be given as a SQL macro constant.

The array descriptor is used in subsequent calls to isc_array_get_slice2() or isc_array_put_slice2().

For a detailed description of the array descriptor, see Chapter 8, “Working with Array Data.”

Note There are ways to fill in an array descriptor other than by calling isc_array_set_desc2(). You can also:

• Call isc_array_lookup_bounds2(). This function is similar to isc_array_lookup_desc2(), except that isc_array_lookup_bounds2() also fills in information about the upper and lower bounds of each dimension.

• Call isc_array_lookup_desc2(). This function is similar to isc_array_lookup_bounds2(), except that isc_array_lookup_desc2() does not fill in information about the upper and lower bounds of each dimension.

• Set the descriptor fields directly.

• You must set array_desc_version to ARR_DESC_CURRENT_VERSION

• The array_desc_field_name and array_desc_relation_name parameters must be null-terminated:

• array_desc_dtype must be expressed as one of the datatypes in the following table

Table 15.16 Datatypes for array descriptor fields

array_desc_dtype | Corresponding InterBase datatype
blr_boolean_dtype | BOOLEAN
blr_text | CHAR
blr_text2 | CHAR
blr_short | SMALLINT
blr_long | INTEGER
blr_quad | ISC_QUAD structure
blr_float | FLOAT
blr_double | DOUBLE PRECISION
blr_sql_date | DATE
blr_sql_time | TIME
blr_timestamp | TIMESTAMP
blr_varying | VARCHAR
blr_varying2 | VARCHAR
blr_blob_id | ISC_QUAD structure
blr_cstring | NULL-terminated string
blr_cstring2 | NULL-terminated string

Example The following illustrates a sample call to isc_array_set_desc2(). More complete examples of accessing arrays are found in the example programs for isc_array_get_slice2() and isc_array_put_slice2().

    #include <ibase.h>
    ISC_STATUS status_vector[20];
    ISC_ARRAY_DESC_V2 desc;
    short dtype = SQL_TEXT;
    short len = 8;
    short dims = 1;

    isc_array_set_desc2(
      status_vector,
      "TABLE1",
      "CHAR_ARRAY",
      &dtype,
      &len,
      &dims,
      &desc);
    if (status_vector[0] == 1 && status_vector[1])
    {
      /* Process error. */
      isc_print_status(status_vector);
      return(1);
    }

Return Value isc_array_set_desc2() returns the second element of the status vector. Zero indicates success. A nonzero value indicates an error. For InterBase errors, the first element of the status vector is set to 1, and the second element is set to an InterBase error code.

To check for an InterBase error, examine the first two elements of the status vector directly. For more information about examining the status vector, see Chapter 10, “Handling Error Conditions.”

See also isc_array_get_slice2(), isc_array_lookup_bounds2(), isc_array_lookup_desc2(), isc_array_put_slice2()

u Back to top

isc_attach_database()

Attaches to an existing database.

    Syntax  ISC_STATUS isc_attach_database(
                     ISC_STATUS *status_vector,
                     short db_name_length,
                     char *db_name,
                     isc_db_handle *db_handle,
                     short parm_buffer_length,
                     char *parm_buffer);

Parameter | Type | Description
status_vector | ISC_STATUS * | Pointer to the error status vector
db_name_length | short | Number of bytes in db_name string; if 0, the string is assumed to be null-terminated
db_name | char * | Database name
db_handle | isc_db_handle * | Pointer to a database handle set by this function; It is recommended that you set db_handle to NULL before passing it to isc_attach_database()
parm_buffer_length | short | Number of bytes in the database parameter buffer (DPB)
parm_buffer | char * | Address of the DPB

Description The isc_attach_database() function connects to an existing database to enable subsequent program access. It also optionally specifies various operational characteristics, such as a user name and password combination for access to a database on a remote server, or the number of database cache buffers to use. These optional characteristics are passed in a database parameter buffer (DPB) supplied and populated by the calling program, either through direct program construction, and by calling isc_expand_dpb() to build the DPB.

A program passes the name of the database file to which to attach in db_name. For programs not written in C, the program must also pass the length, in bytes, of db_name in the db_name_length parameter. C programs should pass a 0 length in this parameter.

If successful, isc_attach_database() assigns a unique ID to db_handle. Subsequent API calls use this handle to identify the database against which they operate.

When finished accessing a database, disconnect from the database with isc_detach_database().

Example The following program fragment attaches to a database named employee.db. In the parameter buffer, it specifies a user name and password. These come from the contents of char * variables named user_name and user_password, respectively.

    char dpb_buffer[256], *dpb, *p;
    ISC_STATUS status_vector[20];
    isc_db_handle handle = NULL;
    short dpb_length;

    /* Construct the database parameter buffer. */
    dpb = dpb_buffer;
    *dpb++ = isc_dpb_version1;

    *dpb++ = isc_dpb_user_name;
    *dpb++ = strlen(user_name);
    for (p = user_name; *p;)
      *dpb++ = *p++;

    *dpb++ = isc_dpb_password;
    *dpb++ = strlen(user_password);
    for (p = user_password; *p;)
      *dpb++ = *p++;
    /* An alternate choice for the above construction is to call:
    isc_expand_dpb(). */

    dpb_length = dpb - dpb_buffer;

    isc_attach_database(
      status_vector,
      0,
      "employee.db",
      &handle,
      dpb_length,
      dpb_buffer);
    if (status_vector[0] == 1 && status_vector[1])
    {
      /* An error occurred. */
      isc_print_status (status_vector);
      return(1);
    }

Return Value isc_attach_database() returns the second element of the status vector. Zero indicates success. A nonzero value indicates an error. For InterBase errors, the first element of the status vector is set to 1, and the second element is set to an InterBase error code.

To check for an InterBase error, examine the first two elements of the status vector directly. For more information about examining the status vector, see Chapter 10, “Handling Error Conditions.”

See also isc_detach_database(), isc_expand_dpb()

For more information about creating and populating a DPB, see “Creating and populating a DPB” on page 4-3. For more information about attaching to a database, see “Connecting to databases” on page 4-2.

isc_blob_default_desc()

Deprecated. Like isc_blob_default_desc2(), but does not support metadata names longer than 32 bytes.

isc_blob_default_desc2()

Loads a data structure with default information about a Blob, including its subtype, character set, and segment size.

    Syntax  void isc_blob_default_desc2(
                     ISC_BLOB_DESC_V2 *desc,
                     unsigned char *table_name,
                     unsigned char *column_name);

Parameter | Type | Description
desc | ISC_BLOB_DESC_V2 * | Pointer to a Blob descriptor
table_name | unsigned char * | Table name
column_name | unsigned char * | Blob column name

Description isc_blob_default_desc2() loads a Blob descriptor, desc, with the specified table_name and column_name, and the following default values prior to calling isc_blob_gen_bpb2() to generate a Blob parameter buffer (BPB) for the Blob column being accessed:

• Subtype is set to TEXT.

• Character set is set to the default character set for the process or database.

• Segment size is set to 80 bytes.

• ISC_BLOB_DESC_V2 supports long metadata names of length METADATALENGTH. The older ISC_BLOB_DESC structure supports only metadata names of 32 bytes or less.

isc_blob_default_desc2() and three related functions, isc_blob_gen_bpb2(), isc_blob_lookup_desc2(), and isc_blob_set_desc2(), provide dynamic access to Blob information. In particular, these functions can define and access information about a Blob for filtering purposes, such as character set information for text Blob data, and subtype information for text and non-text Blob data.

The following table lists the fields in the desc structure:

Table 15.17 Blob descriptor fields

Parameter | Type | Description
blob_desc_version | short | Set to BLOB_DESC_CURRENT_VERSION
blob_desc_subtype | short | Subtype of the Blob filter
blob_desc_charset | short | Character set being used
blob_desc_segment_size | short | Blob segment size
blob_desc_field_name [METADATALENGTH] | char | Array containing the name of the Blob column
blob_desc_relation_name [METADATALENGTH] | char | Array containing the name of the table in which the Blob is stored

Example The following fragment loads the Blob descriptor with default information:

    typedef struct
    {
      short         blob_desc_version
      short         blob_desc_subtype;
      short         blob_desc_charset;
      short         blob_desc_segment_size;
      unsigned char blob_desc_field_name[METADATALENGTH];
      unsigned char blob_desc_relation_name[METADATALENGTH];
    } ISC_BLOB_DESC2;

    isc_blob_default_desc2(&desc, &relation, &field);

Return Value None.

See also isc_blob_gen_bpb2(), isc_blob_lookup_desc2(), isc_blob_set_desc2()

u Back to top

isc_blob_gen_bpb()

Deprecated; like isc_blob_gen_bpb2(), but does not support metadata names longer than 32 bytes.

isc_blob_gen_bpb2()

Generates a Blob parameter buffer (BPB) to allow dynamic access to Blob subtype and character set information.

    Syntax  ISC_STATUS isc_blob_gen_bpb2(
                     ISC_STATUS *status_vector,
                     ISC_BLOB_DESC_V2 *to_desc,
                     ISC_BLOB_DESC_V2 *from_desc,
                     unsigned short bpb_buffer_length,
                     unsigned char *bpb_buffer,
                     unsigned short *bpb_length);

Parameter | Type | Description
status_vector | ISC_STATUS * | Pointer to the error status vector
to_desc | ISC_BLOB_DESC_V2 * | Pointer to the target Blob descriptor
from_desc | ISC_BLOB_DESC_V2 * | Pointer to the source Blob descriptor
bpb_buffer_length | unsigned short | Length of the BPB bpb_buffer
bpb_buffer | unsigned char * | Pointer to the BPB
bpb_length | unsigned short * | Pointer to the length of the data stored into the BPB

Description isc_blob_gen_bpb2() generates a Blob parameter buffer (BPB) from subtype and character set information stored in the source Blob descriptor from_desc and the target (destination) Blob descriptor to_desc.

A BPB is needed whenever a filter will be used when writing to or reading from a Blob column. Two Blob descriptors are needed for filtering: one (from_desc) to describe the filter source data, and the other (to_desc) to describe the destination. The descriptors must have been previously created either directly, or via a call to isc_blob_default_desc2(), isc_blob_lookup_desc2(), or isc_blob_set_desc2().

The BPB generated by isc_blob_gen_bpb2() is subsequently needed in calls to isc_open_blob2() or isc_create_blob2() if filtering will be utilized. For more information about the BPB, see Chapter 7, “Working with Blob Data.”

Important In the two ISC_BLOB_DESC_V2 structures passed by to_desc and from_desc, you must set the blob_desc_version fields to BLB_DESC_CURRENT_VERSION. ISC_BLOB_DESC_V2 supports long metadata names of length METADATALENGTH. The older ISC_BLOB_DESC structure supports only metadata names of 32 bytes or less.

Example The following fragment generates the Blob descriptor:

    isc_blob_gen_bpb2(status, &to_desc, &from_desc, bpb_length, &buffer, &buf_length);

Return Value isc_blob_gen_bpb2() returns the second element of the status vector. Zero indicates success. A nonzero value indicates an error. For InterBase errors, the first element of the status vector is set to 1, and the second element is set to an InterBase error code.

To check for an InterBase error, examine the first two elements of the status vector directly.

See also isc_blob_default_desc2(), isc_blob_lookup_desc2(), isc_blob_set_desc2(), isc_create_blob2(), isc_open_blob2()

u Back to top

isc_blob_info()

Returns information about an open Blob.

    Syntax  ISC_STATUS isc_blob_info(
                     ISC_STATUS *status_vector,
                     isc_blob_handle *blob_handle,
                     short item_list_buffer_length,
                     char *item_list_buffer,
                     short result_buffer_length,
                     char *result_buffer);

Parameter | Type | Description
status_vector | ISC_STATUS * | Pointer to the error status vector
blob_handle | isc_blob_handle * | Pointer to the Blob
item_list_buffer_length | short | Length of the item-list buffer in which you specify the items for which you want information
item_list_buffer | char * | Pointer to the item-list buffer
result_buffer_length | short | Length of the result buffer into which InterBase returns the requested information
result_buffer | char * | Pointer to the result buffer

Description isc_blob_info() returns information about an existing Blob specified by blob_handle. The item-list buffer is an unstructured byte vector. An application lists the items about which it wants information in the item-list buffer.

InterBase returns the requested information to the result buffer as a series of clusters of information, one per item requested. Each cluster consists of three parts:

1 A one-byte item type. Each is the same as one of the item types in the item-list buffer.

2 A 2-byte number specifying the number of bytes that follow in the remainder of the cluster.

3 A value, stored in a variable number of bytes, whose interpretation depends on the item type.

A calling program is responsible for interpreting the contents of the result buffer and for deciphering each cluster as appropriate.

For a list of items that can be requested and returned, see Chapter 7, “Working with Blob Data.”

Example The following example retrieves information about the current open Blob:

    static char blob_items[] = {
      isc_info_blob_max_segment,
      isc_info_blob_num_segments,
      isc_info_blob_type};

    CHAR blob_info[32];

    isc_open_blob2(status_vector, &db, &tr_handle, &blob_handle, &blob_id, blength,
    baddr)
    if (status_vector[0] == 1 && status_vector[1])
    {
      isc_print_status(status_vector);
      return(1);
    }
    isc_blob_info(status_vector, &blob_handle, sizeof(blob_items),
         blob_items, sizeof(blob_info), blob_info));

Return Value isc_blob_info() returns the second element of the status vector. Zero indicates success. A nonzero value indicates an error. For InterBase errors, the first element of the status vector is set to 1, and the second element is set to an InterBase error code.

To check for an InterBase error, examine the first two elements of the status vector directly.

See also isc_create_blob2(), isc_open_blob2()

u Back to top

isc_blob_lookup_desc()

Deprecated. Like isc_blob_lokup_desc2(), but does not support metadata names longer than 32 bytes.

isc_blob_lookup_desc2()

Determines the subtype, character set, and segment size of a Blob, given a table name and Blob column name.

    Syntax  ISC_STATUS isc_blob_lookup_desc(
                     ISC_STATUS *status_vector,
                     isc_db_handle **db_handle,
                     isc_tr_handle **trans_handle,
                     unsigned char *table_name,
                     unsigned char *column_name,
                     ISC_BLOB_DESC_V2 *desc,
                     unsigned char *global);

Parameter | Type | Description
status_vector | ISC_STATUS * | Pointer to the error status vector
db_handle | isc_db_handle ** | Pointer to a database handle set by a previous call to isc_attach_database() db_handle returns an error in status_vector if it is NULL
trans_handle | isc_tr_handle ** | Pointer to a transaction handle whose value has been set by a previous isc_start_transaction() call; trans_handle returns an error if NULL
table_name | unsigned char * | Name of the table containing the Blob column
column_name | unsigned char * | Name of the Blob column
desc | ISC_BLOB_DESC_V2 * | Pointer to the Blob descriptor to which the function returns information
global | unsigned char * | Global column name, returned by this function

Description isc_blob_lookup_desc2() uses the system tables of a database to determine the subtype, character set, and segment size of a Blob given a table name and Blob column name.

isc_blob_lookup_desc2() and three related functions, isc_blob_default_desc2(), isc_blob_gen_bpb2(), and isc_blob_set_desc2() provide dynamic access to Blob information. In particular, you can use these functions to define and access information about Blob data for filtering purposes, such as character set information for text Blob data, and subtype information for text and non-text Blob data.

Note The ISC_BLOB_DESC_V2 structure supports long metadata names of length METADATALENGTH. The older ISC_BLOB_DESC structure supports only metadata names of 32 bytes or less.

isc_blob_lookup_desc2() stores the requested information about the Blob into the desc Blob descriptor structure. The following table describes the desc structure:

Table 15.18 Blob descriptor fields

Parameter | Type | Description
blob_desc_version | short | Set to BLOB_DESC_CURRENT_VERSION
blob_desc_subtype | short | Subtype of the Blob filter
blob_desc_charset | short | Character set being used
blob_desc_segment_size | short | Blob segment size
blob_desc_field_name [METADATALENGTH] | char | Array containing the name of the Blob column
blob_desc_relation_name [METADATALENGTH] | char | Array containing the name of the table in which the Blob is stored

The blob_desc_version field is set to BLB_DESC_CURRENT_VERSION by isc_blob_default_desc2(), isc_blob_lookup_desc2(), and isc_blob_set_desc2(). isc_blob_gen_bpb2() requires that the user set the blob_desc_version to BLB_DESC_CURRENT_VERSION explicitly.

Example The following fragment retrieves information into a Blob descriptor:

    isc_blob_lookup_desc2(status, &db_handle, &tr_handle, &relation_name,
      f&field_name, &desc, &global);

Return Value isc_blob_lookup_desc2() returns the second element of the status vector. Zero indicates success. A nonzero value indicates an error. For InterBase errors, the first element of the status vector is set to 1, and the second element is set to an InterBase error code. To check for an InterBase error, examine the first two elements of the status vector directly. For more information about examining the status vector, see Chapter 10, “Handling Error Conditions.”

See also isc_blob_default_desc2(), isc_blob_gen_bpb2(), isc_blob_set_desc2()

u Back to top

isc_blob_set_desc()

Deprecated; like isc_blob_set_desc2(), but does not support metadata names longer than 32 bytes.

isc_blob_set_desc2()

Sets the subtype and character set for a Blob.

    Syntax  ISC_STATUS isc_blob_set_desc2(
                     ISC_STATUS *status_vector,
                     unsigned char *table_name,
                     unsigned char *column_name,
                     short subtype,
                     short charset,
                     short segment_size,
                     ISC_BLOB_DESC_V2 *desc);

Parameter | Type | Description
status_vector | ISC_STATUS * | Pointer to the error status vector
table_name | unsigned char * | Name of the table containing the Blob column
column_name | unsigned char * | Name of the Blob column in the table
subtype | short | Specifies the subtype of the Blob; value are: • InterBase-defined subtype values, 0 or 1 (TEXT) • User-defined subtypes, –1 to –32768
charset | short | Specifies the character set for the Blob
segment_size | short | Specifies the segment size for the Blob
desc | ISC_BLOB_DESC * | Pointer to a Blob descriptor to populate

Description isc_blob_set_desc2() sets the Blob column name, table name, subtype, segment size, and character set for a Blob column to values specified by the application. To set these values to InterBase defaults, use isc_blob_default_desc2().

isc_blob_set_desc2() and three related functions, isc_blob_default_des2c(), isc_blob_gen_bpb2(), and isc_blob_lookup_desc2() provide dynamic access to Blob data. In particular, you can use these functions to define and access information about Blob data for filtering purposes, such as character set information for text Blob data, and subtype information for text and non-text Blob data.

You can manually set the subtype and character set information (for a TEXT subtype) in a Blob descriptor, by way of a call to isc_blob_set_desc2(). Pass the subtype, character set, and segment size to the Blob descriptor in your application.

isc_blob_set_desc2() is useful for setting the contents of the Blob descriptor without querying the system tables for the information. Calls to this function also let an application specify character set and subtype for custom filtering operations.

Note The ISC_BLOB_DESC_V2 structure supports long metadata names of length METADATALENGTH. The older ISC_BLOB_DESC structure supports only metadata names of 32 bytes or less.

Note Do not call this function while running against a V3.x database.

Example The following example sets the default values for a tour guide application, including subtype, character set, and segment size:

    isc_blob_set_desc2(status, "TOURISM", "GUIDEBOOK", 1, 2, 80, &desc);

Return Value isc_blob_set_desc2() returns the second element of the status vector. Zero indicates success. A nonzero value indicates an error. For InterBase errors, the first element of the status vector is set to 1, and the second element is set to an InterBase error code.

To check for an InterBase error, examine the first two elements of the status vector directly. For more information about examining the status vector, see Chapter 10, “Handling Error Conditions.”

See also isc_blob_default_desc2(), isc_blob_gen_bpb2(), isc_blob_lookup_desc2()

u Back to top

isc_cancel_blob()

Discards a Blob, frees internal storage used by the Blob, and sets the Blob handle to NULL.

    Syntax  ISC_STATUS isc_cancel_blob(
                     ISC_STATUS *status_vector,
                     isc_blob_handle *blob_handle);

Parameter | Type | Description
status_vector | ISC_STATUS * | Pointer to the error status vector
blob_handle | isc_blob_handle * | Pointer to the handle for the Blob you want to cancel; sets the handle to zero and returns a successful result even if the handle is NULL

Description InterBase temporarily stores Blob data in the database during create operations. If, for some reason, you do not, or cannot, close a Blob, the storage space remains allocated in the database and InterBase does not set the handle to NULL. Call isc_cancel_blob() to release the temporary storage in the database, and to set blob_handle to NULL. If you close the Blob in the normal course of your application processing logic, this step is unnecessary as InterBase releases system resources on a call to isc_close_blob().

Note A call to this function does not produce an error when the handle is NULL. Therefore, it is good practice to call isc_cancel_blob() before creating or opening a Blob to clean up existing Blob operations.

Example The following fragment cancels any open Blob before creating a new one:

    isc_cancel_blob(status_vector, &blob_handle);
    if (status_vector[0] == 1 && status_vector[1])
    {
      /* process error */
      isc_print_status(status_vector);
      return(1);
    }

    isc_create_blob(status_vector, &DB, &trans, &blob_handle, &blob_id)

Return Value isc_cancel_blob() returns the second element of the status vector. Zero indicates success. A nonzero value indicates an error. For InterBase errors, the first element of the status vector is set to 1, and the second element is set to an InterBase error code.

To check for an InterBase error, examine the first two elements of the status vector directly.

See also isc_close_blob()

u Back to top

isc_cancel_events()

Cancels an application’s interest in asynchronous notification of any of a specified group of events.

    Syntax  ISC_STATUS isc_cancel_events(
                     ISC_STATUS *status_vector,
                     isc_db_handle *db_handle,
                     ISC_LONG *event_id);

Parameter | Type | Description
status_vector | ISC_STATUS * | Pointer to the error status vector
db_handle | isc_db_handle * | Pointer to a database handle set by a previous call to isc_attach_database(); the handle identifies the database for which the event watch is to be canceled. db_handle returns an error in status_vector if it is NULL
event_id | ISC_LONG * | Pointer to the event or events to cancel; set by a previous call to isc_que_events()

Description isc_cancel_events() cancels an application program’s asynchronous wait for any of a specified list of events. The events are the ones that were associated with event_id as a result of a previous call to isc_que_events().

Example The following call cancels a program’s wait for events associated with event_id, where event_id was previously returned from a call to isc_que_events():

    isc_cancel_events(status_vector, &database_handle, &event_id);

A more complete example is provided in the section on isc_que_events().

Return Value isc_cancel_events() returns the second element of the status vector. Zero indicates success. A nonzero value indicates an error. For InterBase errors, the first element of the status vector is set to 1, and the second element is set to an InterBase error code.

To check for an InterBase error, examine the first two elements of the status vector directly.

See also isc_que_events()

u Back to top

isc_close_blob()

Closes an open Blob, which involves flushing any remaining segments, releasing system resources associated with Blob update or retrieval, and setting the Blob handle to zero.

    Syntax  ISC_STATUS isc_close_blob(
                     ISC_STATUS *status_vector,
                     isc_blob_handle *blob_handle);

Parameter | Type | Description
status_vector | ISC_STATUS * | Pointer to the error status vector
blob_handle | isc_blob_handle * | Pointer to the handle of the Blob to close

Description isc_close_blob() is used to store a Blob in the database and clean up after Blob operations. Close any Blob after reading from or writing to it. If, for some reason, your application does not close a Blob, you can lose data. If your application might open a Blob without closing it then you should call isc_cancel_blob() to make sure that the application does not try to open a
Blob that is already open.

blob_handle is set by a call to isc_create_blob2() or to isc_open_blob2().

Example The following example closes a Blob and frees system resources:

    if (status_vector[1] == isc_segstr_eof)
      isc_close_blob(status_vector, &blob_handle)

Return Value isc_close_blob() returns the second element of the status vector. Zero indicates success. A nonzero value indicates an error. For InterBase errors, the first element of the status vector is set to 1, and the second element is set to an InterBase error code.

To check for an InterBase error, examine the first two elements of the status vector directly.

See also isc_cancel_blob(), isc_create_blob2(), isc_open_blob2()

u Back to top

isc_commit_retaining()

Commits an active transaction and retains the transaction context after a commit.

    Syntax  ISC_STATUS isc_commit_retaining(
                     ISC_STATUS *status_vector,
                     isc_tr_handle *trans_handle);

Parameter | Type | Description
status_vector | ISC_STATUS * | Pointer to the error status vector
trans_handle | isc_tr_handle * | Pointer to a transaction handle whose value has been set by a previous isc_start_transaction() call; trans_handle returns an error if NULL

Description isc_commit_retaining() commits an active transaction and immediately clones itself. This means that the function retains the transaction name, system resources associated with the transaction, and the current state of any open cursors in the transaction. Although the function is actually initiating a new transaction, by assigning the new transaction the active transaction handle it is, in effect, keeping the transaction open across commits. This results in improved performance by allowing an application to minimize the overhead of initiating additional transactions. isc_commit_retaining() allows you to commit updates while keeping a cursor open.

You can initiate a rollback within the active transaction but the rollback only affects uncommitted updates. In other words, a rollback is legal, even after the transaction context has been passed to the cloned transaction, but, in that case, the rollback will only affect the updates your application has made to the database since the last commit.

To audit the commits made by your calls to this function, check the first element in the status vector to see if the call was successful. If this element contains a zero, the call was successful.

The transaction ends when you commit or roll back without using the retention feature, with a call to isc_commit_transaction() or isc_rollback_transaction().

Examples The following C/C++ code commits a transaction, prints a message, and starts a new transaction with the same handle within the same request:

    if (!isc_commit_retaining(status, &retained_trans))
    {
      fprintf(stderr, "Committed and retained\n");
      isc_print_status(status);
    }

The following call commits a transaction, prints a confirmation message, starts a new transaction with the same handle within the same request, or, if the commit fails, prints an error message and rolls back.

    isc_commit_retaining(status, &retained_trans);
    if (status[0] == 1 && status[1])
    {
      fprintf(stderr, "Error during commit, rolling back.\n");
      rb_status = isc_rollback_transaction(status, &retained_trans);
    }
    else
    {
      fprintf(stderr, "Commit successful.\n");
      tr_count++; /*Increments the number of recycles. */
    }

Return Value isc_commit_retaining() returns the second element of the status vector. Zero indicates success. A nonzero value indicates an error. For InterBase errors, the first element of the status vector is set to 1, and the second element is set to an InterBase error code.

To check for an InterBase error, examine the first two elements of the status vector directly.

See also isc_commit_transaction(), isc_rollback_transaction(), isc_start_transaction()

u Back to top

isc_commit_transaction()

Commits a specified active transaction.

    Syntax  ISC_STATUS isc_commit_transaction(
                     ISC_STATUS *status_vector,
                     isc_tr_handle *trans_handle);

Parameter | Type | Description
status_vector | ISC_STATUS * | Pointer to the error status vector
trans_handle | isc_tr_handle * | Pointer to a transaction handle whose value has been set by a previous isc_start_transaction() call; trans_handle returns an error if NULL

Description isc_commit_transaction() closes record streams, frees system resources, and sets the transaction handle to zero for the specified transaction.

When you call this function to execute a commit operation against multiple databases, InterBase first initiates a call to the isc_prepare_transaction() function. isc_prepare_transaction() executes the first phase of a two-phase commit. This puts the transaction into limbo and signals your intention to commit, so that InterBase can poll all target databases to verify that they are ready to accept the commit. Also, isc_commit_transaction() writes a Blob message to the RDB$TRANSACTION_DESCRIPTION column of the RDB$TRANSACTIONS system table, detailing information required by InterBase to perform a reconnect in case of system failure during the commit process.

The isc_commit_transaction() function also performs the second phase of a two-phase commit upon receiving verification that all databases are ready to accept the commit. Also, isc_commit_transaction() cleans up RDB$TRANSACTIONS.

Example The following call commits a transaction and prints a message:

    isc_commit_transaction(status, &trans);
    if (status[0] == 1 && status[1])
    {
      fprintf(stderr, "Error on write\n");
      isc_print_status(status);
    }

Return Value isc_commit_transaction() returns the second element of the status vector. Zero indicates success. A nonzero value indicates an error. For InterBase errors, the first element of the status vector is set to 1, and the second element is set to an InterBase error code.

To check for an InterBase error, examine the first two elements of the status vector directly.

See also isc_commit_retaining(), isc_prepare_transaction()

isc_create_blob2()

Creates and opens the Blob for write access, and optionally specifies the filters to be used to translate the Blob from one subtype to another.

    Syntax  ISC_STATUS isc_create_blob2(
                     ISC_STATUS *status_vector,
                     isc_db_handle *db_handle,
                     isc_tr_handle *trans_handle,
                     isc_blob_handle *blob_handle,
                     ISC_QUAD *blob_id,
                     short bpb_length,
                     char *bpb_address);

Parameter | Type | Description
status_vector | ISC_STATUS * | Pointer to the error status vector
db_handle | isc_db_handle * | Pointer to a database handle set by a previous call to isc_attach_database() db_handle returns an error in status_vector if it is NULL
trans_handle | isc_tr_handle * | Pointer to the handle of the transaction in which you want the Blob to be created
blob_handle | isc_blob_handle * | Pointer to the Blob handle
blob_id | ISC_QUAD * | Pointer to the 64-bit system-defined Blob ID, which is stored in a field in the table and points to the first segment of the Blob or to a page of pointers to Blob fragments
bpb_length | short | Length of the Blob parameter buffer (BPB)
bpb_address | char * | Pointer to the BPB

Description isc_create_blob2() creates a context for storing a Blob, opens a Blob for write access, and optionally specifies the filters used to translate from one Blob format to another. Subsequent calls to isc_put_segment() write data from an application buffer to the Blob.

If a Blob filter is used, it is called for each segment written to the Blob. InterBase selects the filter to be used based on the source and target subtypes specified in a previously populated Blob parameter buffer (BPB), pointed to by bpb_address.

If a Blob filter is not needed or cannot be used, a BPB is not needed; pass 0 for bpb_length and NULL for bpb_address.

The Blob handle pointed to by blob_handle must be zero when isc_create_blob2() is called. To reuse blob_handle, close the Blob with a call to isc_close_blob() to zero out the handle before calling isc_create_blob2().

On success, isc_create_blob2() assigns a unique ID to blob_handle, and a Blob identifier to blob_id. Subsequent API calls require one or both of these to identify the Blob against which they operate.

After a blob is created, data can be written to it by a sequence of calls to isc_put_segment(). When finished writing to the Blob, close it with isc_close_blob().

When you create a Blob, it is essentially an “orphan” until you assign its blob_id to a particular Blob column of a particular row of a table. You do this, after closing the Blob, by using DSQL to execute either an INSERT statement to insert a new row containing the Blob (and any other columns desired), or an UPDATE statement to replace an existing Blob with the new one.

For more information about BPBs and Blob filters, see Chapter 7, “Working with Blob Data.”

Example The following fragment declares a BPB, populates it with filter information, then creates a Blob and passes the BPB:

    isc_blob_handle blob_handle; /* declare at beginning */
    ISC_QUAD blob_id; /* declare at beginning */
    char bpb[] = {
      isc_bpb_version1,
      isc_bpb_target_type,
      1,    /* # bytes that follow which specify target subtype */
      1,    /* target subtype (TEXT) */
      isc_bpb_source_type,
      1,    /* # bytes that follow which specify source subtype */
      -4,   /* source subtype*/
      };

    . . .

    isc_create_blob2(
      status_vector,
      &db_handle,
      &tr_handle,
      &blob_handle,  /* to be filled in by this function */
      &blob_id,     /* to be filled in by this function */
      actual_bpb_length,  /* length of BPB data */
      &bpb          /* Blob parameter buffer */
      )

Return Value isc_create_blob2() returns the second element of the status vector. Zero indicates success. A nonzero value indicates an error. For InterBase errors, the first element of the status vector is set to 1, and the second element is set to an InterBase error code.

To check for an InterBase error, examine the first two elements of the status vector directly.

See also isc_blob_gen_bpb2(), isc_open_blob2(), isc_put_segment()

u Back to top

isc_create_database()

The isc_create_database() method is not currently supported from user applications. It is for internal use only. Use isc_dsql_execute_immediate() to create a database with a valid database handle.

isc_database_info()

Reports requested information about a previously attached database.

    Syntax  ISC_STATUS isc_database_info(
                     ISC_STATUS *status_vector,
                     isc_db_handle *db_handle,
                     short item_list_buffer_length,
                     char *item_list_buffer,
                     short result_buffer_length,
                     char *result_buffer);

Parameter | Type | Description
status_vector | ISC_STATUS * | Pointer to the error status vector
db_handle | isc_db_handle * | Pointer to a database handle set by a previous call to isc_attach_database() db_handle returns an error in status_vector if it is NULL
item_list_buffer_length | short | Number of bytes in the item-list buffer
item_list_buffer | char * | Address of the item-list buffer
result_buffer_length | short | Number of bytes in the result buffer
result_buffer | char * | Address of the result buffer

Description isc_database_info() returns information about an attached database. Typically, isc_database_info() is called to:

• Determine how much space is used for page caches. The space is the product of the number of buffers and the page size, which are determined by calling isc_database_info() with the isc_info_num_buffers and isc_info_page_size item-list options.

• Monitor performance. For example, to compare the efficiency of two update strategies, such as updating a sorted or unsorted stream.

The calling program passes its request for information through the item-list buffer supplied by the program, and InterBase returns the information to a program-supplied result buffer.

Example The following program fragment requests the page size and the number of buffers, then examines the result buffer to retrieve the values supplied by the InterBase engine:

    char db_items[] = {
      isc_info_page_size, isc_info_num_buffers,
      isc_info_end};
    char res_buffer[40], *p, item;
    int length;
    SLONG page_size = 0L, num_buffers = 0L;
    ISC_STATUS status_vector[20];

    isc_database_info(
      status_vector,
      &handle, /* Set in previous isc_attach_database() call. */
      sizeof(db_items),
      db_items,
      sizeof(res_buffer),
      res_buffer);
    if (status_vector[0] == 1 && status_vector[1])
    {
      /* An error occurred. */
      isc_print_status(status_vector);
      return(1);
    };
    /* Extract the values returned in the result buffer. */
    for (p = res_buffer; *p != isc_info_end ;)
    {
      item = *p++;
      length = isc_portable_integer (p, 2);
      p += 2;
      switch (item)
      {
         case isc_info_page_size:
            page_size = isc_portable_integer (p, length);
            break;
         case isc_info_num_buffers:
            num_buffers = isc_portable_integer (p, length);
            break;
         default:
            break;
      }
      p += length;
    };

Return Value isc_database_info() returns the second element of the status vector. Zero indicates success. A nonzero value indicates an error. For InterBase errors, the first element of the status vector is set to 1, and the second element is set to an InterBase error code.

To check for an InterBase error, examine the first two elements of the status vector directly. For more information about examining the status vector, see Chapter 10, “Handling Error Conditions.”

See also isc_attach_database(), isc_detach_database()

u Back to top

isc_decode_sql_date()

Translates a date from InterBase ISC_DATE format into the C struct tm format.

    Syntax  void isc_decode_sql_date(
                     ISC_DATE *ib_date,
                     void *tm_date);

Parameter | Type | Description
ib_date | ISC_DATE * | Pointer to a four-byte ISC_DATE structure containing a date in InterBase format
tm_date | void * | Pointer to a C tm structure

Description isc_decode_sql_date() translates a date retrieved from a table and stored in an ISC_DATE variable, ib_date, into a C time structure for program manipulation. Both ib_date and tm_date must be declared and initialized before use.

Use the isc_dsql family of API calls to retrieve InterBase DATE data from a table into the ISC_DATE structure prior to translation.

Note In InterBase 6 and later, the DATE datatype is available only in dialect 3. It holds only date information, and does not include time information. In dialect 1, the TIMESTAMP datatype holds both date and time information and is exactly equivalent to the DATE datatype that was present in earlier versions of InterBase.

Example The following code fragment illustrates declaring time structures and calling isc_decode_sql_date() to translate an InterBase date format into a C time format:

    #include <time.h>
    #include <ibase.h>
    . . .
    struct tm hire_time;
    ISC_DATE hire_date;
    . . .
    /* Retrieve DATE data from a table here. */
    . . .
    isc_decode_sql_date(&hire_date, &hire_time);

Return Value None.

See also isc_decode_sql_time(), isc_decode_timestamp(), isc_encode_sql_date()

u Back to top

isc_decode_sql_time()

Translates a time from InterBase ISC_TIME format into the C struct tm format.

    Syntax  void isc_decode_sql_time(
                     ISC_TIME *ib_time,
                     void *tm_date);

Parameter | Type | Description
ib_time | ISC_TIME * | Pointer to a four-byte ISC_TIME structure containing a time in InterBase format
tm_date | void * | Pointer to a C struct tm structure

Description isc_decode_sql_time() translates a time retrieved from a table and stored in an ISC_TIME variable, ib_time, into a C time structure for program manipulation. Both ib_time and tm_date must be declared and initialized before use.

Use the isc_dsql family of API calls to retrieve InterBase TIME data from a table into the ISC_TIME structure prior to translation.

Note isc_decode_sql_time() does not support milliseconds, because encode/decode functions use the structure struct tm from time.h, which does not support a fractional part for seconds.

Example The following code fragment illustrates declaring time structures and calling isc_decode_sql_time() to translate an InterBase date format into a C time format:

    #include <time.h>
    #include <ibase.h>
    . . .
    struct tm hire_time;
    ISC_TIME hire_date;
    . . .
    /* Retrieve TIME data from a table here. */
    . . .
    isc_decode_sql_time(&hire_date, &hire_time);

Return Value None.

See also isc_decode_sql_date(), isc_decode_sql_time(), isc_encode_sql_date()

u Back to top

isc_decode_timestamp()

Translates a date and time from InterBase ISC_TIMESTAMP format into the C struct tm format.

    Syntax  void isc_decode_timestamp(
                     ISC_TIMESTAMP *ib_date,
                     void *tm_date);

Parameter | Type | Description
ib_timestamp | ISC_TIMESTAMP * | Pointer to an eight-byte ISC_TIMESTAMP structure containing a date and time in InterBase format
tm_date | void * | Pointer to a C struct tm structure

Description isc_decode_timestamp() translates a date retrieved from a table and stored in an ISC_TIMESTAMP variable, ib_timestamp, into a C time structure for program manipulation. Both ib_timestamp and tm_date must be declared and initialized before use. The isc_decode_timestamp() is exactly the same as the isc_decode_date() function in versions of InterBase prior to 6.0.

Use the isc_dsql family of API calls to retrieve InterBase TIMESTAMP data from a table into the ISC_TIMESTAMP structure prior to translation.

Note isc_decode_timestamp() does not support milliseconds, because encode/decode functions use the structure struct tm from time.h, which does not support a fractional part for seconds.

Example The following code fragment illustrates declaring time structures and calling isc_decode_sql_timestamp() to translate an InterBase date format into a C time format:

    #include <time.h>
    #include <ibase.h>
    . . .
    struct tm hire_time;
    ISC_TIMESTAMP hire_date;
    . . .
    /* Retrieve TIMESTAMP data from a table here. */
    . . .
    isc_decode_timestamp(&hire_date, &hire_time);

Return Value None.

See also isc_decode_sql_date(), isc_decode_sql_time(), isc_encode_sql_date()

u Back to top

isc_delete_user()

Deletes a user record from the InterBase security database (admin.ib by default).

Note Use of this function is deprecated. It is replaced by a full featured Services API. See Chapter 12, “Working with Services” on page 12-1 and the reference entry for “isc_service_start()” on page 15-148.

    Syntax  ISC_STATUS isc_delete_user(
                     ISC_STATUS *status
                     USER_SEC_DATA *user_sec_data);

Parameter | Type | Description
status vector | ISC_STATUS * | Pointer to the error status vector
user_sec_data | USER_SEC_DATA * | Pointer to a struct that is defined in ibase.h

Description The three security functions, isc_add_user(), isc_delete_user(), and isc_modify_user() mirror functionality that is available in the gsec command-line utility. isc_delete_user() deletes a record from the InterBase security database.

At a minimum, you must provide the user name. If the server is not local, you must provide both a server name and a protocol. Valid choices for the protocol field are sec_protocol_tcpip, sec_protocol_netbeui, and sec_protocol_local.

InterBase reads the settings for the ISC_USER and ISC_PASSWORD environment variables if you do not provide a DBA user name and password.

The definition for the USER_SEC_DATA struct in ibase.h is as follows:

    typedef struct {
      short  sec_flags;  /* which fields are specified */
      int    uid;         /* the user's id */
      int    gid;         /* the user's group id */
      int    protocol;    /* protocol to use for connection */
      char   *server;     /* server to administer */
      char   *user_name;  /* the user's name */
      char   *password;  /* the user's password */
      char   *group_name; /* the group name */
      char   *first_name; /* the user's first name */
      char   *middle_name; /* the user's middle name */
      char   *last_name; /* the user's last name */
      char   *dba_user_name; /* the dba user name */
      char   *dba_password; /* the dba password */
    } USER_SEC_DATA;

When you pass this struct to one of the three security functions, you can tell it which fields you have specified by doing a bitwise OR of the following values, which are defined in ibase.h:

    sec_uid_spec                0x01
    sec_gid_spec                0x02
    sec_server_spec             0x04
    sec_password_spec           0x08
    sec_group_name_spec         0x10
    sec_first_name_spec         0x20
    sec_middle_name_spec        0x40
    sec_last_name_spec          0x80
    sec_dba_user_name_spec      0x100
    sec_dba_password_spec       0x200

No bit values are available for user name and password, since they are required.

The following error messages exist for this function:

Table 15.19 Error messages for isc_deleteuser()

Code | Value | Description
isc_usrname_too_long | 335544747 | The user name passed in is greater than 31 bytes
isc_password_too_long | 335544748 | The password passed in is longer than 8 bytes
isc_usrname_required | 335544749 | The operation requires a user name
isc_password_required | 335544750 | The operation requires a password
isc_bad_protocol | 335544751 | The protocol specified is invalid
isc_dup_usrname_found | 335544752 | The user name being added already exists in the security database.
isc_usrname_not_found | 335544753 | The user name was not found in the security database
isc_error_adding_sec_record | 335544754 | An unknown error occurred while adding a user
isc_error_deleting_sec_record | 335544755 | An unknown error occurred while deleting a user
isc_error_modifying_sec_record | 335544756 | An unknown error occurred while modifying a user
isc_error_updating_sec_db | 335544757 | An unknown error occurred while updating the security database

Example The following example deletes a user (“Socks”) from the password database, using the bitwise OR technique for passing values from the USER_SEC_DATA struct.

    {
      ISC_STATUS status[20];
      USER_SEC_DATA sec;

      sec.server      = "kennel";
      sec.dba_user_name = "sysdba";
      sec.dba_password = "masterkey";
      sec.protocol    = sec_protocol_tcpip;
      sec.user_name   = "socks";
      sec.sec_flags   = sec_server_spec
                      | sec_dba_user_name_spec
                      | sec_dba_password_name_spec;

      isc_delete_user(status, &sec);
      /* check status for errors */
      if (status[0] == 1 && status[1])
      {
         switch (status[1]) {
         case isc_usrname_too_long:
            printf("Security database cannot accept long user names\n");
            break;
         ...
         }
      }
    }

Return Value isc_delete_user() returns the second element of the status vector. Zero indicates success. A nonzero value indicates an error. See the “Description” section for this function for a list of error codes.

See also isc_add_user(), isc_modify_user()

u Back to top

isc_detach_database()

Detaches from a database previously connected with isc_attach_database().

    Syntax  ISC_STATUS isc_detach_database(
                     ISC_STATUS *status_vector,
                     isc_db_handle *db_handle);

Parameter | Type | Description
status_vector | ISC_STATUS * | Pointer to the error status vector
db_handle | isc_db_handle * | Pointer to a database handle set by a previous call to isc_attach_database() db_handle returns an error in status_vector if it is NULL

Description isc_detach_database() detaches an attached database. Call this function to release system resources when you are done using a database or before re-attaching the database with different attach parameters. isc_detach_database() also releases the buffers and structures that control the remote interface on the client and the remote server where the database is stored.

Before calling isc_detach_database() commit or roll back transactions affecting the database from which you want to detach.

Example The following conditional statement detaches a database:

    if (handle)
      isc_detach_database(status_vector, &handle);

Assuming that handle is valid and identifies an attached database, the specified database is detached when this statement executes.

Return Value isc_detach_database() returns the second element of the status vector. Zero indicates success. A nonzero value indicates an error. For InterBase errors, the first element of the status vector is set to 1, and the second element is set to an InterBase error code.

To check for an InterBase error, examine the first two elements of the status vector directly.

See also isc_attach_database()

u Back to top

isc_drop_database()

Deletes a currently attached database and all of its supporting files, such as secondary database files, write-ahead log files, and shadow files.

    Syntax  ISC_STATUS isc_drop_database(
                     ISC_STATUS *status_vector,
                     isc_db_handle *db_handle);

Parameter | Type | Description
status_vector | ISC_STATUS * | Pointer to the error status vector
db_handle | isc_db_handle * | Pointer to a database handle set by a previous call to isc_attach_database(); the handle identifies the database containing the array column db_handle returns an error in status_vector if it is NULL

Description isc_drop_database() deletes an attached database and all of its supporting files. Call this routine when you no longer have a use for the database (for example, if you moved all the data into another database, or if the database was just temporary and is no longer needed). To succeed, isc_drop_database() must be issued when no other processes are attached to the database.

Example The following conditional statement drops a database:

    if (handle)
      isc_drop_database(status_vector, &handle);

Assuming that handle is valid and identifies an attached database, the specified database is dropped when this statement executes.

Return Value isc_drop_database() returns the second element of the status vector. Zero indicates success. A nonzero value indicates an error. For InterBase errors, the first element of the status vector is set to 1, and the second element is set to an InterBase error code.

To check for an InterBase error, examine the first two elements of the status vector directly.

See also isc_attach_database()

u Back to top

isc_dsql_allocate_statement()

Allocates a statement handle for subsequent use with other API dynamic SQL (DSQL) calls.

    Syntax  ISC_STATUS isc_dsql_allocate_statement(
                     ISC_STATUS *status_vector,
                     isc_db_handle *db_handle,
                     isc_stmt_handle *stmt_handle);

Parameter | Type | Description
status_vector | ISC_STATUS * | Pointer to the error status vector
db_handle | isc_db_handle * | Pointer to a database handle set by a previous call to isc_attach_database() db_handle returns an error in status_vector if it is NULL
stmt_handle | isc_stmt_handle * | Pointer to the statement handle to be allocated by this function; the handle must be NULL when this function is called, or an error is returned in status_vector

Description isc_dsql_allocate_statement() allocates a statement handle and returns a pointer to it in stmt_handle. This pointer is passed to isc_dsql_prepare() to associate the statement handle with a particular DSQL statement for processing.

If a DSQL statement is to be executed multiple times, or if it returns output (other than the results from a stored procedure), isc_dsql_allocate_statement() or isc_dsql_alloc_statement2() should be called to allocate a statement handle prior to preparing and executing the statement with isc_dsql_prepare() and isc_dsql_execute().

Note The function, isc_dsql_allocate_statement(), is very similar to the function, isc_dsql_alloc_statement2() except that statement handles allocated using isc_dsql_allocate_statement() are not automatically reset to NULL when the database under which they are allocated is detached. To reset statement handles automatically, use isc_dsql_alloc_statement2().

When you are done processing a statement, the statement handle can be freed with the isc_dsql_free_statement() or by calling isc_detach_database().

Example The following program fragment allocates a statement handle for a SQL statement that will access the database referenced by the database handle, database_handle:

    ISC_STATUS status_vector[20];
    isc_stmt_handle statement_handle;

    statement_handle = NULL; /* Set handle to NULL before allocating it. */
    isc_dsql_allocate_statement(
      status_vector,
      &database_handle, /* Set in previous isc_attach_database() call. */
      &statement_handle);
    if (status_vector[0] == 1 && status_vector[1])
    {
      isc_print_status(status_vector); /* Display error message. */
      return(1);  /* Return now. */
    }
    /* Call other functions to associate a particular SQL statement with the
    * statement handle, and to do other operations necessary to prepare and execute
    * the DSQL statement. Free the statement handle when it is no longer needed. */

Return Value isc_dsql_allocate_statement() returns the second element of the status vector. Zero indicates success. A nonzero value indicates an error. For InterBase errors, the first element of the status vector is set to 1, and the second element is set to isc_bad_stmt_handle, isc_bad_db_handle, or another InterBase error code.

To check for an InterBase error, examine the first two elements of the status vector directly.

See also isc_dsql_alloc_statement2(), isc_dsql_execute(), isc_dsql_free_statement(), isc_dsql_prepare()

u Back to top

isc_dsql_alloc_statement2()

Allocates a statement handle for subsequent use with other API dynamic SQL (DSQL) calls.

    Syntax  ISC_STATUS isc_dsql_alloc_statement2(
                     ISC_STATUS *status_vector,
                     isc_db_handle *db_handle,
                     isc_stmt_handle *stmt_handle);

Parameter | Type | Description
status_vector | ISC_STATUS * | Pointer to the error status vector
db_handle | isc_db_handle * | Pointer to a database handle set by a previous call to isc_attach_database(); the handle identifies the database containing the array column db_handle returns an error in status_vector if it is NULL
stmt_handle | isc_stmt_handle * | Pointer to the statement handle to be allocated by this function; the handle must be NULL when this function is called, or an error is returned in status_vector

Description isc_dsql_alloc_statement2() allocates a statement handle and returns a pointer to it in stmt_handle. This pointer is passed to isc_dsql_prepare() to associate the statement handle with a particular DSQL statement for processing.

If a DSQL statement is to be executed multiple times, or if it returns output (other than the results from a stored procedure), isc_dsql_alloc_statement2() or isc_dsql_allocate_statement() should be called to allocate a statement handle prior to preparing and executing the statement with isc_dsql_prepare() and isc_dsql_execute().

Note The isc_dsql_allocate_statement2() function is similar to the isc_dsql_alloc_statement() function except that statement handles allocated using isc_dsql_allocate_statement2() are automatically reset to NULL when the database under which they are allocated is detached.

Example The following program fragment allocates a statement handle for a SQL statement that will access the database referenced by the database handle, database_handle:

    ISC_STATUS status_vector[20];
    isc_stmt_handle statement_handle;

    isc_dsql_alloc_statement2(
      status_vector,
      &database_handle, /* Set in previous isc_attach_database() call. */
      &statement_handle);
    if (status_vector[0] == 1 && status_vector[1])
    {
      isc_print_status(status_vector); /* Display an error message. */
      return(1); /* Return now. */
    }
    ;
    /* Call other functions to associate a particular SQL statement with the
     * statement handle, and to do other operations necessary to prepare and
     * execute the DSQL statement. */

Return Value isc_dsql_alloc_statement2() returns the second element of the status vector. Zero indicates success. A nonzero value indicates an error. For InterBase errors, the first element of the status vector is set to 1, and the second element is set to isc_bad_stmt_handle, isc_bad_db_handle, or another InterBase error code.

To check for an InterBase error, examine the first two elements of the status vector directly.

See also isc_dsql_allocate_statement(), isc_dsql_execute(), isc_dsql_free_statement(), isc_dsql_prepare()

u Back to top

isc_dsql_describe()

Provides information about columns retrieved by the execution of a DSQL SELECT or EXECUTE PROCEDURE statement.

    Syntax  ISC_STATUS isc_dsql_describe(
                     ISC_STATUS *status_vector,
                     isc_stmt_handle *stmt_handle,
                     unsigned short da_version,
                     XSQLDA *xsqlda);

Parameter | Type | Description
status_vector | ISC_STATUS * | Pointer to the error status vector
stmt_handle | isc_stmt_handle * | Pointer to a statement handle previously allocated with isc_dsql_allocate_statement() or isc_dsql_alloc_statement2(); the handle returns an error in status_vector if it is NULL
da_version | unsigned short | Specifies that the XSQLDA descriptor, rather than SQLDA, should be used; set this value to 1
xsqlda | XSQLDA * | Pointer to a previously allocated XSQLDA used for output

Description isc_dsql_describe() stores into XSQLDA a description of the columns that make up the rows returned for a SELECT statement, or a description of the result values returned by an EXECUTE PROCEDURE statement. These statements must have been previously prepared for execution with isc_dsql_prepare(), before isc_dsql_describe() can be called.

Note Using isc_dsql_describe() is not necessary unless a previously issued isc_dsql_prepare() function indicates that there is insufficient room in the output XSQLDA for the return values of the DSQL statement to be executed.

Example The following program fragment illustrates a sequence of calls which allocates an XSQLDA, prepares a statement, checks whether or not the appropriate number of XSQLVAR s was allocated, and corrects the situation if needed.

    #include <ibase.h>
    ISC_STATUS status_vector[20];
    XSQLDA *osqlda;
    int n;
    char *query =  "SELECT * FROM CITIES
      WHERE STATE = 'NY'
      ORDER BY CITY DESCENDING";

    osqlda = (XSQLDA *)malloc(XSQLDA_LENGTH(3);
    osqlda->version = SQLDA_CURRENT_VERSION;
    osqlda->sqln = 3;

    isc_dsql_prepare(
      status_vector,
      &tr_handle,  /* Set in previous isc_start_transaction() call. */
      &stmt_handle,
       /* Allocated previously by isc_dsql_allocate_statement()
         or isc_dsql_alloc_statement2() call. */
      0,
      query,
      1,
      osqlda);
    if (status_vector[0] == 1 && status_vector[1])
    {
      /* Process error. */
      isc_print_status(status_vector);
      return(1);
    }

    if (osqlda->sqld > osqlda->sqln) /* Need more XSQLVARS. */
    {
      n = osqlda->sqld;
      free(osqlda);
      osqlda = (XSQLDA *)malloc(XSQLDA_LENGTH(n);
      osqlda->sqln = n;
      osqlda->version = SQLDA_CURRENT_VERSION;
      isc_dsql_describe(
         status_vector,
         &stmt_handle,
         1,
         osqlda);
      if (status_vector[0] == 1 && status_vector[1])
      {
         /* Process error. */
         isc_print_status(status_vector);
         return(1);
      }
    }

Return Value isc_dsql_describe() returns the second element of the status vector. Zero indicates success. A nonzero value indicates an error. For InterBase errors, the first element of the status vector is set to 1, and the second element is set to isc_bad_stmt_handle, or another InterBase error code.

To check for an InterBase error, examine the first two elements of the status vector directly. For more information about examining the status vector, see Chapter 10, “Handling Error Conditions.”

See also isc_dsql_describe_bind(), isc_dsql_execute(), isc_dsql_execute2(), isc_dsql_prepare()

u Back to top

isc_dsql_describe_bind()

Provides information about dynamic input parameters required by a previously prepared DSQL statement.

    Syntax  ISC_STATUS isc_dsql_describe_bind(
                     ISC_STATUS *status_vector,
                     isc_stmt_handle *stmt_handle,
                     unsigned short da_version,
                     XSQLDA *xsqlda);

Parameter | Type | Description
status_vector | ISC_STATUS * | Pointer to the error status vector
stmt_handle | isc_stmt_handle * | Pointer to a statement handle previously allocated with isc_dsql_allocate_statement() or isc_dsql_alloc_statement2(); the handle returns an error in status_vector if it is NULL
da_version | unsigned short | Specifies that the XSQLDA descriptor, rather than SQLDA, should be used; set this value to 1
xsqlda | XSQLDA * | Pointer to a previously allocated XSQLDA used for input

Description isc_dsql_describe_bind() stores into the input XSQLDA xsqlda information about the dynamic input parameters required by a DSQL statement previously prepared with isc_dsql_prepare().

Before an application can execute a statement with input parameters, it must supply values for them in an input XSQLDA structure. If you know exactly how many parameters are required, and their datatypes, you can set up the XSQLDA directly without calling isc_dsql_describe_bind(). But if you need InterBase to analyze the statement and provide information such as the number of parameters and their datatypes, you must call isc_dsql_describe_bind() to supply the information.

Example The following program fragment illustrates a sequence of calls that allocates an input XSQLDA, prepares a DSQL UPDATE statement, calls the function isc_dsql_describe_bind(), checks whether or not the appropriate number of XSQLVAR s was allocated, and corrects the situation if necessary.

    #include <ibase.h>
    ISC_STATUS status_vector[20];
    XSQLDA *isqlda
    int n;
    char *str = "UPDATE DEPARTMENT SET BUDGET = ?, LOCATION = ?";

    isc_dsql_prepare(
      status_vector,
      &tr_handle,  /* Set in previous isc_start_transaction() call. */
      &stmt_handle,
      /* Allocated previously by isc_dsql_allocate_statement()
         or isc_dsql_alloc_statement2() call. */
      0,
      str,
      1,
      NULL);
    if (status_vector[0] == 1 && status_vector[1])
    {
       /* Process error. */
      isc_print_status(status_vector);
      return(1);
    }
    /* Allocate an input XSQLDA. */
    isqlda = (XSQLDA *)malloc(XSQLDA_LENGTH(1);
    isqlda->version = SQLDA_CURRENT_VERSION;
    isqlda->sqln = 1;
    isc_dsql_describe_bind(
      status_vector,
      &stmt_handle,
      /* Allocated previously by isc_dsql_allocate_statement()
         or isc_dsql_alloc_statement2() call. */
      1,
      isqlda);
    if (status_vector[0] == 1 && status_vector[1])
    {
      /* Process error. */
      isc_print_status(status_vector);
      return(1);
    }
    if (isqlda->sqld > isqlda->sqln) /* Need more XSQLVARs. */
    {
      n = isqlda->sqld;
      free(isqlda);
      isqlda = (XSQLDA *)malloc(XSQLDA_LENGTH(n);
      isqlda->sqln = n;
      isqlda->version = SQLDA_CURRENT_VERSION;
      isc_dsql_describe_bind(
            status_vector,
            &stmt_handle,
            1,
            isqlda);
      if (status_vector[0] == 1 && status_vector[1])
      {
          /* Process error. */
         isc_print_status(status_vector);
         return(1);
      }
    }

Return Value isc_dsql_describe_bind() returns the second element of the status vector. Zero indicates success. A nonzero value indicates an error. For InterBase errors, the first element of the status vector is set to 1, and the second element is set to isc_bad_stmt_handle, or another InterBase error code.

To check for an InterBase error, examine the first two elements of the status vector directly. For more information about examining the status vector, see Chapter 10, “Handling Error Conditions.”

See also isc_dsql_describe(), isc_dsql_execute(), isc_dsql_execute2(), isc_dsql_prepare()

isc_dsql_execute()

Executes a previously prepared DSQL statement.

    Syntax  ISC_STATUS isc_dsql_execute(
                     ISC_STATUS *status_vector,
                     isc_tr_handle *trans_handle,
                     isc_stmt_handle *stmt_handle,
                     unsigned short da_version,
                     XSQLDA *xsqlda);

Parameter | Type | Description
status_vector | ISC_STATUS * | Pointer to the error status vector
trans_handle | isc_tr_handle * | Pointer to a transaction handle whose value has been set by a previous isc_start_transaction() call; trans_handle returns an error if NULL
stmt_handle | isc_stmt_handle * | Pointer to a statement handle previously allocated with isc_dsql_allocate_statement() or isc_dsql_alloc_statement2(); returns an error in status_vector if NULL
da_version | unsigned short | Specifies that the XSQLDA descriptor, rather than SQLDA, should be used; set this value to 1
xsqlda | XSQLDA * | Pointer to a previously allocated XSQLDA used for input

Description isc_dsql_execute() executes a DSQL statement previously prepared with isc_dsql_prepare(). isc_dsql_execute() can be used to execute two types of statements:

• Statements that may return more than one row of data.

• Statements that need to be executed more than once.

If a statement to execute has input parameters, then isc_dsql_execute() requires an input XSQLDA to describe those parameters. It does not provide for an output XSQLDA. A call to isc_dsql_execute() that executes a SELECT statement results in the creation of a list containing all the rows of data that are the result of execution of the statement. To access these rows, call isc_dsql_fetch() in a loop. Each call to isc_dsql_fetch() fetches the next row from the select-list.

If the statement to be executed requires input parameter values (that is, if it contains parameter markers), these values must be supplied in the input XSQLDA xsqlda before calling isc_dsql_execute().

Note To execute a statement repeatedly when it both has input parameters and return values, such as EXECUTE PROCEDURE, use isc_dsql_execute2() which requires both an input and an output XSQLDA.

If you only need to execute a statement once, and it does not return any data, call isc_dsql_execute_immediate() instead of isc_dsql_prepare() and isc_dsql_execute(). To execute a statement with both input and output parameters a single time, use isc_dsql_exec_immed2().

Note CREATE DATABASE and SET TRANSACTION cannot be executed with isc_dsql_execute() or isc_dsql_execute2(). To execute these statements, use isc_dsql_execute_immediate().

Example The following program fragment illustrates calls to isc_dsql_execute() and isc_dsql_fetch(). It allocates input and output XSQLDA s, prepares a SELECT statement, executes it, and fetches and processes each row one-by-one.

    #include <ibase.h>
    ISC_STATUS status_vector[20], fetch_stat;
    XSQLDA *isqlda, *osqlda;
    XSQLVAR *ivar, *ovar;
    char *str = "SELECT CITY, POPULATION FROM CITIES WHERE STATE = ?";
    char *state = "CA";
    /* Allocate an output XSQLDA osqlda. */
    osqlda = (XSQLDA *)malloc(XSQLDA_LENGTH(2);
    osqlda->version = SQLDA_CURRENT_VERSION;
    osqlda->sqln = 2;

    /* Prepare the statement, including filling in osqlda with information about the
    select-list items to be returned by the statement. */
    isc_dsql_prepare(
      status_vector,
      &tr_handle,  /* Set in previous isc_start_transaction() call. */
      &stmt_handle,
         /* Allocated previously by isc_dsql_allocate_statement()
            or isc_dsql_alloc_statement2() call. */
      0,
      str,
      1,
      osqlda);
    if (status_vector[0] == 1 && status_vector[1])
    {
      /* Process error. */
      isc_print_status(status_vector);
      return(1);
    }

    /* Check to see whether or not the output XSQLDA had enough XSQLVARS allocated. If
    not, correct it -- see isc_dsql_describe(). */

    /* Allocate and fill in the input XSQLDA. This example assumes you know how many
    input parameters there are (1), and all other information necessary to supply a
    value. If this is not true, you will need to call isc_dsql_describe_bind(). */
    isqlda = (XSQLDA *)malloc(XSQLDA_LENGTH(1));
    isqlda->version = SQLDA_CURRENT_VERSION;
    isqlda->sqln = 1;
    isqlda->sqld = 1;
    ivar = isqlda->sqlvar[0];
    ivar->sqltype = SQL_TEXT;
    ivar->sqllen = sizeof(state);
    ivar->sqldata = state;

    /* Execute the statement. */
    isc_dsql_execute(
      status_vector,
      &tr_handle,  /* Set in previous isc_start_transaction() call. */
      &stmt_handle,
         /* Allocated previously by isc_dsql_allocate_statement()
            or isc_dsql_alloc_statement2() call. */
      1,
      isqlda);
    if (status_vector[0] == 1 && status_vector[1])
    {
      /* Process error. */
      isc_print_status(status_vector);
      return(1);
    }

    /* Set up an output XSQLVAR structure to allocate space for each item to be
    returned. */
    for (i=0, ovar = osqlda->sqlvar; i < osqlda->sqld; i++, ovar++)
    {
      dtype = (ovar->sqltype & ~1) /* Drop NULL bit for now. */
      switch(dtype)
         {
         case SQL_TEXT:
            ovar->sqldata = (char *)malloc(sizeof(char) * ovar->sqllen);
            break;
         case SQL_LONG:
            ovar->sqldata = (char *)malloc(sizeof(long));
         /* Process remaining types. */
            . . .
         }
      if (ovar->sqltype & 1)
      {
         /* Assign a variable to hold NULL status. */
         ovar->sqlind = (short *)malloc(sizeof(short));
      }
    } /* end of for loop */

    /* Fetch and process the rows in the select list one by one. */
    while ((fetch_stat = isc_dsql_fetch(
      status_vector,
      &stmt_handle,
      1,
      osqlda)) == 0)
    {
      for (i=0; i < osqlda->sqld; i++)
      {
         /* Call a function you’ve written to process each returned
         select-list item. */
         process_column(osqlda->sqlvar[i]);
      }
    }

Return Value isc_dsql_execute() returns the second element of the status vector. Zero indicates success. A nonzero value indicates an error. For InterBase errors, the first element of the status vector is set to 1, and the second element is set to isc_bad_stmt_handle, isc_bad_trans_handle, or another InterBase error code.

To check for an InterBase error, examine the first two elements of the status vector directly. For more information about examining the status vector, see Chapter 10, “Handling Error Conditions.”

See also isc_dsql_describe_bind(), isc_dsql_exec_immed2(), isc_dsql_execute_immediate(), isc_dsql_execute2(), isc_dsql_fetch(), isc_dsql_prepare()

u Back to top

isc_dsql_execute2()

Executes a previously prepared DSQL statement.

    Syntax  ISC_STATUS isc_dsql_execute2(
                     ISC_STATUS *status_vector,
                     isc_tr_handle *trans_handle,
                     isc_stmt_handle *stmt_handle,
                     unsigned short da_version,
                     XSQLDA *in_xsqlda,
                     XSQLDA *out_xsqlda);

Parameter | Type | Description
status_vector | ISC_STATUS * | Pointer to the error status vector
trans_handle | isc_tr_handle * | Pointer to a transaction handle whose value has been set by a previous isc_start_transaction() call; trans_handle returns an error if NULL
stmt_handle | isc_stmt_handle * | Pointer to a statement handle previously allocated with isc_dsql_allocate_statement() or isc_dsql_alloc_statement2(); the handle returns an error in status_vector if it is NULL
da_version | unsigned short | Specifies that the XSQLDA descriptor, rather than SQLDA, should be used; set this value to 1
in_xsqlda | XSQLDA * | Pointer to an optional, previously allocated XSQLDA used for input; if input parameters are not supplied, set this value to NULL
out_xsqlda | XSQLDA * | Pointer to an optional, previously allocated XSQLDA used for results of statement execution; if not required, set this value to NULL

Description isc_dsql_execute2() executes a previously prepared DSQL statement that has input parameters and returns results, such as EXECUTE PROCEDURE and SELECT.

If the statement to execute requires input parameter values (that is, if it contains parameter markers), these values must be supplied in the input XSQLDA, in_xsqlda before calling isc_dsql_execute2().

If the statement to execute returns values, they are placed in the specified output XSQLDA, out_xsqlda. If a NULL value is supplied for the output XSQLDA and the statement returns values, they are stored in a result set. To access the returned data, use isc_dsql_fetch() in a loop.

Tip If you just want to execute once a statement returning just one group of data, call isc_dsql_exec_immed2() instead of isc_dsql_prepare() and isc_dsql_execute2().

To execute a statement that does not return any data a single time, call isc_dsql_execute_immediate() instead of isc_dsql_prepare() and isc_dsql_execute2().

Note CREATE DATABASE and SET TRANSACTION cannot be executed with isc_dsql_execute() or isc_dsql_execute2(). To execute these statements, use isc_dsql_execute_immediate().

Example The following program fragment illustrates a sequence of calls that allocates an input XSQLDA and loads values into it, allocates an output XSQLDA, prepares an EXECUTE PROCEDURE statement, allocates space in the output XSQLDA for each column returned for each row retrieved by the call, and executes the prepared statement, placing return values in the output XSQLDA.

    #include <ibase.h>
    ISC_STATUS status_vector[20];
    XSQLDA *isqlda, *osqlda;
    XSQLVAR *ivar, *ovar;
    short null_flag;
    char *str = "EXECUTE PROCEDURE P1";
    char *state = "CA";
    /* Allocate an output XSQLDA osqlda. This example assumes you know that P1 will
    return one value. */
    osqlda = (XSQLDA *)malloc(XSQLDA_LENGTH(1);
    osqlda->version = SQLDA_CURRENT_VERSION;
    osqlda->sqln = 1;

    /* Prepare the statement, including filling in osqlda with information about the
    item to be returned by the statement (procedure). */
    isc_dsql_prepare(
      status_vector,
      &tr_handle,  /* Set in previous isc_start_transaction() call. */
      &stmt_handle,
      /* Allocated previously by isc_dsql_allocate_statement()
            or isc_dsql_alloc_statement2() call. */
      0,
      str,
      1,
      osqlda);
    if (status_vector[0] == 1 && status_vector[1])
    {
      /* Process error. */
      isc_print_status(status_vector);
      return(1);
    }

    /* Set up the output XSQLVAR structure to allocate space for the return value.
    Again, this example assumes you know that P1 returns just one value. For an
    example of what to do if you’re not sure, see isc_dsql_describe(). For an example
    of setting up an output XSQLVAR structure to allocate space for multiple return
    items, see the isc_dsql_execute() example program. */
    ovar = osqlda->sqlvar[0];
    dtype = (ovar->sqltype & ~1); /* Drop NULL bit for now. */
    switch(dtype)
    {
      case SQL_TEXT:
         ovar->sqldata = (char *)malloc(sizeof(char) * ovar->sqllen);
         break;
      case SQL_LONG:
         ovar->sqldata = (char *)malloc(sizeof(long));
      /* Process remaining types. */
      . . .
    }
    if (ovar->sqltype & 1)
    {
      /* Assign a variable to hold NULL status. */
      ovar->sqlind = &null_flag;
    }

    /* Allocate and fill in the input XSQLDA. This example assumes you know how many
    input parameters there are (1), and all other information necessary to supply a
    value. If this is not true, you will need to call isc_dsql_describe_bind(). */
    isqlda = (XSQLDA *)malloc(XSQLDA_LENGTH(1);
    isqlda->version = SQLDA_CURRENT_VERSION;
    isqlda->sqln = 1;
    isqlda->sqld = 1;
    ivar = isqlda->sqlvar[0];
    ivar->sqltype = SQL_TEXT;
    ivar->sqllen = sizeof(state);
    ivar->sqldata = state;

    /* Execute the statement. */
    isc_dsql_execute2(
      status_vector,
      &tr_handle,  /* Set in previous isc_start_transaction() call. */
      &stmt_handle,
      /* Allocated previously by isc_dsql_allocate_statement()
            or isc_dsql_alloc_statement2() call. */
      1,
      isqlda,
      osqlda);
    if (status_vector[0] == 1 && status_vector[1])
    {
      /* Process error. */
      isc_print_status(status_vector);
      return(1);
    }
    /* Now process the value returned in osqlda->sqlvar[0]. */
    . . .

Return Value isc_dsql_execute2() returns the second element of the status vector. Zero indicates success. A nonzero value indicates an error. For InterBase errors, the first element of the status vector is set to 1, and the second element is set to isc_bad_stmt_handle, isc_bad_trans_handle, or another InterBase error code.

To check for an InterBase error, examine the first two elements of the status vector directly. For more information about examining the status vector, see Chapter 10, “Handling Error Conditions.”

See also isc_dsql_exec_immed2(), isc_dsql_execute_immediate(), isc_dsql_execute(), isc_dsql_fetch(), isc_dsql_prepare()

u Back to top

isc_dsql_execute_immediate()

Prepares and executes just once a DSQL statement that does not return data. There is a special case of isc_dsql_execute_immediate() for creating databases.

    Syntax  ISC_STATUS isc_dsql_execute_immediate(
                     ISC_STATUS *status_vector,
                     isc_db_handle *db_handle,
                     isc_tr_handle *trans_handle,
                     unsigned short length,
                     char *statement,
                     unsigned short dialect,
                     XSQLDA *xsqlda);

Note In the special case where the statement is CREATE DATABASE, there is no transaction, so db_handle and trans_handle must be pointers to handles whose value is NULL. When isc_dsql_execute_immediate() returns, db_handle is a valid handle, just as though you had made a call to isc_attach_database().

Parameter | Type | Description
status_vector | ISC_STATUS * | Pointer to the error status vector
db_handle | isc_db_handle * | • If statement is not CREATE DATABASE, this is a pointer to a database handle set by a previous call to isc_attach_database(); db_handle returns an error in status_vector if it is NULL • If statement is CREATE DATABASE, this must point to a database handle whose value is NULL
trans_handle | isc_tr_handle * | • If statement is not CREATE DATABASE, this is a pointer to a transaction handle whose value has been set by a previous isc_start_transaction() call; trans_handle returns an error if NULL • If statement is CREATE DATABASE or SET TRANSACTION, this must point to a transaction handle whose value is NULL
length | unsigned short | Length of the DSQL statement in bytes; set to 0 in C programs to indicate a null-terminated string
statement | char * | DSQL string to be executed
dialect | unsigned short | • Indicates the SQL dialect of statement • Must be less than or equal to the SQL dialect of the client
xsqlda | XSQLDA * | Pointer to an optional, previously allocated XSQLDA used for input; if you don’t supply input parameters, set this value to NULL

Description isc_dsql_execute_immediate() prepares the DSQL statement specified in statement, executes it once, and discards it. The statement must not be one that returns data (that is, it must not be a SELECT or EXECUTE PROCEDURE statement).

If statement requires input parameter values (that is, if it contains parameter markers), these values must be supplied in the input XSQLDA, xsqlda.

To create a database using isc_dsql_execute_immediate(), supply a CREATE DATABASE statement and have db_handle and trans_handle point to handles with a NULL value.

Tip If statement returns data, or if it needs to be executed more than once, use isc_dsql_prepare() and isc_dsql_execute() (or isc_dsql_execute2()) instead of isc_dsql_execute_immediate().

Note You must call isc_dsql_execute_immediate() rather than isc_dsql_prepare() and isc_dsql_execute() for CREATE DATABASE or SET TRANSACTION. To start a transaction, you also have the option of using isc_start_transaction().

Examples The following program fragment calls isc_dsql_execute_immediate() to perform an insert:

    #include <ibase.h>
    ISC_STATUS status_vector[20];
    char *insert_stmt =
      "INSERT INTO CUSTOMER(CUSTNAME, BAL, CUSTNO)
      VALUES("John Smith", 299.0, 5050)";

    isc_dsql_execute_immediate(
      status_vector,
      &database_handle,  /* Set in previous isc_attach_database() call. */
      &tr_handle,  /* Set in previous isc_start_transaction() call. */
      0,
      insert_stmt,
      1,
      NULL);
    if (status_vector[0] == 1 && status_vector[1])
    {
      /* Process error. */
      isc_print_status(status_vector);
      return(1);
    }

The following C/C++ code fragment uses isc_dsql_execute_immediate() to create a database and return a handle to the new database:

    #include <ibase.h>
    ISC_STATUS status_vector[20];
    char *statement =
      "CREATE DATABASE 'C:/INVENTORY.IB' PAGE_SIZE 4096 \
         USER 'SYSDBA' PASSWORD 'masterkey'";
    isc_db_handle db_handle = NULL;
    isc_tr_handle dummy_handle = NULL;

    isc_dsql_execute_immediate(
      status_vector,
      &db_handle,
      &dummy_handle,
      0,
      statement,
      1,
      NULL);
    if (status_vector[0] == 1 && status_vector[1])
    {
      /* Process error. */
      isc_print_status(status_vector);
      return(1);
    }

Return Value isc_dsql_execute_immediate() returns the second element of the status vector. Zero indicates success. A nonzero value indicates an error. For InterBase errors, the first element of the status vector is set to 1, and the second element is set to isc_bad_db_handle, isc_bad_trans_handle, or another InterBase error code.

To check for an InterBase error, examine the first two elements of the status vector directly. For more information about examining the status vector, see Chapter 10, “Handling Error Conditions.”

See also isc_dsql_exec_immed2(), isc_dsql_execute(), isc_dsql_prepare()

For more information about creating and populating the XSQLDA, see “Understanding the XSQLDA” on page 6-6.

To check for an InterBase error, examine the first two elements of the status vector directly.

u Back to top

isc_dsql_exec_immed2()

Prepares and executes just once, a DSQL statement that returns no more than one row of data.

    Syntax  ISC_STATUS isc_dsql_exec_immed2(
                     ISC_STATUS *status_vector,
                     isc_db_handle *db_handle,
                     isc_tr_handle *trans_handle,
                     unsigned short length,
                     char *statement,
                     unsigned short dialect,
                     XSQLDA *in_xsqlda,
                     XSQLDA *out_xsqlda);

Parameter | Type | Description
status_vector | ISC_STATUS * | Pointer to the error status vector
db_handle | isc_db_handle * | Pointer to a database handle set by a previous call to isc_attach_database() db_handle returns an error in status_vector if it is NULL
trans_handle | isc_tr_handle * | Pointer to a transaction handle whose value has been set by a previous isc_start_transaction() call; trans_handle returns an error if NULL
length | unsigned short | Length of the DSQL statement, in bytes; set to 0 in C programs to indicate a null-terminated string
statement | char * | DSQL string to be executed
dialect | unsigned short | • Indicates the SQL dialect of statement • Must be less than or equal to the SQL dialect of the client
in_xsqlda | XSQLDA * | Pointer to an optional, previously allocated XSQLDA used for input; if input parameters are not supplied, set this value to NULL
out_xsqlda | XSQLDA * | Pointer to an optional, previously allocated XSQLDA used for results of statement execution. If not required, set this value to NULL

Description isc_dsql_exec_immed2() prepares the DSQL statement specified in statement, executes it once, and discards it. statement can return a single set of values (i.e, it can be an EXECUTE PROCEDURE or singleton SELECT) in the output XSQLDA.

If statement requires input parameter values (that is, if it contains parameter markers), these values must be supplied in the input XSQLDA, in_xsqlda.

For statements that return multiple rows of data, use isc_dsql_prepare(), isc_dsql_execute2(), and isc_dsql_fetch().

Example The following program fragment calls isc_dsql_exec_immed2():

    ISC_STATUS status_vector[20];
    XSQLDA *in_xsqlda, *out_xsqlda;
    char *execute_p1 = "EXECUTE PROCEDURE P1 ?";
    /* Set up input and output XSQLDA structures here. */
    . . .
    isc_dsql_exec_immed2(
      status_vector,
      &database_handle,  /* Set in previous isc_attach_database() call. */
      &tr_handle,  /* Set in previous isc_start_transaction() call. */
      0,
      execute_p1,
      1,
      in_xsqlda,
      out_xsqlda);
    if (status_vector[0] == 1 && status_vector[1]) {
      /* Process error. */
      isc_print_status(status_vector);
      return(1);
    }

Return Value isc_dsql_exec_immed2() returns the second element of the status vector. Zero indicates success. A nonzero value indicates an error. For InterBase errors, the first element of the status vector is set to 1, and the second element is set to isc_bad_db_handle, isc_bad_trans_handle, or another InterBase error code.

To check for an InterBase error, examine the first two elements of the status vector directly.

See also isc_dsql_execute2(), isc_dsql_prepare()

u Back to top

isc_dsql_fetch()

Retrieves data returned by a previously prepared and executed DSQL statement.

    Syntax  ISC_STATUS isc_dsql_fetch(
                     ISC_STATUS *status_vector,
                     isc_stmt_handle *stmt_handle,
                     unsigned short da_version,
                     XSQLDA *xsqlda);

Parameter | Type | Description
status_vector | ISC_STATUS * | Pointer to the error status vector
stmt_handle | isc_stmt_handle * | Pointer to a statement handle previously allocated with isc_dsql_allocate_statement() or isc_dsql_alloc_statement2(); the handle returns an error in status_vector if it is NULL
da_version | unsigned short | Specifies that the XSQLDA descriptor, rather than SQLDA, should be used; set this value to 1
xsqlda | XSQLDA * | Pointer to an optional, previously allocated XSQLDA used for results of statement execution

Description isc_dsql_fetch() retrieves one row of data into xsqlda each time it is called. It is used in a loop to retrieve and process each row of data for statements that return multiple rows in a cursor.

A cursor is a one-way pointer into the ordered set of rows retrieved by a statement. A cursor is only needed to process positioned UPDATE and DELETE statements made against the rows retrieved by isc_dsql_fetch() for SELECT statements that specify an optional FOR UPDATE OF clause.

It is up to the application to provide the loop construct for fetching the data.

Before calling isc_dsql_fetch(), a statement must be prepared with isc_dsql_prepare(), and executed with isc_dsql_execute() (or isc_dsql_execute2() with a NULL output xsqlda argument). Statement execution produces a result set containing the data returned. Each call to isc_dsql_fetch() retrieves the next available row of data from the result set into xsqlda.

Example The following program fragment illustrates a sequence of calls that allocates an output XSQLDA, prepares a statement for execution, allocates an XSQLVAR structure in the XSQLDA for each column of data to be retrieved, executes the statement, producing a select list of returned data, then fetches and processes each row in a loop:

    #include <ibase.h>
    #define LASTLEN 20
    #define FIRSTLEN 15
    #define EXTLEN 4
    typedef struct vary {
      short vary_length;
      char vary_string[1];
    } VARY;
    ISC_STATUS status_vector[20], retcode;
    long SQLCODE;
    XSQLDA *osqlda;
    XSQLVAR *ovar;
    short flag0, flag1, flag2;
    char *str =
         "SELECT last_name, first_name, phone_ext FROM phone_list
            WHERE location = "Monterey" ORDER BY last_name, first_name";
    char last_name[LASTLEN + 2];
    char first_name[FIRSTLEN + 2];
    char phone_ext[EXTLEN + 2];
    VARY *vary;
    /* Allocate an output XSQLDA osqlda. */
    osqlda = (XSQLDA *)malloc(XSQLDA_LENGTH(3);
    osqlda->version = SQLDA_CURRENT_VERSION;
    osqlda->sqln = 3;
    /* Prepare the statement. */
    isc_dsql_prepare(
      status_vector,
      &tr_handle,  /* Set in previous isc_start_transaction() call. */
      &stmt_handle,
      /* Allocated previously by isc_dsql_allocate_statement()
            or isc_dsql_alloc_statement2() call. */
      0,
      str,
      1,
      osqlda);
    if (status_vector[0] == 1 && status_vector[1])
    {
      /* Process error. */
      isc_print_status(status_vector);
      return(1);
    }
    /* Set up an output XSQLVAR structure to allocate space for each item to be
    returned. */
    osqlda->sqlvar[0].sqldata = last_name;
    osqlda->sqlvar[0].sqltype = SQL_VARYING + 1;
    osqlda->sqlvar[0].sqlind = &flag0;
    osqlda->sqlvar[1].sqldata = first_name;
    osqlda->sqlvar[1].sqltype = SQL_VARYING + 1;
    osqlda->sqlvar[1].sqlind = &flag1;
    osqlda->sqlvar[2].sqldata = phone_ext;
    osqlda->sqlvar[2].sqltype = SQL_VARYING + 1;
    osqlda->sqlvar[2].sqlind = &flag2;
    /* Execute the statement. */
    isc_dsql_execute(
      status_vector,
      &tr_handle,  /* Set in previous isc_start_transaction() call. */
      &stmt_handle,
         /* Allocated previously by isc_dsql_allocate_statement()
            or isc_dsql_alloc_statement2() call. */
      1,
      NULL);
    if (status_vector[0] == 1 && status_vector[1])
    {
      /* Process error. */
      isc_print_status(status_vector);
      return(1);
    }

    printf("\n%-20s %-15s %-10s\n\n", "LAST NAME", "FIRST NAME", "EXTENSION");
    /* Fetch and print the records in the select list one by one. */
    while ((retcode = isc_dsql_fetch(
      status_vector,
      &stmt_handle,
      1,
      osqlda)) == 0)
    {
      vary = (VARY *)last_name;
      printf("%-20.*s ", vary->vary_length, vary->vary_string);
      vary = (VARY *)first_name;
      printf("%-15.*s ", vary->vary_length, vary->vary_string);
      vary = (VARY *)phone_ext;
      printf("%-4.*s ", vary->vary_length, vary->vary_string);
    }
    if (retcode != 100L)
    {
      SQLCODE = isc_sqlcode(status_vector);
      isc_print_sqlerror(SQLCODE, status_vector);
      return(1);
    }

Return Value isc_dsql_fetch() returns the second element of the status vector. Zero indicates success. The value 100 indicates that no more rows remain to be retrieved. Any other nonzero value indicates an error. For InterBase errors, the first element of the status vector is set to 1, and the second element is set to isc_bad_stmt_handle, or another InterBase error code.

To check for an InterBase error, examine the first two elements of the status vector directly.

See also isc_dsql_execute(), isc_dsql_execute2(), isc_dsql_prepare()

u Back to top

isc_dsql_free_statement()

Performs one of three actions:

• Frees a statement handle and all resources allocated for it

• Closes a cursor associated with the statement referenced by a statement handle

• Cancels statement execution in the server

    Syntax  ISC_STATUS isc_dsql_free_statement(
                     ISC_STATUS *status_vector,
                     isc_stmt_handle *stmt_handle,
                     unsigned short option);

Parameter | Type | Description
status_vector | ISC_STATUS * | Pointer to the error status vector
stmt_handle | isc_stmt_handle * | Pointer to a statement handle previously allocated with isc_dsql_allocate_statement() or isc_dsql_alloc_statement2(); the handle returns an error in status_vector if it is NULL
option | unsigned short | One of the following: DSQL_close DSQL_drop DSQL_cancel

Description isc_dsql_free_statement() either frees a statement handle and all resources allocated for it (option = DSQL_drop), closes a cursor associated with the statement (option = DSQL_close), or cancels execution of the statement (option = DSQL_cancel).

Note isc_dsql_free_statement() does nothing if it is called with an option value other than DSQL_drop, DSQL_close, or DSQL_cancel.

DSQL_close

The DSQL_close option closes a cursor after it is no longer needed, that is, after fetching and processing all the rows resulting from the execution of a query. A cursor need only be closed in this manner if it was previously opened and associated with stmt_handle by isc_dsql_set_cursor_name().

DSQL_close closes a cursor, but the statement it was associated with remains available for further execution.

If you have used a cursor to perform updates or deletes on all the rows returned from the execution of a query, and you want to perform other update or delete operations on rows resulting from execution of the same statement again (possibly with different input parameters), follow these steps:

1 Close the cursor with isc_dsql_free_statement().

2 Re-open it with isc_dsql_set_cursor_name().

3 If desired, change the input parameters to be passed to the statement.

4 Re-execute the statement to retrieve a new select list.

5 Retrieve rows in a loop with isc_dsql_fetch() and process them again with isc_dsql_execute_immediate().

DSQL_drop

Statement handles allocated with isc_dsql_allocate_statement() must be released when no longer needed by calling isc_dsql_free_statement() with the DSQL_drop option. This option frees all resources associated with the statement handle, and closes any open cursors associated with the statement handle.

Example The following program fragment shows examples of the two types of isc_dsql_free_statement() calls. It assumes that stmt_handle1 and stmt_handle2 are statement handles, each of which was previously allocated with either isc_dsql_allocate_statement() or isc_dsql_alloc_statement2(). A cursor is also assumed to have been associated with the statement referenced by stmt_handle1.

    #include <ibase.h>
    ISC_STATUS status_vector[20];
    . . .
    /* Free the cursor associated with stmt_handle1. */
    isc_dsql_free_statement(
      status_vector,
      &stmt_handle1,
      DSQL_close);
    if (status_vector[0] == 1 && status_vector[1])
    {
      isc_print_status(status_vector);
      return(1);
    }
    /* Free stmt_handle2. */
    isc_dsql_free_statement(
      status_vector,
      &stmt_handle2,
      DSQL_drop);
    if (status_vector[0] == 1 && status_vector[1])
    {
      isc_print_status(status_vector);
      return(1);
    }

DSQL_cancel

The DSQL_cancel option allows for the asynchronous cancellation of an executing statement. The client that was executing the statement receives a status code of isc_cancelled. Once a statement has been cancelled, any subsequent execution restarts the statement, rather than resuming it.

Return Value isc_dsql_free_statement() returns the second element of the status vector. Zero indicates success. A nonzero value indicates an error. For InterBase errors, the first element of the status vector is set to 1, and the second element is set to isc_bad_stmt_handle, or another InterBase error code. To check for an InterBase error, examine the first two elements of the status vector directly.

See also isc_dsql_allocate_statement(), isc_dsql_alloc_statement2(), isc_dsql_set_cursor_name()

u Back to top

isc_dsql_prepare()

Prepares a DSQL statement for repeated execution.

    Syntax  ISC_STATUS isc_dsql_prepare(
                     ISC_STATUS *status_vector,
                     isc_tr_handle *trans_handle,
                     isc_stmt_handle *stmt_handle,
                     unsigned short length,
                     char *statement,
                     unsigned short dialect,
                     XSQLDA *xsqlda);

Parameter | Type | Description
status_vector | ISC_STATUS * | Pointer to the error status vector
trans_handle | isc_tr_handle * | Pointer to a transaction handle whose value has been set by a previous isc_start_transaction() call; trans_handle returns an error if NULL
stmt_handle | isc_stmt_handle * | Pointer to a statement handle previously allocated with isc_dsql_allocate_statement() or isc_dsql_alloc_statement2(); the handle returns an error in status_vector if it is NULL
length | unsigned short | Length of the DSQL statement, in bytes; set to 0 in C programs to indicate a null-terminated string
statement | char * | DSQL string to be executed
dialect | unsigned short | • Indicates the SQL dialect of statement • Must be less than or equal to the SQL dialect of the client
xsqlda | XSQLDA * | Pointer to an optional, previously allocated XSQLDA used for results of statement execution

Description isc_dsql_prepare() readies the DSQL statement specified in statement for repeated execution by checking it for syntax errors and parsing it into a format that can be efficiently executed. All SELECT statements must be prepared with isc_dsql_prepare().

After a statement is prepared, it is available for execution as many times as necessary during the current session. Preparing a statement for repeated execution is more efficient than using isc_dsql_execute_immediate() or isc_dsql_exec_immed2() over and over again to prepare and execute a statement.

If a statement to be prepared does not return data, set the output XSQLDA to NULL. Otherwise, the output XSQLDA must be allocated prior to calling isc_dsql_prepare(). Allocate the XSQLDA using the macro, XSQLDA_LENGTH, defined in ibase.h, as follows:

    xsqlda = (XSQLDA *)malloc(XSQLDA_LENGTH(n));

XSQLDA_LENGTH calculates the number of bytes required when n result columns will be returned by the statement, and allocates the appropriate amount of storage.

After allocating the XSQLDA xsqlda, set xsqlda->version to SQLDA_CURRENT_VERSION, and set xsqlda_sqln to indicate the number of XSQLVAR structures allocated.

When isc_dsql_prepare() is called, it fills in the other fields of the XSQLDA and all the XSQLVAR s with information such as the datatype, length, and name of the corresponding select-list items in the statement. It fills in xsqlda->sqld with the actual number of select-list items returned. If xsqlda->sqld is greater than xsqlda->sqln, then enough room is not allocated, and the XSQLDA must be resized by following these steps:

1 Record the current value of the xsqlda->sqld.

2 Free the storage previously allocated for xsqlda.

3 Reallocate storage for xsqlda, this time specifying the correct number (from step 1) in the argument to XSQLDA_LENGTH.

4 Reset xsqlda->sqld and xsqlda->version.

5 Execute isc_dsql_describe() to fill in the xsqlda fields.

Note If the prepared statement requires input parameter values, then an input XSQLDA will need to be allocated and filled in with appropriate values prior to calling isc_dsql_execute() or isc_dsql_execute2(). You can either allocate and directly fill in all the fields of the input XSQLDA, or you can allocate it, call isc_dsql_describe_bind() to get information regarding the number and types of parameters required, then fill in appropriate values.

Example The following program fragment illustrates the allocation of the output XSQLDA, and a call to isc_dsql_prepare():

    #include <ibase.h>
    ISC_STATUS status_vector[20];
    XSQLDA *osqlda;
    char *query =  "SELECT CITY, STATE, POPULATION FROM CITIES \
      WHERE STATE = "NY" ORDER BY CITY DESCENDING";

    osqlda = (XSQLDA *)malloc(XSQLDA_LENGTH(3);
    osqlda->version = SQLDA_CURRENT_VERSION;
    osqlda->sqln = 3;

    isc_dsql_prepare(
      status_vector,
      &tr_handle,  /* Set in previous isc_start_transaction() call. */
      &stmt_handle,
         /* Allocated previously by isc_dsql_allocate_statement()
            or isc_dsql_alloc_statement2() call. */
      0,
      query,
      1,
      osqlda);
    if (status_vector[0] == 1 && status_vector[1])
    {
      isc_print_status(status_vector);
      return(1);
    }

More complete examples showing the subsequent execution and fetching of result data are provided in the example programs for isc_dsql_execute(), isc_dsql_execute2(), and isc_dsql_fetch().

Return Value isc_dsql_prepare() returns the second element of the status vector. Zero indicates success. A nonzero value indicates an error. For InterBase errors, the first element of the status vector is set to 1, and the second element is set to isc_bad_stmt_handle, isc_bad_trans_handle, or another InterBase error code.

To check for an InterBase error, examine the first two elements of the status vector directly.

See also isc_dsql_describe(), isc_dsql_describe_bind(), isc_dsql_execute(), isc_dsql_execute2(), isc_dsql_fetch()

u Back to top

isc_dsql_set_cursor_name()

Defines a cursor name and associates it with a DSQL statement.

    Syntax  ISC_STATUS isc_dsql_set_cursor_name(
                     ISC_STATUS *status_vector,
                     isc_stmt_handle *stmt_handle,
                     char *cursor_name,
                     unsigned short type);

Parameter | Type | Description
status_vector | ISC_STATUS * | Pointer to the error status vector
stmt_handle | isc_stmt_handle * | Pointer to a statement handle previously allocated with isc_dsql_allocate_statement() or isc_dsql_alloc_statement2(); the handle returns an error in status_vector if it is NULL
cursor_name | char * | String name of a cursor
type | unsigned short | Reserved for future use; set to NULL

Description isc_dsql_set_cursor_name() defines a cursor name and associates it with a DSQL statement handle for a statement that returns multiple rows of data (for example, SELECT), effectively opening the cursor for access.

A cursor is a one-way pointer into the ordered set of rows retrieved by a statement. A cursor is only needed to process positioned UPDATE and DELETE statements made against the rows retrieved by isc_dsql_fetch() for SELECT statements that specify an optional FOR UPDATE OF clause.

Note In UPDATE or DELETE statements, the cursor name cannot be supplied as a parameter marker (?).

When a cursor is no longer needed, close it with the DSQL_close option of isc_dsql_free_statement().

Example The following pseudo-code illustrates the calling sequence necessary to execute an UPDATE or DELETE with the WHERE CURRENT OF clause using a cursor name established and opened with isc_dsql_set_cursor_name():

    #include <ibase.h>
    ISC_STATUS status_vector[20], fetch_stat;
    isc_stmt_handle st_handle = NULL;
    char *cursor = "S";

    /* Allocate the statement handle st_handle. */
    isc_dsql_allocate_statement(
      status_vector,
      &db, /* Database handle set by isc_attach_database() call. /*
      &st_handle);
    if (status_vector[0] == 1 && status_vector[1])
    {
      isc_print_status(status_vector);
      return(1);
    }
    /* Set up an output XSQLDA osqlda here. */
    /* Call isc_dsql_prepare() to prepare the SELECT statement. */
    /* Set up an input XSQLDA, if needed, for the SELECT statement. */
    /* Call isc_dsql_execute() to execute the SELECT statement. */
    /* Set up an input XSQLDA (if needed) for the UPDATE or DELETE statement. */
    /* Declare the cursor name, and associate it with st_handle. */
    isc_dsql_set_cursor_name(
      status_vector,
      &st_handle,
      cursor, 0);
    if (status_vector[0] == 1 && status_vector[1])
    {
      isc_print_status(status_vector);
      return(1);
    }
    /* Fetch rows one by one, with the cursor pointing to each row as it is fetched,
    and execute an UPDATE or DELETE statement to update or delete the row pointed to
    by the cursor. */
    while ((fetch_stat = isc_dsql_fetch(
      status_vector, &st_handle, 1, osqlda)) == 0)
    {
      . . .
      /* Update or delete the current row by executing an "UPDATE ...
         WHERE CURRENT OF S" or "DELETE ... WHERE CURRENT OF S"
         statement, where "S" is the name of the cursor declared in
         isc_dsql_set_cursor_name(). */
    }

Return Value isc_dsql_set_cursor_name() returns the second element of the status vector. Zero indicates success. A nonzero value indicates an error. For InterBase errors, the first element of the status vector is set to 1, and the second element is set to isc_bad_stmt_handle, or another InterBase error code.

To check for an InterBase error, examine the first two elements of the status vector directly.

See also isc_dsql_fetch(), isc_dsql_free_statement()

u Back to top

isc_dsql_sql_info()

Returns requested information about a prepared DSQL statement.

    Syntax  ISC_STATUS isc_dsql_sql_info(
                     ISC_STATUS *status_vector,
                     isc_stmt_handle *stmt_handle,
                     unsigned short item_length,
                     char *items,
                     unsigned short buffer_length,
                     char *buffer);

Parameter | Type | Description
status_vector | ISC_STATUS * | Pointer to the error status vector
stmt_handle | isc_stmt_handle * | Pointer to a statement handle previously allocated with isc_dsql_allocate_statement() or isc_dsql_alloc_statement2(); the handle returns an error in status_vector if it is NULL
item_length | unsigned short | Number of bytes in the string of information items in items
items | char * | String of requested information items
buffer_length | unsigned short | Number of bytes in the result buffer, buffer
buffer | char * | User-provided buffer for holding returned data; must be large enough to hold the information requested

Description isc_dsql_sql_info() returns requested information about a statement prepared with a call to isc_dsql_prepare(). The main application need for this function is to determine the statement type of an unknown prepared statement, for example, a statement entered by the user at run time.

Requested information can include the:

• Statement type

• Number of input parameters required by the statement

• Number of output values returned by the statement

• Detailed information regarding each input parameter or output value, including its datatype, scale, and length

• The query plan prepared by the optimizer

Example The following illustrates a call to isc_dsql_sql_info() to determine the statement type of the statement whose handle is referenced by stmt:

    int statement_type;
    int length;
    char type_item[] = {isc_info_sql_stmt_type};
    char  res_buffer[8];
    isc_dsql_sql_info(
      status_vector,
      &stmt,
         /* Allocated previously by isc_dsql_allocate_statement() or
            isc_dsql_alloc_statement2() call. */
      sizeof(type_item),
      type_item,
      sizeof(res_buffer),
      res_buffer);

    if (res_buffer[0] == isc_info_sql_stmt_type)
    {
      length = isc_portable_integer(buffer[1], 2);
      statement_type = isc_portable_integer(buffer[3], length);
    }

Return Value isc_dsql_sql_info() returns the second element of the status vector. Zero indicates success. A nonzero value indicates an error. For InterBase errors, the first element of the status vector is set to 1, and the second element is set to an InterBase error code.

To check for an InterBase error, examine the first two elements of the status vector directly.

See also isc_dsql_describe_bind(), isc_dsql_describe(), isc_vax_integer()

u Back to top

isc_dsql_xml_buffer_fetch()

Returns XML-formatted text to the specified buffer.

    Syntax  int isc_dsql_xml_buffer_fetch(
                     ISC_STATUS *status_vector,
                     isc_stmt_handle *stmt_handle,
                     unsigned short da_version,
                     char *buffer
                     int buffer_size
                     XSQLDA *xsqlda,
                     IB_XMLDA *ib_xmlda);

Parameter | Type | Description
status_vector | ISC_STATUS * | Pointer to the error status vector
stmt_handle | isc_stmt_handle * | Pointer to a statement handle previously executed with isc_dsql_execute_statement() or isc_dsql_alloc_execute2()
da_version | unsigned short | Specifies that the XSQLDA descriptor, rather than SQLDA, should be used; set this value to 1
buffer | char * | Pointer to a character buffer that holds the returned XML
buffer_size | int | Size of buffer
xsqlda | XSQLDA * | Pointer to an optional, previously allocated XSQLDA used for results of statement execution
ib_xmlda | IB_XMLDA* | Pointer to an initialized XML descriptor area, IB_XMLDA

Description isc_dsql_buffer_fetch() returns XML-formatted text to the buffer. It must be called more than once to complete the file if buffer is not large enough to hold the data. If you are interested in looking a the data one row at a time, use isc_dsql_xml_fetch().

In order to use isc_dsql_xml_buffer_fetch(), you must allocate a character array, buffer, that is at least 1024 bytes long. The buffer_size argument reports the size of this passed buffer. The function does not return incomplete headers, footers, or records. It sets xmlda_more_data if the call should be made once again to get the complete XML buffer.

Example The following example retrieves data from a previously prepared and executed statement handle and prints the XML to stdout;

    int buff_size = 2048;
    . . .
    while (!done){
      char *buffer = malloc (buff_size);
      int size;
      /* the buffer mode .. */
      size = isc_dsql_xml_buffer_fetch(
         status, &stmt, buffer, buff_size, 1, sqlda, &xmlda);
      if (size == -2)
    /* must increase the size of the buffer */
         {buff_size = buff_size + 1024;
         done = 0;
         }
      else if (size == -1)
    /* not enough memory break out */
         {printf ("out of memory /n");
            free (buffer);
            break;
         }
      else
         {printf ("%s", buffer);
      if (xmlda.xmlda_more_data)
         done = 0;
      else
         done = 1;
      }
      free (buffer);
    }

Return Value The function returns the number of characters written into the buffer (without the terminating null character). It returns –1 if there is not enough memory for it to continue, or –2 if the buffer is too small.

See also isc_dsql_xml_fetch(), isc_dsql_xml_fetch_all()

u Back to top

isc_dsql_xml_fetch()

Appends retrieved data to an XML-formatted file and returns this data to the XSQLDA.

    Syntax  int isc_dsql_xml_fetch(
                     ISC_STATUS *status_vector,
                     isc_stmt_handle *stmt_handle,
                     unsigned short da_version,
                     XSQLDA *xsqlda,
                     IB_XMLDA *ib_xmlda);

Parameter | Type | Description
status_vector | ISC_STATUS * | Pointer to the error status vector
stmt_handle | isc_stmt_handle * | Pointer to a statement handle previously executed with isc_dsql_execute_statement() or isc_dsql_alloc_execute2()
da_version | unsigned short | Specifies that XSQLDA, rather than SQLDA, should be used; set this value to 1
xsqlda | XSQLDA * | Pointer to an optional, previously allocated XSQLDA used for results of statement execution
ib_xmlda | IB_XMLDA* | Pointer to an initialized XML descriptor area, IB_XMLDA

Description isc_dsql_xml_fetch() works on a previously prepared and executed statement and returns one row of data into the xmlda_file_name file each time it is called. Each time it is called in a loop, it retrieves and processes one row of data. It is used in the same manner as isc_dsql_fetch(). It is up to the application code to provide the loop construct for fetching the data.

The ib_xmlda descriptor area is described in detail on page 14-2 of the “Exporting XML” chapter in this book.

Before calling isc_dsql_xml_fetch(), a statement must be prepared with isc_dsql_prepare() and executed with isc_dsql_execute(). Statement execution produces a result set containing the returned row. Each call to isc_dsql_xml_fetch() retrieves the next available row of data from the InterBase database using stmt_handle and produces two possible outputs: it retrieves into the XSQLDA and appends to the XML file specified by xmlda_file_name in the ib_xmlda descriptor.

After calling isc_dsql_xml_fetch(), you still have access to the data in the cursor using XSQLDA.

Example

                 fetch_stat = isc_dsql_xml_fetch(
      status_vector, &stmt_handle, 1, sqlda, &xmlda) == 0

See also isc_dsql_xml_buffer_fetch(), isc_dsql_xml_fetch_all()

u Back to top

isc_dsql_xml_fetch_all()

Creates an XML-formatted file using a previously prepared and executed statement handle.

    Syntax  int isc_dsql_xml_fetch(
                     ISC_STATUS *status_vector,
                     isc_stmt_handle *stmt_handle,
                     unsigned short da_version,
                     XSQLDA *xsqlda,
                     IB_XMLDA *ib_xmlda);

Parameter | Type | Description
status_vector | ISC_STATUS * | Pointer to the error status vector
stmt_handle | isc_stmt_handle * | Pointer to a statement handle previously executed with isc_dsql_execute_statement() or isc_dsql_alloc_execute2()
da_version | unsigned short | Specifies that the XSQLDA descriptor, rather than SQLDA, should be used; set this value to 1
xsqlda | XSQLDA * | Pointer to an optional, previously allocated XSQLDA used for results of statement execution
ib_xmlda | IB_XMLDA* | Pointer to an initialized XML descriptor area, IB_XMLDA

Description isc_dsql_xml_fetch_all() creates an XML-formatted result set for a query. Use this function if you are interested in creating a complete XML file, but don’t need to look at the data one row at a time. This function needs to be called only once (unlike isc_dsql_xml_fetch()). If you are interested in looking a the data one row at a time, use isc_dsql_xml_fetch().

See also isc_dsql_xml_buffer_fetch(), isc_dsql_xml_fetch()

u Back to top

isc_encode_sql_date()

Translates a date from the C struct tm format to InterBase ISC_DATE format prior to inserting or updating a DATE value in a table.

    Syntax  void isc_encode_sql_date(
                     void *tm_date,
                     ISC_DATE *ib_date);

Parameter | Type | Description
tm_date | void * | Pointer to a C struct tm structure
ib_date | ISC_DATE * | Pointer to a four-byte ISC_DATE structure containing a date in InterBase format

Description isc_encode_sql_date() translates a date in a C time structure into an ISC_DATE format internal to InterBase. This call is used prior to writing DATE data to a table to guarantee that the date is in a format recognized by InterBase.

Use the isc_dsql family of API calls to insert or update DATE data from the ISC_DATE structure in a table.

Note In InterBase 6 and later, the DATE datatype is available only in dialect 3. It holds only date information, and does not include time information. In dialect 1, the TIMESTAMP datatype holds both date and time information and is exactly equivalent to the DATE datatype that was present in earlier versions of InterBase.

Example The following code fragment illustrates declaring time structures and calling isc_encode_sql_date() to translate a C time format into an InterBase date format prior to inserting or updating a table:

    #include <time.h>
    #include <ibase.h>
    . . .
    struct tm hire_time;
    ISC_DATE hire_date;
    . . .
    /* Store date info into the tm struct here. */
    . . .
    isc_encode_sql_date(&hire_time, &hire_date);
    /* Now use a DSQL INSERT or UPDATE statement to move the date into a DATE column.
    */

Return Value None.

See also isc_decode_sql_date(), isc_encode_sql_time(), isc_encode_timestamp()

u Back to top

isc_encode_sql_time()

Translates a time from the C struct tm format to InterBase ISC_SQL_TIME format prior to inserting or updating a TIME value in a table.

    Syntax  void isc_encode_sql_time(
                     void *tm_date,
                     ISC_TIME *ib_time);

Parameter | Type | Description
tm_date | void * | Pointer to a C tm structure
ib_time | ISC_TIME * | Pointer to a four-byte ISC_TIME structure containing a time in InterBase format

Description isc_encode_sql_time() translates a date in a C time structure into an ISC_TIME format internal to InterBase. This call is used prior to writing TIME data to a table to guarantee that the time is in a format recognized by InterBase.

Use the isc_dsql family of API calls to insert or update TIME data from the ISC_TIME structure in a table.

Note isc_encode_sql time() does not support milliseconds, because encode/decode functions use the structure struct tm from time.h, which does not support a fractional part for seconds.

Example The following code fragment illustrates declaring time structures and calling isc_encode_sql_time() to translate a C time format into an InterBase date format prior to inserting or updating a table:

    #include <time.h>
    #include <ibase.h>
    . . .
    struct tm hire_time;
    ISC_TIME hire_date;
    . . .
    /* Store time info into the tm struct here. */
    . . .
    isc_encode_sql_time(&hire_time, &hire_date);
    /* Now use a DSQL INSERT or UPDATE statement to move the
     * date into a TIME column. */

Return Value None.

See also isc_decode_sql_time(), isc_encode_sql_date(), isc_encode_timestamp()

u Back to top

isc_encode_timestamp()

Translates a time from the C struct tm format to InterBase ISC_TIMESTAMP format prior to inserting or updating a TIMESTAMP value in a table.

    Syntax  void isc_encode_timestamp(
                     void *tm_date,
                     ISC_TIMESTAMP *ib_timestamp);

Parameter | Type | Description
tm_date | void * | Pointer to a C tm structure
ib_timestamp | ISC_TIMESTAMP * | Pointer to an eight-byte ISC_TIMESTAMP structure containing a date and time in InterBase format

Description isc_encode_timestamp() translates a date in a C time structure into an ISC_TIMESTAMP format internal to InterBase. This call is used prior to writing TIMESTAMP data to a table to guarantee that the date and time are in a format recognized by InterBase. This call is exactly the same as the older isc_encode_date(), which is still available for backward compatibility.

Use the isc_dsql family of API calls to insert or update TIMESTAMP data from the ISC_TIMESTAMP structure in a table.

Note isc_encode_timestamp() does not support milliseconds, because encode/decode functions use the structure struct tm from time.h, which does not support a fractional part for seconds.

Example The following code fragment illustrates declaring time structures and calling isc_encode_timestamp() to translate a C time format into an InterBase date format prior to inserting or updating a table:

    #include <time.h>
    #include <ibase.h>
    . . .
    struct tm hire_time;
    ISC_TIMESTAMP hire_date;
    . . .
    /* Store date and time info into the tm struct here. */
    . . .
    isc_encode_timestamp (&hire_time, &hire_date);
    /* Now use a DSQL INSERT or UPDATE statement to move the date into a TIMESTAMP
    column. */

Return Value None.

See also isc_decode_timestamp(), isc_encode_sql_date(), isc_encode_sql_time()

u Back to top

isc_event_block()

Allocates two event parameter buffers (EPBs) for subsequent use with other API event calls.

    Syntax  long isc_event_block(
                     char **event_buffer,
                     char **result_buffer,
                     unsigned short id_count,
                     . . .);

Parameter | Type | Description
event_buffer | char ** | Address of a character pointer; this function allocates and initializes an event parameter buffer and stores its address into the character pointer
result_buffer | char ** | Address of a character pointer; this function allocates an event parameter buffer, and stores its address into the character pointer
id_count | unsigned short | Number of event identifier strings that follow
… | char * | Up to 15 null-terminated and comma-separated strings that each name an event

Description isc_event_block() must be called before any other event functions. It:

• Allocates two event parameter buffers of the same size, and stores their addresses into the character pointers addressed by event_buffer and result_buffer.

• Stores into the buffer referenced by event_buffer the names and event counts for each of the specified events. The names are the ones that appear as the final arguments to isc_event_block(). The event counts are initialized to zero and are used to specify how many times each event has been posted prior to each wait for events to occur.

• Returns the length, in bytes, of the buffers.

The buffers, and their lengths, are used in subsequent calls to the functions isc_wait_for_event(), isc_que_events(), and isc_event_counts(). event_buffer is used to indicate the events of interest, and to hold the counts in effect before a wait for one of the events. After an event is posted, result_buffer is filled in exactly as event_buffer, except that the event counts are updated. isc_event_counts() is then called to determine which events were posted between the time the counts were set in event_buffer, and the time the counts are set in result_buffer.

Example The following program fragment illustrates a call to isc_event_block():

    #define number_of_stocks 3;

    char *event_buffer, *result_buffer;
    long length;

    length = isc_event_block(
      &event_buffer,
      &result_buffer,
      number_of_stocks,
      "DEC", "HP", "SUN");

Return Value isc_event_block() returns a number that is the size, in bytes, of each event parameter buffer it allocates.

See also isc_event_counts(), isc_que_events(), isc_wait_for_event()

u Back to top

isc_event_counts()

Compares event parameter buffers (EPBs) to determine which events have been posted, and prepares the event parameter buffers for the next call to isc_que_events() or isc_wait_for_event().

    Syntax  void isc_event_counts(
                     ISC_STATUS *status_vector,
                     short buffer_length,
                     char *event_buffer,
                     char *result_buffer);

Parameter | Type | Description
status_vector | long * | Pointer to the status vector, which is used to store the differences in event counts for each corresponding event in event_buffer and result_buffer
buffer_length | short | Length of the event parameter buffers, returned by the isc_event_block() call that allocated them
event_buffer | char * | Pointer to the event parameter buffer that specifies the event counts prior to the previous call to isc_wait_for_event() or isc_que_events()
result_buffer | char * | Pointer to the event parameter buffer filled in as a result of posting an event

Description isc_event_counts() compares the event counts in the event parameter buffers, event_buffer and result_buffer, and sets up to the first 15 elements of status_array to contain the differences. It then modifies event_buffer to contain the same event counts as result_buffer in preparation for the next call to either isc_wait_for_event() or isc_que_events().

The counts in event_buffer specify how many times each event had been posted since the previous call to isc_event_wait() or isc_que_events(). The counts in result_buffer equal the values in event_buffer plus the number of additional times an event is posted after the current call to isc_event_wait() or isc_que_events(). If an event is posted after a call to either of these functions, its count is greater in result_buffer than in event_buffer. Other event counts may also be greater because an event may have been posted between calls to either of these functions. The values in status_array are the differences in values between event_buffer and result_buffer. This mechanism of comparing all the counts ensures that no event postings are missed.

Example The following program fragment illustrates the set-up and waiting on any of the events named “DEC”, “HP”, or “SUN”, then calling isc_event_counts() to determine which events have been posted:

    #include <ibase.h>
    #define number_of_stocks 3;

    char *event_buffer, *result_buffer;
    ISC_STATUS status_vector[20];
    char *event_names[] = {"DEC", "HP", "SUN"};
    long length;
    int i;

    length = isc_event_block(
      &event_buffer,
      &result_buffer,
      number_of_stocks,
      "DEC", "HP", "SUN");

    isc_wait_for_event(
      status_vector,
      &database_handle, /* Set by previous isc_attach_database(). */
      length, /* Returned from isc_event_block(). */
      event_buffer,
      result_buffer);
    if (status_vector[0] == 1 && status_vector[1])
    {
      isc_print_status(status_vector); /* Display error message. */
      return(1);
    }

    isc_event_counts(
      status_vector,
      (short) length,
      event_buffer,
      result_buffer);

    for (i=0; i<number_of_stocks; i++)
      if (status_vector[i])
      {
         /* The event has been posted. Do whatever is appropriate, for example,
          initiating a buy or sell order. */
         ;
      }

Return Value None.

See also isc_que_events(), isc_wait_for_event()

u Back to top

isc_expand_dpb()

Dynamically builds or expands a database parameter buffer (DPB) to include database parameters.

    Syntax  void isc_expand_dpb(
                     char **dpb,
                     unsigned short *dpb_size,
                     . . .);

Parameter | Type | Description
dpb | char ** | Pointer to an existing DPB
dpb_size | unsigned short * | Pointer to the current size, in bytes, of the DPB
… | char * | Pointers to items to insert into the expanded DPB

Description isc_expand_dpb() builds or expands a DPB dynamically. Its main use is to simplify the building of the DPB prior to a call to isc_attach_database(), or to allow an end user to supply a user name and password combination at run time. In many cases, the DPB must be constructed programmatically, but isc_expand_dpb() enables an application to pass user names, password, message file, and character set parameters to the function, which then adds them to an existing DPB.

A pointer to a previously allocated and initialized DPB must be passed to isc_expand_dpb() along with a pointer to a variable containing the amount of space used in the DPB when this function is called. The function allocates a new DPB, preserving its current contents, and adds the new parameters.

To ensure proper memory management, applications that call isc_expand_dpb() should call isc_free() to release the allocated buffer.

Example The following code calls isc_expand_dpb() to create a DPB, then attaches to a database using the newly created DPB. user_name and user_password are assumed to be variables whose values have been filled in, for example, after asking the user to specify the name and password to be used.

    #include <ibase.h>
    char *dpb;
    ISC_STATUS status_vector[20];
    isc_db_handle handle = NULL;
    short dpb_length;

    /* Build the database parameter buffer. */

    dpb = (char *) malloc(50);
    dpb_length = 0;

    isc_expand_dpb(&dpb, &dpb_length, isc_dpb_user_name, user_name, isc_dpb_password,
    user_password, NULL);

    isc_attach_database(
      status_vector,
      0,
      "employee.db",
      &handle,
      dpb_length,
      dpb_buffer);
    if (status_vector[0] == 1 && status_vector[1])
    {
      /* An error occurred. */
      isc_print_status(status_vector);
      return(1);
    }

Return Value None.

See also isc_attach_database()

u Back to top

isc_get_client_version()

Returns the client version string.

    Syntax  void isc_get_client_version(char *version)

Description isc_get_client_version() populates version with the version string, typically in the following format:

    XX-dM.N.n.b

The elements of this format are as follows:

Element | Description
XX | The all-caps two-character hardware/software platform code: • WI = Windows/Intel • SO = Solaris/Sparc • LI = Linux/Intel
d | A distribution indicator • B = beta • T = test • V = verified • I = internal
M | The major version number
N | The minor version number
n | A minor-minor version number
b | A build number

You must pass a character buffer that is a least 20 characters long to this function. It does not perform the checks if the buffer is too short.

Return Value isc_get_client_version() returns the version in the form described above in the string pointed to by version.

u Back to top

isc_get_client_major_version()

Returns the major version number of the client library.

    Syntax  int isc_get_client_major_version()

isc_get_client_minor_version()

Returns the minor version number of the client library.

    Syntax  int isc_get_client_minor_version ()

isc_get_segment()

Reads a segment from an open Blob.

    Syntax  ISC_STATUS isc_get_segment(
                     ISC_STATUS *status_vector,
                     isc_blob_handle *blob_handle,
                     unsigned short *actual_seg_length,
                     unsigned short seg_buffer_length,
                     char *seg_buffer);

Parameter | Type | Description
status_vector | ISC_STATUS * | Pointer to the error status vector
blob_handle | isc_blob_handle * | Pointer to the handle of the Blob you want to read.
actual_seg_length | unsigned short * | Pointer to the actual segment length that InterBase reads into the buffer; useful if the segment length is shorter than the buffer length
seg_buffer_length | unsigned short | Length of the segment buffer
seg_buffer | char * | Pointer to the segment buffer

Description isc_get_segment() reads a Blob segment from a previously opened Blob. You can set the seg_buffer_length parameter to a size that is efficient for a particular type of Blob data. For example, if you are reading Blob data from a text file, you might set the segment buffer length to 80, to take advantage of the 72 to 80 character line lengths that are common in text files. By periodically checking the value of the actual segment length in your loop, you can determine an end-of-line or end-of-file condition.

Before reading any part of a Blob, you must open the Blob with a call to isc_open_blob2(). isc_get_segment() behaves differently depending on which call precedes it. If the most recent call is to isc_open_blob2(), then a call to isc_get_segment() reads the first segment in the Blob. If the most recent call is to isc_get_segment(), then it reads the next segment.

If Blob filters are specified when a Blob is opened, then each segment retrieved by isc_get_segment() is filtered on read.

You can read bitmaps and other binary files directly, without filtering, if you don’t need to change from one format to another, say from TIF to JPEG. You can also store compressed bitmaps directly in a database in formats such as JPG (JPEG), BMP (Windows native bitmaps), or GIF (CompuServe Graphic Interchange Format). No filtering is required.

You can store bitmaps in a database in row-major or column-major order.

If the buffer is not large enough to hold the entire current segment, the function returns isc_segment, and the next call to isc_get_segment() gets the next chunk of the oversized segment rather than getting the next segment.

When isc_get_segment() reads the last segment of the Blob, the function returns the code isc_segstr_eof.

For more information about reading data from a Blob, see Chapter 7, “Working with Blob Data.”

Example The following call gets a segment from one Blob and writes it to another:

    get_status = isc_get_segment(status, &from_blob, &seg_len, 80, buffer);
    if (status[0] == 1 && status[1])
    {
      isc_print_status(status);
      return(1);
    }
    if (get_status != isc_segstr_eof)
      write_status = isc_put_segment(status, &to_blob, seg_len, buffer);
    if (status[0] == 1 && status[1])
    {
      isc_print_status(status);
      return(1);
    }

Return Value isc_get_segment() returns the second element of the status vector. Zero indicates success. isc_segment indicates the buffer is not large enough to hold the entire current segment; the next call to isc_get_segment() gets the next chunk of the oversized segment rather than getting the next segment. isc_segstr_eof indicates that the last segment of the Blob has been read. Any other nonzero value indicates an error. For InterBase errors, the first element of the status vector is set to 1, and the second element is set to an InterBase error code.

To check for an InterBase error, examine the first two elements of the status vector directly.

See also isc_create_blob2(), isc_open_blob2(), isc_put_segment()

u Back to top

isc_install_clear_options()

Clears all options set by isc_install_set_option().

    Syntax  MSG_NO isc_install_clear_options(OPTIONS_HANDLE *phandle)

Parameter | Type | Description
phandle | OPTIONS_HANDLE* | • Pointer to the handle of the list of options for the current install • You must initialize this to zero before first use • Handle is maintained by the install engine; you do not need to and should not dereference it

Description isc_install_clear_options() clears all the options and other install data stored in handle and sets handle to zero. It returns a warning if handle is already zero.

It is good practice to call this function both at the beginning and at the end of an install to free all resources. After calling isc_install_clear_options(), you must pass handle to isc_install_set_option() at least once before passing it to any of the other install functions.

Return Value If successful, isc_install_clear_options() returns isc_install_success. If the function completes, but with warnings, a number smaller than isc_install_success is returned. If a fatal error occurs, isc_install_clear_options() returns a number larger than isc_install_success.

Call isc_install_get_message() to obtain the error message when the result is not equal to isc_install_success.

u Back to top

isc_install_execute()

Performs the actual install, including file copying, registry entries, saving uninstall options, and modifying the services file if necessary.

    Syntax  MSG_NO isc_install_execute(OPTIONS_HANDLE handle, TEXT *source_path,
                     TEXT *dest_path, FP_STATUS *fp_status, void *status_arg,
                     FP_ERROR *fp_error, void *error_arg, TEXT *uninst_file_name)

Parameter | Type | Description
handle | OPTIONS_HANDLE | The handle to the list of options created by isc_install_set_option(); returns an error if the value of handle is NULL or zero
source_path | TEXT* | The path where the files to be installed are located, typically on a CDROM; the function returns an error if source_path is NULL or an empty string
dest_path | TEXT* | The path to the desired install location; the function returns an error if dest_path is NULL or an empty string
fp_status | FP_STATUS* | A pointer to a callback function that accepts an integer from 0 to 100; may be NULL if no status information is required by the user
status_arg | void* | User-defined data to be passed to fp_status(); value is often NULL
fp_error | FP_ERROR* | A pointer to a callback function that accepts an error number and returns a mnemonic specifying whether isc_install_execute() should abort, continue, or retry
error_arg | void* | User-defined data to be passed to fp_error(); value is often NULL
uninst_file_name | TEXT* | A pointer to a buffer containing the name of the uninstall file; can be set to NULL

Description isc_install_execute() performs the actual install, including the following operations:

• Calls isc_install_precheck() to ensure that the install can be performed; if isc_install_precheck() returns an error the install aborts

• Logs all actions to a temporary file called ib_install.log

• Creates the destination directory if it does not already exist

• Copies the files using all the correct version checks and delayed copying methods if necessary

• Creates the required registry entries

• Increments UseCount entries in the registry for shared files

• Installs the Guardian and Server as services on Windows NT/2000/XP, or adds the Guardian to the Run section of the Registry on Windows 98

• If necessary, add gds_db to the Services file

• Streams the selected options into ib_uninst.nnn (where nnn is a sequence number) for use at uninstall

• Frees the options list from memory

• Upon completion, moves ib_install.log to the install directory

• Calls fp_status() at regular intervals to pass information on the install progress (percent complete)

• Attempts to clean up if at any point the install is canceled by the user or by an error

If you choose to write functions for displaying status and handling errors, you pass in pointers to these functions as the fp_status and fp_error parameters. In addition, you can pass context information or data to these functions by passing in values for status_arg and error_arg, although these last two parameters are more commonly NULL.

Return Value Returns zero if the function executes successfully, a positive number if an error occurs, and a negative number if the function completes with warnings.

Call isc_install_get_message() to obtain the error message when the result is nonzero.

u Back to top

isc_install_get_info()

Returns the requested information in human-readable form: a suggested install directory, required disk space, an option name, or option description.

    Syntax  MSG_NO isc_install_get_info(OPT option, int info_type, void *info_buf,
                     unsigned int buf_len)

Parameter | Type | Description |
option | OPT | Option for which information is requested if info_type is 2 through 4; returns an error if option is not one of the following tokens:
|  | • IB_CONNECTIVITY_SERVER • IB_CLIENT • IB_CMD_TOOLS • IB_DEV • IB_DOC

• IB_EXAMPLES

• IB_EXAMPLE_API

• IB_EXAMPLE_DB

• IB_GUI_TOOLS

• IB_JDBC

• IB_JDBC_CLIENT

• IB_JDBC_DOCS

• IB_SERVER

|  | See isc_install_set_option() for a description of each option.
info_type | int | Specifies the type of information requested; can be any one of the following values: • isc_install_info_destination returns a suggested destination and ignores any value passed for option • isc_install_info_opspace returns the disk space required to install a particular option; option requires a valid value

• isc_install_info_opname returns a human-readable option name for the specified option; option requires a valid value

• isc_install_info_opdescription returns a human-readable description for the specified option; option requires a valid value

info_buf | void* | isc_install_get_info() writes the requested information to this buffer, and returns an error if info_buf is NULL; if disk space information is requested, the result is an unsigned long
buf_len | unsigned int | The length in bytes of info_buf; returns an error if buf_len is NULL. Value should be at least isc_install_max_message_len bytes. If a destination suggestion is requested, the recommended buffer size is isc_install_max_path

Description isc_install_get_info() returns the information requested by info_type into info_buf location. The info_buf and buf_len parameters cannot be NULL.

Return Value Returns zero if the function executes successfully, a positive number if an error occurs, and a negative number if the function completes but with warnings.

Call isc_install_get_message() to obtain the error message when the result is nonzero.

The contents of info_buf are undetermined if isc_install_get_message() returns anything other than zero, so the caller should always check the return from this function.

u Back to top

isc_install_get_message()

Returns the text of the requested error or warning message number.

    Syntax  MSG_NO isc_install_get_message(MSG_NO msg_no, TEXT *msg, int msg_len)

Parameter | Type | Description
msg_no | MSG_NO | Message number for which text is requested; this is the return from all the InstallAPI functions.
msg | TEXT* | A pointer to the buffer in which the message will be returned; the message is always NULL-terminated.
msg_len | int | The length of msg, in bytes; value must be at least isc_install_max_message_len.

Description isc_install_get message() converts the error or warning value stored in msg_no and returns the corresponding message text to the developer.

Return Value Returns zero if the function executes successfully, a positive number if an error occurs, and a negative number if the function completes but with warnings. Call isc_install_get_message() to obtain the error message when the result is nonzero.

u Back to top

isc_install_load_external_text()

Loads the messages from the specified message file.

    Syntax  MSG_NO isc_install_load_external_text(TEXT *external_path)

Parameter | Type | Description
external_path | TEXT* | Pointer to a buffer that contains the full path and file name of a file or error and warning messages in a language other than English

Description isc_install_load_external_text() loads the message file from the named path. This file contains the text of the install error and warning messages as well as option names and descriptions, and action text, description, and status messages.

Return Value Returns zero if the function executes successfully, a positive number if an error occurs, and a negative number if the function completes but with warnings.

u Back to top

isc_install_precheck()

Checks the install environment for conditions such as existing servers, disk space and access, user permissions, and option dependencies.

    Syntax  MSG_NO isc_install_precheck(OPTIONS_HANDLE handle, TEXT *source_path,
                     TEXT *dest_path)

Parameter | Type | Description
handle | OPTIONS_HANDLE | The handle to the list of options created by isc_install_set_option(); precheck returns an error if the value of handle is NULL or zero.
source_path | TEXT* | The path where the files to be installed are located (typically on a CDROM); this check is skipped if source_path is NULL
dest_path | TEXT* | The path to the desired install location; the disk space check is skipped if dest_path is NULL.

Description isc_install_precheck() performs a number of checks to ensure that installation is possible. Specifically, it checks:

• That a valid operating system is present (currently, it checks for all valid Windows platforms)

• That an InterBase Classic server (version 4.1 or earlier) is not present, since the InterBase server (SuperServer) is a multithreaded architecture and cannot coexist with the Classic server

• That source_path exists and is a directory readable by the user; no check is performed if source_path is NULL or an empty string

• That dest_path is a directory writable by the user and that the drive contains enough space to install the selected components; no check is performed if dest_path is NULL or an empty string

• If the IB_SERVER option is specified, checks whether any existing newer or older version of the SuperServer is already running.

• On Windows NT/2000/XP, if the IB_SERVER option is specified, checks that the user performing the install has administrative privileges.

• The dependencies of the options specified/required; these dependencies are described in the table below:

If any of these are specified: | These options must be installed also:
IB_CMD_TOOLS, IB_GUI_TOOLS, IB_DEV, IB_JDBC, IB_JDBC_CLIENT, IB_CONNECTIVITY | IB_CLIENT
IB_EXAMPLES | IB_SERVER, IB_CLIENT, and IB_DEV
IB_EXAMPLE_AP13 | IB_CLIENT and IB_DEV
IB_EXAMPLE_DB | IB_DEV

Example The following call creates a destination directory, and checks it.

    strcpy(dest, dest_path);
    if(access(dest, 0) == -1)
    {
      len = strlen(dest);
      if(dest[len - 1] == ‘\\’ || dest[len - 1] == ‘/’)
         dest[len - 1] = ‘\0’;
    status = UTIL_make_directory(dest);
      if(status > isc_install_success)
            return status;
    }
    status = isc_install_precheck(handle, source_path, dest);
    if(status > isc_install_success)
      return status;

Return Value Returns isc_install_success if the function executes successfully, a number larger than isc_install_success if an error occurs, and a number smaller than isc_install_success if the function completes but with warnings. Call isc_install_get_message() to obtain the error message when the result is not equal to isc_install_success.

isc_install_precheck() returns an error if any of the checks besides option dependencies fail. It returns a warning if necessary options have not been specified.

u Back to top

isc_install_set_option()

Creates a handle to a list of selected install options; must be called once for each option.

    Syntax  MSG_NO isc_install_set_option(OPTIONS_HANDLE *phandle,
                     OPT option)

Parameter | Type | Description
phandle | OPTIONS_HANDLE | Pointer to the handle of the list of options for the current install; you must initialize this to zero before first use. handle is maintained by the install engine; you do not need to and should not dereference it.
option | OPT | option can be any one of the following values: • IB_SERVER installs the Server component of InterBase: server, message file, Guardian, server configuration tools, gstat, UDF library, gds_lock_print/iblockpr, the international character set library, and the help files. IB_SERVER makes all necessary additions to the registry, creates the InterBase service (and adds gds_db to the Services file, if necessary) on NT/2000/XP.

• IB_CLIENT installs the InterBase client, including the client library and the message file, and makes Windows registry changes and/or adds the NT/2000/XP gds_db service, if necessary

• IB_CMD_TOOLS installs all the command line tools for InterBase on Windows platforms: gbak, gfix, gsec, gstat, iblockpr, and isql. It issues a warning if IB_CLIENT has not been specified

• IB_GUI_TOOLS installs IBConsole and its related help files; it issues a warning if the IB_CLIENT option has not been specified

• IB_JDBC installs the latest InterClient JDBC driver and associated documentation

• IB_JDBC_CLIENT installs the latest InterClient JDBC driver without documentation

• IB_JDBC_DOCS installs only the documentation for InterClient

• IB_DOC installs the InterBase documentation

• IB_EXAMPLES installs all InterBase examples (it has the same effect as specifying IB_EXAMPLE_API or IB_EXAMPLE_DB); it issues a warning if IB_SERVER, IB_CLIENT, and IB_DEV have not been specified

• IB_EXAMPLE_API installs API, SQL, DSQL, and ESQL example files; it issues a warning if IB_CLIENT and IB_DEV are not specified

• IB_EXAMPLE_DB installs all example databases; issues a warning if IB_SERVER has not been specified

• IB_DEV installs gpre, the import libraries, and the header files

Description isc_install_set_option() creates and maintains a handle to a list of requested option values. You must call isc_install_set_option() once for each option to be installed. In an interactive install, the function is typically invoked by a mouse click in a check box.

You must initialize handle to zero before calling isc_install_set_option() for the first time.

Return Value Returns isc_install_success if the function executes successfully, a number larger than isc_install_success if an error occurs, and a number smaller than isc_install_success if the function completes but with warnings. Call isc_install_get_message() to obtain the error message when the result is not equal to isc_install_success.

u Back to top

isc_install_unset_option()

Removes an option from the list of selected options obtained from isc_install_set_option().

    Syntax  MSG_NO isc_install_unset_option(OPTIONS_HANDLE *phandle, OPT option)

Parameter | Type | Description
phandle | OPTIONS_HANDLE | Pointer to the handle of the list of options for the current install; you must initialize this to zero before first use. handle is maintained by the install engine; you do not need to and should not dereference it.
option | OPT | option can be any of the values listed for isc_install_set_option(). If option is the only member of the list, sets handle to zero.

Description isc_install_unset_option() removes the option specified by option from the list maintained by handle. You must call this function once for each option to be removed. If handle is zero when this function is called, the function generates a warning.

Return Value Returns isc_install_success if the function executes successfully, a number larger than isc_install_success if an error occurs, and a number smaller than isc_install_success if the function completes but with warnings. Call isc_install_get_message() to obtain the error message when the result is not equal to isc_install_success.

u Back to top

isc_interprete()

Extracts the text for an InterBase error message from the error status vector to a user-defined buffer.

    Syntax  ISC_STATUS isc_interprete(
                     char *buffer,
                     ISC_STATUS **status_vector);

Parameter | Type | Description
buffer | char * | Application buffer for storing an InterBase error message
status_vector | ISC_STATUS ** | Pointer to a pointer to the error status vector

Description Given both the location of a storage buffer allocated in a program, and the address of the status vector, isc_interprete() builds an error message string from the information in the status vector, puts the formatted string in the buffer where the program can manipulate it, and advances the status vector pointer to the start of the next cluster of error message information. For example, you might declare an error string buffer, call isc_interprete() to retrieve the first error message and insert the message into the buffer, write the buffer to a log file, then peek at the next cluster to see if it contains more error information.

isc_interprete() retrieves and formats a single message each time it is called. When an error occurs, however, the status vector usually contains more than one error message. To retrieve all relevant error messages, you must make repeated calls to isc_interprete() until no more messages are returned.

Note Do not pass the address of the status vector directly, because each time isc_interprete() is called, it modifies the pointer to the status vector to point to the start of the next available message.

To display all error messages on the screen instead of to a buffer, use isc_print_status().

Example The following code declares a message buffer, a status vector, and a pointer to the vector, then illustrates how repeated calls are made to isc_interprete() to store all messages in the buffer:

    #include <ibase.h>
    char msg[512];
    ISC_STATUS status_vector[20];
    long *pvector; /* Pointer to pointer to status vector. */
    FILE *efile; /* Code fragment assumes this points to an open file. */
    . . .
    pvector = status_vector; /* (Re)set to start of status vector. */
    isc_interprete(msg, &pvector); /* Retrieve first message. */
    fprintf(efile, "%s\n", msg); /* Write buffer to log file. */
    msg[0] = '-'; /* Append leading hyphen to secondary messages. */
    while(isc_interprete(msg + 1,&pvector)) /* More messages? */
    {
      fprintf(efile, "%s\n", msg); /* If so, write them, too. */
    }
    fclose(efile);
    . . .

Return Value If successful, isc_interprete() returns the length of the error message string it stores in buffer. It also advances the status vector pointer to the start of the next cluster of error message information.

If there are no more messages in the status vector, or if isc_interprete() cannot interpret the next message, it returns 0.

See also isc_print_sqlerror(), isc_print_status(), isc_sqlcode(), isc_sql_interprete()

u Back to top

isc_license_add()

Adds a certificate ID and key pair to the InterBase license file.

    Syntax  int isc_license_add(char *cert_id, char *cert_key)

Parameter | Type | Description
cert_id | char * | Pointer to a NULL-terminated character buffer containing the certificate ID to be added
cert_key | char * | Pointer to a NULL-terminated character buffer containing the certificate key to be added

Description Adds a line containing the specified certificate ID and key pair to the ib_license.dat file in the InterBase install directory. This ID/key pair must be a valid authorization code obtained from Borland sales. InterBase might require several authorization codes to run and you must call the function once for each ID/key pair you need to add.

Return Value isc_license_add() returns isc_license_msg_restart if it successfully adds the authorization code. If it returns an error, pass the return value to isc_license_get_msg() to obtain the exact error message. The possible return values are:

Table 15.20 Error codes from isc_license_add()

Return | Description
isc_license_msg_restart | Authorization code was successfully added
isc_license_msg_writefailed | The authorization code could not be written
isc_license_msg_dupid | The authorization code was not added to the license file because it is a duplicate of one already present in the file
isc_license_msg_convertfailed | The ID/key combination is invalid

u Back to top

isc_license_check()

Checks whether the supplied ID/key pair is valid.

    Syntax  int isc_license_check(char *cert_id, char *cert_key)

Parameter | Type | Description
cert_id | char * | Pointer to a NULL-terminated character buffer containing the certificate ID to be checked
cert_key | char * | Pointer to a NULL-terminated character buffer containing the certificate key to be checked

Description Checks whether the specified ID/key pair is valid and could be added to ib_license.dat. Calling this function does not actually add anything to the file.

Return Value isc_license_check() returns isc_license_success if it determines that the authorization code could be added. If it returns an error, pass the return value to isc_license_get_msg() to obtain the exact error message. The possible return values are:

Table 15.21 Error codes from isc_license_check()

Return | Description
isc_license_success | Authorization code could be successfully added
isc_license_msg_dupid | The authorization code was not added to the license file because it is a duplicate of one already present in the file
isc_license_msg_convertfailed | The ID/key combination is invalid

u Back to top

isc_license_remove()

Removes the specified line from the InterBase license file.

    Syntax  int isc_license_remove(char *cert_key)

Parameter | Type | Description
cert_key | char | Pointer to a NULL-terminated character buffer containing the certificate key to be removed

Description Removes the line specified by cert_key from ib_license.dat.

Return Value isc_license_remove() has the following return values:

Table 15.22 Returns codes from isc_license_remove()

Return | Description
isc_license_msg_restart | Authorization code was successfully removed
isc_license_msg_notremoved | The authorization code could not be removed; possible reasons are: • The key specified by cert_key does not exist in ib_license.dat • cert_key identifies an evaluation license

u Back to top

isc_license_display()

Copies ID/key pairs from the InterBase license file into a buffer.

    Syntax  unsigned short isc_license_display(char *buf, unsigned short buf_len)

Parameter | Type | Description
buf | char * | • A character buffer for the result • Must be allocated by the programmer • isc_license_get_message() returns an error if buf is not long enough • Must be NULL-terminated
buf_len | short | • Length of buf

Description Places all certificate ID/key pairs that are currently in ib_license.dat into buf, separated by commas and NULL-terminated.

Return Value Returns zero if it succeeds. Otherwise, it returns the length that buf must have in order to contain the message text, and buf itself contains NULL.

u Back to top

isc_license_get_msg()

Returns the text of an error code.

    Syntax  unsigned short isc_get_msg(short msg_no, char *msg,
                     unsigned short msg_len)

Parameter | Type | Description
msg_no | short | A message number returned by one of the other isc_license_*() functions
msg | char * | • A character buffer for the message that corresponds to msg_no • Must be allocated by the programmer • Recommended length is ISC_LICENSE_MAX_MESSAGE_LEN
msg_len | short | The length of msg

Description When passed an error code from one of the other four functions in the License API, isc_license_get_msg() returns the text of the corresponding error message in the msg buffer.

Return Value isc_license_get_msg() returns zero if it succeeds. Otherwise, it returns the length that msg must have in order to contains the message text.

u Back to top

isc_modify_user()

Modifies a user record from the InterBase security database (admin.ib by default).

Note Use of this function is deprecated. It is replaced by a full featured Services API. See Chapter 12, “Working with Services” on page 12-1 and the reference entry for “isc_service_start()” on page 15-148.

    Syntax  ISC_STATUS isc_modify_user(
                     ISC_STATUS *status
                     USER_SEC_DATA *user_sec_data);

Parameter | Type | Description
status vector | ISC_STATUS * | Pointer to the error status vector
user_sec_data | USER_SEC_DATA * | Pointer to a struct that is defined in ibase.h

Description The three security functions, isc_add_user(), isc_delete_user(), and isc_modify_user() mirror functionality that is available in the gsec command-line utility. isc_modify_user() modifies a record from the InterBase security database.

At a minimum, you must provide the user name. Any additional user information that you supply, such as first name, last name, or password, overwrites the information that is already in the security database.

If the server is not local, you must provide both a server name and a protocol. Valid choices for the protocol field are sec_protocol_tcpip, sec_protocol_netbeui, and sec_protocol_local.

InterBase reads the settings for the ISC_USER and ISC_PASSWORD environment variables if you do not provide a DBA user name and password.

The definition for the USER_SEC_DATA struct in ibase.h is as follows:

    typedef struct {
      short  sec_flags;  /* which fields are specified */
      int    uid;         /* the user's id */
      int    gid;         /* the user's group id */
      int    protocol;    /* protocol to use for connection */
      char   *server;     /* server to administer */
      char   *user_name;  /* the user's name */
      char   *password;  /* the user's password */
      char   *group_name; /* the group name */
      char   *first_name; /* the user's first name */
      char   *middle_name; /* the user's middle name */
      char   *last_name; /* the user's last name */
      char   *dba_user_name; /* the dba user name */
      char   *dba_password; /* the dba password */
    } USER_SEC_DATA;

When you pass this struct to one of the three security functions, you can tell it which fields you have specified by doing a bitwise OR of the following values, which are defined in ibase.h:

    sec_uid_spec                0x01
    sec_gid_spec                0x02
    sec_server_spec             0x04
    sec_password_spec           0x08
    sec_group_name_spec         0x10
    sec_first_name_spec         0x20
    sec_middle_name_spec        0x40
    sec_last_name_spec          0x80
    sec_dba_user_name_spec      0x100
    sec_dba_password_spec       0x200

No bit values are available for user name and password, since they are required.

The following error messages exist for this function:

Table 15.23 Error messages for isc_modifyuser()

Code | Value | Description
isc_usrname_too_long | 335544747 | The user name passed in is greater than 31 bytes
isc_password_too_long | 335544748 | The password passed in is longer than 8 bytes
isc_usrname_required | 335544749 | The operation requires a user name
isc_password_required | 335544750 | The operation requires a password
isc_bad_protocol | 335544751 | The protocol specified is invalid
isc_dup_usrname_found | 335544752 | The user name being added already exists in the security database.
isc_usrname_not_found | 335544753 | The user name was not found in the security database
isc_error_adding_sec_record | 335544754 | An unknown error occurred while adding a user
isc_error_deleting_sec_record | 335544755 | An unknown error occurred while deleting a user
isc_error_modifying_sec_record | 335544756 | An unknown error occurred while modifying a user
isc_error_updating_sec_db | 335544757 | An unknown error occurred while updating the security database

Example The following example modifies the InterBase security database to change the password for the user Socks, using the bitwise OR technique for passing values from the USER_SEC_DATA struct.

    {
      ISC_STATUS status[20];
      USER_SEC_DATA sec;

      sec.server    = "kennel";
      sec.dba_user_name = "sysdba";
      sec.dba_password = "masterkey";
      sec.protocol  = sec_protocol_tcpip;
      sec.user_name = "socks";
      sec.password  = "feed_me!"; /* Note: do not hardcode passwords */
      sec.sec_flags = sec_server_spec
                    | sec_password_spec
                    | sec_dba_user_name_spec
                    | sec_dba_password_spec;

                      isc_add_user(status, &sec);
      /* check status for errors */
      if (status[0] == 1 && status[1])
      {
         switch (status[1]) {
         case isc_usrname_too_long:
            printf("Security database cannot accept long user names\n");
            break;
         ...
         }
      }
    }

Return Value isc_modify_user() returns the second element of the status vector. Zero indicates success. A nonzero value indicates an error. See the “Description” section for this function for a list of error codes. For more information about examining the status vector, see Chapter 10, “Handling Error Conditions.”

See also isc_add_user(), isc_delete_user()

u Back to top

isc_open_blob2()

Opens an existing Blob for retrieval and optional filtering.

    Syntax  ISC_STATUS isc_open_blob2(
                     ISC_STATUS *status_vector,
                     isc_db_handle *db_handle,
                     isc_tr_handle *trans_handle,
                     isc_blob_handle *blob_handle,
                     ISC_QUAD *blob_id,
                     short bpb_length,
                     char *bpb_address);

Parameter | Type | Description
status_vector | ISC_STATUS * | Pointer to the error status vector
db_handle | isc_db_handle * | Pointer to a database handle set by a previous call to isc_attach_database() db_handle returns an error in status_vector if it is NULL
trans_handle | isc_tr_handle * | Pointer to a transaction handle whose value has been set by a previous isc_start_transaction() call; trans_handle returns an error if NULL
blob_handle | isc_blob_handle * | Pointer to the Blob handle, which must be NULL when you make this call
blob_id | ISC_QUAD * | Pointer to the 64-bit system-defined Blob ID, which is stored in a field in the table and points to the first segment of the Blob or to a page of pointers to Blob fragments
bpb_length | short | Length of the Blob parameter buffer (BPB)
bpb_address | char * | Pointer to the BPB

Description isc_open_blob2() opens an existing Blob for retrieval and optional filtering from one Blob subtype to another.

Input and output Blob filter types are passed to isc_open_blob2() as subtype information in a previously populated BPB, pointed to by bpb_address. If Blob filters are not needed or cannot be used, a BPB is not needed; pass 0 for bpb_length and NULL for bpb_address.

The blob_id identifies which particular Blob is to be opened. This blob_id is set by a sequence of DSQL function calls.

On success, isc_open_blob2() assigns a unique ID to blob_handle. Subsequent API calls use this handle to identify the Blob against which they operate.

After a blob is opened, its data can be read by a sequence of calls to isc_get_segment().

When finished accessing the Blob, close it with isc_close_blob().

For more information about opening a Blob for retrieval and optional filtering, see Chapter 7, “Working with Blob Data.”

Example The following fragment is excerpted from the example file, api9.c. The example program displays job descriptions that are passed through a filter.

    while ((fetch_stat = isc_dsql_fetch(status, &stmt, 1, sqlda)) == 0)
    {
      printf("\nJOB CODE: %5s GRADE: %d", job_code, job_grade);
      printf(" COUNTRY: %-20s\n\n", job_country);
      /* Open the blob with the fetched blob_id. */
      isc_open_blob2(status, &DB, &trans, &blob_handle, &blob_id, 9, bpb);
      if (status[0] == 1 && status[1])
      {
         isc_print_status(status);
         return(1);
      }
    }

Return Value isc_open_blob2() returns the second element of the status vector. Zero indicates success. A nonzero value indicates an error. For InterBase errors, the first element of the status vector is set to 1, and the second element is set to an InterBase error code.

To check for an InterBase error, examine the first two elements of the status vector directly.

See also isc_close_blob()

u Back to top

isc_portable_integer()

Reverses the byte order of an integer. This supports INT64 (8 byte integer) values and is a superset of isc_vax_integer(), which supports only up to LONG (4 bytes) values.

    Syntax  ISC_INT64 isc_portable_integer(
                     char *buffer,
                     short length);

Parameter | Type | Description
buffer | char * | Pointer to the integer to convert
length | short | Length, in bytes, of the integer to convert Valid lengths are 1, 2, 4, and 8 bytes

Description isc_portable_integer() reverses the byte order of an integer, specified in buffer, and returns the newly ordered value.

A typical use for this function is to convert integer values passed into a database parameter buffer to a format where the least significant byte must be first and the most significant byte last. In InterBase, integer values must be represented in input parameter buffers (for example, the DPB) and are returned in result buffers in a generic format where the least significant byte is first, and the most significant byte last. isc_portable_integer() is used to convert integers to and from this format.

Example The following code fragment converts a 2-byte value, stored in a character buffer that is the result buffer returned by a function such as isc_database_info():

    #include <ibase.h>
    char *p;
    . . .
    for(p = res_buffer; *p != isc_info_end;)
    {
      /* Read item type of next cluster in the result buffer. */
      item = *p++;
      /* Read length of next value in result buffer, and convert. */
      len = isc_portable_integer(p, 2);
      p += len;
      /* Now process the actual value, len bytes in size. */
      . . .
    }

Return Value isc_portable_integer() always returns a byte-reversed INT64 (8 byte) value.

See also isc_attach_database(), isc_database_info()

u Back to top

isc_prepare_transaction()

Executes the first phase of a two-phase commit against multiple databases.

    Syntax  ISC_STATUS isc_prepare_transaction(
                     ISC_STATUS *status_vector,
                     isc_tr_handle *trans_handle);

Parameter | Type | Description
status_vector | ISC_STATUS * | Pointer to the error status vector
trans_handle | isc_tr_handle * | Pointer to a transaction handle whose value has been set by a previous isc_start_transaction() call; trans_handle returns an error if NULL

Description isc_prepare_transaction() initiates the first phase of a two-phase commit under program direction. It alerts InterBase, which polls all database participants and waits for replies. The isc_prepare_transaction() function puts the transaction in limbo.

Because a call to this function indicates that you intend to control all phases of the commit, you must complete the second phase of the commit by explicitly calling the isc_commit_transaction() function.

If a call to isc_prepare_transaction() fails, the application should roll back the transaction with a call to the isc_rollback_transaction() function.

Note If you want InterBase to automatically perform the two-phase commit, call isc_commit_transaction() without calling isc_prepare_transaction().

Example The following example executes the first phase of a two-phase commit and includes a rollback in case of failure:

    isc_prepare_transaction(status_vector, &trans);
    if (status_vector[0] == 1 && status_vector[1])
      rb_status = isc_rollback_transaction(status_vector, &trans)
    else
    {
      isc_commit_transaction(status_vector, &trans);
      if (!(status_vector[0] == 1 && status_vector[1]))
         fprintf(stderr, "Commit successful.\n");
    }

Return Value isc_prepare_transaction() returns the second element of the status vector. Zero indicates success. A nonzero value indicates an error. For InterBase errors, the first element of the status vector is set to 1, and the second element is set to an InterBase error code.

To check for an InterBase error, examine the first two elements of the status vector directly.

See also isc_commit_transaction(), isc_prepare_transaction2(), isc_rollback_transaction()

u Back to top

isc_prepare_transaction2()

Performs the first phase of a two-phase commit for multi-database transactions.

    Syntax  ISC_STATUS isc_prepare_transaction2(
                     ISC_STATUS *status_vector,
                     isc_tr_handle *trans_handle,
                     unsigned short msg_length,
                     char *message);

Parameter | Type | Description
status_vector | ISC_STATUS * | Pointer to the error status vector
trans_handle | isc_tr_handle * | Pointer to a transaction handle whose value has been set by a previous isc_start_transaction() call; trans_handle returns an error if NULL
msg_length | unsigned short | Length of message in bytes
message | char * | Transaction description buffer

Description isc_prepare_transaction2() performs the first phase of a two-phase commit, just as isc_prepare_transaction() does, but isc_prepare_transaction2() expects you to provide two additional arguments:

• An information message to write to the RDB$TRANSACTION_DESCRIPTION column in the RDB$TRANSACTIONS system table that describes the transaction to commit, so that recovery is possible in the event a system crash occurs during the completion of the commit.

• The length, in bytes, of the information message.

By electing to use isc_prepare_transaction2(), you are, in effect, disabling the automatic recovery functions inherent in the two-phase commit. It is your responsibility to deal with recovery issues that might occur during failure of the two-phase commit. Normally, InterBase automatically writes to the RDB$TRANSACTION_DESCRIPTION column in the RDB$TRANSACTIONS system table information that makes it possible to reconnect following a system crash during the commit. You can manually write a message string into RDB$TRANSACTIONS, by using the message parameter in this function.

At the risk of preventing recovery in the event of a system crash, you might choose to avoid writing a message to RDB$TRANSACTION altogether if you determine that there is too much overhead associated with this extra action every time your application commits.

Example The following example executes the first phase of a two-phase commit and includes a rollback in case of failure:

    isc_prepare_transaction2(status_vector, &trans, msg_len, msg);
    if (status_vector[0] == 1 && status_vector[1])
      rb_status = isc_rollback_transaction(status_vector, &trans);

Return Value isc_prepare_transaction2() returns the second element of the status vector. Zero indicates success. A nonzero value indicates an error. For InterBase errors, the first element of the status vector is set to 1, and the second element is set to an InterBase error code.

To check for an InterBase error, examine the first two elements of the status vector directly.

See also isc_commit_transaction(), isc_prepare_transaction(), isc_rollback_transaction()

u Back to top

isc_print_sqlerror()

Displays a SQLCODE value, a corresponding SQL error message, and any additional InterBase error messages in the error status vector.

    Syntax  void isc_print_sqlerror(
                     short SQLCODE,
                     ISC_STATUS *status_vector);

Parameter | Type | Description
SQLCODE | short | Variable containing a SQLCODE value
status_vector | ISC_STATUS * | Pointer to the error status vector

Description During the processing of DSQL API calls, SQL errors can occur. SQL errors are generally reported in a variable called SQLCODE. DSQL calls return error information to a user-defined error status vector like any other API call, but isc_print_sqlerror() can be used to interpret the primary error condition as a SQL error message for direct display on the screen. To use isc_print_sqlerror(), an application must declare both a SQLCODE variable for holding the SQL error number, and an error status vector for holding InterBase error information. isc_print_sqlerror() displays the SQLCODE value, a related SQL error message, and any additional InterBase error messages in the status array.

Note Some windowing systems do not permit direct screen writes. Do not use isc_print_sqlerror() when developing applications for these environments. Instead, use isc_sql_interprete() and isc_interprete() to capture messages to a buffer for display.

Example The following code calls isc_print_sqlerror() when an error occurs:

    #include <ibase.h>
    long SQLCODE;
    ISC_STATUS status_vector[20];
    . . .
    if (status_vector[0] == 1 && status_vector[1])
    {
      SQLCODE = isc_sqlcode(status_vector);
      isc_print_sqlerror(SQLCODE, status_vector);
    }

Return Value None.

See also isc_interprete(), isc_print_status(), isc_sql_interprete(), isc_sqlcode()

u Back to top

isc_print_status()

Builds and displays error messages based on the contents of the InterBase error status vector.

    Syntax  ISC_STATUS isc_print_status(ISC_STATUS *status_vector);

Parameter | Type | Description
status_vector | ISC_STATUS * | Pointer to the error status vector

Description isc_print_status() builds all error messages based on the contents of the error status vector, and displays them on the screen. status_vector must be declared in the program as an array of twenty elements.

Example The following code displays error messages when an error occurs during processing:

    #include <ibase.h>
    ISC_STATUS status_vector[20];
    . . .
    if (status_vector[0] == 1 && status_vector[1])
    {
      isc_print_status(status_vector);
      return(1);
    }

Return Value isc_print_status() returns the second element of the status vector. Zero indicates success. A nonzero value indicates an error. For InterBase errors, the first element of the status vector is set to 1, and the second element is set to an InterBase error code.

To check for an InterBase error, examine the first two elements of the status vector directly. For more information about examining the status vector, see Chapter 10, “Handling Error Conditions.”

See also isc_interprete(), isc_print_sqlerror(), isc_sqlcode(), isc_sql_interprete()

u Back to top

isc_put_segment()

Writes a Blob segment.

    Syntax  ISC_STATUS isc_put_segment(
                     ISC_STATUS *status_vector,
                     isc_blob_handle *blob_handle,
                     unsigned short seg_buffer_length,
                     char *seg_buffer);

Parameter | Type | Description
status_vector | ISC_STATUS * | Pointer to the error status vector
blob_handle | isc_blob_handle * | Pointer to the handle of the Blob to which you want to write; use isc_create_blob2() to set a value for this handle
seg_buffer_length | unsigned short | Length of the Blob segment buffer
seg_buffer_address | char * | Pointer to the Blob segment buffer that contains data for writing

Description isc_put_segment() writes a Blob segment in seg_buffer_address to a Blob previously created and opened with isc_create_blob2().

If a Blob filter was specified when the Blob was created, then each segment is filtered before storing the result into the Blob.

The behavior of isc_put_segment() depends on what call preceded it. If the most recent call was to isc_create_blob() or isc_create_blob2(), then a call to isc_put_segment() writes the first segment of the Blob. If the most recent call was to isc_put_segment(), then it writes the next segment.

You can write bitmaps and other binary files directly, without filtering, unless you intend to change from one format to another, say from GEM to BMP. You can also store compressed bitmaps directly in a database, in formats such as JPG (JPEG), BMP (Windows native bitmaps), or GIF (CompuServe Graphic Interchange Format).

You can store bitmaps in your database in row-major or column-major order.

You cannot update a Blob directly. If you want to modify Blob data, you must do one of the following:

• Create a new Blob.

• Read the old Blob data into a buffer where you can edit or modify it.

• Write the modified data to the new Blob.

• Prepare and execute an UPDATE statement that will modify the Blob column to contain the Blob ID of the new Blob, replacing the old Blob’s Blob ID.

For more information about creating and writing Blob data, see Chapter 7, “Working with Blob Data.”

Note To read a segment that you wrote with a call to isc_put_segment(), you must close the Blob with isc_close_blob(), and then open it with isc_open_blob2().

Example The following example reads a segment of one Blob and writes it to another Blob:

    get_status = isc_get_segment(status, &from_blob, &seg_len, 80, buffer);
    if (status[0] == 1 && status[1])
    {
      isc_print_status(status);
      return(1);
    }
    if (get_status != isc_segstr_eof)
      write_status = isc_put_segment(status, &to_blob, seg_len, buffer);
    if (status[0] == 1 && status[1])
    {
      isc_print_status(status);
      return(1);
    }

Return Value isc_put_segment() returns the second element of the status vector. Zero indicates success. A nonzero value indicates an error. For InterBase errors, the first element of the status vector is set to 1, and the second element is set to an InterBase error code.

To check for an InterBase error, examine the first two elements of the status vector directly. For more information about examining the status vector, see Chapter 10, “Handling Error Conditions.”

See also isc_close_blob(), isc_get_segment(), isc_open_blob2()

u Back to top

isc_que_events()

Requests asynchronous notification of one of a specified group of events.

    Syntax  ISC_STATUS isc_que_events(
                     ISC_STATUS *status_vector,
                     isc_db_handle *db_handle,
                     ISC_LONG *event_id,
                     short length,
                     char *event_buffer,
                     isc_callback event_function,
                     void *event_function_arg);

Parameter | Type | Description
status_vector | ISC_STATUS * | Pointer to the error status vector
db_handle | isc_db_handle * | Pointer to a database handle set by a previous call to isc_attach_database(); the handle identifies the database against which the events are expected to be posted db_handle returns an error in status_vector if it is NULL
event_id | ISC_LONG * | Pointer to an event identifier to set
length | short | Length of the event parameter buffers, returned by the isc_event_block() call which allocated them
event_buffer | char * | Pointer to the event parameter buffer that specifies the current counts of the events to be waited on; this buffer should have been initially allocated and filled in by a call to isc_event_block()
event_function | isc_callback | Pointer to the address of the function to receive event notification
event_function_arg | void * | First argument to be passed to event_function, usually a pointer to the event parameter buffer you want filled in with updated event counts

Description isc_que_events() is called to request asynchronous notification of any of the events listed in event_buffer. Upon completion of the call, but before events are posted, control is returned to the calling application, which can continue other processing. When a requested event is posted, InterBase calls the function specified in event_function to process event occurrence.

After event_function is called, you must call isc_que_events() again if you want to start another asynchronous wait on the specified events.

Note isc_que_events() cannot be called from within event_function.

If you want to cancel your isc_que_events() request for asynchronous event notification, call isc_cancel_events().

Note To request synchronous notification, call isc_wait_for_event().

Example The following program fragment illustrates calling isc_que_events() to wait asynchronously for event occurrences. Within a loop, it performs other processing, and checks the event flag (presumably set by the specified event function) to determine when an event has been posted. If one has, the program resets the event flag, calls isc_event_counts() to determine which events have been posted since the last call to isc_que_events(), and calls isc_que_events() to initiate another asynchronous wait.

    #include <ibase.h>
    #define number_of_stocks 3;
    #define MAX_LOOP 10

    char *event_names[] = {"DEC", "HP", "SUN"};
    char *event_buffer, *result_buffer;
    ISC_STATUS count_array[number_of_stocks];
    short length;
    ISC_LONG event_id;
    int i, counter;
    int event_flag = 0;

    length = (short)isc_event_block(
      &event_buffer,
      &result_buffer,
      number_of_stocks,
      "DEC", "HP", "SUN");

    isc_que_events(
      status_vector,
      &database_handle, /* Set in previous isc_attach_database(). */
      &event_id,
      length, /* Returned from isc_event_block(). */
      event_buffer,
      (isc_callback)event_function,
      result_buffer);
    if (status_vector[0] == 1 && status_vector[1])
    {
      isc_print_status(status_vector); /* Display error message. */
      return(1);
    };

    counter = 0;
    while (counter < MAX_LOOP)
    {
      counter++;

      if (!event_flag)
      {
         /* Do whatever other processing you want. */
         ;
      }
      else
      {  event_flag = 0;
         isc_event_counts(
            count_array,
            length,
            event_buffer,
            result_buffer);
         if (status_vector[0] == 1 && status_vector[1])
         {
            isc_print_status(status_vector); /* Display error message. */
            return(1);
         }

         for (i=0; i<number_of_stocks; i++)
            if (count_array[i])
            {
              /* The event has been posted. Do whatever is appropriate,
                 for example, initiating a buy or sell order.
                 Note: event_names[i] tells the name of the event
                 corresponding to count_array[i]. */
              ;
            }

         isc_que_events(
            status_vector,
            &database_handle,
            &event_id,
            length,
            event_buffer,
            (isc_callback)event_function,
            result_buffer);
         if (status_vector[0] == 1 && status_vector[1])
         {
            isc_print_status(status_vector); /* Display error message. */
            return(1);
         }
      }  /* End of else. */
    } /* End of while. */

    /* Let InterBase know you no longer want to wait asynchronously. */
    isc_cancel_events(
      status_vector,
      &database_handle,
      &event_id);
    if (status_vector[0] == 1 && status_vector[1])
    {
      isc_print_status(status_vector); /* Display error message. */
      return(1);
    }

Return Value isc_que_events() returns the second element of the status vector. Zero indicates success. A nonzero value indicates an error. For InterBase errors, the first element of the status vector is set to 1, and the second element is set to an InterBase error code.

To check for an InterBase error, examine the first two elements of the status vector directly.

See also isc_cancel_events(), isc_event_block(), isc_event_counts(), isc_wait_for_event()

u Back to top

isc_rollback_retaining()

Undoes changes made by a transaction and retains the transaction context after the rollback.

    Syntax  ISC_STATUS isc_rollback_retaining(
                     ISC_STATUS *status_vector,
                     isc_tr_handle *trans_handle);

Parameter | Type | Description
status_vector | ISC_STATUS * | Pointer to the error status vector
trans_handle | isc_tr_handle * | Pointer to a transaction handle whose value has been set by a previous isc_start_transaction() call; this function returns an error if trans_handle is NULL

Description isc_rollback_retaining() rolls back an active transaction and immediately clones itself. This means that the function retains the transaction name, system resources associated with the transaction, and the current state of any open cursors in the transaction. Although the function is actually initiating a new transaction, by assigning the new transaction the existing transaction handle it is, in effect, keeping the transaction open after the rollback. This results in improved performance by allowing an application to minimize the overhead of initiating additional transactions. isc_rollback_retaining() allows you to roll back updates while keeping a cursor open.

You can initiate a rollback within the active transaction but the rollback only affects uncommitted updates. In other words, a rollback is legal, even after the transaction context has been passed to the cloned transaction, but, in that case, the rollback will only affect the updates your application has made to the database since the last commit or rollback.

To audit the rollbacks made by your calls to this function, check the first element in the status vector to see if the call was successful. If this element contains a zero, the call was successful.

The transaction ends when you commit or roll back without using the retention feature, with a call to isc_commit_transaction() or isc_rollback_transaction().

Because the errors that trigger a rollback are frequently in the transaction context, you may find that calling isc_rollback_retaining() leads to a repetition of the original error. Unless you include error detection code for that case, you may inadvertently create an inescapable code loop.

Examples The following C/C++ code rolls back a transaction, prints a message, and starts a new transaction with the same handle within the same request:

    if (!isc_rollback_retaining(status, &retained_trans))
    {
      fprintf(stderr, "Rolled back and retained\n");
      isc_print_status(status);
    }

The following C/C++ code rolls back a transaction, prints a confirmation message, starts a new transaction with the same handle within the same request, or, if the rollback fails, prints an error message and rolls back.

    isc_rollback_retaining(status, &retained_trans);
    if (status[0] == 1 && status[1])
    {
      fprintf(stderr, "Error retaining; rolling back instead.\n");
      rb_status = isc_rollback_transaction(status, &retained_trans);
    }
    else
    {
      fprintf(stderr, "Rollback retaining successful.\n");
      tr_count++; /* Increments the number of recycles. */
    }

Return Value isc_rollback_retaining() returns the second element of the status vector. Zero indicates success. A nonzero value indicates an error. For InterBase errors, the first element of the status vector is set to 1, and the second element is set to an InterBase error code.

To check for an InterBase error, examine the first two elements of the status vector directly. For more information about examining the status vector, see Chapter 10, “Handling Error Conditions.”

See also isc_commit_retaining(), isc_commit_transaction(), isc_rollback_transaction(), isc_start_transaction()

u Back to top

isc_rollback_transaction()

Undoes changes made by a transaction, and restores the database to its state prior to the start of the specified transaction.

    Syntax  ISC_STATUS isc_rollback_transaction(
                     ISC_STATUS *status_vector,
                     isc_tr_handle *trans_handle);

Parameter | Type | Description
status_vector | ISC_STATUS * | Pointer to the error status vector
trans_handle | isc_tr_handle * | Pointer to a transaction handle whose value has been set by a previous isc_start_transaction() call; trans_handle returns an error if NULL

Description isc_rollback_transaction() rolls back a specified transaction, closes record streams, frees system resources, and sets the transaction handle to zero. It is typically used to undo all database changes made by a transaction when an error occurs.

A call to this function can fail only if:

• You pass a NULL or invalid transaction handle.

• The transaction dealt with more than one database and a communications link fails during the rollback operation. If that happens, subtransactions on the remote node will end up in limbo. You must use the database maintenance utility to manually roll back those transactions.

Example The following call rolls back a transaction:

    isc_rollback_transaction(status_vector, &trans);

Return Value isc_rollback_transaction() returns the second element of the status vector. Zero indicates success. A nonzero value indicates an error. For InterBase errors, the first element of the status vector is set to 1, and the second element is set to an InterBase error code.

To check for an InterBase error, examine the first two elements of the status vector directly.

See also isc_commit_transaction(), isc_rollback_retaining(), isc_start_transaction()

u Back to top

isc_service_attach()

Attaches to the InterBase Services Manager facility. You must do this before using the InterBase services functions to request execution of tasks or query information from the Services Manager.

    Syntax  ISC_STATUS isc_service_attach(
                     ISC_STATUS *status_vector,
                     unsigned short service_length,
                     char *service,
                     isc_svc_handle *svc_handle,
                     unsigned short spb_length,
                     char *spb);

Parameter | Type | Description
status_vector | ISC_STATUS * | Pointer to the error status vector
service_length | unsigned short | Length in characters of the service name; a value of zero means that the service name is a null-terminated string
service | char * | String containing the name of the service to which the client requests an attachment
svc_handle | isc_svc_handle * | Pointer to a long value containing the handle of the service structure
spb_length | unsigned short | Length in bytes of the services parameter buffer
spb | char * | Pointer to a services parameter buffer

Description You can use this function to attach to the Services Manager on a given InterBase server. The InterBase service must be running on that host before you can attach to the Services Manager.

You must specify the hostname and the literal string service_mgr in the service argument. For example, jupiter:service_mgr is the string you use to connect to the Services Manager on host jupiter using TCP/IP as the network protocol.

You must specify a user ID and the corresponding password as part of the options in the service parameter buffer. The Services Manager uses this user ID when performing service tasks you request.

There are components in the InterBase Express™ package for Delphi and C++Builder that provide a visual interface to the Services Manager. See the Developer’s Guide.

Example See “Attaching to the Services Manager with isc_service_attach( )” on page 12-3 for an example using C/C++ code.

Return Value isc_service_attach() returns the second element of the status vector. Zero indicates success. A nonzero value indicates an error. For InterBase errors, the first element of the status vector is set to 1, and the second element is set to an InterBase error code.

To check for an InterBase error, examine the first two elements of the status vector directly.

See also isc_service_detach(), isc_service_query(), isc_service_start()

u Back to top

isc_service_detach()

Terminates the attachment to the InterBase Services Manager.

    Syntax  ISC_STATUS isc_service_detach(
                     ISC_STATUS *status_vector,
                     isc_svc_handle *svc_handle);

Parameter | Type | Description
status_vector | ISC_STATUS * | Pointer to the error status vector
svc_handle | isc_svc_handle * | Pointer to a long value containing the handle of the service structure

Description After you have performed all tasks and retrieved all information needed from the Services Manager, you should use this function to detach.

There are components in the InterBase Express™ package for Delphi and C++Builder that provide a visual interface to the Services Manager. See the Developer’s Guide.

Example See “Detaching from a Services Manager with isc_service_detach( )” on page 12-5 for an example using C/C++ code.

Return Value isc_service_detach() returns the second element of the status vector. Zero indicates success. A nonzero value indicates an error. For InterBase errors, the first element of the status vector is set to 1, and the second element is set to an InterBase error code.

To check for an InterBase error, examine the first two elements of the status vector directly. For more information about examining the status vector, see Chapter 10, “Handling Error Conditions.”

See also isc_service_attach(), isc_service_query(), isc_service_start()

u Back to top

isc_service_query()

Requests and retrieves information about the InterBase server to which the client is attached.

    Syntax  ISC_STATUS isc_service_query(
                     ISC_STATUS *status_vector,
                     isc_svc_handle *svc_handle,
                     isc_resv_handle *reserved,
                     unsigned short send_spb_length,
                     char *send_spb,
                     unsigned short request_spb_length,
                     char *request_spb,
                     unsigned short buffer_length,
                     char *buffer);

Parameter | Type | Description
status_vector | ISC_STATUS * | Pointer to the error status vector
svc_handle | isc_svc_handle * | Pointer to a long value containing the handle of the service structure
reserved | isc_resv_handle * | Reserved for future use; should be NULL
send_spb_length | unsigned short | Length in bytes of the service parameter buffer
send_spb | char * | Pointer to a service parameter buffer containing flags for the Services Manager
request_spb_length | unsigned short | Length in bytes of the request buffer
request_spb | char * | Pointer to a buffer containing item specifiers for requested information
buffer_length | unsigned short | Length in bytes of the return buffer
buffer | char * | Pointer to a buffer containing information received from the Services Manager

Description Use isc_service_query() to request information from the Services Manager. You must have an active connection to a running Services Manager, made using isc_service_attach() (see page 15-145).

There are components in the InterBase Express™ package for Delphi and C++Builder that provide a visual interface to the Services Manager. See the Developer’s Guide.

Example There are several examples of using isc_service_query() with C/C++ in “Querying the Services Manager” on page 12-21.

Return Value isc_service_query() returns the second element of the status vector. Zero indicates success. A nonzero value indicates an error. For InterBase errors, the first element of the status vector is set to 1, and the second element is set to an InterBase error code.

To check for an InterBase error, examine the first two elements of the status vector directly.

See also isc_service_attach(), isc_service_detach(), isc_service_start()

u Back to top

isc_service_start()

Performs a service task on the InterBase server to which the client is attached.

    Syntax  ISC_STATUS isc_service_start(
                     ISC_STATUS *status_vector,
                     isc_svc_handle *svc_handle,
                     isc_resv_handle *reserved,
                     unsigned short spb_length,
                     char *spb);

Parameter | Type | Description
status_vector | ISC_STATUS * | Pointer to the error status vector
svc_handle | isc_svc_handle * | Pointer to a long value containing the handle of the service structure
reserved | isc_resv_handle * | Reserved for future use; should be NULL
spb_length | unsigned short | Length in bytes of the service parameter buffer
spb | char * | Pointer to a service parameter buffer containing flags and optional arguments instructing the Services Manager to perform specified tasks

Description Use isc_service_start() to initiate a task execution by the Services Manager. You must have an active connection to a running Services Manager, made using isc_service_attach() (see page 15-145).

There are components in the InterBase Express™ package for Delphi and C++Builder that provide a visual interface to the Services Manager. See the Developer’s Guide.

Example There are several examples of using isc_service_start() with C/C++ in “Invoking service tasks with isc_service_start( )” on page 12-5.

Return Value isc_service_start() returns the second element of the status vector. Zero indicates success. A nonzero value indicates an error. For InterBase errors, the first element of the status vector is set to 1, and the second element is set to an InterBase error code.

To check for an InterBase error, examine the first two elements of the status vector directly. For more information about examining the status vector, see Chapter 10, “Handling Error Conditions.”

See also isc_service_attach(), isc_service_detach(), isc_service_query()

u Back to top

isc_sqlcode()

Translates an InterBase error code in the error status vector to a SQL error code number.

    Syntax  ISC_LONG isc_sqlcode (ISC_STATUS *status_vector);

Parameter | Type | Description
status_vector | ISC_STATUS * | Pointer to the error status vector

Description isc_sqlcode() searches status_vector for a reported SQL error, and if it finds it, translates the InterBase error code number into an appropriate SQL error code. Typically, this call is used to populate a program variable (usually called SQLCODE for portability among SQL implementations) with a SQL error number for use in a SQL error-handling routine.

Example The following code illustrates how isc_sqlcode() might be called in a DSQL application:

    #include <ibase.h>
    long SQLCODE;
    ISC_STATUS status_vector[20];
    . . .
    if (status_vector[0] == 1 && status_vector[1])
    {
      SQLCODE = isc_sqlcode(status_vector);
      isc_print_sqlerror(SQLCODE, status_vector);
    }

Return Value If successful, isc_sqlcode() returns the first valid SQL error code decoded from the InterBase status vector.

If no valid SQL error code is found, isc_sqlcode() returns –999.

See also isc_interprete(), isc_print_sqlerror(), isc_print_status(), isc_sql_interprete()

u Back to top

isc_sql_interprete()

Builds a SQL error message string and stores it in a user-defined buffer.

    Syntax  void isc_sql_interprete(
                     short SQLCODE,
                     char *buffer,
                     short buffer_length);

Parameter | Type | Description
SQLCODE | short | Variable containing a SQLCODE value
buffer | char * | Application buffer into which to store a SQL error message
buffer_length | short | Length, in bytes, of buffer

Description Given a SQLCODE value less than zero, isc_sql_interprete() builds a corresponding SQL error message string, and stores it in a user-defined buffer. The size of the buffer, in bytes, must also be passed to this function.

To display a SQL error message corresponding to a SQLCODE value, use isc_print_sqlerror() instead of this call.

Example The following code fragment illustrates a call to isc_sql_interprete():

    #include <ibase.h>
    long SQLCODE;
    char err_buf[256];
    . . .
    if (status_vector[0] == 1 && status_vector[1])
    {
      SQLCODE = isc_sqlcode(status_vector);
      isc_sql_interprete(SQLCODE, err_buf, sizeof(err_buff));
    }

Return Value None.

See also isc_interprete(), isc_print_sqlerror(), isc_print_status(), isc_sqlcode()

u Back to top

isc_start_multiple()

Begins a new transaction against multiple databases.

    Syntax  ISC_STATUS isc_start_multiple(
                     ISC_STATUS *status_vector,
                     isc_tr_handle *trans_handle,
                     short db_handle_count,
                     void *teb_vector_address);

Parameter | Type | Description
status_vector | ISC_STATUS * | Pointer to the error status vector
trans_handle | isc_tr_handle * | Pointer to a transaction handle whose value has been set by a previous isc_start_transaction() call; trans_handle returns an error if NULL
db_handle_count | short | Number of database handles passed in this call via transaction existence buffers (TEBs)
teb_vector_address | void * | Pointer to the TEB

Description Call isc_start_multiple() if you:

• Are using a language that does not support a variable number of arguments in a function call.

• Do not know how many databases you want to attach to when coding the start transaction function.

isc_start_multiple() passes information about each target database to InterBase. That information is stored in an array of transaction existence blocks (TEBs) pointed to by the teb_vector parameter.

teb_vector is a pointer to a byte array that consists of consecutive TEBs, one TEB for each database to connect to. Each TEB consists of three items: a pointer to the database handle for a database against which the transaction should run; the length, in bytes, of the transaction parameter buffer (TPB) for the database, and a pointer to the TPB. The items in a TEB correspond to the items passed directly as parameters in calls to isc_start_transaction(). C programmers should use isc_start_transaction() instead of isc_start_multiple() whenever possible because it does not require setting up TEBs.

For more information about establishing TEBs and calling isc_start_multiple(), see “Calling isc_start_multiple()” on page 5-13 of Chapter 5, “Working with Transactions.”

Example The following program starts a multiple-database transaction:

    #include <ibase.h>

    typedef struct { /* Define the ISC_TEB structure. */
      int *dbb_ptr;
      long tpb_len;
      char *tpb_ptr;
    } ISC_TEB;

    ISC_TEB  teb_vec[2]; /* Declare the TEB vector. */

    ISC_STATUS isc_status[20]; /* Status vector. */
    long *db0, *db1, /* Database handle. */
    long *trans; /* Transaction handle. */

    static char
      isc_tpb_0[] = { /* Declare the first transaction parameter
    buffer. */
         isc_tpb_version3,  /* InterBase version. */
         isc_tpb_write, /* Read-write access. */
         isc_tpb_consistency,  /* Serializable. */
         isc_tpb_wait, /* Wait on lock. */
         isc_tpb_lock_write, 3, /* Reserving IDS for update. */
         'I','D','S',
         isc_tpb_protected}, /* Don't allow other transactions to
                    write to the table. */

      isc_tpb_1[] = { /* Declare the second transaction.*/
                    /* Parameter buffer. */
         isc_tpb_version3,  /* InterBase version. */
         isc_tpb_write, /* Read-write access. */
         isc_tpb_consistency,  /* Serializable. */
         isc_tpb_wait, /* Wait on lock. */
         isc_tpb_lock_write, 3, /* Reserving table OZS for update. */
         'O','Z','S',
         isc_tpb_protected}; /* Don’t allow other transactions to
                    write to the table. */

    main()
    {
    db0 = db1 = 0;
    trans = 0;

    /* If you can't attach to test_0 database, attach to test_1. */

    isc_attach_database(isc_status, 0, "test_0.ib", &db0, 0,0);
    if (isc_status[0] == 1 && isc_status[1])
      isc_attach_database(isc_status, 0, "test_1.ib", &db1, 0,0);

    if (db0 && db1)
      {          /* Assign database handles, tpb length, and
                 tbp handle to the teb vectors. */
      teb_vec[0].dbb_ptr = &db0;
      teb_vec[0].tpb_len = sizeof (isc_tpb_0);
      teb_vec[0].tpb_ptr = isc_tpb_0;

      teb_vec[1].dbb_ptr = &db1;
      teb_vec[1].tpb_len = sizeof (isc_tpb_1);
      teb_vec[1].tpb_ptr = isc_tpb_1;

      if (isc_start_multiple(isc_status, &trans, 2, teb_vec))
      isc_print_status(isc_status);
      }

    if (trans)
      isc_commit_transaction(isc_status, &trans);

    if (db0 && !trans)
      isc_detach_database(isc_status, &db0);

    if (db1 && !(trans && db0))
      isc_detach_database(isc_status, &db1);

    if (isc_status[0] == 1 && isc_status[1])
      isc_print_status(isc_status);
    }

Return Value isc_start_multiple() returns the second element of the status vector. Zero indicates success. A nonzero value indicates an error. For InterBase errors, the first element of the status vector is set to 1, and the second element is set to an InterBase error code.

To check for an InterBase error, examine the first two elements of the status vector directly.

See also isc_commit_transaction(), isc_prepare_transaction(), isc_prepare_transaction2(), isc_rollback_transaction(), isc_start_transaction()

u Back to top

isc_start_transaction()

Starts a new transaction against one or more databases.

    Syntax  ISC_STATUS isc_start_transaction(
                     ISC_STATUS *status_vector,
                     isc_tr_handle *trans_handle,
                     short db_handle_count,
                     isc_db_handle *db_handle,
                     unsigned short tpb_length,
                     char *tpb_address,
                     [isc_db_handle *db_handle,
                     unsigned short tpb_length,
                     char *tpb_address ...]);

Parameter | Type | Description
status_vector | ISC_STATUS * | Pointer to the error status vector
trans_handle | isc_tr_handle * | Pointer to a transaction handle whose value has been set by a previous isc_start_transaction() call; trans_handle returns an error if NULL
db_handle_count | short | Number of database handles passed in this call
db_handle | isc_db_handle * | Pointer to a database handle set by a previous call to isc_attach_database(); the handle identifies the database against which the events are expected to be posted db_handle returns an error in status_vector if it is NULL
tpb_length | unsigned short | Length of the transaction parameter buffer (TPB)
tpb_address | char * | Pointer to the TPB

Description isc_start_transaction() starts a new transaction against one or more databases specified as database handles.

Note If you have a variable number of databases to update, or are using a language that does not support a variable number of arguments in a function call, use isc_start_multiple() instead of isc_start_transaction().

A single transaction can access multiple databases. This function passes information about each database it accesses and the conditions of access for that database in a transaction parameter buffer (TPB). The TPB is a variably-sized vector of bytes declared and populated by the program. It contains information describing intended transaction behavior such as its access and lock modes.

isc_start_transaction() can start a transaction against up to 16 databases. You must pass a database handle and a TPB for each referenced database. If you want to use defaults for the transaction, set tpb_length to zero. In this case, tpb_vector is a NULL pointer.

Example The following program includes a call to the start transaction function:

    #include <ibase.h>

    long
      isc_status[20], /* Status vector. */
      *db, /* Database handle. */
      *trans, /* Transaction handle. */

    static char
      isc_tpb_0[] = {
         isc_tpb_version3,  /* InterBase version. */
         isc_tpb_write, /* Read-write access. */
         isc_tpb_consistency,  /* Consistency-mode transaction. */
         isc_tpb_wait, /* Wait on lock. */
         isc_tpb_lock_write, 3, /* Reserving IDS table for update. */
         "I","D","S",
         isc_tpb_protected}; /* Don't allow other transactions to
                    write against this table. */
    main()
    {
    db = trans = 0;
    isc_attach_database(isc_status, 0, "test.ib", &db, 0,0);

    if (db)
    {
      isc_start_transaction(
         isc_status, &trans, 1, &db,
         sizeof(isc_tpb_0), isc_tpb_0);
      if (isc_status[0] == 1 && isc_status[1])
         isc_print_status(isc_status);
    }
    if (trans)
      isc_commit_transaction(isc_status, &trans);

    if (db && !trans)
      isc_detach_database(isc_status, &db);

    if (status_vector[0] == 1 && status_vector[1])
      isc_print_status(isc_status);
    }

Return Value isc_start_transaction() returns the second element of the status vector. Zero indicates success. A nonzero value indicates an error. For InterBase errors, the first element of the status vector is set to 1, and the second element is set to an InterBase error code.

To check for an InterBase error, examine the first two elements of the status vector directly.

See also isc_commit_transaction(), isc_prepare_transaction(), isc_prepare_transaction2(), isc_rollback_transaction(), isc_start_multiple()

u Back to top

isc_transaction_info()

Returns information about the specified named transaction.

    Syntax  ISC_STATUS isc_transaction_info(
                     ISC_STATUS *status_vector,
                     isc_tr_handle *trans_handle,
                     short item_list_buffer_length,
                     char *item_list_buffer,
                     short result_buffer_length,
                     char *result_buffer);

Parameter | Type | Description
status_vector | ISC_STATUS * | Pointer to the error status vector
trans_handle | isc_tr_handle * | Pointer to a transaction handle whose value has been set by a previous isc_start_transaction() call; trans_handle returns an error if NULL
item_list_buffer_length | short | Number of bytes in the item-list buffer
item_list_buffer | char * | Pointer to the item-list buffer
result_buffer_length | short | Number of bytes in the result buffer
result_buffer | char * | Pointer to the result buffer

Description isc_transaction_info() returns information necessary for keeping track of transaction IDs. This call is used internally by isc_prepare_transaction(). You should not need to use it in your own applications.

You can explicitly retrieve information about the transaction ID by including the following constant in the item-list buffer, where the transaction items about which you want information are listed:

Table 15.24 Transaction information request item

Item | Purpose | Size of next value | Value
isc_info_tra_id | Determine the transaction ID | 2 bytes | transaction ID

isc_transaction_info() uses two buffers defined in the calling program: the item-list buffer, which lists transaction items about which you want information, and a result buffer, where the information requested is reported.

To define the item-list buffer, include the parameters item_list_buffer_length and item_list_buffer_address. The item-list buffer is a regular byte vector with no structure.

To define the result buffer, include the parameters result_buffer_length and result_buffer_address. These parameters specify the length and address of a buffer where the InterBase engine will place the return values from the function call.

The values returned to the result buffer are unaligned clusters of generic binary numbers. Furthermore, all numbers are represented in a generic format, with the least significant byte first, and the most significant byte last. Signed numbers have the sign in the last byte. Convert the numbers to a datatype native to your system before interpreting them.

In your call, include the item specifying the transaction ID, isc_info_tra_id. InterBase returns the transaction ID in the result buffer. In addition to the information InterBase returns in response to a request, InterBase can also return one or more of the following status messages to the result buffer. Each status message is one unsigned byte in length:

Table 15.25 Status message return items

Item | Description
isc_info_end | End of the messages
isc_info_truncated | Result buffer is too small to hold any more requested information
isc_info_error | Requested information is unavailable; check the status vector for an error code and message

The function return value indicates only that InterBase accepted the request for information. It does not mean that it understood the request or that it supplied all of the requested information. Your application must interpret the contents of the result buffer for details about the transaction.

Example The following code fragment gets information about a transaction:

    static char     /* Declare item-list buffer. */
    tra_items[] =
      {isc_info_tra_id};
                    /* Declare result buffer. */
    CHAR tra_info[32];

    isc_transaction_info(status_vector,
         &tr_handle,
         sizeof (tra_items), /* Length of item-list buffer. */
         &tra_items,  /* Address of item-list buffer. */
         sizeof (tra_info), /* Length of result buffer. */
         &tra_info); /* Address of result buffer. */
    if (status_vector[0] == 1 && status_vector[1])
    {
      isc_print_status(status_vector);
      return(1);
    }

Return Value isc_transaction_info() returns the second element of the status vector. Zero indicates success. A nonzero value indicates an error. For InterBase errors, the first element of the status vector is set to 1, and the second element is set to an InterBase error code.

To check for an InterBase error, examine the first two elements of the status vector directly.

See also isc_start_transaction()

u Back to top

isc_uninstall_execute()

Removes installed InterBase files (with the exceptions noted below), updates the registry, removes shared files that have a reference count less than 1, and uninstalls the InterBase Guardian and Server services.

    Syntax  MSG_NO isc_uninstall_execute(TEXT *uninstall_file_name,
                     FP_STATUS *fpstatus, void *status_arg, FP_ERROR *fp_error,
                     void *error_arg)

Parameter | Type | Description
uninstall_file_ name | TEXT * | The name of the file containing the options that were installed; cannot be NULL
fp_status | FP_STATUS * | A pointer to a callback function that accepts an integer from 0 to 100; can be NULL if no status information is required by the end user
status_arg | void* | User-defined data to be passed to fp_status(); value is often NULL
fp_error | FP_ERROR* | A pointer to a callback function that accepts an error number and returns a mnemonic specifying whether isc_uninstall_execute() should abort, retry, or continue
error_arg | void* | User-defined data to be passed to fp_error(); value is often NULL

Description isc_uninstall_execute() performs the actual uninstall, including the following steps:

• Calls isc_uninstall_precheck() to ensure the uninstall can be performed

• Decrements UseCount entries in the Registry for shared files and removes any files that have a reference count less than one, except for files that have a value of zero preassigned by Microsoft (such as msvcrt.dll)

• Removes all InterBase files named in ib_uninst.nnn except for the InterBase security database (admin.ib by default) and its backup, and ib_license.dat.

• Removes all registry entries in ib_uninst.nnn

• On Windows NT/2000/XP, uninstalls the Guardian and Server services; on Windows 98, removes their Run registry entries

• Calls fp_status() at regular intervals to keep caller informed of uninstall status

• Cleans up if uninstall is cancelled by the user or by an error.

Return Value Returns zero if the function executes successfully, a positive number if an error occurs, and a negative number if the function completes but with warnings. Call isc_install_get_message() to obtain the error message when the result is nonzero.

u Back to top

isc_uninstall_precheck()

Checks for a running server, correct user permission, and validity of the uninstall file.

    Syntax  MSG_NO isc_uninstall_precheck(TEXT *uninstall_file_name)

Parameter | Type | Description
uninstall_file_name | TEXT * | A pointer to the name of the uninstall file that was created by isc_install_execute(); cannot be NULL.

Description isc_uninstall_precheck() performs several checks to determine if an uninstall is possible. It checks:

• That the operating system is valid: Windows

• That the uninstall file (ib_uninst.nnn) is valid and contains the streamed list of options

• That the server, if installed, is not running

• That the user performing the uninstall is a member of either the administrator or poweruser groups when the platform is Windows NT/2000/XP; no equivalent check is performed on Windows 98.

Return Value Returns zero if the function executes successfully, a positive number if an error occurs, and a negative number if the function completes but with warnings. Call isc_install_get_message() to obtain the error message when the result is nonzero.

u Back to top

isc_vax_integer()

Deprecated. Reverses the byte order of an integer. this function is still supported, but has been replaced by isc_portable_integer(); isc_vax_integer() only supports up to LONG (4 bytes) values.

    Syntax  ISC_LONG isc_vax_integer(
                     char *buffer,
                     short length);

Parameter | Type | Description
buffer | char * | Pointer to the integer to convert
length | short | Length, in bytes, of the integer to convert Valid lengths are 1, 2, and 4 bytes

Description isc_vax_integer() reverses the byte order of an integer, specified in buffer, and returns the newly ordered value.

A typical use for this function is to convert integer values passed into a database parameter buffer to a format where the least significant byte must be first and the most significant byte last. In InterBase, integer values must be represented in input parameter buffers (for example, the DPB) and are returned in result buffers in a generic format where the least significant byte is first, and the most significant byte last. isc_vax_integer() is used to convert integers to and from this format.

Example The following code fragment converts a 2-byte value, stored in a character buffer that is the result buffer returned by a function such as isc_database_info():

    #include <ibase.h>
    char *p;
    . . .
    for(p = res_buffer; *p != isc_info_end;)
    {
      /* Read item type of next cluster in the result buffer. */
      item = *p++;
      /* Read length of next value in result buffer, and convert. */
      len = isc_vax_integer(p, 2);
      p += len;
      /* Now process the actual value, len bytes in size. */
      . . .
    }

Return Value isc_vax_integer() always returns a byte-reversed long integer value.

See also isc_attach_database(), isc_database_info()

u Back to top

isc_version()

Returns database implementation and version information.

    Syntax  int isc_version(
                     isc_db_handle *db_handle,
                     isc_callback function_name,
                     void *user_arg);

Parameter | Type | Description
db_handle | isc_db_handle * | • Pointer to a database handle set by a previous call to isc_attach_database() • db_handle returns an error in status_vector if it is NULL
function_name | isc_callback | • Pointer to a function to call with the relevant information • Passing a NULL pointer in C programs calls printf()
user_arg | void * | An application-specified parameter to pass as the first of two arguments to function_name

Description isc_version() determines the database implementation and on-disk structure (ODS) version numbers for the database specified by db_handle. It passes this information in two separate calls to the callback function pointed to by function_name.

function_name should point to an application function that takes two arguments: a void pointer, user_arg, and a char pointer. Applications can pass any kind of parameter desired in user_arg.

isc_version() makes two calls to function_name. First it determines the database implementation number, builds a string containing the information, and calls function_name with user_arg, and a pointer to the string containing the implementation number in the following format:

    <implementation>(<class>), version "<version>"

where:

• implementation is a text string, such as “InterBase/NT”.

• class is a text string specifying the implementation class, such as “access method”.

• version is a version identification string, such as “7.0”.

The callback function specified by function_name is free to do with this information what it pleases.

After the callback function returns control to isc_version(), isc_version() builds a new string containing the ODS major and minor version numbers, then calls function_name a second time with user_arg, and a pointer to the string containing the ODS version number in the following format:

    on disk structure version <ods_major_num>.<ods_minor_num>

where:

• ods_major_num is the major ODS number. InterBase supports both ODS version 9 and ODS version 10. A database server can access databases of either version, but a single database must be either version 9 or version 10.

• ods_minor_num is the minor ODS number. Differences in the minor ODS number do not affect database access.

Tip If a NULL pointer is passed for function_name, isc_version() sets function_name to point to the C printf() function.

Examples The following code fragment calls isc_version() with a NULL callback function:

    #include <ibase.h>
    . . .
    int ret;
    . . .
    ret = isc_version(&db1, NULL, "\t%s\n");

Return Value If successful, isc_version() returns 0. Otherwise, it returns a nonzero value.

See also isc_database_info()

u Back to top

isc_wait_for_event()

Waits synchronously until one of a specified group of events is posted.

Note The isc_wait_for_event() function was called gds_$event_wait() in InterBase 3.3. It is therefore the only function that can’t be translated from 3.3 nomenclature to all later versions by replacing gds_$ with isc_.

    Syntax  ISC_STATUS isc_wait_for_event(
                     ISC_STATUS *status_vector,
                     isc_db_handle *db_handle,
                     short length,
                     char *event_buffer,
                     char *result_buffer);

Parameter | Type | Description
status_vector | ISC_STATUS * | Pointer to the error status vector
db_handle | isc_db_handle * | • Pointer to a database handle set by a previous call to isc_attach_database(); the handle identifies the database against which the events are expected to be posted • db_handle returns an error in status_vector if it is NULL
length | short | Length of the event parameter buffers, returned by the isc_event_block() call which allocated them
event_buffer | char * | Pointer to the event parameter buffer that specifies the current counts of the events to be waited on; this buffer should have been initially allocated and filled in by a call to isc_event_block()
result_buffer | char * | Pointer to the event parameter buffer to be filled in with updated event counts as a result of this function call; this buffer should have been initially allocated by a call to isc_event_block()

Description isc_wait_for_event() is used to wait synchronously until one of a specified group of events is posted. Control is not returned to the calling application until one of the specified events occurs.

Events to wait on are specified in event_buffer, which should have been initially allocated and filled in by a previous call to isc_event_block().

When one of these events is posted, isc_wait_for_event() fills in result_buffer with data that exactly corresponds to that in the initial buffer, except that the event counts will be the updated ones. Control then returns from isc_wait_for_event() to the calling application. The application should then call isc_event_counts() to determine which event was posted.

Note To request asynchronous notification of event postings, use isc_que_events() instead of isc_wait_for_event(). You must use asynchronous notifications in Microsoft Windows applications, or wherever a process must not stop processing.

Example The following program fragment illustrates a call to isc_wait_for_event() to wait for a posting of any of the events named “DEC”, “HP”, or “SUN”.

    #include <ibase.h>
    #define number_of_stocks 3;

    char *event_buffer, *result_buffer;
    short length;

    length = (short)isc_event_block(
      &event_buffer,
      &result_buffer,
      number_of_stocks,
      "DEC", "HP", "SUN");

    isc_wait_for_event(
      status_vector,
      &database_handle,
      length, /* Returned from isc_event_block(). */
      event_buffer,
      result_buffer);
    if (status_vector[0] == 1 && status_vector[1])
    {
      isc_print_status(status_vector); /* Display error message. */
      return(1);
    }

    /* Call isc_event_counts() to compare event counts in the buffers and thus
    determine which event(s) were posted. */

Return Value isc_wait_for_event() returns the second element of the status vector. Zero indicates success. A nonzero value indicates an error. For InterBase errors, the first element of the status vector is set to 1, and the second element is set to an InterBase error code.

To check for an InterBase error, examine the first two elements of the status vector directly. For more information about examining the status vector, see Chapter 10, “Handling Error Conditions.”

See also isc_event_block(), isc_que_events()

u Back to top