[ruby-oci8-commit] [306] trunk/ruby-oci8: * ext/oci8/oci8.c: delete OCI8. oracle_client_version implemented

nobody at rubyforge.org nobody at rubyforge.org
Sun Jan 4 08:54:57 EST 2009


Revision: 306
Author:   kubo
Date:     2009-01-04 08:54:56 -0500 (Sun, 04 Jan 2009)

Log Message:
-----------
* ext/oci8/oci8.c: delete OCI8.oracle_client_version implemented
    in C. add OCI8.oracle_client_vernum whose value is retrieved
    by OCIClientVersion() if Oracle 10.2 or upper.
* ext/oci8/oci8.h: add macro rb_define_singleton_method_nodoc,
    which prevents rdoc from gathering the specified method.
* lib/.document, lib/oci8/.document: add lib/oci8.rb and
    lib/oci8/oracle_version.rb to rdoc targets.
* lib/oci8.rb.in, lib/oci8/oracle_version.rb: add
    OCI8::OracleVersion OCI8.oracle_client_version.
* test/config.rb: change version checking code to use
    OCI8::OracleVersion.
* test/test_all.rb, test/test_oracle_version.rb: add test cases
    of OCI8::OracleVersion.

Modified Paths:
--------------
    trunk/ruby-oci8/ChangeLog
    trunk/ruby-oci8/ext/oci8/oci8.c
    trunk/ruby-oci8/ext/oci8/oci8.h
    trunk/ruby-oci8/lib/.document
    trunk/ruby-oci8/lib/oci8/.document
    trunk/ruby-oci8/lib/oci8.rb.in
    trunk/ruby-oci8/test/config.rb
    trunk/ruby-oci8/test/test_all.rb

Added Paths:
-----------
    trunk/ruby-oci8/lib/oci8/oracle_version.rb
    trunk/ruby-oci8/test/test_oracle_version.rb

Modified: trunk/ruby-oci8/ChangeLog
===================================================================
--- trunk/ruby-oci8/ChangeLog	2009-01-03 16:58:01 UTC (rev 305)
+++ trunk/ruby-oci8/ChangeLog	2009-01-04 13:54:56 UTC (rev 306)
@@ -1,3 +1,18 @@
+2009-01-04  KUBO Takehiro  <kubo at jiubao.org>
+	* ext/oci8/oci8.c: delete OCI8.oracle_client_version implemented
+	    in C. add OCI8.oracle_client_vernum whose value is retrieved
+	    by OCIClientVersion() if Oracle 10.2 or upper.
+	* ext/oci8/oci8.h: add macro rb_define_singleton_method_nodoc,
+	    which prevents rdoc from gathering the specified method.
+	* lib/.document, lib/oci8/.document: add lib/oci8.rb and
+	    lib/oci8/oracle_version.rb to rdoc targets.
+	* lib/oci8.rb.in, lib/oci8/oracle_version.rb: add
+	    OCI8::OracleVersion OCI8.oracle_client_version.
+	* test/config.rb: change version checking code to use
+	    OCI8::OracleVersion.
+	* test/test_all.rb, test/test_oracle_version.rb: add test cases
+	    of OCI8::OracleVersion.
+
 2009-01-03  KUBO Takehiro  <kubo at jiubao.org>
 	* ext/oci8/encoding.c, ext/oci8/error.c, ext/oci8/ocinumber.c,
 	  ext/oci8/oradate.c: use rb_usascii_str_new() or

Modified: trunk/ruby-oci8/ext/oci8/oci8.c
===================================================================
--- trunk/ruby-oci8/ext/oci8/oci8.c	2009-01-03 16:58:01 UTC (rev 305)
+++ trunk/ruby-oci8/ext/oci8/oci8.c	2009-01-04 13:54:56 UTC (rev 306)
@@ -2,7 +2,7 @@
 /*
  * oci8.c - part of ruby-oci8
  *
- * Copyright (C) 2002-2008 KUBO Takehiro <kubo at jiubao.org>
+ * Copyright (C) 2002-2009 KUBO Takehiro <kubo at jiubao.org>
  *
  */
 #include "oci8.h"
@@ -57,15 +57,16 @@
     sizeof(oci8_svcctx_t)
 };
 
