ghazel-mysql2 0.2.6.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.gitignore +12 -0
- data/.rspec +2 -0
- data/CHANGELOG.md +117 -0
- data/MIT-LICENSE +20 -0
- data/README.rdoc +240 -0
- data/Rakefile +5 -0
- data/VERSION +1 -0
- data/benchmark/active_record.rb +53 -0
- data/benchmark/allocations.rb +33 -0
- data/benchmark/escape.rb +39 -0
- data/benchmark/query_with_mysql_casting.rb +83 -0
- data/benchmark/query_without_mysql_casting.rb +50 -0
- data/benchmark/sequel.rb +39 -0
- data/benchmark/setup_db.rb +115 -0
- data/examples/eventmachine.rb +21 -0
- data/examples/threaded.rb +20 -0
- data/ext/mysql2/client.c +728 -0
- data/ext/mysql2/client.h +41 -0
- data/ext/mysql2/extconf.rb +69 -0
- data/ext/mysql2/mysql2_ext.c +12 -0
- data/ext/mysql2/mysql2_ext.h +38 -0
- data/ext/mysql2/result.c +478 -0
- data/ext/mysql2/result.h +20 -0
- data/lib/active_record/connection_adapters/em_mysql2_adapter.rb +62 -0
- data/lib/active_record/connection_adapters/mysql2_adapter.rb +657 -0
- data/lib/active_record/fiber_patches.rb +104 -0
- data/lib/arel/engines/sql/compilers/mysql2_compiler.rb +11 -0
- data/lib/mysql2.rb +16 -0
- data/lib/mysql2/client.rb +240 -0
- data/lib/mysql2/em.rb +37 -0
- data/lib/mysql2/em_fiber.rb +29 -0
- data/lib/mysql2/error.rb +15 -0
- data/lib/mysql2/result.rb +5 -0
- data/mysql2.gemspec +90 -0
- data/spec/em/em_spec.rb +49 -0
- data/spec/mysql2/client_spec.rb +367 -0
- data/spec/mysql2/error_spec.rb +25 -0
- data/spec/mysql2/result_spec.rb +318 -0
- data/spec/rcov.opts +3 -0
- data/spec/spec_helper.rb +67 -0
- data/tasks/benchmarks.rake +8 -0
- data/tasks/compile.rake +54 -0
- data/tasks/jeweler.rake +17 -0
- data/tasks/rspec.rake +16 -0
- data/tasks/vendor_mysql.rake +41 -0
- metadata +119 -0
data/mysql2.gemspec
ADDED
@@ -0,0 +1,90 @@
|
|
1
|
+
# Generated by jeweler
|
2
|
+
# DO NOT EDIT THIS FILE DIRECTLY
|
3
|
+
# Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
|
4
|
+
# -*- encoding: utf-8 -*-
|
5
|
+
|
6
|
+
Gem::Specification.new do |s|
|
7
|
+
s.name = %q{ghazel-mysql2}
|
8
|
+
s.version = "0.2.6.1"
|
9
|
+
|
10
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
|
+
s.authors = ["Brian Lopez"]
|
12
|
+
s.date = %q{2010-10-19}
|
13
|
+
s.email = %q{seniorlopez@gmail.com}
|
14
|
+
s.extensions = ["ext/mysql2/extconf.rb"]
|
15
|
+
s.extra_rdoc_files = [
|
16
|
+
"README.rdoc"
|
17
|
+
]
|
18
|
+
s.files = [
|
19
|
+
".gitignore",
|
20
|
+
".rspec",
|
21
|
+
"CHANGELOG.md",
|
22
|
+
"MIT-LICENSE",
|
23
|
+
"README.rdoc",
|
24
|
+
"Rakefile",
|
25
|
+
"VERSION",
|
26
|
+
"benchmark/active_record.rb",
|
27
|
+
"benchmark/allocations.rb",
|
28
|
+
"benchmark/escape.rb",
|
29
|
+
"benchmark/query_with_mysql_casting.rb",
|
30
|
+
"benchmark/query_without_mysql_casting.rb",
|
31
|
+
"benchmark/sequel.rb",
|
32
|
+
"benchmark/setup_db.rb",
|
33
|
+
"examples/eventmachine.rb",
|
34
|
+
"examples/threaded.rb",
|
35
|
+
"ext/mysql2/client.c",
|
36
|
+
"ext/mysql2/client.h",
|
37
|
+
"ext/mysql2/extconf.rb",
|
38
|
+
"ext/mysql2/mysql2_ext.c",
|
39
|
+
"ext/mysql2/mysql2_ext.h",
|
40
|
+
"ext/mysql2/result.c",
|
41
|
+
"ext/mysql2/result.h",
|
42
|
+
"lib/active_record/connection_adapters/em_mysql2_adapter.rb",
|
43
|
+
"lib/active_record/connection_adapters/mysql2_adapter.rb",
|
44
|
+
"lib/active_record/fiber_patches.rb",
|
45
|
+
"lib/arel/engines/sql/compilers/mysql2_compiler.rb",
|
46
|
+
"lib/mysql2.rb",
|
47
|
+
"lib/mysql2/client.rb",
|
48
|
+
"lib/mysql2/em.rb",
|
49
|
+
"lib/mysql2/em_fiber.rb",
|
50
|
+
"lib/mysql2/error.rb",
|
51
|
+
"lib/mysql2/result.rb",
|
52
|
+
"mysql2.gemspec",
|
53
|
+
"spec/em/em_spec.rb",
|
54
|
+
"spec/mysql2/client_spec.rb",
|
55
|
+
"spec/mysql2/error_spec.rb",
|
56
|
+
"spec/mysql2/result_spec.rb",
|
57
|
+
"spec/rcov.opts",
|
58
|
+
"spec/spec_helper.rb",
|
59
|
+
"tasks/benchmarks.rake",
|
60
|
+
"tasks/compile.rake",
|
61
|
+
"tasks/jeweler.rake",
|
62
|
+
"tasks/rspec.rake",
|
63
|
+
"tasks/vendor_mysql.rake"
|
64
|
+
]
|
65
|
+
s.homepage = %q{http://github.com/brianmario/mysql2}
|
66
|
+
s.rdoc_options = ["--charset=UTF-8"]
|
67
|
+
s.require_paths = ["lib", "ext"]
|
68
|
+
s.rubygems_version = %q{1.3.7}
|
69
|
+
s.summary = %q{A simple, fast Mysql library for Ruby, binding to libmysql}
|
70
|
+
s.test_files = [
|
71
|
+
"spec/em/em_spec.rb",
|
72
|
+
"spec/mysql2/client_spec.rb",
|
73
|
+
"spec/mysql2/error_spec.rb",
|
74
|
+
"spec/mysql2/result_spec.rb",
|
75
|
+
"spec/spec_helper.rb",
|
76
|
+
"examples/eventmachine.rb",
|
77
|
+
"examples/threaded.rb"
|
78
|
+
]
|
79
|
+
|
80
|
+
if s.respond_to? :specification_version then
|
81
|
+
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
82
|
+
s.specification_version = 3
|
83
|
+
|
84
|
+
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
85
|
+
else
|
86
|
+
end
|
87
|
+
else
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
data/spec/em/em_spec.rb
ADDED
@@ -0,0 +1,49 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
if defined? EventMachine
|
3
|
+
require 'spec_helper'
|
4
|
+
require 'mysql2/em'
|
5
|
+
|
6
|
+
describe Mysql2::EM::Client do
|
7
|
+
it "should support async queries" do
|
8
|
+
results = []
|
9
|
+
EM.run do
|
10
|
+
client1 = Mysql2::EM::Client.new
|
11
|
+
defer1 = client1.query "SELECT sleep(0.1) as first_query"
|
12
|
+
defer1.callback do |result|
|
13
|
+
results << result.first
|
14
|
+
EM.stop_event_loop
|
15
|
+
end
|
16
|
+
|
17
|
+
client2 = Mysql2::EM::Client.new
|
18
|
+
defer2 = client2.query "SELECT sleep(0.025) second_query"
|
19
|
+
defer2.callback do |result|
|
20
|
+
results << result.first
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
results[0].keys.should include("second_query")
|
25
|
+
results[1].keys.should include("first_query")
|
26
|
+
end
|
27
|
+
|
28
|
+
it "should support queries in callbacks" do
|
29
|
+
results = []
|
30
|
+
EM.run do
|
31
|
+
client = Mysql2::EM::Client.new
|
32
|
+
defer1 = client.query "SELECT sleep(0.025) as first_query"
|
33
|
+
defer1.callback do |result|
|
34
|
+
results << result.first
|
35
|
+
defer2 = client.query "SELECT sleep(0.025) as second_query"
|
36
|
+
defer2.callback do |result|
|
37
|
+
results << result.first
|
38
|
+
EM.stop_event_loop
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
results[0].keys.should include("first_query")
|
44
|
+
results[1].keys.should include("second_query")
|
45
|
+
end
|
46
|
+
end
|
47
|
+
else
|
48
|
+
puts "EventMachine not installed, skipping the specs that use it"
|
49
|
+
end
|
@@ -0,0 +1,367 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
require 'spec_helper'
|
3
|
+
|
4
|
+
describe Mysql2::Client do
|
5
|
+
before(:each) do
|
6
|
+
@client = Mysql2::Client.new
|
7
|
+
end
|
8
|
+
|
9
|
+
if defined? Encoding
|
10
|
+
it "should raise an exception on create for invalid encodings" do
|
11
|
+
lambda {
|
12
|
+
c = Mysql2::Client.new(:encoding => "fake")
|
13
|
+
}.should raise_error(Mysql2::Error)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
it "should accept connect flags and pass them to #connect" do
|
18
|
+
klient = Class.new(Mysql2::Client) do
|
19
|
+
attr_reader :connect_args
|
20
|
+
def connect *args
|
21
|
+
@connect_args ||= []
|
22
|
+
@connect_args << args
|
23
|
+
end
|
24
|
+
end
|
25
|
+
client = klient.new :flags => Mysql2::Client::FOUND_ROWS
|
26
|
+
(client.connect_args.last.last & Mysql2::Client::FOUND_ROWS).should be_true
|
27
|
+
end
|
28
|
+
|
29
|
+
it "should default flags to (REMEMBER_OPTIONS, LONG_PASSWORD, LONG_FLAG, TRANSACTIONS, PROTOCOL_41, SECURE_CONNECTION)" do
|
30
|
+
klient = Class.new(Mysql2::Client) do
|
31
|
+
attr_reader :connect_args
|
32
|
+
def connect *args
|
33
|
+
@connect_args ||= []
|
34
|
+
@connect_args << args
|
35
|
+
end
|
36
|
+
end
|
37
|
+
client = klient.new
|
38
|
+
(client.connect_args.last.last & (Mysql2::Client::REMEMBER_OPTIONS |
|
39
|
+
Mysql2::Client::LONG_PASSWORD |
|
40
|
+
Mysql2::Client::LONG_FLAG |
|
41
|
+
Mysql2::Client::TRANSACTIONS |
|
42
|
+
Mysql2::Client::PROTOCOL_41 |
|
43
|
+
Mysql2::Client::SECURE_CONNECTION)).should be_true
|
44
|
+
end
|
45
|
+
|
46
|
+
it "should have a global default_query_options hash" do
|
47
|
+
Mysql2::Client.should respond_to(:default_query_options)
|
48
|
+
end
|
49
|
+
|
50
|
+
it "should be able to connect via SSL options" do
|
51
|
+
pending("DON'T WORRY, THIS TEST PASSES :) - but is machine-specific. You need to have MySQL running with SSL configured and enabled. Then update the paths in this test to your needs and remove the pending state.")
|
52
|
+
ssl_client = nil
|
53
|
+
lambda {
|
54
|
+
ssl_client = Mysql2::Client.new(
|
55
|
+
:sslkey => '/path/to/client-key.pem',
|
56
|
+
:sslcert => '/path/to/client-cert.pem',
|
57
|
+
:sslca => '/path/to/ca-cert.pem',
|
58
|
+
:sslcapath => '/path/to/newcerts/',
|
59
|
+
:sslcipher => 'DHE-RSA-AES256-SHA'
|
60
|
+
)
|
61
|
+
}.should_not raise_error(Mysql2::Error)
|
62
|
+
|
63
|
+
results = ssl_client.query("SHOW STATUS WHERE Variable_name = \"Ssl_version\" OR Variable_name = \"Ssl_cipher\"").to_a
|
64
|
+
results[0]['Variable_name'].should eql('Ssl_cipher')
|
65
|
+
results[0]['Value'].should_not be_nil
|
66
|
+
results[0]['Value'].class.should eql(String)
|
67
|
+
|
68
|
+
results[1]['Variable_name'].should eql('Ssl_version')
|
69
|
+
results[1]['Value'].should_not be_nil
|
70
|
+
results[1]['Value'].class.should eql(String)
|
71
|
+
end
|
72
|
+
|
73
|
+
it "should respond to #close" do
|
74
|
+
@client.should respond_to(:close)
|
75
|
+
end
|
76
|
+
|
77
|
+
it "should be able to close properly" do
|
78
|
+
@client.close.should be_nil
|
79
|
+
lambda {
|
80
|
+
@client.query "SELECT 1"
|
81
|
+
}.should raise_error(Mysql2::Error)
|
82
|
+
end
|
83
|
+
|
84
|
+
it "should respond to #query" do
|
85
|
+
@client.should respond_to(:query)
|
86
|
+
end
|
87
|
+
|
88
|
+
it "should expect read_timeout to be a positive integer" do
|
89
|
+
lambda {
|
90
|
+
Mysql2::Client.new(:read_timeout => -1)
|
91
|
+
}.should raise_error(Mysql2::Error)
|
92
|
+
end
|
93
|
+
|
94
|
+
context "#query" do
|
95
|
+
it "should only accept strings as the query parameter" do
|
96
|
+
lambda {
|
97
|
+
@client.query ["SELECT 'not right'"]
|
98
|
+
}.should raise_error(TypeError)
|
99
|
+
end
|
100
|
+
|
101
|
+
it "should accept an options hash that inherits from Mysql2::Client.default_query_options" do
|
102
|
+
@client.query "SELECT 1", :something => :else
|
103
|
+
@client.query_options.should eql(@client.query_options.merge(:something => :else))
|
104
|
+
end
|
105
|
+
|
106
|
+
it "should return results as a hash by default" do
|
107
|
+
@client.query("SELECT 1").first.class.should eql(Hash)
|
108
|
+
end
|
109
|
+
|
110
|
+
it "should be able to return results as an array" do
|
111
|
+
@client.query("SELECT 1", :as => :array).first.class.should eql(Array)
|
112
|
+
@client.query("SELECT 1").each(:as => :array)
|
113
|
+
end
|
114
|
+
|
115
|
+
it "should be able to return results with symbolized keys" do
|
116
|
+
@client.query("SELECT 1", :symbolize_keys => true).first.keys[0].class.should eql(Symbol)
|
117
|
+
end
|
118
|
+
|
119
|
+
it "should not allow another query to be sent without fetching a result first" do
|
120
|
+
@client.query("SELECT 1", :async => true)
|
121
|
+
lambda {
|
122
|
+
@client.query("SELECT 1")
|
123
|
+
}.should raise_error(Mysql2::Error)
|
124
|
+
end
|
125
|
+
|
126
|
+
it "should require an open connection" do
|
127
|
+
@client.close
|
128
|
+
lambda {
|
129
|
+
@client.query "SELECT 1"
|
130
|
+
}.should raise_error(Mysql2::Error)
|
131
|
+
end
|
132
|
+
|
133
|
+
it "should timeout if we wait longer than :read_timeout" do
|
134
|
+
client = Mysql2::Client.new(:read_timeout => 1)
|
135
|
+
lambda {
|
136
|
+
client.query("SELECT sleep(2)")
|
137
|
+
}.should raise_error(Mysql2::Error)
|
138
|
+
end
|
139
|
+
|
140
|
+
# XXX this test is not deterministic (because Unix signal handling is not)
|
141
|
+
# and may fail on a loaded system
|
142
|
+
if RUBY_PLATFORM !~ /mingw|mswin/
|
143
|
+
it "should run signal handlers while waiting for a response" do
|
144
|
+
mark = {}
|
145
|
+
trap(:USR1) { mark[:USR1] = Time.now }
|
146
|
+
begin
|
147
|
+
mark[:START] = Time.now
|
148
|
+
pid = fork do
|
149
|
+
sleep 1 # wait for client "SELECT sleep(2)" query to start
|
150
|
+
Process.kill(:USR1, Process.ppid)
|
151
|
+
sleep # wait for explicit kill to prevent GC disconnect
|
152
|
+
end
|
153
|
+
@client.query("SELECT sleep(2)")
|
154
|
+
mark[:END] = Time.now
|
155
|
+
mark.include?(:USR1).should be_true
|
156
|
+
(mark[:USR1] - mark[:START]).should >= 1
|
157
|
+
(mark[:USR1] - mark[:START]).should < 1.1
|
158
|
+
(mark[:END] - mark[:USR1]).should > 0.9
|
159
|
+
(mark[:END] - mark[:START]).should >= 2
|
160
|
+
(mark[:END] - mark[:START]).should < 2.1
|
161
|
+
Process.kill(:TERM, pid)
|
162
|
+
Process.waitpid2(pid)
|
163
|
+
ensure
|
164
|
+
trap(:USR1, 'DEFAULT')
|
165
|
+
end
|
166
|
+
end
|
167
|
+
end
|
168
|
+
end
|
169
|
+
|
170
|
+
it "should respond to #escape" do
|
171
|
+
@client.should respond_to(:escape)
|
172
|
+
end
|
173
|
+
|
174
|
+
context "#escape" do
|
175
|
+
it "should return a new SQL-escape version of the passed string" do
|
176
|
+
@client.escape("abc'def\"ghi\0jkl%mno").should eql("abc\\'def\\\"ghi\\0jkl%mno")
|
177
|
+
end
|
178
|
+
|
179
|
+
it "should return the passed string if nothing was escaped" do
|
180
|
+
str = "plain"
|
181
|
+
@client.escape(str).object_id.should eql(str.object_id)
|
182
|
+
end
|
183
|
+
|
184
|
+
it "should not overflow the thread stack" do
|
185
|
+
lambda {
|
186
|
+
Thread.new { @client.escape("'" * 256 * 1024) }.join
|
187
|
+
}.should_not raise_error(SystemStackError)
|
188
|
+
end
|
189
|
+
|
190
|
+
it "should not overflow the process stack" do
|
191
|
+
lambda {
|
192
|
+
Thread.new { @client.escape("'" * 1024 * 1024 * 4) }.join
|
193
|
+
}.should_not raise_error(SystemStackError)
|
194
|
+
end
|
195
|
+
|
196
|
+
it "should require an open connection" do
|
197
|
+
@client.close
|
198
|
+
lambda {
|
199
|
+
@client.escape ""
|
200
|
+
}.should raise_error(Mysql2::Error)
|
201
|
+
end
|
202
|
+
end
|
203
|
+
|
204
|
+
it "should respond to #info" do
|
205
|
+
@client.should respond_to(:info)
|
206
|
+
end
|
207
|
+
|
208
|
+
it "#info should return a hash containing the client version ID and String" do
|
209
|
+
info = @client.info
|
210
|
+
info.class.should eql(Hash)
|
211
|
+
info.should have_key(:id)
|
212
|
+
info[:id].class.should eql(Fixnum)
|
213
|
+
info.should have_key(:version)
|
214
|
+
info[:version].class.should eql(String)
|
215
|
+
end
|
216
|
+
|
217
|
+
if defined? Encoding
|
218
|
+
context "strings returned by #info" do
|
219
|
+
it "should default to the connection's encoding if Encoding.default_internal is nil" do
|
220
|
+
Encoding.default_internal = nil
|
221
|
+
@client.info[:version].encoding.should eql(Encoding.find('utf-8'))
|
222
|
+
|
223
|
+
client2 = Mysql2::Client.new :encoding => 'ascii'
|
224
|
+
client2.info[:version].encoding.should eql(Encoding.find('us-ascii'))
|
225
|
+
end
|
226
|
+
|
227
|
+
it "should use Encoding.default_internal" do
|
228
|
+
Encoding.default_internal = Encoding.find('utf-8')
|
229
|
+
@client.info[:version].encoding.should eql(Encoding.default_internal)
|
230
|
+
Encoding.default_internal = Encoding.find('us-ascii')
|
231
|
+
@client.info[:version].encoding.should eql(Encoding.default_internal)
|
232
|
+
end
|
233
|
+
end
|
234
|
+
end
|
235
|
+
|
236
|
+
it "should respond to #server_info" do
|
237
|
+
@client.should respond_to(:server_info)
|
238
|
+
end
|
239
|
+
|
240
|
+
it "#server_info should return a hash containing the client version ID and String" do
|
241
|
+
server_info = @client.server_info
|
242
|
+
server_info.class.should eql(Hash)
|
243
|
+
server_info.should have_key(:id)
|
244
|
+
server_info[:id].class.should eql(Fixnum)
|
245
|
+
server_info.should have_key(:version)
|
246
|
+
server_info[:version].class.should eql(String)
|
247
|
+
end
|
248
|
+
|
249
|
+
it "#server_info should require an open connection" do
|
250
|
+
@client.close
|
251
|
+
lambda {
|
252
|
+
@client.server_info
|
253
|
+
}.should raise_error(Mysql2::Error)
|
254
|
+
end
|
255
|
+
|
256
|
+
if defined? Encoding
|
257
|
+
context "strings returned by #server_info" do
|
258
|
+
it "should default to the connection's encoding if Encoding.default_internal is nil" do
|
259
|
+
Encoding.default_internal = nil
|
260
|
+
@client.server_info[:version].encoding.should eql(Encoding.find('utf-8'))
|
261
|
+
|
262
|
+
client2 = Mysql2::Client.new :encoding => 'ascii'
|
263
|
+
client2.server_info[:version].encoding.should eql(Encoding.find('us-ascii'))
|
264
|
+
end
|
265
|
+
|
266
|
+
it "should use Encoding.default_internal" do
|
267
|
+
Encoding.default_internal = Encoding.find('utf-8')
|
268
|
+
@client.server_info[:version].encoding.should eql(Encoding.default_internal)
|
269
|
+
Encoding.default_internal = Encoding.find('us-ascii')
|
270
|
+
@client.server_info[:version].encoding.should eql(Encoding.default_internal)
|
271
|
+
end
|
272
|
+
end
|
273
|
+
end
|
274
|
+
|
275
|
+
it "should respond to #socket" do
|
276
|
+
@client.should respond_to(:socket)
|
277
|
+
end
|
278
|
+
|
279
|
+
it "#socket should return a Fixnum (file descriptor from C)" do
|
280
|
+
@client.socket.class.should eql(Fixnum)
|
281
|
+
@client.socket.should_not eql(0)
|
282
|
+
end
|
283
|
+
|
284
|
+
it "#socket should require an open connection" do
|
285
|
+
@client.close
|
286
|
+
lambda {
|
287
|
+
@client.socket
|
288
|
+
}.should raise_error(Mysql2::Error)
|
289
|
+
end
|
290
|
+
|
291
|
+
it "should raise a Mysql2::Error exception upon connection failure" do
|
292
|
+
lambda {
|
293
|
+
bad_client = Mysql2::Client.new :host => "dfjhdi9wrhw", :username => 'asdfasdf8d2h'
|
294
|
+
}.should raise_error(Mysql2::Error)
|
295
|
+
|
296
|
+
lambda {
|
297
|
+
good_client = Mysql2::Client.new
|
298
|
+
}.should_not raise_error(Mysql2::Error)
|
299
|
+
end
|
300
|
+
|
301
|
+
it "threaded queries should be supported" do
|
302
|
+
threads, results = [], {}
|
303
|
+
connect = lambda{ Mysql2::Client.new(:host => "localhost", :username => "root") }
|
304
|
+
Timeout.timeout(0.7) do
|
305
|
+
5.times {
|
306
|
+
threads << Thread.new do
|
307
|
+
results[Thread.current.object_id] = connect.call.query("SELECT sleep(0.5) as result")
|
308
|
+
end
|
309
|
+
}
|
310
|
+
end
|
311
|
+
threads.each{|t| t.join }
|
312
|
+
results.keys.sort.should eql(threads.map{|t| t.object_id }.sort)
|
313
|
+
end
|
314
|
+
|
315
|
+
it "evented async queries should be supported" do
|
316
|
+
# should immediately return nil
|
317
|
+
@client.query("SELECT sleep(0.1)", :async => true).should eql(nil)
|
318
|
+
|
319
|
+
io_wrapper = IO.for_fd(@client.socket)
|
320
|
+
loops = 0
|
321
|
+
loop do
|
322
|
+
if IO.select([io_wrapper], nil, nil, 0.05)
|
323
|
+
break
|
324
|
+
else
|
325
|
+
loops += 1
|
326
|
+
end
|
327
|
+
end
|
328
|
+
|
329
|
+
# make sure we waited some period of time
|
330
|
+
(loops >= 1).should be_true
|
331
|
+
|
332
|
+
result = @client.async_result
|
333
|
+
result.class.should eql(Mysql2::Result)
|
334
|
+
end
|
335
|
+
|
336
|
+
context 'write operations api' do
|
337
|
+
before(:each) do
|
338
|
+
@client.query "USE test"
|
339
|
+
@client.query "CREATE TABLE lastIdTest (`id` int(11) NOT NULL AUTO_INCREMENT, blah INT(11), PRIMARY KEY (`id`))"
|
340
|
+
end
|
341
|
+
|
342
|
+
after(:each) do
|
343
|
+
@client.query "DROP TABLE lastIdTest"
|
344
|
+
end
|
345
|
+
|
346
|
+
it "should respond to #last_id" do
|
347
|
+
@client.should respond_to(:last_id)
|
348
|
+
end
|
349
|
+
|
350
|
+
it "#last_id should return a Fixnum, the from the last INSERT/UPDATE" do
|
351
|
+
@client.last_id.should eql(0)
|
352
|
+
@client.query "INSERT INTO lastIdTest (blah) VALUES (1234)"
|
353
|
+
@client.last_id.should eql(1)
|
354
|
+
end
|
355
|
+
|
356
|
+
it "should respond to #last_id" do
|
357
|
+
@client.should respond_to(:last_id)
|
358
|
+
end
|
359
|
+
|
360
|
+
it "#last_id should return a Fixnum, the from the last INSERT/UPDATE" do
|
361
|
+
@client.query "INSERT INTO lastIdTest (blah) VALUES (1234)"
|
362
|
+
@client.affected_rows.should eql(1)
|
363
|
+
@client.query "UPDATE lastIdTest SET blah=4321 WHERE id=1"
|
364
|
+
@client.affected_rows.should eql(1)
|
365
|
+
end
|
366
|
+
end
|
367
|
+
end
|