/* fetch() */ static VALUE stmt_fetch(VALUE obj) { struct mysql_stmt* s = DATA_PTR(obj); VALUE ret; int i; int r; check_stmt_closed(obj); r = mysql_stmt_fetch(s->stmt); if (r == MYSQL_NO_DATA) return Qnil; #ifdef MYSQL_DATA_TRUNCATED if (r == MYSQL_DATA_TRUNCATED) rb_raise(rb_eRuntimeError, "unexpectedly data truncated"); #endif if (r == 1) mysql_stmt_raise(s->stmt); ret = rb_ary_new2(s->result.n); for (i = 0; i < s->result.n; i++) { if (s->result.is_null[i]) rb_ary_push(ret, Qnil); else { VALUE v; MYSQL_TIME *t; switch (s->result.bind[i].buffer_type) { case MYSQL_TYPE_TINY: if (s->result.bind[i].is_unsigned) v = UINT2NUM(*(unsigned char *)s->result.bind[i].buffer); else v = INT2NUM(*(signed char *)s->result.bind[i].buffer); break; case MYSQL_TYPE_SHORT: case MYSQL_TYPE_YEAR: if (s->result.bind[i].is_unsigned) v = UINT2NUM(*(unsigned short *)s->result.bind[i].buffer); else v = INT2NUM(*(short *)s->result.bind[i].buffer); break; case MYSQL_TYPE_INT24: case MYSQL_TYPE_LONG: if (s->result.bind[i].is_unsigned) v = UINT2NUM(*(unsigned int *)s->result.bind[i].buffer); else v = INT2NUM(*(int *)s->result.bind[i].buffer); break; case MYSQL_TYPE_LONGLONG: if (s->result.bind[i].is_unsigned) v = ULL2NUM(*(unsigned long long *)s->result.bind[i].buffer); else v = LL2NUM(*(long long *)s->result.bind[i].buffer); break; case MYSQL_TYPE_FLOAT: v = rb_float_new((double)(*(float *)s->result.bind[i].buffer)); break; case MYSQL_TYPE_DOUBLE: v = rb_float_new(*(double *)s->result.bind[i].buffer); break; case MYSQL_TYPE_TIME: case MYSQL_TYPE_DATE: case MYSQL_TYPE_DATETIME: case MYSQL_TYPE_TIMESTAMP: t = (MYSQL_TIME *)s->result.bind[i].buffer; v = rb_obj_alloc(cMysqlTime); rb_funcall(v, rb_intern("initialize"), 8, INT2FIX(t->year), INT2FIX(t->month), INT2FIX(t->day), INT2FIX(t->hour), INT2FIX(t->minute), INT2FIX(t->second), (t->neg ? Qtrue : Qfalse), INT2FIX(t->second_part)); break; case MYSQL_TYPE_DECIMAL: case MYSQL_TYPE_STRING: case MYSQL_TYPE_VAR_STRING: case MYSQL_TYPE_TINY_BLOB: case MYSQL_TYPE_BLOB: case MYSQL_TYPE_MEDIUM_BLOB: case MYSQL_TYPE_LONG_BLOB: #if MYSQL_VERSION_ID >= 50003 case MYSQL_TYPE_NEWDECIMAL: case MYSQL_TYPE_BIT: #endif v = rb_tainted_str_new(s->result.bind[i].buffer, s->result.length[i]); break; default: rb_raise(rb_eTypeError, "unknown buffer_type: %d", s->result.bind[i].buffer_type); } rb_ary_push(ret, v); } } return ret; }