3 * Description: See "connection.c"
5 * Comments: See "notice.txt" for copyright and license information.
9 #ifndef __CONNECTION_H__
10 #define __CONNECTION_H__
16 #include "descriptor.h"
18 #if defined (POSIX_MULTITHREAD_SUPPORT)
27 CONN_NOT_CONNECTED
, /* Connection has not been established */
28 CONN_CONNECTED
, /* Connection is up and has been established */
29 CONN_DOWN
, /* Connection is broken */
30 CONN_EXECUTING
/* the connection is currently executing a
36 DISALLOW_UPDATABLE_CURSORS
= 0, /* No cursors are updatable */
37 ALLOW_STATIC_CURSORS
= 1L, /* Static cursors are updatable */
38 ALLOW_KEYSET_DRIVEN_CURSORS
= (1L << 1), /* Keyset-driven cursors are updatable */
39 ALLOW_DYNAMIC_CURSORS
= (1L << 2), /* Dynamic cursors are updatable */
40 ALLOW_BULK_OPERATIONS
= (1L << 3), /* Bulk operations available */
41 SENSE_SELF_OPERATIONS
= (1L << 4), /* Sense self update/delete/add */
44 /* These errors have general sql error state */
45 #define CONNECTION_SERVER_NOT_REACHED 101
46 #define CONNECTION_MSG_TOO_LONG 103
47 #define CONNECTION_COULD_NOT_SEND 104
48 #define CONNECTION_NO_SUCH_DATABASE 105
49 #define CONNECTION_BACKEND_CRAZY 106
50 #define CONNECTION_NO_RESPONSE 107
51 #define CONNECTION_SERVER_REPORTED_ERROR 108
52 #define CONNECTION_COULD_NOT_RECEIVE 109
53 #define CONNECTION_SERVER_REPORTED_WARNING 110
54 #define CONNECTION_NEED_PASSWORD 112
55 #define CONNECTION_COMMUNICATION_ERROR 113
57 #define CONN_TRUNCATED (-2)
58 #define CONN_OPTION_VALUE_CHANGED (-1)
59 /* These errors correspond to specific SQL states */
60 #define CONN_INIREAD_ERROR 201
61 #define CONN_OPENDB_ERROR 202
62 #define CONN_STMT_ALLOC_ERROR 203
63 #define CONN_IN_USE 204
64 #define CONN_UNSUPPORTED_OPTION 205
65 /* Used by SetConnectoption to indicate unsupported options */
66 #define CONN_INVALID_ARGUMENT_NO 206
67 /* SetConnectOption: corresponds to ODBC--"S1009" */
68 #define CONN_TRANSACT_IN_PROGRES 207
69 #define CONN_NO_MEMORY_ERROR 208
70 #define CONN_NOT_IMPLEMENTED_ERROR 209
71 #define CONN_INVALID_AUTHENTICATION 210
72 #define CONN_AUTH_TYPE_UNSUPPORTED 211
73 #define CONN_UNABLE_TO_LOAD_DLL 212
75 #define CONN_VALUE_OUT_OF_RANGE 214
77 #define CONN_OPTION_NOT_FOR_THE_DRIVER 216
78 #define CONN_EXEC_ERROR 217
80 /* Conn_status defines */
81 #define CONN_IN_AUTOCOMMIT 1L
82 #define CONN_IN_TRANSACTION (1L<<1)
83 #define CONN_IN_MANUAL_TRANSACTION (1L<<2)
84 #define CONN_IN_ERROR_BEFORE_IDLE (1L<<3)
86 #define CC_get_errornumber(x) (x->__error_number)
87 #define CC_get_errormsg(x) (x->__error_message)
88 #define CC_set_errornumber(x, n) (x->__error_number = n)
90 /* Unicode handling */
91 #define CONN_UNICODE_DRIVER (1L)
92 #define CONN_ANSI_APP (1L << 1)
93 #define CONN_DISALLOW_WCHAR (1L << 2)
94 #define CC_set_in_unicode_driver(x) (x->unicode |= CONN_UNICODE_DRIVER)
95 #define CC_set_in_ansi_app(x) (x->unicode |= CONN_ANSI_APP)
96 #define CC_is_in_unicode_driver(x) (0 != (x->unicode & CONN_UNICODE_DRIVER))
97 #define CC_is_in_ansi_app(x) (0 != (x->unicode & CONN_ANSI_APP))
98 #define ALLOW_WCHAR(x) (0 != (x->unicode & CONN_UNICODE_DRIVER) && 0 == (x->unicode & CONN_DISALLOW_WCHAR))
100 #define CC_MALLOC_return_with_error(t, tp, s, x, m, ret) \
102 if (t = (char *)malloc(s), NULL == t) \
104 CC_set_error(x, CONN_NO_MEMORY_ERROR, m, ""); \
108 #define CC_REALLOC_return_with_error(t, tp, s, x, m, ret) \
110 if (t = (tp *) realloc(t, s), NULL == t) \
112 CC_set_error(x, CONN_NO_MEMORY_ERROR, m, ""); \
117 /* For Multi-thread */
118 #if defined(WIN_MULTITHREAD_SUPPORT)
119 #define INIT_CONN_CS(x) InitializeCriticalSection(&((x)->cs))
120 #define INIT_CONNLOCK(x) InitializeCriticalSection(&((x)->slock))
121 #define ENTER_CONN_CS(x) EnterCriticalSection(&((x)->cs))
122 #define CONNLOCK_ACQUIRE(x) EnterCriticalSection(&((x)->slock))
123 #define TRY_ENTER_CONN_CS(x) TryEnterCriticalSection(&((x)->cs))
124 #define ENTER_INNER_CONN_CS(x, entered) \
126 EnterCriticalSection(&((x)->cs)); \
129 #define LEAVE_CONN_CS(x) LeaveCriticalSection(&((x)->cs))
130 #define CONNLOCK_RELEASE(x) LeaveCriticalSection(&((x)->slock))
131 #define DELETE_CONN_CS(x) DeleteCriticalSection(&((x)->cs))
132 #define DELETE_CONNLOCK(x) DeleteCriticalSection(&((x)->slock))
133 #elif defined(POSIX_THREADMUTEX_SUPPORT)
134 #define INIT_CONN_CS(x) pthread_mutex_init(&((x)->cs), getMutexAttr())
135 #define INIT_CONNLOCK(x) pthread_mutex_init(&((x)->slock), getMutexAttr())
136 #define ENTER_CONN_CS(x) pthread_mutex_lock(&((x)->cs))
137 #define CONNLOCK_ACQUIRE(x) pthread_mutex_lock(&((x)->slock))
138 #define TRY_ENTER_CONN_CS(x) (0 == pthread_mutex_trylock(&((x)->cs)))
139 #define ENTER_INNER_CONN_CS(x, entered) \
141 if (getMutexAttr()) \
143 if (pthread_mutex_lock(&((x)->cs)) == 0) \
147 #define LEAVE_CONN_CS(x) pthread_mutex_unlock(&((x)->cs))
148 #define CONNLOCK_RELEASE(x) pthread_mutex_unlock(&((x)->slock))
149 #define DELETE_CONN_CS(x) pthread_mutex_destroy(&((x)->cs))
150 #define DELETE_CONNLOCK(x) pthread_mutex_destroy(&((x)->slock))
152 #define INIT_CONN_CS(x)
153 #define INIT_CONNLOCK(x)
154 #define TRY_ENTER_CONN_CS(x)
155 #define ENTER_CONN_CS(x)
156 #define CONNLOCK_ACQUIRE(x)
157 #define ENTER_INNER_CONN_CS(x, entered)
158 #define LEAVE_CONN_CS(x)
159 #define CONNLOCK_RELEASE(x)
160 #define DELETE_CONN_CS(x)
161 #define DELETE_CONNLOCK(x)
162 #endif /* WIN_MULTITHREAD_SUPPORT */
164 #define LEAVE_INNER_CONN_CS(entered, conn) \
168 LEAVE_CONN_CS(conn); \
172 #define CLEANUP_FUNC_CONN_CS(entered, conn) \
174 while (entered > 0) \
176 LEAVE_CONN_CS(conn); \
181 /* Authentication types */
182 #define AUTH_REQ_OK 0
183 #define AUTH_REQ_KRB4 1
184 #define AUTH_REQ_KRB5 2
185 #define AUTH_REQ_PASSWORD 3
186 #define AUTH_REQ_CRYPT 4
187 #define AUTH_REQ_MD5 5
188 #define AUTH_REQ_SCM_CREDS 6
190 /* Startup Packet sizes */
191 #define SM_DATABASE 64
193 #define SM_OPTIONS 64
197 /* Old 6.2 protocol defines */
198 #define NO_AUTHENTICATION 7
201 #define USRNAMEDATALEN 16
203 typedef unsigned int ProtocolVersion
;
205 #define PG_PROTOCOL(major, minor) (((major) << 16) | (minor))
206 #define PG_PROTOCOL_LATEST PG_PROTOCOL(3, 0)
207 #define PG_PROTOCOL_74 PG_PROTOCOL(3, 0)
208 #define PG_PROTOCOL_64 PG_PROTOCOL(2, 0)
209 #define PG_PROTOCOL_63 PG_PROTOCOL(1, 0)
210 #define PG_PROTOCOL_62 PG_PROTOCOL(0, 0)
212 /* This startup packet is to support latest Postgres protocol (6.4, 6.3) */
213 typedef struct _StartupPacket
215 ProtocolVersion protoVersion
;
216 char database
[SM_DATABASE
];
218 char options
[SM_OPTIONS
];
219 char unused
[SM_UNUSED
];
224 /* This startup packet is to support pre-Postgres 6.3 protocol */
225 typedef struct _StartupPacket6_2
227 unsigned int authtype
;
228 char database
[PATH_SIZE
];
229 char user
[USRNAMEDATALEN
];
230 char options
[ARGV_SIZE
];
231 char execfile
[ARGV_SIZE
];
235 /* Transferred from pqcomm.h: */
238 typedef ProtocolVersion MsgType
;
240 #define CANCEL_REQUEST_CODE PG_PROTOCOL(1234,5678)
242 typedef struct CancelRequestPacket
244 /* Note that each field is stored in network byte order! */
245 MsgType cancelRequestCode
; /* code to identify a cancel request */
246 unsigned int backendPID
; /* PID of client's backend */
247 unsigned int cancelAuthCode
; /* secret key to authorize cancel */
248 } CancelRequestPacket
;
250 /* Structure to hold all the connection attributes for a specific
251 connection (used for both registry and file, DSN and DRIVER)
255 char dsn
[MEDIUM_REGISTRY_LEN
];
256 char desc
[MEDIUM_REGISTRY_LEN
];
257 char drivername
[MEDIUM_REGISTRY_LEN
];
258 char server
[MEDIUM_REGISTRY_LEN
];
259 char database
[MEDIUM_REGISTRY_LEN
];
260 char username
[MEDIUM_REGISTRY_LEN
];
261 char password
[MEDIUM_REGISTRY_LEN
];
262 char conn_settings
[LARGE_REGISTRY_LEN
];
263 char protocol
[SMALL_REGISTRY_LEN
];
264 char port
[SMALL_REGISTRY_LEN
];
265 char dbus_moniker
[MEDIUM_REGISTRY_LEN
];
266 char sslmode
[SMALL_REGISTRY_LEN
];
267 char onlyread
[SMALL_REGISTRY_LEN
];
268 char fake_oid_index
[SMALL_REGISTRY_LEN
];
269 char show_oid_column
[SMALL_REGISTRY_LEN
];
270 char row_versioning
[SMALL_REGISTRY_LEN
];
271 char show_system_tables
[SMALL_REGISTRY_LEN
];
272 char translation_dll
[MEDIUM_REGISTRY_LEN
];
273 char translation_option
[SMALL_REGISTRY_LEN
];
275 signed char disallow_premature
;
276 signed char allow_keyset
;
277 signed char updatable_cursors
;
278 signed char lf_conversion
;
279 signed char true_is_minus1
;
281 signed char bytea_as_longvarbinary
;
282 signed char use_server_side_prepare
;
283 signed char lower_case_identifier
;
284 signed char rollback_on_error
;
285 signed char force_abbrev_connstr
;
286 signed char bde_environment
;
287 signed char fake_mss
;
288 signed char cvt_null_date_string
;
289 #ifdef _HANDLE_ENLIST_IN_DTC_
291 #endif /* _HANDLE_ENLIST_IN_DTC_ */
292 GLOBAL_VALUES drivers
; /* moved from driver's option */
295 /* Macro to determine is the connection using 6.2 protocol? */
296 #define PROTOCOL_62(conninfo_) (strncmp((conninfo_)->protocol, PG62, strlen(PG62)) == 0)
298 /* Macro to determine is the connection using 6.3 protocol? */
299 #define PROTOCOL_63(conninfo_) (strncmp((conninfo_)->protocol, PG63, strlen(PG63)) == 0)
301 /* Macro to determine is the connection using 6.4 protocol? */
302 #define PROTOCOL_64(conninfo_) (strncmp((conninfo_)->protocol, PG64, strlen(PG64)) == 0)
304 /* Macro to determine is the connection using 7.4 protocol? */
305 #define PROTOCOL_74(conninfo_) (strncmp((conninfo_)->protocol, PG74, strlen(PG74)) == 0)
307 #define SUPPORT_DESCRIBE_PARAM(conninfo_) (PROTOCOL_74(conninfo_) && conninfo_->use_server_side_prepare)
309 * Macros to compare the server's version with a specified version
310 * 1st parameter: pointer to a ConnectionClass object
311 * 2nd parameter: major version number
312 * 3rd parameter: minor version number
314 #define SERVER_VERSION_GT(conn, major, minor) \
315 ((conn)->pg_version_major > major || \
316 ((conn)->pg_version_major == major && (conn)->pg_version_minor > minor))
317 #define SERVER_VERSION_GE(conn, major, minor) \
318 ((conn)->pg_version_major > major || \
319 ((conn)->pg_version_major == major && (conn)->pg_version_minor >= minor))
320 #define SERVER_VERSION_EQ(conn, major, minor) \
321 ((conn)->pg_version_major == major && (conn)->pg_version_minor == minor)
322 #define SERVER_VERSION_LE(conn, major, minor) (! SERVER_VERSION_GT(conn, major, minor))
323 #define SERVER_VERSION_LT(conn, major, minor) (! SERVER_VERSION_GE(conn, major, minor))
324 /*#if ! defined(HAVE_CONFIG_H) || defined(HAVE_STRINGIZE)*/
325 #define STRING_AFTER_DOT(string) (strchr(#string, '.') + 1)
327 #define STRING_AFTER_DOT(str) (strchr("str", '.') + 1)
330 * Simplified macros to compare the server's version with a
332 * Note: Never pass a variable as the second parameter.
333 * It must be a decimal constant of the form %d.%d .
335 #define PG_VERSION_GT(conn, ver) \
336 (SERVER_VERSION_GT(conn, (int) ver, atoi(STRING_AFTER_DOT(ver))))
337 #define PG_VERSION_GE(conn, ver) \
338 (SERVER_VERSION_GE(conn, (int) ver, atoi(STRING_AFTER_DOT(ver))))
339 #define PG_VERSION_EQ(conn, ver) \
340 (SERVER_VERSION_EQ(conn, (int) ver, atoi(STRING_AFTER_DOT(ver))))
341 #define PG_VERSION_LE(conn, ver) (! PG_VERSION_GT(conn, ver))
342 #define PG_VERSION_LT(conn, ver) (! PG_VERSION_GE(conn, ver))
344 /* This is used to store cached table information in the connection */
347 Int2 num_reserved_cols
;
348 QResultClass
*result
;
353 #define col_info_initialize(coli) (memset(coli, 0, sizeof(COL_INFO)))
355 /* Translation DLL entry points */
357 #define DLLHANDLE HINSTANCE
359 #define WINAPI CALLBACK
360 #define DLLHANDLE void *
361 #define HINSTANCE void *
364 typedef BOOL (FAR WINAPI
* DataSourceToDriverProc
) (UDWORD
, SWORD
, PTR
,
365 SDWORD
, PTR
, SDWORD
, SDWORD FAR
*, UCHAR FAR
*, SWORD
,
367 typedef BOOL (FAR WINAPI
* DriverToDataSourceProc
) (UDWORD
, SWORD
, PTR
,
368 SDWORD
, PTR
, SDWORD
, SDWORD FAR
*, UCHAR FAR
*, SWORD
,
373 /******* The Connection handle ************/
374 struct ConnectionClass_
376 EnvironmentClass
*henv
; /* environment this connection was
379 SQLUINTEGER login_timeout
;
380 StatementOptions stmtOptions
;
381 ARDFields ardOptions
;
382 APDFields apdOptions
;
383 char *__error_message
;
388 StatementClass
**stmts
;
394 long translation_option
;
395 HINSTANCE translation_handle
;
396 DataSourceToDriverProc DataSourceToDriver
;
397 DriverToDataSourceProc DriverToDataSource
;
398 Int2 driver_version
; /* prepared for ODBC3.0 */
399 char errormsg_created
; /* has an informative error msg
401 char pg_version
[MAX_INFO_STRING
]; /* Version of PostgreSQL
402 * we're connected to -
404 float pg_version_number
;
405 Int2 pg_version_major
;
406 Int2 pg_version_minor
;
411 char escape_in_literal
;
412 char *original_client_encoding
;
413 char *current_client_encoding
;
414 char *server_encoding
;
416 Int2 mb_maxbyte_per_char
;
417 int be_pid
; /* pid returned by backend */
418 int be_key
; /* auth code needed to send cancel */
420 char *current_schema
;
421 Int2 max_identifier_length
;
425 DescriptorClass
**descs
;
428 #if defined(WIN_MULTITHREAD_SUPPORT)
430 CRITICAL_SECTION slock
;
431 #elif defined(POSIX_THREADMUTEX_SUPPORT)
433 pthread_mutex_t slock
;
434 #endif /* WIN_MULTITHREAD_SUPPORT */
435 #ifdef _HANDLE_ENLIST_IN_DTC_
437 #endif /* _HANDLE_ENLIST_IN_DTC_ */
441 /* Accessor functions */
442 #define CC_get_socket(x) (x->sock)
443 #define CC_get_database(x) (x->connInfo.database)
444 #define CC_get_server(x) (x->connInfo.server)
445 #define CC_get_DSN(x) (x->connInfo.dsn)
446 #define CC_get_username(x) (x->connInfo.username)
447 #define CC_is_onlyread(x) (x->connInfo.onlyread[0] == '1')
448 #define CC_get_escape(x) (x->escape_in_literal)
449 #define CC_fake_mss(x) (/* 0 != (x)->ms_jet && */ 0 < (x)->connInfo.fake_mss)
450 #define CC_default_is_c(x) (CC_is_in_ansi_app(x) || x->ms_jet /* not only */ || TRUE /* but for any other ? */)
451 /* for CC_DSN_info */
452 #define CONN_DONT_OVERWRITE 0
453 #define CONN_OVERWRITE 1
457 ConnectionClass
*CC_Constructor(void);
458 void CC_conninfo_init(ConnInfo
*conninfo
);
459 char CC_Destructor(ConnectionClass
*self
);
460 int CC_cursor_count(ConnectionClass
*self
);
461 char CC_cleanup(ConnectionClass
*self
);
462 char CC_begin(ConnectionClass
*self
);
463 char CC_commit(ConnectionClass
*self
);
464 char CC_abort(ConnectionClass
*self
);
465 int CC_set_translation(ConnectionClass
*self
);
466 char CC_add_statement(ConnectionClass
*self
, StatementClass
*stmt
);
467 char CC_remove_statement(ConnectionClass
*self
, StatementClass
*stmt
)
469 char CC_add_descriptor(ConnectionClass
*self
, DescriptorClass
*desc
);
470 char CC_remove_descriptor(ConnectionClass
*self
, DescriptorClass
*desc
);
471 void CC_set_error(ConnectionClass
*self
, int number
, const char *message
, const char *func
);
472 void CC_set_errormsg(ConnectionClass
*self
, const char *message
);
473 char CC_get_error(ConnectionClass
*self
, int *number
, char **message
);
474 QResultClass
*CC_send_query(ConnectionClass
*self
, char *query
, QueryInfo
*qi
, UDWORD flag
, StatementClass
*stmt
);
475 void CC_clear_error(ConnectionClass
*self
);
476 char CC_send_settings(ConnectionClass
*self
);
477 void CC_initialize_pg_version(ConnectionClass
*conn
);
478 void CC_log_error(const char *func
, const char *desc
, const ConnectionClass
*self
);
479 int CC_get_max_query_len(const ConnectionClass
*self
);
480 int CC_send_cancel_request(const ConnectionClass
*conn
);
481 void ProcessRollback(ConnectionClass
*conn
, BOOL undo
, BOOL partial
);
482 const char *CC_get_current_schema(ConnectionClass
*conn
);
483 int CC_mark_a_object_to_discard(ConnectionClass
*conn
, int type
, const char *plan
);
484 int CC_discard_marked_objects(ConnectionClass
*conn
);
486 const char *CurrCat(const ConnectionClass
*self
);
487 const char *CurrCatString(const ConnectionClass
*self
);
489 /* CC_send_query options */
491 IGNORE_ABORT_ON_CONN
= 1L /* not set the error result even when */
492 ,CREATE_KEYSET
= (1L << 1) /* create keyset for updatable curosrs */
493 // VX_CLEANUP: Neither GO_INTO_TRANSACTION nor ROLLBACK_ON_ERROR make
495 ,GO_INTO_TRANSACTION
= (1L << 2) /* issue begin in advance */
496 , ROLLBACK_ON_ERROR
= (1L << 3) /* rollback the query when an error occurs */
498 /* CC_on_abort options */
500 #define CONN_DEAD (1L << 1) /* connection is no longer valid */
505 #endif /* __CONNECTION_H__ */