[ruby-oci8-commit] [419] trunk/ruby-oci8: * dist-files, lib/oci8.rb.in, lib/oci8/.document, lib/oci8/properties.rb:

nobody at rubyforge.org nobody at rubyforge.org
Tue Dec 14 06:30:44 EST 2010


Revision: 419
Author:   kubo
Date:     2010-12-14 06:30:44 -0500 (Tue, 14 Dec 2010)

Log Message:
-----------
* dist-files, lib/oci8.rb.in, lib/oci8/.document, lib/oci8/properties.rb:
    add OCI8.properties to get and set ruby-oci8 global setting.
* ext/oci8/bind.c, lib/oci8/bindtype.rb: fix NCHAR support and add
    OCI8.properties[:bind_string_as_nchar] to control charset form (CHAR or NCHAR)
    when binding string values.
    See: http://rubyforge.org/forum/forum.php?thread_id=48838&forum_id=1078

Modified Paths:
--------------
    branches/ruby-oci8-2.0/ChangeLog
    branches/ruby-oci8-2.0/dist-files
    branches/ruby-oci8-2.0/ext/oci8/bind.c
    branches/ruby-oci8-2.0/lib/oci8/.document
    branches/ruby-oci8-2.0/lib/oci8/bindtype.rb
    branches/ruby-oci8-2.0/lib/oci8.rb.in
    trunk/ruby-oci8/ChangeLog
    trunk/ruby-oci8/dist-files
    trunk/ruby-oci8/ext/oci8/bind.c
    trunk/ruby-oci8/lib/oci8/.document
    trunk/ruby-oci8/lib/oci8/bindtype.rb
    trunk/ruby-oci8/lib/oci8.rb.in

Added Paths:
-----------
    branches/ruby-oci8-2.0/lib/oci8/properties.rb
    trunk/ruby-oci8/lib/oci8/properties.rb

Modified: branches/ruby-oci8-2.0/ChangeLog
===================================================================
--- branches/ruby-oci8-2.0/ChangeLog	2010-12-04 12:49:51 UTC (rev 418)
+++ branches/ruby-oci8-2.0/ChangeLog	2010-12-14 11:30:44 UTC (rev 419)
@@ -1,3 +1,11 @@
+2010-12-14  KUBO Takehiro  <kubo at jiubao.org>
+	* dist-files, lib/oci8.rb.in, lib/oci8/.document, lib/oci8/properties.rb:
+	    add OCI8.properties to get and set ruby-oci8 global setting.
+	* ext/oci8/bind.c, lib/oci8/bindtype.rb: fix NCHAR support and add
+	    OCI8.properties[:bind_string_as_nchar] to control charset form (CHAR or NCHAR)
+	    when binding string values.
+	    See: http://rubyforge.org/forum/forum.php?thread_id=48838&forum_id=1078
+
 2010-12-04  KUBO Takehiro  <kubo at jiubao.org>
 	* ext/oci8/object.c, ext/oci8/bind.c, lib/oci8/object.rb,
 	  test/test_object.rb: fix a problem to assign NULL bind value

Modified: branches/ruby-oci8-2.0/dist-files
===================================================================
--- branches/ruby-oci8-2.0/dist-files	2010-12-04 12:49:51 UTC (rev 418)
+++ branches/ruby-oci8-2.0/dist-files	2010-12-14 11:30:44 UTC (rev 419)
@@ -55,6 +55,7 @@
 lib/oci8/object.rb
 lib/oci8/oci8.rb
 lib/oci8/oracle_version.rb
+lib/oci8/properties.rb
 test/README
 test/config.rb
 test/test_all.rb

