ibm_db 1.1.1-mswin32 → 1.5.0-mswin32

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,389 @@
1
+ /*
2
+ +----------------------------------------------------------------------+
3
+ | Licensed Materials - Property of IBM |
4
+ | |
5
+ | (C) Copyright IBM Corporation 2009 |
6
+ +----------------------------------------------------------------------+
7
+ | Authors: Praveen Devarao |
8
+ +----------------------------------------------------------------------+
9
+ */
10
+
11
+ #ifndef RUBY_IBM_DB_CLI_H
12
+ #define RUBY_IBM_DB_CLI_H
13
+
14
+ #include <ruby.h>
15
+ #include <stdio.h>
16
+ #include <string.h>
17
+ #include <stdlib.h>
18
+ #include <sqlcli1.h>
19
+
20
+ /* Defines a linked list structure for caching param data */
21
+ typedef struct _param_cache_node {
22
+ SQLSMALLINT data_type; /* Datatype */
23
+ SQLUINTEGER param_size; /* param size */
24
+ SQLSMALLINT nullable; /* is Nullable */
25
+ SQLSMALLINT scale; /* Decimal scale */
26
+ SQLUINTEGER file_options; /* File options if PARAM_FILE */
27
+ SQLINTEGER bind_indicator; /* indicator variable for SQLBindParameter */
28
+ int param_num; /* param number in stmt */
29
+ int param_type; /* Type of param - INP/OUT/INP-OUT/FILE */
30
+ int size; /* Size of param */
31
+ char *varname; /* bound variable name */
32
+ long ivalue; /* Temp storage value */
33
+ double fvalue; /* Temp storage value */
34
+ char *svalue; /* Temp storage value */
35
+ struct _param_cache_node *next; /* Pointer to next node */
36
+ } param_node;
37
+
38
+ typedef struct _conn_handle_struct {
39
+ SQLHANDLE henv;
40
+ SQLHANDLE hdbc;
41
+ long auto_commit;
42
+ long c_bin_mode;
43
+ long c_case_mode;
44
+ long c_cursor_type;
45
+ int handle_active;
46
+ SQLSMALLINT error_recno_tracker;
47
+ SQLSMALLINT errormsg_recno_tracker;
48
+ int flag_pconnect; /* Indicates that this connection is persistent */
49
+
50
+ int errorType; /*Indicates Whether the error logged in ruby_error_msg is a statement error or connection error*/
51
+
52
+ char *ruby_error_msg;
53
+ char *ruby_error_state;
54
+
55
+ } conn_handle;
56
+
57
+ typedef union {
58
+ SQLINTEGER i_val;
59
+ SQLDOUBLE d_val;
60
+ SQLFLOAT f_val;
61
+ SQLSMALLINT s_val;
62
+ SQLCHAR *str_val;
63
+ } ibm_db_row_data_type;
64
+
65
+ typedef struct {
66
+ SQLINTEGER out_length;
67
+ ibm_db_row_data_type data;
68
+ } ibm_db_row_type;
69
+
70
+ typedef struct _ibm_db_result_set_info_struct {
71
+ SQLCHAR *name;
72
+ SQLSMALLINT type;
73
+ SQLUINTEGER size;
74
+ SQLSMALLINT scale;
75
+ SQLSMALLINT nullable;
76
+ SQLINTEGER lob_loc;
77
+ SQLINTEGER loc_ind;
78
+ SQLSMALLINT loc_type;
79
+ } ibm_db_result_set_info;
80
+
81
+ typedef struct _row_hash_struct {
82
+ VALUE hash;
83
+ } row_hash_struct;
84
+
85
+ typedef struct _stmt_handle_struct {
86
+ SQLHANDLE hdbc;
87
+ SQLHANDLE hstmt;
88
+ long s_bin_mode;
89
+ long cursor_type;
90
+ long s_case_mode;
91
+ SQLSMALLINT error_recno_tracker;
92
+ SQLSMALLINT errormsg_recno_tracker;
93
+
94
+ /* Parameter Caching variables */
95
+ param_node *head_cache_list;
96
+ param_node *current_node;
97
+
98
+ int num_params; /* Number of Params */
99
+ int file_param; /* if option passed in is FILE_PARAM */
100
+ int num_columns;
101
+ int is_executing;
102
+
103
+ ibm_db_result_set_info *column_info;
104
+ ibm_db_row_type *row_data;
105
+
106
+ char *ruby_stmt_err_msg;
107
+ char *ruby_stmt_err_state;
108
+ } stmt_handle;
109
+
110
+ /*
111
+ Structure holding the data to be passed to SQLConnect or SQLDriverConnect CLI call
112
+ */
113
+ typedef struct _ibm_db_connect_args_struct {
114
+ char *database;
115
+ char *uid;
116
+ char *password;
117
+ long database_len;
118
+ long uid_len;
119
+ long password_len;
120
+ int ctlg_conn; /*Indicates if the connection is a cataloged connection or not*/
121
+ SQLHANDLE *hdbc;
122
+ } connect_args;
123
+
124
+ /*
125
+ Structure holding the necessary info to be passed to SQLEndTran CLI call
126
+ */
127
+ typedef struct _ibm_db_end_tran_args_struct {
128
+ SQLHANDLE *hdbc;
129
+ SQLSMALLINT handleType;
130
+ SQLSMALLINT completionType;
131
+ } end_tran_args;
132
+
133
+ /*
134
+ Structure holding the necessary info to be passed to SQLDescribeparam CLI call
135
+ */
136
+ typedef struct _ibm_db_describeparam_args_struct {
137
+ stmt_handle *stmt_res;
138
+ SQLUSMALLINT param_no;
139
+ SQLSMALLINT sql_data_type;
140
+ SQLUINTEGER sql_precision;
141
+ SQLSMALLINT sql_scale;
142
+ SQLSMALLINT sql_nullable;
143
+ } describeparam_args;
144
+
145
+ /*
146
+ Structure holding the necessary info to be passed to SQLDescribeCol CLI call
147
+ */
148
+ typedef struct _ibm_db_describecol_args_struct {
149
+ stmt_handle *stmt_res;
150
+ SQLUSMALLINT col_no;
151
+ SQLSMALLINT name_length;
152
+ SQLSMALLINT buff_length;
153
+ } describecol_args;
154
+ /*
155
+ Structure holding the necessary info to be passed to CLI calls like SQLColumns
156
+ SQLForeignKeys etc. The same structure is used to get the SP parameters, with table_name as proc_name
157
+ */
158
+ typedef struct _ibm_db_metadata_args_struct {
159
+ stmt_handle *stmt_res;
160
+ SQLCHAR *qualifier;
161
+ SQLCHAR *owner;
162
+ SQLCHAR *table_name;
163
+ SQLCHAR *proc_name; /*Used for call SQLProcedureColumns*/
164
+ SQLCHAR *column_name;
165
+ SQLCHAR *table_type;
166
+ int scope; /*Used in SQLSpecialColumns To determine the scope of the unique row identifier*/
167
+ int unique; /*Used in SQLStatistics to determine if only unique indexes are to be fetched or all*/
168
+
169
+ } metadata_args;
170
+
171
+ /*
172
+ Structure holding the necessary info to be passed to SQLPrepare and SQLExecDirect CLI call
173
+ */
174
+ typedef struct _ibm_db_exec_direct_args_struct {
175
+ stmt_handle *stmt_res;
176
+ SQLCHAR *stmt_string;
177
+ long stmt_string_len;
178
+ } exec_cum_prepare_args;
179
+
180
+ /*
181
+ Structure holding the necessary info to be passed to SQLParamData and SQLPutData CLI call
182
+ */
183
+ typedef struct _ibm_db_param_and_put_data_struct {
184
+ stmt_handle *stmt_res;
185
+ SQLPOINTER valuePtr;
186
+ } param_cum_put_data_args;
187
+
188
+ /*
189
+ Structure holding the necessary info to be passed to SQLNextResult CLI call
190
+ */
191
+ typedef struct _ibm_db_next_result_args_struct {
192
+ SQLHSTMT *new_hstmt;
193
+ stmt_handle *stmt_res;
194
+
195
+ } next_result_args;
196
+
197
+ /*
198
+ Structure holding the necessary info to be passed to calls SQLNumResultCols/SQLRowcount/SQLNumParams
199
+ */
200
+ typedef struct _ibm_db_row_col_count_struct {
201
+ stmt_handle *stmt_res;
202
+ SQLINTEGER count;
203
+ } row_col_count_args;
204
+
205
+ /*
206
+ Structure holding the necessary info to be passed to call SQLColAttributes
207
+ */
208
+ typedef struct _ibm_db_col_attr_struct {
209
+ stmt_handle *stmt_res;
210
+ SQLSMALLINT col_num;
211
+ SQLSMALLINT FieldIdentifier;
212
+ SQLINTEGER num_attr;
213
+ } col_attr_args;
214
+
215
+ /*
216
+ Structure holding the necessary info to be passed to call SQLBindCol
217
+ */
218
+ typedef struct _ibm_db_bind_col_struct {
219
+ stmt_handle *stmt_res;
220
+ SQLUSMALLINT col_num;
221
+ SQLSMALLINT TargetType;
222
+ SQLPOINTER TargetValuePtr;
223
+ SQLLEN buff_length;
224
+ SQLLEN *out_length;
225
+ } bind_col_args;
226
+
227
+ /*
228
+ Structure holding the necessary info to be passed to call SQLGetData
229
+ */
230
+ typedef struct _ibm_db_get_data_args_struct {
231
+ stmt_handle *stmt_res;
232
+ SQLSMALLINT col_num;
233
+ SQLSMALLINT targetType;
234
+ SQLPOINTER *buff;
235
+ SQLLEN buff_length;
236
+ SQLLEN *out_length;
237
+ } get_data_args;
238
+
239
+ /*
240
+ Structure holding the necessary info to be passed to call SQLGetLength
241
+ */
242
+ typedef struct _ibm_db_get_data_length_struct {
243
+ SQLHSTMT *new_hstmt;
244
+ SQLSMALLINT col_num;
245
+ stmt_handle *stmt_res;
246
+ SQLINTEGER *sLength;
247
+
248
+ } get_length_args;
249
+
250
+ /*
251
+ Structure holding the necessary info to be passed to call SQLGetSubString
252
+ */
253
+ typedef struct _ibm_db_get_data_subString_struct {
254
+ SQLHSTMT *new_hstmt;
255
+ SQLSMALLINT col_num;
256
+ stmt_handle *stmt_res;
257
+ SQLUINTEGER forLength;
258
+ SQLSMALLINT targetCType;
259
+ SQLPOINTER buffer;
260
+ SQLLEN buff_length;
261
+ SQLINTEGER *out_length;
262
+
263
+ } get_subString_args;
264
+
265
+ /*
266
+ Structure holding the necessary info to be passed to call SQLFetchScroll and SQLFetch
267
+ */
268
+ typedef struct _ibm_db_fetch_data_struct {
269
+ stmt_handle *stmt_res;
270
+ SQLSMALLINT fetchOrientation;
271
+ SQLLEN fetchOffset;
272
+ } fetch_data_args;
273
+
274
+ /*
275
+ Structure holding the necessary info to be passed to calls SQLSetStmtAttr/SQLSetConnectAttr/SQLEnvAttr
276
+ */
277
+ typedef struct _ibm_db_set_handle_attr_struct {
278
+ SQLHANDLE *handle;
279
+ SQLINTEGER attribute;
280
+ SQLPOINTER valuePtr;
281
+ SQLINTEGER strLength;
282
+
283
+ } set_handle_attr_args;
284
+
285
+ /*
286
+ Structure holding the necessary info to be passed to call SQLGetStmtAttr and SQLGetConnectAttr
287
+ */
288
+ typedef struct _ibm_db_get_handle_attr_struct {
289
+ SQLHANDLE *handle;
290
+ SQLINTEGER attribute;
291
+ SQLPOINTER valuePtr;
292
+ SQLINTEGER buff_length;
293
+ SQLINTEGER *out_length;
294
+ } get_handle_attr_args;
295
+
296
+ /*
297
+ Structure holding the necessary info to be passed to call SQLBindParameter
298
+ */
299
+ typedef struct _ibm_db_bind_parameter_struct {
300
+ stmt_handle *stmt_res;
301
+ SQLSMALLINT param_num;
302
+ SQLSMALLINT IOType;
303
+ SQLSMALLINT valueType;
304
+ SQLSMALLINT paramType;
305
+ SQLULEN colSize;
306
+ SQLSMALLINT decimalDigits;
307
+ SQLPOINTER paramValPtr;
308
+ SQLLEN buff_length;
309
+ SQLLEN *out_length;
310
+ } bind_parameter_args;
311
+
312
+ /*
313
+ Structure holding the necessary info to be passed to call SQLGetInfo
314
+ */
315
+ typedef struct _ibm_db_get_info_struct {
316
+ conn_handle *conn_res;
317
+ SQLUSMALLINT infoType;
318
+ SQLPOINTER infoValue;
319
+ SQLSMALLINT buff_length;
320
+ SQLSMALLINT *out_length;
321
+ } get_info_args;
322
+
323
+ /*
324
+ Structure holding the necessary info to be passed to call SQLGetDiagRec
325
+ */
326
+ typedef struct _ibm_db_get_diagRec_struct {
327
+ SQLSMALLINT hType;
328
+ SQLHANDLE handle;
329
+ SQLSMALLINT recNum;
330
+ SQLCHAR *SQLState;
331
+ SQLINTEGER *NativeErrorPtr;
332
+ SQLCHAR *msgText;
333
+ SQLSMALLINT buff_length;
334
+ SQLSMALLINT *text_length_ptr;
335
+ } get_diagRec_args;
336
+
337
+ /*
338
+ Structure holding the necessary info to be passed to call SQLFreestmt
339
+ */
340
+ typedef struct _ibm_db_free_stmt_struct {
341
+ stmt_handle *stmt_res;
342
+ SQLUSMALLINT option;
343
+ } free_stmt_args;
344
+
345
+ int _ruby_ibm_db_SQLConnect_helper(connect_args *data);
346
+ int _ruby_ibm_db_SQLDisconnect_helper(SQLHANDLE *hdbc);
347
+ void _ruby_ibm_db_Connection_level_UBF(void *data);
348
+ int _ruby_ibm_db_SQLEndTran(end_tran_args *endtran_args);
349
+ int _ruby_ibm_db_SQLDescribeParam_helper(describeparam_args *data);
350
+ int _ruby_ibm_db_SQLDescribeCol_helper(describecol_args *data);
351
+ int _ruby_ibm_db_SQLBindCol_helper(bind_col_args *data);
352
+ int _ruby_ibm_db_SQLColumnPrivileges_helper(metadata_args *data);
353
+ int _ruby_ibm_db_SQLColumns_helper(metadata_args *data);
354
+ int _ruby_ibm_db_SQLPrimaryKeys_helper(metadata_args *data);
355
+ int _ruby_ibm_db_SQLForeignKeys_helper(metadata_args *data);
356
+ int _ruby_ibm_db_SQLProcedureColumns_helper(metadata_args *data);
357
+ int _ruby_ibm_db_SQLProcedures_helper(metadata_args *data);
358
+ int _ruby_ibm_db_SQLSpecialColumns_helper(metadata_args *data);
359
+ int _ruby_ibm_db_SQLStatistics_helper(metadata_args *data);
360
+ int _ruby_ibm_db_SQLTablePrivileges_helper(metadata_args *data);
361
+ int _ruby_ibm_db_SQLTables_helper(metadata_args *data);
362
+ int _ruby_ibm_db_SQLExecDirect_helper(exec_cum_prepare_args *data);
363
+ int _ruby_ibm_db_SQLPrepare_helper(exec_cum_prepare_args *data);
364
+ int _ruby_ibm_db_SQLFreeStmt_helper(free_stmt_args *data);
365
+ int _ruby_ibm_db_SQLExecute_helper(stmt_handle *stmt_res);
366
+ int _ruby_ibm_db_SQLParamData_helper(param_cum_put_data_args *data);
367
+ int _ruby_ibm_db_SQLColAttributes_helper(col_attr_args *data);
368
+ int _ruby_ibm_db_SQLPutData_helper(param_cum_put_data_args *data);
369
+ int _ruby_ibm_db_SQLGetData_helper(get_data_args *data);
370
+ int _ruby_ibm_db_SQLGetLength_helper(get_length_args *data);
371
+ int _ruby_ibm_db_SQLGetSubString_helper(get_subString_args *data);
372
+ int _ruby_ibm_db_SQLNextResult_helper(next_result_args *data);
373
+ int _ruby_ibm_db_SQLFetchScroll_helper(fetch_data_args *data);
374
+ int _ruby_ibm_db_SQLFetch_helper(fetch_data_args *data);
375
+ int _ruby_ibm_db_SQLNumResultCols_helper(row_col_count_args *data);
376
+ int _ruby_ibm_db_SQLNumParams_helper(row_col_count_args *data);
377
+ int _ruby_ibm_db_SQLRowCount_helper(row_col_count_args *data);
378
+ int _ruby_ibm_db_SQLGetInfo_helper(get_info_args *data);
379
+ int _ruby_ibm_db_SQLGetDiagRec_helper(get_diagRec_args *data);
380
+ int _ruby_ibm_db_SQLSetStmtAttr_helper(set_handle_attr_args *data);
381
+ int _ruby_ibm_db_SQLSetConnectAttr_helper(set_handle_attr_args *data);
382
+ int _ruby_ibm_db_SQLSetEnvAttr_helper(set_handle_attr_args *data);
383
+ int _ruby_ibm_db_SQLGetStmtAttr_helper(get_handle_attr_args *data);
384
+ int _ruby_ibm_db_SQLGetConnectAttr_helper(get_handle_attr_args *data);
385
+ int _ruby_ibm_db_SQLBindFileToParam_helper(stmt_handle *stmt_res, param_node *curr);
386
+ int _ruby_ibm_db_SQLBindParameter_helper(bind_parameter_args *data);
387
+ void _ruby_ibm_db_Statement_level_UBF(stmt_handle *stmt_res);
388
+
389
+ #endif /* RUBY_IBM_DB_CLI_H */
@@ -63,13 +63,12 @@ module ActiveRecord
63
63
  else
