[ruby-oci8-commit] [405] trunk/ruby-oci8: * ext/oci8/lob.c, ext/oci8/object.c, ext/oci8/oci8.h ,

nobody at rubyforge.org nobody at rubyforge.org
Sun Aug 15 08:33:14 EDT 2010


Revision: 405
Author:   kubo
Date:     2010-08-15 08:33:14 -0400 (Sun, 15 Aug 2010)

Log Message:
-----------
* ext/oci8/lob.c, ext/oci8/object.c, ext/oci8/oci8.h,
  lib/oci8/object.rb: support LOB datatypes in Oracle objects.
* ext/oci8/ocihandle.c: fix SEGV in finalizer when temporary LOBs
    are used. This bug was introduced by the previous commit.

Modified Paths:
--------------
    branches/ruby-oci8-2.0/ChangeLog
    branches/ruby-oci8-2.0/ext/oci8/lob.c
    branches/ruby-oci8-2.0/ext/oci8/object.c
    branches/ruby-oci8-2.0/ext/oci8/oci8.h
    branches/ruby-oci8-2.0/ext/oci8/ocihandle.c
    branches/ruby-oci8-2.0/lib/oci8/object.rb
    trunk/ruby-oci8/ChangeLog
    trunk/ruby-oci8/ext/oci8/lob.c
    trunk/ruby-oci8/ext/oci8/object.c
    trunk/ruby-oci8/ext/oci8/oci8.h
    trunk/ruby-oci8/ext/oci8/ocihandle.c
    trunk/ruby-oci8/lib/oci8/object.rb

Modified: branches/ruby-oci8-2.0/ChangeLog
===================================================================
--- branches/ruby-oci8-2.0/ChangeLog	2010-08-15 05:12:32 UTC (rev 404)
+++ branches/ruby-oci8-2.0/ChangeLog	2010-08-15 12:33:14 UTC (rev 405)
@@ -1,4 +1,10 @@
 2010-08-15  KUBO Takehiro  <kubo at jiubao.org>
+	* ext/oci8/lob.c, ext/oci8/object.c, ext/oci8/oci8.h,
+	  lib/oci8/object.rb: support LOB datatypes in Oracle objects.
+	* ext/oci8/ocihandle.c: fix SEGV in finalizer when temporary LOBs
+	    are used. This bug was introduced by the previous commit.
+
+2010-08-15  KUBO Takehiro  <kubo at jiubao.org>
 	* ext/oci8/apiwrap.yml, ext/oci8/lob.c: fix memory leak when temporary
 	    lobs are used.
 

Modified: branches/ruby-oci8-2.0/ext/oci8/lob.c
===================================================================
--- branches/ruby-oci8-2.0/ext/oci8/lob.c	2010-08-15 05:12:32 UTC (rev 404)
+++ branches/ruby-oci8-2.0/ext/oci8/lob.c	2010-08-15 12:33:14 UTC (rev 405)
@@ -64,6 +64,33 @@
     return oci8_make_lob(cOCI8BFILE, svcctx, s);
 }
 
