[ruby-oci8-commit] [351] trunk/ruby-oci8: * ext/oci8/object.c, lib/oci8/datetime.rb, lib/oci8/ object.rb:

nobody at rubyforge.org nobody at rubyforge.org
Sun May 24 06:44:58 EDT 2009


Revision: 351
Author:   kubo
Date:     2009-05-24 06:44:58 -0400 (Sun, 24 May 2009)

Log Message:
-----------
* ext/oci8/object.c, lib/oci8/datetime.rb, lib/oci8/object.rb:
    add DATE datatype support in object types.

Modified Paths:
--------------
    trunk/ruby-oci8/ChangeLog
    trunk/ruby-oci8/ext/oci8/object.c
    trunk/ruby-oci8/lib/oci8/datetime.rb
    trunk/ruby-oci8/lib/oci8/object.rb

Modified: trunk/ruby-oci8/ChangeLog
===================================================================
--- trunk/ruby-oci8/ChangeLog	2009-05-19 12:51:28 UTC (rev 350)
+++ trunk/ruby-oci8/ChangeLog	2009-05-24 10:44:58 UTC (rev 351)
@@ -1,3 +1,7 @@
+2009-05-24  KUBO Takehiro  <kubo at jiubao.org>
+	* ext/oci8/object.c, lib/oci8/datetime.rb, lib/oci8/object.rb:
+	    add DATE datatype support in object types.
+
 2009-05-19  KUBO Takehiro  <kubo at jiubao.org>
 	* ext/oci8/bind.c: delete OCI8::BindType::Fixnum.
 	* lib/oci8/compat.rb: add OCI8::BindType::Fixnum as an alias

Modified: trunk/ruby-oci8/ext/oci8/object.c
===================================================================
--- trunk/ruby-oci8/ext/oci8/object.c	2009-05-19 12:51:28 UTC (rev 350)
+++ trunk/ruby-oci8/ext/oci8/object.c	2009-05-24 10:44:58 UTC (rev 351)
@@ -37,6 +37,7 @@
     ATTR_OCINUMBER,
     ATTR_FLOAT,
     ATTR_INTEGER,
+    ATTR_OCIDATE,
     ATTR_BINARY_DOUBLE,
     ATTR_BINARY_FLOAT,
     ATTR_NAMED_TYPE,
@@ -167,6 +168,8 @@
         return oci8_make_float((OCINumber *)data, oci8_errhp);
     case ATTR_INTEGER:
         return oci8_make_integer((OCINumber *)data, oci8_errhp);
+    case ATTR_OCIDATE:
+        return oci8_make_ocidate((OCIDate *)data);
     case ATTR_BINARY_DOUBLE:
         return rb_float_new(*(double*)data);
     case ATTR_BINARY_FLOAT:
@@ -309,6 +312,9 @@
         OCINumberSetZero(oci8_errhp, &cb_data.data.num);
         cb_data.indp = &cb_data.ind;
         break;
+    case ATTR_OCIDATE:
+        cb_data.indp = &cb_data.ind;
+        break;
     case ATTR_BINARY_DOUBLE:
         cb_data.data.dbl = 0.0;
         cb_data.indp = &cb_data.ind;
@@ -370,6 +376,7 @@
         case ATTR_OCINUMBER:
         case ATTR_FLOAT:
         case ATTR_INTEGER:
+        case ATTR_OCIDATE:
         case ATTR_BINARY_DOUBLE:
         case ATTR_BINARY_FLOAT:
             elem_ptr = &cb_data->data;
@@ -403,6 +410,7 @@
     case ATTR_OCINUMBER:
     case ATTR_FLOAT:
     case ATTR_INTEGER:
+    case ATTR_OCIDATE:
     case ATTR_BINARY_DOUBLE:
     case ATTR_BINARY_FLOAT:
         break;
@@ -441,6 +449,9 @@
     case ATTR_INTEGER:
         oci8_set_integer((OCINumber*)data, val, oci8_errhp);
         break;
