ruby-oci8 2.2.3 → 2.2.12

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 (77) hide show
  1. checksums.yaml +7 -0
  2. data/ChangeLog +427 -0
  3. data/NEWS +335 -42
  4. data/README.md +20 -9
  5. data/dist-files +9 -3
  6. data/docs/bind-array-to-in_cond.md +2 -2
  7. data/docs/conflicts-local-connections-and-processes.md +7 -4
  8. data/docs/hanging-after-inactivity.md +63 -0
  9. data/docs/install-binary-package.md +15 -11
  10. data/docs/install-full-client.md +18 -21
  11. data/docs/install-instant-client.md +45 -27
  12. data/docs/install-on-osx.md +31 -120
  13. data/docs/ldap-auth-and-function-interposition.md +123 -0
  14. data/docs/number-type-mapping.md +79 -0
  15. data/docs/platform-specific-issues.md +17 -50
  16. data/docs/report-installation-issue.md +3 -0
  17. data/docs/timeout-parameters.md +3 -0
  18. data/ext/oci8/apiwrap.c.tmpl +2 -5
  19. data/ext/oci8/apiwrap.rb +6 -1
  20. data/ext/oci8/apiwrap.yml +34 -22
  21. data/ext/oci8/attr.c +4 -2
  22. data/ext/oci8/bind.c +366 -6
  23. data/ext/oci8/connection_pool.c +3 -3
  24. data/ext/oci8/encoding.c +5 -5
  25. data/ext/oci8/env.c +8 -2
  26. data/ext/oci8/error.c +24 -16
  27. data/ext/oci8/extconf.rb +8 -4
  28. data/ext/oci8/hook_funcs.c +274 -61
  29. data/ext/oci8/lob.c +31 -75
  30. data/ext/oci8/metadata.c +2 -2
  31. data/ext/oci8/object.c +72 -27
  32. data/ext/oci8/oci8.c +45 -132
  33. data/ext/oci8/oci8.h +32 -88
  34. data/ext/oci8/oci8lib.c +178 -38
  35. data/ext/oci8/ocihandle.c +37 -37
  36. data/ext/oci8/ocinumber.c +23 -18
  37. data/ext/oci8/oraconf.rb +158 -339
  38. data/ext/oci8/oradate.c +19 -19
  39. data/ext/oci8/plthook.h +10 -0
  40. data/ext/oci8/plthook_elf.c +433 -268
  41. data/ext/oci8/plthook_osx.c +40 -9
  42. data/ext/oci8/plthook_win32.c +9 -0
  43. data/ext/oci8/stmt.c +52 -17
  44. data/ext/oci8/win32.c +4 -22
  45. data/lib/oci8/bindtype.rb +1 -15
  46. data/lib/oci8/check_load_error.rb +57 -10
  47. data/lib/oci8/cursor.rb +57 -25
  48. data/lib/oci8/metadata.rb +9 -1
  49. data/lib/oci8/object.rb +10 -0
  50. data/lib/oci8/oci8.rb +33 -28
  51. data/lib/oci8/oracle_version.rb +11 -1
  52. data/lib/oci8/properties.rb +22 -0
  53. data/lib/oci8/version.rb +1 -1
  54. data/lib/oci8.rb +48 -4
  55. data/lib/ruby-oci8.rb +0 -3
  56. data/pre-distclean.rb +1 -3
  57. data/ruby-oci8.gemspec +3 -8
  58. data/setup.rb +11 -2
  59. data/test/README.md +37 -0
  60. data/test/config.rb +1 -1
  61. data/test/setup_test_object.sql +21 -13
  62. data/test/setup_test_package.sql +59 -0
  63. data/test/test_all.rb +2 -0
  64. data/test/test_bind_boolean.rb +99 -0
  65. data/test/test_bind_integer.rb +47 -0
  66. data/test/test_break.rb +11 -9
  67. data/test/test_clob.rb +4 -16
  68. data/test/test_connstr.rb +29 -13
  69. data/test/test_datetime.rb +8 -3
  70. data/test/test_object.rb +27 -9
  71. data/test/test_oci8.rb +170 -46
  72. data/test/test_oranumber.rb +12 -6
  73. data/test/test_package_type.rb +15 -3
  74. data/test/test_properties.rb +17 -0
  75. metadata +40 -54
  76. data/docs/osx-install-dev-tools.png +0 -0
  77. data/test/README +0 -42
data/ext/oci8/bind.c CHANGED
@@ -11,6 +11,7 @@
11
11
  #endif
12
12
 
13
13
  static ID id_bind_type;
14
+ static ID id_charset_form;
14
15
  static VALUE sym_length;
15
16
  static VALUE sym_length_semantics;
16
17
  static VALUE sym_char;
@@ -25,6 +26,29 @@ typedef struct {
25
26
  ub1 csfrm;
26
27
  } oci8_bind_string_t;
