ruby-oci8 2.0.4 → 2.0.5

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.
@@ -3,7 +3,7 @@
3
3
  * oradate.c
4
4
  *
5
5
  * $Author: kubo $
6
- * $Date: 2009-01-04 01:58:01 +0900 (Sun, 04 Jan 2009) $
6
+ * $Date: 2010-09-05 22:07:21 +0900 (日, 05 9月 2010) $
7
7
  *
8
8
  * Copyright (C) 2002-2008 KUBO Takehiro <kubo@jiubao.org>
9
9
  *
@@ -146,7 +146,7 @@ static VALUE ora_date_initialize_copy(VALUE lhs, VALUE rhs)
146
146
  {
147
147
  ora_date_t *l, *r;
148
148
 
149
- rb_obj_init_copy(lhs, rhs);
149
+ rb_call_super(1, &rhs);
150
150
  Data_Get_Struct(lhs, ora_date_t, l);
151
151
  Data_Get_Struct(rhs, ora_date_t, r);
152
152
  memcpy(l, r, sizeof(ora_date_t));
@@ -37,9 +37,24 @@ int oranumber_to_str(const OCINumber *on, char *buf, int buflen)
37
37
  PUTEND();
38
38
  return 1;
39
39
  }
40
+ if (on->OCINumberPart[1] == 0) {
41
+ /* negative infinity */
42
+ PUTC('-');
43
+ PUTC('~');
44
+ PUTEND();
45
+ return 2;
46
+ }
40
47
  /* unexpected format */
41
48
  return -1;
42
49
  }
50
+ if (datalen == 2) {
51
+ if (on->OCINumberPart[1] == 255 && on->OCINumberPart[2] == 101) {
52
+ /* positive infinity */
53
+ PUTC('~');
54
+ PUTEND();
55
+ return 1;
56
+ }
57
+ }
43
58
  if (datalen > 21) {
44
59
  /* too long */
45
60
  return -1;
@@ -137,6 +152,28 @@ int oranumber_from_str(OCINumber *on, const char *buf, int buflen)
137
152
  buf++;
138
153
  is_positive = 0;
139
154
  }
155
+ if (*buf == '~') {
156
+ buf ++;
157
+ /* skip trailing spaces */
158
+ while (buf < end && *buf == ' ') {
159
+ buf++;
160
+ }
161
+ if (buf != end) {
162
+ return ORANUMBER_INVALID_NUMBER;
163
+ }
164
+ if (is_positive) {
165
+ /* positive infinity */
166
+ on->OCINumberPart[0] = 2;
167
+ on->OCINumberPart[1] = 255;
168
+ on->OCINumberPart[2] = 101;
169
+ } else {
170
+ /* negative infinity */
171
+ on->OCINumberPart[0] = 1;
172
+ on->OCINumberPart[1] = 0;
173
+ }
174
+ return ORANUMBER_SUCCESS;
175
+ }
176
+
140
177
  /* next should be number or a dot */
141
178
  if ((*buf < '0' || '9' < *buf) && *buf != '.') {
142
179
  return ORANUMBER_INVALID_NUMBER;
@@ -308,7 +345,7 @@ int oranumber_dump(const OCINumber *on, char *buf)
308
345
  len = 21;
309
346
  }
310
347
  for (idx = 1; idx <= len; idx++) {
311
- offset += sprintf(buf + offset, "%hhu,", on->OCINumberPart[idx]);
348
+ offset += sprintf(buf + offset, "%u,", (ub4)on->OCINumberPart[idx]);
312
349
  }
313
350
  buf[--offset] = '\0';
314
351
  return offset;
@@ -3,7 +3,7 @@
3
3
  * stmt.c - part of ruby-oci8
4
4
  * implement the methods of OCIStmt.
5
5
  *
6
- * Copyright (C) 2002-2007 KUBO Takehiro <kubo@jiubao.org>
6
+ * Copyright (C) 2002-2010 KUBO Takehiro <kubo@jiubao.org>
7
7
  *
8
8
  */
9
9
  #include "oci8.h"
@@ -28,6 +28,8 @@ static ID id_clear;
28
28
 
29
29
  VALUE cOCIStmt;
30
30
 
