pg 0.15.0.pre.454-x64-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.tar.gz.sig +0 -0
  2. data/.gemtest +0 -0
  3. data/BSDL +22 -0
  4. data/ChangeLog +2945 -0
  5. data/Contributors.rdoc +46 -0
  6. data/History.rdoc +205 -0
  7. data/LICENSE +56 -0
  8. data/Manifest.txt +53 -0
  9. data/POSTGRES +23 -0
  10. data/README-OS_X.rdoc +68 -0
  11. data/README-Windows.rdoc +67 -0
  12. data/README.ja.rdoc +14 -0
  13. data/README.rdoc +111 -0
  14. data/Rakefile +156 -0
  15. data/Rakefile.cross +271 -0
  16. data/ext/extconf.rb +91 -0
  17. data/ext/gvl_wrappers.c +13 -0
  18. data/ext/gvl_wrappers.h +185 -0
  19. data/ext/pg.c +525 -0
  20. data/ext/pg.h +126 -0
  21. data/ext/pg_connection.c +3600 -0
  22. data/ext/pg_result.c +939 -0
  23. data/ext/vc/pg.sln +26 -0
  24. data/ext/vc/pg_18/pg.vcproj +216 -0
  25. data/ext/vc/pg_19/pg_19.vcproj +209 -0
  26. data/lib/2.0/pg_ext.so +0 -0
  27. data/lib/pg.rb +52 -0
  28. data/lib/pg/connection.rb +71 -0
  29. data/lib/pg/constants.rb +11 -0
  30. data/lib/pg/exceptions.rb +11 -0
  31. data/lib/pg/result.rb +16 -0
  32. data/sample/array_insert.rb +20 -0
  33. data/sample/async_api.rb +106 -0
  34. data/sample/async_copyto.rb +39 -0
  35. data/sample/async_mixed.rb +56 -0
  36. data/sample/check_conn.rb +21 -0
  37. data/sample/copyfrom.rb +81 -0
  38. data/sample/copyto.rb +19 -0
  39. data/sample/cursor.rb +21 -0
  40. data/sample/disk_usage_report.rb +186 -0
  41. data/sample/issue-119.rb +94 -0
  42. data/sample/losample.rb +69 -0
  43. data/sample/minimal-testcase.rb +17 -0
  44. data/sample/notify_wait.rb +72 -0
  45. data/sample/pg_statistics.rb +294 -0
  46. data/sample/replication_monitor.rb +231 -0
  47. data/sample/test_binary_values.rb +33 -0
  48. data/sample/wal_shipper.rb +434 -0
  49. data/sample/warehouse_partitions.rb +320 -0
  50. data/spec/data/expected_trace.out +26 -0
  51. data/spec/data/random_binary_data +0 -0
  52. data/spec/lib/helpers.rb +279 -0
  53. data/spec/pg/connection_spec.rb +1013 -0
  54. data/spec/pg/result_spec.rb +278 -0
  55. data/spec/pg_spec.rb +31 -0
  56. metadata +275 -0
  57. metadata.gz.sig +0 -0