+static void oci8_assign_lob(VALUE klass, oci8_svcctx_t *svcctx, VALUE lob, OCILobLocator **dest)
+{
+    oci8_base_t *base;
+    Check_Handle(lob, klass, base);
+    oci_lc(OCILobLocatorAssign_nb(svcctx, svcctx->base.hp.svc, oci8_errhp, base->hp.lob, dest));
+}
+
+void oci8_assign_clob(oci8_svcctx_t *svcctx, VALUE lob, OCILobLocator **dest)
+{
+    oci8_assign_lob(cOCI8CLOB, svcctx, lob, dest);
+}
+
+void oci8_assign_nclob(oci8_svcctx_t *svcctx, VALUE lob, OCILobLocator **dest)
+{
+    oci8_assign_lob(cOCI8NCLOB, svcctx, lob, dest);
+}
+
+void oci8_assign_blob(oci8_svcctx_t *svcctx, VALUE lob, OCILobLocator **dest)
+{
+    oci8_assign_lob(cOCI8BLOB, svcctx, lob, dest);
+}
+
+void oci8_assign_bfile(oci8_svcctx_t *svcctx, VALUE lob, OCILobLocator **dest)
+{
+    oci8_assign_lob(cOCI8BFILE, svcctx, lob, dest);
+}
+
 static void oci8_lob_mark(oci8_base_t *base)
 {
     oci8_lob_t *lob = (oci8_lob_t *)base;

Modified: branches/ruby-oci8-2.0/ext/oci8/object.c
===================================================================
--- branches/ruby-oci8-2.0/ext/oci8/object.c	2010-08-15 05:12:32 UTC (rev 404)
+++ branches/ruby-oci8-2.0/ext/oci8/object.c	2010-08-15 12:33:14 UTC (rev 405)
@@ -42,6 +42,10 @@
     ATTR_BINARY_FLOAT,
     ATTR_NAMED_TYPE,
     ATTR_NAMED_COLLECTION,
+    ATTR_CLOB,
+    ATTR_NCLOB,
+    ATTR_BLOB,
+    ATTR_BFILE,
 };
 
 static VALUE get_attribute(VALUE self, VALUE datatype, VALUE typeinfo, void *data, OCIInd *ind);
@@ -198,6 +202,14 @@
         rv = rb_funcall(tmp_obj, id_to_value, 0);
         oci8_unlink_from_parent(&obj->base);
         return rv;
+    case ATTR_CLOB:
+        return oci8_make_clob(oci8_get_svcctx(typeinfo), *(OCILobLocator**)data);
+    case ATTR_NCLOB:
+        return oci8_make_nclob(oci8_get_svcctx(typeinfo), *(OCILobLocator**)data);
+    case ATTR_BLOB:
+        return oci8_make_blob(oci8_get_svcctx(typeinfo), *(OCILobLocator**)data);
+    case ATTR_BFILE:
+        return oci8_make_bfile(oci8_get_svcctx(typeinfo), *(OCILobLocator**)data);
     default:
         rb_raise(rb_eRuntimeError, "not supported datatype");
     }
@@ -335,6 +347,11 @@
         oci_lc(OCIObjectNew(oci8_envhp, oci8_errhp, svcctx->hp.svc, OCI_TYPECODE_NAMEDCOLLECTION, tdo->hp.tdo, NULL, OCI_DURATION_SESSION, TRUE, &cb_data.data.ptr));
         oci_lc(OCIObjectGetInd(oci8_envhp, oci8_errhp, cb_data.data.ptr, (dvoid**)&cb_data.indp));
         break;
+    case ATTR_CLOB:
+    case ATTR_NCLOB:
+    case ATTR_BLOB:
+    case ATTR_BFILE:
+        rb_raise(rb_eRuntimeError, "Could not set LOB objects to collection types yet.");
     default:
         rb_raise(rb_eRuntimeError, "not supported datatype");
     }
@@ -482,6 +499,18 @@
         rb_funcall(tmp_obj, id_set_attributes, 1, val);
         oci8_unlink_from_parent(&obj->base);
         break;
+    case ATTR_CLOB:
+        oci8_assign_clob(oci8_get_svcctx(typeinfo), val, (OCILobLocator **)data);
+        break;
+    case ATTR_NCLOB:
+        oci8_assign_nclob(oci8_get_svcctx(typeinfo), val, (OCILobLocator **)data);
+        break;
+    case ATTR_BLOB:
+        oci8_assign_blob(oci8_get_svcctx(typeinfo), val, (OCILobLocator **)data);
+        break;
+    case ATTR_BFILE:
+        oci8_assign_bfile(oci8_get_svcctx(typeinfo), val, (OCILobLocator **)data);
+        break;
     default:
         rb_raise(rb_eRuntimeError, "not supported datatype");
     }
@@ -615,6 +644,10 @@
     rb_define_const(cOCI8TDO, "ATTR_BINARY_FLOAT", INT2FIX(ATTR_BINARY_FLOAT));
     rb_define_const(cOCI8TDO, "ATTR_NAMED_TYPE", INT2FIX(ATTR_NAMED_TYPE));
     rb_define_const(cOCI8TDO, "ATTR_NAMED_COLLECTION", INT2FIX(ATTR_NAMED_COLLECTION));
+    rb_define_const(cOCI8TDO, "ATTR_CLOB", INT2FIX(ATTR_CLOB));
+    rb_define_const(cOCI8TDO, "ATTR_NCLOB", INT2FIX(ATTR_NCLOB));
+    rb_define_const(cOCI8TDO, "ATTR_BLOB", INT2FIX(ATTR_BLOB));
+    rb_define_const(cOCI8TDO, "ATTR_BFILE", INT2FIX(ATTR_BFILE));
 #define ALIGNMENT_OF(type) (size_t)&(((struct {char c; type t;}*)0)->t)
     rb_define_const(cOCI8TDO, "SIZE_OF_POINTER", INT2FIX(sizeof(void *)));
     rb_define_const(cOCI8TDO, "ALIGNMENT_OF_POINTER", INT2FIX(ALIGNMENT_OF(void *)));

Modified: branches/ruby-oci8-2.0/ext/oci8/oci8.h
===================================================================
--- branches/ruby-oci8-2.0/ext/oci8/oci8.h	2010-08-15 05:12:32 UTC (rev 404)
+++ branches/ruby-oci8-2.0/ext/oci8/oci8.h	2010-08-15 12:33:14 UTC (rev 405)
@@ -460,6 +460,10 @@
 VALUE oci8_make_nclob(oci8_svcctx_t *svcctx, OCILobLocator *s);
 VALUE oci8_make_blob(oci8_svcctx_t *svcctx, OCILobLocator *s);
 VALUE oci8_make_bfile(oci8_svcctx_t *svcctx, OCILobLocator *s);
+void oci8_assign_clob(oci8_svcctx_t *svcctx, VALUE lob, OCILobLocator **dest);
+void oci8_assign_nclob(oci8_svcctx_t *svcctx, VALUE lob, OCILobLocator **dest);
+void oci8_assign_blob(oci8_svcctx_t *svcctx, VALUE lob, OCILobLocator **dest);
+void oci8_assign_bfile(oci8_svcctx_t *svcctx, VALUE lob, OCILobLocator **dest);
 
 /* oradate.c */
 void Init_ora_date(void);

Modified: branches/ruby-oci8-2.0/ext/oci8/ocihandle.c
===================================================================
--- branches/ruby-oci8-2.0/ext/oci8/ocihandle.c	2010-08-15 05:12:32 UTC (rev 404)
+++ branches/ruby-oci8-2.0/ext/oci8/ocihandle.c	2010-08-15 12:33:14 UTC (rev 405)
@@ -61,6 +61,14 @@
 
 static void oci8_handle_cleanup(oci8_base_t *base)
 {
+    if (oci8_in_finalizer) {
+        /* Do nothing when the program exits.
+         * The first two words of memory addressed by VALUE datatype is
+         * changed in finalizer. If a ruby function which access it such
+         * as rb_obj_is_kind_of is called, it may cause SEGV.
+         */
+        return;
+    }
     oci8_base_free(base);
     xfree(base);
 }

Modified: branches/ruby-oci8-2.0/lib/oci8/object.rb
===================================================================
--- branches/ruby-oci8-2.0/lib/oci8/object.rb	2010-08-15 05:12:32 UTC (rev 404)
+++ branches/ruby-oci8-2.0/lib/oci8/object.rb	2010-08-15 12:33:14 UTC (rev 405)
@@ -457,6 +457,16 @@
         #[ATTR_NAMED_COLLECTION, [datatype, typeinfo], SIZE_OF_POINTER, 2, ALIGNMENT_OF_POINTER]
         tdo = con.get_tdo_by_metadata(metadata.type_metadata)
         [ATTR_NAMED_COLLECTION, tdo, tdo.val_size, tdo.ind_size, tdo.alignment]
