📄 hdbc.c
字号:
* 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;}SQLRETURN SQL_APISQLSetConnectOption ( SQLHDBC hdbc, SQLUSMALLINT fOption, SQLUINTEGER vParam){ CONN (pdbc, hdbc); SQLRETURN retcode; ENTER_HDBC (pdbc); retcode = _iodbcdm_SetConnectOption (hdbc, fOption, vParam); LEAVE_HDBC (pdbc, retcode);}SQLRETURN SQL_API_iodbcdm_GetConnectOption ( SQLHDBC hdbc, SQLUSMALLINT fOption, SQLPOINTER pvParam){ CONN (pdbc, hdbc); int sqlstat = en_00000; HPROC hproc = SQL_NULL_HPROC; SQLRETURN retcode;#if (ODBCVER < 0x0300) /* 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; }#endif /* 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 (ODBCVER >= 0x0300) if (fOption == SQL_OPT_TRACE || fOption == SQL_ATTR_TRACE)#else if (fOption == SQL_OPT_TRACE)#endif { if (pdbc->trace) *((UDWORD *) pvParam) = (UDWORD) SQL_OPT_TRACE_ON; else *((UDWORD *) pvParam) = (UDWORD) SQL_OPT_TRACE_OFF; return SQL_SUCCESS; }#if (ODBCVER >= 0x0300) if (fOption == SQL_OPT_TRACEFILE || fOption == SQL_ATTR_TRACEFILE)#else if (fOption == SQL_OPT_TRACEFILE)#endif { STRCPY (pvParam, pdbc->tfile); return SQL_SUCCESS; } if (pdbc->state != en_dbc_allocated) /* if already connected, we will invoke driver's function */ {#if (ODBCVER >= 0x0300) hproc = _iodbcdm_getproc (pdbc, en_GetConnectAttr); if (hproc != SQL_NULL_HPROC) { switch (fOption) { /* integer attributes */ case SQL_ATTR_ACCESS_MODE: case SQL_ATTR_AUTOCOMMIT: case SQL_ATTR_LOGIN_TIMEOUT: case SQL_ATTR_ODBC_CURSORS: case SQL_ATTR_PACKET_SIZE: case SQL_ATTR_QUIET_MODE: case SQL_ATTR_TRANSLATE_OPTION: case SQL_ATTR_TXN_ISOLATION: CALL_DRIVER (hdbc, pdbc, retcode, hproc, en_GetConnectAttr, (pdbc->dhdbc, fOption, pvParam, 0, NULL)); break; /* ODBC3 defined options */ case SQL_ATTR_ASYNC_ENABLE: case SQL_ATTR_AUTO_IPD: case SQL_ATTR_CONNECTION_DEAD: case SQL_ATTR_CONNECTION_TIMEOUT: case SQL_ATTR_METADATA_ID: PUSHSQLERR (pdbc->herr, en_IM001); return SQL_ERROR; default: /* string & driver defined */ CALL_DRIVER (hdbc, pdbc, retcode, hproc, en_GetConnectAttr, (pdbc->dhdbc, fOption, pvParam, SQL_MAX_OPTION_STRING_LENGTH, NULL)); } } else#endif { hproc = _iodbcdm_getproc (pdbc, en_GetConnectOption); if (hproc == SQL_NULL_HPROC) { PUSHSQLERR (pdbc->herr, en_IM001); return SQL_ERROR; } CALL_DRIVER (hdbc, pdbc, 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;}SQLRETURN SQL_APISQLGetConnectOption ( SQLHDBC hdbc, SQLUSMALLINT fOption, SQLPOINTER pvParam){ CONN (pdbc, hdbc); SQLRETURN retcode; ENTER_HDBC (pdbc); retcode = _iodbcdm_GetConnectOption (hdbc, fOption, pvParam); LEAVE_HDBC (pdbc, retcode);}static SQLRETURN_iodbcdm_transact ( HDBC hdbc, UWORD fType){ CONN (pdbc, hdbc); STMT_t FAR *pstmt; HPROC hproc; SQLRETURN 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 (pdbc, en_Transact); if (hproc != SQL_NULL_HPROC) { CALL_DRIVER (hdbc, pdbc, retcode, hproc, en_Transact, (SQL_NULL_HENV, pdbc->dhdbc, fType)); } else {#if (ODBCVER >= 0x300) hproc = _iodbcdm_getproc (pdbc, en_EndTran); if (hproc != SQL_NULL_HPROC) { CALL_DRIVER (pdbc, pdbc, retcode, hproc, en_EndTran, (SQL_HANDLE_DBC, pdbc->dhdbc, fType)); } else { PUSHSQLERR (pdbc->herr, en_IM001); return SQL_ERROR; }#else PUSHSQLERR (pdbc->herr, en_IM001); return SQL_ERROR;#endif } /* 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;}SQLRETURN SQL_APISQLTransact ( SQLHENV henv, SQLHDBC hdbc, SQLUSMALLINT fType){ GENV (genv, henv); CONN (pdbc, hdbc); HERR herr; SQLRETURN retcode = SQL_SUCCESS; ODBC_LOCK (); if (IS_VALID_HDBC (pdbc)) { CLEAR_ERRORS (pdbc); herr = pdbc->herr; } else if (IS_VALID_HENV (genv)) { CLEAR_ERRORS (genv); herr = genv->herr; } else { ODBC_UNLOCK (); return SQL_INVALID_HANDLE; } /* check argument */ if (fType != SQL_COMMIT && fType != SQL_ROLLBACK) { SQLHENV handle = IS_VALID_HDBC (pdbc) ? ((SQLHENV) pdbc) : genv; PUSHSQLERR (herr, en_S1012); ODBC_UNLOCK (); return SQL_ERROR; } if (hdbc != SQL_NULL_HDBC) { retcode = _iodbcdm_transact (pdbc, fType); } else { for (pdbc = (DBC_t FAR *) (genv->hdbc); pdbc != NULL; pdbc = pdbc->next) { retcode |= _iodbcdm_transact (pdbc, fType); } } if (retcode != SQL_SUCCESS && retcode != SQL_SUCCESS_WITH_INFO) { ODBC_UNLOCK (); /* fail on one of the connection */ return SQL_ERROR; } ODBC_UNLOCK (); return retcode;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -