1 /** Connect(load) driver
3 Copyright (C) 1995 by Ke Jin <kejin@empress.com>
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.
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.
16 #include <../iodbc/iodbc.h>
18 #include <../iodbc/isql.h>
19 #include <../iodbc/isqlext.h>
21 #include <../iodbc/dlproc.h>
23 #include <../iodbc/herr.h>
24 #include <../iodbc/henv.h>
25 #include <../iodbc/hdbc.h>
26 #include <../iodbc/hstmt.h>
28 #include <../iodbc/itrace.h>
32 extern char* _iodbcdm_getkeyvalbydsn();
33 extern char* _iodbcdm_getkeyvalinstr();
34 extern RETCODE
_iodbcdm_driverunload();
37 * Following id string is a copyright mark. Removing(i.e. use
38 * souce code of this package without it or make it not appear
39 * in the final object file) or modifing it without permission
40 * from original author(kejin@empress.com) are copyright
44 = "@(#)iODBC driver manager " "2.12" ", Copyright(c) 1995 by Ke Jin";
46 static RETCODE
_iodbcdm_driverload(
49 /* - Load driver share library( or increase its reference count
50 * if it has already been loaded by another active connection)
51 * - Call driver's SQLAllocEnv() (for the first reference only)
52 * - Call driver's SQLAllocConnect()
53 * - Call driver's SQLSetConnectOption() (set login time out)
54 * - Increase the bookkeeping reference count
57 DBC_t FAR
* pdbc
= (DBC_t FAR
*)hdbc
;
59 ENV_t FAR
* penv
= NULL
;
62 RETCODE retcode
= SQL_SUCCESS
;
63 int sqlstat
= en_00000
;
65 if( path
== NULL
|| path
[0] == '\0' )
67 PUSHSQLERR ( pdbc
->herr
, en_IM002
);
72 if( hdbc
== SQL_NULL_HDBC
73 || pdbc
->genv
== SQL_NULL_HENV
)
75 return SQL_INVALID_HANDLE
;
78 genv
= (GENV_t FAR
*)pdbc
->genv
;
80 hdll
= _iodbcdm_dllopen( (char FAR
*) path
);
81 /* This will either load the
82 * driver dll or increase its
85 if( hdll
== SQL_NULL_HDLL
)
87 PUSHSYSERR ( pdbc
->herr
, _iodbcdm_dllerror() );
88 PUSHSQLERR ( pdbc
->herr
, en_IM003
);
92 penv
= (ENV_t FAR
*)(pdbc
->henv
);
96 if( penv
->hdll
!= hdll
)
98 _iodbcdm_driverunload(hdbc
);
102 _iodbcdm_dllclose( hdll
);
103 /* this will not unload the driver
104 * but only decrease its internal
112 /* find out whether this dll has already
113 * been loaded on another connection */
114 for( penv
= (ENV_t FAR
*)genv
->henv
;
116 penv
= (ENV_t FAR
*)penv
->next
)
118 if( penv
->hdll
== hdll
)
120 _iodbcdm_dllclose( hdll
);
121 /* this will not unload the driver
122 * but only decrease its internal
130 /* no connection attaching with this dll */
134 /* create a new dll env instance */
135 penv
= (ENV_t FAR
*)MEM_ALLOC ( sizeof(ENV_t
) );
139 _iodbcdm_dllclose(hdll
);
141 PUSHSQLERR ( pdbc
->herr
, en_S1001
);
146 for( i
= 0; i
< SQL_EXT_API_LAST
+ 1; i
++)
148 (penv
->dllproc_tab
)[i
] = SQL_NULL_HPROC
;
154 /* call driver's SQLAllocHandle() or SQLAllocEnv() */
155 #if (ODBCVER >= 0x0300)
156 hproc
= _iodbcdm_getproc( hdbc
, en_AllocHandle
);
160 CALL_DRIVER ( hdbc
, retcode
, hproc
, en_AllocHandle
,
161 ( SQL_HANDLE_ENV
, SQL_NULL_HANDLE
, &(penv
->dhenv
) )
163 else /* try driver's SQLAllocEnv() */
166 hproc
= _iodbcdm_getproc( hdbc
, en_AllocEnv
);
168 if( hproc
== SQL_NULL_HPROC
)
174 CALL_DRIVER ( hdbc
, retcode
, hproc
,
175 en_AllocEnv
, (&(penv
->dhenv
)) )
179 if( retcode
== SQL_ERROR
)
184 if( sqlstat
!= en_00000
)
186 _iodbcdm_dllclose ( hdll
);
188 PUSHSQLERR ( pdbc
->herr
, en_IM004
);
193 /* insert into dll env list */
194 penv
->next
= (ENV_t FAR
*)genv
->henv
;
197 /* initiate this new env entry */
198 penv
->refcount
= 0; /* we will increase it after
199 * driver's SQLAllocConnect()
206 if( pdbc
->dhdbc
== SQL_NULL_HDBC
)
208 #if (ODBCVER >= 0x0300)
209 hproc
= _iodbcdm_getproc( hdbc
, en_AllocHandle
);
213 CALL_DRIVER( hdbc
, retcode
, hproc
, en_AllocHandle
,
214 (SQL_HANDLE_DBC
, penv
->dhenv
, &(pdbc
->dhdbc
)) )
219 hproc
= _iodbcdm_getproc( hdbc
, en_AllocConnect
);
221 if( hproc
== SQL_NULL_HPROC
)
227 CALL_DRIVER ( hdbc
, retcode
, hproc
,
228 en_AllocConnect
, (penv
->dhenv
, &(pdbc
->dhdbc
)) )
232 if( retcode
== SQL_ERROR
)
237 if( sqlstat
!= en_00000
)
239 _iodbcdm_driverunload(hdbc
);
241 pdbc
->dhdbc
= SQL_NULL_HDBC
;
242 PUSHSQLERR ( pdbc
->herr
, en_IM005
);
249 penv
->refcount
++; /* bookkeeping reference count on this driver */
252 /* driver's login timeout option must been set before
253 * its SQLConnect() call */
254 if( pdbc
->login_timeout
!= 0UL )
256 hproc
= _iodbcdm_getproc( hdbc
, en_SetConnectOption
);
258 if( hproc
== SQL_NULL_HPROC
)
264 CALL_DRIVER ( hdbc
, retcode
, hproc
,
265 en_SetConnectOption
, (
268 pdbc
->login_timeout
) )
270 if( retcode
== SQL_ERROR
)
272 PUSHSQLERR ( pdbc
->herr
, en_IM006
);
274 return SQL_SUCCESS_WITH_INFO
;
282 RETCODE
_iodbcdm_driverunload( HDBC hdbc
)
283 /* - Call driver's SQLFreeConnect()
284 * - Call driver's SQLFreeEnv() ( for the last reference only)
285 * - Unload the share library( or decrease its reference
286 * count if it is not the last referenct )
287 * - decrease bookkeeping reference count
288 * - state transition to allocated
291 DBC_t FAR
* pdbc
= (DBC_t FAR
*)hdbc
;
296 RETCODE retcode
= SQL_SUCCESS
;
297 /* int sqlstat = en_00000; */
299 if( hdbc
== SQL_NULL_HDBC
)
301 return SQL_INVALID_HANDLE
;
304 /* no pointer check will be performed in this function */
305 penv
= (ENV_t FAR
*)pdbc
->henv
;
306 genv
= (GENV_t FAR
*)pdbc
->genv
;
309 || penv
->hdll
== SQL_NULL_HDLL
)
314 #if (ODBCVER >= 0x0300)
315 hproc
= _iodbcdm_getproc( hdbc
, en_FreeHandle
);
319 CALL_DRIVER ( hdbc
, retcode
, hproc
, en_FreeHandle
,
320 ( SQL_HANDLE_DBC
, pdbc
->dhdbc
) )
325 hproc
= _iodbcdm_getproc( hdbc
, en_FreeConnect
);
327 if( hproc
!= SQL_NULL_HPROC
)
329 CALL_DRIVER ( hdbc
, retcode
, hproc
,
330 en_FreeConnect
, ( pdbc
->dhdbc
) )
332 pdbc
->dhdbc
= SQL_NULL_HDBC
;
338 if( ! penv
->refcount
)
339 /* no other connections still attaching with this driver */
341 #if (ODBCVER >= 0x0300)
342 hproc
= _iodbcdm_getproc( hdbc
, en_FreeHandle
);
346 CALL_DRIVER ( hdbc
, retcode
, hproc
, en_FreeHandle
,
347 ( SQL_HANDLE_ENV
, penv
->dhenv
) )
352 hproc
= _iodbcdm_getproc( hdbc
, en_FreeEnv
);
354 if( hproc
!= SQL_NULL_HPROC
)
356 CALL_DRIVER ( hdbc
, retcode
, hproc
, en_FreeEnv
,
359 penv
->dhenv
= SQL_NULL_HENV
;
363 _iodbcdm_dllclose ( penv
->hdll
);
365 penv
->hdll
= SQL_NULL_HDLL
;
367 for( tpenv
= (ENV_t FAR
*)genv
->henv
;
369 tpenv
= (ENV_t FAR
*)penv
->next
)
373 genv
->henv
= penv
->next
;
377 if( tpenv
->next
== penv
)
379 tpenv
->next
= penv
->next
;
387 pdbc
->henv
= SQL_NULL_HENV
;
388 pdbc
->hstmt
= SQL_NULL_HSTMT
;
389 /* pdbc->herr = SQL_NULL_HERR;
390 -- delay to DM's SQLFreeConnect() */
391 pdbc
->dhdbc
= SQL_NULL_HDBC
;
392 pdbc
->state
= en_dbc_allocated
;
394 /* set connect options to default values */
396 pdbc->access_mode = SQL_MODE_DEFAULT;
397 pdbc->autocommit = SQL_AUTOCOMMIT_DEFAULT;
398 pdbc->login_timeout = 0UL;
400 pdbc
->odbc_cursors
= SQL_CUR_DEFAULT
;
401 pdbc
->packet_size
= 0UL;
402 pdbc
->quiet_mode
= (UDWORD
)NULL
;
403 pdbc
->txn_isolation
= SQL_TXN_READ_UNCOMMITTED
;
405 if( pdbc
->current_qualifier
!= NULL
)
407 MEM_FREE ( pdbc
->current_qualifier
);
408 pdbc
->current_qualifier
= NULL
;
414 static RETCODE
_iodbcdm_dbcdelayset( HDBC hdbc
)
416 DBC_t FAR
* pdbc
= (DBC_t FAR
*)hdbc
;
419 RETCODE retcode
= SQL_SUCCESS
;
424 hproc
= _iodbcdm_getproc( hdbc
, en_SetConnectOption
);
426 if( hproc
== SQL_NULL_HPROC
)
428 PUSHSQLERR ( pdbc
->herr
, en_IM006
);
430 return SQL_SUCCESS_WITH_INFO
;
433 if( pdbc
->access_mode
!= SQL_MODE_DEFAULT
)
435 CALL_DRIVER ( hdbc
, ret
, hproc
,
436 en_SetConnectOption
, (
443 if( pdbc
->autocommit
!= SQL_AUTOCOMMIT_DEFAULT
)
445 CALL_DRIVER ( hdbc
, ret
, hproc
,
446 en_SetConnectOption
, (
454 if( pdbc
->current_qualifier
!= NULL
)
456 CALL_DRIVER ( hdbc
, ret
, hproc
,
457 en_SetConnectOption
, (
459 SQL_CURRENT_QUALIFIER
,
460 pdbc
->current_qualifier
) )
465 if( pdbc
->packet_size
!= 0UL )
467 CALL_DRIVER ( hdbc
, ret
, hproc
,
468 en_SetConnectOption
, (
471 pdbc
->packet_size
) )
476 if( pdbc
->quiet_mode
!= (UDWORD
)NULL
)
478 CALL_DRIVER ( hdbc
, ret
, hproc
,
479 en_SetConnectOption
, (
487 if( pdbc
->txn_isolation
!= SQL_TXN_READ_UNCOMMITTED
)
489 CALL_DRIVER ( hdbc
, ret
, hproc
,
490 en_SetConnectOption
, (
493 pdbc
->txn_isolation
) )
496 /* check error code for driver's SQLSetConnectOption() call */
497 if( retcode
!= SQL_SUCCESS
498 && retcode
!= SQL_SUCCESS_WITH_INFO
)
500 PUSHSQLERR ( pdbc
->herr
, en_IM006
);
505 /* get cursor behavior on transaction commit or rollback */
506 hproc
= _iodbcdm_getproc( hdbc
, en_GetInfo
);
508 if( hproc
== SQL_NULL_HPROC
)
510 PUSHSQLERR ( pdbc
->herr
, en_01000
);
515 CALL_DRIVER ( hdbc
, ret
, hproc
,
518 SQL_CURSOR_COMMIT_BEHAVIOR
,
519 (PTR
)&(pdbc
->cb_commit
),
520 sizeof(pdbc
->cb_commit
),
525 CALL_DRIVER ( hdbc
, ret
, hproc
,
528 SQL_CURSOR_ROLLBACK_BEHAVIOR
,
529 (PTR
)&(pdbc
->cb_rollback
),
530 sizeof(pdbc
->cb_rollback
),
535 if( retcode
!= SQL_SUCCESS
536 && retcode
!= SQL_SUCCESS_WITH_INFO
)
544 static RETCODE
_iodbcdm_settracing( HDBC hdbc
, char* dsn
, int dsnlen
)
548 RETCODE setopterr
= SQL_SUCCESS
;
550 /* Get Driver's DLL path from specificed or default dsn section */
551 ptr
= _iodbcdm_getkeyvalbydsn( dsn
, dsnlen
, "TraceFile",
552 (char FAR
*)buf
, sizeof(buf
));
554 if( ptr
== NULL
|| ptr
[0] == '\0' )
556 ptr
= (char FAR
*)(SQL_OPT_TRACE_FILE_DEFAULT
);
559 setopterr
|= SQLSetConnectOption( hdbc
,
560 SQL_OPT_TRACEFILE
, (UDWORD
)(ptr
));
562 ptr
= _iodbcdm_getkeyvalbydsn( dsn
, dsnlen
, "Trace",
563 (char FAR
*)buf
, sizeof(buf
));
567 UDWORD opt
= (UDWORD
)(-1L);
572 || STREQ(ptr
, "1" ) )
574 opt
= SQL_OPT_TRACE_ON
;
577 if( STREQ(ptr
, "OFF")
580 || STREQ(ptr
, "0" ) )
582 opt
= SQL_OPT_TRACE_OFF
;
585 if( opt
!= (UDWORD
)(-1L) )
587 setopterr
|= SQLSetConnectOption( hdbc
,
595 RETCODE SQL_API
SQLConnect (
601 UCHAR FAR
* szAuthStr
,
604 DBC_t FAR
* pdbc
= (DBC_t FAR
*)hdbc
;
605 RETCODE retcode
= SQL_SUCCESS
;
606 RETCODE setopterr
= SQL_SUCCESS
;
607 char driver
[1024] = { '\0' }; /* MS SDK Guide
614 if( hdbc
== SQL_NULL_HDBC
)
616 return SQL_INVALID_HANDLE
;
619 /* check arguments */
620 if( ( cbDSN
< 0 && cbDSN
!= SQL_NTS
)
621 || ( cbUID
< 0 && cbUID
!= SQL_NTS
)
622 || ( cbAuthStr
< 0 && cbAuthStr
!= SQL_NTS
)
623 || ( cbDSN
> SQL_MAX_DSN_LENGTH
) )
625 PUSHSQLERR ( pdbc
->herr
, en_S1090
);
630 if( szDSN
== NULL
|| cbDSN
== 0 )
632 PUSHSQLERR ( pdbc
->herr
, en_IM002
);
638 if( pdbc
->state
!= en_dbc_allocated
)
640 PUSHSQLERR ( pdbc
->herr
, en_08002
);
645 setopterr
|= _iodbcdm_settracing( hdbc
,
646 (char*)szDSN
, cbDSN
);
648 ptr
= _iodbcdm_getkeyvalbydsn( szDSN
, cbDSN
, "Driver",
649 (char FAR
*)driver
, sizeof(driver
));
652 /* No specified or default dsn section or
653 * no driver specification in this dsn section */
655 PUSHSQLERR ( pdbc
->herr
, en_IM002
);
660 retcode
= _iodbcdm_driverload( driver
, hdbc
);
667 case SQL_SUCCESS_WITH_INFO
:
668 setopterr
= SQL_ERROR
;
669 /* unsuccessed in calling driver's
670 * SQLSetConnectOption() to set login
679 hproc
= _iodbcdm_getproc( hdbc
, en_Connect
);
681 if( hproc
== SQL_NULL_HPROC
)
683 _iodbcdm_driverunload( hdbc
);
685 PUSHSQLERR ( pdbc
->herr
, en_IM001
);
690 CALL_DRIVER ( hdbc
, retcode
, hproc
, en_Connect
, (
694 szAuthStr
, cbAuthStr
) )
697 retcode
= hproc(pdbc
->dhdbc
,
700 szAuthStr
, cbAuthStr
);
703 if( retcode
!= SQL_SUCCESS
704 && retcode
!= SQL_SUCCESS_WITH_INFO
)
706 /* not unload driver for retrive error
707 * messge from driver */
709 _iodbcdm_driverunload( hdbc );
715 /* state transition */
716 pdbc
->state
= en_dbc_connected
;
718 /* do delaid option setting */
719 setopterr
|= _iodbcdm_dbcdelayset( hdbc
);
721 if( setopterr
!= SQL_SUCCESS
)
723 return SQL_SUCCESS_WITH_INFO
;
729 RETCODE SQL_API
SQLDriverConnect (
732 UCHAR FAR
* szConnStrIn
,
734 UCHAR FAR
* szConnStrOut
,
735 SWORD cbConnStrOutMax
,
736 SWORD FAR
* pcbConnStrOut
,
737 UWORD fDriverCompletion
)
739 DBC_t FAR
* pdbc
= (DBC_t FAR
*)hdbc
;
744 char dsnbuf
[SQL_MAX_DSN_LENGTH
+ 1];
745 UCHAR cnstr2drv
[1024];
747 HPROC hproc
, dialproc
;
749 int sqlstat
= en_00000
;
750 RETCODE retcode
= SQL_SUCCESS
;
751 RETCODE setopterr
= SQL_SUCCESS
;
753 if( hdbc
== SQL_NULL_HDBC
)
755 return SQL_INVALID_HANDLE
;
758 /* check arguments */
759 if( ( cbConnStrIn
< 0 && cbConnStrIn
!= SQL_NTS
)
760 || cbConnStrOutMax
< 0 )
762 PUSHSQLERR (pdbc
->herr
, en_S1090
);
768 if( pdbc
->state
!= en_dbc_allocated
)
770 PUSHSQLERR (pdbc
->herr
, en_08002
);
775 drv
= _iodbcdm_getkeyvalinstr(szConnStrIn
, cbConnStrIn
,
776 "DRIVER", drvbuf
, sizeof(drvbuf
));
778 dsn
= _iodbcdm_getkeyvalinstr(szConnStrIn
, cbConnStrIn
,
779 "DSN", dsnbuf
, sizeof(dsnbuf
));
781 switch( fDriverCompletion
)
783 case SQL_DRIVER_NOPROMPT
:
786 case SQL_DRIVER_COMPLETE
:
787 case SQL_DRIVER_COMPLETE_REQUIRED
:
792 /* fall to next case */
793 case SQL_DRIVER_PROMPT
:
794 /* Get data source dialog box function from
795 * current executable */
796 hdll
= _iodbcdm_dllopen((char FAR
*)NULL
);
797 dialproc
= _iodbcdm_dllproc( hdll
,
798 "_iodbcdm_drvconn_dialbox");
800 if( dialproc
== SQL_NULL_HPROC
)
807 hwnd
, /* window or display handle */
808 dsnbuf
, /* input/output dsn buf */
809 sizeof(dsnbuf
), /* buf size */
810 &sqlstat
); /* error code */
812 if( retcode
!= SQL_SUCCESS
)
817 if( cbConnStrIn
== SQL_NTS
)
819 cbConnStrIn
= STRLEN(szConnStrIn
);
829 if( cbConnStrIn
> sizeof(cnstr2drv
)
830 - STRLEN(dsn
) - STRLEN("DSN=;") -1 )
832 sqlstat
= en_S1001
; /* a lazy way to avoid
833 * using heap memory */
837 sprintf( (char FAR
*)cnstr2drv
, "DSN=%s;", dsn
);
838 cbConnStrIn
+= STRLEN(cnstr2drv
);
839 STRNCAT( cnstr2drv
, szConnStrIn
, cbConnStrIn
);
840 szConnStrIn
= cnstr2drv
;
848 if( sqlstat
!= en_00000
)
850 PUSHSQLERR( pdbc
->herr
, sqlstat
);
855 if( dsn
== NULL
|| dsn
[0] == '\0' )
859 else /* if you want tracing, you must use a DSN */
861 setopterr
|= _iodbcdm_settracing( hdbc
,
862 (char*)dsn
, SQL_NTS
);
865 if( drv
== NULL
|| drv
[0] == '\0' )
867 drv
= _iodbcdm_getkeyvalbydsn( dsn
, SQL_NTS
, "Driver",
868 drvbuf
, sizeof(drvbuf
));
873 PUSHSQLERR( pdbc
->herr
, en_IM002
);
878 retcode
= _iodbcdm_driverload( drv
, hdbc
);
885 case SQL_SUCCESS_WITH_INFO
:
886 setopterr
= SQL_ERROR
;
887 /* unsuccessed in calling driver's
888 * SQLSetConnectOption() to set login
897 hproc
= _iodbcdm_getproc( hdbc
, en_DriverConnect
);
899 if( hproc
== SQL_NULL_HPROC
)
901 _iodbcdm_driverunload( hdbc
);
903 PUSHSQLERR ( pdbc
->herr
, en_IM001
);
908 CALL_DRIVER ( hdbc
, retcode
, hproc
, en_DriverConnect
, (
910 szConnStrIn
, cbConnStrIn
,
911 szConnStrOut
, cbConnStrOutMax
,
912 pcbConnStrOut
, fDriverCompletion
) )
915 retcode
= hproc(pdbc
->dhdbc
, hwnd
,
916 szConnStrIn
, cbConnStrIn
,
917 szConnStrOut
, cbConnStrOutMax
,
918 pcbConnStrOut
, fDriverCompletion
);
921 if( retcode
!= SQL_SUCCESS
922 && retcode
!= SQL_SUCCESS_WITH_INFO
)
924 /* don't unload driver here for retrive
925 * error message from driver */
927 _iodbcdm_driverunload( hdbc );
933 /* state transition */
934 pdbc
->state
= en_dbc_connected
;
936 /* do delaid option setting */
937 setopterr
|= _iodbcdm_dbcdelayset( hdbc
);
939 if( setopterr
!= SQL_SUCCESS
)
941 return SQL_SUCCESS_WITH_INFO
;
947 RETCODE SQL_API
SQLBrowseConnect (
950 UCHAR FAR
* szConnStrIn
,
952 UCHAR FAR
* szConnStrOut
,
953 SWORD cbConnStrOutMax
,
954 SWORD FAR
* pcbConnStrOut
)
956 DBC_t FAR
* pdbc
= (DBC_t FAR
*)hdbc
;
961 char dsnbuf
[SQL_MAX_DSN_LENGTH
+ 1];
962 /* UCHAR cnstr2drv[1024]; */
964 HPROC hproc
/*, dialproc*/ ;
966 /* int sqlstat = en_00000; */
967 RETCODE retcode
= SQL_SUCCESS
;
968 RETCODE setopterr
= SQL_SUCCESS
;
970 if( hdbc
== SQL_NULL_HDBC
)
972 return SQL_INVALID_HANDLE
;
975 /* check arguments */
976 if( ( cbConnStrIn
< 0 && cbConnStrIn
!= SQL_NTS
)
977 || cbConnStrOutMax
< 0 )
979 PUSHSQLERR (pdbc
->herr
, en_S1090
);
984 if( pdbc
->state
== en_dbc_allocated
)
986 drv
= _iodbcdm_getkeyvalinstr(szConnStrIn
, cbConnStrIn
,
987 "DRIVER", drvbuf
, sizeof(drvbuf
));
989 dsn
= _iodbcdm_getkeyvalinstr(szConnStrIn
, cbConnStrIn
,
990 "DSN", dsnbuf
, sizeof(dsnbuf
));
992 if( dsn
== NULL
|| dsn
[0] == '\0' )
996 else /* if you want tracing, you must use a DSN */
998 setopterr
|= _iodbcdm_settracing( hdbc
,
999 (char*)dsn
, SQL_NTS
);
1002 if( drv
== NULL
|| drv
[0] == '\0' )
1004 drv
= _iodbcdm_getkeyvalbydsn( dsn
, SQL_NTS
, "Driver",
1005 drvbuf
, sizeof(drvbuf
));
1010 PUSHSQLERR( pdbc
->herr
, en_IM002
);
1015 retcode
= _iodbcdm_driverload( drv
, hdbc
);
1022 case SQL_SUCCESS_WITH_INFO
:
1023 setopterr
= SQL_ERROR
;
1024 /* unsuccessed in calling driver's
1025 * SQLSetConnectOption() to set login
1034 else if( pdbc
->state
!= en_dbc_needdata
)
1036 PUSHSQLERR ( pdbc
->herr
, en_08002
);
1041 hproc
= _iodbcdm_getproc( hdbc
, en_BrowseConnect
);
1043 if( hproc
== SQL_NULL_HPROC
)
1045 _iodbcdm_driverunload( hdbc
);
1047 pdbc
->state
= en_dbc_allocated
;
1049 PUSHSQLERR( pdbc
->herr
, en_IM001
);
1054 CALL_DRIVER ( hdbc
, retcode
, hproc
, en_BrowseConnect
, (
1056 szConnStrIn
, cbConnStrIn
,
1057 szConnStrOut
, cbConnStrOutMax
,
1061 retcode
= hproc(pdbc
->dhdbc
, hwnd
,
1062 szConnStrIn
, cbConnStrIn
,
1063 szConnStrOut
, cbConnStrOutMax
,
1070 case SQL_SUCCESS_WITH_INFO
:
1071 pdbc
->state
= en_dbc_connected
;
1072 setopterr
|= _iodbcdm_dbcdelayset( hdbc
);
1073 if( setopterr
!= SQL_SUCCESS
)
1075 retcode
= SQL_SUCCESS_WITH_INFO
;
1080 pdbc
->state
= en_dbc_needdata
;
1084 pdbc
->state
= en_dbc_allocated
;
1085 /* but the driver will not unloaded
1086 * to allow application retrive err
1087 * message from driver
1098 RETCODE SQL_API
SQLDisconnect ( HDBC hdbc
)
1100 DBC_t FAR
* pdbc
= (DBC_t
*)hdbc
;
1105 int sqlstat
= en_00000
;
1107 if( hdbc
== SQL_NULL_HDBC
)
1109 return SQL_INVALID_HANDLE
;
1112 /* check hdbc state */
1113 if ( pdbc
->state
== en_dbc_allocated
)
1118 /* check stmt(s) state */
1119 for( pstmt
= (STMT_t FAR
*)pdbc
->hstmt
;
1120 pstmt
!= NULL
&& sqlstat
== en_00000
;
1121 pstmt
= (STMT_t FAR
*)pstmt
->next
)
1123 if( pstmt
->state
>= en_stmt_needdata
1124 || pstmt
->asyn_on
!= en_NullProc
)
1125 /* In this case one need to call
1126 * SQLCancel() first */
1132 if( sqlstat
== en_00000
)
1134 hproc
= _iodbcdm_getproc( hdbc
, en_Disconnect
);
1136 if( hproc
== SQL_NULL_HPROC
)
1142 if( sqlstat
!= en_00000
)
1144 PUSHSQLERR ( pdbc
->herr
, sqlstat
);
1149 CALL_DRIVER ( hdbc
, retcode
, hproc
, en_Disconnect
, (
1153 retcode
= hproc( pdbc
->dhdbc
);
1156 if( retcode
== SQL_SUCCESS
1157 || retcode
== SQL_SUCCESS_WITH_INFO
)
1159 /* diff from MS specs. We disallow
1160 * driver SQLDisconnect() return
1161 * SQL_SUCCESS_WITH_INFO and post
1164 retcode
= SQL_SUCCESS
;
1171 /* free all statement handle(s) on this connection */
1174 _iodbcdm_dropstmt( pdbc
->hstmt
);
1178 retcode
= _iodbcdm_driverunload( hdbc
);
1181 /* state transition */
1182 if( retcode
== SQL_SUCCESS
)
1184 pdbc
->state
= en_dbc_allocated
;
1190 RETCODE SQL_API
SQLNativeSql(
1192 UCHAR FAR
* szSqlStrIn
,
1194 UCHAR FAR
* szSqlStr
,
1196 SDWORD FAR
* pcbSqlStr
)
1198 DBC_t FAR
* pdbc
= (DBC_t FAR
*)hdbc
;
1200 int sqlstat
= en_00000
;
1203 if( hdbc
== SQL_NULL_HDBC
)
1205 return SQL_INVALID_HANDLE
;
1208 /* check argument */
1209 if( szSqlStrIn
== NULL
)
1213 else if( cbSqlStrIn
< 0
1214 && cbSqlStrIn
!= SQL_NTS
)
1219 if( sqlstat
!= en_00000
)
1221 PUSHSQLERR ( pdbc
->herr
, sqlstat
);
1227 if( pdbc
->state
<= en_dbc_needdata
)
1229 PUSHSQLERR ( pdbc
->herr
, en_08003
);
1235 hproc
= _iodbcdm_getproc( hdbc
, en_NativeSql
);
1237 if( hproc
== SQL_NULL_HPROC
)
1239 PUSHSQLERR ( pdbc
->herr
, en_IM001
);
1244 CALL_DRIVER ( hdbc
, retcode
, hproc
, en_NativeSql
, (
1253 retcode
= hproc(pdbc
->dhdbc
,