em-pg-client 0.2.0 → 0.2.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.
@@ -1,3 +1,8 @@
1
+ 0.2.1
2
+ - support for pg >= 0.14 native PG::Result#check
3
+ - support for pg >= 0.14 native PG::Connection#set_default_encoding
4
+ - fix: connection option Hash argument was modified by Client.new and Client.async_connect
5
+
1
6
  0.2.0
2
7
  - disabled async_autoreconnect by default unless on_autoreconnect is set
3
8
  - async_connect sets #internal_encoding to Encoding.default_internal
@@ -43,8 +43,8 @@ RDBMS. It is based on ruby-pg[https://bitbucket.org/ged/ruby-pg].
43
43
 
44
44
  == REQUIREMENTS
45
45
 
46
- * ruby >= 1.9 (tested: 1.9.3-p194, 1.9.2-p320, 1.9.2-p280, 1.9.1-p378)
47
- * https://bitbucket.org/ged/ruby-pg >= 0.13
46
+ * ruby >= 1.9 (tested: 1.9.3-p194, 1.9.2-p320, 1.9.1-p378)
47
+ * https://bitbucket.org/ged/ruby-pg >= 0.13.2 (>= 0.14 recommended)
48
48
  * PostgreSQL[http://www.postgresql.org/ftp/source/] RDBMS >= 8.3
49
49
  * http://rubyeventmachine.com >= 0.12.10
50
50
  * (optional) EM-Synchrony[https://github.com/igrigorik/em-synchrony]
@@ -56,9 +56,9 @@ RDBMS. It is based on ruby-pg[https://bitbucket.org/ged/ruby-pg].
56
56
  ==== Gemfile
57
57
 
58
58
  # eventmachine
59
- gem "em-pg-client", "~> 0.2.0", :require => 'pg/em'
59
+ gem "em-pg-client", "~> 0.2.1", :require => 'pg/em'
60
60
  # em-synchrony
61
- gem "em-pg-client", "~> 0.2.0", :require => ['pg/em', 'em-synchrony/pg']
61
+ gem "em-pg-client", "~> 0.2.1", :require => ['pg/em', 'em-synchrony/pg']
62
62
 
63
63
  ==== Github
64
64
 
data/Rakefile CHANGED
@@ -8,8 +8,10 @@ desc "Run spec tests"
8
8
  task :test, [:which] do |t, args|
9
9
  args.with_defaults(:which => 'safe')
10
10
 
11
- env_unix_socket = {'PGDATABASE' => 'test', 'PGHOST' => '/tmp'}
12
- env_tcpip = {'PGDATABASE' => 'test', 'PGHOST' => 'localhost'}
11
+ env_common = {'PGDATABASE' => 'test'}
12
+ env_pg_013 = {'EM_PG_CLIENT_TEST_PG_VERSION' => '= 0.13.2'}
13
+ env_unix_socket = env_common.merge('PGHOST' => '/tmp')
14
+ env_tcpip = env_common.merge('PGHOST' => 'localhost')
13
15
 
14
16
  puts "WARNING: The test needs to be run with an available local PostgreSQL server"
15
17
 
@@ -21,10 +23,13 @@ task :test, [:which] do |t, args|
21
23
  ].each do |spec|
22
24
  sh env_unix_socket, "rspec #{spec}"
23
25
  sh env_tcpip, "rspec #{spec}"
26
+ sh env_pg_013.merge(env_unix_socket), "rspec #{spec}"
27
+ sh env_pg_013.merge(env_tcpip), "rspec #{spec}"
24
28
  end
25
29
  end
26
30
 
27
31
  if %w[all unsafe dangerous autoreconnect].include? args[:which]
32
+ raise "Set PGDATA environment variable before running the autoreconnect tests." unless ENV['PGDATA']
28
33
  %w[
29
34
  spec/em_client_autoreconnect.rb
30
35
  spec/em_synchrony_client_autoreconnect.rb
@@ -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.2.0"
5
+ s.version = "0.2.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"
@@ -13,34 +13,6 @@ end
13
13
 
14
14
  module PG
15
15
 
16
- class Result
17
- class << self
18
- unless method_defined? :check_result
19
- # pg_check_result is internal ext function. I wish it was rubified.
20
- # https://bitbucket.org/ged/ruby-pg/issue/123/rubify-pg_check_result
21
- def check_result(connection, result)
22
- if result.nil?
23
- if (error_message = connection.error_message)
24
- error = PG::Error.new(error_message)
25
- end
26
- else
27
- case result.result_status
28
- when PG::PGRES_BAD_RESPONSE,
29
- PG::PGRES_FATAL_ERROR,
30
- PG::PGRES_NONFATAL_ERROR
31
- error = PG::Error.new(result.error_message)
32
- error.instance_variable_set('@result', result)
33
- end
34
- end
35
- if error
36
- error.instance_variable_set('@connection', connection)
37
- raise error
38
- end
39
- end
40
- end
41
- end
42
- end
43
-
44
16
  module EM
45
17
  class FeaturedDeferrable < ::EM::DefaultDeferrable
46
18
  def initialize(&blk)
@@ -215,8 +187,12 @@ module PG
215
187
  @client.consume_input
216
188
  until @client.is_busy
217
189
  if (single_result = @client.get_result).nil?
218
- result = @last_result
219
- Result.check_result(@client, result)
190
+ if (result = @last_result).nil?
191
+ error = PG::Error.new(@client.error_message)
192
+ error.instance_variable_set(:@connection, @client)
193
+ raise error
194
+ end
195
+ result.check
220
196
  detach
221
197
  @timer.cancel if @timer
222
198
  break
@@ -283,7 +259,7 @@ module PG
283
259
  when PG::PGRES_POLLING_OK, PG::PGRES_POLLING_FAILED
284
260
  @timer.cancel if @timer
285
261
  detach
286
- success = @deferrable.protect_and_succeed do
262
+ @deferrable.protect_and_succeed do
287
263
  unless @client.status == PG::CONNECTION_OK
288
264
  begin
289
265
  raise PG::Error, @client.error_message
@@ -292,20 +268,14 @@ module PG
292
268
  end
293
269
  end
294
270
  # mimic blocking connect behavior
295
- unless Encoding.default_internal.nil? || reconnecting?
296
- begin
297
- @client.internal_encoding = Encoding.default_internal
298
- rescue EncodingError
299
- warn "warning: Failed to set the default_internal encoding to #{Encoding.default_internal}: '#{@client.error_message}'"
300
- end
301
- end
271
+ @client.set_default_encoding unless reconnecting?
302
272
  @client
303
273
  end
304
274
  end
305
275
  end
306
276
  end
307
277
 
308
- def self.parse_async_args(*args)
278
+ def self.parse_async_args(args)
309
279
  async_args = {
310
280
  :@async_autoreconnect => nil,
311
281
  :@connect_timeout => 0,
@@ -314,7 +284,7 @@ module PG
314
284
  :@async_command_aborted => false,
315
285
  }
316
286
  if args.last.is_a? Hash
317
- args.last.reject! do |key, value|
287
+ args[-1] = args.last.reject do |key, value|
318
288
  case key.to_s
319
289
  when 'async_autoreconnect'
320
290
  async_args[:@async_autoreconnect] = !!value
@@ -353,7 +323,7 @@ module PG
353
323
  # +client_encoding+ *will* be set for you according to Encoding.default_internal.
354
324
  def self.async_connect(*args, &blk)
355
325
  df = PG::EM::FeaturedDeferrable.new(&blk)
356
- async_args = parse_async_args(*args)
326
+ async_args = parse_async_args(args)
357
327
  conn = df.protect { connect_start(*args) }
358
328
  if conn
359
329
  async_args.each {|k, v| conn.instance_variable_set(k, v) }
@@ -393,7 +363,7 @@ module PG
393
363
  # +em-synchrony+ version *will* do set +client_encoding+ for you according to
394
364
  # Encoding.default_internal.
395
365
  def initialize(*args)
396
- Client.parse_async_args(*args).each {|k, v| self.instance_variable_set(k, v) }
366
+ Client.parse_async_args(args).each {|k, v| self.instance_variable_set(k, v) }
397
367
  super(*args)
398
368
  end
399
369
 
@@ -476,6 +446,48 @@ module PG
476
446
 
477
447
  alias_method :query, :exec
478
448
  alias_method :async_query, :async_exec
449
+
450
+ # support for pg < 0.14.0
451
+ unless method_defined? :set_default_encoding
452
+ def set_default_encoding
453
+ unless Encoding.default_internal.nil?
454
+ self.internal_encoding = Encoding.default_internal
455
+ end
456
+ rescue EncodingError
457
+ warn "warning: Failed to set the default_internal encoding to #{Encoding.default_internal}: '#{self.error_message}'"
458
+ Encoding.default_internal
459
+ end
460
+ end
461
+
462
+ end
463
+ end
464
+
465
+ # support for pg < 0.14.0
466
+ unless Result.method_defined? :check
467
+ class Result
468
+ def check
469
+ case result_status
470
+ when PG::PGRES_BAD_RESPONSE,
471
+ PG::PGRES_FATAL_ERROR,
472
+ PG::PGRES_NONFATAL_ERROR
473
+ error = PG::Error.new(error_message)
474
+ error.instance_variable_set(:@result, self)
475
+ error.instance_variable_set(:@connection, @connection)
476
+ raise error
477
+ end
478
+ end
479
+ alias_method :check_result, :check
480
+ end
481
+
482
+ module EM
483
+ class Client < PG::Connection
484
+ def get_result(&blk)
485
+ result = super(&blk)
486
+ result.instance_variable_set(:@connection, self) unless block_given?
487
+ result
488
+ end
489
+ end
479
490
  end
480
491
  end
492
+
481
493
  end
@@ -19,6 +19,14 @@ end
19
19
  describe 'em-pg default autoreconnect' do
20
20
  include_context 'em-pg common'
21
21
 
22
+ it "should not have modified argument Hash" do
23
+ begin
24
+ @options.should eq(async_autoreconnect: true)
25
+ ensure
26
+ EM.stop
27
+ end
28
+ end
29
+
22
30
  it "should get database size using query" do
23
31
  @tested_proc.call
24
32
  end
@@ -50,7 +58,8 @@ describe 'em-pg default autoreconnect' do
50
58
  EM.stop
51
59
  end.should be_a_kind_of ::EM::DefaultDeferrable
52
60
  end
53
- @client = PG::EM::Client.new(async_autoreconnect: true)
61
+ @options = {async_autoreconnect: true}
62
+ @client = PG::EM::Client.new(@options)
54
63
  @client.set_notice_processor {|msg| puts "warning from pgsql: #{msg.to_s.chomp.inspect}"}
55
64
  end
56
65
  end
@@ -58,6 +67,14 @@ end
58
67
  describe 'em-pg autoreconnect with on_autoreconnect' do
59
68
  include_context 'em-pg common'
60
69
 
70
+ it "should not have modified argument Hash" do
71
+ begin
72
+ @options.should eq(on_autoreconnect: @on_autoreconnect)
73
+ ensure
74
+ EM.stop
75
+ end
76
+ end
77
+
61
78
  it "should get database size using prepared statement"do
62
79
  @tested_proc.call
63
80
  end
@@ -76,12 +93,13 @@ describe 'em-pg autoreconnect with on_autoreconnect' do
76
93
  EM.stop
77
94
  end.should be_a_kind_of ::EM::DefaultDeferrable
78
95
  end
79
- on_autoreconnect = proc do |client, ex|
96
+ @on_autoreconnect = proc do |client, ex|
80
97
  df = client.prepare('get_db_size', 'SELECT pg_database_size(current_database());')
81
98
  df.should be_a_kind_of ::EM::DefaultDeferrable
82
99
  df
83
100
  end
84
- @client = PG::EM::Client.new(on_autoreconnect: on_autoreconnect)
101
+ @options = {on_autoreconnect: @on_autoreconnect}
102
+ @client = PG::EM::Client.new(@options)
85
103
  @client.set_notice_processor {|msg| puts "warning from pgsql: #{msg.to_s.chomp.inspect}"}
86
104
  @client.prepare('get_db_size', 'SELECT pg_database_size(current_database());')
87
105
  end
@@ -68,7 +68,7 @@ shared_context 'em-pg common before' do
68
68
  @client.close
69
69
  end
70
70
 
71
- it "should be a client" do
71
+ it "should be a client #{PG::VERSION}" do
72
72
  ensure_em_stop do
73
73
  @client.should be_an_instance_of described_class
74
74
  end
@@ -90,21 +90,27 @@ shared_context 'em-pg common before' do
90
90
  it "should set async_autoreconnect according to on_autoreconnect" do
91
91
  ensure_em_stop do
92
92
  on_autoreconnect = proc {|c, e| false }
93
- async_args = described_class.parse_async_args
93
+ async_args = described_class.parse_async_args([])
94
94
  async_args.should be_an_instance_of Hash
95
95
  async_args[:@on_autoreconnect].should be_nil
96
96
  async_args[:@async_autoreconnect].should be_false
97
- async_args = described_class.parse_async_args(on_autoreconnect: on_autoreconnect)
97
+ args = [on_autoreconnect: on_autoreconnect]
98
+ async_args = described_class.parse_async_args(args)
99
+ args.should eq [{}]
98
100
  async_args.should be_an_instance_of Hash
99
101
  async_args[:@on_autoreconnect].should be on_autoreconnect
100
102
  async_args[:@async_autoreconnect].should be_true
101
- async_args = described_class.parse_async_args(async_autoreconnect: false,
102
- on_autoreconnect: on_autoreconnect)
103
+ args = [async_autoreconnect: false,
104
+ on_autoreconnect: on_autoreconnect]
105
+ async_args = described_class.parse_async_args(args)
106
+ args.should eq [{}]
103
107
  async_args.should be_an_instance_of Hash
104
108
  async_args[:@on_autoreconnect].should be on_autoreconnect
105
109
  async_args[:@async_autoreconnect].should be_false
106
- async_args = described_class.parse_async_args(on_autoreconnect: on_autoreconnect,
107
- async_autoreconnect: false)
110
+ args = [on_autoreconnect: on_autoreconnect,
111
+ async_autoreconnect: false]
112
+ async_args = described_class.parse_async_args(args)
113
+ args.should eq [{}]
108
114
  async_args.should be_an_instance_of Hash
109
115
  async_args[:@on_autoreconnect].should be on_autoreconnect
110
116
  async_args[:@async_autoreconnect].should be_false
@@ -1,5 +1,6 @@
1
1
  $:.unshift "lib"
2
2
  gem 'eventmachine', '>= 1.0.0.beta.1'
3
+ gem 'pg', ENV['EM_PG_CLIENT_TEST_PG_VERSION']
3
4
  require 'date'
4
5
  require 'eventmachine'
5
6
  require 'pg/em'
@@ -1,5 +1,6 @@
1
1
  $:.unshift "lib"
2
2
  gem 'eventmachine', '= 0.12.10'
3
+ gem 'pg', ENV['EM_PG_CLIENT_TEST_PG_VERSION']
3
4
  require 'date'
4
5
  require 'eventmachine'
5
6
  require 'pg/em'
@@ -1,11 +1,12 @@
1
1
  $:.unshift "lib"
2
+ gem 'pg', ENV['EM_PG_CLIENT_TEST_PG_VERSION']
2
3
  require 'date'
3
4
  require 'em-synchrony'
4
5
  require 'em-synchrony/pg'
5
6
 
6
7
  describe PG::EM::Client do
7
8
 
8
- it "should be client" do
9
+ it "should be client #{PG::VERSION}" do
9
10
  @client.should be_an_instance_of described_class
10
11
  end
11
12
 
@@ -22,6 +22,10 @@ end
22
22
  describe 'em-synchrony-pg default autoreconnect' do
23
23
  include_context 'em-synchrony-pg common'
24
24
 
25
+ it "should not have modified argument Hash" do
26
+ @options.should eq(async_autoreconnect: true)
27
+ end
28
+
25
29
  it "should get database size using query" do
26
30
  @tested_proc.call
27
31
  end
@@ -51,7 +55,8 @@ describe 'em-synchrony-pg default autoreconnect' do
51
55
  result[0]['pg_database_size'].to_i.should be > 0
52
56
  end
53
57
  end
54
- @client = PG::EM::Client.new(async_autoreconnect: true)
58
+ @options = {async_autoreconnect: true}
59
+ @client = PG::EM::Client.new(@options)
55
60
  @client.set_notice_processor {|msg| puts "warning from pgsql: #{msg.to_s.chomp.inspect}"}
56
61
  end
57
62
  end
@@ -59,6 +64,10 @@ end
59
64
  describe 'em-synchrony-pg autoreconnect with on_autoreconnect' do
60
65
  include_context 'em-synchrony-pg common'
61
66
 
67
+ it "should not have modified argument Hash" do
68
+ @options.should eq(on_autoreconnect: @on_autoreconnect)
69
+ end
70
+
62
71
  it "should get database size using prepared statement" do
63
72
  @tested_proc.call
64
73
  end
@@ -76,12 +85,13 @@ describe 'em-synchrony-pg autoreconnect with on_autoreconnect' do
76
85
  result[0]['pg_database_size'].to_i.should be > 0
77
86
  end
78
87
  end
79
- on_autoreconnect = proc do |client, ex|
88
+ @on_autoreconnect = proc do |client, ex|
80
89
  client.prepare('get_db_size', 'SELECT pg_database_size(current_database());')
81
90
  end
82
- @client = PG::EM::Client.new(on_autoreconnect: on_autoreconnect)
91
+ @options = {on_autoreconnect: @on_autoreconnect}
92
+ @client = PG::EM::Client.new(@options)
83
93
  @client.set_notice_processor {|msg| puts "warning from pgsql: #{msg.to_s.chomp.inspect}"}
84
- on_autoreconnect.call @client
94
+ @on_autoreconnect.call @client
85
95
  end
86
96
  end
87
97
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: em-pg-client
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.2.1
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,11 +9,11 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-05-08 00:00:00.000000000 Z
12
+ date: 2012-09-07 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: pg
16
- requirement: !ruby/object:Gem::Requirement
16
+ requirement: &244130120 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ! '>='
@@ -21,15 +21,10 @@ dependencies:
21
21
  version: 0.13.2
22
22
  type: :runtime
23
23
  prerelease: false
24
- version_requirements: !ruby/object:Gem::Requirement
25
- none: false
26
- requirements:
27
- - - ! '>='
28
- - !ruby/object:Gem::Version
29
- version: 0.13.2
24
+ version_requirements: *244130120
30
25
  - !ruby/object:Gem::Dependency
31
26
  name: eventmachine
32
- requirement: !ruby/object:Gem::Requirement
27
+ requirement: &244129580 !ruby/object:Gem::Requirement
33
28
  none: false
34
29
  requirements:
35
30
  - - ! '>='
@@ -37,15 +32,10 @@ dependencies:
37
32
  version: 0.12.10
38
33
  type: :runtime
39
34
  prerelease: false
40
- version_requirements: !ruby/object:Gem::Requirement
41
- none: false
42
- requirements:
43
- - - ! '>='
44
- - !ruby/object:Gem::Version
45
- version: 0.12.10
35
+ version_requirements: *244129580
46
36
  - !ruby/object:Gem::Dependency
47
37
  name: rspec
48
- requirement: !ruby/object:Gem::Requirement
38
+ requirement: &244128480 !ruby/object:Gem::Requirement
49
39
  none: false
50
40
  requirements:
51
41
  - - ~>
@@ -53,15 +43,10 @@ dependencies:
53
43
  version: 2.8.0
54
44
  type: :development
55
45
  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
46
+ version_requirements: *244128480
62
47
  - !ruby/object:Gem::Dependency
63
48
  name: eventmachine
64
- requirement: !ruby/object:Gem::Requirement
49
+ requirement: &244127700 !ruby/object:Gem::Requirement
65
50
  none: false
66
51
  requirements:
67
52
  - - ! '>='
@@ -69,15 +54,10 @@ dependencies:
69
54
  version: 1.0.0.beta.1
70
55
  type: :development
71
56
  prerelease: false
72
- version_requirements: !ruby/object:Gem::Requirement
73
- none: false
74
- requirements:
75
- - - ! '>='
76
- - !ruby/object:Gem::Version
77
- version: 1.0.0.beta.1
57
+ version_requirements: *244127700
78
58
  - !ruby/object:Gem::Dependency
79
59
  name: em-synchrony
80
- requirement: !ruby/object:Gem::Requirement
60
+ requirement: &244126900 !ruby/object:Gem::Requirement
81
61
  none: false
82
62
  requirements:
83
63
  - - ~>
@@ -85,12 +65,7 @@ dependencies:
85
65
  version: 1.0.0
86
66
  type: :development
87
67
  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
68
+ version_requirements: *244126900
94
69
  description: PostgreSQL asynchronous EventMachine client, based on pg interface (PG::Connection)
95
70
  email: rafal@yeondir.com
96
71
  executables: []
@@ -138,7 +113,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
138
113
  requirements:
139
114
  - PostgreSQL server
140
115
  rubyforge_project:
141
- rubygems_version: 1.8.23
116
+ rubygems_version: 1.8.17
142
117
  signing_key:
143
118
  specification_version: 3
144
119
  summary: EventMachine PostgreSQL client