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.
- data/.gemtest +0 -0
- data/ChangeLog +1647 -462
- data/Contributors.rdoc +39 -0
- data/History.rdoc +61 -0
- data/Manifest.txt +43 -0
- data/README.OS_X.rdoc +68 -0
- data/README.ja.rdoc +7 -0
- data/{README → README.rdoc} +38 -18
- data/{README.windows → README.windows.rdoc} +23 -31
- data/Rakefile +104 -318
- data/Rakefile.cross +234 -0
- data/ext/compat.c +2 -2
- data/ext/extconf.rb +10 -2
- data/ext/pg.c +223 -43
- data/ext/vc/pg.sln +26 -0
- data/ext/vc/pg_18/pg.vcproj +216 -0
- data/ext/vc/pg_19/pg_19.vcproj +209 -0
- data/lib/1.8/pg_ext.so +0 -0
- data/lib/1.9/pg_ext.so +0 -0
- data/lib/pg.rb +5 -7
- data/misc/openssl-pg-segfault.rb +31 -0
- data/sample/async_api.rb +109 -0
- data/sample/async_copyto.rb +39 -0
- data/sample/copyfrom.rb +81 -0
- data/sample/copyto.rb +19 -0
- data/sample/cursor.rb +21 -0
- data/sample/losample.rb +69 -0
- data/sample/notify_wait.rb +43 -0
- data/sample/psql.rb +1181 -0
- data/sample/psqlHelp.rb +158 -0
- data/sample/test1.rb +60 -0
- data/sample/test2.rb +44 -0
- data/sample/test4.rb +71 -0
- data/sample/test_binary_values.rb +35 -0
- data/spec/lib/helpers.rb +6 -4
- data/spec/m17n_spec.rb +2 -2
- data/spec/pgconn_spec.rb +51 -6
- data/spec/pgresult_spec.rb +30 -4
- metadata +147 -86
- data.tar.gz.sig +0 -3
- data/Contributors +0 -32
- data/README.OS_X +0 -19
- data/README.ja +0 -183
- data/Rakefile.local +0 -312
- data/rake/191_compat.rb +0 -26
- data/rake/dependencies.rb +0 -76
- data/rake/documentation.rb +0 -123
- data/rake/helpers.rb +0 -502
- data/rake/hg.rb +0 -318
- data/rake/manual.rb +0 -787
- data/rake/packaging.rb +0 -129
- data/rake/publishing.rb +0 -341
- data/rake/style.rb +0 -62
- data/rake/svn.rb +0 -668
- data/rake/testing.rb +0 -152
- data/rake/verifytask.rb +0 -64
- metadata.gz.sig +0 -3
data/lib/1.8/pg_ext.so
CHANGED
Binary file
|
data/lib/1.9/pg_ext.so
CHANGED
Binary file
|
data/lib/pg.rb
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
begin
|
4
4
|
require 'pg_ext'
|
5
|
-
rescue LoadError
|
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
|
-
|
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
|
-
###
|
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
|
+
|
data/sample/async_api.rb
ADDED
@@ -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
|
+
|
data/sample/copyfrom.rb
ADDED
@@ -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
|
+
|
data/sample/copyto.rb
ADDED
@@ -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
|
+
|
data/sample/cursor.rb
ADDED
@@ -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
|
+
|
data/sample/losample.rb
ADDED
@@ -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
|
+
|