6 * Connect (load) driver
8 * The iODBC driver manager.
10 * Copyright (C) 1995 by Ke Jin <kejin@empress.com>
12 * This library is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU Library General Public
14 * License as published by the Free Software Foundation; either
15 * version 2 of the License, or (at your option) any later version.
17 * This library is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 * Library General Public License for more details.
22 * You should have received a copy of the GNU Library General Public
23 * License along with this library; if not, write to the Free
24 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
41 extern char* _iodbcdm_getkeyvalbydsn();
42 extern char* _iodbcdm_getkeyvalinstr();
43 extern RETCODE
_iodbcdm_driverunload();
46 * Following id string is a copyright mark. Removing(i.e. use
47 * souce code of this package without it or make it not appear
48 * in the final object file) or modifing it without permission
49 * from original author(kejin@empress.com) are copyright
53 = "@(#)iODBC driver manager 2.5, Copyright(c) 1995 by Ke Jin";
55 /* - Load driver share library( or increase its reference count
56 * if it has already been loaded by another active connection)
57 * - Call driver's SQLAllocEnv() (for the first reference only)
58 * - Call driver's SQLAllocConnect()
59 * - Call driver's SQLSetConnectOption() (set login time out)
60 * - Increase the bookkeeping reference count
67 DBC_t FAR
*pdbc
= (DBC_t FAR
*) hdbc
;
69 ENV_t FAR
*penv
= NULL
;
72 RETCODE retcode
= SQL_SUCCESS
;
73 int sqlstat
= en_00000
;
75 if (path
== NULL
|| path
[0] == '\0')
77 PUSHSQLERR (pdbc
->herr
, en_IM002
);
82 if (hdbc
== SQL_NULL_HDBC
|| pdbc
->genv
== SQL_NULL_HENV
)
84 return SQL_INVALID_HANDLE
;
87 genv
= (GENV_t FAR
*) pdbc
->genv
;
89 /* This will either load the driver dll or increase its reference count */
90 hdll
= _iodbcdm_dllopen ((char FAR
*) path
);
92 if (hdll
== SQL_NULL_HDLL
)
94 PUSHSYSERR (pdbc
->herr
, _iodbcdm_dllerror ());
95 PUSHSQLERR (pdbc
->herr
, en_IM003
);
99 penv
= (ENV_t FAR
*) (pdbc
->henv
);
103 if (penv
->hdll
!= hdll
)
105 _iodbcdm_driverunload (hdbc
);
110 * this will not unload the driver but only decrease its internal
113 _iodbcdm_dllclose (hdll
);
120 * find out whether this dll has already been loaded on another
123 for (penv
= (ENV_t FAR
*) genv
->henv
;
125 penv
= (ENV_t FAR
*) penv
->next
)
127 if (penv
->hdll
== hdll
)
130 * this will not unload the driver but only decrease its internal
133 _iodbcdm_dllclose (hdll
);
139 /* no connection attaching with this dll */
143 /* create a new dll env instance */
144 penv
= (ENV_t FAR
*) MEM_ALLOC (sizeof (ENV_t
));
148 _iodbcdm_dllclose (hdll
);
150 PUSHSQLERR (pdbc
->herr
, en_S1001
);
155 for (i
= 0; i
< SQL_EXT_API_LAST
+ 1; i
++)
157 (penv
->dllproc_tab
)[i
] = SQL_NULL_HPROC
;
163 /* call driver's SQLAllocHandle() or SQLAllocEnv() */
165 #if (ODBCVER >= 0x0300)
166 hproc
= _iodbcdm_getproc (hdbc
, en_AllocHandle
);
170 CALL_DRIVER (hdbc
, retcode
, hproc
, en_AllocHandle
,
171 (SQL_HANDLE_ENV
, SQL_NULL_HANDLE
, &(penv
->dhenv
)))
173 else /* try driver's SQLAllocEnv() */
176 hproc
= _iodbcdm_getproc (hdbc
, en_AllocEnv
);
178 if (hproc
== SQL_NULL_HPROC
)
184 CALL_DRIVER (hdbc
, retcode
, hproc
,
185 en_AllocEnv
, (&(penv
->dhenv
)))
189 if (retcode
== SQL_ERROR
)
194 if (sqlstat
!= en_00000
)
196 _iodbcdm_dllclose (hdll
);
198 PUSHSQLERR (pdbc
->herr
, en_IM004
);
203 /* insert into dll env list */
204 penv
->next
= (ENV_t FAR
*) genv
->henv
;
207 /* initiate this new env entry */
208 penv
->refcount
= 0; /* we will increase it after
209 * driver's SQLAllocConnect()
216 if (pdbc
->dhdbc
== SQL_NULL_HDBC
)
219 #if (ODBCVER >= 0x0300)
220 hproc
= _iodbcdm_getproc (hdbc
, en_AllocHandle
);
224 CALL_DRIVER (hdbc
, retcode
, hproc
, en_AllocHandle
,
225 (SQL_HANDLE_DBC
, penv
->dhenv
, &(pdbc
->dhdbc
)))
231 hproc
= _iodbcdm_getproc (hdbc
, en_AllocConnect
);
233 if (hproc
== SQL_NULL_HPROC
)
239 CALL_DRIVER (hdbc
, retcode
, hproc
,
240 en_AllocConnect
, (penv
->dhenv
, &(pdbc
->dhdbc
)))
244 if (retcode
== SQL_ERROR
)
249 if (sqlstat
!= en_00000
)
251 _iodbcdm_driverunload (hdbc
);
253 pdbc
->dhdbc
= SQL_NULL_HDBC
;
254 PUSHSQLERR (pdbc
->herr
, en_IM005
);
261 penv
->refcount
++; /* bookkeeping reference count on this driver */
264 /* driver's login timeout option must been set before
265 * its SQLConnect() call */
266 if (pdbc
->login_timeout
!= 0UL)
268 hproc
= _iodbcdm_getproc (hdbc
, en_SetConnectOption
);
270 if (hproc
== SQL_NULL_HPROC
)
276 CALL_DRIVER (hdbc
, retcode
, hproc
,
277 en_SetConnectOption
, (
280 pdbc
->login_timeout
))
282 if (retcode
== SQL_ERROR
)
284 PUSHSQLERR (pdbc
->herr
, en_IM006
);
286 return SQL_SUCCESS_WITH_INFO
;
295 /* - Call driver's SQLFreeConnect()
296 * - Call driver's SQLFreeEnv() ( for the last reference only)
297 * - Unload the share library( or decrease its reference
298 * count if it is not the last referenct )
299 * - decrease bookkeeping reference count
300 * - state transition to allocated
303 _iodbcdm_driverunload (HDBC hdbc
)
305 DBC_t FAR
*pdbc
= (DBC_t FAR
*) hdbc
;
310 RETCODE retcode
= SQL_SUCCESS
;
312 if (hdbc
== SQL_NULL_HDBC
)
314 return SQL_INVALID_HANDLE
;
317 /* no pointer check will be performed in this function */
318 penv
= (ENV_t FAR
*) pdbc
->henv
;
319 genv
= (GENV_t FAR
*) pdbc
->genv
;
321 if (penv
== NULL
|| penv
->hdll
== SQL_NULL_HDLL
)
326 #if (ODBCVER >= 0x0300)
327 hproc
= _iodbcdm_getproc (hdbc
, en_FreeHandle
);
331 CALL_DRIVER (hdbc
, retcode
, hproc
, en_FreeHandle
,
332 (SQL_HANDLE_DBC
, pdbc
->dhdbc
))
338 hproc
= _iodbcdm_getproc (hdbc
, en_FreeConnect
);
340 if (hproc
!= SQL_NULL_HPROC
)
342 CALL_DRIVER (hdbc
, retcode
, hproc
,
343 en_FreeConnect
, (pdbc
->dhdbc
))
345 pdbc
->dhdbc
= SQL_NULL_HDBC
;
352 /* no other connections still attaching with this driver */
355 #if (ODBCVER >= 0x0300)
356 hproc
= _iodbcdm_getproc (hdbc
, en_FreeHandle
);
360 CALL_DRIVER (hdbc
, retcode
, hproc
, en_FreeHandle
,
361 (SQL_HANDLE_ENV
, penv
->dhenv
))
367 hproc
= _iodbcdm_getproc (hdbc
, en_FreeEnv
);
369 if (hproc
!= SQL_NULL_HPROC
)
371 CALL_DRIVER (hdbc
, retcode
, hproc
, en_FreeEnv
,
374 penv
->dhenv
= SQL_NULL_HENV
;
378 _iodbcdm_dllclose (penv
->hdll
);
380 penv
->hdll
= SQL_NULL_HDLL
;
382 for (tpenv
= (ENV_t FAR
*) genv
->henv
;
384 tpenv
= (ENV_t FAR
*) penv
->next
)
388 genv
->henv
= penv
->next
;
392 if (tpenv
->next
== penv
)
394 tpenv
->next
= penv
->next
;
402 pdbc
->henv
= SQL_NULL_HENV
;
403 pdbc
->hstmt
= SQL_NULL_HSTMT
;
404 /* pdbc->herr = SQL_NULL_HERR;
405 -- delay to DM's SQLFreeConnect() */
406 pdbc
->dhdbc
= SQL_NULL_HDBC
;
407 pdbc
->state
= en_dbc_allocated
;
409 /* set connect options to default values */
411 pdbc->access_mode = SQL_MODE_DEFAULT;
412 pdbc->autocommit = SQL_AUTOCOMMIT_DEFAULT;
413 pdbc->login_timeout = 0UL;
415 pdbc
->odbc_cursors
= SQL_CUR_DEFAULT
;
416 pdbc
->packet_size
= 0UL;
417 pdbc
->quiet_mode
= (UDWORD
) NULL
;
418 pdbc
->txn_isolation
= SQL_TXN_READ_UNCOMMITTED
;
420 if (pdbc
->current_qualifier
!= NULL
)
422 MEM_FREE (pdbc
->current_qualifier
);
423 pdbc
->current_qualifier
= NULL
;
431 _iodbcdm_dbcdelayset (HDBC hdbc
)
433 DBC_t FAR
*pdbc
= (DBC_t FAR
*) hdbc
;
436 RETCODE retcode
= SQL_SUCCESS
;
441 hproc
= _iodbcdm_getproc (hdbc
, en_SetConnectOption
);
443 if (hproc
== SQL_NULL_HPROC
)
445 PUSHSQLERR (pdbc
->herr
, en_IM006
);
447 return SQL_SUCCESS_WITH_INFO
;
450 if (pdbc
->access_mode
!= SQL_MODE_DEFAULT
)
452 CALL_DRIVER (hdbc
, ret
, hproc
,
453 en_SetConnectOption
, (
460 if (pdbc
->autocommit
!= SQL_AUTOCOMMIT_DEFAULT
)
462 CALL_DRIVER (hdbc
, ret
, hproc
,
463 en_SetConnectOption
, (
471 if (pdbc
->current_qualifier
!= NULL
)
473 CALL_DRIVER (hdbc
, ret
, hproc
,
474 en_SetConnectOption
, (
476 SQL_CURRENT_QUALIFIER
,
477 pdbc
->current_qualifier
))
482 if (pdbc
->packet_size
!= 0UL)
484 CALL_DRIVER (hdbc
, ret
, hproc
,
485 en_SetConnectOption
, (
493 if (pdbc
->quiet_mode
!= (UDWORD
) NULL
)
495 CALL_DRIVER (hdbc
, ret
, hproc
,
496 en_SetConnectOption
, (
504 if (pdbc
->txn_isolation
!= SQL_TXN_READ_UNCOMMITTED
)
506 CALL_DRIVER (hdbc
, ret
, hproc
,
507 en_SetConnectOption
, (
510 pdbc
->txn_isolation
))
513 /* check error code for driver's SQLSetConnectOption() call */
514 if (retcode
!= SQL_SUCCESS
&& retcode
!= SQL_SUCCESS_WITH_INFO
)
516 PUSHSQLERR (pdbc
->herr
, en_IM006
);
521 /* get cursor behavior on transaction commit or rollback */
522 hproc
= _iodbcdm_getproc (hdbc
, en_GetInfo
);
524 if (hproc
== SQL_NULL_HPROC
)
526 PUSHSQLERR (pdbc
->herr
, en_01000
);
531 CALL_DRIVER (hdbc
, ret
, hproc
,
534 SQL_CURSOR_COMMIT_BEHAVIOR
,
535 (PTR
) & (pdbc
->cb_commit
),
536 sizeof (pdbc
->cb_commit
),
541 CALL_DRIVER (hdbc
, ret
, hproc
,
544 SQL_CURSOR_ROLLBACK_BEHAVIOR
,
545 (PTR
) & (pdbc
->cb_rollback
),
546 sizeof (pdbc
->cb_rollback
),
551 if (retcode
!= SQL_SUCCESS
552 && retcode
!= SQL_SUCCESS_WITH_INFO
)
562 _iodbcdm_settracing (HDBC hdbc
, char *dsn
, int dsnlen
)
566 RETCODE setopterr
= SQL_SUCCESS
;
568 /* Get Driver's DLL path from specificed or default dsn section */
569 ptr
= _iodbcdm_getkeyvalbydsn (dsn
, dsnlen
, "TraceFile",
570 (char FAR
*) buf
, sizeof (buf
));
572 if (ptr
== NULL
|| ptr
[0] == '\0')
574 ptr
= (char FAR
*) (SQL_OPT_TRACE_FILE_DEFAULT
);
577 setopterr
|= SQLSetConnectOption (hdbc
, SQL_OPT_TRACEFILE
, (UDWORD
) (ptr
));
579 ptr
= _iodbcdm_getkeyvalbydsn (dsn
, dsnlen
, "Trace",
580 (char FAR
*) buf
, sizeof (buf
));
584 UDWORD opt
= (UDWORD
) (-1L);
586 if (STREQ (ptr
, "ON")
591 opt
= SQL_OPT_TRACE_ON
;
594 if (STREQ (ptr
, "OFF")
595 || STREQ (ptr
, "Off")
596 || STREQ (ptr
, "off")
599 opt
= SQL_OPT_TRACE_OFF
;
602 if (opt
!= (UDWORD
) (-1L))
604 setopterr
|= SQLSetConnectOption (hdbc
,
620 UCHAR FAR
* szAuthStr
,
623 DBC_t FAR
*pdbc
= (DBC_t FAR
*) hdbc
;
624 RETCODE retcode
= SQL_SUCCESS
;
625 RETCODE setopterr
= SQL_SUCCESS
;
626 char driver
[1024] = {'\0'}; /* MS SDK Guide
633 if (hdbc
== SQL_NULL_HDBC
)
635 return SQL_INVALID_HANDLE
;
638 /* check arguments */
639 if ((cbDSN
< 0 && cbDSN
!= SQL_NTS
)
640 || (cbUID
< 0 && cbUID
!= SQL_NTS
)
641 || (cbAuthStr
< 0 && cbAuthStr
!= SQL_NTS
)
642 || (cbDSN
> SQL_MAX_DSN_LENGTH
))
644 PUSHSQLERR (pdbc
->herr
, en_S1090
);
649 if (szDSN
== NULL
|| cbDSN
== 0)
651 PUSHSQLERR (pdbc
->herr
, en_IM002
);
657 if (pdbc
->state
!= en_dbc_allocated
)
659 PUSHSQLERR (pdbc
->herr
, en_08002
);
664 setopterr
|= _iodbcdm_settracing (hdbc
,
665 (char *) szDSN
, cbDSN
);
667 ptr
= _iodbcdm_getkeyvalbydsn (szDSN
, cbDSN
, "Driver",
668 (char FAR
*) driver
, sizeof (driver
));
671 /* No specified or default dsn section or
672 * no driver specification in this dsn section */
674 PUSHSQLERR (pdbc
->herr
, en_IM002
);
679 retcode
= _iodbcdm_driverload (driver
, hdbc
);
686 case SQL_SUCCESS_WITH_INFO
:
687 setopterr
= SQL_ERROR
;
688 /* unsuccessed in calling driver's
689 * SQLSetConnectOption() to set login
698 hproc
= _iodbcdm_getproc (hdbc
, en_Connect
);
700 if (hproc
== SQL_NULL_HPROC
)
702 _iodbcdm_driverunload (hdbc
);
704 PUSHSQLERR (pdbc
->herr
, en_IM001
);
709 CALL_DRIVER (hdbc
, retcode
, hproc
, en_Connect
, (
713 szAuthStr
, cbAuthStr
))
715 if (retcode
!= SQL_SUCCESS
716 && retcode
!= SQL_SUCCESS_WITH_INFO
)
718 /* not unload driver for retrive error
719 * messge from driver */
721 _iodbcdm_driverunload( hdbc );
727 /* state transition */
728 pdbc
->state
= en_dbc_connected
;
730 /* do delaid option setting */
731 setopterr
|= _iodbcdm_dbcdelayset (hdbc
);
733 if (setopterr
!= SQL_SUCCESS
)
735 return SQL_SUCCESS_WITH_INFO
;
746 UCHAR FAR
* szConnStrIn
,
748 UCHAR FAR
* szConnStrOut
,
749 SWORD cbConnStrOutMax
,
750 SWORD FAR
* pcbConnStrOut
,
751 UWORD fDriverCompletion
)
753 DBC_t FAR
*pdbc
= (DBC_t FAR
*) hdbc
;
758 char dsnbuf
[SQL_MAX_DSN_LENGTH
+ 1];
759 UCHAR cnstr2drv
[1024];
764 int sqlstat
= en_00000
;
765 RETCODE retcode
= SQL_SUCCESS
;
766 RETCODE setopterr
= SQL_SUCCESS
;
768 if (hdbc
== SQL_NULL_HDBC
)
770 return SQL_INVALID_HANDLE
;
773 /* check arguments */
774 if ((cbConnStrIn
< 0 && cbConnStrIn
!= SQL_NTS
)
775 || cbConnStrOutMax
< 0)
777 PUSHSQLERR (pdbc
->herr
, en_S1090
);
783 if (pdbc
->state
!= en_dbc_allocated
)
785 PUSHSQLERR (pdbc
->herr
, en_08002
);
790 drv
= _iodbcdm_getkeyvalinstr (szConnStrIn
, cbConnStrIn
,
791 "DRIVER", drvbuf
, sizeof (drvbuf
));
793 dsn
= _iodbcdm_getkeyvalinstr (szConnStrIn
, cbConnStrIn
,
794 "DSN", dsnbuf
, sizeof (dsnbuf
));
796 switch (fDriverCompletion
)
798 case SQL_DRIVER_NOPROMPT
:
801 case SQL_DRIVER_COMPLETE
:
802 case SQL_DRIVER_COMPLETE_REQUIRED
:
803 if (dsn
!= NULL
|| drv
!= NULL
)
807 /* fall to next case */
808 case SQL_DRIVER_PROMPT
:
809 /* Get data source dialog box function from
810 * current executable */
811 hdll
= _iodbcdm_dllopen ((char FAR
*) NULL
);
812 dialproc
= _iodbcdm_dllproc (hdll
,
813 "_iodbcdm_drvconn_dialbox");
815 if (dialproc
== SQL_NULL_HPROC
)
822 hwnd
, /* window or display handle */
823 dsnbuf
, /* input/output dsn buf */
824 sizeof (dsnbuf
), /* buf size */
825 &sqlstat
); /* error code */
827 if (retcode
!= SQL_SUCCESS
)
832 if (cbConnStrIn
== SQL_NTS
)
834 cbConnStrIn
= STRLEN (szConnStrIn
);
844 if (cbConnStrIn
> sizeof (cnstr2drv
)
845 - STRLEN (dsn
) - STRLEN ("DSN=;") - 1)
847 sqlstat
= en_S1001
; /* a lazy way to avoid
848 * using heap memory */
852 sprintf ((char*)cnstr2drv
, "DSN=%s;", dsn
);
853 cbConnStrIn
+= STRLEN (cnstr2drv
);
854 STRNCAT (cnstr2drv
, szConnStrIn
, cbConnStrIn
);
855 szConnStrIn
= cnstr2drv
;
863 if (sqlstat
!= en_00000
)
865 PUSHSQLERR (pdbc
->herr
, sqlstat
);
870 if (dsn
== NULL
|| dsn
[0] == '\0')
875 /* if you want tracing, you must use a DSN */
877 setopterr
|= _iodbcdm_settracing (hdbc
,
878 (char *) dsn
, SQL_NTS
);
881 if (drv
== NULL
|| drv
[0] == '\0')
883 drv
= _iodbcdm_getkeyvalbydsn (dsn
, SQL_NTS
, "Driver",
884 drvbuf
, sizeof (drvbuf
));
889 PUSHSQLERR (pdbc
->herr
, en_IM002
);
894 retcode
= _iodbcdm_driverload (drv
, hdbc
);
901 case SQL_SUCCESS_WITH_INFO
:
902 setopterr
= SQL_ERROR
;
903 /* unsuccessed in calling driver's
904 * SQLSetConnectOption() to set login
913 hproc
= _iodbcdm_getproc (hdbc
, en_DriverConnect
);
915 if (hproc
== SQL_NULL_HPROC
)
917 _iodbcdm_driverunload (hdbc
);
919 PUSHSQLERR (pdbc
->herr
, en_IM001
);
924 CALL_DRIVER (hdbc
, retcode
, hproc
, en_DriverConnect
, (
926 szConnStrIn
, cbConnStrIn
,
927 szConnStrOut
, cbConnStrOutMax
,
928 pcbConnStrOut
, fDriverCompletion
))
930 if (retcode
!= SQL_SUCCESS
&& retcode
!= SQL_SUCCESS_WITH_INFO
)
932 /* don't unload driver here for retrive
933 * error message from driver */
935 _iodbcdm_driverunload( hdbc );
941 /* state transition */
942 pdbc
->state
= en_dbc_connected
;
944 /* do delaid option setting */
945 setopterr
|= _iodbcdm_dbcdelayset (hdbc
);
947 if (setopterr
!= SQL_SUCCESS
)
949 return SQL_SUCCESS_WITH_INFO
;
959 UCHAR FAR
* szConnStrIn
,
961 UCHAR FAR
* szConnStrOut
,
962 SWORD cbConnStrOutMax
,
963 SWORD FAR
* pcbConnStrOut
)
965 DBC_t FAR
*pdbc
= (DBC_t FAR
*) hdbc
;
969 char dsnbuf
[SQL_MAX_DSN_LENGTH
+ 1];
973 RETCODE retcode
= SQL_SUCCESS
;
974 RETCODE setopterr
= SQL_SUCCESS
;
976 if (hdbc
== SQL_NULL_HDBC
)
978 return SQL_INVALID_HANDLE
;
981 /* check arguments */
982 if ((cbConnStrIn
< 0 && cbConnStrIn
!= SQL_NTS
) || cbConnStrOutMax
< 0)
984 PUSHSQLERR (pdbc
->herr
, en_S1090
);
989 if (pdbc
->state
== en_dbc_allocated
)
991 drv
= _iodbcdm_getkeyvalinstr (szConnStrIn
, cbConnStrIn
,
992 "DRIVER", drvbuf
, sizeof (drvbuf
));
994 dsn
= _iodbcdm_getkeyvalinstr (szConnStrIn
, cbConnStrIn
,
995 "DSN", dsnbuf
, sizeof (dsnbuf
));
997 if (dsn
== NULL
|| dsn
[0] == '\0')
1002 /* if you want tracing, you must use a DSN */
1004 setopterr
|= _iodbcdm_settracing (hdbc
,
1005 (char *) dsn
, SQL_NTS
);
1008 if (drv
== NULL
|| drv
[0] == '\0')
1010 drv
= _iodbcdm_getkeyvalbydsn (dsn
, SQL_NTS
, "Driver",
1011 drvbuf
, sizeof (drvbuf
));
1016 PUSHSQLERR (pdbc
->herr
, en_IM002
);
1021 retcode
= _iodbcdm_driverload (drv
, hdbc
);
1028 case SQL_SUCCESS_WITH_INFO
:
1029 setopterr
= SQL_ERROR
;
1030 /* unsuccessed in calling driver's
1031 * SQLSetConnectOption() to set login
1040 else if (pdbc
->state
!= en_dbc_needdata
)
1042 PUSHSQLERR (pdbc
->herr
, en_08002
);
1047 hproc
= _iodbcdm_getproc (hdbc
, en_BrowseConnect
);
1049 if (hproc
== SQL_NULL_HPROC
)
1051 _iodbcdm_driverunload (hdbc
);
1053 pdbc
->state
= en_dbc_allocated
;
1055 PUSHSQLERR (pdbc
->herr
, en_IM001
);
1060 CALL_DRIVER (hdbc
, retcode
, hproc
, en_BrowseConnect
, (
1062 szConnStrIn
, cbConnStrIn
,
1063 szConnStrOut
, cbConnStrOutMax
,
1069 case SQL_SUCCESS_WITH_INFO
:
1070 pdbc
->state
= en_dbc_connected
;
1071 setopterr
|= _iodbcdm_dbcdelayset (hdbc
);
1072 if (setopterr
!= SQL_SUCCESS
)
1074 retcode
= SQL_SUCCESS_WITH_INFO
;
1079 pdbc
->state
= en_dbc_needdata
;
1083 pdbc
->state
= en_dbc_allocated
;
1084 /* but the driver will not unloaded
1085 * to allow application retrive err
1086 * message from driver
1099 SQLDisconnect (HDBC hdbc
)
1101 DBC_t FAR
*pdbc
= (DBC_t
*) hdbc
;
1106 int sqlstat
= en_00000
;
1108 if (hdbc
== SQL_NULL_HDBC
)
1110 return SQL_INVALID_HANDLE
;
1113 /* check hdbc state */
1114 if (pdbc
->state
== en_dbc_allocated
)
1119 /* check stmt(s) state */
1120 for (pstmt
= (STMT_t FAR
*) pdbc
->hstmt
;
1121 pstmt
!= NULL
&& sqlstat
== en_00000
;
1122 pstmt
= (STMT_t FAR
*) pstmt
->next
)
1124 if (pstmt
->state
>= en_stmt_needdata
1125 || pstmt
->asyn_on
!= en_NullProc
)
1126 /* In this case one need to call
1127 * SQLCancel() first */
1133 if (sqlstat
== en_00000
)
1135 hproc
= _iodbcdm_getproc (hdbc
, en_Disconnect
);
1137 if (hproc
== SQL_NULL_HPROC
)
1143 if (sqlstat
!= en_00000
)
1145 PUSHSQLERR (pdbc
->herr
, sqlstat
);
1150 CALL_DRIVER (hdbc
, retcode
, hproc
, en_Disconnect
, (
1153 if (retcode
== SQL_SUCCESS
|| retcode
== SQL_SUCCESS_WITH_INFO
)
1155 /* diff from MS specs. We disallow
1156 * driver SQLDisconnect() return
1157 * SQL_SUCCESS_WITH_INFO and post
1160 retcode
= SQL_SUCCESS
;
1167 /* free all statement handle(s) on this connection */
1168 for (; pdbc
->hstmt
;)
1170 _iodbcdm_dropstmt (pdbc
->hstmt
);
1173 /* state transition */
1174 if (retcode
== SQL_SUCCESS
)
1176 pdbc
->state
= en_dbc_allocated
;
1186 UCHAR FAR
* szSqlStrIn
,
1188 UCHAR FAR
* szSqlStr
,
1190 SDWORD FAR
* pcbSqlStr
)
1192 DBC_t FAR
*pdbc
= (DBC_t FAR
*) hdbc
;
1194 int sqlstat
= en_00000
;
1197 if (hdbc
== SQL_NULL_HDBC
)
1199 return SQL_INVALID_HANDLE
;
1202 /* check argument */
1203 if (szSqlStrIn
== NULL
)
1207 else if (cbSqlStrIn
< 0 && cbSqlStrIn
!= SQL_NTS
)
1212 if (sqlstat
!= en_00000
)
1214 PUSHSQLERR (pdbc
->herr
, sqlstat
);
1220 if (pdbc
->state
<= en_dbc_needdata
)
1222 PUSHSQLERR (pdbc
->herr
, en_08003
);
1228 hproc
= _iodbcdm_getproc (hdbc
, en_NativeSql
);
1230 if (hproc
== SQL_NULL_HPROC
)
1232 PUSHSQLERR (pdbc
->herr
, en_IM001
);
1237 CALL_DRIVER (hdbc
, retcode
, hproc
, en_NativeSql
,
1238 (pdbc
->dhdbc
, szSqlStrIn
, cbSqlStrIn
, szSqlStr
, cbSqlStrMax
, pcbSqlStr
))