From nobody at rubyforge.org Fri Aug 19 03:43:14 2011 From: nobody at rubyforge.org (nobody at rubyforge.org) Date: Fri, 19 Aug 2011 03:43:14 -0400 (EDT) Subject: [ruby-oci8-commit] [437] trunk/ruby-oci8/.gitignore: add .gitignore Message-ID: <20110819074314.7E54418581B2@rubyforge.org> Revision: 437 Author: kubo Date: 2011-08-19 03:43:13 -0400 (Fri, 19 Aug 2011) Log Message: ----------- add .gitignore Added Paths: ----------- trunk/ruby-oci8/.gitignore Added: trunk/ruby-oci8/.gitignore =================================================================== --- trunk/ruby-oci8/.gitignore (rev 0) +++ trunk/ruby-oci8/.gitignore 2011-08-19 07:43:13 UTC (rev 437) @@ -0,0 +1,8 @@ +config.save +ext/oci8/apiwrap.h +ext/oci8/Makefile +ext/oci8/apiwrap.c +ext/oci8/depend +ext/oci8/extconf.h +ext/oci8/mkmf.log +lib/oci8.rb From nobody at rubyforge.org Fri Aug 19 03:43:34 2011 From: nobody at rubyforge.org (nobody at rubyforge.org) Date: Fri, 19 Aug 2011 03:43:34 -0400 (EDT) Subject: [ruby-oci8-commit] [438] trunk/ruby-oci8: fix a bug not to find the OCI library location listed in 'ldconfig -p' when LD_LIBRARY_PATH is set. Message-ID: <20110819074334.9CF5318581B2@rubyforge.org> Revision: 438 Author: kubo Date: 2011-08-19 03:43:34 -0400 (Fri, 19 Aug 2011) Log Message: ----------- fix a bug not to find the OCI library location listed in 'ldconfig -p' when LD_LIBRARY_PATH is set. (Reported by Edgars Beigarts.) Modified Paths: -------------- trunk/ruby-oci8/ChangeLog trunk/ruby-oci8/ext/oci8/oraconf.rb Modified: trunk/ruby-oci8/ChangeLog =================================================================== --- trunk/ruby-oci8/ChangeLog 2011-08-19 07:43:13 UTC (rev 437) +++ trunk/ruby-oci8/ChangeLog 2011-08-19 07:43:34 UTC (rev 438) @@ -1,3 +1,8 @@ +2011-08-19 KUBO Takehiro + * ext/oci8/oraconf.rb: fix a bug not to find the OCI library location listed in + 'ldconfig -p' when LD_LIBRARY_PATH is set. + (Reported by Edgars Beigarts.) + 2011-07-16 KUBO Takehiro * ext/oci8/extconf.rb, ext/oci8/oci8.h: fix for Solaris compiler. (Reported by Sanjiv Patel.) Modified: trunk/ruby-oci8/ext/oci8/oraconf.rb =================================================================== --- trunk/ruby-oci8/ext/oci8/oraconf.rb 2011-08-19 07:43:13 UTC (rev 437) +++ trunk/ruby-oci8/ext/oci8/oraconf.rb 2011-08-19 07:43:34 UTC (rev 438) @@ -574,6 +574,7 @@ puts "yes" return path, files[0] end + nil end def init From nobody at rubyforge.org Fri Aug 19 04:13:11 2011 From: nobody at rubyforge.org (nobody at rubyforge.org) Date: Fri, 19 Aug 2011 04:13:11 -0400 (EDT) Subject: [ruby-oci8-commit] [439] branches/ruby-oci8-2.0/.gitignore: add .gitignore Message-ID: <20110819081311.A75E91588062@rubyforge.org> Revision: 439 Author: kubo Date: 2011-08-19 04:13:11 -0400 (Fri, 19 Aug 2011) Log Message: ----------- add .gitignore Added Paths: ----------- branches/ruby-oci8-2.0/.gitignore Added: branches/ruby-oci8-2.0/.gitignore =================================================================== --- branches/ruby-oci8-2.0/.gitignore (rev 0) +++ branches/ruby-oci8-2.0/.gitignore 2011-08-19 08:13:11 UTC (rev 439) @@ -0,0 +1,8 @@ +config.save +ext/oci8/apiwrap.h +ext/oci8/Makefile +ext/oci8/apiwrap.c +ext/oci8/depend +ext/oci8/extconf.h +ext/oci8/mkmf.log +lib/oci8.rb From nobody at rubyforge.org Fri Aug 19 04:13:31 2011 From: nobody at rubyforge.org (nobody at rubyforge.org) Date: Fri, 19 Aug 2011 04:13:31 -0400 (EDT) Subject: [ruby-oci8-commit] [440] branches/ruby-oci8-2.0: fix a bug not to find the OCI library location listed in 'ldconfig -p' when LD_LIBRARY_PATH is set. Message-ID: <20110819081331.62F011588062@rubyforge.org> Revision: 440 Author: kubo Date: 2011-08-19 04:13:31 -0400 (Fri, 19 Aug 2011) Log Message: ----------- fix a bug not to find the OCI library location listed in 'ldconfig -p' when LD_LIBRARY_PATH is set. (Reported by Edgars Beigarts.) Modified Paths: -------------- branches/ruby-oci8-2.0/ChangeLog branches/ruby-oci8-2.0/ext/oci8/oraconf.rb Modified: branches/ruby-oci8-2.0/ChangeLog =================================================================== --- branches/ruby-oci8-2.0/ChangeLog 2011-08-19 08:13:11 UTC (rev 439) +++ branches/ruby-oci8-2.0/ChangeLog 2011-08-19 08:13:31 UTC (rev 440) @@ -1,3 +1,8 @@ +2011-08-19 KUBO Takehiro + * ext/oci8/oraconf.rb: fix a bug not to find the OCI library location listed in + 'ldconfig -p' when LD_LIBRARY_PATH is set. + (Reported by Edgars Beigarts.) + 2011-07-16 KUBO Takehiro * ext/oci8/extconf.rb, ext/oci8/oci8.h: fix for Solaris compiler. (Reported by Sanjiv Patel.) Modified: branches/ruby-oci8-2.0/ext/oci8/oraconf.rb =================================================================== --- branches/ruby-oci8-2.0/ext/oci8/oraconf.rb 2011-08-19 08:13:11 UTC (rev 439) +++ branches/ruby-oci8-2.0/ext/oci8/oraconf.rb 2011-08-19 08:13:31 UTC (rev 440) @@ -574,6 +574,7 @@ puts "yes" return path, files[0] end + nil end def init From nobody at rubyforge.org Fri Aug 19 09:19:36 2011 From: nobody at rubyforge.org (nobody at rubyforge.org) Date: Fri, 19 Aug 2011 09:19:36 -0400 (EDT) Subject: [ruby-oci8-commit] [441] trunk/ruby-oci8: Decimal to float and float to decimal conversions are done as exactly ruby does by default . Message-ID: <20110819131936.6226218581B2@rubyforge.org> Revision: 441 Author: kubo Date: 2011-08-19 09:19:35 -0400 (Fri, 19 Aug 2011) Log Message: ----------- Decimal to float and float to decimal conversions are done as exactly ruby does by default. The behavior is customizable by OCI8.properties[:float_conversion_type]. Modified Paths: -------------- trunk/ruby-oci8/.gitignore trunk/ruby-oci8/ChangeLog trunk/ruby-oci8/ext/oci8/bind.c trunk/ruby-oci8/ext/oci8/oci8.c trunk/ruby-oci8/ext/oci8/oci8.h trunk/ruby-oci8/ext/oci8/ocinumber.c trunk/ruby-oci8/lib/oci8/properties.rb Modified: trunk/ruby-oci8/.gitignore =================================================================== --- trunk/ruby-oci8/.gitignore 2011-08-19 08:13:31 UTC (rev 440) +++ trunk/ruby-oci8/.gitignore 2011-08-19 13:19:35 UTC (rev 441) @@ -5,4 +5,7 @@ ext/oci8/depend ext/oci8/extconf.h ext/oci8/mkmf.log +ext/oci8/*.o +ext/oci8/*.so +ext/oci8/*.obj lib/oci8.rb Modified: trunk/ruby-oci8/ChangeLog =================================================================== --- trunk/ruby-oci8/ChangeLog 2011-08-19 08:13:31 UTC (rev 440) +++ trunk/ruby-oci8/ChangeLog 2011-08-19 13:19:35 UTC (rev 441) @@ -1,4 +1,10 @@ 2011-08-19 KUBO Takehiro + * ext/oci8/bind.c, ext/oci8/oci8.c, ext/oci8/oci8.h, ext/oci8/ocinumber.c, + lib/oci8/properties.rb: Decimal to float and float to decimal conversions + are done as exactly ruby does by default. The behavior is customizable by + OCI8.properties[:float_conversion_type]. + +2011-08-19 KUBO Takehiro * ext/oci8/oraconf.rb: fix a bug not to find the OCI library location listed in 'ldconfig -p' when LD_LIBRARY_PATH is set. (Reported by Edgars Beigarts.) Modified: trunk/ruby-oci8/ext/oci8/bind.c =================================================================== --- trunk/ruby-oci8/ext/oci8/bind.c 2011-08-19 08:13:31 UTC (rev 440) +++ trunk/ruby-oci8/ext/oci8/bind.c 2011-08-19 13:19:35 UTC (rev 441) @@ -2,7 +2,7 @@ /* * bind.c * - * Copyright (C) 2002-2010 KUBO Takehiro + * Copyright (C) 2002-2011 KUBO Takehiro */ #include "oci8.h" @@ -298,41 +298,25 @@ #endif /* USE_DYNAMIC_FETCH */ /* - * bind_float + * bind_binary_double */ -static VALUE bind_float_get(oci8_bind_t *obind, void *data, void *null_struct) +static VALUE bind_binary_double_get(oci8_bind_t *obind, void *data, void *null_struct) { return rb_float_new(*(double*)data); } -static void bind_float_set(oci8_bind_t *obind, void *data, void **null_structp, VALUE val) +static void bind_binary_double_set(oci8_bind_t *obind, void *data, void **null_structp, VALUE val) { /* val is converted to Float if it isn't Float. */ *(double*)data = RFLOAT_VALUE(rb_Float(val)); } -static void bind_float_init(oci8_bind_t *obind, VALUE svc, VALUE val, VALUE length) +static void bind_binary_double_init(oci8_bind_t *obind, VALUE svc, VALUE val, VALUE length) { obind->value_sz = sizeof(double); obind->alloc_sz = sizeof(double); } -static const oci8_bind_class_t bind_float_class = { - { - NULL, - oci8_bind_free, - sizeof(oci8_bind_t) - }, - bind_float_get, - bind_float_set, - bind_float_init, - NULL, - NULL, - NULL, - NULL, - SQLT_FLT -}; - #ifndef SQLT_BDOUBLE #define SQLT_BDOUBLE 22 #endif @@ -342,9 +326,9 @@ oci8_bind_free, sizeof(oci8_bind_t) }, - bind_float_get, - bind_float_set, - bind_float_init, + bind_binary_double_get, + bind_binary_double_set, + bind_binary_double_init, NULL, NULL, NULL, @@ -516,7 +500,6 @@ oci8_define_bind_class("Long", &bind_long_class); oci8_define_bind_class("LongRaw", &bind_long_raw_class); #endif /* USE_DYNAMIC_FETCH */ - oci8_define_bind_class("Float", &bind_float_class); if (oracle_client_version >= ORAVER_10_1) { oci8_define_bind_class("BinaryDouble", &bind_binary_double_class); } Modified: trunk/ruby-oci8/ext/oci8/oci8.c =================================================================== --- trunk/ruby-oci8/ext/oci8/oci8.c 2011-08-19 08:13:31 UTC (rev 440) +++ trunk/ruby-oci8/ext/oci8/oci8.c 2011-08-19 13:19:35 UTC (rev 441) @@ -2,7 +2,7 @@ /* * oci8.c - part of ruby-oci8 * - * Copyright (C) 2002-2010 KUBO Takehiro + * Copyright (C) 2002-2011 KUBO Takehiro * */ #include "oci8.h" @@ -124,6 +124,27 @@ return oracle_client_vernum; } +static VALUE oci8_s_set_property(VALUE klass, VALUE name, VALUE val) +{ + const char *name_str; + + Check_Type(name, T_SYMBOL); + name_str = rb_id2name(SYM2ID(name)); + if (strcmp(name_str, "float_conversion_type") == 0) { + const char *val_str; + Check_Type(val, T_SYMBOL); + val_str = rb_id2name(SYM2ID(val)); + if (strcmp(val_str, "ruby") == 0) { + oci8_float_conversion_type_is_ruby = 1; + } else if (strcmp(val_str, "oracle") == 0) { + oci8_float_conversion_type_is_ruby = 0; + } else { + rb_raise(rb_eArgError, "float_conversion_type's value should be either :ruby or :oracle."); + } + } + return Qnil; +} + /* * call-seq: * OCI8.error_message(message_no) -> string @@ -1016,6 +1037,7 @@ rb_define_const(cOCI8, "VERSION", rb_obj_freeze(rb_usascii_str_new_cstr(OCI8LIB_VERSION))); rb_define_singleton_method_nodoc(cOCI8, "oracle_client_vernum", oci8_s_oracle_client_vernum, 0); + rb_define_singleton_method_nodoc(cOCI8, "__set_property", oci8_s_set_property, 2); if (have_OCIMessageOpen && have_OCIMessageGet) { rb_define_singleton_method(cOCI8, "error_message", oci8_s_error_message, 1); } Modified: trunk/ruby-oci8/ext/oci8/oci8.h =================================================================== --- trunk/ruby-oci8/ext/oci8/oci8.h 2011-08-19 08:13:31 UTC (rev 440) +++ trunk/ruby-oci8/ext/oci8/oci8.h 2011-08-19 13:19:35 UTC (rev 441) @@ -490,6 +490,7 @@ void Init_ora_date(void); /* ocinumber.c */ +extern int oci8_float_conversion_type_is_ruby; void Init_oci_number(VALUE mOCI, OCIError *errhp); OCINumber *oci8_get_ocinumber(VALUE num); VALUE oci8_make_ocinumber(OCINumber *s, OCIError *errhp); @@ -497,6 +498,8 @@ VALUE oci8_make_float(OCINumber *s, OCIError *errhp); OCINumber *oci8_set_ocinumber(OCINumber *result, VALUE self, OCIError *errhp); OCINumber *oci8_set_integer(OCINumber *result, VALUE self, OCIError *errhp); +double oci8_onum_to_dbl(OCINumber *s, OCIError *errhp); +OCINumber *oci8_dbl_to_onum(OCINumber *result, double dbl, OCIError *errhp); /* ocidatetim.c */ void Init_oci_datetime(void); Modified: trunk/ruby-oci8/ext/oci8/ocinumber.c =================================================================== --- trunk/ruby-oci8/ext/oci8/ocinumber.c 2011-08-19 08:13:31 UTC (rev 440) +++ trunk/ruby-oci8/ext/oci8/ocinumber.c 2011-08-19 13:19:35 UTC (rev 441) @@ -2,12 +2,13 @@ /* * ocinumber.c * - * Copyright (C) 2005-2009 KUBO Takehiro + * Copyright (C) 2005-2011 KUBO Takehiro * */ #include "oci8.h" #include #include +#include #include "oranumber_util.h" #ifndef RB_NUM_COERCE_FUNCS_NEED_OPID @@ -16,6 +17,12 @@ #define rb_num_coerce_bin(x, y, id) rb_num_coerce_bin((x), (y)) #endif +int oci8_float_conversion_type_is_ruby = 1; + +#ifndef INFINITY +#define INFINITY (1.0/+0.0) +#endif + static ID id_power; /* rb_intern("**") */ static ID id_cmp; /* rb_intern("<=>") */ static ID id_finite_p; @@ -136,10 +143,7 @@ VALUE oci8_make_float(OCINumber *s, OCIError *errhp) { - double dbl; - - oci_lc(OCINumberToReal(errhp, s, sizeof(double), &dbl)); - return rb_float_new(dbl); + return rb_float_new(oci8_onum_to_dbl(s, errhp)); } /* fill C structure (OCINumber) from a string. */ @@ -191,7 +195,6 @@ static int set_oci_number_from_num(OCINumber *result, VALUE num, int force, OCIError *errhp) { signed long sl; - double dbl; if (!RTEST(rb_obj_is_kind_of(num, rb_cNumeric))) rb_raise(rb_eTypeError, "expect Numeric but %s", rb_class2name(CLASS_OF(num))); @@ -206,8 +209,7 @@ return 1; case T_FLOAT: /* set from double. */ - dbl = NUM2DBL(num); - oci_lc(OCINumberFromReal(errhp, &dbl, sizeof(dbl), result)); + oci8_dbl_to_onum(result, NUM2DBL(num), errhp); return 1; case T_BIGNUM: /* change via string. */ @@ -313,6 +315,68 @@ return result; } +double oci8_onum_to_dbl(OCINumber *s, OCIError *errhp) +{ + if (oci8_float_conversion_type_is_ruby) { + char buf[256]; + sword rv; + + double dbl; + + oci_lc(OCINumberToReal(errhp, s, sizeof(double), &dbl)); + + rv = oranumber_to_str(s, buf, sizeof(buf)); + if (rv <= 0) { + char buf[ORANUMBER_DUMP_BUF_SIZ]; + + oranumber_dump(s, buf); + rb_raise(eOCIException, "Invalid internal number format: %s", buf); + } + if (strcmp(buf, "~") == 0) { + return INFINITY; + } else if (strcmp(buf, "-~") == 0) { + return -INFINITY; + } + return rb_cstr_to_dbl(buf, Qtrue); + } else { + double dbl; + + oci_lc(OCINumberToReal(errhp, s, sizeof(double), &dbl)); + return dbl; + } +} + +OCINumber *oci8_dbl_to_onum(OCINumber *result, double dbl, OCIError *errhp) +{ + switch (fpclassify(dbl)) { + case FP_NAN: + rb_raise(rb_eFloatDomainError, "NaN"); + /* never reach here */ + break; + case FP_INFINITE: + if (dbl > 0.0) { + oranumber_from_str(result, "~", 1); + } else { + oranumber_from_str(result, "-~", 2); + } + return result; + } + + if (oci8_float_conversion_type_is_ruby) { + VALUE str; + sword rv; + + str = rb_obj_as_string(rb_float_new(dbl)); + rv = oranumber_from_str(result, RSTRING_PTR(str), RSTRING_LEN(str)); + if (rv != 0) { + oci8_raise_by_msgno(rv, NULL); + } + } else { + oci_lc(OCINumberFromReal(errhp, &dbl, sizeof(dbl), result)); + } + return result; +} + /* * call-seq: * OCI8::Math.atan2(y, x) -> oranumber @@ -1107,11 +1171,7 @@ */ static VALUE onum_to_f(VALUE self) { - OCIError *errhp = oci8_errhp; - double dbl; - - oci_lc(OCINumberToReal(errhp, _NUMBER(self), sizeof(dbl), &dbl)); - return rb_float_new(dbl); + return rb_float_new(oci8_onum_to_dbl(_NUMBER(self), oci8_errhp)); } /* @@ -1363,6 +1423,11 @@ return oci8_make_integer((OCINumber*)data, oci8_errhp); } +static VALUE bind_float_get(oci8_bind_t *obind, void *data, void *null_struct) +{ + return oci8_make_float((OCINumber*)data, oci8_errhp); +} + static void bind_ocinumber_set(oci8_bind_t *obind, void *data, void **null_structp, VALUE val) { set_oci_number_from_num((OCINumber*)data, val, 1, oci8_errhp); @@ -1425,6 +1490,22 @@ SQLT_VNU, }; +static const oci8_bind_class_t bind_float_class = { + { + NULL, + oci8_bind_free, + sizeof(oci8_bind_t) + }, + bind_float_get, + bind_ocinumber_set, + bind_ocinumber_init, + bind_ocinumber_init_elem, + NULL, + NULL, + NULL, + SQLT_VNU, +}; + void Init_oci_number(VALUE cOCI8, OCIError *errhp) { @@ -1544,6 +1625,7 @@ oci8_define_bind_class("OraNumber", &bind_ocinumber_class); oci8_define_bind_class("Integer", &bind_integer_class); + oci8_define_bind_class("Float", &bind_float_class); } OCINumber *oci8_get_ocinumber(VALUE num) Modified: trunk/ruby-oci8/lib/oci8/properties.rb =================================================================== --- trunk/ruby-oci8/lib/oci8/properties.rb 2011-08-19 08:13:31 UTC (rev 440) +++ trunk/ruby-oci8/lib/oci8/properties.rb 2011-08-19 13:19:35 UTC (rev 441) @@ -1,11 +1,12 @@ # properties.rb -- implements OCI8.properties # -# Copyright (C) 2010 KUBO Takehiro +# Copyright (C) 2010-2011 KUBO Takehiro class OCI8 @@properties = { :bind_string_as_nchar => false, + :float_conversion_type => :ruby, } def @@properties.[](name) @@ -18,6 +19,9 @@ case name when :bind_string_as_nchar val = val ? true : false + when :float_conversion_type + # handled by native code in oci8lib_xx.so. + OCI8.__set_property(name, val) end super(name, val) end @@ -44,6 +48,14 @@ # [:bind_string_as_nchar] # +true+ when string bind variables are bound as NCHAR, # otherwise +false+. The default value is +false+. + # + # [:float_conversion_type] + # (new in 2.1.0) + # Specifies who converts decimal to float and vice versa. + # It should be either +:ruby+ or +:oracle+. The default value + # is +:ruby+. + # See: http://rubyforge.org/forum/forum.php?thread_id=50030&forum_id=1078 + # def self.properties @@properties end From nobody at rubyforge.org Sun Aug 21 09:33:54 2011 From: nobody at rubyforge.org (nobody at rubyforge.org) Date: Sun, 21 Aug 2011 09:33:54 -0400 (EDT) Subject: [ruby-oci8-commit] [442] web/hiki_data: update http://ruby-oci8.rubyforge.org Message-ID: <20110821133354.8C2541588062@rubyforge.org> Revision: 442 Author: kubo Date: 2011-08-21 09:33:54 -0400 (Sun, 21 Aug 2011) Log Message: ----------- update http://ruby-oci8.rubyforge.org Modified Paths: -------------- web/hiki_data/en/info.db web/hiki_data/en/text/FAQ_uninstall web/hiki_data/en/text/FrontPage web/hiki_data/en/text/PlatformSpecificIssue web/hiki_data/ja/info.db web/hiki_data/ja/text/FAQ_uninstall web/hiki_data/ja/text/FrontPage web/hiki_data/ja/text/PlatformSpecificIssue Modified: web/hiki_data/en/info.db =================================================================== --- web/hiki_data/en/info.db 2011-08-19 13:19:35 UTC (rev 441) +++ web/hiki_data/en/info.db 2011-08-21 13:33:54 UTC (rev 442) @@ -64,7 +64,7 @@ :freeze => false, :keyword => [ ], -:last_modified => Time.at(1169528599), +:last_modified => Time.at(1298351291), :references => [ ], :title => "How to uninstall ruby-oci8", @@ -75,7 +75,7 @@ :freeze => false, :keyword => [ ], -:last_modified => Time.at(1256185375), +:last_modified => Time.at(1276000575), :references => [ "InstallForInstantClient", ], @@ -160,7 +160,7 @@ :freeze => false, :keyword => [ ], -:last_modified => Time.at(1234097653), +:last_modified => Time.at(1313933077), :references => [ "InstallForFullClient", ], Modified: web/hiki_data/en/text/FAQ_uninstall =================================================================== --- web/hiki_data/en/text/FAQ_uninstall 2011-08-19 13:19:35 UTC (rev 441) +++ web/hiki_data/en/text/FAQ_uninstall 2011-08-21 13:33:54 UTC (rev 442) @@ -1,10 +1,25 @@ -Delete the following three files. -* oci8.rb -* oci8lib.so -* DBD/OCI8/OCI8.rb +'gem uninstall ruby-oci8' for gem packages. +Otherwise, run the following commands and look downward. -''oci8.rb'' and ''DBD/OCI8/OCI8.rb'' are in sitelib directory: ruby -r rbconfig -e "puts Config::CONFIG['sitelibdir']" + ruby -r rbconfig -e "puts Config::CONFIG['sitearchdir']" + # Use rbx command instead of ruby for rubinius. -''oci8lib.so'' is in sitearch directory: - ruby -r rbconfig -e "puts Config::CONFIG['sitearchdir']" +! ruby-oci8 2.0 + +Delete the following files in in Config::CONFIG['sitelibdir']. +* oci8.rb +* oci8/* +* dbd/OCI8.rb + +Delete the following file in in Config::CONFIG['sitearchdir']. +* oci8lib_18.so, oci8lib_191.so or oci8lib_rbx18.so + +! ruby-oci8 1.0 + +Delete the following two files in in Config::CONFIG['sitelibdir']. +* oci8.rb +* dbd/OCI8.rb or DBD/OCI8/OCI8.rb + +Delete the following file in in Config::CONFIG['sitearchdir']. +* oci8lib.so Modified: web/hiki_data/en/text/FrontPage =================================================================== --- web/hiki_data/en/text/FrontPage 2011-08-19 13:19:35 UTC (rev 441) +++ web/hiki_data/en/text/FrontPage 2011-08-21 13:33:54 UTC (rev 442) @@ -7,3 +7,5 @@ ! Sample one-liner connect to scott/tiger, select emp and print as CSV format. ruby -r oci8 -e "OCI8.new('scott', 'tiger').exec('select * from emp') do |r| puts r.join(','); end" + +If you install a ruby-oci8 gem package, you may need to add "-rubygems" before "-r oci8." Modified: web/hiki_data/en/text/PlatformSpecificIssue =================================================================== --- web/hiki_data/en/text/PlatformSpecificIssue 2011-08-19 13:19:35 UTC (rev 441) +++ web/hiki_data/en/text/PlatformSpecificIssue 2011-08-21 13:33:54 UTC (rev 442) @@ -1,17 +1,31 @@ ! Mac OS X -You need to delete '-arch ppc' or '-arch i386' in rbconfig.rb because -the ruby distributed with Mac is universal binary but the Oracle instant -client is not. -See: [[How to setup Ruby and new Oracle Instant Client on Leopard|http://blog.rayapps.com/2008/04/24/how-to-setup-ruby-and-new-oracle-instant-client-on-leopard/]]. -(PowerPC mac users need to swap ppc and i386 in the blog.) +!! OS X 10.7 Lion +64-bit instant client doesn't work. Use 32-bit instant client or jruby. + +See: +* http://rubyforge.org/forum/forum.php?thread_id=49548&forum_id=1078 +* https://forums.oracle.com/forums/thread.jspa?threadID=2187558 + +!! Intel Mac (64-bit) + +See [[How to setup Ruby and Oracle Instant Client on Snow Leopard|http://blog.rayapps.com/2009/09/06/how-to-setup-ruby-and-oracle-instant-client-on-snow-leopard/]]. Note that setting the environment variable RC_ARCHS=x86_64 instead of ARCHFLAGS="-arch x86_64" will work fine also. + +!! Intel Mac (32-bit) + +See [[How to setup Ruby and Oracle Instant Client on Snow Leopard|http://blog.rayapps.com/2009/09/06/how-to-setup-ruby-and-oracle-instant-client-on-snow-leopard/]]. Note that you need to replace x86_64 with i386 in the blog. + The Intel Instant client is for Mac OS X 10.5 Leopard. If you are using 10.4 Tiger, use one of the following workarounds. # compile ruby as ppc. (look at [[How to setup Ruby and Oracle client on Intel Mac|http://blog.rayapps.com/2007/08/27/how-to-setup-ruby-and-oracle-client-on-intel-mac/]]) # use [[ruby-odbc|http://www.ch-werner.de/rubyodbc/]] and a third party ODBC driver ([[Actual Technologies|http://www.actualtechnologies.com/]] or [[OpenLink Software|http://uda.openlinksw.com/]]). # use JRuby and Oracle JDBC driver. +!! PowerPC Mac + +See [[How to setup Ruby and Oracle Instant Client on Snow Leopard|http://blog.rayapps.com/2009/09/06/how-to-setup-ruby-and-oracle-instant-client-on-snow-leopard/]]. Note that you need to replace x86_64 with ppc in the blog. + ! Solaris You need a same compiler which is used to make ruby itself. @@ -27,6 +41,14 @@ If you use Blastwave.org's ruby and want not to install Sun Studio, you can edit rbconfig.rb by your self. [[(look at here)|http://forum.textdrive.com/viewtopic.php?id=12630]] +If you use Sunfreeware.com's ruby and + $ ruby -r rbconfig -e "p Config::CONFIG['GNU_LD']" +prints "yes", you may need to edit rbconfig.rb distributed with the ruby +as follows: + + from: CONFIG["LDFLAGS"] = "-L. -Wl,-E" + to: CONFIG["LDFLAGS"] = "-L. " + ! Linux Use the same bit-width of libraries with ruby. For example, x86_64 instant client for x86_64 ruby and 32-bit instant client for 32-bit ruby. It depends on the ruby but not on the OS. As for full client, x86_64 ruby cannot use with 32-bit full client, but 32-bit ruby can use with 64-bit full client because 32-bit libraries are in $ORACLE_HOME/lib32. Modified: web/hiki_data/ja/info.db =================================================================== --- web/hiki_data/ja/info.db 2011-08-19 13:19:35 UTC (rev 441) +++ web/hiki_data/ja/info.db 2011-08-21 13:33:54 UTC (rev 442) @@ -63,7 +63,7 @@ :freeze => false, :keyword => [ ], -:last_modified => Time.at(1169620412), +:last_modified => Time.at(1298351216), :references => [ ], :title => "\343\202\242\343\203\263\343\202\244\343\203\263\343\202\271\343\203\210\343\203\274\343\203\253\346\226\271\346\263\225", @@ -74,7 +74,7 @@ :freeze => false, :keyword => [ ], -:last_modified => Time.at(1256185906), +:last_modified => Time.at(1276001083), :references => [ "InstallForInstantClient", ], @@ -148,7 +148,7 @@ :freeze => false, :keyword => [ ], -:last_modified => Time.at(1234097682), +:last_modified => Time.at(1313933203), :references => [ "InstallForFullClient", ], Modified: web/hiki_data/ja/text/FAQ_uninstall =================================================================== --- web/hiki_data/ja/text/FAQ_uninstall 2011-08-19 13:19:35 UTC (rev 441) +++ web/hiki_data/ja/text/FAQ_uninstall 2011-08-21 13:33:54 UTC (rev 442) @@ -1,10 +1,25 @@ -???????????????????? -* oci8.rb -* oci8lib.so -* DBD/OCI8/OCI8.rb +gem ????????? 'gem uninstall ruby-oci8' ?????????? +gem ?????????????????????????????????????? -oci8.rb ? DBD/OCI8/OCI8.rb ? sitelib ???????????? ruby -r rbconfig -e "puts Config::CONFIG['sitelibdir']" + ruby -r rbconfig -e "puts Config::CONFIG['sitearchdir']" + # rubinius ?????ruby ????? rbx ??????? -oci8lib.so ? sitearch ???????????? - ruby -r rbconfig -e "puts Config::CONFIG['sitearchdir']" +! ruby-oci8 2.0 + +Config::CONFIG['sitelibdir'] ?????????????????? +* oci8.rb +* oci8/* +* dbd/OCI8.rb + +Config::CONFIG['sitearchdir'] ?????????????????? +* oci8lib_18.so, oci8lib_191.so ??? oci8lib_rbx18.so + +! ruby-oci8 1.0 + +Config::CONFIG['sitelibdir'] ?????????????????? +* oci8.rb +* dbd/OCI8.rb ??? DBD/OCI8/OCI8.rb + +Config::CONFIG['sitearchdir'] ?????????????????? +* oci8lib.so Modified: web/hiki_data/ja/text/FrontPage =================================================================== --- web/hiki_data/ja/text/FrontPage 2011-08-19 13:19:35 UTC (rev 441) +++ web/hiki_data/ja/text/FrontPage 2011-08-21 13:33:54 UTC (rev 442) @@ -8,3 +8,5 @@ scott/tiger ??????emp ????? select ???CSV ???????? ruby -r oci8 -e "OCI8.new('scott', 'tiger').exec('select * from emp') do |r| puts r.join(','); end" + +ruby-oci8 ? gem ????????????????????"-r oci8" ??? "-rubygems" ?????????????????? Modified: web/hiki_data/ja/text/PlatformSpecificIssue =================================================================== --- web/hiki_data/ja/text/PlatformSpecificIssue 2011-08-19 13:19:35 UTC (rev 441) +++ web/hiki_data/ja/text/PlatformSpecificIssue 2011-08-21 13:33:54 UTC (rev 442) @@ -1,20 +1,32 @@ ! Mac OS X -(???????? Mac OS X ?? instant client ???????? -[[??????|http://www.oracle.com/technology/tech/oci/instantclient/index.html]]??????) +!! OS X 10.7 Lion -rbconfig.rb ?? '-arch ppc' ????'-arch i386' ?????????? -??????Mac ??? ruby ? Universal binary ????Oracle instant -client ? Universal binary ????????? -[[How to setup Ruby and new Oracle Instant Client on Leopard|http://blog.rayapps.com/2008/04/24/how-to-setup-ruby-and-new-oracle-instant-client-on-leopard/]] ???????? -(PowerPC mac ???????????? ppc ? i386 ???????????) +64????? Instant Client ??????? +32???????????jruby ?????????? +??URL: +* http://rubyforge.org/forum/forum.php?thread_id=49548&forum_id=1078 +* https://forums.oracle.com/forums/thread.jspa?threadID=2187558 + +!! Intel Mac (64-bit) + +[[How to setup Ruby and Oracle Instant Client on Snow Leopard|http://blog.rayapps.com/2009/09/06/how-to-setup-ruby-and-oracle-instant-client-on-snow-leopard/]] ?????????????? ARCHFLAGS="-arch x86_64" ??????RC_ARCHS=x86_64 ?????????? + +!! Intel Mac (32-bit) + +[[How to setup Ruby and Oracle Instant Client on Snow Leopard|http://blog.rayapps.com/2009/09/06/how-to-setup-ruby-and-oracle-instant-client-on-snow-leopard/]] ?????????????????? x86_64 ? i386 ??????????? + Intel ?? Instant client ? Mac OS X 10.5 Leopard ????10.4 Tiger ??? ???????????????????????????? # ruby ? ppc ???????????([[How to setup Ruby and Oracle client on Intel Mac|http://blog.rayapps.com/2007/08/27/how-to-setup-ruby-and-oracle-client-on-intel-mac/]] ???) -* [[ruby-odbc|http://www.ch-werner.de/rubyodbc/]]?????????ODBC????([[Actual Technologies|http://www.actualtechnologies.com/]] ??? [[OpenLink Software|http://uda.openlinksw.com/]])?????? +# [[ruby-odbc|http://www.ch-werner.de/rubyodbc/]]?????????ODBC????([[Actual Technologies|http://www.actualtechnologies.com/]] ??? [[OpenLink Software|http://uda.openlinksw.com/]])?????? # JRuby ? Oracle JDBC driver ?????? +!! PowerPC Mac + +[[How to setup Ruby and Oracle Instant Client on Snow Leopard|http://blog.rayapps.com/2009/09/06/how-to-setup-ruby-and-oracle-instant-client-on-snow-leopard/]] ?????????????????? x86_64 ? ppc ??????????? + ! Solaris ruby ????????????????????????? @@ -28,6 +40,16 @@ Blastwave.org?ruby???????Sun Studio????????????????rbconfig.rb ???????????????[[(?????)|http://forum.textdrive.com/viewtopic.php?id=12630]] +Sunfreeware.com?ruby??????? + + $ ruby -r rbconfig -e "p Config::CONFIG['GNU_LD']" + +? "yes" ?????????ruby????????????? rbconfig.rb ????????? +??????????????? + + ????: CONFIG["LDFLAGS"] = "-L. -Wl,-E" + ?????: CONFIG["LDFLAGS"] = "-L. " + ! Linux ruby ??????????????????????????? x86_64 ?? ruby ?? x86_64 ? instant client, 32???? ruby ?? 32???? instant client ??????OS??????????ruby ?????????????? From nobody at rubyforge.org Tue Aug 23 06:58:33 2011 From: nobody at rubyforge.org (nobody at rubyforge.org) Date: Tue, 23 Aug 2011 06:58:33 -0400 (EDT) Subject: [ruby-oci8-commit] [443] trunk/ruby-oci8: warn when the Oracle instant client is 64-bit on OS X Lion. Message-ID: <20110823105833.A4C121588062@rubyforge.org> Revision: 443 Author: kubo Date: 2011-08-23 06:58:33 -0400 (Tue, 23 Aug 2011) Log Message: ----------- warn when the Oracle instant client is 64-bit on OS X Lion. Modified Paths: -------------- trunk/ruby-oci8/ChangeLog trunk/ruby-oci8/ext/oci8/oraconf.rb Modified: trunk/ruby-oci8/ChangeLog =================================================================== --- trunk/ruby-oci8/ChangeLog 2011-08-21 13:33:54 UTC (rev 442) +++ trunk/ruby-oci8/ChangeLog 2011-08-23 10:58:33 UTC (rev 443) @@ -1,3 +1,7 @@ +2011-08-23 KUBO Takehiro + * ext/oci8/oraconf.rb: warn when the Oracle instant client is + 64-bit on OS X Lion. + 2011-08-19 KUBO Takehiro * ext/oci8/bind.c, ext/oci8/oci8.c, ext/oci8/oci8.h, ext/oci8/ocinumber.c, lib/oci8/properties.rb: Decimal to float and float to decimal conversions Modified: trunk/ruby-oci8/ext/oci8/oraconf.rb =================================================================== --- trunk/ruby-oci8/ext/oci8/oraconf.rb 2011-08-21 13:33:54 UTC (rev 442) +++ trunk/ruby-oci8/ext/oci8/oraconf.rb 2011-08-23 10:58:33 UTC (rev 443) @@ -1136,6 +1136,18 @@ else # 10.1.0 doesn't have OCI_MAJOR_VERSION and OCI_MINOR_VERSION in oci.h. @version = "1010" + if RUBY_PLATFORM =~ /darwin/ and 1.size == 8 and `sw_vers -productVersion`.chomp == "10.7" + $stderr.print < Revision: 444 Author: kubo Date: 2011-08-27 04:13:28 -0400 (Sat, 27 Aug 2011) Log Message: ----------- add OCI8.properties[:length_semantics]. Modified Paths: -------------- trunk/ruby-oci8/ChangeLog trunk/ruby-oci8/ext/oci8/bind.c trunk/ruby-oci8/lib/oci8/bindtype.rb trunk/ruby-oci8/lib/oci8/properties.rb Modified: trunk/ruby-oci8/ChangeLog =================================================================== --- trunk/ruby-oci8/ChangeLog 2011-08-23 10:58:33 UTC (rev 443) +++ trunk/ruby-oci8/ChangeLog 2011-08-27 08:13:28 UTC (rev 444) @@ -1,3 +1,7 @@ +2011-08-27 KUBO Takehiro + * ext/oci8/bind.c, lib/oci8/bindtype.rb, lib/oci8/properties.rb: add + OCI8.properties[:length_semantics]. + 2011-08-23 KUBO Takehiro * ext/oci8/oraconf.rb: warn when the Oracle instant client is 64-bit on OS X Lion. Modified: trunk/ruby-oci8/ext/oci8/bind.c =================================================================== --- trunk/ruby-oci8/ext/oci8/bind.c 2011-08-23 10:58:33 UTC (rev 443) +++ trunk/ruby-oci8/ext/oci8/bind.c 2011-08-27 08:13:28 UTC (rev 444) @@ -12,7 +12,8 @@ static ID id_bind_type; static VALUE sym_length; -static VALUE sym_char_semantics; +static VALUE sym_length_semantics; +static VALUE sym_char; static VALUE sym_nchar; static VALUE cOCI8BindTypeBase; @@ -50,20 +51,21 @@ { oci8_bind_string_t *obs = (oci8_bind_string_t *)obind; VALUE length; - VALUE char_semantics; + VALUE length_semantics; VALUE nchar; sb4 sz; Check_Type(param, T_HASH); length = rb_hash_aref(param, sym_length); - char_semantics = rb_hash_aref(param, sym_char_semantics); + length_semantics = rb_hash_aref(param, sym_length_semantics); nchar = rb_hash_aref(param, sym_nchar); sz = NUM2INT(length); if (sz < 0) { rb_raise(rb_eArgError, "invalid bind length %d", sz); } - if (RTEST(char_semantics)) { + if (length_semantics == sym_char) { + /* character semantics */ obs->charlen = sz; obs->bytelen = sz = sz * oci8_nls_ratio; if (oci8_nls_ratio == 1) { @@ -73,6 +75,7 @@ sz *= 2; } } else { + /* byte semantics */ obs->bytelen = sz; obs->charlen = 0; } @@ -486,7 +489,8 @@ cOCI8BindTypeBase = klass; id_bind_type = rb_intern("bind_type"); sym_length = ID2SYM(rb_intern("length")); - sym_char_semantics = ID2SYM(rb_intern("char_semantics")); + sym_length_semantics = ID2SYM(rb_intern("length_semantics")); + sym_char = ID2SYM(rb_intern("char")); sym_nchar = ID2SYM(rb_intern("nchar")); rb_define_method(cOCI8BindTypeBase, "initialize", oci8_bind_initialize, 4); Modified: trunk/ruby-oci8/lib/oci8/bindtype.rb =================================================================== --- trunk/ruby-oci8/lib/oci8/bindtype.rb 2011-08-23 10:58:33 UTC (rev 443) +++ trunk/ruby-oci8/lib/oci8/bindtype.rb 2011-08-27 08:13:28 UTC (rev 444) @@ -1,7 +1,7 @@ #-- # bindtype.rb -- OCI8::BindType # -# Copyright (C) 2009-2010 KUBO Takehiro +# Copyright (C) 2009-2011 KUBO Takehiro #++ class OCI8 @@ -105,13 +105,15 @@ def self.create(con, val, param, max_array_size) case param when Hash - param[:char_semantics] = true unless param.has_key? :char_semantics + param[:length_semantics] = OCI8::properties[:length_semantics] unless param.has_key? :length_semantics unless param[:length] if val.respond_to? :to_str val = val.to_str - if param[:char_semantics] + if param[:length_semantics] == :char + # character semantics param[:length] = val.size else + # byte semantics if OCI8.respond_to? :encoding and OCI8.encoding != val.encoding # If the string encoding is different with NLS_LANG character set, # convert it to get the length. @@ -134,15 +136,15 @@ when OCI8::Metadata::Base case param.data_type when :char, :varchar2 - char_semantics = param.char_used? - if char_semantics + length_semantics = OCI8.properties[:length_semantics] + if length_semantics == :char length = param.char_size else length = param.data_size * OCI8.nls_ratio end param = { :length => length, - :char_semantics => char_semantics, + :length_semantics => length_semantics, :nchar => (param.charset_form == :nchar), } when :raw Modified: trunk/ruby-oci8/lib/oci8/properties.rb =================================================================== --- trunk/ruby-oci8/lib/oci8/properties.rb 2011-08-23 10:58:33 UTC (rev 443) +++ trunk/ruby-oci8/lib/oci8/properties.rb 2011-08-27 08:13:28 UTC (rev 444) @@ -5,6 +5,7 @@ class OCI8 @@properties = { + :length_semantics => :byte, :bind_string_as_nchar => false, :float_conversion_type => :ruby, } @@ -17,6 +18,10 @@ def @@properties.[]=(name, val) raise IndexError, "No such property name: #{name}" unless @@properties.has_key?(name) case name + when :length_semantic + if val != :byte and val != char + raise ArgumentError, "Invalid property value #{val} for :length_semantics." + end when :bind_string_as_nchar val = val ? true : false when :float_conversion_type @@ -45,6 +50,12 @@ # # Supported properties are listed below: # + # [:length_semantics] + # +:char+ when Oracle character length is counted by the number of characters. + # +:byte+ when it is counted by the number of bytes. + # The default setting is +:byte+ because +:char+ causes unexpected behaviour on + # Oracle 9i. + # # [:bind_string_as_nchar] # +true+ when string bind variables are bound as NCHAR, # otherwise +false+. The default value is +false+. From nobody at rubyforge.org Sat Aug 27 04:51:45 2011 From: nobody at rubyforge.org (nobody at rubyforge.org) Date: Sat, 27 Aug 2011 04:51:45 -0400 (EDT) Subject: [ruby-oci8-commit] [445] trunk/ruby-oci8: delete unused and unworkable features: dynamic fetch and xmldb. Message-ID: <20110827085146.1389F158806D@rubyforge.org> Revision: 445 Author: kubo Date: 2011-08-27 04:51:45 -0400 (Sat, 27 Aug 2011) Log Message: ----------- delete unused and unworkable features: dynamic fetch and xmldb. Modified Paths: -------------- trunk/ruby-oci8/ChangeLog trunk/ruby-oci8/ext/oci8/bind.c trunk/ruby-oci8/ext/oci8/extconf.rb trunk/ruby-oci8/ext/oci8/lob.c trunk/ruby-oci8/ext/oci8/object.c trunk/ruby-oci8/ext/oci8/oci8.h trunk/ruby-oci8/ext/oci8/oci8lib.c trunk/ruby-oci8/ext/oci8/ocidatetime.c trunk/ruby-oci8/ext/oci8/ocinumber.c trunk/ruby-oci8/ext/oci8/oradate.c trunk/ruby-oci8/ext/oci8/stmt.c Removed Paths: ------------- trunk/ruby-oci8/ext/oci8/xmldb.c Modified: trunk/ruby-oci8/ChangeLog =================================================================== --- trunk/ruby-oci8/ChangeLog 2011-08-27 08:13:28 UTC (rev 444) +++ trunk/ruby-oci8/ChangeLog 2011-08-27 08:51:45 UTC (rev 445) @@ -1,4 +1,11 @@ 2011-08-27 KUBO Takehiro + * ext/oci8/bind.c, ext/oci8/extconf.rb, ext/oci8/lob.c, ext/oci8/object.c, + ext/oci8/oci8.h, ext/oci8/oci8lib.c, ext/oci8/ocidatetime.c, + ext/oci8/ocinumber.c, ext/oci8/oradate.c, ext/oci8/stmt.c, + ext/oci8/xmldb.c: delete unused and unworkable features: dynamic fetch + and xmldb. + +2011-08-27 KUBO Takehiro * ext/oci8/bind.c, lib/oci8/bindtype.rb, lib/oci8/properties.rb: add OCI8.properties[:length_semantics]. Modified: trunk/ruby-oci8/ext/oci8/bind.c =================================================================== --- trunk/ruby-oci8/ext/oci8/bind.c 2011-08-27 08:13:28 UTC (rev 444) +++ trunk/ruby-oci8/ext/oci8/bind.c 2011-08-27 08:51:45 UTC (rev 445) @@ -113,8 +113,6 @@ bind_string_init, NULL, NULL, - NULL, - NULL, SQLT_LVC, bind_string_post_bind_hook, }; @@ -152,155 +150,10 @@ bind_string_init, NULL, NULL, - NULL, - NULL, SQLT_LVB }; -#ifdef USE_DYNAMIC_FETCH /* don't use DYNAMIC_FETCH. It doesn't work well... */ /* - * bind_long - */ -typedef struct { - VALUE obj; - ub4 alen; - char buf[1]; -} bind_long_t; -#define bind_long_offset ((size_t)((bind_long_t*)0)->buf) - -static void bind_long_mark(oci8_base_t *base) -{ - oci8_bind_t *obind = (oci8_bind_t*)base; - ub4 idx = 0; - - if (obind->valuep == NULL) - return; - do { - bind_long_t *bl = (bind_long_t *)((char*)obind->valuep + obind->alloc_sz * idx); - rb_gc_mark(bl->obj); - } while (++idx < obind->maxar_sz); -} - -static VALUE bind_long_get(oci8_bind_t *obind, void *data, void *null_struct) -{ - bind_long_t *bl = (bind_long_t *)data; - return RTEST(bl->obj) ? rb_str_dup(bl->obj) : Qnil; -} - -static void bind_long_set(oci8_bind_t *obind, void *data, void **null_structp, VALUE val) -{ - bind_long_t *bl = (bind_long_t *)data; - bl->obj = rb_str_dup(val); -} - -static void bind_long_init(oci8_bind_t *obind, VALUE svc, VALUE val, VALUE length) -{ - sb4 sz = 0; - - if (!NIL_P(length)) { - sz = NUM2INT(length); - } - if (sz < 4000) { - sz = 4000; - } - sz += bind_long_offset; - obind->value_sz = INT_MAX; - obind->alloc_sz = (sz + (sizeof(VALUE) - 1)) & ~(sizeof(VALUE) - 1); -} - -static void bind_long_init_elem(oci8_bind_t *obind, VALUE svc) -{ - ub4 idx = 0; - - do { - bind_long_t *bl = (bind_long_t *)((char*)obind->valuep + obind->alloc_sz * idx); - bl->obj = Qnil; - } while (++idx < obind->maxar_sz); -} - -static ub1 bind_long_in(oci8_bind_t *obind, ub4 idx, ub1 piece, void **valuepp, ub4 **alenpp, void **indpp) -{ - bind_long_t *bl = (bind_long_t *)((char*)obind->valuep + obind->alloc_sz * idx); - - *alenpp = &bl->alen; - *indpp = &obind->u.inds[idx]; - if (NIL_P(bl->obj)) { - *valuepp = NULL; - bl->alen = 0; - obind->u.inds[idx] = -1; - } else { - StringValue(bl->obj); - *valuepp = RSTRING_PTR(bl->obj); - bl->alen = RSTRING_LEN(bl->obj); - obind->u.inds[idx] = 0; - } - return OCI_ONE_PIECE; -} - -static void bind_long_out(oci8_bind_t *obind, ub4 idx, ub1 piece, void **valuepp, ub4 **alenpp, void **indpp) -{ - bind_long_t *bl = (bind_long_t *)((char*)obind->valuep + obind->alloc_sz * idx); - - switch (piece) { - case OCI_NEXT_PIECE: - case OCI_LAST_PIECE: - if (bl->alen > 0) { - if (!RTEST(bl->obj)) { - bl->obj = rb_str_buf_new(bl->alen); - } - rb_str_buf_cat(bl->obj, bl->buf, bl->alen); - } - break; - default: - /* OCI_FIRST_PIECE is passed at the first call according to manuals. - * But OCI_ONE_PIECE is passed on Oracle 8 and 8i on Windows... - */ - bl->obj = Qnil; - } - *valuepp = bl->buf; - *alenpp = &bl->alen; - *indpp = &obind->u.inds[idx]; - bl->alen = obind->alloc_sz - bind_long_offset; - obind->u.inds[idx] = 0; -} - -static const oci8_bind_class_t bind_long_class = { - { - bind_long_mark, - oci8_bind_free, - sizeof(oci8_bind_t) - }, - bind_long_get, - bind_long_set, - bind_long_init, - bind_long_init_elem, - bind_long_in, - bind_long_out, - NULL, - SQLT_CHR -}; - -/* - * bind_long_raw - */ -static const oci8_bind_class_t bind_long_raw_class = { - { - bind_long_mark, - oci8_bind_free, - sizeof(oci8_bind_t) - }, - bind_long_get, - bind_long_set, - bind_long_init, - bind_long_init_elem, - bind_long_in, - bind_long_out, - NULL, - SQLT_BIN -}; -#endif /* USE_DYNAMIC_FETCH */ - -/* * bind_binary_double */ static VALUE bind_binary_double_get(oci8_bind_t *obind, void *data, void *null_struct) @@ -334,8 +187,6 @@ bind_binary_double_init, NULL, NULL, - NULL, - NULL, SQLT_BDOUBLE }; @@ -500,10 +351,6 @@ /* register primitive data types. */ oci8_define_bind_class("String", &bind_string_class); oci8_define_bind_class("RAW", &bind_raw_class); -#ifdef USE_DYNAMIC_FETCH - oci8_define_bind_class("Long", &bind_long_class); - oci8_define_bind_class("LongRaw", &bind_long_raw_class); -#endif /* USE_DYNAMIC_FETCH */ if (oracle_client_version >= ORAVER_10_1) { oci8_define_bind_class("BinaryDouble", &bind_binary_double_class); } Modified: trunk/ruby-oci8/ext/oci8/extconf.rb =================================================================== --- trunk/ruby-oci8/ext/oci8/extconf.rb 2011-08-27 08:13:28 UTC (rev 444) +++ trunk/ruby-oci8/ext/oci8/extconf.rb 2011-08-27 08:51:45 UTC (rev 445) @@ -89,7 +89,7 @@ "stmt.o", "bind.o", "metadata.o", "attr.o", "lob.o", "oradate.o", "ocinumber.o", "ocidatetime.o", "object.o", "apiwrap.o", - "encoding.o", "xmldb.o", "oranumber_util.o"] + "encoding.o", "oranumber_util.o"] if RUBY_PLATFORM =~ /mswin32|cygwin|mingw32|bccwin32/ $defs << "-DUSE_WIN32_C" Modified: trunk/ruby-oci8/ext/oci8/lob.c =================================================================== --- trunk/ruby-oci8/ext/oci8/lob.c 2011-08-27 08:13:28 UTC (rev 444) +++ trunk/ruby-oci8/ext/oci8/lob.c 2011-08-27 08:51:45 UTC (rev 445) @@ -692,8 +692,6 @@ bind_lob_init, bind_lob_init_elem, NULL, - NULL, - NULL, SQLT_CLOB }, &cOCI8CLOB @@ -711,8 +709,6 @@ bind_lob_init, bind_lob_init_elem, NULL, - NULL, - NULL, SQLT_CLOB, bind_lob_post_bind_hook_for_nclob, }, @@ -731,8 +727,6 @@ bind_lob_init, bind_lob_init_elem, NULL, - NULL, - NULL, SQLT_BLOB }, &cOCI8BLOB @@ -750,8 +744,6 @@ bind_lob_init, bind_lob_init_elem, NULL, - NULL, - NULL, SQLT_BFILE }, &cOCI8BFILE Modified: trunk/ruby-oci8/ext/oci8/object.c =================================================================== --- trunk/ruby-oci8/ext/oci8/object.c 2011-08-27 08:13:28 UTC (rev 444) +++ trunk/ruby-oci8/ext/oci8/object.c 2011-08-27 08:51:45 UTC (rev 445) @@ -656,8 +656,6 @@ bind_named_type_init, bind_named_type_init_elem, NULL, - NULL, - NULL, SQLT_NTY, bind_name_type_post_bind_hook, }; Modified: trunk/ruby-oci8/ext/oci8/oci8.h =================================================================== --- trunk/ruby-oci8/ext/oci8/oci8.h 2011-08-27 08:13:28 UTC (rev 444) +++ trunk/ruby-oci8/ext/oci8/oci8.h 2011-08-27 08:51:45 UTC (rev 445) @@ -29,9 +29,6 @@ #ifdef __cplusplus } #endif -#ifdef HAVE_XMLOTN_H -#include "xmlotn.h" -#endif #define ORAVERNUM(major, minor, update, patch, port_update) \ (((major) << 24) | ((minor) << 20) | ((update) << 12) | ((patch) << 8) | (port_update)) @@ -259,8 +256,6 @@ void (*set)(oci8_bind_t *obind, void *data, void **null_structp, VALUE val); void (*init)(oci8_bind_t *obind, VALUE svc, VALUE val, VALUE length); void (*init_elem)(oci8_bind_t *obind, VALUE svc); - ub1 (*in)(oci8_bind_t *obind, ub4 idx, ub1 piece, void **valuepp, ub4 **alenpp, void **indpp); - void (*out)(oci8_bind_t *obind, ub4 idx, ub1 piece, void **valuepp, ub4 **alenpp, void **indpp); void (*pre_fetch_hook)(oci8_bind_t *obind, VALUE svc); ub2 dty; void (*post_bind_hook)(oci8_bind_t *obind); @@ -513,18 +508,6 @@ /* object.c */ void Init_oci_object(VALUE mOCI); -/* xmldb.c */ -#ifndef XMLCTX_DEFINED -#define XMLCTX_DEFINED -struct xmlctx; -typedef struct xmlctx xmlctx; -#endif -#ifndef XML_TYPES -typedef struct xmlnode xmlnode; -#endif -void Init_oci_xmldb(void); -VALUE oci8_make_rexml(struct xmlctx *xctx, xmlnode *node); - /* attr.c */ VALUE oci8_get_sb1_attr(oci8_base_t *base, ub4 attrtype); VALUE oci8_get_ub2_attr(oci8_base_t *base, ub4 attrtype); Modified: trunk/ruby-oci8/ext/oci8/oci8lib.c =================================================================== --- trunk/ruby-oci8/ext/oci8/oci8lib.c 2011-08-27 08:13:28 UTC (rev 444) +++ trunk/ruby-oci8/ext/oci8/oci8lib.c 2011-08-27 08:51:45 UTC (rev 445) @@ -133,7 +133,6 @@ Init_ora_date(); Init_oci_datetime(); Init_oci_object(cOCI8); - Init_oci_xmldb(); #ifdef USE_WIN32_C Init_oci8_win32(cOCI8); Modified: trunk/ruby-oci8/ext/oci8/ocidatetime.c =================================================================== --- trunk/ruby-oci8/ext/oci8/ocidatetime.c 2011-08-27 08:13:28 UTC (rev 444) +++ trunk/ruby-oci8/ext/oci8/ocidatetime.c 2011-08-27 08:51:45 UTC (rev 445) @@ -263,8 +263,6 @@ bind_ocitimestamp_tz_init, bind_ocitimestamp_tz_init_elem, NULL, - NULL, - NULL, SQLT_TIMESTAMP_TZ }; @@ -436,8 +434,6 @@ bind_ociinterval_ym_init, bind_ociinterval_ym_init_elem, NULL, - NULL, - NULL, SQLT_INTERVAL_YM }; @@ -452,8 +448,6 @@ bind_ociinterval_ds_init, bind_ociinterval_ds_init_elem, NULL, - NULL, - NULL, SQLT_INTERVAL_DS }; Modified: trunk/ruby-oci8/ext/oci8/ocinumber.c =================================================================== --- trunk/ruby-oci8/ext/oci8/ocinumber.c 2011-08-27 08:13:28 UTC (rev 444) +++ trunk/ruby-oci8/ext/oci8/ocinumber.c 2011-08-27 08:51:45 UTC (rev 445) @@ -321,10 +321,6 @@ char buf[256]; sword rv; - double dbl; - - oci_lc(OCINumberToReal(errhp, s, sizeof(double), &dbl)); - rv = oranumber_to_str(s, buf, sizeof(buf)); if (rv <= 0) { char buf[ORANUMBER_DUMP_BUF_SIZ]; @@ -1469,8 +1465,6 @@ bind_ocinumber_init, bind_ocinumber_init_elem, NULL, - NULL, - NULL, SQLT_VNU, }; @@ -1485,8 +1479,6 @@ bind_ocinumber_init, bind_ocinumber_init_elem, NULL, - NULL, - NULL, SQLT_VNU, }; @@ -1501,8 +1493,6 @@ bind_ocinumber_init, bind_ocinumber_init_elem, NULL, - NULL, - NULL, SQLT_VNU, }; Modified: trunk/ruby-oci8/ext/oci8/oradate.c =================================================================== --- trunk/ruby-oci8/ext/oci8/oradate.c 2011-08-27 08:13:28 UTC (rev 444) +++ trunk/ruby-oci8/ext/oci8/oradate.c 2011-08-27 08:51:45 UTC (rev 445) @@ -568,8 +568,6 @@ bind_oradate_init, bind_oradate_init_elem, NULL, - NULL, - NULL, SQLT_DAT, }; Modified: trunk/ruby-oci8/ext/oci8/stmt.c =================================================================== --- trunk/ruby-oci8/ext/oci8/stmt.c 2011-08-27 08:13:28 UTC (rev 444) +++ trunk/ruby-oci8/ext/oci8/stmt.c 2011-08-27 08:51:45 UTC (rev 445) @@ -101,7 +101,6 @@ oci8_bind_t *obind; const oci8_bind_class_t *bind_class; sword status; - ub4 mode; position = NUM2INT(vposition); /* 1 */ obind = oci8_get_bind(vbindobj); /* 2 */ @@ -109,12 +108,7 @@ oci8_base_free(&obind->base); /* TODO: OK? */ } bind_class = (const oci8_bind_class_t *)obind->base.klass; - if (bind_class->out == NULL) { - mode = OCI_DEFAULT; - } else { - mode = OCI_DYNAMIC_FETCH; - } - status = OCIDefineByPos(stmt->base.hp.stmt, &obind->base.hp.dfn, oci8_errhp, position, obind->valuep, obind->value_sz, bind_class->dty, NIL_P(obind->tdo) ? obind->u.inds : NULL, NULL, 0, mode); + status = OCIDefineByPos(stmt->base.hp.stmt, &obind->base.hp.dfn, oci8_errhp, position, obind->valuep, obind->value_sz, bind_class->dty, NIL_P(obind->tdo) ? obind->u.inds : NULL, NULL, 0, OCI_DEFAULT); if (status != OCI_SUCCESS) { oci8_raise(oci8_errhp, status, stmt->base.hp.ptr); } @@ -151,7 +145,6 @@ VALUE old_value; void *indp; ub4 *curelep; - ub4 mode; if (NIL_P(vplaceholder)) { /* 1 */ placeholder_ptr = NULL; @@ -175,11 +168,6 @@ oci8_base_free(&obind->base); /* TODO: OK? */ } bind_class = (const oci8_bind_class_t *)obind->base.klass; - if (bind_class->in != NULL || bind_class->out != NULL) { - mode = OCI_DATA_AT_EXEC; - } else { - mode = OCI_DEFAULT; - } indp = NIL_P(obind->tdo) ? obind->u.inds : NULL; if (obind->maxar_sz == 0) { @@ -188,9 +176,9 @@ curelep = &obind->curar_sz; } if (placeholder_ptr == (char*)-1) { - status = OCIBindByPos(stmt->base.hp.stmt, &obind->base.hp.bnd, oci8_errhp, position, obind->valuep, obind->value_sz, bind_class->dty, indp, NULL, 0, 0, 0, mode); + status = OCIBindByPos(stmt->base.hp.stmt, &obind->base.hp.bnd, oci8_errhp, position, obind->valuep, obind->value_sz, bind_class->dty, indp, NULL, 0, 0, 0, OCI_DEFAULT); } else { - status = OCIBindByName(stmt->base.hp.stmt, &obind->base.hp.bnd, oci8_errhp, TO_ORATEXT(placeholder_ptr), placeholder_len, obind->valuep, obind->value_sz, bind_class->dty, indp, NULL, 0, 0, 0, mode); + status = OCIBindByName(stmt->base.hp.stmt, &obind->base.hp.bnd, oci8_errhp, TO_ORATEXT(placeholder_ptr), placeholder_len, obind->valuep, obind->value_sz, bind_class->dty, indp, NULL, 0, 0, 0, OCI_DEFAULT); } if (status != OCI_SUCCESS) { oci8_raise(oci8_errhp, status, stmt->base.hp.stmt); @@ -250,54 +238,6 @@ mode = svcctx->is_autocommit ? OCI_COMMIT_ON_SUCCESS : OCI_DEFAULT; } rv = oci8_call_stmt_execute(svcctx, stmt, iters, mode); -#ifdef USE_DYNAMIC_FETCH - while (rv == OCI_NEED_DATA) { - oci8_bind_t *obind; - const oci8_bind_class_t *bind_class; - /* get piece info. */ - dvoid *hp; - ub4 type; - ub1 in_out; - ub4 iter; - ub4 idx; - ub1 piece; - /* set piece info. */ - void *valuep; - ub4 *alenp; - void *indp; - - oci_lc(OCIStmtGetPieceInfo(stmt->base.hp.ptr, oci8_errhp, &hp, &type, &in_out, &iter, &idx, &piece)); - obind = (oci8_bind_t*)stmt->base.children; - do { - if (obind->base.hp.ptr == hp) { - if (type != OCI_HTYPE_BIND) - rb_bug("ruby-oci8: expect OCI_HTYPE_BIND but %d", type); - bind_class = (const oci8_bind_class_t *)obind->base.klass; - switch (in_out) { - case OCI_PARAM_IN: - if (bind_class->in == NULL) - rb_bug("...."); - piece = bind_class->in(obind, idx, piece, &valuep, &alenp, &indp); - break; - case OCI_PARAM_OUT: - if (bind_class->out == NULL) - rb_bug("...."); - bind_class->out(obind, idx, piece, &valuep, &alenp, &indp); - break; - default: - rb_bug("ruby-oci8: expect OCI_PARAM_IN or OCI_PARAM_OUT but %d", in_out); - } - oci_lc(OCIStmtSetPieceInfo(obind->base.hp.ptr, OCI_HTYPE_BIND, oci8_errhp, valuep, alenp, 0, indp, NULL)); - break; - } - obind = (oci8_bind_t*)obind->base.next; - } while (obind != (oci8_bind_t*)stmt->base.children); - if (obind == (oci8_bind_t*)stmt) { - rb_bug("ruby-oci8: No bind handle is found."); - } - rv = oci8_call_stmt_execute(svcctx, stmt, iters, mode); - } -#endif /* USE_DYNAMIC_FETCH */ if (IS_OCI_ERROR(rv)) { oci8_raise(oci8_errhp, rv, stmt->base.hp.stmt); } @@ -351,78 +291,12 @@ } while (obind != (oci8_bind_t*)stmt->base.children); } rv = OCIStmtFetch_nb(svcctx, stmt->base.hp.stmt, oci8_errhp, 1, OCI_FETCH_NEXT, OCI_DEFAULT); -#ifdef USE_DYNAMIC_FETCH - while (rv == OCI_NEED_DATA) { - /* get piece info. */ - dvoid *hp; - ub4 type; - ub1 in_out; - ub4 iter; - ub4 idx; - ub1 piece; - /* set piece info. */ - void *valuep; - ub4 *alenp; - void *indp; - - oci_lc(OCIStmtGetPieceInfo(stmt->base.hp.ptr, oci8_errhp, &hp, &type, &in_out, &iter, &idx, &piece)); - obind = (oci8_bind_t *)stmt->base.children; - do { - if (obind->base.hp.ptr == hp) { - if (type != OCI_HTYPE_DEFINE) - rb_bug("ruby-oci8: expect OCI_HTYPE_DEFINE but %d", type); - bind_class = (const oci8_bind_class_t *)obind->base.klass; - switch (in_out) { - case OCI_PARAM_OUT: - if (bind_class->out == NULL) - rb_bug("...."); - bind_class->out(obind, idx, piece, &valuep, &alenp, &indp); - break; - default: - rb_bug("ruby-oci8: expect OCI_PARAM_OUT but %d", in_out); - } - oci_lc(OCIStmtSetPieceInfo(obind->base.hp.ptr, OCI_HTYPE_DEFINE, oci8_errhp, valuep, alenp, 0, indp, NULL)); - break; - } - obind = (oci8_bind_t *)obind->base.next; - } while (obind != (oci8_bind_t*)stmt->base.children); - if (obind == (oci8_bind_t*)stmt) { - rb_bug("ruby-oci8: No define handle is found."); - } - rv = OCIStmtFetch_nb(svcctx, stmt->base.hp.stmt, oci8_errhp, 1, OCI_FETCH_NEXT, OCI_DEFAULT); - } -#endif /* USE_DYNAMIC_FETCH */ if (rv == OCI_NO_DATA) { return Qnil; } if (IS_OCI_ERROR(rv)) { oci8_raise(oci8_errhp, rv, stmt->base.hp.stmt); } -#ifdef USE_DYNAMIC_FETCH - obind = (oci8_bind_t *)stmt->base.children; - do { - /* set piece info. */ - void *valuep; - ub4 *alenp; - void *indp; - ub1 piece = OCI_LAST_PIECE; - - if (obind->base.type == OCI_HTYPE_DEFINE) { - bind_class = (const oci8_bind_class_t *)obind->base.klass; - if (bind_class->out != NULL) { - if (obind->maxar_sz == 0) { - bind_class->out(obind, 0, piece, &valuep, &alenp, &indp); - } else { - ub4 idx; - for (idx = 0; idx < obind->curar_sz; idx++) { - bind_class->out(obind, idx, piece, &valuep, &alenp, &indp); - } - } - } - } - obind = (oci8_bind_t *)obind->base.next; - } while (obind != (oci8_bind_t*)stmt->base.children); -#endif /* USE_DYNAMIC_FETCH */ ary = rb_ary_new2(RARRAY_LEN(stmt->defns)); for (idx = 0; idx < RARRAY_LEN(stmt->defns); idx++) { rb_ary_store(ary, idx, oci8_bind_get_data(RARRAY_PTR(stmt->defns)[idx])); @@ -746,8 +620,6 @@ bind_stmt_set, bind_stmt_init, bind_stmt_init_elem, - NULL, - NULL, bind_stmt_init_elem, SQLT_RSET }; Deleted: trunk/ruby-oci8/ext/oci8/xmldb.c =================================================================== --- trunk/ruby-oci8/ext/oci8/xmldb.c 2011-08-27 08:13:28 UTC (rev 444) +++ trunk/ruby-oci8/ext/oci8/xmldb.c 2011-08-27 08:51:45 UTC (rev 445) @@ -1,383 +0,0 @@ -/* -*- c-file-style: "ruby"; indent-tabs-mode: nil -*- */ -#include "oci8.h" - -#if 0 /* disabled for a while. */ && (ORACLE_CLIENT_VERSION >= ORAVER_10_1 || defined RUNTIME_API_CHECK) - -#ifndef HAVE_XMLOTN_H -/* declarations in xmlproc.h of Oracle XML Development Kit */ -typedef xmlnode xmlelemnode; -typedef xmlnode xmlpinode; -typedef xmlnode xmldocnode; -typedef xmlnode xmldtdnode; -typedef xmlnode xmlnotenode; -typedef xmlnode xmlnamedmap; -typedef xmlnode xmlattrnode; - -typedef enum { - XMLERR_OK = 0, -} xmlerr; - -typedef enum { - XMLDOM_NONE = 0, /* bogus node */ - XMLDOM_ELEM = 1, /* element */ - XMLDOM_ATTR = 2, /* attribute */ - XMLDOM_TEXT = 3, /* char data not escaped by CDATA */ - XMLDOM_CDATA = 4, /* char data escaped by CDATA */ - XMLDOM_ENTREF = 5, /* entity reference */ - XMLDOM_ENTITY = 6, /* entity */ - XMLDOM_PI = 7, /* */ - XMLDOM_COMMENT = 8, /* */ - XMLDOM_DOC = 9, /* Document */ - XMLDOM_DTD = 10, /* DTD */ - XMLDOM_FRAG = 11, /* Document fragment */ - XMLDOM_NOTATION = 12, /* notation */ - XMLDOM_ELEMDECL = 13, /* DTD element declaration */ - XMLDOM_ATTRDECL = 14, /* DTD attribute declaration */ - XMLDOM_CPELEM = 15, /* element */ - XMLDOM_CPCHOICE = 16, /* choice (a|b) */ - XMLDOM_CPSEQ = 17, /* sequence (a,b) */ - XMLDOM_CPPCDATA = 18, /* #PCDATA */ - XMLDOM_CPSTAR = 19, /* '*' (zero or more) */ - XMLDOM_CPPLUS = 20, /* '+' (one or more) */ - XMLDOM_CPOPT = 21, /* '?' (optional) */ - XMLDOM_CPEND = 22 /* end marker */ -} xmlnodetype; - -typedef struct xmldomcb { - void *cb[1]; -} xmldomcb; - -typedef struct xmlctxhead { - ub4 cw_xmlctxhead; /* checkword */ - oratext *name_xmlctxhead; /* name for context */ - void *cb_xmlctxhead; /* top-level function callbacks */ - xmldomcb *domcb_xmlctxhead; /* DOM function callbacks */ -} xmlctxhead; -#define XML_DOMCB(xctx) ((xmlctxhead *) xctx)->domcb_xmlctxhead - -typedef xmlerr (*XmlDomGetDecl_t)(xmlctx *xctx, xmldocnode *doc, oratext **ver, oratext **enc, sb4 *std); -#define XmlDomGetDecl(xctx, doc, ver, enc, std) \ - ((XmlDomGetDecl_t)XML_DOMCB(xctx)->cb[0])((xctx), (doc), (ver), (enc), (std)) - -typedef xmldtdnode* (*XmlDomGetDTD_t)(xmlctx *xctx, xmldocnode *doc); -#define XmlDomGetDTD(xctx, doc) \ - ((XmlDomGetDTD_t)XML_DOMCB(xctx)->cb[3])((xctx), (doc)) - -typedef xmlnodetype (*XmlDomGetNodeType_t)(xmlctx *xctx, xmlnode *node); -#define XmlDomGetNodeType(xctx, node) \ - ((XmlDomGetNodeType_t)XML_DOMCB(xctx)->cb[34])((xctx), (node)) - -typedef xmlnode* (*XmlDomGetFirstChild_t)(xmlctx *xctx, xmlnode *node); -#define XmlDomGetFirstChild(xctx, node) \ - ((XmlDomGetFirstChild_t)XML_DOMCB(xctx)->cb[46])((xctx), (node)) - -typedef xmlnode* (*XmlDomGetNextSibling_t)(xmlctx *xctx, xmlnode *node); -#define XmlDomGetNextSibling(xctx, node) \ - ((XmlDomGetNextSibling_t)XML_DOMCB(xctx)->cb[53])((xctx), (node)) - -typedef xmlnamedmap* (*XmlDomGetAttrs_t)(xmlctx *xctx, xmlelemnode *elem); -#define XmlDomGetAttrs(xctx, node) \ - ((XmlDomGetAttrs_t)XML_DOMCB(xctx)->cb[55])((xctx), (node)) - -typedef xmlnode* (*XmlDomGetNodeMapItem_t)(xmlctx *xctx, xmlnamedmap *map, ub4 index); -#define XmlDomGetNodeMapItem(xctx, map, index) \ - ((XmlDomGetNodeMapItem_t)XML_DOMCB(xctx)->cb[82])((xctx), (map), (index)) - -typedef ub4 (*XmlDomGetNodeMapLength_t)(xmlctx *xctx, xmlnamedmap *map); -#define XmlDomGetNodeMapLength(xctx, map) \ - ((XmlDomGetNodeMapLength_t)XML_DOMCB(xctx)->cb[83])((xctx), (map)) - -typedef oratext* (*XmlDomGetCharData_t)(xmlctx *xctx, xmlnode *node); -#define XmlDomGetCharData(xctx, node) \ - ((XmlDomGetCharData_t)XML_DOMCB(xctx)->cb[90])((xctx), (node)) - -typedef oratext* (*XmlDomGetAttrName_t)(xmlctx *xctx, xmlattrnode *attr); -#define XmlDomGetAttrName(xctx, attr) \ - ((XmlDomGetAttrName_t)XML_DOMCB(xctx)->cb[98])((xctx), (attr)) - -typedef oratext* (*XmlDomGetAttrValue_t)(xmlctx *xctx, xmlattrnode *attr); -#define XmlDomGetAttrValue(xctx, attr) \ - ((XmlDomGetAttrValue_t)XML_DOMCB(xctx)->cb[106])((xctx), (attr)) - -typedef oratext* (*XmlDomGetTag_t)(xmlctx *xctx, xmlelemnode *elem); -#define XmlDomGetTag(xctx, elem) \ - ((XmlDomGetTag_t)XML_DOMCB(xctx)->cb[112])((xctx), (elem)) - -typedef oratext* (*XmlDomGetDTDName_t)(xmlctx *xctx, xmldtdnode *dtd); -#define XmlDomGetDTDName(xctx, dtd) \ - ((XmlDomGetDTDName_t)XML_DOMCB(xctx)->cb[131])((xctx), (dtd)) - -typedef xmlnamedmap* (*XmlDomGetDTDEntities_t)(xmlctx *xctx, xmldtdnode *dtd); -#define XmlDomGetDTDEntities(xctx, dtd) \ - ((XmlDomGetDTDEntities_t)XML_DOMCB(xctx)->cb[132])((xctx), (dtd)) - -typedef xmlnamedmap* (*XmlDomGetDTDNotations_t)(xmlctx *xctx, xmldtdnode *dtd); -#define XmlDomGetDTDNotations(xctx, dtd) \ - ((XmlDomGetDTDNotations_t)XML_DOMCB(xctx)->cb[133])((xctx), (dtd)) - -typedef oratext* (*XmlDomGetDTDPubID_t)(xmlctx *xctx, xmldtdnode *dtd); -#define XmlDomGetDTDPubID(xctx, dtd) \ - ((XmlDomGetDTDPubID_t)XML_DOMCB(xctx)->cb[134])((xctx), (dtd)) - -typedef oratext* (*XmlDomGetDTDSysID_t)(xmlctx *xctx, xmldtdnode *dtd); -#define XmlDomGetDTDSysID(xctx, dtd) \ - ((XmlDomGetDTDSysID_t)XML_DOMCB(xctx)->cb[135])((xctx), (dtd)) - -typedef oratext* (*XmlDomGetPITarget_t)(xmlctx *xctx, xmlpinode *pi); -#define XmlDomGetPITarget(xctx, pi) \ - ((XmlDomGetPITarget_t)XML_DOMCB(xctx)->cb[143])((xctx), (pi)) - -typedef oratext* (*XmlDomGetPIData_t)(xmlctx *xctx, xmlpinode *pi); -#define XmlDomGetPIData(xctx, pi) \ - ((XmlDomGetPIData_t)XML_DOMCB(xctx)->cb[144])((xctx), (pi)) - -/* end of declarations in xmlproc.h of Oracle XML Development Kit */ -#endif /* HAVE_XMLOTN_H */ - -static ID id_add; -static ID id_add_attribute; -static VALUE REXML_Element; -static VALUE REXML_Text; -static VALUE REXML_CData; -static VALUE REXML_Instruction; -static VALUE REXML_Comment; -static VALUE REXML_Document; -static VALUE REXML_XMLDecl; -static VALUE REXML_DocType; -static VALUE REXML_NotationDecl; - -static VALUE oci8_make_element(struct xmlctx *xctx, xmlelemnode *elem); -static VALUE oci8_make_cdata(struct xmlctx *xctx, xmlnode *node); -static VALUE oci8_make_text(struct xmlctx *xctx, xmlnode *node); -static VALUE oci8_make_pi(struct xmlctx *xctx, xmlpinode *pi); -static VALUE oci8_make_comment(struct xmlctx *xctx, xmlnode *node); -static VALUE oci8_make_document(struct xmlctx *xctx, xmldocnode *doc); -static VALUE oci8_make_dtd(struct xmlctx *xctx, xmldtdnode *dtd); - -static VALUE add_child_nodes(VALUE obj, struct xmlctx *xctx, xmlnode *node); -static VALUE add_attributes(VALUE obj, struct xmlctx *xctx, xmlnode *node); -static VALUE add_nodemap(VALUE obj, struct xmlctx *xctx, xmlnamedmap *map); - -void Init_oci_xmldb(void) -{ - id_add = rb_intern("add"); - id_add_attribute = rb_intern("add_attribute"); - rb_require("rexml/document"); - REXML_Document = rb_eval_string("REXML::Document"); - REXML_Element = rb_eval_string("REXML::Element"); - REXML_Text = rb_eval_string("REXML::Text"); - REXML_CData = rb_eval_string("REXML::CData"); - REXML_Instruction = rb_eval_string("REXML::Instruction"); - REXML_Comment = rb_eval_string("REXML::Comment"); - REXML_XMLDecl = rb_eval_string("REXML::XMLDecl"); - REXML_DocType = rb_eval_string("REXML::DocType"); - REXML_NotationDecl = rb_eval_string("REXML::NotationDecl"); -} - -VALUE oci8_make_rexml(struct xmlctx *xctx, xmlnode *node) -{ - xmlnodetype nodetype = XmlDomGetNodeType(xctx, node); - - switch (nodetype) { - case XMLDOM_NONE: /* 0 */ - rb_raise(rb_eRuntimeError, "unsupported XML node type: XMLDOM_NONE"); - case XMLDOM_ELEM: /* 1 */ - return oci8_make_element(xctx, (xmlelemnode*)node); - case XMLDOM_ATTR: /* 2 */ - rb_raise(rb_eRuntimeError, "unsupported XML node type: XMLDOM_ATTR"); - case XMLDOM_TEXT: /* 3 */ - return oci8_make_text(xctx, node); - case XMLDOM_CDATA: /* 4 */ - return oci8_make_cdata(xctx, node); - case XMLDOM_ENTREF: /* 5 */ - rb_raise(rb_eRuntimeError, "unsupported XML node type: XMLDOM_ENTREF"); - case XMLDOM_ENTITY: /* 6 */ - rb_raise(rb_eRuntimeError, "unsupported XML node type: XMLDOM_ENTITY"); - case XMLDOM_PI: /* 7 */ - return oci8_make_pi(xctx, (xmlpinode*)node); - case XMLDOM_COMMENT: /* 8 */ - return oci8_make_comment(xctx, node); - case XMLDOM_DOC: /* 9 */ - return oci8_make_document(xctx, (xmldocnode*)node); - case XMLDOM_DTD: /* 10 */ - return oci8_make_dtd(xctx, (xmldtdnode*)node); - case XMLDOM_FRAG: /* 11 */ - rb_raise(rb_eRuntimeError, "unsupported XML node type: XMLDOM_FRAG"); - case XMLDOM_NOTATION: /* 12 */ - rb_raise(rb_eRuntimeError, "unsupported XML node type: XMLDOM_NOTATION"); - case XMLDOM_ELEMDECL: /* 13 */ - rb_raise(rb_eRuntimeError, "unsupported XML node type: XMLDOM_ELEMDECL"); - case XMLDOM_ATTRDECL: /* 14 */ - rb_raise(rb_eRuntimeError, "unsupported XML node type: XMLDOM_ATTRDECL"); - case XMLDOM_CPELEM: /* 15 */ - rb_raise(rb_eRuntimeError, "unsupported XML node type: XMLDOM_CPELEM"); - case XMLDOM_CPCHOICE: /* 16 */ - rb_raise(rb_eRuntimeError, "unsupported XML node type: XMLDOM_CPCHOICE"); - case XMLDOM_CPSEQ: /* 17 */ - rb_raise(rb_eRuntimeError, "unsupported XML node type: XMLDOM_CPSEQ"); - case XMLDOM_CPPCDATA: /* 18 */ - rb_raise(rb_eRuntimeError, "unsupported XML node type: XMLDOM_CPPCDATA"); - case XMLDOM_CPSTAR: /* 19 */ - rb_raise(rb_eRuntimeError, "unsupported XML node type: XMLDOM_CPSTAR"); - case XMLDOM_CPPLUS: /* 20 */ - rb_raise(rb_eRuntimeError, "unsupported XML node type: XMLDOM_CPPLUS"); - case XMLDOM_CPOPT: /* 21 */ - rb_raise(rb_eRuntimeError, "unsupported XML node type: XMLDOM_CPOPT"); - case XMLDOM_CPEND: /* 22 */ - rb_raise(rb_eRuntimeError, "unsupported XML node type: XMLDOM_CPEND"); - } - rb_raise(rb_eRuntimeError, "unsupported XML node type: %d", nodetype); -} - -static VALUE oci8_make_element(struct xmlctx *xctx, xmlelemnode *elem) -{ - oratext *name; - VALUE obj; - - name = XmlDomGetTag(xctx, elem); - obj = rb_funcall(REXML_Element, oci8_id_new, 1, rb_str_new2_ora(name)); - add_attributes(obj, xctx, (xmlnode*)elem); - return add_child_nodes(obj, xctx, (xmlnode*)elem); -} - -static VALUE oci8_make_text(struct xmlctx *xctx, xmlnode *node) -{ - oratext *data = XmlDomGetCharData(xctx, node); - return rb_funcall(REXML_Text, oci8_id_new, 1, rb_str_new2_ora(data)); -} - -static VALUE oci8_make_cdata(struct xmlctx *xctx, xmlnode *node) -{ - oratext *data = XmlDomGetCharData(xctx, node); - return rb_funcall(REXML_CData, oci8_id_new, 1, rb_str_new2_ora(data)); -} - -static VALUE oci8_make_pi(struct xmlctx *xctx, xmlpinode *pi) -{ - oratext *target; - oratext *data; - - target= XmlDomGetPITarget(xctx, pi); - data = XmlDomGetPIData(xctx, pi); - return rb_funcall(REXML_Instruction, oci8_id_new, 2, rb_str_new2_ora(target), data ? rb_str_new2_ora(data) : Qnil); -} - -static VALUE oci8_make_comment(struct xmlctx *xctx, xmlnode *node) -{ - oratext *data = XmlDomGetCharData(xctx, node); - return rb_funcall(REXML_Comment, oci8_id_new, 1, rb_str_new2_ora(data)); -} - -static VALUE oci8_make_document(struct xmlctx *xctx, xmldocnode *doc) -{ - xmlerr err; - oratext *ver; - oratext *enc; - sb4 std; -#ifdef ENABLE_DTD - xmldtdnode* dtd; -#endif - VALUE obj; - VALUE decl; - - obj = rb_funcall(REXML_Document, oci8_id_new, 0); - err = XmlDomGetDecl(xctx, doc, &ver, &enc, &std); - if (err == XMLERR_OK) { - decl = rb_funcall(REXML_XMLDecl, oci8_id_new, 3, - ver ? rb_str_new2_ora(ver) : Qnil, - enc ? rb_str_new2_ora(enc) : Qnil, - (std < 0) ? Qnil : ((std > 0) ? rb_str_new2("yes") : rb_str_new2("no"))); - rb_funcall(obj, id_add, 1, decl); - } -#ifdef ENABLE_DTD - dtd = XmlDomGetDTD(xctx, doc); - if (dtd != NULL) { - rb_funcall(obj, id_add, 1, oci8_make_dtd(xctx, dtd)); - } -#endif - return add_child_nodes(obj, xctx, (xmlnode*)doc); -} - -static VALUE oci8_make_dtd(struct xmlctx *xctx, xmldtdnode *dtd) -{ - /* - * DTD support is not finished. - * I don't know how to get full dtd data from xmldtdnode. - */ - oratext *name; - oratext *pubid; - oratext *sysid; - xmlnamedmap *entities; - xmlnamedmap *notations; - VALUE obj; - - name = XmlDomGetDTDName(xctx, dtd); - pubid = XmlDomGetDTDPubID(xctx, dtd); - sysid = XmlDomGetDTDSysID(xctx, dtd); - entities = XmlDomGetDTDEntities(xctx, dtd); - notations = XmlDomGetDTDNotations(xctx, dtd); - - obj = rb_funcall(REXML_DocType, oci8_id_new, 1, rb_str_new2_ora(name)); - if (entities != NULL) - add_nodemap(obj, xctx, entities); - if (notations != NULL) - add_nodemap(obj, xctx, notations); - return obj; -} - -static VALUE add_child_nodes(VALUE obj, struct xmlctx *xctx, xmlnode *node) -{ - node = XmlDomGetFirstChild(xctx, node); - while (node != NULL) { - rb_funcall(obj, id_add, 1, oci8_make_rexml(xctx, node)); - node = XmlDomGetNextSibling(xctx, node); - } - return obj; -} - -static VALUE add_attributes(VALUE obj, struct xmlctx *xctx, xmlnode *node) -{ - xmlnamedmap *attrs; - xmlnode *attr; - oratext *name; - oratext *value; - ub4 num; - ub4 idx; - - attrs = XmlDomGetAttrs(xctx, node); - num = XmlDomGetNodeMapLength(xctx, attrs); - for (idx = 0; idx < num; idx++) { - attr = XmlDomGetNodeMapItem(xctx, attrs, idx); - name = XmlDomGetAttrName(xctx, attr); - value = XmlDomGetAttrValue(xctx, attr); - rb_funcall(obj, id_add_attribute, 2, - rb_str_new2_ora(name), - value ? rb_str_new2_ora(value) : Qnil); - } - return obj; -} - -static VALUE add_nodemap(VALUE obj, struct xmlctx *xctx, xmlnamedmap *map) -{ - xmlnode *node; - ub4 num; - ub4 idx; - - num = XmlDomGetNodeMapLength(xctx, map); - for (idx = 0; idx < num; idx++) { - node = XmlDomGetNodeMapItem(xctx, map, idx); - rb_funcall(obj, id_add, 1, oci8_make_rexml(xctx, node)); - } - return obj; -} - -#else -void Init_oci_xmldb(void) -{ -} - -VALUE oci8_make_rexml(struct xmlctx *xctx, xmlnode *node) -{ - rb_notimplement(); -} -#endif From nobody at rubyforge.org Sat Aug 27 09:21:15 2011 From: nobody at rubyforge.org (nobody at rubyforge.org) Date: Sat, 27 Aug 2011 09:21:15 -0400 (EDT) Subject: [ruby-oci8-commit] [446] trunk/ruby-oci8: refactoring for prior arrangement to properly release garbage sessions. Message-ID: <20110827132115.85CDF158806D@rubyforge.org> Revision: 446 Author: kubo Date: 2011-08-27 09:21:15 -0400 (Sat, 27 Aug 2011) Log Message: ----------- refactoring for prior arrangement to properly release garbage sessions. Modified Paths: -------------- trunk/ruby-oci8/ChangeLog trunk/ruby-oci8/ext/oci8/oci8.c trunk/ruby-oci8/ext/oci8/oci8.h Modified: trunk/ruby-oci8/ChangeLog =================================================================== --- trunk/ruby-oci8/ChangeLog 2011-08-27 08:51:45 UTC (rev 445) +++ trunk/ruby-oci8/ChangeLog 2011-08-27 13:21:15 UTC (rev 446) @@ -1,11 +1,15 @@ 2011-08-27 KUBO Takehiro - * ext/oci8/bind.c, ext/oci8/extconf.rb, ext/oci8/lob.c, ext/oci8/object.c, - ext/oci8/oci8.h, ext/oci8/oci8lib.c, ext/oci8/ocidatetime.c, - ext/oci8/ocinumber.c, ext/oci8/oradate.c, ext/oci8/stmt.c, - ext/oci8/xmldb.c: delete unused and unworkable features: dynamic fetch - and xmldb. + * ext/oci8/oci8.c, ext/oci8/oci8.h: refactoring for prior arrangement to + properly release garbage sessions. 2011-08-27 KUBO Takehiro + * ext/oci8/bind.c, ext/oci8/extconf.rb, ext/oci8/lob.c, ext/oci8/object.c, + ext/oci8/oci8.h, ext/oci8/oci8lib.c, ext/oci8/ocidatetime.c, + ext/oci8/ocinumber.c, ext/oci8/oradate.c, ext/oci8/stmt.c, + ext/oci8/xmldb.c: delete unused and unworkable features: dynamic fetch + and xmldb. + +2011-08-27 KUBO Takehiro * ext/oci8/bind.c, lib/oci8/bindtype.rb, lib/oci8/properties.rb: add OCI8.properties[:length_semantics]. Modified: trunk/ruby-oci8/ext/oci8/oci8.c =================================================================== --- trunk/ruby-oci8/ext/oci8/oci8.c 2011-08-27 08:51:45 UTC (rev 445) +++ trunk/ruby-oci8/ext/oci8/oci8.c 2011-08-27 13:21:15 UTC (rev 446) @@ -36,6 +36,8 @@ static VALUE cOCI8; static VALUE cSession; static VALUE cServer; +static ID id_at_session_handle; +static ID id_at_server_handle; typedef struct oci8_svcctx_associate { oci8_base_t base; @@ -44,17 +46,8 @@ static void oci8_svcctx_associate_free(oci8_base_t *base) { - oci8_svcctx_associate_t *assoc = (oci8_svcctx_associate_t *)base; - if (assoc->svcctx != NULL) { - switch (assoc->base.type) { - case OCI_HTYPE_SESSION: - assoc->svcctx->session = NULL; - break; - case OCI_HTYPE_SERVER: - assoc->svcctx->server = NULL; - break; - } - } + base->type = 0; + base->hp.ptr = NULL; } static oci8_base_class_t oci8_svcctx_associate_class = { @@ -63,41 +56,50 @@ sizeof(oci8_svcctx_associate_t), }; -static void oci8_svcctx_mark(oci8_base_t *base) +static void copy_session_handle(oci8_svcctx_t *svcctx) { - oci8_svcctx_t *svcctx = (oci8_svcctx_t *)base; + VALUE obj = rb_ivar_get(svcctx->base.self, id_at_session_handle); + oci8_base_t *base; - if (svcctx->session) { - rb_gc_mark(svcctx->session->self); - } - if (svcctx->server) { - rb_gc_mark(svcctx->server->self); - } + Check_Handle(obj, cSession, base); + base->type = OCI_HTYPE_SESSION; + base->hp.usrhp = svcctx->usrhp; } +static void copy_server_handle(oci8_svcctx_t *svcctx) +{ + VALUE obj = rb_ivar_get(svcctx->base.self, id_at_server_handle); + oci8_base_t *base; + + Check_Handle(obj, cServer, base); + base->type = OCI_HTYPE_SERVER; + base->hp.srvhp = svcctx->srvhp; +} + static void oci8_svcctx_free(oci8_base_t *base) { oci8_svcctx_t *svcctx = (oci8_svcctx_t *)base; - - if (svcctx->session) { - oci8_base_free(svcctx->session); - svcctx->session = NULL; + if (svcctx->logoff_method != NULL) { + /* TODO: not to block GC. */ + svcctx->logoff_method(svcctx); } - if (svcctx->server) { - oci8_base_free(svcctx->server); - svcctx->server = NULL; - } } static void oci8_svcctx_init(oci8_base_t *base) { oci8_svcctx_t *svcctx = (oci8_svcctx_t *)base; + VALUE obj; svcctx->executing_thread = Qnil; - svcctx->session = DATA_PTR(rb_obj_alloc(cSession)); - svcctx->server = DATA_PTR(rb_obj_alloc(cServer)); - ((oci8_svcctx_associate_t *)svcctx->session)->svcctx = svcctx; - ((oci8_svcctx_associate_t *)svcctx->server)->svcctx = svcctx; + /* set session handle */ + obj = rb_obj_alloc(cSession); + rb_ivar_set(base->self, id_at_session_handle, obj); + oci8_link_to_parent(DATA_PTR(obj), base); + /* set server handle */ + obj = rb_obj_alloc(cServer); + rb_ivar_set(base->self, id_at_server_handle, obj); + oci8_link_to_parent(DATA_PTR(obj), base); + svcctx->pid = getpid(); svcctx->is_autocommit = 0; #ifdef HAVE_RB_THREAD_BLOCKING_REGION @@ -107,7 +109,7 @@ } static oci8_base_class_t oci8_svcctx_class = { - oci8_svcctx_mark, + NULL, oci8_svcctx_free, sizeof(oci8_svcctx_t), oci8_svcctx_init, @@ -227,8 +229,6 @@ static void call_oci_logoff(oci8_svcctx_t *svcctx) { svcctx->logoff_method = NULL; - svcctx->session->type = 0; - svcctx->server->type = 0; oci_lc(OCILogoff_nb(svcctx, svcctx->base.hp.svc, oci8_errhp)); svcctx->base.type = 0; } @@ -238,13 +238,21 @@ sword rv = OCI_SUCCESS; if (svcctx->state & OCI8_STATE_SESSION_BEGIN_WAS_CALLED) { - rv = OCISessionEnd_nb(svcctx, svcctx->base.hp.svc, oci8_errhp, svcctx->session->hp.authhp, OCI_DEFAULT); + rv = OCISessionEnd_nb(svcctx, svcctx->base.hp.svc, oci8_errhp, svcctx->usrhp, OCI_DEFAULT); svcctx->state &= ~OCI8_STATE_SESSION_BEGIN_WAS_CALLED; } if (svcctx->state & OCI8_STATE_SERVER_ATTACH_WAS_CALLED) { - rv = OCIServerDetach_nb(svcctx, svcctx->server->hp.srvhp, oci8_errhp, OCI_DEFAULT); + rv = OCIServerDetach_nb(svcctx, svcctx->srvhp, oci8_errhp, OCI_DEFAULT); svcctx->state &= ~OCI8_STATE_SERVER_ATTACH_WAS_CALLED; } + if (svcctx->usrhp != NULL) { + OCIHandleFree(svcctx->usrhp, OCI_HTYPE_SESSION); + svcctx->usrhp = NULL; + } + if (svcctx->srvhp != NULL) { + OCIHandleFree(svcctx->srvhp, OCI_HTYPE_SERVER); + svcctx->srvhp = NULL; + } svcctx->logoff_method = NULL; if (rv != OCI_SUCCESS) { oci8_raise(oci8_errhp, rv, NULL); @@ -282,6 +290,15 @@ NIL_P(dbname) ? 0 : RSTRING_LEN(dbname))); svcctx->base.type = OCI_HTYPE_SVCCTX; svcctx->logoff_method = call_oci_logoff; + + /* setup the session handle */ + oci_lc(OCIAttrGet(svcctx->base.hp.ptr, OCI_HTYPE_SVCCTX, &svcctx->usrhp, 0, OCI_ATTR_SESSION, oci8_errhp)); + copy_session_handle(svcctx); + + /* setup the server handle */ + oci_lc(OCIAttrGet(svcctx->base.hp.ptr, OCI_HTYPE_SVCCTX, &svcctx->srvhp, 0, OCI_ATTR_SERVER, oci8_errhp)); + copy_server_handle(svcctx); + return Qnil; } @@ -312,16 +329,16 @@ svcctx->base.type = OCI_HTYPE_SVCCTX; /* alocalte a session handle */ - rv = OCIHandleAlloc(oci8_envhp, (void*)&svcctx->session->hp.ptr, OCI_HTYPE_SESSION, 0, 0); + rv = OCIHandleAlloc(oci8_envhp, (void*)&svcctx->usrhp, OCI_HTYPE_SESSION, 0, 0); if (rv != OCI_SUCCESS) oci8_env_raise(oci8_envhp, rv); - svcctx->session->type = OCI_HTYPE_SESSION; + copy_session_handle(svcctx); /* alocalte a server handle */ - rv = OCIHandleAlloc(oci8_envhp, (void*)&svcctx->server->hp.ptr, OCI_HTYPE_SERVER, 0, 0); + rv = OCIHandleAlloc(oci8_envhp, (void*)&svcctx->srvhp, OCI_HTYPE_SERVER, 0, 0); if (rv != OCI_SUCCESS) oci8_env_raise(oci8_envhp, rv); - svcctx->server->type = OCI_HTYPE_SERVER; + copy_server_handle(svcctx); return self; } @@ -335,8 +352,7 @@ */ static VALUE oci8_get_session_handle(VALUE self) { - oci8_svcctx_t *svcctx = oci8_get_svcctx(self); - return svcctx->session->self; + return rb_ivar_get(self, id_at_session_handle); } /* @@ -349,8 +365,7 @@ */ static VALUE oci8_get_server_handle(VALUE self) { - oci8_svcctx_t *svcctx = oci8_get_svcctx(self); - return svcctx->server->self; + return rb_ivar_get(self, id_at_server_handle); } /* @@ -379,12 +394,12 @@ Check_Type(mode, T_FIXNUM); /* attach to the server */ - oci_lc(OCIServerAttach_nb(svcctx, svcctx->server->hp.srvhp, oci8_errhp, + oci_lc(OCIServerAttach_nb(svcctx, svcctx->srvhp, oci8_errhp, NIL_P(dbname) ? NULL : RSTRING_ORATEXT(dbname), NIL_P(dbname) ? 0 : RSTRING_LEN(dbname), FIX2UINT(mode))); oci_lc(OCIAttrSet(svcctx->base.hp.ptr, OCI_HTYPE_SVCCTX, - svcctx->server->hp.srvhp, 0, OCI_ATTR_SERVER, + svcctx->srvhp, 0, OCI_ATTR_SERVER, oci8_errhp)); svcctx->state |= OCI8_STATE_SERVER_ATTACH_WAS_CALLED; return self; @@ -415,10 +430,10 @@ /* begin session */ oci_lc(OCISessionBegin_nb(svcctx, svcctx->base.hp.ptr, oci8_errhp, - svcctx->session->hp.authhp, FIX2UINT(cred), + svcctx->usrhp, FIX2UINT(cred), FIX2UINT(mode))); oci_lc(OCIAttrSet(svcctx->base.hp.ptr, OCI_HTYPE_SVCCTX, - svcctx->session->hp.authhp, 0, OCI_ATTR_SESSION, + svcctx->usrhp, 0, OCI_ATTR_SESSION, oci8_errhp)); svcctx->state |= OCI8_STATE_SESSION_BEGIN_WAS_CALLED; return Qnil; @@ -1022,6 +1037,8 @@ cOCI8 = oci8_define_class("OCI8", &oci8_svcctx_class); cSession = oci8_define_class_under(cOCI8, "Session", &oci8_svcctx_associate_class); cServer = oci8_define_class_under(cOCI8, "Server", &oci8_svcctx_associate_class); + id_at_session_handle = rb_intern("@session_handle"); + id_at_server_handle = rb_intern("@server_handle"); oracle_client_vernum = INT2FIX(oracle_client_version); if (have_OCIClientVersion) { @@ -1083,11 +1100,7 @@ OCISession *oci8_get_oci_session(VALUE obj) { oci8_svcctx_t *svcctx = oci8_get_svcctx(obj); - - if (svcctx->session->hp.authhp == NULL) { - oci_lc(OCIAttrGet(svcctx->base.hp.ptr, OCI_HTYPE_SVCCTX, &svcctx->session->hp.authhp, 0, OCI_ATTR_SESSION, oci8_errhp)); - } - return svcctx->session->hp.authhp; + return svcctx->usrhp; } void oci8_check_pid_consistency(oci8_svcctx_t *svcctx) Modified: trunk/ruby-oci8/ext/oci8/oci8.h =================================================================== --- trunk/ruby-oci8/ext/oci8/oci8.h 2011-08-27 08:51:45 UTC (rev 445) +++ trunk/ruby-oci8/ext/oci8/oci8.h 2011-08-27 13:21:15 UTC (rev 446) @@ -268,7 +268,7 @@ OCISvcCtx *svc; OCICPool *poolhp; OCIServer *srvhp; - OCISession *authhp; + OCISession *usrhp; OCIStmt *stmt; OCIDefine *dfn; OCIBind *bnd; @@ -305,8 +305,8 @@ oci8_base_t base; volatile VALUE executing_thread; void (*logoff_method)(struct oci8_svcctx *svcctx); - oci8_base_t *session; - oci8_base_t *server; + OCISession *usrhp; + OCIServer *srvhp; rb_pid_t pid; unsigned char state; char is_autocommit; From nobody at rubyforge.org Wed Aug 31 10:12:45 2011 From: nobody at rubyforge.org (nobody at rubyforge.org) Date: Wed, 31 Aug 2011 10:12:45 -0400 (EDT) Subject: [ruby-oci8-commit] [447] trunk/ruby-oci8: run connection-cleanup functions in a native thread to correctly release connections in GC . Message-ID: <20110831141245.76BCE158807A@rubyforge.org> Revision: 447 Author: kubo Date: 2011-08-31 10:12:45 -0400 (Wed, 31 Aug 2011) Log Message: ----------- run connection-cleanup functions in a native thread to correctly release connections in GC. Modified Paths: -------------- trunk/ruby-oci8/ChangeLog trunk/ruby-oci8/ext/oci8/env.c trunk/ruby-oci8/ext/oci8/extconf.rb trunk/ruby-oci8/ext/oci8/oci8.c trunk/ruby-oci8/ext/oci8/oci8.h trunk/ruby-oci8/ext/oci8/oci8lib.c Added Paths: ----------- trunk/ruby-oci8/ext/oci8/thread_util.c trunk/ruby-oci8/ext/oci8/thread_util.h Modified: trunk/ruby-oci8/ChangeLog =================================================================== --- trunk/ruby-oci8/ChangeLog 2011-08-27 13:21:15 UTC (rev 446) +++ trunk/ruby-oci8/ChangeLog 2011-08-31 14:12:45 UTC (rev 447) @@ -1,3 +1,9 @@ +2011-08-31 KUBO Takehiro + * ext/oci8/env.c, ext/oci8/extconf.rb, ext/oci8/oci8.c, ext/oci8/oci8.h, + ext/oci8/oci8lib.c, ext/oci8/thread_util.c, ext/oci8/thread_util.h: + run connection-cleanup functions in a native thread to correctly + release connections in GC. + 2011-08-27 KUBO Takehiro * ext/oci8/oci8.c, ext/oci8/oci8.h: refactoring for prior arrangement to properly release garbage sessions. Modified: trunk/ruby-oci8/ext/oci8/env.c =================================================================== --- trunk/ruby-oci8/ext/oci8/env.c 2011-08-27 13:21:15 UTC (rev 446) +++ trunk/ruby-oci8/ext/oci8/env.c 2011-08-31 14:12:45 UTC (rev 447) @@ -12,11 +12,7 @@ #include #endif -#ifdef HAVE_RB_THREAD_BLOCKING_REGION ub4 oci8_env_mode = OCI_OBJECT | OCI_THREADED; -#else -ub4 oci8_env_mode = OCI_OBJECT; -#endif OCIEnv *oci8_global_envhp; Modified: trunk/ruby-oci8/ext/oci8/extconf.rb =================================================================== --- trunk/ruby-oci8/ext/oci8/extconf.rb 2011-08-27 13:21:15 UTC (rev 446) +++ trunk/ruby-oci8/ext/oci8/extconf.rb 2011-08-31 14:12:45 UTC (rev 447) @@ -89,7 +89,7 @@ "stmt.o", "bind.o", "metadata.o", "attr.o", "lob.o", "oradate.o", "ocinumber.o", "ocidatetime.o", "object.o", "apiwrap.o", - "encoding.o", "oranumber_util.o"] + "encoding.o", "oranumber_util.o", "thread_util.o"] if RUBY_PLATFORM =~ /mswin32|cygwin|mingw32|bccwin32/ $defs << "-DUSE_WIN32_C" Modified: trunk/ruby-oci8/ext/oci8/oci8.c =================================================================== --- trunk/ruby-oci8/ext/oci8/oci8.c 2011-08-27 13:21:15 UTC (rev 446) +++ trunk/ruby-oci8/ext/oci8/oci8.c 2011-08-31 14:12:45 UTC (rev 447) @@ -6,6 +6,7 @@ * */ #include "oci8.h" +#include #ifdef HAVE_UNISTD_H #include /* getpid() */ #endif @@ -79,9 +80,21 @@ static void oci8_svcctx_free(oci8_base_t *base) { oci8_svcctx_t *svcctx = (oci8_svcctx_t *)base; - if (svcctx->logoff_method != NULL) { - /* TODO: not to block GC. */ - svcctx->logoff_method(svcctx); + if (svcctx->logoff_strategy != NULL) { + const oci8_logoff_strategy_t *strategy = svcctx->logoff_strategy; + void *data = strategy->prepare(svcctx); + int rv; + svcctx->base.type = 0; + svcctx->logoff_strategy = NULL; + rv = oci8_run_native_thread(strategy->execute, data); + if (rv != 0) { + errno = rv; +#ifdef WIN32 + rb_sys_fail("_beginthread"); +#else + rb_sys_fail("pthread_create"); +#endif + } } } @@ -226,39 +239,101 @@ return rb_ary_new3(4, user, pass, dbname, mode); } -static void call_oci_logoff(oci8_svcctx_t *svcctx) +/* + * Logoff strategy for sessions connected by OCILogon. + */ +typedef struct { + OCISvcCtx *svchp; + OCISession *usrhp; + OCIServer *srvhp; +} simple_logoff_arg_t; + +static void *simple_logoff_prepare(oci8_svcctx_t *svcctx) { - svcctx->logoff_method = NULL; - oci_lc(OCILogoff_nb(svcctx, svcctx->base.hp.svc, oci8_errhp)); - svcctx->base.type = 0; + simple_logoff_arg_t *sla = xmalloc(sizeof(simple_logoff_arg_t)); + sla->svchp = svcctx->base.hp.svc; + sla->usrhp = svcctx->usrhp; + sla->srvhp = svcctx->srvhp; + svcctx->usrhp = NULL; + svcctx->srvhp = NULL; + return sla; } -static void call_session_end(oci8_svcctx_t *svcctx) +static VALUE simple_logoff_execute(void *arg) { + simple_logoff_arg_t *sla = (simple_logoff_arg_t *)arg; + OCIError *errhp = oci8_errhp; + sword rv; + + OCITransRollback(sla->svchp, errhp, OCI_DEFAULT); + rv = OCILogoff(sla->svchp, errhp); + free(sla); + return (VALUE)rv; +} + +static const oci8_logoff_strategy_t simple_logoff = { + simple_logoff_prepare, + simple_logoff_execute, +}; + +/* + * Logoff strategy for sessions connected by OCIServerAttach and OCISessionBegin. + */ + +typedef struct { + OCISvcCtx *svchp; + OCISession *usrhp; + OCIServer *srvhp; + unsigned char state; +} complex_logoff_arg_t; + +static void *complex_logoff_prepare(oci8_svcctx_t *svcctx) +{ + complex_logoff_arg_t *cla = xmalloc(sizeof(complex_logoff_arg_t)); + cla->svchp = svcctx->base.hp.svc; + cla->usrhp = svcctx->usrhp; + cla->srvhp = svcctx->srvhp; + cla->state = svcctx->state; + svcctx->usrhp = NULL; + svcctx->srvhp = NULL; + svcctx->state = 0; + return cla; +} + +static VALUE complex_logoff_execute(void *arg) +{ + complex_logoff_arg_t *cla = (complex_logoff_arg_t *)arg; + OCIError *errhp = oci8_errhp; sword rv = OCI_SUCCESS; - if (svcctx->state & OCI8_STATE_SESSION_BEGIN_WAS_CALLED) { - rv = OCISessionEnd_nb(svcctx, svcctx->base.hp.svc, oci8_errhp, svcctx->usrhp, OCI_DEFAULT); - svcctx->state &= ~OCI8_STATE_SESSION_BEGIN_WAS_CALLED; + OCITransRollback(cla->svchp, errhp, OCI_DEFAULT); + + if (cla->state & OCI8_STATE_SESSION_BEGIN_WAS_CALLED) { + rv = OCISessionEnd(cla->svchp, oci8_errhp, cla->usrhp, OCI_DEFAULT); + cla->state &= ~OCI8_STATE_SESSION_BEGIN_WAS_CALLED; } - if (svcctx->state & OCI8_STATE_SERVER_ATTACH_WAS_CALLED) { - rv = OCIServerDetach_nb(svcctx, svcctx->srvhp, oci8_errhp, OCI_DEFAULT); - svcctx->state &= ~OCI8_STATE_SERVER_ATTACH_WAS_CALLED; + if (cla->state & OCI8_STATE_SERVER_ATTACH_WAS_CALLED) { + rv = OCIServerDetach(cla->srvhp, oci8_errhp, OCI_DEFAULT); + cla->state &= ~OCI8_STATE_SERVER_ATTACH_WAS_CALLED; } - if (svcctx->usrhp != NULL) { - OCIHandleFree(svcctx->usrhp, OCI_HTYPE_SESSION); - svcctx->usrhp = NULL; + if (cla->usrhp != NULL) { + OCIHandleFree(cla->usrhp, OCI_HTYPE_SESSION); } - if (svcctx->srvhp != NULL) { - OCIHandleFree(svcctx->srvhp, OCI_HTYPE_SERVER); - svcctx->srvhp = NULL; + if (cla->srvhp != NULL) { + OCIHandleFree(cla->srvhp, OCI_HTYPE_SERVER); } - svcctx->logoff_method = NULL; - if (rv != OCI_SUCCESS) { - oci8_raise(oci8_errhp, rv, NULL); + if (cla->svchp != NULL) { + OCIHandleFree(cla->svchp, OCI_HTYPE_SVCCTX); } + free(cla); + return (VALUE)rv; } +static const oci8_logoff_strategy_t complex_logoff = { + complex_logoff_prepare, + complex_logoff_execute, +}; + /* * call-seq: * logon(username, password, dbname) -> connection @@ -271,7 +346,7 @@ { oci8_svcctx_t *svcctx = DATA_PTR(self); - if (svcctx->logoff_method != NULL) { + if (svcctx->logoff_strategy != NULL) { rb_raise(rb_eRuntimeError, "Could not reuse the session."); } @@ -289,7 +364,7 @@ NIL_P(dbname) ? NULL : RSTRING_ORATEXT(dbname), NIL_P(dbname) ? 0 : RSTRING_LEN(dbname))); svcctx->base.type = OCI_HTYPE_SVCCTX; - svcctx->logoff_method = call_oci_logoff; + svcctx->logoff_strategy = &simple_logoff; /* setup the session handle */ oci_lc(OCIAttrGet(svcctx->base.hp.ptr, OCI_HTYPE_SVCCTX, &svcctx->usrhp, 0, OCI_ATTR_SESSION, oci8_errhp)); @@ -316,10 +391,10 @@ oci8_svcctx_t *svcctx = DATA_PTR(self); sword rv; - if (svcctx->logoff_method != NULL) { + if (svcctx->logoff_strategy != NULL) { rb_raise(rb_eRuntimeError, "Could not reuse the session."); } - svcctx->logoff_method = call_session_end; + svcctx->logoff_strategy = &complex_logoff; svcctx->state = 0; /* allocate a service context handle */ @@ -380,7 +455,7 @@ { oci8_svcctx_t *svcctx = oci8_get_svcctx(self); - if (svcctx->logoff_method != call_session_end) { + if (svcctx->logoff_strategy != &complex_logoff) { rb_raise(rb_eRuntimeError, "Use this method only for the service context handle created by OCI8#server_handle()."); } if (svcctx->state & OCI8_STATE_SERVER_ATTACH_WAS_CALLED) { @@ -417,7 +492,7 @@ { oci8_svcctx_t *svcctx = DATA_PTR(self); - if (svcctx->logoff_method != call_session_end) { + if (svcctx->logoff_strategy != &complex_logoff) { rb_raise(rb_eRuntimeError, "Use this method only for the service context handle created by OCI8#server_handle()."); } if (svcctx->state & OCI8_STATE_SESSION_BEGIN_WAS_CALLED) { @@ -453,9 +528,12 @@ while (svcctx->base.children != NULL) { oci8_base_free(svcctx->base.children); } - if (svcctx->logoff_method != NULL) { - oci_lc(OCITransRollback_nb(svcctx, svcctx->base.hp.svc, oci8_errhp, OCI_DEFAULT)); - svcctx->logoff_method(svcctx); + if (svcctx->logoff_strategy != NULL) { + const oci8_logoff_strategy_t *strategy = svcctx->logoff_strategy; + void *data = strategy->prepare(svcctx); + svcctx->base.type = 0; + svcctx->logoff_strategy = NULL; + oci_lc(oci8_blocking_region(svcctx, strategy->execute, data)); } return Qtrue; } @@ -519,10 +597,7 @@ #else sb1 non_blocking; - if (svcctx->server->hp.srvhp == NULL) { - oci_lc(OCIAttrGet(svcctx->base.hp.ptr, OCI_HTYPE_SVCCTX, &svcctx->server->hp.srvhp, 0, OCI_ATTR_SERVER, oci8_errhp)); - } - oci_lc(OCIAttrGet(svcctx->server->hp.srvhp, OCI_HTYPE_SERVER, &non_blocking, 0, OCI_ATTR_NONBLOCKING_MODE, oci8_errhp)); + oci_lc(OCIAttrGet(svcctx->srvhp, OCI_HTYPE_SERVER, &non_blocking, 0, OCI_ATTR_NONBLOCKING_MODE, oci8_errhp)); return non_blocking ? Qtrue : Qfalse; #endif } @@ -572,13 +647,10 @@ #else sb1 non_blocking; - if (svcctx->server->hp.srvhp == NULL) { - oci_lc(OCIAttrGet(svcctx->base.hp.ptr, OCI_HTYPE_SVCCTX, &svcctx->server->hp.srvhp, 0, OCI_ATTR_SERVER, oci8_errhp)); - } - oci_lc(OCIAttrGet(svcctx->server->hp.srvhp, OCI_HTYPE_SERVER, &non_blocking, 0, OCI_ATTR_NONBLOCKING_MODE, oci8_errhp)); + oci_lc(OCIAttrGet(svcctx->srvhp, OCI_HTYPE_SERVER, &non_blocking, 0, OCI_ATTR_NONBLOCKING_MODE, oci8_errhp)); if ((RTEST(val) && !non_blocking) || (!RTEST(val) && non_blocking)) { /* toggle blocking / non-blocking. */ - oci_lc(OCIAttrSet(svcctx->server->hp.srvhp, OCI_HTYPE_SERVER, 0, 0, OCI_ATTR_NONBLOCKING_MODE, oci8_errhp)); + oci_lc(OCIAttrSet(svcctx->srvhp, OCI_HTYPE_SERVER, 0, 0, OCI_ATTR_NONBLOCKING_MODE, oci8_errhp)); } #endif return val; Modified: trunk/ruby-oci8/ext/oci8/oci8.h =================================================================== --- trunk/ruby-oci8/ext/oci8/oci8.h 2011-08-27 13:21:15 UTC (rev 446) +++ trunk/ruby-oci8/ext/oci8/oci8.h 2011-08-31 14:12:45 UTC (rev 447) @@ -300,11 +300,12 @@ } u; }; +typedef struct oci8_logoff_strategy oci8_logoff_strategy_t; typedef struct oci8_svcctx { oci8_base_t base; volatile VALUE executing_thread; - void (*logoff_method)(struct oci8_svcctx *svcctx); + const oci8_logoff_strategy_t *logoff_strategy; OCISession *usrhp; OCIServer *srvhp; rb_pid_t pid; @@ -316,6 +317,11 @@ VALUE long_read_len; } oci8_svcctx_t; +struct oci8_logoff_strategy { + void *(*prepare)(oci8_svcctx_t *svcctx); + rb_blocking_function_t *execute; +}; + typedef struct { dvoid *hp; /* OCIBind* or OCIDefine* */ dvoid *valuep; @@ -540,6 +546,7 @@ #define OCI8SafeStringValue(v) SafeStringValue(v) #endif +#include "thread_util.h" #include "apiwrap.h" #endif Modified: trunk/ruby-oci8/ext/oci8/oci8lib.c =================================================================== --- trunk/ruby-oci8/ext/oci8/oci8lib.c 2011-08-27 13:21:15 UTC (rev 446) +++ trunk/ruby-oci8/ext/oci8/oci8lib.c 2011-08-31 14:12:45 UTC (rev 447) @@ -1,6 +1,6 @@ /* -*- c-file-style: "ruby"; indent-tabs-mode: nil -*- */ /* - * Copyright (C) 2002-2009 KUBO Takehiro + * Copyright (C) 2002-2011 KUBO Takehiro */ #include "oci8.h" @@ -90,6 +90,7 @@ rb_set_end_proc(at_exit_func, Qnil); #endif + Init_oci8_thread_util(); Init_oci8_error(); Init_oci8_env(); Added: trunk/ruby-oci8/ext/oci8/thread_util.c =================================================================== --- trunk/ruby-oci8/ext/oci8/thread_util.c (rev 0) +++ trunk/ruby-oci8/ext/oci8/thread_util.c 2011-08-31 14:12:45 UTC (rev 447) @@ -0,0 +1,81 @@ +/* -*- c-file-style: "ruby"; indent-tabs-mode: nil -*- */ +/* + * thread_util.c - part of ruby-oci8 + * + * Copyright (C) 2011 KUBO Takehiro + */ +#include "oci8.h" +#include + +#ifndef WIN32 +#include +static pthread_attr_t detached_thread_attr; +#endif + +typedef struct { + rb_blocking_function_t *func; + void *arg; +} adapter_arg_t; + +void Init_oci8_thread_util(void) +{ +#ifndef WIN32 + pthread_attr_init(&detached_thread_attr); + pthread_attr_setdetachstate(&detached_thread_attr, PTHREAD_CREATE_DETACHED); +#endif +} + +#ifdef WIN32 + +static void __cdecl adapter(void *arg) +{ + adapter_arg_t *aa = (adapter_arg_t *)arg; + aa->func(aa->arg); + free(aa); +} + +int oci8_run_native_thread(rb_blocking_function_t func, void *arg) +{ + adapter_arg_t *aa = malloc(sizeof(adapter_arg_t)); + if (aa == NULL) { + return ENOMEM; + } + + aa->func = func; + aa->arg = arg; + if (_beginthread(adapter, 0, aa) == (uintptr_t)-1L) { + int err = errno; + free(aa); + return err; + } + return 0; +} + +#else + +static void *adapter(void *arg) +{ + adapter_arg_t *aa = (adapter_arg_t *)arg; + aa->func(aa->arg); + free(aa); + return NULL; +} + +int oci8_run_native_thread(rb_blocking_function_t func, void *arg) +{ + pthread_t thread; + adapter_arg_t *aa = malloc(sizeof(adapter_arg_t)); + int rv; + if (aa == NULL) { + return ENOMEM; + } + + aa->func = func; + aa->arg = arg; + rv = pthread_create(&thread, &detached_thread_attr, adapter, aa); + if (rv != 0) { + free(aa); + } + return rv; +} +#endif Added: trunk/ruby-oci8/ext/oci8/thread_util.h =================================================================== --- trunk/ruby-oci8/ext/oci8/thread_util.h (rev 0) +++ trunk/ruby-oci8/ext/oci8/thread_util.h 2011-08-31 14:12:45 UTC (rev 447) @@ -0,0 +1,21 @@ +/* -*- c-file-style: "ruby"; indent-tabs-mode: nil -*- */ +/* + * thread_util.h - part of ruby-oci8 + * + * Copyright (C) 2011 KUBO Takehiro + */ +#ifndef NATIVE_THREAD_H + +/* + * Prepare to execute thread-related functions. + */ +void Init_oci8_thread_util(void); + +/* + * Run the func in a new native thread. + * Don't call any ruby functions in the func. + * The return value is errno. + */ +int oci8_run_native_thread(rb_blocking_function_t func, void *arg); + +#endif