27
28
 
29
+ static ub4 initial_chunk_size = 32 * 1024;
30
+ static ub4 max_chunk_size = 8 * 1024 * 1024;
31
+
32
+ typedef struct chunk {
33
+ struct chunk *next;
34
+ ub4 alloc_len;
35
+ ub4 used_len;
36
+ char buf[1];
37
+ } chunk_t;
38
+
39
+ typedef struct {
40
+ chunk_t *head;
41
+ chunk_t **tail;
42
+ chunk_t **inpos;
43
+ } chunk_buf_t;
44
+
45
+ typedef struct {
46
+ oci8_bind_t obind;
47
+ ub1 csfrm;
48
+ } oci8_bind_long_t;
49
+
50
+ #define IS_BIND_LONG(obind) (((oci8_bind_data_type_t*)obind->base.data_type)->dty == SQLT_CHR)
51
+
28
52
  const oci8_handle_data_type_t oci8_bind_data_type = {
29
53
  {
30
54
  "OCI8::BindType::Base",
@@ -61,7 +85,7 @@ static void bind_string_set(oci8_bind_t *obind, void *data, void **null_structp,
61
85
  rb_raise(rb_eArgError, "too long String to set. (%ld for %d)", RSTRING_LEN(val), obs->bytelen);
62
86
  }
63
87
  memcpy(vstr->buf, RSTRING_PTR(val), RSTRING_LEN(val));
64
- vstr->size = RSTRING_LEN(val);
88
+ vstr->size = RSTRING_LENINT(val);
65
89
  }
66
90
 
67
91
  static void bind_string_init(oci8_bind_t *obind, VALUE svc, VALUE val, VALUE param)
@@ -171,7 +195,7 @@ static void bind_raw_set(oci8_bind_t *obind, void *data, void **null_structp, VA
171
195
  rb_raise(rb_eArgError, "too long String to set. (%ld for %d)", RSTRING_LEN(val), obs->bytelen);
172
196
  }
173
197
  memcpy(vstr->buf, RSTRING_PTR(val), RSTRING_LEN(val));
174
- vstr->size = RSTRING_LEN(val);
198
+ vstr->size = RSTRING_LENINT(val);
175
199
  }
176
200
 
177
201
  static const oci8_bind_data_type_t bind_raw_data_type = {
@@ -306,6 +330,295 @@ static VALUE bind_boolean_alloc(VALUE klass)
306
330
  return oci8_allocate_typeddata(klass, &bind_boolean_data_type.base);
307
331
  }
308
332
 
