ruby-oci8 2.2.4.1 → 2.2.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (62) hide show
  1. checksums.yaml +7 -0
  2. data/ChangeLog +311 -1
  3. data/NEWS +278 -46
  4. data/README.md +5 -2
  5. data/dist-files +8 -4
  6. data/docs/bind-array-to-in_cond.md +1 -1
  7. data/docs/install-instant-client.md +2 -1
  8. data/docs/install-on-osx.md +29 -116
  9. data/docs/ldap-auth-and-function-interposition.md +123 -0
  10. data/docs/number-type-mapping.md +79 -0
  11. data/ext/oci8/apiwrap.c.tmpl +2 -5
  12. data/ext/oci8/apiwrap.rb +6 -1
  13. data/ext/oci8/apiwrap.yml +34 -22
  14. data/ext/oci8/attr.c +4 -2
  15. data/ext/oci8/bind.c +366 -6
  16. data/ext/oci8/connection_pool.c +3 -3
  17. data/ext/oci8/error.c +18 -33
  18. data/ext/oci8/extconf.rb +7 -4
  19. data/ext/oci8/hook_funcs.c +128 -51
  20. data/ext/oci8/lob.c +31 -75
  21. data/ext/oci8/metadata.c +2 -2
  22. data/ext/oci8/object.c +72 -27
  23. data/ext/oci8/oci8.c +27 -119
  24. data/ext/oci8/oci8.h +21 -3
  25. data/ext/oci8/oci8lib.c +50 -37
  26. data/ext/oci8/ocihandle.c +2 -2
  27. data/ext/oci8/ocinumber.c +22 -16
  28. data/ext/oci8/oraconf.rb +130 -257
  29. data/ext/oci8/oradate.c +1 -1
  30. data/ext/oci8/plthook_elf.c +384 -300
  31. data/ext/oci8/plthook_osx.c +10 -10
  32. data/ext/oci8/stmt.c +51 -16
  33. data/ext/oci8/win32.c +4 -22
  34. data/lib/oci8/bindtype.rb +1 -15
  35. data/lib/oci8/check_load_error.rb +57 -10
  36. data/lib/oci8/cursor.rb +48 -17
  37. data/lib/oci8/metadata.rb +9 -1
  38. data/lib/oci8/object.rb +10 -0
  39. data/lib/oci8/oci8.rb +26 -25
  40. data/lib/oci8/oracle_version.rb +11 -1
  41. data/lib/oci8/version.rb +1 -1
  42. data/lib/oci8.rb +11 -4
  43. data/lib/ruby-oci8.rb +0 -3
  44. data/ruby-oci8.gemspec +2 -3
  45. data/setup.rb +11 -2
  46. data/test/README.md +37 -0
  47. data/test/config.rb +1 -1
  48. data/test/setup_test_object.sql +21 -13
  49. data/test/setup_test_package.sql +59 -0
  50. data/test/test_all.rb +1 -0
  51. data/test/test_bind_boolean.rb +99 -0
  52. data/test/test_break.rb +11 -9
  53. data/test/test_clob.rb +4 -16
  54. data/test/test_datetime.rb +8 -3
  55. data/test/test_object.rb +33 -9
  56. data/test/test_oci8.rb +169 -45
  57. data/test/test_oranumber.rb +12 -6
  58. data/test/test_package_type.rb +15 -3
  59. data/test/test_properties.rb +17 -0
  60. metadata +40 -57
  61. data/docs/osx-install-dev-tools.png +0 -0
  62. data/test/README +0 -42
data/ext/oci8/oci8lib.c CHANGED
@@ -71,7 +71,7 @@ static VALUE bind_base_alloc(VALUE klass)
71
71
  rb_raise(rb_eNameError, "private method `new' called for %s:Class", rb_class2name(klass));
72
72
  }
73
73
 
74
- #if defined(HAVE_PLTHOOK) && !defined(WIN32) && !defined(__CYGWIN__)
74
+ #if defined(HAVE_PLTHOOK) && !defined(WIN32) && !defined(__CYGWIN__) && !defined(TRUFFLERUBY)
75
75
  static const char *find_libclntsh(void *handle)
76
76
  {
77
77
  void *symaddr = dlsym(handle, "OCIEnvCreate");
@@ -226,7 +226,7 @@ Init_oci8lib()
226
226
  oracle_client_version = ORAVERNUM(major, minor, update, patch, port_update);
227
227
  }
