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 ) {