Skip to content

Instantly share code, notes, and snippets.

@kubo
Created December 3, 2010 12:36
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kubo/726904 to your computer and use it in GitHub Desktop.
Save kubo/726904 to your computer and use it in GitHub Desktop.
patch to bind null to object type for ruby-oci8 2.0.4
Index: ext/oci8/object.c
===================================================================
--- ext/oci8/object.c (revision 411)
+++ ext/oci8/object.c (working copy)
@@ -248,6 +248,25 @@
return Qnil;
}
+static VALUE oci8_named_type_null_p(VALUE self)
+{
+ void *data;
+ OCIInd *ind;
+
+ oci8_named_type_check_offset(self, INT2FIX(0), INT2FIX(0), sizeof(void*), &data, &ind);
+ return *ind ? Qtrue : Qfalse;
+}
+
+static VALUE oci8_named_type_set_null(VALUE self, VALUE boolean)
+{
+ void *data;
+ OCIInd *ind;
+
+ oci8_named_type_check_offset(self, INT2FIX(0), INT2FIX(0), sizeof(void*), &data, &ind);
+ *ind = RTEST(boolean) ? -1 : 0;
+ return boolean;
+}
+
typedef struct {
VALUE self;
VALUE datatype;
@@ -578,6 +597,7 @@
oci_lc(OCIObjectNew(oci8_envhp, oci8_errhp, svcctx->base.hp.svc, tc, tdo->hp.tdo, NULL, OCI_DURATION_SESSION, TRUE, (dvoid**)obj->instancep));
oci_lc(OCIObjectGetInd(oci8_envhp, oci8_errhp, (dvoid*)*obj->instancep, (dvoid**)obj->null_structp));
+ *(OCIInd*)*obj->null_structp = -1;
} while (++idx < obind->maxar_sz);
}
@@ -633,6 +653,8 @@
rb_define_method(cOCI8NamedType, "tdo", oci8_named_type_tdo, 0);
rb_define_private_method(cOCI8NamedType, "get_attribute", oci8_named_type_get_attribute, 4);
rb_define_private_method(cOCI8NamedType, "set_attribute", oci8_named_type_set_attribute, 5);
+ rb_define_method(cOCI8NamedType, "null?", oci8_named_type_null_p, 0);
+ rb_define_method(cOCI8NamedType, "null=", oci8_named_type_set_null, 1);
/* OCI8::NamedCollection */
cOCI8NamedCollection = oci8_define_class_under(cOCI8, "NamedCollection", &oci8_named_type_class);
Index: ext/oci8/bind.c
===================================================================
--- ext/oci8/bind.c (revision 411)
+++ ext/oci8/bind.c (working copy)
@@ -303,10 +303,12 @@
if (NIL_P(obind->tdo)) {
if (obind->u.inds[idx] != 0)
return Qnil;
+#if 0
} else {
null_structp = &obind->u.null_structs[idx];
if (*(OCIInd*)*null_structp != 0)
return Qnil;
+#endif
}
return obc->get(obind, (void*)((size_t)obind->valuep + obind->alloc_sz * idx), null_structp);
}
@@ -350,6 +352,7 @@
obind->u.inds[idx] = 0;
} else {
null_structp = &obind->u.null_structs[idx];
+ *(OCIInd*)obind->u.null_structs[idx] = 0;
}
obc->set(obind, (void*)((size_t)obind->valuep + obind->alloc_sz * idx), null_structp, val);
}
Index: lib/oci8/object.rb
===================================================================
--- lib/oci8/object.rb (revision 411)
+++ lib/oci8/object.rb (working copy)
@@ -487,6 +487,7 @@
class NamedType
def to_value
+ return nil if self.null?
obj = tdo.ruby_class.new
obj.instance_variable_set(:@attributes, self.attributes)
obj
@@ -503,11 +504,16 @@
end
def attributes=(obj)
- obj = obj.instance_variable_get(:@attributes) unless obj.is_a? Hash
- tdo.attributes.each do |attr|
- 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)
+ if obj.nil?
+ self.null = true
+ else
+ obj = obj.instance_variable_get(:@attributes) unless obj.is_a? Hash
+ tdo.attributes.each do |attr|
+ 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
+ self.null = false
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment