[ruby-oci8-commit] [323] trunk/ruby-oci8: * ext/oci8/apiwrap.yml: add prototypes for OCIServerVersion() and

nobody at rubyforge.org nobody at rubyforge.org
Tue Mar 17 03:12:13 EDT 2009


Revision: 323
Author:   kubo
Date:     2009-03-17 03:12:13 -0400 (Tue, 17 Mar 2009)

Log Message:
-----------
* ext/oci8/apiwrap.yml: add prototypes for OCIServerVersion() and
    OCIServerRelease().
* ext/oci8/oci8.c: (1) add a private method OCI8#oracle_server_vernum,
    which returns Oracle server version number.
    (2) fix a class method OCI8.oracle_client_vernum when using Oracle
    client 10.1 or lower.
* lib/oci8/datetime.rb: fix year information when fetching a date
    whose year is between A.D. 1 and A.D. 139.
* lib/oci8/oci8.rb: (1) add OCI8#oracle_server_version.
*   (2) change the default data type for timestamp with time zone
    from DateTime to Time.

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

Modified: trunk/ruby-oci8/ChangeLog
===================================================================
--- trunk/ruby-oci8/ChangeLog	2009-03-11 13:11:08 UTC (rev 322)
+++ trunk/ruby-oci8/ChangeLog	2009-03-17 07:12:13 UTC (rev 323)
@@ -1,3 +1,16 @@
+2009-03-17  KUBO Takehiro  <kubo at jiubao.org>
+	* ext/oci8/apiwrap.yml: add prototypes for OCIServerVersion() and
+	    OCIServerRelease().
+	* ext/oci8/oci8.c: (1) add a private method OCI8#oracle_server_vernum,
+	    which returns Oracle server version number.
+	    (2) fix a class method OCI8.oracle_client_vernum when using Oracle
+	    client 10.1 or lower.
+	* lib/oci8/datetime.rb: fix year information when fetching a date
+	    whose year is between A.D. 1 and A.D. 139.
+	* lib/oci8/oci8.rb: (1) add OCI8#oracle_server_version.
+	*   (2) change the default data type for timestamp with time zone
+	    from DateTime to Time.
+
 2009-03-11  KUBO Takehiro  <kubo at jiubao.org>
 	* oraconf.rb: fix big/little endian checking problem on Mac OS X ppc.
 	    (contributed by unknown. See: Bug ID 24284 on rubyforge.)

Modified: trunk/ruby-oci8/ext/oci8/apiwrap.yml
===================================================================
--- trunk/ruby-oci8/ext/oci8/apiwrap.yml	2009-03-11 13:11:08 UTC (rev 322)
+++ trunk/ruby-oci8/ext/oci8/apiwrap.yml	2009-03-17 07:12:13 UTC (rev 323)
@@ -773,6 +773,15 @@
             - OCIError *errhp
             - ub4 mode
 
+# round trip: ?
+OCIServerVersion:
+  :version: 800
+  :args:    - dvoid *hndlp
+            - OCIError *errhp
+            - OraText *bufp
+            - ub4 bufsz
+            - ub1 hndltype
+
 # round trip: 1
 OCIStmtExecute_nb:
   :version: 800
@@ -1114,6 +1123,17 @@
             - ub2 *outbflp
             - OCIError *errhp
 
+# An undocumented function from Oracle 9i to Oracle 10g.
+# This is documented in Oracle 11g.
+OCIServerRelease:
+  :version: 900
+  :args:    - dvoid *hndlp
+            - OCIError *errhp
+            - OraText *bufp
+            - ub4 bufsz
+            - ub1 hndltype
+            - ub4 *version
+
 #
 # Oracle 9.2
 #

Modified: trunk/ruby-oci8/ext/oci8/oci8.c
===================================================================
--- trunk/ruby-oci8/ext/oci8/oci8.c	2009-03-11 13:11:08 UTC (rev 322)
+++ trunk/ruby-oci8/ext/oci8/oci8.c	2009-03-17 07:12:13 UTC (rev 323)
@@ -524,11 +524,43 @@
     return val;
 }
 
