Ejemplo n.º 1
0
static void lob_close(oci8_lob_t *lob)
{
    if (lob->state == S_OPEN) {
        oci8_svcctx_t *svcctx = check_svcctx(lob);

        chker2(OCILobClose_nb(svcctx, svcctx->base.hp.svc, oci8_errhp, lob->base.hp.lob),
               &svcctx->base);
        lob->state = S_CLOSE;
    }
}
Ejemplo n.º 2
0
/*
 * @overload exists?
 *
 *  Returns <code>true</code> when the BFILE exists on the server's operating system.
 */
static VALUE oci8_bfile_exists_p(VALUE self)
{
    oci8_lob_t *lob = TO_LOB(self);
    oci8_svcctx_t *svcctx = check_svcctx(lob);
    boolean flag;

    chker2(OCILobFileExists_nb(svcctx, svcctx->base.hp.svc, oci8_errhp, lob->base.hp.lob, &flag),
           &svcctx->base);
    return flag ? Qtrue : Qfalse;
}
Ejemplo n.º 3
0
/*
 * call-seq:
 *   non_blocking = true or false
 *
 * Sets +true+ to enable non-blocking mode, +false+ otherwise.
 * The default setting depends on the ruby version and ruby-oci8
 * version.
 *
 * When the connection is in blocking mode (non_blocking = false),
 * SQL executions block not only the thread, but also the ruby
 * process. It makes the whole application stop while a SQL execution
 * needs long time.
 *
 * When in non-blocking mode (non_blocking = true), SQL executions
 * block only the thread. It does't prevent other threads.
 * A SQL execution which blocks a thread can be canceled by
 * OCI8#break.
 *
 * === ruby 1.9
 * The default setting is +true+ if the ruby-oci8 version is 2.0.3 or
 * upper, +false+ otherwise.
 *
 * Ruby-oci8 makes the connection non-blocking by releasing ruby
 * interpreter's GVL (Global VM Lock or Giant VM Lock) while OCI
 * functions which may need more than one network round trips are in
 * execution.
 *
 * === ruby 1.8
 * The default setting is +false+.
 *
 * Ruby-oci8 makes the connection non-blocking by polling the return
 * values of OCI functions. When an OCI function returns
 * OCI_STILL_EXECUTING, the thread sleeps for 10 milli seconds to make
 * a time for other threads to run. The sleep time is doubled up to
 * 640 milli seconds as the function returns the same value.
 *
 */
static VALUE oci8_set_non_blocking(VALUE self, VALUE val)
{
    oci8_svcctx_t *svcctx = DATA_PTR(self);
#ifdef HAVE_RB_THREAD_BLOCKING_REGION
    svcctx->non_blocking = RTEST(val);
#else
    sb1 non_blocking;

    if (svcctx->state & OCI8_STATE_CPOOL) {
        rb_raise(rb_eRuntimeError, "Could not set non-blocking mode to a connection allocated from OCI8::ConnectionPool.");
    }
    chker2(OCIAttrGet(svcctx->srvhp, OCI_HTYPE_SERVER, &non_blocking, 0, OCI_ATTR_NONBLOCKING_MODE, oci8_errhp), &svcctx->base);
    if ((RTEST(val) && !non_blocking) || (!RTEST(val) && non_blocking)) {
        /* toggle blocking / non-blocking. */
        chker2(OCIAttrSet(svcctx->srvhp, OCI_HTYPE_SERVER, 0, 0, OCI_ATTR_NONBLOCKING_MODE, oci8_errhp), &svcctx->base);
    }
#endif
    return val;
}
Ejemplo n.º 4
0
Archivo: lob.c Proyecto: kubo/ruby-oci8
/*
 *  Returns the chunk size of a LOB.
 *
 *  @see http://docs.oracle.com/database/121/ARPLS/d_lob.htm#ARPLS66706 DBMS_LOB.GETCHUNKSIZE
 *  @return [Integer]
 */
static VALUE oci8_lob_get_chunk_size(VALUE self)
{
    oci8_lob_t *lob = TO_LOB(self);
    oci8_svcctx_t *svcctx = check_svcctx(lob);
    ub4 len;

    chker2(OCILobGetChunkSize_nb(svcctx, svcctx->base.hp.svc, oci8_errhp, lob->base.hp.lob, &len),
           &svcctx->base);
    return UINT2NUM(len);
}
Ejemplo n.º 5
0
static void lob_open(oci8_lob_t *lob)
{
    if (lob->state == S_CLOSE) {
        oci8_svcctx_t *svcctx = check_svcctx(lob);

        chker2(OCILobOpen_nb(svcctx, svcctx->base.hp.svc, oci8_errhp, lob->base.hp.lob, OCI_DEFAULT),
               &svcctx->base);
        lob->state = S_OPEN;
    }
}
Ejemplo n.º 6
0
Archivo: lob.c Proyecto: kubo/ruby-oci8
static VALUE oci8_lob_clone(VALUE self)
{
    oci8_lob_t *lob = TO_LOB(self);
    oci8_lob_t *newlob;
    VALUE newobj = lob->svcctx ? lob->svcctx->base.self : Qnil;
    boolean is_temporary;

    newobj = rb_class_new_instance(1, &newobj, CLASS_OF(self));
    newlob = DATA_PTR(newobj);
    if (OCILobIsTemporary(oci8_envhp, oci8_errhp, lob->base.hp.lob, &is_temporary) == OCI_SUCCESS
        && is_temporary) {
        oci8_svcctx_t *svcctx = check_svcctx(lob);
        chker2(OCILobLocatorAssign_nb(svcctx, svcctx->base.hp.svc, oci8_errhp, lob->base.hp.lob, &newlob->base.hp.lob),
               &svcctx->base);
    } else {
        chker2(OCILobAssign(oci8_envhp, oci8_errhp, lob->base.hp.lob, &newlob->base.hp.lob), &lob->base);
    }
    return newobj;
}
Ejemplo n.º 7
0
/*
 * call-seq:
 *   attr_set_binary(attr_type, attr_value)
 *
 * Sets the value of an attribute as `ub1 *' datatype.
 *
 * @param [Fixnum] attr_type
 * @param [String] attr_value
 * @return [self]
 *
 * @since 2.0.4
 * @private
 */
static VALUE attr_set_binary(VALUE self, VALUE attr_type, VALUE val)
{
    oci8_base_t *base = DATA_PTR(self);

    /* validate arguments */
    Check_Type(attr_type, T_FIXNUM);
    SafeStringValue(val);
    /* set attribute */
    chker2(OCIAttrSet(base->hp.ptr, base->type, RSTRING_PTR(val), RSTRING_LEN(val), FIX2INT(attr_type), oci8_errhp), base);
    return self;
}
Ejemplo n.º 8
0
/*
 * call-seq:
 *   attr_set_integer(attr_type, number)
 *
 * Sets the value of an attribute as `ub1 *' datatype.
 * +number+ is converted to internal Oracle NUMBER format before
 * it is set.
 *
 * @param [Fixnum] attr_type
 * @param [Numeric] number
 * @return [self]
 *
 * @since 2.0.4
 * @private
 */
static VALUE attr_set_integer(VALUE self, VALUE attr_type, VALUE val)
{
    oci8_base_t *base = DATA_PTR(self);
    OCINumber value;

    /* validate arguments */
    Check_Type(attr_type, T_FIXNUM);
    oci8_set_integer(&value, val, oci8_errhp);
    /* set attribute */
    chker2(OCIAttrSet(base->hp.ptr, base->type, &value, sizeof(value), FIX2INT(attr_type), oci8_errhp), base);
    return self;
}
Ejemplo n.º 9
0
/*
 * call-seq:
 *   attr_set_boolean(attr_type, attr_value)
 *
 * Sets the value of an attribute as `boolean' datatype.
 *
 * @note If the specified attr_type's datatype is a
 *   pointer type, it causes a segmentation fault.
 *
 * @param [Fixnum] attr_type
 * @param [true or false] attr_value
 * @return [self]
 *
 * @since 2.0.4
 * @private
 */
static VALUE attr_set_boolean(VALUE self, VALUE attr_type, VALUE val)
{
    oci8_base_t *base = DATA_PTR(self);
    boolean value;

    /* validate arguments */
    Check_Type(attr_type, T_FIXNUM);
    value = RTEST(val) ? TRUE : FALSE;
    /* set attribute */
    chker2(OCIAttrSet(base->hp.ptr, base->type, &value, sizeof(value), FIX2INT(attr_type), oci8_errhp), base);
    return self;
}
Ejemplo n.º 10
0
/*
 * call-seq:
 *   attr_set_sb2(attr_type, attr_value)
 *
 * Sets the value of an attribute as `sb2' datatype.
 *
 * @note If the specified attr_type's datatype is a
 *  pointer type, it causes a segmentation fault.
 *
 * @param [Fixnum] attr_type
 * @param [Fixnum] attr_value
 * @return [self]
 *
 * @since 2.0.4
 * @private
 */
