/* * call-seq: * onum.to_r -> rational * * Return the value as a <code>Rational</code>. * */ static VALUE onum_to_r(VALUE self) { VALUE x, y; int nshift = 0; OCINumber onum[2]; int current = 0; boolean is_int; chkerr(OCINumberAssign(oci8_errhp, _NUMBER(self), &onum[0])); for (;;) { chkerr(OCINumberIsInt(oci8_errhp, &onum[current], &is_int)); if (is_int) { break; } nshift++; chkerr(OCINumberShift(oci8_errhp, &onum[current], 1, &onum[1 - current])); current = 1 - current; } x = oci8_make_integer(&onum[current], oci8_errhp); if (nshift == 0) { y = INT2FIX(1); } else { y = rb_funcall(INT2FIX(10), rb_intern("**"), 1, INT2FIX(nshift)); } #ifdef T_RATIONAL return rb_Rational(x, y); #else if (!cRational) { rb_require("rational"); cRational = rb_const_get(rb_cObject, id_Rational); } return rb_funcall(rb_cObject, id_Rational, 2, x, y); #endif }
/* * call-seq: * onum.ceil -> integer * * Returns the smallest <code>Integer</code> greater than or equal to * <i>onum</i>. */ static VALUE onum_ceil(VALUE self) { OCIError *errhp = oci8_errhp; OCINumber r; chkerr(OCINumberCeil(errhp, _NUMBER(self), &r)); return oci8_make_integer(&r, errhp); }
/* * call-seq: * onum.to_i -> integer * * Returns <i>onum</i> truncated to an <code>Integer</code>. */ static VALUE onum_to_i(VALUE self) { OCIError *errhp = oci8_errhp; OCINumber num; chkerr(OCINumberTrunc(errhp, _NUMBER(self), 0, &num)); return oci8_make_integer(&num, errhp); }
/* * call-seq: * onum.floor -> integer * * Returns the largest <code>Integer</code> less than or equal to <i>onum</i>. */ static VALUE onum_floor(VALUE self) { OCIError *errhp = oci8_errhp; OCINumber r; oci_lc(OCINumberFloor(errhp, _NUMBER(self), &r)); return oci8_make_integer(&r, errhp); }
/* * call-seq: * onum.round -> integer * onum.round(decplace) -> oranumber * * Rounds <i>onum</i> to the nearest <code>Integer</code> when no argument. * Rounds <i>onum</i> to a specified decimal place <i>decplace</i> when one argument. * * OraNumber.new(1.234).round(1) #=> 1.2 * OraNumber.new(1.234).round(2) #=> 1.23 * OraNumber.new(1.234).round(3) #=> 1.234 */ static VALUE onum_round(int argc, VALUE *argv, VALUE self) { OCIError *errhp = oci8_errhp; VALUE decplace; OCINumber r; rb_scan_args(argc, argv, "01", &decplace /* 0 */); chkerr(OCINumberRound(errhp, _NUMBER(self), NIL_P(decplace) ? 0 : NUM2INT(decplace), &r)); if (argc == 0) { return oci8_make_integer(&r, errhp); } else { return oci8_make_ocinumber(&r, errhp); } }
/* * call-seq: * attr_get_integer(attr_type) -> integer * * <b>(new in 2.0.4)</b> * * Gets the value of an attribute as `ub1 *' datatype. * The return value is converted to Integer from internal Oracle NUMBER format. * * <b>Caution:</b> If the specified attr_type's datatype is not a * pointer type, it causes a segmentation fault. */ static VALUE attr_get_integer(VALUE self, VALUE attr_type) { oci8_base_t *base = DATA_PTR(self); union { OCINumber *value; ub8 dummy; /* padding for incorrect attrtype to protect the stack */ } v; ub4 size = 0; v.dummy = 0; Check_Type(attr_type, T_FIXNUM); oci_lc(OCIAttrGet(base->hp.ptr, base->type, &v.value, &size, FIX2INT(attr_type), oci8_errhp)); return oci8_make_integer(v.value, oci8_errhp); }
/* * call-seq: * attr_get_integer(attr_type) -> integer * * Gets the value of an attribute as `ub1 *' datatype. * The return value is converted to Integer from internal Oracle NUMBER format. * * @note If the specified attr_type's datatype is not a * pointer type, it causes a segmentation fault. * * @param [Fixnum] attr_type * @return [Fixnum] * * @since 2.0.4 * @private */ static VALUE attr_get_integer(VALUE self, VALUE attr_type) { oci8_base_t *base = DATA_PTR(self); OCINumber onum; union { void *value; ub8 dummy; /* padding for incorrect attrtype to protect the stack */ } v; ub4 size = 0; v.dummy = 0; Check_Type(attr_type, T_FIXNUM); chker2(OCIAttrGet(base->hp.ptr, base->type, &v.value, &size, FIX2INT(attr_type), oci8_errhp), base); memset(&onum, 0, sizeof(onum)); onum.OCINumberPart[0] = size; memcpy(&onum.OCINumberPart[1], v.value, size); return oci8_make_integer(&onum, oci8_errhp); }
static VALUE bind_integer_get(oci8_bind_t *obind, void *data, void *null_struct) { return oci8_make_integer((OCINumber*)data, oci8_errhp); }
static VALUE attr_get_common(int argc, VALUE *argv, VALUE self, enum datatype datatype) { oci8_base_t *base = DATA_PTR(self); VALUE attr_type; VALUE strict; union { ub1 ub1val; ub2 ub2val; ub4 ub4val; ub8 ub8val; sb1 sb1val; sb2 sb2val; sb4 sb4val; sb8 sb8val; boolean booleanval; char *charptr; ub1 *ub1ptr; } v; ub4 size = 0; sword rv; v.ub8val = MAGIC_NUMBER; rb_scan_args(argc, argv, "11", &attr_type, &strict); if (argc == 1) { strict = Qtrue; } Check_Type(attr_type, T_FIXNUM); rv = OCIAttrGet(base->hp.ptr, base->type, &v, &size, FIX2INT(attr_type), oci8_errhp); if (!RTEST(strict)) { if (rv == OCI_ERROR && oci8_get_error_code(oci8_errhp) == 24328) { /* ignore ORA-24328: illegal attribute value */ return Qnil; } } chker2(rv, base); switch (datatype) { OCINumber onum; static VALUE cOraDate = Qnil; case DATATYPE_UB1: return INT2FIX(v.ub1val); case DATATYPE_UB2: return INT2FIX(v.ub2val); case DATATYPE_UB4: return UINT2NUM(v.ub4val); case DATATYPE_UB8: return ULL2NUM(v.ub8val); case DATATYPE_SB1: return INT2FIX(v.sb1val); case DATATYPE_SB2: return INT2FIX(v.sb2val); case DATATYPE_SB4: return INT2NUM(v.sb4val); case DATATYPE_SB8: return LL2NUM(v.sb8val); case DATATYPE_BOOLEAN: return v.booleanval ? Qtrue : Qfalse; case DATATYPE_STRING: if (size == 0 && !RTEST(strict)) { return Qnil; } return rb_external_str_new_with_enc(v.charptr, size, oci8_encoding); case DATATYPE_BINARY: return rb_tainted_str_new(v.charptr, size); case DATATYPE_INTEGER: if (size > sizeof(onum.OCINumberPart) - 1) { rb_raise(rb_eRuntimeError, "Too long size %u", size); } memset(&onum, 0, sizeof(onum)); onum.OCINumberPart[0] = size; memcpy(&onum.OCINumberPart[1], v.ub1ptr, size); return oci8_make_integer(&onum, oci8_errhp); case DATATYPE_ORADATE: if (NIL_P(cOraDate)) cOraDate = rb_eval_string("OraDate"); return rb_funcall(cOraDate, oci8_id_new, 6, INT2FIX((v.ub1ptr[0] - 100) * 100 + (v.ub1ptr[1] - 100)), INT2FIX(v.ub1ptr[2]), INT2FIX(v.ub1ptr[3]), INT2FIX(v.ub1ptr[4] - 1), INT2FIX(v.ub1ptr[5] - 1), INT2FIX(v.ub1ptr[6] - 1)); } return Qnil; }