#include <iodbc.h>
#include <sql.h>
#include <sqlext.h>
#include <sqlucode.h>
#include <iodbcext.h>
#include <iodbcinst.h>
#include <dlproc.h>
#include <herr.h>
#include <henv.h>
#include <hdbc.h>
#include <hstmt.h>
#include <itrace.h>
#include <unicode.h>
#if defined(__APPLE__) && defined(GUI)
#include <CoreFoundation/CoreFoundation.h>
#endif
static char sccsid[] = "@(#)iODBC driver manager " VERSION "\n";
char *iodbc_version = VERSION;
extern SQLRETURN _iodbcdm_driverunload (HDBC hdbc);
extern SQLRETURN SQL_API _iodbcdm_SetConnectOption (SQLHDBC hdbc,
SQLUSMALLINT fOption, SQLULEN vParam, SQLCHAR waMode);
extern char * _iodbcdm_getkeyvalinstr (char *cnstr, int cnlen,
char *keywd, char *value, int size);
extern wchar_t * _iodbcdm_getkeyvalinstrw (wchar_t *cnstr, int cnlen,
wchar_t *keywd, wchar_t *value, int size);
static SQLRETURN
_iodbcdm_SetConnectOption_init (
SQLHDBC hdbc,
SQLUSMALLINT fOption,
SQLULEN vParam,
UCHAR waMode)
{
CONN (pdbc, hdbc);
ENVR (penv, pdbc->henv);
HPROC hproc = SQL_NULL_HPROC;
SQLRETURN retcode = SQL_SUCCESS;
SQLINTEGER strLength = 0;
void *ptr = (void *) vParam;
void *_vParam = NULL;
if ((penv->unicode_driver && waMode != 'W')
|| (!penv->unicode_driver && waMode == 'W'))
{
switch (fOption)
{
case SQL_ATTR_TRACEFILE:
case SQL_CURRENT_QUALIFIER:
case SQL_TRANSLATE_DLL:
case SQL_APPLICATION_NAME:
case SQL_COPT_SS_ENLIST_IN_DTC:
case SQL_COPT_SS_PERF_QUERY_LOG:
case SQL_COPT_SS_PERF_DATA_LOG:
case SQL_CURRENT_SCHEMA:
if (waMode != 'W')
{
_vParam = dm_SQL_A2W((SQLCHAR *)vParam, SQL_NTS);
}
else
{
_vParam = dm_SQL_W2A((SQLWCHAR *)vParam, SQL_NTS);
}
ptr = _vParam;
strLength = SQL_NTS;
break;
}
}
if (penv->unicode_driver)
{
if ((hproc = _iodbcdm_getproc (pdbc, en_SetConnectOptionW))
!= SQL_NULL_HPROC)
{
CALL_DRIVER (hdbc, pdbc, retcode, hproc,
en_SetConnectOptionW, (pdbc->dhdbc, fOption, ptr));
}
#if (ODBCVER >= 0x300)
else
if ((hproc = _iodbcdm_getproc (pdbc, en_SetConnectAttrW))
!= SQL_NULL_HPROC)
{
CALL_DRIVER (hdbc, pdbc, retcode, hproc,
en_SetConnectAttrW, (pdbc->dhdbc, fOption, ptr, strLength));
}
#endif
}
else
{
if ((hproc = _iodbcdm_getproc (pdbc, en_SetConnectOption))
!= SQL_NULL_HPROC)
{
CALL_DRIVER (hdbc, pdbc, retcode, hproc,
en_SetConnectOption, (pdbc->dhdbc, fOption, vParam));
}
else
if ((hproc = _iodbcdm_getproc (pdbc, en_SetConnectOptionA))
!= SQL_NULL_HPROC)
{
CALL_DRIVER (hdbc, pdbc, retcode, hproc,
en_SetConnectOptionA, (pdbc->dhdbc, fOption, vParam));
}
#if (ODBCVER >= 0x300)
else
if ((hproc = _iodbcdm_getproc (pdbc, en_SetConnectAttr))
!= SQL_NULL_HPROC)
{
CALL_DRIVER (hdbc, pdbc, retcode, hproc,
en_SetConnectAttr, (pdbc->dhdbc, fOption, vParam, strLength));
}
else
if ((hproc = _iodbcdm_getproc (pdbc, en_SetConnectAttrA))
!= SQL_NULL_HPROC)
{
CALL_DRIVER (hdbc, pdbc, retcode, hproc,
en_SetConnectAttrA,(pdbc->dhdbc, fOption, vParam, strLength));
}
#endif
}
MEM_FREE(_vParam);
if (hproc == SQL_NULL_HPROC)
{
PUSHSQLERR (pdbc->herr, en_IM004);
return SQL_SUCCESS_WITH_INFO;
}
return retcode;
}
static SQLRETURN
_iodbcdm_getInfo_init (SQLHDBC hdbc,
SQLUSMALLINT fInfoType,
SQLPOINTER rgbInfoValue,
SQLSMALLINT cbInfoValueMax,
SQLSMALLINT * pcbInfoValue,
SQLCHAR waMode)
{
CONN (pdbc, hdbc);
ENVR (penv, pdbc->henv);
HPROC hproc = SQL_NULL_HPROC;
SQLRETURN retcode = SQL_SUCCESS;
waMode = waMode;
switch(fInfoType)
{
case SQL_CURSOR_COMMIT_BEHAVIOR:
case SQL_CURSOR_ROLLBACK_BEHAVIOR:
break;
default:
return SQL_ERROR;
}
CALL_UDRIVER(hdbc, pdbc, retcode, hproc, penv->unicode_driver,
en_GetInfo, (
pdbc->dhdbc,
fInfoType,
rgbInfoValue,
cbInfoValueMax,
pcbInfoValue));
if (hproc == SQL_NULL_HPROC)
{
PUSHSQLERR (pdbc->herr, en_IM004);
return SQL_SUCCESS_WITH_INFO;
}
return retcode;
}
SQLRETURN
_iodbcdm_driverload (
char * path,
HDBC hdbc,
SWORD thread_safe,
SWORD unload_safe,
UCHAR waMode)
{
CONN (pdbc, hdbc);
ENVR (penv, NULL);
GENV (genv, NULL);
HDLL hdll;
HPROC hproc;
SQLRETURN retcode = SQL_SUCCESS;
sqlstcode_t sqlstat = en_00000;
if (path == NULL || ((char*)path)[0] == '\0')
{
PUSHSQLERR (pdbc->herr, en_IM002);
return SQL_ERROR;
}
if (!IS_VALID_HDBC (pdbc) || pdbc->genv == SQL_NULL_HENV)
{
return SQL_INVALID_HANDLE;
}
genv = (GENV_t *) pdbc->genv;
hdll = _iodbcdm_dllopen ((char *) path);
if (unload_safe)
_iodbcdm_safe_unload (hdll);
if (hdll == SQL_NULL_HDLL)
{
PUSHSYSERR (pdbc->herr, _iodbcdm_dllerror ());
PUSHSQLERR (pdbc->herr, en_IM003);
return SQL_ERROR;
}
penv = (ENV_t *) (pdbc->henv);
if (penv != NULL)
{
if (penv->hdll != hdll)
{
_iodbcdm_driverunload (hdbc);
penv->hdll = hdll;
}
else
{
_iodbcdm_dllclose (hdll);
}
}
if (penv == NULL)
{
for (penv = (ENV_t *) genv->henv;
penv != NULL;
penv = (ENV_t *) penv->next)
{
if (penv->hdll == hdll)
{
_iodbcdm_dllclose (hdll);
break;
}
}
if (penv == NULL)
{
int i;
penv = (ENV_t *) MEM_ALLOC (sizeof (ENV_t));
if (penv == NULL)
{
_iodbcdm_dllclose (hdll);
PUSHSQLERR (pdbc->herr, en_S1001);
return SQL_ERROR;
}
for (i = 0; i < __LAST_API_FUNCTION__; i++)
{
#if 1
(penv->dllproc_tab)[i] = SQL_NULL_HPROC;
#else
(penv->dllproc_tab)[i] = _iodbcdm_getproc(pdbc, i);
#endif
}
pdbc->henv = penv;
penv->hdll = hdll;
penv->thread_safe = thread_safe;
if (!penv->thread_safe)
MUTEX_INIT (penv->drv_lock);
penv->unicode_driver = 0;
if ( _iodbcdm_getproc (pdbc, en_ConnectW))
penv->unicode_driver = 1;
#if (ODBCVER >= 0x0300)
hproc = _iodbcdm_getproc (pdbc, en_AllocHandle);
if (hproc)
{
CALL_DRIVER (hdbc, genv, retcode, hproc, en_AllocHandle,
(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &(penv->dhenv)));
if (retcode == SQL_SUCCESS || retcode == SQL_SUCCESS_WITH_INFO)
{
SQLRETURN save_retcode = retcode;
penv->dodbc_ver = SQL_OV_ODBC2;
hproc = _iodbcdm_getproc (pdbc, en_SetEnvAttr);
if (hproc != SQL_NULL_HPROC)
{
CALL_DRIVER (hdbc, genv, retcode, hproc, en_SetEnvAttr,
(penv->dhenv, SQL_ATTR_ODBC_VERSION, genv->odbc_ver,
0));
if (retcode == SQL_SUCCESS)
penv->dodbc_ver = SQL_OV_ODBC3;
}
retcode = save_retcode;
}
}
else
#endif
{
hproc = _iodbcdm_getproc (pdbc, en_AllocEnv);
if (hproc == SQL_NULL_HPROC)
{
sqlstat = en_IM004;
}
else
{
#if (ODBCVER >= 0x0300)
penv->dodbc_ver = SQL_OV_ODBC2;
#endif
CALL_DRIVER (hdbc, genv, 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;
}
penv->next = (ENV_t *) genv->henv;
genv->henv = penv;
penv->refcount = 0;
}
pdbc->henv = penv;
if (pdbc->dhdbc == SQL_NULL_HDBC)
{
#if (ODBCVER >= 0x0300)
hproc = _iodbcdm_getproc (pdbc, en_AllocHandle);
if (hproc)
{
CALL_DRIVER (hdbc, genv, retcode, hproc, en_AllocHandle,
(SQL_HANDLE_DBC, penv->dhenv, &(pdbc->dhdbc)));
}
else
#endif
{
hproc = _iodbcdm_getproc (pdbc, en_AllocConnect);
if (hproc == SQL_NULL_HPROC)
{
sqlstat = en_IM005;
}
else
{
CALL_DRIVER (hdbc, genv, retcode, hproc,
en_AllocConnect, (penv->dhenv, &(pdbc->dhdbc)));
}
}
if (retcode == SQL_ERROR)
{
sqlstat = en_IM005;
}
if (sqlstat != en_00000)
{
_iodbcdm_driverunload (hdbc);
pdbc->dhdbc = SQL_NULL_HDBC;
PUSHSQLERR (pdbc->herr, en_IM005);
return SQL_ERROR;
}
}
pdbc->henv = penv;
penv->refcount++;
}
if (pdbc->login_timeout != 0UL)
{
retcode = _iodbcdm_SetConnectOption_init (hdbc, SQL_LOGIN_TIMEOUT,
pdbc->login_timeout, waMode);
if (retcode == SQL_ERROR)
{
PUSHSQLERR (pdbc->herr, en_IM006);
return SQL_SUCCESS_WITH_INFO;
}
}
if (pdbc->drvopt != NULL)
{
DRVOPT *popt;
for (popt = pdbc->drvopt; popt != NULL; popt = popt->next)
{
retcode = _iodbcdm_SetConnectOption_init (hdbc, popt->Option,
popt->Param, popt->waMode);
if (retcode == SQL_ERROR)
{
PUSHSQLERR (pdbc->herr, en_IM006);
return SQL_SUCCESS_WITH_INFO;
}
}
}
return SQL_SUCCESS;
}
SQLRETURN
_iodbcdm_driverunload (HDBC hdbc)
{
CONN (pdbc, hdbc);
ENVR (penv, pdbc->henv);
GENV (genv, pdbc->genv);
ENV_t *tpenv;
HPROC hproc;
SQLRETURN retcode = SQL_SUCCESS;
if (!IS_VALID_HDBC (pdbc))
{
return SQL_INVALID_HANDLE;
}
if (penv == NULL || penv->hdll == SQL_NULL_HDLL)
{
return SQL_SUCCESS;
}
#if (ODBCVER >= 0x0300)
hproc = _iodbcdm_getproc (pdbc, en_FreeHandle);
if (hproc)
{
CALL_DRIVER (hdbc, pdbc, retcode, hproc, en_FreeHandle,
(SQL_HANDLE_DBC, pdbc->dhdbc));
}
else
#endif
{
hproc = _iodbcdm_getproc (pdbc, en_FreeConnect);
if (hproc != SQL_NULL_HPROC)
{
CALL_DRIVER (hdbc, pdbc, retcode, hproc,
en_FreeConnect, (pdbc->dhdbc));
pdbc->dhdbc = SQL_NULL_HDBC;
}
}
penv->refcount--;
if (!penv->refcount)
{
#if (ODBCVER >= 0x0300)
hproc = _iodbcdm_getproc (pdbc, en_FreeHandle);
if (hproc)
{
CALL_DRIVER (hdbc, genv, retcode, hproc, en_FreeHandle,
(SQL_HANDLE_ENV, penv->dhenv));
}
else
#endif
{
hproc = _iodbcdm_getproc (pdbc, en_FreeEnv);
if (hproc != SQL_NULL_HPROC)
{
CALL_DRIVER (hdbc, genv, retcode, hproc, en_FreeEnv,
(penv->dhenv));
penv->dhenv = SQL_NULL_HENV;
}
}
_iodbcdm_dllclose (penv->hdll);
penv->hdll = SQL_NULL_HDLL;
for (tpenv = (ENV_t *) genv->henv;
tpenv != NULL;
tpenv = (ENV_t *) penv->next)
{
if (tpenv == penv)
{
genv->henv = penv->next;
break;
}
if (tpenv->next == penv)
{
tpenv->next = penv->next;
break;
}
}
MEM_FREE (penv);
}
pdbc->hstmt = SQL_NULL_HSTMT;
pdbc->dhdbc = SQL_NULL_HDBC;
pdbc->state = en_dbc_allocated;
pdbc->odbc_cursors = SQL_CUR_DEFAULT;
pdbc->packet_size = 0UL;
pdbc->quiet_mode = (UDWORD) NULL;
pdbc->txn_isolation = SQL_TXN_READ_UNCOMMITTED;
if (pdbc->current_qualifier != NULL)
{
MEM_FREE (pdbc->current_qualifier);
pdbc->current_qualifier = NULL;
}
return SQL_SUCCESS;
}
static SQLRETURN
_iodbcdm_dbcdelayset (HDBC hdbc, UCHAR waMode)
{
CONN (pdbc, hdbc);
SQLRETURN retcode = SQL_SUCCESS;
SQLRETURN ret;
if (pdbc->access_mode != SQL_MODE_DEFAULT)
{
ret = _iodbcdm_SetConnectOption_init (hdbc, SQL_ACCESS_MODE,
pdbc->access_mode, waMode);
retcode |= ret;
}
if (pdbc->autocommit != SQL_AUTOCOMMIT_DEFAULT)
{
ret = _iodbcdm_SetConnectOption_init (hdbc, SQL_AUTOCOMMIT,
pdbc->autocommit, waMode);
retcode |= ret;
}
if (pdbc->current_qualifier != NULL)
{
ret = _iodbcdm_SetConnectOption_init (hdbc, SQL_CURRENT_QUALIFIER,
(SQLULEN) pdbc->current_qualifier,
pdbc->current_qualifier_WA);
retcode |= ret;
}
if (pdbc->packet_size != 0UL)
{
ret = _iodbcdm_SetConnectOption_init (hdbc, SQL_PACKET_SIZE,
pdbc->packet_size, waMode);
retcode |= ret;
}
if (pdbc->quiet_mode != (UDWORD) NULL)
{
ret = _iodbcdm_SetConnectOption_init (hdbc, SQL_QUIET_MODE,
pdbc->quiet_mode, waMode);
retcode |= ret;
}
if (pdbc->txn_isolation != SQL_TXN_READ_UNCOMMITTED)
{
ret = _iodbcdm_SetConnectOption_init (hdbc, SQL_TXN_ISOLATION,
pdbc->txn_isolation, waMode);
retcode |= ret;
}
if (retcode != SQL_SUCCESS && retcode != SQL_SUCCESS_WITH_INFO)
{
PUSHSQLERR (pdbc->herr, en_IM006);
retcode = SQL_ERROR;
}
ret = _iodbcdm_getInfo_init (hdbc, SQL_CURSOR_COMMIT_BEHAVIOR,
(PTR) & (pdbc->cb_commit),
sizeof (pdbc->cb_commit),
NULL, waMode);
retcode |= ret;
ret = _iodbcdm_getInfo_init (hdbc, SQL_CURSOR_ROLLBACK_BEHAVIOR,
(PTR) & (pdbc->cb_rollback),
sizeof (pdbc->cb_rollback),
NULL, waMode);
retcode |= ret;
if (retcode != SQL_SUCCESS && retcode != SQL_SUCCESS_WITH_INFO)
{
return SQL_ERROR;
}
return retcode;
}
static SQLRETURN
_iodbcdm_con_settracing (HDBC hdbc, SQLCHAR *dsn, int dsnlen, UCHAR waMode)
{
SQLUINTEGER trace = SQL_OPT_TRACE_OFF;
char buf[1024];
hdbc=hdbc;
dsnlen=dsnlen;
waMode = waMode;
SQLSetConfigMode (ODBC_BOTH_DSN);
if ((SQLGetPrivateProfileString ((char *) dsn, "TraceFile", "",
buf, sizeof (buf), "odbc.ini") == 0 || !buf[0]))
STRCPY (buf, SQL_OPT_TRACE_FILE_DEFAULT);
trace_set_filename (buf);
SQLSetConfigMode (ODBC_BOTH_DSN);
if (SQLGetPrivateProfileString ((char *) dsn, "Trace", "",
buf, sizeof (buf), "odbc.ini")
&& (STRCASEEQ (buf, "on") || STRCASEEQ (buf, "yes")
|| STRCASEEQ (buf, "1")))
{
trace = SQL_OPT_TRACE_ON;
}
if (trace == SQL_OPT_TRACE_ON)
trace_start ();
return SQL_SUCCESS;
}
static
SQLRETURN SQL_API
SQLConnect_Internal (SQLHDBC hdbc,
SQLPOINTER szDSN,
SQLSMALLINT cbDSN,
SQLPOINTER szUID,
SQLSMALLINT cbUID,
SQLPOINTER szAuthStr,
SQLSMALLINT cbAuthStr,
SQLCHAR waMode)
{
CONN (pdbc, hdbc);
ENVR (penv, NULL);
SQLRETURN retcode = SQL_SUCCESS;
SQLRETURN setopterr = SQL_SUCCESS;
char driver[1024] = { '\0' };
char buf[256];
HPROC hproc = SQL_NULL_HPROC;
SWORD thread_safe;
SWORD unload_safe;
void * _szDSN = NULL;
void * _szUID = NULL;
void * _szAuthStr = NULL;
SQLCHAR *_dsn = (SQLCHAR *) szDSN;
SQLSMALLINT _dsn_len = cbDSN;
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;
}
if (pdbc->state != en_dbc_allocated)
{
PUSHSQLERR (pdbc->herr, en_08002);
return SQL_ERROR;
}
if (waMode == 'W')
{
_szDSN = (void *) dm_SQL_WtoU8((SQLWCHAR *)szDSN, cbDSN);
_dsn = (SQLCHAR *) _szDSN;
_dsn_len = SQL_NTS;
if (_dsn == NULL)
{
PUSHSQLERR (pdbc->herr, en_S1001);
return SQL_ERROR;
}
}
if (_iodbcdm_con_settracing (pdbc, _dsn, _dsn_len, waMode) == SQL_ERROR)
{
MEM_FREE(_szDSN);
return SQL_ERROR;
}
thread_safe = 1;
SQLSetConfigMode (ODBC_BOTH_DSN);
if ( SQLGetPrivateProfileString ((char *) _dsn, "ThreadManager", "",
buf, sizeof(buf), "odbc.ini") &&
(STRCASEEQ (buf, "on") || STRCASEEQ (buf, "1")))
{
thread_safe = 0;
}
unload_safe = 0;
SQLSetConfigMode (ODBC_BOTH_DSN);
if ( SQLGetPrivateProfileString ((char *) _dsn, "UnloadSafe", "",
buf, sizeof(buf), "odbc.ini") &&
(STRCASEEQ (buf, "on") || STRCASEEQ (buf, "1")))
{
unload_safe = 1;
}
SQLSetConfigMode (ODBC_BOTH_DSN);
if ( SQLGetPrivateProfileString ((char *) _dsn, "Driver", "",
(char *) driver, sizeof(driver), "odbc.ini") == 0)
{
MEM_FREE(_szDSN);
_szDSN = NULL;
PUSHSQLERR (pdbc->herr, en_IM002);
return SQL_ERROR;
}
MEM_FREE(_szDSN);
_szDSN = NULL;
retcode = _iodbcdm_driverload ((char *)driver, pdbc, thread_safe, unload_safe, waMode);
switch (retcode)
{
case SQL_SUCCESS:
break;
case SQL_SUCCESS_WITH_INFO:
#if 0
setopterr = SQL_ERROR;
#endif
break;
default:
return retcode;
}
penv = (ENV_t *) pdbc->henv;
if ((penv->unicode_driver && waMode != 'W')
|| (!penv->unicode_driver && waMode == 'W'))
{
if (waMode != 'W')
{
_szDSN = dm_SQL_A2W((SQLCHAR *)szDSN, cbDSN);
_szUID = dm_SQL_A2W((SQLCHAR *)szUID, cbUID);
_szAuthStr = dm_SQL_A2W((SQLCHAR *)szAuthStr, cbAuthStr);
}
else
{
_szDSN = dm_SQL_W2A((SQLWCHAR *)szDSN, cbDSN);
_szUID = dm_SQL_W2A((SQLWCHAR *)szUID, cbUID);
_szAuthStr = dm_SQL_W2A((SQLWCHAR *)szAuthStr, cbAuthStr);
}
cbDSN = SQL_NTS;
cbUID = SQL_NTS;
cbAuthStr = SQL_NTS;
szDSN = _szDSN;
szUID = _szUID;
szAuthStr = _szAuthStr;
}
CALL_UDRIVER(hdbc, pdbc, retcode, hproc, penv->unicode_driver,
en_Connect, (
pdbc->dhdbc,
szDSN,
cbDSN,
szUID,
cbUID,
szAuthStr,
cbAuthStr));
MEM_FREE(_szDSN);
MEM_FREE(_szUID);
MEM_FREE(_szAuthStr);
if (hproc == SQL_NULL_HPROC)
{
_iodbcdm_driverunload (pdbc);
PUSHSQLERR (pdbc->herr, en_IM001);
return SQL_ERROR;
}
if (retcode != SQL_SUCCESS && retcode != SQL_SUCCESS_WITH_INFO)
{
return retcode;
}
pdbc->state = en_dbc_connected;
setopterr |= _iodbcdm_dbcdelayset (pdbc, waMode);
if (setopterr != SQL_SUCCESS)
{
return SQL_SUCCESS_WITH_INFO;
}
return retcode;
}
SQLRETURN SQL_API
SQLConnect (
SQLHDBC hdbc,
SQLCHAR * szDSN,
SQLSMALLINT cbDSN,
SQLCHAR * szUID,
SQLSMALLINT cbUID,
SQLCHAR * szAuthStr,
SQLSMALLINT cbAuthStr)
{
ENTER_HDBC (hdbc, 1,
trace_SQLConnect (TRACE_ENTER,
hdbc,
szDSN, cbDSN,
szUID, cbUID,
szAuthStr, cbAuthStr));
retcode = SQLConnect_Internal (
hdbc,
szDSN, cbDSN,
szUID, cbUID,
szAuthStr, cbAuthStr, 'A');
LEAVE_HDBC (hdbc, 1,
trace_SQLConnect (TRACE_LEAVE,
hdbc,
szDSN, cbDSN,
szUID, cbUID,
szAuthStr, cbAuthStr));
}
SQLRETURN SQL_API
SQLConnectA (
SQLHDBC hdbc,
SQLCHAR * szDSN,
SQLSMALLINT cbDSN,
SQLCHAR * szUID,
SQLSMALLINT cbUID,
SQLCHAR * szAuthStr,
SQLSMALLINT cbAuthStr)
{
ENTER_HDBC (hdbc, 1,
trace_SQLConnect (TRACE_ENTER,
hdbc,
szDSN, cbDSN,
szUID, cbUID,
szAuthStr, cbAuthStr));
retcode = SQLConnect_Internal (
hdbc,
szDSN, cbDSN,
szUID, cbUID,
szAuthStr, cbAuthStr, 'A');
LEAVE_HDBC (hdbc, 1,
trace_SQLConnect (TRACE_LEAVE,
hdbc,
szDSN, cbDSN,
szUID, cbUID,
szAuthStr, cbAuthStr));
}
SQLRETURN SQL_API
SQLConnectW (SQLHDBC hdbc,
SQLWCHAR * szDSN,
SQLSMALLINT cbDSN,
SQLWCHAR * szUID,
SQLSMALLINT cbUID,
SQLWCHAR * szAuthStr,
SQLSMALLINT cbAuthStr)
{
ENTER_HDBC (hdbc, 1,
trace_SQLConnectW (TRACE_ENTER,
hdbc,
szDSN, cbDSN,
szUID, cbUID,
szAuthStr, cbAuthStr));
retcode = SQLConnect_Internal (
hdbc,
szDSN, cbDSN,
szUID, cbUID,
szAuthStr, cbAuthStr,
'W');
LEAVE_HDBC (hdbc, 1,
trace_SQLConnectW (TRACE_LEAVE,
hdbc,
szDSN, cbDSN,
szUID, cbUID,
szAuthStr, cbAuthStr));
}
SQLRETURN SQL_API
SQLDriverConnect_Internal (
SQLHDBC hdbc,
SQLHWND hwnd,
SQLPOINTER szConnStrIn,
SQLSMALLINT cbConnStrIn,
SQLPOINTER szConnStrOut,
SQLSMALLINT cbConnStrOutMax,
SQLPOINTER pcbConnStrOut,
SQLUSMALLINT fDriverCompletion,
SQLCHAR waMode)
{
CONN (pdbc, hdbc);
ENVR (penv, NULL);
HDLL hdll;
void *drv;
SQLWCHAR drvbuf[1024];
void *dsn;
SQLWCHAR dsnbuf[SQL_MAX_DSN_LENGTH + 1];
SQLWCHAR prov[1024];
SWORD thread_safe;
SWORD unload_safe;
char buf[1024];
HPROC hproc = SQL_NULL_HPROC;
void *_ConnStrIn = NULL;
void *_ConnStrOut = NULL;
void *connStrOut = szConnStrOut;
void *connStrIn = szConnStrIn;
char *_dsn_u8 = NULL;
char *_drv_u8 = NULL;
UWORD config;
HPROC dialproc = SQL_NULL_HPROC;
sqlstcode_t sqlstat = en_00000;
SQLRETURN retcode = SQL_SUCCESS;
SQLRETURN setopterr = SQL_SUCCESS;
if ((cbConnStrIn < 0 && cbConnStrIn != SQL_NTS) ||
(cbConnStrOutMax < 0 && cbConnStrOutMax != SQL_NTS))
{
PUSHSQLERR (pdbc->herr, en_S1090);
return SQL_ERROR;
}
if (pdbc->state != en_dbc_allocated)
{
PUSHSQLERR (pdbc->herr, en_08002);
return SQL_ERROR;
}
SQLGetConfigMode (&config);
if (waMode != 'W')
{
drv = _iodbcdm_getkeyvalinstr ((char *)szConnStrIn, cbConnStrIn,
"DRIVER", (char *) drvbuf, sizeof (drvbuf));
dsn = _iodbcdm_getkeyvalinstr ((char *)szConnStrIn, cbConnStrIn,
"DSN", (char *) dsnbuf, sizeof (dsnbuf));
}
else
{
drv = _iodbcdm_getkeyvalinstrw ((wchar_t *)szConnStrIn, cbConnStrIn,
L"DRIVER", drvbuf, sizeof (drvbuf) / sizeof (SQLWCHAR));
dsn = _iodbcdm_getkeyvalinstrw ((wchar_t *)szConnStrIn, cbConnStrIn,
L"DSN", dsnbuf, sizeof (dsnbuf) / sizeof (SQLWCHAR));
}
switch (fDriverCompletion)
{
case SQL_DRIVER_NOPROMPT:
if (!dsn && !drv)
{
PUSHSQLERR (pdbc->herr, en_IM007);
return SQL_ERROR;
}
break;
case SQL_DRIVER_COMPLETE:
case SQL_DRIVER_COMPLETE_REQUIRED:
if (dsn != NULL || drv != NULL)
{
break;
}
case SQL_DRIVER_PROMPT:
hdll = _iodbcdm_dllopen ("libiodbcadm.so");
if (dsn == NULL && drv == NULL)
{
if (waMode != 'W')
dialproc = _iodbcdm_dllproc (hdll, "iodbcdm_drvconn_dialbox");
else
dialproc = _iodbcdm_dllproc (hdll, "iodbcdm_drvconn_dialboxw");
if (dialproc == SQL_NULL_HPROC)
{
sqlstat = en_IM008;
break;
}
retcode = dialproc (hwnd,
prov,
sizeof (prov) / sizeof (SQLWCHAR),
&sqlstat,
fDriverCompletion,
&config);
if (retcode != SQL_SUCCESS)
{
if (retcode != SQL_NO_DATA_FOUND)
PUSHSQLERR (pdbc->herr, sqlstat);
goto end;
}
connStrIn = szConnStrIn = prov;
if (cbConnStrIn == SQL_NTS)
{
if (waMode != 'W')
cbConnStrIn = STRLEN (szConnStrIn);
else
cbConnStrIn = WCSLEN (szConnStrIn);
}
if (waMode != 'W')
dsn = _iodbcdm_getkeyvalinstr ((char *) prov, STRLEN (prov),
"DSN", (char *) dsnbuf, sizeof (dsnbuf));
else
dsn = _iodbcdm_getkeyvalinstrw (prov, WCSLEN (prov),
L"DSN", dsnbuf, sizeof (dsnbuf) / sizeof (SQLWCHAR));
}
break;
default:
sqlstat = en_S1110;
break;
}
if (sqlstat != en_00000)
{
PUSHSQLERR (pdbc->herr, sqlstat);
return SQL_ERROR;
}
if (waMode == 'W')
{
if (dsn != NULL)
{
dsn = _dsn_u8 = (char *) dm_SQL_WtoU8((SQLWCHAR*)dsn, SQL_NTS);
if (dsn == NULL)
{
PUSHSQLERR (pdbc->herr, en_S1001);
return SQL_ERROR;
}
}
if (drv != NULL)
{
drv = _drv_u8 = (char *) dm_SQL_WtoU8((SQLWCHAR*)drv, SQL_NTS);
if (drv == NULL)
{
PUSHSQLERR (pdbc->herr, en_S1001);
return SQL_ERROR;
}
}
}
if (dsn == NULL || *(char *) dsn == '\0')
{
dsn = (void *) "default";
}
else
{
setopterr |= _iodbcdm_con_settracing (pdbc, (SQLCHAR *) dsn, SQL_NTS, waMode);
}
thread_safe = 1;
SQLSetConfigMode (ODBC_BOTH_DSN);
if (SQLGetPrivateProfileString ((char *) dsn, "ThreadManager", "",
buf, sizeof (buf), "odbc.ini")
&& (STRCASEEQ (buf, "on") || STRCASEEQ (buf, "1")))
{
thread_safe = 0;
}
unload_safe = 0;
SQLSetConfigMode (ODBC_BOTH_DSN);
if (SQLGetPrivateProfileString ((char *) dsn, "UnloadSafe", "",
buf, sizeof (buf), "odbc.ini")
&& (STRCASEEQ (buf, "on") || STRCASEEQ (buf, "1")))
{
unload_safe = 1;
}
if (drv == NULL || *(char *) drv == '\0')
{
SQLSetConfigMode (ODBC_BOTH_DSN);
if (SQLGetPrivateProfileString ((char *) dsn, "Driver", "",
buf, sizeof (buf), "odbc.ini") != 0)
{
drv = buf;
}
}
if (drv == NULL)
{
MEM_FREE (_dsn_u8);
MEM_FREE (_drv_u8);
PUSHSQLERR (pdbc->herr, en_IM002);
return SQL_ERROR;
}
retcode = _iodbcdm_driverload ((char *) drv, pdbc, thread_safe, unload_safe, waMode);
MEM_FREE (_dsn_u8);
MEM_FREE (_drv_u8);
switch (retcode)
{
case SQL_SUCCESS:
break;
case SQL_SUCCESS_WITH_INFO:
#if 0
setopterr = SQL_ERROR;
#endif
break;
default:
return retcode;
}
penv = (ENV_t *) pdbc->henv;
if ((penv->unicode_driver && waMode != 'W')
|| (!penv->unicode_driver && waMode == 'W'))
{
if (waMode != 'W')
{
if ((_ConnStrOut =
malloc (cbConnStrOutMax * sizeof (SQLWCHAR) + 1)) == NULL)
{
PUSHSQLERR (pdbc->herr, en_HY001);
return SQL_ERROR;
}
_ConnStrIn = dm_SQL_A2W ((SQLCHAR *) szConnStrIn, cbConnStrIn);
}
else
{
if ((_ConnStrOut = malloc (cbConnStrOutMax + 1)) == NULL)
{
PUSHSQLERR (pdbc->herr, en_HY001);
return SQL_ERROR;
}
_ConnStrIn = dm_SQL_W2A ((SQLWCHAR *) szConnStrIn, cbConnStrIn);
}
connStrOut = _ConnStrOut;
connStrIn = _ConnStrIn;
cbConnStrIn = SQL_NTS;
}
SQLSetConfigMode (config);
CALL_UDRIVER (hdbc, pdbc, retcode, hproc, penv->unicode_driver,
en_DriverConnect, (pdbc->dhdbc,
hwnd,
connStrIn,
cbConnStrIn,
connStrOut, cbConnStrOutMax, pcbConnStrOut, fDriverCompletion));
MEM_FREE (_ConnStrIn);
if (hproc == SQL_NULL_HPROC)
{
MEM_FREE (_ConnStrOut);
_iodbcdm_driverunload (pdbc);
PUSHSQLERR (pdbc->herr, en_IM001);
return SQL_ERROR;
}
if (szConnStrOut
&& (retcode == SQL_SUCCESS || retcode == SQL_SUCCESS_WITH_INFO)
&& ((penv->unicode_driver && waMode != 'W')
|| (!penv->unicode_driver && waMode == 'W')))
{
if (waMode != 'W')
{
dm_StrCopyOut2_W2A ((SQLWCHAR *) connStrOut, (SQLCHAR *) szConnStrOut, cbConnStrOutMax, NULL);
}
else
{
dm_StrCopyOut2_A2W ((SQLCHAR *) connStrOut, (SQLWCHAR *) szConnStrOut, cbConnStrOutMax, NULL);
}
}
MEM_FREE (_ConnStrOut);
if (retcode != SQL_SUCCESS && retcode != SQL_SUCCESS_WITH_INFO)
{
return retcode;
}
pdbc->state = en_dbc_connected;
setopterr |= _iodbcdm_dbcdelayset (pdbc, waMode);
if (setopterr != SQL_SUCCESS)
{
return SQL_SUCCESS_WITH_INFO;
}
end:
return retcode;
}
SQLRETURN SQL_API
SQLDriverConnect (SQLHDBC hdbc,
SQLHWND hwnd,
SQLCHAR * szConnStrIn,
SQLSMALLINT cbConnStrIn,
SQLCHAR * szConnStrOut,
SQLSMALLINT cbConnStrOutMax,
SQLSMALLINT * pcbConnStrOut,
SQLUSMALLINT fDriverCompletion)
{
ENTER_HDBC (hdbc, 1,
trace_SQLDriverConnect (TRACE_ENTER,
hdbc,
hwnd,
szConnStrIn, cbConnStrIn,
szConnStrOut, cbConnStrOutMax, pcbConnStrOut,
fDriverCompletion));
retcode = SQLDriverConnect_Internal(
hdbc,
hwnd,
szConnStrIn, cbConnStrIn,
szConnStrOut, cbConnStrOutMax, pcbConnStrOut,
fDriverCompletion,
'A');
LEAVE_HDBC (hdbc, 1,
trace_SQLDriverConnect (TRACE_LEAVE,
hdbc,
hwnd,
szConnStrIn, cbConnStrIn,
szConnStrOut, cbConnStrOutMax, pcbConnStrOut,
fDriverCompletion));
}
SQLRETURN SQL_API
SQLDriverConnectA (SQLHDBC hdbc,
SQLHWND hwnd,
SQLCHAR * szConnStrIn,
SQLSMALLINT cbConnStrIn,
SQLCHAR * szConnStrOut,
SQLSMALLINT cbConnStrOutMax,
SQLSMALLINT * pcbConnStrOut,
SQLUSMALLINT fDriverCompletion)
{
ENTER_HDBC (hdbc, 1,
trace_SQLDriverConnect (TRACE_ENTER,
hdbc,
hwnd,
szConnStrIn, cbConnStrIn,
szConnStrOut, cbConnStrOutMax, pcbConnStrOut,
fDriverCompletion));
retcode = SQLDriverConnect_Internal(
hdbc,
hwnd,
szConnStrIn, cbConnStrIn,
szConnStrOut, cbConnStrOutMax, pcbConnStrOut,
fDriverCompletion,
'A');
LEAVE_HDBC (hdbc, 1,
trace_SQLDriverConnect (TRACE_LEAVE,
hdbc,
hwnd,
szConnStrIn, cbConnStrIn,
szConnStrOut, cbConnStrOutMax, pcbConnStrOut,
fDriverCompletion));
}
SQLRETURN SQL_API
SQLDriverConnectW (SQLHDBC hdbc,
SQLHWND hwnd,
SQLWCHAR * szConnStrIn,
SQLSMALLINT cbConnStrIn,
SQLWCHAR * szConnStrOut,
SQLSMALLINT cbConnStrOutMax,
SQLSMALLINT * pcbConnStrOut,
SQLUSMALLINT fDriverCompletion)
{
ENTER_HDBC (hdbc, 1,
trace_SQLDriverConnectW (TRACE_ENTER,
hdbc,
hwnd,
szConnStrIn, cbConnStrIn,
szConnStrOut, cbConnStrOutMax, pcbConnStrOut,
fDriverCompletion));
retcode = SQLDriverConnect_Internal(
hdbc,
hwnd,
szConnStrIn, cbConnStrIn,
szConnStrOut, cbConnStrOutMax, pcbConnStrOut,
fDriverCompletion,
'W');
LEAVE_HDBC (hdbc, 1,
trace_SQLDriverConnectW (TRACE_LEAVE,
hdbc,
hwnd,
szConnStrIn, cbConnStrIn,
szConnStrOut, cbConnStrOutMax, pcbConnStrOut,
fDriverCompletion));
}
SQLRETURN SQL_API
SQLBrowseConnect_Internal (SQLHDBC hdbc,
SQLPOINTER szConnStrIn,
SQLSMALLINT cbConnStrIn,
SQLPOINTER szConnStrOut,
SQLSMALLINT cbConnStrOutMax, SQLSMALLINT * pcbConnStrOut,
SQLCHAR waMode)
{
CONN (pdbc, hdbc);
ENVR (penv, NULL);
void *drv, *dsn;
char drvbuf[4096];
char dsnbuf[SQL_MAX_DSN_LENGTH * UTF8_MAX_CHAR_LEN + 1];
char buf[1024];
SWORD thread_safe;
SWORD unload_safe;
HPROC hproc = SQL_NULL_HPROC;
void * _ConnStrIn = NULL;
void * _ConnStrOut = NULL;
void * connStrOut = szConnStrOut;
void * connStrIn = szConnStrIn;
SQLRETURN retcode = SQL_SUCCESS;
SQLRETURN setopterr = SQL_SUCCESS;
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 ((char *) szConnStrIn, cbConnStrIn,
"DRIVER", (char*)drvbuf, sizeof (drvbuf));
dsn = _iodbcdm_getkeyvalinstr ((char *) szConnStrIn, cbConnStrIn,
"DSN", (char*)dsnbuf, sizeof (dsnbuf));
if (dsn == NULL || ((char*)dsn)[0] == '\0')
dsn = (void *) "default";
else
{
if (_iodbcdm_con_settracing (pdbc, (SQLCHAR *) dsn, SQL_NTS, waMode) == SQL_ERROR)
{
return SQL_ERROR;
}
}
thread_safe = 1;
SQLSetConfigMode (ODBC_BOTH_DSN);
if ( SQLGetPrivateProfileString ((char *) dsn, "ThreadManager", "",
buf, sizeof(buf), "odbc.ini") &&
(STRCASEEQ (buf, "on") || STRCASEEQ (buf, "1")))
{
thread_safe = 0;
}
unload_safe = 0;
SQLSetConfigMode (ODBC_BOTH_DSN);
if ( SQLGetPrivateProfileString ((char *) dsn, "ThreadManager", "",
buf, sizeof(buf), "odbc.ini") &&
(STRCASEEQ (buf, "on") || STRCASEEQ (buf, "1")))
{
unload_safe = 1;
}
if (drv == NULL || *(char*)drv == '\0')
{
SQLSetConfigMode (ODBC_BOTH_DSN);
if ( SQLGetPrivateProfileString ((char *) dsn, "Driver", "",
buf, sizeof(buf), "odbc.ini") != 0)
{
drv = buf;
}
}
if (drv == NULL)
{
PUSHSQLERR (pdbc->herr, en_IM002);
return SQL_ERROR;
}
retcode = _iodbcdm_driverload ((char *) drv, pdbc, thread_safe, unload_safe, waMode);
switch (retcode)
{
case SQL_SUCCESS:
break;
case SQL_SUCCESS_WITH_INFO:
#if 0
setopterr = SQL_ERROR;
#endif
break;
default:
return retcode;
}
}
else if (pdbc->state != en_dbc_needdata)
{
PUSHSQLERR (pdbc->herr, en_08002);
return SQL_ERROR;
}
penv = (ENV_t *) pdbc->henv;
if ((penv->unicode_driver && waMode != 'W')
|| (!penv->unicode_driver && waMode == 'W'))
{
if (waMode != 'W')
{
if ((_ConnStrOut = malloc(cbConnStrOutMax * sizeof(SQLWCHAR) + 1)) == NULL)
{
PUSHSQLERR (pdbc->herr, en_HY001);
return SQL_ERROR;
}
_ConnStrIn = dm_SQL_A2W((SQLCHAR *)szConnStrIn, SQL_NTS);
}
else
{
if ((_ConnStrOut = malloc(cbConnStrOutMax + 1)) == NULL)
{
PUSHSQLERR (pdbc->herr, en_HY001);
return SQL_ERROR;
}
_ConnStrIn = dm_SQL_W2A((SQLWCHAR *)szConnStrIn, SQL_NTS);
}
connStrIn = _ConnStrIn;
cbConnStrIn = SQL_NTS;
connStrOut = _ConnStrOut;
}
CALL_UDRIVER(hdbc, pdbc, retcode, hproc, penv->unicode_driver,
en_BrowseConnect, (
pdbc->dhdbc,
connStrIn,
cbConnStrIn,
connStrOut,
cbConnStrOutMax,
pcbConnStrOut));
MEM_FREE(_ConnStrIn);
if (hproc == SQL_NULL_HPROC)
{
MEM_FREE(_ConnStrOut);
_iodbcdm_driverunload (pdbc);
pdbc->state = en_dbc_allocated;
PUSHSQLERR (pdbc->herr, en_IM001);
return SQL_ERROR;
}
if (szConnStrOut
&& (retcode == SQL_SUCCESS || retcode == SQL_SUCCESS_WITH_INFO)
&& ((penv->unicode_driver && waMode != 'W')
|| (!penv->unicode_driver && waMode == 'W')))
{
if (waMode != 'W')
{
dm_StrCopyOut2_W2A ((SQLWCHAR *) connStrOut, (SQLCHAR *) szConnStrOut, cbConnStrOutMax, NULL);
}
else
{
dm_StrCopyOut2_A2W ((SQLCHAR *) connStrOut, (SQLWCHAR *) szConnStrOut, cbConnStrOutMax, NULL);
}
}
MEM_FREE(_ConnStrOut);
switch (retcode)
{
case SQL_SUCCESS:
case SQL_SUCCESS_WITH_INFO:
pdbc->state = en_dbc_connected;
setopterr |= _iodbcdm_dbcdelayset (pdbc, waMode);
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;
break;
default:
break;
}
return retcode;
}
SQLRETURN SQL_API
SQLBrowseConnect (SQLHDBC hdbc,
SQLCHAR * szConnStrIn,
SQLSMALLINT cbConnStrIn,
SQLCHAR * szConnStrOut,
SQLSMALLINT cbConnStrOutMax,
SQLSMALLINT * pcbConnStrOut)
{
ENTER_HDBC (hdbc, 1,
trace_SQLBrowseConnect (TRACE_ENTER,
hdbc,
szConnStrIn, cbConnStrIn,
szConnStrOut, cbConnStrOutMax, pcbConnStrOut));
retcode = SQLBrowseConnect_Internal (
hdbc,
szConnStrIn, cbConnStrIn,
szConnStrOut, cbConnStrOutMax, pcbConnStrOut,
'A');
LEAVE_HDBC (hdbc, 1,
trace_SQLBrowseConnect (TRACE_LEAVE,
hdbc,
szConnStrIn, cbConnStrIn,
szConnStrOut, cbConnStrOutMax, pcbConnStrOut));
}
SQLRETURN SQL_API
SQLBrowseConnectA (SQLHDBC hdbc,
SQLCHAR * szConnStrIn,
SQLSMALLINT cbConnStrIn,
SQLCHAR * szConnStrOut,
SQLSMALLINT cbConnStrOutMax,
SQLSMALLINT * pcbConnStrOut)
{
ENTER_HDBC (hdbc, 1,
trace_SQLBrowseConnect (TRACE_ENTER,
hdbc,
szConnStrIn, cbConnStrIn,
szConnStrOut, cbConnStrOutMax, pcbConnStrOut));
retcode = SQLBrowseConnect_Internal (
hdbc,
szConnStrIn, cbConnStrIn,
szConnStrOut, cbConnStrOutMax, pcbConnStrOut,
'A');
LEAVE_HDBC (hdbc, 1,
trace_SQLBrowseConnect (TRACE_LEAVE,
hdbc,
szConnStrIn, cbConnStrIn,
szConnStrOut, cbConnStrOutMax, pcbConnStrOut));
}
SQLRETURN SQL_API
SQLBrowseConnectW (SQLHDBC hdbc,
SQLWCHAR * szConnStrIn,
SQLSMALLINT cbConnStrIn,
SQLWCHAR * szConnStrOut,
SQLSMALLINT cbConnStrOutMax,
SQLSMALLINT * pcbConnStrOut)
{
ENTER_HDBC (hdbc, 1,
trace_SQLBrowseConnectW (TRACE_ENTER,
hdbc,
szConnStrIn, cbConnStrIn,
szConnStrOut, cbConnStrOutMax, pcbConnStrOut));
retcode = SQLBrowseConnect_Internal (
hdbc,
szConnStrIn, cbConnStrIn,
szConnStrOut, cbConnStrOutMax, pcbConnStrOut,
'W');
LEAVE_HDBC (hdbc, 1,
trace_SQLBrowseConnectW (TRACE_LEAVE,
hdbc,
szConnStrIn, cbConnStrIn,
szConnStrOut, cbConnStrOutMax, pcbConnStrOut));
}
static SQLRETURN
SQLDisconnect_Internal (SQLHDBC hdbc)
{
CONN (pdbc, hdbc);
STMT (pstmt, NULL);
SQLRETURN retcode;
HPROC hproc = SQL_NULL_HPROC;
sqlstcode_t sqlstat = en_00000;
if (pdbc->state == en_dbc_allocated)
{
sqlstat = en_08003;
}
for (pstmt = (STMT_t *) pdbc->hstmt;
pstmt != NULL && sqlstat == en_00000;
pstmt = (STMT_t *) pstmt->next)
{
if (pstmt->state >= en_stmt_needdata
|| pstmt->asyn_on != en_NullProc)
{
sqlstat = en_S1010;
}
}
if (sqlstat == en_00000)
{
hproc = _iodbcdm_getproc (pdbc, en_Disconnect);
if (hproc == SQL_NULL_HPROC)
{
sqlstat = en_IM001;
}
}
if (sqlstat != en_00000)
{
PUSHSQLERR (pdbc->herr, sqlstat);
return SQL_ERROR;
}
CALL_DRIVER (hdbc, pdbc, retcode, hproc, en_Disconnect, (
pdbc->dhdbc));
if (retcode == SQL_SUCCESS || retcode == SQL_SUCCESS_WITH_INFO)
{
retcode = SQL_SUCCESS;
}
else
{
return retcode;
}
for (; pdbc->hstmt;)
{
_iodbcdm_dropstmt (pdbc->hstmt);
}
if (retcode == SQL_SUCCESS)
{
pdbc->state = en_dbc_allocated;
}
return retcode;
}
SQLRETURN SQL_API
SQLDisconnect (SQLHDBC hdbc)
{
ENTER_HDBC (hdbc, 1,
trace_SQLDisconnect (TRACE_ENTER, hdbc));
retcode = SQLDisconnect_Internal (hdbc);
LEAVE_HDBC (hdbc, 1,
trace_SQLDisconnect (TRACE_LEAVE, hdbc));
}
SQLRETURN SQL_API
SQLNativeSql_Internal (SQLHDBC hdbc,
SQLPOINTER szSqlStrIn,
SQLINTEGER cbSqlStrIn,
SQLPOINTER szSqlStr,
SQLINTEGER cbSqlStrMax,
SQLINTEGER * pcbSqlStr,
SQLCHAR waMode)
{
CONN (pdbc, hdbc);
ENVR (penv, pdbc->henv);
sqlstcode_t sqlstat = en_00000;
SQLRETURN retcode = SQL_SUCCESS;
HPROC hproc = SQL_NULL_HPROC;
void * _SqlStrIn = NULL;
void * _SqlStr = NULL;
void * sqlStr = szSqlStr;
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;
}
if (pdbc->state <= en_dbc_needdata)
{
PUSHSQLERR (pdbc->herr, en_08003);
return SQL_ERROR;
}
if ((penv->unicode_driver && waMode != 'W')
|| (!penv->unicode_driver && waMode == 'W'))
{
if (waMode != 'W')
{
if ((_SqlStr = malloc(cbSqlStrMax * sizeof(SQLWCHAR) + 1)) == NULL)
{
PUSHSQLERR (pdbc->herr, en_HY001);
return SQL_ERROR;
}
_SqlStrIn = dm_SQL_A2W((SQLCHAR *)szSqlStrIn, SQL_NTS);
}
else
{
if ((_SqlStr = malloc(cbSqlStrMax + 1)) == NULL)
{
PUSHSQLERR (pdbc->herr, en_HY001);
return SQL_ERROR;
}
_SqlStrIn = dm_SQL_W2A((SQLWCHAR *)szSqlStrIn, SQL_NTS);
}
szSqlStrIn = _SqlStrIn;
cbSqlStrIn = SQL_NTS;
sqlStr = _SqlStr;
}
CALL_UDRIVER(hdbc, pdbc, retcode, hproc, penv->unicode_driver,
en_NativeSql, (
pdbc->dhdbc,
szSqlStrIn,
cbSqlStrIn,
sqlStr,
cbSqlStrMax,
pcbSqlStr));
MEM_FREE(_SqlStrIn);
if (hproc == SQL_NULL_HPROC)
{
MEM_FREE(_SqlStr);
PUSHSQLERR (pdbc->herr, en_IM001);
return SQL_ERROR;
}
if (szSqlStr
&& (retcode == SQL_SUCCESS || retcode == SQL_SUCCESS_WITH_INFO)
&& ((penv->unicode_driver && waMode != 'W')
|| (!penv->unicode_driver && waMode == 'W')))
{
if (waMode != 'W')
{
dm_StrCopyOut2_W2A ((SQLWCHAR *) sqlStr, (SQLCHAR *) szSqlStr, cbSqlStrMax, NULL);
}
else
{
dm_StrCopyOut2_A2W ((SQLCHAR *) sqlStr, (SQLWCHAR *) szSqlStr, cbSqlStrMax, NULL);
}
}
MEM_FREE(_SqlStr);
return retcode;
}
SQLRETURN SQL_API
SQLNativeSql (
SQLHDBC hdbc,
SQLCHAR * szSqlStrIn,
SQLINTEGER cbSqlStrIn,
SQLCHAR * szSqlStr,
SQLINTEGER cbSqlStrMax,
SQLINTEGER * pcbSqlStr)
{
ENTER_HDBC (hdbc, 0,
trace_SQLNativeSql (TRACE_ENTER,
hdbc,
szSqlStrIn, cbSqlStrIn,
szSqlStr, cbSqlStrMax, pcbSqlStr));
retcode = SQLNativeSql_Internal (
hdbc,
szSqlStrIn, cbSqlStrIn,
szSqlStr, cbSqlStrMax, pcbSqlStr,
'A');
LEAVE_HDBC (hdbc, 0,
trace_SQLNativeSql (TRACE_LEAVE,
hdbc,
szSqlStrIn, cbSqlStrIn,
szSqlStr, cbSqlStrMax, pcbSqlStr));
}
SQLRETURN SQL_API
SQLNativeSqlA (
SQLHDBC hdbc,
SQLCHAR * szSqlStrIn,
SQLINTEGER cbSqlStrIn,
SQLCHAR * szSqlStr,
SQLINTEGER cbSqlStrMax,
SQLINTEGER * pcbSqlStr)
{
ENTER_HDBC (hdbc, 0,
trace_SQLNativeSql (TRACE_ENTER,
hdbc,
szSqlStrIn, cbSqlStrIn,
szSqlStr, cbSqlStrMax, pcbSqlStr));
retcode = SQLNativeSql_Internal(
hdbc,
szSqlStrIn, cbSqlStrIn,
szSqlStr, cbSqlStrMax, pcbSqlStr,
'A');
LEAVE_HDBC (hdbc, 0,
trace_SQLNativeSql (TRACE_LEAVE,
hdbc,
szSqlStrIn, cbSqlStrIn,
szSqlStr, cbSqlStrMax, pcbSqlStr));
}
SQLRETURN SQL_API
SQLNativeSqlW (
SQLHDBC hdbc,
SQLWCHAR * szSqlStrIn,
SQLINTEGER cbSqlStrIn,
SQLWCHAR * szSqlStr,
SQLINTEGER cbSqlStrMax,
SQLINTEGER * pcbSqlStr)
{
ENTER_HDBC (hdbc, 0,
trace_SQLNativeSqlW (TRACE_ENTER,
hdbc,
szSqlStrIn, cbSqlStrIn,
szSqlStr, cbSqlStrMax, pcbSqlStr));
retcode = SQLNativeSql_Internal(
hdbc,
szSqlStrIn, cbSqlStrIn,
szSqlStr, cbSqlStrMax, pcbSqlStr,
'W');
LEAVE_HDBC (hdbc, 0,
trace_SQLNativeSqlW (TRACE_LEAVE,
hdbc,
szSqlStrIn, cbSqlStrIn,
szSqlStr, cbSqlStrMax, pcbSqlStr));
}