environ.c
上传用户:blenddy
上传日期:2007-01-07
资源大小:6495k
文件大小:14k
- /* Module: environ.c
- *
- * Description: This module contains routines related to
- * the environment, such as storing connection handles,
- * and returning errors.
- *
- * Classes: EnvironmentClass (Functions prefix: "EN_")
- *
- * API functions: SQLAllocEnv, SQLFreeEnv, SQLError
- *
- * Comments: See "notice.txt" for copyright and license information.
- *
- */
- #include "environ.h"
- #include "connection.h"
- #include "statement.h"
- #include <stdlib.h>
- #include <malloc.h>
- /* The one instance of the handles */
- ConnectionClass *conns[MAX_CONNECTIONS];
- RETCODE SQL_API SQLAllocEnv(HENV FAR *phenv)
- {
- static char *func = "SQLAllocEnv";
- mylog("**** in SQLAllocEnv ** n");
- *phenv = (HENV) EN_Constructor();
- if ( ! *phenv) {
- *phenv = SQL_NULL_HENV;
- EN_log_error(func, "Error allocating environment", NULL);
- return SQL_ERROR;
- }
-
- mylog("** exit SQLAllocEnv: phenv = %u **n", *phenv);
- return SQL_SUCCESS;
- }
- RETCODE SQL_API SQLFreeEnv(HENV henv)
- {
- static char *func = "SQLFreeEnv";
- EnvironmentClass *env = (EnvironmentClass *) henv;
- mylog("**** in SQLFreeEnv: env = %u ** n", env);
- if (env && EN_Destructor(env)) {
- mylog(" okn");
- return SQL_SUCCESS;
- }
- mylog(" errorn");
- EN_log_error(func, "Error freeing environment", env);
- return SQL_ERROR;
- }
- // Returns the next SQL error information.
- RETCODE SQL_API SQLError(
- HENV henv,
- HDBC hdbc,
- HSTMT hstmt,
- UCHAR FAR *szSqlState,
- SDWORD FAR *pfNativeError,
- UCHAR FAR *szErrorMsg,
- SWORD cbErrorMsgMax,
- SWORD FAR *pcbErrorMsg)
- {
- char *msg;
- int status;
-
- mylog("**** SQLError: henv=%u, hdbc=%u, hstmt=%un", henv, hdbc, hstmt);
- if (SQL_NULL_HSTMT != hstmt) {
- // CC: return an error of a hstmt
- StatementClass *stmt = (StatementClass *) hstmt;
-
- if (SC_get_error(stmt, &status, &msg)) {
- mylog("SC_get_error: status = %d, msg = #%s#n", status, msg);
- if (NULL == msg) {
- if (NULL != szSqlState)
- strcpy(szSqlState, "00000");
- if (NULL != pcbErrorMsg)
- *pcbErrorMsg = 0;
- if ((NULL != szErrorMsg) && (cbErrorMsgMax > 0))
- szErrorMsg[0] = ' ';
-
- return SQL_NO_DATA_FOUND;
- }
- if (NULL != pcbErrorMsg)
- *pcbErrorMsg = (SWORD)strlen(msg);
-
- if ((NULL != szErrorMsg) && (cbErrorMsgMax > 0))
- strncpy_null(szErrorMsg, msg, cbErrorMsgMax);
-
- if (NULL != pfNativeError)
- *pfNativeError = status;
-
- if (NULL != szSqlState)
-
- switch (status) {
- // now determine the SQLSTATE to be returned
- case STMT_TRUNCATED:
- strcpy(szSqlState, "01004");
- // data truncated
- break;
- case STMT_INFO_ONLY:
- strcpy(szSqlState, "00000");
- // just information that is returned, no error
- break;
- case STMT_EXEC_ERROR:
- strcpy(szSqlState, "08S01");
- // communication link failure
- break;
- case STMT_CREATE_TABLE_ERROR:
- strcpy(szSqlState, "S0001");
- // table already exists
- break;
- case STMT_STATUS_ERROR:
- case STMT_SEQUENCE_ERROR:
- strcpy(szSqlState, "S1010");
- // Function sequence error
- break;
- case STMT_NO_MEMORY_ERROR:
- strcpy(szSqlState, "S1001");
- // memory allocation failure
- break;
- case STMT_COLNUM_ERROR:
- strcpy(szSqlState, "S1002");
- // invalid column number
- break;
- case STMT_NO_STMTSTRING:
- strcpy(szSqlState, "S1001");
- // having no stmtstring is also a malloc problem
- break;
- case STMT_ERROR_TAKEN_FROM_BACKEND:
- strcpy(szSqlState, "S1000");
- // general error
- break;
- case STMT_INTERNAL_ERROR:
- strcpy(szSqlState, "S1000");
- // general error
- break;
- case STMT_ROW_OUT_OF_RANGE:
- strcpy(szSqlState, "S1107");
- break;
- case STMT_OPERATION_CANCELLED:
- strcpy(szSqlState, "S1008");
- break;
- case STMT_NOT_IMPLEMENTED_ERROR:
- strcpy(szSqlState, "S1C00"); // == 'driver not capable'
- break;
- case STMT_OPTION_OUT_OF_RANGE_ERROR:
- strcpy(szSqlState, "S1092");
- break;
- case STMT_BAD_PARAMETER_NUMBER_ERROR:
- strcpy(szSqlState, "S1093");
- break;
- case STMT_INVALID_COLUMN_NUMBER_ERROR:
- strcpy(szSqlState, "S1002");
- break;
- case STMT_RESTRICTED_DATA_TYPE_ERROR:
- strcpy(szSqlState, "07006");
- break;
- case STMT_INVALID_CURSOR_STATE_ERROR:
- strcpy(szSqlState, "24000");
- break;
- case STMT_OPTION_VALUE_CHANGED:
- strcpy(szSqlState, "01S02");
- break;
- case STMT_INVALID_CURSOR_NAME:
- strcpy(szSqlState, "34000");
- break;
- case STMT_NO_CURSOR_NAME:
- strcpy(szSqlState, "S1015");
- break;
- case STMT_INVALID_ARGUMENT_NO:
- strcpy(szSqlState, "S1009");
- // invalid argument value
- break;
- case STMT_INVALID_CURSOR_POSITION:
- strcpy(szSqlState, "S1109");
- break;
-
- case STMT_VALUE_OUT_OF_RANGE:
- strcpy(szSqlState, "22003");
- break;
- case STMT_OPERATION_INVALID:
- strcpy(szSqlState, "S1011");
- break;
- default:
- strcpy(szSqlState, "S1000");
- // also a general error
- break;
- }
- mylog(" szSqlState = '%s', szError='%s'n", szSqlState, szErrorMsg);
-
- } else {
- if (NULL != szSqlState)
- strcpy(szSqlState, "00000");
- if (NULL != pcbErrorMsg)
- *pcbErrorMsg = 0;
- if ((NULL != szErrorMsg) && (cbErrorMsgMax > 0))
- szErrorMsg[0] = ' ';
-
- mylog(" returning NO_DATA_FOUNDn");
- return SQL_NO_DATA_FOUND;
- }
- return SQL_SUCCESS;
-
- } else if (SQL_NULL_HDBC != hdbc) {
- ConnectionClass *conn = (ConnectionClass *) hdbc;
-
- mylog("calling CC_get_errorn");
- if (CC_get_error(conn, &status, &msg)) {
- mylog("CC_get_error: status = %d, msg = #%s#n", status, msg);
- if (NULL == msg) {
- if (NULL != szSqlState)
- strcpy(szSqlState, "00000");
- if (NULL != pcbErrorMsg)
- *pcbErrorMsg = 0;
- if ((NULL != szErrorMsg) && (cbErrorMsgMax > 0))
- szErrorMsg[0] = ' ';
-
- return SQL_NO_DATA_FOUND;
- }
-
- if (NULL != pcbErrorMsg)
- *pcbErrorMsg = (SWORD)strlen(msg);
- if ((NULL != szErrorMsg) && (cbErrorMsgMax > 0))
- strncpy_null(szErrorMsg, msg, cbErrorMsgMax);
- if (NULL != pfNativeError)
- *pfNativeError = status;
-
- if (NULL != szSqlState)
- switch(status) {
- case STMT_OPTION_VALUE_CHANGED:
- case CONN_OPTION_VALUE_CHANGED:
- strcpy(szSqlState, "01S02");
- break;
- case STMT_TRUNCATED:
- case CONN_TRUNCATED:
- strcpy(szSqlState, "01004");
- // data truncated
- break;
- case CONN_INIREAD_ERROR:
- strcpy(szSqlState, "IM002");
- // data source not found
- break;
- case CONN_OPENDB_ERROR:
- strcpy(szSqlState, "08001");
- // unable to connect to data source
- break;
- case CONN_INVALID_AUTHENTICATION:
- case CONN_AUTH_TYPE_UNSUPPORTED:
- strcpy(szSqlState, "28000");
- break;
- case CONN_STMT_ALLOC_ERROR:
- strcpy(szSqlState, "S1001");
- // memory allocation failure
- break;
- case CONN_IN_USE:
- strcpy(szSqlState, "S1000");
- // general error
- break;
- case CONN_UNSUPPORTED_OPTION:
- strcpy(szSqlState, "IM001");
- // driver does not support this function
- case CONN_INVALID_ARGUMENT_NO:
- strcpy(szSqlState, "S1009");
- // invalid argument value
- break;
- case CONN_TRANSACT_IN_PROGRES:
- strcpy(szSqlState, "S1010");
- // when the user tries to switch commit mode in a transaction
- // -> function sequence error
- break;
- case CONN_NO_MEMORY_ERROR:
- strcpy(szSqlState, "S1001");
- break;
- case CONN_NOT_IMPLEMENTED_ERROR:
- case STMT_NOT_IMPLEMENTED_ERROR:
- strcpy(szSqlState, "S1C00");
- break;
- case CONN_VALUE_OUT_OF_RANGE:
- case STMT_VALUE_OUT_OF_RANGE:
- strcpy(szSqlState, "22003");
- break;
- default:
- strcpy(szSqlState, "S1000");
- // general error
- break;
- }
-
- } else {
- mylog("CC_Get_error returned nothing.n");
- if (NULL != szSqlState)
- strcpy(szSqlState, "00000");
- if (NULL != pcbErrorMsg)
- *pcbErrorMsg = 0;
- if ((NULL != szErrorMsg) && (cbErrorMsgMax > 0))
- szErrorMsg[0] = ' ';
-
- return SQL_NO_DATA_FOUND;
- }
- return SQL_SUCCESS;
-
- } else if (SQL_NULL_HENV != henv) {
- EnvironmentClass *env = (EnvironmentClass *)henv;
- if(EN_get_error(env, &status, &msg)) {
- mylog("EN_get_error: status = %d, msg = #%s#n", status, msg);
- if (NULL == msg) {
- if (NULL != szSqlState)
- strcpy(szSqlState, "00000");
- if (NULL != pcbErrorMsg)
- *pcbErrorMsg = 0;
- if ((NULL != szErrorMsg) && (cbErrorMsgMax > 0))
- szErrorMsg[0] = ' ';
- return SQL_NO_DATA_FOUND;
- }
- if (NULL != pcbErrorMsg)
- *pcbErrorMsg = (SWORD)strlen(msg);
- if ((NULL != szErrorMsg) && (cbErrorMsgMax > 0))
- strncpy_null(szErrorMsg, msg, cbErrorMsgMax);
- if (NULL != pfNativeError)
- *pfNativeError = status;
-
- if(szSqlState) {
- switch(status) {
- case ENV_ALLOC_ERROR:
- // memory allocation failure
- strcpy(szSqlState, "S1001");
- break;
- default:
- strcpy(szSqlState, "S1000");
- // general error
- break;
- }
- }
- } else {
- if (NULL != szSqlState)
- strcpy(szSqlState, "00000");
- if (NULL != pcbErrorMsg)
- *pcbErrorMsg = 0;
- if ((NULL != szErrorMsg) && (cbErrorMsgMax > 0))
- szErrorMsg[0] = ' ';
-
- return SQL_NO_DATA_FOUND;
- }
- return SQL_SUCCESS;
- }
-
- if (NULL != szSqlState)
- strcpy(szSqlState, "00000");
- if (NULL != pcbErrorMsg)
- *pcbErrorMsg = 0;
- if ((NULL != szErrorMsg) && (cbErrorMsgMax > 0))
- szErrorMsg[0] = ' ';
-
- return SQL_NO_DATA_FOUND;
- }
- /*********************************************************************/
- /*
- * EnvironmentClass implementation
- */
- EnvironmentClass
- *EN_Constructor(void)
- {
- EnvironmentClass *rv;
- rv = (EnvironmentClass *) malloc(sizeof(EnvironmentClass));
- if( rv) {
- rv->errormsg = 0;
- rv->errornumber = 0;
- }
- return rv;
- }
- char
- EN_Destructor(EnvironmentClass *self)
- {
- int lf;
- char rv = 1;
- mylog("in EN_Destructor, self=%un", self);
- // the error messages are static strings distributed throughout
- // the source--they should not be freed
- /* Free any connections belonging to this environment */
- for (lf = 0; lf < MAX_CONNECTIONS; lf++) {
- if (conns[lf] && conns[lf]->henv == self)
- rv = rv && CC_Destructor(conns[lf]);
- }
- mylog("exit EN_Destructor: rv = %dn", rv);
- return rv;
- }
- char
- EN_get_error(EnvironmentClass *self, int *number, char **message)
- {
- if(self && self->errormsg && self->errornumber) {
- *message = self->errormsg;
- *number = self->errornumber;
- self->errormsg = 0;
- self->errornumber = 0;
- return 1;
- } else {
- return 0;
- }
- }
- char
- EN_add_connection(EnvironmentClass *self, ConnectionClass *conn)
- {
- int i;
- mylog("EN_add_connection: self = %u, conn = %un", self, conn);
- for (i = 0; i < MAX_CONNECTIONS; i++) {
- if ( ! conns[i]) {
- conn->henv = self;
- conns[i] = conn;
- mylog(" added at i =%d, conn->henv = %u, conns[i]->henv = %un", i, conn->henv, conns[i]->henv);
- return TRUE;
- }
- }
- return FALSE;
- }
- char
- EN_remove_connection(EnvironmentClass *self, ConnectionClass *conn)
- {
- int i;
- for (i = 0; i < MAX_CONNECTIONS; i++)
- if (conns[i] == conn && conns[i]->status != CONN_EXECUTING) {
- conns[i] = NULL;
- return TRUE;
- }
- return FALSE;
- }
- void
- EN_log_error(char *func, char *desc, EnvironmentClass *self)
- {
- if (self) {
- qlog("ENVIRON ERROR: func=%s, desc='%s', errnum=%d, errmsg='%s'n", func, desc, self->errornumber, self->errormsg);
- }
- else
- qlog("INVALID ENVIRON HANDLE ERROR: func=%s, desc='%s'n", func, desc);
- }