static VALUE attr_set_sb2(VALUE self, VALUE attr_type, VALUE val)
{
    oci8_base_t *base = DATA_PTR(self);
    sb2 value;

    /* validate arguments */
    Check_Type(attr_type, T_FIXNUM);
    value = (sb2)check_data_range(val, SHRT_MIN, SHRT_MAX, "sb2");
    /* set attribute */
    chker2(OCIAttrSet(base->hp.ptr, base->type, &value, sizeof(value), FIX2INT(attr_type), oci8_errhp), base);
    return self;
}
Ejemplo n.º 11
0
/*
 * call-seq:
 *   attr_set_ub8(attr_type, attr_value)
 *
 * Sets the value of an attribute as `ub8' datatype.
 *
 * @note If the specified attr_type's datatype is a
 *   pointer type, it causes a segmentation fault.
 *
 * @param [Fixnum] attr_type
 * @param [Integer] attr_value
 * @return [self]
 *
 * @since 2.0.4
 * @private
 */
static VALUE attr_set_ub8(VALUE self, VALUE attr_type, VALUE val)
{
    oci8_base_t *base = DATA_PTR(self);
    ub8 value;

    /* validate arguments */
    Check_Type(attr_type, T_FIXNUM);
    value = NUM2ULL(val);
    /* set attribute */
    chker2(OCIAttrSet(base->hp.ptr, base->type, &value, sizeof(value), FIX2INT(attr_type), oci8_errhp), base);
    return self;
}
Ejemplo n.º 12
0
/*
 * call-seq:
 *   non_blocking? -> true or false
 *
 * Returns +true+ if the connection is in non-blocking mode, +false+
 * otherwise.
 *
 * See also #non_blocking=.
 */
static VALUE oci8_non_blocking_p(VALUE self)
{
    oci8_svcctx_t *svcctx = DATA_PTR(self);
#ifdef HAVE_RB_THREAD_BLOCKING_REGION
    return svcctx->non_blocking ? Qtrue : Qfalse;
#else
    sb1 non_blocking;

    chker2(OCIAttrGet(svcctx->srvhp, OCI_HTYPE_SERVER, &non_blocking, 0, OCI_ATTR_NONBLOCKING_MODE, oci8_errhp), &svcctx->base);
    return non_blocking ? Qtrue : Qfalse;
#endif
}
Ejemplo n.º 13
0
/*
 * call-seq:
 *   break
 *
 * Cancels the executing SQL.
 *
 * See also #non_blocking=.
 */
static VALUE oci8_break(VALUE self)
{
    oci8_svcctx_t *svcctx = DATA_PTR(self);

    if (NIL_P(svcctx->executing_thread)) {
        return Qfalse;
    }
#ifndef HAVE_RB_THREAD_BLOCKING_REGION
    chker2(OCIBreak(svcctx->base.hp.ptr, oci8_errhp), &svcctx->base);
#endif
    rb_thread_wakeup(svcctx->executing_thread);
    return Qtrue;
}
Ejemplo n.º 14
0
/*
 * call-seq:
 *   attr_get_boolean(attr_type)
 *
 * Gets the value of an attribute as `boolean' datatype.
 *
 * @param [Fixnum] attr_type
 * @return [true of false]
 *
 * @since 2.0.4
 * @private
 */
static VALUE attr_get_boolean(VALUE self, VALUE attr_type)
{
    oci8_base_t *base = DATA_PTR(self);
    union {
        boolean value;
        ub8 dummy; /* padding for incorrect attrtype to protect the stack */
    } v;

    v.dummy = MAGIC_NUMBER;
    Check_Type(attr_type, T_FIXNUM);
    chker2(OCIAttrGet(base->hp.ptr, base->type, &v.value, NULL, FIX2INT(attr_type), oci8_errhp), base);
    return v.value ? Qtrue : Qfalse;
}
Ejemplo n.º 15
0
/*
 * call-seq:
 *   attr_get_sb4(attr_type)
 *
 * Gets the value of an attribute as `sb4' datatype.
 *
 * @param [Fixnum] attr_type
 * @return [Integer]
 *
 * @since 2.0.4
 * @private
 */
static VALUE attr_get_sb4(VALUE self, VALUE attr_type)
{
    oci8_base_t *base = DATA_PTR(self);
    union {
        sb4 value;
        ub8 dummy;
    } v;

    v.dummy = MAGIC_NUMBER;
    Check_Type(attr_type, T_FIXNUM);
    chker2(OCIAttrGet(base->hp.ptr, base->type, &v.value, NULL, FIX2INT(attr_type), oci8_errhp), base);
    return INT2NUM(v.value);
}
Ejemplo n.º 16
0
/*
 * call-seq:
 *   attr_get_binary(attr_type)
 *
 * Gets the value of an attribute as `ub1 *' datatype.
 * The return value is tagged with ASCII-8BIT when the ruby version is 1.9.
 *
 * @note If the specified attr_type's datatype is not a
 *   pointer type, it causes a segmentation fault.
 *
 * @param [Fixnum] attr_type
 * @return [String]
 *
 * @since 2.0.4
 * @private
 */
