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 ADDED
@@ -0,0 +1,9 @@
1
+ 0.1.1
2
+ - added on_reconnect callback
3
+ - docs updated
4
+ - added development dependency for eventmachine >= 1.0.0.beta.1
5
+ - added separate client specs for eventmachine = 0.12.10
6
+ - added error checking to eventmachine specs
7
+
8
+ 0.1.0
9
+ - first release
data/README.rdoc CHANGED
@@ -1,17 +1,17 @@
1
1
  = em-pg-client
2
2
 
3
- Author:: Rafał Michalski (mailto:royaltm75@gmail.com)
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 (ruby-pg)[https://bitbucket.org/ged/ruby-pg]
10
+ based on ruby-pg[https://bitbucket.org/ged/ruby-pg]
11
11
 
12
12
  == FEATURES
13
13
 
14
- * minimal changes to PG::Conncet API
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 only (ActiveRecord or Sequel)
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
- try_query = lambda |&blk| do
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/em_client.rb"
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.0"
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
- # == PostgreSQL EventMachine client
6
- #
7
- # Author:: Rafal Michalski (mailto:royaltm75@gmail.com)
8
- # Licence:: MIT License
9
- #
10
- #
11
- # PG::EM::Client is a wrapper for PG::Connection which (re)defines methods:
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
- # or pass as new() hash argument:
33
- # PG::EM::Client.new database: 'bar', async_autoreconnect: false
52
+ # Certain rules should apply to on_reconnect proc:
34
53
  #
35
- # Otherwise nothing changes in PG::Connect API.
36
- # See PG::Connect docs for arguments to above methods.
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
- # *Warning:*
65
+ # You may pass this proc as +:on_reconnect+ option to PG::EM::Client.new.
39
66
  #
40
- # +async_exec_prepared+ after +async_prepare+ should only be invoked on
41
- # the *same* connection.
42
- # If you are using connection pool, make sure to acquire single connection first.
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
- if key.to_s == 'async_autoreconnect'
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
- #{send_name}(*args)
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
- @client.query('CREATE TABLE foo (id integer,cdate timestamp with time zone,data varchar)') 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
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
- date: 2012-03-29 00:00:00.000000000 Z
13
- dependencies:
14
- - !ruby/object:Gem::Dependency
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
- version_requirements: !ruby/object:Gem::Requirement
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
- version_requirements: !ruby/object:Gem::Requirement
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
- - !ruby/object:Gem::Dependency
35
+ type: :runtime
36
+ version_requirements: *id002
37
+ - !ruby/object:Gem::Dependency
47
38
  name: rspec
48
- requirement: !ruby/object:Gem::Requirement
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
- 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: 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
- version_requirements: !ruby/object:Gem::Requirement
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
- extra_rdoc_files:
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/em_client.rb
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: '0'
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.21
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