[ruby-oci8-commit] [444] trunk/ruby-oci8: add OCI8.properties[:length_semantics].

nobody at rubyforge.org nobody at rubyforge.org
Sat Aug 27 04:13:29 EDT 2011


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  <kubo at jiubao.org>
+	* ext/oci8/bind.c, lib/oci8/bindtype.rb, lib/oci8/properties.rb: add
+	    OCI8.properties[:length_semantics].
+
 2011-08-23  KUBO Takehiro  <kubo at jiubao.org>
 	* 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 <kubo at jiubao.org>
+# Copyright (C) 2009-2011 KUBO Takehiro <kubo at jiubao.org>
 #++
 
 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+.




More information about the ruby-oci8-commit mailing list