static VALUE attr_get_binary(VALUE self, VALUE attr_type)
{
    oci8_base_t *base = DATA_PTR(self);
    union {
        char *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);
    return rb_tainted_str_new(v.value, size);
}
Ejemplo n.º 17
0
/*
 * call-seq:
 *   attr_get_string(attr_type)
 *
 * Gets the value of an attribute as `oratext *' datatype.
 * The return value is converted to Encoding.default_internal or
 * tagged with {OCI8.encoding} when the ruby version is 1.9.
 *
 * @note If the specified attr_type's datatype is not a
 *   pointer type, it causes a segmentation fault.
 *
 * @param [Fixnum] attr_type
 * @return [String]
 *
 * @since 2.0.4
 * @private
 */
static VALUE attr_get_string(VALUE self, VALUE attr_type)
{
    oci8_base_t *base = DATA_PTR(self);
    union {
        char *value;
        ub8 dummy; /* padding for incorrect attrtype to protect the stack */
    } v;
    ub4 size = 0;

    v.dummy = MAGIC_NUMBER;
    Check_Type(attr_type, T_FIXNUM);
    chker2(OCIAttrGet(base->hp.ptr, base->type, &v.value, &size, FIX2INT(attr_type), oci8_errhp), base);
    return rb_external_str_new_with_enc(v.value, size, oci8_encoding);
}
Ejemplo n.º 18
0
/*
 * call-seq:
 *   logon2(username, password, dbname, mode) -> connection
 *
 * <b>internal use only</b>
 *
 * Creates a simple logon session by the OCI function OCILogon2().
 */
static VALUE oci8_logon2(VALUE self, VALUE username, VALUE password, VALUE dbname, VALUE mode)
{
    oci8_svcctx_t *svcctx = DATA_PTR(self);

    if (svcctx->logoff_strategy != NULL) {
        rb_raise(rb_eRuntimeError, "Could not reuse the session.");
    }

    /* check arugmnets */
    OCI8SafeStringValue(username);
    OCI8SafeStringValue(password);
    if (!NIL_P(dbname)) {
        OCI8SafeStringValue(dbname);
    }

    /* logon */
    svcctx->base.type = OCI_HTYPE_SVCCTX;
    chker2(OCILogon2_nb(svcctx, oci8_envhp, oci8_errhp, &svcctx->base.hp.svc,
                        RSTRING_ORATEXT(username), RSTRING_LEN(username),
                        RSTRING_ORATEXT(password), RSTRING_LEN(password),
                        NIL_P(dbname) ? NULL : RSTRING_ORATEXT(dbname),
                        NIL_P(dbname) ? 0 : RSTRING_LEN(dbname), NUM2UINT(mode)),
           &svcctx->base);
    svcctx->logoff_strategy = &simple_logoff;

    /* setup the session handle */
    chker2(OCIAttrGet(svcctx->base.hp.ptr, OCI_HTYPE_SVCCTX, &svcctx->usrhp, 0, OCI_ATTR_SESSION, oci8_errhp),
           &svcctx->base);
    copy_session_handle(svcctx);

    /* setup the server handle */
    chker2(OCIAttrGet(svcctx->base.hp.ptr, OCI_HTYPE_SVCCTX, &svcctx->srvhp, 0, OCI_ATTR_SERVER, oci8_errhp),
           &svcctx->base);
    copy_server_handle(svcctx);

    return Qnil;
}
Ejemplo n.º 19
0
static void oci8_bfile_set_name(VALUE self, VALUE dir_alias, VALUE filename)
{
    oci8_lob_t *lob = TO_LOB(self);

    bfile_close(lob);
    if (RSTRING_LEN(dir_alias) > UB2MAXVAL) {
        rb_raise(rb_eRuntimeError, "dir_alias is too long.");
    }
    if (RSTRING_LEN(filename) > UB2MAXVAL) {
        rb_raise(rb_eRuntimeError, "filename is too long.");
    }
    chker2(OCILobFileSetName(oci8_envhp, oci8_errhp, &lob->base.hp.lob,
                             RSTRING_ORATEXT(dir_alias), (ub2)RSTRING_LEN(dir_alias),
                             RSTRING_ORATEXT(filename), (ub2)RSTRING_LEN(filename)),
           &lob->base);
}
Ejemplo n.º 20
0
/*
 * call-seq:
 *   logoff
 *
 * Disconnects from the Oracle server. The uncommitted transaction is
 * rollbacked.
 */