228
228
  #endif
229
- #if defined(HAVE_PLTHOOK) && !defined(WIN32) && !defined(__CYGWIN__)
229
+ #if defined(HAVE_PLTHOOK) && !defined(WIN32) && !defined(__CYGWIN__) && !defined(TRUFFLERUBY)
230
230
  rebind_internal_symbols();
231
231
  #endif
232
232
 
@@ -461,6 +461,7 @@ sword oci8_call_without_gvl(oci8_svcctx_t *svcctx, void *(*func)(void *), void *
461
461
  parg.func = func;
462
462
  parg.data = data;
463
463
  rv = (sword)rb_protect(protected_call, (VALUE)&parg, &state);
464
+ RB_OBJ_WRITE(svcctx->base.self, &svcctx->executing_thread, Qnil);
464
465
  if (state) {
465
466
  rb_jump_tag(state);
466
467
  }
@@ -481,8 +482,8 @@ typedef struct {
481
482
  OCIStmt *stmtp;
482
483
  } cb_arg_t;
483
484
 
484
- static VALUE exec_sql(cb_arg_t *arg);
485
- static VALUE ensure_func(cb_arg_t *arg);
485
+ static VALUE exec_sql(VALUE varg);
486
+ static VALUE ensure_func(VALUE varg);
486
487
 
487
488
  /*
488
489
  * utility function to execute a single SQL statement
@@ -503,13 +504,14 @@ sword oci8_exec_sql(oci8_svcctx_t *svcctx, const char *sql_text, ub4 num_define_
503
504
  return (sword)rb_ensure(exec_sql, (VALUE)&arg, ensure_func, (VALUE)&arg);
504
505
  }
505
506
 
506
- static VALUE exec_sql(cb_arg_t *arg)
507
+ static VALUE exec_sql(VALUE varg)
507
508
  {
509
+ cb_arg_t *arg = (cb_arg_t *)varg;
508
510
  ub4 pos;
509
511
  sword rv;
510
512
 
511
513
  chker2(OCIStmtPrepare2(arg->svcctx->base.hp.svc, &arg->stmtp, oci8_errhp,
512
- (text*)arg->sql_text, strlen(arg->sql_text), NULL, 0,
514
+ (text*)arg->sql_text, (ub4)strlen(arg->sql_text), NULL, 0,
513
515
  OCI_NTV_SYNTAX, OCI_DEFAULT),
514
516
  &arg->svcctx->base);
515
517
  for (pos = 0; pos < arg->num_define_vars; pos++) {
@@ -546,8 +548,9 @@ static VALUE exec_sql(cb_arg_t *arg)
546
548
  return (VALUE)rv;
547
549
  }
548
550
 
549
- static VALUE ensure_func(cb_arg_t *arg)
551
+ static VALUE ensure_func(VALUE varg)
550
552
  {
553
+ cb_arg_t *arg = (cb_arg_t *)varg;
551
554
  if (arg->stmtp != NULL) {
552
555
  OCIStmtRelease(arg->stmtp, oci8_errhp, NULL, 0, OCI_DEFAULT);
553
556
  }
@@ -558,6 +561,24 @@ static VALUE ensure_func(cb_arg_t *arg)
558
561
 
559
562
  #ifndef _WIN32
560
563
  #include <dlfcn.h>
564
+ static void *load_file(const char *filename, int flags, VALUE errors)
565
+ {
566
+ void *handle = dlopen(filename, flags);
567
+
568
+ if (handle == NULL) {
569
+ char *err = dlerror();
570
+ VALUE msg;
571
+
572
+ if (strstr(err, filename) == NULL) {
573
+ msg = rb_sprintf("%s: %s", filename, err);
574
+ msg = rb_enc_associate_index(msg, rb_locale_encindex());
575
+ } else {
576
+ msg = rb_locale_str_new_cstr(err);
577
+ }
578
+ rb_ary_push(errors, msg);
579
+ }
580
+ return handle;
581
+ }
561
582
  #endif
562
583
 
563
584
  void *oci8_find_symbol(const char *symbol_name)
@@ -600,58 +621,50 @@ void *oci8_find_symbol(const char *symbol_name)
600
621
  "libclntsh.sl.12.1",
601
622
  "libclntsh.sl.11.1",
602
623
  "libclntsh.sl.10.1",
603
- "libclntsh.sl.9.0",
604
- "libclntsh.sl.8.0",
605
624
  #elif defined(__APPLE__)
606
625
  /* Mac OS X */
626
+ "libclntsh.dylib",
607
627
  "libclntsh.dylib.12.1",
608
628
  "libclntsh.dylib.11.1",
609
629
  "libclntsh.dylib.10.1",
610
630
  #else
611
631
  /* Linux, Solaris and HP-UX(IA64) */
632
+ "libclntsh.so",
612
633
  "libclntsh.so.12.1",
613
634
  "libclntsh.so.11.1",
614
635
  "libclntsh.so.10.1",
615
- "libclntsh.so.9.0",
616
- "libclntsh.so.8.0",
617
636
  #endif
618
637
  };
