pg 0.10.0 → 0.10.1pre209

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,125 +1,22 @@
1
1
  require 'pp'
2
2
  require 'mkmf'
3
3
 
4
+
4
5
  if pgdir = with_config( 'pg' )
5
6
  ENV['PATH'] = "#{pgdir}/bin" + File::PATH_SEPARATOR + ENV['PATH']
6
7
  end
7
8
 
9
+ dir_config 'pg'
8
10
 
9
- ### Turn a version string into a Comparable binary datastructure
10
- def vvec( version )
11
- version.split( '.' ).collect {|i| Integer(i) }.pack( 'N*' )
12
- end
13
-
14
-
15
- if vvec(RUBY_VERSION) < vvec('1.8')
16
- puts 'This library is for ruby-1.8 or higher.'
17
- exit 1
18
- end
19
-
20
- if ENV['CROSS_COMPILING']
21
-
22
- $LDFLAGS << " -L#{CONFIG['libdir']}"
23
-
24
- # Link against all required libraries for static build, if they are available
25
- have_library( 'gdi32', 'CreateDC' ) && append_library( $libs, 'gdi32' )
26
- have_library( 'secur32' ) && append_library( $libs, 'secur32' )
27
- have_library( 'crypto', 'BIO_new' ) && append_library( $libs, 'crypto' )
28
- have_library( 'ssl', 'SSL_new' ) && append_library( $libs, 'ssl' )
29
-
11
+ if pgconfig = ( with_config('pg-config') || with_config('pg_config') || find_executable('pg_config') )
12
+ $stderr.puts "Using config values from %s" % [ pgconfig ]
13
+ $CPPFLAGS << " -I%s" % [ `#{pgconfig} --includedir`.chomp ]
14
+ $LDFLAGS << " -L%s" % [ `#{pgconfig} --libdir`.chomp ]
30
15
  else
31
- pgconfig = with_config( 'pg-config' ) || 'pg_config'
32
- if pgconfig = find_executable( pgconfig )
33
- $CFLAGS << " " + `#{pgconfig} --cflags`.chomp
34
- $CPPFLAGS << " -I%s" % [ `#{pgconfig} --includedir`.chomp ]
35
- $LDFLAGS << " -L%s" % [ `#{pgconfig} --libdir`.chomp ]
36
- end
37
-
38
- # Sort out the universal vs. single-archicture build problems on MacOS X
39
- if RUBY_PLATFORM.include?( 'darwin' )
40
- puts "MacOS X build: fixing architecture flags:"
41
- ruby_archs = Config::CONFIG['CFLAGS'].scan( /-arch (\S+)/ ).flatten
42
- $stderr.puts "Ruby cflags: %p" % [ Config::CONFIG['CFLAGS'] ]
43
-
44
- # Only keep the '-arch <a>' flags present in both the cflags reported
45
- # by pg_config and those that Ruby specifies.
46
- commonflags = nil
47
- if ENV['ARCHFLAGS']
48
- puts " using the value in ARCHFLAGS environment variable (%p)." % [ ENV['ARCHFLAGS'] ]
49
- common_archs = ENV['ARCHFLAGS'].scan( /-arch\s+(\S+)/ ).flatten
50
-
51
- # Warn if the ARCHFLAGS doesn't have at least one architecture in
52
- # common with the running ruby.
53
- if ( (common_archs & ruby_archs).empty? )
54
- $stderr.puts '',
55
- "*** Your ARCHFLAGS setting doesn't seem to contain an architecture in common",
56
- "with the running ruby interpreter (%p vs. %p)" % [ common_archs, ruby_archs ],
57
- "I'll continue anyway, but if it fails, try unsetting ARCHFLAGS."
58
- end
59
-
60
- commonflags = ENV['ARCHFLAGS']
61
- end
62
-
63
- if pgconfig
64
- puts " finding flags common to both Ruby and PostgreSQL..."
65
- archflags = []
66
- pgcflags = `#{pgconfig} --cflags`.chomp
67
- pgarchs = pgcflags.scan( /-arch\s+(\S+)/ ).flatten
68
- pgarchs.each do |arch|
69
- puts " testing for architecture: %p" % [ arch ]
70
- archflags << "-arch #{arch}" if ruby_archs.include?( arch )
71
- end
72
-
73
- if archflags.empty?
74
- $stderr.puts '',
75
- "*** Your PostgreSQL installation doesn't seem to have an architecture " +
76
- "in common with the running ruby interpreter (%p vs. %p)" %
77
- [ pgarchs, ruby_archs ],
78
- "I'll continue anyway, but if it fails, try setting ARCHFLAGS."
79
- else
80
- commonflags = archflags.join(' ')
81
- puts " common arch flags: %s" % [ commonflags ]
82
- end
83
- else
84
- $stderr.puts %{
85
- =========== WARNING ===========
86
-
87
- You are building this extension on OS X without setting the
88
- ARCHFLAGS environment variable, and pg_config wasn't found in
89
- your PATH. If you are seeing this message, that means that the
90
- build will probably fail.
91
-
92
- If it does, you can correct this by either including the path
93
- to 'pg_config' in your PATH or setting the environment variable
94
- ARCHFLAGS to '-arch <arch>' before building.
95
-
96
- For example:
97
- (in bash) $ export PATH=/opt/local/lib/postgresql84/bin:$PATH
98
- $ export ARCHFLAGS='-arch x86_64'
99
- (in tcsh) % set path = ( /opt/local/lib/postgresql84/bin $PATH )
100
- % setenv ARCHFLAGS '-arch x86_64'
101
-
102
- Then try building again.
103
-
104
- ===================================
105
- }.gsub( /^\t+/, ' ' )
106
- end
107
-
108
- if commonflags
109
- $CFLAGS.gsub!( /-arch\s+\S+ /, '' )
110
- $LDFLAGS.gsub!( /-arch\s+\S+ /, '' )
111
- CONFIG['LDSHARED'].gsub!( /-arch\s+\S+ /, '' )
112
-
113
- $CFLAGS << ' ' << commonflags
114
- $LDFLAGS << ' ' << commonflags
115
- CONFIG['LDSHARED'] << ' ' << commonflags
116
- end
117
- end
16
+ $stderr.puts "No pg_config... trying anyway. If building fails, please try again with",
17
+ " --with-pg-config=/path/to/pg_config"
118
18
  end
