#ifndef _DRIVERMANAGER_H
#define _DRIVERMANAGER_H

#define ODBCVER 0x0351

#include <sys/types.h>
#include <pwd.h>
#include <dlfcn.h>
#include <string.h>

#ifdef HAVE_LIBPTHREAD
#include <pthread.h>
#endif

#include <log.h>
#include <ini.h>
#include <odbcinstext.h>
#include <sqlext.h>                     /* THIS WILL BRING IN sql.h and
                                           sqltypes.h AS WELL AS PROVIDE
                                           MS EXTENSIONS */

/*
 * DEFAULT FILE NAMES
 *
 */
#define VERSION "1.8.3"

#define INISYSTEM	"/etc/odbc.ini"
#define INIUSER		"~/.odbc.ini"
#define INIDRIVERS  "/etc/odbcinst.ini"

/*
 * magic numbers
 */

#define HENV_MAGIC      19289
#define HDBC_MAGIC      19290
#define HSTMT_MAGIC     19291
#define HDESC_MAGIC     19292

/*
 * states
 */

#define STATE_E0        0
#define STATE_E1        1
#define STATE_E2        2

#define STATE_C0        0
#define STATE_C1        1
#define STATE_C2        2
#define STATE_C3        3
#define STATE_C4        4
#define STATE_C5        5
#define STATE_C6        6

#define STATE_S0        0
#define STATE_S1        1
#define STATE_S2        2
#define STATE_S3        3
#define STATE_S4        4
#define STATE_S5        5
#define STATE_S6        6
#define STATE_S7        7
#define STATE_S8        8
#define STATE_S9        9
#define STATE_S10       10
#define STATE_S11       11
#define STATE_S12       12

#define STATE_D0        0
#define STATE_D1i       1
#define STATE_D1e       2

/*
 * structure to contain the loaded lib entry points
 */

struct driver_func
{
    int         ordinal;
    char        *name;
    void        *dm_func;               /* this is to fix what seems a bug in */
			                            /* some dlopen implemnations where dlsym */
					                    /* will return the driver manager func */
					                    /* not the driver one */
    SQLRETURN   (*func)();
    int         can_supply;             /* this is used to indicate that */
                                        /* the DM can execute the function */
                                        /* even if the driver does not */
                                        /* supply it */
};

typedef struct error
{
    char        sqlstate[ 6 ];
    char        *msg;
    int         native_error;
    int         return_val;
    struct error *next;
    struct error *prev;

} ERROR;

typedef struct error_header
{
    int         error_count;
    ERROR       *error_list_head;
    ERROR       *error_list_tail;
    int         internal_count;
    ERROR       *internal_list_head;
    ERROR       *internal_list_tail;
} EHEADER;

typedef struct error_head
{
    EHEADER     sql_error_head;
    EHEADER     sql_diag_head;
    void        *owning_handle;
    int         handle_type;
    SQLINTEGER  return_code;
} EHEAD;

typedef struct 
{
    char *program_name;
    char *log_file;
} *DMLHANDLE;

typedef struct environment
{
    int             type;               /* magic number */
    DMLHANDLE       log_handle;         /* handle to log */
    struct environment *next_class_list; /* static list of all env handles */
    SQLCHAR         msg[ LOG_MSG_MAX ];	/* buff to format msgs */
    int             state;              /* state of environment */
    SQLINTEGER      requested_version;  /* SQL_OV_ODBC2 or SQL_OV_ODBC3 */
    int             connection_count;   /* number of hdbc of this env */
    int             sql_driver_count;   /* used for SQLDrivers */
    EHEAD           error;              /* keep track of errors */
    SQLINTEGER      connection_pooling; /* does connection pooling operate */
    SQLINTEGER      cp_match;
    int             fetch_mode;         /* for SQLDataSources */
    int             entry;
#ifdef HAVE_LIBPTHREAD
    pthread_mutex_t mutex;              /* protect the object */
#endif
} *DMHENV;

typedef struct connection
{
    int             type;               /* magic number */
    DMLHANDLE       log_handle;         /* handle to log */
    struct connection *next_class_list; /* static list of all dbc handles */
    SQLCHAR         msg[ LOG_MSG_MAX ];	/* buff to format msgs */
    int             state;              /* state of connection */
    DMHENV          environment;         /* environment that own's the
                                           connection */
    void            *dl_handle;         /* handle of the loaded lib */
    struct driver_func *functions;      /* entry points */
    SQLHANDLE       driver_env;         /* environment handle in client */
    SQLHANDLE       driver_dbc;         /* connection handle in client */
    int             driver_version;     /* required version of the connected */
                                        /* driver */
    int             driver_act_ver;     /* real version of the driver */
    int             statement_count;    /* number of statements on this dbc */
    EHEAD           error;              /* keep track of errors */
    char            dsn[ SQL_MAX_DSN_LENGTH + 1 ];  /* where we are connected */
    int             access_mode;        /* variables set via SQLSetConnectAttr */
    int             autocommit_mode;
    int             login_timeout;
    SQLINTEGER      cursors;
    void            *cl_handle;         /* handle to the cursor lib */
    int             trace;
    char            tracefile[ INI_MAX_PROPERTY_VALUE + 1 ];
#ifdef HAVE_LIBPTHREAD
    pthread_mutex_t mutex;              /* protect the object */
    int             protection_level;
#endif
} *DMHDBC;

