ruby-oci8 2.0.4-x86-mingw32 → 2.0.5-x86-mingw32

Sign up to get free protection for your applications and to get access to all the features.
data/ChangeLog CHANGED
@@ -1,6 +1,163 @@
1
+ 2011-06-12 KUBO Takehiro <kubo@jiubao.org>
2
+ * NEWS: add changes between 2.0.4 and 2.0.5.
3
+ * VERSION: change the version to 2.0.5.
4
+
5
+ 2011-06-12 KUBO Takehiro <kubo@jiubao.org>
6
+ * ext/oci8/oci8lib.c: add __declspec(dllexport) to Init_oci8lib(). The mingw32
7
+ gcc compiler doesn't export functions without it if more than one function
8
+ is declared with it.
9
+ * ext/oci8/oraconf.rb: work around for rubinius 1.2.3, which doesn't support
10
+ Array#pack('P').
11
+ * lib/oci8/oci8.rb: fix a bug introduced by the previous commit.
12
+ * ext/oci8/env.c, ext/oci8/extconf.rb, ext/oci8/oci8.c, ext/oci8/oci8.h,
13
+ ext/oci8/oci8lib.c: Use HAVE_RB_THREAD_BLOCKING_REGION instead of
14
+ HAVE_TYPE_RB_BLOCKING_FUNCTION_T. have_type("rb_blocking_function_t", "ruby.h")
15
+ unexpectedly doesn't work on Visual Studio 2010.
16
+
17
+ 2011-06-10 KUBO Takehiro <kubo@jiubao.org>
18
+ * ext/oci8/apiwrap.yml, lib/oci8/oci8.rb: fix for Psych YAML library.
19
+ * ext/oci8/extconf.rb, ext/oci8/oci8.h, ext/oci8/ocihandle.c: fix to
20
+ work with ruby 1.9.3dev.
21
+
22
+ 2011-06-10 KUBO Takehiro <kubo@jiubao.org>
23
+ * ext/oci8/oci8.c: prevent GC on failed-logon connections from freeing
24
+ alive connections when the service context handle addresses are
25
+ accidentally same.
26
+ * ext/oci8/ocidatetime.c: raise "OCIError: ORA-01805: possible error in
27
+ date/time operation" when Oracle 11gR2's client and server timezone versions
28
+ are not same instead of raising a exception "undefined method `*' for
29
+ nil:NilClass." This is a temporary fix.
30
+ See: http://rubyforge.org/forum/forum.php?thread_id=49102&forum_id=1078
31
+
32
+ 2011-06-10 KUBO Takehiro <kubo@jiubao.org>
33
+ * ext/oci8/env.c, ext/oci8/oci8.h: Free OCI error handles on the
34
+ native thread termination, not on the ruby thread termination.
35
+ (reported by Jordan Curzon and Aaron Qian)
36
+ See: http://rubyforge.org/forum/forum.php?thread_id=49751&forum_id=1078
37
+
38
+ 2011-02-21 KUBO Takehiro <kubo@jiubao.org>
39
+ * ext/oci8/lob.c, ext/oci8/metadata.c, ext/oci8/oci8.c,
40
+ ext/oci8/oci8.h, ext/oci8/oci8lib.c, ext/oci8/stmt.c:
41
+ fix segmentation fault when calling OCI8::Cursor#[] for
42
+ closed statement object's (reported by Hugo L. Borges)
43
+
44
+ 2011-02-01 KUBO Takehiro <kubo@jiubao.org>
45
+ * ext/oci8/ocidatetime.c, lib/oci8/datetime.rb: rename
46
+ the name of the class to binding timestamp with time zone
47
+ from OCITimestamp to OCITimestampTZ. OCITimestamp will be
48
+ used for timestamp without time zone.
49
+
50
+ 2011-01-30 KUBO Takehiro <kubo@jiubao.org>
51
+ * ext/oci8/oraconf.rb: check Oracle client's cpu type on Solaris as
52
+ on Linux and Mac OS X. change error messages on Mac OS X to suggest
53
+ to set RC_ARCHS=x86_64 when mkmf.log contains messages such as
54
+ 'missing required architecture i386 in file.'
55
+
56
+ 2010-12-26 KUBO Takehiro <kubo@jiubao.org>
57
+ * ext/oci8/ocinumber.c, lib/oci8/bindtype.rb, test/test_oranumber.rb:
58
+ add OraNumber#has_decimal_part? and OCI8::BindType::BasicNumberType.
59
+
60
+ 2010-12-14 KUBO Takehiro <kubo@jiubao.org>
61
+ * dist-files, lib/oci8.rb.in, lib/oci8/.document, lib/oci8/properties.rb:
62
+ add OCI8.properties to get and set ruby-oci8 global setting.
63
+ * ext/oci8/bind.c, lib/oci8/bindtype.rb: fix NCHAR support and add
64
+ OCI8.properties[:bind_string_as_nchar] to control charset form (CHAR or NCHAR)
65
+ when binding string values.
66
+ See: http://rubyforge.org/forum/forum.php?thread_id=48838&forum_id=1078
67
+
68
+ 2010-12-04 KUBO Takehiro <kubo@jiubao.org>
69
+ * ext/oci8/object.c, ext/oci8/bind.c, lib/oci8/object.rb,
70
+ test/test_object.rb: fix a problem to assign NULL bind value
71
+ to object type bind variables.
72
+ (reported by Raimonds Simanovskis)
73
+ * ext/oci8/oraconf.rb: fix for 32-bit ruby compiled on
74
+ x86_64 linux. (reported by Jason Renschler)
75
+ * ext/oci8/oranumber_util.c, test/test_oranumber.rb:
76
+ suppress warning: unknown conversion type character 'h' in format
77
+
78
+ 2010-09-18 KUBO Takehiro <kubo@jiubao.org>
79
+ * ext/oci8/win32.c: undefine boolean to pass compilation on
80
+ Cygwin. (reported by Don Hill).
81
+ * lib/oci8/encoding-init.rb, lib/oci8/encoding.yml: add a
82
+ mapping from ZHT16HKSCS to Big5-HKSCS when the latter
83
+ is available in ruby.
84
+
85
+ 2010-09-12 KUBO Takehiro <kubo@jiubao.org>
86
+ * ext/oci8/env.c, ext/oci8/extconf.rb: suppress warning
87
+ 'use "ruby/util.h" instead of bare "util.h".'
88
+ * test/test_break.rb: make tests insensitive to execution timing.
89
+
90
+ 2010-09-10 KUBO Takehiro <kubo@jiubao.org>
91
+ * test/test_array_dml.rb: delete workaround code. It now works
92
+ fine on rubinius head.
93
+
94
+ 2010-09-07 KUBO Takehiro <kubo@jiubao.org>
95
+ * ext/oci8/extconf.rb, ext/oci8/oci8lib.c: Don't use
96
+ rb_set_end_proc() when it isn't available.
97
+ * ext/oci8/extconf.rb, lib/oci8.rb.in: add RUBY_ENGINE to
98
+ the C extension library name when RUBY_ENGINE is not "ruby."
99
+ * test/test_array_dml.rb: skip test_array_insert1 on rubinius.
100
+ This will be enabled after the rubinius issue #445 is fixed.
101
+
102
+ 2010-09-05 KUBO Takehiro <kubo@jiubao.org>
103
+ * ext/oci8/extconf.rb, ext/oci8/oci8.h, ext/oci8/oci8lib.c,
104
+ ext/oci8/ocinumber.c: use rb_intern() to retrieve IDs of '+', '-',
105
+ '*' and '/' on rubinus.
106
+ * ext/oci8/oradate.c: use rb_call_super() instead of
107
+ rb_obj_init_copy(), which is not declared in rubinus.
108
+
109
+ 2010-08-28 KUBO Takehiro <kubo@jiubao.org>
110
+ * ext/oci8/env.c: fix for rubinius.
111
+
112
+ 2010-08-28 KUBO Takehiro <kubo@jiubao.org>
113
+ * ext/oci8/env.c, ext/oci8/error.c, ext/oci8/extconf.rb, ext/oci8/oci8.c,
114
+ ext/oci8/oci8.h, oci8/oci8lib.c, ext/oci8/ocinumber.c: fix for rubinius.
115
+ Note that this is not enough to compile ruby-oci8 on it.
116
+
117
+ 2010-08-23 KUBO Takehiro <kubo@jiubao.org>
118
+ * lib/oci8/object.rb: fix an error when SDO_GEOMETRY is used
119
+ and $VERBOSE is set.
120
+ * test/test_oranumber.rb: change a testcase for ruby 1.9.2.
121
+ Math::atan2(0, 0) behaviour was changed in 1.9.2.
122
+
123
+ 2010-08-15 KUBO Takehiro <kubo@jiubao.org>
124
+ * ext/oci8/lob.c, ext/oci8/object.c, ext/oci8/oci8.h,
125
+ lib/oci8/object.rb: support LOB datatypes in Oracle objects.
126
+ (reported by Michael Sexton)
127
+ * ext/oci8/ocihandle.c: fix SEGV in finalizer when temporary LOBs
128
+ are used. This bug was introduced by the previous commit.
129
+
130
+ 2010-08-15 KUBO Takehiro <kubo@jiubao.org>
131
+ * ext/oci8/apiwrap.yml, ext/oci8/lob.c: fix memory leak when temporary
132
+ lobs are used.
133
+
134
+ 2010-08-14 KUBO Takehiro <kubo@jiubao.org>
135
+ * ext/oci8/bind.c: fix a bug that a string is bound to RAW.
136
+ Its encoding had been convertd to OCI.encoding incorrectly.
137
+ (backport from the trunk)
138
+ * ext/oci8/stmt.c: fix SEGV when an exception is raised while
139
+ a bind value is deallocated.
140
+ (backport from the trunk)
141
+
142
+ 2010-04-23 KUBO Takehiro <kubo@jiubao.org>
143
+ * ext/oci8/oranumber_util.c, test/test_oranumber.rb:
144
+ add limitted support for OraNumber's positive and negative
145
+ infinity. They are converted to '~' and '-~' respectively
146
+ as described in <URL:http://www.ixora.com.au/notes/infinity.htm>.
147
+
148
+ 2010-04-23 KUBO Takehiro <kubo@jiubao.org>
149
+ * Makefile: fix wrong dependencies in Makefile when running
150
+ 'make -jNNN (where NNN >= 2)'
151
+ (contributed by Alyano Alyanos. See bug #28129 on rubyforge.)
152
+
153
+ 2010-03-07 KUBO Takehiro <kubo@jiubao.org>
154
+ * ext/oci8/ocinumber.c: fix to compile on HP-UX.
155
+ Duplicate const qualifiers prevented HP-UX cc from compiling.
156
+ (reported by Sebastian YEPES)
157
+
1
158
  2010-02-28 KUBO Takehiro <kubo@jiubao.org>
2
159
  * NEWS: add changes between 2.0.3 and 2.0.4.
3
- * VERSION: change the version to 2.0.3.
160
+ * VERSION: change the version to 2.0.4.
4
161
  * ext/oci8/stmt.c: fix segmentation fault when OCI8::Cursor#fetch
5
162
  is called prior to OCI8::Cursor#exec.
6
163
  * ext/oci8/oci8.c: minor fix in rdoc comment.
data/Makefile CHANGED
@@ -4,12 +4,10 @@ RDOC = rdoc
4
4
 
5
5
  all: build
6
6
 
7
- build: config.save setup
8
-
9
7
  config.save: lib/oci8.rb.in
10
8
  $(RUBY) setup.rb config
11
9
 
12
- setup:
10
+ build: config.save
13
11
  $(RUBY) setup.rb setup
14
12
 
15
13
  check: build
data/NEWS CHANGED
@@ -1,3 +1,73 @@
1
+ 2.0.5:
2
+
3
+ * New Features
4
+
5
+ - Support Rubinius.
6
+
7
+ - OraNumber#has_decimal_part? -> boolean
8
+
9
+ OraNumber(10).has_decimal_part? # => false
10
+ OraNumber(10.1).has_decimal_part? # => true
11
+
12
+ - Limitted support for OraNumber's positive and negative infinity.
13
+
14
+ They are converted to '~' and '-~' respectively as described in
15
+ <URL:http://www.ixora.com.au/notes/infinity.htm>.
16
+
17
+ - OCI8.properties is added to control ruby-oci8 behaviour.
18
+ It supports :bind_string_as_nchar only for now.
19
+
20
+ - OCI8.properties[:bind_string_as_nchar] is added.
21
+
22
+ You need to set "OCI8.properties[:bind_string_as_nchar] = true"
23
+ if the database character set is not UTF-8 and NCHAR/NVARCHAR2 columns
24
+ contain characters which cannot be converted to the database character set.
25
+ See: http://rubyforge.org/forum/forum.php?thread_id=48838&forum_id=1078
26
+
27
+ * Fixed issues
28
+
29
+ - Fix InvalidHandle errors on Rails.
30
+ (reported by Jordan Curzon and Aaron Qian)
31
+ See: http://rubyforge.org/forum/forum.php?thread_id=49751&forum_id=1078
32
+
33
+ - Raise "OCIError: ORA-01805: possible error in date/time operation"
34
+ when Oracle 11gR2's client and server timezone versions are not same
35
+ instead of raising a exception "undefined method `*' for nil:NilClass."
36
+ See: http://rubyforge.org/forum/forum.php?thread_id=49102&forum_id=1078
37
+
38
+ - Fix unexpectedly disconnect when failed-logon connections is GC'ed
39
+ and the connection object's address is accidentally same with
40
+ an alive connection.
41
+
42
+ - Fix segmentation fault when calling OCI8::Cursor#[] for
43
+ closed statement object's (reported by Hugo L. Borges)
44
+
45
+ - Fix a bug that a string is bound to RAW.
46
+ Its encoding had been convertd to OCI.encoding incorrectly.
47
+
48
+ - Fix memory leaks when temporary lobs are used.
49
+
50
+ - Fix a problem to assign NULL bind value to object type bind variables.
51
+ (reported by Raimonds Simanovskis)
52
+
53
+ - Support LOB datatypes in object type.
54
+ (reported by Michael Sexton)
55
+
56
+ - Fix to compile on cygwin. The declaration of 'boolean' in Oracle
57
+ conflicts with that of latest cygwin.
58
+ (reported by Don Hill).
59
+
60
+ - Fix to complie for the 32-bit ruby which was compiled on x86_64 linux
61
+ and configured without '--build', '--host' nor '--target'.
62
+ The RUBY_PLATFORM is 'x86_64-linux' even though the ruby is 32-bit.
63
+ (reported by Jason Renschler)
64
+
65
+ - Fix wrong dependencies in Makefile when running 'make -jNNN (where NNN >= 2)'
66
+ (contributed by Alyano Alyanos. See bug #28129 on rubyforge.)
67
+
68
+ - Fix to compile on HP-UX. Duplicated const qualifiers prevented HP-UX cc
69
+ from compiling. (reported by Sebastian YEPES)
70
+
1
71
  2.0.4:
2
72
 
3
73
  * New Features
data/VERSION CHANGED
@@ -1 +1 @@
1
- 2.0.4
1
+ 2.0.5
data/dist-files CHANGED
@@ -55,6 +55,7 @@ lib/oci8/metadata.rb
55
55
  lib/oci8/object.rb
56
56
  lib/oci8/oci8.rb
57
57
  lib/oci8/oracle_version.rb
58
+ lib/oci8/properties.rb
58
59
  test/README
59
60
  test/config.rb
60
61
  test/test_all.rb
data/lib/oci8.rb CHANGED
@@ -18,14 +18,24 @@ if RUBY_PLATFORM =~ /cygwin/
18
18
  end
19
19
  end
20
20
 
21
+ so_basename = 'oci8lib_'
22
+ if defined? RUBY_ENGINE and RUBY_ENGINE != 'ruby'
23
+ so_basename += RUBY_ENGINE
24
+ end
25
+
26
+ # The suffix number indicates the ruby API version.
27
+ # 18 - ruby 1.8.x
28
+ # 191 - ruby 1.9.1 and 1.9.2
29
+ # 19x - ruby 1.9.x future version which will break the API compatibility
21
30
  case RUBY_VERSION
22
31
  when /^1\.9/
23
- require 'oci8lib_191'
32
+ so_basename += '191'
24
33
  when /^1\.8/
25
- require 'oci8lib_18'
34
+ so_basename += '18'
26
35
  else
27
36
  raise 'unsupported ruby version: ' + RUBY_VERSION
28
37
  end
38
+ require so_basename
29
39
 
30
40
  if OCI8.respond_to? :encoding
31
41
  if defined? DEFAULT_OCI8_ENCODING
@@ -75,8 +85,9 @@ require 'oci8/bindtype.rb'
75
85
  require 'oci8/metadata.rb'
76
86
  require 'oci8/compat.rb'
77
87
  require 'oci8/object.rb'
88
+ require 'oci8/properties.rb'
78
89
 
79
90
  class OCI8
80
- VERSION = '2.0.4'
91
+ VERSION = '2.0.5'
81
92
  CLIENT_VERSION = '1020'
82
93
  end
data/lib/oci8.rb.in CHANGED
@@ -18,14 +18,24 @@ if RUBY_PLATFORM =~ /cygwin/
18
18
  end
19
19
  end
20
20
 
21
+ so_basename = 'oci8lib_'
22
+ if defined? RUBY_ENGINE and RUBY_ENGINE != 'ruby'
23
+ so_basename += RUBY_ENGINE
24
+ end
25
+
26
+ # The suffix number indicates the ruby API version.
27
+ # 18 - ruby 1.8.x
28
+ # 191 - ruby 1.9.1 and 1.9.2
29
+ # 19x - ruby 1.9.x future version which will break the API compatibility
21
30
  case RUBY_VERSION
22
31
  when /^1\.9/
23
- require 'oci8lib_191'
32
+ so_basename += '191'
24
33
  when /^1\.8/
25
- require 'oci8lib_18'
34
+ so_basename += '18'
26
35
  else
27
36
  raise 'unsupported ruby version: ' + RUBY_VERSION
28
37
  end
38
+ require so_basename
29
39
 
30
40
  if OCI8.respond_to? :encoding
31
41
  if defined? DEFAULT_OCI8_ENCODING
@@ -75,6 +85,7 @@ require 'oci8/bindtype.rb'
75
85
  require 'oci8/metadata.rb'
76
86
  require 'oci8/compat.rb'
77
87
  require 'oci8/object.rb'
88
+ require 'oci8/properties.rb'
78
89
 
79
90
  class OCI8
80
91
  VERSION = '@@OCI8_MODULE_VERSION@@'
data/lib/oci8/.document CHANGED
@@ -3,3 +3,4 @@ object.rb
3
3
  metadata.rb
4
4
  oracle_version.rb
5
5
  oci8.rb
6
+ properties.rb
data/lib/oci8/bindtype.rb CHANGED
@@ -1,7 +1,7 @@
1
1
  #--
2
2
  # bindtype.rb -- OCI8::BindType
3
3
  #
4
- # Copyright (C) 2009 KUBO Takehiro <kubo@jiubao.org>
4
+ # Copyright (C) 2009-2010 KUBO Takehiro <kubo@jiubao.org>
5
5
  #++
6
6
 
7
7
  class OCI8
@@ -46,6 +46,12 @@ class OCI8
46
46
  end
47
47
  end
48
48
 
49
+ class BasicNumberType < OCI8::BindType::OraNumber
50
+ def get()
51
+ (val = super()) && (val.has_decimal_part? ? val.to_f : val.to_i)
52
+ end
53
+ end
54
+
49
55
  # get/set Number (for OCI8::SQLT_NUM)
50
56
  class Number
51
57
  def self.create(con, val, param, max_array_size)
@@ -116,6 +122,8 @@ class OCI8
116
122
  length = val.size
117
123
  end
118
124
  end
125
+ # use the default value when :nchar is not set explicitly.
126
+ nchar = OCI8.properties[:bind_string_as_nchar] unless param.has_key?(:nchar)
119
127
  when OCI8::Metadata::Base
120
128
  case param.data_type
121
129
  when :char, :varchar2
@@ -124,13 +132,18 @@ class OCI8
124
132
  # The length of a Japanese half-width kana is one in Shift_JIS,
125
133
  # two in EUC-JP, three in UTF-8.
126
134
  length *= 3 unless param.char_used?
135
+ nchar = (param.charset_form == :nchar)
127
136
  when :raw
128
137
  # HEX needs twice space.
129
138
  length = param.data_size * 2
130
139
  end
131
140
  end
132
141
  length = @@minimum_bind_length if length.nil? or length < @@minimum_bind_length
133
- self.new(con, val, length, max_array_size)
142
+ if nchar
143
+ OCI8::BindType::NCHAR.new(con, val, length, max_array_size)
144
+ else
145
+ OCI8::BindType::CHAR.new(con, val, length, max_array_size)
146
+ end
134
147
  end
135
148
  end
136
149
 
@@ -153,7 +166,7 @@ class OCI8
153
166
 
154
167
  class Long < OCI8::BindType::String
155
168
  def self.create(con, val, param, max_array_size)
156
- self.new(con, val, con.long_read_len, max_array_size)
169
+ super(con, val, {:length => con.long_read_len}, max_array_size)
157
170
  end
158
171
  end
159
172
 
data/lib/oci8/datetime.rb CHANGED
@@ -38,6 +38,14 @@ class OCI8
38
38
  @@time_new_accepts_timezone = false # prior to ruby 1.9.2
39
39
  end
40
40
 
41
+ begin
42
+ # 2001-01-01 00:00:59.999
43
+ ::DateTime.civil(2001, 1, 1, 0, 0, Rational(59_999, 1000), 0)
44
+ @@datetime_has_fractional_second_bug = false
45
+ rescue ArgumentError
46
+ @@datetime_has_fractional_second_bug = true
47
+ end
48
+
41
49
  def self.default_timezone
42
50
  @@default_timezone
43
51
  end
@@ -162,8 +170,8 @@ class OCI8
162
170
  return nil if ary.nil?
163
171
 
164
172
  year, month, day, hour, minute, sec, fsec, tz_hour, tz_min = ary
165
- if sec >= 59 and fsec != 0
166
- # convert to a DateTime via a String as a last resort.
173
+ if @@datetime_has_fractional_second_bug and sec >= 59 and fsec != 0
174
+ # convert to a DateTime via a String as a workaround
167
175
  if tz_hour >= 0 && tz_min >= 0
168
176
  sign = ?+
169
177
  else
@@ -245,7 +253,7 @@ class OCI8
245
253
  end
246
254
 
247
255
  if OCI8.oracle_client_version >= ORAVER_9_0
248
- class DateTimeViaOCITimestamp < OCI8::BindType::OCITimestamp # :nodoc:
256
+ class DateTimeViaOCITimestampTZ < OCI8::BindType::OCITimestampTZ # :nodoc:
249
257
  include OCI8::BindType::Util
250
258
 
251
259
  def set(val) # :nodoc:
@@ -257,7 +265,7 @@ class OCI8
257
265
  end
258
266
  end
259
267
 
260
- class TimeViaOCITimestamp < OCI8::BindType::OCITimestamp # :nodoc:
268
+ class TimeViaOCITimestampTZ < OCI8::BindType::OCITimestampTZ # :nodoc:
261
269
  include OCI8::BindType::Util
262
270
 
263
271
  def set(val) # :nodoc:
@@ -335,7 +343,7 @@ class OCI8
335
343
  if OCI8.oracle_client_version >= ORAVER_9_0
336
344
  def self.create(con, val, param, max_array_size) # :nodoc:
337
345
  if true # TODO: check Oracle server version
338
- DateTimeViaOCITimestamp.new(con, val, param, max_array_size)
346
+ DateTimeViaOCITimestampTZ.new(con, val, param, max_array_size)
339
347
  else
340
348
  DateTimeViaOCIDate.new(con, val, param, max_array_size)
341
349
  end
@@ -414,7 +422,7 @@ class OCI8
414
422
  if OCI8.oracle_client_version >= ORAVER_9_0
415
423
  def self.create(con, val, param, max_array_size) # :nodoc:
416
424
  if true # TODO: check Oracle server version
417
- TimeViaOCITimestamp.new(con, val, param, max_array_size)
425
+ TimeViaOCITimestampTZ.new(con, val, param, max_array_size)
418
426
  else
419
427
  TimeViaOCIDate.new(con, val, param, max_array_size)
420
428
  end
@@ -5,7 +5,8 @@
5
5
  # try to get NLS_LANG.
6
6
  nls_lang = ENV['NLS_LANG']
7
7
 
8
- if defined? OCI8::Win32Util
8
+ # if NLS_LANG is not set, get it from the Windows registry.
9
+ if nls_lang.nil? and defined? OCI8::Win32Util
9
10
  dll_path = OCI8::Win32Util.dll_path.upcase
10
11
  if dll_path =~ %r{\\BIN\\OCI.DLL}
11
12
  oracle_home = $`
@@ -33,6 +34,10 @@ if nls_lang
33
34
  if enc.nil?
34
35
  raise "Ruby encoding name is not found in encoding.yml for NLS_LANG #{nls_lang}."
35
36
  end
37
+ if enc.is_a? Array
38
+ # Use the first available encoding in the array.
39
+ enc = enc.find do |e| Encoding.find(e) rescue false; end
40
+ end
36
41
  else
37
42
  warn "Warning: NLS_LANG is not set. fallback to US-ASCII."
38
43
  enc = 'US-ASCII'
@@ -40,7 +40,7 @@ ZHS16GBK: GBK
40
40
  # MS Windows Code Page 950 with Hong Kong Supplementary Character
41
41
  # Set HKSCS-2001 (character set conversion to and from Unicode is
42
42
  # based on Unicode 3.0)
43
- ZHT16HKSCS: Big5 # Does the Big5 include HKSCS?
43
+ ZHT16HKSCS: [Big5-HKSCS, Big5]
44
44
 
45
45
  # MS Windows Code Page 950 Traditional Chinese
46
46
  ZHT16MSWIN950: Big5
@@ -166,7 +166,7 @@ ZHT16DBT: nil # FIXME
166
166
  # MS Windows Code Page 950 with Hong Kong Supplementary Character
167
167
  # Set HKSCS-2001 (character set conversion to and from Unicode is
168
168
  # based on Unicode 3.1)
169
- ZHT16HKSCS31: Big5 # Does the Big5 include HKSCS?
169
+ ZHT16HKSCS31: [Big5-HKSCS, Big5]
170
170
 
171
171
  # SOPS 32-bit Traditional Chinese
172
172
  ZHT32SOPS: nil # FIXME
data/lib/oci8/object.rb CHANGED
@@ -394,7 +394,7 @@ EOS
394
394
  @class_methods[type_method.name.downcase.intern] = result_type
395
395
  end
396
396
  else
397
- warn "unsupported return type (#{schema_name}.#{name}.#{type_method.name})" if $VERBOSE
397
+ warn "unsupported return type (#{metadata.schema_name}.#{metadata.name}.#{type_method.name})" if $VERBOSE
398
398
  end
399
399
  end
400
400
  end
@@ -457,6 +457,16 @@ EOS
457
457
  #[ATTR_NAMED_COLLECTION, [datatype, typeinfo], SIZE_OF_POINTER, 2, ALIGNMENT_OF_POINTER]
458
458
  tdo = con.get_tdo_by_metadata(metadata.type_metadata)
459
459
  [ATTR_NAMED_COLLECTION, tdo, tdo.val_size, tdo.ind_size, tdo.alignment]
460
+ when :clob
461
+ if metadata.charset_form != :nchar
462
+ [ATTR_CLOB, con, SIZE_OF_POINTER, 2, ALIGNMENT_OF_POINTER]
463
+ else
464
+ [ATTR_NCLOB, con, SIZE_OF_POINTER, 2, ALIGNMENT_OF_POINTER]
465
+ end
466
+ when :blob
467
+ [ATTR_BLOB, con, SIZE_OF_POINTER, 2, ALIGNMENT_OF_POINTER]
468
+ when :bfile
469
+ [ATTR_BFILE, con, SIZE_OF_POINTER, 2, ALIGNMENT_OF_POINTER]
460
470
  else
461
471
  raise "unsupported typecode #{metadata.typecode}"
462
472
  end
@@ -487,6 +497,7 @@ EOS
487
497
 
488
498
  class NamedType
489
499
  def to_value
500
+ return nil if self.null?
490
501
  obj = tdo.ruby_class.new
491
502
  obj.instance_variable_set(:@attributes, self.attributes)
492
503
  obj
@@ -503,20 +514,28 @@ EOS
503
514
  end
504
515
 
505
516
  def attributes=(obj)
506
- obj = obj.instance_variable_get(:@attributes) unless obj.is_a? Hash
507
- tdo.attributes.each do |attr|
508
- attr_val = obj[attr.name]
509
- attr_val = attr.set_proc.call(attr_val) if attr.set_proc
510
- set_attribute(attr.datatype, attr.typeinfo, attr.val_offset, attr.ind_offset, attr_val)
517
+ if obj.nil?
518
+ self.null = true
519
+ else
520
+ obj = obj.instance_variable_get(:@attributes) unless obj.is_a? Hash
521
+ tdo.attributes.each do |attr|
522
+ attr_val = obj[attr.name]
523
+ attr_val = attr.set_proc.call(attr_val) if attr.set_proc
524
+ set_attribute(attr.datatype, attr.typeinfo, attr.val_offset, attr.ind_offset, attr_val)
525
+ end
526
+ self.null = false
511
527
  end
512
528
  end
513
529
  end
514
530
 
515
531
  class NamedCollection
516
532
  def to_value
517
- obj = tdo.ruby_class.new
518
- obj.instance_variable_set(:@attributes, self.attributes)
519
- obj
533
+ attr = self.attributes
534
+ if attr
535
+ obj = tdo.ruby_class.new
536
+ obj.instance_variable_set(:@attributes, attr)
537
+ obj
538
+ end
520
539
  end
521
540
 
522
541
  def attributes
data/lib/oci8/oci8.rb CHANGED
@@ -8,6 +8,7 @@
8
8
  #
9
9
 
10
10
  require 'date'
11
+ require 'yaml'
11
12
 
12
13
  # A connection to a Oracle database server.
13
14
  #
@@ -543,13 +544,28 @@ class OraDate
543
544
  end
544
545
 
545
546
  class OraNumber
546
- def yaml_initialize(type, val) # :nodoc:
547
- initialize(val)
548
- end
549
547
 
550
- def to_yaml(opts = {}) # :nodoc:
551
- YAML.quick_emit(object_id, opts) do |out|
552
- out.scalar(taguri, self.to_s, :plain)
548
+ if defined? Psych and YAML == Psych
549
+
550
+ yaml_tag '!ruby/object:OraNumber'
551
+ def encode_with coder # :nodoc:
552
+ coder.scalar = self.to_s
553
+ end
554
+
555
+ def init_with coder # :nodoc:
556
+ initialize(coder.scalar)
557
+ end
558
+
559
+ else
560
+
561
+ def yaml_initialize(type, val) # :nodoc:
562
+ initialize(val)
563
+ end
564
+
565
+ def to_yaml(opts = {}) # :nodoc:
566
+ YAML.quick_emit(object_id, opts) do |out|
567
+ out.scalar(taguri, self.to_s, :plain)
568
+ end
553
569
  end
554
570
  end
555
571
 
@@ -0,0 +1,50 @@
1
+ # properties.rb -- implements OCI8.properties
2
+ #
3
+ # Copyright (C) 2010 KUBO Takehiro <kubo@jiubao.org>
4
+
5
+ class OCI8
6
+
7
+ @@properties = {
8
+ :bind_string_as_nchar => false,
9
+ }
10
+
11
+ def @@properties.[](name)
12
+ raise IndexError, "No such property name: #{name}" unless @@properties.has_key?(name)
13
+ super(name)
14
+ end
15
+
16
+ def @@properties.[]=(name, val)
17
+ raise IndexError, "No such property name: #{name}" unless @@properties.has_key?(name)
18
+ case name
19
+ when :bind_string_as_nchar
20
+ val = val ? true : false
21
+ end
22
+ super(name, val)
23
+ end
24
+
25
+ # call-seq:
26
+ # OCI8.properties -> a customized Hash
27
+ #
28
+ # (new in 2.0.5)
29
+ #
30
+ # Returns a Hash which ruby-oci8 global settings.
31
+ # The hash's setter and getter methods are customized to check
32
+ # property names and values.
33
+ #
34
+ # # get properties
35
+ # OCI8.properties[:bind_string_as_nchar] # => false
36
+ # OCI8.properties[:invalid_property_name] # raises an IndexError
37
+ #
38
+ # # set properties
39
+ # OCI8.properties[:bind_string_as_nchar] = true
40
+ # OCI8.properties[:invalid_property_name] = true # raises an IndexError
41
+ #
42
+ # Supported properties are listed below:
43
+ #
44
+ # [:bind_string_as_nchar]
45
+ # +true+ when string bind variables are bound as NCHAR,
46
+ # otherwise +false+. The default value is +false+.
47
+ def self.properties
48
+ @@properties
49
+ end
50
+ end
data/lib/oci8lib_18.so CHANGED
Binary file
data/lib/oci8lib_191.so CHANGED
Binary file
data/test/test_break.rb CHANGED
@@ -23,23 +23,22 @@ class TestBreak < Test::Unit::TestCase
23
23
 
24
24
  TIME_IN_PLSQL = 5
25
25
  TIME_TO_BREAK = 2
26
- MARGIN = 0.1
27
26
 
28
27
  def do_test_ocibreak(conn, expect)
29
28
  $start_time = Time.now
30
29
 
31
30
  th = Thread.start do
32
31
  begin
33
- conn.exec("BEGIN DBMS_LOCK.SLEEP(#{TIME_IN_PLSQL}); END;")
34
- assert_equal(expect[PLSQL_DONE], (Time.now - $start_time + MARGIN).to_i, 'PLSQL_DONE')
32
+ conn.exec("BEGIN DBMS_LOCK.SLEEP(#{TIME_IN_PLSQL}); END;")
33
+ assert_equal(expect[PLSQL_DONE], (Time.now - $start_time).round, 'PLSQL_DONE')
35
34
  rescue OCIBreak
36
- assert_equal(expect[OCIBREAK], (Time.now - $start_time + MARGIN).to_i, 'OCIBREAK')
35
+ assert_equal(expect[OCIBREAK], (Time.now - $start_time).round, 'OCIBREAK')
37
36
  end
38
37
  end
39
38
 
40
- sleep(0.01) # make a time to run DBMS_LOCK.SLEEP
41
- sleep(TIME_TO_BREAK)
42
- assert_equal(expect[SEND_BREAK], (Time.now - $start_time + MARGIN).to_i, 'SEND_BREAK')
39
+ sleep(0.3) # Wait until DBMS_LOCK.SLEEP is running.
40
+ sleep(TIME_TO_BREAK - 0.3)
41
+ assert_equal(expect[SEND_BREAK], (Time.now - $start_time).round, 'SEND_BREAK')
43
42
  conn.break()
44
43
  th.join
45
44
  end
@@ -125,6 +125,33 @@ class TestOraNumber < Test::Unit::TestCase
125
125
  val = $1+'.'+$2 if /(-?)0\.(.*)/ =~ val
126
126
  assert_equal(val, cursor[:out])
127
127
  end
128
+ # Infinity and -Infinity
129
+ ['~', '-~'].each do |val|
130
+ cursor[:in] = OraNumber.new(val)
131
+ cursor.exec
132
+ assert_equal(val, cursor[:out])
133
+ end
134
+ if OCI8::oracle_client_version >= OCI8::ORAVER_10_1
135
+ cursor = conn.parse(<<EOS)
136
+ BEGIN
137
+ IF (:in_oranum = CAST(:in_binary_double AS NUMBER)) THEN
138
+ :result := 'match';
139
+ ELSE
140
+ :result := 'unmatch';
141
+ END IF;
142
+ END;
143
+ EOS
144
+ cursor.bind_param(:in_oranum, nil, OraNumber)
145
+ cursor.bind_param(:in_binary_double, nil, :binary_double)
146
+ cursor.bind_param(:result, nil, String, 7)
147
+ [['~', 1.0/0.0], ['-~', -1.0/0.0]].each do |val|
148
+ cursor[:in_oranum] = OraNumber.new(val[0])
149
+ cursor[:in_binary_double] = val[1]
150
+ cursor.exec
151
+ assert_equal(cursor[:result], 'match')
152
+ end
153
+ end
154
+
128
155
  ensure
129
156
  conn.logoff
130
157
  end
@@ -142,13 +169,39 @@ class TestOraNumber < Test::Unit::TestCase
142
169
  cursor.exec
143
170
  assert_equal(OraNumber.new(val), cursor[:out])
144
171
  end
172
+ # Infinity and -Infinity
173
+ if OCI8::oracle_client_version >= OCI8::ORAVER_10_1
174
+ cursor = conn.parse("BEGIN :out := CAST(:in AS NUMBER); END;")
175
+ cursor.bind_param(:out, OraNumber)
176
+ cursor.bind_param(:in, nil, :binary_double)
177
+ [['~', 1.0/0.0], ['-~', -1.0/0.0]].each do |val|
178
+ cursor[:in] = val[1]
179
+ cursor.exec
180
+ assert_equal(OraNumber.new(val[0]), cursor[:out])
181
+ end
182
+ end
183
+ ensure
184
+ conn.logoff
185
+ end
186
+ end
187
+
188
+ def test_bind_basic_number_type
189
+ conn = get_oci8_connection
190
+ bind_type = OCI8::BindType::Mapping[:number]
191
+ begin
192
+ OCI8::BindType::Mapping[:number] = OCI8::BindType::BasicNumberType
193
+ assert_kind_of(NilClass, conn.select_one('select CAST(NULL AS NUMBER) from dual')[0])
194
+ assert_kind_of(Integer, conn.select_one('select 0.0 from dual')[0])
195
+ assert_kind_of(Integer, conn.select_one('select 10.0 from dual')[0])
196
+ assert_kind_of(Float, conn.select_one('select 10.1 from dual')[0])
145
197
  ensure
146
198
  conn.logoff
199
+ OCI8::BindType::Mapping[:number] = bind_type
147
200
  end
148
201
  end
149
202
 
150
203
  def test_dup
151
- LARGE_RANGE_VALUES.each do |x|
204
+ (LARGE_RANGE_VALUES + ['~', '-~']).each do |x|
152
205
  n = OraNumber.new(x)
153
206
  assert_equal(n, n.dup)
154
207
  assert_equal(n, n.clone)
@@ -156,14 +209,14 @@ class TestOraNumber < Test::Unit::TestCase
156
209
  end
157
210
 
158
211
  def test_marshal
159
- LARGE_RANGE_VALUES.each do |x|
212
+ (LARGE_RANGE_VALUES + ['~', '-~']).each do |x|
160
213
  n = OraNumber.new(x)
161
214
  assert_equal(n, Marshal.load(Marshal.dump(n)))
162
215
  end
163
216
  end
164
217
 
165
218
  def test_yaml
166
- LARGE_RANGE_VALUES.each do |x|
219
+ (LARGE_RANGE_VALUES + ['~', '-~']).each do |x|
167
220
  n = OraNumber.new(x)
168
221
  assert_equal(n, YAML.load(YAML.dump(n)))
169
222
  end
@@ -200,11 +253,28 @@ class TestOraNumber < Test::Unit::TestCase
200
253
 
201
254
  # OCI8::Math.atan2(y, x) -> ocinumber
202
255
  def test_math_atan2
256
+ # Prior to ruby 1.9.2:
257
+ # Following method calls' return values depend on the underneath C library
258
+ # implementation.
259
+ #
260
+ # Math::atan2(+0.0, +0.0)
261
+ # Math::atan2(-0.0, +0.0)
262
+ # Math::atan2(+0.0, -0.0)
263
+ # Math::atan2(-0.0, -0.0)
264
+ #
265
+ # They are +0.0, -0.0, +PI and -PI respectively as far as I checked them on
266
+ # Windows and Linux.
267
+ #
268
+ # After ruby 1.9.2:
269
+ # They all raise a Math::DomainError exception.
270
+ #
271
+ # In contrast to Math::atan2, OCI8::Math::atan2(0, 0) allways returns 0 because
272
+ # OraNumber doesn't have the difference between +0 and -0.
203
273
  compare_with_float2(SMALL_RANGE_VALUES, SMALL_RANGE_VALUES,
204
- Proc.new {|x, y| Math::atan2(x, y.to_f)},
274
+ Proc.new {|x, y| (x.to_f == 0 && y.to_f == 0) ? 0 : Math::atan2(x, y.to_f)},
205
275
  Proc.new {|x, y| OCI8::Math::atan2(x, y.to_f)})
206
276
  compare_with_float2(SMALL_RANGE_VALUES, SMALL_RANGE_VALUES,
207
- Proc.new {|x, y| Math::atan2(y.to_f, x)},
277
+ Proc.new {|x, y| (x.to_f == 0 && y.to_f == 0) ? 0 : Math::atan2(y.to_f, x)},
208
278
  Proc.new {|x, y| OCI8::Math::atan2(y.to_f, x)})
209
279
  end
210
280
 
@@ -652,4 +722,25 @@ class TestOraNumber < Test::Unit::TestCase
652
722
  assert_equal(ary[1], OraNumber.new(ary[0]).to_s)
653
723
  end
654
724
  end
725
+
726
+ def test_dump
727
+ conn = get_oci8_connection
728
+ begin
729
+ cursor = conn.parse("select dump(to_number(:1)) from dual")
730
+ cursor.bind_param(1, nil, String, 40)
731
+ LARGE_RANGE_VALUES.each do |val|
732
+ cursor[1] = val
733
+ cursor.exec
734
+ assert_equal(cursor.fetch[0], OraNumber.new(val).dump)
735
+ end
736
+ ensure
737
+ conn.logoff
738
+ end
739
+ LARGE_RANGE_VALUES
740
+ end
741
+
742
+ def test_has_decimal_part
743
+ assert_equal(false, OraNumber(10.0).has_decimal_part?)
744
+ assert_equal(true, OraNumber(10.1).has_decimal_part?)
745
+ end
655
746
  end
metadata CHANGED
@@ -1,7 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ruby-oci8
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.4
4
+ hash: 5
5
+ prerelease: false
6
+ segments:
7
+ - 2
8
+ - 0
9
+ - 5
10
+ version: 2.0.5
5
11
  platform: x86-mingw32
6
12
  authors:
7
13
  - KUBO Takehiro
@@ -9,7 +15,7 @@ autorequire:
9
15
  bindir: bin
10
16
  cert_chain: []
11
17
 
12
- date: 2010-02-28 00:00:00 +09:00
18
+ date: 2011-06-12 00:00:00 +09:00
13
19
  default_executable:
14
20
  dependencies: []
15
21
 
@@ -52,6 +58,7 @@ files:
52
58
  - lib/oci8/object.rb
53
59
  - lib/oci8/oci8.rb
54
60
  - lib/oci8/oracle_version.rb
61
+ - lib/oci8/properties.rb
55
62
  - test/README
56
63
  - test/config.rb
57
64
  - test/test_all.rb
@@ -86,21 +93,29 @@ rdoc_options:
86
93
  require_paths:
87
94
  - lib
88
95
  required_ruby_version: !ruby/object:Gem::Requirement
96
+ none: false
89
97
  requirements:
90
98
  - - ">="
91
99
  - !ruby/object:Gem::Version
100
+ hash: 55
101
+ segments:
102
+ - 1
103
+ - 8
104
+ - 0
92
105
  version: 1.8.0
93
- version:
94
106
  required_rubygems_version: !ruby/object:Gem::Requirement
107
+ none: false
95
108
  requirements:
96
109
  - - ">="
97
110
  - !ruby/object:Gem::Version
111
+ hash: 3
112
+ segments:
113
+ - 0
98
114
  version: "0"
99
- version:
100
115
  requirements: []
101
116
 
102
117
  rubyforge_project: ruby-oci8
103
- rubygems_version: 1.3.5
118
+ rubygems_version: 1.3.7
104
119
  signing_key:
105
120
  specification_version: 3
106
121
  summary: Ruby interface for Oracle using OCI8 API