[ruby-oci8-commit] [256] trunk/ruby-oci8: * ext/oci8/extconf.rb, ext/oci8/oci8lib.c, ext/oci8/ oci8.h:

nobody at rubyforge.org nobody at rubyforge.org
Sat Mar 29 04:37:21 EDT 2008


Revision: 256
Author:   kubo
Date:     2008-03-29 04:37:20 -0400 (Sat, 29 Mar 2008)

Log Message:
-----------
* ext/oci8/extconf.rb, ext/oci8/oci8lib.c, ext/oci8/oci8.h:
    When '--with-runtime-check' is passed to extconf.rb, oci8lib.so
    is no longer linked to an Oracle client library at compilation
    time. It tries to search the Oracle client library at runtime.
* ext/oci8/bind.c: define OCI8::BindType::BinaryDouble when
    oracle_client_version's value is 10g or later, not when SQLT_BDOUBLE
    is declared. This is for runtime check.

Modified Paths:
--------------
    trunk/ruby-oci8/ChangeLog
    trunk/ruby-oci8/ext/oci8/bind.c
    trunk/ruby-oci8/ext/oci8/extconf.rb
    trunk/ruby-oci8/ext/oci8/oci8.h
    trunk/ruby-oci8/ext/oci8/oci8lib.c

Modified: trunk/ruby-oci8/ChangeLog
===================================================================
--- trunk/ruby-oci8/ChangeLog	2008-03-22 14:11:32 UTC (rev 255)
+++ trunk/ruby-oci8/ChangeLog	2008-03-29 08:37:20 UTC (rev 256)
@@ -1,3 +1,12 @@
+2008-03-29  KUBO Takehiro  <kubo at jiubao.org>
+	* ext/oci8/extconf.rb, ext/oci8/oci8lib.c, ext/oci8/oci8.h:
+	    When '--with-runtime-check' is passed to extconf.rb, oci8lib.so
+	    is no longer linked to an Oracle client library at compilation
+	    time. It tries to search the Oracle client library at runtime.
+	* ext/oci8/bind.c: define OCI8::BindType::BinaryDouble when
+	    oracle_client_version's value is 10g or later, not when SQLT_BDOUBLE
+	    is declared. This is for runtime check.
+
 2008-03-22  KUBO Takehiro  <kubo at jiubao.org>
 	* ext/oci8/bind.c, ext/oci8/lob.c, ext/oci8/object.c, ext/oci8/oci8.h,
 	  ext/oci8/oci8lib.c, ext/oci8/ocidatetime.c, ext/oci8/ocinumber.c,

Modified: trunk/ruby-oci8/ext/oci8/bind.c
===================================================================
--- trunk/ruby-oci8/ext/oci8/bind.c	2008-03-22 14:11:32 UTC (rev 255)
+++ trunk/ruby-oci8/ext/oci8/bind.c	2008-03-29 08:37:20 UTC (rev 256)
@@ -295,7 +295,9 @@
     SQLT_FLT
 };
 
