connect.c

来自「A*算法 A*算法 A*算法 A*算法A*算法A*算法」· C语言 代码 · 共 1,242 行 · 第 1/2 页

C
1,242
字号
{
  DBC_t FAR *pdbc = (DBC_t FAR *) hdbc;
  RETCODE retcode = SQL_SUCCESS;
  RETCODE setopterr = SQL_SUCCESS;
  char driver[1024] = {'\0'};	/* MS SDK Guide 
				 * specifies driver
				 * path can't longer
				 * than 255. */
  char *ptr;
  HPROC hproc;

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

  /* check arguments */
  if ((cbDSN < 0 && cbDSN != SQL_NTS)
      || (cbUID < 0 && cbUID != SQL_NTS)
      || (cbAuthStr < 0 && cbAuthStr != SQL_NTS)
      || (cbDSN > SQL_MAX_DSN_LENGTH))
    {
      PUSHSQLERR (pdbc->herr, en_S1090);

      return SQL_ERROR;
    }

  if (szDSN == NULL || cbDSN == 0)
    {
      PUSHSQLERR (pdbc->herr, en_IM002);

      return SQL_ERROR;
    }

  /* check state */
  if (pdbc->state != en_dbc_allocated)
    {
      PUSHSQLERR (pdbc->herr, en_08002);

      return SQL_ERROR;
    }

  setopterr |= _iodbcdm_settracing (hdbc,
      (char *) szDSN, cbDSN);

  ptr = _iodbcdm_getkeyvalbydsn (szDSN, cbDSN, "Driver",
      (char FAR *) driver, sizeof (driver));

  if (ptr == NULL)
    /* No specified or default dsn section or
     * no driver specification in this dsn section */
    {
      PUSHSQLERR (pdbc->herr, en_IM002);

      return SQL_ERROR;
    }

  retcode = _iodbcdm_driverload (driver, hdbc);

  switch (retcode)
     {
     case SQL_SUCCESS:
       break;

     case SQL_SUCCESS_WITH_INFO:
       setopterr = SQL_ERROR;
       /* unsuccessed in calling driver's 
        * SQLSetConnectOption() to set login
        * timeout.
        */
       break;

     default:
       return retcode;
     }

  hproc = _iodbcdm_getproc (hdbc, en_Connect);

  if (hproc == SQL_NULL_HPROC)
    {
      _iodbcdm_driverunload (hdbc);

      PUSHSQLERR (pdbc->herr, en_IM001);

      return SQL_ERROR;
    }

  CALL_DRIVER (hdbc, retcode, hproc, en_Connect, (
	  pdbc->dhdbc,
	  szDSN, cbDSN,
	  szUID, cbUID,
	  szAuthStr, cbAuthStr))

  if (retcode != SQL_SUCCESS
      && retcode != SQL_SUCCESS_WITH_INFO)
    {
      /* not unload driver for retrive error 
       * messge from driver */
		/*********
		_iodbcdm_driverunload( hdbc );
		**********/

      return retcode;
    }

  /* state transition */
  pdbc->state = en_dbc_connected;

  /* do delaid option setting */
  setopterr |= _iodbcdm_dbcdelayset (hdbc);

  if (setopterr != SQL_SUCCESS)
    {
      return SQL_SUCCESS_WITH_INFO;
    }

  return retcode;
}


