1 2 /* File: connection.h 3 * 4 * Description: See "connection.c" 5 * 6 * Comments: See "notice.txt" for copyright and license information. 7 * 8 */ 9 10 #ifndef __CONNECTION_H__ 11 #define __CONNECTION_H__ 12 13 #ifdef HAVE_CONFIG_H 14 #include "config.h" 15 #endif 16 17 #include "psqlodbc.h" 18 19 #ifndef WIN32 20 #include "isql.h" 21 #include "isqlext.h" 22 #else 23 #include <windows.h> 24 #include <sql.h> 25 #include <sqlext.h> 26 #endif 27 28 29 typedef enum { 30 CONN_NOT_CONNECTED, /* Connection has not been established */ 31 CONN_CONNECTED, /* Connection is up and has been established */ 32 CONN_DOWN, /* Connection is broken */ 33 CONN_EXECUTING /* the connection is currently executing a statement */ 34 } CONN_Status; 35 36 /* These errors have general sql error state */ 37 #define CONNECTION_SERVER_NOT_REACHED 101 38 #define CONNECTION_MSG_TOO_LONG 103 39 #define CONNECTION_COULD_NOT_SEND 104 40 #define CONNECTION_NO_SUCH_DATABASE 105 41 #define CONNECTION_BACKEND_CRAZY 106 42 #define CONNECTION_NO_RESPONSE 107 43 #define CONNECTION_SERVER_REPORTED_ERROR 108 44 #define CONNECTION_COULD_NOT_RECEIVE 109 45 #define CONNECTION_SERVER_REPORTED_WARNING 110 46 #define CONNECTION_NEED_PASSWORD 112 47 48 /* These errors correspond to specific SQL states */ 49 #define CONN_INIREAD_ERROR 201 50 #define CONN_OPENDB_ERROR 202 51 #define CONN_STMT_ALLOC_ERROR 203 52 #define CONN_IN_USE 204 53 #define CONN_UNSUPPORTED_OPTION 205 54 /* Used by SetConnectoption to indicate unsupported options */ 55 #define CONN_INVALID_ARGUMENT_NO 206 56 /* SetConnectOption: corresponds to ODBC--"S1009" */ 57 #define CONN_TRANSACT_IN_PROGRES 207 58 #define CONN_NO_MEMORY_ERROR 208 59 #define CONN_NOT_IMPLEMENTED_ERROR 209 60 #define CONN_INVALID_AUTHENTICATION 210 61 #define CONN_AUTH_TYPE_UNSUPPORTED 211 62 #define CONN_UNABLE_TO_LOAD_DLL 212 63 64 #define CONN_OPTION_VALUE_CHANGED 213 65 #define CONN_VALUE_OUT_OF_RANGE 214 66 67 #define CONN_TRUNCATED 215 68 69 /* Conn_status defines */ 70 #define CONN_IN_AUTOCOMMIT 0x01 71 #define CONN_IN_TRANSACTION 0x02 72 73 /* AutoCommit functions */ 74 #define CC_set_autocommit_off(x) (x->transact_status &= ~CONN_IN_AUTOCOMMIT) 75 #define CC_set_autocommit_on(x) (x->transact_status |= CONN_IN_AUTOCOMMIT) 76 #define CC_is_in_autocommit(x) (x->transact_status & CONN_IN_AUTOCOMMIT) 77 78 /* Transaction in/not functions */ 79 #define CC_set_in_trans(x) (x->transact_status |= CONN_IN_TRANSACTION) 80 #define CC_set_no_trans(x) (x->transact_status &= ~CONN_IN_TRANSACTION) 81 #define CC_is_in_trans(x) (x->transact_status & CONN_IN_TRANSACTION) 82 83 #define CC_get_errornumber(x) (x->__error_number) 84 #define CC_get_errormsg(x) (x->__error_message) 85 #define CC_set_errornumber(x, n) (x->__error_number = n) 86 87 /* Authentication types */ 88 #define AUTH_REQ_OK 0 89 #define AUTH_REQ_KRB4 1 90 #define AUTH_REQ_KRB5 2 91 #define AUTH_REQ_PASSWORD 3 92 #define AUTH_REQ_CRYPT 4 93 #define AUTH_REQ_MD5 5 94 #define AUTH_REQ_SCM_CREDS 6 95 96 /* Startup Packet sizes */ 97 #define SM_DATABASE 64 98 #define SM_USER 32 99 #define SM_OPTIONS 64 100 #define SM_UNUSED 64 101 #define SM_TTY 64 102 103 /* Old 6.2 protocol defines */ 104 #define NO_AUTHENTICATION 7 105 #define PATH_SIZE 64 106 #define ARGV_SIZE 64 107 #define NAMEDATALEN 16 108 109 typedef unsigned int ProtocolVersion; 110 111 #define PG_PROTOCOL(major, minor) (((major) << 16) | (minor)) 112 #define PG_PROTOCOL_LATEST PG_PROTOCOL(2, 0) 113 #define PG_PROTOCOL_63 PG_PROTOCOL(1, 0) 114 #define PG_PROTOCOL_62 PG_PROTOCOL(0, 0) 115 116 /* This startup packet is to support latest Postgres protocol (6.4, 6.3) */ 117 typedef struct _StartupPacket 118 { 119 ProtocolVersion protoVersion; 120 char database[SM_DATABASE]; 121 char user[SM_USER]; 122 char options[SM_OPTIONS]; 123 char unused[SM_UNUSED]; 124 char tty[SM_TTY]; 125 } StartupPacket; 126 127 128 /* This startup packet is to support pre-Postgres 6.3 protocol */ 129 typedef struct _StartupPacket6_2 130 { 131 unsigned int authtype; 132 char database[PATH_SIZE]; 133 char user[NAMEDATALEN]; 134 char options[ARGV_SIZE]; 135 char execfile[ARGV_SIZE]; 136 char tty[PATH_SIZE]; 137 } StartupPacket6_2; 138 139 140 /* Structure to hold all the connection attributes for a specific 141 connection (used for both registry and file, DSN and DRIVER) 142 */ 143 typedef struct { 144 char dsn[MEDIUM_REGISTRY_LEN]; 145 char desc[MEDIUM_REGISTRY_LEN]; 146 char driver[MEDIUM_REGISTRY_LEN]; 147 char server[MEDIUM_REGISTRY_LEN]; 148 char database[MEDIUM_REGISTRY_LEN]; 149 char username[MEDIUM_REGISTRY_LEN]; 150 char password[MEDIUM_REGISTRY_LEN]; 151 char conn_settings[LARGE_REGISTRY_LEN]; 152 char protocol[SMALL_REGISTRY_LEN]; 153 char port[SMALL_REGISTRY_LEN]; 154 char uds[LARGE_REGISTRY_LEN]; 155 char onlyread[SMALL_REGISTRY_LEN]; 156 char fake_oid_index[SMALL_REGISTRY_LEN]; 157 char show_oid_column[SMALL_REGISTRY_LEN]; 158 char row_versioning[SMALL_REGISTRY_LEN]; 159 char show_system_tables[SMALL_REGISTRY_LEN]; 160 char translation_dll[MEDIUM_REGISTRY_LEN]; 161 char translation_option[SMALL_REGISTRY_LEN]; 162 char focus_password; 163 } ConnInfo; 164 165 /* Macro to determine is the connection using 6.2 protocol? */ 166 #define PROTOCOL_62(conninfo_) (strncmp((conninfo_)->protocol, PG62, strlen(PG62)) == 0) 167 168 /* Macro to determine is the connection using 6.3 protocol? */ 169 #define PROTOCOL_63(conninfo_) (strncmp((conninfo_)->protocol, PG63, strlen(PG63)) == 0) 170 171 /* 172 * Macros to compare the server's version with a specified version 173 * 1st parameter: pointer to a ConnectionClass object 174 * 2nd parameter: major version number 175 * 3rd parameter: minor version number 176 */ 177 #define SERVER_VERSION_GT(conn, major, minor) \ 178 ((conn)->pg_version_major > major || \ 179 ((conn)->pg_version_major == major && (conn)->pg_version_minor > minor)) 180 #define SERVER_VERSION_GE(conn, major, minor) \ 181 ((conn)->pg_version_major > major || \ 182 ((conn)->pg_version_major == major && (conn)->pg_version_minor >= minor)) 183 #define SERVER_VERSION_EQ(conn, major, minor) \ 184 ((conn)->pg_version_major == major && (conn)->pg_version_minor == minor) 185 #define SERVER_VERSION_LE(conn, major, minor) (! SERVER_VERSION_GT(conn, major, minor)) 186 #define SERVER_VERSION_LT(conn, major, minor) (! SERVER_VERSION_GE(conn, major, minor)) 187 /*#if ! defined(HAVE_CONFIG_H) || defined(HAVE_STRINGIZE)*/ 188 #define STRING_AFTER_DOT(string) (strchr(#string, '.') + 1) 189 /*#else 190 #define STRING_AFTER_DOT(str) (strchr("str", '.') + 1) 191 #endif*/ 192 /* 193 * Simplified macros to compare the server's version with a 194 * specified version 195 * Note: Never pass a variable as the second parameter. 196 * It must be a decimal constant of the form %d.%d . 197 */ 198 #define PG_VERSION_GT(conn, ver) \ 199 (SERVER_VERSION_GT(conn, (int) ver, atoi(STRING_AFTER_DOT(ver)))) 200 #define PG_VERSION_GE(conn, ver) \ 201 (SERVER_VERSION_GE(conn, (int) ver, atoi(STRING_AFTER_DOT(ver)))) 202 #define PG_VERSION_EQ(conn, ver) \ 203 (SERVER_VERSION_EQ(conn, (int) ver, atoi(STRING_AFTER_DOT(ver)))) 204 #define PG_VERSION_LE(conn, ver) (! PG_VERSION_GT(conn, ver)) 205 #define PG_VERSION_LT(conn, ver) (! PG_VERSION_GE(conn, ver)) 206 207 /* This is used to store cached table information in the connection */ 208 struct col_info { 209 QResultClass *result; 210 char name[MAX_TABLE_LEN+1]; 211 }; 212 213 /* Translation DLL entry points */ 214 #ifdef WIN32 215 #define DLLHANDLE HINSTANCE 216 #else 217 #define WINAPI CALLBACK 218 #define DLLHANDLE void * 219 #define HINSTANCE void * 220 #endif 221 222 typedef BOOL (FAR WINAPI *DataSourceToDriverProc) (UDWORD, 223 SWORD, 224 PTR, 225 SDWORD, 226 PTR, 227 SDWORD, 228 SDWORD FAR *, 229 UCHAR FAR *, 230 SWORD, 231 SWORD FAR *); 232 233 typedef BOOL (FAR WINAPI *DriverToDataSourceProc) (UDWORD, 234 SWORD, 235 PTR, 236 SDWORD, 237 PTR, 238 SDWORD, 239 SDWORD FAR *, 240 UCHAR FAR *, 241 SWORD, 242 SWORD FAR *); 243 244 /******* The Connection handle ************/ 245 struct ConnectionClass_ { 246 HENV henv; /* environment this connection was created on */ 247 StatementOptions stmtOptions; 248 char *__error_message; 249 int __error_number; 250 CONN_Status status; 251 ConnInfo connInfo; 252 StatementClass **stmts; 253 int num_stmts; 254 SocketClass *sock; 255 int lobj_type; 256 int ntables; 257 COL_INFO **col_info; 258 long translation_option; 259 HINSTANCE translation_handle; 260 DataSourceToDriverProc DataSourceToDriver; 261 DriverToDataSourceProc DriverToDataSource; 262 Int2 driver_version; /* prepared for ODBC3.0 */ 263 char transact_status; /* Is a transaction is currently in progress */ 264 char errormsg_created; /* has an informative error msg been created? */ 265 char pg_version[MAX_INFO_STRING]; /* Version of PostgreSQL we're connected to - DJP 25-1-2001 */ 266 float pg_version_number; 267 Int2 pg_version_major; 268 Int2 pg_version_minor; 269 char ms_jet; 270 char unicode; 271 char result_uncommitted; 272 char schema_support; 273 char *client_encoding; 274 char *server_encoding; 275 int ccsc; 276 int be_pid; /* pid returned by backend */ 277 int be_key; /* auth code needed to send cancel */ 278 UInt4 isolation; 279 char *current_schema; 280 int num_discardp; 281 char **discardp; 282 #if (ODBCVER >= 0x0300) 283 int num_descs; 284 DescriptorClass **descs; 285 #endif /* ODBCVER */ 286 #if defined(WIN_MULTITHREAD_SUPPORT) 287 CRITICAL_SECTION cs; 288 #elif defined(POSIX_THREADMUTEX_SUPPORT) 289 pthread_mutex_t cs; 290 #endif /* WIN_MULTITHREAD_SUPPORT */ 291 }; 292 293 294 /* Accessor functions */ 295 #define CC_get_socket(x) (x->sock) 296 #define CC_get_database(x) (x->connInfo.database) 297 #define CC_get_server(x) (x->connInfo.server) 298 #define CC_get_DSN(x) (x->connInfo.dsn) 299 #define CC_get_username(x) (x->connInfo.username) 300 #define CC_is_onlyread(x) (x->connInfo.onlyread[0] == '1') 301 302 303 /* for CC_DSN_info */ 304 #define CONN_DONT_OVERWRITE 0 305 #define CONN_OVERWRITE 1 306 307 308 /* prototypes */ 309 ConnectionClass *CC_Constructor(void); 310 char CC_Destructor(ConnectionClass *self); 311 int CC_cursor_count(ConnectionClass *self); 312 char CC_cleanup(ConnectionClass *self); 313 char CC_abort(ConnectionClass *self); 314 int CC_set_translation (ConnectionClass *self); 315 char CC_connect(ConnectionClass *self, char password_req, char *salt_para); 316 char CC_add_statement(ConnectionClass *self, StatementClass *stmt); 317 char CC_remove_statement(ConnectionClass *self, StatementClass *stmt); 318 void CC_set_error(ConnectionClass *self, int number, const char *message); 319 void CC_set_errormsg(ConnectionClass *self, const char *message); 320 char CC_get_error(ConnectionClass *self, int *number, char **message); 321 QResultClass *CC_send_query(ConnectionClass *self, char *query, QueryInfo *qi); 322 void CC_clear_error(ConnectionClass *self); 323 char *CC_create_errormsg(ConnectionClass *self); 324 int CC_send_function(ConnectionClass *conn, int fnid, void *result_buf, int *actual_result_len, int result_is_int, LO_ARG *argv, int nargs); 325 char CC_send_settings(ConnectionClass *self); 326 void CC_lookup_lo(ConnectionClass *conn); 327 void CC_lookup_pg_version(ConnectionClass *conn); 328 void CC_initialize_pg_version(ConnectionClass *conn); 329 void CC_log_error(char *func, char *desc, ConnectionClass *self); 330 331 332 #endif 333