pg 0.12.2-x86-mingw32 → 0.13.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/.hoerc +2 -0
- data/.tm_properties +12 -0
- data/ChangeLog +166 -59
- data/Contributors.rdoc +7 -0
- data/History.rdoc +29 -0
- data/LICENSE +12 -14
- data/Manifest.txt +15 -14
- data/{BSD → POSTGRES} +0 -0
- data/{README.OS_X.rdoc → README-OS_X.rdoc} +0 -0
- data/{README.windows.rdoc → README-Windows.rdoc} +0 -0
- data/README.ja.rdoc +1 -1
- data/README.rdoc +39 -27
- data/Rakefile +1 -5
- data/Rakefile.cross +2 -2
- data/ext/extconf.rb +8 -2
- data/ext/pg.c +232 -4297
- data/ext/pg.h +88 -23
- data/ext/pg_connection.c +3288 -0
- data/ext/pg_result.c +905 -0
- data/lib/1.8/pg_ext.so +0 -0
- data/lib/1.9/pg_ext.so +0 -0
- data/lib/pg.rb +26 -43
- data/lib/pg/connection.rb +58 -0
- data/lib/pg/constants.rb +11 -0
- data/lib/pg/exceptions.rb +11 -0
- data/lib/pg/result.rb +11 -0
- data/misc/openssl-pg-segfault.rb +1 -1
- data/sample/async_api.rb +16 -21
- data/sample/async_copyto.rb +1 -1
- data/sample/async_mixed.rb +56 -0
- data/sample/copyfrom.rb +1 -1
- data/sample/copyto.rb +1 -1
- data/sample/cursor.rb +1 -1
- data/sample/losample.rb +6 -6
- data/sample/notify_wait.rb +51 -22
- data/sample/test_binary_values.rb +4 -6
- data/spec/lib/helpers.rb +14 -10
- data/spec/{pgconn_spec.rb → pg/connection_spec.rb} +228 -60
- data/spec/{pgresult_spec.rb → pg/result_spec.rb} +31 -35
- data/spec/pg_spec.rb +22 -0
- metadata +52 -41
- data/GPL +0 -340
- data/ext/compat.c +0 -541
- data/ext/compat.h +0 -184
- data/sample/psql.rb +0 -1181
- data/sample/psqlHelp.rb +0 -158
- data/sample/test1.rb +0 -60
- data/sample/test2.rb +0 -44
- data/sample/test4.rb +0 -71
- data/spec/m17n_spec.rb +0 -170
@@ -2,18 +2,16 @@
|
|
2
2
|
|
3
3
|
require 'pg'
|
4
4
|
|
5
|
-
|
6
|
-
|
7
|
-
db = PGconn.connect( connhash )
|
5
|
+
db = PG.connect( :dbname => 'test' )
|
8
6
|
db.exec "DROP TABLE IF EXISTS test"
|
9
7
|
db.exec "CREATE TABLE test (a INTEGER, b BYTEA)"
|
10
8
|
|
11
9
|
a = 42
|
12
10
|
b = [1, 2, 3]
|
13
|
-
db.exec "INSERT INTO test(a, b) VALUES($1::int, $2::bytea)",
|
14
|
-
[a, {:value => b.pack('N*'), :format => 1}]
|
11
|
+
db.exec "INSERT INTO test(a, b) VALUES($1::int, $2::bytea)",
|
12
|
+
[a, {:value => b.pack('N*'), :format => 1}]
|
15
13
|
|
16
|
-
db.exec "SELECT a::int, b::bytea FROM test LIMIT 1", [], 1 do |res|
|
14
|
+
db.exec( "SELECT a::int, b::bytea FROM test LIMIT 1", [], 1 ) do |res|
|
17
15
|
|
18
16
|
res.nfields.times do |i|
|
19
17
|
puts "Field %d is: %s, a %s (%s) column from table %p" % [
|
data/spec/lib/helpers.rb
CHANGED
@@ -3,17 +3,11 @@
|
|
3
3
|
require 'pathname'
|
4
4
|
require 'rspec'
|
5
5
|
require 'shellwords'
|
6
|
+
require 'pg'
|
6
7
|
|
7
8
|
TEST_DIRECTORY = Pathname.getwd + "tmp_test_specs"
|
8
9
|
|
9
|
-
|
10
|
-
ruby_version_vec = RUBY_VERSION.split('.').map {|c| c.to_i }.pack( "N*" )
|
11
|
-
|
12
|
-
config.mock_with :rspec
|
13
|
-
config.filter_run_excluding :ruby_19 => true if ruby_version_vec <= [1,9,1].pack( "N*" )
|
14
|
-
end
|
15
|
-
|
16
|
-
module PgTestingHelpers
|
10
|
+
module PG::TestingHelpers
|
17
11
|
|
18
12
|
|
19
13
|
# Set some ANSI escape code constants (Shamelessly stolen from Perl's
|
@@ -202,7 +196,7 @@ module PgTestingHelpers
|
|
202
196
|
unless (@test_pgdata+"postgresql.conf").exist?
|
203
197
|
FileUtils.rm_rf( @test_pgdata, :verbose => $DEBUG )
|
204
198
|
$stderr.puts "Running initdb"
|
205
|
-
log_and_run @logfile, 'initdb', '--no-locale', '-D', @test_pgdata.to_s
|
199
|
+
log_and_run @logfile, 'initdb', '-E', 'UTF8', '--no-locale', '-D', @test_pgdata.to_s
|
206
200
|
end
|
207
201
|
|
208
202
|
trace "Starting postgres"
|
@@ -221,7 +215,7 @@ module PgTestingHelpers
|
|
221
215
|
fail
|
222
216
|
end
|
223
217
|
|
224
|
-
conn =
|
218
|
+
conn = PG.connect( @conninfo )
|
225
219
|
conn.set_notice_processor do |message|
|
226
220
|
$stderr.puts( message ) if $DEBUG
|
227
221
|
end
|
@@ -238,3 +232,13 @@ module PgTestingHelpers
|
|
238
232
|
end
|
239
233
|
|
240
234
|
|
235
|
+
RSpec.configure do |config|
|
236
|
+
ruby_version_vec = RUBY_VERSION.split('.').map {|c| c.to_i }.pack( "N*" )
|
237
|
+
|
238
|
+
config.include( PG::TestingHelpers )
|
239
|
+
config.treat_symbols_as_metadata_keys_with_true_values = true
|
240
|
+
|
241
|
+
config.mock_with :rspec
|
242
|
+
config.filter_run_excluding :ruby_19 => true if ruby_version_vec <= [1,9,1].pack( "N*" )
|
243
|
+
end
|
244
|
+
|
@@ -1,38 +1,33 @@
|
|
1
1
|
#!/usr/bin/env rspec
|
2
|
-
#
|
2
|
+
#encoding: utf-8
|
3
3
|
|
4
4
|
BEGIN {
|
5
5
|
require 'pathname'
|
6
|
-
require 'rbconfig'
|
7
6
|
|
8
|
-
basedir = Pathname( __FILE__ ).dirname.parent
|
7
|
+
basedir = Pathname( __FILE__ ).dirname.parent.parent
|
9
8
|
libdir = basedir + 'lib'
|
10
|
-
archlib = libdir + Config::CONFIG['sitearch']
|
11
9
|
|
12
10
|
$LOAD_PATH.unshift( basedir.to_s ) unless $LOAD_PATH.include?( basedir.to_s )
|
13
11
|
$LOAD_PATH.unshift( libdir.to_s ) unless $LOAD_PATH.include?( libdir.to_s )
|
14
|
-
$LOAD_PATH.unshift( archlib.to_s ) unless $LOAD_PATH.include?( archlib.to_s )
|
15
12
|
}
|
16
13
|
|
17
14
|
require 'rspec'
|
18
15
|
require 'spec/lib/helpers'
|
19
|
-
require 'pg'
|
20
16
|
require 'timeout'
|
17
|
+
require 'pg'
|
21
18
|
|
22
|
-
describe
|
23
|
-
include PgTestingHelpers
|
24
|
-
|
19
|
+
describe PG::Connection do
|
25
20
|
|
26
21
|
before( :all ) do
|
27
|
-
@conn = setup_testing_db( "
|
22
|
+
@conn = setup_testing_db( "PG_Connection" )
|
28
23
|
end
|
29
24
|
|
30
25
|
before( :each ) do
|
31
|
-
@conn.exec( 'BEGIN' )
|
26
|
+
@conn.exec( 'BEGIN' ) unless example.metadata[:without_transaction]
|
32
27
|
end
|
33
28
|
|
34
29
|
after( :each ) do
|
35
|
-
@conn.exec( 'ROLLBACK' )
|
30
|
+
@conn.exec( 'ROLLBACK' ) unless example.metadata[:without_transaction]
|
36
31
|
end
|
37
32
|
|
38
33
|
after( :all ) do
|
@@ -45,7 +40,7 @@ describe PGconn do
|
|
45
40
|
#
|
46
41
|
|
47
42
|
it "can create a connection option string from a Hash of options" do
|
48
|
-
optstring =
|
43
|
+
optstring = described_class.parse_connect_args(
|
49
44
|
:host => 'pgsql.example.com',
|
50
45
|
:dbname => 'db01',
|
51
46
|
'sslmode' => 'require'
|
@@ -58,7 +53,7 @@ describe PGconn do
|
|
58
53
|
end
|
59
54
|
|
60
55
|
it "can create a connection option string from positional parameters" do
|
61
|
-
optstring =
|
56
|
+
optstring = described_class.parse_connect_args( 'pgsql.example.com', nil, '-c geqo=off', nil,
|
62
57
|
'sales' )
|
63
58
|
|
64
59
|
optstring.should be_a( String )
|
@@ -71,7 +66,7 @@ describe PGconn do
|
|
71
66
|
end
|
72
67
|
|
73
68
|
it "can create a connection option string from a mix of positional and hash parameters" do
|
74
|
-
optstring =
|
69
|
+
optstring = described_class.parse_connect_args( 'pgsql.example.com',
|
75
70
|
:dbname => 'licensing', :user => 'jrandom' )
|
76
71
|
|
77
72
|
optstring.should be_a( String )
|
@@ -81,64 +76,94 @@ describe PGconn do
|
|
81
76
|
end
|
82
77
|
|
83
78
|
it "escapes single quotes and backslashes in connection parameters" do
|
84
|
-
|
79
|
+
described_class.parse_connect_args( "DB 'browser' \\" ).should == "host='DB \\'browser\\' \\\\'"
|
85
80
|
|
86
81
|
end
|
87
82
|
|
88
83
|
it "connects with defaults if no connection parameters are given" do
|
89
|
-
|
84
|
+
described_class.parse_connect_args.should == ''
|
90
85
|
end
|
91
86
|
|
92
87
|
it "connects successfully with connection string" do
|
93
|
-
tmpconn =
|
94
|
-
tmpconn.status.should==
|
88
|
+
tmpconn = described_class.connect(@conninfo)
|
89
|
+
tmpconn.status.should== PG::CONNECTION_OK
|
95
90
|
tmpconn.finish
|
96
91
|
end
|
97
92
|
|
98
93
|
it "connects using 7 arguments converted to strings" do
|
99
|
-
tmpconn =
|
100
|
-
tmpconn.status.should==
|
94
|
+
tmpconn = described_class.connect('localhost', @port, nil, nil, :test, nil, nil)
|
95
|
+
tmpconn.status.should== PG::CONNECTION_OK
|
101
96
|
tmpconn.finish
|
102
97
|
end
|
103
98
|
|
104
99
|
it "connects using a hash of connection parameters" do
|
105
|
-
tmpconn =
|
100
|
+
tmpconn = described_class.connect(
|
106
101
|
:host => 'localhost',
|
107
102
|
:port => @port,
|
108
103
|
:dbname => :test)
|
109
|
-
tmpconn.status.should==
|
104
|
+
tmpconn.status.should== PG::CONNECTION_OK
|
110
105
|
tmpconn.finish
|
111
106
|
end
|
112
107
|
|
113
108
|
it "raises an exception when connecting with an invalid number of arguments" do
|
114
109
|
expect {
|
115
|
-
|
110
|
+
described_class.connect( 1, 2, 3, 4, 5, 6, 7, 'extra' )
|
116
111
|
}.to raise_error( ArgumentError, /extra positional parameter/i )
|
117
112
|
end
|
118
113
|
|
119
114
|
|
120
115
|
it "can connect asynchronously" do
|
121
|
-
tmpconn =
|
122
|
-
|
116
|
+
tmpconn = described_class.connect_start( @conninfo )
|
117
|
+
tmpconn.should be_a( described_class )
|
118
|
+
socket = IO.for_fd( tmpconn.socket )
|
123
119
|
status = tmpconn.connect_poll
|
124
|
-
|
125
|
-
|
126
|
-
|
120
|
+
|
121
|
+
while status != PG::PGRES_POLLING_OK
|
122
|
+
if status == PG::PGRES_POLLING_READING
|
123
|
+
select( [socket], [], [], 5.0 ) or
|
127
124
|
raise "Asynchronous connection timed out!"
|
128
|
-
|
129
|
-
elsif
|
130
|
-
|
125
|
+
|
126
|
+
elsif status == PG::PGRES_POLLING_WRITING
|
127
|
+
select( [], [socket], [], 5.0 ) or
|
131
128
|
raise "Asynchronous connection timed out!"
|
132
|
-
end
|
133
129
|
end
|
134
130
|
status = tmpconn.connect_poll
|
135
131
|
end
|
136
|
-
|
132
|
+
|
133
|
+
tmpconn.status.should == PG::CONNECTION_OK
|
137
134
|
tmpconn.finish
|
138
135
|
end
|
139
136
|
|
137
|
+
it "can connect asynchronously for the duration of a block" do
|
138
|
+
conn = nil
|
139
|
+
|
140
|
+
described_class.connect_start(@conninfo) do |tmpconn|
|
141
|
+
tmpconn.should be_a( described_class )
|
142
|
+
conn = tmpconn
|
143
|
+
socket = IO.for_fd(tmpconn.socket)
|
144
|
+
status = tmpconn.connect_poll
|
145
|
+
|
146
|
+
while status != PG::PGRES_POLLING_OK
|
147
|
+
if status == PG::PGRES_POLLING_READING
|
148
|
+
if(not select([socket],[],[],5.0))
|
149
|
+
raise "Asynchronous connection timed out!"
|
150
|
+
end
|
151
|
+
elsif(status == PG::PGRES_POLLING_WRITING)
|
152
|
+
if(not select([],[socket],[],5.0))
|
153
|
+
raise "Asynchronous connection timed out!"
|
154
|
+
end
|
155
|
+
end
|
156
|
+
status = tmpconn.connect_poll
|
157
|
+
end
|
158
|
+
|
159
|
+
tmpconn.status.should == PG::CONNECTION_OK
|
160
|
+
end
|
161
|
+
|
162
|
+
conn.should be_finished()
|
163
|
+
end
|
164
|
+
|
140
165
|
it "doesn't leave stale server connections after finish" do
|
141
|
-
|
166
|
+
described_class.connect(@conninfo).finish
|
142
167
|
sleep 0.5
|
143
168
|
res = @conn.exec(%[SELECT COUNT(*) AS n FROM pg_stat_activity
|
144
169
|
WHERE usename IS NOT NULL])
|
@@ -213,13 +238,13 @@ describe PGconn do
|
|
213
238
|
@conn.send_query("SELECT pg_sleep(1000)")
|
214
239
|
@conn.cancel
|
215
240
|
tmpres = @conn.get_result
|
216
|
-
if(tmpres.result_status !=
|
241
|
+
if(tmpres.result_status != PG::PGRES_TUPLES_OK)
|
217
242
|
error = true
|
218
243
|
end
|
219
244
|
error.should == true
|
220
245
|
end
|
221
246
|
|
222
|
-
it "automatically rolls back a transaction started with
|
247
|
+
it "automatically rolls back a transaction started with described_class#transaction if an exception " +
|
223
248
|
"is raised" do
|
224
249
|
# abort the per-example transaction so we can test our own
|
225
250
|
@conn.exec( 'ROLLBACK' )
|
@@ -241,10 +266,10 @@ describe PGconn do
|
|
241
266
|
it "not read past the end of a large object" do
|
242
267
|
@conn.transaction do
|
243
268
|
oid = @conn.lo_create( 0 )
|
244
|
-
fd = @conn.lo_open( oid,
|
269
|
+
fd = @conn.lo_open( oid, PG::INV_READ|PG::INV_WRITE )
|
245
270
|
@conn.lo_write( fd, "foobar" )
|
246
271
|
@conn.lo_read( fd, 10 ).should be_nil()
|
247
|
-
@conn.lo_lseek( fd, 0,
|
272
|
+
@conn.lo_lseek( fd, 0, PG::SEEK_SET )
|
248
273
|
@conn.lo_read( fd, 10 ).should == 'foobar'
|
249
274
|
end
|
250
275
|
end
|
@@ -256,7 +281,7 @@ describe PGconn do
|
|
256
281
|
|
257
282
|
pid = fork do
|
258
283
|
begin
|
259
|
-
conn =
|
284
|
+
conn = described_class.connect( @conninfo )
|
260
285
|
sleep 1
|
261
286
|
conn.exec( 'NOTIFY woo' )
|
262
287
|
ensure
|
@@ -277,7 +302,7 @@ describe PGconn do
|
|
277
302
|
|
278
303
|
pid = fork do
|
279
304
|
begin
|
280
|
-
conn =
|
305
|
+
conn = described_class.connect( @conninfo )
|
281
306
|
sleep 1
|
282
307
|
conn.exec( 'NOTIFY woo' )
|
283
308
|
ensure
|
@@ -304,7 +329,7 @@ describe PGconn do
|
|
304
329
|
|
305
330
|
pid = fork do
|
306
331
|
begin
|
307
|
-
conn =
|
332
|
+
conn = described_class.connect( @conninfo )
|
308
333
|
conn.exec( 'NOTIFY woo' )
|
309
334
|
conn.exec( 'NOTIFY war' )
|
310
335
|
conn.exec( 'NOTIFY woz' )
|
@@ -336,7 +361,7 @@ describe PGconn do
|
|
336
361
|
|
337
362
|
pid = fork do
|
338
363
|
begin
|
339
|
-
conn =
|
364
|
+
conn = described_class.connect( @conninfo )
|
340
365
|
conn.exec( 'NOTIFY woo' )
|
341
366
|
ensure
|
342
367
|
conn.finish
|
@@ -367,7 +392,7 @@ describe PGconn do
|
|
367
392
|
@conn.exec( 'LISTEN knees' )
|
368
393
|
|
369
394
|
pid = fork do
|
370
|
-
conn =
|
395
|
+
conn = described_class.connect( @conninfo )
|
371
396
|
conn.exec( %Q{NOTIFY knees, 'skirt and boots'} )
|
372
397
|
conn.finish
|
373
398
|
exit!
|
@@ -391,7 +416,7 @@ describe PGconn do
|
|
391
416
|
@conn.exec( 'LISTEN knees' )
|
392
417
|
|
393
418
|
pid = fork do
|
394
|
-
conn =
|
419
|
+
conn = described_class.connect( @conninfo )
|
395
420
|
conn.exec( %Q{NOTIFY knees} )
|
396
421
|
conn.finish
|
397
422
|
exit!
|
@@ -414,7 +439,7 @@ describe PGconn do
|
|
414
439
|
@conn.exec( 'LISTEN knees' )
|
415
440
|
|
416
441
|
pid = fork do
|
417
|
-
conn =
|
442
|
+
conn = described_class.connect( @conninfo )
|
418
443
|
conn.exec( %Q{NOTIFY knees} )
|
419
444
|
conn.finish
|
420
445
|
exit!
|
@@ -438,7 +463,7 @@ describe PGconn do
|
|
438
463
|
@conn.exec( 'LISTEN knees' )
|
439
464
|
|
440
465
|
pid = fork do
|
441
|
-
conn =
|
466
|
+
conn = described_class.connect( @conninfo )
|
442
467
|
conn.exec( %Q{NOTIFY knees, 'skirt and boots'} )
|
443
468
|
conn.finish
|
444
469
|
exit!
|
@@ -464,7 +489,7 @@ describe PGconn do
|
|
464
489
|
@conn.exec( 'LISTEN knees' )
|
465
490
|
|
466
491
|
pid = fork do
|
467
|
-
conn =
|
492
|
+
conn = described_class.connect( @conninfo )
|
468
493
|
conn.exec( %Q{NOTIFY knees, 'skirt and boots'} )
|
469
494
|
conn.finish
|
470
495
|
exit!
|
@@ -488,7 +513,7 @@ describe PGconn do
|
|
488
513
|
@conn.exec( 'LISTEN knees' )
|
489
514
|
|
490
515
|
pid = fork do
|
491
|
-
conn =
|
516
|
+
conn = described_class.connect( @conninfo )
|
492
517
|
conn.exec( %Q{NOTIFY knees, 'skirt and boots'} )
|
493
518
|
conn.finish
|
494
519
|
exit!
|
@@ -512,7 +537,7 @@ describe PGconn do
|
|
512
537
|
it "yields the result if block is given to exec" do
|
513
538
|
rval = @conn.exec( "select 1234::int as a union select 5678::int as a" ) do |result|
|
514
539
|
values = []
|
515
|
-
result.should be_kind_of(
|
540
|
+
result.should be_kind_of( PG::Result )
|
516
541
|
result.ntuples.should == 2
|
517
542
|
result.each do |tuple|
|
518
543
|
values << tuple['a']
|
@@ -543,7 +568,7 @@ describe PGconn do
|
|
543
568
|
end
|
544
569
|
|
545
570
|
|
546
|
-
it "
|
571
|
+
it "described_class#block shouldn't block a second thread" do
|
547
572
|
t = Thread.new do
|
548
573
|
@conn.send_query( "select pg_sleep(3)" )
|
549
574
|
@conn.block
|
@@ -556,7 +581,7 @@ describe PGconn do
|
|
556
581
|
t.join
|
557
582
|
end
|
558
583
|
|
559
|
-
it "
|
584
|
+
it "described_class#block should allow a timeout" do
|
560
585
|
@conn.send_query( "select pg_sleep(3)" )
|
561
586
|
|
562
587
|
start = Time.now
|
@@ -568,7 +593,7 @@ describe PGconn do
|
|
568
593
|
|
569
594
|
|
570
595
|
it "can encrypt a string given a password and username" do
|
571
|
-
|
596
|
+
described_class.encrypt_password("postgres", "postgres").
|
572
597
|
should =~ /\S+/
|
573
598
|
end
|
574
599
|
|
@@ -576,13 +601,13 @@ describe PGconn do
|
|
576
601
|
it "raises an appropriate error if either of the required arguments for encrypt_password " +
|
577
602
|
"is not valid" do
|
578
603
|
expect {
|
579
|
-
|
604
|
+
described_class.encrypt_password( nil, nil )
|
580
605
|
}.to raise_error( TypeError )
|
581
606
|
expect {
|
582
|
-
|
607
|
+
described_class.encrypt_password( "postgres", nil )
|
583
608
|
}.to raise_error( TypeError )
|
584
609
|
expect {
|
585
|
-
|
610
|
+
described_class.encrypt_password( nil, "postgres" )
|
586
611
|
}.to raise_error( TypeError )
|
587
612
|
end
|
588
613
|
|
@@ -627,14 +652,14 @@ describe PGconn do
|
|
627
652
|
|
628
653
|
it "can connect asynchronously" do
|
629
654
|
serv = TCPServer.new( '127.0.0.1', 54320 )
|
630
|
-
conn =
|
631
|
-
conn.connect_poll.should ==
|
655
|
+
conn = described_class.connect_start( '127.0.0.1', 54320, "", "", "me", "xxxx", "somedb" )
|
656
|
+
conn.connect_poll.should == PG::PGRES_POLLING_WRITING
|
632
657
|
select( nil, [IO.for_fd(conn.socket)], nil, 0.2 )
|
633
658
|
serv.close
|
634
|
-
if conn.connect_poll ==
|
659
|
+
if conn.connect_poll == PG::PGRES_POLLING_READING
|
635
660
|
select( [IO.for_fd(conn.socket)], nil, nil, 0.2 )
|
636
661
|
end
|
637
|
-
conn.connect_poll.should ==
|
662
|
+
conn.connect_poll.should == PG::PGRES_POLLING_FAILED
|
638
663
|
end
|
639
664
|
|
640
665
|
it "discards previous results (if any) before waiting on an #async_exec"
|
@@ -647,4 +672,147 @@ describe PGconn do
|
|
647
672
|
result.should == { 'one' => '47' }
|
648
673
|
end
|
649
674
|
|
675
|
+
|
676
|
+
describe "multinationalization support", :ruby_19 => true do
|
677
|
+
|
678
|
+
it "should return the same bytes in text format that are sent as inline text" do
|
679
|
+
binary_file = File.join(Dir.pwd, 'spec/data', 'random_binary_data')
|
680
|
+
in_bytes = File.open(binary_file, 'r:ASCII-8BIT').read
|
681
|
+
escaped_bytes = described_class.escape_bytea( in_bytes )
|
682
|
+
out_bytes = nil
|
683
|
+
|
684
|
+
@conn.transaction do |conn|
|
685
|
+
conn.exec("SET standard_conforming_strings=on")
|
686
|
+
res = conn.exec("VALUES ('#{escaped_bytes}'::bytea)", [], 0)
|
687
|
+
out_bytes = described_class.unescape_bytea( res[0]['column1'] )
|
688
|
+
end
|
689
|
+
|
690
|
+
out_bytes.should == in_bytes
|
691
|
+
end
|
692
|
+
|
693
|
+
describe "rubyforge #22925: m17n support" do
|
694
|
+
it "should return results in the same encoding as the client (iso-8859-1)" do
|
695
|
+
out_string = nil
|
696
|
+
@conn.transaction do |conn|
|
697
|
+
conn.internal_encoding = 'iso8859-1'
|
698
|
+
res = conn.exec("VALUES ('fantasia')", [], 0)
|
699
|
+
out_string = res[0]['column1']
|
700
|
+
end
|
701
|
+
out_string.should == 'fantasia'
|
702
|
+
out_string.encoding.should == Encoding::ISO8859_1
|
703
|
+
end
|
704
|
+
|
705
|
+
it "should return results in the same encoding as the client (utf-8)" do
|
706
|
+
out_string = nil
|
707
|
+
@conn.transaction do |conn|
|
708
|
+
conn.internal_encoding = 'utf-8'
|
709
|
+
res = conn.exec("VALUES ('世界線航跡蔵')", [], 0)
|
710
|
+
out_string = res[0]['column1']
|
711
|
+
end
|
712
|
+
out_string.should == '世界線航跡蔵'
|
713
|
+
out_string.encoding.should == Encoding::UTF_8
|
714
|
+
end
|
715
|
+
|
716
|
+
it "should return results in the same encoding as the client (EUC-JP)" do
|
717
|
+
out_string = nil
|
718
|
+
@conn.transaction do |conn|
|
719
|
+
conn.internal_encoding = 'EUC-JP'
|
720
|
+
stmt = "VALUES ('世界線航跡蔵')".encode('EUC-JP')
|
721
|
+
res = conn.exec(stmt, [], 0)
|
722
|
+
out_string = res[0]['column1']
|
723
|
+
end
|
724
|
+
out_string.should == '世界線航跡蔵'.encode('EUC-JP')
|
725
|
+
out_string.encoding.should == Encoding::EUC_JP
|
726
|
+
end
|
727
|
+
|
728
|
+
it "returns the results in the correct encoding even if the client_encoding has " +
|
729
|
+
"changed since the results were fetched" do
|
730
|
+
out_string = nil
|
731
|
+
@conn.transaction do |conn|
|
732
|
+
conn.internal_encoding = 'EUC-JP'
|
733
|
+
stmt = "VALUES ('世界線航跡蔵')".encode('EUC-JP')
|
734
|
+
res = conn.exec(stmt, [], 0)
|
735
|
+
conn.internal_encoding = 'utf-8'
|
736
|
+
out_string = res[0]['column1']
|
737
|
+
end
|
738
|
+
out_string.should == '世界線航跡蔵'.encode('EUC-JP')
|
739
|
+
out_string.encoding.should == Encoding::EUC_JP
|
740
|
+
end
|
741
|
+
|
742
|
+
it "the connection should return ASCII-8BIT when it's set to SQL_ASCII" do
|
743
|
+
@conn.exec "SET client_encoding TO SQL_ASCII"
|
744
|
+
@conn.internal_encoding.should == Encoding::ASCII_8BIT
|
745
|
+
end
|
746
|
+
|
747
|
+
it "works around the unsupported JOHAB encoding by returning stuff in 'ASCII_8BIT'" do
|
748
|
+
pending "figuring out how to create a string in the JOHAB encoding" do
|
749
|
+
out_string = nil
|
750
|
+
@conn.transaction do |conn|
|
751
|
+
conn.exec( "set client_encoding = 'JOHAB';" )
|
752
|
+
stmt = "VALUES ('foo')".encode('JOHAB')
|
753
|
+
res = conn.exec( stmt, [], 0 )
|
754
|
+
out_string = res[0]['column1']
|
755
|
+
end
|
756
|
+
out_string.should == 'foo'.encode( Encoding::ASCII_8BIT )
|
757
|
+
out_string.encoding.should == Encoding::ASCII_8BIT
|
758
|
+
end
|
759
|
+
end
|
760
|
+
|
761
|
+
it "uses the client encoding for escaped string" do
|
762
|
+
original = "string to escape".force_encoding( "euc-jp" )
|
763
|
+
@conn.set_client_encoding( "euc_jp" )
|
764
|
+
escaped = @conn.escape( original )
|
765
|
+
escaped.encoding.should == Encoding::EUC_JP
|
766
|
+
end
|
767
|
+
end
|
768
|
+
|
769
|
+
|
770
|
+
describe "Ruby 1.9.x default_internal encoding" do
|
771
|
+
|
772
|
+
it "honors the Encoding.default_internal if it's set and the synchronous interface is used" do
|
773
|
+
@conn.transaction do |txn_conn|
|
774
|
+
txn_conn.internal_encoding = Encoding::ISO8859_1
|
775
|
+
txn_conn.exec( "CREATE TABLE defaultinternaltest ( foo text )" )
|
776
|
+
txn_conn.exec( "INSERT INTO defaultinternaltest VALUES ('Grün und Weiß')" )
|
777
|
+
end
|
778
|
+
|
779
|
+
begin
|
780
|
+
prev_encoding = Encoding.default_internal
|
781
|
+
Encoding.default_internal = Encoding::UTF_8
|
782
|
+
|
783
|
+
conn = PG.connect( @conninfo )
|
784
|
+
conn.internal_encoding.should == Encoding::UTF_8
|
785
|
+
res = conn.exec( "SELECT foo FROM defaultinternaltest" )
|
786
|
+
res[0]['foo'].encoding.should == Encoding::UTF_8
|
787
|
+
ensure
|
788
|
+
conn.finish if conn
|
789
|
+
Encoding.default_internal = prev_encoding
|
790
|
+
end
|
791
|
+
end
|
792
|
+
|
793
|
+
end
|
794
|
+
|
795
|
+
|
796
|
+
it "encodes exception messages with the connection's encoding (#96)", :without_transaction do
|
797
|
+
# Use a new connection so the client_encoding isn't set outside of this example
|
798
|
+
conn = PG.connect( @conninfo )
|
799
|
+
conn.client_encoding = 'iso-8859-15'
|
800
|
+
|
801
|
+
conn.transaction do
|
802
|
+
conn.exec "CREATE TABLE foo (bar TEXT)"
|
803
|
+
|
804
|
+
begin
|
805
|
+
query = "INSERT INTO foo VALUES ('Côte d'Ivoire')".encode( 'iso-8859-15' )
|
806
|
+
conn.exec( query )
|
807
|
+
rescue => err
|
808
|
+
err.message.encoding.should == Encoding::ISO8859_15
|
809
|
+
else
|
810
|
+
fail "No exception raised?!"
|
811
|
+
end
|
812
|
+
end
|
813
|
+
|
814
|
+
conn.finish if conn
|
815
|
+
end
|
816
|
+
|
817
|
+
end
|
650
818
|
end
|