ibm_db 2.5.6-x86-mswin32-60 → 2.5.7-x86-mswin32-60

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.
Files changed (38) hide show
  1. data/CHANGES +6 -0
  2. data/README +1 -1
  3. data/ext/Makefile.nt32 +3 -3
  4. data/ext/Makefile.nt32.191 +212 -0
  5. data/ext/ibm_db.c +30 -5
  6. data/lib/active_record/connection_adapters/ibm_db_adapter.rb +300 -108
  7. data/lib/active_record/connection_adapters/ibm_db_pstmt.rb +1 -1
  8. data/lib/mswin32/rb18x/ibm_db.so +0 -0
  9. data/test/cases/adapter_test.rb +25 -22
  10. data/test/cases/associations/belongs_to_associations_test.rb +245 -43
  11. data/test/cases/associations/cascaded_eager_loading_test.rb +28 -26
  12. data/test/cases/associations/has_and_belongs_to_many_associations_test.rb +60 -156
  13. data/test/cases/associations/join_model_test.rb +96 -146
  14. data/test/cases/attribute_methods_test.rb +98 -33
  15. data/test/cases/base_test.rb +525 -103
  16. data/test/cases/calculations_test.rb +92 -8
  17. data/test/cases/migration_test.rb +533 -207
  18. data/test/cases/persistence_test.rb +636 -0
  19. data/test/cases/query_cache_test.rb +242 -0
  20. data/test/cases/relations_test.rb +1019 -0
  21. data/test/cases/schema_dumper_test.rb +37 -17
  22. data/test/cases/transaction_callbacks_test.rb +300 -0
  23. data/test/cases/validations/uniqueness_validation_test.rb +38 -22
  24. data/test/cases/xml_serialization_test.rb +276 -0
  25. data/test/config.yml +154 -0
  26. data/test/connections/native_ibm_db/connection.rb +2 -0
  27. data/test/models/warehouse_thing.rb +4 -4
  28. data/test/schema/i5/ibm_db_specific_schema.rb +3 -1
  29. data/test/schema/ids/ibm_db_specific_schema.rb +3 -1
  30. data/test/schema/luw/ibm_db_specific_schema.rb +2 -0
  31. data/test/schema/schema.rb +174 -89
  32. data/test/schema/zOS/ibm_db_specific_schema.rb +3 -1
  33. metadata +9 -7
  34. data/lib/mswin32/rb19x/ibm_db.so +0 -0
  35. data/test/cases/associations/eager_test.rb +0 -862
  36. data/test/cases/associations/has_many_through_associations_test.rb +0 -461
  37. data/test/cases/finder_test.rb +0 -1088
  38. data/test/cases/fixtures_test.rb +0 -684
data/CHANGES CHANGED
@@ -1,5 +1,11 @@
1
1
  Change Log
2
2
  ==============
3
+ 2011/09/18 (IBM_DB adapter 2.5.7, driver 2.5.7) :
4
+ - Support for Rails-3.1.0
5
+ - Fixed bug #29052 -> prepare results in empty error message
6
+ - Support for continuation of method IBM_DB.conn_error and IBM_DB.conn_errormsg - #29324
7
+ - Test suite update as for Rails-3.1.0
8
+
3
9
  2011/02/07 (IBM_DB adapter 2.5.6, driver 2.5.6) :
4
10
  - Fixed Bug #28622, #28881
5
11
  - Decimal datatypes will now be returned as BigDecimal type from the driver
data/README CHANGED
@@ -1,5 +1,5 @@
1
1
  =====================================================================
2
- README for the IBM_DB Adapter (2.5.5) and Driver (2.5.5) (2011/02/07)
2
+ README for the IBM_DB Adapter (2.5.7) and Driver (2.5.7) (2011/09/18)
3
3
  For ActiveRecord Version >= 1.15.5 (and Rails >= 1.2.5)
4
4
  =====================================================================
5
5
 
data/ext/Makefile.nt32 CHANGED
@@ -4,12 +4,12 @@ SHELL = /bin/sh
4
4
  #### Start of system configuration section. ####
5
5
 
6
6
  srcdir = .
7
- topdir =$(TOP)/opendbad/win/ruby_1.8.6/lib/ruby/1.8/i386-mswin32
7
+ topdir =$(TOP)/opendbad/win/ruby_win_exes/ruby_1.8.6/lib/ruby/1.8/i386-mswin32
8
8
  hdrdir = $(topdir)
9
9
  VPATH = $(srcdir);$(topdir);$(hdrdir)
10
10
 
11
11
 
12
- DESTDIR = $(TOP)/opendbad/win
12
+ DESTDIR = $(TOP)/opendbad/win/ruby_win_exes
13
13
  prefix = $(DESTDIR)/ruby_1.8.6
14
14
  exec_prefix = $(DESTDIR)/ruby_1.8.6
15
15
  sitedir = $(prefix)/lib/ruby/site_ruby
@@ -51,7 +51,7 @@ RUBY_SO_NAME = msvcrt-ruby18
51
51
  arch = i386-mswin32
52
52
  sitearch = i386-msvcrt
53
53
  ruby_version = 1.8
54
- ruby = $(TOP)/opendbad/win/ruby_1.8.6/bin/ruby.exe
54
+ ruby = $(TOP)/opendbad/win/ruby_win_exes/ruby_1.8.6/bin/ruby.exe
55
55
  RUBY = $(ruby:/=\)
56
56
  RM = $(RUBY) -run -e rm -- -f
57
57
  MAKEDIRS = @$(RUBY) -run -e mkdir -- -p
