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