mirror of https://github.com/postgres/postgres
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
328 lines
11 KiB
328 lines
11 KiB
/* 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 <stdlib.h>
|
|
#include <string.h>
|
|
#include "descriptor.h"
|
|
|
|
|
|
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;
|
|
|
|
/* 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
|
|
|
|
/* 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
|
|
|
|
/* Conn_status defines */
|
|
#define CONN_IN_AUTOCOMMIT 0x01
|
|
#define CONN_IN_TRANSACTION 0x02
|
|
|
|
/* 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)
|
|
#define CC_is_in_trans(x) (x->transact_status & CONN_IN_TRANSACTION)
|
|
|
|
|
|
/* Authentication types */
|
|
#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
|
|
|
|
/* Startup Packet sizes */
|
|
#define SM_DATABASE 64
|
|
#define SM_USER 32
|
|
#define SM_OPTIONS 64
|
|
#define SM_UNUSED 64
|
|
#define SM_TTY 64
|
|
|
|
/* Old 6.2 protocol defines */
|
|
#define NO_AUTHENTICATION 7
|
|
#define PATH_SIZE 64
|
|
#define ARGV_SIZE 64
|
|
#define NAMEDATALEN 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)
|
|
|
|
/* This startup packet is to support latest Postgres protocol (6.4, 6.3) */
|
|
typedef struct _StartupPacket
|
|
{
|
|
ProtocolVersion protoVersion;
|
|
char database[SM_DATABASE];
|
|
char user[SM_USER];
|
|
char options[SM_OPTIONS];
|
|
char unused[SM_UNUSED];
|
|
char tty[SM_TTY];
|
|
} StartupPacket;
|
|
|
|
|
|
/* This startup packet is to support pre-Postgres 6.3 protocol */
|
|
typedef struct _StartupPacket6_2
|
|
{
|
|
unsigned int authtype;
|
|
char database[PATH_SIZE];
|
|
char user[NAMEDATALEN];
|
|
char options[ARGV_SIZE];
|
|
char execfile[ARGV_SIZE];
|
|
char tty[PATH_SIZE];
|
|
} StartupPacket6_2;
|
|
|
|
|
|
/* 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 driver[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 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;
|
|
char disallow_premature;
|
|
char updatable_cursors;
|
|
char lf_conversion;
|
|
char true_is_minus1;
|
|
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 name[MAX_TABLE_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 *errormsg;
|
|
int errornumber;
|
|
CONN_Status status;
|
|
ConnInfo connInfo;
|
|
StatementClass **stmts;
|
|
int num_stmts;
|
|
SocketClass *sock;
|
|
int lobj_type;
|
|
int ntables;
|
|
COL_INFO **col_info;
|
|
long 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;
|
|
#ifdef MULTIBYTE
|
|
char *client_encoding;
|
|
char *server_encoding;
|
|
#endif /* MULTIBYTE */
|
|
int ccsc;
|
|
};
|
|
|
|
|
|
/* Accessor functions */
|
|
#define CC_get_socket(x) (x->sock)
|
|
#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 do_password);
|
|
char CC_add_statement(ConnectionClass *self, StatementClass *stmt);
|
|
char CC_remove_statement(ConnectionClass *self, StatementClass *stmt);
|
|
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);
|
|
void CC_on_commit(ConnectionClass *conn, BOOL set_no_trans);
|
|
void CC_on_abort(ConnectionClass *conn, BOOL set_no_trans);
|
|
|
|
/* 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 */
|
|
#endif
|
|
|