pg 0.8.0 → 0.9.0.pre156
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/ChangeLog +440 -230
- data/Contributors +2 -0
- data/README +41 -98
- data/README.OS_X +19 -0
- data/README.ja +183 -0
- data/README.windows +72 -0
- data/Rakefile.local +239 -0
- data/ext/extconf.rb +101 -62
- data/ext/pg.c +823 -142
- data/ext/pg.h +9 -2
- data/lib/pg.rb +11 -0
- data/rake/191_compat.rb +26 -0
- data/rake/dependencies.rb +76 -0
- data/rake/helpers.rb +435 -0
- data/rake/hg.rb +273 -0
- data/rake/manual.rb +782 -0
- data/rake/packaging.rb +123 -0
- data/rake/publishing.rb +274 -0
- data/rake/rdoc.rb +30 -0
- data/rake/style.rb +62 -0
- data/rake/svn.rb +668 -0
- data/rake/testing.rb +187 -0
- data/rake/verifytask.rb +64 -0
- data/spec/lib/helpers.rb +216 -0
- data/spec/m17n_spec.rb +139 -0
- data/spec/pgconn_spec.rb +199 -38
- data/spec/pgresult_spec.rb +157 -51
- metadata +71 -48
- data/COPYING.txt +0 -340
- data/Rakefile +0 -103
- data/doc/postgres.html +0 -278
- data/doc/postgres.jp.html +0 -256
- data/ext/mingw/Rakefile +0 -24
- data/ext/mingw/build.rake +0 -40
- data/ext/mkrf_config.rb +0 -138
- data/ext/vc/pg.sln +0 -26
- data/sample/losample.rb +0 -47
- data/sample/psql.rb +0 -1181
- data/sample/psqlHelp.rb +0 -158
- data/sample/test1.rb +0 -63
- data/sample/test2.rb +0 -44
- data/sample/test4.rb +0 -71
- data/spec/data/expected_trace.out +0 -26
- data/spec/data/random_binary_data +0 -0
data/spec/m17n_spec.rb
ADDED
@@ -0,0 +1,139 @@
|
|
1
|
+
#!/usr/bin/env spec
|
2
|
+
# encoding: utf-8
|
3
|
+
|
4
|
+
BEGIN {
|
5
|
+
require 'pathname'
|
6
|
+
require 'rbconfig'
|
7
|
+
|
8
|
+
basedir = Pathname( __FILE__ ).dirname.parent
|
9
|
+
libdir = basedir + 'lib'
|
10
|
+
archlib = libdir + Config::CONFIG['sitearch']
|
11
|
+
|
12
|
+
$LOAD_PATH.unshift( libdir.to_s ) unless $LOAD_PATH.include?( libdir.to_s )
|
13
|
+
$LOAD_PATH.unshift( archlib.to_s ) unless $LOAD_PATH.include?( archlib.to_s )
|
14
|
+
}
|
15
|
+
|
16
|
+
require 'pg'
|
17
|
+
|
18
|
+
require 'rubygems'
|
19
|
+
require 'spec'
|
20
|
+
require 'spec/lib/helpers'
|
21
|
+
|
22
|
+
describe "multinationalization support" do
|
23
|
+
include PgTestingHelpers
|
24
|
+
|
25
|
+
RUBY_VERSION_VEC = RUBY_VERSION.split('.').map {|c| c.to_i }.pack("N*")
|
26
|
+
MIN_RUBY_VERSION_VEC = [1,9,1].pack('N*')
|
27
|
+
|
28
|
+
|
29
|
+
before( :all ) do
|
30
|
+
@conn = nil
|
31
|
+
if RUBY_VERSION_VEC >= MIN_RUBY_VERSION_VEC
|
32
|
+
@conn = setup_testing_db( "m17n" )
|
33
|
+
@conn.exec( 'BEGIN' )
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
before( :each ) do
|
38
|
+
pending "depends on m17n support in Ruby >= 1.9.1" if @conn.nil?
|
39
|
+
end
|
40
|
+
|
41
|
+
|
42
|
+
it "should return the same bytes in text format that are sent as inline text" do
|
43
|
+
binary_file = File.join(Dir.pwd, 'spec/data', 'random_binary_data')
|
44
|
+
in_bytes = File.open(binary_file, 'r:ASCII-8BIT').read
|
45
|
+
|
46
|
+
out_bytes = nil
|
47
|
+
@conn.transaction do |conn|
|
48
|
+
conn.exec("SET standard_conforming_strings=on")
|
49
|
+
res = conn.exec("VALUES ('#{PGconn.escape_bytea(in_bytes)}'::bytea)", [], 0)
|
50
|
+
out_bytes = PGconn.unescape_bytea(res[0]['column1'])
|
51
|
+
end
|
52
|
+
out_bytes.should== in_bytes
|
53
|
+
end
|
54
|
+
|
55
|
+
describe "rubyforge #22925: m17n support" do
|
56
|
+
it "should return results in the same encoding as the client (iso-8859-1)" do
|
57
|
+
out_string = nil
|
58
|
+
@conn.transaction do |conn|
|
59
|
+
conn.internal_encoding = 'iso8859-1'
|
60
|
+
res = conn.exec("VALUES ('fantasia')", [], 0)
|
61
|
+
out_string = res[0]['column1']
|
62
|
+
end
|
63
|
+
out_string.should == 'fantasia'
|
64
|
+
out_string.encoding.should == Encoding::ISO8859_1
|
65
|
+
end
|
66
|
+
|
67
|
+
it "should return results in the same encoding as the client (utf-8)" do
|
68
|
+
out_string = nil
|
69
|
+
@conn.transaction do |conn|
|
70
|
+
conn.internal_encoding = 'utf-8'
|
71
|
+
res = conn.exec("VALUES ('世界線航跡蔵')", [], 0)
|
72
|
+
out_string = res[0]['column1']
|
73
|
+
end
|
74
|
+
out_string.should == '世界線航跡蔵'
|
75
|
+
out_string.encoding.should == Encoding::UTF_8
|
76
|
+
end
|
77
|
+
|
78
|
+
it "should return results in the same encoding as the client (EUC-JP)" do
|
79
|
+
out_string = nil
|
80
|
+
@conn.transaction do |conn|
|
81
|
+
conn.internal_encoding = 'EUC-JP'
|
82
|
+
stmt = "VALUES ('世界線航跡蔵')".encode('EUC-JP')
|
83
|
+
res = conn.exec(stmt, [], 0)
|
84
|
+
out_string = res[0]['column1']
|
85
|
+
end
|
86
|
+
out_string.should == '世界線航跡蔵'.encode('EUC-JP')
|
87
|
+
out_string.encoding.should == Encoding::EUC_JP
|
88
|
+
end
|
89
|
+
|
90
|
+
it "returns the results in the correct encoding even if the client_encoding has " +
|
91
|
+
"changed since the results were fetched" do
|
92
|
+
out_string = nil
|
93
|
+
@conn.transaction do |conn|
|
94
|
+
conn.internal_encoding = 'EUC-JP'
|
95
|
+
stmt = "VALUES ('世界線航跡蔵')".encode('EUC-JP')
|
96
|
+
res = conn.exec(stmt, [], 0)
|
97
|
+
conn.internal_encoding = 'utf-8'
|
98
|
+
out_string = res[0]['column1']
|
99
|
+
end
|
100
|
+
out_string.should == '世界線航跡蔵'.encode('EUC-JP')
|
101
|
+
out_string.encoding.should == Encoding::EUC_JP
|
102
|
+
end
|
103
|
+
|
104
|
+
it "the connection should return ASCII-8BIT when the server encoding is SQL_ASCII" do
|
105
|
+
@conn.external_encoding.should == Encoding::ASCII_8BIT
|
106
|
+
end
|
107
|
+
|
108
|
+
it "works around the unsupported JOHAB encoding by returning stuff in 'ASCII_8BIT'" do
|
109
|
+
pending "figuring out how to create a string in the JOHAB encoding" do
|
110
|
+
out_string = nil
|
111
|
+
@conn.transaction do |conn|
|
112
|
+
conn.exec( "set client_encoding = 'JOHAB';" )
|
113
|
+
stmt = "VALUES ('foo')".encode('JOHAB')
|
114
|
+
res = conn.exec( stmt, [], 0 )
|
115
|
+
out_string = res[0]['column1']
|
116
|
+
end
|
117
|
+
out_string.should == 'foo'.encode(Encoding::ASCII_8BIT)
|
118
|
+
out_string.encoding.should == Encoding::ASCII_8BIT
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
it "should use client encoding for escaped string" do
|
123
|
+
original = "string to escape".force_encoding("euc-jp")
|
124
|
+
@conn.set_client_encoding("euc_jp")
|
125
|
+
escaped = @conn.escape(original)
|
126
|
+
escaped.encoding.should == Encoding::EUC_JP
|
127
|
+
end
|
128
|
+
|
129
|
+
end
|
130
|
+
|
131
|
+
|
132
|
+
after( :each ) do
|
133
|
+
@conn.exec( 'ROLLBACK' ) if @conn
|
134
|
+
end
|
135
|
+
|
136
|
+
after( :all ) do
|
137
|
+
teardown_testing_db( @conn ) if @conn
|
138
|
+
end
|
139
|
+
end
|
data/spec/pgconn_spec.rb
CHANGED
@@ -1,36 +1,37 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
#!/usr/bin/env spec
|
2
|
+
# encoding: utf-8
|
3
|
+
|
4
|
+
BEGIN {
|
5
|
+
require 'pathname'
|
6
|
+
require 'rbconfig'
|
7
|
+
|
8
|
+
basedir = Pathname( __FILE__ ).dirname.parent
|
9
|
+
libdir = basedir + 'lib'
|
10
|
+
archlib = libdir + Config::CONFIG['sitearch']
|
11
|
+
|
12
|
+
$LOAD_PATH.unshift( libdir.to_s ) unless $LOAD_PATH.include?( libdir.to_s )
|
13
|
+
$LOAD_PATH.unshift( archlib.to_s ) unless $LOAD_PATH.include?( archlib.to_s )
|
14
|
+
}
|
3
15
|
|
4
|
-
$LOAD_PATH.unshift('ext')
|
5
16
|
require 'pg'
|
6
17
|
|
18
|
+
require 'rubygems'
|
19
|
+
require 'spec'
|
20
|
+
require 'spec/lib/helpers'
|
21
|
+
require 'timeout'
|
22
|
+
|
7
23
|
describe PGconn do
|
24
|
+
include PgTestingHelpers
|
8
25
|
|
9
26
|
before( :all ) do
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
end
|
16
|
-
@port = 54321
|
17
|
-
@conninfo = "host=localhost port=#{@port} dbname=test"
|
18
|
-
Dir.mkdir(@test_directory)
|
19
|
-
Dir.mkdir(@test_pgdata)
|
20
|
-
cmds = []
|
21
|
-
cmds << "initdb -D \"#{@test_pgdata}\""
|
22
|
-
cmds << "pg_ctl -o \"-p #{@port}\" -D \"#{@test_pgdata}\" start"
|
23
|
-
cmds << "sleep 5"
|
24
|
-
cmds << "createdb -p #{@port} test"
|
25
|
-
|
26
|
-
cmds.each do |cmd|
|
27
|
-
if not system(cmd) then
|
28
|
-
raise "Error executing cmd: #{cmd}: #{$?}"
|
29
|
-
end
|
30
|
-
end
|
31
|
-
@conn = PGconn.connect(@conninfo)
|
27
|
+
@conn = setup_testing_db( "PGconn" )
|
28
|
+
end
|
29
|
+
|
30
|
+
before( :each ) do
|
31
|
+
@conn.exec( 'BEGIN' )
|
32
32
|
end
|
33
33
|
|
34
|
+
|
34
35
|
it "should connect successfully with connection string" do
|
35
36
|
tmpconn = PGconn.connect(@conninfo)
|
36
37
|
tmpconn.status.should== PGconn::CONNECTION_OK
|
@@ -86,7 +87,6 @@ describe PGconn do
|
|
86
87
|
# be careful to explicitly close files so that the
|
87
88
|
# directory can be removed and we don't have to wait for
|
88
89
|
# the GC to run.
|
89
|
-
|
90
90
|
expected_trace_file = File.join(Dir.getwd, "spec/data", "expected_trace.out")
|
91
91
|
expected_trace_data = open(expected_trace_file, 'rb').read
|
92
92
|
trace_file = open(File.join(@test_directory, "test_trace.out"), 'wb')
|
@@ -101,7 +101,7 @@ describe PGconn do
|
|
101
101
|
trace_data.should == expected_trace_data
|
102
102
|
end
|
103
103
|
end
|
104
|
-
|
104
|
+
|
105
105
|
it "should cancel a query" do
|
106
106
|
error = false
|
107
107
|
@conn.send_query("SELECT pg_sleep(1000)")
|
@@ -113,18 +113,179 @@ describe PGconn do
|
|
113
113
|
error.should == true
|
114
114
|
end
|
115
115
|
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
116
|
+
it "should not read past the end of a large object" do
|
117
|
+
@conn.transaction do
|
118
|
+
oid = @conn.lo_create( 0 )
|
119
|
+
fd = @conn.lo_open( oid, PGconn::INV_READ|PGconn::INV_WRITE )
|
120
|
+
@conn.lo_write( fd, "foobar" )
|
121
|
+
@conn.lo_read( fd, 10 ).should be_nil()
|
122
|
+
@conn.lo_lseek( fd, 0, PGconn::SEEK_SET )
|
123
|
+
@conn.lo_read( fd, 10 ).should == 'foobar'
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
|
128
|
+
it "should wait for NOTIFY events via select()" do
|
129
|
+
@conn.exec( 'ROLLBACK' )
|
130
|
+
@conn.exec( 'LISTEN woo' )
|
131
|
+
|
132
|
+
pid = fork do
|
133
|
+
conn = PGconn.connect( @conninfo )
|
134
|
+
sleep 1
|
135
|
+
conn.exec( 'NOTIFY woo' )
|
136
|
+
conn.finish
|
137
|
+
exit!
|
138
|
+
end
|
139
|
+
|
140
|
+
@conn.wait_for_notify( 10 ).should == 'woo'
|
141
|
+
@conn.exec( 'UNLISTEN woo' )
|
142
|
+
|
143
|
+
Process.wait( pid )
|
144
|
+
end
|
145
|
+
|
146
|
+
it "yields the result if block is given to exec" do
|
147
|
+
rval = @conn.exec( "select 1234::int as a union select 5678::int as a" ) do |result|
|
148
|
+
values = []
|
149
|
+
result.should be_kind_of( PGresult )
|
150
|
+
result.ntuples.should == 2
|
151
|
+
result.each do |tuple|
|
152
|
+
values << tuple['a']
|
153
|
+
end
|
154
|
+
values
|
155
|
+
end
|
156
|
+
|
157
|
+
rval.should have( 2 ).members
|
158
|
+
rval.should include( '5678', '1234' )
|
159
|
+
end
|
160
|
+
|
161
|
+
|
162
|
+
it "correctly finishes COPY queries passed to #async_exec" do
|
163
|
+
@conn.async_exec( "COPY (SELECT 1 UNION ALL SELECT 2) TO STDOUT" )
|
164
|
+
|
165
|
+
results = []
|
166
|
+
begin
|
167
|
+
data = @conn.get_copy_data( true )
|
168
|
+
if false == data
|
169
|
+
@conn.block( 2.0 )
|
170
|
+
data = @conn.get_copy_data( true )
|
125
171
|
end
|
172
|
+
results << data if data
|
173
|
+
end until data.nil?
|
174
|
+
|
175
|
+
results.should have( 2 ).members
|
176
|
+
results.should include( "1\n", "2\n" )
|
177
|
+
end
|
178
|
+
|
179
|
+
|
180
|
+
it "PGconn#block shouldn't block a second thread" do
|
181
|
+
t = Thread.new do
|
182
|
+
@conn.send_query( "select pg_sleep(3)" )
|
183
|
+
@conn.block
|
126
184
|
end
|
127
|
-
|
128
|
-
|
185
|
+
|
186
|
+
# :FIXME: There's a race here, but hopefully it's pretty small.
|
187
|
+
t.should be_alive()
|
188
|
+
|
189
|
+
@conn.cancel
|
190
|
+
t.join
|
191
|
+
end
|
192
|
+
|
193
|
+
it "PGconn#block should allow a timeout" do
|
194
|
+
@conn.send_query( "select pg_sleep(3)" )
|
195
|
+
|
196
|
+
start = Time.now
|
197
|
+
@conn.block( 0.1 )
|
198
|
+
finish = Time.now
|
199
|
+
|
200
|
+
(finish - start).should be_close( 0.1, 0.05 )
|
201
|
+
end
|
202
|
+
|
203
|
+
|
204
|
+
it "can encrypt a string given a password and username" do
|
205
|
+
PGconn.encrypt_password("postgres", "postgres").
|
206
|
+
should =~ /\S+/
|
207
|
+
end
|
208
|
+
|
209
|
+
|
210
|
+
it "raises an appropriate error if either of the required arguments for encrypt_password " +
|
211
|
+
"is not valid" do
|
212
|
+
expect {
|
213
|
+
PGconn.encrypt_password( nil, nil )
|
214
|
+
}.to raise_error( TypeError )
|
215
|
+
expect {
|
216
|
+
PGconn.encrypt_password( "postgres", nil )
|
217
|
+
}.to raise_error( TypeError )
|
218
|
+
expect {
|
219
|
+
PGconn.encrypt_password( nil, "postgres" )
|
220
|
+
}.to raise_error( TypeError )
|
221
|
+
end
|
222
|
+
|
223
|
+
|
224
|
+
it "allows fetching a column of values from a result by column number" do
|
225
|
+
res = @conn.exec( 'VALUES (1,2),(2,3),(3,4)' )
|
226
|
+
res.column_values( 0 ).should == %w[1 2 3]
|
227
|
+
res.column_values( 1 ).should == %w[2 3 4]
|
228
|
+
end
|
229
|
+
|
230
|
+
|
231
|
+
it "allows fetching a column of values from a result by field name" do
|
232
|
+
res = @conn.exec( 'VALUES (1,2),(2,3),(3,4)' )
|
233
|
+
res.field_values( 'column1' ).should == %w[1 2 3]
|
234
|
+
res.field_values( 'column2' ).should == %w[2 3 4]
|
235
|
+
end
|
236
|
+
|
237
|
+
|
238
|
+
it "raises an error if selecting an invalid column index" do
|
239
|
+
res = @conn.exec( 'VALUES (1,2),(2,3),(3,4)' )
|
240
|
+
expect {
|
241
|
+
res.column_values( 20 )
|
242
|
+
}.to raise_error( IndexError )
|
243
|
+
end
|
244
|
+
|
245
|
+
|
246
|
+
it "raises an error if selecting an invalid field name" do
|
247
|
+
res = @conn.exec( 'VALUES (1,2),(2,3),(3,4)' )
|
248
|
+
expect {
|
249
|
+
res.field_values( 'hUUuurrg' )
|
250
|
+
}.to raise_error( IndexError )
|
251
|
+
end
|
252
|
+
|
253
|
+
|
254
|
+
it "raises an error if column index is not a number" do
|
255
|
+
res = @conn.exec( 'VALUES (1,2),(2,3),(3,4)' )
|
256
|
+
expect {
|
257
|
+
res.column_values( 'hUUuurrg' )
|
258
|
+
}.to raise_error( TypeError )
|
259
|
+
end
|
260
|
+
|
261
|
+
|
262
|
+
it "can connect asynchronously" do
|
263
|
+
serv = TCPServer.new( '127.0.0.1', 54320 )
|
264
|
+
conn = PGconn.connect_start( '127.0.0.1', 54320, "", "", "me", "xxxx", "somedb" )
|
265
|
+
conn.connect_poll.should == PGconn::PGRES_POLLING_WRITING
|
266
|
+
select( nil, [IO.for_fd(conn.socket)], nil, 0.2 )
|
267
|
+
serv.close
|
268
|
+
if conn.connect_poll == PGconn::PGRES_POLLING_READING
|
269
|
+
select( [IO.for_fd(conn.socket)], nil, nil, 0.2 )
|
270
|
+
end
|
271
|
+
conn.connect_poll.should == PGconn::PGRES_POLLING_FAILED
|
272
|
+
end
|
273
|
+
|
274
|
+
it "discards previous results (if any) before waiting on an #async_exec"
|
275
|
+
|
276
|
+
it "calls the block if one is provided to #async_exec" do
|
277
|
+
result = nil
|
278
|
+
@conn.async_exec( "select 47 as one" ) do |pg_res|
|
279
|
+
result = pg_res[0]
|
280
|
+
end
|
281
|
+
result.should == { 'one' => '47' }
|
282
|
+
end
|
283
|
+
|
284
|
+
after( :each ) do
|
285
|
+
@conn.exec( 'ROLLBACK' )
|
286
|
+
end
|
287
|
+
|
288
|
+
after( :all ) do
|
289
|
+
teardown_testing_db( @conn )
|
129
290
|
end
|
130
291
|
end
|
data/spec/pgresult_spec.rb
CHANGED
@@ -1,37 +1,36 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
#!/usr/bin/env spec
|
2
|
+
# encoding: utf-8
|
3
|
+
|
4
|
+
BEGIN {
|
5
|
+
require 'pathname'
|
6
|
+
require 'rbconfig'
|
7
|
+
|
8
|
+
basedir = Pathname( __FILE__ ).dirname.parent
|
9
|
+
libdir = basedir + 'lib'
|
10
|
+
archlib = libdir + Config::CONFIG['sitearch']
|
11
|
+
|
12
|
+
$LOAD_PATH.unshift( libdir.to_s ) unless $LOAD_PATH.include?( libdir.to_s )
|
13
|
+
$LOAD_PATH.unshift( archlib.to_s ) unless $LOAD_PATH.include?( archlib.to_s )
|
14
|
+
}
|
3
15
|
|
4
|
-
$LOAD_PATH.unshift('ext')
|
5
16
|
require 'pg'
|
6
17
|
|
7
|
-
|
18
|
+
require 'rubygems'
|
19
|
+
require 'spec'
|
20
|
+
require 'spec/lib/helpers'
|
21
|
+
|
22
|
+
describe PGresult do
|
23
|
+
include PgTestingHelpers
|
8
24
|
|
9
25
|
before( :all ) do
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
end
|
16
|
-
@port = 54321
|
17
|
-
@conninfo = "host=localhost port=#{@port} dbname=test"
|
18
|
-
Dir.mkdir(@test_directory)
|
19
|
-
Dir.mkdir(@test_pgdata)
|
20
|
-
cmds = []
|
21
|
-
cmds << "initdb -D \"#{@test_pgdata}\""
|
22
|
-
cmds << "pg_ctl -o \"-p #{@port}\" -D \"#{@test_pgdata}\" start"
|
23
|
-
cmds << "sleep 5"
|
24
|
-
cmds << "createdb -p #{@port} test"
|
25
|
-
|
26
|
-
cmds.each do |cmd|
|
27
|
-
if not system(cmd) then
|
28
|
-
raise "Error executing cmd: #{cmd}: #{$?}"
|
29
|
-
end
|
30
|
-
end
|
31
|
-
puts "\n\n"
|
32
|
-
@conn = PGconn.connect(@conninfo)
|
26
|
+
@conn = setup_testing_db( "PGresult" )
|
27
|
+
end
|
28
|
+
|
29
|
+
before( :each ) do
|
30
|
+
@conn.exec( 'BEGIN' )
|
33
31
|
end
|
34
32
|
|
33
|
+
|
35
34
|
it "should act as an array of hashes" do
|
36
35
|
res = @conn.exec("SELECT 1 AS a, 2 AS b")
|
37
36
|
res[0]['a'].should== '1'
|
@@ -66,12 +65,10 @@ describe PGconn do
|
|
66
65
|
binary_file = File.join(Dir.pwd, 'spec/data', 'random_binary_data')
|
67
66
|
in_bytes = File.open(binary_file, 'rb').read
|
68
67
|
out_bytes = nil
|
69
|
-
@conn.
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
end
|
74
|
-
out_bytes.should== in_bytes
|
68
|
+
@conn.exec("SET standard_conforming_strings=on")
|
69
|
+
res = @conn.exec("VALUES ('#{PGconn.escape_bytea(in_bytes)}'::bytea)", [], 1)
|
70
|
+
out_bytes = res[0]['column1']
|
71
|
+
out_bytes.should == in_bytes
|
75
72
|
end
|
76
73
|
|
77
74
|
it "should return the same bytes in text format that are sent in binary format" do
|
@@ -87,26 +84,135 @@ describe PGconn do
|
|
87
84
|
in_bytes = File.open(binary_file, 'rb').read
|
88
85
|
|
89
86
|
out_bytes = nil
|
90
|
-
@conn.
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
87
|
+
@conn.exec("SET standard_conforming_strings=on")
|
88
|
+
res = @conn.exec("VALUES ('#{PGconn.escape_bytea(in_bytes)}'::bytea)", [], 0)
|
89
|
+
out_bytes = PGconn.unescape_bytea(res[0]['column1'])
|
90
|
+
out_bytes.should == in_bytes
|
91
|
+
end
|
92
|
+
|
93
|
+
it "should return the parameter type of the specified prepared statment parameter" do
|
94
|
+
query = 'SELECT * FROM pg_stat_activity WHERE user = $1::name AND current_query = $2::text'
|
95
|
+
@conn.prepare( 'queryfinder', query )
|
96
|
+
res = @conn.describe_prepared( 'queryfinder' )
|
97
|
+
|
98
|
+
@conn.exec( 'SELECT format_type($1, -1)', [res.paramtype(0)] ).getvalue( 0, 0 ).
|
99
|
+
should == 'name'
|
100
|
+
@conn.exec( 'SELECT format_type($1, -1)', [res.paramtype(1)] ).getvalue( 0, 0 ).
|
101
|
+
should == 'text'
|
102
|
+
end
|
103
|
+
|
104
|
+
it "should raise an exception when a negative index is given to #fformat" do
|
105
|
+
res = @conn.exec('SELECT * FROM pg_stat_activity')
|
106
|
+
expect {
|
107
|
+
res.fformat( -1 )
|
108
|
+
}.to raise_error( ArgumentError, /column number/i )
|
109
|
+
end
|
110
|
+
|
111
|
+
it "should raise an exception when a negative index is given to #fmod" do
|
112
|
+
res = @conn.exec('SELECT * FROM pg_stat_activity')
|
113
|
+
expect {
|
114
|
+
res.fmod( -1 )
|
115
|
+
}.to raise_error( ArgumentError, /column number/i )
|
116
|
+
end
|
117
|
+
|
118
|
+
it "should raise an exception when a negative index is given to #[]" do
|
119
|
+
res = @conn.exec('SELECT * FROM pg_stat_activity')
|
120
|
+
expect {
|
121
|
+
res[ -1 ]
|
122
|
+
}.to raise_error( IndexError, /-1 is out of range/i )
|
123
|
+
end
|
124
|
+
|
125
|
+
# PQfmod
|
126
|
+
it "can return the type modifier for a result column" do
|
127
|
+
@conn.exec( 'CREATE TABLE fmodtest ( foo varchar(33) )' )
|
128
|
+
res = @conn.exec( 'SELECT * FROM fmodtest' )
|
129
|
+
res.fmod( 0 ).should == 33 + 4 # Column length + varlena size (4)
|
130
|
+
end
|
131
|
+
|
132
|
+
it "should raise an exception when an invalid index is passed to PGresult#fmod" do
|
133
|
+
@conn.exec( 'CREATE TABLE fmodtest ( foo varchar(33) )' )
|
134
|
+
res = @conn.exec( 'SELECT * FROM fmodtest' )
|
135
|
+
expect { res.fmod(1) }.to raise_error( ArgumentError )
|
136
|
+
end
|
137
|
+
|
138
|
+
it "should raise an exception when an invalid (negative) index is passed to PGresult#fmod" do
|
139
|
+
@conn.exec( 'CREATE TABLE fmodtest ( foo varchar(33) )' )
|
140
|
+
res = @conn.exec( 'SELECT * FROM fmodtest' )
|
141
|
+
expect { res.fmod(-11) }.to raise_error( ArgumentError )
|
142
|
+
end
|
143
|
+
|
144
|
+
it "shouldn't raise an exception when a valid index is passed to PGresult#fmod for a column with no typemod" do
|
145
|
+
@conn.exec( 'CREATE TABLE fmodtest ( foo text )' )
|
146
|
+
res = @conn.exec( 'SELECT * FROM fmodtest' )
|
147
|
+
res.fmod( 0 ).should == -1 # and it shouldn't raise an exception, either
|
148
|
+
end
|
149
|
+
|
150
|
+
# PQftable
|
151
|
+
it "can return the oid of the table from which a result column was fetched" do
|
152
|
+
@conn.exec( 'CREATE TABLE ftabletest ( foo text )' )
|
153
|
+
res = @conn.exec( 'SELECT * FROM ftabletest' )
|
154
|
+
|
155
|
+
res.ftable( 0 ).should == be_nonzero()
|
156
|
+
end
|
157
|
+
|
158
|
+
it "should raise an exception when an invalid index is passed to PGresult#ftable" do
|
159
|
+
@conn.exec( 'CREATE TABLE ftabletest ( foo text )' )
|
160
|
+
res = @conn.exec( 'SELECT * FROM ftabletest' )
|
161
|
+
|
162
|
+
expect { res.ftable(18) }.to raise_error( ArgumentError )
|
163
|
+
end
|
164
|
+
|
165
|
+
it "should raise an exception when an invalid (negative) index is passed to PGresult#ftable" do
|
166
|
+
@conn.exec( 'CREATE TABLE ftabletest ( foo text )' )
|
167
|
+
res = @conn.exec( 'SELECT * FROM ftabletest' )
|
168
|
+
|
169
|
+
expect { res.ftable(-2) }.to raise_error( ArgumentError )
|
170
|
+
end
|
171
|
+
|
172
|
+
it "shouldn't raise an exception when a valid index is passed to PGresult#ftable for a " +
|
173
|
+
"column with no corresponding table" do
|
174
|
+
@conn.exec( 'CREATE TABLE ftabletest ( foo text )' )
|
175
|
+
res = @conn.exec( 'SELECT foo, LENGTH(foo) as length FROM ftabletest' )
|
176
|
+
res.ftable( 1 ).should == PGresult::InvalidOid # and it shouldn't raise an exception, either
|
177
|
+
end
|
178
|
+
|
179
|
+
# PQftablecol
|
180
|
+
it "can return the column number (within its table) of a column in a result" do
|
181
|
+
@conn.exec( 'CREATE TABLE ftablecoltest ( foo text, bar numeric )' )
|
182
|
+
res = @conn.exec( 'SELECT * FROM ftablecoltest' )
|
183
|
+
|
184
|
+
res.ftablecol( 0 ).should == 1
|
185
|
+
res.ftablecol( 1 ).should == 2
|
186
|
+
end
|
187
|
+
|
188
|
+
it "should raise an exception when an invalid index is passed to PGresult#ftablecol" do
|
189
|
+
@conn.exec( 'CREATE TABLE ftablecoltest ( foo text, bar numeric )' )
|
190
|
+
res = @conn.exec( 'SELECT * FROM ftablecoltest' )
|
191
|
+
|
192
|
+
expect { res.ftablecol(32) }.to raise_error( ArgumentError )
|
193
|
+
end
|
194
|
+
|
195
|
+
it "should raise an exception when an invalid (negative) index is passed to PGresult#ftablecol" do
|
196
|
+
@conn.exec( 'CREATE TABLE ftablecoltest ( foo text, bar numeric )' )
|
197
|
+
res = @conn.exec( 'SELECT * FROM ftablecoltest' )
|
198
|
+
|
199
|
+
expect { res.ftablecol(-1) }.to raise_error( ArgumentError )
|
200
|
+
end
|
201
|
+
|
202
|
+
it "shouldn't raise an exception when a valid index is passed to PGresult#ftablecol for a " +
|
203
|
+
"column with no corresponding table" do
|
204
|
+
@conn.exec( 'CREATE TABLE ftablecoltest ( foo text )' )
|
205
|
+
res = @conn.exec( 'SELECT foo, LENGTH(foo) as length FROM ftablecoltest' )
|
206
|
+
res.ftablecol(1).should == 0 # and it shouldn't raise an exception, either
|
207
|
+
end
|
208
|
+
|
209
|
+
|
210
|
+
|
211
|
+
after( :each ) do
|
212
|
+
@conn.exec( 'ROLLBACK' )
|
96
213
|
end
|
97
214
|
|
98
215
|
after( :all ) do
|
99
|
-
|
100
|
-
@conn.finish
|
101
|
-
cmds = []
|
102
|
-
cmds << "pg_ctl -D \"#{@test_pgdata}\" stop"
|
103
|
-
cmds << "rm -rf \"#{@test_directory}\""
|
104
|
-
cmds.each do |cmd|
|
105
|
-
if not system(cmd) then
|
106
|
-
raise "Error executing cmd: #{cmd}: #{$?}"
|
107
|
-
end
|
108
|
-
end
|
109
|
-
puts "====== COMPLETED TESTING PGresult ======"
|
110
|
-
puts ""
|
216
|
+
teardown_testing_db( @conn )
|
111
217
|
end
|
112
218
|
end
|