Skip to content

Commit fd0f716

Browse files
committed
Merge branch 'master' into 0.2.x
2 parents 901b308 + 455396b commit fd0f716

File tree

11 files changed

+126
-14
lines changed

11 files changed

+126
-14
lines changed

.travis.yml

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,6 @@ rvm:
99
- rbx-19mode
1010
- rbx-20mode
1111
bundler_args: --without benchmarks
12-
matrix:
13-
allow_failures:
14-
- rvm: rbx-19mode
15-
- rvm: rbx-20mode
1612
script:
1713
- bundle exec rake
1814
- bundle exec rspec

Gemfile

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,3 +10,7 @@ group :benchmarks do
1010
gem 'sequel'
1111
gem 'faker'
1212
end
13+
14+
group :development do
15+
gem 'pry'
16+
end

Gemfile.lock

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ GEM
2525
arel (4.0.0)
2626
atomic (1.1.10)
2727
builder (3.1.4)
28+
coderay (1.0.9)
2829
data_objects (0.10.13)
2930
addressable (~> 2.1)
3031
diff-lcs (1.1.3)
@@ -34,9 +35,14 @@ GEM
3435
faker (1.1.2)
3536
i18n (~> 0.5)
3637
i18n (0.6.4)
38+
method_source (0.8.1)
3739
minitest (4.7.5)
3840
multi_json (1.7.7)
3941
mysql (2.9.1)
42+
pry (0.9.12.2)
43+
coderay (~> 1.0.5)
44+
method_source (~> 0.8)
45+
slop (~> 3.4)
4046
rake (0.9.6)
4147
rake-compiler (0.8.3)
4248
rake
@@ -49,6 +55,7 @@ GEM
4955
diff-lcs (~> 1.1.2)
5056
rspec-mocks (2.8.0)
5157
sequel (4.0.0)
58+
slop (3.4.5)
5259
thread_safe (0.1.0)
5360
atomic
5461
tzinfo (0.3.37)
@@ -63,6 +70,7 @@ DEPENDENCIES
6370
faker
6471
mysql
6572
mysql2!
73+
pry
6674
rake (~> 0.9.3)
6775
rake-compiler (~> 0.8.1)
6876
rspec (~> 2.8.0)

ext/mysql2/client.c

Lines changed: 39 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -259,6 +259,25 @@ static VALUE rb_mysql_client_warning_count(VALUE self) {
259259
return UINT2NUM(warning_count);
260260
}
261261

