pg 0.11.0 → 0.12.0pre258
Sign up to get free protection for your applications and to get access to all the features.
- data/.gemtest +0 -0
- data/Contributors.rdoc +37 -0
- data/History.rdoc +60 -0
- data/Manifest.txt +39 -0
- data/README.OS_X.rdoc +68 -0
- data/README.ja.rdoc +7 -0
- data/{README → README.rdoc} +33 -18
- data/{README.windows → README.windows.rdoc} +20 -26
- data/Rakefile +98 -324
- data/ext/extconf.rb +7 -2
- data/ext/pg.c +173 -35
- 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/pg.rb +5 -7
- data/misc/openssl-pg-segfault.rb +31 -0
- data/sample/async_api.rb +109 -0
- data/sample/copyfrom.rb +81 -0
- data/sample/copyto.rb +23 -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/m17n_spec.rb +1 -1
- data/spec/pgconn_spec.rb +50 -5
- data/spec/pgresult_spec.rb +1 -1
- metadata +142 -66
- data.tar.gz.sig +0 -2
- data/ChangeLog +0 -693
- 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 -0
@@ -0,0 +1,209 @@
|
|
1
|
+
<?xml version="1.0" encoding="Windows-1252"?>
|
2
|
+
<VisualStudioProject
|
3
|
+
ProjectType="Visual C++"
|
4
|
+
Version="9.00"
|
5
|
+
Name="pg_19"
|
6
|
+
ProjectGUID="{2EE30C74-074F-4611-B39B-38D5F3C9B071}"
|
7
|
+
RootNamespace="pg_19"
|
8
|
+
Keyword="Win32Proj"
|
9
|
+
TargetFrameworkVersion="196613"
|
10
|
+
>
|
11
|
+
<Platforms>
|
12
|
+
<Platform
|
13
|
+
Name="Win32"
|
14
|
+
/>
|
15
|
+
</Platforms>
|
16
|
+
<ToolFiles>
|
17
|
+
</ToolFiles>
|
18
|
+
<Configurations>
|
19
|
+
<Configuration
|
20
|
+
Name="Debug|Win32"
|
21
|
+
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
|
22
|
+
IntermediateDirectory="$(ConfigurationName)"
|
23
|
+
ConfigurationType="2"
|
24
|
+
CharacterSet="1"
|
25
|
+
>
|
26
|
+
<Tool
|
27
|
+
Name="VCPreBuildEventTool"
|
28
|
+
/>
|
29
|
+
<Tool
|
30
|
+
Name="VCCustomBuildTool"
|
31
|
+
/>
|
32
|
+
<Tool
|
33
|
+
Name="VCXMLDataGeneratorTool"
|
34
|
+
/>
|
35
|
+
<Tool
|
36
|
+
Name="VCWebServiceProxyGeneratorTool"
|
37
|
+
/>
|
38
|
+
<Tool
|
39
|
+
Name="VCMIDLTool"
|
40
|
+
/>
|
41
|
+
<Tool
|
42
|
+
Name="VCCLCompilerTool"
|
43
|
+
Optimization="0"
|
44
|
+
PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;PG_19_EXPORTS"
|
45
|
+
MinimalRebuild="true"
|
46
|
+
BasicRuntimeChecks="3"
|
47
|
+
RuntimeLibrary="3"
|
48
|
+
UsePrecompiledHeader="2"
|
49
|
+
WarningLevel="3"
|
50
|
+
DebugInformationFormat="4"
|
51
|
+
/>
|
52
|
+
<Tool
|
53
|
+
Name="VCManagedResourceCompilerTool"
|
54
|
+
/>
|
55
|
+
<Tool
|
56
|
+
Name="VCResourceCompilerTool"
|
57
|
+
/>
|
58
|
+
<Tool
|
59
|
+
Name="VCPreLinkEventTool"
|
60
|
+
/>
|
61
|
+
<Tool
|
62
|
+
Name="VCLinkerTool"
|
63
|
+
LinkIncremental="2"
|
64
|
+
GenerateDebugInformation="true"
|
65
|
+
SubSystem="2"
|
66
|
+
TargetMachine="1"
|
67
|
+
/>
|
68
|
+
<Tool
|
69
|
+
Name="VCALinkTool"
|
70
|
+
/>
|
71
|
+
<Tool
|
72
|
+
Name="VCManifestTool"
|
73
|
+
/>
|
74
|
+
<Tool
|
75
|
+
Name="VCXDCMakeTool"
|
76
|
+
/>
|
77
|
+
<Tool
|
78
|
+
Name="VCBscMakeTool"
|
79
|
+
/>
|
80
|
+
<Tool
|
81
|
+
Name="VCFxCopTool"
|
82
|
+
/>
|
83
|
+
<Tool
|
84
|
+
Name="VCAppVerifierTool"
|
85
|
+
/>
|
86
|
+
<Tool
|
87
|
+
Name="VCPostBuildEventTool"
|
88
|
+
/>
|
89
|
+
</Configuration>
|
90
|
+
<Configuration
|
91
|
+
Name="Release|Win32"
|
92
|
+
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
|
93
|
+
IntermediateDirectory="$(ConfigurationName)"
|
94
|
+
ConfigurationType="2"
|
95
|
+
CharacterSet="1"
|
96
|
+
WholeProgramOptimization="1"
|
97
|
+
>
|
98
|
+
<Tool
|
99
|
+
Name="VCPreBuildEventTool"
|
100
|
+
/>
|
101
|
+
<Tool
|
102
|
+
Name="VCCustomBuildTool"
|
103
|
+
/>
|
104
|
+
<Tool
|
105
|
+
Name="VCXMLDataGeneratorTool"
|
106
|
+
/>
|
107
|
+
<Tool
|
108
|
+
Name="VCWebServiceProxyGeneratorTool"
|
109
|
+
/>
|
110
|
+
<Tool
|
111
|
+
Name="VCMIDLTool"
|
112
|
+
/>
|
113
|
+
<Tool
|
114
|
+
Name="VCCLCompilerTool"
|
115
|
+
Optimization="2"
|
116
|
+
EnableIntrinsicFunctions="true"
|
117
|
+
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;PG_19_EXPORTS"
|
118
|
+
RuntimeLibrary="2"
|
119
|
+
EnableFunctionLevelLinking="true"
|
120
|
+
UsePrecompiledHeader="2"
|
121
|
+
WarningLevel="3"
|
122
|
+
DebugInformationFormat="3"
|
123
|
+
/>
|
124
|
+
<Tool
|
125
|
+
Name="VCManagedResourceCompilerTool"
|
126
|
+
/>
|
127
|
+
<Tool
|
128
|
+
Name="VCResourceCompilerTool"
|
129
|
+
/>
|
130
|
+
<Tool
|
131
|
+
Name="VCPreLinkEventTool"
|
132
|
+
/>
|
133
|
+
<Tool
|
134
|
+
Name="VCLinkerTool"
|
135
|
+
LinkIncremental="1"
|
136
|
+
GenerateDebugInformation="true"
|
137
|
+
SubSystem="2"
|
138
|
+
OptimizeReferences="2"
|
139
|
+
EnableCOMDATFolding="2"
|
140
|
+
TargetMachine="1"
|
141
|
+
/>
|
142
|
+
<Tool
|
143
|
+
Name="VCALinkTool"
|
144
|
+
/>
|
145
|
+
<Tool
|
146
|
+
Name="VCManifestTool"
|
147
|
+
/>
|
148
|
+
<Tool
|
149
|
+
Name="VCXDCMakeTool"
|
150
|
+
/>
|
151
|
+
<Tool
|
152
|
+
Name="VCBscMakeTool"
|
153
|
+
/>
|
154
|
+
<Tool
|
155
|
+
Name="VCFxCopTool"
|
156
|
+
/>
|
157
|
+
<Tool
|
158
|
+
Name="VCAppVerifierTool"
|
159
|
+
/>
|
160
|
+
<Tool
|
161
|
+
Name="VCPostBuildEventTool"
|
162
|
+
/>
|
163
|
+
</Configuration>
|
164
|
+
</Configurations>
|
165
|
+
<References>
|
166
|
+
</References>
|
167
|
+
<Files>
|
168
|
+
<Filter
|
169
|
+
Name="Source Files"
|
170
|
+
Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
|
171
|
+
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
|
172
|
+
>
|
173
|
+
<File
|
174
|
+
RelativePath="..\..\compat.c"
|
175
|
+
>
|
176
|
+
</File>
|
177
|
+
<File
|
178
|
+
RelativePath="..\..\pg.c"
|
179
|
+
>
|
180
|
+
</File>
|
181
|
+
</Filter>
|
182
|
+
<Filter
|
183
|
+
Name="Header Files"
|
184
|
+
Filter="h;hpp;hxx;hm;inl;inc;xsd"
|
185
|
+
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
|
186
|
+
>
|
187
|
+
<File
|
188
|
+
RelativePath="..\..\compat.h"
|
189
|
+
>
|
190
|
+
</File>
|
191
|
+
<File
|
192
|
+
RelativePath="..\..\pg.h"
|
193
|
+
>
|
194
|
+
</File>
|
195
|
+
</Filter>
|
196
|
+
<Filter
|
197
|
+
Name="Resource Files"
|
198
|
+
Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
|
199
|
+
UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
|
200
|
+
>
|
201
|
+
</Filter>
|
202
|
+
<File
|
203
|
+
RelativePath=".\ReadMe.txt"
|
204
|
+
>
|
205
|
+
</File>
|
206
|
+
</Files>
|
207
|
+
<Globals>
|
208
|
+
</Globals>
|
209
|
+
</VisualStudioProject>
|
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
|
+
|
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
|
+
|