Logo Search packages:      
Sourcecode: psqlodbc version File versions  Download package

connection.h

/* File:                connection.h
 *
 * Description:         See "CONNECTION.c"
 *
 * Comments:            See "notice.txt" for copyright and license information.
 *
 */

#ifndef __CONNECTION_H__
#define __CONNECTION_H__

#include "psqlodbc.h"
#include <libpq-fe.h>
#include <stdlib.h>
#include <string.h>
#include "descriptor.h"

#if defined (POSIX_MULTITHREAD_SUPPORT)
#include <pthread.h>
#endif

#if !defined WIN32 && defined HAVE_SYS_UN_H && !defined HAVE_UNIX_SOCKETS
#define HAVE_UNIX_SOCKETS
#endif

/*    These errors have general sql error state */
#define CONNECTION_SERVER_NOT_REACHED                 101
#define CONNECTION_MSG_TOO_LONG                             103
#define CONNECTION_COULD_NOT_SEND                     104
#define CONNECTION_NO_SUCH_DATABASE                   105
#define CONNECTION_BACKEND_CRAZY                      106
#define CONNECTION_NO_RESPONSE                              107
#define CONNECTION_SERVER_REPORTED_ERROR        108
#define CONNECTION_COULD_NOT_RECEIVE                  109
#define CONNECTION_SERVER_REPORTED_WARNING            110
#define CONNECTION_NEED_PASSWORD                      112
#define CONNECTION_COULD_NOT_ESTABLISH                113

/*    These errors correspond to specific SQL states */
#define CONN_INIREAD_ERROR                                  201
#define CONN_OPENDB_ERROR                                   202
#define CONN_STMT_ALLOC_ERROR                         203
#define CONN_IN_USE                                               204
#define CONN_UNSUPPORTED_OPTION                             205
/* Used by SetConnectoption to indicate unsupported options */
#define CONN_INVALID_ARGUMENT_NO                      206
/* SetConnectOption: corresponds to ODBC--"S1009" */
#define CONN_TRANSACT_IN_PROGRES                      207
#define CONN_NO_MEMORY_ERROR                          208
#define CONN_NOT_IMPLEMENTED_ERROR                    209
#define CONN_INVALID_AUTHENTICATION                   210
#define CONN_AUTH_TYPE_UNSUPPORTED                    211
#define CONN_UNABLE_TO_LOAD_DLL                             212

#define CONN_OPTION_VALUE_CHANGED                     213
#define CONN_VALUE_OUT_OF_RANGE                             214

#define CONN_TRUNCATED                                      215


#define CONN_MEMORY_ALLOCATION_FAILED                 301
#define COULD_NOT_GET_RESULT_BACK                     302

/* Conn_status defines */
#define CONN_IN_AUTOCOMMIT          1L
#define CONN_IN_TRANSACTION         (1L<<1)
#define CONN_IN_MANUAL_TRANSACTION  (1L<<2)
#define CONN_IN_ERROR_BEFORE_IDLE   (1L<<3)

/* AutoCommit functions */
#define CC_set_autocommit_off(x)    (x->transact_status &= ~CONN_IN_AUTOCOMMIT)
#define CC_set_autocommit_on(x)           (x->transact_status |= CONN_IN_AUTOCOMMIT)
#define CC_is_in_autocommit(x)            (x->transact_status & CONN_IN_AUTOCOMMIT)

/* Transaction in/not functions */
#define CC_set_in_trans(x)    (x->transact_status |= CONN_IN_TRANSACTION)
#define CC_set_no_trans(x)    (x->transact_status &= ~(CONN_IN_TRANSACTION | CONN_IN_ERROR_BEFORE_IDLE))
#define CC_is_in_trans(x)     (x->transact_status & CONN_IN_TRANSACTION)

/* Manual transaction in/not functions */
#define CC_set_in_manual_trans(x) (x->transact_status |= CONN_IN_MANUAL_TRANSACTION)
#define CC_set_no_manual_trans(x) (x->transact_status &= ~CONN_IN_MANUAL_TRANSACTION)
#define CC_is_in_manual_trans(x) (x->transact_status & CONN_IN_MANUAL_TRANSACTION)

/* Error waiting for ROLLBACK */
#define CC_set_in_error_trans(x) (x->transact_status |= CONN_IN_ERROR_BEFORE_IDLE)
#define CC_set_no_error_trans(x) (x->transact_status &= ~CONN_IN_ERROR_BEFORE_IDLE)
#define CC_is_in_error_trans(x) (x->transact_status & CONN_IN_ERROR_BEFORE_IDLE)

#define CC_get_errornumber(x) (x->__error_number)
#define CC_get_errormsg(x)    (x->__error_message)
#define CC_set_errornumber(x, n)    (x->__error_number = n)

#define CC_MALLOC_return_with_error(t, tp, s, x, m, ret) \
      { \
            if (t = malloc(s), NULL == t) \
            { \
                  CC_set_error(x, CONN_NO_MEMORY_ERROR, m); \
                  return ret; \
            } \
      }
#define CC_REALLOC_return_with_error(t, tp, s, x, m, ret) \
      { \
            if (t = (tp *) realloc(t, s), NULL == t) \
            { \
                  CC_set_error(x, CONN_NO_MEMORY_ERROR, m); \
                  return ret; \
            } \
      }

/* For Multi-thread */
#if defined(WIN_MULTITHREAD_SUPPORT)
#define INIT_CONN_CS(x)       InitializeCriticalSection(&((x)->cs))
#define ENTER_CONN_CS(x)      EnterCriticalSection(&((x)->cs))
#define ENTER_INNER_CONN_CS(x, entered) \
      { EnterCriticalSection(&((x)->cs)); entered++; }
#define LEAVE_CONN_CS(x)      LeaveCriticalSection(&((x)->cs))
#define DELETE_CONN_CS(x)     DeleteCriticalSection(&((x)->cs))
#elif defined(POSIX_THREADMUTEX_SUPPORT)
#define INIT_CONN_CS(x)       pthread_mutex_init(&((x)->cs), getMutexAttr())
#define ENTER_CONN_CS(x)      pthread_mutex_lock(&((x)->cs))
#define ENTER_INNER_CONN_CS(x, entered) \
      { \
            if (getMutexAttr()) \
            { \
                  if (pthread_mutex_lock(&((x)->cs)) == 0) \
                        entered++; \
                  else \
                        -1; \
            } \
            else \
                  0; \
      }
#define LEAVE_CONN_CS(x)      pthread_mutex_unlock(&((x)->cs))
#define DELETE_CONN_CS(x)     pthread_mutex_destroy(&((x)->cs))
#else
#define INIT_CONN_CS(x)
#define ENTER_CONN_CS(x)
#define ENTER_INNER_CONN_CS(x, entered) ((void)(0))
#define LEAVE_CONN_CS(x)
#define DELETE_CONN_CS(x)
#endif /* WIN_MULTITHREAD_SUPPORT */

#define     LEAVE_INNER_CONN_CS(entered, conn) \
      { \
            if (entered > 0) \
            { \
                  LEAVE_CONN_CS(conn); \
                  entered--; \
            } \
      }
#define     CLEANUP_FUNC_CONN_CS(entered, conn) \
      while (entered > 0) \
      { \
            LEAVE_CONN_CS(conn); \
            entered--; \
      }


#define AUTH_REQ_OK                                               0
#define AUTH_REQ_KRB4                                       1
#define AUTH_REQ_KRB5                                       2
#define AUTH_REQ_PASSWORD                                   3
#define AUTH_REQ_CRYPT                                      4
#define AUTH_REQ_MD5                                        5
#define AUTH_REQ_SCM_CREDS                                  6

/*    Old 6.2 protocol defines */
#define NO_AUTHENTICATION                                   7
#define PATH_SIZE                                           64
#define ARGV_SIZE                                           64
#define USRNAMEDATALEN                                      16

typedef unsigned int ProtocolVersion;

