ibm_db 1.5.0-mswin32 → 2.0.0-mswin32
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGES +4 -0
- data/LICENSE +1 -1
- data/ParameterizedQueries README +39 -0
- data/README +1 -1
- data/ext/ibm_db.c +663 -436
- data/ext/ruby_ibm_db.h +6 -2
- data/ext/ruby_ibm_db_cli.c +3 -3
- data/ext/ruby_ibm_db_cli.h +17 -8
- data/lib/IBM_DB.rb +1 -1
- data/lib/active_record/connection_adapters/ibm_db_adapter.rb +383 -70
- data/lib/active_record/connection_adapters/ibm_db_pstmt.rb +1902 -0
- data/lib/mswin32/ibm_db.so +0 -0
- data/test/cases/calculations_test.rb +5 -1
- data/test/cases/helper.rb +75 -0
- data/test/connections/native_ibm_db/connection.rb +26 -24
- data/test/schema/schema.rb +1 -0
- metadata +5 -3
- data/ext/mkmf.log +0 -45
data/ext/ruby_ibm_db.h
CHANGED
@@ -2,11 +2,11 @@
|
|
2
2
|
+----------------------------------------------------------------------+
|
3
3
|
| Licensed Materials - Property of IBM |
|
4
4
|
| |
|
5
|
-
| (C) Copyright IBM Corporation 2006, 2007, 2008, 2009
|
5
|
+
| (C) Copyright IBM Corporation 2006, 2007, 2008, 2009, 2010 |
|
6
6
|
+----------------------------------------------------------------------+
|
7
7
|
| Authors: Sushant Koduru, Lynh Nguyen, Kanchana Padmanabhan, |
|
8
8
|
| Dan Scott, Helmut Tessarek, Kellen Bombardier, Sam Ruby |
|
9
|
-
| Ambrish Bhargava, Tarun Pasrija
|
9
|
+
| Ambrish Bhargava, Tarun Pasrija, Praveen Devarao |
|
10
10
|
+----------------------------------------------------------------------+
|
11
11
|
*/
|
12
12
|
|
@@ -81,6 +81,10 @@
|
|
81
81
|
#define CONN_ERROR 1
|
82
82
|
#define STMT_ERROR 2
|
83
83
|
|
84
|
+
/*Used to decide if LITERAL REPLACEMENT should be turned on or not*/
|
85
|
+
#define SET_QUOTED_LITERAL_REPLACEMENT_ON 1
|
86
|
+
#define SET_QUOTED_LITERAL_REPLACEMENT_OFF 0
|
87
|
+
|
84
88
|
/* DB2 instance environment variable */
|
85
89
|
#define DB2_VAR_INSTANCE "DB2INSTANCE="
|
86
90
|
|
data/ext/ruby_ibm_db_cli.c
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
+----------------------------------------------------------------------+
|
3
3
|
| Licensed Materials - Property of IBM |
|
4
4
|
| |
|
5
|
-
| (C) Copyright IBM Corporation 2009
|
5
|
+
| (C) Copyright IBM Corporation 2009, 2010 |
|
6
6
|
+----------------------------------------------------------------------+
|
7
7
|
| Authors: Praveen Devarao |
|
8
8
|
+----------------------------------------------------------------------+
|
@@ -517,7 +517,7 @@ int _ruby_ibm_db_SQLNumParams_helper(row_col_count_args *data) {
|
|
517
517
|
/*
|
518
518
|
This function calls SQLRowCount cli call to fetch the number of rows affected by the SQL statement
|
519
519
|
*/
|
520
|
-
int _ruby_ibm_db_SQLRowCount_helper(
|
520
|
+
int _ruby_ibm_db_SQLRowCount_helper(sql_row_count_args *data) {
|
521
521
|
int rc = 0;
|
522
522
|
|
523
523
|
data->stmt_res->is_executing = 1;
|
@@ -626,4 +626,4 @@ void _ruby_ibm_db_Statement_level_UBF(stmt_handle *stmt_res) {
|
|
626
626
|
rc = SQLCancel( (SQLHSTMT) stmt_res->hstmt );
|
627
627
|
}
|
628
628
|
return;
|
629
|
-
}
|
629
|
+
}
|
data/ext/ruby_ibm_db_cli.h
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
+----------------------------------------------------------------------+
|
3
3
|
| Licensed Materials - Property of IBM |
|
4
4
|
| |
|
5
|
-
| (C) Copyright IBM Corporation 2009
|
5
|
+
| (C) Copyright IBM Corporation 2009, 2010 |
|
6
6
|
+----------------------------------------------------------------------+
|
7
7
|
| Authors: Praveen Devarao |
|
8
8
|
+----------------------------------------------------------------------+
|
@@ -29,9 +29,9 @@ typedef struct _param_cache_node {
|
|
29
29
|
int param_type; /* Type of param - INP/OUT/INP-OUT/FILE */
|
30
30
|
int size; /* Size of param */
|
31
31
|
char *varname; /* bound variable name */
|
32
|
-
|
33
|
-
|
34
|
-
|
32
|
+
SQLBIGINT ivalue; /* Temp storage value */
|
33
|
+
SQLDOUBLE fvalue; /* Temp storage value */
|
34
|
+
SQLCHAR *svalue; /* Temp storage value */
|
35
35
|
struct _param_cache_node *next; /* Pointer to next node */
|
36
36
|
} param_node;
|
37
37
|
|
@@ -99,6 +99,7 @@ typedef struct _stmt_handle_struct {
|
|
99
99
|
int file_param; /* if option passed in is FILE_PARAM */
|
100
100
|
int num_columns;
|
101
101
|
int is_executing;
|
102
|
+
int is_freed; /* Indicates if the SQLFreeHandle is been called on the handle or not.*/
|
102
103
|
|
103
104
|
ibm_db_result_set_info *column_info;
|
104
105
|
ibm_db_row_type *row_data;
|
@@ -195,13 +196,21 @@ typedef struct _ibm_db_next_result_args_struct {
|
|
195
196
|
} next_result_args;
|
196
197
|
|
197
198
|
/*
|
198
|
-
Structure holding the necessary info to be passed to calls SQLNumResultCols/
|
199
|
+
Structure holding the necessary info to be passed to calls SQLNumResultCols/SQLNumParams
|
199
200
|
*/
|
200
201
|
typedef struct _ibm_db_row_col_count_struct {
|
201
202
|
stmt_handle *stmt_res;
|
202
|
-
|
203
|
+
SQLSMALLINT count;
|
203
204
|
} row_col_count_args;
|
204
205
|
|
206
|
+
/*
|
207
|
+
Structure holding the necessary info to be passed to call SQLRowcount
|
208
|
+
*/
|
209
|
+
typedef struct _ibm_db_row_count_struct {
|
210
|
+
stmt_handle *stmt_res;
|
211
|
+
SQLINTEGER count;
|
212
|
+
} sql_row_count_args;
|
213
|
+
|
205
214
|
/*
|
206
215
|
Structure holding the necessary info to be passed to call SQLColAttributes
|
207
216
|
*/
|
@@ -374,7 +383,7 @@ int _ruby_ibm_db_SQLFetchScroll_helper(fetch_data_args *data);
|
|
374
383
|
int _ruby_ibm_db_SQLFetch_helper(fetch_data_args *data);
|
375
384
|
int _ruby_ibm_db_SQLNumResultCols_helper(row_col_count_args *data);
|
376
385
|
int _ruby_ibm_db_SQLNumParams_helper(row_col_count_args *data);
|
377
|
-
int _ruby_ibm_db_SQLRowCount_helper(
|
386
|
+
int _ruby_ibm_db_SQLRowCount_helper(sql_row_count_args *data);
|
378
387
|
int _ruby_ibm_db_SQLGetInfo_helper(get_info_args *data);
|
379
388
|
int _ruby_ibm_db_SQLGetDiagRec_helper(get_diagRec_args *data);
|
380
389
|
int _ruby_ibm_db_SQLSetStmtAttr_helper(set_handle_attr_args *data);
|
@@ -386,4 +395,4 @@ int _ruby_ibm_db_SQLBindFileToParam_helper(stmt_handle *stmt_res, param_node *cu
|
|
386
395
|
int _ruby_ibm_db_SQLBindParameter_helper(bind_parameter_args *data);
|
387
396
|
void _ruby_ibm_db_Statement_level_UBF(stmt_handle *stmt_res);
|
388
397
|
|
389
|
-
#endif /* RUBY_IBM_DB_CLI_H */
|
398
|
+
#endif /* RUBY_IBM_DB_CLI_H */
|
data/lib/IBM_DB.rb
CHANGED
@@ -1,2 +1,2 @@
|
|
1
|
-
require (RUBY_PLATFORM =~ /mswin32/) ? 'mswin32/ibm_db.so' : 'ibm_db.so'
|
1
|
+
require (RUBY_PLATFORM =~ /mswin32/ || RUBY_PLATFORM =~ /mingw32/ ) ? 'mswin32/ibm_db.so' : 'ibm_db.so'
|
2
2
|
require 'active_record/connection_adapters/ibm_db_adapter'
|
@@ -1,7 +1,7 @@
|
|
1
1
|
# +----------------------------------------------------------------------+
|
2
2
|
# | Licensed Materials - Property of IBM |
|
3
3
|
# | |
|
4
|
-
# | (C) Copyright IBM Corporation 2006, 2007, 2008, 2009
|
4
|
+
# | (C) Copyright IBM Corporation 2006, 2007, 2008, 2009, 2010 |
|
5
5
|
# +----------------------------------------------------------------------+
|
6
6
|
# | Authors: Antonio Cangiano <cangiano@ca.ibm.com> |
|
7
7
|
# | : Mario Ds Briggs <mario.briggs@in.ibm.com> |
|
@@ -66,24 +66,28 @@ module ActiveRecord
|
|
66
66
|
|
67
67
|
update_query << " WHERE #{self.class.primary_key} = ?"
|
68
68
|
values << self[self.class.primary_key.downcase]
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
69
|
+
|
70
|
+
begin
|
71
|
+
unless stmt = IBM_DB.prepare(connection.connection, update_query)
|
72
|
+
error_msg = IBM_DB.getErrormsg( connection.connection, IBM_DB::DB_CONN )
|
73
|
+
if error_msg && !error_msg.empty?
|
74
|
+
raise "Statement prepare for updating LOB/XML column failed : #{error_msg}"
|
75
|
+
else
|
76
|
+
raise StandardError.new('An unexpected error occurred during update of LOB/XML column')
|
77
|
+
end
|
76
78
|
end
|
77
|
-
|
78
|
-
connection.log_query(update_query,'update of LOB/XML field(s)in handle_lobs')
|
79
|
+
connection.log_query(update_query,'update of LOB/XML field(s)in handle_lobs')
|
79
80
|
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
81
|
+
# rollback any failed LOB/XML field updates (and remove associated marker)
|
82
|
+
unless IBM_DB.execute(stmt, values)
|
83
|
+
error_msg = "Failed to insert/update LOB/XML field(s) due to: #{IBM_DB.getErrormsg( stmt, IBM_DB::DB_STMT )}"
|
84
|
+
connection.execute("ROLLBACK")
|
85
|
+
raise error_msg
|
86
|
+
end
|
87
|
+
rescue StandardError => error
|
88
|
+
raise error
|
89
|
+
ensure
|
90
|
+
IBM_DB.free_stmt(stmt) if stmt
|
87
91
|
end
|
88
92
|
end # if clob_sql
|
89
93
|
end #connection.sql.each
|
@@ -103,9 +107,16 @@ module ActiveRecord
|
|
103
107
|
raise LoadError, "Failed to load IBM_DB Ruby driver."
|
104
108
|
end
|
105
109
|
|
110
|
+
if( config.has_key?(:parameterized) && config[:parameterized] == true )
|
111
|
+
require 'active_record/connection_adapters/ibm_db_pstmt'
|
112
|
+
end
|
113
|
+
|
106
114
|
# Converts all +config+ keys to symbols
|
107
115
|
config = config.symbolize_keys
|
108
116
|
|
117
|
+
# Flag to decide if quoted literal replcement should take place. By default it is ON. Set it to OFF if using Pstmt
|
118
|
+
set_quoted_literal_replacement = IBM_DB::QUOTED_LITERAL_REPLACEMENT_ON
|
119
|
+
|
109
120
|
# Retrieves the database alias (local catalog name) or remote name
|
110
121
|
# (for remote TCP/IP connections) from the +config+ hash
|
111
122
|
# or raises ArgumentError in case of failure.
|
@@ -127,6 +138,10 @@ module ActiveRecord
|
|
127
138
|
# Providing default schema (username) when not specified
|
128
139
|
config[:schema] = config.has_key?(:schema) ? config[:schema].to_s : config[:username].to_s
|
129
140
|
|
141
|
+
if(config.has_key?(:parameterized) && config[:parameterized] == true )
|
142
|
+
set_quoted_literal_replacement = IBM_DB::QUOTED_LITERAL_REPLACEMENT_OFF
|
143
|
+
end
|
144
|
+
|
130
145
|
# Extract connection options from the database configuration
|
131
146
|
# (in support to formatting, audit and billing purposes):
|
132
147
|
# Retrieve database objects fields in lowercase
|
@@ -171,10 +186,10 @@ module ActiveRecord
|
|
171
186
|
conn_string << "AUTHENTICATION=#{config[:authentication]};" if config.has_key?(:authentication)
|
172
187
|
conn_string << "CONNECTTIMEOUT=#{config[:timeout]};" if config.has_key?(:timeout)
|
173
188
|
|
174
|
-
connection = IBM_DB.connect conn_string, '', '', conn_options
|
189
|
+
connection = IBM_DB.connect( conn_string, '', '', conn_options, set_quoted_literal_replacement )
|
175
190
|
else
|
176
191
|
# No host implies a local catalog-based connection: +database+ represents catalog alias
|
177
|
-
connection = IBM_DB.connect( database, username, password, conn_options )
|
192
|
+
connection = IBM_DB.connect( database, username, password, conn_options, set_quoted_literal_replacement )
|
178
193
|
end
|
179
194
|
rescue StandardError => connect_err
|
180
195
|
raise "Failed to connect to [#{database}] due to: #{connect_err}"
|
@@ -399,13 +414,18 @@ module ActiveRecord
|
|
399
414
|
# // - to connect to the database server. By default value is SERVER
|
400
415
|
# timeout: 10 // Specifies the time in seconds (0 - 32767) to wait for a reply from server -
|
401
416
|
# //- when trying to establish a connection before generating a timeout
|
417
|
+
# == Parameterized Queries Support
|
418
|
+
# parameterized: false // Specifies if the prepared statement support of
|
419
|
+
# //- the IBM_DB Adapter is to be turned on or off
|
402
420
|
#
|
403
421
|
# When schema is not specified, the username value is used instead.
|
422
|
+
# The default setting of parameterized is false.
|
404
423
|
#
|
405
424
|
class IBM_DBAdapter < AbstractAdapter
|
406
425
|
attr_reader :connection, :servertype
|
407
|
-
attr_accessor :sql,:handle_lobs_triggered
|
426
|
+
attr_accessor :sql,:handle_lobs_triggered, :sql_parameter_values
|
408
427
|
attr_reader :schema, :app_user, :account, :application, :workstation
|
428
|
+
attr_reader :pstmt_support_on, :set_quoted_literal_replacement
|
409
429
|
|
410
430
|
# Name of the adapter
|
411
431
|
def adapter_name
|
@@ -427,6 +447,14 @@ module ActiveRecord
|
|
427
447
|
@security = config[:security] || nil
|
428
448
|
@authentication = config[:authentication] || nil
|
429
449
|
@timeout = config[:timeout] || 0 # default timeout value is 0
|
450
|
+
|
451
|
+
if( config.has_key?(:parameterized) && config[:parameterized] == true )
|
452
|
+
@pstmt_support_on = true
|
453
|
+
@set_quoted_literal_replacement = IBM_DB::QUOTED_LITERAL_REPLACEMENT_OFF
|
454
|
+
else
|
455
|
+
@pstmt_support_on = false
|
456
|
+
@set_quoted_literal_replacement = IBM_DB::QUOTED_LITERAL_REPLACEMENT_ON
|
457
|
+
end
|
430
458
|
|
431
459
|
# Caching database connection options (auditing and billing support)
|
432
460
|
@app_user = conn_options[:app_user] if conn_options.has_key?(:app_user)
|
@@ -434,7 +462,9 @@ module ActiveRecord
|
|
434
462
|
@application = conn_options[:application] if conn_options.has_key?(:application)
|
435
463
|
@workstation = conn_options[:workstation] if conn_options.has_key?(:workstation)
|
436
464
|
|
437
|
-
@sql
|
465
|
+
@sql = []
|
466
|
+
@sql_parameter_values = [] #Used only if pstmt support is turned on
|
467
|
+
|
438
468
|
@handle_lobs_triggered = false
|
439
469
|
|
440
470
|
# Calls the parent class +ConnectionAdapters+' initializer
|
@@ -585,11 +615,11 @@ module ActiveRecord
|
|
585
615
|
@conn_string << "AUTHENTICATION=#{@authentication};" if @authentication
|
586
616
|
@conn_string << "CONNECTTIMEOUT=#{@timeout};"
|
587
617
|
# Connects and assigns the resulting IBM_DB.Connection to the +@connection+ instance variable
|
588
|
-
@connection = IBM_DB.connect(@conn_string, '', '', @conn_options)
|
618
|
+
@connection = IBM_DB.connect(@conn_string, '', '', @conn_options, @set_quoted_literal_replacement)
|
589
619
|
else
|
590
620
|
# Connects to the database using the local alias (@database)
|
591
621
|
# and assigns the connection object (IBM_DB.Connection) to @connection
|
592
|
-
@connection = IBM_DB.connect(@database, @username, @password, @conn_options)
|
622
|
+
@connection = IBM_DB.connect(@database, @username, @password, @conn_options, @set_quoted_literal_replacement)
|
593
623
|
end
|
594
624
|
rescue StandardError => connect_err
|
595
625
|
warn "Connection to database #{@database} failed: #{connect_err}"
|
@@ -640,6 +670,73 @@ module ActiveRecord
|
|
640
670
|
end
|
641
671
|
end
|
642
672
|
|
673
|
+
# Returns an array of hashes with the column names as keys and
|
674
|
+
# column values as values. +sql+ is the select query,
|
675
|
+
# and +name+ is an optional description for logging
|
676
|
+
def prepared_select(sql_param_hash, name = nil)
|
677
|
+
# Replaces {"= NULL" with " IS NULL"} OR {"IN (NULL)" with " IS NULL"}
|
678
|
+
|
679
|
+
results = []
|
680
|
+
# Invokes the method +prepare+ in order prepare the SQL
|
681
|
+
# IBM_DB.Statement is returned from which the statement is executed and results fetched
|
682
|
+
pstmt = prepare(sql_param_hash["sqlSegment"], name)
|
683
|
+
if(execute_prepared_stmt(pstmt, sql_param_hash["paramArray"]))
|
684
|
+
begin
|
685
|
+
@servertype.select(sql_param_hash["sqlSegment"], name, pstmt, results)
|
686
|
+
rescue StandardError => fetch_error # Handle driver fetch errors
|
687
|
+
error_msg = IBM_DB.getErrormsg(pstmt, IBM_DB::DB_STMT )
|
688
|
+
if error_msg && !error_msg.empty?
|
689
|
+
raise StatementInvalid,"Failed to retrieve data: #{error_msg}"
|
690
|
+
else
|
691
|
+
error_msg = "An unexpected error occurred during data retrieval"
|
692
|
+
error_msg = error_msg + ": #{fetch_error.message}" if !fetch_error.message.empty?
|
693
|
+
raise error_msg
|
694
|
+
end
|
695
|
+
ensure
|
696
|
+
# Ensures to free the resources associated with the statement
|
697
|
+
IBM_DB.free_stmt(pstmt) if pstmt
|
698
|
+
end
|
699
|
+
end
|
700
|
+
# The array of record hashes is returned
|
701
|
+
results
|
702
|
+
end
|
703
|
+
|
704
|
+
# Returns an array of hashes with the column names as keys and
|
705
|
+
# column values as values. +sql+ is the select query,
|
706
|
+
# and +name+ is an optional description for logging
|
707
|
+
def prepared_select_values(sql_param_hash, name = nil)
|
708
|
+
# Replaces {"= NULL" with " IS NULL"} OR {"IN (NULL)" with " IS NULL"}
|
709
|
+
|
710
|
+
results = []
|
711
|
+
# Invokes the method +prepare+ in order prepare the SQL
|
712
|
+
# IBM_DB.Statement is returned from which the statement is executed and results fetched
|
713
|
+
pstmt = prepare(sql_param_hash["sqlSegment"], name)
|
714
|
+
if(execute_prepared_stmt(pstmt, sql_param_hash["paramArray"]))
|
715
|
+
begin
|
716
|
+
@servertype.select_rows(sql_param_hash["sqlSegment"], name, pstmt, results)
|
717
|
+
if results
|
718
|
+
return results.map { |v| v[0] }
|
719
|
+
else
|
720
|
+
nil
|
721
|
+
end
|
722
|
+
rescue StandardError => fetch_error # Handle driver fetch errors
|
723
|
+
error_msg = IBM_DB.getErrormsg(pstmt, IBM_DB::DB_STMT )
|
724
|
+
if error_msg && !error_msg.empty?
|
725
|
+
raise StatementInvalid,"Failed to retrieve data: #{error_msg}"
|
726
|
+
else
|
727
|
+
error_msg = "An unexpected error occurred during data retrieval"
|
728
|
+
error_msg = error_msg + ": #{fetch_error.message}" if !fetch_error.message.empty?
|
729
|
+
raise error_msg
|
730
|
+
end
|
731
|
+
ensure
|
732
|
+
# Ensures to free the resources associated with the statement
|
733
|
+
IBM_DB.free_stmt(pstmt) if pstmt
|
734
|
+
end
|
735
|
+
end
|
736
|
+
# The array of record hashes is returned
|
737
|
+
results
|
738
|
+
end
|
739
|
+
|
643
740
|
# Returns an array of hashes with the column names as keys and
|
644
741
|
# column values as values. +sql+ is the select query,
|
645
742
|
# and +name+ is an optional description for logging
|
@@ -665,7 +762,7 @@ module ActiveRecord
|
|
665
762
|
end
|
666
763
|
ensure
|
667
764
|
# Ensures to free the resources associated with the statement
|
668
|
-
IBM_DB.
|
765
|
+
IBM_DB.free_stmt(stmt) if stmt
|
669
766
|
end
|
670
767
|
end
|
671
768
|
# The array of record hashes is returned
|
@@ -697,7 +794,7 @@ module ActiveRecord
|
|
697
794
|
end
|
698
795
|
ensure
|
699
796
|
# Ensures to free the resources associated with the statement
|
700
|
-
IBM_DB.
|
797
|
+
IBM_DB.free_stmt(stmt) if stmt
|
701
798
|
end
|
702
799
|
end
|
703
800
|
# The array of record hashes is returned
|
@@ -765,9 +862,10 @@ module ActiveRecord
|
|
765
862
|
log(insert_query,'fixture insert') do
|
766
863
|
unless IBM_DB.execute(stmt, insert_values)
|
767
864
|
error_msg = IBM_DB.getErrormsg(stmt, IBM_DB::DB_STMT )
|
865
|
+
IBM_DB.free_stmt(stmt) if stmt
|
768
866
|
raise "Failed to insert due to: #{error_msg}"
|
769
867
|
else
|
770
|
-
IBM_DB.
|
868
|
+
IBM_DB.free_stmt(stmt) if stmt
|
771
869
|
end
|
772
870
|
end
|
773
871
|
end
|
@@ -789,8 +887,67 @@ module ActiveRecord
|
|
789
887
|
return id_value || @servertype.last_generated_id(stmt)
|
790
888
|
# Ensures to free the resources associated with the statement
|
791
889
|
ensure
|
792
|
-
IBM_DB.
|
890
|
+
IBM_DB.free_stmt(stmt) if stmt
|
891
|
+
end
|
892
|
+
end
|
893
|
+
end
|
894
|
+
|
895
|
+
# Praveen
|
896
|
+
# Performs an insert using the prepared statement and returns the last ID generated.
|
897
|
+
# This can be the ID passed to the method or the one auto-generated by the database,
|
898
|
+
# and retrieved by the +last_generated_id+ method.
|
899
|
+
def prepared_insert(pstmt, param_array = nil)
|
900
|
+
if @handle_lobs_triggered #Ensure the array of sql is cleared if they have been handled in the callback
|
901
|
+
@sql = []
|
902
|
+
@sql_parameter_values = []
|
903
|
+
@handle_lobs_triggered = false
|
904
|
+
end
|
905
|
+
|
906
|
+
clear_query_cache if defined? clear_query_cache
|
907
|
+
|
908
|
+
begin
|
909
|
+
if execute_prepared_stmt(pstmt, param_array)
|
910
|
+
@sql << @prepared_sql
|
911
|
+
@sql_parameter_values << param_array
|
912
|
+
return @servertype.last_generated_id(pstmt)
|
913
|
+
end
|
914
|
+
rescue StandardError => insert_err
|
915
|
+
raise insert_err
|
916
|
+
ensure
|
917
|
+
IBM_DB.free_stmt(pstmt) if pstmt
|
918
|
+
end
|
919
|
+
end
|
920
|
+
|
921
|
+
# Praveen
|
922
|
+
# Prepares and logs +sql+ commands and
|
923
|
+
# returns a +IBM_DB.Statement+ object.
|
924
|
+
def prepare(sql,name = nil)
|
925
|
+
# The +log+ method is defined in the parent class +AbstractAdapter+
|
926
|
+
@prepared_sql = sql
|
927
|
+
log(sql,name) do
|
928
|
+
@servertype.prepare(sql, name)
|
929
|
+
end
|
930
|
+
end
|
931
|
+
|
932
|
+
# Praveen
|
933
|
+
#Executes the prepared statement
|
934
|
+
#ReturnsTrue on success and False on Failure
|
935
|
+
def execute_prepared_stmt(pstmt, param_array = nil)
|
936
|
+
if !param_array.nil? && param_array.size < 1
|
937
|
+
param_array = nil
|
938
|
+
end
|
939
|
+
|
940
|
+
if( !IBM_DB.execute(pstmt, param_array) )
|
941
|
+
error_msg = IBM_DB.getErrormsg(pstmt, IBM_DB::DB_STMT)
|
942
|
+
if !error_msg.empty?
|
943
|
+
error_msg = "Statement execution failed: " + error_msg
|
944
|
+
else
|
945
|
+
error_msg = "Statement execution failed"
|
793
946
|
end
|
947
|
+
IBM_DB.free_stmt(pstmt) if pstmt
|
948
|
+
raise StatementInvalid, error_msg
|
949
|
+
else
|
950
|
+
return true
|
794
951
|
end
|
795
952
|
end
|
796
953
|
|
@@ -836,15 +993,40 @@ module ActiveRecord
|
|
836
993
|
IBM_DB.num_rows(stmt)
|
837
994
|
# Ensures to free the resources associated with the statement
|
838
995
|
ensure
|
839
|
-
IBM_DB.
|
996
|
+
IBM_DB.free_stmt(stmt) if stmt
|
840
997
|
end
|
841
998
|
end
|
842
999
|
end
|
843
1000
|
|
1001
|
+
#Praveen
|
1002
|
+
def prepared_update(pstmt, param_array = nil )
|
1003
|
+
if @handle_lobs_triggered #Ensure the array of sql is cleared if they have been handled in the callback
|
1004
|
+
@sql = []
|
1005
|
+
@sql_parameter_values = []
|
1006
|
+
@handle_lobs_triggered = false
|
1007
|
+
end
|
1008
|
+
|
1009
|
+
clear_query_cache if defined? clear_query_cache
|
1010
|
+
|
1011
|
+
begin
|
1012
|
+
if execute_prepared_stmt(pstmt, param_array)
|
1013
|
+
@sql << @prepared_sql
|
1014
|
+
@sql_parameter_values << param_array
|
1015
|
+
# Retrieves the number of affected rows
|
1016
|
+
IBM_DB.num_rows(pstmt)
|
1017
|
+
# Ensures to free the resources associated with the statement
|
1018
|
+
end
|
1019
|
+
rescue StandardError => updt_err
|
1020
|
+
raise updt_err
|
1021
|
+
ensure
|
1022
|
+
IBM_DB.free_stmt(pstmt) if pstmt
|
1023
|
+
end
|
1024
|
+
end
|
844
1025
|
# The delete method executes the delete
|
845
1026
|
# statement and returns the number of affected rows.
|
846
1027
|
# The method is an alias for +update+
|
847
1028
|
alias_method :delete, :update
|
1029
|
+
alias_method :prepared_delete, :prepared_update
|
848
1030
|
|
849
1031
|
# Begins the transaction (and turns off auto-committing)
|
850
1032
|
def begin_db_transaction
|
@@ -892,13 +1074,21 @@ module ActiveRecord
|
|
892
1074
|
if limit == 0
|
893
1075
|
# Returns a query that will always generate zero records
|
894
1076
|
# (e.g. WHERE sys_row_num BETWEEN 1 and 0)
|
895
|
-
|
1077
|
+
if( @pstmt_support_on )
|
1078
|
+
sql = @servertype.query_offset_limit!(sql, 0, limit, options)
|
1079
|
+
else
|
1080
|
+
sql = @servertype.query_offset_limit(sql, 0, limit)
|
1081
|
+
end
|
896
1082
|
# If there is a non-zero limit
|
897
1083
|
else
|
898
1084
|
offset = options[:offset]
|
899
1085
|
# If an offset is specified builds the query with offset and limit,
|
900
1086
|
# otherwise retrieves only the first +limit+ rows
|
901
|
-
|
1087
|
+
if( @pstmt_support_on )
|
1088
|
+
sql = @servertype.query_offset_limit!(sql, offset, limit, options)
|
1089
|
+
else
|
1090
|
+
sql = @servertype.query_offset_limit(sql, offset, limit)
|
1091
|
+
end
|
902
1092
|
end
|
903
1093
|
end
|
904
1094
|
# Returns the sql query in any case
|
@@ -914,6 +1104,35 @@ module ActiveRecord
|
|
914
1104
|
# QUOTING
|
915
1105
|
#==============================================
|
916
1106
|
|
1107
|
+
#Praveen
|
1108
|
+
def quote_value_for_pstmt(value, column=nil)
|
1109
|
+
|
1110
|
+
return value.quoted_id if value.respond_to?(:quoted_id)
|
1111
|
+
|
1112
|
+
case value
|
1113
|
+
when String, ActiveSupport::Multibyte::Chars then
|
1114
|
+
value = value.to_s
|
1115
|
+
if column && [:integer, :float].include?(column.type)
|
1116
|
+
value = column.type == :integer ? value.to_i : value.to_f
|
1117
|
+
value
|
1118
|
+
else
|
1119
|
+
value
|
1120
|
+
end
|
1121
|
+
when NilClass then nil
|
1122
|
+
when TrueClass then 1
|
1123
|
+
when FalseClass then 0
|
1124
|
+
when Float, Fixnum, Bignum then value
|
1125
|
+
# BigDecimals need to be output in a non-normalized form and quoted.
|
1126
|
+
when BigDecimal then value.to_s('F')
|
1127
|
+
else
|
1128
|
+
if value.acts_like?(:date) || value.acts_like?(:time)
|
1129
|
+
quoted_date(value)
|
1130
|
+
else
|
1131
|
+
value.to_yaml
|
1132
|
+
end
|
1133
|
+
end
|
1134
|
+
end
|
1135
|
+
|
917
1136
|
# Properly quotes the various data types.
|
918
1137
|
# +value+ contains the data, +column+ is optional and contains info on the field
|
919
1138
|
def quote(value, column = nil)
|
@@ -1080,7 +1299,7 @@ module ActiveRecord
|
|
1080
1299
|
raise error_msg
|
1081
1300
|
end
|
1082
1301
|
ensure
|
1083
|
-
IBM_DB.
|
1302
|
+
IBM_DB.free_stmt(stmt) if stmt # Free resources associated with the statement
|
1084
1303
|
end
|
1085
1304
|
else # Handle driver execution errors
|
1086
1305
|
error_msg = IBM_DB.getErrormsg(@connection, IBM_DB::DB_CONN )
|
@@ -1115,7 +1334,7 @@ module ActiveRecord
|
|
1115
1334
|
raise error_msg
|
1116
1335
|
end
|
1117
1336
|
ensure # Free resources associated with the statement
|
1118
|
-
IBM_DB.
|
1337
|
+
IBM_DB.free_stmt(stmt) if stmt
|
1119
1338
|
end
|
1120
1339
|
else
|
1121
1340
|
error_msg = IBM_DB.getErrormsg( @connection, IBM_DB::DB_CONN )
|
@@ -1171,7 +1390,7 @@ module ActiveRecord
|
|
1171
1390
|
raise error_msg
|
1172
1391
|
end
|
1173
1392
|
ensure # Free resources associated with the statement
|
1174
|
-
IBM_DB.
|
1393
|
+
IBM_DB.free_stmt(stmt) if stmt
|
1175
1394
|
end
|
1176
1395
|
else # Handle driver execution errors
|
1177
1396
|
error_msg = IBM_DB.getErrormsg(@connection, IBM_DB::DB_CONN )
|
@@ -1225,7 +1444,7 @@ module ActiveRecord
|
|
1225
1444
|
raise error_msg
|
1226
1445
|
end
|
1227
1446
|
ensure # Free resources associated with the statement
|
1228
|
-
IBM_DB.
|
1447
|
+
IBM_DB.free_stmt(stmt) if stmt
|
1229
1448
|
end
|
1230
1449
|
else # Handle driver execution errors
|
1231
1450
|
error_msg = IBM_DB.getErrormsg(@connection, IBM_DB::DB_CONN )
|
@@ -1314,7 +1533,7 @@ module ActiveRecord
|
|
1314
1533
|
raise error_msg
|
1315
1534
|
end
|
1316
1535
|
ensure # Free resources associated with the statement
|
1317
|
-
IBM_DB.
|
1536
|
+
IBM_DB.free_stmt(stmt) if stmt
|
1318
1537
|
end
|
1319
1538
|
else # Handle driver execution errors
|
1320
1539
|
error_msg = IBM_DB.getErrormsg(@connection, IBM_DB::DB_CONN )
|
@@ -1338,7 +1557,7 @@ module ActiveRecord
|
|
1338
1557
|
stmt = execute(rename_table_sql)
|
1339
1558
|
# Ensures to free the resources associated with the statement
|
1340
1559
|
ensure
|
1341
|
-
IBM_DB.
|
1560
|
+
IBM_DB.free_stmt(stmt) if stmt
|
1342
1561
|
end
|
1343
1562
|
|
1344
1563
|
# Renames a column.
|
@@ -1482,8 +1701,6 @@ To remove the column, the table must be dropped and recreated without the #{colu
|
|
1482
1701
|
error_msg = error_msg + ": #{fetch_error.message}" if !fetch_error.message.empty?
|
1483
1702
|
raise error_msg
|
1484
1703
|
end
|
1485
|
-
ensure # Free resources associated with the statement
|
1486
|
-
IBM_DB.free_result(stmt)
|
1487
1704
|
end
|
1488
1705
|
end
|
1489
1706
|
|
@@ -1505,8 +1722,24 @@ To remove the column, the table must be dropped and recreated without the #{colu
|
|
1505
1722
|
error_msg = error_msg + ": #{fetch_error.message}" if !fetch_error.message.empty?
|
1506
1723
|
raise error_msg
|
1507
1724
|
end
|
1508
|
-
|
1509
|
-
|
1725
|
+
end
|
1726
|
+
end
|
1727
|
+
|
1728
|
+
# Praveen
|
1729
|
+
def prepare(sql,name = nil)
|
1730
|
+
begin
|
1731
|
+
stmt = IBM_DB.prepare(@adapter.connection, sql)
|
1732
|
+
if( stmt )
|
1733
|
+
stmt
|
1734
|
+
else
|
1735
|
+
raise StatementInvalid, IBM_DB.getErrormsg(@adapter.connection, IBM_DB::DB_CONN )
|
1736
|
+
end
|
1737
|
+
rescue StandardError => prep_err
|
1738
|
+
if prep_err && !prep_err.message.empty?
|
1739
|
+
raise "Failed to prepare sql #{sql} due to: #{prep_err}"
|
1740
|
+
else
|
1741
|
+
raise
|
1742
|
+
end
|
1510
1743
|
end
|
1511
1744
|
end
|
1512
1745
|
|
@@ -1532,6 +1765,9 @@ To remove the column, the table must be dropped and recreated without the #{colu
|
|
1532
1765
|
|
1533
1766
|
def query_offset_limit(sql, offset, limit)
|
1534
1767
|
end
|
1768
|
+
|
1769
|
+
def query_offset_limit!(sql, offset, limit, options)
|
1770
|
+
end
|
1535
1771
|
|
1536
1772
|
def get_datetime_mapping
|
1537
1773
|
end
|
@@ -1580,24 +1816,35 @@ To remove the column, the table must be dropped and recreated without the #{colu
|
|
1580
1816
|
def last_generated_id(stmt)
|
1581
1817
|
# Queries the db to obtain the last ID that was automatically generated
|
1582
1818
|
sql = "SELECT IDENTITY_VAL_LOCAL() FROM SYSIBM.SYSDUMMY1"
|
1583
|
-
stmt = IBM_DB.
|
1819
|
+
stmt = IBM_DB.prepare(@adapter.connection, sql)
|
1584
1820
|
if(stmt)
|
1585
|
-
|
1586
|
-
|
1587
|
-
|
1588
|
-
|
1589
|
-
|
1590
|
-
|
1821
|
+
if(IBM_DB.execute(stmt, nil))
|
1822
|
+
begin
|
1823
|
+
# Fetches the only record available (containing the last id)
|
1824
|
+
IBM_DB.fetch_row(stmt)
|
1825
|
+
# Retrieves and returns the result of the query with the last id.
|
1826
|
+
IBM_DB.result(stmt,0)
|
1827
|
+
rescue StandardError => fetch_error # Handle driver fetch errors
|
1828
|
+
error_msg = IBM_DB.getErrormsg(stmt, IBM_DB::DB_STMT )
|
1829
|
+
if error_msg && !error_msg.empty?
|
1830
|
+
raise "Failed to retrieve last generated id: #{error_msg}"
|
1831
|
+
else
|
1832
|
+
error_msg = "An unexpected error occurred during retrieval of last generated id"
|
1833
|
+
error_msg = error_msg + ": #{fetch_error.message}" if !fetch_error.message.empty?
|
1834
|
+
raise error_msg
|
1835
|
+
end
|
1836
|
+
ensure # Free resources associated with the statement
|
1837
|
+
IBM_DB.free_stmt(stmt) if stmt
|
1838
|
+
end
|
1839
|
+
else
|
1591
1840
|
error_msg = IBM_DB.getErrormsg(stmt, IBM_DB::DB_STMT )
|
1841
|
+
IBM_DB.free_stmt(stmt) if stmt
|
1592
1842
|
if error_msg && !error_msg.empty?
|
1593
1843
|
raise "Failed to retrieve last generated id: #{error_msg}"
|
1594
1844
|
else
|
1595
1845
|
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
1846
|
raise error_msg
|
1598
1847
|
end
|
1599
|
-
ensure # Free resources associated with the statement
|
1600
|
-
IBM_DB.free_result(stmt) if stmt
|
1601
1848
|
end
|
1602
1849
|
else
|
1603
1850
|
error_msg = IBM_DB.getErrormsg(@adapter.connection, IBM_DB::DB_CONN )
|
@@ -1640,7 +1887,7 @@ SET WITH DEFAULT #{@adapter.quote(default)}"
|
|
1640
1887
|
stmt = execute(change_column_sql)
|
1641
1888
|
reorg_table(table_name)
|
1642
1889
|
ensure
|
1643
|
-
IBM_DB.
|
1890
|
+
IBM_DB.free_stmt(stmt) if stmt
|
1644
1891
|
end
|
1645
1892
|
|
1646
1893
|
#DB2 specific ALTER TABLE statement to change the nullability of a column
|
@@ -1659,7 +1906,7 @@ SET WITH DEFAULT #{@adapter.quote(default)}"
|
|
1659
1906
|
stmt = execute(change_column_sql)
|
1660
1907
|
reorg_table(table_name)
|
1661
1908
|
ensure
|
1662
|
-
IBM_DB.
|
1909
|
+
IBM_DB.free_stmt(stmt) if stmt
|
1663
1910
|
end
|
1664
1911
|
|
1665
1912
|
# This method returns the DB2 SQL type corresponding to the Rails
|
@@ -1819,11 +2066,39 @@ SET WITH DEFAULT #{@adapter.quote(default)}"
|
|
1819
2066
|
end
|
1820
2067
|
end
|
1821
2068
|
|
2069
|
+
# Praveen
|
2070
|
+
def prepare(sql,name = nil)
|
2071
|
+
# Check if there is a limit and/or an offset
|
2072
|
+
# If so then make sure and use a static cursor type
|
2073
|
+
begin
|
2074
|
+
if (!@offset.nil? && @offset >= 0) || (!@limit.nil? && @limit > 0)
|
2075
|
+
# Set the cursor type to static so we can later utilize the offset and limit correctly
|
2076
|
+
if stmt = IBM_DB.prepare(@adapter.connection, sql,
|
2077
|
+
{IBM_DB::SQL_ATTR_CURSOR_TYPE => IBM_DB::SQL_CURSOR_STATIC})
|
2078
|
+
stmt # Return the statement object
|
2079
|
+
else
|
2080
|
+
raise StatementInvalid, IBM_DB.getErrormsg(@adapter.connection, IBM_DB::DB_CONN )
|
2081
|
+
end
|
2082
|
+
else
|
2083
|
+
if stmt = IBM_DB.prepare(@adapter.connection, sql)
|
2084
|
+
stmt # Return the statement object
|
2085
|
+
else
|
2086
|
+
raise StatementInvalid, IBM_DB.getErrormsg(@adapter.connection, IBM_DB::DB_CONN )
|
2087
|
+
end
|
2088
|
+
end
|
2089
|
+
rescue StandardError => prep_err
|
2090
|
+
error_msg = "Failed to prepare sql #{sql}"
|
2091
|
+
error_msg = error_msg + ": #{prep_err.message}" if !prep_err.message.empty?
|
2092
|
+
raise error_msg
|
2093
|
+
end
|
2094
|
+
end
|
2095
|
+
|
2096
|
+
# Praveen
|
1822
2097
|
def execute(sql, name = nil)
|
1823
2098
|
# Check if there is a limit and/or an offset
|
1824
2099
|
# If so then make sure and use a static cursor type
|
1825
|
-
|
1826
|
-
|
2100
|
+
begin
|
2101
|
+
if (!@offset.nil? && @offset >= 0) || (!@limit.nil? && @limit > 0)
|
1827
2102
|
# Set the cursor type to static so we can later utilize the offset and limit correctly
|
1828
2103
|
if stmt = IBM_DB.exec(@adapter.connection, sql,
|
1829
2104
|
{IBM_DB::SQL_ATTR_CURSOR_TYPE => IBM_DB::SQL_CURSOR_STATIC})
|
@@ -1831,23 +2106,17 @@ SET WITH DEFAULT #{@adapter.quote(default)}"
|
|
1831
2106
|
else
|
1832
2107
|
raise StatementInvalid, IBM_DB.getErrormsg(@adapter.connection, IBM_DB::DB_CONN )
|
1833
2108
|
end
|
1834
|
-
|
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
|
1838
|
-
end
|
1839
|
-
else
|
1840
|
-
begin
|
2109
|
+
else
|
1841
2110
|
if stmt = IBM_DB.exec(@adapter.connection, sql)
|
1842
2111
|
stmt # Return the statement object
|
1843
2112
|
else
|
1844
2113
|
raise StatementInvalid, IBM_DB.getErrormsg(@adapter.connection, IBM_DB::DB_CONN )
|
1845
2114
|
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
|
1850
2115
|
end
|
2116
|
+
rescue StandardError => exec_err
|
2117
|
+
error_msg = "Failed to execute statement"
|
2118
|
+
error_msg = error_msg + ": #{exec_err.message}" if !exec_err.message.empty?
|
2119
|
+
raise error_msg
|
1851
2120
|
end
|
1852
2121
|
end
|
1853
2122
|
|
@@ -1859,6 +2128,15 @@ SET WITH DEFAULT #{@adapter.quote(default)}"
|
|
1859
2128
|
end
|
1860
2129
|
end
|
1861
2130
|
|
2131
|
+
def query_offset_limit!(sql, offset, limit, options)
|
2132
|
+
@limit = limit
|
2133
|
+
@offset = offset
|
2134
|
+
if (offset.nil?)
|
2135
|
+
sql << " FETCH FIRST #{limit} ROWS ONLY"
|
2136
|
+
end
|
2137
|
+
options[:paramArray] = []
|
2138
|
+
end
|
2139
|
+
|
1862
2140
|
# This method generates the default blob value specified for
|
1863
2141
|
# DB2 Dataservers
|
1864
2142
|
def set_binary_default(value)
|
@@ -1904,6 +2182,24 @@ SET WITH DEFAULT #{@adapter.quote(default)}"
|
|
1904
2182
|
# and retrieve only a LIMIT number of records starting from the OFFSET+1
|
1905
2183
|
sql << ") AS I) AS O WHERE sys_row_num BETWEEN #{offset+1} AND #{last_record}"
|
1906
2184
|
end
|
2185
|
+
|
2186
|
+
def query_offset_limit!(sql, offset, limit, options)
|
2187
|
+
if (offset.nil?)
|
2188
|
+
options[:paramArray] = []
|
2189
|
+
return sql << " FETCH FIRST #{limit} ROWS ONLY"
|
2190
|
+
end
|
2191
|
+
# Defines what will be the last record
|
2192
|
+
last_record = offset + limit
|
2193
|
+
# Transforms the SELECT query in order to retrieve/fetch only
|
2194
|
+
# a number of records after the specified offset.
|
2195
|
+
# 'select' or 'SELECT' is replaced with the partial query below that adds the sys_row_num column
|
2196
|
+
# to select with the condition of this column being between offset+1 and the offset+limit
|
2197
|
+
sql.sub!(/SELECT/i,"SELECT O.* FROM (SELECT I.*, ROW_NUMBER() OVER () sys_row_num FROM (SELECT")
|
2198
|
+
# The final part of the query is appended to include a WHERE...BETWEEN...AND condition,
|
2199
|
+
# and retrieve only a LIMIT number of records starting from the OFFSET+1
|
2200
|
+
sql << ") AS I) AS O WHERE sys_row_num BETWEEN ? AND ?"
|
2201
|
+
options[:paramArray] = [offset+1, last_record]
|
2202
|
+
end
|
1907
2203
|
end # class IBM_DB2_LUW
|
1908
2204
|
|
1909
2205
|
class IBM_DB2_LUW_COBRA < IBM_DB2_LUW
|
@@ -1945,7 +2241,7 @@ SET WITH DEFAULT #{@adapter.quote(default)}"
|
|
1945
2241
|
reorg_table(_table_name)
|
1946
2242
|
|
1947
2243
|
ensure
|
1948
|
-
IBM_DB.free_stmt
|
2244
|
+
IBM_DB.free_stmt(stmt) if stmt
|
1949
2245
|
end #End of begin
|
1950
2246
|
end # End of rename_column
|
1951
2247
|
end #IBM_DB2_LUW_COBRA
|
@@ -2010,7 +2306,7 @@ SET WITH DEFAULT #{@adapter.quote(default)}"
|
|
2010
2306
|
reorg_table(_table_name)
|
2011
2307
|
|
2012
2308
|
ensure
|
2013
|
-
IBM_DB.free_stmt
|
2309
|
+
IBM_DB.free_stmt(stmt) if stmt
|
2014
2310
|
end #End of begin
|
2015
2311
|
end # End of rename_column
|
2016
2312
|
|
@@ -2097,7 +2393,7 @@ SET WITH DEFAULT #{@adapter.quote(default)}"
|
|
2097
2393
|
reorg_table(_table_name)
|
2098
2394
|
|
2099
2395
|
ensure
|
2100
|
-
IBM_DB.free_stmt
|
2396
|
+
IBM_DB.free_stmt(stmt) if stmt
|
2101
2397
|
end #End of begin
|
2102
2398
|
end # End of rename_column
|
2103
2399
|
|
@@ -2136,7 +2432,7 @@ SET WITH DEFAULT #{@adapter.quote(default)}"
|
|
2136
2432
|
reorg_table(table_name)
|
2137
2433
|
# Ensures to free the resources associated with the statement
|
2138
2434
|
ensure
|
2139
|
-
IBM_DB.
|
2435
|
+
IBM_DB.free_stmt(stmt) if stmt
|
2140
2436
|
end
|
2141
2437
|
|
2142
2438
|
# IDS specific ALTER TABLE statement to change the nullability of a column
|
@@ -2160,7 +2456,7 @@ SET WITH DEFAULT #{@adapter.quote(default)}"
|
|
2160
2456
|
stmt = execute(change_column_sql)
|
2161
2457
|
reorg_table(table_name)
|
2162
2458
|
ensure
|
2163
|
-
IBM_DB.
|
2459
|
+
IBM_DB.free_stmt(stmt) if stmt
|
2164
2460
|
end
|
2165
2461
|
|
2166
2462
|
# Reorganizes the table for column changes
|
@@ -2202,6 +2498,23 @@ SET WITH DEFAULT #{@adapter.quote(default)}"
|
|
2202
2498
|
end
|
2203
2499
|
end
|
2204
2500
|
|
2501
|
+
# Handling offset/limit as per Informix requirements
|
2502
|
+
def query_offset_limit!(sql, offset, limit, options)
|
2503
|
+
if limit != 0
|
2504
|
+
if !offset.nil?
|
2505
|
+
# Modifying the SQL to utilize the skip and limit amounts
|
2506
|
+
sql.gsub!(/SELECT/i,"SELECT SKIP #{offset} LIMIT #{limit}")
|
2507
|
+
else
|
2508
|
+
# Modifying the SQL to retrieve only the first #{limit} rows
|
2509
|
+
sql = sql.gsub!("SELECT","SELECT FIRST #{limit}")
|
2510
|
+
end
|
2511
|
+
else
|
2512
|
+
# Modifying the SQL to ensure that no rows will be returned
|
2513
|
+
sql.gsub!(/SELECT/i,"SELECT * FROM (SELECT")
|
2514
|
+
sql << ") WHERE 0 = 1"
|
2515
|
+
end
|
2516
|
+
end
|
2517
|
+
|
2205
2518
|
# Method that returns the last automatically generated ID
|
2206
2519
|
# on the given +@connection+. This method is required by the +insert+
|
2207
2520
|
# method. IDS returns the last generated serial value in the SQLCA unlike
|