Example #1
0
RETCODE SQL_API 
SQLFreeConnect (HDBC hdbc)
{
  GENV_t FAR *genv;
  DBC_t FAR *pdbc = (DBC_t FAR *) hdbc;
  DBC_t FAR *tpdbc;

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

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

      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);
  _iodbcdm_freesqlerrlist (pdbc->herr);

  if (pdbc->tfile)
    {
      MEM_FREE (pdbc->tfile);
    }

  SQLSetConnectOption (pdbc, SQL_OPT_TRACE, SQL_OPT_TRACE_OFF);

  MEM_FREE (pdbc);

  return SQL_SUCCESS;
}
Example #2
0
File: connect.c Project: EdgarTx/wx
/* - Load driver share library( or increase its reference count 
 *   if it has already been loaded by another active connection)
 * - Call driver's SQLAllocEnv() (for the first reference only)
 * - Call driver's SQLAllocConnect()
 * - Call driver's SQLSetConnectOption() (set login time out)
 * - Increase the bookkeeping reference count
 */
static RETCODE 
_iodbcdm_driverload (
    char FAR * path,
    HDBC hdbc)
{
  DBC_t FAR *pdbc = (DBC_t FAR *) hdbc;
  GENV_t FAR *genv;
  ENV_t FAR *penv = NULL;
  HDLL hdll;
  HPROC hproc;
  RETCODE retcode = SQL_SUCCESS;
  int sqlstat = en_00000;

  if (path == NULL || path[0] == '\0')
    {
      PUSHSQLERR (pdbc->herr, en_IM002);

      return SQL_ERROR;
    }

  if (hdbc == SQL_NULL_HDBC || pdbc->genv == SQL_NULL_HENV)
    {
      return SQL_INVALID_HANDLE;
    }

  genv = (GENV_t FAR *) pdbc->genv;

  /* This will either load the driver dll or increase its reference count */
  hdll = _iodbcdm_dllopen ((char FAR *) path);

  if (hdll == SQL_NULL_HDLL)
    {
      PUSHSYSERR (pdbc->herr, _iodbcdm_dllerror ());
      PUSHSQLERR (pdbc->herr, en_IM003);
      return SQL_ERROR;
    }

  penv = (ENV_t FAR *) (pdbc->henv);

  if (penv != NULL)
    {
      if (penv->hdll != hdll)
	{
	  _iodbcdm_driverunload (hdbc);
	}
      else
	{
	  /* 
  	   * this will not unload the driver but only decrease its internal
	   * reference count 
	   */
	  _iodbcdm_dllclose (hdll);
	}
    }

  if (penv == NULL)
    {
      /* 
       * find out whether this dll has already been loaded on another 
       * connection 
       */
      for (penv = (ENV_t FAR *) genv->henv; 
	  penv != NULL;
	  penv = (ENV_t FAR *) penv->next)
	{
	  if (penv->hdll == hdll)
	    {
	      /* 
  	       * this will not unload the driver but only decrease its internal
	       * reference count 
	       */
	      _iodbcdm_dllclose (hdll);
	      break;
	    }
	}

      if (penv == NULL)
	/* no connection attaching with this dll */
	{
	  int i;

	  /* create a new dll env instance */
	  penv = (ENV_t FAR *) MEM_ALLOC (sizeof (ENV_t));

	  if (penv == NULL)
	    {
	      _iodbcdm_dllclose (hdll);

	      PUSHSQLERR (pdbc->herr, en_S1001);

	      return SQL_ERROR;
	    }

	  for (i = 0; i < SQL_EXT_API_LAST + 1; i++)
	    {
	      (penv->dllproc_tab)[i] = SQL_NULL_HPROC;
	    }

	  pdbc->henv = penv;
	  penv->hdll = hdll;

	  /* call driver's SQLAllocHandle() or SQLAllocEnv() */

#if (ODBCVER >= 0x0300)
	  hproc = _iodbcdm_getproc (hdbc, en_AllocHandle);

	  if (hproc)
	    {
	      CALL_DRIVER (hdbc, retcode, hproc, en_AllocHandle,
		  (SQL_HANDLE_ENV, SQL_NULL_HANDLE, &(penv->dhenv)))
	    }
	  else			/* try driver's SQLAllocEnv() */
#endif
	    {
	      hproc = _iodbcdm_getproc (hdbc, en_AllocEnv);

	      if (hproc == SQL_NULL_HPROC)
		{
		  sqlstat = en_IM004;
		}
	      else
		{
		  CALL_DRIVER (hdbc, retcode, hproc,
		      en_AllocEnv, (&(penv->dhenv)))
		}
	    }

	  if (retcode == SQL_ERROR)
	    {
	      sqlstat = en_IM004;
	    }

	  if (sqlstat != en_00000)
	    {
	      _iodbcdm_dllclose (hdll);
	      MEM_FREE (penv);
	      PUSHSQLERR (pdbc->herr, en_IM004);

	      return SQL_ERROR;
	    }

	  /* insert into dll env list */
	  penv->next = (ENV_t FAR *) genv->henv;
	  genv->henv = penv;

	  /* initiate this new env entry */
	  penv->refcount = 0;	/* we will increase it after
				 * driver's SQLAllocConnect()
				 * success
				 */
	}