pg 0.11.0-x86-mingw32 → 0.12.0-x86-mingw32

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.
Files changed (57) hide show
  1. data/.gemtest +0 -0
  2. data/ChangeLog +1647 -462
  3. data/Contributors.rdoc +39 -0
  4. data/History.rdoc +61 -0
  5. data/Manifest.txt +43 -0
  6. data/README.OS_X.rdoc +68 -0
  7. data/README.ja.rdoc +7 -0
  8. data/{README → README.rdoc} +38 -18
  9. data/{README.windows → README.windows.rdoc} +23 -31
  10. data/Rakefile +104 -318
  11. data/Rakefile.cross +234 -0
  12. data/ext/compat.c +2 -2
  13. data/ext/extconf.rb +10 -2
  14. data/ext/pg.c +223 -43
  15. data/ext/vc/pg.sln +26 -0
  16. data/ext/vc/pg_18/pg.vcproj +216 -0
  17. data/ext/vc/pg_19/pg_19.vcproj +209 -0
  18. data/lib/1.8/pg_ext.so +0 -0
  19. data/lib/1.9/pg_ext.so +0 -0
  20. data/lib/pg.rb +5 -7
  21. data/misc/openssl-pg-segfault.rb +31 -0
  22. data/sample/async_api.rb +109 -0
  23. data/sample/async_copyto.rb +39 -0
  24. data/sample/copyfrom.rb +81 -0
  25. data/sample/copyto.rb +19 -0
  26. data/sample/cursor.rb +21 -0
  27. data/sample/losample.rb +69 -0
  28. data/sample/notify_wait.rb +43 -0
  29. data/sample/psql.rb +1181 -0
  30. data/sample/psqlHelp.rb +158 -0
  31. data/sample/test1.rb +60 -0
  32. data/sample/test2.rb +44 -0
  33. data/sample/test4.rb +71 -0
  34. data/sample/test_binary_values.rb +35 -0
  35. data/spec/lib/helpers.rb +6 -4
  36. data/spec/m17n_spec.rb +2 -2
  37. data/spec/pgconn_spec.rb +51 -6
  38. data/spec/pgresult_spec.rb +30 -4
  39. metadata +147 -86
  40. data.tar.gz.sig +0 -3
  41. data/Contributors +0 -32
  42. data/README.OS_X +0 -19
  43. data/README.ja +0 -183
  44. data/Rakefile.local +0 -312
  45. data/rake/191_compat.rb +0 -26
  46. data/rake/dependencies.rb +0 -76
  47. data/rake/documentation.rb +0 -123
  48. data/rake/helpers.rb +0 -502
  49. data/rake/hg.rb +0 -318
  50. data/rake/manual.rb +0 -787
  51. data/rake/packaging.rb +0 -129
  52. data/rake/publishing.rb +0 -341
  53. data/rake/style.rb +0 -62
  54. data/rake/svn.rb +0 -668
  55. data/rake/testing.rb +0 -152
  56. data/rake/verifytask.rb +0 -64
  57. metadata.gz.sig +0 -3
Binary file
Binary file
data/lib/pg.rb CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  begin
4
4
  require 'pg_ext'
5
- rescue LoadError => err
5
+ rescue LoadError
6
6
  # If it's a Windows binary gem, try the <major>.<minor> subdirectory
7
7
  if RUBY_PLATFORM =~/(mswin|mingw)/i
8
8
  major_minor = RUBY_VERSION[ /^(\d+\.\d+)/ ] or
@@ -14,7 +14,8 @@ rescue LoadError => err
14
14
 
15
15
  end
16
16
 
17
- ### The PG connection class.
17
+ #--
18
+ # The PG connection class.
18
19
  class PGconn
19
20
 
20
21
  # The order the options are passed to the ::connect method.
@@ -22,16 +23,13 @@ class PGconn
22
23
 
23
24
 
24
25
  ### Quote the given +value+ for use in a connection-parameter string.
25
- ### @param [String] value the option value to be quoted.
26
- ### @return [String]
27
26
  def self::quote_connstr( value )