typedef struct descriptor
{
    int             type;               /* magic number */
    DMLHANDLE       log_handle;         /* handle to log */
    struct descriptor *next_class_list; /* static list of all desc handles */
    SQLCHAR         msg[ LOG_MSG_MAX ];	/* buff to format msgs */
    int             state;              /* state of descriptor */
    EHEAD           error;              /* keep track of errors */
    SQLHDESC        driver_desc;        /* driver descriptor */
    DMHDBC          connection;         /* DM connection that owns this */
    int             implicit;           /* created by a AllocStmt */
#ifdef HAVE_LIBPTHREAD
    pthread_mutex_t mutex;              /* protect the object */
#endif
} *DMHDESC;

typedef struct statement
{
    int             type;               /* magic number */
    DMLHANDLE       log_handle;         /* handle to log */
    struct statement *next_class_list; /* static list of all stmt handles */
    SQLCHAR         msg[ LOG_MSG_MAX ];	/* buff to format msgs */
    int             state;              /* state of statement */
    DMHDBC          connection;         /* DM connection that owns this */
    SQLHANDLE       driver_stmt;        /* statement in the driver */
    SQLSMALLINT     numcols;            /* Number of columns in the result set */
    int             prepared;           /* the statement has been prepared */
    int             interupted_func;    /* current function running async */
                                        /* or NEED_DATA */
    int             interupted_state;   /* state we went into need data or */
                                        /* still executing from */
    int             bookmarks_on;       /* bookmarks are set on */
    EHEAD           error;              /* keep track of errors */
    DMHDESC         ipd;                /* current descriptors */
    DMHDESC         apd;
    DMHDESC         ird;
    DMHDESC         ard;
    DMHDESC         implicit_ipd;       /* implicit descriptors */
    DMHDESC         implicit_apd;
    DMHDESC         implicit_ird;
    DMHDESC         implicit_ard;
    SQLUINTEGER     *fetch_bm_ptr;      /* Saved for ODBC3 to ODBC2 mapping */ 
    SQLUSMALLINT    *row_ct_ptr;        /* row count ptr */
    SQLUSMALLINT    *row_st_arr;        /* row status array */
#ifdef HAVE_LIBPTHREAD
    pthread_mutex_t mutex;              /* protect the object */
#endif
} *DMHSTMT;

#ifdef HAVE_LIBPTHREAD
#define TS_LEVEL0   0           /* no implicit protection, only for */
                                /* dm internal structures */
#define TS_LEVEL1   1           /* protection on a statement level */
#define TS_LEVEL2   2           /* protection on a connection level */
#define TS_LEVEL3   3           /* protection on a environment level */
#endif

typedef struct connection_pair
{
    char            *name;
    char            *value;
    struct connection_pair *next;
} *connection_attribute;

/*
 * handle allocation functions
 */

DMHENV __alloc_env( void );
int __validate_env( DMHENV );
void __release_env( DMHENV environment );

DMHDBC __alloc_dbc( void );
int __validate_dbc( DMHDBC );
void __release_dbc( DMHDBC connection );

DMHSTMT __alloc_stmt( void );
int __validate_stmt( DMHSTMT );
void __release_stmt( DMHSTMT );

DMHDESC __alloc_desc( void );
int __validate_desc( DMHDESC );
void __release_desc( DMHDESC );

/*
 * generic functions
 */

SQLRETURN __SQLAllocHandle( SQLSMALLINT handle_type,
           SQLHANDLE input_handle,
           SQLHANDLE *output_handle,
           SQLINTEGER requested_version );

SQLRETURN __SQLFreeHandle( SQLSMALLINT handle_type,
           SQLHANDLE handle );

int __connect_part_one( DMHDBC connection, char *driver_lib, char *driver_name );
void __disconnect_part_one( DMHDBC connection );
int __connect_part_two( DMHDBC connection );
void __disconnect_part_two( DMHDBC connection );
DMHDBC __get_dbc_root( void );

void  __check_for_function( DMHDBC connection,
        SQLUSMALLINT function_id,
        SQLUSMALLINT *supported );

/*
 * mapping from ODBC 2 <-> 3 datetime types
 */

#define MAP_SQL_DM2D 	0
#define MAP_SQL_D2DM 	1
#define MAP_C_DM2D 	2
#define MAP_C_D2DM 	3

