ruby-oci8 2.0.0 → 2.0.1

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.
data/ChangeLog CHANGED
@@ -1,3 +1,45 @@
1
+ 2009-03-17 KUBO Takehiro <kubo@jiubao.org>
2
+ * NEWS: add a new file.
3
+ * VERSION: change version to 2.0.1.
4
+ * Makefile: add targets to make a binary gem for Windows.
5
+ * dist-files: add NEWS
6
+ * ext/oci8/extconf.rb, lib/oci8.rb.in: rename oci8lib.so
7
+ to oci8lib_18.so and oci8lib_191.so. The renamed name
8
+ depends on the ruby version.
9
+ * lib/oci8/datetime.rb: fix the fetched type for date column
10
+ when using Oracle 8.x.
11
+ * ruby-oci8.gemspec: fix to make a binary gem which contains
12
+ both oci8lib_18.so and oci8lib_191.so.
13
+
14
+ 2009-03-17 KUBO Takehiro <kubo@jiubao.org>
15
+ * ext/oci8/apiwrap.yml: add prototypes for OCIServerVersion() and
16
+ OCIServerRelease().
17
+ * ext/oci8/oci8.c: (1) add a private method OCI8#oracle_server_vernum,
18
+ which returns Oracle server version number.
19
+ (2) fix a class method OCI8.oracle_client_vernum when using Oracle
20
+ client 10.1 or lower.
21
+ * lib/oci8/datetime.rb: fix year information when fetching a date
22
+ whose year is between A.D. 1 and A.D. 139.
23
+ * lib/oci8/oci8.rb: (1) add OCI8#oracle_server_version.
24
+ * (2) change the default data type for timestamp with time zone
25
+ from DateTime to Time.
26
+
27
+ 2009-03-11 KUBO Takehiro <kubo@jiubao.org>
28
+ * oraconf.rb: fix big/little endian checking problem on Mac OS X ppc.
29
+ (contributed by unknown. See: Bug ID 24284 on rubyforge.)
30
+
31
+ 2009-02-15 KUBO Takehiro <kubo@jiubao.org>
32
+ * ext/oci8/ocidatetime.c: fix array DML and DateTime object problem.
33
+ OCI8::Cursor#bind_param_array(key, array_of_datetime) didn't
34
+ work. (Reported by Leoš Bitto)
35
+ * test/test_array_dml.rb: fix to test array DML and DateTime object.
36
+
37
+ 2009-02-10 KUBO Takehiro <kubo@jiubao.org>
38
+ * ext/oci8/bind.c, ext/oci8/oci8.h, ext/oci8/stmt.c: fix array DML
39
+ and DateTime object problem. It didn't work with bind classes
40
+ which overwrite 'set' and 'get'. (Reported by Leoš Bitto)
41
+ * test/test_array_dml.rb: fix to test array DML and DateTime object.
42
+
1
43
  2009-02-08 KUBO Takehiro <kubo@jiubao.org>
2
44
  * VERSION: change version from 2.0-svn to 2.0.0 to pass ruby
3
45
  gem's version string validator.
data/Makefile CHANGED
@@ -46,3 +46,42 @@ dist-check: dist
46
46
  cd ruby-oci8-$(VERSION) && $(MAKE) RUBY="$(RUBY)" check
47
47
  cd ruby-oci8-$(VERSION)/src && $(MAKE) RUBY="$(RUBY)" sitearchdir=../work sitelibdir=../work site-install
48
48
  cd ruby-oci8-$(VERSION)/test && $(RUBY) -I../work -I../support test_all.rb