333
+ /*
334
+ * bind_long
335
+ */
336
+ static chunk_t *next_chunk(chunk_buf_t *cb)
337
+ {
338
+ chunk_t *chunk;
339
+
340
+ if (*cb->tail != NULL) {
341
+ chunk = *cb->tail;
342
+ } else {
343
+ ub4 alloc_len;
344
+ if (cb->head == NULL) {
345
+ alloc_len = initial_chunk_size;
346
+ } else {
347
+ alloc_len = ((chunk_t*)((size_t)cb->tail - offsetof(chunk_t, next)))->alloc_len * 2;
348
+ if (alloc_len > max_chunk_size) {
349
+ alloc_len = max_chunk_size;
350
+ }
351
+ }
352
+ chunk = xmalloc(offsetof(chunk_t, buf) + alloc_len);
353
+ chunk->next = NULL;
354
+ chunk->alloc_len = alloc_len;
355
+ *cb->tail = chunk;
356
+ }
357
+ cb->tail = &chunk->next;
358
+ return chunk;
359
+ }
360
+
361
+ static sb4 define_callback(void *octxp, OCIDefine *defnp, ub4 iter, void **bufpp, ub4 **alenp, ub1 *piecep, void **indp, ub2 **rcodep)
362
+ {
363
+ oci8_bind_t *obind = (oci8_bind_t *)octxp;
364
+ chunk_buf_t *cb = ((chunk_buf_t*)obind->valuep) + iter;
365
+ chunk_t *chunk;
366
+
367
+ if (*piecep == OCI_FIRST_PIECE) {
368
+ cb->tail = &cb->head;
369
+ }
370
+ chunk = next_chunk(cb);
371
+ chunk->used_len = chunk->alloc_len;
372
+ *bufpp = chunk->buf;
373
+ *alenp = &chunk->used_len;
374
+ *indp = (void*)&obind->u.inds[iter];
375
+ *rcodep = NULL;
376
+ return OCI_CONTINUE;
377
+ }
378
+
379
+ static sb4 in_bind_callback(void *ictxp, OCIBind *bindp, ub4 iter, ub4 index, void **bufpp, ub4 *alenp, ub1 *piecep, void **indp)
380
+ {
381
+ oci8_bind_t *obind = (oci8_bind_t *)ictxp;
382
+ chunk_buf_t *cb = ((chunk_buf_t*)obind->valuep) + iter;
383
+
384
+ if (cb->tail == &cb->head) {
385
+ /* empty string */
386
+ *bufpp = (void *)"";
387
+ *alenp = 0;
388
+ *piecep = OCI_ONE_PIECE;
389
+ } else {
390
+ chunk_t *chunk = *cb->inpos;
391
+ *bufpp = chunk->buf;
392
+ *alenp = chunk->used_len;
393
+ if (cb->tail == &cb->head->next) {
394
+ *piecep = OCI_ONE_PIECE;
395
+ } else if (cb->inpos == &cb->head) {
396
+ *piecep = OCI_FIRST_PIECE;
397
+ cb->inpos = &chunk->next;
398
+ } else if (&chunk->next != cb->tail) {
399
+ *piecep = OCI_NEXT_PIECE;
400
+ cb->inpos = &chunk->next;
401
+ } else {
402
+ *piecep = OCI_LAST_PIECE;
403
+ cb->inpos = &cb->head;
404
+ }
405
+ }
406
+ *indp = (void*)&obind->u.inds[iter];
407
+ return OCI_CONTINUE;
408
+ }
409
+
410
+ static sb4 out_bind_callback(void *octxp, OCIBind *bindp, ub4 iter, ub4 index, void **bufpp, ub4 **alenp, ub1 *piecep, void **indp, ub2 **rcodep)
411
+ {
412
+ oci8_bind_t *obind = (oci8_bind_t *)octxp;
413
+ chunk_buf_t *cb = ((chunk_buf_t*)obind->valuep) + iter;
414
+ chunk_t *chunk;
415
+
416
+ if (*piecep == OCI_ONE_PIECE) {
417
+ *piecep = OCI_FIRST_PIECE;
418
+ cb->tail = &cb->head;
419
+ }
420
+ chunk = next_chunk(cb);
421
+ chunk->used_len = chunk->alloc_len;
422
+ *bufpp = chunk->buf;
423
+ *alenp = &chunk->used_len;
424
+ *indp = (void*)&obind->u.inds[iter];
425
+ *rcodep = NULL;
426
+ return OCI_CONTINUE;
427
+ }
428
+
429
+ static void bind_long_free(oci8_base_t *base)
430
+ {
431
+ oci8_bind_t *obind = (oci8_bind_t *)base;
432
+ chunk_buf_t *cb = (chunk_buf_t *)obind->valuep;
433
+
434
+ if (cb != NULL) {
435
+ ub4 idx = 0;
436
+ do {
437
+ chunk_t *chunk, *chunk_next;
438
+ for (chunk = cb[idx].head; chunk != NULL; chunk = chunk_next) {
439
+ chunk_next = chunk->next;
440
+ xfree(chunk);
441
+ }
442
+ } while (++idx < obind->maxar_sz);
443
+ }
444
+ oci8_bind_free(base);
445
+ }
446
+
447
+ static VALUE bind_long_get(oci8_bind_t *obind, void *data, void *null_struct)
448
+ {
449
+ chunk_buf_t *cb = (chunk_buf_t *)data;
450
+ chunk_t *chunk;
451
+ long len = 0;
452
+ VALUE str;
453
+ char *buf;
454
+
455
+ for (chunk = cb->head; chunk != *cb->tail; chunk = chunk->next) {
456
+ len += chunk->used_len;
457
+ }
458
+ str = rb_str_buf_new(len);
459
+ buf = RSTRING_PTR(str);
460
+ for (chunk = cb->head; chunk != *cb->tail; chunk = chunk->next) {
461
+ memcpy(buf, chunk->buf, chunk->used_len);
462
+ buf += chunk->used_len;
463
+ }
464
+ rb_str_set_len(str, len);
465
+ if (IS_BIND_LONG(obind)) {
466
+ rb_encoding *enc = rb_default_internal_encoding();
467
+
468
+ rb_enc_associate(str, oci8_encoding);
469
+ if (enc != NULL) {
470
+ str = rb_str_conv_enc(str, oci8_encoding, enc);
471
+ }
472
+ }
473
+ return str;
474
+ }
475
+
476
+ static void bind_long_set(oci8_bind_t *obind, void *data, void **null_structp, VALUE val)
477
+ {
478
+ chunk_buf_t *cb = (chunk_buf_t *)data;
479
+ ub4 len;
480
+ const char *buf;
481
+
482
+ if (IS_BIND_LONG(obind)) {
483
+ OCI8StringValue(val);
484
+ } else {
485
+ StringValue(val);
486
+ }
487
+ len = (ub4)RSTRING_LEN(val);
488
+ buf = RSTRING_PTR(val);
489
+ cb->tail = &cb->head;
490
+ while (1) {
491
+ chunk_t *chunk = next_chunk(cb);
492
+ if (len <= chunk->alloc_len) {
493
+ memcpy(chunk->buf, buf, len);
494
+ chunk->used_len = len;
495
+ break;
496
+ }
497
+ memcpy(chunk->buf, buf, chunk->alloc_len);
498
+ chunk->used_len = chunk->alloc_len;
499
+ len -= chunk->alloc_len;
500
+ buf += chunk->alloc_len;
501
+ }
502
+ }
503
+
504
+ static void bind_long_init(oci8_bind_t *obind, VALUE svc, VALUE val, VALUE param)
505
+ {
506
+ if (IS_BIND_LONG(obind)) {
507
+ oci8_bind_long_t *obl = (oci8_bind_long_t *)obind;
508
+ VALUE nchar;
509
+
510
+ if (rb_respond_to(param, id_charset_form)) {
511
+ VALUE csfrm = rb_funcall(param, id_charset_form, 0);
512
+ nchar = (csfrm == sym_nchar) ? Qtrue : Qfalse;
513
+ } else {
514
+ Check_Type(param, T_HASH);
515
+ nchar = rb_hash_aref(param, sym_nchar);
516
+ }
517
+
518
+ if (RTEST(nchar)) {
519
+ obl->csfrm = SQLCS_NCHAR; /* bind as NCHAR/NVARCHAR2 */
520
+ } else {
521
+ obl->csfrm = SQLCS_IMPLICIT; /* bind as CHAR/VARCHAR2 */
522
+ }
523
+ }
524
+ obind->value_sz = SB4MAXVAL;
525
+ obind->alloc_sz = sizeof(chunk_buf_t);
526
+ }
527
+
528
+ static void bind_long_init_elem(oci8_bind_t *obind, VALUE svc)
529
+ {
530
+ chunk_buf_t *cb = (chunk_buf_t *)obind->valuep;
531
+ ub4 idx = 0;
532
+
533
+ do {
534
+ cb[idx].tail = &cb[idx].head;
535
+ cb[idx].inpos = &cb[idx].head;
536
+ } while (++idx < obind->maxar_sz);
537
+ }
538
+
539
+ static void bind_long_post_bind_hook(oci8_bind_t *obind)
540
+ {
541
+ oci8_bind_long_t *ds = (oci8_bind_long_t *)obind;
542
+
543
+ if (IS_BIND_LONG(obind)) {
544
+ chker2(OCIAttrSet(obind->base.hp.ptr, obind->base.type, (void*)&ds->csfrm, 0, OCI_ATTR_CHARSET_FORM, oci8_errhp),
545
+ &obind->base);
546
+ }
547
+ switch (obind->base.type) {
548
+ case OCI_HTYPE_DEFINE:
549
+ chker2(OCIDefineDynamic(obind->base.hp.dfn, oci8_errhp, obind, define_callback),
550
+ &obind->base);
551
+ break;
552
+ case OCI_HTYPE_BIND:
553
+ chker2(OCIBindDynamic(obind->base.hp.bnd, oci8_errhp, obind, in_bind_callback,
554
+ obind, out_bind_callback),
555
+ &obind->base);
556
+ break;
557
+ }
558
+ }
559
+
560
+ static const oci8_bind_data_type_t bind_long_data_type = {
561
+ {
562
+ {
563
+ "OCI8::BindType::Long",
564
+ {
565
+ NULL,
566
+ oci8_handle_cleanup,
567
+ oci8_handle_size,
568
+ },
569
+ &oci8_bind_data_type.rb_data_type, NULL,
570
+ #ifdef RUBY_TYPED_WB_PROTECTED
571
+ RUBY_TYPED_WB_PROTECTED,
572
+ #endif
573
+ },
574
+ bind_long_free,
575
+ sizeof(oci8_bind_long_t)
576
+ },
577
+ bind_long_get,
578
+ bind_long_set,
579
+ bind_long_init,
580
+ bind_long_init_elem,
581
+ NULL,
582
+ SQLT_CHR,
583
+ bind_long_post_bind_hook,
584
+ };
585
+
586
+ static VALUE bind_long_alloc(VALUE klass)
587
+ {
588
+ return oci8_allocate_typeddata(klass, &bind_long_data_type.base);
589
+ }
590
+
591
+ static const oci8_bind_data_type_t bind_long_raw_data_type = {
592
+ {
593
+ {
594
+ "OCI8::BindType::LongRaw",
595
+ {
596
+ NULL,
597
+ oci8_handle_cleanup,
598
+ oci8_handle_size,
599
+ },
600
+ &oci8_bind_data_type.rb_data_type, NULL,
601
+ #ifdef RUBY_TYPED_WB_PROTECTED
602
+ RUBY_TYPED_WB_PROTECTED,
603
+ #endif
604
+ },
605
+ bind_long_free,
606
+ sizeof(oci8_bind_long_t)
607
+ },
608
+ bind_long_get,
609
+ bind_long_set,
610
+ bind_long_init,
611
+ bind_long_init_elem,
612
+ NULL,
613
+ SQLT_BIN,
614
+ bind_long_post_bind_hook,
615
+ };
616
+
617
+ static VALUE bind_long_raw_alloc(VALUE klass)
618
+ {
619
+ return oci8_allocate_typeddata(klass, &bind_long_raw_data_type.base);
620
+ }
621
+
309
622
  static VALUE oci8_bind_get(VALUE self)
