[ruby-oci8-commit] [336] trunk/ruby-oci8: * lib/oci8/oci8.rb, test/test_encoding.rb: The string bind length should

nobody at rubyforge.org nobody at rubyforge.org
Sun Apr 12 09:00:56 EDT 2009


Revision: 336
Author:   kubo
Date:     2009-04-12 09:00:56 -0400 (Sun, 12 Apr 2009)

Log Message:
-----------
* lib/oci8/oci8.rb, test/test_encoding.rb: The string bind length should
    be got from the string bytesize converted to OCI8.encoding.

Modified Paths:
--------------
    trunk/ruby-oci8/ChangeLog
    trunk/ruby-oci8/lib/oci8/oci8.rb
    trunk/ruby-oci8/test/test_encoding.rb

Modified: trunk/ruby-oci8/ChangeLog
===================================================================
--- trunk/ruby-oci8/ChangeLog	2009-04-12 09:03:24 UTC (rev 335)
+++ trunk/ruby-oci8/ChangeLog	2009-04-12 13:00:56 UTC (rev 336)
@@ -1,4 +1,8 @@
 2009-04-12  KUBO Takehiro  <kubo at jiubao.org>
+	* lib/oci8/oci8.rb, test/test_encoding.rb: The string bind length should
+	    be got from the string bytesize converted to OCI8.encoding.
+
+2009-04-12  KUBO Takehiro  <kubo at jiubao.org>
 	* ext/oci8/lob.c: OCI8::BLOB#read should return ASCII-8BIT.
 	    OCI8::BLOB#write should not convert the specified string
 	    to OCI8.encoding.

Modified: trunk/ruby-oci8/lib/oci8/oci8.rb
===================================================================
--- trunk/ruby-oci8/lib/oci8/oci8.rb	2009-04-12 09:03:24 UTC (rev 335)
+++ trunk/ruby-oci8/lib/oci8/oci8.rb	2009-04-12 13:00:56 UTC (rev 336)
@@ -218,15 +218,36 @@
     end
 
     class String
+      # 1333 <= ceil(4000 / 3). 4000 is max size of char. 3 is NLS ratio of UTF-8.
+      @@minimum_bind_length = 1333
+
+      def self.minimum_bind_length
+        @@minimum_bind_length
+      end
+
+      def self.minimum_bind_length=(val)
+        @@minimum_bind_length = val
+      end
+
       def self.create(con, val, param, max_array_size)
         case param
         when Hash
-          # 1333 = ceil(4000 (max size of char) / 3 (NLS ratio of UTF8))
-          length = 1333 # default length
           if param[:length]
+            # If length is passed explicitly, use it.
             length = param[:length]
-          elsif val.respond_to? :to_str and val.to_str.size > length
-            length = val.to_str.size
+          elsif val.is_a? String or (val.respond_to? :to_str and val = val.to_str)
+            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.
+              val = val.encode(OCI8.encoding)
+            end
+            if val.respond_to? :bytesize
+              # ruby 1.8.7 or upper
+              length = val.bytesize
+            else
+              # ruby 1.8.6 or lower
+              length = val.size
+            end
           end
         when OCI8::Metadata::Base
           case param.data_type
@@ -239,10 +260,9 @@
           when :raw
             # HEX needs twice space.
             length = param.data_size * 2
-          else
-            length = 100
           end
         end
+        length = @@minimum_bind_length if length.nil? or length < @@minimum_bind_length
         self.new(con, val, length, max_array_size)
       end
     end

Modified: trunk/ruby-oci8/test/test_encoding.rb
===================================================================
--- trunk/ruby-oci8/test/test_encoding.rb	2009-04-12 09:03:24 UTC (rev 335)
+++ trunk/ruby-oci8/test/test_encoding.rb	2009-04-12 13:00:56 UTC (rev 336)
@@ -71,6 +71,29 @@
     drop_table('test_table')
   end
 
+  if OCI8.encoding.name == "UTF-8"
+    def test_bind_string_with_code_conversion
+      drop_table('test_table')
+      @conn.exec(<<EOS)
+CREATE TABLE test_table
+  (V VARCHAR2(3000))
+STORAGE (
+   INITIAL 4k
+   NEXT 4k
+   MINEXTENTS 1
+   MAXEXTENTS UNLIMITED
+   PCTINCREASE 0)
+EOS
+      utf_8 = "\u00A1" * 1500 # 3000 byte
+      iso_8859_1 = utf_8.encode("ISO-8859-1") # 1500 byte
+      @conn.exec("INSERT INTO test_table VALUES (:1)", iso_8859_1)
+      @conn.exec("SELECT * FROM test_table") do |row|
+        assert_equal(utf_8, row[0])
+      end
+      drop_table('test_table')
+    end
+  end
+
   def teardown
     @conn.logoff
   end




More information about the ruby-oci8-commit mailing list