@@ -0,0 +1,212 @@
1
+
2
+ SHELL = /bin/sh
3
+
4
+ #### Start of system configuration section. ####
5
+
6
+ srcdir = .
7
+ topdir = $(TOP)/opendbad/win/ruby_win_exes/ruby191/include/ruby-1.9.1
8
+ hdrdir = $(TOP)/opendbad/win/ruby_win_exes/ruby191/include/ruby-1.9.1
9
+ arch_hdrdir = $(TOP)/opendbad/win/ruby_win_exes/ruby191/include/ruby-1.9.1/$(arch)
10
+ VPATH = $(srcdir);$(arch_hdrdir)/ruby;$(hdrdir)/ruby
11
+
12
+ DESTDIR = $(TOP)/opendbad/win/ruby_win_exes
13
+ prefix = $(DESTDIR)/ruby191
14
+ exec_prefix = $(prefix)
15
+ bindir = $(exec_prefix)/bin
16
+ sbindir = $(exec_prefix)/sbin
17
+ libexecdir = $(exec_prefix)/libexec
18
+ datadir = $(prefix)/share
19
+ sysconfdir = $(prefix)/etc
20
+ sharedstatedir = $(DESTDIR)/etc
21
+ localstatedir = $(DESTDIR)/var
22
+ libdir = $(exec_prefix)/lib
23
+ includedir = $(prefix)/include
24
+ oldincludedir = $(DESTDIR)/usr/include
25
+ infodir = $(prefix)/info
26
+ mandir = $(prefix)/man
27
+ sitedir = $(prefix)/lib/$(RUBY_INSTALL_NAME)/site_ruby
28
+ vendordir = $(prefix)/lib/$(RUBY_INSTALL_NAME)/vendor_ruby
29
+ rubyhdrdir = $(includedir)/$(RUBY_INSTALL_NAME)-$(ruby_version)
30
+ sitehdrdir = $(rubyhdrdir)/site_ruby
31
+ vendorhdrdir = $(rubyhdrdir)/vendor_ruby
32
+ rubylibdir = $(libdir)/$(ruby_install_name)/$(ruby_version)
33
+ archdir = $(rubylibdir)/$(arch)
34
+ sitelibdir = $(sitedir)/$(ruby_version)
35
+ sitearchdir = $(sitelibdir)/$(sitearch)
36
+ vendorlibdir = $(vendordir)/$(ruby_version)
37
+ vendorarchdir = $(vendorlibdir)/$(sitearch)
38
+
39
+ CC = cl -nologo
40
+ CXX = $(CC)
41
+ LIBRUBY = $(RUBY_SO_NAME).lib
42
+ LIBRUBY_A = $(RUBY_SO_NAME)-static.lib
43
+ LIBRUBYARG_SHARED = $(LIBRUBY)
44
+ LIBRUBYARG_STATIC = $(LIBRUBY_A)
45
+ OUTFLAG = -Fe
46
+ COUTFLAG = -Fo
47
+
48
+ RUBY_EXTCONF_H = unicode_support_version
49
+ cflags =
50
+ optflags =
51
+ debugflags =
52
+ warnflags =
53
+ CFLAGS = -MT -Zi -O2b2xg- -G6 -Zm600
54
+ INCFLAGS = -I. -I$(arch_hdrdir) -I$(hdrdir)/ruby/backward -I$(hdrdir) -I$(srcdir)
55
+ DEFS =
56
+ CPPFLAGS = -DRUBY_EXTCONF_H=\"$(RUBY_EXTCONF_H)\"
57
+ CXXFLAGS = $(CFLAGS) -MT -Zi -O2b2xg- -G6 -Zm600
58
+ ldflags =
59
+ dldflags = -link -incremental:no -debug -opt:ref -opt:icf -dll $(LIBPATH)
60
+ archflag =
61
+ DLDFLAGS = $(ldflags) $(dldflags) $(archflag)
62
+ LDSHARED = cl -nologo -LD
63
+ LDSHAREDXX = $(LDSHARED)
64
+ AR = lib -nologo
65
+ EXEEXT = .exe
66
+
67
+ RUBY_INSTALL_NAME = ruby
68
+ RUBY_SO_NAME = msvcrt-ruby191
69
+ arch = i386-mswin32
70
+ sitearch = i386-msvcrt
71
+ ruby_version = 1.9.1
72
+ ruby = $(TOP)/opendbad/win/ruby_win_exes/ruby191/bin/ruby
73
+ RUBY = $(ruby:/=\)
74
+ RM = $(RUBY) -run -e rm -- -f
75
+ RM_RF = $(RUBY) -run -e rm -- -rf
76
+ RMDIRS = $(RUBY) -run -e rmdir -- -p
77
+ MAKEDIRS = @$(RUBY) -run -e mkdir -- -p
78
+ INSTALL = @$(RUBY) -run -e install -- -vp
79
+ INSTALL_PROG = $(INSTALL) -m 0755
80
+ INSTALL_DATA = $(INSTALL) -m 0644
81
+ COPY = copy > nul
82
+
83
+ #### End of system configuration section. ####
84
+
85
+ preload =
86
+
87
+ libpath = . $(libdir) C:/Progra~1/IBM/SQLLIB/lib
88
+ LIBPATH = -libpath:"." -libpath:"$(libdir)"
89
+ DEFFILE = $(TARGET)-$(arch).def
90
+
91
+ CLEANFILES = mkmf.log
92
+ DISTCLEANFILES = vc*.pdb $(DEFFILE)
93
+ DISTCLEANDIRS =
94
+
95
+ extout =
96
+ extout_prefix =
97
+ target_prefix =
98
+ LOCAL_LIBS =
99
+ LIBS = $(LIBRUBYARG_SHARED) db2cli.lib oldnames.lib user32.lib advapi32.lib shell32.lib ws2_32.lib libcmt.lib
100
+ SRCS = ibm_db.c ruby_ibm_db_cli.c
101
+ OBJS = ibm_db.obj ruby_ibm_db_cli.obj
102
+ TARGET = ibm_db
103
+ DLLIB = $(TARGET).so
104
+ EXTSTATIC =
105
+ STATIC_LIB =
106
+
107
+ BINDIR = $(bindir)
108
+ RUBYCOMMONDIR = $(sitedir)$(target_prefix)
109
+ RUBYLIBDIR = $(sitelibdir)$(target_prefix)
110
+ RUBYARCHDIR = $(sitearchdir)$(target_prefix)
111
+ HDRDIR = $(rubyhdrdir)/ruby$(target_prefix)
112
+ ARCHHDRDIR = $(rubyhdrdir)/$(arch)/ruby$(target_prefix)
113
+
114
+ TARGET_SO = $(DLLIB)
115
+ CLEANLIBS = $(TARGET).so
116
+ CLEANOBJS = *.obj $(TARGET).exp $(TARGET).lib $(TARGET).pdb *.bak
117
+
118
+ all: $(DLLIB)
119
+ static: $(STATIC_LIB)
120
+
121
+ clean-rb-default::
122
+ clean-rb::
123
+ clean-so::
124
+ clean: clean-so clean-rb-default clean-rb
125
+ @-$(RM) $(CLEANLIBS:/=\) $(CLEANOBJS:/=\) $(CLEANFILES:/=\)
126
+
127
+ distclean-rb-default::
128
+ distclean-rb::
129
+ distclean-so::
130
+ distclean: clean distclean-so distclean-rb-default distclean-rb
131
+ @-$(RM) Makefile $(RUBY_EXTCONF_H) conftest.* mkmf.log
132
+ @-$(RM) core ruby$(EXEEXT) *~ $(DISTCLEANFILES:/=\)
133
+ @-$(RMDIRS) $(DISTCLEANDIRS:/=\)
134
+
135
+ realclean: distclean
136
+ install: install-so install-rb
137
+
138
+ install-so: $(RUBYARCHDIR)
139
+ install-so: $(RUBYARCHDIR)/$(DLLIB)
140
+ $(RUBYARCHDIR)/$(DLLIB): $(DLLIB)
141
+ $(INSTALL_PROG) $(DLLIB:/=\) $(RUBYARCHDIR:/=\)
142
+ install-rb: pre-install-rb install-rb-default
143
+ install-rb-default: pre-install-rb-default
144
+ pre-install-rb: Makefile
145
+ pre-install-rb-default: Makefile
146
+ $(RUBYARCHDIR):
147
+ $(MAKEDIRS) $@
148
+
149
+ site-install: site-install-so site-install-rb
150
+ site-install-so: install-so
151
+ site-install-rb: install-rb
152
+
153
+ .SUFFIXES: .c .m .cc .cxx .cpp .obj
154
+
155
+ {$(hdrdir)}.cc.obj:
156
+ $(CXX) $(INCFLAGS) $(CXXFLAGS) $(CPPFLAGS) $(COUTFLAG)$(@) -c -Tp$(<:\=/)
157
+
158
+ {$(topdir)}.cc.obj:
159
+ $(CXX) $(INCFLAGS) $(CXXFLAGS) $(CPPFLAGS) $(COUTFLAG)$(@) -c -Tp$(<:\=/)
160
+
161
+ {$(srcdir)}.cc.obj:
162
+ $(CXX) $(INCFLAGS) $(CXXFLAGS) $(CPPFLAGS) $(COUTFLAG)$(@) -c -Tp$(<:\=/)
163
+
164
+ .cc.obj:
165
+ $(CXX) $(INCFLAGS) $(CXXFLAGS) $(CPPFLAGS) $(COUTFLAG)$(@) -c -Tp$(<:\=/)
166
+
167
+ {$(hdrdir)}.cxx.obj:
168
+ $(CXX) $(INCFLAGS) $(CXXFLAGS) $(CPPFLAGS) $(COUTFLAG)$(@) -c -Tp$(<:\=/)
169
+
170
+ {$(topdir)}.cxx.obj:
171
+ $(CXX) $(INCFLAGS) $(CXXFLAGS) $(CPPFLAGS) $(COUTFLAG)$(@) -c -Tp$(<:\=/)
172
+
173
+ {$(srcdir)}.cxx.obj:
174
+ $(CXX) $(INCFLAGS) $(CXXFLAGS) $(CPPFLAGS) $(COUTFLAG)$(@) -c -Tp$(<:\=/)
175
+
176
+ .cxx.obj:
177
+ $(CXX) $(INCFLAGS) $(CXXFLAGS) $(CPPFLAGS) $(COUTFLAG)$(@) -c -Tp$(<:\=/)
178
+
179
+ {$(hdrdir)}.cpp.obj:
180
+ $(CXX) $(INCFLAGS) $(CXXFLAGS) $(CPPFLAGS) $(COUTFLAG)$(@) -c -Tp$(<:\=/)
181
+
182
+ {$(topdir)}.cpp.obj:
183
+ $(CXX) $(INCFLAGS) $(CXXFLAGS) $(CPPFLAGS) $(COUTFLAG)$(@) -c -Tp$(<:\=/)
184
+
185
+ {$(srcdir)}.cpp.obj:
186
+ $(CXX) $(INCFLAGS) $(CXXFLAGS) $(CPPFLAGS) $(COUTFLAG)$(@) -c -Tp$(<:\=/)
187
+
188
+ .cpp.obj:
189
+ $(CXX) $(INCFLAGS) $(CXXFLAGS) $(CPPFLAGS) $(COUTFLAG)$(@) -c -Tp$(<:\=/)
190
+
191
+ {$(hdrdir)}.c.obj:
192
+ $(CC) $(INCFLAGS) $(CFLAGS) $(CPPFLAGS) $(COUTFLAG)$(@) -c -Tc$(<:\=/)
193
+
194
+ {$(topdir)}.c.obj:
195
+ $(CC) $(INCFLAGS) $(CFLAGS) $(CPPFLAGS) $(COUTFLAG)$(@) -c -Tc$(<:\=/)
196
+
197
+ {$(srcdir)}.c.obj:
198
+ $(CC) $(INCFLAGS) $(CFLAGS) $(CPPFLAGS) $(COUTFLAG)$(@) -c -Tc$(<:\=/)
199
+
200
+ .c.obj:
201
+ $(CC) $(INCFLAGS) $(CFLAGS) $(CPPFLAGS) $(COUTFLAG)$(@) -c -Tc$(<:\=/)
202
+
203
+ $(DLLIB): $(DEFFILE) $(OBJS) Makefile
204
+ @-$(RM) $(@:/=\)
205
+ $(LDSHARED) -Fe$(@) $(OBJS) $(LIBS) $(LOCAL_LIBS) $(DLDFLAGS) -implib:$(*F:.so=)-$(arch).lib -pdb:$(*F:.so=)-$(arch).pdb -def:$(DEFFILE)
206
+
207
+
208
+
209
+ $(DEFFILE):
210
+ $(RUBY) -e "puts 'EXPORTS', 'Init_$(TARGET)'" > $@
211
+
212
+ $(OBJS): {.;$(VPATH)}$(hdrdir)/ruby.h {.;$(VPATH)}$(hdrdir)/ruby/defines.h $(arch_hdrdir)/ruby/config.h $(RUBY_EXTCONF_H)
data/ext/ibm_db.c CHANGED
@@ -12,7 +12,7 @@
12
12
  +----------------------------------------------------------------------+
