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 (
179 DBC_t FAR
*pdbc
= (DBC_t FAR
*) hdbc
;
181 HPROC hproc
= SQL_NULL_HPROC
;
182 int sqlstat
= en_00000
;
183 RETCODE retcode
= SQL_SUCCESS
;
185 if (hdbc
== SQL_NULL_HDBC
)
187 return SQL_INVALID_HANDLE
;
191 if (fOption
< SQL_CONN_OPT_MIN
||
192 (fOption
> SQL_CONN_OPT_MAX
&& fOption
< SQL_CONNECT_OPT_DRVR_START
))
194 PUSHSQLERR (pdbc
->herr
, en_S1092
);
199 /* check state of connection handle */
202 case en_dbc_allocated
:
203 if (fOption
== SQL_TRANSLATE_DLL
|| fOption
== SQL_TRANSLATE_OPTION
)
205 /* This two options are only meaningful
206 * for specified driver. So, has to be
207 * set after a dirver has been loaded.
213 if (fOption
>= SQL_CONNECT_OPT_DRVR_START
&& pdbc
->henv
== SQL_NULL_HENV
)
214 /* An option only meaningful for drivers
215 * is passed before loading a driver.
216 * We classify this as an invalid option error.
217 * This is not documented by MS SDK guide.
225 case en_dbc_needdata
:
229 case en_dbc_connected
:
231 if (fOption
== SQL_ODBC_CURSORS
)
241 /* check state of statement handle(s) */
242 for (pstmt
= (STMT_t FAR
*) pdbc
->hstmt
;
243 pstmt
!= NULL
&& sqlstat
== en_00000
;
244 pstmt
= (STMT_t FAR
*) pstmt
->next
)
246 if (pstmt
->state
>= en_stmt_needdata
|| pstmt
->asyn_on
!= en_NullProc
)
252 if (sqlstat
!= en_00000
)
254 PUSHSQLERR (pdbc
->herr
, sqlstat
);
259 if (fOption
== SQL_OPT_TRACE
)
260 /* tracing flag can be set before and after connect
261 * and only meaningful for driver manager(actually
262 * there is only one tracing file under one global
268 case SQL_OPT_TRACE_ON
:
269 if (pdbc
->tfile
== NULL
)
271 pdbc
->tfile
= (char FAR
*) MEM_ALLOC (1 +
272 STRLEN (SQL_OPT_TRACE_FILE_DEFAULT
));
274 if (pdbc
->tfile
== NULL
)
276 PUSHSQLERR (pdbc
->herr
, en_S1001
);
281 STRCPY (pdbc
->tfile
, SQL_OPT_TRACE_FILE_DEFAULT
);
284 if (pdbc
->tstm
== NULL
)
287 #if defined(stderr) && defined(stdout)
288 if (STREQ (pdbc
->tfile
, "stderr"))
292 else if (STREQ (pdbc
->tfile
, "stdout"))
301 = fopen (pdbc
->tfile
, "a+");
318 case SQL_OPT_TRACE_OFF
:
319 if (pdbc
->trace
&& pdbc
->tstm
)
322 #if defined(stderr) && defined(stdout)
323 if (stderr
!= (FILE FAR
*) (pdbc
->tstm
)
324 && stdout
!= (FILE FAR
*) (pdbc
->tstm
))
336 PUSHSQLERR (pdbc
->herr
, en_S1009
);
340 if (sqlstat
!= en_00000
)
342 PUSHSQLERR (pdbc
->herr
, sqlstat
);
348 if (fOption
== SQL_OPT_TRACEFILE
)
349 /* Tracing file can be set before and after connect
350 * and only meaningful for driver manager.
353 if (vParam
== 0UL || ((char FAR
*) vParam
)[0] == 0)
355 PUSHSQLERR (pdbc
->herr
, en_S1009
);
360 if (pdbc
->tfile
&& STREQ (pdbc
->tfile
, vParam
))
367 PUSHSQLERR (pdbc
->herr
, en_IM014
);
374 MEM_FREE (pdbc
->tfile
);
377 pdbc
->tfile
= (char FAR
*) MEM_ALLOC (1 + STRLEN (vParam
));
379 if (pdbc
->tfile
== NULL
)
381 PUSHSQLERR (pdbc
->herr
, en_S1001
);
386 STRCPY (pdbc
->tfile
, vParam
);
391 if (pdbc
->state
!= en_dbc_allocated
)
393 /* If already connected, then, driver's odbc call
394 * will be invoked. Otherwise, we only save the options
395 * and delay the setting process until the connection
398 hproc
= _iodbcdm_getproc (hdbc
, en_SetConnectOption
);
400 if (hproc
== SQL_NULL_HPROC
)
402 PUSHSQLERR (pdbc
->herr
, en_IM001
);
407 CALL_DRIVER (hdbc
, retcode
, hproc
, en_SetConnectOption
,
408 (pdbc
->dhdbc
, fOption
, vParam
))
410 if (retcode
!= SQL_SUCCESS
&& retcode
!= SQL_SUCCESS_WITH_INFO
)
417 * Now, either driver's odbc call was successed or
418 * driver has not been loaded yet. In the first case, we
419 * need flip flag for(such as access_mode, autocommit, ...)
420 * for our finit state machine. While in the second case,
421 * we need save option values(such as current_qualifier, ...)
422 * for delaied setting. So, ...
425 /* No matter what state we are(i.e. allocated or connected, ..)
426 * we need to flip the flag.
430 case SQL_ACCESS_MODE
:
431 pdbc
->access_mode
= vParam
;
435 pdbc
->autocommit
= vParam
;
439 /* state transition */
440 if (pdbc
->state
!= en_dbc_allocated
)
445 /* Only 'allocated' state is possible here, and we need to
446 * save the options for delaied setting.
450 case SQL_CURRENT_QUALIFIER
:
451 if (pdbc
->current_qualifier
!= NULL
)
453 MEM_FREE (pdbc
->current_qualifier
);
458 pdbc
->current_qualifier
= NULL
;
463 pdbc
->current_qualifier
464 = (char FAR
*) MEM_ALLOC (
465 STRLEN (vParam
) + 1);
467 if (pdbc
->current_qualifier
== NULL
)
469 PUSHSQLERR (pdbc
->herr
, en_S1001
);
473 STRCPY (pdbc
->current_qualifier
, vParam
);
476 case SQL_LOGIN_TIMEOUT
:
477 pdbc
->login_timeout
= vParam
;
480 case SQL_ODBC_CURSORS
:
481 pdbc
->odbc_cursors
= vParam
;
484 case SQL_PACKET_SIZE
:
485 pdbc
->packet_size
= vParam
;
489 pdbc
->quiet_mode
= vParam
;
492 case SQL_TXN_ISOLATION
:
493 pdbc
->txn_isolation
= vParam
;
497 /* Since we didn't save the option value for delaied
498 * setting, we should raise an error here.
508 SQLGetConnectOption (
513 DBC_t FAR
*pdbc
= (DBC_t FAR
*) hdbc
;
514 int sqlstat
= en_00000
;
515 HPROC hproc
= SQL_NULL_HPROC
;
518 if (hdbc
== SQL_NULL_HDBC
)
520 return SQL_INVALID_HANDLE
;
524 if (fOption
< SQL_CONN_OPT_MIN
||
525 (fOption
> SQL_CONN_OPT_MAX
&& fOption
< SQL_CONNECT_OPT_DRVR_START
))
527 PUSHSQLERR (pdbc
->herr
, en_S1092
);
535 case en_dbc_allocated
:
536 if (fOption
!= SQL_ACCESS_MODE
537 && fOption
!= SQL_AUTOCOMMIT
538 && fOption
!= SQL_LOGIN_TIMEOUT
539 && fOption
!= SQL_OPT_TRACE
540 && fOption
!= SQL_OPT_TRACEFILE
)
544 /* MS ODBC SDK document only
545 * allows SQL_ACCESS_MODE
546 * and SQL_AUTOCOMMIT in this
547 * dbc state. We allow another
548 * two options, because they
549 * are only meaningful for driver
554 case en_dbc_needdata
:
562 if (sqlstat
!= en_00000
)
564 PUSHSQLERR (pdbc
->herr
, sqlstat
);
569 /* Tracing and tracing file options are only
570 * meaningful for driver manager
572 if (fOption
== SQL_OPT_TRACE
)
575 *((UDWORD
*) pvParam
) = (UDWORD
) SQL_OPT_TRACE_ON
;
577 *((UDWORD
*) pvParam
) = (UDWORD
) SQL_OPT_TRACE_OFF
;
582 if (fOption
== SQL_OPT_TRACEFILE
)
584 STRCPY (pvParam
, pdbc
->tfile
);
589 if (pdbc
->state
!= en_dbc_allocated
)
590 /* if already connected, we will invoke driver's function */
592 hproc
= _iodbcdm_getproc (hdbc
, en_GetConnectOption
);
594 if (hproc
== SQL_NULL_HPROC
)
596 PUSHSQLERR (pdbc
->herr
, en_IM001
);
601 CALL_DRIVER (hdbc
, retcode
, hproc
, en_GetConnectOption
,
602 (pdbc
->dhdbc
, fOption
, pvParam
))
607 /* We needn't to handle options which are not allowed
608 * to be *get* at a allocated dbc state(and two tracing
609 * options which has been handled and returned). Thus,
610 * there are only two possible cases.
614 case SQL_ACCESS_MODE
:
615 *((UDWORD
*) pvParam
) = pdbc
->access_mode
;
619 *((UDWORD
*) pvParam
) = pdbc
->autocommit
;
622 case SQL_LOGIN_TIMEOUT
:
623 *((UDWORD
*) pvParam
) = pdbc
->login_timeout
;
639 DBC_t FAR
*pdbc
= (DBC_t FAR
*) hdbc
;
647 case en_dbc_allocated
:
648 case en_dbc_needdata
:
649 PUSHSQLERR (pdbc
->herr
, en_08003
);
652 case en_dbc_connected
:
660 for (pstmt
= (STMT_t FAR
*) (pdbc
->hstmt
);
664 if (pstmt
->state
>= en_stmt_needdata
665 || pstmt
->asyn_on
!= en_NullProc
)
667 PUSHSQLERR (pdbc
->herr
, en_S1010
);
673 hproc
= _iodbcdm_getproc (hdbc
, en_Transact
);
675 if (hproc
== SQL_NULL_HPROC
)
677 PUSHSQLERR (pdbc
->herr
, en_IM001
);
682 CALL_DRIVER (hdbc
, retcode
, hproc
, en_Transact
,
683 (SQL_NULL_HENV
, pdbc
->dhdbc
, fType
))
685 /* state transition */
686 if (retcode
!= SQL_SUCCESS
&& retcode
!= SQL_SUCCESS_WITH_INFO
)
691 pdbc
->state
= en_dbc_hstmt
;
693 for (pstmt
= (STMT_t FAR
*) (pdbc
->hstmt
);
697 switch (pstmt
->state
)
699 case en_stmt_prepared
:
700 if (pdbc
->cb_commit
== SQL_CB_DELETE
701 || pdbc
->cb_rollback
== SQL_CB_DELETE
)
703 pstmt
->state
= en_stmt_allocated
;
704 pstmt
->prep_state
= 0;
709 case en_stmt_executed
:
710 case en_stmt_cursoropen
:
711 case en_stmt_fetched
:
712 case en_stmt_xfetched
:
713 if (!pstmt
->prep_state
714 && pdbc
->cb_commit
!= SQL_CB_PRESERVE
715 && pdbc
->cb_rollback
!= SQL_CB_PRESERVE
)
717 pstmt
->state
= en_stmt_allocated
;
718 pstmt
->prep_state
= 0;
719 pstmt
->cursor_state
= en_stmt_cursor_no
;
723 if (pstmt
->prep_state
)
725 if (pdbc
->cb_commit
== SQL_CB_DELETE
726 || pdbc
->cb_rollback
== SQL_CB_DELETE
)
728 pstmt
->state
= en_stmt_allocated
;
729 pstmt
->prep_state
= 0;
730 pstmt
->cursor_state
= en_stmt_cursor_no
;
734 if (pdbc
->cb_commit
== SQL_CB_CLOSE
735 || pdbc
->cb_rollback
== SQL_CB_CLOSE
)
762 GENV_t FAR
*genv
= (GENV_t FAR
*) henv
;
763 DBC_t FAR
*pdbc
= (DBC_t FAR
*) hdbc
;
767 if (hdbc
!= SQL_NULL_HDBC
)
771 else if (henv
!= SQL_NULL_HENV
)
777 return SQL_INVALID_HANDLE
;
781 if (fType
!= SQL_COMMIT
782 && fType
!= SQL_ROLLBACK
)
784 PUSHSQLERR (herr
, en_S1012
);
789 if (hdbc
!= SQL_NULL_HDBC
)
791 retcode
= _iodbcdm_transact (hdbc
, fType
);
795 for (pdbc
= (DBC_t FAR
*) (genv
->hdbc
);
799 retcode
|= _iodbcdm_transact (hdbc
, fType
);
803 if (retcode
!= SQL_SUCCESS
804 && retcode
!= SQL_SUCCESS_WITH_INFO
)
806 /* fail on one of the connection */