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 = DATA_PTR(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; oci_lc(OCILobFileGetName(oci8_envhp, oci8_errhp, lob->base.hp.lob, TO_ORATEXT(d_buf), &d_length, TO_ORATEXT(f_buf), &f_length)); 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; } } }
VALUE oci8_get_error_message(ub4 msgno, const char *default_msg) { char head[32]; size_t headsz; const char *errmsg = NULL; char msgbuf[64]; if (have_OCIMessageGet) { if (msghp == NULL) { chkerr(OCIMessageOpen(oci8_envhp, oci8_errhp, &msghp, TO_ORATEXT("rdbms"), TO_ORATEXT("ora"), OCI_DURATION_PROCESS)); } errmsg = TO_CHARPTR(OCIMessageGet(msghp, msgno, NULL, 0)); } if (errmsg == NULL) { if (default_msg != NULL) { errmsg = default_msg; } else { /* last resort */ snprintf(msgbuf, sizeof(msgbuf), "Message %u not found; product=rdbms; facility=ora", msgno); errmsg = msgbuf; } } headsz = snprintf(head, sizeof(head), "ORA-%05u: ", msgno); return rb_str_append(rb_usascii_str_new(head, headsz), rb_external_str_new_with_enc(errmsg, strlen(errmsg), oci8_encoding)); }
static VALUE get_rowid_attr(rowid_arg_t *arg) { oci8_base_t *base = arg->base; ub4 attrtype = arg->attrtype; char buf[MAX_ROWID_LEN]; ub2 buflen; sword rv; /* get a rowid descriptor from OCIHandle */ rv = OCIDescriptorAlloc(oci8_envhp, (dvoid*)&arg->ridp, OCI_DTYPE_ROWID, 0, NULL); if (rv != OCI_SUCCESS) oci8_env_raise(oci8_envhp, rv); rv = OCIAttrGet(base->hp.ptr, base->type, arg->ridp, 0, attrtype, oci8_errhp); if (rv != OCI_SUCCESS) { oci8_raise(oci8_errhp, rv, NULL); } /* convert the rowid descriptor to a string. */ if (have_OCIRowidToChar) { /* If OCIRowidToChar is available, use it. */ buflen = MAX_ROWID_LEN; rv = OCIRowidToChar(arg->ridp, TO_ORATEXT(buf), &buflen, oci8_errhp); if (rv != OCI_SUCCESS) { oci8_raise(oci8_errhp, rv, NULL); } } else { /* If OCIRowidToChar is not available, convert it on * Oracle Server. */ oci8_base_t *svc; oci8_exec_sql_var_t define_var; oci8_exec_sql_var_t bind_var; /* search a connection from the handle */ svc = base; while (svc->type != OCI_HTYPE_SVCCTX) { svc = svc->parent; if (svc == NULL) { rb_raise(rb_eRuntimeError, "No connection is found!!"); } } /* :strval */ define_var.valuep = buf; define_var.value_sz = sizeof(buf); define_var.dty = SQLT_CHR; define_var.indp = NULL; define_var.alenp = &buflen; /* :rowid */ bind_var.valuep = &arg->ridp; bind_var.value_sz = sizeof(void *); bind_var.dty = SQLT_RDD; bind_var.indp = NULL; bind_var.alenp = NULL; /* convert the rowid descriptor to a string value by querying Oracle server. */ oci8_exec_sql((oci8_svcctx_t*)svc, "SELECT :rid FROM dual", 1, &define_var, 1, &bind_var, 1); if (buflen == 0) { return Qnil; } } return rb_external_str_new_with_enc(buf, buflen, rb_usascii_encoding()); }
/* Converts to BigDecimal via number in scientific notation */ static VALUE onum_to_d_real(OCINumber *num, OCIError *errhp) { char buf[64]; ub4 buf_size = sizeof(buf); const char *fmt = "FM9.99999999999999999999999999999999999999EEEE"; if (!cBigDecimal) { rb_require("bigdecimal"); cBigDecimal = rb_const_get(rb_cObject, id_BigDecimal); } chkerr(OCINumberToText(errhp, num, (const oratext *)fmt, strlen(fmt), NULL, 0, &buf_size, TO_ORATEXT(buf))); return rb_funcall(rb_cObject, id_BigDecimal, 1, rb_usascii_str_new(buf, buf_size)); }
/* * call-seq: * onum.to_char(fmt = nil, nls_params = nil) -> string * * Returns a string containing a representation of self. * <i>fmt</i> and <i>nls_params</i> are same meanings with * <code>TO_CHAR</code> of Oracle function. */ static VALUE onum_to_char(int argc, VALUE *argv, VALUE self) { OCIError *errhp = oci8_errhp; VALUE fmt; VALUE nls_params; char buf[512]; ub4 buf_size = sizeof(buf); oratext *fmt_ptr; oratext *nls_params_ptr; ub4 fmt_len; ub4 nls_params_len; sword rv; rb_scan_args(argc, argv, "02", &fmt /* nil */, &nls_params /* nil */); if (NIL_P(fmt)) { rv = oranumber_to_str(_NUMBER(self), buf, sizeof(buf)); if (rv > 0) { return rb_usascii_str_new(buf, rv); } oranumber_dump(_NUMBER(self), buf); rb_raise(eOCIException, "Invalid internal number format: %s", buf); } 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); } rv = OCINumberToText(errhp, _NUMBER(self), fmt_ptr, fmt_len, nls_params_ptr, nls_params_len, &buf_size, TO_ORATEXT(buf)); if (rv == OCI_ERROR) { sb4 errcode; OCIErrorGet(errhp, 1, NULL, &errcode, NULL, 0, OCI_HTYPE_ERROR); if (errcode == 22065) { /* OCI-22065: number to text translation for the given format causes overflow */ if (NIL_P(fmt)) /* implicit conversion */ return rb_usascii_str_new_cstr("overflow"); } chkerr(rv); } return rb_usascii_str_new(buf, buf_size); }
static VALUE get_error_msg(dvoid *errhp, ub4 type, const char *default_msg, sb4 *errcode_p) { sword rv; size_t len; retry: errbuf[0] = '\0'; rv = OCIErrorGet(errhp, 1, NULL, errcode_p, TO_ORATEXT(errbuf), errbufsiz, type); /* OCI manual says: * If type is set to OCI_HTYPE_ERROR, then the return * code during truncation for OCIErrorGet() is * OCI_ERROR. The client can then specify a bigger * buffer and call OCIErrorGet() again. * * But as far as I tested on Oracle XE 10.2.0.1, the return * code is OCI_SUCCESS when the message is truncated. */ len = strlen(errbuf); if (errbufsiz - len <= 7) { /* The error message may be truncated. * The magic number 7 means the maximum length of one utf-8 * character plus the length of a nul terminator. */ errbufsiz += ERRBUF_EXPAND_LEN; errbuf = xrealloc(errbuf, errbufsiz); goto retry; } if (rv != OCI_SUCCESS) { /* No message is found. Use the default message. */ return rb_usascii_str_new_cstr(default_msg); } /* truncate trailing CR and LF */ while (len > 0 && (errbuf[len - 1] == '\n' || errbuf[len - 1] == '\r')) { len--; } return rb_external_str_new_with_enc(errbuf, len, oci8_encoding); }