static size_t data_handler(char * stream, size_t size, size_t nmemb, VALUE handler) { size_t str_len = size * nmemb; if(TYPE(handler) == T_STRING) { #ifdef HAVE_RUBY_ENCODING_H rb_encoding *default_internal_enc = rb_default_internal_encoding(); if (default_internal_enc) { handler = rb_str_export_to_enc(handler, default_internal_enc); } else { handler = rb_str_export_to_enc(handler, utf8Encoding); } #endif rb_str_buf_cat(handler, stream, str_len); } else { VALUE chunk = rb_str_new(stream, str_len); #ifdef HAVE_RUBY_ENCODING_H rb_encoding *default_internal_enc = rb_default_internal_encoding(); if (default_internal_enc) { chunk = rb_str_export_to_enc(chunk, default_internal_enc); } else { chunk = rb_str_export_to_enc(chunk, utf8Encoding); } #endif rb_funcall(handler, rb_intern("call"), 1, chunk); } return str_len; }
static VALUE rb_raise_mysql2_error(mysql_client_wrapper *wrapper) { VALUE rb_error_msg = rb_str_new2(mysql_error(wrapper->client)); VALUE rb_sql_state = rb_tainted_str_new2(mysql_sqlstate(wrapper->client)); VALUE e; #ifdef HAVE_RUBY_ENCODING_H if (wrapper->server_version < 50500) { /* MySQL < 5.5 uses mixed encoding, just call it binary. */ int err_enc = rb_ascii8bit_encindex(); rb_enc_associate_index(rb_error_msg, err_enc); rb_enc_associate_index(rb_sql_state, err_enc); } else { /* MySQL >= 5.5 uses UTF-8 errors internally and converts them to the connection encoding. */ rb_encoding *default_internal_enc = rb_default_internal_encoding(); rb_encoding *conn_enc = rb_to_encoding(wrapper->encoding); rb_enc_associate(rb_error_msg, conn_enc); rb_enc_associate(rb_sql_state, conn_enc); if (default_internal_enc) { rb_error_msg = rb_str_export_to_enc(rb_error_msg, default_internal_enc); rb_sql_state = rb_str_export_to_enc(rb_sql_state, default_internal_enc); } } #endif e = rb_exc_new3(cMysql2Error, rb_error_msg); rb_funcall(e, intern_error_number_eql, 1, UINT2NUM(mysql_errno(wrapper->client))); rb_funcall(e, intern_sql_state_eql, 1, rb_sql_state); rb_exc_raise(e); return Qnil; }
static int yajl_found_hash_key(void * ctx, const unsigned char * stringVal, unsigned int stringLen) { yajl_parser_wrapper * wrapper; GetParser((VALUE)ctx, wrapper); VALUE keyStr; #ifdef HAVE_RUBY_ENCODING_H rb_encoding *default_internal_enc = rb_default_internal_encoding(); #endif if (wrapper->symbolizeKeys) { char buf[stringLen+1]; memcpy(buf, stringVal, stringLen); buf[stringLen] = 0; yajl_set_static_value(ctx, ID2SYM(rb_intern(buf))); } else { keyStr = rb_str_new((const char *)stringVal, stringLen); #ifdef HAVE_RUBY_ENCODING_H rb_enc_associate(keyStr, utf8Encoding); if (default_internal_enc) { keyStr = rb_str_export_to_enc(keyStr, default_internal_enc); } #endif yajl_set_static_value(ctx, keyStr); } yajl_check_and_fire_callback(ctx); return 1; }
static VALUE rb_mysql_client_info(VALUE self) { VALUE version, client_info; #ifdef HAVE_RUBY_ENCODING_H rb_encoding *default_internal_enc; rb_encoding *conn_enc; #endif GET_CLIENT(self); version = rb_hash_new(); #ifdef HAVE_RUBY_ENCODING_H default_internal_enc = rb_default_internal_encoding(); conn_enc = rb_to_encoding(wrapper->encoding); #endif rb_hash_aset(version, sym_id, LONG2NUM(mysql_get_client_version())); client_info = rb_str_new2(mysql_get_client_info()); #ifdef HAVE_RUBY_ENCODING_H rb_enc_associate(client_info, conn_enc); if (default_internal_enc) { client_info = rb_str_export_to_enc(client_info, default_internal_enc); } #endif rb_hash_aset(version, sym_version, client_info); return version; }
static VALUE rb_mysql_client_server_info(VALUE self) { VALUE version, server_info; #ifdef HAVE_RUBY_ENCODING_H rb_encoding *default_internal_enc; rb_encoding *conn_enc; #endif GET_CLIENT(self); REQUIRE_OPEN_DB(wrapper); #ifdef HAVE_RUBY_ENCODING_H default_internal_enc = rb_default_internal_encoding(); conn_enc = rb_to_encoding(wrapper->encoding); #endif version = rb_hash_new(); rb_hash_aset(version, sym_id, LONG2FIX(mysql_get_server_version(wrapper->client))); server_info = rb_str_new2(mysql_get_server_info(wrapper->client)); #ifdef HAVE_RUBY_ENCODING_H rb_enc_associate(server_info, conn_enc); if (default_internal_enc) { server_info = rb_str_export_to_enc(server_info, default_internal_enc); } #endif rb_hash_aset(version, sym_version, server_info); return version; }
int map_key_callback(void *ctx, const unsigned char *stringVal, size_t stringLen) { VALUE key; #ifdef HAVE_RUBY_ENCODING_H rb_encoding *default_internal_enc; #endif if ( ((CTX *)ctx)->symbolizeKeys ) { #ifdef HAVE_RUBY_ENCODING_H ID id = rb_intern3((const char *)stringVal, stringLen, utf8Encoding); key = ID2SYM(id); #else VALUE str = rb_str_new((const char *)stringVal, stringLen); key = rb_str_intern(str); #endif } else { key = rb_str_new((const char *)stringVal, stringLen); #ifdef HAVE_RUBY_ENCODING_H default_internal_enc = rb_default_internal_encoding(); rb_enc_associate(key, utf8Encoding); if (default_internal_enc) { key = rb_str_export_to_enc(key, default_internal_enc); } #endif } set_key(ctx, key); return 1; }
static VALUE rb_mysql_client_escape(VALUE self, VALUE str) { MYSQL * client; VALUE newStr; unsigned long newLen, oldLen; Check_Type(str, T_STRING); #ifdef HAVE_RUBY_ENCODING_H rb_encoding *default_internal_enc = rb_default_internal_encoding(); rb_encoding *conn_enc = rb_to_encoding(rb_iv_get(self, "@encoding")); // ensure the string is in the encoding the connection is expecting str = rb_str_export_to_enc(str, conn_enc); #endif oldLen = RSTRING_LEN(str); char escaped[(oldLen*2)+1]; Data_Get_Struct(self, MYSQL, client); REQUIRE_OPEN_DB(client); newLen = mysql_real_escape_string(client, escaped, StringValuePtr(str), RSTRING_LEN(str)); if (newLen == oldLen) { // no need to return a new ruby string if nothing changed return str; } else { newStr = rb_str_new(escaped, newLen); #ifdef HAVE_RUBY_ENCODING_H rb_enc_associate(newStr, conn_enc); if (default_internal_enc) { newStr = rb_str_export_to_enc(newStr, default_internal_enc); } #endif return newStr; } }
int rb_comparator_func(void * ctx, int a_len, const void * a, int b_len, const void * b) { VALUE comparator; VALUE a_str; VALUE b_str; VALUE comparison; #ifdef HAVE_RUBY_ENCODING_H rb_encoding * internal_encoding; internal_encoding = rb_default_internal_encoding(); #endif comparator = (VALUE)ctx; a_str = rb_str_new((const char *)a, a_len); b_str = rb_str_new((const char *)b, b_len); #ifdef HAVE_RUBY_ENCODING_H rb_enc_associate_index(a_str, rb_utf8_encindex()); rb_enc_associate_index(b_str, rb_utf8_encindex()); if(internal_encoding) { a_str = rb_str_export_to_enc(a_str, internal_encoding); b_str = rb_str_export_to_enc(b_str, internal_encoding); } #endif comparison = rb_funcall(comparator, rb_intern("compare"), 2, a_str, b_str); return NUM2INT(comparison); }
static VALUE rb_mysql_result_fetch_field(VALUE self, unsigned int idx, int symbolize_keys) { VALUE rb_field; GET_RESULT(self); if (wrapper->fields == Qnil) { wrapper->numberOfFields = mysql_num_fields(wrapper->result); wrapper->fields = rb_ary_new2(wrapper->numberOfFields); } rb_field = rb_ary_entry(wrapper->fields, idx); if (rb_field == Qnil) { MYSQL_FIELD *field = NULL; rb_encoding *default_internal_enc = rb_default_internal_encoding(); rb_encoding *conn_enc = rb_to_encoding(wrapper->encoding); field = mysql_fetch_field_direct(wrapper->result, idx); if (symbolize_keys) { rb_field = rb_intern3(field->name, field->name_length, rb_utf8_encoding()); rb_field = ID2SYM(rb_field); } else { rb_field = rb_str_new(field->name, field->name_length); rb_enc_associate(rb_field, conn_enc); if (default_internal_enc) { rb_field = rb_str_export_to_enc(rb_field, default_internal_enc); } } rb_ary_store(wrapper->fields, idx, rb_field); } return rb_field; }
static VALUE rb_mysql_client_escape(VALUE self, VALUE str) { VALUE newStr; unsigned long newLen, oldLen; GET_CLIENT(self); REQUIRE_OPEN_DB(wrapper); Check_Type(str, T_STRING); #ifdef HAVE_RUBY_ENCODING_H rb_encoding *default_internal_enc = rb_default_internal_encoding(); rb_encoding *conn_enc = rb_to_encoding(wrapper->encoding); // ensure the string is in the encoding the connection is expecting str = rb_str_export_to_enc(str, conn_enc); #endif oldLen = RSTRING_LEN(str); newStr = rb_str_new(0, oldLen*2+1); newLen = mysql_real_escape_string(wrapper->client, RSTRING_PTR(newStr), StringValuePtr(str), oldLen); if (newLen == oldLen) { // no need to return a new ruby string if nothing changed return str; } else { rb_str_resize(newStr, newLen); #ifdef HAVE_RUBY_ENCODING_H rb_enc_associate(newStr, conn_enc); if (default_internal_enc) { newStr = rb_str_export_to_enc(newStr, default_internal_enc); } #endif return newStr; } }
void rb_raise_mysql2_stmt_error(mysql_stmt_wrapper *stmt_wrapper) { VALUE e; GET_CLIENT(stmt_wrapper->client); VALUE rb_error_msg = rb_str_new2(mysql_stmt_error(stmt_wrapper->stmt)); VALUE rb_sql_state = rb_tainted_str_new2(mysql_stmt_sqlstate(stmt_wrapper->stmt)); #ifdef HAVE_RUBY_ENCODING_H rb_encoding *conn_enc; conn_enc = rb_to_encoding(wrapper->encoding); rb_encoding *default_internal_enc = rb_default_internal_encoding(); rb_enc_associate(rb_error_msg, conn_enc); rb_enc_associate(rb_sql_state, conn_enc); if (default_internal_enc) { rb_error_msg = rb_str_export_to_enc(rb_error_msg, default_internal_enc); rb_sql_state = rb_str_export_to_enc(rb_sql_state, default_internal_enc); } #endif e = rb_funcall(cMysql2Error, intern_new_with_args, 4, rb_error_msg, LONG2FIX(wrapper->server_version), UINT2NUM(mysql_stmt_errno(stmt_wrapper->stmt)), rb_sql_state); rb_exc_raise(e); }
int string_callback(void *ctx, const unsigned char *stringVal, size_t stringLen) { VALUE str = rb_str_new((const char *)stringVal, stringLen); #ifdef HAVE_RUBY_ENCODING_H rb_encoding *default_internal_enc = rb_default_internal_encoding(); rb_enc_associate(str, utf8Encoding); if (default_internal_enc) { str = rb_str_export_to_enc(str, default_internal_enc); } #endif set_value(ctx,str); return 1; }
static int yajl_found_string(void * ctx, const unsigned char * stringVal, unsigned int stringLen) { VALUE str = rb_str_new((const char *)stringVal, stringLen); #ifdef HAVE_RUBY_ENCODING_H rb_encoding *default_internal_enc = rb_default_internal_encoding(); rb_enc_associate(str, utf8Encoding); if (default_internal_enc) { str = rb_str_export_to_enc(str, default_internal_enc); } #endif yajl_set_static_value(ctx, str); yajl_check_and_fire_callback(ctx); return 1; }
void CRScriptCore::InitializeEnvironment() { ATLTRACE(_("Initialize Environment in Thread:%08X\n"), GetCurrentThreadId()); #ifndef __IRubyEngine_INTERFACE_DEFINED__ int stacktop; s_pStackTop = reinterpret_cast<LPBYTE>(&stacktop); #endif int dummyargc(1); char* dummyargv[] = {"dummy", NULL }; char** pargv; ruby_sysinit(&dummyargc, &pargv); RUBY_INIT_STACK; ruby_init(); ruby_options(3, asr_argv); s_pEncoding = rb_default_internal_encoding(); if (!s_pEncoding) s_pEncoding = rb_default_external_encoding(); try { rb_require("win32ole"); VALUE v = rb_eval_string("WIN32OLE"); // override original constructor rb_define_singleton_method(v, "new", reinterpret_cast<VALUE(*)(...)>(fole_s_new), -1); rb_define_singleton_method(v, "connect", reinterpret_cast<VALUE(*)(...)>(fole_s_connect), 1); rb_define_singleton_method(v, "attach", reinterpret_cast<VALUE(*)(...)>(foleex_attach), 2); rb_define_method(v, "__release", reinterpret_cast<VALUE(*)(...)>(foleex_release), 0); rb_define_method(v, "method_missing", reinterpret_cast<VALUE(*)(...)>(foleex_missing), -1); rb_define_method(v, "each", reinterpret_cast<VALUE(*)(...)>(foleex_each), 0); if (rb_const_defined_at(v, rb_intern("ARGV")) == Qfalse) { rb_define_const(v, "ARGV", rb_ary_new()); } s_valueWin32Ole = v; s_valueWIN32OLERuntimeError = rb_eval_string("WIN32OLERuntimeError"); v = rb_define_class("WIN32OLEEX", v); s_valueWin32OleEx = v; rb_define_singleton_method(v, "attach", reinterpret_cast<VALUE(*)(...)>(foleex_attach), 2); rb_define_method(v, "method_missing", reinterpret_cast<VALUE(*)(...)>(foleex_missing), -1); // s_valueActiveRubyScript = rb_define_class("ActiveScriptRuby", rb_cObject); rb_define_singleton_method(s_valueActiveRubyScript, "trace", (VALUE(*)(...))trace_hook, 6); rb_define_singleton_method(s_valueActiveRubyScript, "settrace", (VALUE(*)(...))trace_set, 1); rb_define_singleton_method(s_valueActiveRubyScript, "rubyize", (VALUE(*)(...))rubyize, 1); } catch (...) { ATLTRACE(_T("Exception for class\n")); } }
// read from buffer and return a ruby string // params: start=0, length=self.length, encoding=Encoding.default_internal_encoding // return: ruby string VALUE ruv_buffer_read(int argc, VALUE* argv, VALUE rb_buffer) { VALUE rb_start, rb_length, rb_intern_enc, rb_str; size_t start, length; rb_encoding *intern_enc; ruv_buffer_t *buffer; char *str_p; Data_Get_Struct(rb_buffer, ruv_buffer_t, buffer); rb_scan_args(argc, argv, "03", &rb_start, &rb_length, &rb_intern_enc); if(!NIL_P(rb_start)) { Check_Type(rb_start, T_FIXNUM); start = NUM2SIZET(rb_start); } else { start = 0; } if(start >= buffer->length) { rb_raise(rb_eArgError, "start is out of bounds."); } if(!NIL_P(rb_length)) { Check_Type(rb_length, T_FIXNUM); length = NUM2SIZET(length); } else { length = buffer->length - start; } // make sure it's not out of bound length = MIN(length, buffer->length - start); if(!NIL_P(rb_intern_enc)) { intern_enc = rb_enc_get(rb_intern_enc); } else { intern_enc = rb_default_internal_encoding(); } str_p = buffer->data + start; rb_str = rb_tainted_str_new(str_p, length); if(intern_enc) { rb_str = rb_str_export_to_enc(rb_str, intern_enc); } return rb_str; }
static VALUE rb_mysql_result_fetch_field(VALUE self, unsigned int idx, short int symbolize_keys) { mysql2_result_wrapper * wrapper; VALUE rb_field; GetMysql2Result(self, wrapper); if (wrapper->fields == Qnil) { wrapper->numberOfFields = mysql_num_fields(wrapper->result); wrapper->fields = rb_ary_new2(wrapper->numberOfFields); } rb_field = rb_ary_entry(wrapper->fields, idx); if (rb_field == Qnil) { MYSQL_FIELD *field = NULL; #ifdef HAVE_RUBY_ENCODING_H rb_encoding *default_internal_enc = rb_default_internal_encoding(); rb_encoding *conn_enc = rb_to_encoding(wrapper->encoding); #endif field = mysql_fetch_field_direct(wrapper->result, idx); if (symbolize_keys) { char buf[field->name_length+1]; memcpy(buf, field->name, field->name_length); buf[field->name_length] = 0; #ifdef HAVE_RB_INTERN3 rb_field = rb_intern3(buf, field->name_length, rb_utf8_encoding()); rb_field = ID2SYM(rb_field); #else VALUE colStr; colStr = rb_str_new2(buf); rb_field = ID2SYM(rb_to_id(colStr)); #endif } else { rb_field = rb_str_new(field->name, field->name_length); #ifdef HAVE_RUBY_ENCODING_H rb_enc_associate(rb_field, conn_enc); if (default_internal_enc) { rb_field = rb_str_export_to_enc(rb_field, default_internal_enc); } #endif } rb_ary_store(wrapper->fields, idx, rb_field); } return rb_field; }
static VALUE rb_mysql_client_info(RB_MYSQL_UNUSED VALUE self) { VALUE version = rb_hash_new(), client_info; #ifdef HAVE_RUBY_ENCODING_H rb_encoding *default_internal_enc = rb_default_internal_encoding(); rb_encoding *conn_enc = rb_to_encoding(rb_iv_get(self, "@encoding")); #endif rb_hash_aset(version, sym_id, LONG2NUM(mysql_get_client_version())); client_info = rb_str_new2(mysql_get_client_info()); #ifdef HAVE_RUBY_ENCODING_H rb_enc_associate(client_info, conn_enc); if (default_internal_enc) { client_info = rb_str_export_to_enc(client_info, default_internal_enc); } #endif rb_hash_aset(version, sym_version, client_info); return version; }
static VALUE file_path_convert(VALUE name) { #ifndef _WIN32 /* non Windows == Unix */ rb_encoding *fname_encoding = rb_enc_from_index(ENCODING_GET(name)); rb_encoding *fs_encoding; if (rb_default_internal_encoding() != NULL && rb_usascii_encoding() != fname_encoding && rb_ascii8bit_encoding() != fname_encoding && (fs_encoding = rb_filesystem_encoding()) != fname_encoding && !rb_enc_str_asciionly_p(name)) { /* Don't call rb_filesystem_encoding() before US-ASCII and ASCII-8BIT */ /* fs_encoding should be ascii compatible */ name = rb_str_conv_enc(name, fname_encoding, fs_encoding); } #endif return name; }
/* * Common typecasting logic that can be used or overriden by Adapters. */ extern VALUE data_objects_typecast(const char *value, long length, const VALUE type, int encoding) { #ifdef HAVE_RUBY_ENCODING_H rb_encoding *internal_encoding = rb_default_internal_encoding(); #else void *internal_encoding = NULL; #endif if (type == rb_cInteger) { return rb_cstr2inum(value, 10); } else if (type == rb_cString) { return DATA_OBJECTS_STR_NEW(value, length, encoding, internal_encoding); } else if (type == rb_cFloat) { return rb_float_new(rb_cstr_to_dbl(value, Qfalse)); } else if (type == rb_cBigDecimal) { return rb_funcall(rb_cBigDecimal, DO_ID_NEW, 1, rb_str_new(value, length)); } else if (type == rb_cDate) { return data_objects_parse_date(value); } else if (type == rb_cDateTime) { return data_objects_parse_date_time(value); } else if (type == rb_cTime) { return data_objects_parse_time(value); } else if (type == rb_cTrueClass) { return (!value || strcmp("0", value) == 0) ? Qfalse : Qtrue; } else if (type == rb_cByteArray) { return rb_funcall(rb_cByteArray, DO_ID_NEW, 1, rb_str_new(value, length)); } else if (type == rb_cClass) { return rb_funcall(mDO, rb_intern("full_const_get"), 1, rb_str_new(value, length)); } else if (type == rb_cNilClass) { return Qnil; } else { return DATA_OBJECTS_STR_NEW(value, length, encoding, internal_encoding); } }
/* call-seq: * client.escape(string) * * Escape +string+ so that it may be used in a SQL statement. */ static VALUE rb_mysql_client_real_escape(VALUE self, VALUE str) { unsigned char *newStr; VALUE rb_str; unsigned long newLen, oldLen; #ifdef HAVE_RUBY_ENCODING_H rb_encoding *default_internal_enc; rb_encoding *conn_enc; #endif GET_CLIENT(self); REQUIRE_CONNECTED(wrapper); Check_Type(str, T_STRING); #ifdef HAVE_RUBY_ENCODING_H default_internal_enc = rb_default_internal_encoding(); conn_enc = rb_to_encoding(wrapper->encoding); /* ensure the string is in the encoding the connection is expecting */ str = rb_str_export_to_enc(str, conn_enc); #endif oldLen = RSTRING_LEN(str); newStr = xmalloc(oldLen*2+1); newLen = mysql_real_escape_string(wrapper->client, (char *)newStr, RSTRING_PTR(str), oldLen); if (newLen == oldLen) { /* no need to return a new ruby string if nothing changed */ #ifdef HAVE_RUBY_ENCODING_H if (default_internal_enc) { str = rb_str_export_to_enc(str, default_internal_enc); } #endif xfree(newStr); return str; } else { rb_str = rb_str_new((const char*)newStr, newLen); #ifdef HAVE_RUBY_ENCODING_H rb_enc_associate(rb_str, conn_enc); if (default_internal_enc) { rb_str = rb_str_export_to_enc(rb_str, default_internal_enc); } #endif xfree(newStr); return rb_str; } }
/* call-seq: stmt.fields # => array * * Returns a list of fields that will be returned by this statement. */ static VALUE fields(VALUE self) { MYSQL_FIELD *fields; MYSQL_RES *metadata; unsigned int field_count; unsigned int i; VALUE field_list; MYSQL_STMT* stmt; #ifdef HAVE_RUBY_ENCODING_H rb_encoding *default_internal_enc, *conn_enc; #endif GET_STATEMENT(self); stmt = stmt_wrapper->stmt; #ifdef HAVE_RUBY_ENCODING_H default_internal_enc = rb_default_internal_encoding(); { GET_CLIENT(stmt_wrapper->client); conn_enc = rb_to_encoding(wrapper->encoding); } #endif metadata = mysql_stmt_result_metadata(stmt); fields = mysql_fetch_fields(metadata); field_count = mysql_stmt_field_count(stmt); field_list = rb_ary_new2((long)field_count); for(i = 0; i < field_count; i++) { VALUE rb_field; rb_field = rb_str_new(fields[i].name, fields[i].name_length); #ifdef HAVE_RUBY_ENCODING_H rb_enc_associate(rb_field, conn_enc); if (default_internal_enc) { rb_field = rb_str_export_to_enc(rb_field, default_internal_enc); } #endif rb_ary_store(field_list, (long)i, rb_field); } mysql_free_result(metadata); return field_list; }
static VALUE rb_raise_mysql2_error(mysql_client_wrapper *wrapper) { VALUE rb_error_msg = rb_str_new2(mysql_error(wrapper->client)); VALUE rb_sql_state = rb_tainted_str_new2(mysql_sqlstate(wrapper->client)); #ifdef HAVE_RUBY_ENCODING_H rb_encoding *default_internal_enc = rb_default_internal_encoding(); rb_encoding *conn_enc = rb_to_encoding(wrapper->encoding); rb_enc_associate(rb_error_msg, conn_enc); rb_enc_associate(rb_sql_state, conn_enc); if (default_internal_enc) { rb_error_msg = rb_str_export_to_enc(rb_error_msg, default_internal_enc); rb_sql_state = rb_str_export_to_enc(rb_sql_state, default_internal_enc); } #endif VALUE e = rb_exc_new3(cMysql2Error, rb_error_msg); rb_funcall(e, intern_error_number_eql, 1, UINT2NUM(mysql_errno(wrapper->client))); rb_funcall(e, intern_sql_state_eql, 1, rb_sql_state); rb_exc_raise(e); return Qnil; }
static VALUE rb_mysql_client_server_info(VALUE self) { MYSQL * client; VALUE version, server_info; #ifdef HAVE_RUBY_ENCODING_H rb_encoding *default_internal_enc = rb_default_internal_encoding(); rb_encoding *conn_enc = rb_to_encoding(rb_iv_get(self, "@encoding")); #endif Data_Get_Struct(self, MYSQL, client); REQUIRE_OPEN_DB(client); version = rb_hash_new(); rb_hash_aset(version, sym_id, LONG2FIX(mysql_get_server_version(client))); server_info = rb_str_new2(mysql_get_server_info(client)); #ifdef HAVE_RUBY_ENCODING_H rb_enc_associate(server_info, conn_enc); if (default_internal_enc) { server_info = rb_str_export_to_enc(server_info, default_internal_enc); } #endif rb_hash_aset(version, sym_version, server_info); return version; }
/* * call-seq: * parser.parse(yaml) * * Parse the YAML document contained in +yaml+. Events will be called on * the handler set on the parser instance. * * See Psych::Parser and Psych::Parser#handler */ static VALUE parse(VALUE self, VALUE yaml) { yaml_parser_t parser; yaml_event_t event; int done = 0; #ifdef HAVE_RUBY_ENCODING_H int encoding = rb_enc_find_index("ASCII-8BIT"); rb_encoding * internal_enc; #endif VALUE handler = rb_iv_get(self, "@handler"); yaml_parser_initialize(&parser); if(rb_respond_to(yaml, id_read)) { yaml_parser_set_input(&parser, io_reader, (void *)yaml); } else { StringValue(yaml); yaml_parser_set_input_string( &parser, (const unsigned char *)RSTRING_PTR(yaml), (size_t)RSTRING_LEN(yaml) ); } while(!done) { if(!yaml_parser_parse(&parser, &event)) { size_t line = parser.mark.line; size_t column = parser.mark.column; yaml_parser_delete(&parser); rb_raise(ePsychSyntaxError, "couldn't parse YAML at line %d column %d", (int)line, (int)column); } switch(event.type) { case YAML_STREAM_START_EVENT: #ifdef HAVE_RUBY_ENCODING_H switch(event.data.stream_start.encoding) { case YAML_ANY_ENCODING: break; case YAML_UTF8_ENCODING: encoding = rb_enc_find_index("UTF-8"); break; case YAML_UTF16LE_ENCODING: encoding = rb_enc_find_index("UTF-16LE"); break; case YAML_UTF16BE_ENCODING: encoding = rb_enc_find_index("UTF-16BE"); break; default: break; } internal_enc = rb_default_internal_encoding(); #endif rb_funcall(handler, id_start_stream, 1, INT2NUM((long)event.data.stream_start.encoding) ); break; case YAML_DOCUMENT_START_EVENT: { /* Get a list of tag directives (if any) */ VALUE tag_directives = rb_ary_new(); /* Grab the document version */ VALUE version = event.data.document_start.version_directive ? rb_ary_new3( (long)2, INT2NUM((long)event.data.document_start.version_directive->major), INT2NUM((long)event.data.document_start.version_directive->minor) ) : rb_ary_new(); if(event.data.document_start.tag_directives.start) { yaml_tag_directive_t *start = event.data.document_start.tag_directives.start; yaml_tag_directive_t *end = event.data.document_start.tag_directives.end; for(; start != end; start++) { VALUE handle = Qnil; VALUE prefix = Qnil; if(start->handle) { handle = rb_str_new2((const char *)start->handle); #ifdef HAVE_RUBY_ENCODING_H PSYCH_TRANSCODE(handle, encoding, internal_enc); #endif } if(start->prefix) { prefix = rb_str_new2((const char *)start->prefix); #ifdef HAVE_RUBY_ENCODING_H PSYCH_TRANSCODE(prefix, encoding, internal_enc); #endif } rb_ary_push(tag_directives, rb_ary_new3((long)2, handle, prefix)); } } rb_funcall(handler, id_start_document, 3, version, tag_directives, event.data.document_start.implicit == 1 ? Qtrue : Qfalse ); } break; case YAML_DOCUMENT_END_EVENT: rb_funcall(handler, id_end_document, 1, event.data.document_end.implicit == 1 ? Qtrue : Qfalse ); break; case YAML_ALIAS_EVENT: { VALUE alias = Qnil; if(event.data.alias.anchor) { alias = rb_str_new2((const char *)event.data.alias.anchor); #ifdef HAVE_RUBY_ENCODING_H PSYCH_TRANSCODE(alias, encoding, internal_enc); #endif } rb_funcall(handler, id_alias, 1, alias); } break; case YAML_SCALAR_EVENT: { VALUE anchor = Qnil; VALUE tag = Qnil; VALUE plain_implicit, quoted_implicit, style; VALUE val = rb_str_new( (const char *)event.data.scalar.value, (long)event.data.scalar.length ); #ifdef HAVE_RUBY_ENCODING_H PSYCH_TRANSCODE(val, encoding, internal_enc); #endif if(event.data.scalar.anchor) { anchor = rb_str_new2((const char *)event.data.scalar.anchor); #ifdef HAVE_RUBY_ENCODING_H PSYCH_TRANSCODE(anchor, encoding, internal_enc); #endif } if(event.data.scalar.tag) { tag = rb_str_new2((const char *)event.data.scalar.tag); #ifdef HAVE_RUBY_ENCODING_H PSYCH_TRANSCODE(tag, encoding, internal_enc); #endif } plain_implicit = event.data.scalar.plain_implicit == 0 ? Qfalse : Qtrue; quoted_implicit = event.data.scalar.quoted_implicit == 0 ? Qfalse : Qtrue; style = INT2NUM((long)event.data.scalar.style); rb_funcall(handler, id_scalar, 6, val, anchor, tag, plain_implicit, quoted_implicit, style); } break; case YAML_SEQUENCE_START_EVENT: { VALUE anchor = Qnil; VALUE tag = Qnil; VALUE implicit, style; if(event.data.sequence_start.anchor) { anchor = rb_str_new2((const char *)event.data.sequence_start.anchor); #ifdef HAVE_RUBY_ENCODING_H PSYCH_TRANSCODE(anchor, encoding, internal_enc); #endif } tag = Qnil; if(event.data.sequence_start.tag) { tag = rb_str_new2((const char *)event.data.sequence_start.tag); #ifdef HAVE_RUBY_ENCODING_H PSYCH_TRANSCODE(tag, encoding, internal_enc); #endif } implicit = event.data.sequence_start.implicit == 0 ? Qfalse : Qtrue; style = INT2NUM((long)event.data.sequence_start.style); rb_funcall(handler, id_start_sequence, 4, anchor, tag, implicit, style); } break; case YAML_SEQUENCE_END_EVENT: rb_funcall(handler, id_end_sequence, 0); break; case YAML_MAPPING_START_EVENT: { VALUE anchor = Qnil; VALUE tag = Qnil; VALUE implicit, style; if(event.data.mapping_start.anchor) { anchor = rb_str_new2((const char *)event.data.mapping_start.anchor); #ifdef HAVE_RUBY_ENCODING_H PSYCH_TRANSCODE(anchor, encoding, internal_enc); #endif } if(event.data.mapping_start.tag) { tag = rb_str_new2((const char *)event.data.mapping_start.tag); #ifdef HAVE_RUBY_ENCODING_H PSYCH_TRANSCODE(tag, encoding, internal_enc); #endif } implicit = event.data.mapping_start.implicit == 0 ? Qfalse : Qtrue; style = INT2NUM((long)event.data.mapping_start.style); rb_funcall(handler, id_start_mapping, 4, anchor, tag, implicit, style); } break; case YAML_MAPPING_END_EVENT: rb_funcall(handler, id_end_mapping, 0); break; case YAML_NO_EVENT: rb_funcall(handler, id_empty, 0); break; case YAML_STREAM_END_EVENT: rb_funcall(handler, id_end_stream, 0); done = 1; break; } } return self; }
static VALUE step(VALUE self) { sqlite3StmtRubyPtr ctx; sqlite3_stmt *stmt; int value, length; VALUE list; rb_encoding * internal_encoding; Data_Get_Struct(self, sqlite3StmtRuby, ctx); REQUIRE_OPEN_STMT(ctx); if(ctx->done_p) return Qnil; { VALUE db = rb_iv_get(self, "@connection"); rb_funcall(db, rb_intern("encoding"), 0); internal_encoding = rb_default_internal_encoding(); } stmt = ctx->st; value = sqlite3_step(stmt); length = sqlite3_column_count(stmt); list = rb_ary_new2((long)length); switch(value) { case SQLITE_ROW: { int i; for(i = 0; i < length; i++) { switch(sqlite3_column_type(stmt, i)) { case SQLITE_INTEGER: rb_ary_push(list, LL2NUM(sqlite3_column_int64(stmt, i))); break; case SQLITE_FLOAT: rb_ary_push(list, rb_float_new(sqlite3_column_double(stmt, i))); break; case SQLITE_TEXT: { VALUE str = rb_tainted_str_new( (const char *)sqlite3_column_text(stmt, i), (long)sqlite3_column_bytes(stmt, i) ); rb_enc_associate_index(str, rb_utf8_encindex()); if(internal_encoding) str = rb_str_export_to_enc(str, internal_encoding); rb_ary_push(list, str); } break; case SQLITE_BLOB: { VALUE str = rb_tainted_str_new( (const char *)sqlite3_column_blob(stmt, i), (long)sqlite3_column_bytes(stmt, i) ); rb_ary_push(list, str); } break; case SQLITE_NULL: rb_ary_push(list, Qnil); break; default: rb_raise(rb_eRuntimeError, "bad type"); } } } break; case SQLITE_DONE: ctx->done_p = 1; return Qnil; break; default: sqlite3_reset(stmt); ctx->done_p = 0; CHECK(sqlite3_db_handle(ctx->st), value); } return list; }
static VALUE encoding_spec_rb_default_internal_encoding(VALUE self) { rb_encoding* enc = rb_default_internal_encoding(); if(enc == 0) return Qnil; return rb_str_new2(enc->name); }
VALUE rb_enc_default_internal(void) { /* Note: These functions cope with default_internal not being set */ return rb_enc_from_encoding(rb_default_internal_encoding()); }
static VALUE rb_mysql_result_fetch_row_stmt(VALUE self, MYSQL_FIELD * fields, const result_each_args *args) { VALUE rowVal; unsigned int i = 0; #ifdef HAVE_RUBY_ENCODING_H rb_encoding *default_internal_enc; rb_encoding *conn_enc; #endif GET_RESULT(self); #ifdef HAVE_RUBY_ENCODING_H default_internal_enc = rb_default_internal_encoding(); conn_enc = rb_to_encoding(wrapper->encoding); #endif if (args->asArray) { rowVal = rb_ary_new2(wrapper->numberOfFields); } else { rowVal = rb_hash_new(); } if (wrapper->fields == Qnil) { wrapper->numberOfFields = mysql_num_fields(wrapper->result); wrapper->fields = rb_ary_new2(wrapper->numberOfFields); } if (wrapper->result_buffers == NULL) { rb_mysql_result_alloc_result_buffers(self, fields); } if (mysql_stmt_bind_result(wrapper->stmt_wrapper->stmt, wrapper->result_buffers)) { rb_raise_mysql2_stmt_error(wrapper->stmt_wrapper); } { switch((uintptr_t)rb_thread_call_without_gvl(nogvl_stmt_fetch, wrapper->stmt_wrapper->stmt, RUBY_UBF_IO, 0)) { case 0: /* success */ break; case 1: /* error */ rb_raise_mysql2_stmt_error(wrapper->stmt_wrapper); case MYSQL_NO_DATA: /* no more row */ return Qnil; case MYSQL_DATA_TRUNCATED: rb_raise(cMysql2Error, "IMPLBUG: caught MYSQL_DATA_TRUNCATED. should not come here as buffer_length is set to fields[i].max_length."); } } for (i = 0; i < wrapper->numberOfFields; i++) { VALUE field = rb_mysql_result_fetch_field(self, i, args->symbolizeKeys); VALUE val = Qnil; MYSQL_TIME *ts; if (wrapper->is_null[i]) { val = Qnil; } else { const MYSQL_BIND* const result_buffer = &wrapper->result_buffers[i]; switch(result_buffer->buffer_type) { case MYSQL_TYPE_TINY: // signed char if (args->castBool && fields[i].length == 1) { val = (*((unsigned char*)result_buffer->buffer) != 0) ? Qtrue : Qfalse; break; } if (result_buffer->is_unsigned) { val = UINT2NUM(*((unsigned char*)result_buffer->buffer)); } else { val = INT2NUM(*((signed char*)result_buffer->buffer)); } break; case MYSQL_TYPE_SHORT: // short int if (result_buffer->is_unsigned) { val = UINT2NUM(*((unsigned short int*)result_buffer->buffer)); } else { val = INT2NUM(*((short int*)result_buffer->buffer)); } break; case MYSQL_TYPE_INT24: // int case MYSQL_TYPE_LONG: // int case MYSQL_TYPE_YEAR: // int if (result_buffer->is_unsigned) { val = UINT2NUM(*((unsigned int*)result_buffer->buffer)); } else { val = INT2NUM(*((int*)result_buffer->buffer)); } break; case MYSQL_TYPE_LONGLONG: // long long int if (result_buffer->is_unsigned) { val = ULL2NUM(*((unsigned long long int*)result_buffer->buffer)); } else { val = LL2NUM(*((long long int*)result_buffer->buffer)); } break; case MYSQL_TYPE_FLOAT: // float val = rb_float_new((double)(*((float*)result_buffer->buffer))); break; case MYSQL_TYPE_DOUBLE: // double val = rb_float_new((double)(*((double*)result_buffer->buffer))); break; case MYSQL_TYPE_DATE: // MYSQL_TIME case MYSQL_TYPE_NEWDATE: // MYSQL_TIME ts = (MYSQL_TIME*)result_buffer->buffer; val = rb_funcall(cDate, intern_new, 3, INT2NUM(ts->year), INT2NUM(ts->month), INT2NUM(ts->day)); break; case MYSQL_TYPE_TIME: // MYSQL_TIME ts = (MYSQL_TIME*)result_buffer->buffer; val = rb_funcall(rb_cTime, args->db_timezone, 7, opt_time_year, opt_time_month, opt_time_month, UINT2NUM(ts->hour), UINT2NUM(ts->minute), UINT2NUM(ts->second), ULONG2NUM(ts->second_part)); if (!NIL_P(args->app_timezone)) { if (args->app_timezone == intern_local) { val = rb_funcall(val, intern_localtime, 0); } else { // utc val = rb_funcall(val, intern_utc, 0); } } break; case MYSQL_TYPE_DATETIME: // MYSQL_TIME case MYSQL_TYPE_TIMESTAMP: { // MYSQL_TIME uint64_t seconds; ts = (MYSQL_TIME*)result_buffer->buffer; seconds = (ts->year*31557600ULL) + (ts->month*2592000ULL) + (ts->day*86400ULL) + (ts->hour*3600ULL) + (ts->minute*60ULL) + ts->second; if (seconds < MYSQL2_MIN_TIME || seconds > MYSQL2_MAX_TIME) { // use DateTime instead VALUE offset = INT2NUM(0); if (args->db_timezone == intern_local) { offset = rb_funcall(cMysql2Client, intern_local_offset, 0); } val = rb_funcall(cDateTime, intern_civil, 7, UINT2NUM(ts->year), UINT2NUM(ts->month), UINT2NUM(ts->day), UINT2NUM(ts->hour), UINT2NUM(ts->minute), UINT2NUM(ts->second), offset); if (!NIL_P(args->app_timezone)) { if (args->app_timezone == intern_local) { offset = rb_funcall(cMysql2Client, intern_local_offset, 0); val = rb_funcall(val, intern_new_offset, 1, offset); } else { // utc val = rb_funcall(val, intern_new_offset, 1, opt_utc_offset); } } } else { val = rb_funcall(rb_cTime, args->db_timezone, 7, UINT2NUM(ts->year), UINT2NUM(ts->month), UINT2NUM(ts->day), UINT2NUM(ts->hour), UINT2NUM(ts->minute), UINT2NUM(ts->second), ULONG2NUM(ts->second_part)); if (!NIL_P(args->app_timezone)) { if (args->app_timezone == intern_local) { val = rb_funcall(val, intern_localtime, 0); } else { // utc val = rb_funcall(val, intern_utc, 0); } } } break; } case MYSQL_TYPE_DECIMAL: // char[] case MYSQL_TYPE_NEWDECIMAL: // char[] val = rb_funcall(cBigDecimal, intern_new, 1, rb_str_new(result_buffer->buffer, *(result_buffer->length))); break; case MYSQL_TYPE_STRING: // char[] case MYSQL_TYPE_VAR_STRING: // char[] case MYSQL_TYPE_VARCHAR: // char[] case MYSQL_TYPE_TINY_BLOB: // char[] case MYSQL_TYPE_BLOB: // char[] case MYSQL_TYPE_MEDIUM_BLOB: // char[] case MYSQL_TYPE_LONG_BLOB: // char[] case MYSQL_TYPE_BIT: // char[] case MYSQL_TYPE_SET: // char[] case MYSQL_TYPE_ENUM: // char[] case MYSQL_TYPE_GEOMETRY: // char[] default: val = rb_str_new(result_buffer->buffer, *(result_buffer->length)); #ifdef HAVE_RUBY_ENCODING_H val = mysql2_set_field_string_encoding(val, fields[i], default_internal_enc, conn_enc); #endif break; } } if (args->asArray) { rb_ary_push(rowVal, val); } else { rb_hash_aset(rowVal, field, val); } } return rowVal; }
static VALUE rb_mysql_result_fetch_row(VALUE self, MYSQL_FIELD * fields, const result_each_args *args) { VALUE rowVal; MYSQL_ROW row; unsigned int i = 0; unsigned long * fieldLengths; void * ptr; #ifdef HAVE_RUBY_ENCODING_H rb_encoding *default_internal_enc; rb_encoding *conn_enc; #endif GET_RESULT(self); #ifdef HAVE_RUBY_ENCODING_H default_internal_enc = rb_default_internal_encoding(); conn_enc = rb_to_encoding(wrapper->encoding); #endif ptr = wrapper->result; row = (MYSQL_ROW)rb_thread_call_without_gvl(nogvl_fetch_row, ptr, RUBY_UBF_IO, 0); if (row == NULL) { return Qnil; } if (args->asArray) { rowVal = rb_ary_new2(wrapper->numberOfFields); } else { rowVal = rb_hash_new(); } fieldLengths = mysql_fetch_lengths(wrapper->result); if (wrapper->fields == Qnil) { wrapper->numberOfFields = mysql_num_fields(wrapper->result); wrapper->fields = rb_ary_new2(wrapper->numberOfFields); } for (i = 0; i < wrapper->numberOfFields; i++) { VALUE field = rb_mysql_result_fetch_field(self, i, args->symbolizeKeys); if (row[i]) { VALUE val = Qnil; enum enum_field_types type = fields[i].type; if (!args->cast) { if (type == MYSQL_TYPE_NULL) { val = Qnil; } else { val = rb_str_new(row[i], fieldLengths[i]); #ifdef HAVE_RUBY_ENCODING_H val = mysql2_set_field_string_encoding(val, fields[i], default_internal_enc, conn_enc); #endif } } else { switch(type) { case MYSQL_TYPE_NULL: /* NULL-type field */ val = Qnil; break; case MYSQL_TYPE_BIT: /* BIT field (MySQL 5.0.3 and up) */ if (args->castBool && fields[i].length == 1) { val = *row[i] == 1 ? Qtrue : Qfalse; }else{ val = rb_str_new(row[i], fieldLengths[i]); } break; case MYSQL_TYPE_TINY: /* TINYINT field */ if (args->castBool && fields[i].length == 1) { val = *row[i] != '0' ? Qtrue : Qfalse; break; } case MYSQL_TYPE_SHORT: /* SMALLINT field */ case MYSQL_TYPE_LONG: /* INTEGER field */ case MYSQL_TYPE_INT24: /* MEDIUMINT field */ case MYSQL_TYPE_LONGLONG: /* BIGINT field */ case MYSQL_TYPE_YEAR: /* YEAR field */ val = rb_cstr2inum(row[i], 10); break; case MYSQL_TYPE_DECIMAL: /* DECIMAL or NUMERIC field */ case MYSQL_TYPE_NEWDECIMAL: /* Precision math DECIMAL or NUMERIC field (MySQL 5.0.3 and up) */ if (fields[i].decimals == 0) { val = rb_cstr2inum(row[i], 10); } else if (strtod(row[i], NULL) == 0.000000){ val = rb_funcall(cBigDecimal, intern_new, 1, opt_decimal_zero); }else{ val = rb_funcall(cBigDecimal, intern_new, 1, rb_str_new(row[i], fieldLengths[i])); } break; case MYSQL_TYPE_FLOAT: /* FLOAT field */ case MYSQL_TYPE_DOUBLE: { /* DOUBLE or REAL field */ double column_to_double; column_to_double = strtod(row[i], NULL); if (column_to_double == 0.000000){ val = opt_float_zero; }else{ val = rb_float_new(column_to_double); } break; } case MYSQL_TYPE_TIME: { /* TIME field */ int tokens; unsigned int hour=0, min=0, sec=0, msec=0; char msec_char[7] = {'0','0','0','0','0','0','\0'}; tokens = sscanf(row[i], "%2u:%2u:%2u.%6s", &hour, &min, &sec, msec_char); if (tokens < 3) { val = Qnil; break; } msec = msec_char_to_uint(msec_char, sizeof(msec_char)); val = rb_funcall(rb_cTime, args->db_timezone, 7, opt_time_year, opt_time_month, opt_time_month, UINT2NUM(hour), UINT2NUM(min), UINT2NUM(sec), UINT2NUM(msec)); if (!NIL_P(args->app_timezone)) { if (args->app_timezone == intern_local) { val = rb_funcall(val, intern_localtime, 0); } else { /* utc */ val = rb_funcall(val, intern_utc, 0); } } break; } case MYSQL_TYPE_TIMESTAMP: /* TIMESTAMP field */ case MYSQL_TYPE_DATETIME: { /* DATETIME field */ int tokens; unsigned int year=0, month=0, day=0, hour=0, min=0, sec=0, msec=0; char msec_char[7] = {'0','0','0','0','0','0','\0'}; uint64_t seconds; tokens = sscanf(row[i], "%4u-%2u-%2u %2u:%2u:%2u.%6s", &year, &month, &day, &hour, &min, &sec, msec_char); if (tokens < 6) { /* msec might be empty */ val = Qnil; break; } seconds = (year*31557600ULL) + (month*2592000ULL) + (day*86400ULL) + (hour*3600ULL) + (min*60ULL) + sec; if (seconds == 0) { val = Qnil; } else { if (month < 1 || day < 1) { rb_raise(cMysql2Error, "Invalid date in field '%.*s': %s", fields[i].name_length, fields[i].name, row[i]); val = Qnil; } else { if (seconds < MYSQL2_MIN_TIME || seconds > MYSQL2_MAX_TIME) { /* use DateTime for larger date range, does not support microseconds */ VALUE offset = INT2NUM(0); if (args->db_timezone == intern_local) { offset = rb_funcall(cMysql2Client, intern_local_offset, 0); } val = rb_funcall(cDateTime, intern_civil, 7, UINT2NUM(year), UINT2NUM(month), UINT2NUM(day), UINT2NUM(hour), UINT2NUM(min), UINT2NUM(sec), offset); if (!NIL_P(args->app_timezone)) { if (args->app_timezone == intern_local) { offset = rb_funcall(cMysql2Client, intern_local_offset, 0); val = rb_funcall(val, intern_new_offset, 1, offset); } else { /* utc */ val = rb_funcall(val, intern_new_offset, 1, opt_utc_offset); } } } else { msec = msec_char_to_uint(msec_char, sizeof(msec_char)); val = rb_funcall(rb_cTime, args->db_timezone, 7, UINT2NUM(year), UINT2NUM(month), UINT2NUM(day), UINT2NUM(hour), UINT2NUM(min), UINT2NUM(sec), UINT2NUM(msec)); if (!NIL_P(args->app_timezone)) { if (args->app_timezone == intern_local) { val = rb_funcall(val, intern_localtime, 0); } else { /* utc */ val = rb_funcall(val, intern_utc, 0); } } } } } break; } case MYSQL_TYPE_DATE: /* DATE field */ case MYSQL_TYPE_NEWDATE: { /* Newer const used > 5.0 */ int tokens; unsigned int year=0, month=0, day=0; tokens = sscanf(row[i], "%4u-%2u-%2u", &year, &month, &day); if (tokens < 3) { val = Qnil; break; } if (year+month+day == 0) { val = Qnil; } else { if (month < 1 || day < 1) { rb_raise(cMysql2Error, "Invalid date in field '%.*s': %s", fields[i].name_length, fields[i].name, row[i]); val = Qnil; } else { val = rb_funcall(cDate, intern_new, 3, UINT2NUM(year), UINT2NUM(month), UINT2NUM(day)); } } break; } case MYSQL_TYPE_TINY_BLOB: case MYSQL_TYPE_MEDIUM_BLOB: case MYSQL_TYPE_LONG_BLOB: case MYSQL_TYPE_BLOB: case MYSQL_TYPE_VAR_STRING: case MYSQL_TYPE_VARCHAR: case MYSQL_TYPE_STRING: /* CHAR or BINARY field */ case MYSQL_TYPE_SET: /* SET field */ case MYSQL_TYPE_ENUM: /* ENUM field */ case MYSQL_TYPE_GEOMETRY: /* Spatial fielda */ default: val = rb_str_new(row[i], fieldLengths[i]); #ifdef HAVE_RUBY_ENCODING_H val = mysql2_set_field_string_encoding(val, fields[i], default_internal_enc, conn_enc); #endif break; } } if (args->asArray) { rb_ary_push(rowVal, val); } else { rb_hash_aset(rowVal, field, val); } } else { if (args->asArray) { rb_ary_push(rowVal, Qnil); } else { rb_hash_aset(rowVal, field, Qnil); } } } return rowVal; }
static VALUE oci8_lob_read(int argc, VALUE *argv, VALUE self) { oci8_lob_t *lob = DATA_PTR(self); oci8_svcctx_t *svcctx = oci8_get_svcctx(lob->svc); ub4 length; ub4 nchar; ub4 amt; sword rv; char buf[8192]; size_t buf_size_in_char; VALUE size; VALUE v = rb_ary_new(); rb_scan_args(argc, argv, "01", &size); length = oci8_lob_get_length(lob); if (length <= lob->pos) /* EOF */ return Qnil; length -= lob->pos; if (NIL_P(size)) { nchar = length; /* read until EOF */ } else { nchar = NUM2UINT(size); if (nchar > length) nchar = length; } amt = nchar; buf_size_in_char = sizeof(buf) / lob->char_width; do { if (lob->state == S_BFILE_CLOSE) { rv = OCILobFileOpen_nb(svcctx, svcctx->base.hp.svc, oci8_errhp, lob->base.hp.lob, OCI_FILE_READONLY); if (rv == OCI_ERROR && oci8_get_error_code(oci8_errhp) == 22290) { /* ORA-22290: operation would exceed the maximum number of opened files or LOBs */ /* close all opened BFILE implicitly. */ oci8_base_t *base; for (base = &lob->base; base != &lob->base; base = base->next) { if (base->type == OCI_DTYPE_LOB) { oci8_lob_t *tmp = (oci8_lob_t *)base; if (tmp->state == S_BFILE_OPEN) { tmp->state = S_BFILE_CLOSE; } } } oci_lc(OCILobFileCloseAll_nb(svcctx, svcctx->base.hp.svc, oci8_errhp)); continue; } if (rv != OCI_SUCCESS) oci8_raise(oci8_errhp, rv, NULL); lob->state = S_BFILE_OPEN; } /* initialize buf in zeros everytime to check a nul characters. */ memset(buf, 0, sizeof(buf)); rv = OCILobRead_nb(svcctx, svcctx->base.hp.svc, oci8_errhp, lob->base.hp.lob, &amt, lob->pos + 1, buf, sizeof(buf), NULL, NULL, 0, lob->csfrm); if (rv == OCI_ERROR && oci8_get_error_code(oci8_errhp) == 22289) { /* ORA-22289: cannot perform FILEREAD operation on an unopened file or LOB */ if (lob->state == S_BFILE_CLOSE) continue; } if (rv != OCI_SUCCESS && rv != OCI_NEED_DATA) oci8_raise(oci8_errhp, rv, NULL); /* Workaround when using Oracle 10.2.0.4 or 11.1.0.6 client and * variable-length character set (e.g. AL32UTF8). * * When the above mentioned condition, amt may be shorter. So * amt is increaded until a nul character to know the actually * read size. */ while (amt < sizeof(buf) && buf[amt] != '\0') { amt++; } if (amt == 0) break; /* for fixed size charset, amt is the number of characters stored in buf. */ if (amt > buf_size_in_char) rb_raise(eOCIException, "Too large buffer fetched or you set too large size of a character."); amt *= lob->char_width; rb_ary_push(v, rb_str_new(buf, amt)); } while (rv == OCI_NEED_DATA); lob->pos += nchar; if (nchar == length) { lob_close(lob); bfile_close(lob); } if (RARRAY_LEN(v) == 0) { return Qnil; } 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; } }