SQLSMALLINT __map_type( int map, DMHDBC connection, SQLSMALLINT type);

/*
 * error functions
 */

typedef enum error_id
{
    ERROR_01000,
    ERROR_01004,
    ERROR_01S02,
    ERROR_01S06,
    ERROR_07005,
    ERROR_07009,
    ERROR_08002,
    ERROR_08003,
    ERROR_24000,
    ERROR_25000,
    ERROR_25S01,
    ERROR_S1000,
    ERROR_S1010,
    ERROR_S1011,
    ERROR_S1107,
    ERROR_S1108,
    ERROR_S1C00,
    ERROR_HY001,
    ERROR_HY004,
    ERROR_HY009,
    ERROR_HY010,
    ERROR_HY011,
    ERROR_HY013,
    ERROR_HY017,
    ERROR_HY024,
    ERROR_HY090,
    ERROR_HY092,
    ERROR_HY097,
    ERROR_HY098,
    ERROR_HY099,
    ERROR_HY100,
    ERROR_HY101,
    ERROR_HY103,
    ERROR_HY105,
    ERROR_HY106,
    ERROR_HY110,
    ERROR_HYC00,
    ERROR_IM001,
    ERROR_IM002,
    ERROR_IM003,
    ERROR_IM004,
    ERROR_IM005,
    ERROR_IM010,
    ERROR_IM012,
    ERROR_SL004,
    ERROR_SL009,
    ERROR_SL010
} error_id;

void __post_internal_error( EHEAD *error_handle,
        error_id, char *txt, int connection_mode );
void __post_internal_error_ex( EHEAD *error_handle,
        SQLCHAR *sqlstate,
        SQLINTEGER native_error,
        SQLCHAR *message_text );
int function_return( void * handle, int ret_code );
void function_entry( void *handle );
void setup_error_head( EHEAD *error_header, void *handle, int handle_type );
void clear_error_head( EHEAD *error_header );
char * __get_return_status( SQLRETURN ret );
char * __sql_as_text( SQLINTEGER type );
char * __c_as_text( SQLINTEGER type );
char * __string_with_length( SQLCHAR *out, SQLCHAR *str, SQLINTEGER len );
char * __get_pid( SQLCHAR *str );
char * __ptr_as_string( SQLCHAR *s, SQLINTEGER *ptr );
char * __sptr_as_string( SQLCHAR *s, SQLSMALLINT *ptr );
char * __info_as_string( SQLCHAR *s, SQLINTEGER typ );
void __clear_internal_error( struct error *error_handle );
char * __data_as_string( SQLCHAR *s, SQLINTEGER type, 
        SQLINTEGER *ptr, SQLPOINTER buf );
char * __sdata_as_string( SQLCHAR *s, SQLINTEGER type, 
        SQLSMALLINT *ptr, SQLPOINTER buf );
char * __col_attr_as_string( SQLCHAR *s, SQLINTEGER type );
char * __fid_as_string( SQLCHAR *s, SQLINTEGER fid );
char * __con_attr_as_string( SQLCHAR *s, SQLINTEGER type );
char * __env_attr_as_string( SQLCHAR *s, SQLINTEGER type );
char * __stmt_attr_as_string( SQLCHAR *s, SQLINTEGER type );
char * __desc_attr_as_string( SQLCHAR *s, SQLINTEGER type );
char * __diag_attr_as_string( SQLCHAR *s, SQLINTEGER type );
char * __type_as_string( SQLCHAR *s, SQLSMALLINT type );
DMHDBC __get_connection( EHEAD * head );
SQLHANDLE __get_driver_handle( EHEAD * head );

/*
 * thread protection funcs
 */

#ifdef HAVE_LIBPTHREAD

void thread_protect( int type, void *handle );
void thread_release( int type, void *handle );

#else

#define thread_protect(a,b)
#define thread_release(a,b)

#endif

void dbc_change_thread_support( DMHDBC connection, int level );

/*
 * lookup functions
 */

char *__find_lib_name( char *dsn, char *lib_name, char *driver_name );

/*
 * setup the cursor library
 */

SQLRETURN CLConnect( DMHDBC connection );

/*
 * connection string functions
 */

struct con_pair
{
    char            *keyword;
    char            *attribute;
    char            *identifier;
    struct con_pair *next;
};

struct con_struct
{
    int             count;
    struct con_pair *list;
};

int __parse_connection_string( struct con_struct *con_str,
    char *str, int str_len );
char * __get_attribute_value( struct con_struct * con_str, char * keyword );
void __release_conn( struct con_struct *con_str );

/*
 * driver manager logging functions
 */

int dm_log_open( DMLHANDLE *log_handle, char *program_name,
        char *log_file );

