em-pg-client 0.3.0 → 0.3.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.rspec +1 -0
- data/.travis.yml +31 -0
- data/Gemfile +5 -0
- data/HISTORY.md +10 -0
- data/README.md +31 -10
- data/Rakefile +62 -25
- data/benchmarks/em_pg.rb +15 -12
- data/em-pg-client.gemspec +3 -1
- data/examples/single_row_mode.rb +67 -0
- data/lib/pg/em-version.rb +1 -1
- data/lib/pg/em.rb +187 -54
- data/lib/pg/em/client/connect_watcher.rb +2 -8
- data/lib/pg/em/client/watcher.rb +45 -21
- data/spec/em_client_autoreconnect.rb +140 -8
- data/spec/em_client_common.rb +77 -0
- data/spec/em_synchrony_client.rb +77 -9
- data/spec/em_synchrony_client_autoreconnect.rb +120 -6
- data/spec/pg_em_client_connect_finish.rb +1 -1
- data/spec/pg_em_client_options.rb +13 -3
- data/spec/spec_helper.rb +9 -0
- metadata +42 -4
@@ -17,9 +17,7 @@ module PG
|
|
17
17
|
@timer = ::EM::Timer.new(timeout) do
|
18
18
|
detach
|
19
19
|
@deferrable.protect do
|
20
|
-
|
21
|
-
error.instance_variable_set(:@connection, @client)
|
22
|
-
raise error
|
20
|
+
@client.raise_error ConnectionBad, "timeout expired (async)"
|
23
21
|
end
|
24
22
|
end
|
25
23
|
end
|
@@ -45,11 +43,7 @@ module PG
|
|
45
43
|
@timer.cancel if @timer
|
46
44
|
detach
|
47
45
|
@deferrable.protect_and_succeed do
|
48
|
-
unless polling_ok
|
49
|
-
error = ConnectionBad.new(@client.error_message)
|
50
|
-
error.instance_variable_set(:@connection, @client)
|
51
|
-
raise error
|
52
|
-
end
|
46
|
+
@client.raise_error ConnectionBad unless polling_ok
|
53
47
|
@client.set_default_encoding unless reconnecting?
|
54
48
|
@client
|
55
49
|
end
|
data/lib/pg/em/client/watcher.rb
CHANGED
@@ -17,17 +17,31 @@ module PG
|
|
17
17
|
@is_connected
|
18
18
|
end
|
19
19
|
|
20
|
-
def
|
21
|
-
|
20
|
+
def one_result_mode?
|
21
|
+
@one_result_mode
|
22
|
+
end
|
23
|
+
|
24
|
+
def watch_results(deferrable, send_proc=nil, one_result_mode=false)
|
25
|
+
@one_result_mode = one_result_mode
|
22
26
|
@last_result = nil
|
23
27
|
@deferrable = deferrable
|
24
28
|
@send_proc = send_proc
|
25
|
-
|
26
|
-
if
|
27
|
-
@
|
28
|
-
|
29
|
+
cancel_timer
|
30
|
+
if @client.is_busy
|
31
|
+
if @client.status == PG::CONNECTION_OK
|
32
|
+
self.notify_readable = true
|
33
|
+
if (timeout = @client.query_timeout) > 0
|
34
|
+
@notify_timestamp = Time.now
|
35
|
+
setup_timer timeout
|
36
|
+
end
|
37
|
+
else
|
38
|
+
@deferrable.protect do
|
39
|
+
@client.raise_error ConnectionBad
|
40
|
+
end
|
41
|
+
end
|
29
42
|
else
|
30
|
-
|
43
|
+
self.notify_readable = true
|
44
|
+
fetch_results
|
31
45
|
end
|
32
46
|
self
|
33
47
|
end
|
@@ -39,9 +53,7 @@ module PG
|
|
39
53
|
self.notify_readable = false
|
40
54
|
@client.async_command_aborted = true
|
41
55
|
@deferrable.protect do
|
42
|
-
|
43
|
-
error.instance_variable_set(:@connection, @client)
|
44
|
-
raise error
|
56
|
+
@client.raise_error ConnectionBad, "query timeout expired (async)"
|
45
57
|
end
|
46
58
|
else
|
47
59
|
setup_timer timeout, last_interval
|
@@ -56,20 +68,20 @@ module PG
|
|
56
68
|
end
|
57
69
|
end
|
58
70
|
|
59
|
-
# Carefully extract
|
71
|
+
# Carefully extract results without
|
60
72
|
# blocking the EventMachine reactor.
|
61
|
-
def
|
73
|
+
def fetch_results
|
62
74
|
result = false
|
63
75
|
@client.consume_input
|
64
76
|
until @client.is_busy
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
77
|
+
single_result = @client.blocking_get_result
|
78
|
+
if one_result_mode?
|
79
|
+
result = single_result
|
80
|
+
break
|
81
|
+
elsif single_result.nil?
|
82
|
+
if result = @last_result
|
83
|
+
result.check
|
70
84
|
end
|
71
|
-
result.check
|
72
|
-
cancel_timer
|
73
85
|
break
|
74
86
|
end
|
75
87
|
@last_result.clear if @last_result
|
@@ -78,22 +90,34 @@ module PG
|
|
78
90
|
rescue Exception => e
|
79
91
|
self.notify_readable = false
|
80
92
|
cancel_timer
|
93
|
+
send_proc = @send_proc
|
94
|
+
@send_proc = nil
|
95
|
+
df = @deferrable
|
96
|
+
# prevent unbind error on auto re-connect
|
97
|
+
@deferrable = false
|
81
98
|
if e.is_a?(PG::Error)
|
82
|
-
@client.async_autoreconnect!(
|
99
|
+
@client.async_autoreconnect!(df, e, &send_proc)
|
83
100
|
else
|
84
|
-
|
101
|
+
df.fail(e)
|
85
102
|
end
|
86
103
|
else
|
87
104
|
if result == false
|
88
105
|
@notify_timestamp = Time.now if @timer
|
89
106
|
else
|
90
107
|
self.notify_readable = false
|
108
|
+
cancel_timer
|
109
|
+
@send_proc = nil
|
91
110
|
@deferrable.succeed(result)
|
92
111
|
end
|
93
112
|
end
|
94
113
|
|
114
|
+
alias_method :notify_readable, :fetch_results
|
115
|
+
|
95
116
|
def unbind
|
96
117
|
@is_connected = false
|
118
|
+
@deferrable.protect do
|
119
|
+
@client.raise_error ConnectionBad, "connection reset"
|
120
|
+
end if @deferrable
|
97
121
|
end
|
98
122
|
end
|
99
123
|
|
@@ -5,8 +5,10 @@ require 'date'
|
|
5
5
|
require 'eventmachine'
|
6
6
|
require 'pg/em'
|
7
7
|
|
8
|
-
$pgserver_cmd_stop = %Q[sudo -i -u postgres pg_ctl -D "#{ENV['PGDATA']}" stop -s -m fast]
|
9
|
-
$pgserver_cmd_start = %Q[sudo -i -u postgres pg_ctl -D "#{ENV['PGDATA']}" start -s -w]
|
8
|
+
$pgserver_cmd_stop = ENV['PG_CTL_STOP_CMD'] || %Q[sudo -i -u postgres pg_ctl -D "#{ENV['PGDATA']}" stop -s -m fast]
|
9
|
+
$pgserver_cmd_start = ENV['PG_CTL_START_CMD'] || %Q[sudo -i -u postgres pg_ctl -D "#{ENV['PGDATA']}" start -s -w]
|
10
|
+
|
11
|
+
DISCONNECTED_ERROR = ENV['PGHOST'].include?('/') ? PG::UnableToSend : PG::ConnectionBad
|
10
12
|
|
11
13
|
shared_context 'pg-em common' do
|
12
14
|
around(:each) do |testcase|
|
@@ -67,7 +69,7 @@ describe 'pg-em default autoreconnect' do
|
|
67
69
|
it "should not get database size using query after server shutdown" do
|
68
70
|
system($pgserver_cmd_stop).should be_true
|
69
71
|
@client.query_defer('SELECT pg_database_size(current_database());') do |ex|
|
70
|
-
ex.should be_an_instance_of
|
72
|
+
ex.should be_an_instance_of DISCONNECTED_ERROR
|
71
73
|
EM.stop
|
72
74
|
end.should be_a_kind_of ::EM::DefaultDeferrable
|
73
75
|
end
|
@@ -92,12 +94,47 @@ describe 'pg-em default autoreconnect' do
|
|
92
94
|
system($pgserver_cmd_stop).should be_true
|
93
95
|
system($pgserver_cmd_start).should be_true
|
94
96
|
@client.query_defer('SELECT pg_database_size(current_database());') do |ex|
|
95
|
-
ex.should be_an_instance_of
|
97
|
+
ex.should be_an_instance_of DISCONNECTED_ERROR
|
96
98
|
@tested_proc.call
|
97
99
|
end.should be_a_kind_of ::EM::DefaultDeferrable
|
98
100
|
end
|
99
101
|
end
|
100
102
|
|
103
|
+
it "should fail to get last result asynchronously after server restart" do
|
104
|
+
@client.send_query('SELECT pg_sleep(5); SELECT pg_database_size(current_database());')
|
105
|
+
system($pgserver_cmd_stop).should be_true
|
106
|
+
system($pgserver_cmd_start).should be_true
|
107
|
+
@client.get_last_result_defer do |ex|
|
108
|
+
ex.should be_an_instance_of PG::ConnectionBad
|
109
|
+
@client.status.should be PG::CONNECTION_OK
|
110
|
+
@client.get_last_result_defer do |result|
|
111
|
+
result.should be_nil
|
112
|
+
EM.stop
|
113
|
+
end
|
114
|
+
end.should be_a_kind_of EM::DefaultDeferrable
|
115
|
+
end
|
116
|
+
|
117
|
+
it "should fail to get each result asynchronously after server restart" do
|
118
|
+
@client.send_query('SELECT pg_sleep(5); SELECT pg_database_size(current_database());')
|
119
|
+
system($pgserver_cmd_stop).should be_true
|
120
|
+
system($pgserver_cmd_start).should be_true
|
121
|
+
@client.get_result_defer do |result|
|
122
|
+
result.should be_an_instance_of PG::Result
|
123
|
+
expect do
|
124
|
+
result.check
|
125
|
+
end.to raise_error PG::Error
|
126
|
+
@client.status.should be PG::CONNECTION_OK
|
127
|
+
@client.get_result_defer do |ex|
|
128
|
+
ex.should be_an_instance_of PG::ConnectionBad
|
129
|
+
@client.status.should be PG::CONNECTION_OK
|
130
|
+
@client.get_result_defer do |result|
|
131
|
+
result.should be_nil
|
132
|
+
EM.stop
|
133
|
+
end.should be_a_kind_of ::EM::DefaultDeferrable
|
134
|
+
end.should be_a_kind_of EM::DefaultDeferrable
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
101
138
|
before(:all) do
|
102
139
|
@tested_proc = proc do
|
103
140
|
@client.query_defer('SELECT pg_database_size(current_database());') do |result|
|
@@ -148,7 +185,7 @@ describe 'pg-em autoreconnect with on_autoreconnect' do
|
|
148
185
|
system($pgserver_cmd_stop).should be_true
|
149
186
|
system($pgserver_cmd_start).should be_true
|
150
187
|
@client.query_defer('SELECT pg_database_size(current_database());') do |ex|
|
151
|
-
ex.should be_an_instance_of
|
188
|
+
ex.should be_an_instance_of DISCONNECTED_ERROR
|
152
189
|
@tested_proc.call
|
153
190
|
end.should be_a_kind_of ::EM::DefaultDeferrable
|
154
191
|
end
|
@@ -159,7 +196,7 @@ describe 'pg-em autoreconnect with on_autoreconnect' do
|
|
159
196
|
system($pgserver_cmd_stop).should be_true
|
160
197
|
system($pgserver_cmd_start).should be_true
|
161
198
|
@client.query_defer('SELECT pg_database_size(current_database());') do |ex|
|
162
|
-
ex.should be_an_instance_of
|
199
|
+
ex.should be_an_instance_of DISCONNECTED_ERROR
|
163
200
|
EM.stop
|
164
201
|
end.should be_a_kind_of ::EM::DefaultDeferrable
|
165
202
|
end
|
@@ -209,6 +246,45 @@ describe 'pg-em autoreconnect with on_autoreconnect' do
|
|
209
246
|
end.should be_a_kind_of ::EM::DefaultDeferrable
|
210
247
|
end
|
211
248
|
|
249
|
+
it "should fail to get last result asynchronously after server restart" do
|
250
|
+
@client.on_autoreconnect = proc { true }
|
251
|
+
@client.send_query('SELECT pg_sleep(5); SELECT pg_database_size(current_database());')
|
252
|
+
system($pgserver_cmd_stop).should be_true
|
253
|
+
system($pgserver_cmd_start).should be_true
|
254
|
+
@client.get_last_result_defer do |ex|
|
255
|
+
ex.should be_an_instance_of PG::ConnectionBad
|
256
|
+
@client.status.should be PG::CONNECTION_OK
|
257
|
+
@client.get_last_result_defer do |result|
|
258
|
+
result.should be_nil
|
259
|
+
EM.stop
|
260
|
+
end
|
261
|
+
end.should be_a_kind_of EM::DefaultDeferrable
|
262
|
+
end
|
263
|
+
|
264
|
+
it "should fail to get each result asynchronously after server restart" do
|
265
|
+
@client.on_autoreconnect = proc {
|
266
|
+
EM::DefaultDeferrable.new.tap {|df| df.succeed }
|
267
|
+
}
|
268
|
+
@client.send_query('SELECT pg_sleep(5); SELECT pg_database_size(current_database());')
|
269
|
+
system($pgserver_cmd_stop).should be_true
|
270
|
+
system($pgserver_cmd_start).should be_true
|
271
|
+
@client.get_result_defer do |result|
|
272
|
+
result.should be_an_instance_of PG::Result
|
273
|
+
expect do
|
274
|
+
result.check
|
275
|
+
end.to raise_error PG::Error
|
276
|
+
@client.status.should be PG::CONNECTION_OK
|
277
|
+
@client.get_result_defer do |ex|
|
278
|
+
ex.should be_an_instance_of PG::ConnectionBad
|
279
|
+
@client.status.should be PG::CONNECTION_OK
|
280
|
+
@client.get_result_defer do |result|
|
281
|
+
result.should be_nil
|
282
|
+
EM.stop
|
283
|
+
end.should be_a_kind_of ::EM::DefaultDeferrable
|
284
|
+
end.should be_a_kind_of EM::DefaultDeferrable
|
285
|
+
end
|
286
|
+
end
|
287
|
+
|
212
288
|
before(:all) do
|
213
289
|
@tested_proc = proc do
|
214
290
|
@client.exec_prepared_defer('get_db_size') do |result|
|
@@ -240,20 +316,76 @@ describe 'pg-em with autoreconnect disabled' do
|
|
240
316
|
system($pgserver_cmd_stop).should be_true
|
241
317
|
system($pgserver_cmd_start).should be_true
|
242
318
|
@client.query_defer('SELECT pg_database_size(current_database());') do |ex|
|
243
|
-
ex.should be_an_instance_of
|
319
|
+
ex.should be_an_instance_of DISCONNECTED_ERROR
|
320
|
+
@client.status.should be PG::CONNECTION_BAD
|
244
321
|
EM.stop
|
245
322
|
end.should be_a_kind_of ::EM::DefaultDeferrable
|
246
323
|
end
|
247
324
|
|
248
325
|
it "should get database size using query after async manual connection reset" do
|
249
326
|
@client.status.should be PG::CONNECTION_BAD
|
250
|
-
@client.
|
327
|
+
@client.reset_defer do |conn|
|
251
328
|
conn.should be @client
|
252
329
|
@client.status.should be PG::CONNECTION_OK
|
253
330
|
@tested_proc.call
|
254
331
|
end.should be_a_kind_of ::EM::DefaultDeferrable
|
255
332
|
end
|
256
333
|
|
334
|
+
it "should fail to get last result asynchronously after server restart" do
|
335
|
+
system($pgserver_cmd_stop).should be_true
|
336
|
+
system($pgserver_cmd_start).should be_true
|
337
|
+
begin
|
338
|
+
@client.send_query('SELECT pg_sleep(5); SELECT pg_database_size(current_database());')
|
339
|
+
rescue PG::UnableToSend
|
340
|
+
end
|
341
|
+
@client.get_last_result_defer do |ex|
|
342
|
+
ex.should be_an_instance_of PG::ConnectionBad
|
343
|
+
@client.status.should be PG::CONNECTION_BAD
|
344
|
+
@client.get_last_result_defer do |ex|
|
345
|
+
ex.should be_an_instance_of PG::ConnectionBad
|
346
|
+
@client.reset_defer do |conn|
|
347
|
+
conn.should be @client
|
348
|
+
@client.status.should be PG::CONNECTION_OK
|
349
|
+
EM.stop
|
350
|
+
end.should be_a_kind_of ::EM::DefaultDeferrable
|
351
|
+
end
|
352
|
+
end.should be_a_kind_of EM::DefaultDeferrable
|
353
|
+
end
|
354
|
+
|
355
|
+
it "should fail to get each result asynchronously after server restart" do
|
356
|
+
check_get_result = proc do
|
357
|
+
@client.get_result_defer do |ex|
|
358
|
+
ex.should be_an_instance_of PG::ConnectionBad
|
359
|
+
@client.status.should be PG::CONNECTION_BAD
|
360
|
+
@client.reset_defer do |conn|
|
361
|
+
conn.should be @client
|
362
|
+
@client.status.should be PG::CONNECTION_OK
|
363
|
+
EM.stop
|
364
|
+
end.should be_a_kind_of ::EM::DefaultDeferrable
|
365
|
+
end.should be_a_kind_of EM::DefaultDeferrable
|
366
|
+
end
|
367
|
+
system($pgserver_cmd_stop).should be_true
|
368
|
+
system($pgserver_cmd_start).should be_true
|
369
|
+
begin
|
370
|
+
@client.send_query('SELECT pg_sleep(5); SELECT pg_database_size(current_database());')
|
371
|
+
rescue PG::UnableToSend
|
372
|
+
@client.get_result_defer do |result|
|
373
|
+
result.should be_an_instance_of PG::ConnectionBad
|
374
|
+
@client.status.should be PG::CONNECTION_BAD
|
375
|
+
check_get_result.call
|
376
|
+
end
|
377
|
+
else
|
378
|
+
@client.get_result_defer do |result|
|
379
|
+
result.should be_an_instance_of PG::Result
|
380
|
+
expect do
|
381
|
+
result.check
|
382
|
+
end.to raise_error PG::Error
|
383
|
+
@client.status.should be PG::CONNECTION_OK
|
384
|
+
check_get_result.call
|
385
|
+
end
|
386
|
+
end
|
387
|
+
end
|
388
|
+
|
257
389
|
before(:all) do
|
258
390
|
@tested_proc = proc do
|
259
391
|
@client.query_defer('SELECT pg_database_size(current_database());') do |result|
|
data/spec/em_client_common.rb
CHANGED
@@ -106,6 +106,43 @@ end
|
|
106
106
|
|
107
107
|
shared_context 'em-pg common after' do
|
108
108
|
|
109
|
+
if described_class.single_row_mode?
|
110
|
+
|
111
|
+
it "should get each result in single row mode" do
|
112
|
+
@client.single_row_mode?.should be_true
|
113
|
+
@client.get_result_defer do |result|
|
114
|
+
result.should be_nil
|
115
|
+
@client.send_query('SELECT data, id FROM foo order by id')
|
116
|
+
@client.set_single_row_mode
|
117
|
+
EM::Iterator.new(@values, 1).map(proc{ |(data, id), iter|
|
118
|
+
@client.get_result_defer do |result|
|
119
|
+
result.should be_an_instance_of PG::Result
|
120
|
+
result.check
|
121
|
+
result.result_status.should eq PG::PGRES_SINGLE_TUPLE
|
122
|
+
value = result.to_a
|
123
|
+
value.should eq [{'data' => data, 'id' => id.to_s}]
|
124
|
+
result.clear
|
125
|
+
iter.return value
|
126
|
+
end.should be_a_kind_of ::EM::DefaultDeferrable
|
127
|
+
}, proc{ |results|
|
128
|
+
results.length.should eq @values.length
|
129
|
+
@client.get_result_defer do |result|
|
130
|
+
result.should be_an_instance_of PG::Result
|
131
|
+
result.check
|
132
|
+
result.result_status.should eq PG::PGRES_TUPLES_OK
|
133
|
+
result.to_a.should eq []
|
134
|
+
result.clear
|
135
|
+
@client.get_result_defer do |result|
|
136
|
+
result.should be_nil
|
137
|
+
EM.stop
|
138
|
+
end.should be_a_kind_of ::EM::DefaultDeferrable
|
139
|
+
end.should be_a_kind_of ::EM::DefaultDeferrable
|
140
|
+
})
|
141
|
+
end.should be_a_kind_of ::EM::DefaultDeferrable
|
142
|
+
end
|
143
|
+
|
144
|
+
end
|
145
|
+
|
109
146
|
it_should_execute("create prepared statement",
|
110
147
|
:prepare_defer, 'get_foo', 'SELECT * FROM foo order by id')
|
111
148
|
|
@@ -282,4 +319,44 @@ shared_context 'em-pg common after' do
|
|
282
319
|
end
|
283
320
|
end
|
284
321
|
end
|
322
|
+
|
323
|
+
it "should get last result asynchronously" do
|
324
|
+
@client.get_last_result_defer do |result|
|
325
|
+
result.should be_nil
|
326
|
+
@client.send_query('SELECT 1; SELECT 2; SELECT 3')
|
327
|
+
@client.get_last_result_defer do |result|
|
328
|
+
result.should be_an_instance_of PG::Result
|
329
|
+
result.getvalue(0,0).should eq '3'
|
330
|
+
result.clear
|
331
|
+
@client.get_last_result_defer do |result|
|
332
|
+
result.should be_nil
|
333
|
+
EM.stop
|
334
|
+
end
|
335
|
+
end.should be_a_kind_of ::EM::DefaultDeferrable
|
336
|
+
end.should be_a_kind_of ::EM::DefaultDeferrable
|
337
|
+
end
|
338
|
+
|
339
|
+
it "should get each result asynchronously" do
|
340
|
+
@client.get_result_defer do |result|
|
341
|
+
result.should be_nil
|
342
|
+
@client.send_query('SELECT 4; SELECT 5; SELECT 6')
|
343
|
+
EM::Iterator.new(%w[4 5 6], 1).map(proc{ |value, iter|
|
344
|
+
@client.get_result_defer do |result|
|
345
|
+
result.should be_an_instance_of PG::Result
|
346
|
+
result.check
|
347
|
+
result.result_status.should eq PG::PGRES_TUPLES_OK
|
348
|
+
result.getvalue(0,0).should eq value
|
349
|
+
result.clear
|
350
|
+
iter.return value
|
351
|
+
end.should be_a_kind_of ::EM::DefaultDeferrable
|
352
|
+
}, proc{ |results|
|
353
|
+
results.should eq %w[4 5 6]
|
354
|
+
@client.get_result_defer do |result|
|
355
|
+
result.should be_nil
|
356
|
+
EM.stop
|
357
|
+
end.should be_a_kind_of ::EM::DefaultDeferrable
|
358
|
+
})
|
359
|
+
end.should be_a_kind_of ::EM::DefaultDeferrable
|
360
|
+
end
|
361
|
+
|
285
362
|
end
|
data/spec/em_synchrony_client.rb
CHANGED
@@ -113,6 +113,33 @@ describe PG::EM::Client do
|
|
113
113
|
).should be_an_instance_of PG::Result
|
114
114
|
end
|
115
115
|
|
116
|
+
if described_class.single_row_mode?
|
117
|
+
|
118
|
+
it "should get each result in single row mode" do
|
119
|
+
@client.single_row_mode?.should be_true
|
120
|
+
@client.send_query('SELECT data, id FROM foo order by id')
|
121
|
+
@client.set_single_row_mode
|
122
|
+
@values.each do |data, id|
|
123
|
+
result = @client.get_result
|
124
|
+
result.should be_an_instance_of PG::Result
|
125
|
+
result.result_status.should eq PG::PGRES_SINGLE_TUPLE
|
126
|
+
result.check
|
127
|
+
value = result.to_a
|
128
|
+
result.clear
|
129
|
+
value.should eq [{'data' => data, 'id' => id.to_s}]
|
130
|
+
end
|
131
|
+
result = @client.get_result
|
132
|
+
result.should be_an_instance_of PG::Result
|
133
|
+
result.check
|
134
|
+
result.result_status.should eq PG::PGRES_TUPLES_OK
|
135
|
+
result.to_a.should eq []
|
136
|
+
result.clear
|
137
|
+
@client.get_result.should be_nil
|
138
|
+
EM.stop
|
139
|
+
end
|
140
|
+
|
141
|
+
end
|
142
|
+
|
116
143
|
it "should connect to database asynchronously" do
|
117
144
|
this = :first
|
118
145
|
Encoding.default_internal = Encoding::ISO_8859_1
|
@@ -149,12 +176,12 @@ describe PG::EM::Client do
|
|
149
176
|
f = Fiber.current
|
150
177
|
Fiber.new do
|
151
178
|
begin
|
152
|
-
described_class.new
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
179
|
+
conn = described_class.new
|
180
|
+
this = :second
|
181
|
+
Encoding.default_internal = nil
|
182
|
+
conn.should be_an_instance_of described_class
|
183
|
+
conn.external_encoding.should be conn.internal_encoding
|
184
|
+
conn.finish
|
158
185
|
ensure
|
159
186
|
f.resume
|
160
187
|
end
|
@@ -256,18 +283,59 @@ describe PG::EM::Client do
|
|
256
283
|
|
257
284
|
it "should not expire after executing erraneous query" do
|
258
285
|
@client.query_timeout.should eq 0
|
259
|
-
@client.query_timeout =
|
260
|
-
@client.query_timeout.should eq
|
286
|
+
@client.query_timeout = 1
|
287
|
+
@client.query_timeout.should eq 1
|
261
288
|
expect {
|
262
289
|
@client.query('SELLECT 1')
|
263
290
|
}.to raise_error(PG::SyntaxError, /syntax error/)
|
264
291
|
@client.async_command_aborted.should be_false
|
265
292
|
@client.status.should be PG::CONNECTION_OK
|
266
|
-
::EM::Synchrony.sleep
|
293
|
+
::EM::Synchrony.sleep 1.5
|
267
294
|
@client.async_command_aborted.should be_false
|
268
295
|
@client.status.should be PG::CONNECTION_OK
|
269
296
|
end
|
270
297
|
|
298
|
+
it "should get last result asynchronously" do
|
299
|
+
result = @client.get_last_result
|
300
|
+
result.should be_nil
|
301
|
+
@client.get_last_result.should be_nil
|
302
|
+
@client.send_query('SELECT 1; SELECT 2; SELECT 3')
|
303
|
+
asynchronous = false
|
304
|
+
EM.next_tick { asynchronous = true }
|
305
|
+
result = @client.get_last_result
|
306
|
+
result.should be_an_instance_of PG::Result
|
307
|
+
result.getvalue(0,0).should eq '3'
|
308
|
+
result.clear
|
309
|
+
@client.get_last_result.should be_nil
|
310
|
+
asynchronous.should be true
|
311
|
+
end
|
312
|
+
|
313
|
+
it "should get each result asynchronously" do
|
314
|
+
result = @client.get_result
|
315
|
+
result.should be_nil
|
316
|
+
@client.get_result do |result|
|
317
|
+
result.should be_nil
|
318
|
+
end.should be_nil
|
319
|
+
@client.send_query('SELECT 4,pg_sleep(0.1); SELECT 5; SELECT 6')
|
320
|
+
asynchronous = false
|
321
|
+
EM.next_tick { asynchronous = true }
|
322
|
+
%w[4 5 6].map do |value|
|
323
|
+
result = @client.get_result do |result|
|
324
|
+
result.should be_an_instance_of PG::Result
|
325
|
+
result.check
|
326
|
+
result.result_status.should eq PG::PGRES_TUPLES_OK
|
327
|
+
result.getvalue(0,0).should eq value
|
328
|
+
result
|
329
|
+
end
|
330
|
+
expect do
|
331
|
+
result.clear
|
332
|
+
end.to raise_error PG::Error, /cleared/
|
333
|
+
value
|
334
|
+
end.should eq %w[4 5 6]
|
335
|
+
@client.get_result.should be_nil
|
336
|
+
asynchronous.should be true
|
337
|
+
end
|
338
|
+
|
271
339
|
describe 'PG::EM::Client#transaction' do
|
272
340
|
|
273
341
|
it "should raise ArgumentError when there is no block" do
|