28
27
  return "'" + value.to_s.gsub( /[\\']/ ) {|m| '\\' + m } + "'"
29
28
  end
30
29
 
31
30
 
32
- ### Parse the connection +args+ into a connection-parameter string
33
- ### @param [Array<String>] args the connection parameters
34
- ### @return [String] a connection parameters string
31
+ ### Parse the connection +args+ into a connection-parameter string. See PGconn.new
32
+ ### for valid arguments.
35
33
  def self::parse_connect_args( *args )
36
34
  return '' if args.empty?
37
35
 
@@ -0,0 +1,31 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ PGHOST = 'localhost'
4
+ PGDB = 'test'
5
+ #SOCKHOST = 'github.com'
6
+ SOCKHOST = 'it-trac.laika.com'
7
+
8
+ # Load pg first, so the libssl.so that libpq is linked against is loaded.
9
+ require 'pg'
10
+ $stderr.puts "connecting to postgres://#{PGHOST}/#{PGDB}"
11
+ conn = PGconn.connect( PGHOST, :dbname => PGDB )
12
+
13
+ # Now load OpenSSL, which might be linked against a different libssl.
14
+ require 'socket'
15
+ require 'openssl'
16
+ $stderr.puts "Connecting to #{SOCKHOST}"
17
+ sock = TCPSocket.open( SOCKHOST, 443 )
18
+ ctx = OpenSSL::SSL::SSLContext.new
19
+ sock = OpenSSL::SSL::SSLSocket.new( sock, ctx )
20
+ sock.sync_close = true
21
+
22
+ # The moment of truth...
23
+ $stderr.puts "Attempting to connect..."
24
+ begin
25
+ sock.connect
26
+ rescue Errno
27
+ $stderr.puts "Got an error connecting, but no segfault."
28
+ else
29
+ $stderr.puts "Nope, no segfault!"
30
+ end
31
+
@@ -0,0 +1,109 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'pg'
4
+
5
+ # This is a example of how to use the asynchronous API to query the
6
+ # server without blocking other threads. It's intentionally low-level;
7
+ # if you hooked up the PGconn#socket to some kind of reactor, you
8
+ # could make this much nicer.
9
+
10
+ TIMEOUT = 5.0 # seconds to wait for an async operation to complete
11
+ CONN_OPTS = {
12
+ :host => 'localhost',
13
+ :dbname => 'test',
14
+ :user => 'jrandom',
15
+ :password => 'banks!stealUR$',
16
+ }
17
+
18
+ # Print 'x' continuously to demonstrate that other threads aren't
19
+ # blocked while waiting for the connection, for the query to be sent,
20
+ # for results, etc. You might want to sleep inside the loop or
21
+ # comment this out entirely for cleaner output.
22
+ progress_thread = Thread.new { loop { print 'x' } }
23
+
24
+ # Output progress messages
25
+ def output_progress( msg )
26
+ puts "\n>>> #{msg}\n"
27
+ end
28
+
29
+ # Start the connection
30
+ output_progress "Starting connection..."
31
+ conn = PGconn.connect_start( CONN_OPTS ) or abort "Unable to create a new connection!"
32
+ abort "Connection failed: %s" % [ conn.error_message ] if
33
+ conn.status == PGconn::CONNECTION_BAD
34
+
35
+ # Now grab a reference to the underlying socket so we know when the
36
+ # connection is established
37
+ socket = IO.for_fd( conn.socket )
38
+
39
+ # Track the progress of the connection, waiting for the socket to become readable/writable
40
+ # before polling it
41
+ poll_status = PGconn::PGRES_POLLING_WRITING
42
+ until poll_status == PGconn::PGRES_POLLING_OK ||
43
+ poll_status == PGconn::PGRES_POLLING_FAILED
44
+
45
+ # If the socket needs to read, wait 'til it becomes readable to poll again
46
+ case poll_status
47
+ when PGconn::PGRES_POLLING_READING
48
+ output_progress " waiting for socket to become readable"
49
+ select( [socket], nil, nil, TIMEOUT ) or
50
+ raise "Asynchronous connection timed out!"
51
+
52
+ # ...and the same for when the socket needs to write
53
+ when PGconn::PGRES_POLLING_WRITING
54
+ output_progress " waiting for socket to become writable"
55
+ select( nil, [socket], nil, TIMEOUT ) or
56
+ raise "Asynchronous connection timed out!"
57
+ end
58
+
59
+ # Output a status message about the progress
60
+ case conn.status
61
+ when PGconn::CONNECTION_STARTED
62
+ output_progress " waiting for connection to be made."
63
+ when PGconn::CONNECTION_MADE
64
+ output_progress " connection OK; waiting to send."
65
+ when PGconn::CONNECTION_AWAITING_RESPONSE
66
+ output_progress " waiting for a response from the server."
67
+ when PGconn::CONNECTION_AUTH_OK
68
+ output_progress " received authentication; waiting for backend start-up to finish."
69
+ when PGconn::CONNECTION_SSL_STARTUP
70
+ output_progress " negotiating SSL encryption."
71
+ when PGconn::CONNECTION_SETENV
72
+ output_progress " negotiating environment-driven parameter settings."
73
+ end
74
+
75
+ # Check to see if it's finished or failed yet
76
+ poll_status = conn.connect_poll
77
+ end
78
+
79
+ abort "Connect failed: %s" % [ conn.error_message ] unless conn.status == PGconn::CONNECTION_OK
80
+
81
+ output_progress "Sending query"
82
+ conn.send_query( "SELECT * FROM pg_stat_activity" )
83
+
84
+ # Fetch results until there aren't any more
85
+ loop do
86
+ output_progress " waiting for a response"
87
+
88
+ # Buffer any incoming data on the socket until a full result is ready.
89
+ conn.consume_input
90
+ while conn.is_busy
91
+ select( [socket], nil, nil, TIMEOUT ) or
92
+ raise "Timeout waiting for query response."
93
+ conn.consume_input
94
+ end
95
+
96
+ # Fetch the next result. If there isn't one, the query is finished
97
+ result = conn.get_result or break
98
+
99
+ puts "\n\nQuery result:\n%p\n" % [ result.values ]
100
+ end
101
+
102
+ output_progress "Done."
103
+ conn.finish
104
+
105
+ if defined?( progress_thread )
106
+ progress_thread.kill
107
+ progress_thread.join
108
+ end
109
+
@@ -0,0 +1,39 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'pg'
4
+ require 'stringio'
5
+
6
+ # Using COPY asynchronously
7
+
8
+ $stderr.puts "Opening database connection ..."
9
+ conn = PGconn.connect( :dbname => 'test' )
10
+ conn.setnonblocking( true )
11
+
12
+ socket = IO.for_fd( conn.socket )
13
+
14
+ $stderr.puts "Running COPY command ..."
15
+ buf = ''
16
+ conn.transaction do
17
+ conn.send_query( "COPY logs TO STDOUT WITH csv" )
18
+ buf = nil
19
+
20
+ # #get_copy_data returns a row if there's a whole one to return, false
21
+ # if there isn't one but the COPY is still running, or nil when it's
22
+ # finished.
23
+ begin
24
+ $stderr.puts "COPY loop"
25
+ conn.consume_input
26
+ while conn.is_busy
27
+ $stderr.puts " ready loop"
28
+ select( [socket], nil, nil, 5.0 ) or
29
+ raise "Timeout (5s) waiting for query response."
30
+ conn.consume_input
31
+ end
32
+
33
+ buf = conn.get_copy_data
34
+ $stdout.puts( buf ) if buf
35
+ end until buf.nil?
36
+ end
37
+
38
+ conn.finish
39
+
@@ -0,0 +1,81 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'pg'
4
+ require 'stringio'
5
+
6
+ $stderr.puts "Opening database connection ..."
7
+ conn = PGconn.connect( :dbname => 'test' )
8
+
9
+ conn.exec( <<END_SQL )
10
+ DROP TABLE IF EXISTS logs;
11
+ CREATE TABLE logs (
12
+ client_ip inet,
13
+ username text,
14
+ ts timestamp,
15
+ request text,
16
+ status smallint,
17
+ bytes int
18
+ );
19
+ END_SQL
20
+
21
+ copy_data = StringIO.new( <<"END_DATA" )
22
+ "127.0.0.1","","30/Aug/2010:08:21:24 -0700","GET /manual/ HTTP/1.1",404,205
23
+ "127.0.0.1","","30/Aug/2010:08:21:24 -0700","GET /favicon.ico HTTP/1.1",404,209
24
+ "127.0.0.1","","30/Aug/2010:08:21:24 -0700","GET /favicon.ico HTTP/1.1",404,209
25
+ "127.0.0.1","","30/Aug/2010:08:22:29 -0700","GET /manual/ HTTP/1.1",200,11094
26
+ "127.0.0.1","","30/Aug/2010:08:22:38 -0700","GET /manual/index.html HTTP/1.1",200,725
27
+ "127.0.0.1","","30/Aug/2010:08:27:56 -0700","GET /manual/ HTTP/1.1",200,11094
28
+ "127.0.0.1","","30/Aug/2010:08:27:57 -0700","GET /manual/ HTTP/1.1",200,11094
29
+ "127.0.0.1","","30/Aug/2010:08:28:06 -0700","GET /manual/index.html HTTP/1.1",200,7709
30
+ "127.0.0.1","","30/Aug/2010:08:28:06 -0700","GET /manual/images/feather.gif HTTP/1.1",200,6471
31
+ "127.0.0.1","","30/Aug/2010:08:28:06 -0700","GET /manual/images/left.gif HTTP/1.1",200,60
32
+ "127.0.0.1","","30/Aug/2010:08:28:06 -0700","GET /manual/style/css/manual.css HTTP/1.1",200,18674
33
+ "127.0.0.1","","30/Aug/2010:08:28:06 -0700","GET /manual/style/css/manual-print.css HTTP/1.1",200,13200
34
+ "127.0.0.1","","30/Aug/2010:08:28:06 -0700","GET /manual/images/favicon.ico HTTP/1.1",200,1078
35
+ "127.0.0.1","","30/Aug/2010:08:28:06 -0700","GET /manual/style/css/manual-loose-100pc.css HTTP/1.1",200,3065
36
+ "127.0.0.1","","30/Aug/2010:08:28:14 -0700","OPTIONS * HTTP/1.0",200,0
37
+ "127.0.0.1","","30/Aug/2010:08:28:15 -0700","OPTIONS * HTTP/1.0",200,0
38
+ "127.0.0.1","","30/Aug/2010:08:28:47 -0700","GET /manual/mod/directives.html HTTP/1.1",200,33561
39
+ "127.0.0.1","","30/Aug/2010:08:28:53 -0700","GET /manual/mod/mpm_common.html HTTP/1.1",200,67683
40
+ "127.0.0.1","","30/Aug/2010:08:28:53 -0700","GET /manual/images/down.gif HTTP/1.1",200,56
41
+ "127.0.0.1","","30/Aug/2010:08:28:53 -0700","GET /manual/images/up.gif HTTP/1.1",200,57
42
+ "127.0.0.1","","30/Aug/2010:09:19:58 -0700","GET /manual/mod/mod_log_config.html HTTP/1.1",200,28307
43
+ "127.0.0.1","","30/Aug/2010:09:20:19 -0700","GET /manual/mod/core.html HTTP/1.1",200,194144
44
+ "127.0.0.1","","30/Aug/2010:16:02:56 -0700","GET /manual/ HTTP/1.1",200,11094
45
+ "127.0.0.1","","30/Aug/2010:16:03:00 -0700","GET /manual/ HTTP/1.1",200,11094
46
+ "127.0.0.1","","30/Aug/2010:16:06:16 -0700","GET /manual/mod/mod_dir.html HTTP/1.1",200,10583
47
+ "127.0.0.1","","30/Aug/2010:16:06:44 -0700","GET /manual/ HTTP/1.1",200,7709
48
+ END_DATA
49
+
50
+ ### You can test the error case from the database side easily by
51
+ ### changing one of the numbers at the end of one of the above rows to
52
+ ### something non-numeric like "-".
53
+
54
+ $stderr.puts "Running COPY command with data ..."
55
+ buf = ''
56
+ conn.transaction do
57
+ conn.exec( "COPY logs FROM STDIN WITH csv" )
58
+ begin
59
+ while copy_data.read( 256, buf )
60
+ ### Uncomment this to test error-handling for exceptions from the reader side:
61
+ # raise Errno::ECONNRESET, "socket closed while reading"
62
+ $stderr.puts " sending %d bytes of data..." % [ buf.length ]
63
+ until conn.put_copy_data( buf )
64
+ $stderr.puts " waiting for connection to be writable..."
65
+ sleep 0.1
66
+ end
67
+ end
68
+ rescue Errno => err
69
+ errmsg = "%s while reading copy data: %s" % [ err.class.name, err.message ]
70
+ conn.put_copy_end( errmsg )
71
+ else
72
+ conn.put_copy_end
73
+ while res = conn.get_result
74
+ $stderr.puts "Result of COPY is: %s" % [ res.res_status(res.result_status) ]
75
+ end
76
+ end
77
+ end
78
+
79
+
80
+ conn.finish
81
+
@@ -0,0 +1,19 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'pg'
4
+ require 'stringio'
5
+
6
+ # An example of how to stream data to your local host from the database as CSV.
7
+
8
+ $stderr.puts "Opening database connection ..."
9
+ conn = PGconn.connect( :dbname => 'test' )
10
+
11
+ $stderr.puts "Running COPY command ..."
12
+ buf = ''
13
+ conn.transaction do
14
+ conn.exec( "COPY logs TO STDOUT WITH csv" )
15
+ $stdout.puts( buf ) while buf = conn.get_copy_data
16
+ end
17
+
18
+ conn.finish
19
+
@@ -0,0 +1,21 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'pg'
4
+
5
+ # An example of how to use SQL cursors. This is mostly a straight port of
6
+ # the cursor portion of testlibpq.c from src/test/examples.
7
+
8
+ $stderr.puts "Opening database connection ..."
9
+ conn = PGconn.connect( :dbname => 'test' )
10
+
11
+ #
12
+ conn.transaction do
13
+ conn.exec( "DECLARE myportal CURSOR FOR select * from pg_database" )
14
+ res = conn.exec( "FETCH ALL IN myportal" )
15
+
16
+ puts res.fields.collect {|fname| "%-15s" % [fname] }.join( '' )
17
+ res.values.collect do |row|
18
+ puts row.collect {|col| "%-15s" % [col] }.join( '' )
19
+ end
20
+ end
21
+
@@ -0,0 +1,69 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'pg'
4
+
5
+ SAMPLE_WRITE_DATA = 'some sample data'
6
+ SAMPLE_EXPORT_NAME = 'lowrite.txt'
7
+
8
+ conn = PGconn.connect( :dbname => 'test', :host => 'localhost', :port => 5432 )
9
+ puts "dbname: " + conn.db + "\thost: " + conn.host + "\tuser: " + conn.user
10
+
11
+ # Start a transaction, as all large object functions require one.
12
+ puts "Beginning transaction"
13
+ conn.exec( 'BEGIN' )
14
+
15
+ # Test importing from a file
16
+ puts "Import test:"
17
+ puts " importing %s" % [ __FILE__ ]
18
+ oid = conn.lo_import( __FILE__ )
19
+ puts " imported as large object %d" % [ oid ]
20
+
21
+ # Read back 50 bytes of the imported data
22
+ puts "Read test:"
23
+ fd = conn.lo_open( oid, PGconn::INV_READ|PGconn::INV_WRITE )
24
+ conn.lo_lseek( fd, 0, PGconn::SEEK_SET )
25
+ buf = conn.lo_read( fd, 50 )
26
+ puts " read: %p" % [ buf ]
27
+ puts " read was ok!" if buf =~ /require 'pg'/
28
+
29
+ # Append some test data onto the end of the object
30
+ puts "Write test:"
31
+ conn.lo_lseek( fd, 0, PGconn::SEEK_END )
32
+ buf = SAMPLE_WRITE_DATA.dup
33
+ totalbytes = 0
34
+ until buf.empty?
35
+ bytes = conn.lo_write( fd, buf )
36
+ buf.slice!( 0, bytes )
37
+ totalbytes += bytes
38
+ end
39
+ puts " appended %d bytes" % [ totalbytes ]
40
+
41
+ # Now export it
42
+ puts "Export test:"
43
+ File.unlink( SAMPLE_EXPORT_NAME ) if File.exist?( SAMPLE_EXPORT_NAME )
44
+ conn.lo_export( oid, SAMPLE_EXPORT_NAME )
45
+ puts " success!" if File.exist?( SAMPLE_EXPORT_NAME )
46
+ puts " exported as %s (%d bytes)" % [ SAMPLE_EXPORT_NAME, File.size(SAMPLE_EXPORT_NAME) ]
47
+
48
+ conn.exec( 'COMMIT' )
49
+ puts "End of transaction."
50
+
51
+
52
+ puts 'Testing read and delete from a new transaction:'
53
+ puts ' starting a new transaction'
54
+ conn.exec( 'BEGIN' )
55
+
56
+ fd = conn.lo_open( oid, PGconn::INV_READ )
57
+ puts ' reopened okay.'
58
+ conn.lo_lseek( fd, 50, PGconn::SEEK_END )
59
+ buf = conn.lo_read( fd, 50 )
60
+ puts ' read okay.' if buf == SAMPLE_WRITE_DATA
61
+
62
+ puts 'Closing and unlinking:'
63
+ conn.lo_close( fd )
64
+ puts ' closed.'
65
+ conn.lo_unlink( oid )
66
+ puts ' unlinked.'
67
+ conn.exec( 'COMMIT' )
68
+ puts 'Done.'
69
+
@@ -0,0 +1,43 @@
1
+ #!/usr/bin/env ruby
2
+ #
3
+ # Test script, demonstrating a non-poll notification for a table event.
4
+ #
5
+ # To use, create a table called 'test', and attach a NOTIFY trigger to it
6
+ # like so:
7
+ #
8
+ # CREATE OR REPLACE FUNCTION notify_test()
9
+ # RETURNS TRIGGER
10
+ # LANGUAGE plpgsql
11
+ # AS $$
12
+ # BEGIN
13
+ # NOTIFY woo;
14
+ # RETURN NULL;
15
+ # END
16
+ # $$
17
+ #
18
+ # CREATE TRIGGER notify_trigger
19
+ # AFTER UPDATE OR INSERT OR DELETE
20
+ # ON test
21
+ # FOR EACH STATEMENT
22
+ # EXECUTE PROCEDURE notify_test()
23
+ #
24
+
25
+ BEGIN {
26
+ require 'pathname'
27
+ basedir = Pathname.new( __FILE__ ).expand_path.dirname.parent
28
+ libdir = basedir + 'lib'
29
+ $LOAD_PATH.unshift( libdir.to_s ) unless $LOAD_PATH.include?( libdir.to_s )
30
+ }
31
+
32
+ require 'pg'
33
+
34
+ conn = PGconn.connect( :dbname => 'test' )
35
+ conn.exec( 'LISTEN woo' ) # register interest in the 'woo' event
36
+
37
+ puts "Waiting up to 30 seconds for for an event!"
38
+ conn.wait_for_notify( 30 ) do |notify, pid|
39
+ puts "I got one from pid %d: %s" % [ pid, notify ]
40
+ end
41
+
42
+ puts "Awww, I didn't see any events."
43
+