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); }
/* * call-seq: * server_attach(dbname, mode) * * <b>internal use only</b> * * Attachs to the server by the OCI function OCIServerAttach(). */ static VALUE oci8_server_attach(VALUE self, VALUE dbname, VALUE mode) { oci8_svcctx_t *svcctx = oci8_get_svcctx(self); if (svcctx->logoff_method != call_session_end) { rb_raise(rb_eRuntimeError, "Use this method only for the service context handle created by OCI8#server_handle()."); } if (svcctx->state & OCI8_STATE_SERVER_ATTACH_WAS_CALLED) { rb_raise(rb_eRuntimeError, "Could not use this method twice."); } /* check arguments */ if (!NIL_P(dbname)) { OCI8SafeStringValue(dbname); } Check_Type(mode, T_FIXNUM); /* attach to the server */ oci_lc(OCIServerAttach_nb(svcctx, svcctx->server->hp.srvhp, oci8_errhp, NIL_P(dbname) ? NULL : RSTRING_ORATEXT(dbname), NIL_P(dbname) ? 0 : RSTRING_LEN(dbname), FIX2UINT(mode))); oci_lc(OCIAttrSet(svcctx->base.hp.ptr, OCI_HTYPE_SVCCTX, svcctx->server->hp.srvhp, 0, OCI_ATTR_SERVER, oci8_errhp)); svcctx->state |= OCI8_STATE_SERVER_ATTACH_WAS_CALLED; return self; }
/* * call-seq: * server_attach(dbname, mode) * * <b>internal use only</b> * * Attachs to the server by the OCI function OCIServerAttach(). */ static VALUE oci8_server_attach(VALUE self, VALUE dbname, VALUE attach_mode) { oci8_svcctx_t *svcctx = oci8_get_svcctx(self); ub4 mode = NUM2UINT(attach_mode); if (svcctx->logoff_strategy != &complex_logoff) { rb_raise(rb_eRuntimeError, "Use this method only for the service context handle created by OCI8#server_handle()."); } if (svcctx->state & OCI8_STATE_SERVER_ATTACH_WAS_CALLED) { rb_raise(rb_eRuntimeError, "Could not use this method twice."); } /* check arguments */ if (!NIL_P(dbname)) { OCI8SafeStringValue(dbname); } /* attach to the server */ chker2(OCIServerAttach_nb(svcctx, svcctx->srvhp, oci8_errhp, NIL_P(dbname) ? NULL : RSTRING_ORATEXT(dbname), NIL_P(dbname) ? 0 : RSTRING_LEN(dbname), mode), &svcctx->base); chker2(OCIAttrSet(svcctx->base.hp.ptr, OCI_HTYPE_SVCCTX, svcctx->srvhp, 0, OCI_ATTR_SERVER, oci8_errhp), &svcctx->base); svcctx->state |= OCI8_STATE_SERVER_ATTACH_WAS_CALLED; if (mode & OCI_CPOOL) { svcctx->state |= OCI8_STATE_CPOOL; } return self; }
/* fill C structure (OCINumber) from a string. */ static void set_oci_number_from_str(OCINumber *result, VALUE str, VALUE fmt, VALUE nls_params, OCIError *errhp) { oratext *fmt_ptr; oratext *nls_params_ptr; ub4 fmt_len; ub4 nls_params_len; StringValue(str); /* set from string. */ if (NIL_P(fmt)) { int rv = oranumber_from_str(result, RSTRING_PTR(str), RSTRING_LEN(str)); if (rv == ORANUMBER_SUCCESS) { return; /* success */ } else { const char *default_msg = NULL; switch (rv) { case ORANUMBER_INVALID_NUMBER: default_msg = "invalid number"; break; case ORANUMBER_NUMERIC_OVERFLOW: default_msg = "numeric overflow"; break; } oci8_raise_by_msgno(rv, default_msg); } } StringValue(fmt); fmt_ptr = RSTRING_ORATEXT(fmt); fmt_len = RSTRING_LEN(fmt); if (NIL_P(nls_params)) { nls_params_ptr = NULL; nls_params_len = 0; } else { StringValue(nls_params); nls_params_ptr = RSTRING_ORATEXT(nls_params); nls_params_len = RSTRING_LEN(nls_params); } chkerr(OCINumberFromText(errhp, RSTRING_ORATEXT(str), RSTRING_LEN(str), fmt_ptr, fmt_len, nls_params_ptr, nls_params_len, result)); }
/* * 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; }
/* * call-seq: * OraNumber._load(string) -> oranumber * * Unmarshal a dumped <code>OraNumber</code> object. */ static VALUE onum_s_load(VALUE klass, VALUE str) { unsigned char *c; size_t size; OCINumber num; Check_Type(str, T_STRING); c = RSTRING_ORATEXT(str); size = RSTRING_LEN(str); if (size == 0 || size != c[0] + 1u || size > sizeof(num)) { rb_raise(rb_eTypeError, "marshaled OCI::Number format differ"); } memset(&num, 0, sizeof(num)); memcpy(&num, c, size); return oci8_make_ocinumber(&num, oci8_errhp); }
/* =begin --- OraNumber.new() =end */ static VALUE ora_number_initialize(int argc, VALUE *argv, VALUE self) { ora_vnumber_t *ovn = get_ora_number(self); volatile VALUE arg; rb_scan_args(argc, argv, "01", &arg); ovn->size = 1; ovn->num.exponent = 0x80; memset(ovn->num.mantissa, 0, sizeof(ovn->num.mantissa)); if (argc == 1) { if (TYPE(arg) != T_STRING) { arg = rb_obj_as_string(arg); } if (ora_number_from_str(ovn, RSTRING_ORATEXT(arg), RSTRING_LEN(arg)) != 0) { rb_raise(rb_eArgError, "could not convert '%s' to OraNumber", RSTRING_PTR(arg)); } } return Qnil; }
/* * call-seq: * new(username, password, dbname = nil, privilege = nil) * * Connects to an Oracle database server by +username+ and +password+ * at +dbname+ as +privilege+. * * === connecting to the local server * * Set +username+ and +password+ or pass "username/password" as a * single argument. * * OCI8.new('scott', 'tiger') * or * OCI8.new('scott/tiger') * * === connecting to a remote server * * Set +username+, +password+ and +dbname+ or pass * "username/password@dbname" as a single argument. * * OCI8.new('scott', 'tiger', 'orcl.world') * or * OCI8.new('scott/[email protected]') * * The +dbname+ is a net service name or an easy connectection * identifier. The former is a name listed in the file tnsnames.ora. * Ask to your DBA if you don't know what it is. The latter has the * syntax as "//host:port/service_name". * * OCI8.new('scott', 'tiger', '//remote-host:1521/XE') * or * OCI8.new('scott/tiger@//remote-host:1521/XE') * * === connecting as a privileged user * * Set :SYSDBA or :SYSOPER to +privilege+, otherwise * "username/password as sysdba" or "username/password as sysoper" * as a single argument. * * OCI8.new('sys', 'change_on_install', nil, :SYSDBA) * or * OCI8.new('sys/change_on_install as sysdba') * * === external OS authentication * * Set nil to +username+ and +password+, or "/" as a single argument. * * OCI8.new(nil, nil) * or * OCI8.new('/') * * To connect to a remote host: * * OCI8.new(nil, nil, 'dbname') * or * OCI8.new('/@dbname') * * === proxy authentication * * Enclose end user's username with square brackets and add it at the * end of proxy user's username. * * OCI8.new('proxy_user_name[end_user_name]', 'proxy_password') * or * OCI8.new('proxy_user_name[end_user_name]/proxy_password') * */ static VALUE oci8_svcctx_initialize(int argc, VALUE *argv, VALUE self) { VALUE vusername; VALUE vpassword; VALUE vdbname; VALUE vmode; oci8_svcctx_t *svcctx = DATA_PTR(self); sword rv; enum logon_type_t logon_type = T_IMPLICIT; ub4 cred = OCI_CRED_RDBMS; ub4 mode = OCI_DEFAULT; OCISvcCtx *svchp = NULL; svcctx->executing_thread = Qnil; if (argc == 1) { oci8_do_parse_connect_string(argv[0], &vusername, &vpassword, &vdbname, &vmode); } else { rb_scan_args(argc, argv, "22", &vusername, &vpassword, &vdbname, &vmode); } rb_ivar_set(self, id_at_prefetch_rows, Qnil); rb_ivar_set(self, id_at_username, Qnil); if (NIL_P(vusername) && NIL_P(vpassword)) { /* external credential */ logon_type = T_EXPLICIT; cred = OCI_CRED_EXT; } else { /* RDBMS credential */ OCI8SafeStringValue(vusername); /* 1 */ OCI8SafeStringValue(vpassword); /* 2 */ } if (!NIL_P(vdbname)) { OCI8SafeStringValue(vdbname); /* 3 */ } if (!NIL_P(vmode)) { /* 4 */ logon_type = T_EXPLICIT; Check_Type(vmode, T_SYMBOL); if (vmode == sym_SYSDBA) { mode = OCI_SYSDBA; } else if (vmode == sym_SYSOPER) { mode = OCI_SYSOPER; } else { rb_raise(rb_eArgError, "invalid privilege name %s (expect :SYSDBA or :SYSOPER)", rb_id2name(SYM2ID(vmode))); } } switch (logon_type) { case T_IMPLICIT: rv = OCILogon_nb(svcctx, oci8_envhp, oci8_errhp, &svchp, RSTRING_ORATEXT(vusername), RSTRING_LEN(vusername), RSTRING_ORATEXT(vpassword), RSTRING_LEN(vpassword), NIL_P(vdbname) ? NULL : RSTRING_ORATEXT(vdbname), NIL_P(vdbname) ? 0 : RSTRING_LEN(vdbname)); svcctx->base.hp.svc = svchp; svcctx->base.type = OCI_HTYPE_SVCCTX; svcctx->logon_type = T_IMPLICIT; if (rv != OCI_SUCCESS) { oci8_raise(oci8_errhp, rv, NULL); } break; case T_EXPLICIT: /* allocate OCI handles. */ rv = OCIHandleAlloc(oci8_envhp, &svcctx->base.hp.ptr, OCI_HTYPE_SVCCTX, 0, 0); if (rv != OCI_SUCCESS) oci8_env_raise(oci8_envhp, rv); svcctx->base.type = OCI_HTYPE_SVCCTX; rv = OCIHandleAlloc(oci8_envhp, (void*)&svcctx->authhp, OCI_HTYPE_SESSION, 0, 0); if (rv != OCI_SUCCESS) oci8_env_raise(oci8_envhp, rv); rv = OCIHandleAlloc(oci8_envhp, (void*)&svcctx->srvhp, OCI_HTYPE_SERVER, 0, 0); if (rv != OCI_SUCCESS) oci8_env_raise(oci8_envhp, rv); /* set username and password to OCISession. */ if (cred == OCI_CRED_RDBMS) { oci_lc(OCIAttrSet(svcctx->authhp, OCI_HTYPE_SESSION, RSTRING_PTR(vusername), RSTRING_LEN(vusername), OCI_ATTR_USERNAME, oci8_errhp)); oci_lc(OCIAttrSet(svcctx->authhp, OCI_HTYPE_SESSION, RSTRING_PTR(vpassword), RSTRING_LEN(vpassword), OCI_ATTR_PASSWORD, oci8_errhp)); } /* attach to server and set to OCISvcCtx. */ rv = OCIServerAttach_nb(svcctx, svcctx->srvhp, oci8_errhp, NIL_P(vdbname) ? NULL : RSTRING_ORATEXT(vdbname), NIL_P(vdbname) ? 0 : RSTRING_LEN(vdbname), OCI_DEFAULT); if (rv != OCI_SUCCESS) oci8_raise(oci8_errhp, rv, NULL); oci_lc(OCIAttrSet(svcctx->base.hp.ptr, OCI_HTYPE_SVCCTX, svcctx->srvhp, 0, OCI_ATTR_SERVER, oci8_errhp)); /* begin session. */ rv = OCISessionBegin_nb(svcctx, svcctx->base.hp.ptr, oci8_errhp, svcctx->authhp, cred, mode); if (rv != OCI_SUCCESS) oci8_raise(oci8_errhp, rv, NULL); oci_lc(OCIAttrSet(svcctx->base.hp.ptr, OCI_HTYPE_SVCCTX, svcctx->authhp, 0, OCI_ATTR_SESSION, oci8_errhp)); svcctx->logon_type = T_EXPLICIT; break; default: break; } svcctx->pid = getpid(); svcctx->is_autocommit = 0; #ifdef RUBY_VM svcctx->non_blocking = 1; #endif svcctx->long_read_len = INT2FIX(65535); return Qnil; }