-#ifdef SQLT_BDOUBLE
+#ifndef SQLT_BDOUBLE
+#define SQLT_BDOUBLE 22
+#endif
 static const oci8_bind_class_t bind_binary_double_class = {
     {
         NULL,
@@ -311,7 +313,6 @@
     NULL,
     SQLT_BDOUBLE
 };
-#endif
 
 static inline VALUE oci8_get_data_at(const oci8_bind_class_t *obc, oci8_bind_t *obind, ub4 idx)
 {
@@ -470,9 +471,9 @@
     oci8_define_bind_class("LongRaw", &bind_long_raw_class);
     oci8_define_bind_class("Fixnum", &bind_fixnum_class);
     oci8_define_bind_class("Float", &bind_float_class);
-#ifdef SQLT_BDOUBLE
-    oci8_define_bind_class("BinaryDouble", &bind_binary_double_class);
-#endif
+    if (oracle_client_version >= 1000) {
+        oci8_define_bind_class("BinaryDouble", &bind_binary_double_class);
+    }
 }
 
 oci8_bind_t *oci8_get_bind(VALUE obj)

Modified: trunk/ruby-oci8/ext/oci8/extconf.rb
===================================================================
--- trunk/ruby-oci8/ext/oci8/extconf.rb	2008-03-22 14:11:32 UTC (rev 255)
+++ trunk/ruby-oci8/ext/oci8/extconf.rb	2008-03-29 08:37:20 UTC (rev 256)
@@ -30,6 +30,7 @@
 end
 
 $CFLAGS += oraconf.cflags
+saved_libs = $libs
 $libs += oraconf.libs
 
 oci_actual_client_version = 800
@@ -65,6 +66,7 @@
 
 if with_config('runtime-check')
   $defs << "-DRUNTIME_API_CHECK=1"
+  $libs = saved_libs
 end
 
 $objs = ["oci8lib.o", "env.o", "error.o", "oci8.o",

Modified: trunk/ruby-oci8/ext/oci8/oci8.h
===================================================================
--- trunk/ruby-oci8/ext/oci8/oci8.h	2008-03-22 14:11:32 UTC (rev 255)
+++ trunk/ruby-oci8/ext/oci8/oci8.h	2008-03-29 08:37:20 UTC (rev 256)
@@ -63,10 +63,6 @@
 #define rb_errinfo() ruby_errinfo
 #endif
 
-#ifdef _WIN32
-#define RUNTIME_API_CHECK
-#endif
-
 #define IS_OCI_ERROR(v) (((v) != OCI_SUCCESS) && ((v) != OCI_SUCCESS_WITH_INFO))
 
 #if defined(__GNUC__) && ((__GNUC__ > 2) || (__GNUC__ == 2 && __GNUC_MINOR__ >= 96))

Modified: trunk/ruby-oci8/ext/oci8/oci8lib.c
===================================================================
--- trunk/ruby-oci8/ext/oci8/oci8lib.c	2008-03-22 14:11:32 UTC (rev 255)
+++ trunk/ruby-oci8/ext/oci8/oci8lib.c	2008-03-29 08:37:20 UTC (rev 256)
@@ -3,11 +3,6 @@
  * Copyright (C) 2002-2008 KUBO Takehiro <kubo at jiubao.org>
  */
 
-#ifdef __linux__ /* for RTLD_DEFAULT */
-#define _GNU_SOURCE
-#include <dlfcn.h>
-#endif
-
 #include "oci8.h"
 
 #define DEBUG_CORE_FILE 1
@@ -300,18 +295,103 @@
 #endif /* RUBY_VM */
 
 #if defined RUNTIME_API_CHECK
+
+#ifndef _WIN32
+#include <dlfcn.h>
+#endif
+
 void *oci8_find_symbol(const char *symbol_name)
 {
 #if defined _WIN32
+    /* Windows */
     static HMODULE hModule = NULL;
+
     if (hModule == NULL) {
-        hModule = GetModuleHandle("OCI.DLL");
+        hModule = LoadLibrary("OCI.DLL");
+        if (hModule == NULL) {
+            char message[512];
+            int error = GetLastError();
+            char *p;
+
+            memset(message, 0, sizeof(message));
+            FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, error, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), message, sizeof(message), NULL);
+            for (p = message; *p; p++) {
+                if (*p == '\n' || *p == '\r')
+                    *p = ' ';
+            }
+            rb_raise(rb_eLoadError, "OCI.DLL: %d(%s)", error, message);
+        }
     }
     return GetProcAddress(hModule, symbol_name);
-#elif defined RTLD_DEFAULT
-    return dlsym(RTLD_DEFAULT, symbol_name);
 #else
-#error RUNTIME_API_CHECK is not supported on this platform.
+    /* UNIX */
+    static void *handle = NULL;
+
+    if (handle == NULL) {
+        static const char * const sonames[] = {
+#if defined(__CYGWIN__)
+            /* Windows(Cygwin) */
+            "OCI.DLL",
+#elif defined(_AIX)
+            /* AIX */
+            "libclntsh.a(shr.o)",
+#elif defined(__hppa)
+            /* HP-UX(PA-RISC) */
+            "libclntsh.sl.11.1",
+            "libclntsh.sl.10.1",
+            "libclntsh.sl.9.0",
+            "libclntsh.sl.8.0",
+#elif defined(__APPLE__)
+            /* Mac OS X */
+            "libclntsh.dylib.11.1",
+            "libclntsh.dylib.10.1",
+#else
+            /* Linux, Solaris and HP-UX(IA64) */
+            "libclntsh.so.11.1",
+            "libclntsh.so.10.1",
+            "libclntsh.so.9.0",
+            "libclntsh.so.8.0",
 #endif
+        };
+#define NUM_SONAMES (sizeof(sonames)/sizeof(sonames[0]))
+        size_t idx;
+        VALUE err = rb_ary_new();
+
+#ifdef _AIX
+#define DLOPEN_FLAG (RTLD_LAZY|RTLD_GLOBAL|RTLD_MEMBER)
+#else
+#define DLOPEN_FLAG (RTLD_LAZY|RTLD_GLOBAL)
+#endif
+        for (idx = 0; idx < NUM_SONAMES; idx++) {
+            handle = dlopen(sonames[idx], DLOPEN_FLAG);
+            if (handle != NULL) {
+                break;
+            }
+            rb_ary_push(err, rb_str_new2(dlerror()));
+        }
+        if (handle == NULL) {
+            VALUE msg;
+
+            msg = rb_str_buf_new(NUM_SONAMES * 50);
+            for (idx = 0; idx < NUM_SONAMES; idx++) {
+                const char *errmsg = RSTRING_PTR(RARRAY_PTR(err)[idx]);
+                if (idx != 0) {
+                    rb_str_buf_cat2(msg, " ");
+                }
+                if (strstr(errmsg, sonames[idx]) == NULL) {
+                    /* prepend "soname: " if soname is not found in
+                     * the error message.
+                     */
+                    rb_str_buf_cat2(msg, sonames[idx]);
+                    rb_str_buf_cat2(msg, ": ");
+                }
+                rb_str_buf_append(msg, RARRAY_PTR(err)[idx]);
+                rb_str_buf_cat2(msg, ";");
+            }
+            rb_exc_raise(rb_exc_new3(rb_eLoadError, msg));
+        }
+    }
+    return dlsym(handle, symbol_name);
+#endif /* defined _WIN32 */
 }
 #endif /* RUNTIME_API_CHECK */




More information about the ruby-oci8-commit mailing list