262+
static VALUE rb_mysql_info(VALUE self) {
263+
const char *info;
264+
VALUE rb_str;
265+
GET_CLIENT(self);
266+
267+
info = mysql_info(wrapper->client);
268+
269+
if (info == NULL) {
270+
return Qnil;
271+
}
272+
273+
rb_str = rb_str_new2(info);
274+
#ifdef HAVE_RUBY_ENCODING_H
275+
rb_enc_associate(rb_str, rb_utf8_encoding());
276+
#endif
277+
278+
return rb_str;
279+
}
280+
262281
static VALUE rb_connect(VALUE self, VALUE user, VALUE pass, VALUE host, VALUE port, VALUE database, VALUE socket, VALUE flags) {
263282
struct nogvl_connect_args args;
264283
VALUE rv;
@@ -375,6 +394,7 @@ static VALUE nogvl_use_result(void *ptr) {
375394
static VALUE rb_mysql_client_async_result(VALUE self) {
376395
MYSQL_RES * result;
377396
VALUE resultObj;
397+
VALUE current, is_streaming;
378398
GET_CLIENT(self);
379399

380400
/* if we're not waiting on a result, do nothing */
@@ -388,7 +408,7 @@ static VALUE rb_mysql_client_async_result(VALUE self) {
388408
return rb_raise_mysql2_error(wrapper);
389409
}
390410

391-
VALUE is_streaming = rb_hash_aref(rb_iv_get(self, "@current_query_options"), sym_stream);
411+
is_streaming = rb_hash_aref(rb_iv_get(self, "@current_query_options"), sym_stream);
392412
if(is_streaming == Qtrue) {
393413
result = (MYSQL_RES *)rb_thread_blocking_region(nogvl_use_result, wrapper, RUBY_UBF_IO, 0);
394414
} else {
@@ -404,7 +424,11 @@ static VALUE rb_mysql_client_async_result(VALUE self) {
404424
return Qnil;
405425
}
406426

407-
resultObj = rb_mysql_result_to_obj(self, wrapper->encoding, rb_hash_dup(rb_iv_get(self, "@current_query_options")), result);
427+
current = rb_hash_dup(rb_iv_get(self, "@current_query_options"));
428+
RB_GC_GUARD(current);
429+
Check_Type(current, T_HASH);
430+
resultObj = rb_mysql_result_to_obj(self, wrapper->encoding, current, result);
431+
408432
return resultObj;
409433
}
410434

@@ -549,10 +573,13 @@ static VALUE rb_mysql_client_query(int argc, VALUE * argv, VALUE self) {
549573
REQUIRE_CONNECTED(wrapper);
550574
args.mysql = wrapper->client;
551575

552-
rb_iv_set(self, "@current_query_options", rb_hash_dup(rb_iv_get(self, "@query_options")));
553-
current = rb_iv_get(self, "@current_query_options");
576+
current = rb_hash_dup(rb_iv_get(self, "@query_options"));
577+
RB_GC_GUARD(current);
578+
Check_Type(current, T_HASH);
579+
rb_iv_set(self, "@current_query_options", current);
580+
554581
if (rb_scan_args(argc, argv, "11", &args.sql, &opts) == 2) {
555-
opts = rb_funcall(current, intern_merge_bang, 1, opts);
582+
rb_funcall(current, intern_merge_bang, 1, opts);
556583

557584
if (rb_hash_aref(current, sym_async) == Qtrue) {
558585
async = 1;
@@ -930,6 +957,7 @@ static VALUE rb_mysql_client_store_result(VALUE self)
930957
{
931958
MYSQL_RES * result;
932959
VALUE resultObj;
960+
VALUE current;
933961
GET_CLIENT(self);
934962

935963
result = (MYSQL_RES *)rb_thread_blocking_region(nogvl_store_result, wrapper, RUBY_UBF_IO, 0);
@@ -942,9 +970,12 @@ static VALUE rb_mysql_client_store_result(VALUE self)
942970
return Qnil;
943971
}
944972

945-
resultObj = rb_mysql_result_to_obj(self, wrapper->encoding, rb_hash_dup(rb_iv_get(self, "@current_query_options")), result);
946-
return resultObj;
973+
current = rb_hash_dup(rb_iv_get(self, "@current_query_options"));
974+
RB_GC_GUARD(current);
975+
Check_Type(current, T_HASH);
976+
resultObj = rb_mysql_result_to_obj(self, wrapper->encoding, current, result);
947977

978+
return resultObj;
948979
}
949980

950981
#ifdef HAVE_RUBY_ENCODING_H
@@ -1112,6 +1143,7 @@ void init_mysql2_client() {
11121143
rb_define_method(cMysql2Client, "store_result", rb_mysql_client_store_result, 0);
11131144
rb_define_method(cMysql2Client, "reconnect=", set_reconnect, 1);
11141145
rb_define_method(cMysql2Client, "warning_count", rb_mysql_client_warning_count, 0);
1146+
rb_define_method(cMysql2Client, "query_info_string", rb_mysql_info, 0);
11151147
#ifdef HAVE_RUBY_ENCODING_H
11161148
rb_define_method(cMysql2Client, "encoding", rb_mysql_client_encoding, 0);
11171149
#endif

ext/mysql2/extconf.rb

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ def asplode lib
99
have_func('rb_thread_blocking_region')
1010
have_func('rb_wait_for_single_fd')
1111
have_func('rb_hash_dup')
12+
have_func('rb_intern3')
1213

1314
# borrowed from mysqlplus
1415
# http://github.com/oldmoe/mysqlplus/blob/master/ext/extconf.rb
@@ -29,6 +30,14 @@ def asplode lib
2930

3031
if RUBY_PLATFORM =~ /mswin|mingw/
3132
inc, lib = dir_config('mysql')
33+
34+
# Ruby versions not incorporating the mkmf fix at
35+
# https://bugs.ruby-lang.org/projects/ruby-trunk/repository/revisions/39717
36+
# do not properly search for lib directories, and must be corrected
37+
unless lib[-3, 3] == 'lib'
38+
@libdir_basename = 'lib'
39+
inc, lib = dir_config('mysql')
40+
end
3241
exit 1 unless have_library("libmysql")
3342
elsif mc = (with_config('mysql-config') || Dir[GLOB].first) then
3443
mc = Dir[GLOB].first if mc == true

ext/mysql2/result.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,7 @@ static VALUE rb_mysql_result_fetch_field(VALUE self, unsigned int idx, short int
129129
memcpy(buf, field->name, field->name_length);
130130
buf[field->name_length] = 0;
131131

132-
#ifdef HAVE_RUBY_ENCODING_H
132+
#ifdef HAVE_RB_INTERN3
133133
rb_field = rb_intern3(buf, field->name_length, rb_utf8_encoding());
134134
rb_field = ID2SYM(rb_field);
135135
#else
@@ -394,6 +394,7 @@ static VALUE rb_mysql_result_fetch_fields(VALUE self) {
394394
GetMysql2Result(self, wrapper);
395395

396396
defaults = rb_iv_get(self, "@query_options");
397+
Check_Type(defaults, T_HASH);
397398
if (rb_hash_aref(defaults, sym_symbolize_keys) == Qtrue) {
398399
symbolizeKeys = 1;
399400
}
@@ -423,6 +424,7 @@ static VALUE rb_mysql_result_each(int argc, VALUE * argv, VALUE self) {
423424
GetMysql2Result(self, wrapper);
424425

425426
defaults = rb_iv_get(self, "@query_options");
427+
Check_Type(defaults, T_HASH);
426428
if (rb_scan_args(argc, argv, "01&", &opts, &block) == 1) {
427429
opts = rb_funcall(defaults, intern_merge, 1, opts);
428430
} else {

lib/mysql2/client.rb

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,14 @@ def self.default_query_options
6161
@@default_query_options
6262
end
6363

64+
def query_info
65+
info = query_info_string
66+
return {} unless info
67+
info_hash = {}
68+
info.split.each_slice(2) { |s| info_hash[s[0].downcase.delete(':').to_sym] = s[1].to_i }
69+
info_hash
70+
end
71+
6472
private
6573
def self.local_offset
6674
::Time.local(2010).utc_offset.to_r / 86400

lib/mysql2/console.rb

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
# Loaded by script/console. Land helpers here.
2+
3+
Pry.config.prompt = lambda do |context, nesting, pry|
4+
"[mysql2] #{context}> "
5+
end

script/bootstrap

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
#!/bin/sh
2+
set -e
3+
4+
cd "$(dirname "$0")/.."
5+
exec bundle install --binstubs --path vendor/gems "$@"

script/console

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
#!/bin/sh
2+
# Run a Ruby REPL.
3+
4+
set -e
5+
6+
cd $(dirname "$0")/..
7+
exec ruby -S bin/pry -Ilib -r mysql2 -r mysql2/console

spec/mysql2/client_spec.rb

Lines changed: 38 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,42 @@ def connect *args
130130
end
131131
end
132132

133+
it "should respond to #query_info" do
134+
@client.should respond_to(:query_info)
135+
end
136+
137+
context "#query_info" do
138+
context "when no info present" do
139+
before(:each) do
140+
@client.query('select 1')
141+
end
142+
it "should 0" do
143+
@client.query_info.should be_empty
144+
@client.query_info_string.should be_nil
145+
end
146+
end
147+
context "when has some info" do
148+
before(:each) do
149+
@client.query "USE test"
150+
@client.query "CREATE TABLE IF NOT EXISTS infoTest (`id` int(11) NOT NULL AUTO_INCREMENT, blah INT(11), PRIMARY KEY (`id`))"
151+
end
152+
153+
after(:each) do
154+
@client.query "DROP TABLE infoTest"
155+
end
156+
157+
before(:each) do
158+
# http://dev.mysql.com/doc/refman/5.0/en/mysql-info.html says
159+
# # Note that mysql_info() returns a non-NULL value for INSERT ... VALUES only for the multiple-row form of the statement (that is, only if multiple value lists are specified).
160+
@client.query("INSERT INTO infoTest (blah) VALUES (1234),(4535)")
161+
end
162+
it "should retrieve it" do
163+
@client.query_info.should == {:records => 2, :duplicates => 0, :warnings => 0}
164+
@client.query_info_string.should eq 'Records: 2 Duplicates: 0 Warnings: 0'
165+
end
166+
end
167+
end
168+
133169
it "should expect connect_timeout to be a positive integer" do
134170
lambda {
135171
Mysql2::Client.new(:connect_timeout => -1)
@@ -257,10 +293,10 @@ def connect *args
257293
mark[:END] = Time.now
258294
mark.include?(:USR1).should be_true
259295
(mark[:USR1] - mark[:START]).should >= 1
260-
(mark[:USR1] - mark[:START]).should < 1.2
296+
(mark[:USR1] - mark[:START]).should < 1.3
261297
(mark[:END] - mark[:USR1]).should > 0.9
262298
(mark[:END] - mark[:START]).should >= 2
263-
(mark[:END] - mark[:START]).should < 2.2
299+
(mark[:END] - mark[:START]).should < 2.3
264300
Process.kill(:TERM, pid)
265301
Process.waitpid2(pid)
266302
ensure

0 commit comments

Comments
 (0)