ruby-oci8 2.2.3 → 2.2.12

Sign up to get free protection for your applications and to get access to all the features.
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