summaryrefslogtreecommitdiff
path: root/src/interfaces/odbc/connection.h
blob: a80c31b9218c042c000646fd0ac62155f94f3d23 (plain)
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
/* 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>


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;
	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;
	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;
#ifdef	MULTIBYTE
	char	   *client_encoding;
	char	   *server_encoding;
#endif   /* MULTIBYTE */
};


/* 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);
char		CC_Destructor(ConnectionClass *self);
int			CC_cursor_count(ConnectionClass *self);
char		CC_cleanup(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);
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(char *func, char *desc, ConnectionClass *self);
int			CC_get_max_query_len(const ConnectionClass *self);

#endif