hdbc.c
来自「A*算法 A*算法 A*算法 A*算法A*算法A*算法」· C语言 代码 · 共 812 行 · 第 1/2 页
C
812 行
CALL_DRIVER (hdbc, retcode, hproc, en_SetConnectOption,
(pdbc->dhdbc, fOption, vParam))
if (retcode != SQL_SUCCESS && retcode != SQL_SUCCESS_WITH_INFO)
{
return retcode;
}
}
/*
* Now, either driver's odbc call was successed or
* driver has not been loaded yet. In the first case, we
* need flip flag for(such as access_mode, autocommit, ...)
* for our finit state machine. While in the second case,
* we need save option values(such as current_qualifier, ...)
* for delaied setting. So, ...
*/
/* No matter what state we are(i.e. allocated or connected, ..)
* we need to flip the flag.
*/
switch (fOption)
{
case SQL_ACCESS_MODE:
pdbc->access_mode = vParam;
break;
case SQL_AUTOCOMMIT:
pdbc->autocommit = vParam;
break;
}
/* state transition */
if (pdbc->state != en_dbc_allocated)
{
return retcode;
}
/* Only 'allocated' state is possible here, and we need to
* save the options for delaied setting.
*/
switch (fOption)
{
case SQL_CURRENT_QUALIFIER:
if (pdbc->current_qualifier != NULL)
{
MEM_FREE (pdbc->current_qualifier);
}
if (vParam == 0UL)
{
pdbc->current_qualifier = NULL;
break;
}
pdbc->current_qualifier
= (char FAR *) MEM_ALLOC (
STRLEN (vParam) + 1);
if (pdbc->current_qualifier == NULL)
{
PUSHSQLERR (pdbc->herr, en_S1001);
return SQL_ERROR;
}
STRCPY (pdbc->current_qualifier, vParam);
break;
case SQL_LOGIN_TIMEOUT:
pdbc->login_timeout = vParam;
break;
case SQL_ODBC_CURSORS:
pdbc->odbc_cursors = vParam;
break;
case SQL_PACKET_SIZE:
pdbc->packet_size = vParam;
break;
case SQL_QUIET_MODE:
pdbc->quiet_mode = vParam;
break;
case SQL_TXN_ISOLATION:
pdbc->txn_isolation = vParam;
break;
default:
/* Since we didn't save the option value for delaied
* setting, we should raise an error here.
*/
break;
}
return retcode;
}
RETCODE SQL_API
SQLGetConnectOption (
HDBC hdbc,
UWORD fOption,
PTR pvParam)
{
DBC_t FAR *pdbc = (DBC_t FAR *) hdbc;
int sqlstat = en_00000;
HPROC hproc = SQL_NULL_HPROC;
RETCODE retcode;
if (hdbc == SQL_NULL_HDBC)
{
return SQL_INVALID_HANDLE;
}
/* check option */
if (fOption < SQL_CONN_OPT_MIN ||
(fOption > SQL_CONN_OPT_MAX && fOption < SQL_CONNECT_OPT_DRVR_START))
{
PUSHSQLERR (pdbc->herr, en_S1092);
return SQL_ERROR;
}
/* check state */
switch (pdbc->state)
{
case en_dbc_allocated:
if (fOption != SQL_ACCESS_MODE
&& fOption != SQL_AUTOCOMMIT
&& fOption != SQL_LOGIN_TIMEOUT
&& fOption != SQL_OPT_TRACE
&& fOption != SQL_OPT_TRACEFILE)
{
sqlstat = en_08003;
}
/* MS ODBC SDK document only
* allows SQL_ACCESS_MODE
* and SQL_AUTOCOMMIT in this
* dbc state. We allow another
* two options, because they
* are only meaningful for driver
* manager.
*/
break;
case en_dbc_needdata:
sqlstat = en_S1010;
break;
default:
break;
}
if (sqlstat != en_00000)
{
PUSHSQLERR (pdbc->herr, sqlstat);
return SQL_ERROR;
}
/* Tracing and tracing file options are only
* meaningful for driver manager
*/
if (fOption == SQL_OPT_TRACE)
{
if (pdbc->trace)
*((UDWORD *) pvParam) = (UDWORD) SQL_OPT_TRACE_ON;
else
*((UDWORD *) pvParam) = (UDWORD) SQL_OPT_TRACE_OFF;
return SQL_SUCCESS;
}
if (fOption == SQL_OPT_TRACEFILE)
{
STRCPY (pvParam, pdbc->tfile);
return SQL_ERROR;
}
if (pdbc->state != en_dbc_allocated)
/* if already connected, we will invoke driver's function */
{
hproc = _iodbcdm_getproc (hdbc, en_GetConnectOption);
if (hproc == SQL_NULL_HPROC)
{
PUSHSQLERR (pdbc->herr, en_IM001);
return SQL_ERROR;
}
CALL_DRIVER (hdbc, retcode, hproc, en_GetConnectOption,
(pdbc->dhdbc, fOption, pvParam))
return retcode;
}
/* We needn't to handle options which are not allowed
* to be *get* at a allocated dbc state(and two tracing
* options which has been handled and returned). Thus,
* there are only two possible cases.
*/
switch (fOption)
{
case SQL_ACCESS_MODE:
*((UDWORD *) pvParam) = pdbc->access_mode;
break;
case SQL_AUTOCOMMIT:
*((UDWORD *) pvParam) = pdbc->autocommit;
break;
case SQL_LOGIN_TIMEOUT:
*((UDWORD *) pvParam) = pdbc->login_timeout;
break;
default:
break;
}
return SQL_SUCCESS;
}
static RETCODE
_iodbcdm_transact (
HDBC hdbc,
UWORD fType)
{
DBC_t FAR *pdbc = (DBC_t FAR *) hdbc;
STMT_t FAR *pstmt;
HPROC hproc;
RETCODE retcode;
/* check state */
switch (pdbc->state)
{
case en_dbc_allocated:
case en_dbc_needdata:
PUSHSQLERR (pdbc->herr, en_08003);
return SQL_ERROR;
case en_dbc_connected:
return SQL_SUCCESS;
case en_dbc_hstmt:
default:
break;
}
for (pstmt = (STMT_t FAR *) (pdbc->hstmt);
pstmt != NULL;
pstmt = pstmt->next)
{
if (pstmt->state >= en_stmt_needdata
|| pstmt->asyn_on != en_NullProc)
{
PUSHSQLERR (pdbc->herr, en_S1010);
return SQL_ERROR;
}
}
hproc = _iodbcdm_getproc (hdbc, en_Transact);
if (hproc == SQL_NULL_HPROC)
{
PUSHSQLERR (pdbc->herr, en_IM001);
return SQL_ERROR;
}
CALL_DRIVER (hdbc, retcode, hproc, en_Transact,
(SQL_NULL_HENV, pdbc->dhdbc, fType))
/* state transition */
if (retcode != SQL_SUCCESS && retcode != SQL_SUCCESS_WITH_INFO)
{
return retcode;
}
pdbc->state = en_dbc_hstmt;
for (pstmt = (STMT_t FAR *) (pdbc->hstmt);
pstmt != NULL;
pstmt = pstmt->next)
{
switch (pstmt->state)
{
case en_stmt_prepared:
if (pdbc->cb_commit == SQL_CB_DELETE
|| pdbc->cb_rollback == SQL_CB_DELETE)
{
pstmt->state = en_stmt_allocated;
pstmt->prep_state = 0;
break;
}
break;
case en_stmt_executed:
case en_stmt_cursoropen:
case en_stmt_fetched:
case en_stmt_xfetched:
if (!pstmt->prep_state
&& pdbc->cb_commit != SQL_CB_PRESERVE
&& pdbc->cb_rollback != SQL_CB_PRESERVE)
{
pstmt->state = en_stmt_allocated;
pstmt->prep_state = 0;
pstmt->cursor_state = en_stmt_cursor_no;
break;
}
if (pstmt->prep_state)
{
if (pdbc->cb_commit == SQL_CB_DELETE
|| pdbc->cb_rollback == SQL_CB_DELETE)
{
pstmt->state = en_stmt_allocated;
pstmt->prep_state = 0;
pstmt->cursor_state = en_stmt_cursor_no;
break;
}
if (pdbc->cb_commit == SQL_CB_CLOSE
|| pdbc->cb_rollback == SQL_CB_CLOSE)
{
pstmt->state
= en_stmt_prepared;
pstmt->cursor_state
= en_stmt_cursor_no;
break;
}
break;
}
break;
default:
break;
}
}
return retcode;
}
RETCODE SQL_API
SQLTransact (
HENV henv,
HDBC hdbc,
UWORD fType)
{
GENV_t FAR *genv = (GENV_t FAR *) henv;
DBC_t FAR *pdbc = (DBC_t FAR *) hdbc;
HERR herr;
RETCODE retcode = 0;
if (hdbc != SQL_NULL_HDBC)
{
herr = pdbc->herr;
}
else if (henv != SQL_NULL_HENV)
{
herr = genv->herr;
}
else
{
return SQL_INVALID_HANDLE;
}
/* check argument */
if (fType != SQL_COMMIT
&& fType != SQL_ROLLBACK)
{
PUSHSQLERR (herr, en_S1012);
return SQL_ERROR;
}
if (hdbc != SQL_NULL_HDBC)
{
retcode = _iodbcdm_transact (hdbc, fType);
}
else
{
for (pdbc = (DBC_t FAR *) (genv->hdbc);
pdbc != NULL;
pdbc = pdbc->next)
{
retcode |= _iodbcdm_transact (hdbc, fType);
}
}
if (retcode != SQL_SUCCESS
&& retcode != SQL_SUCCESS_WITH_INFO)
{
/* fail on one of the connection */
return SQL_ERROR;
}
return retcode;
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?