Modified: branches/ruby-oci8-2.0/ext/oci8/bind.c
===================================================================
--- branches/ruby-oci8-2.0/ext/oci8/bind.c	2010-12-04 12:49:51 UTC (rev 418)
+++ branches/ruby-oci8-2.0/ext/oci8/bind.c	2010-12-14 11:30:44 UTC (rev 419)
@@ -14,7 +14,7 @@
 static VALUE cOCI8BindTypeBase;
 
 /*
- * bind_string
+ * bind_char and bind_nchar
  */
 static VALUE bind_string_get(oci8_bind_t *obind, void *data, void *null_struct)
 {
@@ -54,7 +54,7 @@
     obind->alloc_sz = (sz + (sizeof(sb4) - 1)) & ~(sizeof(sb4) - 1);
 }
 
-static const oci8_bind_class_t bind_string_class = {
+static const oci8_bind_class_t bind_char_class = {
     {
         NULL,
         oci8_bind_free,
@@ -70,6 +70,23 @@
     SQLT_LVC
 };
 
+static const oci8_bind_class_t bind_nchar_class = {
+    {
+        NULL,
+        oci8_bind_free,
+        sizeof(oci8_bind_t)
+    },
+    bind_string_get,
+    bind_string_set,
+    bind_string_init,
+    NULL,
+    NULL,
+    NULL,
+    NULL,
+    SQLT_LVC,
+    SQLCS_NCHAR,
+};
+
 /*
  * bind_raw
  */
@@ -460,7 +477,8 @@
     rb_define_method(cOCI8BindTypeBase, "set", oci8_bind_set, 1);
 
     /* register primitive data types. */
-    oci8_define_bind_class("String", &bind_string_class);
+    oci8_define_bind_class("CHAR", &bind_char_class);
+    oci8_define_bind_class("NCHAR", &bind_nchar_class);
     oci8_define_bind_class("RAW", &bind_raw_class);
 #ifdef USE_DYNAMIC_FETCH
     oci8_define_bind_class("Long", &bind_long_class);

Modified: branches/ruby-oci8-2.0/lib/oci8/.document
===================================================================
--- branches/ruby-oci8-2.0/lib/oci8/.document	2010-12-04 12:49:51 UTC (rev 418)
+++ branches/ruby-oci8-2.0/lib/oci8/.document	2010-12-14 11:30:44 UTC (rev 419)
@@ -3,3 +3,4 @@
 metadata.rb
 oracle_version.rb
 oci8.rb
+properties.rb

Modified: branches/ruby-oci8-2.0/lib/oci8/bindtype.rb
===================================================================
--- branches/ruby-oci8-2.0/lib/oci8/bindtype.rb	2010-12-04 12:49:51 UTC (rev 418)
+++ branches/ruby-oci8-2.0/lib/oci8/bindtype.rb	2010-12-14 11:30:44 UTC (rev 419)
@@ -1,7 +1,7 @@
 #--
 # bindtype.rb -- OCI8::BindType
 #
-# Copyright (C) 2009 KUBO Takehiro <kubo at jiubao.org>
+# Copyright (C) 2009-2010 KUBO Takehiro <kubo at jiubao.org>
 #++
 
 class OCI8
@@ -116,6 +116,8 @@
               length = val.size
             end
           end
+          # use the default value when :nchar is not set explicitly.
+          nchar = OCI8.properties[:bind_string_as_nchar] unless param.has_key?(:nchar)
         when OCI8::Metadata::Base
           case param.data_type
           when :char, :varchar2
@@ -124,13 +126,18 @@
             # The length of a Japanese half-width kana is one in Shift_JIS,
             # two in EUC-JP, three in UTF-8.
             length *= 3 unless param.char_used?
+            nchar = (param.charset_form == :nchar)
           when :raw
             # HEX needs twice space.
             length = param.data_size * 2
           end
         end
         length = @@minimum_bind_length if length.nil? or length < @@minimum_bind_length
-        self.new(con, val, length, max_array_size)
+        if nchar
+          OCI8::BindType::NCHAR.new(con, val, length, max_array_size)
+        else
+          OCI8::BindType::CHAR.new(con, val, length, max_array_size)
+        end
       end
     end
 
@@ -153,7 +160,7 @@
 
     class Long < OCI8::BindType::String
       def self.create(con, val, param, max_array_size)
-        self.new(con, val, con.long_read_len, max_array_size)
+        super(con, val, {:length => con.long_read_len}, max_array_size)
       end
     end
 

Added: branches/ruby-oci8-2.0/lib/oci8/properties.rb
===================================================================
--- branches/ruby-oci8-2.0/lib/oci8/properties.rb	                        (rev 0)
+++ branches/ruby-oci8-2.0/lib/oci8/properties.rb	2010-12-14 11:30:44 UTC (rev 419)
@@ -0,0 +1,50 @@
+# properties.rb -- implements OCI8.properties
+#
+# Copyright (C) 2010 KUBO Takehiro <kubo at jiubao.org>
+
+class OCI8
+
+  @@properties = {
+    :bind_string_as_nchar => false,
+  }
+
+  def @@properties.[](name)
+    raise IndexError, "No such property name: #{name}" unless @@properties.has_key?(name)
+    super(name)
+  end
+
+  def @@properties.[]=(name, val)
+    raise IndexError, "No such property name: #{name}" unless @@properties.has_key?(name)
+    case name
+    when :bind_string_as_nchar
+      val = val ? true : false
+    end
+    super(name, val)
+  end
+
+  # call-seq:
+  #   OCI8.properties -> a customized Hash
+  #
+  # (new in 2.0.5)
+  #
+  # Returns a Hash which ruby-oci8 global settings.
+  # The hash's setter and getter methods are customized to check
+  # property names and values.
+  #
+  #   # get properties
+  #   OCI8.properties[:bind_string_as_nchar]  # => false
+  #   OCI8.properties[:invalid_property_name] # raises an IndexError
+  #
+  #   # set properties
+  #   OCI8.properties[:bind_string_as_nchar] = true
+  #   OCI8.properties[:invalid_property_name] = true # raises an IndexError
+  #
+  # Supported properties are listed below:
+  #
+  # [:bind_string_as_nchar]
+  #     +true+ when string bind variables are bound as NCHAR,
+  #     otherwise +false+. The default value is +false+.
+  def self.properties
+    @@properties
+  end
+end

Modified: branches/ruby-oci8-2.0/lib/oci8.rb.in
===================================================================
--- branches/ruby-oci8-2.0/lib/oci8.rb.in	2010-12-04 12:49:51 UTC (rev 418)
+++ branches/ruby-oci8-2.0/lib/oci8.rb.in	2010-12-14 11:30:44 UTC (rev 419)
@@ -85,6 +85,7 @@
 require 'oci8/metadata.rb'
 require 'oci8/compat.rb'
 require 'oci8/object.rb'
+require 'oci8/properties.rb'
 
 class OCI8
   VERSION = '@@OCI8_MODULE_VERSION@@'

Modified: trunk/ruby-oci8/ChangeLog
===================================================================
--- trunk/ruby-oci8/ChangeLog	2010-12-04 12:49:51 UTC (rev 418)
+++ trunk/ruby-oci8/ChangeLog	2010-12-14 11:30:44 UTC (rev 419)
@@ -1,3 +1,11 @@
+2010-12-14  KUBO Takehiro  <kubo at jiubao.org>
+	* dist-files, lib/oci8.rb.in, lib/oci8/.document, lib/oci8/properties.rb:
+	    add OCI8.properties to get and set ruby-oci8 global setting.
+	* ext/oci8/bind.c, lib/oci8/bindtype.rb: fix NCHAR support and add
+	    OCI8.properties[:bind_string_as_nchar] to control charset form (CHAR or NCHAR)
+	    when binding string values.
+	    See: http://rubyforge.org/forum/forum.php?thread_id=48838&forum_id=1078
+
 2010-12-04  KUBO Takehiro  <kubo at jiubao.org>
 	* ext/oci8/object.c, ext/oci8/bind.c, lib/oci8/object.rb,
 	  test/test_object.rb: fix a problem to assign NULL bind value

Modified: trunk/ruby-oci8/dist-files
===================================================================
--- trunk/ruby-oci8/dist-files	2010-12-04 12:49:51 UTC (rev 418)
+++ trunk/ruby-oci8/dist-files	2010-12-14 11:30:44 UTC (rev 419)
@@ -58,6 +58,7 @@
 lib/oci8/oci8.rb
 lib/oci8/ocihandle.rb
 lib/oci8/oracle_version.rb
+lib/oci8/properties.rb
 test/README
 test/config.rb
 test/test_all.rb

Modified: trunk/ruby-oci8/ext/oci8/bind.c
===================================================================
--- trunk/ruby-oci8/ext/oci8/bind.c	2010-12-04 12:49:51 UTC (rev 418)
+++ trunk/ruby-oci8/ext/oci8/bind.c	2010-12-14 11:30:44 UTC (rev 419)
@@ -13,6 +13,7 @@
 static ID id_bind_type;
 static VALUE sym_length;
 static VALUE sym_char_semantics;
+static VALUE sym_nchar;
 
 static VALUE cOCI8BindTypeBase;
 
@@ -20,6 +21,7 @@
     oci8_bind_t obind;
     sb4 bytelen;
     sb4 charlen;
+    ub1 csfrm;
 } oci8_bind_string_t;
 
 /*
@@ -49,11 +51,13 @@
     oci8_bind_string_t *obs = (oci8_bind_string_t *)obind;
     VALUE length;
     VALUE char_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);
+    nchar = rb_hash_aref(param, sym_nchar);
 
     sz = NUM2INT(length);
     if (sz < 0) {
@@ -72,6 +76,11 @@
         obs->bytelen = sz;
         obs->charlen = 0;
     }
+    if (RTEST(nchar)) {
+        obs->csfrm = SQLCS_NCHAR; /* bind as NCHAR/NVARCHAR2 */
+    } else {
+        obs->csfrm = SQLCS_IMPLICIT; /* bind as CHAR/VARCHAR2 */
+    }
     if (sz == 0) {
         sz = 1; /* to avoid ORA-01459. */
     }
