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

📄 info.c

📁 一个可以替代windows ODBC驱动程序管理器的通用ODBC数据库引擎
💻 C
字号:
/* *  info.c * *  $Id: info.c,v 1.20 2001/06/04 14:01:25 source Exp $ * *  Information 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>#include <ctype.h>extern char *_iodbcdm_getinifile (char *buf, int size);#define SECT1			"[ODBC Data Sources]"#define SECT2			"Default"#define SECT3			"ODBC Data Sources"#define MAX_ENTRIES		1024static intstricmp (const char *s1, const char *s2){  int cmp;  while (*s1)    {      if ((cmp = toupper (*s1) - toupper (*s2)) != 0)	return cmp;      s1++;      s2++;    }  return (*s2) ? -1 : 0;}static intSectSorter (const void *p1, const void *p2){  char **s1 = (char **) p1;  char **s2 = (char **) p2;  return stricmp (*s1, *s2);}SQLRETURN SQL_APISQLDataSources (    SQLHENV henv,    SQLUSMALLINT fDir,    SQLCHAR FAR * szDSN,    SQLSMALLINT cbDSNMax,    SQLSMALLINT FAR * pcbDSN,    SQLCHAR FAR * szDesc,    SQLSMALLINT cbDescMax,    SQLSMALLINT FAR * pcbDesc){  GENV (genv, henv);  char *path;  char buf[1024];  FILE *fp;  int i;  static int cur_entry = -1;  static int num_entries = 0;  static char **sect = NULL;  ODBC_LOCK ();  if (!IS_VALID_HENV (genv))    {      ODBC_UNLOCK ();      return SQL_INVALID_HANDLE;    }  CLEAR_ERRORS (genv);  /* check argument */  if (cbDSNMax < 0 || cbDescMax < 0)    {      PUSHSQLERR (genv->herr, en_S1090);      ODBC_UNLOCK ();      return SQL_ERROR;    }  if (fDir != SQL_FETCH_FIRST && fDir != SQL_FETCH_NEXT)    {      PUSHSQLERR (genv->herr, en_S1103);      ODBC_UNLOCK ();      return SQL_ERROR;    }  if (cur_entry < 0 || fDir == SQL_FETCH_FIRST)    {      cur_entry = 0;      num_entries = 0;      /*        *  Open the odbc.ini file       */      path = (char *) _iodbcdm_getinifile (buf, sizeof (buf));      if ((fp = fopen (path, "r")) == NULL)	{	  ODBC_UNLOCK ();	  return SQL_NO_DATA_FOUND;	}      /*       *  Free old section list       */      if (sect)	{	  for (i = 0; i < MAX_ENTRIES; i++)	    if (sect[i])	      free (sect[i]);	  free (sect);	}      if ((sect = (char **) calloc (MAX_ENTRIES, sizeof (char *))) == NULL)	{	  fclose (fp);	  PUSHSQLERR (genv->herr, en_S1011);	  ODBC_UNLOCK ();	  return SQL_ERROR;	}      /* Finds the section heading [ODBC Data Sources] */      while (1)	{	  char *str;	  str = fgets (buf, sizeof (buf), fp);	  if (str == NULL)	    break;	  if (strcmp (str, SECT1) >= 0)	    break;	}      /*       *  Build a dynamic list of sections       */      while (1)	{	  char *str, *p;	  str = fgets (buf, sizeof (buf), fp);	  if (str == NULL || *str == '[')	    break;	  if (*str == '\n')	    continue;	  for (p = str; *p; p++)	    {	      if (*p == '=' || *p == '\n')		{		  *p = '\0';		  /*		   *  Trim whitespace from the right		   */		  for (; p > str && (*(p - 1) == ' ' || *(p - 1) == '\t');)		    *--p = '\0';		  break;		}	    }	  /* Add this section to the comma separated list */	  if (num_entries >= MAX_ENTRIES)	    break;		/* Skip the rest */	  sect[num_entries++] = (char *) strdup (str);	}      fclose (fp);      /*       *  Sort all entries so we can present a nice list       */      if (num_entries > 1)	qsort (sect, num_entries, sizeof (char *), SectSorter);    }  /*   *  Try to get to the next item   */  if (cur_entry >= num_entries)    {      cur_entry = 0;		/* Next time, start all over again */      ODBC_UNLOCK ();      return SQL_NO_DATA_FOUND;    }  /*   *  Copy DSN information    */  STRNCPY (szDSN, sect[cur_entry], cbDSNMax);  if (pcbDSN)    *pcbDSN = strlen (sect[cur_entry]);  /*   *  And find the type description that goes with this entry   */#if 0  _iodbcdm_getkeyvalbydsn (sect[cur_entry], strlen (sect[cur_entry]),      "Description", szDesc, cbDescMax);#else  _iodbcdm_getkeyvalbydsn (SECT3, strlen (SECT3),      sect[cur_entry], szDesc, cbDescMax);#endif  if (pcbDesc)    *pcbDesc = strlen(szDesc);  /*   *  Next record   */  cur_entry++;  ODBC_UNLOCK ();  return SQL_SUCCESS;}SQLRETURN SQL_APISQLDrivers (    SQLHENV henv,    SQLUSMALLINT fDir,    SQLCHAR FAR * szDrvDesc,    SQLSMALLINT cbDrvDescMax,    SQLSMALLINT FAR * pcbDrvDesc,    SQLCHAR FAR * szDrvAttr,    SQLSMALLINT cbDrvAttrMax,    SQLSMALLINT FAR * pcbDrvAttr){  GENV (genv, henv);  ODBC_LOCK ();  if (!IS_VALID_HENV (genv))    {      ODBC_UNLOCK ();      return SQL_INVALID_HANDLE;    }  CLEAR_ERRORS (genv);  if (cbDrvDescMax < 0 || cbDrvAttrMax < 0 || cbDrvAttrMax == 1)    {      PUSHSQLERR (genv->herr, en_S1090);      ODBC_UNLOCK ();      return SQL_ERROR;    }  if (fDir != SQL_FETCH_FIRST && fDir != SQL_FETCH_NEXT)    {      PUSHSQLERR (genv->herr, en_S1103);      ODBC_UNLOCK ();      return SQL_ERROR;    }  if (!szDrvDesc || !szDrvAttr || !cbDrvDescMax || !cbDrvAttrMax)    {      PUSHSQLERR (genv->herr, en_01004);      ODBC_UNLOCK ();      return SQL_SUCCESS_WITH_INFO;    }/*********************/  ODBC_UNLOCK ();  return SQL_NO_DATA_FOUND;}SQLRETURN SQL_APISQLGetInfo (    SQLHDBC hdbc,    SQLUSMALLINT fInfoType,    SQLPOINTER rgbInfoValue,    SQLSMALLINT cbInfoValueMax,    SQLSMALLINT FAR * pcbInfoValue){  CONN (pdbc, hdbc);  ENV_t FAR *penv;  STMT_t FAR *pstmt = NULL;  STMT_t FAR *tpstmt;  HPROC hproc;  SQLRETURN retcode = SQL_SUCCESS;  DWORD dword;  int size = 0, len = 0;  char buf[16] =  {'\0'};  ENTER_HDBC(pdbc);  if (cbInfoValueMax < 0)    {      PUSHSQLERR (pdbc->herr, en_S1090);      LEAVE_HDBC (pdbc, SQL_ERROR);    }#if (ODBCVER < 0x0300)  if (				/* fInfoType < SQL_INFO_FIRST || */      (fInfoType > SQL_INFO_LAST	  && fInfoType < SQL_INFO_DRIVER_START))    {      PUSHSQLERR (pdbc->herr, en_S1096);      LEAVE_HDBC (pdbc, SQL_ERROR);    }#endif  if (fInfoType == SQL_ODBC_VER)    {      sprintf (buf, "%02d.%02d",	  (ODBCVER) >> 8, 0x00FF & (ODBCVER));      if (rgbInfoValue != NULL	  && cbInfoValueMax > 0)	{	  len = STRLEN (buf);	  if (len > cbInfoValueMax - 1)	    {	      len = cbInfoValueMax - 1;	      PUSHSQLERR (pdbc->herr, en_01004);	      retcode = SQL_SUCCESS_WITH_INFO;	    }	  STRNCPY (rgbInfoValue, buf, len);	  ((char FAR *) rgbInfoValue)[len] = '\0';	}      if (pcbInfoValue != NULL)	{	  *pcbInfoValue = (SWORD) len;	}      LEAVE_HDBC (pdbc, retcode);    }  if (pdbc->state == en_dbc_allocated || pdbc->state == en_dbc_needdata)    {      PUSHSQLERR (pdbc->herr, en_08003);      LEAVE_HDBC (pdbc, SQL_ERROR);    }  switch (fInfoType)    {    case SQL_DRIVER_HDBC:      dword = (DWORD) (pdbc->dhdbc);      size = sizeof (dword);      break;    case SQL_DRIVER_HENV:      penv = (ENV_t FAR *) (pdbc->henv);      dword = (DWORD) (penv->dhenv);      size = sizeof (dword);      break;    case SQL_DRIVER_HLIB:      penv = (ENV_t FAR *) (pdbc->henv);      dword = (DWORD) (penv->hdll);      size = sizeof (dword);      break;    case SQL_DRIVER_HSTMT:      if (rgbInfoValue != NULL)	{	  pstmt = *((STMT_t FAR **) rgbInfoValue);	}      for (tpstmt = (STMT_t FAR *) (pdbc->hstmt);	  tpstmt != NULL;	  tpstmt = tpstmt->next)	{	  if (tpstmt == pstmt)	    {	      break;	    }	}      if (tpstmt == NULL)	{	  PUSHSQLERR (pdbc->herr, en_S1009);	  LEAVE_HDBC (pdbc, SQL_ERROR);	}      dword = (DWORD) (pstmt->dhstmt);      size = sizeof (dword);      break;    default:      break;    }  if (size)    {      if (rgbInfoValue != NULL)	{	  *((DWORD *) rgbInfoValue) = dword;	}      if (pcbInfoValue != NULL)	{	  *(pcbInfoValue) = (SWORD) size;	}      LEAVE_HDBC (pdbc, SQL_SUCCESS);    }#if (ODBCVER >= 0x0300)  /*   *  This was a temp value in ODBC 2   */  if (((ENV_t FAR *) pdbc->henv)->dodbc_ver == SQL_OV_ODBC2 && 	  fInfoType == SQL_OJ_CAPABILITIES)      fInfoType = 65003;#endif /* ODBCVER >= 0x0300 */  hproc = _iodbcdm_getproc (pdbc, en_GetInfo);  if (hproc == SQL_NULL_HPROC)    {      PUSHSQLERR (pdbc->herr, en_IM001);      LEAVE_HDBC (pdbc, SQL_ERROR);    }  CALL_DRIVER (hdbc, pdbc, retcode, hproc, en_GetInfo,      (pdbc->dhdbc, fInfoType, rgbInfoValue, cbInfoValueMax, pcbInfoValue));  if (retcode == SQL_ERROR      && fInfoType == SQL_DRIVER_ODBC_VER)    {      STRCPY (buf, "01.00");      if (rgbInfoValue != NULL	  && cbInfoValueMax > 0)	{	  len = STRLEN (buf);	  if (len < cbInfoValueMax - 1)	    {	      len = cbInfoValueMax - 1;	      PUSHSQLERR (pdbc->herr, en_01004);	    }	  STRNCPY (rgbInfoValue, buf, len);	  ((char FAR *) rgbInfoValue)[len] = '\0';	}      if (pcbInfoValue != NULL)	{	  *pcbInfoValue = (SWORD) len;	}      /* what should we return in this case ???? */    }  LEAVE_HDBC (pdbc, retcode);}static int FunctionNumbers[] ={    0#define FUNCDEF(A,B,C)	,A#include "henv.ci"#undef FUNCDEF};#if (ODBCVER >= 0x0300)#define SQL_ODBC3_SET_FUNC_ON(pfExists, uwAPI) \	*( ((UWORD*) (pfExists)) + ((uwAPI) >> 4) ) |= (1 << ((uwAPI) & 0x000F))#define SQL_ODBC3_SET_FUNC_OFF(pfExists, uwAPI) \	*( ((UWORD*) (pfExists)) + ((uwAPI) >> 4) ) &= !(1 << ((uwAPI) & 0x000F))#endifSQLRETURN SQL_APISQLGetFunctions (    SQLHDBC hdbc,    SQLUSMALLINT fFunc,    SQLUSMALLINT FAR * pfExists){  CONN (pdbc, hdbc);  HPROC hproc;  SQLRETURN retcode;  int i;  UWORD functions2[100];#if (ODBCVER >= 0x0300)  UWORD functions3[SQL_API_ODBC3_ALL_FUNCTIONS_SIZE];#endif  ENTER_HDBC (pdbc);  if (pdbc->state == en_dbc_allocated      || pdbc->state == en_dbc_needdata)    {      PUSHSQLERR (pdbc->herr, en_S1010);      LEAVE_HDBC (pdbc, SQL_ERROR);    }  if (pfExists == NULL)    {      LEAVE_HDBC (pdbc, SQL_SUCCESS);    }  /*   *  These functions are supported by the iODBC driver manager   */  if (fFunc == SQL_API_SQLDATASOURCES      || fFunc == SQL_API_SQLDRIVERS#if (ODBCVER >= 0x0300)      || fFunc == SQL_API_SQLGETENVATTR      || fFunc == SQL_API_SQLSETENVATTR#endif      )    {      *pfExists = (UWORD) 1;      LEAVE_HDBC (pdbc, SQL_SUCCESS);    }  /*   *  Check if function number is within ODBC version context   */#if (ODBCVER < 0x0300)  if (fFunc > SQL_EXT_API_LAST)    {      PUSHSQLERR (pdbc->herr, en_S1095);      LEAVE_HDBC (pdbc, SQL_ERROR);    }#endif  /*   *  In a ODBC 2.x driver context, the ODBC 3.x API calls are    *  mapped by the driver manager.   */#if (ODBCVER >= 0x0300)  if (((ENV_t FAR *) pdbc->henv)->dodbc_ver == SQL_OV_ODBC2)    {      switch (fFunc)	{	case SQL_API_ALL_FUNCTIONS:	case SQL_API_ODBC3_ALL_FUNCTIONS:	  break;	  /* Mapped ODBC3 app -> ODBC2 driver functions */	case SQL_API_SQLALLOCHANDLE:	case SQL_API_SQLFREEHANDLE:	case SQL_API_SQLSETCONNECTATTR:	case SQL_API_SQLGETCONNECTATTR:	case SQL_API_SQLGETSTMTATTR:	case SQL_API_SQLSETSTMTATTR:	case SQL_API_SQLCOLATTRIBUTE:	case SQL_API_SQLENDTRAN:	case SQL_API_SQLBULKOPERATIONS:	case SQL_API_SQLFETCHSCROLL:	case SQL_API_SQLGETDIAGREC:	case SQL_API_SQLGETDIAGFIELD:	  *pfExists = SQL_TRUE;	  LEAVE_HDBC (pdbc, SQL_SUCCESS);	case SQL_API_SQLBINDPARAM:	  fFunc = SQL_API_SQLBINDPARAMETER;	  break;	default:	  if (fFunc > SQL_API_SQLBINDPARAMETER)	    {	      *pfExists = SQL_FALSE;	      LEAVE_HDBC (pdbc, SQL_SUCCESS);	    }	  break;	}    }#endif  /*   *  If the driver exports a SQLGetFunctions call, use it   */  hproc = _iodbcdm_getproc (pdbc, en_GetFunctions);  if (hproc != SQL_NULL_HPROC)    {      CALL_DRIVER (hdbc, pdbc, retcode, hproc, en_GetFunctions,	  (pdbc->dhdbc, fFunc, pfExists));      LEAVE_HDBC (pdbc, retcode);    }  /*   *  Map deprecated functions   */  if (fFunc == SQL_API_SQLSETPARAM)    {      fFunc = SQL_API_SQLBINDPARAMETER;    }  /*   *  Initialize intermediate result arrays   */  memset (functions2, '\0', sizeof (functions2));#if (ODBCVER > 0x0300)  memset (functions3, '\0', sizeof (functions3));#endif  /*   *  Build result array by scanning for all API calls   */  for (i = 1; i < __LAST_API_FUNCTION__; i++)    {      int j = FunctionNumbers[i];      hproc = _iodbcdm_getproc (pdbc, i);      if (hproc != SQL_NULL_HPROC)	{	  if (j < 100)	    functions2[j] = 1;#if (ODBCVER >= 0x0300)	  functions3[j >> 4] |= (1 << (j & 0x000F));#endif	}    }  /*   *  Finally return the information   */  if (fFunc == SQL_API_ALL_FUNCTIONS)    {      memcpy (pfExists, &functions2, sizeof (functions2));    }#if (ODBCVER < 0x0300)  else    {      *pfExists = functions2[fFunc];    }#else  else if (fFunc == SQL_API_ODBC3_ALL_FUNCTIONS)    {      memcpy (pfExists, &functions3, sizeof (functions3));    }  else    {      *pfExists = SQL_FUNC_EXISTS (functions3, fFunc);    }#endif  LEAVE_HDBC (pdbc, SQL_SUCCESS);}

⌨️ 快捷键说明

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