64
64
  update_query << "(" + params.join(',') + ")"
65
65
  end
66
-
66
+
67
67
  update_query << " WHERE #{self.class.primary_key} = ?"
68
68
  values << self[self.class.primary_key.downcase]
69
69
 
70
70
  unless stmt = IBM_DB.prepare(connection.connection, update_query)
71
- error_msg = IBM_DB.conn_errormsg
72
- error_msg = IBM_DB.stmt_errormsg if error_msg.empty?
71
+ error_msg = IBM_DB.getErrormsg( connection.connection, IBM_DB::DB_CONN )
73
72
  if error_msg && !error_msg.empty?
74
73
  raise "Statement prepare for updating LOB/XML column failed : #{error_msg}"
75
74
  else
@@ -80,8 +79,9 @@ module ActiveRecord
80
79
 
81
80
  # rollback any failed LOB/XML field updates (and remove associated marker)
82
81
  unless IBM_DB.execute(stmt, values)
82
+ error_msg = "Failed to insert/update LOB/XML field(s) due to: #{IBM_DB.getErrormsg( stmt, IBM_DB::DB_STMT )}"
83
83
  connection.execute("ROLLBACK")
84
- raise "Failed to insert/update LOB/XML field(s) due to: #{IBM_DB.stmt_errormsg(stmt)}"
84
+ raise error_msg
85
85
  else