+    case ATTR_OCIDATE:
+        oci8_set_ocidate((OCIDate*)data, val);
+        break;
     case ATTR_BINARY_DOUBLE:
         *(double*)data = NUM2DBL(val);
         break;
@@ -592,6 +603,7 @@
     rb_define_const(cOCI8TDO, "ATTR_OCINUMBER", INT2FIX(ATTR_OCINUMBER));
     rb_define_const(cOCI8TDO, "ATTR_FLOAT", INT2FIX(ATTR_FLOAT));
     rb_define_const(cOCI8TDO, "ATTR_INTEGER", INT2FIX(ATTR_INTEGER));
+    rb_define_const(cOCI8TDO, "ATTR_OCIDATE", INT2FIX(ATTR_OCIDATE));
     rb_define_const(cOCI8TDO, "ATTR_BINARY_DOUBLE", INT2FIX(ATTR_BINARY_DOUBLE));
     rb_define_const(cOCI8TDO, "ATTR_BINARY_FLOAT", INT2FIX(ATTR_BINARY_FLOAT));
     rb_define_const(cOCI8TDO, "ATTR_NAMED_TYPE", INT2FIX(ATTR_NAMED_TYPE));

Modified: trunk/ruby-oci8/lib/oci8/datetime.rb
===================================================================
--- trunk/ruby-oci8/lib/oci8/datetime.rb	2009-05-19 12:51:28 UTC (rev 350)
+++ trunk/ruby-oci8/lib/oci8/datetime.rb	2009-05-24 10:44:58 UTC (rev 351)
@@ -31,6 +31,8 @@
       private
 
       def datetime_to_array(val, full)
+        return nil if val.nil?
+
         # year
         year = val.year
         # month
@@ -100,6 +102,8 @@
       end
 
       def ocidate_to_datetime(ary)
+        return nil if ary.nil?
+
         year, month, day, hour, minute, sec = ary
         if @@default_timezone == :local
           offset = @@datetime_offset
@@ -110,6 +114,8 @@
       end
 
       def ocidate_to_time(ary)
+        return nil if ary.nil?
+
         year, month, day, hour, minute, sec = ary
         if year >= 139
           begin
@@ -123,6 +129,8 @@
       if OCI8.oracle_client_version >= ORAVER_9_0
 
         def ocitimestamp_to_datetime(ary)
+          return nil if ary.nil?
+
           year, month, day, hour, minute, sec, fsec, tz_hour, tz_min = ary
           if sec >= 59 and fsec != 0
             # convert to a DateTime via a String as a last resort.
@@ -144,6 +152,8 @@
         end
 
         def ocitimestamp_to_time(ary)
+          return nil if ary.nil?
+
           year, month, day, hour, minute, sec, fsec, tz_hour, tz_min = ary
 
           if tz_hour == 0 and tz_min == 0
@@ -169,13 +179,11 @@
       include OCI8::BindType::Util
 
       def set(val) # :nodoc:
-        val &&= datetime_to_array(val, false)
-        super(val)
+        super(datetime_to_array(val, false))
       end
 
       def get() # :nodoc:
-        val = super()
-        val ? ocidate_to_datetime(val) : nil
+        ocidate_to_datetime(super())
       end
     end
 
@@ -183,13 +191,11 @@
       include OCI8::BindType::Util
 
       def set(val) # :nodoc:
-        val &&= datetime_to_array(val, false)
-        super(val)
+        super(datetime_to_array(val, false))
       end
 
       def get() # :nodoc:
-        val = super()
-        val ? ocidate_to_time(val) : nil
+        ocidate_to_time(super())
       end
     end
 
@@ -198,13 +204,11 @@
         include OCI8::BindType::Util
 
         def set(val) # :nodoc:
-          val &&= datetime_to_array(val, true)
-          super(val)
+          super(datetime_to_array(val, true))
         end
 
         def get() # :nodoc:
