mysql2 0.3.20-x86-mswin32-60 → 0.3.21-x86-mswin32-60
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/ext/mysql2/client.c +9 -22
- data/ext/mysql2/result.c +8 -2
- data/lib/mysql2.rb +18 -0
- data/lib/mysql2/1.8/mysql2.so +0 -0
- data/lib/mysql2/1.9/mysql2.so +0 -0
- data/lib/mysql2/2.0/mysql2.so +0 -0
- data/lib/mysql2/2.1/mysql2.so +0 -0
- data/lib/mysql2/2.2/mysql2.so +0 -0
- data/lib/mysql2/2.3/mysql2.so +0 -0
- data/lib/mysql2/client.rb +12 -0
- data/lib/mysql2/version.rb +1 -1
- data/spec/mysql2/client_spec.rb +22 -42
- data/spec/mysql2/result_spec.rb +5 -0
- metadata +4 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9ff1d14fd26731590a65e65960ff415527fab067
|
4
|
+
data.tar.gz: 9efdc9b34f09387e91459d0da02d575c97014cfd
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 196f89846597d6e68bf9c1c0e6323e67ec612b625f9d94e46443b9ef583909d39673c1edd1fabb4c521d0bc3c11002d0461a4a87f2f90c70d631ffbcbd4908a8
|
7
|
+
data.tar.gz: cd60433c358414b3e9eaa2a3ed1ceb33941d7b18e51a097e6922d3acab436cb8bb956cab42b26aac8f6c2796d242035b412cb64ad2b1de967e5c6f410af248fa
|
data/ext/mysql2/client.c
CHANGED
@@ -642,40 +642,27 @@ static VALUE rb_mysql_client_abandon_results(VALUE self) {
|
|
642
642
|
* Query the database with +sql+, with optional +options+. For the possible
|
643
643
|
* options, see @@default_query_options on the Mysql2::Client class.
|
644
644
|
*/
|
645
|
-
static VALUE
|
645
|
+
static VALUE rb_query(VALUE self, VALUE sql, VALUE current) {
|
646
646
|
#ifndef _WIN32
|
647
647
|
struct async_query_args async_args;
|
648
648
|
#endif
|
649
649
|
struct nogvl_send_query_args args;
|
650
|
-
int async = 0;
|
651
|
-
VALUE opts, current;
|
652
650
|
VALUE thread_current = rb_thread_current();
|
653
|
-
#ifdef HAVE_RUBY_ENCODING_H
|
654
|
-
rb_encoding *conn_enc;
|
655
|
-
#endif
|
656
651
|
GET_CLIENT(self);
|
657
652
|
|
658
653
|
REQUIRE_CONNECTED(wrapper);
|
659
654
|
args.mysql = wrapper->client;
|
660
655
|
|
661
|
-
current = rb_hash_dup(rb_iv_get(self, "@query_options"));
|
662
656
|
RB_GC_GUARD(current);
|
663
657
|
Check_Type(current, T_HASH);
|
664
658
|
rb_iv_set(self, "@current_query_options", current);
|
665
659
|
|
666
|
-
|
667
|
-
rb_funcall(current, intern_merge_bang, 1, opts);
|
668
|
-
|
669
|
-
if (rb_hash_aref(current, sym_async) == Qtrue) {
|
670
|
-
async = 1;
|
671
|
-
}
|
672
|
-
}
|
673
|
-
|
674
|
-
Check_Type(args.sql, T_STRING);
|
660
|
+
Check_Type(sql, T_STRING);
|
675
661
|
#ifdef HAVE_RUBY_ENCODING_H
|
676
|
-
conn_enc = rb_to_encoding(wrapper->encoding);
|
677
662
|
/* ensure the string is in the encoding the connection is expecting */
|
678
|
-
args.sql = rb_str_export_to_enc(
|
663
|
+
args.sql = rb_str_export_to_enc(sql, rb_to_encoding(wrapper->encoding));
|
664
|
+
#else
|
665
|
+
args.sql = sql;
|
679
666
|
#endif
|
680
667
|
args.sql_ptr = RSTRING_PTR(args.sql);
|
681
668
|
args.sql_len = RSTRING_LEN(args.sql);
|
@@ -699,15 +686,15 @@ static VALUE rb_mysql_client_query(int argc, VALUE * argv, VALUE self) {
|
|
699
686
|
#ifndef _WIN32
|
700
687
|
rb_rescue2(do_send_query, (VALUE)&args, disconnect_and_raise, self, rb_eException, (VALUE)0);
|
701
688
|
|
702
|
-
if (
|
689
|
+
if (rb_hash_aref(current, sym_async) == Qtrue) {
|
690
|
+
return Qnil;
|
691
|
+
} else {
|
703
692
|
async_args.fd = wrapper->client->net.fd;
|
704
693
|
async_args.self = self;
|
705
694
|
|
706
695
|
rb_rescue2(do_query, (VALUE)&async_args, disconnect_and_raise, self, rb_eException, (VALUE)0);
|
707
696
|
|
708
697
|
return rb_mysql_client_async_result(self);
|
709
|
-
} else {
|
710
|
-
return Qnil;
|
711
698
|
}
|
712
699
|
#else
|
713
700
|
do_send_query(&args);
|
@@ -1259,7 +1246,6 @@ void init_mysql2_client() {
|
|
1259
1246
|
rb_define_singleton_method(cMysql2Client, "info", rb_mysql_client_info, 0);
|
1260
1247
|
|
1261
1248
|
rb_define_method(cMysql2Client, "close", rb_mysql_client_close, 0);
|
1262
|
-
rb_define_method(cMysql2Client, "query", rb_mysql_client_query, -1);
|
1263
1249
|
rb_define_method(cMysql2Client, "abandon_results!", rb_mysql_client_abandon_results, 0);
|
1264
1250
|
rb_define_method(cMysql2Client, "escape", rb_mysql_client_real_escape, 1);
|
1265
1251
|
rb_define_method(cMysql2Client, "server_info", rb_mysql_client_server_info, 0);
|
@@ -1292,6 +1278,7 @@ void init_mysql2_client() {
|
|
1292
1278
|
rb_define_private_method(cMysql2Client, "ssl_set", set_ssl_options, 5);
|
1293
1279
|
rb_define_private_method(cMysql2Client, "initialize_ext", initialize_ext, 0);
|
1294
1280
|
rb_define_private_method(cMysql2Client, "connect", rb_connect, 7);
|
1281
|
+
rb_define_private_method(cMysql2Client, "_query", rb_query, 2);
|
1295
1282
|
|
1296
1283
|
sym_id = ID2SYM(rb_intern("id"));
|
1297
1284
|
sym_version = ID2SYM(rb_intern("version"));
|
data/ext/mysql2/result.c
CHANGED
@@ -531,6 +531,10 @@ static VALUE rb_mysql_result_each(int argc, VALUE * argv, VALUE self) {
|
|
531
531
|
return wrapper->rows;
|
532
532
|
}
|
533
533
|
wrapper->rows = rb_ary_new2(wrapper->numberOfRows);
|
534
|
+
} else if (!cacheRows && wrapper->lastRowProcessed == wrapper->numberOfRows) {
|
535
|
+
mysql_data_seek(wrapper->result, 0);
|
536
|
+
wrapper->lastRowProcessed = 0;
|
537
|
+
wrapper->rows = rb_ary_new2(wrapper->numberOfRows);
|
534
538
|
}
|
535
539
|
|
536
540
|
if (cacheRows && wrapper->lastRowProcessed == wrapper->numberOfRows) {
|
@@ -558,7 +562,9 @@ static VALUE rb_mysql_result_each(int argc, VALUE * argv, VALUE self) {
|
|
558
562
|
|
559
563
|
if (row == Qnil) {
|
560
564
|
/* we don't need the mysql C dataset around anymore, peace it */
|
561
|
-
|
565
|
+
if (cacheRows) {
|
566
|
+
rb_mysql_result_free_result(wrapper);
|
567
|
+
}
|
562
568
|
return Qnil;
|
563
569
|
}
|
564
570
|
|
@@ -566,7 +572,7 @@ static VALUE rb_mysql_result_each(int argc, VALUE * argv, VALUE self) {
|
|
566
572
|
rb_yield(row);
|
567
573
|
}
|
568
574
|
}
|
569
|
-
if (wrapper->lastRowProcessed == wrapper->numberOfRows) {
|
575
|
+
if (wrapper->lastRowProcessed == wrapper->numberOfRows && cacheRows) {
|
570
576
|
/* we don't need the mysql C dataset around anymore, peace it */
|
571
577
|
rb_mysql_result_free_result(wrapper);
|
572
578
|
}
|
data/lib/mysql2.rb
CHANGED
@@ -61,4 +61,22 @@ module Mysql2::Util
|
|
61
61
|
Hash[hash.map { |k,v| [k.to_sym, v] }]
|
62
62
|
end
|
63
63
|
|
64
|
+
#
|
65
|
+
# In Mysql2::Client#query and Mysql2::Statement#execute,
|
66
|
+
# Thread#handle_interrupt is used to prevent Timeout#timeout
|
67
|
+
# from interrupting query execution.
|
68
|
+
#
|
69
|
+
# Timeout::ExitException was removed in Ruby 2.3.0, 2.2.3, and 2.1.8,
|
70
|
+
# but is present in earlier 2.1.x and 2.2.x, so we provide a shim.
|
71
|
+
#
|
72
|
+
if Thread.respond_to?(:handle_interrupt)
|
73
|
+
require 'timeout'
|
74
|
+
# rubocop:disable Style/ConstantName
|
75
|
+
TimeoutError = if defined?(::Timeout::ExitException)
|
76
|
+
::Timeout::ExitException
|
77
|
+
else
|
78
|
+
::Timeout::Error
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
64
82
|
end
|
data/lib/mysql2/1.8/mysql2.so
CHANGED
Binary file
|
data/lib/mysql2/1.9/mysql2.so
CHANGED
Binary file
|
data/lib/mysql2/2.0/mysql2.so
CHANGED
Binary file
|
data/lib/mysql2/2.1/mysql2.so
CHANGED
Binary file
|
data/lib/mysql2/2.2/mysql2.so
CHANGED
Binary file
|
Binary file
|
data/lib/mysql2/client.rb
CHANGED
@@ -74,6 +74,18 @@ module Mysql2
|
|
74
74
|
@@default_query_options
|
75
75
|
end
|
76
76
|
|
77
|
+
if Thread.respond_to?(:handle_interrupt)
|
78
|
+
def query(sql, options = {})
|
79
|
+
Thread.handle_interrupt(::Mysql2::Util::TimeoutError => :never) do
|
80
|
+
_query(sql, @query_options.merge(options))
|
81
|
+
end
|
82
|
+
end
|
83
|
+
else
|
84
|
+
def query(sql, options = {})
|
85
|
+
_query(sql, @query_options.merge(options))
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
77
89
|
def query_info
|
78
90
|
info = query_info_string
|
79
91
|
return {} unless info
|
data/lib/mysql2/version.rb
CHANGED
data/spec/mysql2/client_spec.rb
CHANGED
@@ -462,59 +462,39 @@ describe Mysql2::Client do
|
|
462
462
|
}.should raise_error(Mysql2::Error)
|
463
463
|
end
|
464
464
|
|
465
|
-
it
|
466
|
-
|
467
|
-
|
468
|
-
|
469
|
-
end
|
470
|
-
rescue Timeout::Error
|
471
|
-
end
|
465
|
+
it 'should be impervious to connection-corrupting timeouts in #query' do
|
466
|
+
pending('`Thread.handle_interrupt` is not defined') unless Thread.respond_to?(:handle_interrupt)
|
467
|
+
# attempt to break the connection
|
468
|
+
expect { Timeout.timeout(0.1) { @client.query('SELECT SLEEP(1)') } }.to raise_error(Timeout::Error)
|
472
469
|
|
473
|
-
|
474
|
-
|
475
|
-
}.should raise_error(Mysql2::Error, 'closed MySQL connection')
|
470
|
+
# expect the connection to not be broken
|
471
|
+
expect { @client.query('SELECT 1') }.to_not raise_error
|
476
472
|
end
|
477
473
|
|
478
|
-
|
479
|
-
|
480
|
-
|
481
|
-
|
482
|
-
client.query("SELECT sleep(2)")
|
483
|
-
end
|
484
|
-
rescue Timeout::Error
|
474
|
+
context 'when a non-standard exception class is raised' do
|
475
|
+
it "should close the connection when an exception is raised" do
|
476
|
+
expect { Timeout.timeout(0.1, ArgumentError) { @client.query('SELECT SLEEP(1)') } }.to raise_error(ArgumentError)
|
477
|
+
expect { @client.query('SELECT 1') }.to raise_error(Mysql2::Error, 'closed MySQL connection')
|
485
478
|
end
|
486
479
|
|
487
|
-
|
488
|
-
client.
|
489
|
-
}.should_not raise_error(Mysql2::Error)
|
490
|
-
end
|
480
|
+
it "should handle Timeouts without leaving the connection hanging if reconnect is true" do
|
481
|
+
client = Mysql2::Client.new(DatabaseCredentials['root'].merge(:reconnect => true))
|
491
482
|
|
492
|
-
|
493
|
-
|
494
|
-
begin
|
495
|
-
Timeout.timeout(1, Timeout::Error) do
|
496
|
-
client.query("SELECT sleep(2)")
|
497
|
-
end
|
498
|
-
rescue Timeout::Error
|
483
|
+
expect { Timeout.timeout(0.1, ArgumentError) { client.query('SELECT SLEEP(1)') } }.to raise_error(ArgumentError)
|
484
|
+
expect { client.query('SELECT 1') }.to_not raise_error
|
499
485
|
end
|
500
486
|
|
501
|
-
|
502
|
-
client.
|
503
|
-
}.should raise_error(Mysql2::Error)
|
487
|
+
it "should handle Timeouts without leaving the connection hanging if reconnect is set to true after construction true" do
|
488
|
+
client = Mysql2::Client.new(DatabaseCredentials['root'])
|
504
489
|
|
505
|
-
|
490
|
+
expect { Timeout.timeout(0.1, ArgumentError) { client.query('SELECT SLEEP(1)') } }.to raise_error(ArgumentError)
|
491
|
+
expect { client.query('SELECT 1') }.to raise_error(Mysql2::Error)
|
506
492
|
|
507
|
-
|
508
|
-
Timeout.timeout(1, Timeout::Error) do
|
509
|
-
client.query("SELECT sleep(2)")
|
510
|
-
end
|
511
|
-
rescue Timeout::Error
|
512
|
-
end
|
513
|
-
|
514
|
-
lambda {
|
515
|
-
client.query("SELECT 1")
|
516
|
-
}.should_not raise_error(Mysql2::Error)
|
493
|
+
client.reconnect = true
|
517
494
|
|
495
|
+
expect { Timeout.timeout(0.1, ArgumentError) { client.query('SELECT SLEEP(1)') } }.to raise_error(ArgumentError)
|
496
|
+
expect { client.query('SELECT 1') }.to_not raise_error
|
497
|
+
end
|
518
498
|
end
|
519
499
|
|
520
500
|
it "threaded queries should be supported" do
|
data/spec/mysql2/result_spec.rb
CHANGED
@@ -78,6 +78,11 @@ describe Mysql2::Result do
|
|
78
78
|
result.first.object_id.should_not eql(result.first.object_id)
|
79
79
|
end
|
80
80
|
|
81
|
+
it "should be able to iterate a second time even if cache_rows is disabled" do
|
82
|
+
result = @client.query "SELECT 1 UNION SELECT 2", :cache_rows => false
|
83
|
+
result.to_a.should eql(result.to_a)
|
84
|
+
end
|
85
|
+
|
81
86
|
it "should yield different value for #first if streaming" do
|
82
87
|
result = @client.query "SELECT 1 UNION SELECT 2", :stream => true, :cache_rows => false
|
83
88
|
result.first.should_not eql(result.first)
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: mysql2
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.3.
|
4
|
+
version: 0.3.21
|
5
5
|
platform: x86-mswin32-60
|
6
6
|
authors:
|
7
7
|
- Brian Lopez
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2016-05-08 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rake-compiler
|
@@ -80,6 +80,7 @@ files:
|
|
80
80
|
- lib/mysql2/2.0/mysql2.so
|
81
81
|
- lib/mysql2/2.1/mysql2.so
|
82
82
|
- lib/mysql2/2.2/mysql2.so
|
83
|
+
- lib/mysql2/2.3/mysql2.so
|
83
84
|
- lib/mysql2/client.rb
|
84
85
|
- lib/mysql2/console.rb
|
85
86
|
- lib/mysql2/em.rb
|
@@ -136,7 +137,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
136
137
|
version: '0'
|
137
138
|
requirements: []
|
138
139
|
rubyforge_project:
|
139
|
-
rubygems_version: 2.
|
140
|
+
rubygems_version: 2.5.1
|
140
141
|
signing_key:
|
141
142
|
specification_version: 4
|
142
143
|
summary: A simple, fast Mysql library for Ruby, binding to libmysql
|