/* call-seq: * client.query(sql, options = {}) * * Query the database with +sql+, with optional +options+. For the possible * options, see default_query_options on the Mysql2::Client class. */ static VALUE rb_query(VALUE self, VALUE sql, VALUE current) { #ifndef _WIN32 struct async_query_args async_args; #endif struct nogvl_send_query_args args; GET_CLIENT(self); REQUIRE_CONNECTED(wrapper); args.mysql = wrapper->client; (void)RB_GC_GUARD(current); Check_Type(current, T_HASH); rb_iv_set(self, "@current_query_options", current); Check_Type(sql, T_STRING); #ifdef HAVE_RUBY_ENCODING_H /* ensure the string is in the encoding the connection is expecting */ args.sql = rb_str_export_to_enc(sql, rb_to_encoding(wrapper->encoding)); #else args.sql = sql; #endif args.sql_ptr = RSTRING_PTR(args.sql); args.sql_len = RSTRING_LEN(args.sql); args.wrapper = wrapper; rb_mysql_client_set_active_thread(self); #ifndef _WIN32 rb_rescue2(do_send_query, (VALUE)&args, disconnect_and_raise, self, rb_eException, (VALUE)0); if (rb_hash_aref(current, sym_async) == Qtrue) { return Qnil; } else { async_args.fd = wrapper->client->net.fd; async_args.self = self; rb_rescue2(do_query, (VALUE)&async_args, disconnect_and_raise, self, rb_eException, (VALUE)0); return rb_mysql_client_async_result(self); } #else do_send_query(&args); /* this will just block until the result is ready */ return rb_ensure(rb_mysql_client_async_result, self, finish_and_mark_inactive, self); #endif }
/* call-seq: * client.query(sql, options = {}) * * Query the database with +sql+, with optional +options+. For the possible * options, see @@default_query_options on the Mysql2::Client class. */ static VALUE rb_mysql_client_query(int argc, VALUE * argv, VALUE self) { #ifndef _WIN32 struct async_query_args async_args; #endif struct nogvl_send_query_args args; int async = 0; VALUE opts, current; VALUE thread_current = rb_thread_current(); #ifdef HAVE_RUBY_ENCODING_H rb_encoding *conn_enc; #endif GET_CLIENT(self); REQUIRE_CONNECTED(wrapper); args.mysql = wrapper->client; current = rb_hash_dup(rb_iv_get(self, "@query_options")); RB_GC_GUARD(current); Check_Type(current, T_HASH); rb_iv_set(self, "@current_query_options", current); if (rb_scan_args(argc, argv, "11", &args.sql, &opts) == 2) { rb_funcall(current, intern_merge_bang, 1, opts); if (rb_hash_aref(current, sym_async) == Qtrue) { async = 1; } } Check_Type(args.sql, T_STRING); #ifdef HAVE_RUBY_ENCODING_H conn_enc = rb_to_encoding(wrapper->encoding); /* ensure the string is in the encoding the connection is expecting */ args.sql = rb_str_export_to_enc(args.sql, conn_enc); #endif args.sql_ptr = RSTRING_PTR(args.sql); args.sql_len = RSTRING_LEN(args.sql); /* see if this connection is still waiting on a result from a previous query */ if (NIL_P(wrapper->active_thread)) { /* mark this connection active */ wrapper->active_thread = thread_current; } else if (wrapper->active_thread == thread_current) { rb_raise(cMysql2Error, "This connection is still waiting for a result, try again once you have the result"); } else { VALUE inspect = rb_inspect(wrapper->active_thread); const char *thr = StringValueCStr(inspect); rb_raise(cMysql2Error, "This connection is in use by: %s", thr); RB_GC_GUARD(inspect); } args.wrapper = wrapper; #ifndef _WIN32 rb_rescue2(do_send_query, (VALUE)&args, disconnect_and_raise, self, rb_eException, (VALUE)0); if (!async) { async_args.fd = wrapper->client->net.fd; async_args.self = self; rb_rescue2(do_query, (VALUE)&async_args, disconnect_and_raise, self, rb_eException, (VALUE)0); return rb_mysql_client_async_result(self); } else { return Qnil; } #else do_send_query(&args); /* this will just block until the result is ready */ return rb_ensure(rb_mysql_client_async_result, self, finish_and_mark_inactive, self); #endif }
static VALUE rb_mysql_client_query(int argc, VALUE * argv, VALUE self) { #ifndef _WIN32 struct async_query_args async_args; #endif struct nogvl_send_query_args args; int async = 0; VALUE opts, defaults; #ifdef HAVE_RUBY_ENCODING_H rb_encoding *conn_enc; #endif GET_CLIENT(self); REQUIRE_OPEN_DB(wrapper); args.mysql = wrapper->client; 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); rb_iv_set(self, "@query_options", opts); if (rb_hash_aref(opts, sym_async) == Qtrue) { async = 1; } } else { opts = defaults; } Check_Type(args.sql, T_STRING); #ifdef HAVE_RUBY_ENCODING_H conn_enc = rb_to_encoding(wrapper->encoding); // ensure the string is in the encoding the connection is expecting args.sql = rb_str_export_to_enc(args.sql, conn_enc); #endif args.sql_ptr = StringValuePtr(args.sql); args.sql_len = RSTRING_LEN(args.sql); // see if this connection is still waiting on a result from a previous query if (wrapper->active == 0) { // mark this connection active wrapper->active = 1; } else { rb_raise(cMysql2Error, "This connection is still waiting for a result, try again once you have the result"); } args.wrapper = wrapper; #ifndef _WIN32 rb_rescue2(do_send_query, (VALUE)&args, disconnect_and_raise, self, rb_eException, (VALUE)0); if (!async) { async_args.fd = wrapper->client->net.fd; async_args.self = self; rb_rescue2(do_query, (VALUE)&async_args, disconnect_and_raise, self, rb_eException, (VALUE)0); return rb_mysql_client_async_result(self); } else { return Qnil; } #else do_send_query(&args); // this will just block until the result is ready return rb_ensure(rb_mysql_client_async_result, self, finish_and_mark_inactive, self); #endif }