+      when :clob
+        if metadata.charset_form != :nchar
+          [ATTR_CLOB, con, SIZE_OF_POINTER, 2, ALIGNMENT_OF_POINTER]
+        else
+          [ATTR_NCLOB, con, SIZE_OF_POINTER, 2, ALIGNMENT_OF_POINTER]
+        end
+      when :blob
+        [ATTR_BLOB, con, SIZE_OF_POINTER, 2, ALIGNMENT_OF_POINTER]
+      when :bfile
+        [ATTR_BFILE, con, SIZE_OF_POINTER, 2, ALIGNMENT_OF_POINTER]
       else
         raise "unsupported typecode #{metadata.typecode}"
       end

Modified: trunk/ruby-oci8/ChangeLog
===================================================================
--- trunk/ruby-oci8/ChangeLog	2010-08-15 05:12:32 UTC (rev 404)
+++ trunk/ruby-oci8/ChangeLog	2010-08-15 12:33:14 UTC (rev 405)
@@ -1,4 +1,10 @@
 2010-08-15  KUBO Takehiro  <kubo at jiubao.org>
+	* ext/oci8/lob.c, ext/oci8/object.c, ext/oci8/oci8.h,
+	  lib/oci8/object.rb: support LOB datatypes in Oracle objects.
+	* ext/oci8/ocihandle.c: fix SEGV in finalizer when temporary LOBs
+	    are used. This bug was introduced by the previous commit.
+
+2010-08-15  KUBO Takehiro  <kubo at jiubao.org>
 	* ext/oci8/apiwrap.yml, ext/oci8/lob.c: fix memory leak when temporary
 	    lobs are used.
 

Modified: trunk/ruby-oci8/ext/oci8/lob.c
===================================================================
--- trunk/ruby-oci8/ext/oci8/lob.c	2010-08-15 05:12:32 UTC (rev 404)
+++ trunk/ruby-oci8/ext/oci8/lob.c	2010-08-15 12:33:14 UTC (rev 405)
@@ -64,6 +64,33 @@
     return oci8_make_lob(cOCI8BFILE, svcctx, s);
 }
 
+static void oci8_assign_lob(VALUE klass, oci8_svcctx_t *svcctx, VALUE lob, OCILobLocator **dest)
+{
+    oci8_base_t *base;
+    Check_Handle(lob, klass, base);
+    oci_lc(OCILobLocatorAssign_nb(svcctx, svcctx->base.hp.svc, oci8_errhp, base->hp.lob, dest));
+}
+
+void oci8_assign_clob(oci8_svcctx_t *svcctx, VALUE lob, OCILobLocator **dest)
+{
+    oci8_assign_lob(cOCI8CLOB, svcctx, lob, dest);
+}
+
+void oci8_assign_nclob(oci8_svcctx_t *svcctx, VALUE lob, OCILobLocator **dest)
+{
+    oci8_assign_lob(cOCI8NCLOB, svcctx, lob, dest);
+}
+
+void oci8_assign_blob(oci8_svcctx_t *svcctx, VALUE lob, OCILobLocator **dest)
+{
+    oci8_assign_lob(cOCI8BLOB, svcctx, lob, dest);
+}
+
+void oci8_assign_bfile(oci8_svcctx_t *svcctx, VALUE lob, OCILobLocator **dest)
+{
+    oci8_assign_lob(cOCI8BFILE, svcctx, lob, dest);
+}
+
 static void oci8_lob_mark(oci8_base_t *base)
 {
     oci8_lob_t *lob = (oci8_lob_t *)base;

Modified: trunk/ruby-oci8/ext/oci8/object.c
===================================================================
--- trunk/ruby-oci8/ext/oci8/object.c	2010-08-15 05:12:32 UTC (rev 404)
+++ trunk/ruby-oci8/ext/oci8/object.c	2010-08-15 12:33:14 UTC (rev 405)
@@ -42,6 +42,10 @@
     ATTR_BINARY_FLOAT,
     ATTR_NAMED_TYPE,
     ATTR_NAMED_COLLECTION,
+    ATTR_CLOB,
+    ATTR_NCLOB,
+    ATTR_BLOB,
+    ATTR_BFILE,
 };
 
 static VALUE get_attribute(VALUE self, VALUE datatype, VALUE typeinfo, void *data, OCIInd *ind);
