ext/ibm_db.c in ibm_db-1.0.0 vs ext/ibm_db.c in ibm_db-1.0.1

- old
+ new

@@ -1,18 +1,20 @@ /* +----------------------------------------------------------------------+ | Licensed Materials - Property of IBM | | | - | (C) Copyright IBM Corporation 2006, 2007. | + | (C) Copyright IBM Corporation 2006, 2007,2008 | +----------------------------------------------------------------------+ | Authors: Sushant Koduru, Lynh Nguyen, Kanchana Padmanabhan, | | Dan Scott, Helmut Tessarek, Sam Ruby, Kellen Bombardier, | | Tony Cairns, Manas Dadarkar, Swetha Patel, Salvador Ledezma | + | Mario Ds Briggs, Praveen Devarao, Ambrish Bhargava, | + | Tarun Pasrija | +----------------------------------------------------------------------+ */ -#define MODULE_RELEASE "0.10.0" +#define MODULE_RELEASE "1.0.1" #ifdef HAVE_CONFIG_H #include "config.h" #endif @@ -27,10 +29,11 @@ static void _ruby_ibm_db_check_sql_errors( SQLHANDLE handle, SQLSMALLINT hType, int rc, int cpy_to_global, char* ret_str, int API, SQLSMALLINT recno ); static void _ruby_ibm_db_assign_options( void* handle, int type, long opt_key, VALUE data ); static void _ruby_ibm_db_clear_conn_err_cache(); static void _ruby_ibm_db_clear_stmt_err_cache(); +static int _ruby_ibm_db_set_decfloat_rounding_mode_client(SQLHANDLE hdbc); static char * _ruby_ibm_db_instance_name; static int is_systemi, is_informix; /* 1 == TRUE; 0 == FALSE; */ /* Defines a linked list structure for caching param data */ typedef struct _param_cache_node { @@ -397,10 +400,11 @@ case SQL_TYPE_TIMESTAMP: case SQL_BIGINT: case SQL_DECIMAL: case SQL_NUMERIC: case SQL_XML: + case SQL_DECFLOAT: if ( handle->row_data[i].data.str_val != NULL ) { ruby_xfree(handle->row_data[i].data.str_val); handle->row_data[i].data.str_val = NULL; } } @@ -965,10 +969,11 @@ case SQL_TYPE_DATE: case SQL_TYPE_TIME: case SQL_TYPE_TIMESTAMP: case SQL_BIGINT: + case SQL_DECFLOAT: in_length = stmt_res->column_info[i].size+1; row_data->str_val = (SQLCHAR *)ALLOC_N(char, in_length); rc = SQLBindCol((SQLHSTMT)stmt_res->hstmt, (SQLUSMALLINT)(i+1), SQL_C_CHAR, row_data->str_val, in_length, (SQLINTEGER *)(&stmt_res->row_data[i].out_length)); @@ -1200,17 +1205,29 @@ rc = SQLConnect( (SQLHDBC)conn_res->hdbc, (SQLCHAR *)database, (SQLSMALLINT)database_len, (SQLCHAR *)uid, (SQLSMALLINT)uid_len, (SQLCHAR *)password, (SQLSMALLINT)password_len ); } - if ( rc != SQL_SUCCESS ) { + if ( rc == SQL_ERROR ) { _ruby_ibm_db_check_sql_errors(conn_res->hdbc, SQL_HANDLE_DBC, rc, 1, NULL, -1, 1); SQLFreeHandle( SQL_HANDLE_DBC, conn_res->hdbc ); SQLFreeHandle(SQL_HANDLE_ENV, conn_res->henv); break; } +#ifdef CLI_DBC_SERVER_TYPE_DB2LUW +#ifdef SQL_ATTR_DECFLOAT_ROUNDING_MODE + + /** + * Code for setting SQL_ATTR_DECFLOAT_ROUNDING_MODE + * for implementation of Decfloat Datatype + * */ + _ruby_ibm_db_set_decfloat_rounding_mode_client(conn_res->hdbc); + +#endif +#endif + /* Get the server name */ memset(server, 0, sizeof(server)); rc = SQLGetInfo(conn_res->hdbc, SQL_DBMS_NAME, (SQLPOINTER)server, 2048, NULL); if (!strcmp(server, "AS")) is_systemi = 1; if (!strncmp(server, "IDS", 3)) is_informix = 1; @@ -1276,10 +1293,78 @@ return Data_Wrap_Struct(le_conn_struct, _ruby_ibm_db_mark_conn_struct, _ruby_ibm_db_free_conn_struct, conn_res); } } + +#ifdef CLI_DBC_SERVER_TYPE_DB2LUW +#ifdef SQL_ATTR_DECFLOAT_ROUNDING_MODE +/** + * Function for implementation of DECFLOAT Datatype + * + * Description : + * This function retrieves the value of special register decflt_rounding + * from the database server which signifies the current rounding mode set + * on the server. For using decfloat, the rounding mode has to be in sync + * on the client as well as server. Thus we set here on the client, the + * same rounding mode as the server. + * @return: success or failure + * */ +static int _ruby_ibm_db_set_decfloat_rounding_mode_client(SQLHANDLE hdbc) +{ + SQLCHAR decflt_rounding[20]; + SQLHANDLE hstmt; + int rc = 0; + int rounding_mode; + SQLINTEGER decfloat; + + + SQLCHAR *stmt = (SQLCHAR *)"values current decfloat rounding mode"; + + /* Allocate a Statement Handle */ + rc = SQLAllocHandle(SQL_HANDLE_STMT, hdbc, &hstmt); + if (rc == SQL_ERROR) { + _ruby_ibm_db_check_sql_errors(hdbc, SQL_HANDLE_DBC, rc, 1, + NULL, -1, 1); + return rc; + } + rc = SQLExecDirect((SQLHSTMT)hstmt, stmt, SQL_NTS); + if ( rc == SQL_ERROR ) { + _ruby_ibm_db_check_sql_errors((SQLHSTMT)hstmt, + SQL_HANDLE_STMT, rc, 1, NULL, + -1, 1); + return rc; + } + + rc = SQLBindCol((SQLHSTMT)hstmt, 1, SQL_C_DEFAULT, decflt_rounding, 20, NULL); + if ( rc == SQL_ERROR ) { + _ruby_ibm_db_check_sql_errors((SQLHSTMT)hstmt, + SQL_HANDLE_STMT, rc, 1, NULL, + -1, 1); + return rc; + } + rc = SQLFetch(hstmt); + rc = SQLFreeHandle(SQL_HANDLE_STMT, hstmt); + /* Now setting up the same rounding mode on the client*/ + if(strcmp(decflt_rounding,"ROUND_HALF_EVEN")== 0) rounding_mode = ROUND_HALF_EVEN; + if(strcmp(decflt_rounding,"ROUND_HALF_UP")== 0) rounding_mode = ROUND_HALF_UP; + if(strcmp(decflt_rounding,"ROUND_DOWN")== 0) rounding_mode = ROUND_DOWN; + if(strcmp(decflt_rounding,"ROUND_CEILING")== 0) rounding_mode = ROUND_CEILING; + if(strcmp(decflt_rounding,"ROUND_FLOOR")== 0) rounding_mode = ROUND_FLOOR; + +#ifndef PASE + rc = SQLSetConnectAttr(hdbc,SQL_ATTR_DECFLOAT_ROUNDING_MODE,(SQLPOINTER)rounding_mode ,SQL_NTS); +#else + rc = SQLSetConnectAttr(hdbc,SQL_ATTR_DECFLOAT_ROUNDING_MODE,(SQLPOINTER)&rounding_mode ,SQL_NTS); +#endif + + + return rc; +} +#endif +#endif + /* */ /* static void _ruby_ibm_db_clear_conn_err_cache () */ static void _ruby_ibm_db_clear_conn_err_cache() @@ -4456,10 +4541,11 @@ case SQL_REAL: case SQL_FLOAT: case SQL_DOUBLE: case SQL_DECIMAL: case SQL_NUMERIC: + case SQL_DECFLOAT: str_val = "real"; break; case SQL_CLOB: str_val = "clob"; break; @@ -4812,10 +4898,11 @@ case SQL_TYPE_TIME: case SQL_TYPE_TIMESTAMP: case SQL_BIGINT: case SQL_DECIMAL: case SQL_NUMERIC: + case SQL_DECFLOAT: if (column_type == SQL_DECIMAL || column_type == SQL_NUMERIC) in_length = stmt_res->column_info[col_num].size + stmt_res->column_info[col_num].scale + 2 + 1; else in_length = stmt_res->column_info[col_num].size+1; out_ptr = (SQLPOINTER)ALLOC_N(char,in_length); @@ -5107,9 +5194,10 @@ case SQL_TYPE_TIME: case SQL_TYPE_TIMESTAMP: case SQL_BIGINT: case SQL_DECIMAL: case SQL_NUMERIC: + case SQL_DECFLOAT: if ( op & FETCH_ASSOC ) { rb_hash_aset(return_value, rb_str_new2((char *)stmt_res->column_info[i].name), rb_str_new2((char *)row_data->str_val)); } if ( op == FETCH_INDEX ) {