86
86
  IBM_DB.free_result stmt
87
87
  end
@@ -146,44 +146,47 @@ module ActiveRecord
146
146
  end
147
147
  end
148
148
 
149
- # Checks if a host name or address has been specified. If so, this implies a TCP/IP connection
150
- # Returns IBM_DB.Connection object upon succesful DB connection to the database
151
- # If otherwise the connection fails, +false+ is returned
152
- if config.has_key?(:host)
153
- # Retrieves the host address/name
154
- host = config[:host]
155
- # A net address connection requires a port. If no port has been specified, 50000 is used by default
156
- port = config[:port] || 50000
157
- # Connects to the database specified using the hostname, port, authentication type, username and password info
158
- # Starting with DB2 9.1FP5 secure connections using SSL are supported.
159
- # On the client side using CLI this is supported from CLI version V95FP2 and onwards.
160
- # This feature is set by specifying SECURITY=SSL in the connection string.
161
- # Below connection string is constructed and SECURITY parameter is appended if the user has specified the :security option
162
- conn_string = "DRIVER={IBM DB2 ODBC DRIVER};\
163
- DATABASE=#{database};\
164
- HOSTNAME=#{host};\
165
- PORT=#{port};\
166
- PROTOCOL=TCPIP;\
167
- UID=#{username};\
168
- PWD=#{password};"
169
- conn_string << "SECURITY=#{config[:security]};" if config.has_key?(:security)
170
- conn_string << "AUTHENTICATION=#{config[:authentication]};" if config.has_key?(:authentication)
171
- conn_string << "CONNECTTIMEOUT=#{config[:timeout]};" if config.has_key?(:timeout)
149
+ begin
150
+ # Checks if a host name or address has been specified. If so, this implies a TCP/IP connection
151
+ # Returns IBM_DB.Connection object upon succesful DB connection to the database
152
+ # If otherwise the connection fails, +false+ is returned
153
+ if config.has_key?(:host)
154
+ # Retrieves the host address/name
155
+ host = config[:host]
156
+ # A net address connection requires a port. If no port has been specified, 50000 is used by default
157
+ port = config[:port] || 50000
158
+ # Connects to the database specified using the hostname, port, authentication type, username and password info
159
+ # Starting with DB2 9.1FP5 secure connections using SSL are supported.
160
+ # On the client side using CLI this is supported from CLI version V95FP2 and onwards.
161
+ # This feature is set by specifying SECURITY=SSL in the connection string.
162
+ # Below connection string is constructed and SECURITY parameter is appended if the user has specified the :security option
163
+ conn_string = "DRIVER={IBM DB2 ODBC DRIVER};\
164
+ DATABASE=#{database};\
165
+ HOSTNAME=#{host};\
166
+ PORT=#{port};\
167
+ PROTOCOL=TCPIP;\
168
+ UID=#{username};\
169
+ PWD=#{password};"
170
+ conn_string << "SECURITY=#{config[:security]};" if config.has_key?(:security)
171
+ conn_string << "AUTHENTICATION=#{config[:authentication]};" if config.has_key?(:authentication)
172
+ conn_string << "CONNECTTIMEOUT=#{config[:timeout]};" if config.has_key?(:timeout)
172
173
 
173
- connection = IBM_DB.connect conn_string, '', '', conn_options
174
- else
175
- # No host implies a local catalog-based connection: +database+ represents catalog alias
176
- connection = IBM_DB.connect( database, username, password, conn_options )
174
+ connection = IBM_DB.connect conn_string, '', '', conn_options
175
+ else
176
+ # No host implies a local catalog-based connection: +database+ represents catalog alias
177
+ connection = IBM_DB.connect( database, username, password, conn_options )
178
+ end
179
+ rescue StandardError => connect_err
180
+ raise "Failed to connect to [#{database}] due to: #{connect_err}"
177
181
  end
178
-
179
- # Verifies that the connection was succesfull
182
+ # Verifies that the connection was successful
180
183
  if connection
181
184
  # Creates an instance of *IBM_DBAdapter* based on the +connection+
182
185
  # and credentials provided in +config+
