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