@@ -87,6 +96,7 @@
     if (oracle_client_version >= ORAVER_9_0 && obs->charlen != 0) {
         oci_lc(OCIAttrSet(obind->base.hp.ptr, obind->base.type, (void*)&obs->charlen, 0, OCI_ATTR_MAXCHAR_SIZE, oci8_errhp));
     }
+    oci_lc(OCIAttrSet(obind->base.hp.ptr, obind->base.type, (void*)&obs->csfrm, 0, OCI_ATTR_CHARSET_FORM, oci8_errhp));
 }
 
 static const oci8_bind_class_t bind_string_class = {
@@ -493,6 +503,7 @@
     id_bind_type = rb_intern("bind_type");
     sym_length = ID2SYM(rb_intern("length"));
     sym_char_semantics = ID2SYM(rb_intern("char_semantics"));
+    sym_nchar = ID2SYM(rb_intern("nchar"));
 
     rb_define_method(cOCI8BindTypeBase, "initialize", oci8_bind_initialize, 4);
     rb_define_method(cOCI8BindTypeBase, "get", oci8_bind_get, 0);

Modified: trunk/ruby-oci8/lib/oci8/.document
===================================================================
--- trunk/ruby-oci8/lib/oci8/.document	2010-12-04 12:49:51 UTC (rev 418)
+++ trunk/ruby-oci8/lib/oci8/.document	2010-12-14 11:30:44 UTC (rev 419)
@@ -5,3 +5,4 @@
 oci8.rb
 ocihandle.rb
 connection_pool.rb
+properties.rb

Modified: trunk/ruby-oci8/lib/oci8/bindtype.rb
===================================================================
--- trunk/ruby-oci8/lib/oci8/bindtype.rb	2010-12-04 12:49:51 UTC (rev 418)
+++ trunk/ruby-oci8/lib/oci8/bindtype.rb	2010-12-14 11:30:44 UTC (rev 419)
@@ -123,14 +123,22 @@
               param[:length] = @@minimum_bind_length
             end
           end
+          # use the default value when :nchar is not set explicitly.
+          param[:nchar] = OCI8.properties[:bind_string_as_nchar] unless param.has_key?(:nchar)
         when OCI8::Metadata::Base
           case param.data_type
           when :char, :varchar2
-            if param.charset_form == :nchar or param.char_used?
-              param = {:length => param.char_size, :char_semantics => true}
+            char_semantics = param.char_used?
+            if char_semantics
+              length = param.char_size
             else
-              param = {:length => param.data_size}
+              length = param.data_size * OCI8.nls_ratio
             end
+            param = {
+              :length => length,
+              :char_semantics => char_semantics,
+              :nchar => (param.charset_form == :nchar),
+            }
           when :raw
             # HEX needs twice space.
             param = {:length => param.data_size * 2}
@@ -168,7 +176,7 @@
     class Long < OCI8::BindType::String
       def self.create(con, val, param, max_array_size)
         param = {:length => con.long_read_len, :char_semantics => true}
-        self.new(con, val, param, max_array_size)
+        super(con, val, param, max_array_size)
       end
     end
 

Added: trunk/ruby-oci8/lib/oci8/properties.rb
===================================================================
--- trunk/ruby-oci8/lib/oci8/properties.rb	                        (rev 0)
+++ trunk/ruby-oci8/lib/oci8/properties.rb	2010-12-14 11:30:44 UTC (rev 419)
@@ -0,0 +1,50 @@
+# properties.rb -- implements OCI8.properties
+#
+# Copyright (C) 2010 KUBO Takehiro <kubo at jiubao.org>
+
+class OCI8
+
+  @@properties = {
+    :bind_string_as_nchar => false,
+  }
+
+  def @@properties.[](name)
+    raise IndexError, "No such property name: #{name}" unless @@properties.has_key?(name)
+    super(name)
+  end
+
+  def @@properties.[]=(name, val)
+    raise IndexError, "No such property name: #{name}" unless @@properties.has_key?(name)
+    case name
+    when :bind_string_as_nchar
+      val = val ? true : false
+    end
+    super(name, val)
+  end
+
+  # call-seq:
+  #   OCI8.properties -> a customized Hash
+  #
+  # (new in 2.0.5)
+  #
+  # Returns a Hash which ruby-oci8 global settings.
+  # The hash's setter and getter methods are customized to check
+  # property names and values.
+  #
+  #   # get properties
+  #   OCI8.properties[:bind_string_as_nchar]  # => false
+  #   OCI8.properties[:invalid_property_name] # raises an IndexError
+  #
+  #   # set properties
+  #   OCI8.properties[:bind_string_as_nchar] = true
+  #   OCI8.properties[:invalid_property_name] = true # raises an IndexError
+  #
+  # Supported properties are listed below:
+  #
+  # [:bind_string_as_nchar]
+  #     +true+ when string bind variables are bound as NCHAR,
+  #     otherwise +false+. The default value is +false+.
+  def self.properties
+    @@properties
+  end
+end

Modified: trunk/ruby-oci8/lib/oci8.rb.in
===================================================================
--- trunk/ruby-oci8/lib/oci8.rb.in	2010-12-04 12:49:51 UTC (rev 418)
+++ trunk/ruby-oci8/lib/oci8.rb.in	2010-12-14 11:30:44 UTC (rev 419)
@@ -91,3 +91,4 @@
 require 'oci8/compat.rb'
 require 'oci8/object.rb'
 require 'oci8/connection_pool.rb'
+require 'oci8/properties.rb'




More information about the ruby-oci8-commit mailing list