#define PG_PROTOCOL(major, minor)   (((major) << 16) | (minor))
#define PG_PROTOCOL_LATEST                                        PG_PROTOCOL(2, 0)
#define PG_PROTOCOL_63                                            PG_PROTOCOL(1, 0)
#define PG_PROTOCOL_62                                            PG_PROTOCOL(0, 0)


typedef enum
{
      CONN_NOT_CONNECTED,                 /* Connection has not been established */
      CONN_CONNECTED,                     /* Connection is up and has been
                                                 * established */
      CONN_DOWN,                          /* Connection is broken */
      CONN_EXECUTING                      /* the connection is currently executing a
                                                 * statement */
} CONN_Status;

/* Transferred from pqcomm.h:  */


typedef ProtocolVersion MsgType;

/*    Structure to hold all the connection attributes for a specific
      connection (used for both registry and file, DSN and DRIVER) */

typedef struct
{
      char        dsn[MEDIUM_REGISTRY_LEN];
      char        desc[MEDIUM_REGISTRY_LEN];
      char        drivername[MEDIUM_REGISTRY_LEN];
      char        server[MEDIUM_REGISTRY_LEN];
      char        database[MEDIUM_REGISTRY_LEN];
      char        username[MEDIUM_REGISTRY_LEN];
      char        password[MEDIUM_REGISTRY_LEN];
      char        conn_settings[LARGE_REGISTRY_LEN];
      char        protocol[SMALL_REGISTRY_LEN];
      char        port[SMALL_REGISTRY_LEN];
      char        sslmode[MEDIUM_REGISTRY_LEN];
      char        onlyread[SMALL_REGISTRY_LEN];
      char        fake_oid_index[SMALL_REGISTRY_LEN];
      char        show_oid_column[SMALL_REGISTRY_LEN];
      char        row_versioning[SMALL_REGISTRY_LEN];
      char        show_system_tables[SMALL_REGISTRY_LEN];
      char        translation_dll[MEDIUM_REGISTRY_LEN];
      char        translation_option[SMALL_REGISTRY_LEN];
      char        focus_password;
      signed char disallow_premature;
      signed char allow_keyset;
      signed char updatable_cursors;
      signed char lf_conversion;
      signed char true_is_minus1;
      signed char int8_as;
      signed char bytea_as_longvarbinary;
      signed char use_server_side_prepare;
      signed char lower_case_identifier;
      GLOBAL_VALUES drivers;        /* moved from driver's option */
} ConnInfo;


/*    Macro to determine is the connection using 6.2 protocol? */
#define PROTOCOL_62(conninfo_)            (strncmp((conninfo_)->protocol, PG62, strlen(PG62)) == 0)

/*    Macro to determine is the connection using 6.3 protocol? */
#define PROTOCOL_63(conninfo_)            (strncmp((conninfo_)->protocol, PG63, strlen(PG63)) == 0)

/*
 *    Macros to compare the server's version with a specified version
 *          1st parameter: pointer to a ConnectionClass object
 *          2nd parameter: major version number
 *          3rd parameter: minor version number
 */
#define SERVER_VERSION_GT(conn, major, minor) \
      ((conn)->pg_version_major > major || \
      ((conn)->pg_version_major == major && (conn)->pg_version_minor > minor))
#define SERVER_VERSION_GE(conn, major, minor) \
      ((conn)->pg_version_major > major || \
      ((conn)->pg_version_major == major && (conn)->pg_version_minor >= minor))
#define SERVER_VERSION_EQ(conn, major, minor) \
      ((conn)->pg_version_major == major && (conn)->pg_version_minor == minor)
#define SERVER_VERSION_LE(conn, major, minor) (! SERVER_VERSION_GT(conn, major, minor))
#define SERVER_VERSION_LT(conn, major, minor) (! SERVER_VERSION_GE(conn, major, minor))
/*#if ! defined(HAVE_CONFIG_H) || defined(HAVE_STRINGIZE)*/
#define STRING_AFTER_DOT(string)    (strchr(#string, '.') + 1)
/*#else
#define STRING_AFTER_DOT(str) (strchr("str", '.') + 1)
#endif*/
/*
 *    Simplified macros to compare the server's version with a
 *          specified version
 *    Note: Never pass a variable as the second parameter.
 *            It must be a decimal constant of the form %d.%d .
 */
