[ruby-oci8-commit] [374] trunk/ruby-oci8: * ext/oci8/error.c: Use OCIErrorGet() to retrieve the error message
nobody at rubyforge.org
nobody at rubyforge.org
Sun Jan 24 08:43:12 EST 2010
Revision: 374
Author: kubo
Date: 2010-01-24 08:43:11 -0500 (Sun, 24 Jan 2010)
Log Message:
-----------
* ext/oci8/error.c: Use OCIErrorGet() to retrieve the error message
when the OCI return code is OCI_NO_DATA.
(reported by Raimonds Simanovskis)
Modified Paths:
--------------
trunk/ruby-oci8/ChangeLog
trunk/ruby-oci8/ext/oci8/error.c
Modified: trunk/ruby-oci8/ChangeLog
===================================================================
--- trunk/ruby-oci8/ChangeLog 2009-12-06 14:01:37 UTC (rev 373)
+++ trunk/ruby-oci8/ChangeLog 2010-01-24 13:43:11 UTC (rev 374)
@@ -1,3 +1,8 @@
+2010-01-24 KUBO Takehiro <kubo at jiubao.org>
+ * ext/oci8/error.c: Use OCIErrorGet() to retrieve the error message
+ when the OCI return code is OCI_NO_DATA.
+ (reported by Raimonds Simanovskis)
+
2009-12-06 KUBO Takehiro <kubo at jiubao.org>
* ext/oci8/object.c: 1. fix segv when GC starts while initializing
a bind object for object type. (reported by Remi Gagnon)
Modified: trunk/ruby-oci8/ext/oci8/error.c
===================================================================
--- trunk/ruby-oci8/ext/oci8/error.c 2009-12-06 14:01:37 UTC (rev 373)
+++ trunk/ruby-oci8/ext/oci8/error.c 2010-01-24 13:43:11 UTC (rev 374)
@@ -2,7 +2,7 @@
/*
error.c - part of ruby-oci8
- Copyright (C) 2002-2007 KUBO Takehiro <kubo at jiubao.org>
+ Copyright (C) 2002-2010 KUBO Takehiro <kubo at jiubao.org>
=begin
== OCIError
@@ -28,9 +28,52 @@
static ID oci8_id_caller;
static ID oci8_id_set_backtrace;
+#define ERRBUF_EXPAND_LEN 256
+static char *errbuf;
+static ub4 errbufsiz;
+
NORETURN(static void oci8_raise2(dvoid *errhp, sword status, ub4 type, OCIStmt *stmthp, const char *file, int line));
NORETURN(static void set_backtrace_and_raise(VALUE exc, const char *file, int line));
+static VALUE get_error_msg(dvoid *errhp, ub4 type, const char *default_msg, sb4 *errcode_p)
+{
+ sword rv;
+ size_t len;
+
+retry:
+ errbuf[0] = '\0';
+ rv = OCIErrorGet(errhp, 1, NULL, errcode_p, TO_ORATEXT(errbuf), errbufsiz, type);
+ /* OCI manual says:
+ * If type is set to OCI_HTYPE_ERROR, then the return
+ * code during truncation for OCIErrorGet() is
+ * OCI_ERROR. The client can then specify a bigger
+ * buffer and call OCIErrorGet() again.
+ *
+ * But as far as I tested on Oracle XE 10.2.0.1, the return
+ * code is OCI_SUCCESS when the message is truncated.
+ */
+ len = strlen(errbuf);
+ if (errbufsiz - len <= 7) {
+ /* The error message may be truncated.
+ * The magic number 7 means the maximum length of one utf-8
+ * character plus the length of a nul terminator.
+ */
+ errbufsiz += ERRBUF_EXPAND_LEN;
+ errbuf = xrealloc(errbuf, errbufsiz);
+ goto retry;
+ }
+ if (rv != OCI_SUCCESS) {
+ /* No message is found. Use the default message. */
+ return rb_usascii_str_new_cstr(default_msg);
+ }
+
+ /* truncate trailing CR and LF */
+ while (len > 0 && (errbuf[len - 1] == '\n' || errbuf[len - 1] == '\r')) {
+ len--;
+ }
+ return rb_external_str_new_with_enc(errbuf, len, oci8_encoding);
+}
+
static void oci8_raise2(dvoid *errhp, sword status, ub4 type, OCIStmt *stmthp, const char *file, int line)
{
VALUE vcodes = Qnil;
@@ -103,7 +146,7 @@
break;
case OCI_NO_DATA:
exc = eOCINoData;
- msg = rb_usascii_str_new_cstr("No Data");
+ msg = get_error_msg(errhp, type, "No Data", &errcode);
break;
case OCI_INVALID_HANDLE:
exc = eOCIInvalidHandle;
@@ -252,6 +295,9 @@
void Init_oci8_error(void)
{
+ errbufsiz = ERRBUF_EXPAND_LEN;
+ errbuf = xmalloc(errbufsiz);
+
oci8_id_code = rb_intern("code");
oci8_id_message = rb_intern("message");
oci8_id_parse_error_offset = rb_intern("parse_error_offset");
More information about the ruby-oci8-commit
mailing list