static VALUE oci8_svcctx_logoff(VALUE self)
{
    oci8_svcctx_t *svcctx = (oci8_svcctx_t *)DATA_PTR(self);

    while (svcctx->base.children != NULL) {
        oci8_base_free(svcctx->base.children);
    }
    if (svcctx->logoff_strategy != NULL) {
        const oci8_logoff_strategy_t *strategy = svcctx->logoff_strategy;
        void *data = strategy->prepare(svcctx);
        svcctx->base.type = 0;
        svcctx->logoff_strategy = NULL;
        chker2(oci8_blocking_region(svcctx, strategy->execute, data), &svcctx->base);
    }
    return Qtrue;
}
Ejemplo n.º 21
0
static VALUE exec_sql(cb_arg_t *arg)
{
    ub4 pos;
    sword rv;

    rv = OCIHandleAlloc(oci8_envhp, (dvoid*)&arg->stmtp, OCI_HTYPE_STMT, 0, NULL);
    if (rv != OCI_SUCCESS) {
        oci8_env_raise(oci8_envhp, rv);
    }
    chker2(OCIStmtPrepare(arg->stmtp, oci8_errhp, (text*)arg->sql_text,
                          strlen(arg->sql_text), OCI_NTV_SYNTAX, OCI_DEFAULT),
           &arg->svcctx->base);
    for (pos = 0; pos < arg->num_define_vars; pos++) {
        arg->define_vars[pos].hp = NULL;
        chker3(OCIDefineByPos(arg->stmtp, (OCIDefine**)&arg->define_vars[pos].hp,
                              oci8_errhp, pos + 1, arg->define_vars[pos].valuep,
                              arg->define_vars[pos].value_sz,
                              arg->define_vars[pos].dty, arg->define_vars[pos].indp,
                              arg->define_vars[pos].alenp, NULL, OCI_DEFAULT),
               &arg->svcctx->base, arg->stmtp);
    }
    for (pos = 0; pos < arg->num_bind_vars; pos++) {
        arg->bind_vars[pos].hp = NULL;
        chker3(OCIBindByPos(arg->stmtp, (OCIBind**)&arg->bind_vars[pos].hp,
                            oci8_errhp, pos + 1, arg->bind_vars[pos].valuep,
                            arg->bind_vars[pos].value_sz, arg->bind_vars[pos].dty,
                            arg->bind_vars[pos].indp, arg->bind_vars[pos].alenp,
                            NULL, 0, NULL, OCI_DEFAULT),
               &arg->svcctx->base, arg->stmtp);
    }
    rv = OCIStmtExecute_nb(arg->svcctx, arg->svcctx->base.hp.svc, arg->stmtp, oci8_errhp, 1, 0, NULL, NULL, OCI_DEFAULT);
    if (rv == OCI_ERROR) {
        if (oci8_get_error_code(oci8_errhp) == 1000) {
            /* run GC to close unreferred cursors
             * when ORA-01000 (maximum open cursors exceeded).
             */
            rb_gc();
            rv = OCIStmtExecute_nb(arg->svcctx, arg->svcctx->base.hp.svc, arg->stmtp, oci8_errhp, 1, 0, NULL, NULL, OCI_DEFAULT);
        }
    }
    if (arg->raise_on_error) {
        chker3(rv, &arg->svcctx->base, arg->stmtp);
    }
    return (VALUE)rv;
}
Ejemplo n.º 22
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);
}
Ejemplo n.º 23
0
/*
 * call-seq:
 *   module = string or nil
 *
 * <b>(new in 2.0.3)</b>
 *
 * Sets the name of the current module. This information is
 * stored in the V$SESSION view and is also stored in the V$SQL view
 * and the V$SQLAREA view when a SQL statement is executed and the SQL
 * statement is first parsed in the Oracle server.
 *
 * === Oracle 10g client or upper
 *
 * This doesn't perform network round trips. The change is reflected
 * to the server by the next round trip such as OCI8#exec, OCI8#ping,
 * etc.
 *
 * === Oracle 9i client or lower
 *
 * This executes the following PL/SQL block internally.
 * The change is reflected immediately by a network round trip.
 *
 *   DECLARE
 *     action VARCHAR2(32);
 *   BEGIN
 *     -- retrieve action name.
 *     SELECT SYS_CONTEXT('USERENV','ACTION') INTO action FROM DUAL;
 *     -- change module name without modifying the action name.
 *     DBMS_APPLICATION_INFO.SET_MODULE(:module, action);
 *   END;
 *
 * See {Oracle Manual: Oracle Database PL/SQL Packages and Types Reference}[http://download.oracle.com/docs/cd/B19306_01/appdev.102/b14258/d_appinf.htm#i999254]
 *
 */
