ruby-oci8 2.0.6 → 2.1.0
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 +366 -19
- data/Makefile +2 -8
- data/NEWS +111 -0
- data/README +4 -85
- data/VERSION +1 -1
- data/dist-files +9 -2
- data/ext/oci8/.document +1 -0
- data/ext/oci8/apiwrap.c.tmpl +12 -2
- data/ext/oci8/apiwrap.yml +37 -21
- data/ext/oci8/attr.c +23 -74
- data/ext/oci8/bind.c +93 -225
- data/ext/oci8/connection_pool.c +201 -0
- data/ext/oci8/encoding.c +117 -24
- data/ext/oci8/env.c +5 -10
- data/ext/oci8/error.c +171 -189
- data/ext/oci8/extconf.rb +6 -2
- data/ext/oci8/lob.c +81 -79
- data/ext/oci8/metadata.c +42 -177
- data/ext/oci8/object.c +55 -28
- data/ext/oci8/oci8.c +426 -294
- data/ext/oci8/oci8.h +84 -51
- data/ext/oci8/oci8lib.c +75 -53
- data/ext/oci8/ocidatetime.c +67 -88
- data/ext/oci8/ocihandle.c +78 -37
- data/ext/oci8/ocinumber.c +166 -109
- data/ext/oci8/oraconf.rb +68 -157
- data/ext/oci8/oradate.c +2 -7
- data/ext/oci8/stmt.c +40 -183
- data/ext/oci8/thread_util.c +85 -0
- data/ext/oci8/thread_util.h +30 -0
- data/lib/oci8.rb.in +19 -13
- data/lib/oci8/.document +2 -0
- data/lib/oci8/bindtype.rb +62 -45
- data/lib/oci8/connection_pool.rb +118 -0
- data/lib/oci8/datetime.rb +304 -320
- data/lib/oci8/encoding-init.rb +62 -30
- data/lib/oci8/encoding.yml +3 -3
- data/lib/oci8/metadata.rb +552 -497
- data/lib/oci8/object.rb +9 -9
- data/lib/oci8/oci8.rb +161 -2
- data/lib/oci8/ocihandle.rb +427 -0
- data/lib/oci8/properties.rb +31 -1
- data/ruby-oci8.gemspec +10 -3
- data/test/README +41 -3
- data/test/config.rb +16 -0
- data/test/test_all.rb +3 -0
- data/test/test_bind_string.rb +106 -0
- data/test/test_break.rb +33 -7
- data/test/test_clob.rb +13 -10
- data/test/test_connection_pool.rb +125 -0
- data/test/test_connstr.rb +2 -2
- data/test/test_datetime.rb +26 -66
- data/test/test_encoding.rb +7 -3
- data/test/test_error.rb +88 -0
- data/test/test_metadata.rb +1356 -204
- data/test/test_oci8.rb +27 -8
- data/test/test_oranumber.rb +41 -0
- metadata +34 -9
- data/ext/oci8/xmldb.c +0 -383
data/ext/oci8/ocinumber.c
CHANGED
@@ -2,12 +2,13 @@
|
|
2
2
|
/*
|
3
3
|
* ocinumber.c
|
4
4
|
*
|
5
|
-
* Copyright (C) 2005-
|
5
|
+
* Copyright (C) 2005-2011 KUBO Takehiro <kubo@jiubao.org>
|
6
6
|
*
|
7
7
|
*/
|
8
8
|
#include "oci8.h"
|
9
9
|
#include <orl.h>
|
10
10
|
#include <errno.h>
|
11
|
+
#include <math.h>
|
11
12
|
#include "oranumber_util.h"
|
12
13
|
|
13
14
|
#ifndef RB_NUM_COERCE_FUNCS_NEED_OPID
|
@@ -16,6 +17,12 @@
|
|
16
17
|
#define rb_num_coerce_bin(x, y, id) rb_num_coerce_bin((x), (y))
|
17
18
|
#endif
|
18
19
|
|
20
|
+
int oci8_float_conversion_type_is_ruby = 1;
|
21
|
+
|
22
|
+
#ifndef INFINITY
|
23
|
+
#define INFINITY (1.0/+0.0)
|
24
|
+
#endif
|
25
|
+
|
19
26
|
static ID id_power; /* rb_intern("**") */
|
20
27
|
static ID id_cmp; /* rb_intern("<=>") */
|
21
28
|
static ID id_finite_p;
|
@@ -112,7 +119,7 @@ VALUE oci8_make_ocinumber(OCINumber *s, OCIError *errhp)
|
|
112
119
|
OCINumber *d;
|
113
120
|
|
114
121
|
obj = Data_Make_Struct(cOCINumber, OCINumber, NULL, xfree, d);
|
115
|
-
|
122
|
+
chkerr(OCINumberAssign(errhp, s, d));
|
116
123
|
return obj;
|
117
124
|
}
|
118
125
|
|
@@ -136,10 +143,7 @@ VALUE oci8_make_integer(OCINumber *s, OCIError *errhp)
|
|
136
143
|
|
137
144
|
VALUE oci8_make_float(OCINumber *s, OCIError *errhp)
|
138
145
|
{
|
139
|
-
|
140
|
-
|
141
|
-
oci_lc(OCINumberToReal(errhp, s, sizeof(double), &dbl));
|
142
|
-
return rb_float_new(dbl);
|
146
|
+
return rb_float_new(oci8_onum_to_dbl(s, errhp));
|
143
147
|
}
|
144
148
|
|
145
149
|
/* fill C structure (OCINumber) from a string. */
|
@@ -180,7 +184,7 @@ static void set_oci_number_from_str(OCINumber *result, VALUE str, VALUE fmt, VAL
|
|
180
184
|
nls_params_ptr = RSTRING_ORATEXT(nls_params);
|
181
185
|
nls_params_len = RSTRING_LEN(nls_params);
|
182
186
|
}
|
183
|
-
|
187
|
+
chkerr(OCINumberFromText(errhp,
|
184
188
|
RSTRING_ORATEXT(str), RSTRING_LEN(str),
|
185
189
|
fmt_ptr, fmt_len, nls_params_ptr, nls_params_len,
|
186
190
|
result));
|
@@ -191,7 +195,6 @@ static void set_oci_number_from_str(OCINumber *result, VALUE str, VALUE fmt, VAL
|
|
191
195
|
static int set_oci_number_from_num(OCINumber *result, VALUE num, int force, OCIError *errhp)
|
192
196
|
{
|
193
197
|
signed long sl;
|
194
|
-
double dbl;
|
195
198
|
|
196
199
|
if (!RTEST(rb_obj_is_kind_of(num, rb_cNumeric)))
|
197
200
|
rb_raise(rb_eTypeError, "expect Numeric but %s", rb_class2name(CLASS_OF(num)));
|
@@ -202,12 +205,11 @@ static int set_oci_number_from_num(OCINumber *result, VALUE num, int force, OCIE
|
|
202
205
|
case T_FIXNUM:
|
203
206
|
/* set from long. */
|
204
207
|
sl = NUM2LONG(num);
|
205
|
-
|
208
|
+
chkerr(OCINumberFromInt(errhp, &sl, sizeof(sl), OCI_NUMBER_SIGNED, result));
|
206
209
|
return 1;
|
207
210
|
case T_FLOAT:
|
208
211
|
/* set from double. */
|
209
|
-
|
210
|
-
oci_lc(OCINumberFromReal(errhp, &dbl, sizeof(dbl), result));
|
212
|
+
oci8_dbl_to_onum(result, NUM2DBL(num), errhp);
|
211
213
|
return 1;
|
212
214
|
case T_BIGNUM:
|
213
215
|
/* change via string. */
|
@@ -217,7 +219,7 @@ static int set_oci_number_from_num(OCINumber *result, VALUE num, int force, OCIE
|
|
217
219
|
}
|
218
220
|
if (RTEST(rb_obj_is_instance_of(num, cOCINumber))) {
|
219
221
|
/* OCI::Number */
|
220
|
-
|
222
|
+
chkerr(OCINumberAssign(errhp, DATA_PTR(num), result));
|
221
223
|
return 1;
|
222
224
|
}
|
223
225
|
if (rb_respond_to(num, id_split)) {
|
@@ -255,23 +257,11 @@ static int set_oci_number_from_num(OCINumber *result, VALUE num, int force, OCIE
|
|
255
257
|
}
|
256
258
|
exponent = FIX2INT(ary[3]);
|
257
259
|
|
258
|
-
|
259
|
-
/* Oracle 8.1 or upper */
|
260
|
-
oci_lc(OCINumberShift(errhp, &digits, exponent - digits_len, &work));
|
261
|
-
} else {
|
262
|
-
/* Oracle 8.0 */
|
263
|
-
int n = 10;
|
264
|
-
OCINumber base;
|
265
|
-
OCINumber exp;
|
266
|
-
|
267
|
-
oci_lc(OCINumberFromInt(errhp, &n, sizeof(n), OCI_NUMBER_SIGNED, &base));
|
268
|
-
oci_lc(OCINumberIntPower(errhp, &base, exponent - digits_len, &exp));
|
269
|
-
oci_lc(OCINumberMul(errhp, &digits, &exp, &work));
|
270
|
-
}
|
260
|
+
chkerr(OCINumberShift(errhp, &digits, exponent - digits_len, &work));
|
271
261
|
if (sign >= 0) {
|
272
|
-
|
262
|
+
chkerr(OCINumberAssign(errhp, &work, result));
|
273
263
|
} else {
|
274
|
-
|
264
|
+
chkerr(OCINumberNeg(errhp, &work, result));
|
275
265
|
}
|
276
266
|
return 1;
|
277
267
|
}
|
@@ -284,7 +274,7 @@ is_not_big_decimal:
|
|
284
274
|
|
285
275
|
if (set_oci_number_from_num(&numerator, rb_funcall(num, id_numerator, 0), 0, errhp) &&
|
286
276
|
set_oci_number_from_num(&denominator, rb_funcall(num, id_denominator, 0), 0, errhp)) {
|
287
|
-
|
277
|
+
chkerr(OCINumberDiv(errhp, &numerator, &denominator, result));
|
288
278
|
return 1;
|
289
279
|
}
|
290
280
|
}
|
@@ -309,7 +299,65 @@ OCINumber *oci8_set_integer(OCINumber *result, VALUE self, OCIError *errhp)
|
|
309
299
|
OCINumber work;
|
310
300
|
|
311
301
|
set_oci_number_from_num(&work, self, 1, errhp);
|
312
|
-
|
302
|
+
chkerr(OCINumberTrunc(errhp, &work, 0, result));
|
303
|
+
return result;
|
304
|
+
}
|
305
|
+
|
306
|
+
double oci8_onum_to_dbl(OCINumber *s, OCIError *errhp)
|
307
|
+
{
|
308
|
+
if (oci8_float_conversion_type_is_ruby) {
|
309
|
+
char buf[256];
|
310
|
+
sword rv;
|
311
|
+
|
312
|
+
rv = oranumber_to_str(s, buf, sizeof(buf));
|
313
|
+
if (rv <= 0) {
|
314
|
+
char buf[ORANUMBER_DUMP_BUF_SIZ];
|
315
|
+
|
316
|
+
oranumber_dump(s, buf);
|
317
|
+
rb_raise(eOCIException, "Invalid internal number format: %s", buf);
|
318
|
+
}
|
319
|
+
if (strcmp(buf, "~") == 0) {
|
320
|
+
return INFINITY;
|
321
|
+
} else if (strcmp(buf, "-~") == 0) {
|
322
|
+
return -INFINITY;
|
323
|
+
}
|
324
|
+
return rb_cstr_to_dbl(buf, Qtrue);
|
325
|
+
} else {
|
326
|
+
double dbl;
|
327
|
+
|
328
|
+
chkerr(OCINumberToReal(errhp, s, sizeof(double), &dbl));
|
329
|
+
return dbl;
|
330
|
+
}
|
331
|
+
}
|
332
|
+
|
333
|
+
OCINumber *oci8_dbl_to_onum(OCINumber *result, double dbl, OCIError *errhp)
|
334
|
+
{
|
335
|
+
switch (fpclassify(dbl)) {
|
336
|
+
case FP_NAN:
|
337
|
+
rb_raise(rb_eFloatDomainError, "NaN");
|
338
|
+
/* never reach here */
|
339
|
+
break;
|
340
|
+
case FP_INFINITE:
|
341
|
+
if (dbl > 0.0) {
|
342
|
+
oranumber_from_str(result, "~", 1);
|
343
|
+
} else {
|
344
|
+
oranumber_from_str(result, "-~", 2);
|
345
|
+
}
|
346
|
+
return result;
|
347
|
+
}
|
348
|
+
|
349
|
+
if (oci8_float_conversion_type_is_ruby) {
|
350
|
+
VALUE str;
|
351
|
+
sword rv;
|
352
|
+
|
353
|
+
str = rb_obj_as_string(rb_float_new(dbl));
|
354
|
+
rv = oranumber_from_str(result, RSTRING_PTR(str), RSTRING_LEN(str));
|
355
|
+
if (rv != 0) {
|
356
|
+
oci8_raise_by_msgno(rv, NULL);
|
357
|
+
}
|
358
|
+
} else {
|
359
|
+
chkerr(OCINumberFromReal(errhp, &dbl, sizeof(dbl), result));
|
360
|
+
}
|
313
361
|
return result;
|
314
362
|
}
|
315
363
|
|
@@ -332,9 +380,9 @@ static VALUE omath_atan2(VALUE self, VALUE Ycoordinate, VALUE Xcoordinate)
|
|
332
380
|
set_oci_number_from_num(&nX, Xcoordinate, 1, errhp);
|
333
381
|
set_oci_number_from_num(&nY, Ycoordinate, 1, errhp);
|
334
382
|
/* check zero */
|
335
|
-
|
383
|
+
chkerr(OCINumberIsZero(errhp, &nX, &is_zero));
|
336
384
|
if (is_zero) {
|
337
|
-
|
385
|
+
chkerr(OCINumberSign(errhp, &nY, &sign));
|
338
386
|
switch (sign) {
|
339
387
|
case 0:
|
340
388
|
return INT2FIX(0); /* atan2(0, 0) => 0 or ERROR? */
|
@@ -345,7 +393,7 @@ static VALUE omath_atan2(VALUE self, VALUE Ycoordinate, VALUE Xcoordinate)
|
|
345
393
|
}
|
346
394
|
}
|
347
395
|
/* atan2 */
|
348
|
-
|
396
|
+
chkerr(OCINumberArcTan2(errhp, &nY, &nX, &rv));
|
349
397
|
return oci8_make_ocinumber(&rv, errhp);
|
350
398
|
}
|
351
399
|
|
@@ -362,7 +410,7 @@ static VALUE omath_cos(VALUE obj, VALUE radian)
|
|
362
410
|
OCINumber r;
|
363
411
|
OCINumber rv;
|
364
412
|
|
365
|
-
|
413
|
+
chkerr(OCINumberCos(errhp, TO_OCINUM(&r, radian, errhp), &rv));
|
366
414
|
return oci8_make_ocinumber(&rv, errhp);
|
367
415
|
}
|
368
416
|
|
@@ -379,7 +427,7 @@ static VALUE omath_sin(VALUE obj, VALUE radian)
|
|
379
427
|
OCINumber r;
|
380
428
|
OCINumber rv;
|
381
429
|
|
382
|
-
|
430
|
+
chkerr(OCINumberSin(errhp, TO_OCINUM(&r, radian, errhp), &rv));
|
383
431
|
return oci8_make_ocinumber(&rv, errhp);
|
384
432
|
}
|
385
433
|
|
@@ -395,7 +443,7 @@ static VALUE omath_tan(VALUE obj, VALUE radian)
|
|
395
443
|
OCINumber r;
|
396
444
|
OCINumber rv;
|
397
445
|
|
398
|
-
|
446
|
+
chkerr(OCINumberTan(errhp, TO_OCINUM(&r, radian, errhp), &rv));
|
399
447
|
return oci8_make_ocinumber(&rv, errhp);
|
400
448
|
}
|
401
449
|
|
@@ -414,15 +462,15 @@ static VALUE omath_acos(VALUE obj, VALUE num)
|
|
414
462
|
|
415
463
|
set_oci_number_from_num(&n, num, 1, errhp);
|
416
464
|
/* check upper bound */
|
417
|
-
|
465
|
+
chkerr(OCINumberCmp(errhp, &n, &const_p1, &sign));
|
418
466
|
if (sign > 0)
|
419
467
|
rb_raise(rb_eRangeError, "out of range for acos");
|
420
468
|
/* check lower bound */
|
421
|
-
|
469
|
+
chkerr(OCINumberCmp(errhp, &n, &const_m1, &sign));
|
422
470
|
if (sign < 0)
|
423
471
|
rb_raise(rb_eRangeError, "out of range for acos");
|
424
472
|
/* acos */
|
425
|
-
|
473
|
+
chkerr(OCINumberArcCos(errhp, &n, &r));
|
426
474
|
return oci8_make_ocinumber(&r, errhp);
|
427
475
|
}
|
428
476
|
|
@@ -441,15 +489,15 @@ static VALUE omath_asin(VALUE obj, VALUE num)
|
|
441
489
|
|
442
490
|
set_oci_number_from_num(&n, num, 1, errhp);
|
443
491
|
/* check upper bound */
|
444
|
-
|
492
|
+
chkerr(OCINumberCmp(errhp, &n, &const_p1, &sign));
|
445
493
|
if (sign > 0)
|
446
494
|
rb_raise(rb_eRangeError, "out of range for asin");
|
447
495
|
/* check lower bound */
|
448
|
-
|
496
|
+
chkerr(OCINumberCmp(errhp, &n, &const_m1, &sign));
|
449
497
|
if (sign < 0)
|
450
498
|
rb_raise(rb_eRangeError, "out of range for asin");
|
451
499
|
/* asin */
|
452
|
-
|
500
|
+
chkerr(OCINumberArcSin(errhp, &n, &r));
|
453
501
|
return oci8_make_ocinumber(&r, errhp);
|
454
502
|
}
|
455
503
|
|
@@ -465,7 +513,7 @@ static VALUE omath_atan(VALUE obj, VALUE num)
|
|
465
513
|
OCINumber n;
|
466
514
|
OCINumber r;
|
467
515
|
|
468
|
-
|
516
|
+
chkerr(OCINumberArcTan(errhp, TO_OCINUM(&n, num, errhp), &r));
|
469
517
|
return oci8_make_ocinumber(&r, errhp);
|
470
518
|
}
|
471
519
|
|
@@ -481,7 +529,7 @@ static VALUE omath_cosh(VALUE obj, VALUE num)
|
|
481
529
|
OCINumber n;
|
482
530
|
OCINumber r;
|
483
531
|
|
484
|
-
|
532
|
+
chkerr(OCINumberHypCos(errhp, TO_OCINUM(&n, num, errhp), &r));
|
485
533
|
return oci8_make_ocinumber(&r, errhp);
|
486
534
|
}
|
487
535
|
|
@@ -498,7 +546,7 @@ static VALUE omath_sinh(VALUE obj, VALUE num)
|
|
498
546
|
OCINumber n;
|
499
547
|
OCINumber r;
|
500
548
|
|
501
|
-
|
549
|
+
chkerr(OCINumberHypSin(errhp, TO_OCINUM(&n, num, errhp), &r));
|
502
550
|
return oci8_make_ocinumber(&r, errhp);
|
503
551
|
}
|
504
552
|
|
@@ -515,7 +563,7 @@ static VALUE omath_tanh(VALUE obj, VALUE num)
|
|
515
563
|
OCINumber n;
|
516
564
|
OCINumber r;
|
517
565
|
|
518
|
-
|
566
|
+
chkerr(OCINumberHypTan(errhp, TO_OCINUM(&n, num, errhp), &r));
|
519
567
|
return oci8_make_ocinumber(&r, errhp);
|
520
568
|
}
|
521
569
|
|
@@ -531,7 +579,7 @@ static VALUE omath_exp(VALUE obj, VALUE num)
|
|
531
579
|
OCINumber n;
|
532
580
|
OCINumber r;
|
533
581
|
|
534
|
-
|
582
|
+
chkerr(OCINumberExp(errhp, TO_OCINUM(&n, num, errhp), &r));
|
535
583
|
return oci8_make_ocinumber(&r, errhp);
|
536
584
|
}
|
537
585
|
|
@@ -554,20 +602,20 @@ static VALUE omath_log(int argc, VALUE *argv, VALUE obj)
|
|
554
602
|
|
555
603
|
rb_scan_args(argc, argv, "11", &num, &base);
|
556
604
|
set_oci_number_from_num(&n, num, 1, errhp);
|
557
|
-
|
605
|
+
chkerr(OCINumberSign(errhp, &n, &sign));
|
558
606
|
if (sign <= 0)
|
559
607
|
rb_raise(rb_eRangeError, "nonpositive value for log");
|
560
608
|
if (NIL_P(base)) {
|
561
|
-
|
609
|
+
chkerr(OCINumberLn(errhp, &n, &r));
|
562
610
|
} else {
|
563
611
|
set_oci_number_from_num(&b, base, 1, errhp);
|
564
|
-
|
612
|
+
chkerr(OCINumberSign(errhp, &b, &sign));
|
565
613
|
if (sign <= 0)
|
566
614
|
rb_raise(rb_eRangeError, "nonpositive value for the base of log");
|
567
|
-
|
615
|
+
chkerr(OCINumberCmp(errhp, &b, &const_p1, &sign));
|
568
616
|
if (sign == 0)
|
569
617
|
rb_raise(rb_eRangeError, "base 1 for log");
|
570
|
-
|
618
|
+
chkerr(OCINumberLog(errhp, &b, &n, &r));
|
571
619
|
}
|
572
620
|
return oci8_make_ocinumber(&r, errhp);
|
573
621
|
}
|
@@ -586,10 +634,10 @@ static VALUE omath_log10(VALUE obj, VALUE num)
|
|
586
634
|
sword sign;
|
587
635
|
|
588
636
|
set_oci_number_from_num(&n, num, 1, errhp);
|
589
|
-
|
637
|
+
chkerr(OCINumberSign(errhp, &n, &sign));
|
590
638
|
if (sign <= 0)
|
591
639
|
rb_raise(rb_eRangeError, "nonpositive value for log10");
|
592
|
-
|
640
|
+
chkerr(OCINumberLog(errhp, &const_p10, &n, &r));
|
593
641
|
return oci8_make_ocinumber(&r, errhp);
|
594
642
|
}
|
595
643
|
|
@@ -608,12 +656,12 @@ static VALUE omath_sqrt(VALUE obj, VALUE num)
|
|
608
656
|
|
609
657
|
set_oci_number_from_num(&n, num, 1, errhp);
|
610
658
|
/* check whether num is negative */
|
611
|
-
|
659
|
+
chkerr(OCINumberSign(errhp, &n, &sign));
|
612
660
|
if (sign < 0) {
|
613
661
|
errno = EDOM;
|
614
662
|
rb_sys_fail("sqrt");
|
615
663
|
}
|
616
|
-
|
664
|
+
chkerr(OCINumberSqrt(errhp, &n, &r));
|
617
665
|
return oci8_make_ocinumber(&r, errhp);
|
618
666
|
}
|
619
667
|
|
@@ -654,7 +702,7 @@ static VALUE onum_initialize_copy(VALUE lhs, VALUE rhs)
|
|
654
702
|
rb_raise(rb_eTypeError, "invalid type: expected %s but %s",
|
655
703
|
rb_class2name(CLASS_OF(lhs)), rb_class2name(CLASS_OF(rhs)));
|
656
704
|
}
|
657
|
-
|
705
|
+
chkerr(OCINumberAssign(oci8_errhp, _NUMBER(rhs), _NUMBER(lhs)));
|
658
706
|
return lhs;
|
659
707
|
}
|
660
708
|
|
@@ -666,7 +714,7 @@ static VALUE onum_coerce(VALUE self, VALUE other)
|
|
666
714
|
switch(rboci8_type(other)) {
|
667
715
|
case T_FIXNUM:
|
668
716
|
sl = NUM2LONG(other);
|
669
|
-
|
717
|
+
chkerr(OCINumberFromInt(oci8_errhp, &sl, sizeof(sl), OCI_NUMBER_SIGNED, &n));
|
670
718
|
return rb_assoc_new(oci8_make_ocinumber(&n, oci8_errhp), self);
|
671
719
|
case T_BIGNUM:
|
672
720
|
/* change via string. */
|
@@ -695,7 +743,7 @@ static VALUE onum_neg(VALUE self)
|
|
695
743
|
OCIError *errhp = oci8_errhp;
|
696
744
|
OCINumber r;
|
697
745
|
|
698
|
-
|
746
|
+
chkerr(OCINumberNeg(errhp, _NUMBER(self), &r));
|
699
747
|
return oci8_make_ocinumber(&r, errhp);
|
700
748
|
}
|
701
749
|
|
@@ -716,12 +764,12 @@ static VALUE onum_add(VALUE lhs, VALUE rhs)
|
|
716
764
|
case T_FIXNUM:
|
717
765
|
case T_BIGNUM:
|
718
766
|
if (set_oci_number_from_num(&n, rhs, 0, errhp)) {
|
719
|
-
|
767
|
+
chkerr(OCINumberAdd(errhp, _NUMBER(lhs), &n, &r));
|
720
768
|
return oci8_make_ocinumber(&r, errhp);
|
721
769
|
}
|
722
770
|
break;
|
723
771
|
case RBOCI8_T_ORANUMBER:
|
724
|
-
|
772
|
+
chkerr(OCINumberAdd(errhp, _NUMBER(lhs), _NUMBER(rhs), &r));
|
725
773
|
return oci8_make_ocinumber(&r, errhp);
|
726
774
|
case T_FLOAT:
|
727
775
|
return rb_funcall(onum_to_f(lhs), oci8_id_add_op, 1, rhs);
|
@@ -750,12 +798,12 @@ static VALUE onum_sub(VALUE lhs, VALUE rhs)
|
|
750
798
|
case T_FIXNUM:
|
751
799
|
case T_BIGNUM:
|
752
800
|
if (set_oci_number_from_num(&n, rhs, 0, errhp)) {
|
753
|
-
|
801
|
+
chkerr(OCINumberSub(errhp, _NUMBER(lhs), &n, &r));
|
754
802
|
return oci8_make_ocinumber(&r, errhp);
|
755
803
|
}
|
756
804
|
break;
|
757
805
|
case RBOCI8_T_ORANUMBER:
|
758
|
-
|
806
|
+
chkerr(OCINumberSub(errhp, _NUMBER(lhs), _NUMBER(rhs), &r));
|
759
807
|
return oci8_make_ocinumber(&r, errhp);
|
760
808
|
case T_FLOAT:
|
761
809
|
return rb_funcall(onum_to_f(lhs), oci8_id_sub_op, 1, rhs);
|
@@ -783,12 +831,12 @@ static VALUE onum_mul(VALUE lhs, VALUE rhs)
|
|
783
831
|
case T_FIXNUM:
|
784
832
|
case T_BIGNUM:
|
785
833
|
if (set_oci_number_from_num(&n, rhs, 0, errhp)) {
|
786
|
-
|
834
|
+
chkerr(OCINumberMul(errhp, _NUMBER(lhs), &n, &r));
|
787
835
|
return oci8_make_ocinumber(&r, errhp);
|
788
836
|
}
|
789
837
|
break;
|
790
838
|
case RBOCI8_T_ORANUMBER:
|
791
|
-
|
839
|
+
chkerr(OCINumberMul(errhp, _NUMBER(lhs), _NUMBER(rhs), &r));
|
792
840
|
return oci8_make_ocinumber(&r, errhp);
|
793
841
|
case T_FLOAT:
|
794
842
|
return rb_funcall(onum_to_f(lhs), oci8_id_mul_op, 1, rhs);
|
@@ -821,16 +869,16 @@ static VALUE onum_div(VALUE lhs, VALUE rhs)
|
|
821
869
|
}
|
822
870
|
case T_BIGNUM:
|
823
871
|
if (set_oci_number_from_num(&n, rhs, 0, errhp)) {
|
824
|
-
|
872
|
+
chkerr(OCINumberDiv(errhp, _NUMBER(lhs), &n, &r));
|
825
873
|
return oci8_make_ocinumber(&r, errhp);
|
826
874
|
}
|
827
875
|
break;
|
828
876
|
case RBOCI8_T_ORANUMBER:
|
829
|
-
|
877
|
+
chkerr(OCINumberIsZero(errhp, _NUMBER(rhs), &is_zero));
|
830
878
|
if (is_zero) {
|
831
879
|
rb_num_zerodiv();
|
832
880
|
}
|
833
|
-
|
881
|
+
chkerr(OCINumberDiv(errhp, _NUMBER(lhs), _NUMBER(rhs), &r));
|
834
882
|
return oci8_make_ocinumber(&r, errhp);
|
835
883
|
case T_FLOAT:
|
836
884
|
return rb_funcall(onum_to_f(lhs), oci8_id_div_op, 1, rhs);
|
@@ -859,11 +907,11 @@ static VALUE onum_mod(VALUE lhs, VALUE rhs)
|
|
859
907
|
if (!set_oci_number_from_num(&n, rhs, 0, errhp))
|
860
908
|
return rb_num_coerce_bin(lhs, rhs, '%');
|
861
909
|
/* check whether argument is not zero. */
|
862
|
-
|
910
|
+
chkerr(OCINumberIsZero(errhp, &n, &is_zero));
|
863
911
|
if (is_zero)
|
864
912
|
rb_num_zerodiv();
|
865
913
|
/* modulo */
|
866
|
-
|
914
|
+
chkerr(OCINumberMod(errhp, _NUMBER(lhs), &n, &r));
|
867
915
|
return oci8_make_ocinumber(&r, errhp);
|
868
916
|
}
|
869
917
|
|
@@ -880,12 +928,12 @@ static VALUE onum_power(VALUE lhs, VALUE rhs)
|
|
880
928
|
OCINumber r;
|
881
929
|
|
882
930
|
if (FIXNUM_P(rhs)) {
|
883
|
-
|
931
|
+
chkerr(OCINumberIntPower(errhp, _NUMBER(lhs), FIX2INT(rhs), &r));
|
884
932
|
} else {
|
885
933
|
/* change to OCINumber */
|
886
934
|
if (!set_oci_number_from_num(&n, rhs, 0, errhp))
|
887
935
|
return rb_num_coerce_bin(lhs, rhs, id_power);
|
888
|
-
|
936
|
+
chkerr(OCINumberPower(errhp, _NUMBER(lhs), &n, &r));
|
889
937
|
}
|
890
938
|
return oci8_make_ocinumber(&r, errhp);
|
891
939
|
}
|
@@ -908,7 +956,7 @@ static VALUE onum_cmp(VALUE lhs, VALUE rhs)
|
|
908
956
|
if (!set_oci_number_from_num(&n, rhs, 0, errhp))
|
909
957
|
return rb_num_coerce_cmp(lhs, rhs, id_cmp);
|
910
958
|
/* compare */
|
911
|
-
|
959
|
+
chkerr(OCINumberCmp(errhp, _NUMBER(lhs), &n, &r));
|
912
960
|
if (r > 0) {
|
913
961
|
return INT2FIX(1);
|
914
962
|
} else if (r == 0) {
|
@@ -929,7 +977,7 @@ static VALUE onum_floor(VALUE self)
|
|
929
977
|
OCIError *errhp = oci8_errhp;
|
930
978
|
OCINumber r;
|
931
979
|
|
932
|
-
|
980
|
+
chkerr(OCINumberFloor(errhp, _NUMBER(self), &r));
|
933
981
|
return oci8_make_integer(&r, errhp);
|
934
982
|
}
|
935
983
|
|
@@ -945,7 +993,7 @@ static VALUE onum_ceil(VALUE self)
|
|
945
993
|
OCIError *errhp = oci8_errhp;
|
946
994
|
OCINumber r;
|
947
995
|
|
948
|
-
|
996
|
+
chkerr(OCINumberCeil(errhp, _NUMBER(self), &r));
|
949
997
|
return oci8_make_integer(&r, errhp);
|
950
998
|
}
|
951
999
|
|
@@ -968,7 +1016,7 @@ static VALUE onum_round(int argc, VALUE *argv, VALUE self)
|
|
968
1016
|
OCINumber r;
|
969
1017
|
|
970
1018
|
rb_scan_args(argc, argv, "01", &decplace /* 0 */);
|
971
|
-
|
1019
|
+
chkerr(OCINumberRound(errhp, _NUMBER(self), NIL_P(decplace) ? 0 : NUM2INT(decplace), &r));
|
972
1020
|
if (argc == 0) {
|
973
1021
|
return oci8_make_integer(&r, errhp);
|
974
1022
|
} else {
|
@@ -991,7 +1039,7 @@ static VALUE onum_trunc(int argc, VALUE *argv, VALUE self)
|
|
991
1039
|
OCINumber r;
|
992
1040
|
|
993
1041
|
rb_scan_args(argc, argv, "01", &decplace /* 0 */);
|
994
|
-
|
1042
|
+
chkerr(OCINumberTrunc(errhp, _NUMBER(self), NIL_P(decplace) ? 0 : NUM2INT(decplace), &r));
|
995
1043
|
return oci8_make_ocinumber(&r, errhp);
|
996
1044
|
}
|
997
1045
|
|
@@ -1011,7 +1059,7 @@ static VALUE onum_round_prec(VALUE self, VALUE ndigs)
|
|
1011
1059
|
OCIError *errhp = oci8_errhp;
|
1012
1060
|
OCINumber r;
|
1013
1061
|
|
1014
|
-
|
1062
|
+
chkerr(OCINumberPrec(errhp, _NUMBER(self), NUM2INT(ndigs), &r));
|
1015
1063
|
return oci8_make_ocinumber(&r, errhp);
|
1016
1064
|
}
|
1017
1065
|
|
@@ -1067,7 +1115,7 @@ static VALUE onum_to_char(int argc, VALUE *argv, VALUE self)
|
|
1067
1115
|
if (NIL_P(fmt)) /* implicit conversion */
|
1068
1116
|
return rb_usascii_str_new_cstr("overflow");
|
1069
1117
|
}
|
1070
|
-
|
1118
|
+
chkerr(rv);
|
1071
1119
|
}
|
1072
1120
|
return rb_usascii_str_new(buf, buf_size);
|
1073
1121
|
}
|
@@ -1094,7 +1142,7 @@ static VALUE onum_to_i(VALUE self)
|
|
1094
1142
|
OCIError *errhp = oci8_errhp;
|
1095
1143
|
OCINumber num;
|
1096
1144
|
|
1097
|
-
|
1145
|
+
chkerr(OCINumberTrunc(errhp, _NUMBER(self), 0, &num));
|
1098
1146
|
return oci8_make_integer(&num, errhp);
|
1099
1147
|
}
|
1100
1148
|
|
@@ -1107,11 +1155,7 @@ static VALUE onum_to_i(VALUE self)
|
|
1107
1155
|
*/
|
1108
1156
|
static VALUE onum_to_f(VALUE self)
|
1109
1157
|
{
|
1110
|
-
|
1111
|
-
double dbl;
|
1112
|
-
|
1113
|
-
oci_lc(OCINumberToReal(errhp, _NUMBER(self), sizeof(dbl), &dbl));
|
1114
|
-
return rb_float_new(dbl);
|
1158
|
+
return rb_float_new(oci8_onum_to_dbl(_NUMBER(self), oci8_errhp));
|
1115
1159
|
}
|
1116
1160
|
|
1117
1161
|
/*
|
@@ -1129,15 +1173,15 @@ static VALUE onum_to_r(VALUE self)
|
|
1129
1173
|
int current = 0;
|
1130
1174
|
boolean is_int;
|
1131
1175
|
|
1132
|
-
|
1176
|
+
chkerr(OCINumberAssign(oci8_errhp, _NUMBER(self), &onum[0]));
|
1133
1177
|
|
1134
1178
|
for (;;) {
|
1135
|
-
|
1179
|
+
chkerr(OCINumberIsInt(oci8_errhp, &onum[current], &is_int));
|
1136
1180
|
if (is_int) {
|
1137
1181
|
break;
|
1138
1182
|
}
|
1139
1183
|
nshift++;
|
1140
|
-
|
1184
|
+
chkerr(OCINumberShift(oci8_errhp, &onum[current], 1, &onum[1 - current]));
|
1141
1185
|
current = 1 - current;
|
1142
1186
|
}
|
1143
1187
|
x = oci8_make_integer(&onum[current], oci8_errhp);
|
@@ -1180,7 +1224,7 @@ static VALUE onum_to_d_real(OCINumber *num, OCIError *errhp)
|
|
1180
1224
|
rb_require("bigdecimal");
|
1181
1225
|
cBigDecimal = rb_const_get(rb_cObject, id_BigDecimal);
|
1182
1226
|
}
|
1183
|
-
|
1227
|
+
chkerr(OCINumberToText(errhp, num, (const oratext *)fmt, strlen(fmt),
|
1184
1228
|
NULL, 0, &buf_size, TO_ORATEXT(buf)));
|
1185
1229
|
return rb_funcall(rb_cObject, id_BigDecimal, 1, rb_usascii_str_new(buf, buf_size));
|
1186
1230
|
}
|
@@ -1199,7 +1243,7 @@ static VALUE onum_has_decimal_part_p(VALUE self)
|
|
1199
1243
|
OCIError *errhp = oci8_errhp;
|
1200
1244
|
boolean result;
|
1201
1245
|
|
1202
|
-
|
1246
|
+
chkerr(OCINumberIsInt(errhp, _NUMBER(self), &result));
|
1203
1247
|
return result ? Qfalse : Qtrue;
|
1204
1248
|
}
|
1205
1249
|
|
@@ -1227,7 +1271,7 @@ static VALUE onum_zero_p(VALUE self)
|
|
1227
1271
|
OCIError *errhp = oci8_errhp;
|
1228
1272
|
boolean result;
|
1229
1273
|
|
1230
|
-
|
1274
|
+
chkerr(OCINumberIsZero(errhp, _NUMBER(self), &result));
|
1231
1275
|
return result ? Qtrue : Qfalse;
|
1232
1276
|
}
|
1233
1277
|
|
@@ -1243,7 +1287,7 @@ static VALUE onum_abs(VALUE self)
|
|
1243
1287
|
OCIError *errhp = oci8_errhp;
|
1244
1288
|
OCINumber result;
|
1245
1289
|
|
1246
|
-
|
1290
|
+
chkerr(OCINumberAbs(errhp, _NUMBER(self), &result));
|
1247
1291
|
return oci8_make_ocinumber(&result, errhp);
|
1248
1292
|
}
|
1249
1293
|
|
@@ -1259,7 +1303,7 @@ static VALUE onum_shift(VALUE self, VALUE exp)
|
|
1259
1303
|
OCIError *errhp = oci8_errhp;
|
1260
1304
|
OCINumber result;
|
1261
1305
|
|
1262
|
-
|
1306
|
+
chkerr(OCINumberShift(errhp, _NUMBER(self), NUM2INT(exp), &result));
|
1263
1307
|
return oci8_make_ocinumber(&result, errhp);
|
1264
1308
|
}
|
1265
1309
|
|
@@ -1285,7 +1329,7 @@ static VALUE onum_hash(VALUE self)
|
|
1285
1329
|
{
|
1286
1330
|
char *c = DATA_PTR(self);
|
1287
1331
|
int size = c[0] + 1;
|
1288
|
-
|
1332
|
+
long i, hash;
|
1289
1333
|
|
1290
1334
|
/* assert(size <= 22); ?*/
|
1291
1335
|
if (size > 22)
|
@@ -1336,13 +1380,13 @@ static VALUE
|
|
1336
1380
|
onum_s_load(VALUE klass, VALUE str)
|
1337
1381
|
{
|
1338
1382
|
unsigned char *c;
|
1339
|
-
|
1383
|
+
size_t size;
|
1340
1384
|
OCINumber num;
|
1341
1385
|
|
1342
1386
|
Check_Type(str, T_STRING);
|
1343
1387
|
c = RSTRING_ORATEXT(str);
|
1344
1388
|
size = RSTRING_LEN(str);
|
1345
|
-
if (size == 0 || size != c[0] +
|
1389
|
+
if (size == 0 || size != c[0] + 1u || size > sizeof(num)) {
|
1346
1390
|
rb_raise(rb_eTypeError, "marshaled OCI::Number format differ");
|
1347
1391
|
}
|
1348
1392
|
memset(&num, 0, sizeof(num));
|
@@ -1363,6 +1407,11 @@ static VALUE bind_integer_get(oci8_bind_t *obind, void *data, void *null_struct)
|
|
1363
1407
|
return oci8_make_integer((OCINumber*)data, oci8_errhp);
|
1364
1408
|
}
|
1365
1409
|
|
1410
|
+
static VALUE bind_float_get(oci8_bind_t *obind, void *data, void *null_struct)
|
1411
|
+
{
|
1412
|
+
return oci8_make_float((OCINumber*)data, oci8_errhp);
|
1413
|
+
}
|
1414
|
+
|
1366
1415
|
static void bind_ocinumber_set(oci8_bind_t *obind, void *data, void **null_structp, VALUE val)
|
1367
1416
|
{
|
1368
1417
|
set_oci_number_from_num((OCINumber*)data, val, 1, oci8_errhp);
|
@@ -1374,7 +1423,8 @@ static void bind_integer_set(oci8_bind_t *obind, void *data, void **null_structp
|
|
1374
1423
|
OCINumber num;
|
1375
1424
|
|
1376
1425
|
set_oci_number_from_num(&num, val, 1, errhp);
|
1377
|
-
|
1426
|
+
chker2(OCINumberTrunc(errhp, &num, 0, (OCINumber*)data),
|
1427
|
+
&obind->base);
|
1378
1428
|
}
|
1379
1429
|
|
1380
1430
|
static void bind_ocinumber_init(oci8_bind_t *obind, VALUE svc, VALUE val, VALUE length)
|
@@ -1393,7 +1443,7 @@ static void bind_ocinumber_init_elem(oci8_bind_t *obind, VALUE svc)
|
|
1393
1443
|
} while (++idx < obind->maxar_sz);
|
1394
1444
|
}
|
1395
1445
|
|
1396
|
-
static const
|
1446
|
+
static const oci8_bind_vtable_t bind_ocinumber_vtable = {
|
1397
1447
|
{
|
1398
1448
|
NULL,
|
1399
1449
|
oci8_bind_free,
|
@@ -1404,12 +1454,10 @@ static const oci8_bind_class_t bind_ocinumber_class = {
|
|
1404
1454
|
bind_ocinumber_init,
|
1405
1455
|
bind_ocinumber_init_elem,
|
1406
1456
|
NULL,
|
1407
|
-
NULL,
|
1408
|
-
NULL,
|
1409
1457
|
SQLT_VNU,
|
1410
1458
|
};
|
1411
1459
|
|
1412
|
-
static const
|
1460
|
+
static const oci8_bind_vtable_t bind_integer_vtable = {
|
1413
1461
|
{
|
1414
1462
|
NULL,
|
1415
1463
|
oci8_bind_free,
|
@@ -1420,7 +1468,19 @@ static const oci8_bind_class_t bind_integer_class = {
|
|
1420
1468
|
bind_ocinumber_init,
|
1421
1469
|
bind_ocinumber_init_elem,
|
1422
1470
|
NULL,
|
1423
|
-
|
1471
|
+
SQLT_VNU,
|
1472
|
+
};
|
1473
|
+
|
1474
|
+
static const oci8_bind_vtable_t bind_float_vtable = {
|
1475
|
+
{
|
1476
|
+
NULL,
|
1477
|
+
oci8_bind_free,
|
1478
|
+
sizeof(oci8_bind_t)
|
1479
|
+
},
|
1480
|
+
bind_float_get,
|
1481
|
+
bind_ocinumber_set,
|
1482
|
+
bind_ocinumber_init,
|
1483
|
+
bind_ocinumber_init_elem,
|
1424
1484
|
NULL,
|
1425
1485
|
SQLT_VNU,
|
1426
1486
|
};
|
@@ -1515,9 +1575,7 @@ Init_oci_number(VALUE cOCI8, OCIError *errhp)
|
|
1515
1575
|
rb_define_method(cOCINumber, "ceil", onum_ceil, 0);
|
1516
1576
|
rb_define_method(cOCINumber, "round", onum_round, -1);
|
1517
1577
|
rb_define_method(cOCINumber, "truncate", onum_trunc, -1);
|
1518
|
-
|
1519
|
-
rb_define_method(cOCINumber, "round_prec", onum_round_prec, 1);
|
1520
|
-
}
|
1578
|
+
rb_define_method(cOCINumber, "round_prec", onum_round_prec, 1);
|
1521
1579
|
|
1522
1580
|
rb_define_method(cOCINumber, "to_s", onum_to_s, 0);
|
1523
1581
|
rb_define_method(cOCINumber, "to_char", onum_to_char, -1);
|
@@ -1530,9 +1588,7 @@ Init_oci_number(VALUE cOCI8, OCIError *errhp)
|
|
1530
1588
|
|
1531
1589
|
rb_define_method(cOCINumber, "zero?", onum_zero_p, 0);
|
1532
1590
|
rb_define_method(cOCINumber, "abs", onum_abs, 0);
|
1533
|
-
|
1534
|
-
rb_define_method(cOCINumber, "shift", onum_shift, 1);
|
1535
|
-
}
|
1591
|
+
rb_define_method(cOCINumber, "shift", onum_shift, 1);
|
1536
1592
|
rb_define_method(cOCINumber, "dump", onum_dump, 0);
|
1537
1593
|
|
1538
1594
|
rb_define_method_nodoc(cOCINumber, "hash", onum_hash, 0);
|
@@ -1542,8 +1598,9 @@ Init_oci_number(VALUE cOCI8, OCIError *errhp)
|
|
1542
1598
|
rb_define_method(cOCINumber, "_dump", onum__dump, -1);
|
1543
1599
|
rb_define_singleton_method(cOCINumber, "_load", onum_s_load, 1);
|
1544
1600
|
|
1545
|
-
oci8_define_bind_class("OraNumber", &
|
1546
|
-
oci8_define_bind_class("Integer", &
|
1601
|
+
oci8_define_bind_class("OraNumber", &bind_ocinumber_vtable);
|
1602
|
+
oci8_define_bind_class("Integer", &bind_integer_vtable);
|
1603
|
+
oci8_define_bind_class("Float", &bind_float_vtable);
|
1547
1604
|
}
|
1548
1605
|
|
1549
1606
|
OCINumber *oci8_get_ocinumber(VALUE num)
|