+static VALUE oracle_client_vernum; /* Oracle client version number */
 static VALUE sym_SYSDBA;
 static VALUE sym_SYSOPER;
 static ID id_at_prefetch_rows;
 static ID id_at_username;
 static ID id_set_prefetch_rows;
 
-static VALUE oci8_s_oracle_client_version(VALUE klass)
+static VALUE oci8_s_oracle_client_vernum(VALUE klass)
 {
-    return INT2FIX(oracle_client_version);
+    return oracle_client_vernum;
 }
 
 #define CONN_STR_REGEX "/^([^(\\s|\\@)]*)\\/([^(\\s|\\@)]*)(?:\\@(\\S+))?(?:\\s+as\\s+(\\S*)\\s*)?$/i"
@@ -527,13 +528,20 @@
 {
     cOCI8 = oci8_define_class("OCI8", &oci8_svcctx_class);
 
+    oracle_client_vernum = oracle_client_version;
+    if (have_OCIClientVersion) {
+        sword major, minor, update, patch, port_update;
+        OCIClientVersion(&major, &minor, &update, &patch, &port_update);
+        oracle_client_vernum = INT2FIX(ORAVERNUM(major, minor, update, patch, port_update));
+    }
+
     sym_SYSDBA = ID2SYM(rb_intern("SYSDBA"));
     sym_SYSOPER = ID2SYM(rb_intern("SYSOPER"));
     id_at_prefetch_rows = rb_intern("@prefetch_rows");
     id_at_username = rb_intern("@username");
     id_set_prefetch_rows = rb_intern("prefetch_rows=");
 
-    rb_define_singleton_method(cOCI8, "oracle_client_version", oci8_s_oracle_client_version, 0);
+    rb_define_singleton_method_nodoc(cOCI8, "oracle_client_vernum", oci8_s_oracle_client_vernum, 0);
     rb_define_private_method(cOCI8, "parse_connect_string", oci8_parse_connect_string, 1);
     rb_define_method(cOCI8, "initialize", oci8_svcctx_initialize, -1);
     rb_define_method(cOCI8, "logoff", oci8_svcctx_logoff, 0);

Modified: trunk/ruby-oci8/ext/oci8/oci8.h
===================================================================
--- trunk/ruby-oci8/ext/oci8/oci8.h	2009-01-03 16:58:01 UTC (rev 305)
+++ trunk/ruby-oci8/ext/oci8/oci8.h	2009-01-04 13:54:56 UTC (rev 306)
@@ -2,7 +2,7 @@
 /*
   oci8.h - part of ruby-oci8
 
-  Copyright (C) 2002-2008 KUBO Takehiro <kubo at jiubao.org>
+  Copyright (C) 2002-2009 KUBO Takehiro <kubo at jiubao.org>
 */
 #ifndef _RUBY_OCI_H_
 #define _RUBY_OCI_H_ 1
@@ -173,7 +173,11 @@
 #define RSTRING_ORATEXT(obj) TO_ORATEXT(RSTRING_PTR(obj))
 #define rb_str_new2_ora(str) rb_str_new2(TO_CHARPTR(str))
 
+/*
+ * prevent rdoc from gathering the specified method.
+ */
 #define rb_define_method_nodoc rb_define_method
+#define rb_define_singleton_method_nodoc rb_define_singleton_method
 
 /* data structure for SQLT_LVC and SQLT_LVB. */
 typedef struct {

Modified: trunk/ruby-oci8/lib/.document
===================================================================
--- trunk/ruby-oci8/lib/.document	2009-01-03 16:58:01 UTC (rev 305)
+++ trunk/ruby-oci8/lib/.document	2009-01-04 13:54:56 UTC (rev 306)
@@ -1 +1,2 @@
 oci8
+oci8.rb

Modified: trunk/ruby-oci8/lib/oci8/.document
===================================================================
--- trunk/ruby-oci8/lib/oci8/.document	2009-01-03 16:58:01 UTC (rev 305)
+++ trunk/ruby-oci8/lib/oci8/.document	2009-01-04 13:54:56 UTC (rev 306)
@@ -1,3 +1,5 @@
 oci8.rb
 object.rb
 metadata.rb
+oracle_version.rb
+

Added: trunk/ruby-oci8/lib/oci8/oracle_version.rb
===================================================================
--- trunk/ruby-oci8/lib/oci8/oracle_version.rb	                        (rev 0)
+++ trunk/ruby-oci8/lib/oci8/oracle_version.rb	2009-01-04 13:54:56 UTC (rev 306)
@@ -0,0 +1,144 @@
+# oracle_version.rb implements OCI8::OracleVersion.
+#
+# Copyright (C) 2009 KUBO Takehiro <kubo at jiubao.org>
+
+#--
+
+class OCI8
+
+  # A data class, representing Oracle version.
+  #
+  # Oracle version is represented by five numbers:
+  # *major*, *minor*, *update*, *patch* and *port_update*.
+  class OracleVersion
+    include Comparable
+
+    # The first part of the Oracle version.
+    attr_reader :major
+    # The second part of the Oracle version.
+    attr_reader :minor
+    # The third part of the Oracle version.
+    attr_reader :update
+    # The fifth part of the Oracle version.
+    attr_reader :patch
+    # The fourth part of the Oracle version.
+    attr_reader :port_update
+
+    # Creates a OCI8::OracleVersion object.
+    #
+    # If the first argument _arg_ is a String, it is parsed as dotted
+    # version string. If it is bigger than 0x08000000, it is parsed as
+    # a number contains 5-digit Oracle version. Otherwise, it is used
+    # as a major version and the rest arguments are minor, update,
+    # patch and port_update. Unspecified version numbers are zeros by
+    # default.
+    #
+    # == Example
+    #   oraver = OCI8::OracleVersion.new('10.2.0.4')
+    #   oraver.major       # => 10
+    #   oraver.minor       # =>  2
+    #   oraver.update      # =>  0
+    #   oraver.patch       # =>  4
+    #   oraver.port_update # =>  0
+    #
+    #   oraver = OCI8::OracleVersion.new(0x0a200400)
+    #   oraver.major       # => 10
+    #   oraver.minor       # =>  2
+    #   oraver.update      # =>  0
+    #   oraver.patch       # =>  4
+    #   oraver.port_update # =>  0
+    def initialize(arg, minor = nil, update = nil, patch = nil, port_update = nil)
+      if arg.is_a? String
+        major, minor, update, patch, port_update = arg.split('.').collect do |v|
+          v.to_i
+        end
+      elsif arg >= 0x08000000
+        major  = (arg & 0xFF000000) >> 24
+        minor  = (arg & 0x00F00000) >> 20
+        update = (arg & 0x000FF000) >> 12
+        patch  = (arg & 0x00000F00) >> 8
+        port_update = (arg & 0x000000FF)
+      else
+        major = arg
+      end
+      @major = major
+      @minor = minor || 0
+      @update = update || 0
+      @patch = patch || 0
+      @port_update = port_update || 0
+    end
+
+    # :call-seq:
+    #   oraver <=> other_oraver -> -1, 0, +1
+    #
+    # Compares +oraver+ and +other_oraver+.
+    #
+    # <=> is the basis for the methods <, <=, ==, >, >=, and between?,
+    # included from module Comparable.
+    def <=>(other)
+      cmp = @major <=> other.major
+      return cmp if cmp != 0
+      cmp = @minor <=> other.minor
+      return cmp if cmp != 0
+      cmp = @update <=> other.update
+      return cmp if cmp != 0
+      cmp = @patch <=> other.patch
+      return cmp if cmp != 0
+      @port_update <=> other.port_update
+    end
+
+    # :call-seq:
+    #   oraver.to_i -> integer
+    #
+    # Returns an integer number contains 5-digit Oracle version.
+    #
+    # If the hexadecimal notation is 0xAABCCDEE, *major*, *minor*,
+    # *update*, *patch* and *port_update* are 0xAA, 0xB, 0xCC, 0xD and
+    # 0xEE respectively.
+    #
+    # == Example
+    #   oraver = OCI8::OracleVersion.new('10.2.0.4')
+    #   oraver.to_i          # => 169870336
+    #   '%08x' % oraver.to_i # => "0a200400"
+    def to_i
+      (@major << 24) | (@minor << 20) | (@update << 12) | (@patch << 8) | @port_update
+    end
+
+    # :call-seq:
+    #   oraver.to_s -> string
+    #
+    # Returns a dotted version string of the Oracle version.
+    #
+    # == Example
+    #   oraver = OCI8::OracleVersion.new('10.2.0.4')
+    #   oraver.to_s          # => '10.2.0.4.0'
+    def to_s
+      format('%d.%d.%d.%d.%d', @major, @minor, @update, @patch, @port_update)
+    end
+
+    # :call-seq:
+    #   oraver.eql? other -> true or false
+    #
+    # Returns true if +oraver+ and +other+ are the same type and have
+    # equal values.
+    #--
+    # This is for class Hash to test members for equality.
+    def eql?(other)
+      other.is_a? OCI8::OracleVersion and (self <=> other) == 0
+    end
+
+    # :call-seq:
+    #   oraver.hash -> integer
+    #
+    # Returns a hash based on the value of +oraver+.
+    #--
+    # This is for class Hash.
+    def hash
+      to_i
+    end
+
+    def inspect # :nodoc:
+      "#<#{self.class.to_s}: #{self.to_s}>"
+    end
+  end
+end

Modified: trunk/ruby-oci8/lib/oci8.rb.in
===================================================================
--- trunk/ruby-oci8/lib/oci8.rb.in	2009-01-03 16:58:01 UTC (rev 305)
+++ trunk/ruby-oci8/lib/oci8.rb.in	2009-01-04 13:54:56 UTC (rev 306)
@@ -19,15 +19,38 @@
 end
 
 require 'oci8lib'
+require 'oci8/oracle_version.rb'
 
 class OCI8
-  ORAVER_8_0  = 0x08000000 #  8.0
-  ORAVER_8_1  = 0x08100000 #  8.1
-  ORAVER_9_0  = 0x09000000 #  9.0
-  ORAVER_9_2  = 0x09200000 #  9.2
-  ORAVER_10_1 = 0x0a100000 # 10.1
-  ORAVER_10_2 = 0x0a200000 # 10.2
-  ORAVER_11_1 = 0x0b100000 # 11.1
+  ORAVER_8_0  = OCI8::OracleVersion.new(8, 0)
+  ORAVER_8_1  = OCI8::OracleVersion.new(8, 1)
+  ORAVER_9_0  = OCI8::OracleVersion.new(9, 0)
+  ORAVER_9_2  = OCI8::OracleVersion.new(9, 2)
+  ORAVER_10_1 = OCI8::OracleVersion.new(10, 1)
+  ORAVER_10_2 = OCI8::OracleVersion.new(10, 2)
+  ORAVER_11_1 = OCI8::OracleVersion.new(11, 1)
+
+  @@oracle_client_version = OCI8::OracleVersion.new(self.oracle_client_vernum)
+
+  # :call-seq:
+  #   OCI8.oracle_client_version -> oraver
+  #
+  # Returns an OCI8::OracleVersion of the Oracle client version.
+  #
+  # If this library is configured without '--with-runtime-check',
+  # and compiled for Oracle 10.1 or lower, the major and minor
+  # numbers are determined at compile-time. The rests are zeros.
+  #
+  # If this library is configured with '--with-runtime-check'
+  # and the runtime Oracle library is Oracle 10.1 or lower, the
+  # major and minor numbers are determined at run-time. The
+  # rests are zeros.
+  #
+  # Otherwise, it is the version retrieved from an OCI function
+  # OCIClientVersion().
+  def self.oracle_client_version
+    @@oracle_client_version
+  end
 end
 
 require 'oci8/datetime.rb'

Modified: trunk/ruby-oci8/test/config.rb
===================================================================
--- trunk/ruby-oci8/test/config.rb	2009-01-03 16:58:01 UTC (rev 305)
+++ trunk/ruby-oci8/test/config.rb	2009-01-04 13:54:56 UTC (rev 306)
@@ -26,8 +26,7 @@
 conn = OCI8.new($dbuser, $dbpass, $dbname)
 begin
   conn.exec('select value from database_compatible_level') do |row|
-    ver = row[0].split('.').collect do |v| v.to_i; end
-    $oracle_server_version = (ver[0] << 24) + (ver[1] << 20) + (ver[2] << 12)
+    $oracle_server_version = OCI8::OracleVersion.new(row[0])
   end
 rescue OCIError
   raise if $!.code != 942 # ORA-00942: table or view does not exist

Modified: trunk/ruby-oci8/test/test_all.rb
===================================================================
--- trunk/ruby-oci8/test/test_all.rb	2009-01-03 16:58:01 UTC (rev 305)
+++ trunk/ruby-oci8/test/test_all.rb	2009-01-04 13:54:56 UTC (rev 306)
@@ -19,6 +19,7 @@
 require "#{srcdir}/test_metadata"
 require "#{srcdir}/test_array_dml"
 require "#{srcdir}/test_rowid"
+require "#{srcdir}/test_oracle_version"
 
 # Ruby/DBI
 begin

Added: trunk/ruby-oci8/test/test_oracle_version.rb
===================================================================
--- trunk/ruby-oci8/test/test_oracle_version.rb	                        (rev 0)
+++ trunk/ruby-oci8/test/test_oracle_version.rb	2009-01-04 13:54:56 UTC (rev 306)
@@ -0,0 +1,70 @@
+require 'oci8'
+require 'test/unit'
+require File.dirname(__FILE__) + '/config'
+
+class TestOracleVersion < Test::Unit::TestCase
+
+  def test_init
+    oraver = OCI8::OracleVersion.new('8.1.6.2.3')
+    assert_equal(8, oraver.major)
+    assert_equal(1, oraver.minor)
+    assert_equal(6, oraver.update)
+    assert_equal(2, oraver.patch)
+    assert_equal(3, oraver.port_update)
+
+    oraver = OCI8::OracleVersion.new('8.1.6')
+    assert_equal(8, oraver.major)
+    assert_equal(1, oraver.minor)
+    assert_equal(6, oraver.update)
+    assert_equal(0, oraver.patch)
+    assert_equal(0, oraver.port_update)
+
+    oraver = OCI8::OracleVersion.new('10')
+    assert_equal(10, oraver.major)
+    assert_equal(0, oraver.minor)
+    assert_equal(0, oraver.update)
+    assert_equal(0, oraver.patch)
+    assert_equal(0, oraver.port_update)
+
+    oraver = OCI8::OracleVersion.new(0x08106203)
+    assert_equal(8, oraver.major)
+    assert_equal(1, oraver.minor)
+    assert_equal(6, oraver.update)
+    assert_equal(2, oraver.patch)
+    assert_equal(3, oraver.port_update)
+  end
+
+  def test_compare
+    oraver = OCI8::OracleVersion.new('8.1.6.2.3')
+    assert_operator(oraver, :==, OCI8::OracleVersion.new('8.1.6.2.3'))
+    assert_operator(oraver, :<, OCI8::OracleVersion.new('9.1.6.2.3'))
+    assert_operator(oraver, :<, OCI8::OracleVersion.new('8.2.6.2.3'))
+    assert_operator(oraver, :<, OCI8::OracleVersion.new('8.1.7.2.3'))
+    assert_operator(oraver, :<, OCI8::OracleVersion.new('8.1.6.3.3'))
+    assert_operator(oraver, :<, OCI8::OracleVersion.new('8.1.6.2.4'))
+    assert_operator(oraver, :>, OCI8::OracleVersion.new('7.1.6.2.3'))
+    assert_operator(oraver, :>, OCI8::OracleVersion.new('8.0.6.2.3'))
+    assert_operator(oraver, :>, OCI8::OracleVersion.new('8.1.5.2.3'))
+    assert_operator(oraver, :>, OCI8::OracleVersion.new('8.1.6.1.3'))
+    assert_operator(oraver, :>, OCI8::OracleVersion.new('8.1.6.2.2'))
+  end
+
+  def test_to_s
+    oraver = OCI8::OracleVersion.new('8.1.6.2.3')
+    assert_equal('8.1.6.2.3', oraver.to_s)
+  end
+
+  def test_to_i
+    oraver = OCI8::OracleVersion.new('8.1.6.2.3')
+    assert_equal(0x08106203, oraver.to_i)
+  end
+
+  def test_eql
+    oraver = OCI8::OracleVersion.new('8.1.6.2.3')
+    assert_equal(true, oraver.eql?(OCI8::OracleVersion.new('8.1.6.2.3')))
+    assert_equal(false, oraver.eql?(OCI8::OracleVersion.new('8.2.6.2.3')))
+    assert_equal(false, oraver.eql?('8.1.6.2.3'))
+  end
+end
+
+Test::Unit::AutoRunner.run() if $0 == __FILE__




More information about the ruby-oci8-commit mailing list