ibm_db 2.5.6-x86-mingw32 → 2.5.7-x86-mingw32
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGES +6 -0
- data/README +1 -1
- data/ext/Makefile.nt32 +3 -3
- data/ext/Makefile.nt32.191 +212 -0
- data/ext/ibm_db.c +30 -5
- data/lib/active_record/connection_adapters/ibm_db_adapter.rb +300 -108
- data/lib/active_record/connection_adapters/ibm_db_pstmt.rb +1 -1
- data/lib/mswin32/rb18x/ibm_db.so +0 -0
- data/lib/mswin32/rb19x/ibm_db.so +0 -0
- data/test/cases/adapter_test.rb +25 -22
- data/test/cases/associations/belongs_to_associations_test.rb +245 -43
- data/test/cases/associations/cascaded_eager_loading_test.rb +28 -26
- data/test/cases/associations/has_and_belongs_to_many_associations_test.rb +60 -156
- data/test/cases/associations/join_model_test.rb +96 -146
- data/test/cases/attribute_methods_test.rb +98 -33
- data/test/cases/base_test.rb +525 -103
- data/test/cases/calculations_test.rb +92 -8
- data/test/cases/migration_test.rb +533 -207
- data/test/cases/persistence_test.rb +636 -0
- data/test/cases/query_cache_test.rb +242 -0
- data/test/cases/relations_test.rb +1019 -0
- data/test/cases/schema_dumper_test.rb +37 -17
- data/test/cases/transaction_callbacks_test.rb +300 -0
- data/test/cases/validations/uniqueness_validation_test.rb +38 -22
- data/test/cases/xml_serialization_test.rb +276 -0
- data/test/config.yml +154 -0
- data/test/connections/native_ibm_db/connection.rb +2 -0
- data/test/models/warehouse_thing.rb +4 -4
- data/test/schema/i5/ibm_db_specific_schema.rb +3 -1
- data/test/schema/ids/ibm_db_specific_schema.rb +3 -1
- data/test/schema/luw/ibm_db_specific_schema.rb +2 -0
- data/test/schema/schema.rb +174 -89
- data/test/schema/zOS/ibm_db_specific_schema.rb +3 -1
- metadata +10 -7
- data/test/cases/associations/eager_test.rb +0 -862
- data/test/cases/associations/has_many_through_associations_test.rb +0 -461
- data/test/cases/finder_test.rb +0 -1088
- 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.
|
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.
|
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,
|
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
|
-
|
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(
|
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
|
-
#
|
778
|
-
|
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(
|
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
|
-
|
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
|
-
|
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
|
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
|
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
|
-
|
1109
|
-
|
1110
|
-
|
1111
|
-
|
1112
|
-
|
1113
|
-
|
1114
|
-
|
1115
|
-
|
1116
|
-
|
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
|
-
|
1122
|
-
|
1123
|
-
|
1124
|
-
|
1125
|
-
|
1126
|
-
|
1127
|
-
|
1128
|
-
|
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
|
-
|
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
|
-
|
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(
|
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(
|
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
|
-
|
2162
|
-
|
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
|
-
|
2170
|
-
|
2313
|
+
if(offset.nil? && limit.nil?)
|
2314
|
+
options[:paramArray] = []
|
2315
|
+
return sql
|
2316
|
+
end
|
2317
|
+
|
2171
2318
|
if (offset.nil?)
|
2172
|
-
|
2319
|
+
options[:paramArray] = []
|
2320
|
+
return sql << " FETCH FIRST #{limit} ROWS ONLY"
|
2173
2321
|
end
|
2174
|
-
|
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
|