6 * Data source connect object management functions
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.
42 extern RETCODE
_iodbcdm_driverunload();
50 GENV_t FAR
*genv
= (GENV_t FAR
*) henv
;
53 #if (ODBCVER >= 0x0300)
54 if (henv
== SQL_NULL_HENV
|| genv
->type
!= SQL_HANDLE_ENV
)
56 if (henv
== SQL_NULL_HENV
)
60 return SQL_INVALID_HANDLE
;
65 PUSHSQLERR (genv
->herr
, en_S1009
);
70 pdbc
= (DBC_t FAR
*) MEM_ALLOC (sizeof (DBC_t
));
74 *phdbc
= SQL_NULL_HDBC
;
76 PUSHSQLERR (genv
->herr
, en_S1001
);
81 #if (ODBCVER >= 0x0300)
82 pdbc
->type
= SQL_HANDLE_DBC
;
85 /* insert this dbc entry into the link list */
86 pdbc
->next
= genv
->hdbc
;
90 pdbc
->henv
= SQL_NULL_HENV
;
91 pdbc
->hstmt
= SQL_NULL_HSTMT
;
92 pdbc
->herr
= SQL_NULL_HERR
;
93 pdbc
->dhdbc
= SQL_NULL_HDBC
;
94 pdbc
->state
= en_dbc_allocated
;
99 /* set connect options to default values */
100 pdbc
->access_mode
= SQL_MODE_DEFAULT
;
101 pdbc
->autocommit
= SQL_AUTOCOMMIT_DEFAULT
;
102 pdbc
->current_qualifier
= NULL
;
103 pdbc
->login_timeout
= 0UL;
104 pdbc
->odbc_cursors
= SQL_CUR_DEFAULT
;
105 pdbc
->packet_size
= 0UL;
106 pdbc
->quiet_mode
= (UDWORD
) NULL
;
107 pdbc
->txn_isolation
= SQL_TXN_READ_UNCOMMITTED
;
108 pdbc
->cb_commit
= (SWORD
) SQL_CB_DELETE
;
109 pdbc
->cb_rollback
= (SWORD
) SQL_CB_DELETE
;
111 *phdbc
= (HDBC
) pdbc
;
118 SQLFreeConnect (HDBC hdbc
)
121 DBC_t FAR
*pdbc
= (DBC_t FAR
*) hdbc
;
124 if (hdbc
== SQL_NULL_HDBC
)
126 return SQL_INVALID_HANDLE
;
130 if (pdbc
->state
!= en_dbc_allocated
)
132 PUSHSQLERR (pdbc
->herr
, en_S1010
);
137 genv
= (GENV_t FAR
*) pdbc
->genv
;
139 for (tpdbc
= (DBC_t FAR
*) genv
->hdbc
;
145 genv
->hdbc
= pdbc
->next
;
149 if (pdbc
== tpdbc
->next
)
151 tpdbc
->next
= pdbc
->next
;
157 _iodbcdm_driverunload (pdbc
);
158 _iodbcdm_freesqlerrlist (pdbc
->herr
);
162 MEM_FREE (pdbc
->tfile
);
165 SQLSetConnectOption (pdbc
, SQL_OPT_TRACE
, SQL_OPT_TRACE_OFF
);
174 SQLSetConnectOption (
180 DBC_t FAR
*pdbc
= (DBC_t FAR
*) hdbc
;
182 HPROC hproc
= SQL_NULL_HPROC
;
183 int sqlstat
= en_00000
;
184 RETCODE retcode
= SQL_SUCCESS
;
186 if (hdbc
== SQL_NULL_HDBC
)
188 return SQL_INVALID_HANDLE
;
192 if (fOption
< SQL_CONN_OPT_MIN
||
193 (fOption
> SQL_CONN_OPT_MAX
&& fOption
< SQL_CONNECT_OPT_DRVR_START
))
195 PUSHSQLERR (pdbc
->herr
, en_S1092
);
200 /* check state of connection handle */
203 case en_dbc_allocated
:
204 if (fOption
== SQL_TRANSLATE_DLL
|| fOption
== SQL_TRANSLATE_OPTION
)
206 /* This two options are only meaningful
207 * for specified driver. So, has to be
208 * set after a dirver has been loaded.
214 if (fOption
>= SQL_CONNECT_OPT_DRVR_START
&& pdbc
->henv
== SQL_NULL_HENV
)
215 /* An option only meaningful for drivers
216 * is passed before loading a driver.
217 * We classify this as an invalid option error.
218 * This is not documented by MS SDK guide.
226 case en_dbc_needdata
:
230 case en_dbc_connected
:
232 if (fOption
== SQL_ODBC_CURSORS
)
242 /* check state of statement handle(s) */
243 for (pstmt
= (STMT_t FAR
*) pdbc
->hstmt
;
244 pstmt
!= NULL
&& sqlstat
== en_00000
;
245 pstmt
= (STMT_t FAR
*) pstmt
->next
)
247 if (pstmt
->state
>= en_stmt_needdata
|| pstmt
->asyn_on
!= en_NullProc
)
253 if (sqlstat
!= en_00000
)
255 PUSHSQLERR (pdbc
->herr
, sqlstat
);
260 if (fOption
== SQL_OPT_TRACE
)
261 /* tracing flag can be set before and after connect
262 * and only meaningful for driver manager(actually
263 * there is only one tracing file under one global
269 case SQL_OPT_TRACE_ON
:
270 if (pdbc
->tfile
== NULL
)
272 pdbc
->tfile
= (char FAR
*) MEM_ALLOC (1 +
273 STRLEN (SQL_OPT_TRACE_FILE_DEFAULT
));
275 if (pdbc
->tfile
== NULL
)
277 PUSHSQLERR (pdbc
->herr
, en_S1001
);
282 STRCPY (pdbc
->tfile
, SQL_OPT_TRACE_FILE_DEFAULT
);
285 if (pdbc
->tstm
== NULL
)
288 #if defined(stderr) && defined(stdout)
289 if (STREQ (pdbc
->tfile
, "stderr"))
293 else if (STREQ (pdbc
->tfile
, "stdout"))
302 = fopen (pdbc
->tfile
, "a+");
319 case SQL_OPT_TRACE_OFF
:
320 if (pdbc
->trace
&& pdbc
->tstm
)
323 #if defined(stderr) && defined(stdout)
324 if (stderr
!= (FILE FAR
*) (pdbc
->tstm
)
325 && stdout
!= (FILE FAR
*) (pdbc
->tstm
))
337 PUSHSQLERR (pdbc
->herr
, en_S1009
);
341 if (sqlstat
!= en_00000
)
343 PUSHSQLERR (pdbc
->herr
, sqlstat
);
349 if (fOption
== SQL_OPT_TRACEFILE
)
350 /* Tracing file can be set before and after connect
351 * and only meaningful for driver manager.
354 if (vParam
== 0UL || ((char FAR
*) vParam
)[0] == 0)
356 PUSHSQLERR (pdbc
->herr
, en_S1009
);
361 if (pdbc
->tfile
&& STREQ (pdbc
->tfile
, vParam
))
368 PUSHSQLERR (pdbc
->herr
, en_IM014
);
375 MEM_FREE (pdbc
->tfile
);
378 pdbc
->tfile
= (char FAR
*) MEM_ALLOC (1 + STRLEN (vParam
));
380 if (pdbc
->tfile
== NULL
)
382 PUSHSQLERR (pdbc
->herr
, en_S1001
);
387 STRCPY (pdbc
->tfile
, vParam
);
392 if (pdbc
->state
!= en_dbc_allocated
)
394 /* If already connected, then, driver's odbc call
395 * will be invoked. Otherwise, we only save the options
396 * and delay the setting process until the connection
399 hproc
= _iodbcdm_getproc (hdbc
, en_SetConnectOption
);
401 if (hproc
== SQL_NULL_HPROC
)
403 PUSHSQLERR (pdbc
->herr
, en_IM001
);
408 CALL_DRIVER (hdbc
, retcode
, hproc
, en_SetConnectOption
,
409 (pdbc
->dhdbc
, fOption
, vParam
))
411 if (retcode
!= SQL_SUCCESS
&& retcode
!= SQL_SUCCESS_WITH_INFO
)
418 * Now, either driver's odbc call was successed or
419 * driver has not been loaded yet. In the first case, we
420 * need flip flag for(such as access_mode, autocommit, ...)
421 * for our finit state machine. While in the second case,
422 * we need save option values(such as current_qualifier, ...)
423 * for delaied setting. So, ...
426 /* No matter what state we are(i.e. allocated or connected, ..)
427 * we need to flip the flag.
431 case SQL_ACCESS_MODE
:
432 pdbc
->access_mode
= vParam
;
436 pdbc
->autocommit
= vParam
;
440 /* state transition */
441 if (pdbc
->state
!= en_dbc_allocated
)
446 /* Only 'allocated' state is possible here, and we need to
447 * save the options for delaied setting.
451 case SQL_CURRENT_QUALIFIER
:
452 if (pdbc
->current_qualifier
!= NULL
)
454 MEM_FREE (pdbc
->current_qualifier
);
459 pdbc
->current_qualifier
= NULL
;
464 pdbc
->current_qualifier
465 = (char FAR
*) MEM_ALLOC (
466 STRLEN (vParam
) + 1);
468 if (pdbc
->current_qualifier
== NULL
)
470 PUSHSQLERR (pdbc
->herr
, en_S1001
);
474 STRCPY (pdbc
->current_qualifier
, vParam
);
477 case SQL_LOGIN_TIMEOUT
:
478 pdbc
->login_timeout
= vParam
;
481 case SQL_ODBC_CURSORS
:
482 pdbc
->odbc_cursors
= vParam
;
485 case SQL_PACKET_SIZE
:
486 pdbc
->packet_size
= vParam
;
490 pdbc
->quiet_mode
= vParam
;
493 case SQL_TXN_ISOLATION
:
494 pdbc
->txn_isolation
= vParam
;
498 /* Since we didn't save the option value for delaied
499 * setting, we should raise an error here.
509 SQLGetConnectOption (
515 DBC_t FAR
*pdbc
= (DBC_t FAR
*) hdbc
;
516 int sqlstat
= en_00000
;
517 HPROC hproc
= SQL_NULL_HPROC
;
520 if (hdbc
== SQL_NULL_HDBC
)
522 return SQL_INVALID_HANDLE
;
526 if (fOption
< SQL_CONN_OPT_MIN
||
527 (fOption
> SQL_CONN_OPT_MAX
&& fOption
< SQL_CONNECT_OPT_DRVR_START
))
529 PUSHSQLERR (pdbc
->herr
, en_S1092
);
537 case en_dbc_allocated
:
538 if (fOption
!= SQL_ACCESS_MODE
539 && fOption
!= SQL_AUTOCOMMIT
540 && fOption
!= SQL_LOGIN_TIMEOUT
541 && fOption
!= SQL_OPT_TRACE
542 && fOption
!= SQL_OPT_TRACEFILE
)
546 /* MS ODBC SDK document only
547 * allows SQL_ACCESS_MODE
548 * and SQL_AUTOCOMMIT in this
549 * dbc state. We allow another
550 * two options, because they
551 * are only meaningful for driver
556 case en_dbc_needdata
:
564 if (sqlstat
!= en_00000
)
566 PUSHSQLERR (pdbc
->herr
, sqlstat
);
571 /* Tracing and tracing file options are only
572 * meaningful for driver manager
574 if (fOption
== SQL_OPT_TRACE
)
577 *((UDWORD
*) pvParam
) = (UDWORD
) SQL_OPT_TRACE_ON
;
579 *((UDWORD
*) pvParam
) = (UDWORD
) SQL_OPT_TRACE_OFF
;
584 if (fOption
== SQL_OPT_TRACEFILE
)
586 STRCPY (pvParam
, pdbc
->tfile
);
591 if (pdbc
->state
!= en_dbc_allocated
)
592 /* if already connected, we will invoke driver's function */
594 hproc
= _iodbcdm_getproc (hdbc
, en_GetConnectOption
);
596 if (hproc
== SQL_NULL_HPROC
)
598 PUSHSQLERR (pdbc
->herr
, en_IM001
);
603 CALL_DRIVER (hdbc
, retcode
, hproc
, en_GetConnectOption
,
604 (pdbc
->dhdbc
, fOption
, pvParam
))
609 /* We needn't to handle options which are not allowed
610 * to be *get* at a allocated dbc state(and two tracing
611 * options which has been handled and returned). Thus,
612 * there are only two possible cases.
616 case SQL_ACCESS_MODE
:
617 *((UDWORD
*) pvParam
) = pdbc
->access_mode
;
621 *((UDWORD
*) pvParam
) = pdbc
->autocommit
;
624 case SQL_LOGIN_TIMEOUT
:
625 *((UDWORD
*) pvParam
) = pdbc
->login_timeout
;
641 DBC_t FAR
*pdbc
= (DBC_t FAR
*) hdbc
;
649 case en_dbc_allocated
:
650 case en_dbc_needdata
:
651 PUSHSQLERR (pdbc
->herr
, en_08003
);
654 case en_dbc_connected
:
662 for (pstmt
= (STMT_t FAR
*) (pdbc
->hstmt
);
666 if (pstmt
->state
>= en_stmt_needdata
667 || pstmt
->asyn_on
!= en_NullProc
)
669 PUSHSQLERR (pdbc
->herr
, en_S1010
);
675 hproc
= _iodbcdm_getproc (hdbc
, en_Transact
);
677 if (hproc
== SQL_NULL_HPROC
)
679 PUSHSQLERR (pdbc
->herr
, en_IM001
);
684 CALL_DRIVER (hdbc
, retcode
, hproc
, en_Transact
,
685 (SQL_NULL_HENV
, pdbc
->dhdbc
, fType
))
687 /* state transition */
688 if (retcode
!= SQL_SUCCESS
&& retcode
!= SQL_SUCCESS_WITH_INFO
)
693 pdbc
->state
= en_dbc_hstmt
;
695 for (pstmt
= (STMT_t FAR
*) (pdbc
->hstmt
);
699 switch (pstmt
->state
)
701 case en_stmt_prepared
:
702 if (pdbc
->cb_commit
== SQL_CB_DELETE
703 || pdbc
->cb_rollback
== SQL_CB_DELETE
)
705 pstmt
->state
= en_stmt_allocated
;
706 pstmt
->prep_state
= 0;
711 case en_stmt_executed
:
712 case en_stmt_cursoropen
:
713 case en_stmt_fetched
:
714 case en_stmt_xfetched
:
715 if (!pstmt
->prep_state
716 && pdbc
->cb_commit
!= SQL_CB_PRESERVE
717 && pdbc
->cb_rollback
!= SQL_CB_PRESERVE
)
719 pstmt
->state
= en_stmt_allocated
;
720 pstmt
->prep_state
= 0;
721 pstmt
->cursor_state
= en_stmt_cursor_no
;
725 if (pstmt
->prep_state
)
727 if (pdbc
->cb_commit
== SQL_CB_DELETE
728 || pdbc
->cb_rollback
== SQL_CB_DELETE
)
730 pstmt
->state
= en_stmt_allocated
;
731 pstmt
->prep_state
= 0;
732 pstmt
->cursor_state
= en_stmt_cursor_no
;
736 if (pdbc
->cb_commit
== SQL_CB_CLOSE
737 || pdbc
->cb_rollback
== SQL_CB_CLOSE
)
764 GENV_t FAR
*genv
= (GENV_t FAR
*) henv
;
765 DBC_t FAR
*pdbc
= (DBC_t FAR
*) hdbc
;
769 if (hdbc
!= SQL_NULL_HDBC
)
773 else if (henv
!= SQL_NULL_HENV
)
779 return SQL_INVALID_HANDLE
;
783 if (fType
!= SQL_COMMIT
784 && fType
!= SQL_ROLLBACK
)
786 PUSHSQLERR (herr
, en_S1012
);
791 if (hdbc
!= SQL_NULL_HDBC
)
793 retcode
= _iodbcdm_transact (hdbc
, fType
);
797 for (pdbc
= (DBC_t FAR
*) (genv
->hdbc
);
801 retcode
|= _iodbcdm_transact (hdbc
, fType
);
805 if (retcode
!= SQL_SUCCESS
806 && retcode
!= SQL_SUCCESS_WITH_INFO
)
808 /* fail on one of the connection */