619
638
  #define NUM_SONAMES (sizeof(sonames)/sizeof(sonames[0]))
639
+ #if defined(_AIX) /* AIX */
640
+ #define BASE_SONAME "libclntsh.a(shr.o)"
641
+ #elif defined(__hppa) /* HP-UX(PA-RISC) */
642
+ #define BASE_SONAME "libclntsh.sl"
643
+ #elif !defined(__CYGWIN__) && !defined(__APPLE__)
644
+ #define BASE_SONAME "libclntsh.so"
645
+ #endif
620
646
  size_t idx;
621
- volatile VALUE err = rb_ary_new();
647
+ VALUE err = rb_ary_new();
622
648
 
623
649
  #ifdef _AIX
624
650
  #define DLOPEN_FLAG (RTLD_LAZY|RTLD_GLOBAL|RTLD_MEMBER)
625
651
  #else
626
652
  #define DLOPEN_FLAG (RTLD_LAZY|RTLD_GLOBAL)
627
653
  #endif
628
- for (idx = 0; idx < NUM_SONAMES; idx++) {
629
- handle = dlopen(sonames[idx], DLOPEN_FLAG);
630
- if (handle != NULL) {
631
- break;
632
- }
633
- rb_ary_push(err, rb_locale_str_new_cstr(dlerror()));
654
+ #ifdef BASE_SONAME
655
+ char *oracle_home = getenv("ORACLE_HOME");
656
+
657
+ if (oracle_home != NULL) {
658
+ VALUE fname = rb_str_buf_cat2(rb_str_buf_new_cstr(oracle_home), "/lib/" BASE_SONAME);
659
+ handle = load_file(StringValueCStr(fname), DLOPEN_FLAG, err);
660
+ RB_GC_GUARD(fname);
661
+ }
662
+ #endif
663
+ for (idx = 0; handle == NULL && idx < NUM_SONAMES; idx++) {
664
+ handle = load_file(sonames[idx], DLOPEN_FLAG, err);
634
665
  }
635
666
  if (handle == NULL) {
636
- VALUE msg;
637
- const VALUE *arr = RARRAY_CONST_PTR(err);
638
-
639
- msg = rb_str_buf_new(NUM_SONAMES * 50);
640
- for (idx = 0; idx < NUM_SONAMES; idx++) {
641
- const char *errmsg = RSTRING_PTR(arr[idx]);
642
- if (idx != 0) {
643
- rb_str_buf_cat2(msg, " ");
644
- }
645
- if (strstr(errmsg, sonames[idx]) == NULL) {
646
- /* prepend "soname: " if soname is not found in
647
- * the error message.
648
- */
649
- rb_str_buf_cat2(msg, sonames[idx]);
650
- rb_str_buf_cat2(msg, ": ");
651
- }
652
- rb_str_buf_append(msg, arr[idx]);
653
- rb_str_buf_cat2(msg, ";");
654
- }
667
+ VALUE msg = rb_ary_join(err, rb_usascii_str_new_cstr("; "));
655
668
  rb_exc_raise(rb_exc_new3(rb_eLoadError, msg));
656
669
  }
657
670
  }
data/ext/oci8/ocihandle.c CHANGED
@@ -752,7 +752,7 @@ static VALUE attr_set_string(VALUE self, VALUE attr_type, VALUE val)
752
752
  Check_Type(attr_type, T_FIXNUM);
753
753
  OCI8SafeStringValue(val);
754
754
  /* set attribute */
755
- chker2(OCIAttrSet(base->hp.ptr, base->type, RSTRING_PTR(val), RSTRING_LEN(val), FIX2INT(attr_type), oci8_errhp), base);
755
+ chker2(OCIAttrSet(base->hp.ptr, base->type, RSTRING_PTR(val), RSTRING_LENINT(val), FIX2INT(attr_type), oci8_errhp), base);
756
756
  return self;