RETCODE SQL_API 
SQLDriverConnect (
    HDBC hdbc,
    SQLHWND hwnd,
    UCHAR FAR * szConnStrIn,
    SWORD cbConnStrIn,
    UCHAR FAR * szConnStrOut,
    SWORD cbConnStrOutMax,
    SWORD FAR * pcbConnStrOut,
    UWORD fDriverCompletion)
{
  DBC_t FAR *pdbc = (DBC_t FAR *) hdbc;
  HDLL hdll;
  char FAR *drv;
  char drvbuf[1024];
  char FAR *dsn;
  char dsnbuf[SQL_MAX_DSN_LENGTH + 1];
  UCHAR cnstr2drv[1024];

  HPROC hproc;
  HPROC dialproc;

  int sqlstat = en_00000;
  RETCODE retcode = SQL_SUCCESS;
  RETCODE setopterr = SQL_SUCCESS;

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

  /* check arguments */
  if ((cbConnStrIn < 0 && cbConnStrIn != SQL_NTS)
      || cbConnStrOutMax < 0)
    {
      PUSHSQLERR (pdbc->herr, en_S1090);

      return SQL_ERROR;
    }

  /* check state */
  if (pdbc->state != en_dbc_allocated)
    {
      PUSHSQLERR (pdbc->herr, en_08002);

      return SQL_ERROR;
    }

  drv = _iodbcdm_getkeyvalinstr (szConnStrIn, cbConnStrIn,
      "DRIVER", drvbuf, sizeof (drvbuf));

  dsn = _iodbcdm_getkeyvalinstr (szConnStrIn, cbConnStrIn,
      "DSN", dsnbuf, sizeof (dsnbuf));

  switch (fDriverCompletion)
     {
     case SQL_DRIVER_NOPROMPT:
       break;

     case SQL_DRIVER_COMPLETE:
     case SQL_DRIVER_COMPLETE_REQUIRED:
       if (dsn != NULL || drv != NULL)
	 {
	   break;
	 }
       /* fall to next case */
     case SQL_DRIVER_PROMPT:
       /* Get data source dialog box function from
        * current executable */
       hdll = _iodbcdm_dllopen ((char FAR *) NULL);
       dialproc = _iodbcdm_dllproc (hdll,
	   "_iodbcdm_drvconn_dialbox");

       if (dialproc == SQL_NULL_HPROC)
	 {
	   sqlstat = en_IM008;
	   break;
	 }

       retcode = dialproc (
	   hwnd,		/* window or display handle */
	   dsnbuf,		/* input/output dsn buf */
	   sizeof (dsnbuf),	/* buf size */
	   &sqlstat);		/* error code */

       if (retcode != SQL_SUCCESS)
	 {
	   break;
	 }

       if (cbConnStrIn == SQL_NTS)
	 {
	   cbConnStrIn = STRLEN (szConnStrIn);
	 }

       dsn = dsnbuf;

       if (dsn[0] == '\0')
	 {
	   dsn = "default";
	 }

       if (cbConnStrIn > sizeof (cnstr2drv)
	   - STRLEN (dsn) - STRLEN ("DSN=;") - 1)
	 {
	   sqlstat = en_S1001;	/* a lazy way to avoid
				 * using heap memory */
	   break;
	 }

       sprintf ((char*)cnstr2drv, "DSN=%s;", dsn);
       cbConnStrIn += STRLEN (cnstr2drv);
       STRNCAT (cnstr2drv, szConnStrIn, cbConnStrIn);
       szConnStrIn = cnstr2drv;
       break;

     default:
       sqlstat = en_S1110;
       break;
     }

  if (sqlstat != en_00000)
    {
      PUSHSQLERR (pdbc->herr, sqlstat);

      return SQL_ERROR;
    }

  if (dsn == NULL || dsn[0] == '\0')
    {
      dsn = "default";
    }
  else
    /* if you want tracing, you must use a DSN */
    {
      setopterr |= _iodbcdm_settracing (hdbc,
	  (char *) dsn, SQL_NTS);
    }

  if (drv == NULL || drv[0] == '\0')
    {
      drv = _iodbcdm_getkeyvalbydsn (dsn, SQL_NTS, "Driver",
	  drvbuf, sizeof (drvbuf));
    }

  if (drv == NULL)
    {
      PUSHSQLERR (pdbc->herr, en_IM002);

      return SQL_ERROR;
    }

  retcode = _iodbcdm_driverload (drv, hdbc);

  switch (retcode)
     {
     case SQL_SUCCESS:
       break;

     case SQL_SUCCESS_WITH_INFO:
       setopterr = SQL_ERROR;
       /* unsuccessed in calling driver's 
        * SQLSetConnectOption() to set login
        * timeout.
        */
       break;

     default:
       return retcode;
     }

  hproc = _iodbcdm_getproc (hdbc, en_DriverConnect);

  if (hproc == SQL_NULL_HPROC)
    {
      _iodbcdm_driverunload (hdbc);

      PUSHSQLERR (pdbc->herr, en_IM001);

      return SQL_ERROR;
    }

  CALL_DRIVER (hdbc, retcode, hproc, en_DriverConnect, (
	  pdbc->dhdbc, hwnd,
	  szConnStrIn, cbConnStrIn,
	  szConnStrOut, cbConnStrOutMax,
	  pcbConnStrOut, fDriverCompletion))

  if (retcode != SQL_SUCCESS && retcode != SQL_SUCCESS_WITH_INFO)
    {
      /* don't unload driver here for retrive 
       * error message from driver */
		/********
		_iodbcdm_driverunload( hdbc );
		*********/

      return retcode;
    }

  /* state transition */
  pdbc->state = en_dbc_connected;

  /* do delaid option setting */
  setopterr |= _iodbcdm_dbcdelayset (hdbc);

  if (setopterr != SQL_SUCCESS)
    {
      return SQL_SUCCESS_WITH_INFO;
    }

  return retcode;
}


