]>
Commit | Line | Data |
---|---|---|
1a6944fd RR |
1 | /** Connect(load) driver |
2 | ||
7e616b10 | 3 | Copyright (C) 1995 by Ke Jin <kejin@empress.com> |
1a6944fd RR |
4 | |
5 | This program is free software; you can redistribute it and/or modify | |
6 | it under the terms of the GNU General Public License as published by | |
7 | the Free Software Foundation; either version 2 of the License, or | |
8 | (at your option) any later version. | |
9 | ||
10 | This program is distributed in the hope that it will be useful, | |
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | |
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
13 | GNU General Public License for more details. | |
14 | **/ | |
15 | ||
16 | #include <../iodbc/iodbc.h> | |
17 | ||
18 | #include <../iodbc/isql.h> | |
19 | #include <../iodbc/isqlext.h> | |
20 | ||
21 | #include <../iodbc/dlproc.h> | |
22 | ||
23 | #include <../iodbc/herr.h> | |
24 | #include <../iodbc/henv.h> | |
25 | #include <../iodbc/hdbc.h> | |
26 | #include <../iodbc/hstmt.h> | |
27 | ||
28 | #include <../iodbc/itrace.h> | |
7e616b10 | 29 | |
bd7d06f2 RR |
30 | #include <strings.h> |
31 | #include <stdio.h> | |
1a6944fd | 32 | |
7e616b10 RR |
33 | extern char* _iodbcdm_getkeyvalbydsn(); |
34 | extern char* _iodbcdm_getkeyvalinstr(); | |
35 | extern RETCODE _iodbcdm_driverunload(); | |
1a6944fd RR |
36 | |
37 | /* | |
7e616b10 RR |
38 | * Following id string is a copyright mark. Removing(i.e. use |
39 | * souce code of this package without it or make it not appear | |
40 | * in the final object file) or modifing it without permission | |
41 | * from original author(kejin@empress.com) are copyright | |
1a6944fd RR |
42 | * violation. |
43 | */ | |
7e616b10 RR |
44 | static char sccsid[] |
45 | = "@(#)iODBC driver manager " "2.12" ", Copyright(c) 1995 by Ke Jin"; | |
1a6944fd | 46 | |
7e616b10 RR |
47 | static RETCODE _iodbcdm_driverload( |
48 | char FAR* path, | |
49 | HDBC hdbc ) | |
50 | /* - Load driver share library( or increase its reference count | |
1a6944fd RR |
51 | * if it has already been loaded by another active connection) |
52 | * - Call driver's SQLAllocEnv() (for the first reference only) | |
53 | * - Call driver's SQLAllocConnect() | |
54 | * - Call driver's SQLSetConnectOption() (set login time out) | |
55 | * - Increase the bookkeeping reference count | |
56 | */ | |
57 | { | |
7e616b10 RR |
58 | DBC_t FAR* pdbc = (DBC_t FAR*)hdbc; |
59 | GENV_t FAR* genv; | |
60 | ENV_t FAR* penv = NULL; | |
61 | HDLL hdll; | |
62 | HPROC hproc; | |
63 | RETCODE retcode = SQL_SUCCESS; | |
64 | int sqlstat = en_00000; | |
65 | ||
66 | if(pdbc->trace) | |
67 | { | |
68 | fprintf(pdbc->tstm, "_iodbcdm_driverload(%s, 0x%x)\n", path, (int)hdbc); | |
69 | } | |
70 | ||
71 | if( path == NULL || path[0] == '\0' ) | |
72 | { | |
73 | PUSHSQLERR ( pdbc->herr, en_IM002 ); | |
74 | ||
75 | return SQL_ERROR; | |
76 | } | |
77 | ||
78 | if( hdbc == SQL_NULL_HDBC | |
79 | || pdbc->genv == SQL_NULL_HENV ) | |
80 | { | |
81 | return SQL_INVALID_HANDLE; | |
82 | } | |
83 | ||
84 | genv = (GENV_t FAR*)pdbc->genv; | |
85 | ||
86 | hdll = _iodbcdm_dllopen( (char FAR*) path ); | |
87 | /* This will either load the | |
88 | * driver dll or increase its | |
89 | * reference count */ | |
90 | ||
91 | if( hdll == SQL_NULL_HDLL ) | |
92 | { | |
93 | if(pdbc->trace) | |
94 | { | |
95 | fprintf(pdbc->tstm, "ERROR: _iodbcdm_driverload cannot load driver - '%s'\n", _iodbcdm_dllerror()); | |
96 | } | |
97 | ||
98 | PUSHSYSERR ( pdbc->herr, _iodbcdm_dllerror() ); | |
99 | PUSHSQLERR ( pdbc->herr, en_IM003 ); | |
100 | return SQL_ERROR; | |
101 | } | |
102 | ||
103 | penv = (ENV_t FAR*)(pdbc->henv); | |
104 | ||
105 | if( penv != NULL ) | |
106 | { | |
107 | if( penv->hdll != hdll ) | |
108 | { | |
109 | _iodbcdm_driverunload(hdbc); | |
110 | } | |
111 | else | |
112 | { | |
113 | _iodbcdm_dllclose( hdll ); | |
114 | /* this will not unload the driver | |
115 | * but only decrease its internal | |
116 | * reference count | |
117 | */ | |
118 | } | |
119 | } | |
120 | ||
121 | if(penv == NULL ) | |
122 | { | |
123 | /* find out whether this dll has already | |
124 | * been loaded on another connection */ | |
125 | for( penv = (ENV_t FAR*)genv->henv; | |
126 | penv != NULL; | |
127 | penv = (ENV_t FAR*)penv->next ) | |
128 | { | |
129 | if( penv->hdll == hdll ) | |
130 | { | |
131 | _iodbcdm_dllclose( hdll ); | |
132 | /* this will not unload the driver | |
133 | * but only decrease its internal | |
134 | * reference count | |
135 | */ | |
136 | break; | |
137 | } | |
138 | } | |
139 | ||
140 | if( penv == NULL ) | |
141 | /* no connection attaching with this dll */ | |
142 | { | |
143 | int i; | |
144 | ||
145 | /* create a new dll env instance */ | |
146 | penv = (ENV_t FAR*)MEM_ALLOC ( sizeof(ENV_t) ); | |
147 | ||
148 | if( penv == NULL ) | |
149 | { | |
150 | _iodbcdm_dllclose(hdll); | |
151 | ||
152 | PUSHSQLERR ( pdbc->herr, en_S1001 ); | |
153 | ||
154 | return SQL_ERROR; | |
155 | } | |
156 | ||
157 | for( i = 0; i< SQL_EXT_API_LAST + 1; i++) | |
158 | { | |
159 | (penv->dllproc_tab)[i] = SQL_NULL_HPROC; | |
160 | } | |
161 | ||
162 | pdbc->henv = penv; | |
163 | penv->hdll = hdll; | |
164 | ||
165 | /* call driver's SQLAllocHandle() or SQLAllocEnv() */ | |
1a6944fd | 166 | #if (ODBCVER >= 0x0300) |
7e616b10 RR |
167 | hproc = _iodbcdm_getproc( hdbc, en_AllocHandle ); |
168 | ||
169 | if( hproc ) | |
170 | { | |
171 | CALL_DRIVER ( hdbc, retcode, hproc, en_AllocHandle, | |
172 | ( SQL_HANDLE_ENV, SQL_NULL_HANDLE, &(penv->dhenv) ) | |
173 | } | |
174 | else /* try driver's SQLAllocEnv() */ | |
1a6944fd | 175 | #endif |
7e616b10 RR |
176 | { |
177 | hproc = _iodbcdm_getproc( hdbc, en_AllocEnv ); | |
178 | ||
179 | if( hproc == SQL_NULL_HPROC) | |
180 | { | |
181 | sqlstat = en_IM004; | |
182 | } | |
183 | else | |
184 | { | |
185 | CALL_DRIVER ( hdbc, retcode, hproc, | |
186 | en_AllocEnv, (&(penv->dhenv)) ) | |
187 | } | |
188 | } | |
189 | ||
190 | if( retcode == SQL_ERROR ) | |
191 | { | |
192 | sqlstat = en_IM004; | |
193 | } | |
194 | ||
195 | if( sqlstat != en_00000 ) | |
196 | { | |
197 | _iodbcdm_dllclose ( hdll ); | |
198 | MEM_FREE ( penv ); | |
199 | PUSHSQLERR ( pdbc->herr, en_IM004 ); | |
200 | ||
201 | return SQL_ERROR; | |
202 | } | |
203 | ||
204 | /* insert into dll env list */ | |
205 | penv->next = (ENV_t FAR*)genv->henv; | |
206 | genv->henv = penv; | |
207 | ||
208 | /* initiate this new env entry */ | |
209 | penv->refcount = 0; /* we will increase it after | |
210 | * driver's SQLAllocConnect() | |
211 | * success | |
212 | */ | |
213 | } | |
214 | ||
215 | pdbc->henv = penv; | |
216 | ||
217 | if( pdbc->dhdbc == SQL_NULL_HDBC ) | |
218 | { | |
1a6944fd | 219 | #if (ODBCVER >= 0x0300) |
7e616b10 RR |
220 | hproc = _iodbcdm_getproc( hdbc, en_AllocHandle ); |
221 | ||
222 | if( hproc ) | |
223 | { | |
224 | CALL_DRIVER( hdbc, retcode, hproc, en_AllocHandle, | |
225 | (SQL_HANDLE_DBC, penv->dhenv, &(pdbc->dhdbc)) ) | |
226 | } | |
227 | else | |
1a6944fd | 228 | #endif |
7e616b10 RR |
229 | { |
230 | hproc = _iodbcdm_getproc( hdbc, en_AllocConnect ); | |
231 | ||
232 | if( hproc == SQL_NULL_HPROC ) | |
233 | { | |
234 | sqlstat = en_IM005; | |
235 | } | |
236 | else | |
237 | { | |
238 | CALL_DRIVER ( hdbc, retcode, hproc, | |
239 | en_AllocConnect, (penv->dhenv, &(pdbc->dhdbc)) ) | |
240 | } | |
241 | } | |
242 | ||
243 | if( retcode == SQL_ERROR ) | |
244 | { | |
245 | sqlstat = en_IM005; | |
246 | } | |
247 | ||
248 | if( sqlstat != en_00000 ) | |
249 | { | |
250 | _iodbcdm_driverunload(hdbc); | |
251 | ||
252 | pdbc->dhdbc = SQL_NULL_HDBC; | |
253 | PUSHSQLERR ( pdbc->herr, en_IM005 ); | |
254 | ||
255 | return SQL_ERROR; | |
256 | } | |
257 | } | |
258 | ||
259 | pdbc->henv = penv; | |
260 | penv->refcount ++; /* bookkeeping reference count on this driver */ | |
261 | } | |
262 | ||
263 | /* driver's login timeout option must been set before | |
264 | * its SQLConnect() call */ | |
265 | if( pdbc->login_timeout != 0UL ) | |
266 | { | |
267 | hproc = _iodbcdm_getproc( hdbc, en_SetConnectOption ); | |
268 | ||
269 | if( hproc == SQL_NULL_HPROC ) | |
270 | { | |
271 | sqlstat = en_IM004; | |
272 | } | |
273 | else | |
274 | { | |
275 | CALL_DRIVER ( hdbc, retcode, hproc, | |
276 | en_SetConnectOption, ( | |
277 | pdbc->dhdbc, | |
278 | SQL_LOGIN_TIMEOUT, | |
279 | pdbc->login_timeout ) ) | |
280 | ||
281 | if( retcode == SQL_ERROR ) | |
282 | { | |
283 | PUSHSQLERR ( pdbc->herr, en_IM006 ); | |
284 | ||
285 | return SQL_SUCCESS_WITH_INFO; | |
286 | } | |
287 | } | |
288 | } | |
289 | ||
290 | return SQL_SUCCESS; | |
1a6944fd RR |
291 | } |
292 | ||
7e616b10 | 293 | RETCODE _iodbcdm_driverunload( HDBC hdbc ) |
1a6944fd RR |
294 | /* - Call driver's SQLFreeConnect() |
295 | * - Call driver's SQLFreeEnv() ( for the last reference only) | |
296 | * - Unload the share library( or decrease its reference | |
297 | * count if it is not the last referenct ) | |
298 | * - decrease bookkeeping reference count | |
299 | * - state transition to allocated | |
300 | */ | |
301 | { | |
7e616b10 RR |
302 | DBC_t FAR* pdbc = (DBC_t FAR*)hdbc; |
303 | ENV_t FAR* penv; | |
304 | ENV_t FAR* tpenv; | |
305 | GENV_t FAR* genv; | |
306 | HPROC hproc; | |
307 | RETCODE retcode = SQL_SUCCESS; | |
308 | int sqlstat = en_00000; | |
309 | ||
310 | if( hdbc == SQL_NULL_HDBC ) | |
311 | { | |
312 | return SQL_INVALID_HANDLE; | |
313 | } | |
314 | ||
315 | /* no pointer check will be performed in this function */ | |
316 | penv = (ENV_t FAR*)pdbc->henv; | |
317 | genv = (GENV_t FAR*)pdbc->genv; | |
318 | ||
319 | if( penv == NULL | |
320 | || penv->hdll == SQL_NULL_HDLL ) | |
321 | { | |
322 | return SQL_SUCCESS; | |
323 | } | |
1a6944fd RR |
324 | |
325 | #if (ODBCVER >= 0x0300) | |
7e616b10 RR |
326 | hproc = _iodbcdm_getproc( hdbc, en_FreeHandle ); |
327 | ||
328 | if( hproc ) | |
329 | { | |
330 | CALL_DRIVER ( hdbc, retcode, hproc, en_FreeHandle, | |
331 | ( SQL_HANDLE_DBC, pdbc->dhdbc ) ) | |
332 | } | |
333 | else | |
1a6944fd | 334 | #endif |
7e616b10 RR |
335 | { |
336 | hproc = _iodbcdm_getproc( hdbc, en_FreeConnect ); | |
1a6944fd | 337 | |
7e616b10 RR |
338 | if( hproc != SQL_NULL_HPROC ) |
339 | { | |
340 | CALL_DRIVER ( hdbc, retcode, hproc, | |
341 | en_FreeConnect, ( pdbc->dhdbc ) ) | |
1a6944fd | 342 | |
7e616b10 RR |
343 | pdbc->dhdbc = SQL_NULL_HDBC; |
344 | } | |
345 | } | |
1a6944fd | 346 | |
7e616b10 | 347 | penv->refcount --; |
1a6944fd | 348 | |
7e616b10 RR |
349 | if( ! penv->refcount ) |
350 | /* no other connections still attaching with this driver */ | |
351 | { | |
1a6944fd | 352 | #if (ODBCVER >= 0x0300) |
7e616b10 RR |
353 | hproc = _iodbcdm_getproc( hdbc, en_FreeHandle ); |
354 | ||
355 | if( hproc ) | |
356 | { | |
357 | CALL_DRIVER ( hdbc, retcode, hproc, en_FreeHandle, | |
358 | ( SQL_HANDLE_ENV, penv->dhenv ) ) | |
359 | } | |
360 | else | |
1a6944fd | 361 | #endif |
7e616b10 RR |
362 | { |
363 | hproc = _iodbcdm_getproc( hdbc, en_FreeEnv ); | |
364 | ||
365 | if( hproc != SQL_NULL_HPROC ) | |
366 | { | |
367 | CALL_DRIVER ( hdbc, retcode, hproc, en_FreeEnv, | |
368 | ( penv->dhenv ) ) | |
369 | ||
370 | penv->dhenv = SQL_NULL_HENV; | |
371 | } | |
372 | } | |
373 | ||
374 | _iodbcdm_dllclose ( penv->hdll ); | |
375 | ||
376 | penv->hdll == SQL_NULL_HDLL; | |
377 | ||
378 | for( tpenv = (ENV_t FAR*)genv->henv; | |
379 | tpenv != NULL; | |
380 | tpenv = (ENV_t FAR*)penv->next ) | |
381 | { | |
382 | if( tpenv == penv ) | |
383 | { | |
384 | genv->henv = penv->next; | |
385 | break; | |
386 | } | |
387 | ||
388 | if( tpenv->next == penv ) | |
389 | { | |
390 | tpenv->next = penv->next; | |
391 | break; | |
392 | } | |
393 | } | |
394 | ||
395 | MEM_FREE( penv ); | |
396 | } | |
397 | ||
398 | pdbc->henv = SQL_NULL_HENV; | |
399 | pdbc->hstmt= SQL_NULL_HSTMT; | |
400 | /* pdbc->herr = SQL_NULL_HERR; | |
401 | -- delay to DM's SQLFreeConnect() */ | |
402 | pdbc->dhdbc= SQL_NULL_HDBC; | |
403 | pdbc->state= en_dbc_allocated; | |
404 | ||
405 | /* set connect options to default values */ | |
406 | /********** | |
407 | pdbc->access_mode = SQL_MODE_DEFAULT; | |
408 | pdbc->autocommit = SQL_AUTOCOMMIT_DEFAULT; | |
409 | pdbc->login_timeout = 0UL; | |
410 | **********/ | |
411 | pdbc->odbc_cursors = SQL_CUR_DEFAULT; | |
412 | pdbc->packet_size = 0UL; | |
413 | pdbc->quiet_mode = (UDWORD)NULL; | |
414 | pdbc->txn_isolation = SQL_TXN_READ_UNCOMMITTED; | |
415 | ||
416 | if( pdbc->current_qualifier != NULL ) | |
417 | { | |
418 | MEM_FREE ( pdbc->current_qualifier ); | |
419 | pdbc->current_qualifier = NULL; | |
420 | } | |
421 | ||
422 | return SQL_SUCCESS; | |
1a6944fd RR |
423 | } |
424 | ||
7e616b10 | 425 | static RETCODE _iodbcdm_dbcdelayset( HDBC hdbc ) |
1a6944fd | 426 | { |
7e616b10 RR |
427 | DBC_t FAR* pdbc = (DBC_t FAR*)hdbc; |
428 | ENV_t FAR* penv; | |
429 | HPROC hproc; | |
430 | RETCODE retcode = SQL_SUCCESS; | |
431 | RETCODE ret; | |
432 | ||
433 | penv = pdbc->henv; | |
434 | ||
435 | hproc = _iodbcdm_getproc( hdbc, en_SetConnectOption ); | |
436 | ||
437 | if( hproc == SQL_NULL_HPROC ) | |
438 | { | |
439 | PUSHSQLERR ( pdbc->herr, en_IM006 ); | |
440 | ||
441 | return SQL_SUCCESS_WITH_INFO; | |
442 | } | |
443 | ||
444 | if( pdbc->access_mode != SQL_MODE_DEFAULT ) | |
445 | { | |
446 | CALL_DRIVER ( hdbc, ret, hproc, | |
447 | en_SetConnectOption, ( | |
448 | SQL_ACCESS_MODE, | |
449 | pdbc->access_mode) ) | |
450 | ||
451 | retcode |= ret; | |
452 | } | |
453 | ||
454 | if( pdbc->autocommit != SQL_AUTOCOMMIT_DEFAULT ) | |
455 | { | |
456 | CALL_DRIVER ( hdbc, ret, hproc, | |
457 | en_SetConnectOption, ( | |
458 | pdbc->dhdbc, | |
459 | SQL_AUTOCOMMIT, | |
460 | pdbc->autocommit ) ) | |
461 | ||
462 | retcode |= ret; | |
463 | } | |
464 | ||
465 | if( pdbc->current_qualifier != NULL ) | |
466 | { | |
467 | CALL_DRIVER ( hdbc, ret, hproc, | |
468 | en_SetConnectOption, ( | |
469 | pdbc->dhdbc, | |
470 | SQL_CURRENT_QUALIFIER, | |
471 | pdbc->current_qualifier ) ) | |
472 | ||
473 | retcode |= ret; | |
474 | } | |
475 | ||
476 | if( pdbc->packet_size != 0UL ) | |
477 | { | |
478 | CALL_DRIVER ( hdbc, ret, hproc, | |
479 | en_SetConnectOption, ( | |
480 | pdbc->dhdbc, | |
481 | SQL_PACKET_SIZE, | |
482 | pdbc->packet_size ) ) | |
483 | ||
484 | retcode |= ret; | |
485 | } | |
486 | ||
487 | if( pdbc->quiet_mode != (UDWORD)NULL ) | |
488 | { | |
489 | CALL_DRIVER ( hdbc, ret, hproc, | |
490 | en_SetConnectOption, ( | |
491 | pdbc->dhdbc, | |
492 | SQL_QUIET_MODE, | |
493 | pdbc->quiet_mode ) ) | |
494 | ||
495 | retcode |= ret; | |
496 | } | |
497 | ||
498 | if( pdbc->txn_isolation != SQL_TXN_READ_UNCOMMITTED ) | |
499 | { | |
500 | CALL_DRIVER ( hdbc, ret, hproc, | |
501 | en_SetConnectOption, ( | |
502 | pdbc->dhdbc, | |
503 | SQL_TXN_ISOLATION, | |
504 | pdbc->txn_isolation ) ) | |
505 | } | |
506 | ||
507 | /* check error code for driver's SQLSetConnectOption() call */ | |
508 | if( retcode != SQL_SUCCESS | |
509 | && retcode != SQL_SUCCESS_WITH_INFO ) | |
510 | { | |
511 | PUSHSQLERR ( pdbc->herr, en_IM006 ); | |
512 | ||
513 | retcode = SQL_ERROR; | |
514 | } | |
515 | ||
516 | /* get cursor behavior on transaction commit or rollback */ | |
517 | hproc = _iodbcdm_getproc( hdbc, en_GetInfo ); | |
518 | ||
519 | if( hproc == SQL_NULL_HPROC ) | |
520 | { | |
521 | PUSHSQLERR ( pdbc->herr, en_01000 ); | |
522 | ||
523 | return retcode; | |
524 | } | |
525 | ||
526 | CALL_DRIVER ( hdbc, ret, hproc, | |
527 | en_GetInfo, ( | |
528 | pdbc->dhdbc, | |
529 | SQL_CURSOR_COMMIT_BEHAVIOR, | |
530 | (PTR)&(pdbc->cb_commit), | |
531 | sizeof(pdbc->cb_commit), | |
532 | NULL ) ) | |
533 | ||
534 | retcode |= ret; | |
535 | ||
536 | CALL_DRIVER ( hdbc, ret, hproc, | |
537 | en_GetInfo, ( | |
538 | pdbc->dhdbc, | |
539 | SQL_CURSOR_ROLLBACK_BEHAVIOR, | |
540 | (PTR)&(pdbc->cb_rollback), | |
541 | sizeof(pdbc->cb_rollback), | |
542 | NULL ) ) | |
543 | ||
544 | retcode |= ret; | |
545 | ||
546 | if( retcode != SQL_SUCCESS | |
547 | && retcode != SQL_SUCCESS_WITH_INFO ) | |
548 | { | |
549 | return SQL_ERROR; | |
550 | } | |
551 | ||
552 | return retcode; | |
1a6944fd RR |
553 | } |
554 | ||
7e616b10 | 555 | static RETCODE _iodbcdm_settracing( HDBC hdbc, char* dsn, int dsnlen ) |
1a6944fd | 556 | { |
7e616b10 RR |
557 | char buf[256]; |
558 | char* ptr; | |
559 | RETCODE setopterr = SQL_SUCCESS; | |
560 | ||
561 | /* Get Driver's DLL path from specificed or default dsn section */ | |
562 | ptr = _iodbcdm_getkeyvalbydsn( dsn, dsnlen, "TraceFile", | |
563 | (char FAR*)buf, sizeof(buf)); | |
564 | ||
565 | if( ptr == NULL || ptr[0] == '\0' ) | |
566 | { | |
567 | ptr = (char FAR*)(SQL_OPT_TRACE_FILE_DEFAULT); | |
568 | } | |
569 | ||
570 | setopterr |= SQLSetConnectOption( hdbc, | |
571 | SQL_OPT_TRACEFILE, (UDWORD)(ptr)); | |
572 | ||
573 | ptr = _iodbcdm_getkeyvalbydsn( dsn, dsnlen, "Trace", | |
574 | (char FAR*)buf, sizeof(buf)); | |
575 | ||
576 | if( ptr != NULL ) | |
577 | { | |
578 | UDWORD opt = (UDWORD)(-1L); | |
579 | ||
580 | if( STREQ(ptr, "ON") | |
581 | || STREQ(ptr, "On") | |
582 | || STREQ(ptr, "on") | |
583 | || STREQ(ptr, "1" ) ) | |
584 | { | |
585 | opt = SQL_OPT_TRACE_ON; | |
586 | } | |
587 | ||
588 | if( STREQ(ptr, "OFF") | |
589 | || STREQ(ptr, "Off") | |
590 | || STREQ(ptr, "off") | |
591 | || STREQ(ptr, "0" ) ) | |
592 | { | |
593 | opt = SQL_OPT_TRACE_OFF; | |
594 | } | |
595 | ||
596 | if( opt != (UDWORD)(-1L) ) | |
597 | { | |
598 | setopterr |= SQLSetConnectOption( hdbc, | |
599 | SQL_OPT_TRACE, opt); | |
600 | } | |
601 | } | |
602 | return SQL_SUCCESS; | |
1a6944fd RR |
603 | } |
604 | ||
7e616b10 RR |
605 | RETCODE SQL_API SQLConnect ( |
606 | HDBC hdbc, | |
607 | UCHAR FAR* szDSN, | |
608 | SWORD cbDSN, | |
609 | UCHAR FAR* szUID, | |
610 | SWORD cbUID, | |
611 | UCHAR FAR* szAuthStr, | |
612 | SWORD cbAuthStr) | |
1a6944fd | 613 | { |
7e616b10 RR |
614 | DBC_t FAR* pdbc = (DBC_t FAR*)hdbc; |
615 | RETCODE retcode = SQL_SUCCESS; | |
616 | RETCODE setopterr = SQL_SUCCESS; | |
617 | char driver[1024] = { '\0' }; /* MS SDK Guide | |
618 | * specifies driver | |
619 | * path can't longer | |
620 | * than 255. */ | |
621 | char szNewDSN[256]; /* OS/2 !!! */ | |
622 | char *ptr; | |
623 | HPROC hproc; | |
624 | ||
625 | if( hdbc == SQL_NULL_HDBC ) | |
626 | { | |
627 | return SQL_INVALID_HANDLE; | |
628 | } | |
629 | ||
630 | /* check arguments */ | |
631 | if( ( cbDSN < 0 && cbDSN != SQL_NTS ) | |
632 | || ( cbUID < 0 && cbUID != SQL_NTS ) | |
633 | || ( cbAuthStr < 0 && cbAuthStr != SQL_NTS ) | |
634 | || ( cbDSN > SQL_MAX_DSN_LENGTH ) ) | |
635 | { | |
636 | PUSHSQLERR ( pdbc->herr, en_S1090 ); | |
637 | ||
638 | return SQL_ERROR; | |
639 | } | |
640 | ||
641 | if( szDSN == NULL || cbDSN == 0 ) | |
642 | { | |
643 | PUSHSQLERR ( pdbc->herr, en_IM002 ); | |
644 | ||
645 | return SQL_ERROR; | |
646 | } | |
647 | ||
648 | /* check state */ | |
649 | if( pdbc->state != en_dbc_allocated ) | |
650 | { | |
651 | PUSHSQLERR ( pdbc->herr, en_08002 ); | |
652 | ||
653 | return SQL_ERROR; | |
654 | } | |
655 | ||
656 | setopterr |= _iodbcdm_settracing( hdbc, | |
657 | (char*)szDSN, cbDSN ); | |
658 | ||
659 | ptr = _iodbcdm_getkeyvalbydsn( szDSN, cbDSN, "Driver", | |
660 | (char FAR*)driver, sizeof(driver)); | |
661 | ||
662 | if( ptr == NULL ) | |
663 | /* No specified or default dsn section or | |
664 | * no driver specification in this dsn section */ | |
665 | { | |
666 | PUSHSQLERR ( pdbc->herr, en_IM002 ); | |
667 | ||
668 | return SQL_ERROR; | |
669 | } | |
670 | ||
671 | /* | |
672 | ** OS/2 !!! | |
673 | ** | |
674 | ** get new szDSN from INI file, if existing | |
675 | */ | |
676 | if( NULL != _iodbcdm_getkeyvalbydsn( szDSN, cbDSN, "DSN", | |
677 | (char FAR*) &szNewDSN, | |
678 | sizeof(szNewDSN) ) ) | |
679 | { | |
680 | szDSN = &szNewDSN[0]; | |
681 | cbDSN = SQL_NTS; | |
682 | } | |
683 | ||
684 | retcode = _iodbcdm_driverload( driver, hdbc ); | |
685 | ||
686 | switch( retcode ) | |
687 | { | |
688 | case SQL_SUCCESS: | |
689 | break; | |
690 | ||
691 | case SQL_SUCCESS_WITH_INFO: | |
692 | setopterr = SQL_ERROR; | |
693 | /* unsuccessed in calling driver's | |
694 | * SQLSetConnectOption() to set login | |
695 | * timeout. | |
696 | */ | |
697 | break; | |
698 | ||
699 | default: | |
700 | return retcode; | |
701 | } | |
702 | ||
703 | hproc = _iodbcdm_getproc( hdbc, en_Connect ); | |
704 | ||
705 | if( hproc == SQL_NULL_HPROC ) | |
706 | { | |
707 | _iodbcdm_driverunload( hdbc ); | |
708 | ||
709 | PUSHSQLERR ( pdbc->herr, en_IM001 ); | |
710 | ||
711 | return SQL_ERROR; | |
712 | } | |
713 | ||
714 | CALL_DRIVER ( hdbc, retcode, hproc, en_Connect, ( | |
715 | pdbc->dhdbc, | |
716 | szDSN, cbDSN, | |
717 | szUID, cbUID, | |
718 | szAuthStr, cbAuthStr ) ) | |
1a6944fd RR |
719 | |
720 | #if 0 | |
7e616b10 RR |
721 | retcode = hproc(pdbc->dhdbc, |
722 | szDSN, cbDSN, | |
723 | szUID, cbUID, | |
724 | szAuthStr, cbAuthStr ); | |
1a6944fd RR |
725 | #endif |
726 | ||
7e616b10 RR |
727 | if( retcode != SQL_SUCCESS |
728 | && retcode != SQL_SUCCESS_WITH_INFO ) | |
729 | { | |
730 | /* not unload driver for retrive error | |
731 | * messge from driver */ | |
732 | /********* | |
733 | _iodbcdm_driverunload( hdbc ); | |
734 | **********/ | |
1a6944fd | 735 | |
7e616b10 RR |
736 | return retcode; |
737 | } | |
1a6944fd | 738 | |
7e616b10 RR |
739 | /* state transition */ |
740 | pdbc->state = en_dbc_connected; | |
1a6944fd | 741 | |
7e616b10 RR |
742 | /* do delaid option setting */ |
743 | setopterr |= _iodbcdm_dbcdelayset( hdbc ); | |
1a6944fd | 744 | |
7e616b10 RR |
745 | if( setopterr != SQL_SUCCESS ) |
746 | { | |
747 | return SQL_SUCCESS_WITH_INFO; | |
748 | } | |
1a6944fd | 749 | |
7e616b10 | 750 | return retcode; |
1a6944fd | 751 | } |
1a6944fd | 752 | |
7e616b10 RR |
753 | RETCODE SQL_API SQLDriverConnect ( |
754 | HDBC hdbc, | |
755 | HWND hwnd, | |
756 | UCHAR FAR* szConnStrIn, | |
757 | SWORD cbConnStrIn, | |
758 | UCHAR FAR* szConnStrOut, | |
759 | SWORD cbConnStrOutMax, | |
760 | SWORD FAR* pcbConnStrOut, | |
761 | UWORD fDriverCompletion ) | |
762 | { | |
763 | DBC_t FAR* pdbc = (DBC_t FAR*)hdbc; | |
764 | HDLL hdll; | |
765 | char FAR* drv; | |
766 | char drvbuf[1024]; | |
767 | char FAR* dsn; | |
768 | char dsnbuf[SQL_MAX_DSN_LENGTH + 1]; | |
769 | char szNewDSN[256]; /* OS/2 !!! */ | |
770 | UCHAR cnstr2drv[1024]; | |
771 | ||
772 | HPROC hproc, dialproc; | |
773 | ||
774 | int sqlstat = en_00000; | |
775 | RETCODE retcode = SQL_SUCCESS; | |
776 | RETCODE setopterr = SQL_SUCCESS; | |
777 | ||
778 | if( hdbc == SQL_NULL_HDBC ) | |
779 | { | |
780 | return SQL_INVALID_HANDLE; | |
781 | } | |
782 | ||
783 | /* check arguments */ | |
784 | if( ( cbConnStrIn < 0 && cbConnStrIn != SQL_NTS ) | |
785 | || cbConnStrOutMax < 0 ) | |
786 | { | |
787 | PUSHSQLERR (pdbc->herr, en_S1090 ); | |
788 | ||
789 | return SQL_ERROR; | |
790 | } | |
791 | ||
792 | /* check state */ | |
793 | if( pdbc->state != en_dbc_allocated ) | |
794 | { | |
795 | PUSHSQLERR (pdbc->herr, en_08002 ); | |
796 | ||
797 | return SQL_ERROR; | |
798 | } | |
799 | ||
800 | drv = _iodbcdm_getkeyvalinstr(szConnStrIn, cbConnStrIn, | |
801 | "DRIVER", drvbuf, sizeof(drvbuf)); | |
802 | ||
803 | dsn = _iodbcdm_getkeyvalinstr(szConnStrIn, cbConnStrIn, | |
804 | "DSN", dsnbuf, sizeof(dsnbuf)); | |
805 | ||
806 | switch( fDriverCompletion ) | |
807 | { | |
808 | case SQL_DRIVER_NOPROMPT: | |
809 | break; | |
810 | ||
811 | case SQL_DRIVER_COMPLETE: | |
812 | case SQL_DRIVER_COMPLETE_REQUIRED: | |
813 | if( dsn != NULL ) | |
814 | { | |
815 | break; | |
816 | } | |
817 | /* fall to next case */ | |
818 | case SQL_DRIVER_PROMPT: | |
819 | /* Get data source dialog box function from | |
820 | * current executable */ | |
821 | hdll = _iodbcdm_dllopen((char FAR*)NULL); | |
822 | dialproc = _iodbcdm_dllproc( hdll, | |
823 | "_iodbcdm_drvconn_dialbox"); | |
824 | ||
825 | if( dialproc == SQL_NULL_HPROC ) | |
826 | { | |
827 | sqlstat = en_IM008; | |
828 | break; | |
829 | } | |
830 | ||
831 | retcode = dialproc( | |
832 | hwnd, /* window or display handle */ | |
833 | dsnbuf, /* input/output dsn buf */ | |
834 | sizeof(dsnbuf), /* buf size */ | |
835 | &sqlstat); /* error code */ | |
836 | ||
837 | if( retcode != SQL_SUCCESS ) | |
838 | { | |
839 | break; | |
840 | } | |
841 | ||
842 | if( cbConnStrIn == SQL_NTS ) | |
843 | { | |
844 | cbConnStrIn = STRLEN(szConnStrIn ); | |
845 | } | |
846 | ||
847 | dsn = dsnbuf; | |
848 | ||
849 | if( dsn[0] == '\0' ) | |
850 | { | |
851 | dsn = "default"; | |
852 | } | |
853 | ||
854 | if( cbConnStrIn > sizeof(cnstr2drv) | |
855 | - STRLEN(dsn) - STRLEN("DSN=;") -1 ) | |
856 | { | |
857 | sqlstat = en_S1001; /* a lazy way to avoid | |
858 | * using heap memory */ | |
859 | break; | |
860 | } | |
861 | ||
862 | sprintf(cnstr2drv, "DSN=%s;", dsn); | |
863 | cbConnStrIn += STRLEN(cnstr2drv); | |
864 | STRNCAT( cnstr2drv, szConnStrIn, cbConnStrIn ); | |
865 | szConnStrIn = cnstr2drv; | |
866 | break; | |
867 | ||
868 | default: | |
869 | sqlstat = en_S1110; | |
870 | break; | |
871 | } | |
872 | ||
873 | if( sqlstat != en_00000 ) | |
874 | { | |
875 | PUSHSQLERR( pdbc->herr, sqlstat ); | |
876 | ||
877 | return SQL_ERROR; | |
878 | } | |
879 | ||
880 | if( dsn == NULL || dsn[0] == '\0' ) | |
881 | { | |
882 | dsn = "default"; | |
883 | } | |
884 | else /* if you want tracing, you must use a DSN */ | |
885 | { | |
886 | setopterr |= _iodbcdm_settracing( hdbc, | |
887 | (char*)dsn, SQL_NTS ); | |
888 | } | |
889 | ||
890 | if( drv == NULL || drv[0] == '\0' ) | |
891 | { | |
892 | drv = _iodbcdm_getkeyvalbydsn( dsn, SQL_NTS, "Driver", | |
893 | drvbuf, sizeof(drvbuf)); | |
894 | } | |
895 | ||
896 | if( drv == NULL ) | |
897 | { | |
898 | PUSHSQLERR( pdbc->herr, en_IM002 ); | |
899 | ||
900 | return SQL_ERROR; | |
901 | } | |
902 | ||
903 | retcode = _iodbcdm_driverload( drv, hdbc ); | |
904 | ||
905 | switch( retcode ) | |
906 | { | |
907 | case SQL_SUCCESS: | |
908 | break; | |
909 | ||
910 | case SQL_SUCCESS_WITH_INFO: | |
911 | setopterr = SQL_ERROR; | |
912 | /* unsuccessed in calling driver's | |
913 | * SQLSetConnectOption() to set login | |
914 | * timeout. | |
915 | */ | |
916 | break; | |
917 | ||
918 | default: | |
919 | return retcode; | |
920 | } | |
921 | ||
922 | hproc = _iodbcdm_getproc( hdbc, en_DriverConnect ); | |
923 | ||
924 | if( hproc == SQL_NULL_HPROC ) | |
925 | { | |
926 | _iodbcdm_driverunload( hdbc ); | |
927 | ||
928 | PUSHSQLERR ( pdbc->herr, en_IM001 ); | |
929 | ||
930 | return SQL_ERROR; | |
931 | } | |
932 | /* giovanni */ | |
933 | /* | |
934 | ** OS/2 !!! | |
935 | ** | |
936 | ** get new szDSN from INI file, if existing | |
937 | */ | |
938 | strcpy( szNewDSN, "DSN=" ); | |
939 | if( NULL != _iodbcdm_getkeyvalbydsn( dsn, SQL_NTS, "DSN", | |
940 | (char FAR*) &szNewDSN[4], | |
941 | sizeof(szNewDSN) - 4 ) ) | |
942 | { | |
943 | char *psz; | |
944 | ||
945 | strcat( szNewDSN, ";UID=" ); | |
946 | psz = strtok( szNewDSN, "\0" ); | |
947 | ||
948 | ||
949 | ||
950 | ||
951 | if(NULL == _iodbcdm_getkeyvalinstr( szConnStrIn, cbConnStrIn, | |
952 | /* | |
953 | "UID", psz, sizeof(szNewDSN) )) | |
954 | */ | |
955 | "UID", (char FAR*) &szNewDSN[strlen(psz)], | |
956 | (sizeof(szNewDSN) - strlen(psz)) ) ) | |
957 | { | |
958 | _iodbcdm_getkeyvalbydsn( dsn, SQL_NTS, | |
959 | "UID", (char FAR*) &szNewDSN[strlen(psz)], | |
960 | (sizeof(szNewDSN) - strlen(psz)) ); | |
961 | } | |
962 | strcat( szNewDSN, ";PWD=" ); | |
963 | psz = strtok( szNewDSN, "\0" ); | |
964 | if(NULL == _iodbcdm_getkeyvalinstr( szConnStrIn, cbConnStrIn, | |
965 | /* | |
966 | "PWD", psz, sizeof(szNewDSN) )) | |
967 | */ | |
968 | "PWD", (char FAR*) &szNewDSN[strlen(psz)], | |
969 | (sizeof(szNewDSN) - strlen(psz)) ) ) | |
970 | { | |
1a6944fd | 971 | |
7e616b10 RR |
972 | _iodbcdm_getkeyvalbydsn( dsn, SQL_NTS, |
973 | "PWD", (char FAR*) &szNewDSN[strlen(psz)], | |
974 | (sizeof(szNewDSN) - strlen(psz)) ); | |
975 | } | |
976 | /* | |
977 | new from dirk | |
978 | { | |
979 | register char *psz; | |
980 | ||
981 | strcat( szNewDSN, ";UID=" ); | |
982 | psz = strtok( szNewDSN, "\0" ); | |
983 | _iodbcdm_getkeyvalinstr( szConnStrIn, cbConnStrIn, | |
984 | "UID", psz, sizeof(szNewDSN) ); | |
985 | strcat( szNewDSN, ";PWD=" ); | |
986 | psz = strtok( szNewDSN, "\0" ); | |
987 | _iodbcdm_getkeyvalinstr( szConnStrIn, cbConnStrIn, | |
988 | "PWD", psz, sizeof(szNewDSN) ); | |
989 | szConnStrIn = &szNewDSN[0]; | |
990 | cbConnStrIn = SQL_NTS; | |
991 | } | |
992 | ||
993 | ||
994 | */ | |
995 | /******** giovanni & monty ********/ | |
996 | /* Add a lot of optional keywords */ | |
997 | { | |
998 | static char *keywords[]= { "SERVER","PORT","SOCKET","OPTION","DB",0 }; | |
999 | char buff[80],**key,*end; | |
1000 | ||
1001 | psz= szNewDSN+strlen(szNewDSN); | |
1002 | end= szNewDSN+sizeof(szNewDSN); | |
1003 | for (key=keywords ; *key ; key++) | |
1004 | { | |
1005 | if (_iodbcdm_getkeyvalbydsn(dsn, SQL_NTS, | |
1006 | *key, (char FAR*) buff, | |
1007 | sizeof(buff)) && | |
1008 | strlen(*key)+strlen(buff)+2 < (int) (end - psz)) | |
1009 | { | |
1010 | *psz++=';'; | |
1011 | strcpy(psz,*key); psz+=strlen(*key); | |
1012 | *psz++='='; | |
1013 | strcpy(psz,buff); psz+=strlen(buff); | |
1014 | } | |
1015 | } | |
1016 | } | |
1017 | *psz=0; | |
1018 | /******** giovanni */ | |
1019 | szConnStrIn = szNewDSN; /*giovanni, era &szNewDSN */ | |
1020 | cbConnStrIn = SQL_NTS; | |
1021 | } | |
1022 | /* giovanni */ | |
1023 | CALL_DRIVER ( hdbc, retcode, hproc, en_DriverConnect, ( | |
1024 | pdbc->dhdbc, hwnd, | |
1025 | szConnStrIn, cbConnStrIn, | |
1026 | szConnStrOut, cbConnStrOutMax, | |
1027 | pcbConnStrOut, fDriverCompletion ) ) | |
1a6944fd | 1028 | #if 0 |
7e616b10 RR |
1029 | retcode = hproc(pdbc->dhdbc, hwnd, |
1030 | szConnStrIn, cbConnStrIn, | |
1031 | szConnStrOut, cbConnStrOutMax, | |
1032 | pcbConnStrOut, fDriverCompletion ); | |
1a6944fd RR |
1033 | #endif |
1034 | ||
7e616b10 RR |
1035 | if( retcode != SQL_SUCCESS |
1036 | && retcode != SQL_SUCCESS_WITH_INFO ) | |
1037 | { | |
1038 | /* don't unload driver here for retrive | |
1039 | * error message from driver */ | |
1040 | /******** | |
1041 | _iodbcdm_driverunload( hdbc ); | |
1042 | *********/ | |
1a6944fd | 1043 | |
7e616b10 RR |
1044 | return retcode; |
1045 | } | |
1a6944fd | 1046 | |
7e616b10 RR |
1047 | /* state transition */ |
1048 | pdbc->state = en_dbc_connected; | |
1a6944fd | 1049 | |
7e616b10 RR |
1050 | /* do delaid option setting */ |
1051 | setopterr |= _iodbcdm_dbcdelayset( hdbc ); | |
1a6944fd | 1052 | |
7e616b10 RR |
1053 | if( setopterr != SQL_SUCCESS ) |
1054 | { | |
1055 | return SQL_SUCCESS_WITH_INFO; | |
1056 | } | |
1a6944fd | 1057 | |
7e616b10 | 1058 | return retcode; |
1a6944fd RR |
1059 | } |
1060 | ||
7e616b10 RR |
1061 | RETCODE SQL_API SQLBrowseConnect ( |
1062 | HDBC hdbc, | |
1063 | HWND hwnd, | |
1064 | UCHAR FAR* szConnStrIn, | |
1065 | SWORD cbConnStrIn, | |
1066 | UCHAR FAR* szConnStrOut, | |
1067 | SWORD cbConnStrOutMax, | |
1068 | SWORD FAR* pcbConnStrOut ) | |
1a6944fd | 1069 | { |
7e616b10 RR |
1070 | DBC_t FAR* pdbc = (DBC_t FAR*)hdbc; |
1071 | HDLL hdll; | |
1072 | char FAR* drv; | |
1073 | char drvbuf[1024]; | |
1074 | char FAR* dsn; | |
1075 | char dsnbuf[SQL_MAX_DSN_LENGTH + 1]; | |
1076 | UCHAR cnstr2drv[1024]; | |
1077 | ||
1078 | HPROC hproc, dialproc; | |
1079 | ||
1080 | int sqlstat = en_00000; | |
1081 | RETCODE retcode = SQL_SUCCESS; | |
1082 | RETCODE setopterr = SQL_SUCCESS; | |
1083 | ||
1084 | if( hdbc == SQL_NULL_HDBC ) | |
1085 | { | |
1086 | return SQL_INVALID_HANDLE; | |
1087 | } | |
1088 | ||
1089 | /* check arguments */ | |
1090 | if( ( cbConnStrIn < 0 && cbConnStrIn != SQL_NTS ) | |
1091 | || cbConnStrOutMax < 0 ) | |
1092 | { | |
1093 | PUSHSQLERR (pdbc->herr, en_S1090 ); | |
1094 | ||
1095 | return SQL_ERROR; | |
1096 | } | |
1097 | ||
1098 | if( pdbc->state == en_dbc_allocated ) | |
1099 | { | |
1100 | drv = _iodbcdm_getkeyvalinstr(szConnStrIn, cbConnStrIn, | |
1101 | "DRIVER", drvbuf, sizeof(drvbuf)); | |
1102 | ||
1103 | dsn = _iodbcdm_getkeyvalinstr(szConnStrIn, cbConnStrIn, | |
1104 | "DSN", dsnbuf, sizeof(dsnbuf)); | |
1105 | ||
1106 | if( dsn == NULL || dsn[0] == '\0' ) | |
1107 | { | |
1108 | dsn = "default"; | |
1109 | } | |
1110 | else /* if you want tracing, you must use a DSN */ | |
1111 | { | |
1112 | setopterr |= _iodbcdm_settracing( hdbc, | |
1113 | (char*)dsn, SQL_NTS ); | |
1114 | } | |
1115 | ||
1116 | if( drv == NULL || drv[0] == '\0' ) | |
1117 | { | |
1118 | drv = _iodbcdm_getkeyvalbydsn( dsn, SQL_NTS, "Driver", | |
1119 | drvbuf, sizeof(drvbuf)); | |
1120 | } | |
1121 | ||
1122 | if( drv == NULL ) | |
1123 | { | |
1124 | PUSHSQLERR( pdbc->herr, en_IM002 ); | |
1125 | ||
1126 | return SQL_ERROR; | |
1127 | } | |
1128 | ||
1129 | retcode = _iodbcdm_driverload( drv, hdbc ); | |
1130 | ||
1131 | switch( retcode ) | |
1132 | { | |
1133 | case SQL_SUCCESS: | |
1134 | break; | |
1135 | ||
1136 | case SQL_SUCCESS_WITH_INFO: | |
1137 | setopterr = SQL_ERROR; | |
1138 | /* unsuccessed in calling driver's | |
1139 | * SQLSetConnectOption() to set login | |
1140 | * timeout. | |
1141 | */ | |
1142 | break; | |
1143 | ||
1144 | default: | |
1145 | return retcode; | |
1146 | } | |
1147 | } | |
1148 | else if( pdbc->state != en_dbc_needdata ) | |
1149 | { | |
1150 | PUSHSQLERR ( pdbc->herr, en_08002 ); | |
1151 | ||
1152 | return SQL_ERROR; | |
1153 | } | |
1154 | ||
1155 | hproc = _iodbcdm_getproc( hdbc, en_BrowseConnect); | |
1156 | ||
1157 | if( hproc == SQL_NULL_HPROC ) | |
1158 | { | |
1159 | _iodbcdm_driverunload( hdbc ); | |
1160 | ||
1161 | pdbc->state = en_dbc_allocated; | |
1162 | ||
1163 | PUSHSQLERR( pdbc->herr, en_IM001 ); | |
1164 | ||
1165 | return SQL_ERROR; | |
1166 | } | |
1167 | ||
1168 | CALL_DRIVER ( hdbc, retcode, hproc, en_BrowseConnect, ( | |
1169 | pdbc->dhdbc, hwnd, | |
1170 | szConnStrIn, cbConnStrIn, | |
1171 | szConnStrOut, cbConnStrOutMax, | |
1172 | pcbConnStrOut ) ) | |
1a6944fd | 1173 | |
7e616b10 RR |
1174 | #if 0 |
1175 | retcode = hproc(pdbc->dhdbc, hwnd, | |
1176 | szConnStrIn, cbConnStrIn, | |
1177 | szConnStrOut, cbConnStrOutMax, | |
1178 | pcbConnStrOut ); | |
1a6944fd RR |
1179 | #endif |
1180 | ||
7e616b10 RR |
1181 | switch( retcode ) |
1182 | { | |
1183 | case SQL_SUCCESS: | |
1184 | case SQL_SUCCESS_WITH_INFO: | |
1185 | pdbc->state = en_dbc_connected; | |
1186 | setopterr |= _iodbcdm_dbcdelayset( hdbc ); | |
1187 | if( setopterr != SQL_SUCCESS ) | |
1188 | { | |
1189 | retcode = SQL_SUCCESS_WITH_INFO; | |
1190 | } | |
1191 | break; | |
1192 | ||
1193 | case SQL_NEED_DATA: | |
1194 | pdbc->state = en_dbc_needdata; | |
1195 | break; | |
1196 | ||
1197 | case SQL_ERROR: | |
1198 | pdbc->state = en_dbc_allocated; | |
1199 | /* but the driver will not unloaded | |
1200 | * to allow application retrive err | |
1201 | * message from driver | |
1202 | */ | |
1203 | break; | |
1204 | ||
1205 | default: | |
1206 | break; | |
1207 | } | |
1208 | ||
1209 | return retcode; | |
1a6944fd RR |
1210 | } |
1211 | ||
7e616b10 | 1212 | RETCODE SQL_API SQLDisconnect ( HDBC hdbc ) |
1a6944fd | 1213 | { |
7e616b10 RR |
1214 | DBC_t FAR* pdbc = (DBC_t*)hdbc; |
1215 | STMT_t FAR* pstmt; | |
1216 | RETCODE retcode; | |
1217 | HPROC hproc; | |
1218 | ||
1219 | int sqlstat = en_00000; | |
1220 | ||
1221 | if( hdbc == SQL_NULL_HDBC ) | |
1222 | { | |
1223 | return SQL_INVALID_HANDLE; | |
1224 | } | |
1225 | ||
1226 | /* check hdbc state */ | |
1227 | if ( pdbc->state == en_dbc_allocated ) | |
1228 | { | |
1229 | sqlstat = en_08003; | |
1230 | } | |
1231 | ||
1232 | /* check stmt(s) state */ | |
1233 | for( pstmt = (STMT_t FAR*)pdbc->hstmt; | |
1234 | pstmt != NULL && sqlstat == en_00000; | |
1235 | pstmt = (STMT_t FAR*)pstmt->next ) | |
1236 | { | |
1237 | if( pstmt->state >= en_stmt_needdata | |
1238 | || pstmt->asyn_on != en_NullProc ) | |
1239 | /* In this case one need to call | |
1240 | * SQLCancel() first */ | |
1241 | { | |
1242 | sqlstat = en_S1010; | |
1243 | } | |
1244 | } | |
1245 | ||
1246 | if( sqlstat == en_00000 ) | |
1247 | { | |
1248 | hproc = _iodbcdm_getproc( hdbc, en_Disconnect ); | |
1249 | ||
1250 | if( hproc == SQL_NULL_HPROC ) | |
1251 | { | |
1252 | sqlstat = en_IM001; | |
1253 | } | |
1254 | } | |
1255 | ||
1256 | if( sqlstat != en_00000 ) | |
1257 | { | |
1258 | PUSHSQLERR ( pdbc->herr, sqlstat ); | |
1259 | ||
1260 | return SQL_ERROR; | |
1261 | } | |
1262 | ||
1263 | CALL_DRIVER ( hdbc, retcode, hproc, en_Disconnect, ( | |
1264 | pdbc->dhdbc ) ) | |
1a6944fd RR |
1265 | |
1266 | #if 0 | |
7e616b10 | 1267 | retcode = hproc( pdbc->dhdbc ); |
1a6944fd RR |
1268 | #endif |
1269 | ||
7e616b10 RR |
1270 | if( retcode == SQL_SUCCESS |
1271 | || retcode == SQL_SUCCESS_WITH_INFO ) | |
1272 | { | |
1273 | /* diff from MS specs. We disallow | |
1274 | * driver SQLDisconnect() return | |
1275 | * SQL_SUCCESS_WITH_INFO and post | |
1276 | * error message. | |
1277 | */ | |
1278 | retcode = SQL_SUCCESS; | |
1279 | } | |
1280 | else | |
1281 | { | |
1282 | return retcode; | |
1283 | } | |
1284 | ||
1285 | /* free all statement handle(s) on this connection */ | |
1286 | for(;pdbc->hstmt;) | |
1287 | { | |
1288 | _iodbcdm_dropstmt( pdbc->hstmt ); | |
1289 | } | |
1a6944fd RR |
1290 | |
1291 | #if 0 | |
7e616b10 | 1292 | retcode = _iodbcdm_driverunload( hdbc ); |
1a6944fd RR |
1293 | #endif |
1294 | ||
7e616b10 RR |
1295 | /* state transition */ |
1296 | if( retcode == SQL_SUCCESS ) | |
1297 | { | |
1298 | pdbc->state = en_dbc_allocated; | |
1299 | } | |
1a6944fd | 1300 | |
7e616b10 | 1301 | return retcode; |
1a6944fd RR |
1302 | } |
1303 | ||
7e616b10 RR |
1304 | RETCODE SQL_API SQLNativeSql( |
1305 | HDBC hdbc, | |
1306 | UCHAR FAR* szSqlStrIn, | |
1307 | SDWORD cbSqlStrIn, | |
1308 | UCHAR FAR* szSqlStr, | |
1309 | SDWORD cbSqlStrMax, | |
1310 | SDWORD FAR* pcbSqlStr ) | |
1a6944fd | 1311 | { |
7e616b10 RR |
1312 | DBC_t FAR* pdbc = (DBC_t FAR*)hdbc; |
1313 | HPROC hproc; | |
1314 | int sqlstat = en_00000; | |
1315 | RETCODE retcode; | |
1316 | ||
1317 | if( hdbc == SQL_NULL_HDBC ) | |
1318 | { | |
1319 | return SQL_INVALID_HANDLE; | |
1320 | } | |
1321 | ||
1322 | /* check argument */ | |
1323 | if( szSqlStrIn == NULL ) | |
1324 | { | |
1325 | sqlstat = en_S1009; | |
1326 | } | |
1327 | else if( cbSqlStrIn < 0 | |
1328 | && cbSqlStrIn != SQL_NTS ) | |
1329 | { | |
1330 | sqlstat = en_S1090; | |
1331 | } | |
1332 | ||
1333 | if( sqlstat != en_00000 ) | |
1334 | { | |
1335 | PUSHSQLERR ( pdbc->herr, sqlstat ); | |
1336 | ||
1337 | return SQL_ERROR; | |
1338 | } | |
1339 | ||
1340 | /* check state */ | |
1341 | if( pdbc->state <= en_dbc_needdata ) | |
1342 | { | |
1343 | PUSHSQLERR ( pdbc->herr, en_08003 ); | |
1344 | ||
1345 | return SQL_ERROR; | |
1346 | } | |
1347 | ||
1348 | /* call driver */ | |
1349 | hproc = _iodbcdm_getproc( hdbc, en_NativeSql ); | |
1350 | ||
1351 | if( hproc == SQL_NULL_HPROC ) | |
1352 | { | |
1353 | PUSHSQLERR ( pdbc->herr, en_IM001 ); | |
1354 | ||
1355 | return SQL_ERROR; | |
1356 | } | |
1357 | ||
1358 | CALL_DRIVER ( hdbc, retcode, hproc, en_NativeSql, ( | |
1359 | pdbc->dhdbc, | |
1360 | szSqlStrIn, | |
1361 | cbSqlStrIn, | |
1362 | szSqlStr, | |
1363 | cbSqlStrMax, | |
1364 | pcbSqlStr ) ) | |
1a6944fd RR |
1365 | |
1366 | #if 0 | |
7e616b10 RR |
1367 | retcode = hproc(pdbc->dhdbc, |
1368 | szSqlStrIn, | |
1369 | cbSqlStrIn, | |
1370 | szSqlStr, | |
1371 | cbSqlStrMax, | |
1372 | pcbSqlStr ); | |
1a6944fd RR |
1373 | #endif |
1374 | ||
7e616b10 | 1375 | return retcode; |
1a6944fd | 1376 | } |