ruby-oci8 2.2.4.1 → 2.2.11

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