static VALUE oci8_set_module(VALUE self, VALUE val)
{
    const char *ptr;
    ub4 size;

    if (!NIL_P(val)) {
        OCI8SafeStringValue(val);
        ptr = RSTRING_PTR(val);
        size = RSTRING_LEN(val);
    } else {
        ptr = "";
        size = 0;
    }
    if (oracle_client_version >= ORAVER_10_1) {
        /* Oracle 10g or upper */
        chker2(OCIAttrSet(oci8_get_oci_session(self), OCI_HTYPE_SESSION, (dvoid*)ptr,
                          size, OCI_ATTR_MODULE, oci8_errhp),
               DATA_PTR(self));
    } else {
        /* Oracle 9i or lower */
        oci8_exec_sql_var_t bind_vars[1];

        /* :module */
        bind_vars[0].valuep = (dvoid*)ptr;
        bind_vars[0].value_sz = size;
        bind_vars[0].dty = SQLT_CHR;
        bind_vars[0].indp = NULL;
        bind_vars[0].alenp = NULL;

        oci8_exec_sql(oci8_get_svcctx(self),
                      "DECLARE\n"
                      "  action VARCHAR2(32);\n"
                      "BEGIN\n"
                      "  SELECT SYS_CONTEXT('USERENV','ACTION') INTO action FROM DUAL;\n"
                      "  DBMS_APPLICATION_INFO.SET_MODULE(:module, action);\n"
                      "END;\n", 0, NULL, 1, bind_vars, 1);
    }
    return self;
}
Ejemplo n.º 24
0
/*
 * call-seq:
 *   client_identifier = string or nil
 *
 * <b>(new in 2.0.3)</b>
 *
 * Sets the client ID. This information is stored in the V$SESSION
 * view.
 *
 * === Oracle 9i client or upper
 *
 * This doesn't perform network round trips. The change is reflected
 * to the server by the next round trip such as OCI8#exec, OCI8#ping,
 * etc.
 *
 * === Oracle 8i client or lower
 *
 * This executes the following PL/SQL block internally.
 * The change is reflected immediately by a network round trip.
 *
 *   BEGIN
 *     DBMS_SESSION.SET_IDENTIFIER(:client_id);
 *   END;
 *
 * See {Oracle Manual: Oracle Database PL/SQL Packages and Types Reference}[http://download.oracle.com/docs/cd/B19306_01/appdev.102/b14258/d_sessio.htm#i996935]
 *
 */
static VALUE oci8_set_client_identifier(VALUE self, VALUE val)
{
    const char *ptr;
    ub4 size;

    if (!NIL_P(val)) {
        OCI8SafeStringValue(val);
        ptr = RSTRING_PTR(val);
        size = RSTRING_LEN(val);
    } else {
        ptr = "";
        size = 0;
    }

    if (oracle_client_version >= ORAVERNUM(9, 2, 0, 3, 0) || size > 0) {
        if (size > 0 && ptr[0] == ':') {
            rb_raise(rb_eArgError, "client identifier should not start with ':'.");
        }
        chker2(OCIAttrSet(oci8_get_oci_session(self), OCI_HTYPE_SESSION, (dvoid*)ptr,
                          size, OCI_ATTR_CLIENT_IDENTIFIER, oci8_errhp),
               DATA_PTR(self));
    } else {
        /* Workaround for Bug 2449486 */
        oci8_exec_sql_var_t bind_vars[1];

        /* :client_id */
        bind_vars[0].valuep = (dvoid*)ptr;
        bind_vars[0].value_sz = size;
        bind_vars[0].dty = SQLT_CHR;
        bind_vars[0].indp = NULL;
        bind_vars[0].alenp = NULL;

        oci8_exec_sql(oci8_get_svcctx(self),
                      "BEGIN\n"
                      "  DBMS_SESSION.SET_IDENTIFIER(:client_id);\n"
                      "END;\n", 0, NULL, 1, bind_vars, 1);
    }
    return val;
}
Ejemplo n.º 25
0
/*
 * call-seq:
 *   attr_get_oradate(attr_type) -> an OraDate
 *
 * Gets the value of an attribute as `ub1 *' datatype.
 * The return value is converted to OraDate.
 *
 * @note If the specified attr_type's datatype is not a
 *   pointer type, it causes a segmentation fault.
 *
 * @param [Fixnum] attr_type
 * @return [OraDate]
 *
 * @since 2.0.4
 * @private
 */