49
+
50
+ #
51
+ # for Windows
52
+ #
53
+ GEMPKG = ruby-oci8-unstable-2.0.1-x86-mswin32-60.gem
54
+
55
+ ext\oci8\oci8lib_18.so:
56
+ c:\ruby\bin\ruby -r fileutils -e "FileUtils.rm_rf('ruby18')"
57
+ md ruby18
58
+ cd ruby18
59
+ c:\ruby\bin\ruby ..\setup.rb config -- --with-runtime-check
60
+ c:\ruby\bin\ruby ..\setup.rb setup
61
+ rem c:\ruby\bin\ruby ..\setup.rb test
62
+ cd ..
63
+ copy ruby18\ext\oci8\oci8lib_18.so ext\oci8\oci8lib_18.so
64
+
65
+ ext\oci8\oci8lib_191.so:
66
+ c:\ruby\bin\ruby -r fileutils -e "FileUtils.rm_rf('ruby191')"
67
+ md ruby191
68
+ cd ruby191
69
+ c:\ruby-1.9.1\bin\ruby ..\setup.rb config -- --with-runtime-check
70
+ c:\ruby-1.9.1\bin\ruby ..\setup.rb setup
71
+ rem c:\ruby-1.9.1\bin\ruby ..\setup.rb test
72
+ cd ..
73
+ copy ruby191\ext\oci8\oci8lib_191.so ext\oci8\oci8lib_191.so
74
+ copy ruby191\lib\oci8.rb lib\oci8.rb
75
+
76
+ $(GEMPKG): ext\oci8\oci8lib_18.so ext\oci8\oci8lib_191.so ruby-oci8.gemspec
77
+ c:\ruby-1.9.1\bin\gem build ruby-oci8.gemspec -- current
78
+
79
+ test-win32-ruby18: $(GEMPKG)
80
+ c:\ruby\bin\gem install $(GEMPKG) --no-rdoc --no-ri
81
+ c:\ruby\bin\ruby -rubygems test\test_all.rb
82
+
83
+ test-win32-ruby191: $(GEMPKG)
84
+ c:\ruby-1.9.1\bin\gem install $(GEMPKG) --no-rdoc --no-ri
85
+ c:\ruby-1.9.1\bin\ruby test\test_all.rb
86
+
87
+ test-win32: test-win32-ruby18 test-win32-ruby191
data/NEWS ADDED
@@ -0,0 +1,6 @@
1
+ 2.0.1:
2
+
3
+ * release a binary gem for Windows, which contains libraries for both
4
+ ruby 1.8 and ruby 1.9.1.
5
+ * add OCI8#oracle_server_version.
6
+ * fix bugs when fetching and binding time objects.
data/VERSION CHANGED
@@ -1 +1 @@
1
- 2.0.0
1
+ 2.0.1
data/dist-files CHANGED
@@ -1,5 +1,6 @@
1
1
  ChangeLog
2
2
  Makefile
3
+ NEWS
3
4
  README
4
5
  VERSION
5
6
  dist-files
@@ -773,6 +773,15 @@ OCIServerDetach_nb:
773
773
  - OCIError *errhp
774
774
  - ub4 mode
775
775
 
776
+ # round trip: ?
777
+ OCIServerVersion:
778
+ :version: 800
779
+ :args: - dvoid *hndlp
780
+ - OCIError *errhp
781
+ - OraText *bufp
782
+ - ub4 bufsz
783
+ - ub1 hndltype
784
+
776
785
  # round trip: 1
777
786
  OCIStmtExecute_nb:
778
787
  :version: 800
@@ -1114,6 +1123,17 @@ OCIRowidToChar:
1114
1123
  - ub2 *outbflp
1115
1124
  - OCIError *errhp
1116
1125
 
1126
+ # An undocumented function from Oracle 9i to Oracle 10g.
1127
+ # This is documented in Oracle 11g.
1128
+ OCIServerRelease:
1129
+ :version: 900
1130
+ :args: - dvoid *hndlp
1131
+ - OCIError *errhp
1132
+ - OraText *bufp
1133
+ - ub4 bufsz
1134
+ - ub1 hndltype
1135
+ - ub4 *version
1136
+
1117
1137
  #
1118
1138
  # Oracle 9.2
1119
1139
  #
@@ -3,14 +3,13 @@
3
3
  * bind.c
4
4
  *
5
5
  * $Author: kubo $
6
- * $Date: 2009-01-12 00:11:09 +0900 (Mon, 12 Jan 2009) $
6
+ * $Date: 2009-02-10 22:50:40 +0900 (Tue, 10 Feb 2009) $
7
7
  *
8
8
  * Copyright (C) 2002-2008 KUBO Takehiro <kubo@jiubao.org>
9
9
  */
10
10
  #include "oci8.h"
11
11
 
12
12
  static ID id_bind_type;
13
- static ID id_set;
14
13
 
15
14
  static VALUE cOCI8BindTypeBase;
16
15
 
@@ -330,8 +329,11 @@ static const oci8_bind_class_t bind_binary_double_class = {
330
329
  SQLT_BDOUBLE
331
330
  };
332
331
 