RETCODE SQL_API 
SQLBrowseConnect (
    HDBC hdbc,
    UCHAR FAR * szConnStrIn,
    SWORD cbConnStrIn,
    UCHAR FAR * szConnStrOut,
    SWORD cbConnStrOutMax,
    SWORD FAR * pcbConnStrOut)
{
  DBC_t FAR *pdbc = (DBC_t FAR *) hdbc;
  char FAR *drv;
  char drvbuf[1024];
  char FAR *dsn;
  char dsnbuf[SQL_MAX_DSN_LENGTH + 1];

  HPROC hproc;

  RETCODE retcode = SQL_SUCCESS;
  RETCODE setopterr = SQL_SUCCESS;

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

  /* check arguments */
  if ((cbConnStrIn < 0 && cbConnStrIn != SQL_NTS) || cbConnStrOutMax < 0)
    {
      PUSHSQLERR (pdbc->herr, en_S1090);

      return SQL_ERROR;
    }

  if (pdbc->state == en_dbc_allocated)
    {
      drv = _iodbcdm_getkeyvalinstr (szConnStrIn, cbConnStrIn,
	  "DRIVER", drvbuf, sizeof (drvbuf));

      dsn = _iodbcdm_getkeyvalinstr (szConnStrIn, cbConnStrIn,
	  "DSN", dsnbuf, sizeof (dsnbuf));

      if (dsn == NULL || dsn[0] == '\0')
	{
	  dsn = "default";
	}
      else
	/* if you want tracing, you must use a DSN */
	{
	  setopterr |= _iodbcdm_settracing (hdbc,
	      (char *) dsn, SQL_NTS);
	}

      if (drv == NULL || drv[0] == '\0')
	{
	  drv = _iodbcdm_getkeyvalbydsn (dsn, SQL_NTS, "Driver",
	      drvbuf, sizeof (drvbuf));
	}

      if (drv == NULL)
	{
	  PUSHSQLERR (pdbc->herr, en_IM002);

	  return SQL_ERROR;
	}

      retcode = _iodbcdm_driverload (drv, hdbc);

      switch (retcode)
	 {
	 case SQL_SUCCESS:
	   break;

	 case SQL_SUCCESS_WITH_INFO:
	   setopterr = SQL_ERROR;
	   /* unsuccessed in calling driver's 
	    * SQLSetConnectOption() to set login
	    * timeout.
	    */
	   break;

	 default:
	   return retcode;
	 }
    }
  else if (pdbc->state != en_dbc_needdata)
    {
      PUSHSQLERR (pdbc->herr, en_08002);

      return SQL_ERROR;
    }

  hproc = _iodbcdm_getproc (hdbc, en_BrowseConnect);

  if (hproc == SQL_NULL_HPROC)
    {
      _iodbcdm_driverunload (hdbc);

      pdbc->state = en_dbc_allocated;

      PUSHSQLERR (pdbc->herr, en_IM001);

      return SQL_ERROR;
    }

  CALL_DRIVER (hdbc, retcode, hproc, en_BrowseConnect, (
	  pdbc->dhdbc, 
	  szConnStrIn, cbConnStrIn, 
	  szConnStrOut, cbConnStrOutMax,
	  pcbConnStrOut))

  switch (retcode)
     {
     case SQL_SUCCESS:
     case SQL_SUCCESS_WITH_INFO:
       pdbc->state = en_dbc_connected;
       setopterr |= _iodbcdm_dbcdelayset (hdbc);
       if (setopterr != SQL_SUCCESS)
	 {
	   retcode = SQL_SUCCESS_WITH_INFO;
	 }
       break;

     case SQL_NEED_DATA:
       pdbc->state = en_dbc_needdata;
       break;

     case SQL_ERROR:
       pdbc->state = en_dbc_allocated;
       /* but the driver will not unloaded 
        * to allow application retrive err
        * message from driver 
        */
       break;

     default:
       break;
     }

  return retcode;
}


