/* 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;
}