119
19
 
120
- dir_config 'pg'
121
-
122
-
123
20
  find_header( 'libpq-fe.h' ) or abort "Can't find the 'libpq-fe.h header"
124
21
  find_header( 'libpq/libpq-fs.h' ) or abort "Can't find the 'libpq/libpq-fs.h header"
125
22
 
@@ -135,10 +32,14 @@ have_func 'PQprepare'
135
32
  have_func 'PQexecParams'
136
33
  have_func 'PQescapeString'
137
34
  have_func 'PQescapeStringConn'
35
+ have_func 'PQgetCancel'
138
36
  have_func 'lo_create'
139
37
  have_func 'pg_encoding_to_char'
140
38
  have_func 'PQsetClientEncoding'
141
39
 
40
+ $defs.push( "-DHAVE_ST_NOTIFY_EXTRA" ) if
41
+ have_struct_member 'struct pgNotify', 'extra', 'libpq-fe.h'
42
+
142
43
  # unistd.h confilicts with ruby/win32.h when cross compiling for win32 and ruby 1.9.1
143
44
  have_header 'unistd.h' unless enable_config("static-build")
144
45
 
data/ext/pg.c CHANGED
@@ -9,7 +9,7 @@
9
9
  modified at: Wed Jan 20 16:41:51 1999
10
10
 
11
11
  $Author: ged $
12
- $Date: 2010/11/12 03:39:48 $
12
+ $Date: 2010/12/06 16:45:23 $
13
13
  ************************************************/
14
14
 
15
15
  #include "pg.h"
@@ -23,7 +23,7 @@ static VALUE rb_cPGconn;
23
23
  static VALUE rb_cPGresult;
24
24
  static VALUE rb_ePGError;
25
25
 
26
- static const char *VERSION = "0.10.0";
26
+ static const char *VERSION = "0.10.1";
27
27
 
28
28
 