RETCODE SQL_API 
SQLDisconnect (HDBC hdbc)
{
  DBC_t FAR *pdbc = (DBC_t *) hdbc;
  STMT_t FAR *pstmt;
  RETCODE retcode;
  HPROC hproc;

  int sqlstat = en_00000;

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

  /* check hdbc state */
  if (pdbc->state == en_dbc_allocated)
    {
      sqlstat = en_08003;
    }

  /* check stmt(s) state */
  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)
	/* In this case one need to call 
	 * SQLCancel() first */
	{
	  sqlstat = en_S1010;
	}
    }

  if (sqlstat == en_00000)
    {
      hproc = _iodbcdm_getproc (hdbc, en_Disconnect);

      if (hproc == SQL_NULL_HPROC)
	{
	  sqlstat = en_IM001;
	}
    }

  if (sqlstat != en_00000)
    {
      PUSHSQLERR (pdbc->herr, sqlstat);

      return SQL_ERROR;
    }

  CALL_DRIVER (hdbc, retcode, hproc, en_Disconnect, (
	  pdbc->dhdbc))

  if (retcode == SQL_SUCCESS || retcode == SQL_SUCCESS_WITH_INFO)
    {
      /* diff from MS specs. We disallow
       * driver SQLDisconnect() return
       * SQL_SUCCESS_WITH_INFO and post
       * error message.
       */
      retcode = SQL_SUCCESS;
    }
  else
    {
      return retcode;
    }

  /* free all statement handle(s) on this connection */
  for (; pdbc->hstmt;)
    {
      _iodbcdm_dropstmt (pdbc->hstmt);
    }

  /* state transition */
  if (retcode == SQL_SUCCESS)
    {
      pdbc->state = en_dbc_allocated;
    }

  return retcode;
}


RETCODE SQL_API 
SQLNativeSql (
    HDBC hdbc,
    UCHAR FAR * szSqlStrIn,
    SDWORD cbSqlStrIn,
    UCHAR FAR * szSqlStr,
    SDWORD cbSqlStrMax,
    SDWORD FAR * pcbSqlStr)
{
  DBC_t FAR *pdbc = (DBC_t FAR *) hdbc;
  HPROC hproc;
  int sqlstat = en_00000;
  RETCODE retcode;

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

  /* check argument */
  if (szSqlStrIn == NULL)
    {
      sqlstat = en_S1009;
    }
  else if (cbSqlStrIn < 0 && cbSqlStrIn != SQL_NTS)
    {
      sqlstat = en_S1090;
    }

  if (sqlstat != en_00000)
    {
      PUSHSQLERR (pdbc->herr, sqlstat);

      return SQL_ERROR;
    }

  /* check state */
  if (pdbc->state <= en_dbc_needdata)
    {
      PUSHSQLERR (pdbc->herr, en_08003);

      return SQL_ERROR;
    }

  /* call driver */
  hproc = _iodbcdm_getproc (hdbc, en_NativeSql);

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

      return SQL_ERROR;
    }

  CALL_DRIVER (hdbc, retcode, hproc, en_NativeSql,
    (pdbc->dhdbc, szSqlStrIn, cbSqlStrIn, szSqlStr, cbSqlStrMax, pcbSqlStr))

  return retcode;
}

⌨️ 快捷键说明

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