~ubuntu-branches/ubuntu/karmic/psqlodbc/karmic

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
/* 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"

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

#ifdef	__cplusplus
extern "C" {
#endif
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;

enum
{
	DISALLOW_UPDATABLE_CURSORS = 0,	/* No cursors are updatable */
	ALLOW_STATIC_CURSORS = 1L, /* Static cursors are updatable */
	ALLOW_KEYSET_DRIVEN_CURSORS = (1L << 1), /* Keyset-driven cursors are updatable */
	ALLOW_DYNAMIC_CURSORS = (1L << 2), /* Dynamic cursors are updatable */
	ALLOW_BULK_OPERATIONS = (1L << 3), /* Bulk operations available */
	SENSE_SELF_OPERATIONS = (1L << 4), /* Sense self update/delete/add */
};

/*	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_COMMUNICATION_ERROR				113

#define CONN_TRUNCATED							(-2)
#define CONN_OPTION_VALUE_CHANGED					(-1)
/*	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_VALUE_OUT_OF_RANGE						214

#define CONN_OPTION_NOT_FOR_THE_DRIVER					216
#define CONN_EXEC_ERROR							217

/* 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_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)	(0 != (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) (0 != (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)

/* Unicode handling */
#define	CONN_UNICODE_DRIVER	(1L)
#define	CONN_ANSI_APP		(1L << 1)
#define	CONN_DISALLOW_WCHAR	(1L << 2)
#define	CC_set_in_unicode_driver(x)	(x->unicode |= CONN_UNICODE_DRIVER)
#define	CC_set_in_ansi_app(x)	(x->unicode |= CONN_ANSI_APP)
#define	CC_is_in_unicode_driver(x)	(0 != (x->unicode & CONN_UNICODE_DRIVER))
#define	CC_is_in_ansi_app(x)	(0 != (x->unicode & CONN_ANSI_APP))
#define	ALLOW_WCHAR(x)	(0 != (x->unicode & CONN_UNICODE_DRIVER) && 0 == (x->unicode & CONN_DISALLOW_WCHAR))

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

/* For Multi-thread */
#if defined(WIN_MULTITHREAD_SUPPORT)
#define INIT_CONN_CS(x)		InitializeCriticalSection(&((x)->cs))
#define INIT_CONNLOCK(x)	InitializeCriticalSection(&((x)->slock))
#define ENTER_CONN_CS(x)	EnterCriticalSection(&((x)->cs))
#define CONNLOCK_ACQUIRE(x)	EnterCriticalSection(&((x)->slock))
#define TRY_ENTER_CONN_CS(x)	TryEnterCriticalSection(&((x)->cs))
#define ENTER_INNER_CONN_CS(x, entered) \
do { \
	EnterCriticalSection(&((x)->cs)); \
	entered++; \
} while (0)
#define LEAVE_CONN_CS(x)	LeaveCriticalSection(&((x)->cs))
#define CONNLOCK_RELEASE(x)	LeaveCriticalSection(&((x)->slock))
#define DELETE_CONN_CS(x)	DeleteCriticalSection(&((x)->cs))
#define DELETE_CONNLOCK(x)	DeleteCriticalSection(&((x)->slock))
#elif defined(POSIX_THREADMUTEX_SUPPORT)
#define INIT_CONN_CS(x)		pthread_mutex_init(&((x)->cs), getMutexAttr())
#define INIT_CONNLOCK(x)	pthread_mutex_init(&((x)->slock), getMutexAttr())
#define ENTER_CONN_CS(x)	pthread_mutex_lock(&((x)->cs))
#define CONNLOCK_ACQUIRE(x) 	pthread_mutex_lock(&((x)->slock))
#define TRY_ENTER_CONN_CS(x)	(0 == pthread_mutex_trylock(&((x)->cs)))
#define ENTER_INNER_CONN_CS(x, entered) \
do { \
	if (getMutexAttr()) \
	{ \
		if (pthread_mutex_lock(&((x)->cs)) == 0) \
			entered++; \
	} \
} while (0)
#define LEAVE_CONN_CS(x)	pthread_mutex_unlock(&((x)->cs))
#define CONNLOCK_RELEASE(x) 	pthread_mutex_unlock(&((x)->slock))
#define DELETE_CONN_CS(x)	pthread_mutex_destroy(&((x)->cs))
#define DELETE_CONNLOCK(x)	pthread_mutex_destroy(&((x)->slock))
#else
#define INIT_CONN_CS(x)	
#define INIT_CONNLOCK(x)	
#define TRY_ENTER_CONN_CS(x)
#define ENTER_CONN_CS(x)
#define CONNLOCK_ACQUIRE(x)
#define ENTER_INNER_CONN_CS(x, entered)
#define LEAVE_CONN_CS(x)
#define CONNLOCK_RELEASE(x)
#define DELETE_CONN_CS(x)
#define DELETE_CONNLOCK(x)
#endif /* WIN_MULTITHREAD_SUPPORT */

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

/* 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 USRNAMEDATALEN		16

typedef unsigned int ProtocolVersion;

#define PG_PROTOCOL(major, minor)	(((major) << 16) | (minor))
#define PG_PROTOCOL_LATEST	PG_PROTOCOL(3, 0) 
#define PG_PROTOCOL_74	PG_PROTOCOL(3, 0) 
#define PG_PROTOCOL_64	PG_PROTOCOL(2, 0) 
#define PG_PROTOCOL_63	PG_PROTOCOL(1, 0)
#define PG_PROTOCOL_62	PG_PROTOCOL(0, 0)
#define PG_NEGOTIATE_SSLMODE	PG_PROTOCOL(1234, 5679)

/*	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[USRNAMEDATALEN];
	char		options[ARGV_SIZE];
	char		execfile[ARGV_SIZE];
	char		tty[PATH_SIZE];
} StartupPacket6_2;

/* Transferred from pqcomm.h:  */


typedef ProtocolVersion MsgType;

#define CANCEL_REQUEST_CODE PG_PROTOCOL(1234,5678)

typedef struct CancelRequestPacket
{
	/* Note that each field is stored in network byte order! */
	MsgType		cancelRequestCode;	/* code to identify a cancel request */
	unsigned int	backendPID;	/* PID of client's backend */
	unsigned int	cancelAuthCode; /* secret key to authorize cancel */
} CancelRequestPacket;

/*	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[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;
	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;
	signed char	rollback_on_error;
	signed char	force_abbrev_connstr;
	signed char	bde_environment;
	signed char	fake_mss;
	signed char	cvt_null_date_string;
	signed char	autocommit_public;
	signed char	accessible_only;
	UInt4		extra_opts;
#ifdef	_HANDLE_ENLIST_IN_DTC_
	signed char	xa_opt;
#endif /* _HANDLE_ENLIST_IN_DTC_ */
	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)

/*	Macro to determine is the connection using 6.4 protocol? */
#define PROTOCOL_64(conninfo_)		(strncmp((conninfo_)->protocol, PG64, strlen(PG64)) == 0)

/*	Macro to determine is the connection using 7.4 protocol? */
#define PROTOCOL_74(conninfo_)		(strncmp((conninfo_)->protocol, PG74, strlen(PG74)) == 0)

/*	Macro to determine is the connection using 7.4 rejected? */
#define PROTOCOL_74REJECTED(conninfo_)	(strncmp((conninfo_)->protocol, PG74REJECTED, strlen(PG74REJECTED)) == 0)

#define SUPPORT_DESCRIBE_PARAM(conninfo_) (PROTOCOL_74(conninfo_) && conninfo_->use_server_side_prepare)
/*
 *	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
{
	Int2		num_reserved_cols;
	QResultClass	*result;
	pgNAME		schema_name;
	pgNAME		table_name;
	OID		table_oid;
};
#define col_info_initialize(coli) (memset(coli, 0, sizeof(COL_INFO)))

 /* 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 */
	SQLUINTEGER	login_timeout;
	StatementOptions stmtOptions;
	ARDFields	ardOptions;
	APDFields	apdOptions;
	char		*__error_message;
	int		__error_number;
	char		sqlstate[8];
	CONN_Status	status;
	ConnInfo	connInfo;
	StatementClass	**stmts;
	Int2		num_stmts;
	Int2		ncursors;
	SocketClass	*sock;
	Int4		lobj_type;
	Int2		coli_allocated;
	Int2		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;
	char		result_uncommitted;
	char		schema_support;
	char		lo_is_domain;
	char		escape_in_literal;
	char		*original_client_encoding;
	char		*current_client_encoding;
	char		*server_encoding;
	Int2		ccsc;
	Int2		mb_maxbyte_per_char;
	int		be_pid;	/* pid returned by backend */
	int		be_key; /* auth code needed to send cancel */
	UInt4		isolation;
	char		*current_schema;
	Int2		max_identifier_length;
	Int2		num_discardp;
	char		**discardp;