@@ -198,6 +202,14 @@
         rv = rb_funcall(tmp_obj, id_to_value, 0);
         oci8_unlink_from_parent(&obj->base);
         return rv;
+    case ATTR_CLOB:
+        return oci8_make_clob(oci8_get_svcctx(typeinfo), *(OCILobLocator**)data);
+    case ATTR_NCLOB:
+        return oci8_make_nclob(oci8_get_svcctx(typeinfo), *(OCILobLocator**)data);
+    case ATTR_BLOB:
+        return oci8_make_blob(oci8_get_svcctx(typeinfo), *(OCILobLocator**)data);
+    case ATTR_BFILE:
+        return oci8_make_bfile(oci8_get_svcctx(typeinfo), *(OCILobLocator**)data);
     default:
         rb_raise(rb_eRuntimeError, "not supported datatype");
     }
@@ -335,6 +347,11 @@
         oci_lc(OCIObjectNew(oci8_envhp, oci8_errhp, svcctx->hp.svc, OCI_TYPECODE_NAMEDCOLLECTION, tdo->hp.tdo, NULL, OCI_DURATION_SESSION, TRUE, &cb_data.data.ptr));
         oci_lc(OCIObjectGetInd(oci8_envhp, oci8_errhp, cb_data.data.ptr, (dvoid**)&cb_data.indp));
         break;
+    case ATTR_CLOB:
+    case ATTR_NCLOB:
+    case ATTR_BLOB:
+    case ATTR_BFILE:
+        rb_raise(rb_eRuntimeError, "Could not set LOB objects to collection types yet.");
     default:
         rb_raise(rb_eRuntimeError, "not supported datatype");
     }
@@ -482,6 +499,18 @@
         rb_funcall(tmp_obj, id_set_attributes, 1, val);
         oci8_unlink_from_parent(&obj->base);
         break;
+    case ATTR_CLOB:
+        oci8_assign_clob(oci8_get_svcctx(typeinfo), val, (OCILobLocator **)data);
+        break;
+    case ATTR_NCLOB:
+        oci8_assign_nclob(oci8_get_svcctx(typeinfo), val, (OCILobLocator **)data);
+        break;
+    case ATTR_BLOB:
+        oci8_assign_blob(oci8_get_svcctx(typeinfo), val, (OCILobLocator **)data);
+        break;
+    case ATTR_BFILE:
+        oci8_assign_bfile(oci8_get_svcctx(typeinfo), val, (OCILobLocator **)data);
+        break;
     default:
         rb_raise(rb_eRuntimeError, "not supported datatype");
     }
@@ -631,6 +660,10 @@
     rb_define_const(cOCI8TDO, "ATTR_BINARY_FLOAT", INT2FIX(ATTR_BINARY_FLOAT));
     rb_define_const(cOCI8TDO, "ATTR_NAMED_TYPE", INT2FIX(ATTR_NAMED_TYPE));
     rb_define_const(cOCI8TDO, "ATTR_NAMED_COLLECTION", INT2FIX(ATTR_NAMED_COLLECTION));
+    rb_define_const(cOCI8TDO, "ATTR_CLOB", INT2FIX(ATTR_CLOB));
+    rb_define_const(cOCI8TDO, "ATTR_NCLOB", INT2FIX(ATTR_NCLOB));
+    rb_define_const(cOCI8TDO, "ATTR_BLOB", INT2FIX(ATTR_BLOB));
+    rb_define_const(cOCI8TDO, "ATTR_BFILE", INT2FIX(ATTR_BFILE));
 #define ALIGNMENT_OF(type) (size_t)&(((struct {char c; type t;}*)0)->t)
     rb_define_const(cOCI8TDO, "SIZE_OF_POINTER", INT2FIX(sizeof(void *)));
     rb_define_const(cOCI8TDO, "ALIGNMENT_OF_POINTER", INT2FIX(ALIGNMENT_OF(void *)));