+/*
+ * call-seq:
+ *   oracle_server_vernum -> Oracle server version number
+ *
+ */
+static VALUE oci8_oracle_server_vernum(VALUE self)
+{
+    oci8_svcctx_t *svcctx = DATA_PTR(self);
+    char buf[100];
+    ub4 version;
+    char *p;
+
+    if (have_OCIServerRelease) {
+        /* Oracle 9i or later */
+        oci_lc(OCIServerRelease(svcctx->base.hp.ptr, oci8_errhp, (text*)buf, sizeof(buf), svcctx->base.type, &version));
+        return UINT2NUM(version);
+    } else {
+        /* Oracle 8.x */
+        oci_lc(OCIServerVersion(svcctx->base.hp.ptr, oci8_errhp, (text*)buf, sizeof(buf), svcctx->base.type));
+        if ((p = strchr(buf, '.')) != NULL) {
+            unsigned int major, minor, update, patch, port_update;
+            while (p >= buf && *p != ' ') {
+                p--;
+            }
+            if (sscanf(p + 1, "%u.%u.%u.%u.%u", &major, &minor, &update, &patch, &port_update) == 5) {
+                return INT2FIX(ORAVERNUM(major, minor, update, patch, port_update));
+            }
+        }
+        return Qnil;
+    }
+}
+
 VALUE Init_oci8(void)
 {
     cOCI8 = oci8_define_class("OCI8", &oci8_svcctx_class);
 
-    oracle_client_vernum = oracle_client_version;
+    oracle_client_vernum = INT2FIX(oracle_client_version);
     if (have_OCIClientVersion) {
         sword major, minor, update, patch, port_update;
         OCIClientVersion(&major, &minor, &update, &patch, &port_update);
@@ -556,6 +588,7 @@
     rb_define_method(cOCI8, "long_read_len=", oci8_set_long_read_len, 1);
     rb_define_method(cOCI8, "break", oci8_break, 0);
     rb_define_method(cOCI8, "prefetch_rows=", oci8_set_prefetch_rows, 1);
+    rb_define_private_method(cOCI8, "oracle_server_vernum", oci8_oracle_server_vernum, 0);
     return cOCI8;
 }
 

Modified: trunk/ruby-oci8/lib/oci8/datetime.rb
===================================================================
--- trunk/ruby-oci8/lib/oci8/datetime.rb	2009-03-11 13:11:08 UTC (rev 322)
+++ trunk/ruby-oci8/lib/oci8/datetime.rb	2009-03-17 07:12:13 UTC (rev 323)
@@ -20,7 +20,7 @@
       #
       # This parameter is used when both or either of Oracle server and client
       # version is Oracle 8i or lower. If both versions are Oracle 9i or upper,
-      # the default timezone is determined by session timezone.
+      # the default timezone is determined by the session timezone.
       def self.default_timezone=(tz)
         if tz != :local and tz != :utc
           raise ArgumentError, "expected :local or :utc but #{tz}"
@@ -111,11 +111,13 @@
 
       def ocidate_to_time(ary)
         year, month, day, hour, minute, sec = ary
-        begin
-          ::Time.send(@@default_timezone, year, month, day, hour, minute, sec)
-        rescue StandardError
-          ocidate_to_datetime(ary)
+        if year >= 139
+          begin
+            ::Time.send(@@default_timezone, year, month, day, hour, minute, sec)
+          rescue StandardError
+          end
         end
+        ocidate_to_datetime(ary)
       end
 
       if OCI8.oracle_client_version >= ORAVER_9_0
@@ -149,7 +151,7 @@
           elsif @@time_offset == tz_hour * 3600 + tz_min * 60
             timezone = :local
           end
-          if timezone
+          if timezone and year >= 139
             begin
               # Ruby 1.9 Time class's resolution is nanosecond.
               # But the last argument type is millisecond.

Modified: trunk/ruby-oci8/lib/oci8/oci8.rb
===================================================================
--- trunk/ruby-oci8/lib/oci8/oci8.rb	2009-03-11 13:11:08 UTC (rev 322)
+++ trunk/ruby-oci8/lib/oci8/oci8.rb	2009-03-17 07:12:13 UTC (rev 323)
@@ -135,6 +135,31 @@
     "#<OCI8:#{username}>"
   end
 
+  # :call-seq:
+  #   oracle_server_version -> oraver
+  #
+  # Returns an OCI8::OracleVersion of the Oracle server version.
+  #
+  # See also: OCI8.oracle_client_version
+  def oracle_server_version
+    unless defined? @oracle_server_version
+      if vernum = oracle_server_vernum
+        # If the Oracle client is Oracle 9i or upper,
+        # get the server version from the OCI function OCIServerRelease.
+        @oracle_server_version = OCI8::OracleVersion.new(vernum)
+      else
+        # Otherwise, get it from v$version.
+        self.exec('select banner from v$version') do |row|
+          if /^Oracle.*?(\d+\.\d+\.\d+\.\d+\.\d+)/ =~ row[0]
+            @oracle_server_version = OCI8::OracleVersion.new($1)
+            break
+          end
+        end
+      end
+    end
+    @oracle_server_version
+  end
+
   module BindType
     Mapping = {}
 
@@ -703,7 +728,7 @@
 
 if OCI8.oracle_client_version >= OCI8::ORAVER_9_0
   OCI8::BindType::Mapping[:timestamp] = OCI8::BindType::Time
-  OCI8::BindType::Mapping[:timestamp_tz] = OCI8::BindType::DateTime
+  OCI8::BindType::Mapping[:timestamp_tz] = OCI8::BindType::Time
   OCI8::BindType::Mapping[:timestamp_ltz] = OCI8::BindType::Time
   OCI8::BindType::Mapping[:interval_ym] = OCI8::BindType::IntervalYM
   OCI8::BindType::Mapping[:interval_ds] = OCI8::BindType::IntervalDS




More information about the ruby-oci8-commit mailing list