ruby-oci8 2.0.0 → 2.0.1

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