-          val = super()
-          val ? ocitimestamp_to_datetime(val) : nil
+          ocitimestamp_to_datetime(super())
         end
       end
 
@@ -212,13 +216,11 @@
         include OCI8::BindType::Util
 
         def set(val) # :nodoc:
-          val &&= datetime_to_array(val, true)
-          super(val)
+          super(datetime_to_array(val, true))
         end
 
         def get() # :nodoc:
-          val = super()
-          val ? ocitimestamp_to_time(val) : nil
+          ocitimestamp_to_time(super())
         end
       end
     end

Modified: trunk/ruby-oci8/lib/oci8/object.rb
===================================================================
--- trunk/ruby-oci8/lib/oci8/object.rb	2009-05-19 12:51:28 UTC (rev 350)
+++ trunk/ruby-oci8/lib/oci8/object.rb	2009-05-24 10:44:58 UTC (rev 351)
@@ -425,6 +425,9 @@
       'INTERVAL DAY TO SECOND'  => :interval_ds,
     }
 
+    # for datetime_to_array and ocidate_to_datetime
+    extend OCI8::BindType::Util
+
     def self.check_metadata(con, metadata)
       case metadata.typecode
       when :char, :varchar, :varchar2
@@ -437,6 +440,11 @@
         [ATTR_INTEGER,   nil, SIZE_OF_OCINUMBER, 2, ALIGNMENT_OF_OCINUMBER]
       when :real, :double, :float
         [ATTR_FLOAT,     nil, SIZE_OF_OCINUMBER, 2, ALIGNMENT_OF_OCINUMBER]
+      when :date
+        [ATTR_OCIDATE,   nil, SIZE_OF_OCIDATE, 2, ALIGNMENT_OF_OCIDATE,
+         Proc.new do |val| datetime_to_array(val, false) end, # set_proc
+         Proc.new do |val| ocidate_to_datetime(val) end, # get_proc
+        ]
       when :binary_double
         [ATTR_BINARY_DOUBLE, nil, SIZE_OF_DOUBLE, 2, ALIGNMENT_OF_DOUBLE]
       when :binary_float
@@ -461,11 +469,13 @@
       attr_reader :alignment
       attr_reader :datatype
       attr_reader :typeinfo
+      attr_reader :set_proc
+      attr_reader :get_proc
       def initialize(con, metadata, val_offset, ind_offset)
         if metadata.respond_to? :name
           @name = metadata.name.downcase.intern
         end
-        @datatype, @typeinfo, @val_size, @ind_size, @alignment, = OCI8::TDO.check_metadata(con, metadata)
+        @datatype, @typeinfo, @val_size, @ind_size, @alignment, @set_proc, @get_proc, = OCI8::TDO.check_metadata(con, metadata)
         @val_offset = (val_offset + @alignment - 1) & ~(@alignment - 1)
         @ind_offset = ind_offset
       end
@@ -485,7 +495,9 @@
     def attributes
       attrs = {}
       tdo.attributes.each do |attr|
-        attrs[attr.name] = get_attribute(attr.datatype, attr.typeinfo, attr.val_offset, attr.ind_offset)
+        attr_val = get_attribute(attr.datatype, attr.typeinfo, attr.val_offset, attr.ind_offset)
+        attr_val = attr.get_proc.call(attr_val) if attr.get_proc
+        attrs[attr.name] = attr_val
       end
       attrs
     end
@@ -493,7 +505,9 @@
     def attributes=(obj)
       obj = obj.instance_variable_get(:@attributes) unless obj.is_a? Hash
       tdo.attributes.each do |attr|
-        set_attribute(attr.datatype, attr.typeinfo, attr.val_offset, attr.ind_offset, obj[attr.name])
+        attr_val = obj[attr.name]
+        attr_val = attr.set_proc.call(attr_val) if attr.set_proc
+        set_attribute(attr.datatype, attr.typeinfo, attr.val_offset, attr.ind_offset, attr_val)
       end
     end
   end




More information about the ruby-oci8-commit mailing list