31
+ #define TO_STMT(obj) ((oci8_stmt_t *)oci8_get_handle((obj), cOCIStmt))
32
+
31
33
  typedef struct {
32
34
  oci8_base_t base;
33
35
  VALUE svc;
@@ -94,7 +96,7 @@ static VALUE oci8_stmt_initialize(int argc, VALUE *argv, VALUE self)
94
96
 
95
97
  static VALUE oci8_define_by_pos(VALUE self, VALUE vposition, VALUE vbindobj)
96
98
  {
97
- oci8_stmt_t *stmt = DATA_PTR(self);
99
+ oci8_stmt_t *stmt = TO_STMT(self);
98
100
  ub4 position;
99
101
  oci8_bind_t *obind;
100
102
  const oci8_bind_class_t *bind_class;
@@ -117,6 +119,10 @@ static VALUE oci8_define_by_pos(VALUE self, VALUE vposition, VALUE vbindobj)
117
119
  oci8_raise(oci8_errhp, status, stmt->base.hp.ptr);
118
120
  }
119
121
  obind->base.type = OCI_HTYPE_DEFINE;
122
+ /* link to the parent as soon as possible to preserve deallocation order. */
123
+ oci8_unlink_from_parent((oci8_base_t*)obind);
124
+ oci8_link_to_parent((oci8_base_t*)obind, (oci8_base_t*)stmt);
125
+
120
126
  if (NIL_P(obind->tdo) && obind->maxar_sz > 0) {
121
127
  oci_lc(OCIDefineArrayOfStruct(obind->base.hp.dfn, oci8_errhp, obind->alloc_sz, sizeof(sb2), 0, 0));
122
128
  }
@@ -135,14 +141,12 @@ static VALUE oci8_define_by_pos(VALUE self, VALUE vposition, VALUE vbindobj)
135
141
  oci_lc(OCIAttrSet(obind->base.hp.ptr, OCI_HTYPE_DEFINE, (void*)&bind_class->csfrm, 0, OCI_ATTR_CHARSET_FORM, oci8_errhp));
136
142
  }
137
143
  rb_ary_store(stmt->defns, position - 1, obind->base.self);
138
- oci8_unlink_from_parent((oci8_base_t*)obind);
139
- oci8_link_to_parent((oci8_base_t*)obind, (oci8_base_t*)stmt);
140
144
  return obind->base.self;
141
145
  }
142
146
 
143
147
  static VALUE oci8_bind(VALUE self, VALUE vplaceholder, VALUE vbindobj)
144
148
  {
145
- oci8_stmt_t *stmt = DATA_PTR(self);
149
+ oci8_stmt_t *stmt = TO_STMT(self);
146
150
  char *placeholder_ptr = (char*)-1; /* initialize as an invalid value */
147
151
  ub4 placeholder_len = 0;
148
152
  ub4 position = 0;
@@ -197,6 +201,10 @@ static VALUE oci8_bind(VALUE self, VALUE vplaceholder, VALUE vbindobj)
197
201
  oci8_raise(oci8_errhp, status, stmt->base.hp.stmt);
198
202
  }
199
203
  obind->base.type = OCI_HTYPE_BIND;
204
+ /* link to the parent as soon as possible to preserve deallocation order. */
205
+ oci8_unlink_from_parent((oci8_base_t*)obind);
206
+ oci8_link_to_parent((oci8_base_t*)obind, (oci8_base_t*)stmt);
207
+
200
208
  if (NIL_P(obind->tdo) && obind->maxar_sz > 0) {
201
209
  oci_lc(OCIBindArrayOfStruct(obind->base.hp.bnd, oci8_errhp, obind->alloc_sz, sizeof(sb2), 0, 0));
202
210
  }
@@ -213,8 +221,6 @@ static VALUE oci8_bind(VALUE self, VALUE vplaceholder, VALUE vbindobj)
213
221
  oci8_base_free((oci8_base_t*)oci8_get_bind(old_value));
214
222
  }
215
223
  rb_hash_aset(stmt->binds, vplaceholder, obind->base.self);
216
- oci8_unlink_from_parent((oci8_base_t*)obind);
217
- oci8_link_to_parent((oci8_base_t*)obind, (oci8_base_t*)stmt);
218
224
  return obind->base.self;