#if (ODBCVER >= 0x0300)
	int		num_descs;
	DescriptorClass	**descs;
#endif /* ODBCVER */
	pgNAME		schemaIns;
	pgNAME		tableIns;
#ifdef	USE_SSPI
	UInt4		svcs_allowed;
#endif /* USE_SSPI */
#if defined(WIN_MULTITHREAD_SUPPORT)
	CRITICAL_SECTION	cs;
	CRITICAL_SECTION	slock;
#elif defined(POSIX_THREADMUTEX_SUPPORT)
	pthread_mutex_t		cs;
	pthread_mutex_t		slock;
#endif /* WIN_MULTITHREAD_SUPPORT */
#ifdef	_HANDLE_ENLIST_IN_DTC_
	void		*asdum;
#endif /* _HANDLE_ENLIST_IN_DTC_ */
};


/* Accessor functions */
#define CC_get_env(x)				((x)->henv)
#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')
#define CC_get_escape(x)			(x->escape_in_literal)
#define CC_fake_mss(x)	(/* 0 != (x)->ms_jet && */ 0 < (x)->connInfo.fake_mss)
#define CC_accessible_only(x)	(0 < (x)->connInfo.accessible_only && PG_VERSION_GE((x), 7.2))
#define CC_default_is_c(x)	(CC_is_in_ansi_app(x) || x->ms_jet /* not only */ || TRUE /* but for any other ? */)
/*	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);
char		CC_set_autocommit(ConnectionClass *self, BOOL on);
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)
;
#if (ODBCVER >= 0x0300)
char		CC_add_descriptor(ConnectionClass *self, DescriptorClass *desc);
char		CC_remove_descriptor(ConnectionClass *self, DescriptorClass *desc);
#endif /* ODBCVER */
void		CC_set_error(ConnectionClass *self, int number, const char *message, const char *func);
void		CC_set_errormsg(ConnectionClass *self, const char *message);
char		CC_get_error(ConnectionClass *self, int *number, char **message);
QResultClass *CC_send_query_append(ConnectionClass *self, const char *query, QueryInfo *qi, UDWORD flag, StatementClass *stmt, const char *appendq);
#define CC_send_query(self, query, qi, flag, stmt) CC_send_query_append(self, query, qi, flag, stmt, NULL)
void		CC_clear_error(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);
/*
char		*CC_create_errormsg(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		CC_on_abort_partial(ConnectionClass *conn);
void		ProcessRollback(ConnectionClass *conn, BOOL undo, BOOL partial);
const char	*CC_get_current_schema(ConnectionClass *conn);
int             CC_mark_a_object_to_discard(ConnectionClass *conn, int type, const char *plan);
int             CC_discard_marked_objects(ConnectionClass *conn);

int	handle_error_message(ConnectionClass *self, char *msgbuf, size_t buflen,
		 char *sqlstate, const char *comment, QResultClass *res);
int	handle_notice_message(ConnectionClass *self, char *msgbuf, size_t buflen,
		 char *sqlstate, const char *comment, QResultClass *res);
int		EatReadyForQuery(ConnectionClass *self);
void		getParameterValues(ConnectionClass *self);
int		CC_get_max_idlen(ConnectionClass *self);

BOOL		SendSyncRequest(ConnectionClass *self);

const		char *CurrCat(const ConnectionClass *self);
const		char *CurrCatString(const ConnectionClass *self);

/* CC_send_query options */
enum {
	IGNORE_ABORT_ON_CONN	= 1L /* not set the error result even when  */
	,CREATE_KEYSET		= (1L << 1) /* create keyset for updatable curosrs */
	,GO_INTO_TRANSACTION	= (1L << 2) /* issue begin in advance */
	,ROLLBACK_ON_ERROR	= (1L << 3) /* rollback the query when an error occurs */
	,END_WITH_COMMIT	= (1L << 4) /* the query ends with COMMMIT command */
	,IGNORE_ROUND_TRIP	= (1L << 5) /* the commincation round trip time is considered ignorable */
};
/* CC_on_abort options */
#define	NO_TRANS		1L
#define	CONN_DEAD		(1L << 1) /* connection is no longer valid */

#ifdef	__cplusplus
}
#endif
#endif /* __CONNECTION_H__ */