29
29
  /* The following functions are part of libpq, but not
@@ -2046,7 +2046,7 @@ pgconn_flush(self)
2046
2046
  * conn.cancel() -> String
2047
2047
  *
2048
2048
  * Requests cancellation of the command currently being
2049
- * processed.
2049
+ * processed. (Only implemented in PostgreSQL >= 8.0)
2050
2050
  *
2051
2051
  * Returns +nil+ on success, or a string containing the
2052
2052
  * error message if a failure occurs.
@@ -2054,6 +2054,7 @@ pgconn_flush(self)
2054
2054
  static VALUE
2055
2055
  pgconn_cancel(VALUE self)
2056
2056
  {
2057
+ #ifdef HAVE_PQGETCANCEL
2057
2058
  char errbuf[256];
2058
2059
  PGcancel *cancel;
2059
2060
  VALUE retval;
@@ -2071,6 +2072,9 @@ pgconn_cancel(VALUE self)
2071
2072
 
2072
2073
  PQfreeCancel(cancel);
2073
2074
  return retval;
2075
+ #else
2076
+ rb_notimplement();
2077
+ #endif
2074
2078
  }
2075
2079
 
2076
2080
 
@@ -2136,7 +2140,7 @@ pgconn_wait_for_notify(int argc, VALUE *argv, VALUE self)
2136
2140
  int ret;
2137
2141
  struct timeval timeout;
2138
2142
  struct timeval *ptimeout = NULL;
2139
- VALUE timeout_in, relname = Qnil, be_pid = Qnil;
2143
+ VALUE timeout_in, relname = Qnil, be_pid = Qnil, extra = Qnil;
2140
2144
  double timeout_sec;
2141
2145
  fd_set sd_rset;
2142
2146
 
@@ -2169,10 +2173,13 @@ pgconn_wait_for_notify(int argc, VALUE *argv, VALUE self)
2169
2173
 
2170
2174
  relname = rb_tainted_str_new2( notification->relname );
2171
2175
  be_pid = INT2NUM( notification->be_pid );
2176
+ #ifdef HAVE_ST_NOTIFY_EXTRA
2177
+ extra = rb_str_new2( notification->extra );
2178
+ #endif
2172
2179
  PQfreemem( notification );
2173
2180
 
2174
2181
  if ( rb_block_given_p() )
2175
- rb_yield_splat( rb_ary_new3(2, relname, be_pid) );
2182
+ rb_yield_values( 3, relname, be_pid, extra );
2176
2183
 
2177
2184
  return relname;
2178
2185
  }
data/lib/pg.rb CHANGED
@@ -1,13 +1,17 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
- require 'pathname'
4
3
  require 'rbconfig'
5
4
 
6
5
  # Load the correct version if it's a Windows binary gem
7
6
  if RUBY_PLATFORM =~/(mswin|mingw)/i
8
7
  major_minor = RUBY_VERSION[ /^(\d+\.\d+)/ ] or
9
8
  raise "Oops, can't extract the major/minor version from #{RUBY_VERSION.dump}"
10
- require "#{major_minor}/pg_ext"
9
+
10
+ begin
11
+ require "#{major_minor}/pg_ext"
12
+ rescue LoadError
13
+ require 'pg_ext'
14
+ end
11
15
  else
12
16
  require 'pg_ext'
13
17
  end
data/rake/hg.rb CHANGED
@@ -83,6 +83,15 @@ unless defined?( HG_DOTDIR )
83
83
  return paths
84
84
  end
85
85
 
86
+ ### Return the list of files which are not of status 'clean'
87
+ def get_uncommitted_files
88
+ list = read_command_output( 'hg', 'status', '-n', '--color', 'never' )
89
+ list = list.split( /\n/ )
90
+
91
+ trace "Changed files: %p" % [ list ]
92
+ return list
93
+ end
94
+
86
95
  ### Return the list of files which are of status 'unknown'
87
96
  def get_unknown_files
88
97
  list = read_command_output( 'hg', 'status', '-un', '--color', 'never' )
@@ -149,11 +158,21 @@ unless defined?( HG_DOTDIR )
149
158
 
150
159
  desc "Prepare for a new release"
151
160
  task :prep_release do
161
+ uncommitted_files = get_uncommitted_files()
162
+ unless uncommitted_files.empty?
163
+ log "Uncommitted files:\n",
164
+ *uncommitted_files.map {|fn| " #{fn}\n" }
165
+ ask_for_confirmation( "\nRelease anyway?", true ) do
166
+ log "Okay, releasing with uncommitted versions."
167
+ end
168
+ end
169
+
152
170
  tags = get_tags()
153
171
  rev = get_current_rev()
172
+ pkg_version_tag = "v#{PKG_VERSION}"
154
173
 
155
174
  # Look for a tag for the current release version, and if it exists abort
156
- if tags.include?( PKG_VERSION )
175
+ if tags.include?( pkg_version_tag )
157
176
  error "Version #{PKG_VERSION} already has a tag. Did you mean " +
158
177
  "to increment the version in #{VERSION_FILE}?"
159
178
  fail
@@ -164,8 +183,8 @@ unless defined?( HG_DOTDIR )
164
183
  run 'hg', 'sign'
165
184
 
166
185
  # Tag the current rev
167
- log "Tagging rev #{rev} as #{PKG_VERSION}"
168
- run 'hg', 'tag', PKG_VERSION
186
+ log "Tagging rev #{rev} as #{pkg_version_tag}"
187
+ run 'hg', 'tag', pkg_version_tag
169
188
 
170
189
  # Offer to push
171
190
  Rake::Task['hg:push'].invoke
@@ -229,6 +248,18 @@ unless defined?( HG_DOTDIR )
229
248
  end
230
249
 
231
250
 
251
+ desc "Update to tip"
252
+ task :update do
253
+ run 'hg', 'update'
254
+ end
255
+
256
+
257
+ desc "Clobber all changes (hg up -C)"
258
+ task :update_and_clobber do
259
+ run 'hg', 'update', '-C'
260
+ end
261
+
262
+
232
263
  desc "Check the current code in if tests pass"
233
264
  task :checkin => ['hg:pull', 'hg:newfiles', 'test', COMMIT_MSG_FILE] do
234
265
  targets = get_target_args()
@@ -47,6 +47,7 @@ begin
47
47
  ### Task: spec
48
48
  desc "Run specs"
49
49
  task :spec => 'spec:doc'
50
+ task :specs => :spec
50
51
 
51
52
  namespace :spec do
52
53
  desc "Run rspec every time there's a change to one of the files"
@@ -161,15 +161,18 @@ module PgTestingHelpers
161
161
  datadir = testdir + 'data'
162
162
  pidfile = datadir + 'postmaster.pid'
163
163
  if pidfile.exist? && pid = pidfile.read.chomp.to_i
164
+ $stderr.puts "pidfile (%p) exists: %d" % [ pidfile, pid ]
164
165
  begin
165
166
  Process.kill( 0, pid )
166
167
  rescue Errno::ESRCH
167
- trace "No postmaster running for %s" % [ datadir ]
168
+ $stderr.puts "No postmaster running for %s" % [ datadir ]
168
169
  # Process isn't alive, so don't try to stop it
169
170
  else
170
- trace "Stopping lingering database at PID %d" % [ pid ]
171
+ $stderr.puts "Stopping lingering database at PID %d" % [ pid ]
171
172
  run 'pg_ctl', '-D', datadir.to_s, '-m', 'fast', 'stop'
172
173
  end
174
+ else
175
+ $stderr.puts "No pidfile (%p)" % [ pidfile ]
173
176
  end
174
177
  end
175
178
  end
@@ -196,20 +199,19 @@ module PgTestingHelpers
196
199
  begin
197
200
  unless (@test_pgdata+"postgresql.conf").exist?
198
201
  FileUtils.rm_rf( @test_pgdata, :verbose => $DEBUG )
199
- trace "Running initdb"
202
+ $stderr.puts "Running initdb"
200
203
  log_and_run @logfile, 'initdb', '--no-locale', '-D', @test_pgdata.to_s
201
204
  end
202
205
 
203
206
  trace "Starting postgres"
204
207
  log_and_run @logfile, 'pg_ctl', '-w', '-o', "-k #{@test_directory.to_s.inspect}",
205
208
  '-D', @test_pgdata.to_s, 'start'
209
+ sleep 2
210
+
211
+ $stderr.puts "Creating the test DB"
212
+ log_and_run @logfile, 'psql', '-e', '-c', 'DROP DATABASE IF EXISTS test', 'postgres'
213
+ log_and_run @logfile, 'createdb', '-e', 'test'
206
214
 
207
- if `psql -l` =~ /^\s*test\s/
208
- trace "Dropping the test DB"
209
- log_and_run @logfile, 'dropdb', 'test'
210
- end
211
- trace "Creating the test DB"
212
- log_and_run @logfile, 'createdb', 'test'
213
215
  rescue => err
214
216
  $stderr.puts "%p during test setup: %s" % [ err.class, err.message ]
215
217
  $stderr.puts "See #{@logfile} for details."
@@ -289,6 +289,116 @@ describe PGconn do
289
289
  @conn.exec( 'UNLISTEN woo' )
290
290
  end
291
291
 
292
+ context "under PostgreSQL 9" do
293
+
294
+ before( :each ) do
295
+ pending "only works under PostgreSQL 9" if @conn.server_version < 9_00_00
296
+ end
297
+
298
+ it "calls the block supplied to wait_for_notify with the notify payload if it accepts " +
299
+ "any number of arguments" do
300
+
301
+ @conn.exec( 'ROLLBACK' )
302
+ @conn.exec( 'LISTEN knees' )
303
+
304
+ pid = fork do
305
+ conn = PGconn.connect( @conninfo )
306
+ conn.exec( %Q{NOTIFY knees, 'skirt and boots'} )
307
+ conn.finish
308
+ exit!
309
+ end
310
+
311
+ Process.wait( pid )
312
+
313
+ event, pid, msg = nil
314
+ @conn.wait_for_notify( 10 ) do |*args|
315
+ event, pid, msg = *args
316
+ end
317
+ @conn.exec( 'UNLISTEN woo' )
318
+
319
+ event.should == 'knees'
320
+ pid.should be_a_kind_of( Integer )
321
+ msg.should == 'skirt and boots'
322
+ end
323
+
324
+ it "calls the block supplied to wait_for_notify with the notify payload if it accepts " +
325
+ "two arguments" do
326
+
327
+ @conn.exec( 'ROLLBACK' )
328
+ @conn.exec( 'LISTEN knees' )
329
+
330
+ pid = fork do
331
+ conn = PGconn.connect( @conninfo )
332
+ conn.exec( %Q{NOTIFY knees, 'skirt and boots'} )
333
+ conn.finish
334
+ exit!
335
+ end
336
+
337
+ Process.wait( pid )
338
+
339
+ event, pid, msg = nil
340
+ @conn.wait_for_notify( 10 ) do |arg1, arg2|
341
+ event, pid, msg = arg1, arg2
342
+ end
343
+ @conn.exec( 'UNLISTEN woo' )
344
+
345
+ event.should == 'knees'
346
+ pid.should be_a_kind_of( Integer )
347
+ msg.should be_nil()
348
+ end
349
+
350
+ it "calls the block supplied to wait_for_notify with the notify payload if it " +
351
+ "doesn't accept arguments" do
352
+
353
+ @conn.exec( 'ROLLBACK' )
354
+ @conn.exec( 'LISTEN knees' )
355
+
356
+ pid = fork do
357
+ conn = PGconn.connect( @conninfo )
358
+ conn.exec( %Q{NOTIFY knees, 'skirt and boots'} )
359
+ conn.finish
360
+ exit!
361
+ end
362
+
363
+ Process.wait( pid )
364
+
365
+ notification_received = false
366
+ @conn.wait_for_notify( 10 ) do
367
+ notification_received = true
368
+ end
369
+ @conn.exec( 'UNLISTEN woo' )
370
+
371
+ notification_received.should be_true()
372
+ end
373
+
374
+ it "calls the block supplied to wait_for_notify with the notify payload if it accepts " +
375
+ "three arguments" do
376
+
377
+ @conn.exec( 'ROLLBACK' )
378
+ @conn.exec( 'LISTEN knees' )
379
+
380
+ pid = fork do
381
+ conn = PGconn.connect( @conninfo )
382
+ conn.exec( %Q{NOTIFY knees, 'skirt and boots'} )
383
+ conn.finish
384
+ exit!
385
+ end
386
+
387
+ Process.wait( pid )
388
+
389
+ event, pid, msg = nil
390
+ @conn.wait_for_notify( 10 ) do |arg1, arg2, arg3|
391
+ event, pid, msg = arg1, arg2, arg3
392
+ end
393
+ @conn.exec( 'UNLISTEN woo' )
394
+
395
+ event.should == 'knees'
396
+ pid.should be_a_kind_of( Integer )
397
+ msg.should == 'skirt and boots'
398
+ end
399
+
400
+ end
401
+
292
402
  it "yields the result if block is given to exec" do
293
403
  rval = @conn.exec( "select 1234::int as a union select 5678::int as a" ) do |result|
294
404
  values = []
@@ -343,7 +453,7 @@ describe PGconn do
343
453
  @conn.block( 0.1 )
344
454
  finish = Time.now
345
455
 
346
- (finish - start).should be_close( 0.1, 0.05 )
456
+ (finish - start).should be_within( 0.05 ).of( 0.1 )
347
457
  end
348
458
 
349
459