예제 #1
0
/*
 *  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
}
예제 #2
0
/*
 *  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);
}
예제 #3
0
/*
 *  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);
}
예제 #4
0
/*
 *  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);
}
예제 #5
0
/*
 *  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);
    }
}
예제 #6
0
/*
 * 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);
}
예제 #7
0
/*
 * 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);
}
예제 #8
0
static VALUE bind_integer_get(oci8_bind_t *obind, void *data, void *null_struct)
{
    return oci8_make_integer((OCINumber*)data, oci8_errhp);
}
예제 #9
0
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;
}