⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 hdbc.c

📁 一个可以替代windows ODBC驱动程序管理器的通用ODBC数据库引擎
💻 C
📖 第 1 页 / 共 2 页
字号:
/* *  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 + -