void dm_log_write( DMLHANDLE log_handle, char *pid,
        char *function_name, int line, int type, int severity, char *message );

void dm_log_close( DMLHANDLE log_handle );

/*
 * Macros to check and call functions in the driver
 */

#define DM_SQLALLOCCONNECT          0
#define CHECK_SQLALLOCCONNECT(con)  (con->functions[0].func!=NULL)
#define SQLALLOCCONNECT(con,env,oh)\
                                    (con->functions[0].func)(env,oh)

#define DM_SQLALLOCENV              1
#define CHECK_SQLALLOCENV(con)      (con->functions[1].func!=NULL)
#define SQLALLOCENV(con,oh)\
                                    (con->functions[1].func)(oh)

#define DM_SQLALLOCHANDLE           2
#define CHECK_SQLALLOCHANDLE(con)   (con->functions[2].func!=NULL)
    /*
     * if the function is in the cursor lib, pass a additional
     * arg that allows the cursor lib to get the dm handle
     */
#define SQLALLOCHANDLE(con,ht,ih,oh,dmh)\
            (con->cl_handle?\
                    (con->functions[2].func)(ht,ih,oh,dmh):\
                    (con->functions[2].func)(ht,ih,oh))

#define DM_SQLALLOCSTMT             3
#define CHECK_SQLALLOCSTMT(con)     (con->functions[3].func!=NULL)
#define SQLALLOCSTMT(con,dbc,oh,dmh)\
            (con->cl_handle?\
                    (con->functions[3].func)(dbc,oh,dmh):\
                    (con->functions[3].func)(dbc,oh))

#define DM_SQLALLOCHANDLESTD        4

#define DM_SQLBINDCOL               5
#define CHECK_SQLBINDCOL(con)       (con->functions[5].func!=NULL)
#define SQLBINDCOL(con,stmt,cn,tt,tvp,bl,sli)\
                                    (con->functions[5].func)\
                                        (stmt,cn,tt,tvp,bl,sli)

#define DM_SQLBINDPARAM             6
#define CHECK_SQLBINDPARAM(con)     (con->functions[6].func!=NULL)
#define SQLBINDPARAM(con,stmt,pn,vt,pt,cs,dd,pvp,ind)\
                                    (con->functions[6].func)\
                                        (stmt,pn,vt,pt,cs,dd,pvp,ind)

#define DM_SQLBINDPARAMETER         7
#define CHECK_SQLBINDPARAMETER(con) (con->functions[7].func!=NULL)
#define SQLBINDPARAMETER(con,stmt,pn,typ,vt,pt,cs,dd,pvp,bl,ind)\
                                    (con->functions[7].func)\
                                        (stmt,pn,typ,vt,pt,cs,dd,pvp,bl,ind)

#define DM_SQLBROWSECONNECT         8
#define CHECK_SQLBROWSECONNECT(con) (con->functions[8].func!=NULL)
#define SQLBROWSECONNECT(con,dbc,ics,sl1,ocs,bl,sl2)\
                                    (con->functions[8].func)\
                                    (dbc,ics,sl1,ocs,bl,sl2)
    
#define DM_SQLBULKOPERATIONS        9
#define CHECK_SQLBULKOPERATIONS(con)    (con->functions[9].func!=NULL)
#define SQLBULKOPERATIONS(con,stmt,op)\
                                    (con->functions[9].func)(stmt,op)

#define DM_SQLCANCEL                10
#define CHECK_SQLCANCEL(con)        (con->functions[10].func!=NULL)
#define SQLCANCEL(con,stmt)\
                                    (con->functions[10].func)(stmt)

#define DM_SQLCLOSECURSOR           11
#define CHECK_SQLCLOSECURSOR(con)   (con->functions[11].func!=NULL)
#define SQLCLOSECURSOR(con,stmt)\
                                    (con->functions[11].func)(stmt)

#define DM_SQLCOLATTRIBUTE          12
#define CHECK_SQLCOLATTRIBUTE(con)  (con->functions[12].func!=NULL)
#define SQLCOLATTRIBUTE(con,stmt,cn,fi,cap,bl,slp,nap)\
                                    (con->functions[12].func)\
                                        (stmt,cn,fi,cap,bl,slp,nap)

#define DM_SQLCOLATTRIBUTES         13
#define CHECK_SQLCOLATTRIBUTES(con) (con->functions[13].func!=NULL)
#define SQLCOLATTRIBUTES(con,stmt,cn,fi,cap,bl,slp,nap)\
                                    (con->functions[13].func)\
                                        (stmt,cn,fi,cap,bl,slp,nap)

#define DM_SQLCOLUMNPRIVILEGES      14 
#define CHECK_SQLCOLUMNPRIVILEGES(con)  (con->functions[14].func!=NULL)
#define SQLCOLUMNPRIVILEGES(con,stmt,cn,nl1,sn,nl2,tn,nl3,col,nl4)\
                                    (con->functions[14].func)\
                                        (stmt,cn,nl1,sn,nl2,tn,nl3,col,nl4)

#define DM_SQLCOLUMNS               15
#define CHECK_SQLCOLUMNS(con)       (con->functions[15].func!=NULL)
#define SQLCOLUMNS(con,stmt,cn,nl1,sn,nl2,tn,nl3,col,nl4)\
                                    (con->functions[15].func)\
                                        (stmt,cn,nl1,sn,nl2,tn,nl3,col,nl4)

#define DM_SQLCONNECT               16
#define CHECK_SQLCONNECT(con)       (con->functions[16].func!=NULL)
#define SQLCONNECT(con,dbc,dsn,l1,uid,l2,at,l3)\
                                    (con->functions[16].func)\
                                    (dbc,dsn,l1,uid,l2,at,l3)

#define DM_SQLCOPYDESC              17
#define CHECK_SQLCOPYDESC(con)      (con->functions[17].func!=NULL)
#define SQLCOPYDESC(con,sd,td)\
                                    (con->functions[17].func)(sd,td)

#define DM_SQLDATASOURCES           18

#define DM_SQLDESCRIBECOL           19
#define CHECK_SQLDESCRIBECOL(con)   (con->functions[19].func!=NULL)
#define SQLDESCRIBECOL(con,stmt,cnum,cn,bli,nl,dt,cs,dd,n)\
                                    (con->functions[19].func)\
                                        (stmt,cnum,cn,bli,nl,dt,cs,dd,n)

#define DM_SQLDESCRIBEPARAM         20
#define CHECK_SQLDESCRIBEPARAM(con) (con->functions[20].func!=NULL)
#define SQLDESCRIBEPARAM(con,stmt,pn,dtp,psp,ddp,np)\
                                    (con->functions[20].func)\
                                        (stmt,pn,dtp,psp,ddp,np)

#define DM_SQLDISCONNECT            21
#define CHECK_SQLDISCONNECT(con)    (con->functions[21].func!=NULL)
#define SQLDISCONNECT(con,dbc)\
                                    (con->functions[21].func)(dbc)

#define DM_SQLDRIVERCONNECT         22
#define CHECK_SQLDRIVERCONNECT(con) (con->functions[22].func!=NULL)
#define SQLDRIVERCONNECT(con,dbc,wh,ics,sl1,ocs,bl,sl2p,dc)\
                                    (con->functions[22].func)\
                                        (dbc,wh,ics,sl1,ocs,bl,sl2p,dc)

#define DM_SQLDRIVERS               23

#define DM_SQLENDTRAN               24
#define CHECK_SQLENDTRAN(con)       (con->functions[24].func!=NULL)
#define SQLENDTRAN(con,ht,h,op)\
                                    (con->functions[24].func)(ht,h,op)

#define DM_SQLERROR                 25
#define CHECK_SQLERROR(con)         (con->functions[25].func!=NULL)
#define SQLERROR(con,env,dbc,stmt,st,nat,msg,mm,pcb)\
                                    (con->functions[25].func)\
                                        (env,dbc,stmt,st,nat,msg,mm,pcb)

#define DM_SQLEXECDIRECT            26
#define CHECK_SQLEXECDIRECT(con)    (con->functions[26].func!=NULL)
#define SQLEXECDIRECT(con,stmt,sql,len)\
                                    (con->functions[26].func)(stmt,sql,len)

#define DM_SQLEXECUTE               27
#define CHECK_SQLEXECUTE(con)       (con->functions[27].func!=NULL)
#define SQLEXECUTE(con,stmt)\
                                    (con->functions[27].func)(stmt)

#define DM_SQLEXTENDEDFETCH         28
#define CHECK_SQLEXTENDEDFETCH(con) (con->functions[28].func!=NULL)
#define SQLEXTENDEDFETCH(con,stmt,fo,of,rcp,ssa)\
                                    (con->functions[28].func)\
                                        (stmt,fo,of,rcp,ssa)

#define DM_FETCH                    29
#define CHECK_SQLFETCH(con)         (con->functions[29].func!=NULL)
#define SQLFETCH(con,stmt)\
                                    (con->functions[29].func)(stmt)

#define DM_SQLFETCHSCROLL           30
#define CHECK_SQLFETCHSCROLL(con)   (con->functions[30].func!=NULL)
#define SQLFETCHSCROLL(con,stmt,or,of)\
                                    (con->functions[30].func)\
                                        (stmt,or,of)

#define DM_SQLFOREIGNKEYS           31
#define CHECK_SQLFOREIGNKEYS(con)   (con->functions[31].func!=NULL)
#define SQLFOREIGNKEYS(con,stmt,cn,nl1,sn,nl2,tn,nl3,fcn,nl4,fsn,nl5,ftn,nl6)\
                                    (con->functions[31].func)\
                                        (stmt,cn,nl1,sn,nl2,tn,nl3,fcn,nl4,fsn,nl5,ftn,nl6)

#define DM_SQLFREEENV               32
#define CHECK_SQLFREEENV(con)       (con->functions[32].func!=NULL)
#define SQLFREEENV(con,env)\
                                    (con->functions[32].func)(env)

#define DM_SQLFREEHANDLE            33
#define CHECK_SQLFREEHANDLE(con)    (con->functions[33].func!=NULL)
#define SQLFREEHANDLE(con,typ,env)\
                                    (con->functions[33].func)(typ,env)

#define DM_SQLFREESTMT              34
#define CHECK_SQLFREESTMT(con)      (con->functions[34].func!=NULL)
#define SQLFREESTMT(con,stmt,opt)\
                                    (con->functions[34].func)(stmt,opt)

#define DM_SQLFREECONNECT           35
#define CHECK_SQLFREECONNECT(con)   (con->functions[35].func!=NULL)
#define SQLFREECONNECT(con,dbc)\
                                    (con->functions[35].func)(dbc)

#define DM_SQLGETCONNECTATTR        36
#define CHECK_SQLGETCONNECTATTR(con)    (con->functions[36].func!=NULL)
#define SQLGETCONNECTATTR(con,dbc,at,vp,bl,slp)\
                                    (con->functions[36].func)\
                                        (dbc,at,vp,bl,slp)

#define DM_SQLGETCONNECTOPTION      37
#define CHECK_SQLGETCONNECTOPTION(con)  (con->functions[37].func!=NULL)
#define SQLGETCONNECTOPTION(con,dbc,at,val)\
                                    (con->functions[37].func)\
                                        (dbc,at,val)

#define DM_SQLGETCURSORNAME         38
#define CHECK_SQLGETCURSORNAME(con) (con->functions[38].func!=NULL)
#define SQLGETCURSORNAME(con,stmt,cn,bl,nlp)\
                                    (con->functions[38].func)\
                                        (stmt,cn,bl,nlp)

#define DM_SQLGETDATA               39
#define CHECK_SQLGETDATA(con)       (con->functions[39].func!=NULL)
#define SQLGETDATA(con,stmt,cn,tt,tvp,bl,sli)\
                                    (con->functions[39].func)\
                                        (stmt,cn,tt,tvp,bl,sli)

#define DM_SQLGETDESCFIELD          40
#define CHECK_SQLGETDESCFIELD(con)  (con->functions[40].func!=NULL)
#define SQLGETDESCFIELD(con,des,rn,fi,vp,bl,slp)\
                                    (con->functions[40].func)\
                                        (des,rn,fi,vp,bl,slp)

#define DM_SQLGETDESCREC            41
#define CHECK_SQLGETDESCREC(con)    (con->functions[41].func!=NULL)
#define SQLGETDESCREC(con,des,rn,n,bl,slp,tp,stp,lp,pp,sp,np)\
                                    (con->functions[41].func)\
                                        (des,rn,n,bl,slp,tp,stp,lp,pp,sp,np)

#define DM_SQLGETDIAGFIELD          42
#define CHECK_SQLGETDIAGFIELD(con)  (con->functions[42].func!=NULL)
#define SQLGETDIAGFIELD(con,typ,han,rn,di,dip,bl,slp)\
                                    (con->functions[42].func)\
                                        (typ,han,rn,di,dip,bl,slp)

#define DM_SQLGETENVATTR            43
#define CHECK_SQLGETENVATTR(con)    (con->functions[43].func!=NULL)
#define SQLGETENVATTR(con,env,attr,val,len,ol)\
                                    (con->functions[43].func)\
                                    (env,attr,val,len,ol)

#define DM_SQLGETFUNCTIONS          44
#define CHECK_SQLGETFUNCTIONS(con)  (con->functions[44].func!=NULL)
#define SQLGETFUNCTIONS(con,dbc,id,ptr)\
                                    (con->functions[44].func)\
                                        (dbc,id,ptr)

#define DM_SQLGETINFO               45
#define CHECK_SQLGETINFO(con)       (con->functions[45].func!=NULL)
#define SQLGETINFO(con,dbc,it,ivo,bl,slp)\
                                    (con->functions[45].func)\
                                        (dbc,it,ivo,bl,slp)

#define DM_SQLGETSTMTATTR           46
#define CHECK_SQLGETSTMTATTR(con)   (con->functions[46].func!=NULL)
#define SQLGETSTMTATTR(con,stmt,at,vp,bl,slp)\
                                    (con->functions[46].func)\
                                        (stmt,at,vp,bl,slp)