Binary file
@@ -0,0 +1,52 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ begin
4
+ require 'pg_ext'
5
+ rescue LoadError
6
+ # If it's a Windows binary gem, try the <major>.<minor> subdirectory
7
+ if RUBY_PLATFORM =~/(mswin|mingw)/i
8
+ major_minor = RUBY_VERSION[ /^(\d+\.\d+)/ ] or
9
+ raise "Oops, can't extract the major/minor version from #{RUBY_VERSION.dump}"
10
+ require "#{major_minor}/pg_ext"
11
+ else
12
+ raise
13
+ end
14
+
15
+ end
16
+
17
+
18
+ # The top-level PG namespace.
19
+ module PG
20
+
21
+ # Library version
22
+ VERSION = '0.15.0.pre.454'
23
+
24
+ # VCS revision
25
+ REVISION = %q$Revision$
26
+
27
+
28
+ ### Get the PG library version. If +include_buildnum+ is +true+, include the build ID.
29
+ def self::version_string( include_buildnum=false )
30
+ vstring = "%s %s" % [ self.name, VERSION ]
31
+ vstring << " (build %s)" % [ REVISION[/: ([[:xdigit:]]+)/, 1] || '0' ] if include_buildnum
32
+ return vstring
33
+ end
34
+
35
+
36
+ ### Convenience alias for PG::Connection.new.
37
+ def self::connect( *args )
38
+ return PG::Connection.new( *args )
39
+ end
40
+
41
+
42
+ require 'pg/exceptions'
43
+ require 'pg/constants'
44
+ require 'pg/connection'
45
+ require 'pg/result'
46
+
47
+ end # module PG
48
+
49
+
50
+ # Backward-compatible aliase
51
+ PGError = PG::Error
52
+
@@ -0,0 +1,71 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'pg' unless defined?( PG )
4
+
5
+ # The PG connection class.
6
+ class PG::Connection
7
+
8
+ # The order the options are passed to the ::connect method.
9
+ CONNECT_ARGUMENT_ORDER = %w[host port options tty dbname user password]
10
+
11
+
12
+ ### Quote the given +value+ for use in a connection-parameter string.
13
+ def self::quote_connstr( value )
14
+ return "'" + value.to_s.gsub( /[\\']/ ) {|m| '\\' + m } + "'"
15
+ end
16
+
17
+
18
+ ### Parse the connection +args+ into a connection-parameter string. See PG::Connection.new
19
+ ### for valid arguments.
20
+ def self::parse_connect_args( *args )
21
+ return '' if args.empty?
22
+
23
+ # This will be swapped soon for code that makes options like those required for
24
+ # PQconnectdbParams()/PQconnectStartParams(). For now, stick to an options string for
25
+ # PQconnectdb()/PQconnectStart().
26
+
27
+ # Parameter 'fallback_application_name' was introduced in PostgreSQL 9.0
28
+ # together with PQescapeLiteral().
29
+ if PG::Connection.instance_methods.find{|m| m.to_sym == :escape_literal }
30
+ appname = PG::Connection.quote_connstr( $0 )
31
+ connopts = ["fallback_application_name=#{appname}"]
32
+ else
33
+ connopts = []
34
+ end
35
+
36
+ # Handle an options hash first
37
+ if args.last.is_a?( Hash )
38
+ opthash = args.pop
39
+ opthash.each do |key, val|
40
+ connopts.push( "%s=%s" % [key, PG::Connection.quote_connstr(val)] )
41
+ end
42
+ end
43
+
44
+ # Option string style
45
+ if args.length == 1 && args.first.to_s.index( '=' )
46
+ connopts.unshift( args.first )
47
+
48
+ # Append positional parameters
49
+ else
50
+ args.each_with_index do |val, i|
51
+ next unless val # Skip nil placeholders
52
+
53
+ key = CONNECT_ARGUMENT_ORDER[ i ] or
54
+ raise ArgumentError, "Extra positional parameter %d: %p" % [ i+1, val ]
55
+ connopts.push( "%s=%s" % [key, PG::Connection.quote_connstr(val.to_s)] )
56
+ end
57
+ end
58
+
59
+ return connopts.join(' ')
60
+ end
61
+
62
+
63
+ # Backward-compatibility aliases for stuff that's moved into PG.
64
+ class << self
65
+ define_method( :isthreadsafe, &PG.method(:isthreadsafe) )
66
+ end
67
+ end # class PG::Connection
68
+
69
+ # Backward-compatible alias
70
+ PGconn = PG::Connection
71
+
@@ -0,0 +1,11 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'pg' unless defined?( PG )
4
+
5
+
6
+ module PG::Constants
7
+
8
+ # Most of these are defined in the extension.
9
+
10
+ end # module PG::Constants
11
+
@@ -0,0 +1,11 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'pg' unless defined?( PG )
4
+
5
+
6
+ module PG
7
+
8
+ class Error < StandardError; end
9
+
10
+ end # module PG
11
+
@@ -0,0 +1,16 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'pg' unless defined?( PG )
4
+
5
+
6
+ class PG::Result
7
+
8
+ ### Returns all tuples as an array of arrays
9
+ def values
10
+ return enum_for(:each_row).to_a
11
+ end
12
+
13
+ end # class PG::Result
14
+
15
+ # Backward-compatible alias
16
+ PGresult = PG::Result
@@ -0,0 +1,20 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'pg'
4
+
5
+ c = PG.connect( dbname: 'test' )
6
+
7
+ # this one works:
8
+ c.exec( "DROP TABLE IF EXISTS foo" )
9
+ c.exec( "CREATE TABLE foo (strings character varying[]);" )
10
+
11
+ # But using a prepared statement works:
12
+ c.set_error_verbosity( PG::PQERRORS_VERBOSE )
13
+ c.prepare( 'stmt', "INSERT INTO foo VALUES ($1);" )
14
+
15
+ # This won't work
16
+ #c.exec_prepared( 'stmt', ["ARRAY['this','that']"] )
17
+
18
+ # but this will:
19
+ c.exec_prepared( 'stmt', ["{'this','that'}"] )
20
+
@@ -0,0 +1,106 @@
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 PG::Connection#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
+
12
+ # Print 'x' continuously to demonstrate that other threads aren't
13
+ # blocked while waiting for the connection, for the query to be sent,
14
+ # for results, etc. You might want to sleep inside the loop or
15
+ # comment this out entirely for cleaner output.
16
+ progress_thread = Thread.new { loop { print 'x' } }
17
+
18
+ # Output progress messages
19
+ def output_progress( msg )
20
+ puts "\n>>> #{msg}\n"
21
+ end
22
+
23
+ # Start the connection
24
+ output_progress "Starting connection..."
25
+ conn = PG::Connection.connect_start( :dbname => 'test' ) or
26
+ abort "Unable to create a new connection!"
27
+ abort "Connection failed: %s" % [ conn.error_message ] if
28
+ conn.status == PG::CONNECTION_BAD
29
+
30
+ # Now grab a reference to the underlying socket so we know when the
31
+ # connection is established
32
+ socket = conn.socket_io
33
+
34
+ # Track the progress of the connection, waiting for the socket to become readable/writable
35
+ # before polling it
36
+ poll_status = PG::PGRES_POLLING_WRITING
37
+ until poll_status == PG::PGRES_POLLING_OK ||
38
+ poll_status == PG::PGRES_POLLING_FAILED
39
+
40
+ # If the socket needs to read, wait 'til it becomes readable to poll again
41
+ case poll_status
42
+ when PG::PGRES_POLLING_READING
43
+ output_progress " waiting for socket to become readable"
44
+ select( [socket], nil, nil, TIMEOUT ) or
45
+ raise "Asynchronous connection timed out!"
46
+
47
+ # ...and the same for when the socket needs to write
48
+ when PG::PGRES_POLLING_WRITING
49
+ output_progress " waiting for socket to become writable"
50
+ select( nil, [socket], nil, TIMEOUT ) or
51
+ raise "Asynchronous connection timed out!"
52
+ end
53
+
54
+ # Output a status message about the progress
55
+ case conn.status
56
+ when PG::CONNECTION_STARTED
57
+ output_progress " waiting for connection to be made."
58
+ when PG::CONNECTION_MADE
59
+ output_progress " connection OK; waiting to send."
60
+ when PG::CONNECTION_AWAITING_RESPONSE
61
+ output_progress " waiting for a response from the server."
62
+ when PG::CONNECTION_AUTH_OK
63
+ output_progress " received authentication; waiting for backend start-up to finish."
64
+ when PG::CONNECTION_SSL_STARTUP
65
+ output_progress " negotiating SSL encryption."
66
+ when PG::CONNECTION_SETENV
67
+ output_progress " negotiating environment-driven parameter settings."
68
+ when PG::CONNECTION_NEEDED
69
+ output_progress " internal state: connect() needed."
70
+ end
71
+
72
+ # Check to see if it's finished or failed yet
73
+ poll_status = conn.connect_poll
74
+ end
75
+
76
+ abort "Connect failed: %s" % [ conn.error_message ] unless conn.status == PG::CONNECTION_OK
77
+
78
+ output_progress "Sending query"
79
+ conn.send_query( "SELECT * FROM pg_stat_activity" )
80
+
81
+ # Fetch results until there aren't any more
82
+ loop do
83
+ output_progress " waiting for a response"
84
+
85
+ # Buffer any incoming data on the socket until a full result is ready.
86
+ conn.consume_input
87
+ while conn.is_busy
88
+ select( [socket], nil, nil, TIMEOUT ) or
89
+ raise "Timeout waiting for query response."
90
+ conn.consume_input
91
+ end
92
+
93
+ # Fetch the next result. If there isn't one, the query is finished
94
+ result = conn.get_result or break
95
+
96
+ puts "\n\nQuery result:\n%p\n" % [ result.values ]
97
+ end
98
+
99
+ output_progress "Done."
100
+ conn.finish
101
+
102
+ if defined?( progress_thread )
103
+ progress_thread.kill
104
+ progress_thread.join
105
+ end
106
+
@@ -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 = PG.connect( :dbname => 'test' )
10
+ conn.setnonblocking( true )
11
+
12
+ socket = conn.socket_io
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,56 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'pg'
4
+
5
+ $stdout.sync = true
6
+
7
+ # This is a example of how to mix and match synchronous and async APIs. In this case,
8
+ # the connection to the server is made syncrhonously, and then queries are
9
+ # asynchronous.
10
+
11
+ TIMEOUT = 5.0 # seconds to wait for an async operation to complete
12
+ CONN_OPTS = {
13
+ :host => 'localhost',
14
+ :dbname => 'test',
15
+ }
16
+
17
+ # Output progress messages
18
+ def output_progress( msg )
19
+ puts ">>> #{msg}\n"
20
+ end
21
+
22
+ # Start the (synchronous) connection
23
+ output_progress "Starting connection..."
24
+ conn = PG.connect( CONN_OPTS ) or abort "Unable to create a new connection!"
25
+
26
+ abort "Connect failed: %s" % [ conn.error_message ] unless conn.status == PG::CONNECTION_OK
27
+
28
+ # Now grab a reference to the underlying socket to select() on while the query is running
29
+ socket = conn.socket_io
30
+
31
+ # Send the (asynchronous) query
32
+ output_progress "Sending query"
33
+ conn.send_query( "SELECT * FROM pg_stat_activity" )
34
+
35
+ # Fetch results until there aren't any more
36
+ loop do
37
+ output_progress " waiting for a response"
38
+
39
+ # Buffer any incoming data on the socket until a full result is ready.
40
+ conn.consume_input
41
+ while conn.is_busy
42
+ output_progress " waiting for data to be available on %p..." % [ socket ]
43
+ select( [socket], nil, nil, TIMEOUT ) or
44
+ raise "Timeout waiting for query response."
45
+ conn.consume_input
46
+ end
47
+
48
+ # Fetch the next result. If there isn't one, the query is finished
49
+ result = conn.get_result or break
50
+
51
+ output_progress "Query result:\n%p\n" % [ result.values ]
52
+ end
53
+
54
+ output_progress "Done."
55
+ conn.finish
56
+
@@ -0,0 +1,21 @@
1
+ #!/usr/bin/env ruby
2
+ # vim: set nosta noet ts=4 sw=4:
3
+ # encoding: utf-8
4
+
5
+ require 'pg'
6
+
7
+ # This is a minimal example of a function that can test an existing PG::Connection and
8
+ # reset it if necessary.
9
+
10
+ def check_connection( conn )
11
+ begin
12
+ conn.exec( "SELECT 1" )
13
+ rescue PG::Error => err
14
+ $stderr.puts "%p while testing connection: %s" % [ err.class, err.message ]
15
+ conn.reset
16
+ end
17
+ end
18
+
19
+ conn = PG.connect( dbname: 'test' )
20
+ check_connection( conn )
21
+
@@ -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 = PG.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
+