static VALUE attr_get_oradate(VALUE self, VALUE attr_type)
{
    oci8_base_t *base = DATA_PTR(self);
    union {
        ub1 *value;
        ub8 dummy; /* padding for incorrect attrtype to protect the stack */
    } v;
    ub4 size = 0;
    static VALUE cOraDate = RB_QNIL;

    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);
    if (NIL_P(cOraDate))
        cOraDate = RB_CLASS("OraDate");
    return rb_funcall(cOraDate, oci8_id_new, 6,
                      INT2FIX((v.value[0] - 100) * 100 + (v.value[1] - 100)),
                      INT2FIX(v.value[2]),
                      INT2FIX(v.value[3]),
                      INT2FIX(v.value[4] - 1),
                      INT2FIX(v.value[5] - 1),
                      INT2FIX(v.value[6] - 1));
}
Ejemplo n.º 26
0
static void oci8_bfile_get_name(VALUE self, VALUE *dir_alias_p, VALUE *filename_p)
{
    int need_get = 0;
    if (dir_alias_p != NULL) {
        *dir_alias_p = rb_ivar_get(self, id_dir_alias);
        if (NIL_P(*dir_alias_p))
            need_get = 1;
    }
    if (filename_p != NULL) {
        *filename_p = rb_ivar_get(self, id_filename);
        if (NIL_P(*filename_p))
            need_get = 1;
    }
    if (need_get) {
        oci8_lob_t *lob = TO_LOB(self);
        char d_buf[31];
        ub2 d_length = sizeof(d_buf);
        char f_buf[256];
        ub2 f_length = sizeof(f_buf);
        VALUE dir_alias;
        VALUE filename;

        chker2(OCILobFileGetName(oci8_envhp, oci8_errhp, lob->base.hp.lob, TO_ORATEXT(d_buf), &d_length, TO_ORATEXT(f_buf), &f_length),
               &lob->base);
        dir_alias = rb_external_str_new_with_enc(d_buf, d_length, oci8_encoding);
        filename = rb_external_str_new_with_enc(f_buf, f_length, oci8_encoding);
        rb_ivar_set(self, id_dir_alias, dir_alias);
        rb_ivar_set(self, id_filename, filename);
        if (dir_alias_p != NULL) {
            *dir_alias_p = dir_alias;
        }
        if (filename_p != NULL) {
            *filename_p = filename;
        }
    }
}
Ejemplo n.º 27
0
/*
 * call-seq:
 *   action = string or nil
 *
 * <b>(new in 2.0.3)</b>
 *
 * Sets the name of the current action within the current module.
 * This information is stored in the V$SESSION view and is also
 * stored in the V$SQL view and the V$SQLAREA view when a SQL
 * statement is executed and the SQL statement is first parsed
 * in the Oracle server.
 *
 * === Oracle 10g client or upper
 *
 * This doesn't perform network round trips. The change is reflected
 * to the server by the next round trip such as OCI8#exec, OCI8#ping,
 * etc.
 *
 * === Oracle 9i client or lower
 *
 * This executes the following PL/SQL block internally.
 * The change is reflected immediately by a network round trip.
 *
 *   BEGIN
 *     DBMS_APPLICATION_INFO.SET_ACTION(:action);
 *   END;
 *
 * See {Oracle Manual: Oracle Database PL/SQL Packages and Types Reference}[http://download.oracle.com/docs/cd/B19306_01/appdev.102/b14258/d_appinf.htm#i999254]
 *
 */
static VALUE oci8_set_action(VALUE self, VALUE val)
{
    const char *ptr;
    ub4 size;

    if (!NIL_P(val)) {
        OCI8SafeStringValue(val);
        ptr = RSTRING_PTR(val);
        size = RSTRING_LEN(val);
    } else {
        ptr = "";
        size = 0;
    }
    if (oracle_client_version >= ORAVER_10_1) {
        /* Oracle 10g or upper */
        chker2(OCIAttrSet(oci8_get_oci_session(self), OCI_HTYPE_SESSION, (dvoid*)ptr,
                          size, OCI_ATTR_ACTION, oci8_errhp),
               DATA_PTR(self));
    } else {
        /* Oracle 9i or lower */
        oci8_exec_sql_var_t bind_vars[1];

        /* :action */
        bind_vars[0].valuep = (dvoid*)ptr;
        bind_vars[0].value_sz = size;
        bind_vars[0].dty = SQLT_CHR;
        bind_vars[0].indp = NULL;
        bind_vars[0].alenp = NULL;

        oci8_exec_sql(oci8_get_svcctx(self),
                      "BEGIN\n"
                      "  DBMS_APPLICATION_INFO.SET_ACTION(:action);\n"
                      "END;\n", 0, NULL, 1, bind_vars, 1);
    }
    return val;
}
Ejemplo n.º 28
0
/*
 * @overload read
 *
 *  
 *
 *  @param [Integer] length number of characters if +self+ is a {CLOB} or a {NCLOB}.
 *    number of bytes if +self+ is a {BLOB} or a {BFILE}.
 *  @return [String or nil] data read. <code>nil</code> means it
 *    met EOF at beginning. It returns an empty string '' as a special exception
 *    when <i>length</i> is <code>nil</code> and the lob is empty.
 *
 * @overload read(length)
 *
 *  Reads <i>length</i> characters for {CLOB} and {NCLOB} or <i>length</i>
 *  bytes for {BLOB} and {BFILE} from the current position.
 *  If <i>length</i> is <code>nil</code>, it reads data until EOF.
 *
 *  @param [Integer] length number of characters if +self+ is a {CLOB} or a {NCLOB}.
 *    number of bytes if +self+ is a {BLOB} or a {BFILE}.
 *  @return [String or nil] data read. <code>nil</code> means it
 *    met EOF at beginning. It returns an empty string '' as a special exception
 *    when <i>length</i> is <code>nil</code> and the lob is empty.
 */
