I really want prepared statement functionality for mysql so I wrote a little
proof of concept.
It can be used like this: db.prepared("insert into log
values(0,?,?)",[123,"abc"]);
I'm new to v8 and v8cgi and haven't used the mysql C api that much either but
the code works so far.
It's not complete, I don't bother freeing memory, etc. - but if there is
interest in including something like this I could improve and maintain it.
JS_METHOD(_prepared) {
MYSQL_PTR;
ASSERT_CONNECTED;
if (args.Length() < 1) {
return JS_ERROR("No query specified");
}
if (args.Length() < 2 || !args[1]->IsArray()) {
return JS_ERROR("no prepare stuff");
}
if (args.Length() > 2) {
return JS_ERROR("too many args");
}
v8::Handle<v8::Array> js_query_params = v8::Handle<v8::Array>::Cast(args[1]);
if (js_query_params->Length()<=0) {
return JS_ERROR("prepared param array empty");
}
MYSQL_STMT *stmt;
{
stmt = mysql_stmt_init(conn);
v8::String::Utf8Value q(args[0]);
if (mysql_stmt_prepare(stmt, *q, q.length()) != 0) {
return JS_ERROR(MYSQL_ERROR);
}
}
MYSQL_BIND c_query_params[js_query_params->Length()];
for (unsigned int i = 0; i < js_query_params->Length(); i++) {
if (js_query_params->Get(i)->IsString()) {
v8::String::Utf8Value s(js_query_params->Get(i));
c_query_params[i].buffer_type = MYSQL_TYPE_VAR_STRING;
c_query_params[i].buffer = strndup(*s,s.length()+1);
c_query_params[i].is_unsigned = 0;
c_query_params[i].is_null = 0;
c_query_params[i].length = new unsigned long(s.length());
continue;
}
if (js_query_params->Get(i)->IsNumber()) {
v8::Handle<v8::Number> n=v8::Handle<v8::Number>::Cast(js_query_params->Get(i));
c_query_params[i].buffer_type = MYSQL_TYPE_DOUBLE;
c_query_params[i].buffer = new double((*n)->Value());
c_query_params[i].is_unsigned = 0;
c_query_params[i].is_null = 0;
c_query_params[i].length = 0;
continue;
}
return JS_ERROR("invalid type for prepared arg");
}
if(mysql_stmt_bind_param(stmt, c_query_params) != 0) {
return JS_ERROR(MYSQL_ERROR);
}
int code = mysql_stmt_execute(stmt);
if (code != 0) { return JS_ERROR(MYSQL_ERROR); }
int qc = args.This()->Get(JS_STR("queryCount"))->ToInteger()->Int32Value();
args.This()->Set(JS_STR("queryCount"), JS_INT(qc+1));
return createResult(conn);
}
Original issue reported on code.google.com by rom.p.k...@gmail.com on 7 May 2012 at 12:36
Original issue reported on code.google.com by
rom.p.k...@gmail.com
on 7 May 2012 at 12:36