[ruby-oci8-commit] [320] trunk/ruby-oci8: * ext/oci8/bind.c, ext/oci8/oci8.h, ext/oci8/stmt.c: fix array DML
nobody at rubyforge.org
nobody at rubyforge.org
Tue Feb 10 08:50:41 EST 2009
Revision: 320
Author: kubo
Date: 2009-02-10 08:50:40 -0500 (Tue, 10 Feb 2009)
Log Message:
-----------
* ext/oci8/bind.c, ext/oci8/oci8.h, ext/oci8/stmt.c: fix array DML
and DateTime object problem. It didn't work with bind classes
which overwrite 'set' and 'get'. (Reported by Leo?\197?\161 Bitto)
* test/test_array_dml.rb: fix to test array DML and DateTime object.
Modified Paths:
--------------
trunk/ruby-oci8/ChangeLog
trunk/ruby-oci8/ext/oci8/bind.c
trunk/ruby-oci8/ext/oci8/oci8.h
trunk/ruby-oci8/ext/oci8/stmt.c
trunk/ruby-oci8/test/test_array_dml.rb
Modified: trunk/ruby-oci8/ChangeLog
===================================================================
--- trunk/ruby-oci8/ChangeLog 2009-02-08 13:28:56 UTC (rev 319)
+++ trunk/ruby-oci8/ChangeLog 2009-02-10 13:50:40 UTC (rev 320)
@@ -1,3 +1,9 @@
+2009-02-10 KUBO Takehiro <kubo at jiubao.org>
+ * ext/oci8/bind.c, ext/oci8/oci8.h, ext/oci8/stmt.c: fix array DML
+ and DateTime object problem. It didn't work with bind classes
+ which overwrite 'set' and 'get'. (Reported by Leoš Bitto)
+ * test/test_array_dml.rb: fix to test array DML and DateTime object.
+
2009-02-08 KUBO Takehiro <kubo at jiubao.org>
* VERSION: change version from 2.0-svn to 2.0.0 to pass ruby
gem's version string validator.
Modified: trunk/ruby-oci8/ext/oci8/bind.c
===================================================================
--- trunk/ruby-oci8/ext/oci8/bind.c 2009-02-08 13:28:56 UTC (rev 319)
+++ trunk/ruby-oci8/ext/oci8/bind.c 2009-02-10 13:50:40 UTC (rev 320)
@@ -10,7 +10,6 @@
#include "oci8.h"
static ID id_bind_type;
-static ID id_set;
static VALUE cOCI8BindTypeBase;
@@ -330,8 +329,11 @@
SQLT_BDOUBLE
};
-static inline VALUE oci8_get_data_at(const oci8_bind_class_t *obc, oci8_bind_t *obind, ub4 idx)
+static VALUE oci8_bind_get(VALUE self)
{
+ oci8_bind_t *obind = DATA_PTR(self);
+ const oci8_bind_class_t *obc = (const oci8_bind_class_t *)obind->base.klass;
+ ub4 idx = obind->curar_idx;
void **null_structp = NULL;
if (NIL_P(obind->tdo)) {
@@ -345,26 +347,30 @@
return obc->get(obind, (void*)((size_t)obind->valuep + obind->alloc_sz * idx), null_structp);
}
-static VALUE oci8_get_data(VALUE self)
+VALUE oci8_bind_get_data(VALUE self)
{
oci8_bind_t *obind = DATA_PTR(self);
- const oci8_bind_class_t *obc = (const oci8_bind_class_t *)obind->base.klass;
if (obind->maxar_sz == 0) {
- return oci8_get_data_at(obc, obind, 0);
+ obind->curar_idx = 0;
+ return rb_funcall(self, oci8_id_get, 0);
} else {
volatile VALUE ary = rb_ary_new2(obind->curar_sz);
ub4 idx;
for (idx = 0; idx < obind->curar_sz; idx++) {
- rb_ary_store(ary, idx, oci8_get_data_at(obc, obind, idx));
+ obind->curar_idx = idx;
+ rb_ary_store(ary, idx, rb_funcall(self, oci8_id_get, 0));
}
return ary;
}
}
-static inline void oci8_set_data_at(const oci8_bind_class_t *obc, oci8_bind_t *obind, ub4 idx, VALUE val)
+static VALUE oci8_bind_set(VALUE self, VALUE val)
{
+ oci8_bind_t *obind = DATA_PTR(self);
+ const oci8_bind_class_t *obc = (const oci8_bind_class_t *)obind->base.klass;
+ ub4 idx = obind->curar_idx;
if (NIL_P(val)) {
if (NIL_P(obind->tdo)) {
@@ -383,15 +389,16 @@
}
obc->set(obind, (void*)((size_t)obind->valuep + obind->alloc_sz * idx), null_structp, val);
}
+ return self;
}
-static VALUE oci8_set_data(VALUE self, VALUE val)
+void oci8_bind_set_data(VALUE self, VALUE val)
{
oci8_bind_t *obind = DATA_PTR(self);
- const oci8_bind_class_t *obc = (const oci8_bind_class_t *)obind->base.klass;
if (obind->maxar_sz == 0) {
- oci8_set_data_at(obc, obind, 0, val);
+ obind->curar_idx = 0;
+ rb_funcall(self, oci8_id_set, 1, val);
} else {
ub4 size;
ub4 idx;
@@ -402,11 +409,11 @@
rb_raise(rb_eRuntimeError, "over the max array size");
}
for (idx = 0; idx < size; idx++) {
- oci8_set_data_at(obc, obind, idx, RARRAY_PTR(val)[idx]);
+ obind->curar_idx = idx;
+ rb_funcall(self, oci8_id_set, 1, RARRAY_PTR(val)[idx]);
}
obind->curar_sz = size;
}
- return self;
}
static VALUE oci8_bind_initialize(VALUE self, VALUE svc, VALUE val, VALUE length, VALUE max_array_size)
@@ -438,7 +445,7 @@
bind_class->init_elem(obind, svc);
}
if (!NIL_P(val)) {
- rb_funcall(self, id_set, 1, val);
+ oci8_bind_set_data(self, val);
}
return Qnil;
}
@@ -474,11 +481,10 @@
{
cOCI8BindTypeBase = klass;
id_bind_type = rb_intern("bind_type");
- id_set = rb_intern("set");
rb_define_method(cOCI8BindTypeBase, "initialize", oci8_bind_initialize, 4);
- rb_define_method(cOCI8BindTypeBase, "get", oci8_get_data, 0);
- rb_define_method(cOCI8BindTypeBase, "set", oci8_set_data, 1);
+ rb_define_method(cOCI8BindTypeBase, "get", oci8_bind_get, 0);
+ rb_define_method(cOCI8BindTypeBase, "set", oci8_bind_set, 1);
/* register primitive data types. */
oci8_define_bind_class("String", &bind_string_class);
Modified: trunk/ruby-oci8/ext/oci8/oci8.h
===================================================================
--- trunk/ruby-oci8/ext/oci8/oci8.h 2009-02-08 13:28:56 UTC (rev 319)
+++ trunk/ruby-oci8/ext/oci8/oci8.h 2009-02-10 13:50:40 UTC (rev 320)
@@ -241,6 +241,7 @@
sb4 alloc_sz; /* size of a element. */
ub4 maxar_sz; /* maximum array size. */
ub4 curar_sz; /* current array size. */
+ ub4 curar_idx;/* current array index. */
VALUE tdo;
union {
void **null_structs;
@@ -375,6 +376,8 @@
void oci8_bind_hp_obj_mark(oci8_base_t *base);
void Init_oci8_bind(VALUE cOCI8BindTypeBase);
oci8_bind_t *oci8_get_bind(VALUE obj);
+void oci8_bind_set_data(VALUE self, VALUE val);
+VALUE oci8_bind_get_data(VALUE self);
/* metadata.c */
extern VALUE cOCI8MetadataBase;
Modified: trunk/ruby-oci8/ext/oci8/stmt.c
===================================================================
--- trunk/ruby-oci8/ext/oci8/stmt.c 2009-02-08 13:28:56 UTC (rev 319)
+++ trunk/ruby-oci8/ext/oci8/stmt.c 2009-02-10 13:50:40 UTC (rev 320)
@@ -25,7 +25,6 @@
static ID id_empty_p;
static ID id_at_con;
static ID id_clear;
-static ID id_set;
VALUE cOCIStmt;
@@ -428,7 +427,7 @@
#endif /* USE_DYNAMIC_FETCH */
ary = rb_ary_new2(RARRAY_LEN(stmt->defns));
for (idx = 0; idx < RARRAY_LEN(stmt->defns); idx++) {
- rb_ary_store(ary, idx, rb_funcall(RARRAY_PTR(stmt->defns)[idx], oci8_id_get, 0));
+ rb_ary_store(ary, idx, oci8_bind_get_data(RARRAY_PTR(stmt->defns)[idx]));
}
return ary;
}
@@ -599,7 +598,7 @@
if (NIL_P(obj)) {
return Qnil;
}
- return rb_funcall(obj, oci8_id_get, 0);
+ return oci8_bind_get_data(obj);
}
/*
@@ -650,8 +649,8 @@
rb_ivar_set(self, id_at_actual_array_size, INT2NUM(bind_array_size));
}
}
-
- return rb_funcall(obj, oci8_id_set, 1, val);
+ oci8_bind_set_data(obj, val);
+ return val;
}
/*
@@ -781,7 +780,6 @@
id_at_con = rb_intern("@con");
id_empty_p = rb_intern("empty?");
id_clear = rb_intern("clear");
- id_set = rb_intern("set");
rb_define_private_method(cOCIStmt, "initialize", oci8_stmt_initialize, -1);
rb_define_private_method(cOCIStmt, "__define", oci8_define_by_pos, 2);
Modified: trunk/ruby-oci8/test/test_array_dml.rb
===================================================================
--- trunk/ruby-oci8/test/test_array_dml.rb 2009-02-08 13:28:56 UTC (rev 319)
+++ trunk/ruby-oci8/test/test_array_dml.rb 2009-02-10 13:50:40 UTC (rev 320)
@@ -22,7 +22,8 @@
N NUMBER(10, 2),
D DATE,
INT NUMBER(30),
- BIGNUM NUMBER(30))
+ BIGNUM NUMBER(30),
+ T TIMESTAMP)
STORAGE (
INITIAL 4k
NEXT 4k
@@ -31,23 +32,25 @@
PCTINCREASE 0)
EOS
@conn.exec(sql)
- cursor = @conn.parse("INSERT INTO test_table VALUES (:C, :V, :N, :D, :INT, :BIGNUM)")
+ cursor = @conn.parse("INSERT INTO test_table VALUES (:C, :V, :N, :D, :INT, :BIGNUM, :T)")
max_array_size = 3
cursor.max_array_size= max_array_size
cursor.bind_param_array(1, nil, String)
cursor.bind_param_array(2, nil ,String)
cursor.bind_param_array(3, nil, Fixnum)
- cursor.bind_param_array(4, nil, OraDate)
+ cursor.bind_param_array(4, nil, OraDate)
cursor.bind_param_array(5, nil, Integer)
cursor.bind_param_array(6, nil, Bignum)
-
+ cursor.bind_param_array(7, nil, DateTime)
+
c_arr = Array.new
v_arr = Array.new
n_arr = Array.new
d_arr = Array.new
int_arr = Array.new
bignum_arr = Array.new
+ t_arr = Array.new
1.upto(30) do |i|
c_arr << format("%10d", i * 10)
@@ -56,6 +59,7 @@
d_arr << OraDate.new(2000 + i, 12, 24, 23, 59, 59)
int_arr << i * 11111111111
bignum_arr << i * 10000000000
+ t_arr << DateTime.new(2000 + i, 12, 24, 23, 59, 59)
if i%max_array_size == 0
cursor[1] = c_arr
@@ -64,15 +68,24 @@
cursor[4] = d_arr
cursor[5] = int_arr
cursor[6] = bignum_arr
+ cursor[7] = t_arr
r = cursor.exec_array
assert_equal(max_array_size, r)
+ assert_equal(c_arr, cursor[1])
+ assert_equal(v_arr, cursor[2])
+ assert_equal(n_arr, cursor[3])
+ assert_equal(d_arr, cursor[4])
+ assert_equal(int_arr, cursor[5])
+ assert_equal(bignum_arr, cursor[6])
+ assert_equal(t_arr, cursor[7])
c_arr.clear
v_arr.clear
n_arr.clear
d_arr.clear
int_arr.clear
bignum_arr.clear
+ t_arr.clear
end
end
cursor.close
@@ -81,7 +94,7 @@
cursor.define(5, Integer)
cursor.define(6, Bignum)
cursor.exec
- assert_equal(["C","V","N","D","INT","BIGNUM"], cursor.get_col_names)
+ assert_equal(["C","V","N","D","INT","BIGNUM","T"], cursor.get_col_names)
1.upto(30) do |i|
rv = cursor.fetch
assert_equal(format("%10d", i * 10), rv[0])
@@ -91,6 +104,7 @@
assert_equal(tm, rv[3])
assert_equal(i * 11111111111, rv[4])
assert_equal(i * 10000000000, rv[5])
+ assert_equal(tm, rv[6])
end
assert_nil(cursor.fetch)
drop_table('test_table')
More information about the ruby-oci8-commit
mailing list