let's try that again - libmysql only allows one query be sent at a time per connection, bail early if that's attempted

This commit is contained in:
Brian Lopez 2010-08-03 20:37:49 -07:00
parent 1a70e83a74
commit c0cf2f13a0
2 changed files with 29 additions and 3 deletions

View File

@ -12,6 +12,9 @@ extern ID intern_merge;
return Qnil; \
}
#define MARK_CONN_INACTIVE(conn) \
rb_iv_set(conn, "@active", Qfalse);
/*
* used to pass all arguments to mysql_real_connect while inside
* rb_thread_blocking_region
@ -147,8 +150,7 @@ static VALUE rb_connect(VALUE self, VALUE user, VALUE pass, VALUE host, VALUE po
args.mysql = client;
args.client_flag = 0;
if (rb_thread_blocking_region(nogvl_connect, &args, RUBY_UBF_IO, 0) == Qfalse)
{
if (rb_thread_blocking_region(nogvl_connect, &args, RUBY_UBF_IO, 0) == Qfalse) {
// unable to connect
return rb_raise_mysql2_error(client);
}
@ -214,10 +216,16 @@ static VALUE rb_mysql_client_async_result(VALUE self) {
REQUIRE_OPEN_DB(client);
if (rb_thread_blocking_region(nogvl_read_query_result, client, RUBY_UBF_IO, 0) == Qfalse) {
// an error occurred, mark this connection inactive
MARK_CONN_INACTIVE(self);
return rb_raise_mysql2_error(client);
}
result = (MYSQL_RES *)rb_thread_blocking_region(nogvl_store_result, client, RUBY_UBF_IO, 0);
// we have our result, mark this connection inactive
MARK_CONN_INACTIVE(self);
if (result == NULL) {
if (mysql_field_count(client) != 0) {
rb_raise_mysql2_error(client);
@ -240,13 +248,22 @@ static VALUE rb_mysql_client_query(int argc, VALUE * argv, VALUE self) {
fd_set fdset;
int fd, retval;
int async = 0;
VALUE opts, defaults;
VALUE opts, defaults, active;
MYSQL *client;
Data_Get_Struct(self, MYSQL, client);
REQUIRE_OPEN_DB(client);
args.mysql = client;
active = rb_iv_get(self, "@active");
// see if this connection is still waiting on a result from a previous query
if (NIL_P(active) || active == Qfalse) {
// mark this connection active
rb_iv_set(self, "@active", Qtrue);
} else {
rb_raise(cMysql2Error, "This connection is still waiting for a result, try again once you have the result");
}
defaults = rb_iv_get(self, "@query_options");
if (rb_scan_args(argc, argv, "11", &args.sql, &opts) == 2) {
opts = rb_funcall(defaults, intern_merge, 1, opts);
@ -266,6 +283,8 @@ static VALUE rb_mysql_client_query(int argc, VALUE * argv, VALUE self) {
#endif
if (rb_thread_blocking_region(nogvl_send_query, &args, RUBY_UBF_IO, 0) == Qfalse) {
// an error occurred, we're not active anymore
MARK_CONN_INACTIVE(self);
return rb_raise_mysql2_error(client);
}

View File

@ -71,6 +71,13 @@ describe Mysql2::Client do
it "should be able to return results with symbolized keys" do
@client.query("SELECT 1", :symbolize_keys => true).first.keys[0].class.should eql(Symbol)
end
it "should not allow another query to be sent without fetching a result first" do
@client.query("SELECT 1", :async => true)
lambda {
@client.query("SELECT 1")
}.should raise_error(Mysql2::Error)
end
end
it "should respond to #escape" do