219
225
  }
220
226
 
@@ -237,7 +243,7 @@ static sword oci8_call_stmt_execute(oci8_svcctx_t *svcctx, oci8_stmt_t *stmt, ub
237
243
 
238
244
  static VALUE oci8_stmt_execute(VALUE self, VALUE iteration_count)
239
245
  {
240
- oci8_stmt_t *stmt = DATA_PTR(self);
246
+ oci8_stmt_t *stmt = TO_STMT(self);
241
247
  oci8_svcctx_t *svcctx = oci8_get_svcctx(stmt->svc);
242
248
  ub4 iters;
243
249
  ub4 mode;
@@ -323,8 +329,8 @@ static VALUE clear_binds_iterator_proc(VALUE val, VALUE arg)
323
329
 
324
330
  static VALUE oci8_stmt_clear_binds(VALUE self)
325
331
  {
326
- oci8_stmt_t *stmt = DATA_PTR(self);
327
-
332
+ oci8_stmt_t *stmt = TO_STMT(self);
333
+
328
334
  if(!RTEST(rb_funcall(stmt->binds, id_empty_p, 0)))
329
335
  {
330
336
  rb_iterate(each_value, stmt->binds, clear_binds_iterator_proc, Qnil);
@@ -449,7 +455,7 @@ static VALUE oci8_stmt_do_fetch(oci8_stmt_t *stmt, oci8_svcctx_t *svcctx)
449
455
  */
450
456
  static VALUE oci8_stmt_fetch(VALUE self)
451
457
  {
452
- oci8_stmt_t *stmt = DATA_PTR(self);
458
+ oci8_stmt_t *stmt = TO_STMT(self);
453
459
  oci8_svcctx_t *svcctx = oci8_get_svcctx(stmt->svc);
454
460
 
455
461
  if (rb_block_given_p()) {
@@ -466,7 +472,7 @@ static VALUE oci8_stmt_fetch(VALUE self)
466
472
 
467
473
  static VALUE oci8_stmt_get_param(VALUE self, VALUE pos)
468
474
  {
469
- oci8_stmt_t *stmt = DATA_PTR(self);
475
+ oci8_stmt_t *stmt = TO_STMT(self);
470
476
  OCIParam *parmhp = NULL;
471
477
  sword rv;
472
478
 
@@ -498,7 +504,7 @@ static VALUE oci8_stmt_get_param(VALUE self, VALUE pos)
498
504
  */
499
505
  static VALUE oci8_stmt_get_stmt_type(VALUE self)
500
506
  {
501
- VALUE stmt_type = oci8_get_ub2_attr(DATA_PTR(self), OCI_ATTR_STMT_TYPE);
507
+ VALUE stmt_type = oci8_get_ub2_attr(oci8_get_handle(self, cOCIStmt), OCI_ATTR_STMT_TYPE);
502
508
  switch (FIX2INT(stmt_type)) {
503
509
  case OCI_STMT_SELECT:
504
510
  return oci8_sym_select_stmt;
@@ -528,7 +534,7 @@ static VALUE oci8_stmt_get_stmt_type(VALUE self)
528
534
  */
529
535
  static VALUE oci8_stmt_get_row_count(VALUE self)
530
536
  {
531
- return oci8_get_ub4_attr(DATA_PTR(self), OCI_ATTR_ROW_COUNT);
537
+ return oci8_get_ub4_attr(oci8_get_handle(self, cOCIStmt), OCI_ATTR_ROW_COUNT);
532
538
  }
533
539
 
534
540
  /*
@@ -547,12 +553,12 @@ static VALUE oci8_stmt_get_row_count(VALUE self)
547
553
  */
548
554
  static VALUE oci8_stmt_get_rowid(VALUE self)
549
555
  {
550
- return oci8_get_rowid_attr(DATA_PTR(self), OCI_ATTR_ROWID);
556
+ return oci8_get_rowid_attr(oci8_get_handle(self, cOCIStmt), OCI_ATTR_ROWID);
551
557
  }
552
558
 
553
559
  static VALUE oci8_stmt_get_param_count(VALUE self)
554
560
  {
555
- return oci8_get_ub4_attr(DATA_PTR(self), OCI_ATTR_PARAM_COUNT);
561
+ return oci8_get_ub4_attr(oci8_get_handle(self, cOCIStmt), OCI_ATTR_PARAM_COUNT);
556
562
  }
557
563
 
558
564
  /*
@@ -595,7 +601,7 @@ static VALUE oci8_stmt_get_param_count(VALUE self)
595
601
  */
596
602
  static VALUE oci8_stmt_aref(VALUE self, VALUE key)
597
603
  {
598
- oci8_stmt_t *stmt = DATA_PTR(self);
604
+ oci8_stmt_t *stmt = TO_STMT(self);
599
605
  VALUE obj = rb_hash_aref(stmt->binds, key);
600
606
  if (NIL_P(obj)) {
601
607
  return Qnil;
@@ -633,7 +639,7 @@ static VALUE oci8_stmt_aset(VALUE self, VALUE key, VALUE val)
633
639
  long actual_array_size;
634
640
  long bind_array_size;
635
641
 
636
- oci8_stmt_t *stmt = DATA_PTR(self);
642
+ oci8_stmt_t *stmt = TO_STMT(self);
637
643
  VALUE obj = rb_hash_aref(stmt->binds, key);
638
644
  if (NIL_P(obj)) {
639
645
  return Qnil; /* ?? MUST BE ERROR? */
@@ -650,7 +656,7 @@ static VALUE oci8_stmt_aset(VALUE self, VALUE key, VALUE val)
650
656
  if(bind_array_size <= max_array_size && actual_array_size == 0) {
651
657
  rb_ivar_set(self, id_at_actual_array_size, INT2NUM(bind_array_size));
652
658
  }
653
- }
659
+ }
654
660
  oci8_bind_set_data(obj, val);
655
661
  return val;
656
662
  }
@@ -663,13 +669,13 @@ static VALUE oci8_stmt_aset(VALUE self, VALUE key, VALUE val)
663
669
  */
664
670
  static VALUE oci8_stmt_keys(VALUE self)
665
671
  {
666
- oci8_stmt_t *stmt = DATA_PTR(self);
672
+ oci8_stmt_t *stmt = TO_STMT(self);
667
673
  return rb_funcall(stmt->binds, oci8_id_keys, 0);
668
674
  }
669
675
 
670
676
  static VALUE oci8_stmt_defined_p(VALUE self, VALUE pos)
671
677
  {
672
- oci8_stmt_t *stmt = DATA_PTR(self);
678
+ oci8_stmt_t *stmt = TO_STMT(self);
673
679
  long position = NUM2INT(pos);
674
680
 
675
681
  if (position - 1 < RARRAY_LEN(stmt->defns)) {
@@ -693,7 +699,7 @@ static VALUE oci8_stmt_defined_p(VALUE self, VALUE pos)
693
699
  */
694
700
  static VALUE oci8_stmt_set_prefetch_rows(VALUE self, VALUE rows)
695
701
  {
696
- oci8_stmt_t *stmt = DATA_PTR(self);
702
+ oci8_stmt_t *stmt = TO_STMT(self);
697
703
  ub4 num = NUM2UINT(rows);
698
704
 
699
705
  oci_lc(OCIAttrSet(stmt->base.hp.ptr, OCI_HTYPE_STMT, &num, 0, OCI_ATTR_PREFETCH_ROWS, oci8_errhp));
@@ -2,9 +2,15 @@
2
2
  /*
3
3
  win32.c - part of ruby-oci8
4
4
 
5
- Copyright (C) 2009 KUBO Takehiro <kubo@jiubao.org>
5
+ Copyright (C) 2009-2010 KUBO Takehiro <kubo@jiubao.org>
6
6
  */
7
7
  #include "oci8.h"
8
+ #ifdef __CYGWIN__
9
+ /* boolean is defined as a macro in oratypes.h.
10
+ * It conflicts with the definition in windows.h.
11
+ */
12
+ #undef boolean
13
+ #endif
8
14
  #include <windows.h>
9
15
 
10
16
  NORETURN(static void raise_error(void));
@@ -84,14 +90,14 @@ static VALUE enum_homes_real(enum_homes_arg_t *arg)
84
90
  }
85
91
  /* Get ORACLE_HOME */
86
92
  name_len = sizeof(name);
87
- rv = RegQueryValueEx(arg->hSubKey, "ORACLE_HOME", NULL, &type, name, &name_len);
93
+ rv = RegQueryValueEx(arg->hSubKey, "ORACLE_HOME", NULL, &type, TO_ORATEXT(name), &name_len);
88
94
  if (rv != ERROR_SUCCESS || type != REG_SZ) {
89
95
  continue;
90
96
  }
91
97
  oracle_home = rb_locale_str_new_cstr(name);
92
98
  /* Get NLS_LANG */
93
99
  name_len = sizeof(name);
94
- rv = RegQueryValueEx(arg->hSubKey, "NLS_LANG", NULL, &type, name, &name_len);
100
+ rv = RegQueryValueEx(arg->hSubKey, "NLS_LANG", NULL, &type, TO_ORATEXT(name), &name_len);
95
101
  if (rv != ERROR_SUCCESS || type != REG_SZ) {
96
102
  continue;
97
103
  }
@@ -18,14 +18,24 @@ if RUBY_PLATFORM =~ /cygwin/
18
18
  end
19
19
  end
20
20
 
21
+ so_basename = 'oci8lib_'
22
+ if defined? RUBY_ENGINE and RUBY_ENGINE != 'ruby'
23
+ so_basename += RUBY_ENGINE
24
+ end
25
+
26
+ # The suffix number indicates the ruby API version.
27
+ # 18 - ruby 1.8.x
28
+ # 191 - ruby 1.9.1 and 1.9.2
29
+ # 19x - ruby 1.9.x future version which will break the API compatibility
21
30
  case RUBY_VERSION
22
31
  when /^1\.9/
23
- require 'oci8lib_191'
32
+ so_basename += '191'
24
33
  when /^1\.8/
25
- require 'oci8lib_18'
34
+ so_basename += '18'
26
35
  else
27
36
  raise 'unsupported ruby version: ' + RUBY_VERSION
28
37
  end
38
+ require so_basename
29
39
 
30
40
  if OCI8.respond_to? :encoding
31
41
  if defined? DEFAULT_OCI8_ENCODING
@@ -75,6 +85,7 @@ require 'oci8/bindtype.rb'
75
85
  require 'oci8/metadata.rb'
76
86
  require 'oci8/compat.rb'
77
87
  require 'oci8/object.rb'
88
+ require 'oci8/properties.rb'
78
89
 
79
90
  class OCI8
80
91
  VERSION = '@@OCI8_MODULE_VERSION@@'
@@ -3,3 +3,4 @@ object.rb
3
3
  metadata.rb
4
4
  oracle_version.rb
5
5
  oci8.rb
6
+ properties.rb
@@ -1,7 +1,7 @@
1
1
  #--
2
2
  # bindtype.rb -- OCI8::BindType
3
3
  #
4
- # Copyright (C) 2009 KUBO Takehiro <kubo@jiubao.org>
4
+ # Copyright (C) 2009-2010 KUBO Takehiro <kubo@jiubao.org>
5
5
  #++
6
6
 
7
7
  class OCI8
@@ -46,6 +46,12 @@ class OCI8
46
46
  end
47
47
  end
48
48
 
49
+ class BasicNumberType < OCI8::BindType::OraNumber
50
+ def get()
51
+ (val = super()) && (val.has_decimal_part? ? val.to_f : val.to_i)
52
+ end
53
+ end
54
+
49
55
  # get/set Number (for OCI8::SQLT_NUM)
50
56
  class Number
51
57
  def self.create(con, val, param, max_array_size)
@@ -116,6 +122,8 @@ class OCI8
116
122
  length = val.size
117
123
  end
118
124
  end
125
+ # use the default value when :nchar is not set explicitly.
126
+ nchar = OCI8.properties[:bind_string_as_nchar] unless param.has_key?(:nchar)
119
127
  when OCI8::Metadata::Base
120
128
  case param.data_type
121
129
  when :char, :varchar2
@@ -124,13 +132,18 @@ class OCI8
124
132
  # The length of a Japanese half-width kana is one in Shift_JIS,
125
133
  # two in EUC-JP, three in UTF-8.
126
134
  length *= 3 unless param.char_used?
135
+ nchar = (param.charset_form == :nchar)
127
136
  when :raw
128
137
  # HEX needs twice space.
129
138
  length = param.data_size * 2
130
139
  end
131
140
  end
132
141
  length = @@minimum_bind_length if length.nil? or length < @@minimum_bind_length
133
- self.new(con, val, length, max_array_size)
142
+ if nchar
143
+ OCI8::BindType::NCHAR.new(con, val, length, max_array_size)
144
+ else
145
+ OCI8::BindType::CHAR.new(con, val, length, max_array_size)
146
+ end
134
147
  end
135
148
  end
136
149
 
@@ -153,7 +166,7 @@ class OCI8
153
166
 
154
167
  class Long < OCI8::BindType::String
155
168
  def self.create(con, val, param, max_array_size)
156
- self.new(con, val, con.long_read_len, max_array_size)
169
+ super(con, val, {:length => con.long_read_len}, max_array_size)
157
170
  end
158
171
  end
159
172
 
@@ -38,6 +38,14 @@ class OCI8
38
38
  @@time_new_accepts_timezone = false # prior to ruby 1.9.2
39
39
  end
40
40
 
41
+ begin
42
+ # 2001-01-01 00:00:59.999
43
+ ::DateTime.civil(2001, 1, 1, 0, 0, Rational(59_999, 1000), 0)
44
+ @@datetime_has_fractional_second_bug = false
45
+ rescue ArgumentError
46
+ @@datetime_has_fractional_second_bug = true
47
+ end
48
+
41
49
  def self.default_timezone
42
50
  @@default_timezone
43
51
  end
@@ -162,8 +170,8 @@ class OCI8
162
170
  return nil if ary.nil?
163
171
 
164
172
  year, month, day, hour, minute, sec, fsec, tz_hour, tz_min = ary
165
- if sec >= 59 and fsec != 0
166
- # convert to a DateTime via a String as a last resort.
173
+ if @@datetime_has_fractional_second_bug and sec >= 59 and fsec != 0
174
+ # convert to a DateTime via a String as a workaround
167
175
  if tz_hour >= 0 && tz_min >= 0
168
176
  sign = ?+
169
177
  else
@@ -245,7 +253,7 @@ class OCI8
245
253
  end
246
254
 
247
255
  if OCI8.oracle_client_version >= ORAVER_9_0
248
- class DateTimeViaOCITimestamp < OCI8::BindType::OCITimestamp # :nodoc:
256
+ class DateTimeViaOCITimestampTZ < OCI8::BindType::OCITimestampTZ # :nodoc:
249
257
  include OCI8::BindType::Util
250
258
 
251
259
  def set(val) # :nodoc:
@@ -257,7 +265,7 @@ class OCI8
257
265
  end
258
266
  end
259
267
 
260
- class TimeViaOCITimestamp < OCI8::BindType::OCITimestamp # :nodoc:
268
+ class TimeViaOCITimestampTZ < OCI8::BindType::OCITimestampTZ # :nodoc:
261
269
  include OCI8::BindType::Util
262
270
 
263
271
  def set(val) # :nodoc:
@@ -335,7 +343,7 @@ class OCI8
335
343
  if OCI8.oracle_client_version >= ORAVER_9_0
336
344
  def self.create(con, val, param, max_array_size) # :nodoc:
337
345
  if true # TODO: check Oracle server version
338
- DateTimeViaOCITimestamp.new(con, val, param, max_array_size)
346
+ DateTimeViaOCITimestampTZ.new(con, val, param, max_array_size)
339
347
  else
340
348
  DateTimeViaOCIDate.new(con, val, param, max_array_size)
341
349
  end
@@ -414,7 +422,7 @@ class OCI8
414
422
  if OCI8.oracle_client_version >= ORAVER_9_0
415
423
  def self.create(con, val, param, max_array_size) # :nodoc:
416
424
  if true # TODO: check Oracle server version
417
- TimeViaOCITimestamp.new(con, val, param, max_array_size)
425
+ TimeViaOCITimestampTZ.new(con, val, param, max_array_size)
418
426
  else
419
427
  TimeViaOCIDate.new(con, val, param, max_array_size)
420
428
  end