Modified: trunk/ruby-oci8/ext/oci8/oci8.h
===================================================================
--- trunk/ruby-oci8/ext/oci8/oci8.h	2010-08-15 05:12:32 UTC (rev 404)
+++ trunk/ruby-oci8/ext/oci8/oci8.h	2010-08-15 12:33:14 UTC (rev 405)
@@ -471,6 +471,10 @@
 VALUE oci8_make_nclob(oci8_svcctx_t *svcctx, OCILobLocator *s);
 VALUE oci8_make_blob(oci8_svcctx_t *svcctx, OCILobLocator *s);
 VALUE oci8_make_bfile(oci8_svcctx_t *svcctx, OCILobLocator *s);
+void oci8_assign_clob(oci8_svcctx_t *svcctx, VALUE lob, OCILobLocator **dest);
+void oci8_assign_nclob(oci8_svcctx_t *svcctx, VALUE lob, OCILobLocator **dest);
+void oci8_assign_blob(oci8_svcctx_t *svcctx, VALUE lob, OCILobLocator **dest);
+void oci8_assign_bfile(oci8_svcctx_t *svcctx, VALUE lob, OCILobLocator **dest);
 
 /* oradate.c */
 void Init_ora_date(void);

Modified: trunk/ruby-oci8/ext/oci8/ocihandle.c
===================================================================
--- trunk/ruby-oci8/ext/oci8/ocihandle.c	2010-08-15 05:12:32 UTC (rev 404)
+++ trunk/ruby-oci8/ext/oci8/ocihandle.c	2010-08-15 12:33:14 UTC (rev 405)
@@ -61,6 +61,14 @@
 
 static void oci8_handle_cleanup(oci8_base_t *base)
 {
+    if (oci8_in_finalizer) {
+        /* Do nothing when the program exits.
+         * The first two words of memory addressed by VALUE datatype is
+         * changed in finalizer. If a ruby function which access it such
+         * as rb_obj_is_kind_of is called, it may cause SEGV.
+         */
+        return;
+    }
     oci8_base_free(base);
     xfree(base);
 }

Modified: trunk/ruby-oci8/lib/oci8/object.rb
===================================================================
--- trunk/ruby-oci8/lib/oci8/object.rb	2010-08-15 05:12:32 UTC (rev 404)
+++ trunk/ruby-oci8/lib/oci8/object.rb	2010-08-15 12:33:14 UTC (rev 405)
@@ -457,6 +457,16 @@
         #[ATTR_NAMED_COLLECTION, [datatype, typeinfo], SIZE_OF_POINTER, 2, ALIGNMENT_OF_POINTER]
         tdo = con.get_tdo_by_metadata(metadata.type_metadata)
         [ATTR_NAMED_COLLECTION, tdo, tdo.val_size, tdo.ind_size, tdo.alignment]
+      when :clob
+        if metadata.charset_form != :nchar
+          [ATTR_CLOB, con, SIZE_OF_POINTER, 2, ALIGNMENT_OF_POINTER]
+        else
+          [ATTR_NCLOB, con, SIZE_OF_POINTER, 2, ALIGNMENT_OF_POINTER]
+        end
+      when :blob
+        [ATTR_BLOB, con, SIZE_OF_POINTER, 2, ALIGNMENT_OF_POINTER]
+      when :bfile
+        [ATTR_BFILE, con, SIZE_OF_POINTER, 2, ALIGNMENT_OF_POINTER]
       else
         raise "unsupported typecode #{metadata.typecode}"
       end




More information about the ruby-oci8-commit mailing list