183
186
  ConnectionAdapters::IBM_DBAdapter.new(connection, logger, config, conn_options)
184
187
  else
185
- # If the connection failed, it raises a Runtime error
186
- raise "Failed to connect to [#{database}] due to: #{IBM_DB.conn_errormsg}"
188
+ # If the connection failure was not caught previoulsy, it raises a Runtime error
189
+ raise "An unexpected error occured during connect attempt to [#{database}]"
187
190
  end
188
191
  end # method self.ibm_db_connection
189
192
  end # class Base
@@ -278,13 +281,13 @@ module ActiveRecord
278
281
  ibm_parse_column_attributes_args('double',*args)
279
282
  return self
280
283
  end
281
-
284
+
282
285
  #Method to support the new syntax of rails 2.0 migrations (short-hand definitions) for columns of type decfloat
283
286
  def decfloat(*args)
284
287
  ibm_parse_column_attributes_args('decfloat',*args)
285
288
  return self
286
289
  end
287
-
290
+
288
291
  #Method to support the new syntax of rails 2.0 migrations (short-hand definitions) for columns of type char [character]
289
292
  def char(*args)
290
293
  ibm_parse_column_attributes_args('char',*args)
@@ -306,13 +309,13 @@ module ActiveRecord
306
309
  end
307
310
  end
308
311
  private :ibm_parse_column_attributes_args
309
-
312
+
310
313
  #Method to support the new syntax of rails 2.0 migrations for columns of type xml
311
314
  def xml(*args )
312
315
  ibm_parse_column_attributes_args('xml', *args)
313
316
  return self
314
317
  end
315
-
318
+
316
319
  #Method to support the new syntax of rails 2.0 migrations (short-hand definitions) for columns of type double
317
320
  def double(*args)
318
321
  ibm_parse_column_attributes_args('double',*args)
@@ -324,14 +327,14 @@ module ActiveRecord
324
327
  ibm_parse_column_attributes_args('decfloat',*args)
325
328
  return self
326
329
  end
327
-
330
+
328
331
  #Method to support the new syntax of rails 2.0 migrations (short-hand definitions) for columns of type char [character]
329
332
  def char(*args)
330
333
  ibm_parse_column_attributes_args('char',*args)
331
334
  return self
332
335
  end
333
336
  alias_method :character, :char
334
-
337
+
335
338
  # Overrides the abstract adapter in order to handle
336
339
  # the DEFAULT option for the native XML datatype
337
340
  def column(name, type, options ={})
@@ -440,27 +443,37 @@ module ActiveRecord
440
443
 
441
444
  if @connection
442
445
  server_info = IBM_DB.server_info( @connection )
443
- case server_info.DBMS_NAME
444
- when /DB2\//i # DB2 for Linux, Unix and Windows (LUW)
445
- case server_info.DBMS_VER
446
- when /09.07/i # DB2 Version 9.7 (Cobra)
447
- @servertype = IBM_DB2_LUW_COBRA.new(self)
448
- else # DB2 Version 9.5 or below
449
- @servertype = IBM_DB2_LUW.new(self)
450
- end
451
- when /DB2/i # DB2 for zOS
452
- case server_info.DBMS_VER
453
- when /09/ # DB2 for zOS version 9
454
- @servertype = IBM_DB2_ZOS.new(self)
455
- when /08/ # DB2 for zOS version 8
456
- @servertype = IBM_DB2_ZOS_8.new(self)
457
- else # DB2 for zOS version 7
458
- raise "Only DB2 z/OS version 8 and above are currently supported"
459
- end
460
- when /AS/i # DB2 for i5 (iSeries)
461
- @servertype = IBM_DB2_I5.new(self)
462
- when /IDS/i # Informix Dynamic Server
463
- @servertype = IBM_IDS.new(self)
446
+ if( server_info )
447
+ case server_info.DBMS_NAME
448
+ when /DB2\//i # DB2 for Linux, Unix and Windows (LUW)
449
+ case server_info.DBMS_VER
450
+ when /09.07/i # DB2 Version 9.7 (Cobra)
451
+ @servertype = IBM_DB2_LUW_COBRA.new(self)
452
+ else # DB2 Version 9.5 or below
453
+ @servertype = IBM_DB2_LUW.new(self)
454
+ end
455
+ when /DB2/i # DB2 for zOS
456
+ case server_info.DBMS_VER
457
+ when /09/ # DB2 for zOS version 9
458
+ @servertype = IBM_DB2_ZOS.new(self)
459
+ when /08/ # DB2 for zOS version 8
460
+ @servertype = IBM_DB2_ZOS_8.new(self)
461
+ else # DB2 for zOS version 7
462
+ raise "Only DB2 z/OS version 8 and above are currently supported"
463
+ end
464
+ when /AS/i # DB2 for i5 (iSeries)
465
+ @servertype = IBM_DB2_I5.new(self)
466
+ when /IDS/i # Informix Dynamic Server
467
+ @servertype = IBM_IDS.new(self)
468
+ else
469
+ log( "server_info", "Forcing servertype to LUW: DBMS name could not be retrieved. Check if your client version is of the right level")
470
+ warn "Forcing servertype to LUW: DBMS name could not be retrieved. Check if your client version is of the right level"
471
+ @servertype = IBM_DB2_LUW.new(self)
472
+ end
473
+ else
474
+ error_msg = IBM_DB.getErrormsg( @connection, IBM_DB::DB_CONN )
475
+ IBM_DB.close( @connection )
476
+ raise "Cannot retrieve server information: #{error_msg}"
464
477
  end
465
478
  end
466
479
 
@@ -531,14 +544,14 @@ module ActiveRecord
531
544
  def supports_migrations?
532
545
  true
533
546
  end
534
-
547
+
535
548
  # This Adapter supports DDL transactions.
536
549
  # This means CREATE TABLE and other DDL statements can be carried out as a transaction.
537
550
  # That is the statements executed can be ROLLED BACK in case of any error during the process.
538
551
  def supports_ddl_transactions?
539
552
  true
540
553
  end
541
-
554
+
542
555
  def log_query(sql, name) #:nodoc:
543
556
  # Used by handle_lobs
544
557
  log(sql,name){}
@@ -559,23 +572,28 @@ module ActiveRecord
559
572
  # It connects to the database with the initially provided credentials
560
573
  def connect
561
574
  # If the type of connection is net based
562
- if @host
563
- @conn_string = "DRIVER={IBM DB2 ODBC DRIVER};\
564
- DATABASE=#{@database};\
565
- HOSTNAME=#{@host};\
566
- PORT=#{@port};\
567
- PROTOCOL=TCPIP;\
568
- UID=#{@username};\
569
- PWD=#{@password};"
570
- @conn_string << "SECURITY=#{@security};" if @security
571
- @conn_string << "AUTHENTICATION=#{@authentication};" if @authentication
572
- @conn_string << "CONNECTTIMEOUT=#{@timeout};"
573
- # Connects and assigns the resulting IBM_DB.Connection to the +@connection+ instance variable
574
- @connection = IBM_DB.connect(@conn_string, '', '', @conn_options)
575
- else
576
- # Connects to the database using the local alias (@database)
577
- # and assigns the connection object (IBM_DB.Connection) to @connection
578
- @connection = IBM_DB.connect(@database, @username, @password, @conn_options)
575
+ begin
576
+ if @host
577
+ @conn_string = "DRIVER={IBM DB2 ODBC DRIVER};\
578
+ DATABASE=#{@database};\
579
+ HOSTNAME=#{@host};\
580
+ PORT=#{@port};\
581
+ PROTOCOL=TCPIP;\
582
+ UID=#{@username};\
583
+ PWD=#{@password};"
584
+ @conn_string << "SECURITY=#{@security};" if @security
585
+ @conn_string << "AUTHENTICATION=#{@authentication};" if @authentication
586
+ @conn_string << "CONNECTTIMEOUT=#{@timeout};"
587
+ # Connects and assigns the resulting IBM_DB.Connection to the +@connection+ instance variable
588
+ @connection = IBM_DB.connect(@conn_string, '', '', @conn_options)
589
+ else
590
+ # Connects to the database using the local alias (@database)
591
+ # and assigns the connection object (IBM_DB.Connection) to @connection
592
+ @connection = IBM_DB.connect(@database, @username, @password, @conn_options)
593
+ end
594
+ rescue StandardError => connect_err
595
+ warn "Connection to database #{@database} failed: #{connect_err}"
596
+ @connection = false
579
597
  end
580
598
  # Sets the schema if different from default (username)
581
599
  if @schema && @schema != @username
@@ -632,16 +650,18 @@ module ActiveRecord
632
650
  results = []
633
651
  # Invokes the method +execute+ in order to log and execute the SQL
634
652
  # IBM_DB.Statement is returned from which results can be fetched
635
- if stmt = execute(sql, name)
653
+ stmt = execute(sql, name)
654
+ if(stmt)
636
655
  begin
637
656
  @servertype.select(sql, name, stmt, results)
638
- rescue StandardError # Handle driver fetch errors
639
- error_msg = IBM_DB.conn_errormsg
640
- error_msg = IBM_DB.stmt_errormsg if error_msg.empty?
657
+ rescue StandardError => fetch_error # Handle driver fetch errors
658
+ error_msg = IBM_DB.getErrormsg(stmt, IBM_DB::DB_STMT )
641
659
  if error_msg && !error_msg.empty?
642
660
  raise StatementInvalid,"Failed to retrieve data: #{error_msg}"
643
661
  else
644
- raise "An unexpected error occurred during data retrieval"
662
+ error_msg = "An unexpected error occurred during data retrieval"
663
+ error_msg = error_msg + ": #{fetch_error.message}" if !fetch_error.message.empty?
664
+ raise error_msg
645
665
  end
646
666
  ensure
647
667
  # Ensures to free the resources associated with the statement
@@ -662,16 +682,18 @@ module ActiveRecord
662
682
  results = []
663
683
  # Invokes the method +execute+ in order to log and execute the SQL
664
684
  # IBM_DB.Statement is returned from which results can be fetched
665
- if stmt = execute(sql, name)
685
+ stmt = execute(sql, name)
686
+ if(stmt)
666
687
  begin
667
688
  @servertype.select_rows(sql, name, stmt, results)
668
- rescue StandardError # Handle driver fetch errors
669
- error_msg = IBM_DB.conn_errormsg
670
- error_msg = IBM_DB.stmt_errormsg if error_msg.empty?
689
+ rescue StandardError => fetch_error # Handle driver fetch errors
690
+ error_msg = IBM_DB.getErrormsg(stmt, IBM_DB::DB_STMT )
671
691
  if error_msg && !error_msg.empty?
672
692
  raise StatementInvalid,"Failed to retrieve data: #{error_msg}"
673
693
  else
674
- raise "An unexpected error occurred during data retrieval"
694
+ error_msg = "An unexpected error occurred during data retrieval"
695
+ error_msg = error_msg + ": #{fetch_error.message}" if !fetch_error.message.empty?
696
+ raise error_msg
675
697
  end
676
698
  ensure
677
699
  # Ensures to free the resources associated with the statement
@@ -681,7 +703,7 @@ module ActiveRecord
681
703
  # The array of record hashes is returned
682
704
  results
683
705
  end
684
-
706
+
685
707
  # Returns a record hash with the column names as keys and column values
686
708
  # as values.
687
709
  def select_one(sql, name = nil)
@@ -731,25 +753,25 @@ module ActiveRecord
731
753
 
732
754
  insert_query << " VALUES ("+ params.join(',') + ")"
733
755
  unless stmt = IBM_DB.prepare(@connection, insert_query)
734
- error_msg = IBM_DB.conn_errormsg
735
- error_msg = IBM_DB.stmt_errormsg if error_msg.empty?
756
+ error_msg = IBM_DB.getErrormsg( @connection, IBM_DB::DB_CONN )
736
757
  if error_msg && !error_msg.empty?
737
- raise "Failed to prepare statement due to : #{error_msg}"
758
+ raise "Failed to prepare statement for fixtures insert due to : #{error_msg}"
738
759
  else
739
- raise StandardError.new('An unexpected error occurred during insert')
760
+ raise StandardError.new('An unexpected error occurred during preparing SQL for fixture insert')
740
761
  end
741
762
  end
742
763
 
743
764
  #log_query(insert_query,'fixture insert')
744
765
  log(insert_query,'fixture insert') do
745
766
  unless IBM_DB.execute(stmt, insert_values)
746
- raise "Failed to insert due to: #{IBM_DB.stmt_errormsg(stmt)}"
767
+ error_msg = IBM_DB.getErrormsg(stmt, IBM_DB::DB_STMT )
768
+ raise "Failed to insert due to: #{error_msg}"
747
769
  else
748
770
  IBM_DB.free_result stmt
749
771
  end
750
772
  end
751
773
  end
752
-
774
+
753
775
  # Perform an insert and returns the last ID generated.
754
776
  # This can be the ID passed to the method or the one auto-generated by the database,
755
777
  # and retrieved by the +last_generated_id+ method.
@@ -1037,8 +1059,9 @@ module ActiveRecord
1037
1059
  # Initializes the tables array
1038
1060
  tables = []
1039
1061
  # Retrieve table's metadata through IBM_DB driver
1040
- if stmt = IBM_DB.tables(@connection, nil,
1041
- @servertype.set_case(@schema))
1062
+ stmt = IBM_DB.tables(@connection, nil,
1063
+ @servertype.set_case(@schema))
1064
+ if(stmt)
1042
1065
  begin
1043
1066
  # Fetches all the records available
1044
1067
  while tab = IBM_DB.fetch_assoc(stmt)
@@ -1047,20 +1070,20 @@ module ActiveRecord
1047
1070
  tables << tab["table_name"].downcase
1048
1071
  end
1049
1072
  end
1050
- rescue StandardError # Handle driver fetch errors
1051
- error_msg = IBM_DB.conn_errormsg
1052
- error_msg = IBM_DB.stmt_errormsg if error_msg.empty?
1073
+ rescue StandardError => fetch_error # Handle driver fetch errors
1074
+ error_msg = IBM_DB.getErrormsg(stmt, IBM_DB::DB_STMT )
1053
1075
  if error_msg && !error_msg.empty?
1054
1076
  raise "Failed to retrieve table metadata during fetch: #{error_msg}"
1055
1077
  else
1056
- raise "An unexpected error occurred during retrieval of table metadata"
1078
+ error_msg = "An unexpected error occurred during retrieval of table metadata"
1079
+ error_msg = error_msg + ": #{fetch_error.message}" if !fetch_error.message.empty?
1080
+ raise error_msg
1057
1081
  end
1058
1082
  ensure
1059
1083
  IBM_DB.free_result(stmt) # Free resources associated with the statement
1060
1084
  end
1061
1085
  else # Handle driver execution errors
1062
- error_msg = IBM_DB.conn_errormsg
1063
- error_msg = IBM_DB.stmt_errormsg if error_msg.empty?
1086
+ error_msg = IBM_DB.getErrormsg(@connection, IBM_DB::DB_CONN )
1064
1087
  if error_msg && !error_msg.empty?
1065
1088
  raise "Failed to retrieve tables metadata due to error: #{error_msg}"
1066
1089
  else
@@ -1074,24 +1097,33 @@ module ActiveRecord
1074
1097
  # Returns the primary key of the mentioned table
1075
1098
  def primary_key(table_name)
1076
1099
  pk_name = nil
1077
- if stmt = IBM_DB.primary_keys( @connection, nil,
1078
- @servertype.set_case(@schema),
1079
- @servertype.set_case(table_name))
1100
+ stmt = IBM_DB.primary_keys( @connection, nil,
1101
+ @servertype.set_case(@schema),
1102
+ @servertype.set_case(table_name))
1103
+ if(stmt)
1080
1104
  begin