#define PG_VERSION_GT(conn, ver) \
 (SERVER_VERSION_GT(conn, (int) ver, atoi(STRING_AFTER_DOT(ver))))
#define PG_VERSION_GE(conn, ver) \
 (SERVER_VERSION_GE(conn, (int) ver, atoi(STRING_AFTER_DOT(ver))))
#define PG_VERSION_EQ(conn, ver) \
 (SERVER_VERSION_EQ(conn, (int) ver, atoi(STRING_AFTER_DOT(ver))))
#define PG_VERSION_LE(conn, ver) (! PG_VERSION_GT(conn, ver))
#define PG_VERSION_LT(conn, ver) (! PG_VERSION_GE(conn, ver))

/*    This is used to store cached table information in the connection */
struct col_info
{
      QResultClass *result;
      char        *schema;
      char        name[TABLE_NAME_STORAGE_LEN + 1];
};

 /* Translation DLL entry points */
#ifdef WIN32
#define DLLHANDLE HINSTANCE
#else
#define WINAPI CALLBACK
#define DLLHANDLE void *
#define HINSTANCE void *
#endif

typedef BOOL (FAR WINAPI * DataSourceToDriverProc) 
      (UDWORD,SWORD,PTR,SDWORD,PTR,SDWORD,SDWORD FAR *,UCHAR FAR *,SWORD,SWORD FAR *);

typedef BOOL (FAR WINAPI * DriverToDataSourceProc) 
      (UDWORD,SWORD,PTR,SDWORD,PTR,SDWORD,SDWORD FAR *,UCHAR FAR *,SWORD,SWORD FAR *);

 /*******   The Connection handle   ************/
struct ConnectionClass_
{
      HENV        henv;             /* environment this connection was created
                                                 * on */
      StatementOptions stmtOptions;
      ARDFields   ardOptions;
      APDFields   apdOptions;
      char     *__error_message;
      int               __error_number;
      char        __sqlstate[SQLSTATE_LENGTH + 1];  /* Set only by LIBPQ_execute_query() */
      CONN_Status status;
      ConnInfo    connInfo;
      StatementClass **stmts;
      int               num_stmts;
      PGconn *pgconn;
      int               lobj_type;
      int               ntables;
      COL_INFO  **col_info;
      UDWORD            translation_option;
      HINSTANCE   translation_handle;
      DataSourceToDriverProc DataSourceToDriver;
      DriverToDataSourceProc DriverToDataSource;
      Int2        driver_version; /* prepared for ODBC3.0 */
      char        transact_status;/* Is a transaction is currently in
                                                 * progress */
      char        errormsg_created;       /* has an informative error msg
                                                             * been created?  */
      char        pg_version[MAX_INFO_STRING];  /* Version of PostgreSQL
                                                                         * we're connected to -
                                                                         * DJP 25-1-2001 */
      float       pg_version_number;
      Int2        pg_version_major;
      Int2        pg_version_minor;
      char        ms_jet;
      char        unicode;
      char        result_uncommitted;
      char        schema_support;
      char        *client_encoding;
      char        *server_encoding;
      int         ccsc;
      int         be_pid;     /* pid returned by backend */
      int         be_key; /* auth code needed to send cancel */
      UInt4       isolation;
      char        *current_schema;
      int         num_discardp;
      char        **discardp;
      int         num_descs;
      DescriptorClass   **descs;
#if defined(WIN_MULTITHREAD_SUPPORT)
      CRITICAL_SECTION  cs;
#elif defined(POSIX_THREADMUTEX_SUPPORT)
      pthread_mutex_t         cs;
#endif /* WIN_MULTITHREAD_SUPPORT */
};


