pg 0.9.0 → 0.10.0

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,9 +1,19 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
3
  require 'pathname'
4
+ require 'rspec'
5
+
6
+
7
+ RSpec.configure do |config|
8
+ ruby_version_vec = RUBY_VERSION.split('.').map {|c| c.to_i }.pack( "N*" )
9
+
10
+ config.mock_with :rspec
11
+ config.filter_run_excluding :ruby_19 => true if ruby_version_vec <= [1,9,1].pack( "N*" )
12
+ end
4
13
 
5
14
  module PgTestingHelpers
6
15
 
16
+
7
17
  # Set some ANSI escape code constants (Shamelessly stolen from Perl's
8
18
  # Term::ANSIColor by Russ Allbery <rra@stanford.edu> and Zenin <zenin@best.com>
9
19
  ANSI_ATTRIBUTES = {
@@ -104,6 +114,8 @@ module PgTestingHelpers
104
114
  end
105
115
 
106
116
 
117
+ NOFORK_PLATFORMS = %w{java}
118
+
107
119
  ### Run the specified command +cmd+ after redirecting stdout and stderr to the specified
108
120
  ### +logpath+, failing if the execution fails.
109
121
  def log_and_run( logpath, *cmd )
@@ -115,16 +127,24 @@ module PgTestingHelpers
115
127
  trace( cmd )
116
128
  end
117
129
 
118
- logfh = File.open( logpath, File::WRONLY|File::CREAT|File::APPEND )
119
- if pid = fork
120
- logfh.close
121
- Process.wait
130
+ # Eliminate the noise of creating/tearing down the database by
131
+ # redirecting STDERR/STDOUT to a logfile if the Ruby interpreter
132
+ # supports fork()
133
+ if NOFORK_PLATFORMS.include?( RUBY_PLATFORM )
134
+ system( *cmd )
122
135
  else
123
- $stdout.reopen( logfh )
124
- $stderr.reopen( $stdout )
125
- exec( *cmd )
126
- $stderr.puts "After the exec()?!??!"
127
- exit!
136
+ logfh = File.open( logpath, File::WRONLY|File::CREAT|File::APPEND )
137
+ if pid = fork
138
+ logfh.close
139
+ else
140
+ $stdout.reopen( logfh )
141
+ $stderr.reopen( $stdout )
142
+ exec( *cmd )
143
+ $stderr.puts "After the exec()?!??!"
144
+ exit!
145
+ end
146
+
147
+ Process.wait( pid )
128
148
  end
129
149
 
130
150
  raise "Command failed: [%s]" % [cmd.join(' ')] unless $?.success?
@@ -147,7 +167,7 @@ module PgTestingHelpers
147
167
  trace "No postmaster running for %s" % [ datadir ]
148
168
  # Process isn't alive, so don't try to stop it
149
169
  else
150
- trace "Stopping lingering database at PID %d"
170
+ trace "Stopping lingering database at PID %d" % [ pid ]
151
171
  run 'pg_ctl', '-D', datadir.to_s, '-m', 'fast', 'stop'
152
172
  end
153
173
  end
@@ -9,33 +9,21 @@ BEGIN {
9
9
  libdir = basedir + 'lib'
10
10
  archlib = libdir + Config::CONFIG['sitearch']
11
11
 
12
+ $LOAD_PATH.unshift( basedir.to_s ) unless $LOAD_PATH.include?( basedir.to_s )
12
13
  $LOAD_PATH.unshift( libdir.to_s ) unless $LOAD_PATH.include?( libdir.to_s )
13
14
  $LOAD_PATH.unshift( archlib.to_s ) unless $LOAD_PATH.include?( archlib.to_s )
14
15
  }
15
16
 
16
- require 'pg'
17
-
18
- require 'rubygems'
19
- require 'spec'
17
+ require 'rspec'
20
18
  require 'spec/lib/helpers'
19
+ require 'pg'
21
20
 
22
- describe "multinationalization support" do
21
+ describe "multinationalization support", :ruby_19 => true do
23
22
  include PgTestingHelpers
24
23
 
25
- RUBY_VERSION_VEC = RUBY_VERSION.split('.').map {|c| c.to_i }.pack("N*")
26
- MIN_RUBY_VERSION_VEC = [1,9,1].pack('N*')
27
-
28
-
29
24
  before( :all ) do
30
- @conn = nil
31
- if RUBY_VERSION_VEC >= MIN_RUBY_VERSION_VEC
32
- @conn = setup_testing_db( "m17n" )
33
- @conn.exec( 'BEGIN' )
34
- end
35
- end
36
-
37
- before( :each ) do
38
- pending "depends on m17n support in Ruby >= 1.9.1" if @conn.nil?
25
+ @conn = setup_testing_db( "m17n" )
26
+ @conn.exec( 'BEGIN' )
39
27
  end
40
28
 
41
29
 
@@ -49,7 +37,7 @@ describe "multinationalization support" do
49
37
  res = conn.exec("VALUES ('#{PGconn.escape_bytea(in_bytes)}'::bytea)", [], 0)
50
38
  out_bytes = PGconn.unescape_bytea(res[0]['column1'])
51
39
  end
52
- out_bytes.should== in_bytes
40
+ out_bytes.should == in_bytes
53
41
  end
54
42
 
55
43
  describe "rubyforge #22925: m17n support" do
@@ -114,17 +102,41 @@ describe "multinationalization support" do
114
102
  res = conn.exec( stmt, [], 0 )
115
103
  out_string = res[0]['column1']
116
104
  end
117
- out_string.should == 'foo'.encode(Encoding::ASCII_8BIT)
105
+ out_string.should == 'foo'.encode( Encoding::ASCII_8BIT )
118
106
  out_string.encoding.should == Encoding::ASCII_8BIT
119
107
  end
120
108
  end
121
109
 
122
- it "should use client encoding for escaped string" do
123
- original = "string to escape".force_encoding("euc-jp")
124
- @conn.set_client_encoding("euc_jp")
125
- escaped = @conn.escape(original)
110
+ it "uses the client encoding for escaped string" do
111
+ original = "string to escape".force_encoding( "euc-jp" )
112
+ @conn.set_client_encoding( "euc_jp" )
113
+ escaped = @conn.escape( original )
126
114
  escaped.encoding.should == Encoding::EUC_JP
127
115
  end
116
+ end
117
+
118
+ describe "Ruby 1.9.x default_internal encoding" do
119
+
120
+ it "honors the Encoding.default_internal if it's set and the synchronous interface is used" do
121
+ @conn.transaction do |txn_conn|
122
+ txn_conn.internal_encoding = Encoding::ISO8859_1
123
+ txn_conn.exec( "CREATE TABLE defaultinternaltest ( foo text )" )
124
+ txn_conn.exec( "INSERT INTO defaultinternaltest VALUES ('Grün und Weiß')" )
125
+ end
126
+
127
+ begin
128
+ prev_encoding = Encoding.default_internal
129
+ Encoding.default_internal = Encoding::UTF_8
130
+
131
+ conn = PGconn.connect( @conninfo )
132
+ conn.internal_encoding.should == Encoding::UTF_8
133
+ res = conn.exec( "SELECT foo FROM defaultinternaltest" )
134
+ res[0]['foo'].encoding.should == Encoding::UTF_8
135
+ ensure
136
+ conn.finish if conn
137
+ Encoding.default_internal = prev_encoding
138
+ end
139
+ end
128
140
 
129
141
  end
130
142
 
@@ -9,15 +9,14 @@ BEGIN {
9
9
  libdir = basedir + 'lib'
10
10
  archlib = libdir + Config::CONFIG['sitearch']
11
11
 
12
+ $LOAD_PATH.unshift( basedir.to_s ) unless $LOAD_PATH.include?( basedir.to_s )
12
13
  $LOAD_PATH.unshift( libdir.to_s ) unless $LOAD_PATH.include?( libdir.to_s )
13
14
  $LOAD_PATH.unshift( archlib.to_s ) unless $LOAD_PATH.include?( archlib.to_s )
14
15
  }
15
16
 
16
- require 'pg'
17
-
18
- require 'rubygems'
19
- require 'spec'
17
+ require 'rspec'
20
18
  require 'spec/lib/helpers'
19
+ require 'pg'
21
20
  require 'timeout'
22
21
 
23
22
  describe PGconn do
@@ -82,27 +81,69 @@ describe PGconn do
82
81
  res[0]['n'].should == '1'
83
82
  end
84
83
 
84
+
85
+ EXPECTED_TRACE_OUTPUT = %{
86
+ To backend> Msg Q
87
+ To backend> "SELECT 1 AS one"
88
+ To backend> Msg complete, length 21
89
+ From backend> T
90
+ From backend (#4)> 28
91
+ From backend (#2)> 1
92
+ From backend> "one"
93
+ From backend (#4)> 0
94
+ From backend (#2)> 0
95
+ From backend (#4)> 23
96
+ From backend (#2)> 4
97
+ From backend (#4)> -1
98
+ From backend (#2)> 0
99
+ From backend> D
100
+ From backend (#4)> 11
101
+ From backend (#2)> 1
102
+ From backend (#4)> 1
103
+ From backend (1)> 1
104
+ From backend> C
105
+ From backend (#4)> 13
106
+ From backend> "SELECT 1"
107
+ From backend> Z
108
+ From backend (#4)> 5
109
+ From backend> Z
110
+ From backend (#4)> 5
111
+ From backend> T
112
+ }.gsub( /^\t{2}/, '' ).lstrip
113
+
85
114
  unless RUBY_PLATFORM =~ /mswin|mingw/
86
115
  it "should trace and untrace client-server communication" do
87
116
  # be careful to explicitly close files so that the
88
117
  # directory can be removed and we don't have to wait for
89
118
  # the GC to run.
90
- expected_trace_file = File.join(Dir.getwd, "spec/data", "expected_trace.out")
91
- expected_trace_data = open(expected_trace_file, 'rb').read
92
- trace_file = open(File.join(@test_directory, "test_trace.out"), 'wb')
93
- @conn.trace(trace_file)
94
- trace_file.close
119
+ trace_file = @test_directory + "test_trace.out"
120
+ trace_io = trace_file.open( 'w', 0600 )
121
+ @conn.trace( trace_io )
122
+ trace_io.close
123
+
95
124
  res = @conn.exec("SELECT 1 AS one")
96
125
  @conn.untrace
126
+
97
127
  res = @conn.exec("SELECT 2 AS two")
98
- trace_file = open(File.join(@test_directory, "test_trace.out"), 'rb')
128
+
99
129
  trace_data = trace_file.read
100
- trace_file.close
101
- trace_data.should == expected_trace_data
130
+
131
+ expected_trace_output = EXPECTED_TRACE_OUTPUT.dup
132
+ # For PostgreSQL < 9.0, the output will be different:
133
+ # -From backend (#4)> 13
134
+ # -From backend> "SELECT 1"
135
+ # +From backend (#4)> 11
136
+ # +From backend> "SELECT"
137
+ if @conn.server_version < 90000
138
+ expected_trace_output.sub!( /From backend \(#4\)> 13/, 'From backend (#4)> 11' )
139
+ expected_trace_output.sub!( /From backend> "SELECT 1"/, 'From backend> "SELECT"' )
140
+ end
141
+
142
+ trace_data.should == expected_trace_output
102
143
  end
103
144
  end
104
145
 
105
- it "should cancel a query" do
146
+ it "allows a query to be cancelled" do
106
147
  error = false
107
148
  @conn.send_query("SELECT pg_sleep(1000)")
108
149
  @conn.cancel
@@ -113,6 +154,25 @@ describe PGconn do
113
154
  error.should == true
114
155
  end
115
156
 
157
+ it "automatically rolls back a transaction started with PGconn#transaction if an exception " +
158
+ "is raised" do
159
+ # abort the per-example transaction so we can test our own
160
+ @conn.exec( 'ROLLBACK' )
161
+
162
+ res = nil
163
+ @conn.exec( "CREATE TABLE pie ( flavor TEXT )" )
164
+
165
+ expect {
166
+ res = @conn.transaction do
167
+ @conn.exec( "INSERT INTO pie VALUES ('rhubarb'), ('cherry'), ('schizophrenia')" )
168
+ raise "Oh noes! All pie is gone!"
169
+ end
170
+ }.to raise_exception( RuntimeError, /all pie is gone/i )
171
+
172
+ res = @conn.exec( "SELECT * FROM pie" )
173
+ res.ntuples.should == 0
174
+ end
175
+
116
176
  it "should not read past the end of a large object" do
117
177
  @conn.transaction do
118
178
  oid = @conn.lo_create( 0 )
@@ -125,16 +185,19 @@ describe PGconn do
125
185
  end
126
186
 
127
187
 
128
- it "should wait for NOTIFY events via select()" do
188
+ it "can wait for NOTIFY events" do
129
189
  @conn.exec( 'ROLLBACK' )
130
190
  @conn.exec( 'LISTEN woo' )
131
191
 
132
192
  pid = fork do
133
- conn = PGconn.connect( @conninfo )
134
- sleep 1
135
- conn.exec( 'NOTIFY woo' )
136
- conn.finish
137
- exit!
193
+ begin
194
+ conn = PGconn.connect( @conninfo )
195
+ sleep 1
196
+ conn.exec( 'NOTIFY woo' )
197
+ ensure
198
+ conn.finish
199
+ exit!
200
+ end
138
201
  end
139
202
 
140
203
  @conn.wait_for_notify( 10 ).should == 'woo'
@@ -143,6 +206,89 @@ describe PGconn do
143
206
  Process.wait( pid )
144
207
  end
145
208
 
209
+ it "calls a block for NOTIFY events if one is given" do
210
+ @conn.exec( 'ROLLBACK' )
211
+ @conn.exec( 'LISTEN woo' )
212
+
213
+ pid = fork do
214
+ begin
215
+ conn = PGconn.connect( @conninfo )
216
+ sleep 1
217
+ conn.exec( 'NOTIFY woo' )
218
+ ensure
219
+ conn.finish
220
+ exit!
221
+ end
222
+ end
223
+
224
+ eventpid = event = nil
225
+ @conn.wait_for_notify( 10 ) {|*args| event, eventpid = args }
226
+ event.should == 'woo'
227
+ eventpid.should be_an( Integer )
228
+
229
+ @conn.exec( 'UNLISTEN woo' )
230
+
231
+ Process.wait( pid )
232
+ end
233
+
234
+ it "doesn't collapse sequential notifications" do
235
+ @conn.exec( 'ROLLBACK' )
236
+ @conn.exec( 'LISTEN woo' )
237
+ @conn.exec( 'LISTEN war' )
238
+ @conn.exec( 'LISTEN woz' )
239
+
240
+ pid = fork do
241
+ begin
242
+ conn = PGconn.connect( @conninfo )
243
+ conn.exec( 'NOTIFY woo' )
244
+ conn.exec( 'NOTIFY war' )
245
+ conn.exec( 'NOTIFY woz' )
246
+ ensure
247
+ conn.finish
248
+ exit!
249
+ end
250
+ end
251
+
252
+ Process.wait( pid )
253
+
254
+ channels = []
255
+ 3.times do
256
+ channels << @conn.wait_for_notify( 2 )
257
+ end
258
+
259
+ channels.should have( 3 ).members
260
+ channels.should include( 'woo', 'war', 'woz' )
261
+
262
+ @conn.exec( 'UNLISTEN woz' )
263
+ @conn.exec( 'UNLISTEN war' )
264
+ @conn.exec( 'UNLISTEN woo' )
265
+ end
266
+
267
+ it "returns notifications which are already in the queue before wait_for_notify is called " +
268
+ "without waiting for the socket to become readable" do
269
+ @conn.exec( 'ROLLBACK' )
270
+ @conn.exec( 'LISTEN woo' )
271
+
272
+ pid = fork do
273
+ begin
274
+ conn = PGconn.connect( @conninfo )
275
+ conn.exec( 'NOTIFY woo' )
276
+ ensure
277
+ conn.finish
278
+ exit!
279
+ end
280
+ end
281
+
282
+ # Wait for the forked child to send the notification
283
+ Process.wait( pid )
284
+
285
+ # Cause the notification to buffer, but not be read yet
286
+ @conn.exec( 'SELECT 1' )
287
+
288
+ @conn.wait_for_notify( 10 ).should == 'woo'
289
+ @conn.exec( 'UNLISTEN woo' )
290
+ end
291
+
146
292
  it "yields the result if block is given to exec" do
147
293
  rval = @conn.exec( "select 1234::int as a union select 5678::int as a" ) do |result|
148
294
  values = []
@@ -9,15 +9,14 @@ BEGIN {
9
9
  libdir = basedir + 'lib'
10
10
  archlib = libdir + Config::CONFIG['sitearch']
11
11
 
12
+ $LOAD_PATH.unshift( basedir.to_s ) unless $LOAD_PATH.include?( basedir.to_s )
12
13
  $LOAD_PATH.unshift( libdir.to_s ) unless $LOAD_PATH.include?( libdir.to_s )
13
14
  $LOAD_PATH.unshift( archlib.to_s ) unless $LOAD_PATH.include?( archlib.to_s )
14
15
  }
15
16
 
16
- require 'pg'
17
-
18
- require 'rubygems'
19
- require 'spec'
17
+ require 'rspec'
20
18
  require 'spec/lib/helpers'
19
+ require 'pg'
21
20
 
22
21
  describe PGresult do
23
22
  include PgTestingHelpers
@@ -206,8 +205,6 @@ describe PGresult do
206
205
  res.ftablecol(1).should == 0 # and it shouldn't raise an exception, either
207
206
  end
208
207
 
209
-
210
-
211
208
  after( :each ) do
212
209
  @conn.exec( 'ROLLBACK' )
213
210
  end
metadata CHANGED
@@ -1,15 +1,42 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pg
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.9.0
4
+ hash: 55
5
+ prerelease: false
6
+ segments:
7
+ - 0
8
+ - 10
9
+ - 0
10
+ version: 0.10.0
5
11
  platform: ruby
6
12
  authors:
13
+ - Jeff Davis
7
14
  - Michael Granger
8
15
  autorequire:
9
16
  bindir: bin
10
- cert_chain: []
17
+ cert_chain:
18
+ - |
19
+ -----BEGIN CERTIFICATE-----
20
+ MIIDLDCCAhSgAwIBAgIBADANBgkqhkiG9w0BAQUFADA8MQwwCgYDVQQDDANnZWQx
21
+ FzAVBgoJkiaJk/IsZAEZFgdfYWVyaWVfMRMwEQYKCZImiZPyLGQBGRYDb3JnMB4X
22
+ DTEwMDkxNjE0NDg1MVoXDTExMDkxNjE0NDg1MVowPDEMMAoGA1UEAwwDZ2VkMRcw
23
+ FQYKCZImiZPyLGQBGRYHX2FlcmllXzETMBEGCgmSJomT8ixkARkWA29yZzCCASIw
24
+ DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALy//BFxC1f/cPSnwtJBWoFiFrir
25
+ h7RicI+joq/ocVXQqI4TDWPyF/8tqkvt+rD99X9qs2YeR8CU/YiIpLWrQOYST70J
26
+ vDn7Uvhb2muFVqq6+vobeTkILBEO6pionWDG8jSbo3qKm1RjKJDwg9p4wNKhPuu8
27
+ KGue/BFb67KflqyApPmPeb3Vdd9clspzqeFqp7cUBMEpFS6LWxy4Gk+qvFFJBJLB
28
+ BUHE/LZVJMVzfpC5Uq+QmY7B+FH/QqNndn3tOHgsPadLTNimuB1sCuL1a4z3Pepd
29
+ TeLBEFmEao5Dk3K/Q8o8vlbIB/jBDTUx6Djbgxw77909x6gI9doU4LD5XMcCAwEA
30
+ AaM5MDcwCQYDVR0TBAIwADALBgNVHQ8EBAMCBLAwHQYDVR0OBBYEFJeoGkOr9l4B
31
+ +saMkW/ZXT4UeSvVMA0GCSqGSIb3DQEBBQUAA4IBAQBG2KObvYI2eHyyBUJSJ3jN
32
+ vEnU3d60znAXbrSd2qb3r1lY1EPDD3bcy0MggCfGdg3Xu54z21oqyIdk8uGtWBPL
33
+ HIa9EgfFGSUEgvcIvaYqiN4jTUtidfEFw+Ltjs8AP9gWgSIYS6Gr38V0WGFFNzIH
34
+ aOD2wmu9oo/RffW4hS/8GuvfMzcw7CQ355wFR4KB/nyze+EsZ1Y5DerCAagMVuDQ
35
+ U0BLmWDFzPGGWlPeQCrYHCr+AcJz+NRnaHCKLZdSKj/RHuTOt+gblRex8FAh8NeA
36
+ cmlhXe46pZNJgWKbxZah85jIjx95hR8vOI+NAM5iH9kOqK13DrxacTKPhqj5PjwF
37
+ -----END CERTIFICATE-----
11
38
 
12
- date: 2010-02-28 00:00:00 -08:00
39
+ date: 2010-12-01 00:00:00 -08:00
13
40
  default_executable:
14
41
  dependencies: []
15
42
 
@@ -17,6 +44,7 @@ description: |-
17
44
  This is the extension library to access a PostgreSQL database from Ruby.
18
45
  This library works with PostgreSQL 7.4 and later.
19
46
  email:
47
+ - ruby-pg@j-davis.com
20
48
  - ged@FaerieMUD.org
21
49
  executables: []
22
50
 
@@ -25,11 +53,17 @@ extensions:
25
53
  extra_rdoc_files:
26
54
  - ChangeLog
27
55
  - README
56
+ - README.ja
57
+ - README.OS_X
58
+ - README.windows
28
59
  - LICENSE
29
60
  files:
30
61
  - Rakefile
31
62
  - ChangeLog
32
63
  - README
64
+ - README.ja
65
+ - README.OS_X
66
+ - README.windows
33
67
  - LICENSE
34
68
  - spec/m17n_spec.rb
35
69
  - spec/pgconn_spec.rb
@@ -43,12 +77,12 @@ files:
43
77
  - ext/extconf.rb
44
78
  - rake/191_compat.rb
45
79
  - rake/dependencies.rb
80
+ - rake/documentation.rb
46
81
  - rake/helpers.rb
47
82
  - rake/hg.rb
48
83
  - rake/manual.rb
49
84
  - rake/packaging.rb
50
85
  - rake/publishing.rb
51
- - rake/rdoc.rb
52
86
  - rake/style.rb
53
87
  - rake/svn.rb
54
88
  - rake/testing.rb
@@ -60,42 +94,49 @@ files:
60
94
  - ./BSD
61
95
  - ./Contributors
62
96
  - Rakefile.local
97
+ - spec/data/expected_trace.out
98
+ - spec/data/random_binary_data
63
99
  has_rdoc: true
64
100
  homepage: http://bitbucket.org/ged/ruby-pg/
65
- licenses: []
66
-
101
+ licenses:
102
+ - Ruby
103
+ - GPL
104
+ - BSD
67
105
  post_install_message:
68
106
  rdoc_options:
69
- - -w
70
- - "4"
71
- - -HN
72
- - -i
107
+ - --tab-width=4
108
+ - --show-hash
109
+ - --include
73
110
  - .
74
- - -m
75
- - README
76
- - -t
77
- - pg
78
- - -W
79
- - http://bitbucket.org/ged/ruby-pg/browser/
111
+ - --main=README
112
+ - --title=pg
80
113
  require_paths:
81
114
  - lib
82
115
  - ext
83
116
  required_ruby_version: !ruby/object:Gem::Requirement
117
+ none: false
84
118
  requirements:
85
119
  - - ">="
86
120
  - !ruby/object:Gem::Version
87
- version: "0"
88
- version:
121
+ hash: 57
122
+ segments:
123
+ - 1
124
+ - 8
125
+ - 7
126
+ version: 1.8.7
89
127
  required_rubygems_version: !ruby/object:Gem::Requirement
128
+ none: false
90
129
  requirements:
91
130
  - - ">="
92
131
  - !ruby/object:Gem::Version
132
+ hash: 3
133
+ segments:
134
+ - 0
93
135
  version: "0"
94
- version:
95
136
  requirements:
96
137
  - PostgreSQL >=7.4
97
138
  rubyforge_project:
98
- rubygems_version: 1.3.5
139
+ rubygems_version: 1.3.7
99
140
  signing_key:
100
141
  specification_version: 3
101
142
  summary: A Ruby interface to the PostgreSQL RDBMS