static VALUE oci8_lob_read(int argc, VALUE *argv, VALUE self)
{
    oci8_lob_t *lob = TO_LOB(self);
    oci8_svcctx_t *svcctx = check_svcctx(lob);
    ub8 lob_length;
    ub8 read_len;
    ub8 pos = lob->pos;
    long strbufsiz;
    ub8 byte_amt;
    ub8 char_amt;
    sword rv;
    VALUE size;
    VALUE v = rb_ary_new();
    OCIError *errhp = oci8_errhp;
    ub1 piece = OCI_FIRST_PIECE;

    rb_scan_args(argc, argv, "01", &size);
    lob_length = oci8_lob_get_length(lob);
    if (lob_length == 0 && NIL_P(size)) {
        return rb_usascii_str_new("", 0);
    }
    if (lob_length <= pos) /* EOF */
        return Qnil;
    if (NIL_P(size)) {
        read_len = lob_length - pos;
    } else {
        ub8 sz = NUM2ULL(size);
        read_len = MIN(sz, lob_length - pos);
    }
    if (lob->lobtype == OCI_TEMP_CLOB) {
        byte_amt = 0;
        char_amt = read_len;
        if (oci8_nls_ratio == 1) {
            strbufsiz = MIN(read_len, ULONG_MAX);
        } else {
            strbufsiz = MIN(read_len + read_len / 8, ULONG_MAX);
        }
        if (strbufsiz <= 10) {
            strbufsiz = 10;
        }
    } else {
        byte_amt = read_len;
        char_amt = 0;
        strbufsiz = MIN(read_len, ULONG_MAX);
    }
    if (lob->state == S_BFILE_CLOSE) {
        open_bfile(svcctx, lob, errhp);
    }
    do {
        VALUE strbuf = rb_str_buf_new(strbufsiz);
        char *buf = RSTRING_PTR(strbuf);

        rv = OCILobRead2_nb(svcctx, svcctx->base.hp.svc, errhp, lob->base.hp.lob, &byte_amt, &char_amt, pos + 1, buf, strbufsiz, piece, NULL, NULL, 0, lob->csfrm);
        svcctx->suppress_free_temp_lobs = 0;
        switch (rv) {
        case OCI_SUCCESS:
            break;
        case OCI_NEED_DATA:
            /* prevent OCILobFreeTemporary() from being called.
             * See: https://github.com/kubo/ruby-oci8/issues/20
             */
            svcctx->suppress_free_temp_lobs = 1;
            piece = OCI_NEXT_PIECE;
            break;
        default:
            chker2(rv, &svcctx->base);
        }
        if (byte_amt == 0)
            break;
        if (lob->lobtype == OCI_TEMP_CLOB) {
            pos += char_amt;
        } else {
            pos += byte_amt;
        }
        rb_str_set_len(strbuf, byte_amt);
        rb_ary_push(v, strbuf);
    } while (rv == OCI_NEED_DATA);

    if (pos >= lob_length) {
        lob_close(lob);
        bfile_close(lob);
    }
    lob->pos = pos;
    switch (RARRAY_LEN(v)) {
    case 0:
        return Qnil;
    case 1:
        v = RARRAY_AREF(v, 0);
        break;
    default:
        v = rb_ary_join(v, Qnil);
    }
    OBJ_TAINT(v);
    if (lob->lobtype == OCI_TEMP_CLOB) {
        /* set encoding */
        rb_enc_associate(v, oci8_encoding);
        return rb_str_conv_enc(v, oci8_encoding, rb_default_internal_encoding());
    } else {
        /* ASCII-8BIT */
        return v;
    }
}
Ejemplo n.º 29
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;
}
Ejemplo n.º 30
0
/*
 * call-seq:
 *   rollback
 *
 * Rollbacks the transaction.
 */
static VALUE oci8_rollback(VALUE self)
{
    oci8_svcctx_t *svcctx = DATA_PTR(self);
    chker2(OCITransRollback_nb(svcctx, svcctx->base.hp.svc, oci8_errhp, OCI_DEFAULT), &svcctx->base);
    return self;
}