757
757
  }
758
758
 
@@ -776,7 +776,7 @@ static VALUE attr_set_binary(VALUE self, VALUE attr_type, VALUE val)
776
776
  Check_Type(attr_type, T_FIXNUM);
777
777
  SafeStringValue(val);
778
778
  /* set attribute */
779
- chker2(OCIAttrSet(base->hp.ptr, base->type, RSTRING_PTR(val), RSTRING_LEN(val), FIX2INT(attr_type), oci8_errhp), base);
779
+ chker2(OCIAttrSet(base->hp.ptr, base->type, RSTRING_PTR(val), RSTRING_LENINT(val), FIX2INT(attr_type), oci8_errhp), base);
780
780
  return self;
781
781
  }
782
782
 
data/ext/oci8/ocinumber.c CHANGED
@@ -154,7 +154,7 @@ static void set_oci_number_from_str(OCINumber *result, VALUE str, VALUE fmt, VAL
154
154
  StringValue(str);
155
155
  /* set from string. */
156
156
  if (NIL_P(fmt)) {
157
- int rv = oranumber_from_str(result, RSTRING_PTR(str), RSTRING_LEN(str));
157
+ int rv = oranumber_from_str(result, RSTRING_PTR(str), RSTRING_LENINT(str));
158
158
  if (rv == ORANUMBER_SUCCESS) {
159
159
  return; /* success */
160
160
  } else {
@@ -172,17 +172,17 @@ static void set_oci_number_from_str(OCINumber *result, VALUE str, VALUE fmt, VAL
172
172
  }
173
173
  StringValue(fmt);
174
174
  fmt_ptr = RSTRING_ORATEXT(fmt);
175
- fmt_len = RSTRING_LEN(fmt);
175
+ fmt_len = RSTRING_LENINT(fmt);
176
176
  if (NIL_P(nls_params)) {
177
177
  nls_params_ptr = NULL;
178
178
  nls_params_len = 0;
179
179
  } else {
180
180
  StringValue(nls_params);
181
181
  nls_params_ptr = RSTRING_ORATEXT(nls_params);
182
- nls_params_len = RSTRING_LEN(nls_params);
182
+ nls_params_len = RSTRING_LENINT(nls_params);
183
183
  }
184
184
  chkerr(OCINumberFromText(errhp,
185
- RSTRING_ORATEXT(str), RSTRING_LEN(str),
185
+ RSTRING_ORATEXT(str), RSTRING_LENINT(str),
186
186
  fmt_ptr, fmt_len, nls_params_ptr, nls_params_len,
187
187
  result));
188
188
  }
@@ -216,6 +216,8 @@ static int set_oci_number_from_num(OCINumber *result, VALUE num, int force, OCIE
216
216
  num = rb_big2str(num, 10);
217
217
  set_oci_number_from_str(result, num, Qnil, Qnil, errhp);
218
218
  return 1;
219
+ default:
220
+ break;
219
221
  }
220
222
  if (RTEST(rb_obj_is_instance_of(num, cOCINumber))) {
221
223
  /* OCI::Number */
@@ -247,7 +249,7 @@ static int set_oci_number_from_num(OCINumber *result, VALUE num, int force, OCIE
247
249
  if (TYPE(ary[1]) != T_STRING) {
248
250
  goto is_not_big_decimal;
249
251
  }
250
- digits_len = RSTRING_LEN(ary[1]);
252
+ digits_len = RSTRING_LENINT(ary[1]);
251
253
  set_oci_number_from_str(&digits, ary[1], Qnil, Qnil, errhp);
252
254
  /* check base */
253
255
  if (TYPE(ary[2]) != T_FIXNUM || FIX2LONG(ary[2]) != 10) {
@@ -363,7 +365,7 @@ OCINumber *oci8_dbl_to_onum(OCINumber *result, double dbl, OCIError *errhp)
363
365
  sword rv;
364
366
 
365
367
  str = rb_obj_as_string(rb_float_new(dbl));
366
- rv = oranumber_from_str(result, RSTRING_PTR(str), RSTRING_LEN(str));
368
+ rv = oranumber_from_str(result, RSTRING_PTR(str), RSTRING_LENINT(str));
367
369
  if (rv != 0) {
368
370
  oci8_raise_by_msgno(rv, NULL);
369
371
  }
@@ -1307,14 +1309,14 @@ static VALUE onum_to_char(int argc, VALUE *argv, VALUE self)
1307
1309
  }
1308
1310
  StringValue(fmt);
1309
1311
  fmt_ptr = RSTRING_ORATEXT(fmt);
1310
- fmt_len = RSTRING_LEN(fmt);
1312
+ fmt_len = RSTRING_LENINT(fmt);
1311
1313
  if (NIL_P(nls_params)) {
1312
1314
  nls_params_ptr = NULL;
1313
1315
  nls_params_len = 0;
1314
1316
  } else {
1315
1317
  StringValue(nls_params);
1316
1318
  nls_params_ptr = RSTRING_ORATEXT(nls_params);
1317
- nls_params_len = RSTRING_LEN(nls_params);
1319
+ nls_params_len = RSTRING_LENINT(nls_params);
1318
1320
  }
1319
1321
  rv = OCINumberToText(errhp, _NUMBER(self),
1320
1322
  fmt_ptr, fmt_len, nls_params_ptr, nls_params_len,
@@ -1435,23 +1437,23 @@ static VALUE onum_to_d_real(OCINumber *num, OCIError *errhp)
1435
1437
  rb_require("bigdecimal");
1436
1438
  cBigDecimal = rb_const_get(rb_cObject, id_BigDecimal);
1437
1439
  }
1438
- chkerr(OCINumberToText(errhp, num, (const oratext *)fmt, strlen(fmt),
1440
+ chkerr(OCINumberToText(errhp, num, (const oratext *)fmt, (ub4)strlen(fmt),
1439
1441
  NULL, 0, &buf_size, TO_ORATEXT(buf)));
1440
1442
  return rb_funcall(rb_cObject, id_BigDecimal, 1, rb_usascii_str_new(buf, buf_size));
1441
1443
  }
1442
1444
 
1443
1445
  /*
1444
- * @overload has_decimal_part?
1446
+ * @overload has_fractional_part?
1445
1447
  *
1446
- * Returns <code>true</code> if <i>self</i> has a decimal part.
1448
+ * Returns <code>true</code> if <i>self</i> has a fractional part.
1447
1449
  *
1448
1450
  * @example
1449
- * OraNumber(10).has_decimal_part? # => false
1450
- * OraNumber(10.1).has_decimal_part? # => true
1451
+ * OraNumber(10).has_fractional_part? # => false
1452
+ * OraNumber(10.1).has_fractional_part? # => true
1451
1453
  *
1452
- * @since 2.0.5
1454
+ * @since 2.2.5
1453
1455
  */
1454
- static VALUE onum_has_decimal_part_p(VALUE self)
1456
+ static VALUE onum_has_fractional_part_p(VALUE self)
1455
1457
  {
1456
1458
  OCIError *errhp = oci8_errhp;
1457
1459
  boolean result;
@@ -1873,7 +1875,7 @@ Init_oci_number(VALUE cOCI8, OCIError *errhp)
1873
1875
  rb_define_method(cOCINumber, "to_f", onum_to_f, 0);
1874
1876
  rb_define_method(cOCINumber, "to_r", onum_to_r, 0);
1875
1877
  rb_define_method(cOCINumber, "to_d", onum_to_d, 0);
1876
- rb_define_method(cOCINumber, "has_decimal_part?", onum_has_decimal_part_p, 0);
1878
+ rb_define_method(cOCINumber, "has_fractional_part?", onum_has_fractional_part_p, 0);
1877
1879
  rb_define_method(cOCINumber, "to_onum", onum_to_onum, 0);
1878
1880
 
1879
1881
  rb_define_method(cOCINumber, "zero?", onum_zero_p, 0);
@@ -1902,6 +1904,10 @@ Init_oci_number(VALUE cOCI8, OCIError *errhp)
1902
1904
  dummy2 = rb_define_class_under(mOCI8BindType, "Integer", cOCI8BindTypeBase);
1903
1905
  dummy3 = rb_define_class_under(mOCI8BindType, "Float", cOCI8BindTypeBase);
1904
1906
  #endif
1907
+
1908
+ /* The following method definition is for backward-compatibility.
1909
+ I misunderstood the name of numbers after a decimal point. */
1910
+ rb_define_method_nodoc(cOCINumber, "has_decimal_part?", onum_has_fractional_part_p, 0);
1905
1911
  }
1906
1912
 
1907
1913
  /*