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

📄 hdbc.c

📁 一个可以替代windows ODBC驱动程序管理器的通用ODBC数据库引擎
💻 C
📖 第 1 页 / 共 2 页
字号:
   * need flip flag for(such as access_mode, autocommit, ...)   * for our finit state machine. While in the second case,    * we need save option values(such as current_qualifier, ...)   * for delaied setting. So, ...   */  /* No matter what state we are(i.e. allocated or connected, ..)   * we need to flip the flag.   */  switch (fOption)    {    case SQL_ACCESS_MODE:      pdbc->access_mode = vParam;      break;    case SQL_AUTOCOMMIT:      pdbc->autocommit = vParam;      break;    }  /* state transition */  if (pdbc->state != en_dbc_allocated)    {      return retcode;    }  /* Only 'allocated' state is possible here, and we need to   * save the options for delaied setting.   */  switch (fOption)    {    case SQL_CURRENT_QUALIFIER:      if (pdbc->current_qualifier != NULL)	{	  MEM_FREE (pdbc->current_qualifier);	}      if (vParam == 0UL)	{	  pdbc->current_qualifier = NULL;	  break;	}      pdbc->current_qualifier	  = (char FAR *) MEM_ALLOC (	  STRLEN (vParam) + 1);      if (pdbc->current_qualifier == NULL)	{	  PUSHSQLERR (pdbc->herr, en_S1001);	  return SQL_ERROR;	}      STRCPY (pdbc->current_qualifier, vParam);      break;    case SQL_LOGIN_TIMEOUT:      pdbc->login_timeout = vParam;      break;    case SQL_ODBC_CURSORS:      pdbc->odbc_cursors = vParam;      break;    case SQL_PACKET_SIZE:      pdbc->packet_size = vParam;      break;    case SQL_QUIET_MODE:      pdbc->quiet_mode = vParam;      break;    case SQL_TXN_ISOLATION:      pdbc->txn_isolation = vParam;      break;    default:      /* Since we didn't save the option value for delaied       * setting, we should raise an error here.       */      break;    }  return retcode;}SQLRETURN SQL_APISQLSetConnectOption (    SQLHDBC hdbc,    SQLUSMALLINT fOption,    SQLUINTEGER vParam){  CONN (pdbc, hdbc);  SQLRETURN retcode;  ENTER_HDBC (pdbc);  retcode = _iodbcdm_SetConnectOption (hdbc, fOption, vParam);  LEAVE_HDBC (pdbc, retcode);}SQLRETURN SQL_API_iodbcdm_GetConnectOption (    SQLHDBC hdbc,    SQLUSMALLINT fOption,    SQLPOINTER pvParam){  CONN (pdbc, hdbc);  int sqlstat = en_00000;  HPROC hproc = SQL_NULL_HPROC;  SQLRETURN retcode;#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 */  switch (pdbc->state)    {    case en_dbc_allocated:      if (fOption != SQL_ACCESS_MODE	  && fOption != SQL_AUTOCOMMIT	  && fOption != SQL_LOGIN_TIMEOUT	  && fOption != SQL_OPT_TRACE	  && fOption != SQL_OPT_TRACEFILE)	{	  sqlstat = en_08003;	}      /* MS ODBC SDK document only       * allows SQL_ACCESS_MODE       * and SQL_AUTOCOMMIT in this       * dbc state. We allow another        * two options, because they        * are only meaningful for driver        * manager.         */      break;    case en_dbc_needdata:      sqlstat = en_S1010;      break;    default:      break;    }  if (sqlstat != en_00000)    {      PUSHSQLERR (pdbc->herr, sqlstat);      return SQL_ERROR;    }  /* Tracing and tracing file options are only    * meaningful for driver manager   */#if (ODBCVER >= 0x0300)  if (fOption == SQL_OPT_TRACE || fOption == SQL_ATTR_TRACE)#else  if (fOption == SQL_OPT_TRACE)#endif    {      if (pdbc->trace)	*((UDWORD *) pvParam) = (UDWORD) SQL_OPT_TRACE_ON;      else	*((UDWORD *) pvParam) = (UDWORD) SQL_OPT_TRACE_OFF;      return SQL_SUCCESS;    }#if (ODBCVER >= 0x0300)  if (fOption == SQL_OPT_TRACEFILE || fOption == SQL_ATTR_TRACEFILE)#else  if (fOption == SQL_OPT_TRACEFILE)#endif    {      STRCPY (pvParam, pdbc->tfile);      return SQL_SUCCESS;    }  if (pdbc->state != en_dbc_allocated)    /* if already connected, we will invoke driver's function */    {#if (ODBCVER >= 0x0300)      hproc = _iodbcdm_getproc (pdbc, en_GetConnectAttr);      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_GetConnectAttr,		  (pdbc->dhdbc, fOption, pvParam, 0, NULL));	      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_GetConnectAttr,		  (pdbc->dhdbc, fOption, pvParam, SQL_MAX_OPTION_STRING_LENGTH, NULL));	    }	}      else#endif	{	  hproc = _iodbcdm_getproc (pdbc, en_GetConnectOption);	  if (hproc == SQL_NULL_HPROC)	    {	      PUSHSQLERR (pdbc->herr, en_IM001);	      return SQL_ERROR;	    }	  CALL_DRIVER (hdbc, pdbc, retcode, hproc, en_GetConnectOption,	      (pdbc->dhdbc, fOption, pvParam));	}      return retcode;    }  /* We needn't to handle options which are not allowed    * to be *get* at a allocated dbc state(and two tracing   * options which has been handled and returned). Thus,    * there are only two possible cases.    */  switch (fOption)    {    case SQL_ACCESS_MODE:      *((UDWORD *) pvParam) = pdbc->access_mode;      break;    case SQL_AUTOCOMMIT:      *((UDWORD *) pvParam) = pdbc->autocommit;      break;    case SQL_LOGIN_TIMEOUT:      *((UDWORD *) pvParam) = pdbc->login_timeout;      break;    default:      break;    }  return SQL_SUCCESS;}SQLRETURN SQL_APISQLGetConnectOption (    SQLHDBC hdbc,    SQLUSMALLINT fOption,    SQLPOINTER pvParam){  CONN (pdbc, hdbc);  SQLRETURN retcode;  ENTER_HDBC (pdbc);  retcode = _iodbcdm_GetConnectOption (hdbc, fOption, pvParam);  LEAVE_HDBC (pdbc, retcode);}static SQLRETURN_iodbcdm_transact (    HDBC hdbc,    UWORD fType){  CONN (pdbc, hdbc);  STMT_t FAR *pstmt;  HPROC hproc;  SQLRETURN retcode;  /* check state */  switch (pdbc->state)    {    case en_dbc_allocated:    case en_dbc_needdata:      PUSHSQLERR (pdbc->herr, en_08003);      return SQL_ERROR;    case en_dbc_connected:      return SQL_SUCCESS;    case en_dbc_hstmt:    default:      break;    }  for (pstmt = (STMT_t FAR *) (pdbc->hstmt);      pstmt != NULL;      pstmt = pstmt->next)    {      if (pstmt->state >= en_stmt_needdata	  || pstmt->asyn_on != en_NullProc)	{	  PUSHSQLERR (pdbc->herr, en_S1010);	  return SQL_ERROR;	}    }  hproc = _iodbcdm_getproc (pdbc, en_Transact);  if (hproc != SQL_NULL_HPROC)    {      CALL_DRIVER (hdbc, pdbc, retcode, hproc, en_Transact,	  (SQL_NULL_HENV, pdbc->dhdbc, fType));    }  else    {#if (ODBCVER >= 0x300)      hproc = _iodbcdm_getproc (pdbc, en_EndTran);      if (hproc != SQL_NULL_HPROC)	{	  CALL_DRIVER (pdbc, pdbc, retcode, hproc, en_EndTran,	      (SQL_HANDLE_DBC, pdbc->dhdbc, fType));	}      else	{	  PUSHSQLERR (pdbc->herr, en_IM001);	  return SQL_ERROR;	}#else      PUSHSQLERR (pdbc->herr, en_IM001);      return SQL_ERROR;#endif    }  /* state transition */  if (retcode != SQL_SUCCESS && retcode != SQL_SUCCESS_WITH_INFO)    {      return retcode;    }  pdbc->state = en_dbc_hstmt;  for (pstmt = (STMT_t FAR *) (pdbc->hstmt);      pstmt != NULL;      pstmt = pstmt->next)    {      switch (pstmt->state)	{	case en_stmt_prepared:	  if (pdbc->cb_commit == SQL_CB_DELETE	      || pdbc->cb_rollback == SQL_CB_DELETE)	    {	      pstmt->state = en_stmt_allocated;	      pstmt->prep_state = 0;	      break;	    }	  break;	case en_stmt_executed:	case en_stmt_cursoropen:	case en_stmt_fetched:	case en_stmt_xfetched:	  if (!pstmt->prep_state	      && pdbc->cb_commit != SQL_CB_PRESERVE	      && pdbc->cb_rollback != SQL_CB_PRESERVE)	    {	      pstmt->state = en_stmt_allocated;	      pstmt->prep_state = 0;	      pstmt->cursor_state = en_stmt_cursor_no;	      break;	    }	  if (pstmt->prep_state)	    {	      if (pdbc->cb_commit == SQL_CB_DELETE		  || pdbc->cb_rollback == SQL_CB_DELETE)		{		  pstmt->state = en_stmt_allocated;		  pstmt->prep_state = 0;		  pstmt->cursor_state = en_stmt_cursor_no;		  break;		}	      if (pdbc->cb_commit == SQL_CB_CLOSE		  || pdbc->cb_rollback == SQL_CB_CLOSE)		{		  pstmt->state		      = en_stmt_prepared;		  pstmt->cursor_state		      = en_stmt_cursor_no;		  break;		}	      break;	    }	  break;	default:	  break;	}    }  return retcode;}SQLRETURN SQL_APISQLTransact (    SQLHENV henv,    SQLHDBC hdbc,    SQLUSMALLINT fType){  GENV (genv, henv);  CONN (pdbc, hdbc);  HERR herr;  SQLRETURN retcode = SQL_SUCCESS;  ODBC_LOCK ();  if (IS_VALID_HDBC (pdbc))    {      CLEAR_ERRORS (pdbc);      herr = pdbc->herr;    }  else if (IS_VALID_HENV (genv))    {      CLEAR_ERRORS (genv);      herr = genv->herr;    }  else    {      ODBC_UNLOCK ();      return SQL_INVALID_HANDLE;    }  /* check argument */  if (fType != SQL_COMMIT && fType != SQL_ROLLBACK)    {      SQLHENV handle = IS_VALID_HDBC (pdbc) ? ((SQLHENV) pdbc) : genv;      PUSHSQLERR (herr, en_S1012);      ODBC_UNLOCK ();      return SQL_ERROR;    }  if (hdbc != SQL_NULL_HDBC)    {      retcode = _iodbcdm_transact (pdbc, fType);    }  else    {      for (pdbc = (DBC_t FAR *) (genv->hdbc); pdbc != NULL; pdbc = pdbc->next)	{	  retcode |= _iodbcdm_transact (pdbc, fType);	}    }  if (retcode != SQL_SUCCESS && retcode != SQL_SUCCESS_WITH_INFO)    {      ODBC_UNLOCK ();      /* fail on one of the connection */      return SQL_ERROR;    }  ODBC_UNLOCK ();  return retcode;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -