environ.c
上传用户:blenddy
上传日期:2007-01-07
资源大小:6495k
文件大小:14k
源码类别:

数据库系统

开发平台:

Unix_Linux

  1. /* Module:          environ.c
  2.  *
  3.  * Description:     This module contains routines related to 
  4.  *                  the environment, such as storing connection handles,
  5.  *                  and returning errors.
  6.  *
  7.  * Classes:         EnvironmentClass (Functions prefix: "EN_")
  8.  *
  9.  * API functions:   SQLAllocEnv, SQLFreeEnv, SQLError
  10.  *
  11.  * Comments:        See "notice.txt" for copyright and license information.
  12.  *
  13.  */
  14. #include "environ.h"
  15. #include "connection.h"
  16. #include "statement.h"
  17. #include <stdlib.h>
  18. #include <malloc.h>
  19. /* The one instance of the handles */
  20. ConnectionClass *conns[MAX_CONNECTIONS];
  21. RETCODE SQL_API SQLAllocEnv(HENV FAR *phenv)
  22. {
  23. static char *func = "SQLAllocEnv";
  24. mylog("**** in SQLAllocEnv ** n");
  25. *phenv = (HENV) EN_Constructor();
  26. if ( ! *phenv) {
  27. *phenv = SQL_NULL_HENV;
  28. EN_log_error(func, "Error allocating environment", NULL);
  29. return SQL_ERROR;
  30. }
  31.  
  32. mylog("** exit SQLAllocEnv: phenv = %u **n", *phenv);
  33. return SQL_SUCCESS;
  34. }
  35. RETCODE SQL_API SQLFreeEnv(HENV henv)
  36. {
  37. static char *func = "SQLFreeEnv";
  38. EnvironmentClass *env = (EnvironmentClass *) henv;
  39. mylog("**** in SQLFreeEnv: env = %u ** n", env);
  40. if (env && EN_Destructor(env)) {
  41. mylog("   okn");
  42. return SQL_SUCCESS;
  43. }
  44. mylog("    errorn");
  45. EN_log_error(func, "Error freeing environment", env);
  46. return SQL_ERROR;
  47. }
  48. //      Returns the next SQL error information.
  49. RETCODE SQL_API SQLError(
  50.         HENV       henv,
  51.         HDBC       hdbc,
  52.         HSTMT      hstmt,
  53.         UCHAR  FAR *szSqlState,
  54.         SDWORD FAR *pfNativeError,
  55.         UCHAR  FAR *szErrorMsg,
  56.         SWORD      cbErrorMsgMax,
  57.         SWORD  FAR *pcbErrorMsg)
  58. {
  59. char *msg;
  60. int status;
  61.     
  62. mylog("**** SQLError: henv=%u, hdbc=%u, hstmt=%un", henv, hdbc, hstmt);
  63.     if (SQL_NULL_HSTMT != hstmt) {
  64.         // CC: return an error of a hstmt 
  65.         StatementClass *stmt = (StatementClass *) hstmt;
  66.         
  67.         if (SC_get_error(stmt, &status, &msg)) {
  68. mylog("SC_get_error: status = %d, msg = #%s#n", status, msg);
  69.             if (NULL == msg) {
  70.                 if (NULL != szSqlState)
  71.                     strcpy(szSqlState, "00000");
  72.                 if (NULL != pcbErrorMsg)
  73.                     *pcbErrorMsg = 0;
  74.                 if ((NULL != szErrorMsg) && (cbErrorMsgMax > 0)) 
  75.                     szErrorMsg[0] = '';
  76.                 
  77.                 return SQL_NO_DATA_FOUND;
  78.             }                
  79.             if (NULL != pcbErrorMsg)                
  80.                 *pcbErrorMsg = (SWORD)strlen(msg);
  81.             
  82.             if ((NULL != szErrorMsg) && (cbErrorMsgMax > 0))
  83.                 strncpy_null(szErrorMsg, msg, cbErrorMsgMax);
  84.             
  85.             if (NULL != pfNativeError) 
  86.                 *pfNativeError = status;
  87.             
  88.             if (NULL != szSqlState)    
  89.                 
  90.                 switch (status) {
  91.                     // now determine the SQLSTATE to be returned
  92.                 case STMT_TRUNCATED:
  93.                     strcpy(szSqlState, "01004");
  94.                     // data truncated
  95.                     break;
  96.                 case STMT_INFO_ONLY:
  97.                     strcpy(szSqlState, "00000");
  98.                     // just information that is returned, no error
  99.                     break;
  100.                 case STMT_EXEC_ERROR:
  101.                     strcpy(szSqlState, "08S01");
  102.                     // communication link failure
  103.                     break;
  104.                 case STMT_CREATE_TABLE_ERROR:
  105.                     strcpy(szSqlState, "S0001");
  106.                     // table already exists
  107.                     break;
  108.                 case STMT_STATUS_ERROR:
  109.                 case STMT_SEQUENCE_ERROR:
  110.                     strcpy(szSqlState, "S1010");
  111.                     // Function sequence error
  112.                     break;
  113.                 case STMT_NO_MEMORY_ERROR:
  114.                     strcpy(szSqlState, "S1001");
  115.                     // memory allocation failure
  116.                     break;
  117.                 case STMT_COLNUM_ERROR:
  118.                     strcpy(szSqlState, "S1002");
  119.                     // invalid column number
  120.                     break;
  121.                 case STMT_NO_STMTSTRING:
  122.                     strcpy(szSqlState, "S1001");
  123.                     // having no stmtstring is also a malloc problem
  124.                     break;
  125.                 case STMT_ERROR_TAKEN_FROM_BACKEND:
  126.                     strcpy(szSqlState, "S1000");
  127.                     // general error
  128.                     break;
  129.                 case STMT_INTERNAL_ERROR:
  130.                     strcpy(szSqlState, "S1000");
  131.                     // general error
  132.                     break;  
  133. case STMT_ROW_OUT_OF_RANGE:
  134. strcpy(szSqlState, "S1107");
  135. break;
  136. case STMT_OPERATION_CANCELLED:
  137. strcpy(szSqlState, "S1008");
  138. break;
  139.                 case STMT_NOT_IMPLEMENTED_ERROR:
  140.                     strcpy(szSqlState, "S1C00"); // == 'driver not capable'
  141.                     break;
  142.                 case STMT_OPTION_OUT_OF_RANGE_ERROR:
  143.                     strcpy(szSqlState, "S1092");
  144.                     break;
  145.                 case STMT_BAD_PARAMETER_NUMBER_ERROR:
  146.                     strcpy(szSqlState, "S1093");
  147.                     break;
  148.                 case STMT_INVALID_COLUMN_NUMBER_ERROR:
  149.                     strcpy(szSqlState, "S1002");
  150.                     break;
  151.                 case STMT_RESTRICTED_DATA_TYPE_ERROR:
  152.                     strcpy(szSqlState, "07006");
  153.                     break;
  154.                 case STMT_INVALID_CURSOR_STATE_ERROR:
  155.                     strcpy(szSqlState, "24000");
  156.                     break;
  157.                 case STMT_OPTION_VALUE_CHANGED:
  158.                     strcpy(szSqlState, "01S02");
  159.                     break;
  160. case STMT_INVALID_CURSOR_NAME:
  161.                     strcpy(szSqlState, "34000");
  162.                     break;
  163. case STMT_NO_CURSOR_NAME:
  164.                     strcpy(szSqlState, "S1015");
  165.                     break;
  166.                 case STMT_INVALID_ARGUMENT_NO:
  167.                     strcpy(szSqlState, "S1009");
  168.                     // invalid argument value
  169.                     break;
  170. case STMT_INVALID_CURSOR_POSITION:
  171.                     strcpy(szSqlState, "S1109");
  172.                     break;
  173.                 
  174. case STMT_VALUE_OUT_OF_RANGE:
  175. strcpy(szSqlState, "22003");
  176. break;
  177. case STMT_OPERATION_INVALID:
  178. strcpy(szSqlState, "S1011");
  179. break;
  180. default:
  181.                     strcpy(szSqlState, "S1000");
  182.                     // also a general error
  183.                     break;
  184.                 }         
  185. mylog("       szSqlState = '%s', szError='%s'n", szSqlState, szErrorMsg);
  186.             
  187.         } else {
  188.             if (NULL != szSqlState)
  189.                 strcpy(szSqlState, "00000");
  190.             if (NULL != pcbErrorMsg)
  191.                 *pcbErrorMsg = 0;
  192.             if ((NULL != szErrorMsg) && (cbErrorMsgMax > 0)) 
  193.                 szErrorMsg[0] = '';
  194.             
  195. mylog("       returning NO_DATA_FOUNDn");
  196.             return SQL_NO_DATA_FOUND;
  197.         }
  198.         return SQL_SUCCESS;    
  199.         
  200.     } else if (SQL_NULL_HDBC != hdbc) {
  201.         ConnectionClass *conn = (ConnectionClass *) hdbc;
  202.         
  203. mylog("calling CC_get_errorn");
  204.         if (CC_get_error(conn, &status, &msg)) {
  205. mylog("CC_get_error: status = %d, msg = #%s#n", status, msg);
  206.             if (NULL == msg) {
  207.                 if (NULL != szSqlState)
  208.                     strcpy(szSqlState, "00000");
  209.                 if (NULL != pcbErrorMsg)
  210.                     *pcbErrorMsg = 0;
  211.                 if ((NULL != szErrorMsg) && (cbErrorMsgMax > 0)) 
  212.                     szErrorMsg[0] = '';
  213.                 
  214.                 return SQL_NO_DATA_FOUND;
  215.             }                
  216.             
  217.             if (NULL != pcbErrorMsg)
  218.                 *pcbErrorMsg = (SWORD)strlen(msg);
  219.             if ((NULL != szErrorMsg) && (cbErrorMsgMax > 0))    
  220.                 strncpy_null(szErrorMsg, msg, cbErrorMsgMax);
  221.             if (NULL != pfNativeError)    
  222.                 *pfNativeError = status;
  223.             
  224.             if (NULL != szSqlState) 
  225.                 switch(status) {
  226. case STMT_OPTION_VALUE_CHANGED:
  227. case CONN_OPTION_VALUE_CHANGED:
  228.                     strcpy(szSqlState, "01S02");
  229. break;
  230.                 case STMT_TRUNCATED:
  231. case CONN_TRUNCATED:
  232.                     strcpy(szSqlState, "01004");
  233.                     // data truncated
  234.                     break;
  235.                 case CONN_INIREAD_ERROR:
  236.                     strcpy(szSqlState, "IM002");
  237.                     // data source not found
  238.                     break;
  239.                 case CONN_OPENDB_ERROR:
  240.                     strcpy(szSqlState, "08001");
  241.                     // unable to connect to data source
  242.                     break;
  243. case CONN_INVALID_AUTHENTICATION:
  244. case CONN_AUTH_TYPE_UNSUPPORTED:
  245. strcpy(szSqlState, "28000");
  246. break;
  247.                 case CONN_STMT_ALLOC_ERROR:
  248.                     strcpy(szSqlState, "S1001");
  249.                     // memory allocation failure
  250.                     break;
  251.                 case CONN_IN_USE:
  252.                     strcpy(szSqlState, "S1000");
  253.                     // general error
  254.                     break;
  255.                 case CONN_UNSUPPORTED_OPTION:
  256.                     strcpy(szSqlState, "IM001");
  257.                     // driver does not support this function
  258.                 case CONN_INVALID_ARGUMENT_NO:
  259.                     strcpy(szSqlState, "S1009");
  260.                     // invalid argument value
  261.                     break;
  262.                 case CONN_TRANSACT_IN_PROGRES:
  263.                     strcpy(szSqlState, "S1010");
  264.                     // when the user tries to switch commit mode in a transaction
  265.                     // -> function sequence error
  266.                     break;
  267.                 case CONN_NO_MEMORY_ERROR:
  268.                     strcpy(szSqlState, "S1001");
  269.                     break;
  270.                 case CONN_NOT_IMPLEMENTED_ERROR:
  271. case STMT_NOT_IMPLEMENTED_ERROR:
  272.                     strcpy(szSqlState, "S1C00");
  273.                     break;
  274. case CONN_VALUE_OUT_OF_RANGE:
  275. case STMT_VALUE_OUT_OF_RANGE:
  276. strcpy(szSqlState, "22003");
  277. break;
  278.                 default:
  279.                     strcpy(szSqlState, "S1000");
  280.                     // general error
  281.                     break;
  282.                 }
  283.        
  284.         } else {
  285. mylog("CC_Get_error returned nothing.n");
  286.             if (NULL != szSqlState)
  287.                 strcpy(szSqlState, "00000");
  288.             if (NULL != pcbErrorMsg)
  289.                 *pcbErrorMsg = 0;
  290.             if ((NULL != szErrorMsg) && (cbErrorMsgMax > 0)) 
  291.                 szErrorMsg[0] = '';
  292.             
  293.             return SQL_NO_DATA_FOUND;
  294.         }
  295.         return SQL_SUCCESS;
  296.         
  297.     } else if (SQL_NULL_HENV != henv) {
  298.         EnvironmentClass *env = (EnvironmentClass *)henv;
  299.         if(EN_get_error(env, &status, &msg)) {
  300. mylog("EN_get_error: status = %d, msg = #%s#n", status, msg);
  301.             if (NULL == msg) {
  302.                 if (NULL != szSqlState)
  303.                     strcpy(szSqlState, "00000");
  304.                 if (NULL != pcbErrorMsg)
  305.                     *pcbErrorMsg = 0;
  306.                 if ((NULL != szErrorMsg) && (cbErrorMsgMax > 0)) 
  307.                     szErrorMsg[0] = '';
  308.                 return SQL_NO_DATA_FOUND;
  309.             }                
  310.             if (NULL != pcbErrorMsg)                
  311.                 *pcbErrorMsg = (SWORD)strlen(msg);
  312.             if ((NULL != szErrorMsg) && (cbErrorMsgMax > 0))
  313.                 strncpy_null(szErrorMsg, msg, cbErrorMsgMax);
  314.             if (NULL != pfNativeError) 
  315.                 *pfNativeError = status;
  316.             
  317.             if(szSqlState) {
  318.                 switch(status) {
  319.                 case ENV_ALLOC_ERROR:
  320.                     // memory allocation failure
  321.                     strcpy(szSqlState, "S1001");
  322.                     break;
  323.                 default:
  324.                     strcpy(szSqlState, "S1000");
  325.                     // general error
  326.                     break;
  327.                 }
  328.             }
  329.         } else {
  330.             if (NULL != szSqlState)
  331.                 strcpy(szSqlState, "00000");
  332.             if (NULL != pcbErrorMsg)
  333.                 *pcbErrorMsg = 0;
  334.             if ((NULL != szErrorMsg) && (cbErrorMsgMax > 0)) 
  335.                 szErrorMsg[0] = '';
  336.             
  337.             return SQL_NO_DATA_FOUND;
  338.         }
  339.         return SQL_SUCCESS;
  340.     }
  341.     
  342.     if (NULL != szSqlState)
  343.         strcpy(szSqlState, "00000");
  344.     if (NULL != pcbErrorMsg)
  345.         *pcbErrorMsg = 0;
  346.     if ((NULL != szErrorMsg) && (cbErrorMsgMax > 0)) 
  347.         szErrorMsg[0] = '';
  348.     
  349.     return SQL_NO_DATA_FOUND;
  350. }
  351. /*********************************************************************/
  352. /*
  353.  * EnvironmentClass implementation
  354.  */
  355. EnvironmentClass
  356. *EN_Constructor(void)
  357. {
  358. EnvironmentClass *rv;
  359.     rv = (EnvironmentClass *) malloc(sizeof(EnvironmentClass));
  360.     if( rv) {
  361. rv->errormsg = 0;
  362. rv->errornumber = 0;
  363. }
  364.     return rv;
  365. }
  366. char
  367. EN_Destructor(EnvironmentClass *self)
  368. {
  369. int lf;
  370. char rv = 1;
  371. mylog("in EN_Destructor, self=%un", self);
  372.     // the error messages are static strings distributed throughout
  373.     // the source--they should not be freed
  374. /* Free any connections belonging to this environment */
  375. for (lf = 0; lf < MAX_CONNECTIONS; lf++) {
  376. if (conns[lf] && conns[lf]->henv == self)
  377. rv = rv && CC_Destructor(conns[lf]);
  378. }
  379. mylog("exit EN_Destructor: rv = %dn", rv);
  380. return rv;
  381. }
  382. char
  383. EN_get_error(EnvironmentClass *self, int *number, char **message)
  384. {
  385. if(self && self->errormsg && self->errornumber) {
  386. *message = self->errormsg;
  387. *number = self->errornumber;
  388. self->errormsg = 0;
  389. self->errornumber = 0;
  390. return 1;
  391. } else {
  392. return 0;
  393. }
  394. }
  395. char
  396. EN_add_connection(EnvironmentClass *self, ConnectionClass *conn)
  397. {
  398. int i;
  399. mylog("EN_add_connection: self = %u, conn = %un", self, conn);
  400. for (i = 0; i < MAX_CONNECTIONS; i++) {
  401. if ( ! conns[i]) {
  402. conn->henv = self;
  403. conns[i] = conn;
  404. mylog("       added at i =%d, conn->henv = %u, conns[i]->henv = %un", i, conn->henv, conns[i]->henv);
  405. return TRUE;
  406. }
  407. }
  408. return FALSE;
  409. }
  410. char
  411. EN_remove_connection(EnvironmentClass *self, ConnectionClass *conn)
  412. {
  413. int i;
  414. for (i = 0; i < MAX_CONNECTIONS; i++)
  415. if (conns[i] == conn && conns[i]->status != CONN_EXECUTING) {
  416. conns[i] = NULL;
  417. return TRUE;
  418. }
  419. return FALSE;
  420. }
  421. void
  422. EN_log_error(char *func, char *desc, EnvironmentClass *self)
  423. {
  424. if (self) {
  425. qlog("ENVIRON ERROR: func=%s, desc='%s', errnum=%d, errmsg='%s'n", func, desc, self->errornumber, self->errormsg);
  426. }
  427. else
  428. qlog("INVALID ENVIRON HANDLE ERROR: func=%s, desc='%s'n", func, desc);
  429. }