ibm_db 1.1.1-mswin32 → 1.5.0-mswin32

Sign up to get free protection for your applications and to get access to all the features.
@@ -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