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/object.c CHANGED
@@ -44,6 +44,8 @@ enum {
44
44
  ATTR_FLOAT,
45
45
  ATTR_INTEGER,
46
46
  ATTR_OCIDATE,
47
+ ATTR_TIMESTAMP,
48
+ ATTR_TIMESTAMP_TZ,
47
49
  ATTR_BINARY_DOUBLE,
48
50
  ATTR_BINARY_FLOAT,
49
51
  ATTR_NAMED_TYPE,
@@ -235,6 +237,10 @@ static VALUE get_attribute(VALUE self, VALUE datatype, VALUE typeinfo, void *dat
235
237
  return oci8_make_integer((OCINumber *)data, oci8_errhp);
236
238
  case ATTR_OCIDATE:
237
239
  return oci8_make_ocidate((OCIDate *)data);
240
+ case ATTR_TIMESTAMP:
241
+ return oci8_make_ocitimestamp(*(OCIDateTime**)data, FALSE);
242
+ case ATTR_TIMESTAMP_TZ:
243
+ return oci8_make_ocitimestamp(*(OCIDateTime**)data, TRUE);
238
244
  case ATTR_BINARY_DOUBLE:
239
245
  return rb_float_new(*(double*)data);
240
246
  case ATTR_BINARY_FLOAT:
@@ -413,6 +419,18 @@ static VALUE oci8_named_coll_set_coll_element(VALUE self, VALUE datatype, VALUE
413
419
  case ATTR_OCIDATE:
414
420
  cb_data.indp = &cb_data.ind;
415
421
  break;
422
+ case ATTR_TIMESTAMP:
423
+ chker2(OCIObjectNew(oci8_envhp, oci8_errhp, svcctx->hp.svc, OCI_TYPECODE_TIMESTAMP, NULL, NULL, OCI_DURATION_SESSION, TRUE, &cb_data.data.ptr),
424
+ svcctx);
425
+ chker2(OCIObjectGetInd(oci8_envhp, oci8_errhp, cb_data.data.ptr, (dvoid**)&cb_data.indp),
426
+ svcctx);
427
+ break;
428
+ case ATTR_TIMESTAMP_TZ:
429
+ chker2(OCIObjectNew(oci8_envhp, oci8_errhp, svcctx->hp.svc, OCI_TYPECODE_TIMESTAMP_TZ, NULL, NULL, OCI_DURATION_SESSION, TRUE, &cb_data.data.ptr),
430
+ svcctx);
431
+ chker2(OCIObjectGetInd(oci8_envhp, oci8_errhp, cb_data.data.ptr, (dvoid**)&cb_data.indp),
432
+ svcctx);
433
+ break;
416
434
  case ATTR_BINARY_DOUBLE:
417
435
  cb_data.data.dbl = 0.0;
418
436
  cb_data.indp = &cb_data.ind;
@@ -467,7 +485,7 @@ static VALUE set_coll_element_func(set_coll_element_cb_data_t *cb_data)
467
485
 
468
486
  chkerr(OCICollSize(oci8_envhp, oci8_errhp, coll, &size));
469
487
  if (RARRAY_LEN(val) < size) {
470
- chkerr(OCICollTrim(oci8_envhp, oci8_errhp, size - RARRAY_LEN(val), coll));
488
+ chkerr(OCICollTrim(oci8_envhp, oci8_errhp, (sb4)(size - RARRAY_LEN(val)), coll));
471
489
  }
472
490
  for (idx = 0; idx < RARRAY_LEN(val); idx++) {
473
491
  switch (FIX2INT(datatype)) {
@@ -507,6 +525,8 @@ static VALUE set_coll_element_ensure(set_coll_element_cb_data_t *cb_data)
507
525
  switch (FIX2INT(datatype)) {
508
526
  case ATTR_STRING:
509
527
  case ATTR_RAW:
528
+ case ATTR_TIMESTAMP:
529
+ case ATTR_TIMESTAMP_TZ:
510
530
  case ATTR_NAMED_TYPE:
511
531
  case ATTR_NAMED_COLLECTION:
512
532
  if (cb_data->data.ptr != NULL) {
@@ -539,13 +559,13 @@ static void set_attribute(VALUE self, VALUE datatype, VALUE typeinfo, void *data
539
559
  case ATTR_STRING:
540
560
  OCI8StringValue(val);
541
561
  chkerr(OCIStringAssignText(oci8_envhp, oci8_errhp,
542
- RSTRING_ORATEXT(val), RSTRING_LEN(val),
562
+ RSTRING_ORATEXT(val), RSTRING_LENINT(val),
543
563
  (OCIString **)data));
544
564
  break;
545
565
  case ATTR_RAW:
546
566
  StringValue(val);
547
567
  chkerr(OCIRawAssignBytes(oci8_envhp, oci8_errhp,
548
- RSTRING_ORATEXT(val), RSTRING_LEN(val),
568
+ RSTRING_ORATEXT(val), RSTRING_LENINT(val),
549
569
  (OCIRaw **)data));
550
570
  break;
551
571
  case ATTR_OCINUMBER:
@@ -558,6 +578,12 @@ static void set_attribute(VALUE self, VALUE datatype, VALUE typeinfo, void *data
558
578
  case ATTR_OCIDATE:
559
579
  oci8_set_ocidate((OCIDate*)data, val);
560
580
  break;
581
+ case ATTR_TIMESTAMP:
582
+ oci8_set_ocitimestamp_tz(*(OCIDateTime **)data, val, Qnil);
583
+ break;
584
+ case ATTR_TIMESTAMP_TZ:
585
+ oci8_set_ocitimestamp_tz(*(OCIDateTime **)data, val, Qnil);
586
+ break;
561
587
  case ATTR_BINARY_DOUBLE:
562
588
  *(double*)data = NUM2DBL(val);
563
589
  break;
@@ -654,45 +680,57 @@ static VALUE oci8_named_collection_alloc(VALUE klass)
654
680
  return oci8_allocate_typeddata(klass, &oci8_named_collection_data_type);
655
681
  }
656
682
 
683
+ typedef struct {
684
+ oci8_bind_t bind;
685
+ VALUE *obj;
686
+ } bind_named_type_t;
687
+
657
688
  static void bind_named_type_mark(oci8_base_t *base)
658
689
  {
659
- oci8_bind_t *obind = (oci8_bind_t *)base;
660
- oci8_hp_obj_t *oho = (oci8_hp_obj_t *)obind->valuep;
690
+ bind_named_type_t *bnt = (bind_named_type_t *)base;
661
691
 
662
- if (oho != NULL) {
692
+ if (bnt->obj != NULL) {
663
693
  ub4 idx = 0;
664
694
 
665
695
  do {
666
- rb_gc_mark(oho[idx].obj);
667
- } while (++idx < obind->maxar_sz);
696
+ rb_gc_mark(bnt->obj[idx]);
697
+ } while (++idx < bnt->bind.maxar_sz);
668
698
  }
669
- rb_gc_mark(obind->tdo);
699
+ rb_gc_mark(bnt->bind.tdo);
670
700
  }
671
701
 
672
702
  static void bind_named_type_free(oci8_base_t *base)
673
703
  {
674
- oci8_bind_t *obind = (oci8_bind_t *)base;
675
- oci8_hp_obj_t *oho = (oci8_hp_obj_t *)obind->valuep;
704
+ bind_named_type_t *bnt = (bind_named_type_t *)base;
705
+ void **hp = (void **)bnt->bind.valuep;
676
706
 
677
- if (oho != NULL) {
707
+ if (hp != NULL) {
678
708
  ub4 idx = 0;
679
709
 
680
710
  do {
681
- if (oho[idx].hp != NULL) {
682
- OCIObjectFree(oci8_envhp, oci8_errhp, oho[idx].hp, OCI_DEFAULT);
683
- oho[idx].hp = NULL;
711
+ if (hp[idx] != NULL) {
712
+ OCIObjectFree(oci8_envhp, oci8_errhp, hp[idx], OCI_DEFAULT);
713
+ hp[idx] = NULL;
684
714
  }
685
- } while (++idx < obind->maxar_sz);
715
+ } while (++idx < bnt->bind.maxar_sz);
716
+ }
717
+ if (bnt->obj != NULL) {
718
+ xfree(bnt->obj);
719
+ bnt->obj = NULL;
686
720
  }
687
721
  oci8_bind_free(base);
688
722
  }
689
723
 
690
724
  static VALUE bind_named_type_get(oci8_bind_t *obind, void *data, void *null_struct)
691
725
  {
692
- oci8_hp_obj_t *oho = (oci8_hp_obj_t *)data;
693
- return oho->obj;
726
+ bind_named_type_t *bnt = (bind_named_type_t *)obind;
727
+ ub4 idx = obind->curar_idx;
728
+
729
+ return bnt->obj[idx];
694
730
  }
695
731
 
732
+ NORETURN(static void bind_named_type_set(oci8_bind_t *obind, void *data, void **null_structp, VALUE val));
733
+
696
734
  static void bind_named_type_set(oci8_bind_t *obind, void *data, void **null_structp, VALUE val)
697
735
  {
698
736
  rb_raise(rb_eRuntimeError, "not supported");
@@ -700,10 +738,12 @@ static void bind_named_type_set(oci8_bind_t *obind, void *data, void **null_stru
700
738
 
701
739
  static void bind_named_type_init(oci8_bind_t *obind, VALUE svc, VALUE val, VALUE length)
702
740
  {
741
+ bind_named_type_t *bnt = (bind_named_type_t *)obind;
703
742
  VALUE tdo_obj = length;
704
743
 
705
744
  obind->value_sz = sizeof(void*);
706
- obind->alloc_sz = sizeof(oci8_hp_obj_t);
745
+ obind->alloc_sz = sizeof(void*);
746
+ bnt->obj = xcalloc(sizeof(VALUE), obind->maxar_sz ? obind->maxar_sz : 1);
707
747
 
708
748
  CHECK_TDO(tdo_obj);
709
749
  RB_OBJ_WRITE(obind->base.self, &obind->tdo, tdo_obj);
@@ -711,7 +751,8 @@ static void bind_named_type_init(oci8_bind_t *obind, VALUE svc, VALUE val, VALUE
711
751
 
712
752
  static void bind_named_type_init_elem(oci8_bind_t *obind, VALUE svc)
713
753
  {
714
- oci8_hp_obj_t *oho = (oci8_hp_obj_t *)obind->valuep;
754
+ bind_named_type_t *bnt = (bind_named_type_t *)obind;
755
+ void **hp = (void **)obind->valuep;
715
756
  oci8_base_t *tdo = DATA_PTR(obind->tdo);
716
757
  OCITypeCode tc = OCITypeTypeCode(oci8_envhp, oci8_errhp, tdo->hp.tdo);
717
758
  VALUE klass = Qnil;
@@ -729,14 +770,14 @@ static void bind_named_type_init_elem(oci8_bind_t *obind, VALUE svc)
729
770
  }
730
771
  svcctx = oci8_get_svcctx(svc);
731
772
  do {
732
- oho[idx].obj = rb_class_new_instance(0, NULL, klass);
733
- RB_OBJ_WRITTEN(obind->base.self, Qundef, oho[idx].obj);
734
- obj = DATA_PTR(oho[idx].obj);
735
- RB_OBJ_WRITE(oho[idx].obj, &obj->tdo, obind->tdo);
736
- obj->instancep = (char**)&oho[idx].hp;
773
+ bnt->obj[idx] = rb_class_new_instance(0, NULL, klass);
774
+ RB_OBJ_WRITTEN(obind->base.self, Qundef, bnt->obj[idx]);
775
+ obj = DATA_PTR(bnt->obj[idx]);
776
+ RB_OBJ_WRITE(bnt->obj[idx], &obj->tdo, obind->tdo);
777
+ obj->instancep = (char**)&hp[idx];
737
778
  obj->null_structp = (char**)&obind->u.null_structs[idx];
738
779
  oci8_link_to_parent(&obj->base, &obind->base);
739
- RB_OBJ_WRITTEN(oho[idx].obj, Qundef, obind->base.self);
780
+ RB_OBJ_WRITTEN(bnt->obj[idx], Qundef, obind->base.self);
740
781
 
741
782
  chker2(OCIObjectNew(oci8_envhp, oci8_errhp, svcctx->base.hp.svc, tc, tdo->hp.tdo, NULL, OCI_DURATION_SESSION, TRUE, (dvoid**)obj->instancep),
742
783
  &svcctx->base);
@@ -778,7 +819,7 @@ static const oci8_bind_data_type_t bind_named_type_data_type = {
778
819
  #endif
779
820
  },
780
821
  bind_named_type_free,
781
- sizeof(oci8_bind_t)
822
+ sizeof(bind_named_type_t)
782
823
  },
783
824
  bind_named_type_get,
784
825
  bind_named_type_set,
@@ -818,6 +859,10 @@ void Init_oci_object(VALUE cOCI8)
818
859
  /* @private */
819
860
  rb_define_const(cOCI8TDO, "ATTR_OCIDATE", INT2FIX(ATTR_OCIDATE));
820
861
  /* @private */
862
+ rb_define_const(cOCI8TDO, "ATTR_TIMESTAMP", INT2FIX(ATTR_TIMESTAMP));
863
+ /* @private */
864
+ rb_define_const(cOCI8TDO, "ATTR_TIMESTAMP_TZ", INT2FIX(ATTR_TIMESTAMP_TZ));
865
+ /* @private */
821
866
  rb_define_const(cOCI8TDO, "ATTR_BINARY_DOUBLE", INT2FIX(ATTR_BINARY_DOUBLE));
822
867
  /* @private */
823
868
  rb_define_const(cOCI8TDO, "ATTR_BINARY_FLOAT", INT2FIX(ATTR_BINARY_FLOAT));
data/ext/oci8/oci8.c CHANGED
@@ -2,7 +2,7 @@
2
2
  /*
3
3
  * oci8.c - part of ruby-oci8
4
4
  *
5
- * Copyright (C) 2002-2015 Kubo Takehiro <kubo@jiubao.org>
5
+ * Copyright (C) 2002-2019 Kubo Takehiro <kubo@jiubao.org>
6
6
  *
7
7
  */
8
8
  #include "oci8.h"
@@ -424,49 +424,6 @@ static VALUE oci8_parse_connect_string(VALUE self, VALUE conn_str)
424
424
  return rb_ary_new3(4, user, pass, dbname, mode);
425
425
  }
426
426
 
427
- /*
428
- * Logoff strategy for sessions connected by OCILogon.
429
- */
430
- typedef struct {
431
- OCISvcCtx *svchp;
432
- OCISession *usrhp;
433
- OCIServer *srvhp;
434
- } simple_logoff_arg_t;
435
-
436
- static void *simple_logoff_prepare(oci8_svcctx_t *svcctx)
437
- {
438
- simple_logoff_arg_t *sla = xmalloc(sizeof(simple_logoff_arg_t));
439
- sla->svchp = svcctx->base.hp.svc;
440
- sla->usrhp = svcctx->usrhp;
441
- sla->srvhp = svcctx->srvhp;
442
- svcctx->usrhp = NULL;
443
- svcctx->srvhp = NULL;
444
- return sla;
445
- }
446
-
447
- static void *simple_logoff_execute(void *arg)
448
- {
449
- simple_logoff_arg_t *sla = (simple_logoff_arg_t *)arg;
450
- OCIError *errhp = oci8_errhp;
451
- boolean txn = TRUE;
452
- sword rv;
453
-
454
- if (oracle_client_version >= ORAVER_12_1) {
455
- OCIAttrGet(sla->usrhp, OCI_HTYPE_SESSION, &txn, NULL, OCI_ATTR_TRANSACTION_IN_PROGRESS, errhp);
456
- }
457
- if (txn) {
458
- OCITransRollback(sla->svchp, errhp, OCI_DEFAULT);
459
- }
460
- rv = OCILogoff(sla->svchp, errhp);
461
- xfree(sla);
462
- return (void*)(VALUE)rv;
463
- }
464
-
465
- static const oci8_logoff_strategy_t simple_logoff = {
466
- simple_logoff_prepare,
467
- simple_logoff_execute,
468
- };
469
-
470
427
  /*
471
428
  * Logoff strategy for sessions connected by OCIServerAttach and OCISessionBegin.
472
429
  */
@@ -531,61 +488,6 @@ static const oci8_logoff_strategy_t complex_logoff = {
531
488
  complex_logoff_execute,
532
489
  };
533
490
 
534
- /*
535
- * @overload logon2(username, password, dbname, mode)
536
- *
537
- * Creates a simple logon session by the OCI function OCILogon2().
538
- *
539
- * @param [String] username
540
- * @param [String] password
541
- * @param [String] dbname
542
- * @param [Integer] mode
543
- * @private
544
- */
545
- static VALUE oci8_logon2(VALUE self, VALUE username, VALUE password, VALUE dbname, VALUE mode)
546
- {
547
- oci8_svcctx_t *svcctx = oci8_get_svcctx(self);
548
- ub4 logon2_mode;
549
-
550
- if (svcctx->logoff_strategy != NULL) {
551
- rb_raise(rb_eRuntimeError, "Could not reuse the session.");
552
- }
553
-
554
- /* check arugmnets */
555
- OCI8SafeStringValue(username);
556
- OCI8SafeStringValue(password);
557
- if (!NIL_P(dbname)) {
558
- OCI8SafeStringValue(dbname);
559
- }
560
- logon2_mode = NUM2UINT(mode);
561
-
562
- /* logon */
563
- svcctx->base.type = OCI_HTYPE_SVCCTX;
564
- chker2(OCILogon2_nb(svcctx, oci8_envhp, oci8_errhp, &svcctx->base.hp.svc,
565
- RSTRING_ORATEXT(username), RSTRING_LEN(username),
566
- RSTRING_ORATEXT(password), RSTRING_LEN(password),
567
- NIL_P(dbname) ? NULL : RSTRING_ORATEXT(dbname),
568
- NIL_P(dbname) ? 0 : RSTRING_LEN(dbname), logon2_mode),
569
- &svcctx->base);
570
- svcctx->logoff_strategy = &simple_logoff;
571
-
572
- if (logon2_mode & OCI_LOGON2_CPOOL) {
573
- svcctx->state |= OCI8_STATE_CPOOL;
574
- }
575
-
576
- /* setup the session handle */
577
- chker2(OCIAttrGet(svcctx->base.hp.ptr, OCI_HTYPE_SVCCTX, &svcctx->usrhp, 0, OCI_ATTR_SESSION, oci8_errhp),
578
- &svcctx->base);
579
- copy_session_handle(svcctx);
580
-
581
- /* setup the server handle */
582
- chker2(OCIAttrGet(svcctx->base.hp.ptr, OCI_HTYPE_SVCCTX, &svcctx->srvhp, 0, OCI_ATTR_SERVER, oci8_errhp),
583
- &svcctx->base);
584
- copy_server_handle(svcctx);
585
-
586
- return Qnil;
587
- }
588
-
589
491
  /*
590
492
  * @overload allocate_handles()
591
493
  *
@@ -654,7 +556,7 @@ static VALUE oci8_server_attach(VALUE self, VALUE dbname, VALUE attach_mode)
654
556
  /* attach to the server */
655
557
  chker2(OCIServerAttach_nb(svcctx, svcctx->srvhp, oci8_errhp,
656
558
  NIL_P(dbname) ? NULL : RSTRING_ORATEXT(dbname),
657
- NIL_P(dbname) ? 0 : RSTRING_LEN(dbname),
559
+ NIL_P(dbname) ? 0 : RSTRING_LENINT(dbname),
658
560
  mode),
659
561
  &svcctx->base);
660
562
  chker2(OCIAttrSet(svcctx->base.hp.ptr, OCI_HTYPE_SVCCTX,
@@ -680,6 +582,8 @@ static VALUE oci8_server_attach(VALUE self, VALUE dbname, VALUE attach_mode)
680
582
  static VALUE oci8_session_begin(VALUE self, VALUE cred, VALUE mode)
681
583
  {
682
584
  oci8_svcctx_t *svcctx = oci8_get_svcctx(self);
585
+ char buf[100];
586
+ ub4 version;
683
587
 
684
588
  if (svcctx->logoff_strategy != &complex_logoff) {
685
589
  rb_raise(rb_eRuntimeError, "Use this method only for the service context handle created by OCI8#server_handle().");
@@ -702,6 +606,16 @@ static VALUE oci8_session_begin(VALUE self, VALUE cred, VALUE mode)
702
606
  oci8_errhp),
703
607
  &svcctx->base);
704
608
  svcctx->state |= OCI8_STATE_SESSION_BEGIN_WAS_CALLED;
609
+ if (have_OCIServerRelease2) {
610
+ chker2(OCIServerRelease2(svcctx->base.hp.ptr, oci8_errhp, (text*)buf,
611
+ sizeof(buf), (ub1)svcctx->base.type, &version, OCI_DEFAULT),
612
+ &svcctx->base);
613
+ } else {
614
+ chker2(OCIServerRelease(svcctx->base.hp.ptr, oci8_errhp, (text*)buf,
615
+ sizeof(buf), (ub1)svcctx->base.type, &version),
616
+ &svcctx->base);
617
+ }
618
+ svcctx->server_version = version;
705
619
  return Qnil;
706
620
  }
707
621
 
@@ -820,14 +734,9 @@ static VALUE oci8_set_autocommit(VALUE self, VALUE val)
820
734
  /*
821
735
  * @overload long_read_len
822
736
  *
823
- * Gets the maximum length in bytes to fetch a LONG or LONG RAW
824
- * column. The default value is 65535.
825
- *
826
- * If the actual data length is longer than long_read_len,
827
- * the fetched valud is truncated and the value of {OCI8#last_error}
828
- * become {OCISuccessWithInfo} whose message is "ORA-01406: fetched column value was truncated".
829
- *
830
- * Note: long_read_len is also used for maximum length of XMLTYPE data type.
737
+ * @deprecated This has no effect since ruby-oci8 2.2.7.
738
+ * LONG, LONG RAW and XMLTYPE columns are fetched up to 4 gigabytes
739
+ * without this parameter.
831
740
  *
832
741
  * @return [Integer]
833
742
  * @see #long_read_len=
@@ -835,14 +744,16 @@ static VALUE oci8_set_autocommit(VALUE self, VALUE val)
835
744
  static VALUE oci8_long_read_len(VALUE self)
836
745
  {
837
746
  oci8_svcctx_t *svcctx = oci8_get_svcctx(self);
747
+ rb_warning("OCI8.long_read_len has no effect since ruby-oci8 2.2.7");
838
748
  return svcctx->long_read_len;
839
749
  }
840
750
 
841
751
  /*
842
752
  * @overload long_read_len=(length)
843
753
  *
844
- * Sets the maximum length in bytes to fetch a LONG or LONG RAW
845
- * column.
754
+ * @deprecated This has no effect since ruby-oci8 2.2.7.
755
+ * LONG, LONG RAW and XMLTYPE columns are fetched up to 4 gigabytes
756
+ * without this parameter.
846
757
  *
847
758
  * @param [Integer] length
848
759
  * @see #long_read_len
@@ -852,6 +763,7 @@ static VALUE oci8_set_long_read_len(VALUE self, VALUE val)
852
763
  oci8_svcctx_t *svcctx = oci8_get_svcctx(self);
853
764
  Check_Type(val, T_FIXNUM);
854
765
  RB_OBJ_WRITE(self, &svcctx->long_read_len, val);
766
+ rb_warning("OCI8.long_read_len= has no effect since ruby-oci8 2.2.7");
855
767
  return val;
856
768
  }
857
769
 
@@ -894,11 +806,8 @@ static VALUE oci8_break(VALUE self)
894
806
  static VALUE oci8_oracle_server_vernum(VALUE self)
895
807
  {
896
808
  oci8_svcctx_t *svcctx = oci8_get_svcctx(self);
897
- char buf[100];
898
- ub4 version;
899
809
 
900
- chker2(OCIServerRelease(svcctx->base.hp.ptr, oci8_errhp, (text*)buf, sizeof(buf), (ub1)svcctx->base.type, &version), &svcctx->base);
901
- return UINT2NUM(version);
810
+ return UINT2NUM(svcctx->server_version);
902
811
  }
903
812
 
904
813
  /*
@@ -955,7 +864,7 @@ static VALUE oci8_set_client_identifier(VALUE self, VALUE val)
955
864
  if (!NIL_P(val)) {
956
865
  OCI8SafeStringValue(val);
957
866
  ptr = RSTRING_PTR(val);
958
- size = RSTRING_LEN(val);
867
+ size = RSTRING_LENINT(val);
959
868
  } else {
960
869
  ptr = "";
961
870
  size = 0;
@@ -990,7 +899,7 @@ static VALUE oci8_set_module(VALUE self, VALUE val)
990
899
  if (!NIL_P(val)) {
991
900
  OCI8SafeStringValue(val);
992
901
  ptr = RSTRING_PTR(val);
993
- size = RSTRING_LEN(val);
902
+ size = RSTRING_LENINT(val);
994
903
  } else {
995
904
  ptr = "";
996
905
  size = 0;
@@ -1024,7 +933,7 @@ static VALUE oci8_set_action(VALUE self, VALUE val)
1024
933
  if (!NIL_P(val)) {
1025
934
  OCI8SafeStringValue(val);
1026
935
  ptr = RSTRING_PTR(val);
1027
- size = RSTRING_LEN(val);
936
+ size = RSTRING_LENINT(val);
1028
937
  } else {
1029
938
  ptr = "";
1030
939
  size = 0;
@@ -1055,7 +964,7 @@ static VALUE oci8_set_client_info(VALUE self, VALUE val)
1055
964
  if (!NIL_P(val)) {
1056
965
  OCI8SafeStringValue(val);
1057
966
  ptr = RSTRING_PTR(val);
1058
- size = RSTRING_LEN(val);
967
+ size = RSTRING_LENINT(val);
1059
968
  } else {
1060
969
  ptr = "";
1061
970
  size = 0;
@@ -1107,7 +1016,6 @@ void Init_oci8(VALUE *out)
1107
1016
  rb_define_singleton_method_nodoc(cOCI8, "__set_prop", oci8_s_set_prop, 2);
1108
1017
  rb_define_singleton_method(cOCI8, "error_message", oci8_s_error_message, 1);
1109
1018
  rb_define_private_method(cOCI8, "parse_connect_string", oci8_parse_connect_string, 1);
1110
- rb_define_private_method(cOCI8, "logon2", oci8_logon2, 4);
1111
1019
  rb_define_private_method(cOCI8, "allocate_handles", oci8_allocate_handles, 0);
1112
1020
  rb_define_private_method(cOCI8, "server_attach", oci8_server_attach, 2);
1113
1021
  rb_define_private_method(cOCI8, "session_begin", oci8_session_begin, 2);
data/ext/oci8/oci8.h CHANGED
@@ -21,8 +21,23 @@ extern "C"
21
21
  }
22
22
  #endif
23
23
 
24
+ /*
25
+ * Oracle version number format in 32-bit integer.
26
+ *
27
+ * Oracle 12c or earier Oracle 18c or later
28
+ *
29
+ * hexadecimal -> dotted version number hexadecimal -> dotted version number
30
+ * 0c102304 -> 12.1.2.3.4 12012034 -> 18.1.2.3.4
31
+ * ^ ^ ^ ^ ^ ^ ^ ^ ^ ^
32
+ * 0c ------------' | | | | 2 bytes 12 ------------' | | | | 2 bytes
33
+ * 1 --------------' | | | 1 byte 01 -------------' | | | 2 bytes
34
+ * 02 --------------' | | 2 bytes 2 --------------' | | 1 byte
35
+ * 3 ---------------' | 1 byte 03 --------------' | 2 bytes
36
+ * 04 ---------------' 2 bytes 4 ---------------' 1 byte
37
+ */
24
38
  #define ORAVERNUM(major, minor, update, patch, port_update) \
25
- (((major) << 24) | ((minor) << 20) | ((update) << 12) | ((patch) << 8) | (port_update))
39
+ (((major) >= 18) ? (((major) << 24) | ((minor) << 16) | ((update) << 12) | ((patch) << 4) | (port_update)) \
40
+ : (((major) << 24) | ((minor) << 20) | ((update) << 12) | ((patch) << 8) | (port_update)))
26
41
 
27
42
  #define ORAVER_8_0 ORAVERNUM(8, 0, 0, 0, 0)
28
43
  #define ORAVER_8_1 ORAVERNUM(8, 1, 0, 0, 0)
@@ -32,6 +47,7 @@ extern "C"
32
47
  #define ORAVER_10_2 ORAVERNUM(10, 2, 0, 0, 0)
33
48
  #define ORAVER_11_1 ORAVERNUM(11, 1, 0, 0, 0)
34
49
  #define ORAVER_12_1 ORAVERNUM(12, 1, 0, 0, 0)
50
+ #define ORAVER_18 ORAVERNUM(18, 0, 0, 0, 0)
35
51
 
36
52
  #include "extconf.h"
37
53
  #include <ruby/encoding.h>
@@ -316,6 +332,7 @@ typedef struct oci8_svcctx {
316
332
  const oci8_logoff_strategy_t *logoff_strategy;
317
333
  OCISession *usrhp;
318
334
  OCIServer *srvhp;
335
+ ub4 server_version;
319
336
  rb_pid_t pid;
320
337
  unsigned char state;
321
338
  char is_autocommit;
@@ -407,6 +424,7 @@ void *oci8_check_typeddata(VALUE obj, const oci8_handle_data_type_t *data_type,
407
424
  extern VALUE eOCIException;
408
425
  extern VALUE eOCIBreak;
409
426
  void Init_oci8_error(void);
427
+ NORETURN(void oci8_do_raise(OCIError *errhp, sword status, OCIStmt *stmthp, const char *file, int line));
410
428
  NORETURN(void oci8_do_env_raise(OCIEnv *envhp, sword status, int free_envhp, const char *file, int line));
411
429
  NORETURN(void oci8_do_raise_init_error(const char *file, int line));
412
430
  sb4 oci8_get_error_code(OCIError *errhp);
@@ -489,8 +507,8 @@ OCINumber *oci8_dbl_to_onum(OCINumber *result, double dbl, OCIError *errhp);
489
507
  void Init_oci_datetime(void);
490
508
  VALUE oci8_make_ocidate(OCIDate *od);
491
509
  OCIDate *oci8_set_ocidate(OCIDate *od, VALUE val);
492
- VALUE oci8_make_ocidatetime(OCIDateTime *dttm);
493
- OCIDateTime *oci8_set_ocidatetime(OCIDateTime *dttm, VALUE val);
510
+ VALUE oci8_make_ocitimestamp(OCIDateTime *dttm, boolean have_tz);
511
+ OCIDateTime *oci8_set_ocitimestamp_tz(OCIDateTime *dttm, VALUE val, VALUE svc);
494
512
  VALUE oci8_make_interval_ym(OCIInterval *s);
495
513
  VALUE oci8_make_interval_ds(OCIInterval *s);
496
514