1081
1105
  if ( pk_index_row = IBM_DB.fetch_array(stmt) )
1082
1106
  pk_name = pk_index_row[3].downcase
1083
1107
  end
1084
- rescue StandardError # Handle driver fetch errors
1085
- error_msg = IBM_DB.conn_errormsg
1086
- error_msg = IBM_DB.stmt_errormsg if error_msg.empty?
1108
+ rescue StandardError => fetch_error # Handle driver fetch errors
1109
+ error_msg = IBM_DB.getErrormsg( stmt, IBM_DB::DB_STMT )
1087
1110
  if error_msg && !error_msg.empty?
1088
1111
  raise "Failed to retrieve primarykey metadata during fetch: #{error_msg}"
1089
1112
  else
1090
- raise "An unexpected error occurred during retrieval of primary metadata"
1113
+ error_msg = "An unexpected error occurred during retrieval of primary key metadata"
1114
+ error_msg = error_msg + ": #{fetch_error.message}" if !fetch_error.message.empty?
1115
+ raise error_msg
1091
1116
  end
1092
1117
  ensure # Free resources associated with the statement
1093
1118
  IBM_DB.free_result(stmt) if stmt
1094
1119
  end
1120
+ else
1121
+ error_msg = IBM_DB.getErrormsg( @connection, IBM_DB::DB_CONN )
1122
+ if error_msg && !error_msg.empty?
1123
+ raise "Failed to retrieve primary key metadata due to error: #{error_msg}"
1124
+ else
1125
+ raise StandardError.new('An unexpected error occurred during primary key retrieval')
1126
+ end
1095
1127
  end
1096
1128
  return pk_name
1097
1129
  end
@@ -1113,9 +1145,10 @@ module ActiveRecord
1113
1145
  #TABLE_NAME:: pk_index[2]
1114
1146
  #COLUMN_NAME:: pk_index[3]
1115
1147
  #PK_NAME:: pk_index[5]
1116
- if stmt = IBM_DB.primary_keys( @connection, nil,
1117
- @servertype.set_case(@schema),
1118
- @servertype.set_case(table_name))
1148
+ stmt = IBM_DB.primary_keys( @connection, nil,
1149
+ @servertype.set_case(@schema),
1150
+ @servertype.set_case(table_name))
1151
+ if(stmt)
1119
1152
  begin
1120
1153
  while ( pk_index_row = IBM_DB.fetch_array(stmt) )
1121
1154
  if pk_index_row[5]
@@ -1128,36 +1161,36 @@ module ActiveRecord
1128
1161
  end
1129
1162
  end
1130
1163
  end
1131
- rescue StandardError # Handle driver fetch errors
1132
- error_msg = IBM_DB.conn_errormsg
1133
- error_msg = IBM_DB.stmt_errormsg if error_msg.empty?
1164
+ rescue StandardError => fetch_error # Handle driver fetch errors
1165
+ error_msg = IBM_DB.getErrormsg(stmt, IBM_DB::DB_STMT )
1134
1166
  if error_msg && !error_msg.empty?
1135
1167
  raise "Failed to retrieve primarykey metadata during fetch: #{error_msg}"
1136
1168
  else
1137
- raise "An unexpected error occurred during retrieval of primary metadata"
1169
+ error_msg = "An unexpected error occurred during retrieval of primary key metadata"
1170
+ error_msg = error_msg + ": #{fetch_error.message}" if !fetch_error.message.empty?
1171
+ raise error_msg
1138
1172
  end
1139
1173
  ensure # Free resources associated with the statement
1140
1174
  IBM_DB.free_result(stmt) if stmt
1141
1175
  end
1142
1176
  else # Handle driver execution errors
1143
- error_msg = IBM_DB.conn_errormsg
1144
- error_msg = IBM_DB.stmt_errormsg if error_msg.empty?
1177
+ error_msg = IBM_DB.getErrormsg(@connection, IBM_DB::DB_CONN )
1145
1178
  if error_msg && !error_msg.empty?
1146
1179
  raise "Failed to retrieve primary key metadata due to error: #{error_msg}"
1147
1180
  else
1148
1181
  raise StandardError.new('An unexpected error occurred during primary key retrieval')
1149
1182
  end
1150
1183
  end
1151
-
1152
-
1184
+
1153
1185
  # Query table statistics for all indexes on the table
1154
1186
  # "TABLE_NAME: #{index_stats[2]}"
1155
1187
  # "NON_UNIQUE: #{index_stats[3]}"
1156
1188
  # "INDEX_NAME: #{index_stats[5]}"
1157
1189
  # "COLUMN_NAME: #{index_stats[8]}"
1158
- if stmt = IBM_DB.statistics( @connection, nil,
1159
- @servertype.set_case(@schema),
1160
- @servertype.set_case(table_name), 1 )
1190
+ stmt = IBM_DB.statistics( @connection, nil,
1191
+ @servertype.set_case(@schema),
1192
+ @servertype.set_case(table_name), 1 )
1193
+ if(stmt)
1161
1194
  begin
1162
1195
  while ( index_stats = IBM_DB.fetch_array(stmt) )
1163
1196
  is_composite = false
@@ -1182,20 +1215,20 @@ module ActiveRecord
1182
1215
  end
1183
1216
  end
1184
1217
  end
1185
- rescue StandardError # Handle driver fetch errors
1186
- error_msg = IBM_DB.conn_errormsg
1187
- error_msg = IBM_DB.stmt_errormsg if error_msg.empty?
1218
+ rescue StandardError => fetch_error # Handle driver fetch errors
1219
+ error_msg = IBM_DB.getErrormsg(stmt, IBM_DB::DB_STMT )
1188
1220
  if error_msg && !error_msg.empty?
1189
1221
  raise "Failed to retrieve index metadata during fetch: #{error_msg}"
1190
1222
  else
1191
- raise "An unexpected error occurred during retrieval of index metadata"
1223
+ error_msg = "An unexpected error occurred during retrieval of index metadata"
1224
+ error_msg = error_msg + ": #{fetch_error.message}" if !fetch_error.message.empty?
1225
+ raise error_msg
1192
1226
  end
1193
1227
  ensure # Free resources associated with the statement
1194
1228
  IBM_DB.free_result(stmt) if stmt
1195
1229
  end
1196
1230
  else # Handle driver execution errors
1197
- error_msg = IBM_DB.conn_errormsg
1198
- error_msg = IBM_DB.stmt_errormsg if error_msg.empty?
1231
+ error_msg = IBM_DB.getErrormsg(@connection, IBM_DB::DB_CONN )
1199
1232
  if error_msg && !error_msg.empty?
1200
1233
  raise "Failed to retrieve index metadata due to error: #{error_msg}"
1201
1234
  else
@@ -1215,7 +1248,7 @@ module ActiveRecord
1215
1248
  # Returns the indexes array
1216
1249
  return indexes
1217
1250
  end
1218
-
1251
+
1219
1252
  # Returns an array of Column objects for the table specified by +table_name+
1220
1253
  def columns(table_name, name = nil)
1221
1254
  # to_s required because it may be a symbol.
@@ -1226,9 +1259,10 @@ module ActiveRecord
1226
1259
  # +columns+ will contain the resulting array
1227
1260
  columns = []
1228
1261
  # Statement required to access all the columns information
