[ruby-oci8-commit] [478] trunk/ruby-oci8: raise a RuntimeError when non-blocking mode is set to a connection allocated from OCI8 ::ConnectionPool on ruby 1.8.

nobody at rubyforge.org nobody at rubyforge.org
Tue Dec 6 06:10:34 EST 2011


Revision: 478
Author:   kubo
Date:     2011-12-06 06:10:34 -0500 (Tue, 06 Dec 2011)

Log Message:
-----------
raise a RuntimeError when non-blocking mode is set to a connection allocated from OCI8::ConnectionPool on ruby 1.8.

Modified Paths:
--------------
    trunk/ruby-oci8/ChangeLog
    trunk/ruby-oci8/ext/oci8/oci8.c
    trunk/ruby-oci8/test/test_connection_pool.rb
    trunk/ruby-oci8/test/test_oranumber.rb

Modified: trunk/ruby-oci8/ChangeLog
===================================================================
--- trunk/ruby-oci8/ChangeLog	2011-12-05 13:25:24 UTC (rev 477)
+++ trunk/ruby-oci8/ChangeLog	2011-12-06 11:10:34 UTC (rev 478)
@@ -1,3 +1,10 @@
+2011-12-06  KUBO Takehiro  <kubo at jiubao.org>
+	* ext/oci8/oci8.c: raise a RuntimeError when non-blocking mode is set to a connection
+	    allocated from OCI8::ConnectionPool on ruby 1.8.
+	    Ruby 1.9.x and rubinius don't have the limitation.
+	* test/test_connection_pool.rb: fix for ruby 1.8.
+	* test/test_oranumber.rb: fix for ruby 1.9.1 and 1.8.
+
 2011-12-05  KUBO Takehiro  <kubo at jiubao.org>
 	* lib/oci8/oci8.rb, lib/oci8/properties.rb, test/test_datetime.rb.
 	    add OCI8.properties[:time_zone] and use ENV['TZ'] or the time_zone
@@ -2,3 +9,3 @@
 	    propery to set Oracle session time zone.
-	    Fix #3 at http://github.com/kubo/ruby-oci8.
+	    Fix #2 at http://github.com/kubo/ruby-oci8.
 	    (reported by Yasuo Honda)

Modified: trunk/ruby-oci8/ext/oci8/oci8.c
===================================================================
--- trunk/ruby-oci8/ext/oci8/oci8.c	2011-12-05 13:25:24 UTC (rev 477)
+++ trunk/ruby-oci8/ext/oci8/oci8.c	2011-12-06 11:10:34 UTC (rev 478)
@@ -33,6 +33,7 @@
 
 #define OCI8_STATE_SESSION_BEGIN_WAS_CALLED 0x01
 #define OCI8_STATE_SERVER_ATTACH_WAS_CALLED 0x02
+#define OCI8_STATE_CPOOL 0x04
 
 static VALUE cOCI8;
 static VALUE cSession;
@@ -446,9 +447,10 @@
  *
  * Attachs to the server by the OCI function OCIServerAttach().
  */
-static VALUE oci8_server_attach(VALUE self, VALUE dbname, VALUE mode)
+static VALUE oci8_server_attach(VALUE self, VALUE dbname, VALUE attach_mode)
 {
     oci8_svcctx_t *svcctx = oci8_get_svcctx(self);
+    ub4 mode = NUM2UINT(attach_mode);
 
     if (svcctx->logoff_strategy != &complex_logoff) {
         rb_raise(rb_eRuntimeError, "Use this method only for the service context handle created by OCI8#server_handle().");
@@ -461,19 +463,21 @@
     if (!NIL_P(dbname)) {
         OCI8SafeStringValue(dbname);
     }
-    Check_Type(mode, T_FIXNUM);
 
     /* attach to the server */
     chker2(OCIServerAttach_nb(svcctx, svcctx->srvhp, oci8_errhp,
                               NIL_P(dbname) ? NULL : RSTRING_ORATEXT(dbname),
                               NIL_P(dbname) ? 0 : RSTRING_LEN(dbname),
-                              FIX2UINT(mode)),
+                              mode),
            &svcctx->base);
     chker2(OCIAttrSet(svcctx->base.hp.ptr, OCI_HTYPE_SVCCTX,
                       svcctx->srvhp, 0, OCI_ATTR_SERVER,
                       oci8_errhp),
            &svcctx->base);
     svcctx->state |= OCI8_STATE_SERVER_ATTACH_WAS_CALLED;
+    if (mode & OCI_CPOOL) {
+        svcctx->state |= OCI8_STATE_CPOOL;
+    }
     return self;
 }
 
@@ -630,6 +634,9 @@
 #else
     sb1 non_blocking;
 
