| ATTR_UPDATE_MAX_LENGTH | = | INT2NUM(STMT_ATTR_UPDATE_MAX_LENGTH) |
/* affected_rows() */
static VALUE stmt_affected_rows(VALUE obj)
{
struct mysql_stmt* s = DATA_PTR(obj);
my_ulonglong n;
check_stmt_closed(obj);
n = mysql_stmt_affected_rows(s->stmt);
return INT2NUM(n);
}
attr_get(option)
/* attr_get(option) */
static VALUE stmt_attr_get(VALUE obj, VALUE opt)
{
struct mysql_stmt* s = DATA_PTR(obj);
check_stmt_closed(obj);
if (NUM2INT(opt) == STMT_ATTR_UPDATE_MAX_LENGTH) {
my_bool arg;
mysql_stmt_attr_get(s->stmt, STMT_ATTR_UPDATE_MAX_LENGTH, &arg);
return arg == 1 ? Qtrue : Qfalse;
}
rb_raise(eMysql, "unknown option: %d", NUM2INT(opt));
}
attr_set(option, arg)
/* attr_set(option, arg) */
static VALUE stmt_attr_set(VALUE obj, VALUE opt, VALUE val)
{
struct mysql_stmt* s = DATA_PTR(obj);
check_stmt_closed(obj);
if (NUM2INT(opt) == STMT_ATTR_UPDATE_MAX_LENGTH) {
my_bool arg;
arg = (val == Qnil || val == Qfalse) ? 0 : 1;
mysql_stmt_attr_set(s->stmt, STMT_ATTR_UPDATE_MAX_LENGTH, &arg);
return obj;
}
rb_raise(eMysql, "unknown option: %d", NUM2INT(opt));
}
close()
/* close() */
static VALUE stmt_close(VALUE obj)
{
struct mysql_stmt* s = DATA_PTR(obj);
check_stmt_closed(obj);
mysql_stmt_close(s->stmt);
s->closed = Qtrue;
return Qnil;
}
each {…}
/* each {...} */
static VALUE stmt_each(VALUE obj)
{
VALUE row;
check_stmt_closed(obj);
while ((row = stmt_fetch(obj)) != Qnil)
rb_yield(row);
return obj;
}
execute(arg,…)
/* execute(arg,...) */
static VALUE stmt_execute(int argc, VALUE *argv, VALUE obj)
{
struct mysql_stmt *s = DATA_PTR(obj);
MYSQL_STMT *stmt = s->stmt;
my_bool true = 1;
my_bool false = 0;
int i;
check_stmt_closed(obj);
if (s->param.n != argc)
rb_raise(eMysql, "execute: param_count(%d) != number of argument(%d)", s->param.n, argc);
memset(s->param.bind, 0, sizeof(*(s->param.bind))*argc);
for (i = 0; i < argc; i++) {
switch (TYPE(argv[i])) {
case T_NIL:
s->param.bind[i].buffer_type = MYSQL_TYPE_NULL;
s->param.bind[i].is_null = &true;
break;
case T_FIXNUM:
s->param.bind[i].buffer_type = MYSQL_TYPE_LONG;
s->param.bind[i].buffer = &(s->param.buffer[i]);
*(long*)(s->param.bind[i].buffer) = FIX2INT(argv[i]);
break;
case T_BIGNUM:
s->param.bind[i].buffer_type = MYSQL_TYPE_LONGLONG;
s->param.bind[i].buffer = &(s->param.buffer[i]);
*(long long*)(s->param.bind[i].buffer) = rb_big2ll(argv[i]);
break;
case T_FLOAT:
s->param.bind[i].buffer_type = MYSQL_TYPE_DOUBLE;
s->param.bind[i].buffer = &(s->param.buffer[i]);
*(double*)(s->param.bind[i].buffer) = NUM2DBL(argv[i]);
break;
case T_STRING:
s->param.bind[i].buffer_type = MYSQL_TYPE_STRING;
s->param.bind[i].buffer = RSTRING(argv[i])->ptr;
s->param.bind[i].buffer_length = RSTRING(argv[i])->len;
s->param.length[i] = RSTRING(argv[i])->len;
s->param.bind[i].length = &(s->param.length[i]);
break;
default:
if (CLASS_OF(argv[i]) == rb_cTime) {
MYSQL_TIME t;
VALUE a = rb_funcall(argv[i], rb_intern("to_a"), 0);
s->param.bind[i].buffer_type = MYSQL_TYPE_DATETIME;
s->param.bind[i].buffer = &(s->param.buffer[i]);
t.second_part = 0;
t.neg = 0;
t.second = FIX2INT(RARRAY(a)->ptr[0]);
t.minute = FIX2INT(RARRAY(a)->ptr[1]);
t.hour = FIX2INT(RARRAY(a)->ptr[2]);
t.day = FIX2INT(RARRAY(a)->ptr[3]);
t.month = FIX2INT(RARRAY(a)->ptr[4]);
t.year = FIX2INT(RARRAY(a)->ptr[5]);
t.time_type = MYSQL_TYPE_DATETIME;
*(MYSQL_TIME*)&(s->param.buffer[i]) = t;
} else if (CLASS_OF(argv[i]) == cMysqlTime) {
MYSQL_TIME t;
s->param.bind[i].buffer_type = MYSQL_TYPE_DATETIME;
s->param.bind[i].buffer = &(s->param.buffer[i]);
t.second_part = 0;
t.neg = 0;
t.second = NUM2INT(rb_iv_get(argv[i], "second"));
t.minute = NUM2INT(rb_iv_get(argv[i], "minute"));
t.hour = NUM2INT(rb_iv_get(argv[i], "hour"));
t.day = NUM2INT(rb_iv_get(argv[i], "day"));
t.month = NUM2INT(rb_iv_get(argv[i], "month"));
t.year = NUM2INT(rb_iv_get(argv[i], "year"));
t.time_type = MYSQL_TYPE_DATETIME;
*(MYSQL_TIME*)&(s->param.buffer[i]) = t;
} else
rb_raise(rb_eTypeError, "unsupported type: %d", TYPE(argv[i]));
}
}
if (mysql_stmt_bind_param(stmt, s->param.bind))
mysql_stmt_raise(stmt);
if (mysql_stmt_execute(stmt))
mysql_stmt_raise(stmt);
if (s->res) {
MYSQL_FIELD *field;
if (mysql_stmt_store_result(stmt))
mysql_stmt_raise(stmt);
field = mysql_fetch_fields(s->res);
for (i = 0; i < s->result.n; i++) {
if (s->result.bind[i].buffer_type == MYSQL_TYPE_STRING ||
s->result.bind[i].buffer_type == MYSQL_TYPE_BLOB) {
s->result.bind[i].buffer = xmalloc(field[i].max_length);
memset(s->result.bind[i].buffer, 0, field[i].max_length);
s->result.bind[i].buffer_length = field[i].max_length;
} else {
s->result.bind[i].buffer = xmalloc(sizeof(MYSQL_TIME));
s->result.bind[i].buffer_length = sizeof(MYSQL_TIME);
memset(s->result.bind[i].buffer, 0, sizeof(MYSQL_TIME));
}
}
if (mysql_stmt_bind_result(s->stmt, s->result.bind))
mysql_stmt_raise(s->stmt);
}
return obj;
}
fetch()
/* 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;
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_LONG:
v = INT2NUM(*(long*)s->result.bind[i].buffer);
break;
case MYSQL_TYPE_LONGLONG:
v = rb_ll2inum(*(long long*)s->result.bind[i].buffer);
break;
case MYSQL_TYPE_DOUBLE:
v = rb_float_new(*(double*)s->result.bind[i].buffer);
break;
case MYSQL_TYPE_TIMESTAMP:
case MYSQL_TYPE_DATE:
case MYSQL_TYPE_TIME:
case MYSQL_TYPE_DATETIME:
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_STRING:
case MYSQL_TYPE_BLOB:
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;
}
/* field_count() */
static VALUE stmt_field_count(VALUE obj)
{
struct mysql_stmt* s = DATA_PTR(obj);
unsigned int n;
check_stmt_closed(obj);
n = mysql_stmt_field_count(s->stmt);
return INT2NUM(n);
}
/* free_result() */
static VALUE stmt_free_result(VALUE obj)
{
struct mysql_stmt* s = DATA_PTR(obj);
check_stmt_closed(obj);
if (s->res) {
mysql_free_result(s->res);
s->res = NULL;
}
if (mysql_stmt_free_result(s->stmt))
mysql_stmt_raise(s->stmt);
return obj;
}
/* param_count() */
static VALUE stmt_param_count(VALUE obj)
{
struct mysql_stmt* s = DATA_PTR(obj);
unsigned long n;
check_stmt_closed(obj);
n = mysql_stmt_param_count(s->stmt);
return INT2NUM(n);
}
reset()
/* reset() */
static VALUE stmt_reset(VALUE obj)
{
struct mysql_stmt* s = DATA_PTR(obj);
check_stmt_closed(obj);
if (mysql_stmt_reset(s->stmt))
mysql_stmt_raise(s->stmt);
return obj;
}
/* result_metadata() */
static VALUE stmt_result_metadata(VALUE obj)
{
struct mysql_stmt* s = DATA_PTR(obj);
MYSQL_RES *res;
check_stmt_closed(obj);
res = mysql_stmt_result_metadata(s->stmt);
if (res == NULL && mysql_stmt_errno(s->stmt) != 0)
mysql_stmt_raise(s->stmt);
return mysqlres2obj(res);
}
row_seek(offset)
/* row_seek(offset) */
static VALUE stmt_row_seek(VALUE obj, VALUE offset)
{
struct mysql_stmt* s = DATA_PTR(obj);
MYSQL_ROW_OFFSET prev_offset;
if (CLASS_OF(offset) != cMysqlRowOffset)
rb_raise(rb_eTypeError, "wrong argument type %s (expected Mysql::RowOffset)", rb_obj_classname(offset));
check_stmt_closed(obj);
prev_offset = mysql_stmt_row_seek(s->stmt, DATA_PTR(offset));
return Data_Wrap_Struct(cMysqlRowOffset, 0, NULL, prev_offset);
}
send_long_data(col, data)
/* send_long_data(col, data) */
static VALUE stmt_send_long_data(VALUE obj, VALUE col, VALUE data)
{
struct mysql_stmt* s = DATA_PTR(obj);
int c;
check_stmt_closed(obj);
c = NUM2INT(col);
if (0 <= c && c < s->param.n) {
s->param.bind[c].buffer_type = MYSQL_TYPE_STRING;
if (mysql_stmt_bind_param(s->stmt, s->param.bind))
mysql_stmt_raise(s->stmt);
}
if (mysql_stmt_send_long_data(s->stmt, c, RSTRING(data)->ptr, RSTRING(data)->len))
mysql_stmt_raise(s->stmt);
return obj;
}