333
- static inline VALUE oci8_get_data_at(const oci8_bind_class_t *obc, oci8_bind_t *obind, ub4 idx)
332
+ static VALUE oci8_bind_get(VALUE self)
334
333
  {
334
+ oci8_bind_t *obind = DATA_PTR(self);
335
+ const oci8_bind_class_t *obc = (const oci8_bind_class_t *)obind->base.klass;
336
+ ub4 idx = obind->curar_idx;
335
337
  void **null_structp = NULL;
336
338
 
337
339
  if (NIL_P(obind->tdo)) {
@@ -345,26 +347,30 @@ static inline VALUE oci8_get_data_at(const oci8_bind_class_t *obc, oci8_bind_t *
345
347
  return obc->get(obind, (void*)((size_t)obind->valuep + obind->alloc_sz * idx), null_structp);
346
348
  }
347
349
 
348
- static VALUE oci8_get_data(VALUE self)
350
+ VALUE oci8_bind_get_data(VALUE self)
349
351
  {
350
352
  oci8_bind_t *obind = DATA_PTR(self);
351
- const oci8_bind_class_t *obc = (const oci8_bind_class_t *)obind->base.klass;
352
353
 
353
354
  if (obind->maxar_sz == 0) {
354
- return oci8_get_data_at(obc, obind, 0);
355
+ obind->curar_idx = 0;
356
+ return rb_funcall(self, oci8_id_get, 0);
355
357
  } else {
356
358
  volatile VALUE ary = rb_ary_new2(obind->curar_sz);
357
359
  ub4 idx;
358
360
 
359
361
  for (idx = 0; idx < obind->curar_sz; idx++) {
360
- rb_ary_store(ary, idx, oci8_get_data_at(obc, obind, idx));
362
+ obind->curar_idx = idx;
363
+ rb_ary_store(ary, idx, rb_funcall(self, oci8_id_get, 0));
361
364
  }
362
365
  return ary;
363
366
  }
364
367
  }
365
368
 
366
- static inline void oci8_set_data_at(const oci8_bind_class_t *obc, oci8_bind_t *obind, ub4 idx, VALUE val)
369
+ static VALUE oci8_bind_set(VALUE self, VALUE val)
367
370
  {
371
+ oci8_bind_t *obind = DATA_PTR(self);
372
+ const oci8_bind_class_t *obc = (const oci8_bind_class_t *)obind->base.klass;
373
+ ub4 idx = obind->curar_idx;
368
374
 
369
375
  if (NIL_P(val)) {
370
376
  if (NIL_P(obind->tdo)) {
@@ -383,15 +389,16 @@ static inline void oci8_set_data_at(const oci8_bind_class_t *obc, oci8_bind_t *o
383
389
  }
384
390
  obc->set(obind, (void*)((size_t)obind->valuep + obind->alloc_sz * idx), null_structp, val);
385
391
  }
392
+ return self;
386
393
  }
387
394
 
388
- static VALUE oci8_set_data(VALUE self, VALUE val)
395
+ void oci8_bind_set_data(VALUE self, VALUE val)
389
396
  {
390
397
  oci8_bind_t *obind = DATA_PTR(self);
391
- const oci8_bind_class_t *obc = (const oci8_bind_class_t *)obind->base.klass;
392
398
 
393
399
  if (obind->maxar_sz == 0) {
394
- oci8_set_data_at(obc, obind, 0, val);
400
+ obind->curar_idx = 0;
401
+ rb_funcall(self, oci8_id_set, 1, val);
395
402
  } else {
396
403
  ub4 size;
397
404
  ub4 idx;
@@ -402,11 +409,11 @@ static VALUE oci8_set_data(VALUE self, VALUE val)
402
409
  rb_raise(rb_eRuntimeError, "over the max array size");
403
410
  }
404
411
  for (idx = 0; idx < size; idx++) {
405
- oci8_set_data_at(obc, obind, idx, RARRAY_PTR(val)[idx]);
412
+ obind->curar_idx = idx;
413
+ rb_funcall(self, oci8_id_set, 1, RARRAY_PTR(val)[idx]);
406
414
  }
407
415
  obind->curar_sz = size;
408
416
  }
409
- return self;
410
417
  }
411
418
 
412
419
  static VALUE oci8_bind_initialize(VALUE self, VALUE svc, VALUE val, VALUE length, VALUE max_array_size)
@@ -438,7 +445,7 @@ static VALUE oci8_bind_initialize(VALUE self, VALUE svc, VALUE val, VALUE length
438
445
  bind_class->init_elem(obind, svc);
439
446
  }
440
447
  if (!NIL_P(val)) {
441
- rb_funcall(self, id_set, 1, val);
448
+ oci8_bind_set_data(self, val);
442
449
  }
443
450
  return Qnil;
444
451
  }
@@ -474,11 +481,10 @@ void Init_oci8_bind(VALUE klass)
474
481
  {
475
482
  cOCI8BindTypeBase = klass;
476
483
  id_bind_type = rb_intern("bind_type");
477
- id_set = rb_intern("set");
478
484
 
479
485
  rb_define_method(cOCI8BindTypeBase, "initialize", oci8_bind_initialize, 4);
480
- rb_define_method(cOCI8BindTypeBase, "get", oci8_get_data, 0);
481
- rb_define_method(cOCI8BindTypeBase, "set", oci8_set_data, 1);
486
+ rb_define_method(cOCI8BindTypeBase, "get", oci8_bind_get, 0);
487
+ rb_define_method(cOCI8BindTypeBase, "set", oci8_bind_set, 1);
482
488
 
483
489
  /* register primitive data types. */
484
490
  oci8_define_bind_class("String", &bind_string_class);
@@ -113,6 +113,16 @@ replace = {
113
113
  # make ruby script before running create_makefile.
114
114
  replace_keyword(File.dirname(__FILE__) + '/../../lib/oci8.rb.in', '../../lib/oci8.rb', replace)
115
115
 
116
+ case RUBY_VERSION
117
+ when /^1\.9\.1/
118
+ so_basename = "oci8lib_191"
119
+ when /^1\.8/
120
+ so_basename = "oci8lib_18"
121
+ else
122
+ raise 'unsupported ruby version: ' + RUBY_VERSION
123
+ end
124
+ $defs << "-DInit_oci8lib=Init_#{so_basename}"
125
+
116
126
  create_header()
117
127
 
118
128
  # make dependency file
@@ -140,6 +150,6 @@ end
140
150
 
141
151
  create_apiwrap()
142
152
 
143
- create_makefile("oci8lib")
153
+ create_makefile(so_basename)
144
154
 
145
155
  exit 0
@@ -524,11 +524,43 @@ static VALUE oci8_set_prefetch_rows(VALUE self, VALUE val)
524
524
  return val;
525
525
  }
526
526
 
527
+ /*
528
+ * call-seq:
529
+ * oracle_server_vernum -> Oracle server version number
530
+ *
531
+ */
532
+ static VALUE oci8_oracle_server_vernum(VALUE self)
533
+ {
534
+ oci8_svcctx_t *svcctx = DATA_PTR(self);
535
+ char buf[100];
536
+ ub4 version;
537
+ char *p;
538
+
539
+ if (have_OCIServerRelease) {
540
+ /* Oracle 9i or later */
541
+ oci_lc(OCIServerRelease(svcctx->base.hp.ptr, oci8_errhp, (text*)buf, sizeof(buf), svcctx->base.type, &version));
542
+ return UINT2NUM(version);
543
+ } else {
544
+ /* Oracle 8.x */
545
+ oci_lc(OCIServerVersion(svcctx->base.hp.ptr, oci8_errhp, (text*)buf, sizeof(buf), svcctx->base.type));
546
+ if ((p = strchr(buf, '.')) != NULL) {
547
+ unsigned int major, minor, update, patch, port_update;
548
+ while (p >= buf && *p != ' ') {
549
+ p--;
550
+ }
551
+ if (sscanf(p + 1, "%u.%u.%u.%u.%u", &major, &minor, &update, &patch, &port_update) == 5) {
552
+ return INT2FIX(ORAVERNUM(major, minor, update, patch, port_update));
553
+ }
554
+ }
555
+ return Qnil;
556
+ }
557
+ }
558
+
527
559
  VALUE Init_oci8(void)
528
560
  {
529
561
  cOCI8 = oci8_define_class("OCI8", &oci8_svcctx_class);
530
562
 
531
- oracle_client_vernum = oracle_client_version;
563
+ oracle_client_vernum = INT2FIX(oracle_client_version);
532
564
  if (have_OCIClientVersion) {
533
565
  sword major, minor, update, patch, port_update;
534
566
  OCIClientVersion(&major, &minor, &update, &patch, &port_update);
@@ -556,6 +588,7 @@ VALUE Init_oci8(void)
556
588
  rb_define_method(cOCI8, "long_read_len=", oci8_set_long_read_len, 1);
557
589
  rb_define_method(cOCI8, "break", oci8_break, 0);
558
590
  rb_define_method(cOCI8, "prefetch_rows=", oci8_set_prefetch_rows, 1);
591
+ rb_define_private_method(cOCI8, "oracle_server_vernum", oci8_oracle_server_vernum, 0);
559
592
  return cOCI8;
560
593
  }
561
594
 
@@ -241,6 +241,7 @@ struct oci8_bind {
241
241
  sb4 alloc_sz; /* size of a element. */
242
242
  ub4 maxar_sz; /* maximum array size. */
243
243
  ub4 curar_sz; /* current array size. */
244
+ ub4 curar_idx;/* current array index. */
244
245
  VALUE tdo;
245
246
  union {
246
247
  void **null_structs;
@@ -375,6 +376,8 @@ void oci8_bind_free(oci8_base_t *base);
375
376
  void oci8_bind_hp_obj_mark(oci8_base_t *base);
376
377
  void Init_oci8_bind(VALUE cOCI8BindTypeBase);
377
378
  oci8_bind_t *oci8_get_bind(VALUE obj);
379
+ void oci8_bind_set_data(VALUE self, VALUE val);
380
+ VALUE oci8_bind_get_data(VALUE self);
378
381
 
379
382
  /* metadata.c */
380
383
  extern VALUE cOCI8MetadataBase;
@@ -3,7 +3,7 @@
3
3
  * ocidatetime.c
4
4
  *
5
5
  * $Author: kubo $
6
- * $Date: 2008-09-10 23:07:07 +0900 (Wed, 10 Sep 2008) $
6
+ * $Date: 2009-02-15 23:58:37 +0900 (Sun, 15 Feb 2009) $
7
7
  *
8
8
  * Copyright (C) 2005-2008 KUBO Takehiro <kubo@jiubao.org>
9
9
  *
@@ -244,19 +244,19 @@ static VALUE bind_ocitimestamp_get(oci8_bind_t *obind, void *data, void *null_st
244
244
 
245
245
  static void bind_ocitimestamp_set(oci8_bind_t *obind, void *data, void **null_structp, VALUE val)
246
246
  {
247
- oci8_base_t *stmt;
247
+ oci8_base_t *parent;
248
248
  oci8_base_t *svcctx;
249
249
 
250
- stmt = obind->base.parent;
251
- if (stmt == NULL || stmt->type != OCI_HTYPE_STMT) {
252
- rb_raise(rb_eRuntimeError, "oci8lib.so internal error [%s:%d, %p, %d]",
253
- __FILE__, __LINE__,
254
- stmt, stmt ? stmt->type : -1);
250
+ parent = obind->base.parent;
251
+ if (parent != NULL && parent->type == OCI_HTYPE_STMT) {
252
+ svcctx = parent->parent;
253
+ } else {
254
+ svcctx = parent;
255
255
  }
256
- svcctx = stmt->parent;
257
256
  if (svcctx == NULL || svcctx->type != OCI_HTYPE_SVCCTX) {
258
- rb_raise(rb_eRuntimeError, "oci8lib.so internal error [%s:%d, %p, %d]",
257
+ rb_raise(rb_eRuntimeError, "oci8lib.so internal error [%s:%d, %p, %d, %p, %d]",
259
258
  __FILE__, __LINE__,
259
+ parent, parent ? parent->type : -1,
260
260
  svcctx, svcctx ? svcctx->type : -1);
261
261
  }
262
262
  oci8_set_ocitimestamp(*(OCIDateTime **)data, val, svcctx->self);
@@ -266,6 +266,7 @@ static void bind_ocitimestamp_init(oci8_bind_t *obind, VALUE svc, VALUE val, VAL
266
266
  {
267
267
  oci8_bind_dsc_t *obind_dsc = (oci8_bind_dsc_t *)obind;
268
268
 
269
+ oci8_link_to_parent((oci8_base_t*)obind, (oci8_base_t*)oci8_get_svcctx(svc));
269
270
  obind->value_sz = sizeof(OCIDateTime *);
270
271
  obind->alloc_sz = sizeof(OCIDateTime *);
271
272
  obind_dsc->type = OCI_DTYPE_TIMESTAMP_TZ;
@@ -425,7 +425,7 @@ EOS
425
425
  so_ext = 'dylib'
426
426
  check_proc = Proc.new do |file|
427
427
  is_32bit = [0].pack('l!').size == 4
428
- is_big_endian = "\x01\x02".unpack('s') == 0x0102
428
+ is_big_endian = "\x01\x02".unpack('s')[0] == 0x0102
429
429
  if is_32bit
430
430
  if is_big_endian
431
431
  this_cpu = :ppc # 32-bit big-endian
@@ -444,7 +444,12 @@ EOS
444
444
  if so.cpu.include? this_cpu
445
445
  true
446
446
  else
447
- puts " skip: #{file} is for #{so.cpu} cpu."
447
+ if so.cpu.size > 1
448
+ arch_types = so.cpu[0..-2].join(', ') + ' and ' + so.cpu[-1].to_s
449
+ else
450
+ arch_types = so.cpu[0]
451
+ end
452
+ puts " skip: #{file} is for #{arch_types} cpu."
448
453
  false
449
454
  end
450
455
  else
@@ -25,7 +25,6 @@ static ID id_at_names;
25
25
  static ID id_empty_p;
26
26
  static ID id_at_con;
27
27
  static ID id_clear;
28
- static ID id_set;
29
28
 
30
29
  VALUE cOCIStmt;
31
30
 
@@ -428,7 +427,7 @@ static VALUE oci8_stmt_do_fetch(oci8_stmt_t *stmt, oci8_svcctx_t *svcctx)
428
427
  #endif /* USE_DYNAMIC_FETCH */
429
428
  ary = rb_ary_new2(RARRAY_LEN(stmt->defns));
430
429
  for (idx = 0; idx < RARRAY_LEN(stmt->defns); idx++) {
431
- rb_ary_store(ary, idx, rb_funcall(RARRAY_PTR(stmt->defns)[idx], oci8_id_get, 0));
430
+ rb_ary_store(ary, idx, oci8_bind_get_data(RARRAY_PTR(stmt->defns)[idx]));
432
431
  }
433
432
  return ary;
434
433
  }
@@ -599,7 +598,7 @@ static VALUE oci8_stmt_aref(VALUE self, VALUE key)
599
598
  if (NIL_P(obj)) {
600
599
  return Qnil;
601
600
  }
602
- return rb_funcall(obj, oci8_id_get, 0);
601
+ return oci8_bind_get_data(obj);
603
602
  }
604
603
 
605
604
  /*
@@ -650,8 +649,8 @@ static VALUE oci8_stmt_aset(VALUE self, VALUE key, VALUE val)
650
649
  rb_ivar_set(self, id_at_actual_array_size, INT2NUM(bind_array_size));
651
650
  }
652
651
  }
653
-
654
- return rb_funcall(obj, oci8_id_set, 1, val);
652
+ oci8_bind_set_data(obj, val);
653
+ return val;
655
654
  }
656
655
 
657
656
  /*
@@ -781,7 +780,6 @@ void Init_oci8_stmt(VALUE cOCI8)
781
780
  id_at_con = rb_intern("@con");
782
781
  id_empty_p = rb_intern("empty?");
783
782
  id_clear = rb_intern("clear");
784
- id_set = rb_intern("set");
785
783
 
786
784
  rb_define_private_method(cOCIStmt, "initialize", oci8_stmt_initialize, -1);
787
785
  rb_define_private_method(cOCIStmt, "__define", oci8_define_by_pos, 2);
@@ -18,7 +18,14 @@ if RUBY_PLATFORM =~ /cygwin/
18
18
  end
19
19
  end
20
20
 
21
- require 'oci8lib'
21
+ case RUBY_VERSION
22
+ when /^1\.9\.1/
23
+ require 'oci8lib_191'
24
+ when /^1\.8/
25
+ require 'oci8lib_18'
26
+ else
27
+ raise 'unsupported ruby version: ' + RUBY_VERSION
28
+ end
22
29
 
23
30
  if OCI8.respond_to? :encoding
24
31
  if defined? DEFAULT_OCI8_ENCODING
@@ -20,7 +20,7 @@ class OCI8
20
20
  #
21
21
  # This parameter is used when both or either of Oracle server and client
22
22
  # version is Oracle 8i or lower. If both versions are Oracle 9i or upper,
23
- # the default timezone is determined by session timezone.
23
+ # the default timezone is determined by the session timezone.
24
24
  def self.default_timezone=(tz)
25
25
  if tz != :local and tz != :utc
26
26
  raise ArgumentError, "expected :local or :utc but #{tz}"
@@ -111,11 +111,13 @@ class OCI8
111
111
 
112
112
  def ocidate_to_time(ary)
113
113
  year, month, day, hour, minute, sec = ary
114
- begin
115
- ::Time.send(@@default_timezone, year, month, day, hour, minute, sec)
116
- rescue StandardError
117
- ocidate_to_datetime(ary)
114
+ if year >= 139
115
+ begin
116
+ return ::Time.send(@@default_timezone, year, month, day, hour, minute, sec)
117
+ rescue StandardError
118
+ end
118
119
  end
120
+ ocidate_to_datetime(ary)
119
121
  end
120
122
 
121
123
  if OCI8.oracle_client_version >= ORAVER_9_0
@@ -149,7 +151,7 @@ class OCI8
149
151
  elsif @@time_offset == tz_hour * 3600 + tz_min * 60
150
152
  timezone = :local
151
153
  end
152
- if timezone
154
+ if timezone and year >= 139
153
155
  begin
154
156
  # Ruby 1.9 Time class's resolution is nanosecond.
155
157
  # But the last argument type is millisecond.
@@ -135,6 +135,31 @@ class OCI8
135
135
  "#<OCI8:#{username}>"
136
136
  end
137
137
 
138
+ # :call-seq:
139
+ # oracle_server_version -> oraver
140
+ #
141
+ # Returns an OCI8::OracleVersion of the Oracle server version.
142
+ #
143
+ # See also: OCI8.oracle_client_version
144
+ def oracle_server_version
145
+ unless defined? @oracle_server_version
146
+ if vernum = oracle_server_vernum
147
+ # If the Oracle client is Oracle 9i or upper,
148
+ # get the server version from the OCI function OCIServerRelease.
149
+ @oracle_server_version = OCI8::OracleVersion.new(vernum)
150
+ else
151
+ # Otherwise, get it from v$version.
152
+ self.exec('select banner from v$version') do |row|
153
+ if /^Oracle.*?(\d+\.\d+\.\d+\.\d+\.\d+)/ =~ row[0]
154
+ @oracle_server_version = OCI8::OracleVersion.new($1)
155
+ break
156
+ end
157
+ end
158
+ end
159
+ end
160
+ @oracle_server_version
161
+ end
162
+
138
163
  module BindType
139
164
  Mapping = {}
140
165
 
@@ -703,7 +728,7 @@ OCI8::BindType::Mapping[:date] = OCI8::BindType::Time
703
728
 
704
729
  if OCI8.oracle_client_version >= OCI8::ORAVER_9_0
705
730
  OCI8::BindType::Mapping[:timestamp] = OCI8::BindType::Time
706
- OCI8::BindType::Mapping[:timestamp_tz] = OCI8::BindType::DateTime
731
+ OCI8::BindType::Mapping[:timestamp_tz] = OCI8::BindType::Time
707
732
  OCI8::BindType::Mapping[:timestamp_ltz] = OCI8::BindType::Time
708
733
  OCI8::BindType::Mapping[:interval_ym] = OCI8::BindType::IntervalYM
709
734
  OCI8::BindType::Mapping[:interval_ds] = OCI8::BindType::IntervalDS
@@ -6,6 +6,7 @@
6
6
  # To make a binary gems package:
7
7
  # gem build ruby-oci8.gemspec -- current
8
8
  #
9
+ require 'fileutils'
9
10
 
10
11
  if ARGV.size > 3
11
12
  gem_platform = ARGV[3]
@@ -28,27 +29,35 @@ EOS
28
29
  s.platform = gem_platform
29
30
  files = File.read('dist-files').split("\n")
30
31
  if gem_platform == Gem::Platform::RUBY
31
- s.require_paths = ['lib']
32
32
  s.extensions << 'ext/oci8/extconf.rb'
33
33
  s.required_ruby_version = '>= 1.8.0'
34
34
  else
35
- s.require_paths = ['lib', 'ext/oci8']
36
- if RUBY_VERSION =~ /^1\.9\./
35
+ so_files = Dir.glob('ext/oci8/oci8lib_*.so')
36
+ has_1_8 = so_files.include? 'ext/oci8/oci8lib_18.so'
37
+ has_1_9_1 = so_files.include? 'ext/oci8/oci8lib_191.so'
38
+ if has_1_8 and has_1_9_1
39
+ puts 'Binary gem for ruby 1.8 and 1.9.1'
40
+ s.required_ruby_version = '>= 1.8.0'
41
+ elsif has_1_8 and !has_1_9_1
42
+ puts 'Binary gem for ruby 1.8'
43
+ s.required_ruby_version = '~> 1.8.0'
44
+ elsif !has_1_8 and has_1_9_1
45
+ puts 'Binary gem for ruby 1.9.1'
37
46
  s.required_ruby_version = '~> 1.9.1'
38
47
  else
39
- s.required_ruby_version = '~> 1.8.0'
48
+ raise "No compiled binary are found. Run make in advance."
40
49
  end
41
- # check files created by a make command.
42
- ['ext/oci8/oci8lib.so', 'lib/oci8.rb'].each do |file|
43
- raise <<EOS unless File.exist?(file)
44
- #{file} doesn't exist. Run make in advance.
45
- EOS
46
- #'
47
- files << file
50
+ FileUtils.copy so_files, 'lib', :preserve => true
51
+ files.reject! do |fname|
52
+ fname =~ /^ext/
53
+ end
54
+ so_files.each do |fname|
55
+ files << 'lib/' + File.basename(fname)
48
56
  end
57
+ files << 'lib/oci8.rb'
49
58
  end
50
59
  s.files = files
51
60
  s.test_files = 'test/test_all.rb'
52
- s.rdoc_options = ['--main', 'README', '--exclude', 'ext/*']
61
+ s.rdoc_options = ['--main', 'README']
53
62
  s.extra_rdoc_files = ['README']
54
63
  end
@@ -22,7 +22,8 @@ CREATE TABLE test_table
22
22
  N NUMBER(10, 2),
23
23
  D DATE,
24
24
  INT NUMBER(30),
25
- BIGNUM NUMBER(30))
25
+ BIGNUM NUMBER(30),
26
+ T TIMESTAMP)
26
27
  STORAGE (
27
28
  INITIAL 4k
28
29
  NEXT 4k
@@ -31,23 +32,25 @@ STORAGE (
31
32
  PCTINCREASE 0)
32
33
  EOS
33
34
  @conn.exec(sql)
34
- cursor = @conn.parse("INSERT INTO test_table VALUES (:C, :V, :N, :D, :INT, :BIGNUM)")
35
+ cursor = @conn.parse("INSERT INTO test_table VALUES (:C, :V, :N, :D, :INT, :BIGNUM, :T)")
35
36
  max_array_size = 3
36
37
  cursor.max_array_size= max_array_size
37
38
 
38
39
  cursor.bind_param_array(1, nil, String)
39
40
  cursor.bind_param_array(2, nil ,String)
40
41
  cursor.bind_param_array(3, nil, Fixnum)
41
- cursor.bind_param_array(4, nil, OraDate)
42
+ cursor.bind_param_array(4, nil, OraDate)
42
43
  cursor.bind_param_array(5, nil, Integer)
43
44
  cursor.bind_param_array(6, nil, Bignum)
44
-
45
+ cursor.bind_param_array(7, nil, DateTime)
46
+
45
47
  c_arr = Array.new
46
48
  v_arr = Array.new
47
49
  n_arr = Array.new
48
50
  d_arr = Array.new
49
51
  int_arr = Array.new
50
52
  bignum_arr = Array.new
53
+ t_arr = Array.new
51
54
 
52
55
  1.upto(30) do |i|
53
56
  c_arr << format("%10d", i * 10)
@@ -56,6 +59,7 @@ EOS
56
59
  d_arr << OraDate.new(2000 + i, 12, 24, 23, 59, 59)
57
60
  int_arr << i * 11111111111
58
61
  bignum_arr << i * 10000000000
62
+ t_arr << DateTime.new(2000 + i, 12, 24, 23, 59, 59)
59
63
 
60
64
  if i%max_array_size == 0
61
65
  cursor[1] = c_arr
@@ -64,15 +68,24 @@ EOS
64
68
  cursor[4] = d_arr
65
69
  cursor[5] = int_arr
66
70
  cursor[6] = bignum_arr
71
+ cursor[7] = t_arr
67
72
 
68
73
  r = cursor.exec_array
69
74
  assert_equal(max_array_size, r)
75
+ assert_equal(c_arr, cursor[1])
76
+ assert_equal(v_arr, cursor[2])
77
+ assert_equal(n_arr, cursor[3])
78
+ assert_equal(d_arr, cursor[4])
79
+ assert_equal(int_arr, cursor[5])
80
+ assert_equal(bignum_arr, cursor[6])
81
+ assert_equal(t_arr, cursor[7])
70
82
  c_arr.clear
71
83
  v_arr.clear
72
84
  n_arr.clear
73
85
  d_arr.clear
74
86
  int_arr.clear
75
87
  bignum_arr.clear
88
+ t_arr.clear
76
89
  end
77
90
  end
78
91
  cursor.close
@@ -81,7 +94,7 @@ EOS
81
94
  cursor.define(5, Integer)
82
95
  cursor.define(6, Bignum)
83
96
  cursor.exec
84
- assert_equal(["C","V","N","D","INT","BIGNUM"], cursor.get_col_names)
97
+ assert_equal(["C","V","N","D","INT","BIGNUM","T"], cursor.get_col_names)
85
98
  1.upto(30) do |i|
86
99
  rv = cursor.fetch
87
100
  assert_equal(format("%10d", i * 10), rv[0])
@@ -91,6 +104,7 @@ EOS
91
104
  assert_equal(tm, rv[3])
92
105
  assert_equal(i * 11111111111, rv[4])
93
106
  assert_equal(i * 10000000000, rv[5])
107
+ assert_equal(tm, rv[6])
94
108
  end
95
109
  assert_nil(cursor.fetch)
96
110
  drop_table('test_table')
@@ -131,13 +145,15 @@ EOS
131
145
  sql = <<-EOS
132
146
  CREATE TABLE test_table
133
147
  (N NUMBER(10, 2) NOT NULL,
134
- V VARCHAR(20))
148
+ V VARCHAR(20),
149
+ T TIMESTAMP)
135
150
  EOS
136
151
  @conn.exec(sql)
137
- cursor = @conn.parse("INSERT INTO test_table VALUES (:N, :V)")
152
+ cursor = @conn.parse("INSERT INTO test_table VALUES (:N, :V, :T)")
138
153
  cursor.max_array_size = 3
139
154
  cursor.bind_param_array(1, [1, 2, 3])
140
155
  cursor.bind_param_array(2, ['happy', 'new', 'year'])
156
+ cursor.bind_param_array(3, [Time.gm(1990,1,1), Time.gm(2000,1,1), Time.gm(2010,1,1)])
141
157
  assert_nothing_raised() { cursor.exec_array }
142
158
  cursor.max_array_size = 2
143
159
  assert_raise(RuntimeError) { cursor.exec_array }
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ruby-oci8
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.0
4
+ version: 2.0.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - KUBO Takehiro
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2009-02-08 00:00:00 +09:00
12
+ date: 2009-03-18 00:00:00 +09:00
13
13
  default_executable:
14
14
  dependencies: []
15
15
 
@@ -24,6 +24,7 @@ extra_rdoc_files:
24
24
  files:
25
25
  - ChangeLog
26
26
  - Makefile
27
+ - NEWS
27
28
  - README
28
29
  - VERSION
29
30
  - dist-files
@@ -98,8 +99,6 @@ post_install_message:
98
99
  rdoc_options:
99
100
  - --main
100
101
  - README
101
- - --exclude
102
- - ext/*
103
102
  require_paths:
104
103
  - lib
105
104
  required_ruby_version: !ruby/object:Gem::Requirement
@@ -117,7 +116,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
117
116
  requirements: []
118
117
 
119
118
  rubyforge_project: ruby-oci8
120
- rubygems_version: 1.3.1
119
+ rubygems_version: 1.2.0
121
120
  signing_key:
122
121
  specification_version: 2
123
122
  summary: Ruby interface for Oracle using OCI8 API