ext/ibm_db.c in ibm_db-0.7.5 vs ext/ibm_db.c in ibm_db-0.8.0

- old
+ new

@@ -8,11 +8,11 @@ | Dan Scott, Helmut Tessarek, Sam Ruby, Kellen Bombardier, | | Tony Cairns | +----------------------------------------------------------------------+ */ -#define MODULE_RELEASE "0.6.0" +#define MODULE_RELEASE "0.7.0" #ifdef HAVE_CONFIG_H #include "config.h" #endif @@ -28,11 +28,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 char * _ruby_ibm_db_instance_name; -static int is_systemi; /* 1 == TRUE; 0 == FALSE; */ +static int is_systemi, is_informix; /* 1 == TRUE; 0 == FALSE; */ /* Defines a linked list structure for caching param data */ typedef struct _param_cache_node { SQLSMALLINT data_type; /* Datatype */ SQLUINTEGER param_size; /* param size */ @@ -185,10 +185,11 @@ rb_define_module_function(mDB, "free_result", ibm_db_free_result, -1); rb_define_module_function(mDB, "set_option", ibm_db_set_option, -1); rb_define_module_function(mDB, "setoption", ibm_db_set_option, -1); rb_define_module_function(mDB, "get_option", ibm_db_get_option, -1); rb_define_module_function(mDB, "getoption", ibm_db_get_option, -1); + rb_define_module_function(mDB, "get_last_serial_value", ibm_db_get_last_serial_value, -1); rb_define_module_function(mDB, "fetch_object", ibm_db_fetch_object, -1); rb_define_module_function(mDB, "server_info", ibm_db_server_info, -1); rb_define_module_function(mDB, "client_info", ibm_db_client_info, -1); rb_define_module_function(mDB, "active", ibm_db_active, -1); @@ -242,10 +243,11 @@ RUBY_FE(free_result) RUBY_FE(set_option) RUBY_FALIAS(setoption, set_option) RUBY_FE(get_option) RUBY_FALIAS(getoption, get_option) + RUBY_FE(get_last_serial_value) RUBY_FE(fetch_object) RUBY_FE(server_info) RUBY_FE(client_info) RUBY_FE(active) @@ -1079,11 +1081,11 @@ password = rb_str2cstr(r_passwd, &password_len); do { /* Check if we already have a connection for this userID & database combination */ if (isPersistent) { - hKeyLen = strlen(database) + strlen(uid) + strlen(password) + 9; + hKeyLen = strlen(database) + strlen(uid) + strlen(password) + 12; hKey = ALLOC_N(char, hKeyLen); sprintf(hKey, "__ibm_db_%s.%s.%s", uid, database, password); if ( !NIL_P(entry=rb_hash_aref(persistent_list, rb_str_new2(hKey))) ) { @@ -1152,23 +1154,10 @@ SQLSetConnectOption((SQLHDBC)conn_res->hdbc, SQL_ATTR_COMMIT, (SQLPOINTER)&nocommitpase); } } #endif - /* Set SQL_ATTR_REPLACE_QUOTED_LITERALS connection attribute to - * enable CLI numeric literal feature. This is equivalent to - * PATCH2=71 in the db2cli.ini file - */ -#ifndef PASE - rc = SQLSetConnectAttr((SQLHDBC)conn_res->hdbc, SQL_ATTR_REPLACE_QUOTED_LITERALS, (SQLPOINTER)(enable_numeric_literals), SQL_IS_INTEGER); -#else - rc = SQLSetConnectAttr((SQLHDBC)conn_res->hdbc, SQL_ATTR_REPLACE_QUOTED_LITERALS, (SQLPOINTER)(&enable_numeric_literals), SQL_IS_INTEGER); -#endif - if (rc != SQL_SUCCESS) { - _ruby_ibm_db_check_sql_errors(conn_res->hdbc, SQL_HANDLE_DBC, rc, 1, NULL, -1, 1); - } - conn_res->c_bin_mode = IBM_DB_G(bin_mode); conn_res->c_case_mode = CASE_NATURAL; conn_res->c_cursor_type = SQL_SCROLL_FORWARD_ONLY; conn_res->error_recno_tracker = 1; @@ -1206,10 +1195,30 @@ /* 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; + + /* Set SQL_ATTR_REPLACE_QUOTED_LITERALS connection attribute to + * enable CLI numeric literal feature. This is equivalent to + * PATCH2=71 in the db2cli.ini file + */ +#ifndef PASE + /* Only enable this feature if we are not connected to an Informix data server */ + if (!is_informix) { + rc = SQLSetConnectAttr((SQLHDBC)conn_res->hdbc, SQL_ATTR_REPLACE_QUOTED_LITERALS, (SQLPOINTER)(enable_numeric_literals), SQL_IS_INTEGER); + } +#else + /* Only enable this feature if we are not connected to an Informix data server */ + if (!is_informix) { + rc = SQLSetConnectAttr((SQLHDBC)conn_res->hdbc, SQL_ATTR_REPLACE_QUOTED_LITERALS, (SQLPOINTER)(&enable_numeric_literals), SQL_IS_INTEGER); + } +#endif + if (rc != SQL_SUCCESS) { + _ruby_ibm_db_check_sql_errors(conn_res->hdbc, SQL_HANDLE_DBC, rc, 1, NULL, -1, 1); + } } conn_res->handle_active = 1; } while (0); if (hKey != NULL) { @@ -3255,11 +3264,11 @@ switch ( curr->data_type ) { case SQL_CLOB: if (curr->param_type == SQL_PARAM_OUTPUT || curr->param_type == SQL_PARAM_INPUT_OUTPUT) { curr->bind_indicator = curr->ivalue; valueType = SQL_C_CHAR; - paramValuePtr = (SQLPOINTER)curr; + paramValuePtr = (SQLPOINTER)curr->svalue; } else { curr->bind_indicator = SQL_DATA_AT_EXEC; valueType = SQL_C_CHAR; /* The correct dataPtr will be set during SQLPutData with the len from this struct */ #ifndef PASE @@ -6289,9 +6298,58 @@ } } } } + + +/* + * IBM_DB::get_last_serial_value -- Gets the last inserted serial value from IDS + * + * ===Description + * string IBM_DB::get_last_serial_value ( resource stmt ) + * + * Returns a string, that is the last inserted value for a serial column for IDS. + * The last inserted value could be auto-generated or entered explicitly by the user + * This function is valid for IDS (Informix Dynamic Server only) + * + * ===Parameters + * + * stmt + * A valid statement resource. + * + * ===Return Values + * + * Returns a string representation of last inserted serial value on a successful call. + * Returns FALSE on failure. + */ +VALUE ibm_db_get_last_serial_value(int argc, VALUE *argv, VALUE self) +{ + VALUE stmt = Qnil; + SQLCHAR *value = NULL; + stmt_handle *stmt_res; + int rc = 0; + + rb_scan_args(argc, argv, "1", &stmt); + + if (!NIL_P(stmt)) { + Data_Get_Struct(stmt, stmt_handle, stmt_res); + + /* We allocate a buffer of size 31 as per recommendations from the CLI IDS team */ + value = ALLOC_N(char, 31); + rc = SQLGetStmtAttr((SQLHSTMT)stmt_res->hstmt, SQL_ATTR_GET_GENERATED_VALUE, (SQLPOINTER)value, 31, NULL); + if ( rc == SQL_ERROR ) { + _ruby_ibm_db_check_sql_errors( (SQLHSTMT)stmt_res->hstmt, SQL_HANDLE_STMT, rc, 1, NULL, -1, 1); + return Qfalse; + } + return INT2NUM(atoi(value)); + } + else { + rb_throw("Supplied statement handle is invalid", Qnil); + return Qfalse; + } +} + /* * Local variables: * tab-width: 4 * c-basic-offset: 4