#define DM_SQLGETSTMTOPTION         47
#define CHECK_SQLGETSTMTOPTION(con) (con->functions[47].func!=NULL)
#define SQLGETSTMTOPTION(con,stmt,op,val)\
                                    (con->functions[47].func)\
                                        (stmt,op,val)

#define DM_SQLGETTYPEINFO           48
#define CHECK_SQLGETTYPEINFO(con)   (con->functions[48].func!=NULL)
#define SQLGETTYPEINFO(con,stmt,typ)\
                                    (con->functions[48].func)(stmt,typ)

#define DM_SQLMORERESULTS           49
#define CHECK_SQLMORERESULTS(con)   (con->functions[49].func!=NULL)
#define SQLMORERESULTS(con,stmt)\
                                    (con->functions[49].func)(stmt)

#define DM_SQLNATIVESQL             50
#define CHECK_SQLNATIVESQL(con)     (con->functions[50].func!=NULL)
#define SQLNATIVESQL(con,dbc,ist,tl,ost,bl,tlp)\
                                    (con->functions[50].func)\
                                        (dbc,ist,tl,ost,bl,tlp)

#define DM_SQLNUMPARAMS             51
#define CHECK_SQLNUMPARAMS(con)     (con->functions[51].func!=NULL)
#define SQLNUMPARAMS(con,stmt,cnt)\
                                    (con->functions[51].func)(stmt,cnt)

#define DM_SQLNUMRESULTCOLS         52
#define CHECK_SQLNUMRESULTCOLS(con) (con->functions[52].func!=NULL)
#define SQLNUMRESULTCOLS(con,stmt,cnt)\
                                    (con->functions[52].func)(stmt,cnt)

#define DM_SQLPARAMDATA             53
#define CHECK_SQLPARAMDATA(con)     (con->functions[53].func!=NULL)
#define SQLPARAMDATA(con,stmt,val)\
                                    (con->functions[53].func)(stmt,val)

#define DM_SQLPARAMOPTIONS          54
#define CHECK_SQLPARAMOPTIONS(con)  (con->functions[54].func!=NULL)
#define SQLPARAMOPTIONS(con,stmt,cr,pi)\
                                    (con->functions[54].func)(stmt,cr,pi)

#define DM_SQLPREPARE               55
#define CHECK_SQLPREPARE(con)       (con->functions[55].func!=NULL)
#define SQLPREPARE(con,stmt,sql,len)\
                                    (con->functions[55].func)(stmt,sql,len)

#define DM_SQLPRIMARYKEYS           56
#define CHECK_SQLPRIMARYKEYS(con)   (con->functions[56].func!=NULL)
#define SQLPRIMARYKEYS(con,stmt,cn,nl1,sn,nl2,tn,nl3)\
                                    (con->functions[56].func)\
                                        (stmt,cn,nl1,sn,nl2,tn,nl3)

#define DM_SQLPROCEDURECOLUMNS      57
#define CHECK_SQLPROCEDURECOLUMNS(con)  (con->functions[57].func!=NULL)
#define SQLPROCEDURECOLUMNS(con,stmt,cn,nl1,sn,nl2,tn,nl3,col,nl4)\
                                    (con->functions[57].func)\
                                        (stmt,cn,nl1,sn,nl2,tn,nl3,col,nl4)

#define DM_SQLPROCEDURES            58
#define CHECK_SQLPROCEDURES(con)    (con->functions[58].func!=NULL)
#define SQLPROCEDURES(con,stmt,cn,nl1,sn,nl2,tn,nl3)\
                                    (con->functions[58].func)\
                                        (stmt,cn,nl1,sn,nl2,tn,nl3)

#define DM_SQLPUTDATA               59
#define CHECK_SQLPUTDATA(con)       (con->functions[59].func!=NULL)
#define SQLPUTDATA(con,stmt,d,p)\
                                    (con->functions[59].func)(stmt,d,p)

#define DM_SQLROWCOUNT              60
#define CHECK_SQLROWCOUNT(con)      (con->functions[60].func!=NULL)
#define SQLROWCOUNT(con,stmt,cnt)\
                                    (con->functions[60].func)(stmt,cnt)

#define DM_SQLSETCONNECTATTR        61
#define CHECK_SQLSETCONNECTATTR(con)    (con->functions[61].func!=NULL)
#define SQLSETCONNECTATTR(con,dbc,at,vp,sl)\
                                    (con->functions[61].func)\
                                        (dbc,at,vp,sl)

#define DM_SQLSETCONNECTOPTION      62
#define CHECK_SQLSETCONNECTOPTION(con)  (con->functions[62].func!=NULL)
#define SQLSETCONNECTOPTION(con,dbc,op,p)\
                                    (con->functions[62].func)\
                                        (dbc,op,p)

#define DM_SQLSETCURSORNAME         63
#define CHECK_SQLSETCURSORNAME(con) (con->functions[63].func!=NULL)
#define SQLSETCURSORNAME(con,stmt,nam,len)\
                                    (con->functions[63].func)(stmt,nam,len)