13
13
  */
14
14
 
15
- #define MODULE_RELEASE "2.5.6"
15
+ #define MODULE_RELEASE "2.5.7"
16
16
 
17
17
  #ifdef HAVE_CONFIG_H
18
18
  #include "config.h"
@@ -5197,7 +5197,7 @@ static int _ruby_ibm_db_do_prepare(conn_handle *conn_res, VALUE stmt, stmt_handl
5197
5197
  #endif
5198
5198
 
5199
5199
  if ( rc == SQL_ERROR ) {
5200
- _ruby_ibm_db_check_sql_errors( conn_res, DB_CONN, stmt_res->hstmt, SQL_HANDLE_STMT, rc, 0,
5200
+ _ruby_ibm_db_check_sql_errors( conn_res, DB_CONN, stmt_res->hstmt, SQL_HANDLE_STMT, rc, 1,
5201
5201
  NULL, NULL, -1, 1, 1 );
5202
5202
  }
5203
5203
  }
@@ -6381,7 +6381,8 @@ static VALUE _ruby_ibm_db_execute_helper(stmt_bind_array *bind_array) {
6381
6381
 
6382
6382
  put_param_data_args->stmt_res = stmt_res;
6383
6383
 
6384
- while ( _ruby_ibm_db_SQLParamData_helper( put_param_data_args ) == SQL_NEED_DATA ) {
6384
+ rc = _ruby_ibm_db_SQLParamData_helper( put_param_data_args );
6385
+ while ( rc == SQL_NEED_DATA ) {
6385
6386
 
6386
6387
  /* passing data value for a parameter */
6387
6388
  rc = _ruby_ibm_db_SQLPutData_helper(put_param_data_args);
@@ -6412,13 +6413,37 @@ static VALUE _ruby_ibm_db_execute_helper(stmt_bind_array *bind_array) {
6412
6413
 
6413
6414
  return Qnil;
6414
6415
  }
6416
+ rc = _ruby_ibm_db_SQLParamData_helper( put_param_data_args );
6415
6417
  }
6416
6418
 
6417
6419
  if (put_param_data_args != NULL) {
6418
6420
  ruby_xfree( put_param_data_args );
6419
6421
  put_param_data_args = NULL;
6420
6422
  }
6423
+
6424
+ if ( rc == SQL_ERROR ) {
6425
+ _ruby_ibm_db_check_sql_errors( stmt_res, DB_STMT, stmt_res->hstmt, SQL_HANDLE_STMT, rc, 1, NULL, NULL, -1, 1, 0 );
6426
+ if( stmt_res != NULL && stmt_res->ruby_stmt_err_msg != NULL ) {
6427
+ #ifdef UNICODE_SUPPORT_VERSION
6428
+ *error = rb_str_concat( _ruby_ibm_db_export_char_to_utf8_rstr( "Sending data failed: "),
6429
+ _ruby_ibm_db_export_sqlwchar_to_utf8_rstr( stmt_res->ruby_stmt_err_msg,
6430
+ stmt_res->ruby_stmt_err_msg_len )
6431
+ );
6432
+ #else
6433
+ *error = rb_str_cat2(rb_str_new2("Sending data failed: "), stmt_res->ruby_stmt_err_msg );
6434
+ #endif
6435
+ } else {
6436
+ #ifdef UNICODE_SUPPORT_VERSION
6437
+ *error = _ruby_ibm_db_export_char_to_utf8_rstr("Sending data failed: <error message could not be retrieved>");
6438
+ #else
6439
+ *error = rb_str_new2("Sending data failed: <error message could not be retrieved>");
6440
+ #endif
6441
+ }
6442
+
6443
+ return Qnil;
6444
+ }
6421
6445
  }
6446
+
6422
6447
  return Qtrue;
6423
6448
  }
6424
6449
  /*
@@ -6642,7 +6667,7 @@ VALUE ibm_db_conn_errormsg(int argc, VALUE *argv, VALUE self)
6642
6667
 
6643
6668
  rb_scan_args(argc, argv, "01", &connection);
6644
6669
 
6645
- rb_warn("Method conn_errormsg is deprecated, use getErrormsg");
6670
+ /*rb_warn("Method conn_errormsg is deprecated, use getErrormsg");*/
6646
6671
 
6647
6672
  if (!NIL_P(connection)) {
6648
6673
  Data_Get_Struct(connection, conn_handle, conn_res);
@@ -6796,7 +6821,7 @@ VALUE ibm_db_conn_error(int argc, VALUE *argv, VALUE self)
6796
6821
 
6797
6822
  rb_scan_args(argc, argv, "01", &connection);
6798
6823
 
6799
- rb_warn("Method conn_error is deprecated, use getErrorstate");
6824
+ /*rb_warn("Method conn_error is deprecated, use getErrorstate");*/
6800
6825
 
6801
6826
  if (!NIL_P(connection)) {
6802
6827
  Data_Get_Struct(connection, conn_handle, conn_res);
@@ -521,7 +521,7 @@ module ActiveRecord
521
521
  end
522
522
  when /DB2/i # DB2 for zOS
523
523
  case server_info.DBMS_VER
524
- when /09/ # DB2 for zOS version 9
524
+ when /09/ || /10/ # DB2 for zOS version 9 and version 10
525
525
  @servertype = IBM_DB2_ZOS.new(self)
526
526
  when /08/ # DB2 for zOS version 8
527
527
  @servertype = IBM_DB2_ZOS_8.new(self)
@@ -603,6 +603,19 @@ module ActiveRecord
603
603
  end
604
604
  end
605
605
 
606
+ def self.visitor_for(pool)
607
+ Arel::Visitors::IBM_DB.new(pool)
608
+ end
609
+
610
+ def to_sql(arel)
611
+ if arel.respond_to?(:ast)
612
+ visitor.accept(arel.ast)
613
+ else
614
+ arel
615
+ end
616
+
617
+ end
618
+
606
619
  # This adapter supports migrations.
607
620
  # Current limitations:
608
621
  # +rename_column+ is not currently supported by the IBM data servers
@@ -719,7 +732,7 @@ module ActiveRecord
719
732
  pstmt = prepare(sql_param_hash["sqlSegment"], name)
720
733
  if(execute_prepared_stmt(pstmt, sql_param_hash["paramArray"]))
721
734
  begin
722
- @servertype.select(sql_param_hash["sqlSegment"], name, pstmt, results)
735
+ results = @servertype.select(pstmt)
723
736
  rescue StandardError => fetch_error # Handle driver fetch errors
724
737
  error_msg = IBM_DB.getErrormsg(pstmt, IBM_DB::DB_STMT )
725
738
  if error_msg && !error_msg.empty?
@@ -743,14 +756,13 @@ module ActiveRecord
743
756
  # and +name+ is an optional description for logging
744
757
  def prepared_select_values(sql_param_hash, name = nil)
745
758
  # Replaces {"= NULL" with " IS NULL"} OR {"IN (NULL)" with " IS NULL"}
746
-
747
759
  results = []
748
760
  # Invokes the method +prepare+ in order prepare the SQL
749
761
  # IBM_DB.Statement is returned from which the statement is executed and results fetched
750
762
  pstmt = prepare(sql_param_hash["sqlSegment"], name)
751
763
  if(execute_prepared_stmt(pstmt, sql_param_hash["paramArray"]))
752
764
  begin
753
- @servertype.select_rows(sql_param_hash["sqlSegment"], name, pstmt, results)
765
+ results = @servertype.select_rows(sql_param_hash["sqlSegment"], name, pstmt, results)
754
766
  if results
755
767
  return results.map { |v| v[0] }
756
768
  else
@@ -774,20 +786,11 @@ module ActiveRecord
774
786
  results
775
787
  end
776
788
 
777
- # Returns an array of hashes with the column names as keys and
778
- # column values as values. +sql+ is the select query,
779
- # and +name+ is an optional description for logging
780
- def select(sql, name = nil)
781
- # Replaces {"= NULL" with " IS NULL"} OR {"IN (NULL)" with " IS NULL"}
782
- sql.gsub!( /(=\s*NULL|IN\s*\(NULL\))/i, " IS NULL" )
783
-
784
- results = []
785
- # Invokes the method +execute+ in order to log and execute the SQL
786
- # IBM_DB.Statement is returned from which results can be fetched
787
- stmt = execute(sql, name)
789
+ #Calls the servertype select method to fetch the data
790
+ def fetch_data(stmt)
788
791
  if(stmt)
789
792
  begin
790
- @servertype.select(sql, name, stmt, results)
793
+ return @servertype.select(stmt)
791
794
  rescue StandardError => fetch_error # Handle driver fetch errors
792
795
  error_msg = IBM_DB.getErrormsg(stmt, IBM_DB::DB_STMT )
793
796
  if error_msg && !error_msg.empty?
@@ -798,13 +801,47 @@ module ActiveRecord
798
801
  raise error_msg
799
802
  end
800
803
  ensure
801
- # Ensures to free the resources associated with the statement
804
+ # Ensures to free the resources associated with the statement
802
805
  IBM_DB.free_stmt(stmt) if stmt
803
806
  end
804
807
  end
808
+ end
809
+ =begin
810
+ # Returns an array of hashes with the column names as keys and
811
+ # column values as values. +sql+ is the select query,
812
+ # and +name+ is an optional description for logging
813
+ def select(sql, name = nil)
814
+ # Replaces {"= NULL" with " IS NULL"} OR {"IN (NULL)" with " IS NULL"}
815
+ sql.gsub!( /(=\s*NULL|IN\s*\(NULL\))/i, " IS NULL" )
816
+
817
+ results = []
818
+ # Invokes the method +execute+ in order to log and execute the SQL
819
+ # IBM_DB.Statement is returned from which results can be fetched
820
+ stmt = execute(sql, name)
821
+
822
+ results = fetch_data(stmt)
805
823
  # The array of record hashes is returned
806
824
  results
807
825
  end
826
+ =end
827
+ def select(sql, name = nil, binds = [])
828
+ # Replaces {"= NULL" with " IS NULL"} OR {"IN (NULL)" with " IS NULL"}
829
+ sql.gsub!( /(=\s*NULL|IN\s*\(NULL\))/i, " IS NULL" )
830
+
831
+ results = []
832
+
833
+ if(binds.nil? || binds.empty?)
834
+ stmt = execute(sql, name)
835
+ else
836
+ stmt = exec_query(sql, name, binds)
837
+ end
838
+
839
+ if( stmt )
840
+ results = fetch_data(stmt)
841
+ end
842
+
843
+ return results
844
+ end
808
845
 
809
846
  #Returns an array of arrays containing the field values.
810
847
  #This is an implementation for the abstract method
@@ -819,7 +856,7 @@ module ActiveRecord
819
856
  stmt = execute(sql, name)
820
857
  if(stmt)
821
858
  begin
822
- @servertype.select_rows(sql, name, stmt, results)
859
+ results = @servertype.select_rows(sql, name, stmt, results)
823
860
  rescue StandardError => fetch_error # Handle driver fetch errors
824
861
  error_msg = IBM_DB.getErrormsg(stmt, IBM_DB::DB_STMT )
825
862
  if error_msg && !error_msg.empty?
@@ -850,7 +887,12 @@ module ActiveRecord
850
887
  #overridden to handle LOB's fixture insertion, as, in normal inserts callbacks are triggered but during fixture insertion callbacks are not triggered
851
888
  #hence only markers like @@@IBMBINARY@@@ will be inserted and are not updated to actual data
852
889
  def insert_fixture(fixture, table_name)
853
- insert_query = "INSERT INTO #{quote_table_name(table_name)} ( #{fixture.key_list})"
890
+ if(fixture.respond_to?(:keys))
891
+ insert_query = "INSERT INTO #{quote_table_name(table_name)} ( #{fixture.keys.join(', ')})"
892
+ else
893
+ insert_query = "INSERT INTO #{quote_table_name(table_name)} ( #{fixture.key_list})"
894
+ end
895
+
854
896
  insert_values = []
855
897
  params = []
856
898
  if @servertype.instance_of? IBM_IDS
@@ -910,7 +952,7 @@ module ActiveRecord
910
952
  # Perform an insert and returns the last ID generated.
911
953
  # This can be the ID passed to the method or the one auto-generated by the database,
912
954
  # and retrieved by the +last_generated_id+ method.
913
- def insert(sql, name = nil, pk = nil, id_value = nil, sequence_name = nil)
955
+ def insert_direct(sql, name = nil, pk = nil, id_value = nil, sequence_name = nil)
914
956
  if @handle_lobs_triggered #Ensure the array of sql is cleared if they have been handled in the callback
915
957
  @sql = []
916
958
  @handle_lobs_triggered = false
@@ -929,11 +971,30 @@ module ActiveRecord
929
971
  end
930
972
  end
931
973
 
974
+ def insert(arel, name = nil, pk = nil, id_value = nil, sequence_name = nil, binds = [] )
975
+ sql, binds = [to_sql(arel),binds]
976
+
977
+ #unless IBM_DBAdapter.respond_to?(:exec_insert)
978
+ if binds.nil? || binds.empty?
979
+ return insert_direct(sql, name, pk, id_value, sequence_name)
980
+ end
981
+
982
+ clear_query_cache if defined? clear_query_cache
983
+ if stmt = exec_insert(sql, name, binds)
984
+ begin
985
+ @sql << sql
986
+ return id_value || @servertype.last_generated_id(stmt)
987
+ ensure
988
+ IBM_DB.free_stmt(stmt) if stmt
989
+ end
990
+ end
991
+ end
992
+
932
993
  # Praveen
933
994
  # Performs an insert using the prepared statement and returns the last ID generated.
934
995
  # This can be the ID passed to the method or the one auto-generated by the database,
935
996
  # and retrieved by the +last_generated_id+ method.
936
- def prepared_insert(pstmt, param_array = nil)
997
+ def prepared_insert(pstmt, param_array = nil, id_value = nil)
937
998
  if @handle_lobs_triggered #Ensure the array of sql is cleared if they have been handled in the callback
938
999
  @sql = []
939
1000
  @sql_parameter_values = []
@@ -946,7 +1007,7 @@ module ActiveRecord
946
1007
  if execute_prepared_stmt(pstmt, param_array)
947
1008
  @sql << @prepared_sql
948
1009
  @sql_parameter_values << param_array
949
- return @servertype.last_generated_id(pstmt)
1010
+ return id_value || @servertype.last_generated_id(pstmt)
950
1011
  end
951
1012
  rescue StandardError => insert_err
952
1013
  raise insert_err
@@ -988,6 +1049,29 @@ module ActiveRecord
988
1049
  end
989
1050
  end
990
1051
 
1052
+ # Executes +sql+ statement in the context of this connection using
1053
+ # +binds+ as the bind substitutes. +name+ is logged along with
1054
+ # the executed +sql+ statement.
1055
+ def exec_query(sql, name = 'SQL', binds = [])
1056
+ begin
1057
+ param_array = binds.map do |column,value|
1058
+ quote_value_for_pstmt(value, column)
1059
+ end
1060
+
1061
+ stmt = prepare(sql, name)
1062
+
1063
+ if( stmt )
1064
+ if(execute_prepared_stmt(stmt, param_array))
1065
+ return stmt
1066
+ end
1067
+ else
1068
+ return false
1069
+ end
1070
+ ensure
1071
+ @offset = @limit = nil
1072
+ end
1073
+ end
1074
+
991
1075
  # Executes and logs +sql+ commands and
992
1076
  # returns a +IBM_DB.Statement+ object.
993
1077
  def execute(sql, name = nil)
@@ -999,29 +1083,12 @@ module ActiveRecord
999
1083
  end
1000
1084
 
1001
1085
  # Executes an "UPDATE" SQL statement
1002
- def update(sql, name = nil)
1086
+ def update_direct(sql, name = nil)
1003
1087
  if @handle_lobs_triggered #Ensure the array of sql is cleared if they have been handled in the callback
1004
1088
  @sql = []
1005
1089
  @handle_lobs_triggered = false
1006
1090
  end
1007
1091
 
1008
- clear_query_cache if defined? clear_query_cache
1009
-
1010
- # Make sure the WHERE clause handles NULL's correctly
1011
- sqlarray = sql.split(/\s*WHERE\s*/)
1012
- size = sqlarray.size
1013
- if size > 1
1014
- sql = sqlarray[0] + " WHERE "
1015
- if size > 2
1016
- 1.upto size-2 do |index|
1017
- sqlarray[index].gsub!( /(=\s*NULL|IN\s*\(NULL\))/i, " IS NULL" ) unless sqlarray[index].nil?
1018
- sql = sql + sqlarray[index] + " WHERE "
1019
- end
1020
- end
1021
- sqlarray[size-1].gsub!( /(=\s*NULL|IN\s*\(NULL\))/i, " IS NULL" ) unless sqlarray[size-1].nil?
1022
- sql = sql + sqlarray[size-1]
1023
- end
1024
-
1025
1092
  # Logs and execute the given sql query.
1026
1093
  if stmt = execute(sql, name)
1027
1094
  begin
@@ -1062,9 +1129,39 @@ module ActiveRecord
1062
1129
  # The delete method executes the delete
1063
1130
  # statement and returns the number of affected rows.
1064
1131
  # The method is an alias for +update+
1065
- alias_method :delete, :update
1066
1132
  alias_method :prepared_delete, :prepared_update
1067
1133
 
1134
+ def update(arel, name = nil, binds = [])
1135
+ sql = to_sql(arel)
1136
+
1137
+ # Make sure the WHERE clause handles NULL's correctly
1138
+ sqlarray = sql.split(/\s*WHERE\s*/)
1139
+ size = sqlarray.size
1140
+ if size > 1
1141
+ sql = sqlarray[0] + " WHERE "
1142
+ if size > 2
1143
+ 1.upto size-2 do |index|
1144
+ sqlarray[index].gsub!( /(=\s*NULL|IN\s*\(NULL\))/i, " IS NULL" ) unless sqlarray[index].nil?
1145
+ sql = sql + sqlarray[index] + " WHERE "
1146
+ end
1147
+ end
1148
+ sqlarray[size-1].gsub!( /(=\s*NULL|IN\s*\(NULL\))/i, " IS NULL" ) unless sqlarray[size-1].nil?
1149
+ sql = sql + sqlarray[size-1]
1150
+ end
1151
+
1152
+ clear_query_cache if defined? clear_query_cache
1153
+
1154
+ if binds.nil? || binds.empty?
1155
+ update_direct(sql, name)
1156
+ else
1157
+ if stmt = exec_query(sql,name,binds)
1158
+ IBM_DB.num_rows(stmt)
1159
+ end
1160
+ end
1161
+ end
1162
+
1163
+ alias_method :delete, :update
1164
+
1068
1165
  # Begins the transaction (and turns off auto-committing)
1069
1166
  def begin_db_transaction
1070
1167
  # Turns off the auto-commit
@@ -1105,27 +1202,26 @@ module ActiveRecord
1105
1202
  # generates "SELECT O.* FROM (SELECT I.*, ROW_NUMBER() OVER () sys_rownum
1106
1203
  # FROM (SELECT * FROM staff) AS I) AS O WHERE sys_row_num BETWEEN 31 AND 40"
1107
1204
  def add_limit_offset!(sql, options)
1108
- # If there is a limit
1109
- if limit = options[:limit]
1110
- # if the limit is zero
1111
- if limit == 0
1112
- # Returns a query that will always generate zero records
1113
- # (e.g. WHERE sys_row_num BETWEEN 1 and 0)
1114
- if( @pstmt_support_on )
1115
- sql = @servertype.query_offset_limit!(sql, 0, limit, options)
1116
- else
1117
- sql = @servertype.query_offset_limit(sql, 0, limit)
1118
- end
1119
- # If there is a non-zero limit
1205
+ limit = options[:limit]
1206
+ offset = options[:offset]
1207
+
1208
+ # if the limit is zero
1209
+ if limit && limit == 0
1210
+ # Returns a query that will always generate zero records
1211
+ # (e.g. WHERE sys_row_num BETWEEN 1 and 0)
1212
+ if( @pstmt_support_on )
1213
+ sql = @servertype.query_offset_limit!(sql, 0, limit, options)
1120
1214
  else
1121
- offset = options[:offset]
1122
- # If an offset is specified builds the query with offset and limit,
1123
- # otherwise retrieves only the first +limit+ rows
1124
- if( @pstmt_support_on )
1125
- sql = @servertype.query_offset_limit!(sql, offset, limit, options)
1126
- else
1127
- sql = @servertype.query_offset_limit(sql, offset, limit)
1128
- end
1215
+ sql = @servertype.query_offset_limit(sql, 0, limit)
1216
+ end
1217
+ # If there is a non-zero limit
1218
+ else
1219
+ # If an offset is specified builds the query with offset and limit,
1220
+ # otherwise retrieves only the first +limit+ rows
1221
+ if( @pstmt_support_on )
1222
+ sql = @servertype.query_offset_limit!(sql, offset, limit, options)
1223
+ else
1224
+ sql = @servertype.query_offset_limit(sql, offset, limit)
1129
1225
  end
1130
1226
  end
1131
1227
  # Returns the sql query in any case
@@ -1161,6 +1257,7 @@ module ActiveRecord
1161
1257
  when Float, Fixnum, Bignum then value
1162
1258
  # BigDecimals need to be output in a non-normalized form and quoted.
1163
1259
  when BigDecimal then value.to_s('F')
1260
+ when Numeric, Symbol then value.to_s
1164
1261
  else
1165
1262
  if value.acts_like?(:date) || value.acts_like?(:time)
1166
1263
  quoted_date(value)
@@ -1173,6 +1270,8 @@ module ActiveRecord
1173
1270
  # Properly quotes the various data types.
1174
1271
  # +value+ contains the data, +column+ is optional and contains info on the field
1175
1272
  def quote(value, column = nil)
1273
+ return value.quoted_id if value.respond_to?(:quoted_id)
1274
+
1176
1275
  case value
1177
1276
  # If it's a numeric value and the column type is not a string, it shouldn't be quoted
1178
1277
  # (IBM_DB doesn't accept quotes on numeric types)
@@ -1213,14 +1312,22 @@ module ActiveRecord
1213
1312
  end
1214
1313
  else
1215
1314
  unless caller[0] =~ /insert_fixture/i
1216
- "'#{quote_string(value)}'"
1315
+ super
1217
1316
  else
1218
1317
  "#{value}"
1219
1318
  end
1220
1319
  end
1221
1320
  when TrueClass then quoted_true # return '1' for true
1222
1321
  when FalseClass then quoted_false # return '0' for false
1223
- else super # rely on superclass handling
1322
+ when nil then "NULL"
1323
+ when Date, Time then "'#{quoted_date(value)}'"
1324
+ when Symbol then "'#{quote_string(value.to_s)}'"
1325
+ else
1326
+ unless caller[0] =~ /insert_fixture/i
1327
+ "'#{quote_string(YAML.dump(value))}'"
1328
+ else
1329
+ "#{quote_string(YAML.dump(value))}"
1330
+ end
1224
1331
  end
1225
1332
  end
1226
1333
 
@@ -1525,6 +1632,8 @@ module ActiveRecord
1525
1632
  column_default_value = col["column_def"]
1526
1633
  # If there is no default value, it assigns NIL
1527
1634
  column_default_value = nil if (column_default_value && column_default_value.upcase == 'NULL')
1635
+ # If default value is IDENTITY GENERATED BY DEFAULT (this value is retrieved in case of id columns)
1636
+ column_default_value = nil if (column_default_value && column_default_value.upcase =~ /IDENTITY GENERATED BY DEFAULT/i)
1528
1637
  # Removes single quotes from the default value
1529
1638
  column_default_value.gsub!(/^'(.*)'$/, '\1') unless column_default_value.nil?
1530
1639
  # Assigns the column type
@@ -1643,6 +1752,15 @@ module ActiveRecord
1643
1752
  end
1644
1753
  =end
1645
1754
 
1755
+ #Add distinct clause to the sql if there is no order by specified
1756
+ def distinct(columns, order_by)
1757
+ if order_by.nil?
1758
+ "DISTINCT #{columns}"
1759
+ else
1760
+ "#{columns}"
1761
+ end
1762
+ end
1763
+
1646
1764
  # Sets a new default value for a column. This does not set the default
1647
1765
  # value to +NULL+, instead, it needs DatabaseStatements#execute which
1648
1766
  # can execute the appropriate SQL statement for setting the value.
@@ -1717,7 +1835,8 @@ To remove the column, the table must be dropped and recreated without the #{colu
1717
1835
  end
1718
1836
  end
1719
1837
 
1720
- def select(sql, name, stmt, results)
1838
+ def select(stmt)
1839
+ results = []
1721
1840
  # Fetches all the results available. IBM_DB.fetch_assoc(stmt) returns
1722
1841
  # an hash for each single record.
1723
1842
  # The loop stops when there aren't any more valid records to fetch
@@ -1736,6 +1855,7 @@ To remove the column, the table must be dropped and recreated without the #{colu
1736
1855
  raise error_msg
1737
1856
  end
1738
1857
  end
1858
+ return results
1739
1859
  end
1740
1860
 
1741
1861
  def select_rows(sql, name, stmt, results)
@@ -1757,6 +1877,7 @@ To remove the column, the table must be dropped and recreated without the #{colu
1757
1877
  raise error_msg
1758
1878
  end
1759
1879
  end
1880
+ return results
1760
1881
  end
1761
1882
 
1762
1883
  # Praveen
@@ -1962,11 +2083,14 @@ SET WITH DEFAULT #{@adapter.quote(default)}"
1962
2083
  def get_double_mapping
1963
2084
  return "double"
1964
2085
  end
1965
-
2086
+ =begin
2087
+ # Commenting this code, as offset handling is now part of sql and we need to handle it in select and also
2088
+ # need not set cursor type during prepare or execute
1966
2089
  # Fetches all the results available. IBM_DB.fetch_assoc(stmt) returns
1967
2090
  # an hash for each single record.
1968
2091
  # The loop stops when there aren't any more valid records to fetch
1969
- def select(sql, name, stmt, results)
2092
+ def select(stmt)
2093
+ results = []
1970
2094
  begin
1971
2095
  if (!@offset.nil? && @offset >= 0) || (!@limit.nil? && @limit > 0)
1972
2096
  # We know at this point that there is an offset and/or a limit
@@ -2016,6 +2140,7 @@ SET WITH DEFAULT #{@adapter.quote(default)}"
2016
2140
  # Add the record to the +results+ array
2017
2141
  results << single_hash
2018
2142
  end
2143
+ return results
2019
2144
  end
2020
2145
  rescue StandardError => fetch_error # Handle driver fetch errors
2021
2146
  error_msg = IBM_DB.getErrormsg(stmt, IBM_DB::DB_STMT )
@@ -2101,6 +2226,7 @@ SET WITH DEFAULT #{@adapter.quote(default)}"
2101
2226
  @offset = nil
2102
2227
  @limit = nil
2103
2228
  end
2229
+ return results
2104
2230
  end
2105
2231
 
2106
2232
  # Praveen
@@ -2156,22 +2282,62 @@ SET WITH DEFAULT #{@adapter.quote(default)}"
2156
2282
  raise error_msg
2157
2283
  end
2158
2284
  end
2159
-
2285
+ =end
2160
2286
  def query_offset_limit(sql, offset, limit)
2161
- @limit = limit
2162
- @offset = offset
2287
+ if(offset.nil? && limit.nil?)
2288
+ return sql
2289
+ end
2290
+
2163
2291
  if (offset.nil?)
2164
- sql << " FETCH FIRST #{limit} ROWS ONLY"
2292
+ return sql << " FETCH FIRST #{limit} ROWS ONLY"
2165
2293
  end
2294
+
2295
+ if(limit.nil?)
2296
+ sql.sub!(/SELECT/i,"SELECT O.* FROM (SELECT I.*, ROW_NUMBER() OVER () sys_row_num FROM (SELECT")
2297
+ return sql << ") AS I) AS O WHERE sys_row_num > #{offset}"
2298
+ end
2299
+
2300
+ # Defines what will be the last record
2301
+ last_record = offset + limit
2302
+ # Transforms the SELECT query in order to retrieve/fetch only
2303
+ # a number of records after the specified offset.
2304
+ # 'select' or 'SELECT' is replaced with the partial query below that adds the sys_row_num column
2305
+ # to select with the condition of this column being between offset+1 and the offset+limit
2306
+ sql.sub!(/SELECT/i,"SELECT O.* FROM (SELECT I.*, ROW_NUMBER() OVER () sys_row_num FROM (SELECT")
2307
+ # The final part of the query is appended to include a WHERE...BETWEEN...AND condition,
2308
+ # and retrieve only a LIMIT number of records starting from the OFFSET+1
2309
+ sql << ") AS I) AS O WHERE sys_row_num BETWEEN #{offset+1} AND #{last_record}"
2166
2310
  end
2167
2311
 
2168
2312
  def query_offset_limit!(sql, offset, limit, options)
2169
- @limit = limit
2170
- @offset = offset
2313
+ if(offset.nil? && limit.nil?)
2314
+ options[:paramArray] = []
2315
+ return sql
2316
+ end
2317
+
2171
2318
  if (offset.nil?)
2172
- sql << " FETCH FIRST #{limit} ROWS ONLY"
2319
+ options[:paramArray] = []
2320
+ return sql << " FETCH FIRST #{limit} ROWS ONLY"
2173
2321
  end
2174
- options[:paramArray] = []
2322
+
2323
+ if(limit.nil?)
2324
+ sql.sub!(/SELECT/i,"SELECT O.* FROM (SELECT I.*, ROW_NUMBER() OVER () sys_row_num FROM (SELECT")
2325
+ sql << ") AS I) AS O WHERE sys_row_num > ?"
2326
+ options[:paramArray] = [offset]
2327
+ return
2328
+ end
2329
+
2330
+ # Defines what will be the last record
2331
+ last_record = offset + limit
2332
+ # Transforms the SELECT query in order to retrieve/fetch only
2333
+ # a number of records after the specified offset.
2334
+ # 'select' or 'SELECT' is replaced with the partial query below that adds the sys_row_num column
2335
+ # to select with the condition of this column being between offset+1 and the offset+limit
2336
+ sql.sub!(/SELECT/i,"SELECT O.* FROM (SELECT I.*, ROW_NUMBER() OVER () sys_row_num FROM (SELECT")
2337
+ # The final part of the query is appended to include a WHERE...BETWEEN...AND condition,
2338
+ # and retrieve only a LIMIT number of records starting from the OFFSET+1
2339
+ sql << ") AS I) AS O WHERE sys_row_num BETWEEN ? AND ?"
2340
+ options[:paramArray] = [offset+1, last_record]
2175
2341
  end
2176
2342
 
2177
2343
  # This method generates the default blob value specified for
@@ -2203,40 +2369,6 @@ SET WITH DEFAULT #{@adapter.quote(default)}"
2203
2369
  def reorg_table(table_name)
2204
2370
  execute("CALL ADMIN_CMD('REORG TABLE #{table_name}')")
2205
2371
  end
2206
-
2207
- def query_offset_limit(sql, offset, limit)
2208
- if (offset.nil?)
2209
- return sql << " FETCH FIRST #{limit} ROWS ONLY"
2210
- end
2211
- # Defines what will be the last record
2212
- last_record = offset + limit
2213
- # Transforms the SELECT query in order to retrieve/fetch only
2214
- # a number of records after the specified offset.
2215
- # 'select' or 'SELECT' is replaced with the partial query below that adds the sys_row_num column
2216
- # to select with the condition of this column being between offset+1 and the offset+limit
2217
- sql.sub!(/SELECT/i,"SELECT O.* FROM (SELECT I.*, ROW_NUMBER() OVER () sys_row_num FROM (SELECT")
2218
- # The final part of the query is appended to include a WHERE...BETWEEN...AND condition,
2219
- # and retrieve only a LIMIT number of records starting from the OFFSET+1
2220
- sql << ") AS I) AS O WHERE sys_row_num BETWEEN #{offset+1} AND #{last_record}"
2221
- end
2222
-
2223
- def query_offset_limit!(sql, offset, limit, options)
2224
- if (offset.nil?)
2225
- options[:paramArray] = []
2226
- return sql << " FETCH FIRST #{limit} ROWS ONLY"
2227
- end
2228
- # Defines what will be the last record
2229
- last_record = offset + limit
2230
- # Transforms the SELECT query in order to retrieve/fetch only
2231
- # a number of records after the specified offset.
2232
- # 'select' or 'SELECT' is replaced with the partial query below that adds the sys_row_num column
2233
- # to select with the condition of this column being between offset+1 and the offset+limit
2234
- sql.sub!(/SELECT/i,"SELECT O.* FROM (SELECT I.*, ROW_NUMBER() OVER () sys_row_num FROM (SELECT")
2235
- # The final part of the query is appended to include a WHERE...BETWEEN...AND condition,
2236
- # and retrieve only a LIMIT number of records starting from the OFFSET+1
2237
- sql << ") AS I) AS O WHERE sys_row_num BETWEEN ? AND ?"
2238
- options[:paramArray] = [offset+1, last_record]
2239
- end
2240
2372
  end # class IBM_DB2_LUW
2241
2373
 
2242
2374
  class IBM_DB2_LUW_COBRA < IBM_DB2_LUW
@@ -2371,6 +2503,20 @@ SET WITH DEFAULT #{@adapter.quote(default)}"
2371
2503
  class IBM_DB2_ZOS_8 < IBM_DB2_ZOS
2372
2504
  include HostedDataServer
2373
2505
 
2506
+ def query_offset_limit(sql, offset, limit)
2507
+ if (!limit.nil?)
2508
+ sql << " FETCH FIRST #{limit} ROWS ONLY"
2509
+ end
2510
+ return sql
2511
+ end
2512
+
2513
+ def query_offset_limit!(sql, offset, limit, options)
2514
+ if (!limit.nil?)
2515
+ sql << " FETCH FIRST #{limit} ROWS ONLY"
2516
+ end
2517
+ options[:paramArray] = []
2518
+ end
2519
+
2374
2520
  # This call is needed on DB2 z/OS v8 for the creation of tables
2375
2521
  # with LOBs. When issued, this call does the following:
2376
2522
  # DB2 creates LOB table spaces, auxiliary tables, and indexes on auxiliary
@@ -2596,3 +2742,49 @@ SET WITH DEFAULT #{@adapter.quote(default)}"
2596
2742
  end # class IBM_IDS
2597
2743
  end # module ConnectionAdapters
2598
2744
  end # module ActiveRecord
2745
+
2746
+ module Arel
2747
+ module Visitors
2748
+ class Visitor #opening and closing the class to ensure backward compatibility
2749
+ end
2750
+
2751
+ class ToSql < Arel::Visitors::Visitor #opening and closing the class to ensure backward compatibility
2752
+ end
2753
+
2754
+ class IBM_DB < Arel::Visitors::ToSql
2755
+ private
2756
+
2757
+ def visit_Arel_Nodes_Limit o
2758
+ visit o.expr
2759
+ end
2760
+
2761
+ def visit_Arel_Nodes_Offset o
2762
+ visit o.expr
2763
+ end
2764
+
2765
+ def visit_Arel_Nodes_SelectStatement o
2766
+ sql = [
2767
+ (visit(o.with) if o.with),
2768
+ o.cores.map { |x| visit_Arel_Nodes_SelectCore x }.join,
2769
+ ("ORDER BY #{o.orders.map { |x| visit x }.join(', ')}" unless o.orders.empty?),
2770
+ (visit(o.lock) if o.lock),
2771
+ ].compact.join ' '
2772
+
2773
+ if o.limit
2774
+ limit = visit(o.limit)
2775
+ else
2776
+ limit = nil
2777
+ end
2778
+
2779
+ if o.offset
2780
+ offset = visit(o.offset)
2781
+ else
2782
+ offset = nil
2783
+ end
2784
+ @connection.add_limit_offset!(sql, {:limit => limit, :offset => offset})
2785
+ return sql
2786
+ end
2787
+
2788
+ end
2789
+ end
2790
+ end