em-pg-client 0.2.0.pre.3 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/BENCHMARKS.rdoc +1 -1
- data/HISTORY.rdoc +10 -0
- data/README.rdoc +189 -52
- data/em-pg-client.gemspec +2 -2
- data/lib/em-synchrony/pg.rb +32 -5
- data/lib/pg/em.rb +140 -70
- data/spec/em_client_autoreconnect.rb +4 -2
- data/spec/em_client_common.rb +191 -65
- data/spec/em_devel_client.rb +3 -0
- data/spec/em_release_client.rb +3 -0
- data/spec/em_synchrony_client.rb +130 -21
- data/spec/em_synchrony_client_autoreconnect.rb +4 -2
- metadata +82 -61
data/spec/em_devel_client.rb
CHANGED
data/spec/em_release_client.rb
CHANGED
data/spec/em_synchrony_client.rb
CHANGED
@@ -9,10 +9,30 @@ describe PG::EM::Client do
|
|
9
9
|
@client.should be_an_instance_of described_class
|
10
10
|
end
|
11
11
|
|
12
|
-
it "should
|
12
|
+
it "should have disabled async_autoreconnect" do
|
13
|
+
@client.async_autoreconnect.should be_false
|
14
|
+
end
|
15
|
+
|
16
|
+
it "should enable async_autoreconnect" do
|
17
|
+
@client.async_autoreconnect = true
|
18
|
+
@client.async_autoreconnect.should be_true
|
19
|
+
end
|
20
|
+
|
21
|
+
it "should have same internal and external encoding" do
|
22
|
+
@client.external_encoding.should be @client.internal_encoding
|
23
|
+
end
|
24
|
+
|
25
|
+
it "should begin transaction" do
|
26
|
+
@client.query('BEGIN TRANSACTION').should be_an_instance_of PG::Result
|
27
|
+
end
|
28
|
+
|
29
|
+
it "should drop table `foo` if exists" do
|
13
30
|
@client.query(
|
14
31
|
'DROP TABLE IF EXISTS foo'
|
15
32
|
).should be_an_instance_of PG::Result
|
33
|
+
end
|
34
|
+
|
35
|
+
it "should create simple table `foo`" do
|
16
36
|
@client.query(
|
17
37
|
'CREATE TABLE foo (id integer,cdate timestamp with time zone,data varchar)'
|
18
38
|
).should be_an_instance_of PG::Result
|
@@ -30,33 +50,112 @@ describe PG::EM::Client do
|
|
30
50
|
results.each {|r| r.should be_an_instance_of DateTime }
|
31
51
|
end
|
32
52
|
|
33
|
-
it "should
|
53
|
+
it "should create prepared statement" do
|
34
54
|
@client.prepare('get_foo',
|
35
55
|
'SELECT * FROM foo order by id'
|
36
56
|
).should be_an_instance_of PG::Result
|
37
|
-
|
57
|
+
end
|
58
|
+
|
59
|
+
it "should describe prepared statement" do
|
60
|
+
@client.describe_prepared('get_foo') do |result|
|
61
|
+
result.should be_an_instance_of PG::Result
|
62
|
+
result.nfields.should eq 3
|
63
|
+
result.fname(0).should eq 'id'
|
64
|
+
result.values.should be_empty
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
it "should read foo table with prepared statement" do
|
69
|
+
ret = @client.exec_prepared('get_foo') do |result|
|
38
70
|
result.should be_an_instance_of PG::Result
|
39
71
|
result.each_with_index do |row, i|
|
40
72
|
row['id'].to_i.should == i
|
41
73
|
DateTime.parse(row['cdate']).should == @cdates[i]
|
42
74
|
row['data'].should == @values[i][0]
|
43
75
|
end
|
76
|
+
result
|
77
|
+
end
|
78
|
+
ret.should be_an_instance_of PG::Result
|
79
|
+
expect { ret.fields }.to raise_error(PG::Error, /result has been cleared/)
|
80
|
+
end
|
81
|
+
|
82
|
+
it "should declare cursor" do
|
83
|
+
@client.query(
|
84
|
+
'DECLARE foobar SCROLL CURSOR FOR SELECT * FROM foo'
|
85
|
+
).should be_an_instance_of PG::Result
|
86
|
+
end
|
87
|
+
|
88
|
+
it "should fetch two rows from table" do
|
89
|
+
ret = @client.query('FETCH FORWARD 2 FROM foobar') do |result|
|
90
|
+
result.should be_an_instance_of PG::Result
|
91
|
+
result.nfields.should eq 3
|
92
|
+
result.fname(0).should eq 'id'
|
93
|
+
result.values.length.should eq 2
|
94
|
+
result
|
95
|
+
end
|
96
|
+
ret.should be_an_instance_of PG::Result
|
97
|
+
expect { ret.fields }.to raise_error(PG::Error, /result has been cleared/)
|
98
|
+
end
|
99
|
+
|
100
|
+
it "should describe cursor with describe_portal" do
|
101
|
+
@client.describe_portal('foobar') do |result|
|
102
|
+
result.should be_an_instance_of PG::Result
|
103
|
+
result.nfields.should eq 3
|
104
|
+
result.fname(0).should eq 'id'
|
44
105
|
end
|
45
106
|
end
|
46
107
|
|
108
|
+
it "should close cursor" do
|
109
|
+
@client.query(
|
110
|
+
'CLOSE foobar'
|
111
|
+
).should be_an_instance_of PG::Result
|
112
|
+
end
|
113
|
+
|
47
114
|
it "should connect to database asynchronously" do
|
48
115
|
this = :first
|
116
|
+
Encoding.default_internal = Encoding::ISO_8859_1
|
49
117
|
f = Fiber.current
|
50
118
|
Fiber.new do
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
119
|
+
begin
|
120
|
+
result = described_class.new do |conn|
|
121
|
+
this = :second
|
122
|
+
Encoding.default_internal = nil
|
123
|
+
conn.should be_an_instance_of described_class
|
124
|
+
conn.external_encoding.should_not eq(conn.internal_encoding)
|
125
|
+
conn.internal_encoding.should be Encoding::ISO_8859_1
|
126
|
+
conn.get_client_encoding.should eq "LATIN1"
|
127
|
+
conn.query('SELECT pg_database_size(current_database());') do |result|
|
128
|
+
result.should be_an_instance_of PG::Result
|
129
|
+
result[0]['pg_database_size'].to_i.should be > 0
|
130
|
+
end
|
131
|
+
conn
|
132
|
+
end
|
133
|
+
result.should be_an_instance_of described_class
|
134
|
+
result.finished?.should be_true
|
135
|
+
ensure
|
136
|
+
f.resume
|
137
|
+
end
|
138
|
+
end.resume
|
139
|
+
this.should be :first
|
140
|
+
Fiber.yield
|
141
|
+
this.should be :second
|
142
|
+
end
|
143
|
+
|
144
|
+
it "should connect without setting incompatible encoding" do
|
145
|
+
this = :first
|
146
|
+
Encoding.default_internal = Encoding::Emacs_Mule
|
147
|
+
f = Fiber.current
|
148
|
+
Fiber.new do
|
149
|
+
begin
|
150
|
+
described_class.new do |conn|
|
151
|
+
this = :second
|
152
|
+
Encoding.default_internal = nil
|
153
|
+
conn.should be_an_instance_of described_class
|
154
|
+
conn.external_encoding.should be conn.internal_encoding
|
155
|
+
end
|
156
|
+
ensure
|
157
|
+
f.resume
|
57
158
|
end
|
58
|
-
conn.close
|
59
|
-
f.resume
|
60
159
|
end.resume
|
61
160
|
this.should be :first
|
62
161
|
Fiber.yield
|
@@ -67,12 +166,12 @@ describe PG::EM::Client do
|
|
67
166
|
expect {
|
68
167
|
@client.query('SELECT * from pg_class; SRELECT CURRENT_TIMESTAMP; SELECT 42 number')
|
69
168
|
}.to raise_error(PG::Error, /syntax error/)
|
169
|
+
end
|
170
|
+
|
171
|
+
it "should rollback transaction" do
|
70
172
|
@client.query('ROLLBACK') do |result|
|
71
173
|
result.should be_an_instance_of PG::Result
|
72
174
|
end
|
73
|
-
@client.query('BEGIN TRANSACTION') do |result|
|
74
|
-
result.should be_an_instance_of PG::Result
|
75
|
-
end
|
76
175
|
end
|
77
176
|
|
78
177
|
it "should return only last statement" do
|
@@ -94,9 +193,7 @@ describe PG::EM::Client do
|
|
94
193
|
@client.query_timeout = 0
|
95
194
|
@client.query_timeout.should eq 0
|
96
195
|
@client.async_command_aborted.should be_true
|
97
|
-
@client.
|
98
|
-
result.should be_an_instance_of PG::Result
|
99
|
-
end
|
196
|
+
@client.status.should be PG::CONNECTION_BAD
|
100
197
|
end
|
101
198
|
|
102
199
|
it "should timeout not expire while executing query with partial results" do
|
@@ -116,6 +213,7 @@ describe PG::EM::Client do
|
|
116
213
|
@client.query_timeout = 0
|
117
214
|
@client.query_timeout.should eq 0
|
118
215
|
@client.async_command_aborted.should be_false
|
216
|
+
@client.status.should be PG::CONNECTION_OK
|
119
217
|
end
|
120
218
|
end
|
121
219
|
|
@@ -133,14 +231,24 @@ describe PG::EM::Client do
|
|
133
231
|
'SELECT 42 number')
|
134
232
|
}.to raise_error(PG::Error, /query timeout expired/)
|
135
233
|
(Time.now - start_time).should be > 2
|
234
|
+
@client.async_command_aborted.should be_true
|
235
|
+
@client.status.should be PG::CONNECTION_BAD
|
136
236
|
@client.query_timeout = 0
|
137
237
|
@client.query_timeout.should eq 0
|
138
|
-
|
139
|
-
|
238
|
+
end
|
239
|
+
|
240
|
+
it "should clear connection with blocking reset" do
|
241
|
+
@after_em_stop = proc do
|
242
|
+
@client.async_command_aborted.should be_true
|
243
|
+
@client.status.should be PG::CONNECTION_BAD
|
244
|
+
@client.reset
|
245
|
+
@client.async_command_aborted.should be_false
|
246
|
+
@client.status.should be PG::CONNECTION_OK
|
140
247
|
end
|
141
248
|
end
|
142
249
|
|
143
250
|
around(:each) do |testcase|
|
251
|
+
@after_em_stop = nil
|
144
252
|
EM.synchrony do
|
145
253
|
begin
|
146
254
|
testcase.call
|
@@ -148,17 +256,18 @@ describe PG::EM::Client do
|
|
148
256
|
EM.stop
|
149
257
|
end
|
150
258
|
end
|
259
|
+
@after_em_stop.call if @after_em_stop
|
151
260
|
end
|
152
261
|
|
153
262
|
before(:all) do
|
154
263
|
@cdates = []
|
155
264
|
@values = Array(('AA'..'ZZ').each_with_index)
|
265
|
+
ENV['PGCLIENTENCODING'] = nil
|
266
|
+
Encoding.default_internal = nil
|
156
267
|
@client = described_class.new
|
157
|
-
@client.query 'BEGIN TRANSACTION'
|
158
268
|
end
|
159
269
|
|
160
270
|
after(:all) do
|
161
|
-
@client.query 'ROLLBACK TRANSACTION'
|
162
271
|
@client.close
|
163
272
|
end
|
164
273
|
|
@@ -51,7 +51,7 @@ describe 'em-synchrony-pg default autoreconnect' do
|
|
51
51
|
result[0]['pg_database_size'].to_i.should be > 0
|
52
52
|
end
|
53
53
|
end
|
54
|
-
@client = PG::EM::Client.new
|
54
|
+
@client = PG::EM::Client.new(async_autoreconnect: true)
|
55
55
|
@client.set_notice_processor {|msg| puts "warning from pgsql: #{msg.to_s.chomp.inspect}"}
|
56
56
|
end
|
57
57
|
end
|
@@ -101,7 +101,9 @@ describe 'em-synchrony-pg with autoreconnect disabled' do
|
|
101
101
|
end
|
102
102
|
|
103
103
|
it "should get database size using query after manual connection reset" do
|
104
|
+
@client.status.should be PG::CONNECTION_BAD
|
104
105
|
@client.reset
|
106
|
+
@client.status.should be PG::CONNECTION_OK
|
105
107
|
@tested_proc.call
|
106
108
|
end
|
107
109
|
|
@@ -112,7 +114,7 @@ describe 'em-synchrony-pg with autoreconnect disabled' do
|
|
112
114
|
result[0]['pg_database_size'].to_i.should be > 0
|
113
115
|
end
|
114
116
|
end
|
115
|
-
@client = PG::EM::Client.new
|
117
|
+
@client = PG::EM::Client.new
|
116
118
|
@client.set_notice_processor {|msg| puts "warning from pgsql: #{msg.to_s.chomp.inspect}"}
|
117
119
|
end
|
118
120
|
end
|
metadata
CHANGED
@@ -1,82 +1,104 @@
|
|
1
|
-
--- !ruby/object:Gem::Specification
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
2
|
name: em-pg-client
|
3
|
-
version: !ruby/object:Gem::Version
|
4
|
-
|
5
|
-
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.2.0
|
5
|
+
prerelease:
|
6
6
|
platform: ruby
|
7
|
-
authors:
|
7
|
+
authors:
|
8
8
|
- Rafal Michalski
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
- !ruby/object:Gem::Dependency
|
12
|
+
date: 2012-05-08 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
16
15
|
name: pg
|
17
|
-
|
18
|
-
requirement: &id001 !ruby/object:Gem::Requirement
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
19
17
|
none: false
|
20
|
-
requirements:
|
21
|
-
- -
|
22
|
-
- !ruby/object:Gem::Version
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
23
21
|
version: 0.13.2
|
24
22
|
type: :runtime
|
25
|
-
version_requirements: *id001
|
26
|
-
- !ruby/object:Gem::Dependency
|
27
|
-
name: eventmachine
|
28
23
|
prerelease: false
|
29
|
-
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ! '>='
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: 0.13.2
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: eventmachine
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
30
33
|
none: false
|
31
|
-
requirements:
|
32
|
-
- -
|
33
|
-
- !ruby/object:Gem::Version
|
34
|
+
requirements:
|
35
|
+
- - ! '>='
|
36
|
+
- !ruby/object:Gem::Version
|
34
37
|
version: 0.12.10
|
35
38
|
type: :runtime
|
36
|
-
version_requirements: *id002
|
37
|
-
- !ruby/object:Gem::Dependency
|
38
|
-
name: rspec
|
39
39
|
prerelease: false
|
40
|
-
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
41
|
none: false
|
42
|
-
requirements:
|
42
|
+
requirements:
|
43
|
+
- - ! '>='
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: 0.12.10
|
46
|
+
- !ruby/object:Gem::Dependency
|
47
|
+
name: rspec
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
49
|
+
none: false
|
50
|
+
requirements:
|
43
51
|
- - ~>
|
44
|
-
- !ruby/object:Gem::Version
|
52
|
+
- !ruby/object:Gem::Version
|
45
53
|
version: 2.8.0
|
46
54
|
type: :development
|
47
|
-
version_requirements: *id003
|
48
|
-
- !ruby/object:Gem::Dependency
|
49
|
-
name: eventmachine
|
50
55
|
prerelease: false
|
51
|
-
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
58
|
+
requirements:
|
59
|
+
- - ~>
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: 2.8.0
|
62
|
+
- !ruby/object:Gem::Dependency
|
63
|
+
name: eventmachine
|
64
|
+
requirement: !ruby/object:Gem::Requirement
|
52
65
|
none: false
|
53
|
-
requirements:
|
54
|
-
- -
|
55
|
-
- !ruby/object:Gem::Version
|
66
|
+
requirements:
|
67
|
+
- - ! '>='
|
68
|
+
- !ruby/object:Gem::Version
|
56
69
|
version: 1.0.0.beta.1
|
57
70
|
type: :development
|
58
|
-
version_requirements: *id004
|
59
|
-
- !ruby/object:Gem::Dependency
|
60
|
-
name: em-synchrony
|
61
71
|
prerelease: false
|
62
|
-
|
72
|
+
version_requirements: !ruby/object:Gem::Requirement
|
63
73
|
none: false
|
64
|
-
requirements:
|
74
|
+
requirements:
|
75
|
+
- - ! '>='
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
version: 1.0.0.beta.1
|
78
|
+
- !ruby/object:Gem::Dependency
|
79
|
+
name: em-synchrony
|
80
|
+
requirement: !ruby/object:Gem::Requirement
|
81
|
+
none: false
|
82
|
+
requirements:
|
65
83
|
- - ~>
|
66
|
-
- !ruby/object:Gem::Version
|
84
|
+
- !ruby/object:Gem::Version
|
67
85
|
version: 1.0.0
|
68
86
|
type: :development
|
69
|
-
|
70
|
-
|
87
|
+
prerelease: false
|
88
|
+
version_requirements: !ruby/object:Gem::Requirement
|
89
|
+
none: false
|
90
|
+
requirements:
|
91
|
+
- - ~>
|
92
|
+
- !ruby/object:Gem::Version
|
93
|
+
version: 1.0.0
|
94
|
+
description: PostgreSQL asynchronous EventMachine client, based on pg interface (PG::Connection)
|
71
95
|
email: rafal@yeondir.com
|
72
96
|
executables: []
|
73
|
-
|
74
97
|
extensions: []
|
75
|
-
|
76
|
-
extra_rdoc_files:
|
98
|
+
extra_rdoc_files:
|
77
99
|
- README.rdoc
|
78
100
|
- BENCHMARKS.rdoc
|
79
|
-
files:
|
101
|
+
files:
|
80
102
|
- BENCHMARKS.rdoc
|
81
103
|
- HISTORY.rdoc
|
82
104
|
- README.rdoc
|
@@ -93,35 +115,34 @@ files:
|
|
93
115
|
- spec/em_synchrony_client_autoreconnect.rb
|
94
116
|
homepage: http://github.com/royaltm/ruby-em-pg-client
|
95
117
|
licenses: []
|
96
|
-
|
97
118
|
post_install_message:
|
98
|
-
rdoc_options:
|
119
|
+
rdoc_options:
|
99
120
|
- --title
|
100
121
|
- em-pg-client
|
101
122
|
- --main
|
102
123
|
- README.rdoc
|
103
|
-
require_paths:
|
124
|
+
require_paths:
|
104
125
|
- lib
|
105
|
-
required_ruby_version: !ruby/object:Gem::Requirement
|
126
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
106
127
|
none: false
|
107
|
-
requirements:
|
108
|
-
- -
|
109
|
-
- !ruby/object:Gem::Version
|
128
|
+
requirements:
|
129
|
+
- - ! '>='
|
130
|
+
- !ruby/object:Gem::Version
|
110
131
|
version: 1.9.1
|
111
|
-
required_rubygems_version: !ruby/object:Gem::Requirement
|
132
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
112
133
|
none: false
|
113
|
-
requirements:
|
114
|
-
- -
|
115
|
-
- !ruby/object:Gem::Version
|
116
|
-
version:
|
117
|
-
requirements:
|
134
|
+
requirements:
|
135
|
+
- - ! '>='
|
136
|
+
- !ruby/object:Gem::Version
|
137
|
+
version: '0'
|
138
|
+
requirements:
|
118
139
|
- PostgreSQL server
|
119
140
|
rubyforge_project:
|
120
|
-
rubygems_version: 1.8.
|
141
|
+
rubygems_version: 1.8.23
|
121
142
|
signing_key:
|
122
143
|
specification_version: 3
|
123
144
|
summary: EventMachine PostgreSQL client
|
124
|
-
test_files:
|
145
|
+
test_files:
|
125
146
|
- spec/em_synchrony_client.rb
|
126
147
|
- spec/em_devel_client.rb
|
127
148
|
- spec/em_client_common.rb
|