#define DM_SQLSETDESCFIELD          64
#define CHECK_SQLSETDESCFIELD(con)  (con->functions[64].func!=NULL)
#define SQLSETDESCFIELD(con,des,rn,fi,vp,bl)\
                                    (con->functions[64].func)\
                                    (des,rn,fi,vp,bl)

#define DM_SQLSETDESCREC            65
#define CHECK_SQLSETDESCREC(con)    (con->functions[65].func!=NULL)
#define SQLSETDESCREC(con,des,rn,t,st,l,p,sc,dp,slp,ip)\
                                    (con->functions[65].func)\
                                        (des,rn,t,st,l,p,sc,dp,slp,ip)

#define DM_SQLSETENVATTR            66
#define CHECK_SQLSETENVATTR(con)    (con->functions[66].func!=NULL)
#define SQLSETENVATTR(con,env,attr,val,len)\
                                    (con->functions[66].func)(env,attr,val,len)

#define DM_SQLSETPARAM              67
#define CHECK_SQLSETPARAM(con)      (con->functions[67].func!=NULL)
#define SQLSETPARAM(con,stmt,pn,vt,pt,lp,ps,pv,sli)\
                                    (con->functions[67].func)\
                                        (stmt,pn,vt,pt,lp,ps,pv,sli)

#define DM_SQLSETPOS                68
#define CHECK_SQLSETPOS(con)        (con->functions[68].func!=NULL)
#define SQLSETPOS(con,stmt,rn,op,lt)\
                                    (con->functions[68].func)\
                                        (stmt,rn,op,lt)

#define DM_SQLSETSCROLLOPTIONS      69
#define CHECK_SQLSETSCROLLOPTIONS(con)  (con->functions[69].func!=NULL)
#define SQLSETSCROLLOPTIONS(con,stmt,fc,cr,rs)\
                                    (con->functions[69].func)\
                                        (stmt,fc,cr,rs)

#define DM_SQLSETSTMTATTR           70
#define CHECK_SQLSETSTMTATTR(con)   (con->functions[70].func!=NULL)
#define SQLSETSTMTATTR(con,stmt,attr,vp,sl)\
                                    (con->functions[70].func)\
                                        (stmt,attr,vp,sl)

#define DM_SQLSETSTMTOPTION         71
#define CHECK_SQLSETSTMTOPTION(con) (con->functions[71].func!=NULL)
#define SQLSETSTMTOPTION(con,stmt,op,val)\
                                    (con->functions[71].func)\
                                        (stmt,op,val)

#define DM_SQLSPECIALCOLUMNS        72
#define CHECK_SQLSPECIALCOLUMNS(con)    (con->functions[72].func!=NULL)
#define SQLSPECIALCOLUMNS(con,stmt,it,cn,nl1,sn,nl2,tn,nl3,s,n)\
                                    (con->functions[72].func)\
                                        (stmt,it,cn,nl1,sn,nl2,tn,nl3,s,n)

#define DM_SQLSTATISTICS            73
#define CHECK_SQLSTATISTICS(con)    (con->functions[73].func!=NULL)
#define SQLSTATISTICS(con,stmt,cn,nl1,sn,nl2,tn,nl3,un,res)\
                                    (con->functions[73].func)\
                                        (stmt,cn,nl1,sn,nl2,tn,nl3,un,res)

#define DM_SQLTABLEPRIVILEGES       74
#define CHECK_SQLTABLEPRIVILEGES(con)   (con->functions[74].func!=NULL)
#define SQLTABLEPRIVILEGES(con,stmt,cn,nl1,sn,nl2,tn,nl3)\
                                    (con->functions[74].func)\
                                        (stmt,cn,nl1,sn,nl2,tn,nl3)

#define DM_SQLTABLES                75
#define CHECK_SQLTABLES(con)        (con->functions[75].func!=NULL)
#define SQLTABLES(con,stmt,cn,nl1,sn,nl2,tn,nl3,tt,nl4)\
                                    (con->functions[75].func)\
                                        (stmt,cn,nl1,sn,nl2,tn,nl3,tt,nl4)

#define DM_SQLTRANSACT              76
#define CHECK_SQLTRANSACT(con)      (con->functions[76].func!=NULL)
#define SQLTRANSACT(con,eh,ch,op)\
                                    (con->functions[76].func)(eh,ch,op)


#define DM_SQLGETDIAGREC            77
#define CHECK_SQLGETDIAGREC(con)    (con->functions[77].func!=NULL)
#define SQLGETDIAGREC(con,typ,han,rn,st,nat,msg,bl,tlp)\
                                    (con->functions[77].func)\
                                        (typ,han,rn,st,nat,msg,bl,tlp)

#endif