1229
- if stmt = IBM_DB.columns( @connection, nil,
1262
+ stmt = IBM_DB.columns( @connection, nil,
1230
1263
  @servertype.set_case(@schema),
1231
1264
  @servertype.set_case(table_name) )
1265
+ if(stmt)
1232
1266
  begin
1233
1267
  # Fetches all the columns and assigns them to col.
1234
1268
  # +col+ is an hash with keys/value pairs for a column
@@ -1270,20 +1304,20 @@ module ActiveRecord
1270
1304
  columns << IBM_DBColumn.new(column_name, column_default_value, column_type, column_nullable)
1271
1305
  end
1272
1306
  end
1273
- rescue StandardError # Handle driver fetch errors
1274
- error_msg = IBM_DB.conn_errormsg
1275
- error_msg = IBM_DB.stmt_errormsg if error_msg.empty?
1307
+ rescue StandardError => fetch_error # Handle driver fetch errors
1308
+ error_msg = IBM_DB.getErrormsg(stmt, IBM_DB::DB_STMT )
1276
1309
  if error_msg && !error_msg.empty?
1277
1310
  raise "Failed to retrieve column metadata during fetch: #{error_msg}"
1278
1311
  else
1279
- raise "An unexpected error occurred during retrieval of metadata"
1312
+ error_msg = "An unexpected error occurred during retrieval of column metadata"
1313
+ error_msg = error_msg + ": #{fetch_error.message}" if !fetch_error.message.empty?
1314
+ raise error_msg
1280
1315
  end
1281
1316
  ensure # Free resources associated with the statement
1282
1317
  IBM_DB.free_result(stmt)
1283
1318
  end
1284
1319
  else # Handle driver execution errors
1285
- error_msg = IBM_DB.conn_errormsg
1286
- error_msg = IBM_DB.stmt_errormsg if error_msg.empty?
1320
+ error_msg = IBM_DB.getErrormsg(@connection, IBM_DB::DB_CONN )
1287
1321
  if error_msg && !error_msg.empty?
1288
1322
  raise "Failed to retrieve column metadata due to error: #{error_msg}"
1289
1323
  else
@@ -1355,7 +1389,7 @@ module ActiveRecord
1355
1389
  end
1356
1390
  end
1357
1391
  =end
1358
-
1392
+
1359
1393
  # Sets a new default value for a column. This does not set the default
1360
1394
  # value to +NULL+, instead, it needs DatabaseStatements#execute which
1361
1395
  # can execute the appropriate SQL statement for setting the value.
@@ -1366,12 +1400,12 @@ module ActiveRecord
1366
1400
  def change_column_default(table_name, column_name, default)
1367
1401
  @servertype.change_column_default(table_name, column_name, default)
1368
1402
  end
1369
-
1403
+
1370
1404
  #Changes the nullability value of a column
1371
1405
  def change_column_null(table_name, column_name, null, default = nil)
1372
1406
  @servertype.change_column_null(table_name, column_name, null, default)
1373
1407
  end
1374
-
1408
+
1375
1409
  # Remove the given index from the table.
1376
1410
  #
1377
1411
  # Remove the suppliers_name_index in the suppliers table (legacy support, use the second or third forms).
@@ -1439,13 +1473,14 @@ To remove the column, the table must be dropped and recreated without the #{colu
1439
1473
  # Add the record to the +results+ array
1440
1474
  results << single_hash
1441
1475
  end
1442
- rescue StandardError # Handle driver fetch errors
1443
- error_msg = IBM_DB.conn_errormsg
1444
- error_msg = IBM_DB.stmt_errormsg if error_msg.empty?
1476
+ rescue StandardError => fetch_error # Handle driver fetch errors
1477
+ error_msg = IBM_DB.getErrormsg(stmt, IBM_DB::DB_STMT )
1445
1478
  if error_msg && !error_msg.empty?
1446
1479
  raise StatementInvalid,"Failed to retrieve data: #{error_msg}"
1447
1480
  else
1448
- raise "An unexpected error occurred during data retrieval"
1481
+ error_msg = "An unexpected error occurred during data retrieval"
1482
+ error_msg = error_msg + ": #{fetch_error.message}" if !fetch_error.message.empty?
1483
+ raise error_msg
1449
1484
  end
1450
1485
  ensure # Free resources associated with the statement
1451
1486
  IBM_DB.free_result(stmt)
@@ -1461,30 +1496,30 @@ To remove the column, the table must be dropped and recreated without the #{colu
1461
1496
  #Add the array to results array
1462
1497
  results << single_array
1463
1498
  end
1464
- rescue StandardError # Handle driver fetch errors
1465
- error_msg = IBM_DB.conn_errormsg
1466
- error_msg = IBM_DB.stmt_errormsg if error_msg.empty?
1499
+ rescue StandardError => fetch_error # Handle driver fetch errors
1500
+ error_msg = IBM_DB.getErrormsg(stmt, IBM_DB::DB_STMT )
1467
1501
  if error_msg && !error_msg.empty?
1468
1502
  raise StatementInvalid,"Failed to retrieve data: #{error_msg}"
1469
1503
  else
1470
- raise "An unexpected error occurred during data retrieval"
1504
+ error_msg = "An unexpected error occurred during data retrieval"
1505
+ error_msg = error_msg + ": #{fetch_error.message}" if !fetch_error.message.empty?
1506
+ raise error_msg
1471
1507
  end
1472
1508
  ensure # Free resources associated with the statement
1473
1509
  IBM_DB.free_result(stmt)
1474
1510
  end
1475
1511
  end
1476
-
1512
+
1477
1513
  def execute(sql, name = nil)
1478
1514
  begin
1479
1515
  if stmt = IBM_DB.exec(@adapter.connection, sql)
1480
1516
  stmt # Return the statement object
1481
1517
  else
1482
- raise StatementInvalid, IBM_DB.stmt_errormsg
1518
+ raise StatementInvalid, IBM_DB.getErrormsg(@adapter.connection, IBM_DB::DB_CONN )
1483
1519
  end
1484
- rescue StandardError
1485
- error_msg = IBM_DB.conn_errormsg
1486
- if error_msg && !error_msg.empty?
1487
- raise "Failed to execute statement due to communication error: #{error_msg}"
1520
+ rescue StandardError => exec_err
1521
+ if exec_err && !exec_err.message.empty?
1522
+ raise "Failed to execute statement due to: #{exec_err}"
1488
1523
  else
1489
1524
  raise
1490
1525
  end
@@ -1545,26 +1580,27 @@ To remove the column, the table must be dropped and recreated without the #{colu
1545
1580
  def last_generated_id(stmt)
1546
1581
  # Queries the db to obtain the last ID that was automatically generated
1547
1582
  sql = "SELECT IDENTITY_VAL_LOCAL() FROM SYSIBM.SYSDUMMY1"
1548
- if stmt = IBM_DB.exec(@adapter.connection, sql)
1583
+ stmt = IBM_DB.exec(@adapter.connection, sql)
1584
+ if(stmt)
1549
1585
  begin
1550
1586
  # Fetches the only record available (containing the last id)
1551
1587
  IBM_DB.fetch_row(stmt)
1552
1588
  # Retrieves and returns the result of the query with the last id.
1553
1589
  IBM_DB.result(stmt,0)
1554
- rescue StandardError # Handle driver fetch errors
1555
- error_msg = IBM_DB.conn_errormsg
1556
- error_msg = IBM_DB.stmt_errormsg if error_msg.empty?
1590
+ rescue StandardError => fetch_error # Handle driver fetch errors
1591
+ error_msg = IBM_DB.getErrormsg(stmt, IBM_DB::DB_STMT )
1557
1592
  if error_msg && !error_msg.empty?
1558
1593
  raise "Failed to retrieve last generated id: #{error_msg}"
1559
1594
  else
1560
- raise "An unexpected error occurred during retrieval of last generated id"
1595
+ error_msg = "An unexpected error occurred during retrieval of last generated id"
1596
+ error_msg = error_msg + ": #{fetch_error.message}" if !fetch_error.message.empty?
1597
+ raise error_msg
1561
1598
  end
1562
1599
  ensure # Free resources associated with the statement
1563
1600
  IBM_DB.free_result(stmt) if stmt
1564
1601
  end
1565
1602
  else
1566
- error_msg = IBM_DB.conn_errormsg
1567
- error_msg = IBM_DB.stmt_errormsg if error_msg.empty?
1603
+ error_msg = IBM_DB.getErrormsg(@adapter.connection, IBM_DB::DB_CONN )
1568
1604
  if error_msg && !error_msg.empty?
1569
1605
  raise "Failed to retrieve last generated id due to error: #{error_msg}"
1570
1606
  else
@@ -1642,7 +1678,7 @@ SET WITH DEFAULT #{@adapter.quote(default)}"
1642
1678
  def get_double_mapping
1643
1679
  return "double"
1644
1680
  end
1645
-
1681
+
1646
1682
  # Fetches all the results available. IBM_DB.fetch_assoc(stmt) returns
1647
1683
  # an hash for each single record.
1648
1684
  # The loop stops when there aren't any more valid records to fetch
@@ -1697,13 +1733,14 @@ SET WITH DEFAULT #{@adapter.quote(default)}"
1697
1733
  results << single_hash
1698
1734
  end
1699
1735
  end
1700
- rescue StandardError # Handle driver fetch errors
1701
- error_msg = IBM_DB.conn_errormsg
1702
- error_msg = IBM_DB.stmt_errormsg if error_msg.empty?
1736
+ rescue StandardError => fetch_error # Handle driver fetch errors
1737
+ error_msg = IBM_DB.getErrormsg(stmt, IBM_DB::DB_STMT )
1703
1738
  if error_msg && !error_msg.empty?
1704
1739
  raise StatementInvalid,"Failed to retrieve data: #{error_msg}"
1705
1740
  else
1706
- raise "An unexpected error occurred during data retrieval"
1741
+ error_msg = "An unexpected error occurred during data retrieval"
1742
+ error_msg = error_msg + ": #{fetch_error.message}" if !fetch_error.message.empty?
1743
+ raise error_msg
1707
1744
  end
1708
1745
  ensure
1709
1746
  # Assign the instance variables to nil. We will not be using them again
@@ -1766,13 +1803,14 @@ SET WITH DEFAULT #{@adapter.quote(default)}"
1766
1803
  results << single_array
1767
1804
  end
1768
1805
  end
1769
- rescue StandardError # Handle driver fetch errors
1770
- error_msg = IBM_DB.conn_errormsg
1771
- error_msg = IBM_DB.stmt_errormsg if error_msg.empty?
1806
+ rescue StandardError => fetch_error # Handle driver fetch errors
1807
+ error_msg = IBM_DB.getErrormsg(stmt, IBM_DB::DB_STMT )
1772
1808
  if error_msg && !error_msg.empty?
1773
1809
  raise StatementInvalid,"Failed to retrieve data: #{error_msg}"
1774
1810
  else
1775
- raise "An unexpected error occurred during data retrieval"
1811
+ error_msg = "An unexpected error occurred during data retrieval"
1812
+ error_msg = error_msg + ": #{fetch_error.message}" if !fetch_error.message.empty?
1813
+ raise error_msg
1776
1814
  end
1777
1815
  ensure
1778
1816
  # Assign the instance variables to nil. We will not be using them again
@@ -1780,7 +1818,7 @@ SET WITH DEFAULT #{@adapter.quote(default)}"
1780
1818
  @limit = nil
1781
1819
  end
1782
1820
  end
1783
-
1821
+
1784
1822
  def execute(sql, name = nil)
1785
1823
  # Check if there is a limit and/or an offset
1786
1824
  # If so then make sure and use a static cursor type
@@ -1791,30 +1829,24 @@ SET WITH DEFAULT #{@adapter.quote(default)}"
1791
1829
  {IBM_DB::SQL_ATTR_CURSOR_TYPE => IBM_DB::SQL_CURSOR_STATIC})