310
623
  {
311
624
  oci8_bind_t *obind = TO_BIND(self);
@@ -320,11 +633,20 @@ static VALUE oci8_bind_get(VALUE self)
320
633
  return data_type->get(obind, (void*)((size_t)obind->valuep + obind->alloc_sz * idx), null_structp);
321
634
  }
322
635
 
323
- static VALUE oci8_bind_get_data(VALUE self)
636
+ static VALUE oci8_bind_get_data(int argc, VALUE *argv, VALUE self)
324
637
  {
325
638
  oci8_bind_t *obind = TO_BIND(self);
639
+ VALUE index;
326
640
 
327
- if (obind->maxar_sz == 0) {
641
+ rb_scan_args(argc, argv, "01", &index);
642
+ if (!NIL_P(index)) {
643
+ ub4 idx = NUM2UINT(index);
644
+ if (idx >= obind->maxar_sz) {
645
+ rb_raise(rb_eRuntimeError, "data index is too big. (%u for %u)", idx, obind->maxar_sz);
646
+ }
647
+ obind->curar_idx = idx;
648
+ return rb_funcall(self, oci8_id_get, 0);
649
+ } else if (obind->maxar_sz == 0) {
328
650
  obind->curar_idx = 0;
329
651
  return rb_funcall(self, oci8_id_get, 0);
330
652
  } else {
@@ -378,7 +700,7 @@ static VALUE oci8_bind_set_data(VALUE self, VALUE val)
378
700
  ub4 idx;
379
701
  Check_Type(val, T_ARRAY);
380
702
 
381
- size = RARRAY_LEN(val);
703
+ size = RARRAY_LENINT(val);
382
704
  if (size > obind->maxar_sz) {
383
705
  rb_raise(rb_eRuntimeError, "over the max array size");
384
706
  }
@@ -391,6 +713,36 @@ static VALUE oci8_bind_set_data(VALUE self, VALUE val)
391
713
  return self;
392
714
  }
393
715
 
716
+ static VALUE get_initial_chunk_size(VALUE klass)
717
+ {
718
+ return UINT2NUM(initial_chunk_size);
719
+ }
720
+
721
+ static VALUE set_initial_chunk_size(VALUE klass, VALUE arg)
722
+ {
723
+ ub4 size = NUM2UINT(arg);
724
+ if (size == 0) {
725
+ rb_raise(rb_eArgError, "Could not set zero");
726
+ }
727
+ initial_chunk_size = size;
728
+ return arg;
729
+ }
730
+
731
+ static VALUE get_max_chunk_size(VALUE klass)
732
+ {
733
+ return UINT2NUM(max_chunk_size);
734
+ }
735
+
736
+ static VALUE set_max_chunk_size(VALUE klass, VALUE arg)
737
+ {
738
+ ub4 size = NUM2UINT(arg);
739
+ if (size == 0) {
740
+ rb_raise(rb_eArgError, "Could not set zero");
741
+ }
742
+ max_chunk_size = size;
743
+ return arg;
744
+ }
745
+
394
746
  static VALUE oci8_bind_initialize(VALUE self, VALUE svc, VALUE val, VALUE length, VALUE max_array_size)
395
747
  {
396
748
  oci8_bind_t *obind = TO_BIND(self);
@@ -456,6 +808,7 @@ void Init_oci8_bind(VALUE klass)
456
808
  {
457
809
  cOCI8BindTypeBase = klass;
458
810
  id_bind_type = rb_intern("bind_type");
811
+ id_charset_form = rb_intern("charset_form");
459
812
  sym_length = ID2SYM(rb_intern("length"));
460
813
  sym_length_semantics = ID2SYM(rb_intern("length_semantics"));
461
814
  sym_char = ID2SYM(rb_intern("char"));
@@ -464,9 +817,14 @@ void Init_oci8_bind(VALUE klass)
464
817
  rb_define_method(cOCI8BindTypeBase, "initialize", oci8_bind_initialize, 4);
465
818
  rb_define_method(cOCI8BindTypeBase, "get", oci8_bind_get, 0);
466
819
  rb_define_method(cOCI8BindTypeBase, "set", oci8_bind_set, 1);
467
- rb_define_private_method(cOCI8BindTypeBase, "get_data", oci8_bind_get_data, 0);
820
+ rb_define_private_method(cOCI8BindTypeBase, "get_data", oci8_bind_get_data, -1);
468
821
  rb_define_private_method(cOCI8BindTypeBase, "set_data", oci8_bind_set_data, 1);
469
822
 
823
+ rb_define_singleton_method(klass, "initial_chunk_size", get_initial_chunk_size, 0);
824
+ rb_define_singleton_method(klass, "initial_chunk_size=", set_initial_chunk_size, 1);
825
+ rb_define_singleton_method(klass, "max_chunk_size", get_max_chunk_size, 0);
826
+ rb_define_singleton_method(klass, "max_chunk_size=", set_max_chunk_size, 1);
827
+
470
828
  /* register primitive data types. */
471
829
  oci8_define_bind_class("String", &bind_string_data_type, bind_string_alloc);
472
830
  oci8_define_bind_class("RAW", &bind_raw_data_type, bind_raw_alloc);
@@ -474,4 +832,6 @@ void Init_oci8_bind(VALUE klass)
474
832
  if (oracle_client_version >= ORAVER_12_1) {
475
833
  oci8_define_bind_class("Boolean", &bind_boolean_data_type, bind_boolean_alloc);
476
834
  }
835
+ klass = oci8_define_bind_class("Long", &bind_long_data_type, bind_long_alloc);
836
+ klass = oci8_define_bind_class("LongRaw", &bind_long_data_type, bind_long_raw_alloc);
477
837
  }
@@ -144,13 +144,13 @@ static VALUE oci8_cpool_initialize(int argc, VALUE *argv, VALUE self)
144
144
  chker2(OCIConnectionPoolCreate(oci8_envhp, oci8_errhp, cpool->base.hp.poolhp,
145
145
  &pool_name, &pool_name_len,
146
146
  NIL_P(dbname) ? NULL : RSTRING_ORATEXT(dbname),
147
- NIL_P(dbname) ? 0 : RSTRING_LEN(dbname),
147
+ NIL_P(dbname) ? 0 : RSTRING_LENINT(dbname),
148
148
  FIX2UINT(conn_min), FIX2UINT(conn_max),
149
149
  FIX2UINT(conn_incr),
150
150
  NIL_P(username) ? NULL : RSTRING_ORATEXT(username),
151
- NIL_P(username) ? 0 : RSTRING_LEN(username),
151
+ NIL_P(username) ? 0 : RSTRING_LENINT(username),
152
152
  NIL_P(password) ? NULL : RSTRING_ORATEXT(password),
153
- NIL_P(password) ? 0 : RSTRING_LEN(password),
153
+ NIL_P(password) ? 0 : RSTRING_LENINT(password),
154
154
  OCI_DEFAULT),
155
155
  &cpool->base);
156
156
  RB_OBJ_WRITE(cpool->base.self, &cpool->pool_name, rb_str_new(TO_CHARPTR(pool_name), pool_name_len));
data/ext/oci8/encoding.c CHANGED
@@ -23,7 +23,7 @@ rb_encoding *oci8_encoding;
23
23
  * Returns the Oracle character set name from the specified
24
24
  * character set ID if it is valid. Otherwise, +nil+ is returned.
25
25
  *
26
- * @param [Fixnum] charset_id Oracle character set id
26
+ * @param [Integer] charset_id Oracle character set id
27
27
  * @return [String] Oracle character set name or nil
28
28
  * @since 2.2.0
29
29
  */
@@ -48,7 +48,7 @@ VALUE oci8_s_charset_id2name(VALUE klass, VALUE csid)
48
48
  * character set name if it is valid. Othewise, +nil+ is returned.
49
49
  *
50
50
  * @param [String] charset_name Oracle character set name
51
- * @return [Fixnum] Oracle character set id or nil
51
+ * @return [Integer] Oracle character set id or nil
52
52
  * @since 2.2.0
53
53
  */
54
54
  static VALUE oci8_s_charset_name2id(VALUE klass, VALUE name)
@@ -71,7 +71,7 @@ static VALUE oci8_s_charset_name2id(VALUE klass, VALUE name)
71
71
  * internal buffer size of a string bind variable whose nls length
72
72
  * semantics is char.
73
73
  *
74
- * @return [Fixnum] NLS ratio
74
+ * @return [Integer] NLS ratio
75
75
  * @since 2.1.0
76
76
  * @private
77
77
  */
@@ -150,7 +150,7 @@ static VALUE oci8_set_encoding(VALUE klass, VALUE encoding)
150
150
  * character set name if it is valid. Othewise, +nil+ is returned.
151
151
  *
152
152
  * @param [String] charset_name Oracle character set name
153
- * @return [Fixnum] Oracle character set id or nil
153
+ * @return [Integer] Oracle character set id or nil
154
154
  * @since 2.0.0
155
155
  * @deprecated Use {OCI8.charset_name2id} instead.
156
156
  */
@@ -167,7 +167,7 @@ static VALUE oci8_charset_name2id(VALUE svc, VALUE name)
167
167
  * Returns the Oracle character set name from the specified
168
168
  * character set ID if it is valid. Otherwise, +nil+ is returned.
169
169
  *
170
- * @param [Fixnum] charset_id Oracle character set id
170
+ * @param [Integer] charset_id Oracle character set id
171
171
  * @return [String] Oracle character set name or nil
172
172
  * @since 2.0.0
173
173
  * @deprecated Use {OCI8.charset_id2name} instead.
data/ext/oci8/env.c CHANGED
@@ -14,11 +14,17 @@ OCIEnv *oci8_global_envhp;
14
14
  OCIEnv *oci8_make_envhp(void)
15
15
  {
16
16
  sword rv;
17
+ OCIEnv *envhp = NULL;
17
18
 
18
- rv = OCIEnvCreate(&oci8_global_envhp, oci8_env_mode, NULL, NULL, NULL, NULL, 0, NULL);
19
+ rv = OCIEnvCreate(&envhp, oci8_env_mode, NULL, NULL, NULL, NULL, 0, NULL);
19
20
  if (rv != OCI_SUCCESS) {
20
- oci8_raise_init_error();
21
+ if (envhp != NULL) {
22
+ oci8_env_free_and_raise(envhp, rv);
23
+ } else {
24
+ oci8_raise_init_error();
25
+ }
21
26
  }
27
+ oci8_global_envhp = envhp;
22
28
  return oci8_global_envhp;
23
29
  }
24
30
 
data/ext/oci8/error.c CHANGED
@@ -75,6 +75,21 @@ retry:
75
75
  return rb_external_str_new_with_enc(errbuf, len, oci8_encoding);
76
76
  }
77
77
 
78
+ /*
79
+ * Don't call rb_class_new_instance() with more than one argument in this function.
80
+ * This may be called before OCIError#initialize is defined in lib/oci8/oci8.rb.
81
+ */
82
+ static VALUE oci_exception_new(VALUE klass, VALUE msg, VALUE code, VALUE sql, VALUE parse_error_offset)
83
+ {
84
+ VALUE obj = rb_class_new_instance(NIL_P(msg) ? 0 : 1, &msg, klass);
85
+ if (rb_obj_is_kind_of(obj, eOCIError)) {
86
+ rb_ivar_set(obj, oci8_id_at_code, code);
87
+ rb_ivar_set(obj, oci8_id_at_sql, sql);
88
+ rb_ivar_set(obj, oci8_id_at_parse_error_offset, parse_error_offset);
89
+ }
90
+ return obj;
91
+ }
92
+
78
93
  static VALUE oci8_make_exc(dvoid *errhp, sword status, ub4 type, OCIStmt *stmthp, const char *file, int line)
79
94
  {
80
95
  VALUE exc;
@@ -84,24 +99,19 @@ static VALUE oci8_make_exc(dvoid *errhp, sword status, ub4 type, OCIStmt *stmthp
84
99
  VALUE parse_error_offset = Qnil;
85
100
  VALUE sql = Qnil;
86
101
  int rv;
87
- VALUE args[4];
88
- int numarg = 1;
89
102
 
90
103
  switch (status) {
91
104
  case OCI_ERROR:
92
105
  exc = eOCIError;
93
106
  msg = get_error_msg(errhp, type, "Error", &errcode);
94
- numarg = 4;
95
107
  break;
96
108
  case OCI_SUCCESS_WITH_INFO:
97
109
  exc = eOCISuccessWithInfo;
98
110
  msg = get_error_msg(errhp, type, "Error", &errcode);
99
- numarg = 4;
100
111
  break;
101
112
  case OCI_NO_DATA:
102
113
  exc = eOCINoData;
103
114
  msg = get_error_msg(errhp, type, "No Data", &errcode);
104
- numarg = 4;
105
115
  break;
106
116
  case OCI_INVALID_HANDLE:
107
117
  exc = eOCIInvalidHandle;
@@ -138,11 +148,7 @@ static VALUE oci8_make_exc(dvoid *errhp, sword status, ub4 type, OCIStmt *stmthp
138
148
  sql = rb_external_str_new_with_enc(TO_CHARPTR(text), size, oci8_encoding);
139
149
  }
140
150
  }
141
- args[0] = msg;
142
- args[1] = INT2FIX(errcode);
143
- args[2] = sql;
144
- args[3] = parse_error_offset;
145
- exc = rb_class_new_instance(numarg, args, exc);
151
+ exc = oci_exception_new(exc, msg, INT2FIX(errcode), sql, parse_error_offset);
146
152
  return set_backtrace(exc, file, line);
147
153
  }
148
154
 
@@ -208,9 +214,13 @@ void oci8_do_raise(OCIError *errhp, sword status, OCIStmt *stmthp, const char *f
208
214
  rb_exc_raise(oci8_make_exc(errhp, status, OCI_HTYPE_ERROR, stmthp, file, line));
209
215
  }
210
216
 
211
- void oci8_do_env_raise(OCIEnv *envhp, sword status, const char *file, int line)
217
+ void oci8_do_env_raise(OCIEnv *envhp, sword status, int free_envhp, const char *file, int line)
212
218
  {
213
- rb_exc_raise(oci8_make_exc(envhp, status, OCI_HTYPE_ENV, NULL, file, line));
219
+ VALUE exc = oci8_make_exc(envhp, status, OCI_HTYPE_ENV, NULL, file, line);
220
+ if (free_envhp) {
221
+ OCIHandleFree(envhp, OCI_HTYPE_ENV);
222
+ }
223
+ rb_exc_raise(exc);
214
224
  }
215
225
 
216
226
  void oci8_do_raise_init_error(const char *file, int line)
@@ -255,11 +265,9 @@ VALUE oci8_get_error_message(ub4 msgno, const char *default_msg)
255
265
  void oci8_do_raise_by_msgno(ub4 msgno, const char *default_msg, const char *file, int line)
256
266
  {
257
267
  VALUE msg = oci8_get_error_message(msgno, default_msg);
258
- VALUE args[2];
259
- args[0] = msg;
260
- args[1] = INT2FIX(-1);
268
+ VALUE exc = oci_exception_new(eOCIError, msg, INT2FIX(-1), Qnil, Qnil);
261
269
 
262
- rb_exc_raise(set_backtrace(rb_class_new_instance(2, args, eOCIError), file, line));
270
+ rb_exc_raise(set_backtrace(exc, file, line));
263
271
  }
264
272
 
265
273
  void oci8_check_error_(sword status, oci8_base_t *base, OCIStmt *stmthp, const char *file, int line)
data/ext/oci8/extconf.rb CHANGED
@@ -72,7 +72,7 @@ $objs = ["oci8lib.o", "env.o", "error.o", "oci8.o", "ocihandle.o",
72
72
  "ocinumber.o", "ocidatetime.o", "object.o", "apiwrap.o",
73
73
  "encoding.o", "oranumber_util.o", "thread_util.o", "util.o"]
74
74
 
75
- if RUBY_PLATFORM =~ /mswin32|cygwin|mingw32|bccwin32/
75
+ if RUBY_PLATFORM =~ /mswin32|cygwin|mingw/
76
76
  $defs << "-DUSE_WIN32_C"
77
77
  $objs << "win32.o"
78
78
  end
@@ -139,6 +139,8 @@ when 'rbx'
139
139
  so_basename += 'rbx'
140
140
  when 'jruby'
141
141
  raise "Ruby-oci8 doesn't support jruby because its C extension support is in development in jruby 1.6 and deprecated in jruby 1.7."
142
+ when 'truffleruby'
143
+ so_basename += 'truffleruby'
142
144
  else
143
145
  raise 'unsupported ruby engine: ' + RUBY_ENGINE
144
146
  end
@@ -146,20 +148,22 @@ end
146
148
  print "checking for plthook... "
147
149
  STDOUT.flush
148
150
  case RUBY_PLATFORM
149
- when /mswin32|cygwin|mingw32|bccwin32/
151
+ when /mswin32|cygwin|mingw/
150
152
  plthook_src = "plthook_win32.c"
151
153
  when /darwin/
152
154
  plthook_src = "plthook_osx.c"
153
155
  else
154
156
  plthook_src = "plthook_elf.c"
155
157
  end
156
- if xsystem(cc_command("").gsub(CONFTEST_C, File.dirname(__FILE__) + "/" + plthook_src))
157
- File.delete(plthook_src.gsub(/\.c$/, '.' + RbConfig::CONFIG["OBJEXT"]))
158
+ FileUtils.copy(File.dirname(__FILE__) + "/" + plthook_src, CONFTEST_C)
159
+ if xsystem(cc_command(""))
160
+ FileUtils.rm_f("#{CONFTEST}.#{$OBJEXT}")
158
161
  puts plthook_src
159
162
  $objs << plthook_src.gsub(/\.c$/, '.o')
160
163
  $objs << "hook_funcs.o"
161
164
  $defs << "-DHAVE_PLTHOOK"
162
165
  have_library('dbghelp', 'ImageDirectoryEntryToData', ['windows.h', 'dbghelp.h']) if RUBY_PLATFORM =~ /cygwin/
166
+ $libs += ' -lws2_32' if RUBY_PLATFORM =~ /cygwin/
163
167
  else
164
168
  puts "no"
165
169
  end