+    if (svcctx->state & OCI8_STATE_CPOOL) {
+        rb_raise(rb_eRuntimeError, "Could not set non-blocking mode to a connection allocated from OCI8::ConnectionPool.");
+    }
     chker2(OCIAttrGet(svcctx->srvhp, OCI_HTYPE_SERVER, &non_blocking, 0, OCI_ATTR_NONBLOCKING_MODE, oci8_errhp), &svcctx->base);
     if ((RTEST(val) && !non_blocking) || (!RTEST(val) && non_blocking)) {
         /* toggle blocking / non-blocking. */

Modified: trunk/ruby-oci8/test/test_connection_pool.rb
===================================================================
--- trunk/ruby-oci8/test/test_connection_pool.rb	2011-12-05 13:25:24 UTC (rev 477)
+++ trunk/ruby-oci8/test/test_connection_pool.rb	2011-12-06 11:10:34 UTC (rev 478)
@@ -39,10 +39,22 @@
     assert_equal(min_cnt, pool.open_count, msg)
     assert_equal(0, pool.busy_count, msg)
 
+    non_blocking = true
+
     # Create connections from the pool.
     conns = []
-    max_cnt.times do
-      conns << OCI8.new($dbuser, $dbpass, pool)
+    max_cnt.times do |cnt|
+      conn = OCI8.new($dbuser, $dbpass, pool)
+      if cnt == 0
+        unless conn.non_blocking?
+          non_blocking = false
+          assert_raise(RuntimeError) do
+            # This should raise "Could not set non-blocking mode to a connection allocated from OCI8::ConnectionPool."
+            conn.non_blocking = true
+          end
+        end
+      end
+      conns << conn
     end
     assert_equal(min_cnt, pool.open_count, msg)
     assert_equal(0, pool.busy_count, msg)
@@ -54,7 +66,7 @@
       end
       sleep(0.5)
       assert_equal(min_cnt, pool.open_count, msg)
-      assert_equal(1, pool.busy_count, msg)
+      assert_equal(non_blocking ? 1 : 0, pool.busy_count, msg)
       thread.join
     end
     assert_equal(min_cnt, pool.open_count, msg)
@@ -68,8 +80,8 @@
       end
     end
     sleep(0.5)
-    assert_equal(min_cnt + incr_cnt, pool.open_count, msg)
-    assert_equal(min_cnt + 1, pool.busy_count, msg)
+    assert_equal(non_blocking ? (min_cnt + incr_cnt) : min_cnt, pool.open_count, msg)
+    assert_equal(non_blocking ? (min_cnt + 1) : 0, pool.busy_count, msg)
 
     # Execute blocking SQL statements parallel up to maximum.
     (min_cnt + 1).upto(max_cnt - 1) do |n|
@@ -78,20 +90,20 @@
       end
     end
     sleep(0.5)
-    assert_equal(max_cnt, pool.open_count, msg)
-    assert_equal(max_cnt, pool.busy_count, msg)
+    assert_equal(non_blocking ? max_cnt : min_cnt, pool.open_count, msg)
+    assert_equal(non_blocking ? max_cnt : 0, pool.busy_count, msg)
 
     # 
     threads.each do |thr|
       thr.join
     end
-    assert_equal(max_cnt, pool.open_count, msg)
+    assert_equal(non_blocking ? max_cnt : min_cnt, pool.open_count, msg)
     assert_equal(0, pool.busy_count, msg)
 
     # Set timeout
     pool.timeout = 1
     sleep(1.5)
-    assert_equal(max_cnt, pool.open_count, msg) # open_count doesn't shrink.
+    assert_equal(non_blocking ? max_cnt : min_cnt, pool.open_count, msg) # open_count doesn't shrink.
     assert_equal(0, pool.busy_count, msg)
     conns[0].ping # make a network roundtrip.
     sleep(0.5)

Modified: trunk/ruby-oci8/test/test_oranumber.rb
===================================================================
--- trunk/ruby-oci8/test/test_oranumber.rb	2011-12-05 13:25:24 UTC (rev 477)
+++ trunk/ruby-oci8/test/test_oranumber.rb	2011-12-06 11:10:34 UTC (rev 478)
@@ -760,15 +760,25 @@
       end
       cursor.close
       # Ruby Float -> Oracle Number
-      cursor = conn.parse('begin :out := :in; end;')
-      cursor.bind_param(:in, nil, Float)
-      cursor.bind_param(:out, nil, String, 50)
       LARGE_RANGE_VALUES.each do |n|
-        cursor[:in] = n.to_f
-        cursor.exec
-        assert_equal(n.to_f, cursor[:out].to_f)
+        float_val = n.to_f
+        expected_val = float_val.to_s
+        # convert 
+        if /(-?)(\d).(\d+)e([+-]?\d+)/ =~ expected_val
+          sign = $1
+          int = $2
+          frac = $3
+          shift = $4.to_i
+          if frac.length <= shift
+            expected_val = sign + int + frac + '0' * (shift - frac.length)
+          elsif shift < 0
+            expected_val = sign + '0.' + '0' * (-shift - 1) + int + frac
+            expected_val.gsub!(/0+$/, '')
+          end
+        end
+        expected_val.gsub!(/\.0$/, '')
+        assert_equal(expected_val, OraNumber(float_val).to_s, "n = #{n}, float_val.to_s = #{float_val.to_s}")
       end
-      cursor.close
     ensure
       OCI8.properties[:float_conversion_type] = orig
       conn.logoff




More information about the ruby-oci8-commit mailing list