1792
1830
  stmt # Return the statement object
1793
1831
  else
1794
- raise StatementInvalid, IBM_DB.stmt_errormsg
1795
- end
1796
- rescue StandardError
1797
- error_msg = IBM_DB.conn_errormsg
1798
- if error_msg && !error_msg.empty?
1799
- raise "Failed to execute statement due to communication error: #{error_msg}"
1800
- else
1801
- raise
1832
+ raise StatementInvalid, IBM_DB.getErrormsg(@adapter.connection, IBM_DB::DB_CONN )
1802
1833
  end
1834
+ rescue StandardError => exec_err
1835
+ error_msg = "Failed to execute statement due to"
1836
+ error_msg = error_msg + ": #{exec_err.message}" if !exec_err.message.empty?
1837
+ raise error_msg
1803
1838
  end
1804
1839
  else
1805
1840
  begin
1806
1841
  if stmt = IBM_DB.exec(@adapter.connection, sql)
1807
1842
  stmt # Return the statement object
1808
1843
  else
1809
- raise StatementInvalid, IBM_DB.stmt_errormsg
1810
- end
1811
- rescue StandardError
1812
- error_msg = IBM_DB.conn_errormsg
1813
- if error_msg && !error_msg.empty?
1814
- raise "Failed to execute statement due to communication error: #{error_msg}"
1815
- else
1816
- raise
1844
+ raise StatementInvalid, IBM_DB.getErrormsg(@adapter.connection, IBM_DB::DB_CONN )
1817
1845
  end
1846
+ rescue StandardError => exec_err
1847
+ error_msg = "Failed to execute statement due to"
1848
+ error_msg = error_msg + ": #{exec_err.message}" if !exec_err.message.empty?
1849
+ raise error_msg
1818
1850
  end
1819
1851
  end
1820
1852
  end
@@ -1902,8 +1934,7 @@ SET WITH DEFAULT #{@adapter.quote(default)}"
1902
1934
  TO #{_new_column_name}"
1903
1935
 
1904
1936
  unless stmt = execute(rename_column_sql)
1905
- error_msg = IBM_DB.conn_errormsg
1906
- error_msg = IBM_DB.stmt_errormsg if error_msg.empty?
1937
+ error_msg = IBM_DB.getErrormsg(@adapter.connection, IBM_DB::DB_CONN )
1907
1938
  if error_msg && !error_msg.empty?
1908
1939
  raise "Rename column failed : #{error_msg}"
1909
1940
  else
@@ -1968,8 +1999,7 @@ SET WITH DEFAULT #{@adapter.quote(default)}"
1968
1999
  TO #{_new_column_name}"
1969
2000
 
1970
2001
  unless stmt = execute(rename_column_sql)
1971
- error_msg = IBM_DB.conn_errormsg
1972
- error_msg = IBM_DB.stmt_errormsg if error_msg.empty?
2002
+ error_msg = IBM_DB.getErrormsg(@adapter.connection, IBM_DB::DB_CONN )
1973
2003
  if error_msg && !error_msg.empty?
1974
2004
  raise "Rename column failed : #{error_msg}"
1975
2005
  else
@@ -1998,7 +2028,7 @@ SET WITH DEFAULT #{@adapter.quote(default)}"
1998
2028
  super
1999
2029
  end
2000
2030
  end
2001
-
2031
+
2002
2032
  def change_column_null(table_name, column_name, null, default)
2003
2033
  raise NotImplementedError,
2004
2034
  "DB2 for zOS data server does not support changing the column's nullability"
@@ -2007,7 +2037,7 @@ SET WITH DEFAULT #{@adapter.quote(default)}"
2007
2037
 
2008
2038
  class IBM_DB2_ZOS_8 < IBM_DB2_ZOS
2009
2039
  include HostedDataServer
2010
-
2040
+
2011
2041
  # This call is needed on DB2 z/OS v8 for the creation of tables
2012
2042
  # with LOBs. When issued, this call does the following:
2013
2043
  # DB2 creates LOB table spaces, auxiliary tables, and indexes on auxiliary
@@ -2056,8 +2086,7 @@ SET WITH DEFAULT #{@adapter.quote(default)}"
2056
2086
  #{new_column_name}"
2057
2087
 
2058
2088
  unless stmt = execute(rename_column_sql)
2059
- error_msg = IBM_DB.conn_errormsg
2060
- error_msg = IBM_DB.stmt_errormsg if error_msg.empty?
2089
+ error_msg = IBM_DB.getErrormsg(@adapter.connection, IBM_DB::DB_CONN )
2061
2090
  if error_msg && !error_msg.empty?
2062
2091
  raise "Rename column failed : #{error_msg}"
2063
2092
  else