ibm_db 1.5.0-mswin32 → 2.0.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.
- 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
|