em-pg-client 0.1.0 → 0.1.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/HISTORY.rdoc +9 -0
- data/README.rdoc +66 -11
- data/Rakefile +2 -1
- data/em-pg-client.gemspec +2 -1
- data/lib/pg/em.rb +94 -43
- data/spec/{em_client.rb → em_devel_client.rb} +9 -3
- data/spec/em_release_client.rb +69 -0
- metadata +66 -68
data/HISTORY.rdoc
ADDED
data/README.rdoc
CHANGED
@@ -1,17 +1,17 @@
|
|
1
1
|
= em-pg-client
|
2
2
|
|
3
|
-
Author:: Rafał Michalski (mailto:
|
3
|
+
Author:: Rafał Michalski (mailto:rafal@yeondir.com)
|
4
4
|
|
5
5
|
* http://github.com/royaltm/ruby-em-pg-client
|
6
6
|
|
7
7
|
== DESCRIPTION
|
8
8
|
|
9
9
|
*em-pg-client* is a PostgreSQL EventMachine client wrapper for Ruby
|
10
|
-
based on
|
10
|
+
based on ruby-pg[https://bitbucket.org/ged/ruby-pg]
|
11
11
|
|
12
12
|
== FEATURES
|
13
13
|
|
14
|
-
* minimal changes to PG::
|
14
|
+
* minimal changes to PG::Connection API
|
15
15
|
* auto reconnects on socket connection loss (like server restarts)
|
16
16
|
* true non-blocking asynchronous processing
|
17
17
|
* EM-Synchrony[https://github.com/igrigorik/em-synchrony] support
|
@@ -49,7 +49,7 @@ I've found at least 3 other implementations of EM postgres client:
|
|
49
49
|
and (except the bundled one which uses no longer maintained postgres-pr library)
|
50
50
|
all of them have similiar flaws:
|
51
51
|
|
52
|
-
* 2 of them are designed to support some ORM
|
52
|
+
* 2 of them are designed to support some ORM (ActiveRecord or Sequel)
|
53
53
|
so they are EM-Synchrony only,
|
54
54
|
* non-standard API method names,
|
55
55
|
* no (nonexistent or non-working) autoreconnect implementation,
|
@@ -81,14 +81,14 @@ The greetz go to:
|
|
81
81
|
# no async
|
82
82
|
pg = PG::EM::Client.new dbname: 'test'
|
83
83
|
pq.query('select * from foo') do |result|
|
84
|
-
puts result
|
84
|
+
puts Array(result).inspect
|
85
85
|
end
|
86
86
|
|
87
87
|
# asynchronous
|
88
88
|
EM.run do
|
89
89
|
pq.query('select * from foo') do |result|
|
90
90
|
raise result if result.is_a? ::Exception
|
91
|
-
puts result
|
91
|
+
puts Array(result).inspect
|
92
92
|
EM.stop
|
93
93
|
end
|
94
94
|
puts "sent"
|
@@ -98,11 +98,10 @@ The greetz go to:
|
|
98
98
|
|
99
99
|
EM.run do
|
100
100
|
pg = PG::EM::Client.new dbname: 'test'
|
101
|
-
|
102
|
-
|
103
|
-
pq.query('select * from foo') do |result|
|
101
|
+
try_query = lambda do |&blk|
|
102
|
+
pg.query('select * from foo') do |result|
|
104
103
|
raise result if result.is_a? ::Exception
|
105
|
-
puts result
|
104
|
+
puts Array(result).inspect
|
106
105
|
blk.call
|
107
106
|
end
|
108
107
|
end
|
@@ -124,6 +123,37 @@ or
|
|
124
123
|
pg = PG::EM::Client.new dbname: 'test',
|
125
124
|
async_autoreconnect: false
|
126
125
|
|
126
|
+
It's also possible to define +on_reconnect+ callback to be invoked
|
127
|
+
while the connection has been reset. It's called just before the send query
|
128
|
+
command is executed:
|
129
|
+
|
130
|
+
EM.run do
|
131
|
+
pg = PG::EM::Client.new dbname: 'test'
|
132
|
+
pg.prepare('bar', 'select * from foo order by cdate desc') do
|
133
|
+
pg.on_reconnect = proc { |c, e|
|
134
|
+
c.prepare('bar', 'select * from foo order by cdate desc')
|
135
|
+
}
|
136
|
+
try_query = lambda do |&blk|
|
137
|
+
pg.exec_prepared('bar') do |result|
|
138
|
+
raise result if result.is_a? ::Exception
|
139
|
+
puts Array(result).inspect
|
140
|
+
blk.call
|
141
|
+
end
|
142
|
+
end
|
143
|
+
try_query.call {
|
144
|
+
system 'pg_ctl stop -m fast'
|
145
|
+
system 'pg_ctl start -w'
|
146
|
+
EM.add_timer(1) do
|
147
|
+
try_query.call { EM.stop }
|
148
|
+
end
|
149
|
+
}
|
150
|
+
end
|
151
|
+
end
|
152
|
+
|
153
|
+
As you can see it's possible to send async query from inside on_reconnect
|
154
|
+
proc. However you have to pass +Deferrable+ from the async callback to the
|
155
|
+
caller. See +#on_reconnect+ docs for details.
|
156
|
+
|
127
157
|
=== TRUE ASYNC
|
128
158
|
|
129
159
|
EM.run do
|
@@ -147,7 +177,7 @@ or
|
|
147
177
|
EM.synchrony do
|
148
178
|
pg = PG::EM::Client.new dbname: 'test'
|
149
179
|
pg.query('select * from foo') do |result|
|
150
|
-
puts result
|
180
|
+
puts Array(result).inspect
|
151
181
|
end
|
152
182
|
EM.stop
|
153
183
|
end
|
@@ -198,6 +228,31 @@ or
|
|
198
228
|
EM.stop
|
199
229
|
end
|
200
230
|
|
231
|
+
==== Async reconnect with on_reconnect callback
|
232
|
+
|
233
|
+
EM.synchrony do
|
234
|
+
pg = EM::Synchrony::ConnectionPool.new(size: 5) do
|
235
|
+
p = PG::EM::Client.new dbname: 'test'
|
236
|
+
p.on_reconnect = proc do |c, e|
|
237
|
+
c.prepare('bar', 'select * from foo order by cdate desc')
|
238
|
+
end
|
239
|
+
p.on_reconnect.call p
|
240
|
+
p
|
241
|
+
end
|
242
|
+
try_query = lambda do
|
243
|
+
pg.exec_prepared('bar') do |result|
|
244
|
+
raise result if result.is_a? ::Exception
|
245
|
+
puts Array(result).inspect
|
246
|
+
end
|
247
|
+
end
|
248
|
+
try_query.call
|
249
|
+
system 'pg_ctl stop -m fast'
|
250
|
+
system 'pg_ctl start -w'
|
251
|
+
EM::Synchrony.sleep(1)
|
252
|
+
try_query.call
|
253
|
+
EM.stop
|
254
|
+
end
|
255
|
+
|
201
256
|
== LICENCE
|
202
257
|
|
203
258
|
The MIT License - Copyright (c) 2012 Rafał Michalski
|
data/Rakefile
CHANGED
@@ -7,7 +7,8 @@ $gem_name = "em-pg-client"
|
|
7
7
|
desc "Run tests"
|
8
8
|
task :test do
|
9
9
|
puts "WARNING: The test needs to be run with an available local PostgreSQL server"
|
10
|
-
sh "rspec spec/
|
10
|
+
sh "rspec spec/em_release_client.rb"
|
11
|
+
sh "rspec spec/em_devel_client.rb"
|
11
12
|
sh "rspec spec/em_synchrony_client.rb"
|
12
13
|
end
|
13
14
|
|
data/em-pg-client.gemspec
CHANGED
@@ -2,7 +2,7 @@ $:.unshift "lib"
|
|
2
2
|
|
3
3
|
Gem::Specification.new do |s|
|
4
4
|
s.name = "em-pg-client"
|
5
|
-
s.version = "0.1.
|
5
|
+
s.version = "0.1.1"
|
6
6
|
s.required_ruby_version = ">= 1.9.1"
|
7
7
|
s.date = "#{Time.now.strftime("%Y-%m-%d")}"
|
8
8
|
s.summary = "EventMachine PostgreSQL client"
|
@@ -21,5 +21,6 @@ Gem::Specification.new do |s|
|
|
21
21
|
s.add_runtime_dependency "pg", ">= 0.13.2"
|
22
22
|
s.add_runtime_dependency "eventmachine", ">= 0.12.10"
|
23
23
|
s.add_development_dependency "rspec", "~> 2.8.0"
|
24
|
+
s.add_development_dependency "eventmachine", ">= 1.0.0.beta.1"
|
24
25
|
s.add_development_dependency "em-synchrony", "~> 1.0.0"
|
25
26
|
end
|
data/lib/pg/em.rb
CHANGED
@@ -1,48 +1,75 @@
|
|
1
1
|
require 'pg'
|
2
2
|
module PG
|
3
3
|
module EM
|
4
|
+
# == PostgreSQL EventMachine client
|
5
|
+
#
|
6
|
+
# Author:: Rafal Michalski (mailto:royaltm75@gmail.com)
|
7
|
+
# Licence:: MIT License
|
8
|
+
#
|
9
|
+
#
|
10
|
+
# PG::EM::Client is a wrapper for PG::Connection which (re)defines methods:
|
11
|
+
#
|
12
|
+
# - +async_exec+ (alias: +async_query+)
|
13
|
+
# - +async_prepare+
|
14
|
+
# - +async_exec_prepared+
|
15
|
+
#
|
16
|
+
# and following:
|
17
|
+
#
|
18
|
+
# - +exec+ (alias: +query+)
|
19
|
+
# - +exec_prepared+
|
20
|
+
# - +prepare+
|
21
|
+
#
|
22
|
+
# which autodetects if EventMachine is running and uses appropriate
|
23
|
+
# (async or sync) method version.
|
24
|
+
#
|
25
|
+
# Async methods might try to reset connection on connection error,
|
26
|
+
# you won't even notice that (except for warning message from PG).
|
27
|
+
#
|
28
|
+
# To disable such behavior set:
|
29
|
+
# client.async_autoreconnect = false
|
30
|
+
#
|
31
|
+
# or pass as new() hash argument:
|
32
|
+
# PG::EM::Client.new database: 'bar', async_autoreconnect: false
|
33
|
+
#
|
34
|
+
# Otherwise nothing changes in PG::Connect API.
|
35
|
+
# See PG::Connect docs for arguments to above methods.
|
36
|
+
#
|
37
|
+
# *Warning:*
|
38
|
+
#
|
39
|
+
# +async_exec_prepared+ after +async_prepare+ should only be invoked on
|
40
|
+
# the *same* connection.
|
41
|
+
# If you are using connection pool, make sure to acquire single connection first.
|
42
|
+
#
|
4
43
|
class Client < PG::Connection
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
#
|
9
|
-
#
|
10
|
-
#
|
11
|
-
#
|
12
|
-
#
|
13
|
-
# - +async_exec+ (alias: +async_query+)
|
14
|
-
# - +async_prepare+
|
15
|
-
# - +async_exec_prepared+
|
16
|
-
#
|
17
|
-
# and following:
|
18
|
-
#
|
19
|
-
# - +exec+ (alias: +query+)
|
20
|
-
# - +exec_prepared+
|
21
|
-
# - +prepare+
|
22
|
-
#
|
23
|
-
# which autodetects if EventMachine is running and uses appropriate
|
24
|
-
# (async or sync) method version.
|
25
|
-
#
|
26
|
-
# Async methods might try to reset connection on connection error,
|
27
|
-
# you won't even notice that (except for warning message from PG).
|
28
|
-
#
|
29
|
-
# To disable such behavior set:
|
30
|
-
# client.async_autoreconnect = false
|
44
|
+
|
45
|
+
attr_accessor :async_autoreconnect
|
46
|
+
|
47
|
+
# +on_reconnect+ is a user defined Proc that is called after a connection
|
48
|
+
# with the server has been re-established.
|
49
|
+
# It's invoked with +connection+ as first argument and original
|
50
|
+
# +exception+ that caused the reconnecting process as second argument.
|
31
51
|
#
|
32
|
-
#
|
33
|
-
# PG::EM::Client.new database: 'bar', async_autoreconnect: false
|
52
|
+
# Certain rules should apply to on_reconnect proc:
|
34
53
|
#
|
35
|
-
#
|
36
|
-
#
|
54
|
+
# - +async_autoreconnect+ is switched off (do not try to change it from
|
55
|
+
# inside on_reconnect proc).
|
56
|
+
# - If proc returns +false+ (explicitly, +nil+ is ignored)
|
57
|
+
# the original +exception+ is raised and the send query command is
|
58
|
+
# not invoked at all.
|
59
|
+
# - If return value responds to +callback+ and +errback+ methods
|
60
|
+
# (like +Deferrable+), the send query command will be bound to this
|
61
|
+
# deferrable's success callback. Otherwise the send query command is called
|
62
|
+
# immediately after on_reconnect proc is executed.
|
63
|
+
# - Other return values are ignored.
|
37
64
|
#
|
38
|
-
#
|
65
|
+
# You may pass this proc as +:on_reconnect+ option to PG::EM::Client.new.
|
39
66
|
#
|
40
|
-
#
|
41
|
-
#
|
42
|
-
#
|
67
|
+
# Example:
|
68
|
+
# pg.on_reconnect = proc do |conn, ex|
|
69
|
+
# conn.prepare("birds_by_name", "select id, name from animals order by name where species=$1", ['birds'])
|
70
|
+
# end
|
43
71
|
#
|
44
|
-
|
45
|
-
attr_accessor :async_autoreconnect
|
72
|
+
attr_accessor :on_reconnect
|
46
73
|
|
47
74
|
module Watcher
|
48
75
|
def initialize(client, deferrable)
|
@@ -66,11 +93,16 @@ module PG
|
|
66
93
|
|
67
94
|
def initialize(*args)
|
68
95
|
@async_autoreconnect = true
|
96
|
+
@on_reconnect = nil
|
69
97
|
if args.last.is_a? Hash
|
70
98
|
args.last.reject! do |key, value|
|
71
|
-
|
99
|
+
case key.to_s
|
100
|
+
when 'async_autoreconnect'
|
72
101
|
@async_autoreconnect = !!value
|
73
102
|
true
|
103
|
+
when 'on_reconnect'
|
104
|
+
@on_reconnect = value if value.respond_to? :call
|
105
|
+
true
|
74
106
|
end
|
75
107
|
end
|
76
108
|
end
|
@@ -85,22 +117,41 @@ module PG
|
|
85
117
|
|
86
118
|
class_eval <<-EOD
|
87
119
|
def async_#{name}(*args, &blk)
|
120
|
+
df = ::EM::DefaultDeferrable.new
|
121
|
+
if block_given?
|
122
|
+
df.callback(&blk)
|
123
|
+
df.errback(&blk)
|
124
|
+
end
|
88
125
|
begin
|
89
126
|
#{send_name}(*args)
|
90
127
|
rescue PG::Error => e
|
91
128
|
if self.status != PG::CONNECTION_OK && async_autoreconnect
|
92
129
|
reset
|
93
|
-
|
130
|
+
if on_reconnect
|
131
|
+
begin
|
132
|
+
self.async_autoreconnect = false
|
133
|
+
returned_df = on_reconnect.call(self, e)
|
134
|
+
raise e if returned_df == false
|
135
|
+
if returned_df.respond_to?(:callback) && returned_df.respond_to?(:errback)
|
136
|
+
returned_df.callback do
|
137
|
+
#{send_name}(*args)
|
138
|
+
::EM.watch(self.socket, Watcher, self, df).notify_readable = true
|
139
|
+
end
|
140
|
+
returned_df.errback do |ex|
|
141
|
+
df.fail(ex)
|
142
|
+
end
|
143
|
+
return df
|
144
|
+
end
|
145
|
+
ensure
|
146
|
+
self.async_autoreconnect = true
|
147
|
+
end
|
148
|
+
end
|
149
|
+
#{send_name}(*args)
|
94
150
|
else
|
95
151
|
raise e
|
96
152
|
end
|
97
153
|
end
|
98
|
-
df = ::EM::DefaultDeferrable.new
|
99
154
|
::EM.watch(self.socket, Watcher, self, df).notify_readable = true
|
100
|
-
if block_given?
|
101
|
-
df.callback(&blk)
|
102
|
-
df.errback(&blk)
|
103
|
-
end
|
104
155
|
df
|
105
156
|
end
|
106
157
|
EOD
|
@@ -1,4 +1,5 @@
|
|
1
1
|
$:.unshift "lib"
|
2
|
+
gem 'eventmachine', '>= 1.0.0.beta.1'
|
2
3
|
require 'date'
|
3
4
|
require 'eventmachine'
|
4
5
|
require 'pg/em'
|
@@ -6,8 +7,10 @@ require 'pg/em'
|
|
6
7
|
describe PG::EM::Client do
|
7
8
|
|
8
9
|
it "should create simple table `foo`" do
|
9
|
-
@client.query('DROP TABLE IF EXISTS foo') do
|
10
|
-
|
10
|
+
@client.query('DROP TABLE IF EXISTS foo') do |result|
|
11
|
+
raise result if result.is_a? ::Exception
|
12
|
+
@client.query('CREATE TABLE foo (id integer,cdate timestamp with time zone,data varchar)') do |result|
|
13
|
+
raise result if result.is_a? ::Exception
|
11
14
|
EM.stop
|
12
15
|
end
|
13
16
|
end
|
@@ -16,6 +19,7 @@ describe PG::EM::Client do
|
|
16
19
|
it "should populate foo with some data " do
|
17
20
|
EM::Iterator.new(@values).map(proc{ |(data, id), iter|
|
18
21
|
@client.query('INSERT INTO foo (id,cdate,data) VALUES($1,$2,$3) returning cdate', [id, DateTime.now, data]) do |result|
|
22
|
+
raise result if result.is_a? ::Exception
|
19
23
|
iter.return(DateTime.parse(result[0]['cdate']))
|
20
24
|
end
|
21
25
|
}, proc{ |results|
|
@@ -27,8 +31,10 @@ describe PG::EM::Client do
|
|
27
31
|
end
|
28
32
|
|
29
33
|
it "should read foo table with prepared statement" do
|
30
|
-
@client.prepare('get_foo', 'SELECT * FROM foo order by id') do
|
34
|
+
@client.prepare('get_foo', 'SELECT * FROM foo order by id') do |result|
|
35
|
+
raise result if result.is_a? ::Exception
|
31
36
|
@client.exec_prepared('get_foo') do |result|
|
37
|
+
raise result if result.is_a? ::Exception
|
32
38
|
result.each_with_index do |row, i|
|
33
39
|
row['id'].to_i.should == i
|
34
40
|
DateTime.parse(row['cdate']).should == @cdates[i]
|
@@ -0,0 +1,69 @@
|
|
1
|
+
$:.unshift "lib"
|
2
|
+
gem 'eventmachine', '= 0.12.10'
|
3
|
+
require 'date'
|
4
|
+
require 'eventmachine'
|
5
|
+
require 'pg/em'
|
6
|
+
|
7
|
+
describe PG::EM::Client do
|
8
|
+
|
9
|
+
it "should create simple table `foo`" do
|
10
|
+
@client.query('DROP TABLE IF EXISTS foo') do |result|
|
11
|
+
raise result if result.is_a? ::Exception
|
12
|
+
@client.query('CREATE TABLE foo (id integer,cdate timestamp with time zone,data varchar)') do |result|
|
13
|
+
raise result if result.is_a? ::Exception
|
14
|
+
EM.stop
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
it "should populate foo with some data " do
|
20
|
+
values = @values.dup
|
21
|
+
results = []
|
22
|
+
do_query = proc do
|
23
|
+
data, id = values.shift
|
24
|
+
@client.query('INSERT INTO foo (id,cdate,data) VALUES($1,$2,$3) returning cdate', [id, DateTime.now, data]) do |result|
|
25
|
+
raise result if result.is_a? ::Exception
|
26
|
+
results << DateTime.parse(result[0]['cdate'])
|
27
|
+
if values.empty?
|
28
|
+
@cdates.replace results
|
29
|
+
results.length.should == @values.length
|
30
|
+
results.each {|r| r.class.should == DateTime }
|
31
|
+
EM.stop
|
32
|
+
else
|
33
|
+
do_query.call
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
do_query.call
|
38
|
+
end
|
39
|
+
|
40
|
+
it "should read foo table with prepared statement" do
|
41
|
+
@client.prepare('get_foo', 'SELECT * FROM foo order by id') do
|
42
|
+
@client.exec_prepared('get_foo') do |result|
|
43
|
+
raise result if result.is_a? ::Exception
|
44
|
+
result.each_with_index do |row, i|
|
45
|
+
row['id'].to_i.should == i
|
46
|
+
DateTime.parse(row['cdate']).should == @cdates[i]
|
47
|
+
row['data'].should == @values[i][0]
|
48
|
+
end
|
49
|
+
EM.stop
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
around(:each) do |testcase|
|
55
|
+
EM.run &testcase
|
56
|
+
end
|
57
|
+
|
58
|
+
before(:all) do
|
59
|
+
@cdates = []
|
60
|
+
@values = Array(('AA'..'ZZ').each_with_index)
|
61
|
+
@client = PG::EM::Client.new(dbname: 'test')
|
62
|
+
@client.query 'BEGIN TRANSACTION'
|
63
|
+
end
|
64
|
+
|
65
|
+
after(:all) do
|
66
|
+
@client.query 'ROLLBACK TRANSACTION'
|
67
|
+
@client.close
|
68
|
+
end
|
69
|
+
end
|
metadata
CHANGED
@@ -1,126 +1,124 @@
|
|
1
|
-
--- !ruby/object:Gem::Specification
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
2
|
name: em-pg-client
|
3
|
-
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.0
|
3
|
+
version: !ruby/object:Gem::Version
|
5
4
|
prerelease:
|
5
|
+
version: 0.1.1
|
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
|
-
|
12
|
+
|
13
|
+
date: 2012-04-27 00:00:00 Z
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
15
16
|
name: pg
|
16
|
-
requirement: !ruby/object:Gem::Requirement
|
17
|
-
none: false
|
18
|
-
requirements:
|
19
|
-
- - ! '>='
|
20
|
-
- !ruby/object:Gem::Version
|
21
|
-
version: 0.13.2
|
22
|
-
type: :runtime
|
23
17
|
prerelease: false
|
24
|
-
|
18
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
25
19
|
none: false
|
26
|
-
requirements:
|
27
|
-
- -
|
28
|
-
- !ruby/object:Gem::Version
|
20
|
+
requirements:
|
21
|
+
- - ">="
|
22
|
+
- !ruby/object:Gem::Version
|
29
23
|
version: 0.13.2
|
30
|
-
- !ruby/object:Gem::Dependency
|
31
|
-
name: eventmachine
|
32
|
-
requirement: !ruby/object:Gem::Requirement
|
33
|
-
none: false
|
34
|
-
requirements:
|
35
|
-
- - ! '>='
|
36
|
-
- !ruby/object:Gem::Version
|
37
|
-
version: 0.12.10
|
38
24
|
type: :runtime
|
25
|
+
version_requirements: *id001
|
26
|
+
- !ruby/object:Gem::Dependency
|
27
|
+
name: eventmachine
|
39
28
|
prerelease: false
|
40
|
-
|
29
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
41
30
|
none: false
|
42
|
-
requirements:
|
43
|
-
- -
|
44
|
-
- !ruby/object:Gem::Version
|
31
|
+
requirements:
|
32
|
+
- - ">="
|
33
|
+
- !ruby/object:Gem::Version
|
45
34
|
version: 0.12.10
|
46
|
-
|
35
|
+
type: :runtime
|
36
|
+
version_requirements: *id002
|
37
|
+
- !ruby/object:Gem::Dependency
|
47
38
|
name: rspec
|
48
|
-
|
39
|
+
prerelease: false
|
40
|
+
requirement: &id003 !ruby/object:Gem::Requirement
|
49
41
|
none: false
|
50
|
-
requirements:
|
42
|
+
requirements:
|
51
43
|
- - ~>
|
52
|
-
- !ruby/object:Gem::Version
|
44
|
+
- !ruby/object:Gem::Version
|
53
45
|
version: 2.8.0
|
54
46
|
type: :development
|
47
|
+
version_requirements: *id003
|
48
|
+
- !ruby/object:Gem::Dependency
|
49
|
+
name: eventmachine
|
55
50
|
prerelease: false
|
56
|
-
|
57
|
-
none: false
|
58
|
-
requirements:
|
59
|
-
- - ~>
|
60
|
-
- !ruby/object:Gem::Version
|
61
|
-
version: 2.8.0
|
62
|
-
- !ruby/object:Gem::Dependency
|
63
|
-
name: em-synchrony
|
64
|
-
requirement: !ruby/object:Gem::Requirement
|
51
|
+
requirement: &id004 !ruby/object:Gem::Requirement
|
65
52
|
none: false
|
66
|
-
requirements:
|
67
|
-
- -
|
68
|
-
- !ruby/object:Gem::Version
|
69
|
-
version: 1.0.0
|
53
|
+
requirements:
|
54
|
+
- - ">="
|
55
|
+
- !ruby/object:Gem::Version
|
56
|
+
version: 1.0.0.beta.1
|
70
57
|
type: :development
|
58
|
+
version_requirements: *id004
|
59
|
+
- !ruby/object:Gem::Dependency
|
60
|
+
name: em-synchrony
|
71
61
|
prerelease: false
|
72
|
-
|
62
|
+
requirement: &id005 !ruby/object:Gem::Requirement
|
73
63
|
none: false
|
74
|
-
requirements:
|
64
|
+
requirements:
|
75
65
|
- - ~>
|
76
|
-
- !ruby/object:Gem::Version
|
66
|
+
- !ruby/object:Gem::Version
|
77
67
|
version: 1.0.0
|
68
|
+
type: :development
|
69
|
+
version_requirements: *id005
|
78
70
|
description: PostgreSQL asynchronous EventMachine client (ruby-pg) wrapper
|
79
71
|
email: rafal@yeondir.com
|
80
72
|
executables: []
|
73
|
+
|
81
74
|
extensions: []
|
82
|
-
|
75
|
+
|
76
|
+
extra_rdoc_files:
|
83
77
|
- README.rdoc
|
84
78
|
- BENCHMARKS.rdoc
|
85
|
-
files:
|
79
|
+
files:
|
86
80
|
- BENCHMARKS.rdoc
|
81
|
+
- HISTORY.rdoc
|
87
82
|
- README.rdoc
|
88
83
|
- Rakefile
|
89
84
|
- benchmarks/em_pg.rb
|
90
85
|
- em-pg-client.gemspec
|
91
86
|
- lib/em-synchrony/pg.rb
|
92
87
|
- lib/pg/em.rb
|
93
|
-
- spec/
|
88
|
+
- spec/em_devel_client.rb
|
89
|
+
- spec/em_release_client.rb
|
94
90
|
- spec/em_synchrony_client.rb
|
95
91
|
homepage: http://github.com/royaltm/ruby-em-pg-client
|
96
92
|
licenses: []
|
93
|
+
|
97
94
|
post_install_message:
|
98
|
-
rdoc_options:
|
95
|
+
rdoc_options:
|
99
96
|
- --title
|
100
97
|
- em-pg-client
|
101
98
|
- --main
|
102
99
|
- README.rdoc
|
103
|
-
require_paths:
|
100
|
+
require_paths:
|
104
101
|
- lib
|
105
|
-
required_ruby_version: !ruby/object:Gem::Requirement
|
102
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
106
103
|
none: false
|
107
|
-
requirements:
|
108
|
-
- -
|
109
|
-
- !ruby/object:Gem::Version
|
104
|
+
requirements:
|
105
|
+
- - ">="
|
106
|
+
- !ruby/object:Gem::Version
|
110
107
|
version: 1.9.1
|
111
|
-
required_rubygems_version: !ruby/object:Gem::Requirement
|
108
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
112
109
|
none: false
|
113
|
-
requirements:
|
114
|
-
- -
|
115
|
-
- !ruby/object:Gem::Version
|
116
|
-
version:
|
117
|
-
requirements:
|
110
|
+
requirements:
|
111
|
+
- - ">="
|
112
|
+
- !ruby/object:Gem::Version
|
113
|
+
version: "0"
|
114
|
+
requirements:
|
118
115
|
- PostgreSQL server
|
119
116
|
rubyforge_project:
|
120
|
-
rubygems_version: 1.8.
|
117
|
+
rubygems_version: 1.8.17
|
121
118
|
signing_key:
|
122
119
|
specification_version: 3
|
123
120
|
summary: EventMachine PostgreSQL client
|
124
|
-
test_files:
|
125
|
-
- spec/em_client.rb
|
121
|
+
test_files:
|
126
122
|
- spec/em_synchrony_client.rb
|
123
|
+
- spec/em_devel_client.rb
|
124
|
+
- spec/em_release_client.rb
|