/* Accessor functions */
#define CC_get_database(x)                            (x->connInfo.database)
#define CC_get_server(x)                              (x->connInfo.server)
#define CC_get_DSN(x)                                 (x->connInfo.dsn)
#define CC_get_username(x)                            (x->connInfo.username)
#define CC_is_onlyread(x)                             (x->connInfo.onlyread[0] == '1')

/*    for CC_DSN_info */
#define CONN_DONT_OVERWRITE         0
#define CONN_OVERWRITE              1


/*    prototypes */
ConnectionClass *CC_Constructor(void);
void        CC_conninfo_init(ConnInfo *conninfo);
char        CC_Destructor(ConnectionClass *self);
int               CC_cursor_count(ConnectionClass *self);
char        CC_cleanup(ConnectionClass *self);
char        CC_begin(ConnectionClass *self);
char        CC_commit(ConnectionClass *self);
char        CC_abort(ConnectionClass *self);
int               CC_set_translation(ConnectionClass *self);
char        CC_connect(ConnectionClass *self, char password_req, char *salt);
char        CC_add_statement(ConnectionClass *self, StatementClass *stmt);
char        CC_remove_statement(ConnectionClass *self, StatementClass *stmt);
char        CC_add_descriptor(ConnectionClass *self, DescriptorClass *desc);
char        CC_remove_descriptor(ConnectionClass *self, DescriptorClass *desc);
void        CC_set_error(ConnectionClass *self, int number, const char *message);
void        CC_set_errormsg(ConnectionClass *self, const char *message);
char        CC_get_error(ConnectionClass *self, int *number, char **message);
QResultClass   *CC_send_query(ConnectionClass *self, char *query, QueryInfo *qi, UDWORD flag);
void        CC_clear_error(ConnectionClass *self);
char     *CC_create_errormsg(ConnectionClass *self);
int         CC_send_function(ConnectionClass *conn, int fnid, void *result_buf, int *actual_result_len, int result_is_int, LO_ARG *argv, int nargs);
char        CC_send_settings(ConnectionClass *self);
void        CC_lookup_lo(ConnectionClass *conn);
void        CC_lookup_pg_version(ConnectionClass *conn);
void        CC_initialize_pg_version(ConnectionClass *conn);
void        CC_log_error(const char *func, const char *desc, const ConnectionClass *self);
int         CC_get_max_query_len(const ConnectionClass *self);
int         CC_send_cancel_request(const ConnectionClass *conn);
void        CC_on_commit(ConnectionClass *conn);
void        CC_on_abort(ConnectionClass *conn, UDWORD opt);
void        ProcessRollback(ConnectionClass *conn, BOOL undo);
const char  *CC_get_current_schema(ConnectionClass *conn);
int         CC_mark_a_plan_to_discard(ConnectionClass *conn, const char *plannm);
int         CC_discard_marked_plans(ConnectionClass *conn);
void        CC_set_sqlstate(ConnectionClass *self, const char *sqlstate);
char        *CC_get_sqlstate(ConnectionClass *self);

/* Accessor functions*/
PGconn                  *LIBPQ_Constructor();
void              LIBPQ_Destructor(PGconn *pgconn);
int               LIBPQ_connect(ConnectionClass *self);
QResultClass            *LIBPQ_execute_query(ConnectionClass *self,char *query);
QResultClass            *CC_mapping(ConnectionClass *self,PGresult *pgres,QResultClass *qres);
void        CC_is_server_alive(ConnectionClass *conn);
/* CC_send_query options */
#define     CLEAR_RESULT_ON_ABORT   1L
#define     CREATE_KEYSET           (1L << 1) /* create keyset for updatable curosrs */
#define     GO_INTO_TRANSACTION     (1L << 2) /* issue begin in advance */
/* CC_on_abort options */
#define     NO_TRANS          1L
#define     CONN_DEAD         (1L << 1) /* connection is no longer valid */

#endif /* __CONNECTION_H__ */

Generated by  Doxygen 1.6.0   Back to index