[ruby-oci8-commit] [295] branches/ruby-oci8-1.0: * lib/oci8.rb.in:
nobody at rubyforge.org
nobody at rubyforge.org
Sun Dec 14 03:03:02 EST 2008
Revision: 295
Author: kubo
Date: 2008-12-14 03:03:02 -0500 (Sun, 14 Dec 2008)
Log Message:
-----------
* lib/oci8.rb.in:
1. fix to fetch a rowid column as s String.
2. change the return type of OCI8#rowid from OCIRowid
to String. It is a local call on Oracle 9.0 or upper.
But on Oracle 8.x client, it needs one network roundtrip
to convert OCIRowid to String on server side.
3. fix OCI8#describe_table to prevent OCIStillExecuting when
non-blocking mode is enabled and it needs a time to
retrieve table information.
* ext/oci8/extconf.rb, ext/oci8/oci8.c: add OCIRowid#to_s
when OCIRowidToChar() is available.
* test/test_all.rb, test/test_rowid.rb: add a rowid test case.
* test/test_dbi_clob.rb: fix to pass tests when the test directory
path is too long.
Modified Paths:
--------------
branches/ruby-oci8-1.0/ChangeLog
branches/ruby-oci8-1.0/ext/oci8/extconf.rb
branches/ruby-oci8-1.0/ext/oci8/oci8.c
branches/ruby-oci8-1.0/lib/oci8.rb.in
branches/ruby-oci8-1.0/test/test_all.rb
branches/ruby-oci8-1.0/test/test_dbi_clob.rb
Added Paths:
-----------
branches/ruby-oci8-1.0/test/test_rowid.rb
Modified: branches/ruby-oci8-1.0/ChangeLog
===================================================================
--- branches/ruby-oci8-1.0/ChangeLog 2008-12-13 15:04:19 UTC (rev 294)
+++ branches/ruby-oci8-1.0/ChangeLog 2008-12-14 08:03:02 UTC (rev 295)
@@ -1,3 +1,19 @@
+2008-12-14 KUBO Takehiro <kubo at jiubao.org>
+ * lib/oci8.rb.in:
+ 1. fix to fetch a rowid column as s String.
+ 2. change the return type of OCI8#rowid from OCIRowid
+ to String. It is a local call on Oracle 9.0 or upper.
+ But on Oracle 8.x client, it needs one network roundtrip
+ to convert OCIRowid to String on server side.
+ 3. fix OCI8#describe_table to prevent OCIStillExecuting when
+ non-blocking mode is enabled and it needs a time to
+ retrieve table information.
+ * ext/oci8/extconf.rb, ext/oci8/oci8.c: add OCIRowid#to_s
+ when OCIRowidToChar() is available.
+ * test/test_all.rb, test/test_rowid.rb: add a rowid test case.
+ * test/test_dbi_clob.rb: fix to pass tests when the test directory
+ path is too long.
+
2008-08-10 KUBO Takehiro <kubo at jiubao.org>
* NEWS: add changes between 1.0.2 and 1.0.3.
* VERSION: change version to 1.0.3.
@@ -12,7 +28,7 @@
2008-08-09 KUBO Takehiro <kubo at jiubao.org>
* ext/oci8/lob.c: fix OCILobLocator#getLength for a lob over 1GB,
which affect OCI8::LOB#size and OCI8::LOB#read. fix
- OCILobLocator#read and OCILobLocator#write to set offset over 2BG,
+ OCILobLocator#read and OCILobLocator#write to set offset over 2GB,
which affect OCI8::LOB#read and OCI8::LOB#write.
(This probmem was reported by Jonathan Hadders.)
Modified: branches/ruby-oci8-1.0/ext/oci8/extconf.rb
===================================================================
--- branches/ruby-oci8-1.0/ext/oci8/extconf.rb 2008-12-13 15:04:19 UTC (rev 294)
+++ branches/ruby-oci8-1.0/ext/oci8/extconf.rb 2008-12-14 08:03:02 UTC (rev 295)
@@ -77,6 +77,8 @@
have_func("OCILobGetChunkSize")
have_func("OCILobLocatorAssign")
+have_func("OCIRowidToChar")
+
$defs.push("-DHAVE_OCIRESET") unless /80./ =~ oraconf.version
# Checking gcc or not
Modified: branches/ruby-oci8-1.0/ext/oci8/oci8.c
===================================================================
--- branches/ruby-oci8-1.0/ext/oci8/oci8.c 2008-12-13 15:04:19 UTC (rev 294)
+++ branches/ruby-oci8-1.0/ext/oci8/oci8.c 2008-12-14 08:03:02 UTC (rev 295)
@@ -77,6 +77,8 @@
VALUE cOraDate;
VALUE cOraNumber;
+static void Init_OCIRowid(void);
+
void
Init_oci8lib()
{
@@ -131,7 +133,46 @@
Init_ora_date();
Init_ora_number();
+ Init_OCIRowid();
+
#ifdef DEBUG_CORE_FILE
signal(SIGSEGV, SIG_DFL);
#endif
}
+
+#if defined(WIN32)
+typedef sword (*OCIRowidToChar_func_t)(OCIRowid *rowidDesc, OraText *outbfp, ub2 *outbflp, OCIError *errhp);
+static OCIRowidToChar_func_t OCIRowidToChar_func;
+#define OCIRowidToChar OCIRowidToChar_func
+#endif
+
+#if defined(WIN32) || defined(HAVE_OCIROWIDTOCHAR)
+static VALUE oci8_rowid_to_s(VALUE self)
+{
+ oci8_handle_t *h;
+ char buf[64];
+ ub2 buflen = sizeof(buf);
+ sword rv;
+
+ Get_Handle(self, h);
+ rv = OCIRowidToChar(h->hp, (text*)buf, &buflen, h->errhp);
+ if (rv != OCI_SUCCESS)
+ oci8_raise(h->errhp, rv, NULL);
+ return rb_str_new(buf, buflen);
+}
+#endif
+
+static void Init_OCIRowid(void)
+{
+#if defined(WIN32)
+ HANDLE hModule = GetModuleHandle("OCI.DLL");
+ if (hModule != NULL) {
+ OCIRowidToChar_func = (OCIRowidToChar_func_t)GetProcAddress(hModule, "OCIRowidToChar");
+ }
+ if (OCIRowidToChar_func != NULL) {
+ rb_define_method(cOCIRowid, "to_s", oci8_rowid_to_s, 0);
+ }
+#elif defined(HAVE_OCIROWIDTOCHAR)
+ rb_define_method(cOCIRowid, "to_s", oci8_rowid_to_s, 0);
+#endif
+}
Modified: branches/ruby-oci8-1.0/lib/oci8.rb.in
===================================================================
--- branches/ruby-oci8-1.0/lib/oci8.rb.in 2008-12-13 15:04:19 UTC (rev 294)
+++ branches/ruby-oci8-1.0/lib/oci8.rb.in 2008-12-14 08:03:02 UTC (rev 295)
@@ -351,7 +351,7 @@
def describe_table(table_name)
desc = @@env.alloc(OCIDescribe)
desc.attrSet(OCI_ATTR_DESC_PUBLIC, -1)
- desc.describeAny(@svc, table_name.to_s, OCI_PTYPE_UNK)
+ do_ocicall(@ctx) { desc.describeAny(@svc, table_name.to_s, OCI_PTYPE_UNK) }
param = desc.attrGet(OCI_ATTR_PARAM)
case param.attrGet(OCI_ATTR_PTYPE)
@@ -811,8 +811,25 @@
@stmttype = nil
end # close
+ # Get the rowid of the last inserted/updated/deleted row.
def rowid
- @stmt.attrGet(OCI_ATTR_ROWID)
+ # get the binary rowid
+ rid = @stmt.attrGet(OCI_ATTR_ROWID)
+ # convert it to a string rowid.
+ if rid.respond_to? :to_s
+ # (Oracle 9.0 or upper)
+ rid.to_s
+ else
+ # (Oracle 8.1 or lower)
+ stmt = @env.alloc(OCIStmt)
+ stmt.prepare('begin :1 := :2; end;')
+ b = stmt.bindByPos(1, OCI8::SQLT_CHR, 64)
+ stmt.bindByPos(2, OCI8::SQLT_RDD, rid)
+ do_ocicall(@ctx) { stmt.execute(@svc, 1, OCI_DEFAULT) }
+ str_rid = b.get()
+ stmt.free()
+ str_rid
+ end
end
def prefetch_rows=(rows)
@@ -899,6 +916,8 @@
datatype = :nclob if p.attrGet(OCI_ATTR_CHARSET_FORM) == SQLCS_NCHAR
when SQLT_BIN
datasize *= 2 if OCI8::BindType::Mapping[datatype] == OCI8::BindType::String
+ when SQLT_RDD
+ datasize = 64
end
bind_or_define(:define, i, nil, datatype, datasize, precision, scale, true)
@@ -1210,7 +1229,7 @@
# datatype type size prec scale
# -------------------------------------------------
# ROWID SQLT_RDD 4 0 0
- BindType::Mapping[OCI8::SQLT_RDD] = BindType::OCIRowid
+ BindType::Mapping[OCI8::SQLT_RDD] = BindType::String
# datatype type size prec scale
# -----------------------------------------------------
Modified: branches/ruby-oci8-1.0/test/test_all.rb
===================================================================
--- branches/ruby-oci8-1.0/test/test_all.rb 2008-12-13 15:04:19 UTC (rev 294)
+++ branches/ruby-oci8-1.0/test/test_all.rb 2008-12-14 08:03:02 UTC (rev 295)
@@ -18,6 +18,7 @@
require "#{srcdir}/test_oci8"
require "#{srcdir}/test_connstr"
require "#{srcdir}/test_metadata"
+require "#{srcdir}/test_rowid"
# Ruby/DBI
begin
Modified: branches/ruby-oci8-1.0/test/test_dbi_clob.rb
===================================================================
--- branches/ruby-oci8-1.0/test/test_dbi_clob.rb 2008-12-13 15:04:19 UTC (rev 294)
+++ branches/ruby-oci8-1.0/test/test_dbi_clob.rb 2008-12-14 08:03:02 UTC (rev 295)
@@ -11,13 +11,14 @@
end
def test_insert
- @dbh.do("DELETE FROM test_clob WHERE filename = :1", $lobfile)
+ filename = File.basename($lobfile)
+ @dbh.do("DELETE FROM test_clob WHERE filename = :1", filename)
# insert an empty clob and get the rowid.
- rowid = @dbh.execute("INSERT INTO test_clob(filename, content) VALUES (:1, EMPTY_CLOB())", $lobfile) do |sth|
+ rowid = @dbh.execute("INSERT INTO test_clob(filename, content) VALUES (:1, EMPTY_CLOB())", filename) do |sth|
sth.func(:rowid)
end
- lob = @dbh.select_one("SELECT content FROM test_clob WHERE filename = :1 FOR UPDATE", $lobfile)[0]
+ lob = @dbh.select_one("SELECT content FROM test_clob WHERE filename = :1 FOR UPDATE", filename)[0]
begin
open($lobfile) do |f|
while f.gets()
@@ -30,8 +31,9 @@
end
def test_read
+ filename = File.basename($lobfile)
test_insert() # first insert data.
- lob = @dbh.select_one("SELECT content FROM test_clob WHERE filename = :1 FOR UPDATE", $lobfile)[0]
+ lob = @dbh.select_one("SELECT content FROM test_clob WHERE filename = :1 FOR UPDATE", filename)[0]
begin
open($lobfile) do |f|
while buf = lob.read($lobreadnum)
Added: branches/ruby-oci8-1.0/test/test_rowid.rb
===================================================================
--- branches/ruby-oci8-1.0/test/test_rowid.rb (rev 0)
+++ branches/ruby-oci8-1.0/test/test_rowid.rb 2008-12-14 08:03:02 UTC (rev 295)
@@ -0,0 +1,38 @@
+require 'oci8'
+require 'runit/testcase'
+require 'runit/cui/testrunner'
+require File.dirname(__FILE__) + '/config'
+
+class TestRowid < RUNIT::TestCase
+
+ def setup
+ @conn = get_oci_connection()
+ end
+
+ def teardown
+ @conn.logoff
+ end
+
+ def test_rowid
+ drop_table('test_table')
+ sql = <<-EOS
+CREATE TABLE test_table (N NUMBER(38))
+EOS
+ @conn.exec(sql)
+ cursor = @conn.parse("INSERT INTO test_table values(1)");
+ cursor.exec
+ rid1 = cursor.rowid
+ assert_instance_of(String, rid1)
+ cursor.close
+ rid2 = nil
+ @conn.exec('select rowid from test_table where rowid = :1', rid1) do |row|
+ rid2 = row[0]
+ end
+ assert_equal(rid2, rid1)
+ drop_table('test_table')
+ end
+end # TestRowid
+
+if $0 == __FILE__
+ RUNIT::CUI::TestRunner.run(TestRowid.suite())
+end
More information about the ruby-oci8-commit
mailing list