示例#1
0
SQLRETURN SQL_API
SQLFreeEnv (SQLHENV henv)
{
  GENV (genv, henv);
  int retcode = SQL_SUCCESS;

  ODBC_LOCK ();

  TRACE (trace_SQLFreeEnv (TRACE_ENTER, henv));

  retcode = SQLFreeEnv_Internal (henv);

  TRACE (trace_SQLFreeEnv (TRACE_LEAVE, henv));

  MEM_FREE (genv);

  /*
   *  Close trace after last environment handle is freed
   */
  if (--_iodbc_env_counter == 0)
    trace_stop();

  ODBC_UNLOCK ();

  return retcode;
}
示例#2
0
SQLRETURN SQL_API
SQLAllocEnv (SQLHENV * phenv)
{
  GENV (genv, NULL);
  int retcode = SQL_SUCCESS;

  /* 
   *  One time initialization
   */
  Init_iODBC();

  ODBC_LOCK ();
  retcode = SQLAllocEnv_Internal (phenv, SQL_OV_ODBC2);

  genv = (GENV_t *) *phenv;

  /*
   * Start tracing
   */
  TRACE (trace_SQLAllocEnv (TRACE_ENTER, phenv));
  TRACE (trace_SQLAllocEnv (TRACE_LEAVE, phenv));

  ODBC_UNLOCK ();

  return retcode;
}
示例#3
0
SQLRETURN
SQLFreeEnv_Internal (SQLHENV henv)
{
  GENV (genv, henv);

  if (!IS_VALID_HENV (genv))
    {
      return SQL_INVALID_HANDLE;
    }
  CLEAR_ERRORS (genv);

  if (genv->hdbc != SQL_NULL_HDBC)
    {
      PUSHSQLERR (genv->herr, en_S1010);

      return SQL_ERROR;
    }

#if (ODBCVER >= 0x300)
  /* Drop connections from the pool */
  while (genv->pdbc_pool != NULL)
    _iodbcdm_pool_drop_conn (genv->pdbc_pool, NULL);
#endif

  /*
   *  Invalidate this handle
   */
  genv->type = 0;

  return SQL_SUCCESS;
}
示例#4
0
SQLRETURN 
SQLAllocEnv_Internal (SQLHENV * phenv, int odbc_ver)
{
  GENV (genv, NULL);
  int retcode = SQL_SUCCESS;

  genv = (GENV_t *) MEM_ALLOC (sizeof (GENV_t));

  if (genv == NULL)
    {
      *phenv = SQL_NULL_HENV;

      return SQL_ERROR;
    }
  genv->rc = 0;

  /*
   *  Initialize this handle
   */
  genv->type = SQL_HANDLE_ENV;
  genv->henv = SQL_NULL_HENV;	/* driver's env list */
  genv->hdbc = SQL_NULL_HDBC;	/* driver's dbc list */
  genv->herr = SQL_NULL_HERR;	/* err list          */
#if (ODBCVER >= 0x300)
  genv->odbc_ver = odbc_ver;
  genv->connection_pooling = _iodbcdm_attr_connection_pooling;
  genv->cp_match = SQL_CP_MATCH_DEFAULT;
  genv->pdbc_pool = NULL;
#endif
  genv->err_rec = 0;

  *phenv = (SQLHENV) genv;

  /*
   * Initialize tracing 
   */
  if (++_iodbc_env_counter == 1)
    _iodbcdm_env_settracing (genv);

  return retcode;
}
示例#5
0
static SQLRETURN
SQLDescribeParam_Internal (
    SQLHSTMT		  hstmt,
    SQLUSMALLINT	  ipar,
    SQLSMALLINT		* pfSqlType,
    SQLULEN		* pcbColDef,
    SQLSMALLINT		* pibScale, 
    SQLSMALLINT 	* pfNullable)
{
  STMT (pstmt, hstmt);
  CONN (pdbc, pstmt->hdbc);
  GENV (genv, pdbc->genv);

  HPROC hproc;
  SQLRETURN retcode;

  /* check argument */
  if (ipar == 0)
    {
      PUSHSQLERR (pstmt->herr, en_S1093);

      return SQL_ERROR;
    }

  /* check state */
  if (pstmt->asyn_on == en_NullProc)
    {
      switch (pstmt->state)
	{
	case en_stmt_allocated:
	case en_stmt_needdata:
	case en_stmt_mustput:
	case en_stmt_canput:
	  PUSHSQLERR (pstmt->herr, en_S1010);
	  return SQL_ERROR;

	default:
	  break;
	}
    }
  else if (pstmt->asyn_on != en_DescribeParam)
    {
      PUSHSQLERR (pstmt->herr, en_S1010);

      return SQL_ERROR;
    }

  /* call driver */
  hproc = _iodbcdm_getproc (pstmt->hdbc, en_DescribeParam);

  if (hproc == SQL_NULL_HPROC)
    {
      PUSHSQLERR (pstmt->herr, en_IM001);

      return SQL_ERROR;
    }

  CALL_DRIVER (pstmt->hdbc, pstmt, retcode, hproc,
      (pstmt->dhstmt, ipar, pfSqlType, pcbColDef, pibScale, pfNullable));

  /*
   *  Convert sql type to ODBC version of application
   */
  if (SQL_SUCCEEDED(retcode) && pfSqlType)
    *pfSqlType = _iodbcdm_map_sql_type (*pfSqlType, genv->odbc_ver);


  /* state transition */
  if (pstmt->asyn_on == en_DescribeParam)
    {
      switch (retcode)
	{
	case SQL_SUCCESS:
	case SQL_SUCCESS_WITH_INFO:
	case SQL_ERROR:
	  break;

	default:
	  return retcode;
	}
    }

  if (retcode == SQL_STILL_EXECUTING)
    {
      pstmt->asyn_on = en_DescribeParam;
    }

  return retcode;
}
示例#6
0
SQLRETURN SQL_API 
_iodbcdm_sqlerror (
  SQLHENV		  henv,
  SQLHDBC		  hdbc,
  SQLHSTMT		  hstmt,
  SQLPOINTER		  szSqlstate,
  SQLINTEGER		* pfNativeError,
  SQLPOINTER		  szErrorMsg,
  SQLSMALLINT		  cbErrorMsgMax,
  SQLSMALLINT 		* pcbErrorMsg,
  int		  	  bDelete,
  SQLCHAR		  waMode)
{
  GENV (genv, henv);
  CONN (pdbc, hdbc);
  STMT (pstmt, hstmt);
  HDBC thdbc = SQL_NULL_HDBC;

  HENV dhenv = SQL_NULL_HENV;
  HDBC dhdbc = SQL_NULL_HDBC;
  HSTMT dhstmt = SQL_NULL_HSTMT;

  HERR herr = SQL_NULL_HERR;
  HPROC hproc2 = SQL_NULL_HPROC;
  HPROC hproc3 = SQL_NULL_HPROC;
#if (ODBCVER >= 0x0300)  
  SQLINTEGER handleType = 0;
  SQLHANDLE handle3;
  SQLHANDLE dhandle3 = 0;
  SQLSMALLINT *perr_rec = NULL;
#endif
  SWORD unicode_driver = 0;
  SQLUINTEGER dodbc_ver = SQL_OV_ODBC2;	
  SQLUINTEGER odbc_ver = SQL_OV_ODBC2;	
  wchar_t _sqlState[6] = {L"\0"};
  void *SqlstateOut = szSqlstate;
  void *_ErrorMsg = NULL;
  void *errorMsgOut = szErrorMsg;

  void *errmsg = NULL;
  void *ststr = NULL;

  int handle = 0;
  SQLRETURN retcode = SQL_SUCCESS;

  if (IS_VALID_HSTMT (hstmt))	/* retrieve stmt err */
    {
      herr = pstmt->herr;
      thdbc = pstmt->hdbc;

      if (thdbc == SQL_NULL_HDBC)
	{
	  return SQL_INVALID_HANDLE;
	}

#if (ODBCVER >= 0x0300)
      handleType = SQL_HANDLE_STMT;
      handle3 = hstmt;
      dhandle3 = pstmt->dhstmt;
      perr_rec = &((STMT_t *)pstmt)->err_rec;
#endif      
      dhstmt = pstmt->dhstmt;
      handle = 3;
    }
  else if (IS_VALID_HDBC (hdbc))	/* retrieve dbc err */
    {
      herr = pdbc->herr;
      thdbc = pdbc;
      if (thdbc == SQL_NULL_HDBC)
	{
	  return SQL_INVALID_HANDLE;
	}

#if (ODBCVER >= 0x0300)
      handleType = SQL_HANDLE_DBC;
      handle3 = hdbc;
      dhandle3 = pdbc->dhdbc;
      perr_rec = &((DBC_t *)pdbc)->err_rec;
#endif      
      dhdbc = pdbc->dhdbc;
      handle = 2;

      if (herr == SQL_NULL_HERR
	  && pdbc->henv == SQL_NULL_HENV)
	{
	  return SQL_NO_DATA_FOUND;
	}
    }
  else if (IS_VALID_HENV (henv))	/* retrieve env err */
    {
      herr = genv->herr;

      /* Drivers shouldn't push error message 
       * on environment handle */

      if (herr == SQL_NULL_HERR)
	{
	  return SQL_NO_DATA_FOUND;
	}

      handle = 1;
    }
  else
    {
      return SQL_INVALID_HANDLE;
    }

  if (szErrorMsg != NULL)
    {
      if (cbErrorMsgMax < 0)
	{
	  return SQL_ERROR;
	  /* SQLError() doesn't post error for itself */
	}
    }

  if (herr == SQL_NULL_HERR)	/* no err on drv mng */
    {
      if (thdbc && ((DBC_t *)thdbc)->genv)
        odbc_ver = ((GENV_t *) ((DBC_t *)thdbc)->genv)->odbc_ver;

      if (thdbc && ((DBC_t *)thdbc)->henv)
        {
          unicode_driver = ((ENV_t *) ((DBC_t *)thdbc)->henv)->unicode_driver;
          dodbc_ver = ((ENV_t *) ((DBC_t *)thdbc)->henv)->dodbc_ver;
        }

      /* call driver */
      if ((unicode_driver && waMode != 'W') 
          || (!unicode_driver && waMode == 'W'))
        {
          if (waMode != 'W')
            {
            /* ansi=>unicode*/
              if ((_ErrorMsg = malloc(cbErrorMsgMax * sizeof(wchar_t) + 1)) == NULL)
                return SQL_ERROR;
            }
          else
            {
            /* unicode=>ansi*/
              if ((_ErrorMsg = malloc(cbErrorMsgMax + 1)) == NULL)
                return SQL_ERROR;
            }
          errorMsgOut = _ErrorMsg;
          SqlstateOut = _sqlState;
        }
    
      /* call driver */
      if (unicode_driver)
        {
          /* SQL_XXX_W */
          hproc2 = _iodbcdm_getproc (thdbc, en_ErrorW);
#if (ODBCVER >= 0x300)
          hproc3 = _iodbcdm_getproc (thdbc, en_GetDiagRecW);
#endif
        }
      else
        {
          /* SQL_XXX */
          /* SQL_XXX_A */
          hproc2 = _iodbcdm_getproc (thdbc, en_Error);
          if (hproc2 == SQL_NULL_HPROC)
            hproc2 = _iodbcdm_getproc (thdbc, en_ErrorA);
#if (ODBCVER >= 0x300)
          hproc3 = _iodbcdm_getproc (thdbc, en_GetDiagRec);
          if (hproc3 == SQL_NULL_HPROC)
            hproc3 = _iodbcdm_getproc (thdbc, en_GetDiagRecA);
#endif
        }

      if (odbc_ver == SQL_OV_ODBC2 && 
          (  dodbc_ver == SQL_OV_ODBC2
           || (dodbc_ver == SQL_OV_ODBC3 && hproc2 != SQL_NULL_HPROC)))
        hproc3 = SQL_NULL_HPROC;

#if (ODBCVER >= 0x300)
      if (hproc3 != SQL_NULL_HPROC)
        {
          (*perr_rec) = (*perr_rec) + 1;
          CALL_DRIVER (thdbc, NULL, retcode, hproc3, (
                  handleType, 
                  dhandle3, 
                  (*perr_rec),
                  SqlstateOut, 
                  pfNativeError, 
                  errorMsgOut,
                  cbErrorMsgMax, 
                  pcbErrorMsg));
        }
      else
#endif
        {
          if (hproc2 == SQL_NULL_HPROC)
            {
              MEM_FREE(_ErrorMsg);
              return SQL_NO_DATA_FOUND;
            }
           CALL_DRIVER (thdbc, NULL, retcode, hproc2, (
                   dhenv, 
                   dhdbc, 
                   dhstmt, 
                   SqlstateOut, 
                   pfNativeError, 
                   errorMsgOut,
                   cbErrorMsgMax, 
                   pcbErrorMsg));
        }
    
      if (szErrorMsg 
          && SQL_SUCCEEDED (retcode)
          && ((unicode_driver && waMode != 'W') 
              || (!unicode_driver && waMode == 'W')))
        {
          if (waMode != 'W')
            {
            /* ansi<=unicode*/
              dm_StrCopyOut2_W2A ((SQLWCHAR *)errorMsgOut, (SQLCHAR *)szErrorMsg, cbErrorMsgMax, NULL);
              dm_StrCopyOut2_W2A ((SQLWCHAR *)SqlstateOut, (SQLCHAR *)szSqlstate, 6, NULL);
            }
          else
            {
            /* unicode<=ansi*/
              dm_StrCopyOut2_A2W ((SQLCHAR *)errorMsgOut, (SQLWCHAR *)szErrorMsg, cbErrorMsgMax, NULL);
              dm_StrCopyOut2_A2W ((SQLCHAR *)SqlstateOut, (SQLWCHAR *)szSqlstate, 6, NULL);
            }
        }
    
      MEM_FREE(_ErrorMsg);

      return retcode;
    }

  if (szSqlstate != NULL)
    {
      int len;

      /* get sql state  string */
      ststr = (char *) _iodbcdm_getsqlstate (herr,
	  (void *) sqlerrmsg_tab);

      if (ststr == NULL)
	{
	  len = 0;
	}
      else
	{
	  len = (int) STRLEN (ststr);
	}

      /* buffer size of szSqlstate is not checked. Applications
       * suppose provide enough ( not less than 6 bytes ) buffer
       * or NULL for it.
       */
      if (waMode != 'W')
        {	
          STRNCPY (szSqlstate, ststr, len);
          ((char*)szSqlstate)[len] = 0;
        }
      else
        {
          dm_StrCopyOut2_A2W ((SQLCHAR *)ststr, (SQLWCHAR *)szSqlstate, 6, NULL);
          ((wchar_t*)szSqlstate)[len] = 0;
        }
    }

  if (pfNativeError != NULL)
    {
      /* native error code is specific to data source */
      *pfNativeError = (SDWORD) 0L;
    }

  if (szErrorMsg == NULL || cbErrorMsgMax == 0)
    {
      if (pcbErrorMsg != NULL)
	{
	  *pcbErrorMsg = (SWORD) 0;
	}
    }
  else
    {
      int len;
      char msgbuf[256] = {'\0'};

      /* get sql state message */
      errmsg = _iodbcdm_getsqlerrmsg (herr, (void *) sqlerrmsg_tab);

      if (errmsg == NULL)
	{
	  errmsg = (char *) "";
	}

#if defined(HAVE_SNPRINTF)
      snprintf (msgbuf, sizeof(msgbuf), "%s%s", sqlerrhd, (char*)errmsg);
#else
      sprintf (msgbuf, "%s%s", sqlerrhd, (char*)errmsg);
#endif

      len = STRLEN (msgbuf);

      if (len < cbErrorMsgMax - 1)
	{
	  retcode = SQL_SUCCESS;
	}
      else
	{
	  len = cbErrorMsgMax - 1;
	  retcode = SQL_SUCCESS_WITH_INFO;
	  /* and not posts error for itself */
	}

      if (waMode != 'W')
        {
          STRNCPY ((char *) szErrorMsg, msgbuf, len);
          ((char*)szErrorMsg)[len] = 0;
          if (pcbErrorMsg != NULL)
	    *pcbErrorMsg = (SWORD) len;
        }
      else
        {
          dm_StrCopyOut2_A2W ((SQLCHAR *) msgbuf, 
	  	(SQLWCHAR *) szErrorMsg, cbErrorMsgMax, pcbErrorMsg);
        }
    }

  if (bDelete)
    switch (handle)		/* free this err */
      {
	case 1:
	    genv->herr = _iodbcdm_popsqlerr (genv->herr);
	    break;

	case 2:
	    pdbc->herr = _iodbcdm_popsqlerr (pdbc->herr);
	    break;

	case 3:
	    pstmt->herr = _iodbcdm_popsqlerr (pstmt->herr);
	    break;

	default:
	    break;
      }

  return retcode;
}
示例#7
0
RETCODE SQL_API
SQLGetDiagField_Internal (
  SQLSMALLINT		  nHandleType,
  SQLHANDLE		  Handle,
  SQLSMALLINT		  nRecNumber,
  SQLSMALLINT		  nDiagIdentifier,
  SQLPOINTER		  pDiagInfoPtr,
  SQLSMALLINT		  nBufferLength,
  SQLSMALLINT		* pnStringLengthPtr,
  SQLCHAR		  waMode)
{
  GENV (genv, Handle);
  CONN (con, Handle);
  STMT (stmt, Handle);
  DESC (desc, Handle);
  HERR err;
  HPROC hproc = SQL_NULL_HPROC;
  RETCODE retcode = SQL_SUCCESS;
  SQLHANDLE dhandle = SQL_NULL_HANDLE;
  SWORD unicode_driver = 0;
  void *_DiagInfoPtr = NULL;
  void *diagInfoPtr = pDiagInfoPtr;


  switch (nHandleType)
    {
    case SQL_HANDLE_ENV:
      if (!IS_VALID_HENV (Handle))
	{
	  return SQL_INVALID_HANDLE;
	}
      err = genv->herr;
      con = NULL;
      stmt = NULL;
      desc = NULL;
      break;

    case SQL_HANDLE_DBC:
      if (!IS_VALID_HDBC (Handle))
	{
	  return SQL_INVALID_HANDLE;
	}
      err = con->herr;
      genv = (GENV_t *) con->genv;
      stmt = NULL;
      desc = NULL;
      dhandle = con->dhdbc;
      break;

    case SQL_HANDLE_STMT:
      if (!IS_VALID_HSTMT (Handle))
	{
	  return SQL_INVALID_HANDLE;
	}
      err = stmt->herr;
      con = (DBC_t *) stmt->hdbc;
      genv = (GENV_t *) con->genv;
      desc = NULL;
      dhandle = stmt->dhstmt;
      break;

    case SQL_HANDLE_DESC:
      if (!IS_VALID_HDESC (Handle))
	{
	  return SQL_INVALID_HANDLE;
	}
      err = desc->herr;
      stmt = (STMT_t *) desc->hstmt;
      con = (DBC_t *) desc->hdbc;
      genv = (GENV_t *) con->genv;
      dhandle = desc->dhdesc;
      break;

    default:
      return SQL_INVALID_HANDLE;
    }

  if (con != NULL && con->henv != SQL_NULL_HENV)
    unicode_driver = ((ENV_t *) con->henv)->unicode_driver;

  switch (nRecNumber)
    {

    case 0:			/* Header record */
      switch (nDiagIdentifier)
	{
	case SQL_DIAG_ROW_COUNT:
	  {
	    if (nHandleType != SQL_HANDLE_STMT || !stmt)
	      {
		return SQL_ERROR;
	      }

	    if (stmt->state != en_stmt_executed_with_info &&
	    	stmt->state != en_stmt_executed &&
		stmt->state != en_stmt_cursoropen)
	      {
		return SQL_ERROR;
	      }
	    if (!con)
	      {
		return SQL_INVALID_HANDLE;
	      }

            CALL_UDRIVER(con, stmt, retcode, hproc, unicode_driver, en_GetDiagField,
              (SQL_HANDLE_DBC, stmt->dhstmt, nRecNumber, nDiagIdentifier, 
               pDiagInfoPtr, nBufferLength, pnStringLengthPtr ));
            if (hproc == SQL_NULL_HPROC)
              {
		if (!con)
		  {
		    return SQL_INVALID_HANDLE;
		  }
		hproc = _iodbcdm_getproc (con, en_RowCount);
		if (!hproc)
		  {
		    return SQL_ERROR;
		  }
		CALL_DRIVER (stmt->hdbc, stmt, retcode, hproc,
		    (stmt->dhstmt, pDiagInfoPtr));
              }
	    return retcode;
	  }

	case SQL_DIAG_CURSOR_ROW_COUNT:
	case SQL_DIAG_DYNAMIC_FUNCTION:
	case SQL_DIAG_DYNAMIC_FUNCTION_CODE:

	  {
	    if (nHandleType != SQL_HANDLE_STMT || !stmt)
	      {
		return SQL_ERROR;
	      }

	    if (stmt->state != en_stmt_executed_with_info &&
	    	stmt->state != en_stmt_executed &&
		stmt->state != en_stmt_cursoropen)
	      {
		return SQL_ERROR;
	      }
	    if (!con)
	      {
		return SQL_INVALID_HANDLE;
	      }

            CALL_UDRIVER(con, stmt, retcode, hproc, unicode_driver, en_GetDiagField,
              (SQL_HANDLE_DBC, stmt->dhstmt, nRecNumber, nDiagIdentifier, 
               pDiagInfoPtr, nBufferLength, pnStringLengthPtr ));
            if (hproc == SQL_NULL_HPROC)
              return SQL_ERROR;
            else
	      return retcode;
	  }

	case SQL_DIAG_RETURNCODE:

	  if (pDiagInfoPtr)
	    *((SQLRETURN *) pDiagInfoPtr) = ((GENV_t *) Handle)->rc;
	  {
	    return SQL_SUCCESS;
	  }

	case SQL_DIAG_NUMBER:

	  if (pDiagInfoPtr)
	    {
	      (*(SQLINTEGER *) pDiagInfoPtr) = 0;
	      /* get the number from the driver */
	      if (con)
		{
                  CALL_UDRIVER(con, Handle, retcode, hproc, unicode_driver, en_GetDiagField,
                    (nHandleType, dhandle, 0, nDiagIdentifier, 
                     pDiagInfoPtr, nBufferLength, pnStringLengthPtr ));
                  if (hproc != SQL_NULL_HPROC)
                    {
		      if (retcode != SQL_SUCCESS)
			{
			  return retcode;
			}

		      /* and add the DM's value */
		      (*(SQLINTEGER *) pDiagInfoPtr) += error_rec_count (err);
                    }
		  else if (((ENV_t *) con->henv)->dodbc_ver == SQL_OV_ODBC2 &&
		      ((GENV_t *) Handle)->rc)
		    {		/* ODBC2 drivers can only have one error */
		      (*(SQLINTEGER *) pDiagInfoPtr) = 1;
		    }
		}
	      else if (genv)
		{
		  (*(SQLINTEGER *) pDiagInfoPtr) = error_rec_count (err);
		}

	    }
	  break;

	default:
	  return SQL_ERROR;
	}
      break;

    default:			/* status records */
      {
	int nRecs = 0;

	if (nRecNumber < 1)
	  {
	    return SQL_ERROR;
	  }
	nRecs = error_rec_count (err);
	if (nRecNumber <= nRecs)
	  {			/* DM Errors */
	    char *szval = "";
	    int ival = 0;
	    int isInt = 0;
	    sqlerr_t *rec = NULL;

	    rec = get_nth_error (err, nRecNumber - 1);

	    if (!rec)
	      {
		return (SQL_NO_DATA_FOUND);
	      }

	    switch (nDiagIdentifier)
	      {

	      case SQL_DIAG_SUBCLASS_ORIGIN:
	      case SQL_DIAG_CLASS_ORIGIN:
		isInt = 0;

		szval = (rec->code >= en_HY001
		    && rec->code <= en_IM014) ? (char *) "ODBC 3.0" : (char *) "ISO 9075";
		break;

	      case SQL_DIAG_COLUMN_NUMBER:

		if (nHandleType != SQL_HANDLE_STMT || !stmt)
		  {
		    return SQL_ERROR;
		  }
		if (!con)
		  {
		    return SQL_INVALID_HANDLE;
		  }

		if (pDiagInfoPtr)
		  *((SQLINTEGER *) pDiagInfoPtr) = SQL_COLUMN_NUMBER_UNKNOWN;

		return SQL_SUCCESS;

	      case SQL_DIAG_CONNECTION_NAME:
	      case SQL_DIAG_SERVER_NAME:

		isInt = 0;
		if (con)
		  {
		    if (waMode != 'W')
		       retcode = SQLGetInfo (con, SQL_DATA_SOURCE_NAME, 
		          pDiagInfoPtr,	nBufferLength, pnStringLengthPtr);
		    else
		       retcode = SQLGetInfoW (con, SQL_DATA_SOURCE_NAME, 
		          pDiagInfoPtr,	nBufferLength, pnStringLengthPtr);

		    return retcode;
		  }
		else
		  break;

	      case SQL_DIAG_MESSAGE_TEXT:

		isInt = 0;
		szval =
		    _iodbcdm_getsqlerrmsg (rec, (void *) sqlerrmsg_tab);
		break;

	      case SQL_DIAG_NATIVE:

		isInt = 1;
		ival = 0;
		break;

	      case SQL_DIAG_ROW_NUMBER:

		isInt = 1;
		if (nHandleType != SQL_HANDLE_STMT || !stmt)
		  {
		    return SQL_ERROR;
		  }
		if (!con)
		  {
		    return SQL_INVALID_HANDLE;
		  }
                CALL_UDRIVER(con, Handle, retcode, hproc, unicode_driver, en_GetDiagField,
                  (nHandleType, dhandle, nRecNumber, nDiagIdentifier, 
                   pDiagInfoPtr, nBufferLength, pnStringLengthPtr ));
               if (hproc != SQL_NULL_HPROC)
                 {
		    return retcode;
                 }
               else
                 {
		    ival = SQL_ROW_NUMBER_UNKNOWN;
		    break;
                 }

	      case SQL_DIAG_SQLSTATE:

		isInt = 0;
		szval = _iodbcdm_getsqlstate (rec, (void *) sqlerrmsg_tab);
		break;

	      default:
		return SQL_ERROR;
	      }
	    if (isInt)
	      {
		if (pDiagInfoPtr)
		  *((SQLINTEGER *) pDiagInfoPtr) = ival;
	      }
	    else
	      {
	        if (waMode != 'W')
	          {
		    int len = strlen (szval), len1;
		    len1 = len > nBufferLength ? nBufferLength : len;
		    if (pnStringLengthPtr)
		      *pnStringLengthPtr = len;
		    if (pDiagInfoPtr)
		      {
		        STRNCPY (pDiagInfoPtr, szval, len1);
		        *(((SQLCHAR *) pDiagInfoPtr) + len1) = 0;
		      }
		  }
		else
		  {
		    dm_StrCopyOut2_A2W((SQLCHAR *) szval, 
		    	(SQLWCHAR *) pDiagInfoPtr, nBufferLength, pnStringLengthPtr);
		  }
	      
	      }
	    break;
	  }
	else
	  {			/* Driver's errors */
	    nRecNumber -= nRecs;

	    if (!con)
	      {
		return SQL_NO_DATA_FOUND;
	      }

            if ((unicode_driver && waMode != 'W') 
                || (!unicode_driver && waMode == 'W'))
              {
                switch(nDiagIdentifier)
                  {
                  case SQL_DIAG_DYNAMIC_FUNCTION:
                  case SQL_DIAG_CLASS_ORIGIN:
                  case SQL_DIAG_CONNECTION_NAME:
                  case SQL_DIAG_MESSAGE_TEXT:
                  case SQL_DIAG_SERVER_NAME:
                  case SQL_DIAG_SQLSTATE:
                  case SQL_DIAG_SUBCLASS_ORIGIN:
                    if (waMode != 'W')
                      {
                      /* ansi=>unicode*/
                        if ((_DiagInfoPtr = malloc((nBufferLength + 1) * 
                               sizeof(wchar_t))) == NULL)
                          {
                            return SQL_ERROR;
                          }
                      }
                    else
                      {
                      /* unicode=>ansi*/
                        if ((_DiagInfoPtr = malloc(nBufferLength + 1)) == NULL)
                          {
                            return SQL_ERROR;
                          }
                      }
                    diagInfoPtr = _DiagInfoPtr;
                    break;
                  }
              }

            CALL_UDRIVER(con, Handle, retcode, hproc, unicode_driver, en_GetDiagField,
              (nHandleType, dhandle, nRecNumber, nDiagIdentifier, 
               diagInfoPtr, nBufferLength, pnStringLengthPtr ));
            if (hproc != SQL_NULL_HPROC)
              {
                if (pDiagInfoPtr
                    && SQL_SUCCEEDED (retcode)
                    && ((unicode_driver && waMode != 'W')
                        || (!unicode_driver && waMode == 'W')))
                  {
                    switch(nDiagIdentifier)
                      {
                      case SQL_DIAG_DYNAMIC_FUNCTION:
                      case SQL_DIAG_CLASS_ORIGIN:
                      case SQL_DIAG_CONNECTION_NAME:
                      case SQL_DIAG_MESSAGE_TEXT:
                      case SQL_DIAG_SERVER_NAME:
                      case SQL_DIAG_SQLSTATE:
                      case SQL_DIAG_SUBCLASS_ORIGIN:
                        if (waMode != 'W')
                          {
                          /* ansi<=unicode*/
                            dm_StrCopyOut2_W2A ((SQLWCHAR *) diagInfoPtr, 
				(SQLCHAR *) pDiagInfoPtr, 
				nBufferLength, pnStringLengthPtr);
                          }
                        else
                          {
                          /* unicode<=ansi*/
                            dm_StrCopyOut2_A2W ((SQLCHAR *)diagInfoPtr, 
			    	(SQLWCHAR *) pDiagInfoPtr, 
				nBufferLength, pnStringLengthPtr);
                          }
                      }
                  }

                MEM_FREE(_DiagInfoPtr);
		return retcode;
              }
            else
	      {			/* an ODBC2->ODBC3 translation */
		char *szval = "";
		wchar_t szState[6];
		SQLINTEGER nNative;

		if (nRecNumber > 1)
		  {
                    MEM_FREE(_DiagInfoPtr);
		    return SQL_NO_DATA_FOUND;
		  }

		if (nHandleType == SQL_HANDLE_DESC)
		  {
                    MEM_FREE(_DiagInfoPtr);
		    return SQL_INVALID_HANDLE;
		  }

		if (nDiagIdentifier != SQL_DIAG_MESSAGE_TEXT)
                   MEM_FREE(_DiagInfoPtr);

		switch (nDiagIdentifier)
		  {
		  case SQL_DIAG_SUBCLASS_ORIGIN:
		  case SQL_DIAG_CLASS_ORIGIN:
		    
		    CALL_UDRIVER (con, Handle, retcode, hproc, unicode_driver,
		      en_Error, (SQL_NULL_HENV,
		       nHandleType == SQL_HANDLE_DBC ? dhandle : SQL_NULL_HDBC,
		       nHandleType == SQL_HANDLE_STMT ? dhandle : SQL_NULL_HSTMT,
 		       szState, &nNative, NULL, 0, NULL));
                    if (hproc == SQL_NULL_HPROC)
                      {
		        return SQL_INVALID_HANDLE;
                      }
		    if (retcode != SQL_SUCCESS)
		      {
			return SQL_NO_DATA_FOUND;
		      }
		    if (waMode != 'W')
                      {
		        szval = !STRNEQ (szState, "IM", 2) ? (char *) "ODBC 3.0" : (char *) "ISO 9075";
                      }
		    else
                      {
                        if (szState[0] != L'I' && szState[1] != L'M')
		          szval = (char *) "ODBC 3.0";
                        else
		          szval = (char *) "ISO 9075";
                      }
		    break;

		  case SQL_DIAG_ROW_NUMBER:
		  case SQL_DIAG_COLUMN_NUMBER:
		    if (nHandleType != SQL_HANDLE_STMT || !stmt)
		      {
			return SQL_ERROR;
		      }
		    if (!con)
		      {
			return SQL_INVALID_HANDLE;
		      }
		    if (pDiagInfoPtr)
		      *((SQLINTEGER *) pDiagInfoPtr) =
			  SQL_COLUMN_NUMBER_UNKNOWN;
		    {
		      return SQL_SUCCESS;
		    }

		  case SQL_DIAG_SERVER_NAME:
		  case SQL_DIAG_CONNECTION_NAME:
		    break;

		  case SQL_DIAG_MESSAGE_TEXT:
		    CALL_UDRIVER (con, Handle, retcode, hproc, unicode_driver,
		      en_Error, (SQL_NULL_HENV,
		      nHandleType == SQL_HANDLE_DBC ? dhandle : SQL_NULL_HDBC,
		      nHandleType == SQL_HANDLE_STMT ? dhandle : SQL_NULL_HSTMT,
 		      szState, &nNative, diagInfoPtr, nBufferLength, 
 		      pnStringLengthPtr));
                    if (hproc == SQL_NULL_HPROC)
                      {
                        MEM_FREE(_DiagInfoPtr);
		        return SQL_INVALID_HANDLE;
                      }
                    if (pDiagInfoPtr
                        && SQL_SUCCEEDED (retcode)
                        && ((unicode_driver && waMode != 'W')
                            || (!unicode_driver && waMode == 'W')))
                      {
                        if (waMode != 'W')
                          {
                          /* ansi<=unicode*/
                            dm_StrCopyOut2_W2A ((SQLWCHAR *) diagInfoPtr, 
				(SQLCHAR *) pDiagInfoPtr, 
		      		nBufferLength, pnStringLengthPtr);
                          }
                        else
                          {
                          /* unicode<=ansi*/
                            dm_StrCopyOut2_A2W ((SQLCHAR *)diagInfoPtr, 
			    	(SQLWCHAR *) pDiagInfoPtr, 
				nBufferLength, pnStringLengthPtr);
                          }
                      }

                    MEM_FREE(_DiagInfoPtr);
		    return retcode;

		  case SQL_DIAG_NATIVE:
		    CALL_UDRIVER (con, Handle, retcode, hproc, unicode_driver,
		      en_Error, (SQL_NULL_HENV,
		      nHandleType == SQL_HANDLE_DBC ? dhandle : SQL_NULL_HDBC,
		      nHandleType == SQL_HANDLE_STMT ? dhandle : SQL_NULL_HSTMT,
 		      szState, &nNative, NULL, 0, NULL));
                    if (hproc == SQL_NULL_HPROC)
                      {
		        return SQL_INVALID_HANDLE;
                      }
		    if (pDiagInfoPtr)
		      *((SQLINTEGER *) pDiagInfoPtr) = nNative;
		    return retcode;

		  case SQL_DIAG_SQLSTATE:
		    CALL_UDRIVER (con, Handle, retcode, hproc, unicode_driver,
		      en_Error, (SQL_NULL_HENV,
		      nHandleType == SQL_HANDLE_DBC ? dhandle : SQL_NULL_HDBC,
		      nHandleType == SQL_HANDLE_STMT ? dhandle : SQL_NULL_HSTMT,
 		      szState, &nNative, NULL, 0, NULL));
                    if (hproc == SQL_NULL_HPROC)
                      {
		        return SQL_INVALID_HANDLE;
                      }
                    if (pDiagInfoPtr
                        && SQL_SUCCEEDED (retcode)
                        && ((unicode_driver && waMode != 'W')
                            || (!unicode_driver && waMode == 'W')))
                      {
                        if (waMode != 'W')
                          {
                          /* ansi<=unicode*/
                            dm_StrCopyOut2_W2A ((SQLWCHAR *) szState, 
				(SQLCHAR *) pDiagInfoPtr, 
		      		nBufferLength, pnStringLengthPtr);
                          }
                        else
                          {
                          /* unicode<=ansi*/
                            dm_StrCopyOut2_A2W ((SQLCHAR *)szState, 
			    	(SQLWCHAR *) pDiagInfoPtr, 
				nBufferLength, pnStringLengthPtr);
                          }
                      }

		    return retcode;

		  default:
		    return SQL_ERROR;
		  }

	        if (waMode != 'W')
	          {
		    if (pDiagInfoPtr)
		      {
		        int len = strlen (szval);
		        if (len > nBufferLength)
		          len = nBufferLength;
		        if (len)
		          _iodbcdm_strlcpy ((char *) pDiagInfoPtr, szval, len);
		      }
		    if (pnStringLengthPtr)
		      *pnStringLengthPtr = strlen (szval);
		  }
		else
		  {
		    dm_StrCopyOut2_A2W((SQLCHAR *) szval, 
		    	(SQLWCHAR *) pDiagInfoPtr, 
			nBufferLength, pnStringLengthPtr);
		  }
	      }			/* ODBC3->ODBC2 */
	  }			/* driver's errors */
      }				/* status records */
    }				/* switch (nRecNumber */
  return (SQL_SUCCESS);
}
示例#8
0
SQLRETURN SQL_API
SQLDrivers_Internal (
  SQLHENV		  henv,
  SQLUSMALLINT		  fDir,
  SQLPOINTER		  szDrvDesc,
  SQLSMALLINT		  cbDrvDescMax,
  SQLSMALLINT 		* pcbDrvDesc,
  SQLPOINTER		  szDrvAttr,
  SQLSMALLINT		  cbDrvAttrMax,
  SQLSMALLINT 		* pcbDrvAttr,
  SQLCHAR		  waMode)
{
  GENV (genv, henv);
  char buffer[4096], desc[1024], *ptr;
  int i, j, usernum = 0;
  static int cur_entry = -1;
  static int num_entries = 0;
  static void **sect = NULL;
  SQLUSMALLINT fDirOld = fDir;

  waMode = waMode; /*UNUSED*/

  /* check argument */
  if (cbDrvDescMax < 0 || cbDrvAttrMax < 0)
    {
      PUSHSQLERR (genv->herr, en_S1090);
      return SQL_ERROR;
    }

  if (fDir != SQL_FETCH_FIRST && fDir != SQL_FETCH_NEXT)
    {
      PUSHSQLERR (genv->herr, en_S1103);
      return SQL_ERROR;
    }

  if (cur_entry < 0 || fDir == SQL_FETCH_FIRST)
    {
      cur_entry = 0;
      num_entries = 0;

      /*
      *  Free old section list
      */
      if (sect)
	{
	  for (i = 0; i < MAX_ENTRIES; i++)
	    if (sect[i])
	      free (sect[i]);
	  free (sect);
	}
      if ((sect = (void **) calloc (MAX_ENTRIES, sizeof (void *))) == NULL)
	{
	  PUSHSQLERR (genv->herr, en_S1011);
	  return SQL_ERROR;
	}

      if (fDirOld == SQL_FETCH_FIRST)
        fDir = SQL_FETCH_FIRST_USER;

      do {
        SQLSetConfigMode (fDir == SQL_FETCH_FIRST_SYSTEM ? ODBC_SYSTEM_DSN : ODBC_USER_DSN);
        SQLGetPrivateProfileString (SECT2, NULL, "", buffer, sizeof(buffer) / sizeof(SQLTCHAR), "odbcinst.ini");

        /* For each datasources */
        for(ptr = buffer, i = 1 ; *ptr && i ; ptr += STRLEN(ptr) + 1)
          {
            /* Add this section to the datasources list */
            if (fDirOld == SQL_FETCH_FIRST && fDir == SQL_FETCH_FIRST_SYSTEM)
              {
                for(j = 0 ; j<usernum ; j++)
                  {
                    if(STREQ(sect[j<<1], ptr))
                      j = usernum;
                  }
                if(j == usernum + 1)
                  continue;
              }

            if ((num_entries << 1) >= MAX_ENTRIES)
              {
                i = 0;
                break;
              }			/* Skip the rest */

            /* ... and its description */
            SQLSetConfigMode (fDir == SQL_FETCH_FIRST_SYSTEM ? ODBC_SYSTEM_DSN : ODBC_USER_DSN);
            SQLGetPrivateProfileString (SECT2, ptr, "", desc, sizeof(desc) / sizeof(SQLTCHAR), "odbcinst.ini");

            /* Check if the driver is installed */
				if(!STRCASEEQ(desc, "Installed"))
				  continue;

            /* Copy the driver name */
            sect[num_entries<<1] = STRDUP (ptr);
            sect[(num_entries++<<1) + 1] = STRDUP (desc);
          }

        switch(fDir)
          {
            case SQL_FETCH_FIRST_USER:
              fDir = SQL_FETCH_FIRST_SYSTEM;
              usernum = num_entries;
              break;
            case SQL_FETCH_FIRST_SYSTEM:
              fDir = SQL_FETCH_FIRST;
              break;
          };
      } while (fDir!=SQL_FETCH_FIRST && fDirOld==SQL_FETCH_FIRST);

      fDir = fDirOld;

      /*
       *  Sort all entries so we can present a nice list
       */
      if (num_entries > 1)
	{
          qsort (sect, num_entries, sizeof (char **) + sizeof (char **),
            SectSorter);
	}
    }

  /*
   *  Try to get to the next item
   */
  if (cur_entry >= num_entries)
    {
      cur_entry = 0;		/* Next time, start all over again */
      return SQL_NO_DATA_FOUND;
    }

  /*
   *  Copy Driver information 
   */
  STRNCPY (szDrvDesc, sect[cur_entry << 1], cbDrvDescMax);

  if (pcbDrvDesc)
    *pcbDrvDesc = STRLEN (szDrvDesc);

  /*
   *  And find the description that goes with this entry
   */
  STRNCPY (szDrvAttr, sect[(cur_entry << 1) + 1], cbDrvAttrMax);

  if (pcbDrvAttr)
    *pcbDrvAttr = STRLEN (szDrvAttr);

  /*
   *  Next record
   */
  cur_entry++;

  return SQL_SUCCESS;
}