📄 hdbc.c
字号:
/* * hdbc.c * * $Id: hdbc.c,v 1.14 2001/06/04 14:01:25 source Exp $ * * Data source connect object management functions * * The iODBC driver manager. * * Copyright (C) 1995 by Ke Jin <kejin@empress.com> * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this library; if not, write to the Free * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */#include <iodbc.h>#include <sql.h>#include <sqlext.h>#include <dlproc.h>#include <herr.h>#include <henv.h>#include <hdbc.h>#include <hstmt.h>#include <itrace.h>#include <stdio.h>SQLRETURN SQL_APISQLAllocConnect ( SQLHENV henv, SQLHDBC FAR * phdbc){ GENV (genv, henv); DBC_t FAR *pdbc; ODBC_LOCK (); if (!IS_VALID_HENV (genv)) { ODBC_UNLOCK (); return SQL_INVALID_HANDLE; } CLEAR_ERRORS (genv); if (phdbc == NULL) { PUSHSQLERR (genv->herr, en_S1009); ODBC_UNLOCK (); return SQL_ERROR; } pdbc = (DBC_t FAR *) MEM_ALLOC (sizeof (DBC_t)); if (pdbc == NULL) { *phdbc = SQL_NULL_HDBC; PUSHSQLERR (genv->herr, en_S1001); ODBC_UNLOCK (); return SQL_ERROR; } pdbc->rc = 0; /* * Initialize this handle */ pdbc->type = SQL_HANDLE_DBC; /* insert this dbc entry into the link list */ pdbc->next = genv->hdbc; genv->hdbc = pdbc;#if (ODBCVER >= 0x0300) if (genv->odbc_ver == 0) genv->odbc_ver = SQL_OV_ODBC2; pdbc->hdesc = NULL;#endif pdbc->genv = genv; pdbc->henv = SQL_NULL_HENV; pdbc->hstmt = SQL_NULL_HSTMT; pdbc->herr = SQL_NULL_HERR; pdbc->dhdbc = SQL_NULL_HDBC; pdbc->state = en_dbc_allocated; pdbc->trace = 0; pdbc->tstm = NULL; pdbc->tfile = NULL; pdbc->dbc_cip = 0; /* set connect options to default values */ pdbc->access_mode = SQL_MODE_DEFAULT; pdbc->autocommit = SQL_AUTOCOMMIT_DEFAULT; pdbc->current_qualifier = NULL; pdbc->login_timeout = 0UL; pdbc->odbc_cursors = SQL_CUR_DEFAULT; pdbc->packet_size = 0UL; pdbc->quiet_mode = (UDWORD) NULL; pdbc->txn_isolation = SQL_TXN_READ_UNCOMMITTED; pdbc->cb_commit = (SWORD) SQL_CB_DELETE; pdbc->cb_rollback = (SWORD) SQL_CB_DELETE; *phdbc = (SQLHDBC) pdbc; ODBC_UNLOCK (); return SQL_SUCCESS;}SQLRETURN SQL_APISQLFreeConnect (SQLHDBC hdbc){ GENV_t FAR *genv; CONN (pdbc, hdbc); DBC_t FAR *tpdbc; ODBC_LOCK (); if (!IS_VALID_HDBC (pdbc)) { ODBC_UNLOCK (); return SQL_INVALID_HANDLE; } CLEAR_ERRORS (pdbc); /* check state */ if (pdbc->state != en_dbc_allocated) { PUSHSQLERR (pdbc->herr, en_S1010); ODBC_UNLOCK (); return SQL_ERROR; } genv = (GENV_t FAR *) pdbc->genv; for (tpdbc = (DBC_t FAR *) genv->hdbc; tpdbc != NULL; tpdbc = tpdbc->next) { if (pdbc == tpdbc) { genv->hdbc = pdbc->next; break; } if (pdbc == tpdbc->next) { tpdbc->next = pdbc->next; break; } } /* free this dbc */ _iodbcdm_driverunload (pdbc); if (pdbc->tfile) { MEM_FREE (pdbc->tfile); } _iodbcdm_SetConnectOption (hdbc, SQL_OPT_TRACE, SQL_OPT_TRACE_OFF); /* * Invalidate this handle */ pdbc->type = 0; MEM_FREE (pdbc); ODBC_UNLOCK (); return SQL_SUCCESS;}SQLRETURN SQL_API_iodbcdm_SetConnectOption ( SQLHDBC hdbc, SQLUSMALLINT fOption, SQLUINTEGER vParam){ CONN (pdbc, hdbc); STMT_t FAR *pstmt; HPROC hproc = SQL_NULL_HPROC; int sqlstat = en_00000; SQLRETURN retcode = SQL_SUCCESS;#if (ODBCVER < 0x0300) /* check option */ if (fOption < SQL_CONN_OPT_MIN || (fOption > SQL_CONN_OPT_MAX && fOption < SQL_CONNECT_OPT_DRVR_START)) { PUSHSQLERR (pdbc->herr, en_S1092); return SQL_ERROR; }#endif /* check state of connection handle */ switch (pdbc->state) { case en_dbc_allocated: if (fOption == SQL_TRANSLATE_DLL || fOption == SQL_TRANSLATE_OPTION) { /* This two options are only meaningful * for specified driver. So, has to be * set after a dirver has been loaded. */ sqlstat = en_08003; break; } if (fOption >= SQL_CONNECT_OPT_DRVR_START && pdbc->henv == SQL_NULL_HENV) /* An option only meaningful for drivers * is passed before loading a driver. * We classify this as an invalid option error. * This is not documented by MS SDK guide. */ { sqlstat = en_S1092; break; } break; case en_dbc_needdata: sqlstat = en_S1010; break; case en_dbc_connected: case en_dbc_hstmt: if (fOption == SQL_ODBC_CURSORS) { sqlstat = en_08002; } break; default: break; } /* check state of statement handle(s) */ for (pstmt = (STMT_t FAR *) pdbc->hstmt; pstmt != NULL && sqlstat == en_00000; pstmt = (STMT_t FAR *) pstmt->next) { if (pstmt->state >= en_stmt_needdata || pstmt->asyn_on != en_NullProc) { sqlstat = en_S1010; } } if (sqlstat != en_00000) { PUSHSQLERR (pdbc->herr, sqlstat); return SQL_ERROR; }#if (ODBCVER >= 0x0300) if (fOption == SQL_OPT_TRACE || fOption == SQL_ATTR_TRACE)#else if (fOption == SQL_OPT_TRACE)#endif /* tracing flag can be set before and after connect * and only meaningful for driver manager(actually * there is only one tracing file under one global * environment). */ { switch (vParam) { case SQL_OPT_TRACE_ON: if (pdbc->tfile == NULL) { pdbc->tfile = (char FAR *) MEM_ALLOC (1 + STRLEN (SQL_OPT_TRACE_FILE_DEFAULT)); if (pdbc->tfile == NULL) { PUSHSQLERR (pdbc->herr, en_S1001); return SQL_ERROR; } STRCPY (pdbc->tfile, SQL_OPT_TRACE_FILE_DEFAULT); } if (pdbc->tstm == NULL) {#if defined(stderr) && defined(stdout) if (STREQ (pdbc->tfile, "stderr")) { pdbc->tstm = stderr; } else if (STREQ (pdbc->tfile, "stdout")) { pdbc->tstm = stdout; } else#endif {#if defined (UNIX) /* * As this is a security risk, we refuse root to start * a trace log */ if (geteuid() == 0) { pdbc->tstm = NULL; pdbc->trace = 0; return SQL_SUCCESS; } else { pdbc->tstm = fopen (pdbc->tfile, "w"); }#else pdbc->tstm = fopen (pdbc->tfile, "w");#endif } if (pdbc->tstm) { pdbc->trace = 1; } else { pdbc->trace = 0; sqlstat = en_IM013; retcode = SQL_ERROR; } } break; case SQL_OPT_TRACE_OFF: if (pdbc->trace && pdbc->tstm) {#if defined(stderr) && defined(stdout) if (stderr != (FILE FAR *) (pdbc->tstm) && stdout != (FILE FAR *) (pdbc->tstm))#endif { fclose (pdbc->tstm); } } pdbc->tstm = NULL; pdbc->trace = 0; break; default: PUSHSQLERR (pdbc->herr, en_S1009); retcode = SQL_ERROR; } if (sqlstat != en_00000) { PUSHSQLERR (pdbc->herr, sqlstat); } return retcode; }#if (ODBCVER >= 0x0300) if (fOption == SQL_OPT_TRACEFILE || fOption == SQL_ATTR_TRACEFILE)#else if (fOption == SQL_OPT_TRACEFILE)#endif /* Tracing file can be set before and after connect * and only meaningful for driver manager. */ { if (vParam == 0UL || ((char FAR *) vParam)[0] == 0) { PUSHSQLERR (pdbc->herr, en_S1009); return SQL_ERROR; } if (pdbc->tfile && STREQ (pdbc->tfile, vParam)) { return SQL_SUCCESS; } if (pdbc->trace) { PUSHSQLERR (pdbc->herr, en_IM014); return SQL_ERROR; } if (pdbc->tfile) { MEM_FREE (pdbc->tfile); } pdbc->tfile = (char FAR *) MEM_ALLOC (1 + STRLEN (vParam)); if (pdbc->tfile == NULL) { PUSHSQLERR (pdbc->herr, en_S1001); return SQL_ERROR; } STRCPY (pdbc->tfile, vParam); return SQL_SUCCESS; } if (pdbc->state != en_dbc_allocated) { /* If already connected, then, driver's odbc call * will be invoked. Otherwise, we only save the options * and delay the setting process until the connection * been established. */#if (ODBCVER >= 0x0300) hproc = _iodbcdm_getproc (pdbc, en_SetConnectAttr); if (hproc != SQL_NULL_HPROC) { switch (fOption) { /* integer attributes */ case SQL_ATTR_ACCESS_MODE: case SQL_ATTR_AUTOCOMMIT: case SQL_ATTR_LOGIN_TIMEOUT: case SQL_ATTR_ODBC_CURSORS: case SQL_ATTR_PACKET_SIZE: case SQL_ATTR_QUIET_MODE: case SQL_ATTR_TRANSLATE_OPTION: case SQL_ATTR_TXN_ISOLATION: CALL_DRIVER (hdbc, pdbc, retcode, hproc, en_SetConnectAttr, (pdbc->dhdbc, fOption, vParam, 0)); break; /* ODBC3 defined options */ case SQL_ATTR_ASYNC_ENABLE: case SQL_ATTR_AUTO_IPD: case SQL_ATTR_CONNECTION_DEAD: case SQL_ATTR_CONNECTION_TIMEOUT: case SQL_ATTR_METADATA_ID: PUSHSQLERR (pdbc->herr, en_IM001); return SQL_ERROR; default: /* string & driver defined */ CALL_DRIVER (hdbc, pdbc, retcode, hproc, en_SetConnectAttr, (pdbc->dhdbc, fOption, vParam, SQL_NTS)); } } else#endif { hproc = _iodbcdm_getproc (pdbc, en_SetConnectOption); if (hproc == SQL_NULL_HPROC) { PUSHSQLERR (pdbc->herr, en_IM001); return SQL_ERROR; } CALL_DRIVER (hdbc, pdbc, retcode, hproc, en_SetConnectOption, (pdbc->dhdbc, fOption, vParam)); } if (retcode != SQL_SUCCESS && retcode != SQL_SUCCESS_WITH_INFO) { return retcode; } } /* * Now, either driver's odbc call was successed or * driver has not been loaded yet. In the first case, we
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -