pg 0.17.1 → 0.17.2.pre.546
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.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +0 -0
- data.tar.gz.sig +0 -0
- data/Manifest.txt +1 -1
- data/Rakefile +4 -2
- data/ext/pg_connection.c +2 -2
- data/ext/pg_result.c +10 -10
- data/lib/pg.rb +1 -1
- data/spec/{lib/helpers.rb → helpers.rb} +41 -38
- data/spec/pg/connection_spec.rb +171 -205
- data/spec/pg/result_spec.rb +94 -116
- data/spec/pg_spec.rb +10 -18
- metadata +59 -45
- metadata.gz.sig +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 637de7550ad54596f1d2296e620abf62627bfd15
|
4
|
+
data.tar.gz: 7ddb6d5c72f909b0378360011aa13c020f0d88cf
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ce2fa474c1921e469990bdb6c99a2bd73a0568197946639850f6d1da126acb8d7e36137b78f156417fbc46f63f42e6d0cae61301127ce05954818a58be4e5d23
|
7
|
+
data.tar.gz: 9525dd2c6a8805c0aaca253c3cf497533a7077e466bdf2ea0c25ecf1c0d47e4053639766d73cbfad548d5b8568453e82b83e73280f0f9dc552eee379a850c37b
|
checksums.yaml.gz.sig
CHANGED
Binary file
|
data.tar.gz.sig
CHANGED
Binary file
|
data/Manifest.txt
CHANGED
data/Rakefile
CHANGED
@@ -53,14 +53,16 @@ $hoespec = Hoe.spec 'pg' do
|
|
53
53
|
self.extra_rdoc_files = Rake::FileList[ '*.rdoc' ]
|
54
54
|
self.extra_rdoc_files.include( 'POSTGRES', 'LICENSE' )
|
55
55
|
self.extra_rdoc_files.include( 'ext/*.c' )
|
56
|
+
self.license :BSD
|
56
57
|
|
57
58
|
self.developer 'Michael Granger', 'ged@FaerieMUD.org'
|
58
59
|
self.developer 'Lars Kanis', 'lars@greiz-reinsdorf.de'
|
59
60
|
|
60
61
|
self.dependency 'rake-compiler', '~> 0.9', :developer
|
61
|
-
self.dependency 'hoe', '~> 3.
|
62
|
-
self.dependency 'hoe-deveiate', '~> 0.
|
62
|
+
self.dependency 'hoe', '~> 3.12', :developer
|
63
|
+
self.dependency 'hoe-deveiate', '~> 0.6', :developer
|
63
64
|
self.dependency 'hoe-bundler', '~> 1.0', :developer
|
65
|
+
self.dependency 'rspec', '~> 3.0', :developer
|
64
66
|
|
65
67
|
self.spec_extras[:licenses] = ['BSD', 'Ruby', 'GPL']
|
66
68
|
self.spec_extras[:extensions] = [ 'ext/extconf.rb' ]
|
data/ext/pg_connection.c
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
/*
|
2
2
|
* pg_connection.c - PG::Connection class extension
|
3
|
-
* $Id: pg_connection.c,v
|
3
|
+
* $Id: pg_connection.c,v 6c2444dc63e1 2013/12/30 16:49:29 lars $
|
4
4
|
*
|
5
5
|
*/
|
6
6
|
|
@@ -1522,7 +1522,7 @@ pgconn_escape_identifier(VALUE self, VALUE string)
|
|
1522
1522
|
* Then call Connection#get_result repeatedly, until it returns nil.
|
1523
1523
|
*
|
1524
1524
|
* Each (but the last) received Result has exactly one row and a
|
1525
|
-
* Result#result_status of PGRES_SINGLE_TUPLE. The last
|
1525
|
+
* Result#result_status of PGRES_SINGLE_TUPLE. The last Result has
|
1526
1526
|
* zero rows and is used to indicate a successful execution of the query.
|
1527
1527
|
* All of these Result objects will contain the same row description data
|
1528
1528
|
* (column names, types, etc) that an ordinary Result object for the query
|
data/ext/pg_result.c
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
/*
|
2
2
|
* pg_result.c - PG::Result class extension
|
3
|
-
* $Id: pg_result.c,v
|
3
|
+
* $Id: pg_result.c,v 738d4c4125a1 2014/07/23 18:10:52 mina $
|
4
4
|
*
|
5
5
|
*/
|
6
6
|
|
@@ -299,7 +299,7 @@ pgresult_ntuples(VALUE self)
|
|
299
299
|
|
300
300
|
/*
|
301
301
|
* call-seq:
|
302
|
-
* res.nfields() ->
|
302
|
+
* res.nfields() -> Integer
|
303
303
|
*
|
304
304
|
* Returns the number of columns in the query result.
|
305
305
|
*/
|
@@ -370,7 +370,7 @@ pgresult_fnumber(VALUE self, VALUE name)
|
|
370
370
|
|
371
371
|
/*
|
372
372
|
* call-seq:
|
373
|
-
* res.ftable( column_number ) ->
|
373
|
+
* res.ftable( column_number ) -> Integer
|
374
374
|
*
|
375
375
|
* Returns the Oid of the table from which the column _column_number_
|
376
376
|
* was fetched.
|
@@ -389,7 +389,7 @@ pgresult_ftable(VALUE self, VALUE column_number)
|
|
389
389
|
rb_raise(rb_eArgError,"Invalid column index: %d", col_number);
|
390
390
|
|
391
391
|
n = PQftable(pgresult, col_number);
|
392
|
-
return
|
392
|
+
return UINT2NUM(n);
|
393
393
|
}
|
394
394
|
|
395
395
|
/*
|
@@ -440,7 +440,7 @@ pgresult_fformat(VALUE self, VALUE column_number)
|
|
440
440
|
|
441
441
|
/*
|
442
442
|
* call-seq:
|
443
|
-
* res.ftype( column_number )
|
443
|
+
* res.ftype( column_number ) -> Integer
|
444
444
|
*
|
445
445
|
* Returns the data type associated with _column_number_.
|
446
446
|
*
|
@@ -464,7 +464,7 @@ pgresult_ftype(VALUE self, VALUE index)
|
|
464
464
|
if (i < 0 || i >= PQnfields(result)) {
|
465
465
|
rb_raise(rb_eArgError, "invalid field number %d", i);
|
466
466
|
}
|
467
|
-
return
|
467
|
+
return UINT2NUM(PQftype(result, i));
|
468
468
|
}
|
469
469
|
|
470
470
|
/*
|
@@ -640,7 +640,7 @@ pgresult_paramtype(VALUE self, VALUE param_number)
|
|
640
640
|
PGresult *result;
|
641
641
|
|
642
642
|
result = pgresult_get(self);
|
643
|
-
return
|
643
|
+
return UINT2NUM(PQparamtype(result,NUM2INT(param_number)));
|
644
644
|
}
|
645
645
|
|
646
646
|
/*
|
@@ -659,7 +659,7 @@ pgresult_cmd_status(VALUE self)
|
|
659
659
|
|
660
660
|
/*
|
661
661
|
* call-seq:
|
662
|
-
* res.cmd_tuples() ->
|
662
|
+
* res.cmd_tuples() -> Integer
|
663
663
|
*
|
664
664
|
* Returns the number of tuples (rows) affected by the SQL command.
|
665
665
|
*
|
@@ -681,7 +681,7 @@ pgresult_cmd_tuples(VALUE self)
|
|
681
681
|
|
682
682
|
/*
|
683
683
|
* call-seq:
|
684
|
-
* res.oid_value() ->
|
684
|
+
* res.oid_value() -> Integer
|
685
685
|
*
|
686
686
|
* Returns the +oid+ of the inserted row if applicable,
|
687
687
|
* otherwise +nil+.
|
@@ -693,7 +693,7 @@ pgresult_oid_value(VALUE self)
|
|
693
693
|
if (n == InvalidOid)
|
694
694
|
return Qnil;
|
695
695
|
else
|
696
|
-
return
|
696
|
+
return UINT2NUM(n);
|
697
697
|
}
|
698
698
|
|
699
699
|
/* Utility methods not in libpq */
|
data/lib/pg.rb
CHANGED
@@ -9,6 +9,38 @@ TEST_DIRECTORY = Pathname.getwd + "tmp_test_specs"
|
|
9
9
|
|
10
10
|
module PG::TestingHelpers
|
11
11
|
|
12
|
+
### Automatically set up the database when it's used, and wrap a transaction around
|
13
|
+
### examples that don't disable it.
|
14
|
+
def self::included( mod )
|
15
|
+
super
|
16
|
+
|
17
|
+
if mod.respond_to?( :around )
|
18
|
+
|
19
|
+
mod.before( :all ) { @conn = setup_testing_db(described_class.name) }
|
20
|
+
|
21
|
+
mod.around( :each ) do |example|
|
22
|
+
begin
|
23
|
+
@conn.exec( 'BEGIN' ) unless example.metadata[:without_transaction]
|
24
|
+
if PG.respond_to?( :library_version )
|
25
|
+
desc = example.source_location.join(':')
|
26
|
+
@conn.exec_params %Q{SET application_name TO '%s'} %
|
27
|
+
[@conn.escape_string(desc.slice(-60))]
|
28
|
+
end
|
29
|
+
example.run
|
30
|
+
ensure
|
31
|
+
@conn.exec( 'ROLLBACK' ) unless example.metadata[:without_transaction]
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
mod.after( :all ) { teardown_testing_db(@conn) }
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
39
|
+
|
40
|
+
|
41
|
+
#
|
42
|
+
# Examples
|
43
|
+
#
|
12
44
|
|
13
45
|
# Set some ANSI escape code constants (Shamelessly stolen from Perl's
|
14
46
|
# Term::ANSIColor by Russ Allbery <rra@stanford.edu> and Zenin <zenin@best.com>
|
@@ -121,28 +153,9 @@ module PG::TestingHelpers
|
|
121
153
|
end
|
122
154
|
|
123
155
|
# Eliminate the noise of creating/tearing down the database by
|
124
|
-
# redirecting STDERR/STDOUT to a logfile
|
125
|
-
# supports fork()
|
156
|
+
# redirecting STDERR/STDOUT to a logfile
|
126
157
|
logfh = File.open( logpath, File::WRONLY|File::CREAT|File::APPEND )
|
127
|
-
|
128
|
-
pid = fork
|
129
|
-
rescue NotImplementedError
|
130
|
-
logfh.close
|
131
|
-
system( *cmd )
|
132
|
-
else
|
133
|
-
if pid
|
134
|
-
logfh.close
|
135
|
-
else
|
136
|
-
$stdout.reopen( logfh )
|
137
|
-
$stderr.reopen( $stdout )
|
138
|
-
$stderr.puts( ">>> " + cmd.shelljoin )
|
139
|
-
exec( *cmd )
|
140
|
-
$stderr.puts "After the exec()?!??!"
|
141
|
-
exit!
|
142
|
-
end
|
143
|
-
|
144
|
-
Process.wait( pid )
|
145
|
-
end
|
158
|
+
system( *cmd, [STDOUT, STDERR] => logfh )
|
146
159
|
|
147
160
|
raise "Command failed: [%s]" % [cmd.join(' ')] unless $?.success?
|
148
161
|
end
|
@@ -248,29 +261,19 @@ module PG::TestingHelpers
|
|
248
261
|
end
|
249
262
|
end
|
250
263
|
|
251
|
-
def connection_string_should_contain_application_name(conn_args, app_name)
|
252
|
-
conn_name = conn_args.match(/application_name='(.*)'/)[1]
|
253
|
-
conn_name.should include(app_name[0..10])
|
254
|
-
conn_name.should include(app_name[-10..-1])
|
255
|
-
conn_name.length.should <= 64
|
256
|
-
end
|
257
|
-
|
258
|
-
# Ensure the connection is in a clean execution status.
|
259
|
-
def verify_clean_exec_status
|
260
|
-
@conn.send_query( "VALUES (1)" )
|
261
|
-
@conn.get_last_result.values.should == [["1"]]
|
262
|
-
end
|
263
264
|
end
|
264
265
|
|
265
266
|
|
266
267
|
RSpec.configure do |config|
|
267
|
-
ruby_version_vec = RUBY_VERSION.split('.').map {|c| c.to_i }.pack( "N*" )
|
268
|
-
|
269
268
|
config.include( PG::TestingHelpers )
|
270
|
-
config.treat_symbols_as_metadata_keys_with_true_values = true
|
271
269
|
|
272
|
-
config.
|
273
|
-
config.
|
270
|
+
config.run_all_when_everything_filtered = true
|
271
|
+
config.filter_run :focus
|
272
|
+
config.order = 'random'
|
273
|
+
config.mock_with( :rspec ) do |mock|
|
274
|
+
mock.syntax = :expect
|
275
|
+
end
|
276
|
+
|
274
277
|
if RUBY_PLATFORM =~ /mingw|mswin/
|
275
278
|
config.filter_run_excluding :unix
|
276
279
|
else
|
data/spec/pg/connection_spec.rb
CHANGED
@@ -1,49 +1,14 @@
|
|
1
1
|
#!/usr/bin/env rspec
|
2
2
|
#encoding: utf-8
|
3
3
|
|
4
|
-
|
5
|
-
require 'pathname'
|
4
|
+
require_relative '../helpers'
|
6
5
|
|
7
|
-
basedir = Pathname( __FILE__ ).dirname.parent.parent
|
8
|
-
libdir = basedir + 'lib'
|
9
|
-
|
10
|
-
$LOAD_PATH.unshift( basedir.to_s ) unless $LOAD_PATH.include?( basedir.to_s )
|
11
|
-
$LOAD_PATH.unshift( libdir.to_s ) unless $LOAD_PATH.include?( libdir.to_s )
|
12
|
-
}
|
13
|
-
|
14
|
-
require 'rspec'
|
15
|
-
require 'spec/lib/helpers'
|
16
6
|
require 'timeout'
|
17
7
|
require 'socket'
|
18
8
|
require 'pg'
|
19
9
|
|
20
10
|
describe PG::Connection do
|
21
11
|
|
22
|
-
before( :all ) do
|
23
|
-
@conn = setup_testing_db( described_class.name )
|
24
|
-
end
|
25
|
-
|
26
|
-
before( :each ) do
|
27
|
-
@conn.exec( 'BEGIN' ) unless example.metadata[:without_transaction]
|
28
|
-
if PG.respond_to?( :library_version )
|
29
|
-
@conn.exec_params %Q{SET application_name TO '%s'} %
|
30
|
-
[@conn.escape_string(example.description[0,60])]
|
31
|
-
end
|
32
|
-
end
|
33
|
-
|
34
|
-
after( :each ) do
|
35
|
-
@conn.exec( 'ROLLBACK' ) unless example.metadata[:without_transaction]
|
36
|
-
end
|
37
|
-
|
38
|
-
after( :all ) do
|
39
|
-
teardown_testing_db( @conn )
|
40
|
-
end
|
41
|
-
|
42
|
-
|
43
|
-
#
|
44
|
-
# Examples
|
45
|
-
#
|
46
|
-
|
47
12
|
it "can create a connection option string from a Hash of options" do
|
48
13
|
optstring = described_class.parse_connect_args(
|
49
14
|
:host => 'pgsql.example.com',
|
@@ -51,54 +16,55 @@ describe PG::Connection do
|
|
51
16
|
'sslmode' => 'require'
|
52
17
|
)
|
53
18
|
|
54
|
-
optstring.
|
55
|
-
optstring.
|
56
|
-
optstring.
|
57
|
-
optstring.
|
19
|
+
expect( optstring ).to be_a( String )
|
20
|
+
expect( optstring ).to match( /(^|\s)host='pgsql.example.com'/ )
|
21
|
+
expect( optstring ).to match( /(^|\s)dbname='db01'/ )
|
22
|
+
expect( optstring ).to match( /(^|\s)sslmode='require'/ )
|
58
23
|
end
|
59
24
|
|
60
25
|
it "can create a connection option string from positional parameters" do
|
61
26
|
optstring = described_class.parse_connect_args( 'pgsql.example.com', nil, '-c geqo=off', nil,
|
62
27
|
'sales' )
|
63
28
|
|
64
|
-
optstring.
|
65
|
-
optstring.
|
66
|
-
optstring.
|
67
|
-
optstring.
|
29
|
+
expect( optstring ).to be_a( String )
|
30
|
+
expect( optstring ).to match( /(^|\s)host='pgsql.example.com'/ )
|
31
|
+
expect( optstring ).to match( /(^|\s)dbname='sales'/ )
|
32
|
+
expect( optstring ).to match( /(^|\s)options='-c geqo=off'/ )
|
68
33
|
|
69
|
-
optstring.
|
70
|
-
optstring.
|
34
|
+
expect( optstring ).to_not match( /port=/ )
|
35
|
+
expect( optstring ).to_not match( /tty=/ )
|
71
36
|
end
|
72
37
|
|
73
38
|
it "can create a connection option string from a mix of positional and hash parameters" do
|
74
39
|
optstring = described_class.parse_connect_args( 'pgsql.example.com',
|
75
40
|
:dbname => 'licensing', :user => 'jrandom' )
|
76
41
|
|
77
|
-
optstring.
|
78
|
-
optstring.
|
79
|
-
optstring.
|
80
|
-
optstring.
|
42
|
+
expect( optstring ).to be_a( String )
|
43
|
+
expect( optstring ).to match( /(^|\s)host='pgsql.example.com'/ )
|
44
|
+
expect( optstring ).to match( /(^|\s)dbname='licensing'/ )
|
45
|
+
expect( optstring ).to match( /(^|\s)user='jrandom'/ )
|
81
46
|
end
|
82
47
|
|
83
48
|
it "escapes single quotes and backslashes in connection parameters" do
|
84
|
-
|
85
|
-
|
49
|
+
expect(
|
50
|
+
described_class.parse_connect_args( "DB 'browser' \\" )
|
51
|
+
).to match( /host='DB \\'browser\\' \\\\'/ )
|
86
52
|
|
87
53
|
end
|
88
54
|
|
89
55
|
it "connects with defaults if no connection parameters are given" do
|
90
|
-
described_class.parse_connect_args.
|
56
|
+
expect( described_class.parse_connect_args ).to eq( '' )
|
91
57
|
end
|
92
58
|
|
93
59
|
it "connects successfully with connection string" do
|
94
60
|
tmpconn = described_class.connect(@conninfo)
|
95
|
-
tmpconn.status.
|
61
|
+
expect( tmpconn.status ).to eq( PG::CONNECTION_OK )
|
96
62
|
tmpconn.finish
|
97
63
|
end
|
98
64
|
|
99
65
|
it "connects using 7 arguments converted to strings" do
|
100
66
|
tmpconn = described_class.connect('localhost', @port, nil, nil, :test, nil, nil)
|
101
|
-
tmpconn.status.
|
67
|
+
expect( tmpconn.status ).to eq( PG::CONNECTION_OK )
|
102
68
|
tmpconn.finish
|
103
69
|
end
|
104
70
|
|
@@ -107,7 +73,7 @@ describe PG::Connection do
|
|
107
73
|
:host => 'localhost',
|
108
74
|
:port => @port,
|
109
75
|
:dbname => :test)
|
110
|
-
tmpconn.status.
|
76
|
+
expect( tmpconn.status ).to eq( PG::CONNECTION_OK )
|
111
77
|
tmpconn.finish
|
112
78
|
end
|
113
79
|
|
@@ -117,7 +83,7 @@ describe PG::Connection do
|
|
117
83
|
:port => @port,
|
118
84
|
:dbname => :test,
|
119
85
|
:keepalives => 1)
|
120
|
-
tmpconn.status.
|
86
|
+
expect( tmpconn.status ).to eq( PG::CONNECTION_OK )
|
121
87
|
tmpconn.finish
|
122
88
|
end
|
123
89
|
|
@@ -129,7 +95,7 @@ describe PG::Connection do
|
|
129
95
|
|
130
96
|
it "can connect asynchronously", :socket_io do
|
131
97
|
tmpconn = described_class.connect_start( @conninfo )
|
132
|
-
tmpconn.
|
98
|
+
expect( tmpconn ).to be_a( described_class )
|
133
99
|
socket = tmpconn.socket_io
|
134
100
|
status = tmpconn.connect_poll
|
135
101
|
|
@@ -145,7 +111,7 @@ describe PG::Connection do
|
|
145
111
|
status = tmpconn.connect_poll
|
146
112
|
end
|
147
113
|
|
148
|
-
tmpconn.status.
|
114
|
+
expect( tmpconn.status ).to eq( PG::CONNECTION_OK )
|
149
115
|
tmpconn.finish
|
150
116
|
end
|
151
117
|
|
@@ -153,7 +119,7 @@ describe PG::Connection do
|
|
153
119
|
conn = nil
|
154
120
|
|
155
121
|
described_class.connect_start(@conninfo) do |tmpconn|
|
156
|
-
tmpconn.
|
122
|
+
expect( tmpconn ).to be_a( described_class )
|
157
123
|
conn = tmpconn
|
158
124
|
socket = tmpconn.socket_io
|
159
125
|
status = tmpconn.connect_poll
|
@@ -171,10 +137,10 @@ describe PG::Connection do
|
|
171
137
|
status = tmpconn.connect_poll
|
172
138
|
end
|
173
139
|
|
174
|
-
tmpconn.status.
|
140
|
+
expect( tmpconn.status ).to eq( PG::CONNECTION_OK )
|
175
141
|
end
|
176
142
|
|
177
|
-
conn.
|
143
|
+
expect( conn ).to be_finished()
|
178
144
|
end
|
179
145
|
|
180
146
|
it "raises proper error when sending fails" do
|
@@ -188,7 +154,7 @@ describe PG::Connection do
|
|
188
154
|
res = @conn.exec(%[SELECT COUNT(*) AS n FROM pg_stat_activity
|
189
155
|
WHERE usename IS NOT NULL])
|
190
156
|
# there's still the global @conn, but should be no more
|
191
|
-
res[0]['n'].
|
157
|
+
expect( res[0]['n'] ).to eq( '1' )
|
192
158
|
end
|
193
159
|
|
194
160
|
|
@@ -248,7 +214,7 @@ describe PG::Connection do
|
|
248
214
|
expected_trace_output.sub!( /From backend> "SELECT 1"/, 'From backend> "SELECT"' )
|
249
215
|
end
|
250
216
|
|
251
|
-
trace_data.
|
217
|
+
expect( trace_data ).to eq( expected_trace_output )
|
252
218
|
end
|
253
219
|
|
254
220
|
it "allows a query to be cancelled" do
|
@@ -259,7 +225,7 @@ describe PG::Connection do
|
|
259
225
|
if(tmpres.result_status != PG::PGRES_TUPLES_OK)
|
260
226
|
error = true
|
261
227
|
end
|
262
|
-
error.
|
228
|
+
expect( error ).to eq( true )
|
263
229
|
end
|
264
230
|
|
265
231
|
it "can stop a thread that runs a blocking query with async_exec" do
|
@@ -271,7 +237,7 @@ describe PG::Connection do
|
|
271
237
|
|
272
238
|
t.kill
|
273
239
|
t.join
|
274
|
-
(Time.now - start).
|
240
|
+
expect( (Time.now - start) ).to be < 10
|
275
241
|
end
|
276
242
|
|
277
243
|
it "should work together with signal handlers" do
|
@@ -285,7 +251,7 @@ describe PG::Connection do
|
|
285
251
|
Process.kill("USR1", Process.pid)
|
286
252
|
end
|
287
253
|
@conn.exec("select pg_sleep(0.3)")
|
288
|
-
signal_received.
|
254
|
+
expect( signal_received ).to be_truthy
|
289
255
|
|
290
256
|
signal_received = false
|
291
257
|
Thread.new do
|
@@ -293,7 +259,7 @@ describe PG::Connection do
|
|
293
259
|
Process.kill("USR1", Process.pid)
|
294
260
|
end
|
295
261
|
@conn.async_exec("select pg_sleep(0.3)")
|
296
|
-
signal_received.
|
262
|
+
expect( signal_received ).to be_truthy
|
297
263
|
end
|
298
264
|
|
299
265
|
|
@@ -313,7 +279,7 @@ describe PG::Connection do
|
|
313
279
|
}.to raise_exception( RuntimeError, /all pie is gone/i )
|
314
280
|
|
315
281
|
res = @conn.exec( "SELECT * FROM pie" )
|
316
|
-
res.ntuples.
|
282
|
+
expect( res.ntuples ).to eq( 0 )
|
317
283
|
end
|
318
284
|
|
319
285
|
it "returns the block result from Connection#transaction" do
|
@@ -323,7 +289,7 @@ describe PG::Connection do
|
|
323
289
|
res = @conn.transaction do
|
324
290
|
"transaction result"
|
325
291
|
end
|
326
|
-
res.
|
292
|
+
expect( res ).to eq( "transaction result" )
|
327
293
|
end
|
328
294
|
|
329
295
|
it "not read past the end of a large object" do
|
@@ -331,9 +297,9 @@ describe PG::Connection do
|
|
331
297
|
oid = @conn.lo_create( 0 )
|
332
298
|
fd = @conn.lo_open( oid, PG::INV_READ|PG::INV_WRITE )
|
333
299
|
@conn.lo_write( fd, "foobar" )
|
334
|
-
@conn.lo_read( fd, 10 ).
|
300
|
+
expect( @conn.lo_read( fd, 10 ) ).to be_nil()
|
335
301
|
@conn.lo_lseek( fd, 0, PG::SEEK_SET )
|
336
|
-
@conn.lo_read( fd, 10 ).
|
302
|
+
expect( @conn.lo_read( fd, 10 ) ).to eq( 'foobar' )
|
337
303
|
end
|
338
304
|
end
|
339
305
|
|
@@ -345,7 +311,7 @@ describe PG::Connection do
|
|
345
311
|
@conn.exec( "INSERT INTO students VALUES( $1, $2 )", ['Dorothy', 4] )
|
346
312
|
|
347
313
|
res = @conn.exec( "SELECT name FROM students WHERE age >= $1", [6] )
|
348
|
-
res.values.
|
314
|
+
expect( res.values ).to eq( [ ['Wally'], ['Sally'] ] )
|
349
315
|
end
|
350
316
|
|
351
317
|
it "supports explicitly calling #exec_params" do
|
@@ -355,7 +321,7 @@ describe PG::Connection do
|
|
355
321
|
@conn.exec( "INSERT INTO students VALUES( $1, $2 )", ['Dorothy', 4] )
|
356
322
|
|
357
323
|
res = @conn.exec_params( "SELECT name FROM students WHERE age >= $1", [6] )
|
358
|
-
res.values.
|
324
|
+
expect( res.values ).to eq( [ ['Wally'], ['Sally'] ] )
|
359
325
|
end
|
360
326
|
|
361
327
|
|
@@ -373,7 +339,7 @@ describe PG::Connection do
|
|
373
339
|
end
|
374
340
|
end
|
375
341
|
|
376
|
-
@conn.wait_for_notify( 10 ).
|
342
|
+
expect( @conn.wait_for_notify( 10 ) ).to eq( 'woo' )
|
377
343
|
@conn.exec( 'UNLISTEN woo' )
|
378
344
|
|
379
345
|
t.join
|
@@ -395,8 +361,8 @@ describe PG::Connection do
|
|
395
361
|
|
396
362
|
eventpid = event = nil
|
397
363
|
@conn.wait_for_notify( 10 ) {|*args| event, eventpid = args }
|
398
|
-
event.
|
399
|
-
eventpid.
|
364
|
+
expect( event ).to eq( 'woo' )
|
365
|
+
expect( eventpid ).to be_an( Integer )
|
400
366
|
|
401
367
|
@conn.exec( 'UNLISTEN woo' )
|
402
368
|
|
@@ -423,8 +389,8 @@ describe PG::Connection do
|
|
423
389
|
channels << @conn.wait_for_notify( 2 )
|
424
390
|
end
|
425
391
|
|
426
|
-
channels.
|
427
|
-
channels.
|
392
|
+
expect( channels.size ).to eq( 3 )
|
393
|
+
expect( channels ).to include( 'woo', 'war', 'woz' )
|
428
394
|
|
429
395
|
@conn.exec( 'UNLISTEN woz' )
|
430
396
|
@conn.exec( 'UNLISTEN war' )
|
@@ -446,7 +412,7 @@ describe PG::Connection do
|
|
446
412
|
# Cause the notification to buffer, but not be read yet
|
447
413
|
@conn.exec( 'SELECT 1' )
|
448
414
|
|
449
|
-
@conn.wait_for_notify( 10 ).
|
415
|
+
expect( @conn.wait_for_notify( 10 ) ).to eq( 'woo' )
|
450
416
|
@conn.exec( 'UNLISTEN woo' )
|
451
417
|
end
|
452
418
|
|
@@ -457,41 +423,42 @@ describe PG::Connection do
|
|
457
423
|
end
|
458
424
|
st = Time.now
|
459
425
|
@conn.send_query "SELECT pg_sleep(0.5); do $$ BEGIN RAISE NOTICE 'woohoo'; END; $$ LANGUAGE plpgsql;"
|
460
|
-
@conn.wait_for_notify( 1 ).
|
461
|
-
notices.first.
|
426
|
+
expect( @conn.wait_for_notify( 1 ) ).to be_nil
|
427
|
+
expect( notices.first ).to_not be_nil
|
462
428
|
et = Time.now
|
463
|
-
(et - notices.first[1]).
|
464
|
-
(et - st).
|
465
|
-
(et - st).
|
429
|
+
expect( (et - notices.first[1]) ).to be >= 0.4
|
430
|
+
expect( (et - st) ).to be >= 0.9
|
431
|
+
expect( (et - st) ).to be < 1.4
|
466
432
|
end
|
467
433
|
|
468
434
|
it "yields the result if block is given to exec" do
|
469
435
|
rval = @conn.exec( "select 1234::int as a union select 5678::int as a" ) do |result|
|
470
436
|
values = []
|
471
|
-
result.
|
472
|
-
result.ntuples.
|
437
|
+
expect( result ).to be_kind_of( PG::Result )
|
438
|
+
expect( result.ntuples ).to eq( 2 )
|
473
439
|
result.each do |tuple|
|
474
440
|
values << tuple['a']
|
475
441
|
end
|
476
442
|
values
|
477
443
|
end
|
478
444
|
|
479
|
-
rval.
|
480
|
-
rval.
|
445
|
+
expect( rval.size ).to eq( 2 )
|
446
|
+
expect( rval ).to include( '5678', '1234' )
|
481
447
|
end
|
482
448
|
|
483
449
|
it "can process #copy_data output queries" do
|
484
450
|
rows = []
|
485
451
|
res2 = @conn.copy_data( "COPY (SELECT 1 UNION ALL SELECT 2) TO STDOUT" ) do |res|
|
486
|
-
res.result_status.
|
487
|
-
res.nfields.
|
452
|
+
expect( res.result_status ).to eq( PG::PGRES_COPY_OUT )
|
453
|
+
expect( res.nfields ).to eq( 1 )
|
488
454
|
while row=@conn.get_copy_data
|
489
455
|
rows << row
|
490
456
|
end
|
491
457
|
end
|
492
|
-
rows.
|
493
|
-
res2.result_status.
|
494
|
-
|
458
|
+
expect( rows ).to eq( ["1\n", "2\n"] )
|
459
|
+
expect( res2.result_status ).to eq( PG::PGRES_COMMAND_OK )
|
460
|
+
@conn.send_query( "VALUES (1)" )
|
461
|
+
expect( @conn.get_last_result.values ).to eq( [["1"]] )
|
495
462
|
end
|
496
463
|
|
497
464
|
it "can handle incomplete #copy_data output queries" do
|
@@ -500,7 +467,8 @@ describe PG::Connection do
|
|
500
467
|
@conn.get_copy_data
|
501
468
|
end
|
502
469
|
}.to raise_error(PG::NotAllCopyDataRetrieved, /Not all/)
|
503
|
-
|
470
|
+
@conn.send_query( "VALUES (1)" )
|
471
|
+
expect( @conn.get_last_result.values ).to eq( [["1"]] )
|
504
472
|
end
|
505
473
|
|
506
474
|
it "can handle client errors in #copy_data for output" do
|
@@ -509,7 +477,8 @@ describe PG::Connection do
|
|
509
477
|
raise "boom"
|
510
478
|
end
|
511
479
|
}.to raise_error(RuntimeError, "boom")
|
512
|
-
|
480
|
+
@conn.send_query( "VALUES (1)" )
|
481
|
+
expect( @conn.get_last_result.values ).to eq( [["1"]] )
|
513
482
|
end
|
514
483
|
|
515
484
|
it "can handle server errors in #copy_data for output" do
|
@@ -523,23 +492,25 @@ describe PG::Connection do
|
|
523
492
|
end
|
524
493
|
}.to raise_error(PG::Error, /test-error/)
|
525
494
|
end
|
526
|
-
|
495
|
+
@conn.send_query( "VALUES (1)" )
|
496
|
+
expect( @conn.get_last_result.values ).to eq( [["1"]] )
|
527
497
|
end
|
528
498
|
|
529
499
|
it "can process #copy_data input queries" do
|
530
500
|
@conn.exec( "CREATE TEMP TABLE copytable (col1 TEXT)" )
|
531
501
|
res2 = @conn.copy_data( "COPY copytable FROM STDOUT" ) do |res|
|
532
|
-
res.result_status.
|
533
|
-
res.nfields.
|
502
|
+
expect( res.result_status ).to eq( PG::PGRES_COPY_IN )
|
503
|
+
expect( res.nfields ).to eq( 1 )
|
534
504
|
@conn.put_copy_data "1\n"
|
535
505
|
@conn.put_copy_data "2\n"
|
536
506
|
end
|
537
|
-
res2.result_status.
|
507
|
+
expect( res2.result_status ).to eq( PG::PGRES_COMMAND_OK )
|
538
508
|
|
539
|
-
|
509
|
+
@conn.send_query( "VALUES (1)" )
|
510
|
+
expect( @conn.get_last_result.values ).to eq( [["1"]] )
|
540
511
|
|
541
512
|
res = @conn.exec( "SELECT * FROM copytable ORDER BY col1" )
|
542
|
-
res.values.
|
513
|
+
expect( res.values ).to eq( [["1"], ["2"]] )
|
543
514
|
end
|
544
515
|
|
545
516
|
it "can handle client errors in #copy_data for input" do
|
@@ -552,7 +523,8 @@ describe PG::Connection do
|
|
552
523
|
end
|
553
524
|
}.to raise_error(RuntimeError, "boom")
|
554
525
|
end
|
555
|
-
|
526
|
+
@conn.send_query( "VALUES (1)" )
|
527
|
+
expect( @conn.get_last_result.values ).to eq( [["1"]] )
|
556
528
|
end
|
557
529
|
|
558
530
|
it "can handle server errors in #copy_data for input" do
|
@@ -565,7 +537,8 @@ describe PG::Connection do
|
|
565
537
|
end
|
566
538
|
}.to raise_error(PG::Error, /invalid input syntax for integer/)
|
567
539
|
end
|
568
|
-
|
540
|
+
@conn.send_query( "VALUES (1)" )
|
541
|
+
expect( @conn.get_last_result.values ).to eq( [["1"]] )
|
569
542
|
end
|
570
543
|
|
571
544
|
it "should raise an error for non copy statements in #copy_data" do
|
@@ -573,7 +546,8 @@ describe PG::Connection do
|
|
573
546
|
@conn.copy_data( "SELECT 1" ){}
|
574
547
|
}.to raise_error(ArgumentError, /no COPY/)
|
575
548
|
|
576
|
-
|
549
|
+
@conn.send_query( "VALUES (1)" )
|
550
|
+
expect( @conn.get_last_result.values ).to eq( [["1"]] )
|
577
551
|
end
|
578
552
|
|
579
553
|
it "correctly finishes COPY queries passed to #async_exec" do
|
@@ -589,8 +563,8 @@ describe PG::Connection do
|
|
589
563
|
results << data if data
|
590
564
|
end until data.nil?
|
591
565
|
|
592
|
-
results.
|
593
|
-
results.
|
566
|
+
expect( results.size ).to eq( 2 )
|
567
|
+
expect( results ).to include( "1\n", "2\n" )
|
594
568
|
end
|
595
569
|
|
596
570
|
|
@@ -602,10 +576,10 @@ describe PG::Connection do
|
|
602
576
|
end
|
603
577
|
|
604
578
|
sleep 0.5
|
605
|
-
t.
|
579
|
+
expect( t ).to be_alive()
|
606
580
|
@conn.cancel
|
607
581
|
t.join
|
608
|
-
(Time.now - start).
|
582
|
+
expect( (Time.now - start) ).to be < 3
|
609
583
|
end
|
610
584
|
|
611
585
|
it "described_class#block should allow a timeout" do
|
@@ -615,13 +589,12 @@ describe PG::Connection do
|
|
615
589
|
@conn.block( 0.1 )
|
616
590
|
finish = Time.now
|
617
591
|
|
618
|
-
(finish - start).
|
592
|
+
expect( (finish - start) ).to be_within( 0.05 ).of( 0.1 )
|
619
593
|
end
|
620
594
|
|
621
595
|
|
622
596
|
it "can encrypt a string given a password and username" do
|
623
|
-
described_class.encrypt_password("postgres", "postgres").
|
624
|
-
should =~ /\S+/
|
597
|
+
expect( described_class.encrypt_password("postgres", "postgres") ).to match( /\S+/ )
|
625
598
|
end
|
626
599
|
|
627
600
|
|
@@ -641,15 +614,15 @@ describe PG::Connection do
|
|
641
614
|
|
642
615
|
it "allows fetching a column of values from a result by column number" do
|
643
616
|
res = @conn.exec( 'VALUES (1,2),(2,3),(3,4)' )
|
644
|
-
res.column_values( 0 ).
|
645
|
-
res.column_values( 1 ).
|
617
|
+
expect( res.column_values( 0 ) ).to eq( %w[1 2 3] )
|
618
|
+
expect( res.column_values( 1 ) ).to eq( %w[2 3 4] )
|
646
619
|
end
|
647
620
|
|
648
621
|
|
649
622
|
it "allows fetching a column of values from a result by field name" do
|
650
623
|
res = @conn.exec( 'VALUES (1,2),(2,3),(3,4)' )
|
651
|
-
res.field_values( 'column1' ).
|
652
|
-
res.field_values( 'column2' ).
|
624
|
+
expect( res.field_values( 'column1' ) ).to eq( %w[1 2 3] )
|
625
|
+
expect( res.field_values( 'column2' ) ).to eq( %w[2 3 4] )
|
653
626
|
end
|
654
627
|
|
655
628
|
|
@@ -680,13 +653,13 @@ describe PG::Connection do
|
|
680
653
|
it "can connect asynchronously", :socket_io do
|
681
654
|
serv = TCPServer.new( '127.0.0.1', 54320 )
|
682
655
|
conn = described_class.connect_start( '127.0.0.1', 54320, "", "", "me", "xxxx", "somedb" )
|
683
|
-
[PG::PGRES_POLLING_WRITING, PG::CONNECTION_OK].
|
656
|
+
expect( [PG::PGRES_POLLING_WRITING, PG::CONNECTION_OK] ).to include conn.connect_poll
|
684
657
|
select( nil, [conn.socket_io], nil, 0.2 )
|
685
658
|
serv.close
|
686
659
|
if conn.connect_poll == PG::PGRES_POLLING_READING
|
687
660
|
select( [conn.socket_io], nil, nil, 0.2 )
|
688
661
|
end
|
689
|
-
conn.connect_poll.
|
662
|
+
expect( conn.connect_poll ).to eq( PG::PGRES_POLLING_FAILED )
|
690
663
|
end
|
691
664
|
|
692
665
|
it "discards previous results (if any) before waiting on an #async_exec"
|
@@ -696,7 +669,7 @@ describe PG::Connection do
|
|
696
669
|
@conn.async_exec( "select 47 as one" ) do |pg_res|
|
697
670
|
result = pg_res[0]
|
698
671
|
end
|
699
|
-
result.
|
672
|
+
expect( result ).to eq( { 'one' => '47' } )
|
700
673
|
end
|
701
674
|
|
702
675
|
it "raises a rescue-able error if #finish is called twice", :without_transaction do
|
@@ -710,7 +683,7 @@ describe PG::Connection do
|
|
710
683
|
conn = PG.connect( @conninfo )
|
711
684
|
io = conn.socket_io
|
712
685
|
conn.finish
|
713
|
-
io.
|
686
|
+
expect( io ).to be_closed()
|
714
687
|
expect { conn.socket_io }.to raise_error( PG::ConnectionBad, /connection is closed/i )
|
715
688
|
end
|
716
689
|
|
@@ -718,8 +691,8 @@ describe PG::Connection do
|
|
718
691
|
conn = PG.connect( @conninfo )
|
719
692
|
io = conn.socket_io
|
720
693
|
conn.reset
|
721
|
-
io.
|
722
|
-
conn.socket_io.
|
694
|
+
expect( io ).to be_closed()
|
695
|
+
expect( conn.socket_io ).to_not equal( io )
|
723
696
|
conn.finish
|
724
697
|
end
|
725
698
|
|
@@ -742,7 +715,11 @@ describe PG::Connection do
|
|
742
715
|
|
743
716
|
it "sets the fallback_application_name on new connections" do
|
744
717
|
conn_string = PG::Connection.parse_connect_args( 'dbname=test' )
|
745
|
-
|
718
|
+
|
719
|
+
conn_name = conn_string[ /application_name='(.*?)'/, 1 ]
|
720
|
+
expect( conn_name ).to include( $0[0..10] )
|
721
|
+
expect( conn_name ).to include( $0[-10..-1] )
|
722
|
+
expect( conn_name.length ).to be <= 64
|
746
723
|
end
|
747
724
|
|
748
725
|
it "sets a shortened fallback_application_name on new connections" do
|
@@ -750,7 +727,10 @@ describe PG::Connection do
|
|
750
727
|
begin
|
751
728
|
$0 = "/this/is/a/very/long/path/with/many/directories/to/our/beloved/ruby"
|
752
729
|
conn_string = PG::Connection.parse_connect_args( 'dbname=test' )
|
753
|
-
|
730
|
+
conn_name = conn_string[ /application_name='(.*?)'/, 1 ]
|
731
|
+
expect( conn_name ).to include( $0[0..10] )
|
732
|
+
expect( conn_name ).to include( $0[-10..-1] )
|
733
|
+
expect( conn_name.length ).to be <= 64
|
754
734
|
ensure
|
755
735
|
$0 = old_0
|
756
736
|
end
|
@@ -772,9 +752,9 @@ describe PG::Connection do
|
|
772
752
|
end
|
773
753
|
@conn.exec( 'UNLISTEN knees' )
|
774
754
|
|
775
|
-
event.
|
776
|
-
pid.
|
777
|
-
msg.
|
755
|
+
expect( event ).to eq( 'knees' )
|
756
|
+
expect( pid ).to be_a_kind_of( Integer )
|
757
|
+
expect( msg ).to eq( 'skirt and boots' )
|
778
758
|
end
|
779
759
|
|
780
760
|
it "accepts nil as the timeout in #wait_for_notify " do
|
@@ -791,8 +771,8 @@ describe PG::Connection do
|
|
791
771
|
end
|
792
772
|
@conn.exec( 'UNLISTEN knees' )
|
793
773
|
|
794
|
-
event.
|
795
|
-
pid.
|
774
|
+
expect( event ).to eq( 'knees' )
|
775
|
+
expect( pid ).to be_a_kind_of( Integer )
|
796
776
|
end
|
797
777
|
|
798
778
|
it "sends nil as the payload if the notification wasn't given one" do
|
@@ -809,7 +789,7 @@ describe PG::Connection do
|
|
809
789
|
end
|
810
790
|
@conn.exec( 'UNLISTEN knees' )
|
811
791
|
|
812
|
-
payload.
|
792
|
+
expect( payload ).to be_nil()
|
813
793
|
end
|
814
794
|
|
815
795
|
it "calls the block supplied to wait_for_notify with the notify payload if it accepts " +
|
@@ -828,9 +808,9 @@ describe PG::Connection do
|
|
828
808
|
end
|
829
809
|
@conn.exec( 'UNLISTEN knees' )
|
830
810
|
|
831
|
-
event.
|
832
|
-
pid.
|
833
|
-
msg.
|
811
|
+
expect( event ).to eq( 'knees' )
|
812
|
+
expect( pid ).to be_a_kind_of( Integer )
|
813
|
+
expect( msg ).to be_nil()
|
834
814
|
end
|
835
815
|
|
836
816
|
it "calls the block supplied to wait_for_notify with the notify payload if it " +
|
@@ -849,7 +829,7 @@ describe PG::Connection do
|
|
849
829
|
end
|
850
830
|
@conn.exec( 'UNLISTEN knees' )
|
851
831
|
|
852
|
-
notification_received.
|
832
|
+
expect( notification_received ).to be_truthy()
|
853
833
|
end
|
854
834
|
|
855
835
|
it "calls the block supplied to wait_for_notify with the notify payload if it accepts " +
|
@@ -868,9 +848,9 @@ describe PG::Connection do
|
|
868
848
|
end
|
869
849
|
@conn.exec( 'UNLISTEN knees' )
|
870
850
|
|
871
|
-
event.
|
872
|
-
pid.
|
873
|
-
msg.
|
851
|
+
expect( event ).to eq( 'knees' )
|
852
|
+
expect( pid ).to be_a_kind_of( Integer )
|
853
|
+
expect( msg ).to eq( 'skirt and boots' )
|
874
854
|
end
|
875
855
|
|
876
856
|
end
|
@@ -879,12 +859,12 @@ describe PG::Connection do
|
|
879
859
|
|
880
860
|
it "pings successfully with connection string" do
|
881
861
|
ping = described_class.ping(@conninfo)
|
882
|
-
ping.
|
862
|
+
expect( ping ).to eq( PG::PQPING_OK )
|
883
863
|
end
|
884
864
|
|
885
865
|
it "pings using 7 arguments converted to strings" do
|
886
866
|
ping = described_class.ping('localhost', @port, nil, nil, :test, nil, nil)
|
887
|
-
ping.
|
867
|
+
expect( ping ).to eq( PG::PQPING_OK )
|
888
868
|
end
|
889
869
|
|
890
870
|
it "pings using a hash of connection parameters" do
|
@@ -892,7 +872,7 @@ describe PG::Connection do
|
|
892
872
|
:host => 'localhost',
|
893
873
|
:port => @port,
|
894
874
|
:dbname => :test)
|
895
|
-
ping.
|
875
|
+
expect( ping ).to eq( PG::PQPING_OK )
|
896
876
|
end
|
897
877
|
|
898
878
|
it "returns correct response when ping connection cannot be established" do
|
@@ -900,12 +880,12 @@ describe PG::Connection do
|
|
900
880
|
:host => 'localhost',
|
901
881
|
:port => 9999,
|
902
882
|
:dbname => :test)
|
903
|
-
ping.
|
883
|
+
expect( ping ).to eq( PG::PQPING_NO_RESPONSE )
|
904
884
|
end
|
905
885
|
|
906
886
|
it "returns correct response when ping connection arguments are wrong" do
|
907
887
|
ping = described_class.ping('localhost', 'localhost', nil, nil, :test, nil, nil)
|
908
|
-
ping.
|
888
|
+
expect( ping ).to eq( PG::PQPING_NO_ATTEMPT )
|
909
889
|
end
|
910
890
|
|
911
891
|
|
@@ -930,15 +910,15 @@ describe PG::Connection do
|
|
930
910
|
res = @conn.get_result or break
|
931
911
|
results << res
|
932
912
|
end
|
933
|
-
results.length.
|
913
|
+
expect( results.length ).to eq( 11 )
|
934
914
|
results[0..-2].each do |res|
|
935
|
-
res.result_status.
|
915
|
+
expect( res.result_status ).to eq( PG::PGRES_SINGLE_TUPLE )
|
936
916
|
values = res.field_values('generate_series')
|
937
|
-
values.length.
|
938
|
-
values.first.to_i.
|
917
|
+
expect( values.length ).to eq( 1 )
|
918
|
+
expect( values.first.to_i ).to be > 0
|
939
919
|
end
|
940
|
-
results.last.result_status.
|
941
|
-
results.last.ntuples.
|
920
|
+
expect( results.last.result_status ).to eq( PG::PGRES_TUPLES_OK )
|
921
|
+
expect( results.last.ntuples ).to eq( 0 )
|
942
922
|
end
|
943
923
|
|
944
924
|
it "should receive rows before entire query is finished" do
|
@@ -952,8 +932,8 @@ describe PG::Connection do
|
|
952
932
|
res.check
|
953
933
|
first_row_time = Time.now unless first_row_time
|
954
934
|
end
|
955
|
-
(Time.now - start_time).
|
956
|
-
(first_row_time - start_time).
|
935
|
+
expect( (Time.now - start_time) ).to be >= 1.0
|
936
|
+
expect( (first_row_time - start_time) ).to be < 1.0
|
957
937
|
end
|
958
938
|
|
959
939
|
it "should receive rows before entire query fails" do
|
@@ -969,8 +949,8 @@ describe PG::Connection do
|
|
969
949
|
first_result ||= res
|
970
950
|
end
|
971
951
|
end.to raise_error(PG::Error)
|
972
|
-
first_result.kind_of?(PG::Result).
|
973
|
-
first_result.result_status.
|
952
|
+
expect( first_result.kind_of?(PG::Result) ).to be_truthy
|
953
|
+
expect( first_result.result_status ).to eq( PG::PGRES_SINGLE_TUPLE )
|
974
954
|
end
|
975
955
|
end
|
976
956
|
end
|
@@ -985,8 +965,8 @@ describe PG::Connection do
|
|
985
965
|
res = conn.exec("VALUES ('fantasia')", [], 0)
|
986
966
|
out_string = res[0]['column1']
|
987
967
|
end
|
988
|
-
out_string.
|
989
|
-
out_string.encoding.
|
968
|
+
expect( out_string ).to eq( 'fantasia' )
|
969
|
+
expect( out_string.encoding ).to eq( Encoding::ISO8859_1 )
|
990
970
|
end
|
991
971
|
|
992
972
|
it "should return results in the same encoding as the client (utf-8)" do
|
@@ -996,8 +976,8 @@ describe PG::Connection do
|
|
996
976
|
res = conn.exec("VALUES ('世界線航跡蔵')", [], 0)
|
997
977
|
out_string = res[0]['column1']
|
998
978
|
end
|
999
|
-
out_string.
|
1000
|
-
out_string.encoding.
|
979
|
+
expect( out_string ).to eq( '世界線航跡蔵' )
|
980
|
+
expect( out_string.encoding ).to eq( Encoding::UTF_8 )
|
1001
981
|
end
|
1002
982
|
|
1003
983
|
it "should return results in the same encoding as the client (EUC-JP)" do
|
@@ -1008,8 +988,8 @@ describe PG::Connection do
|
|
1008
988
|
res = conn.exec(stmt, [], 0)
|
1009
989
|
out_string = res[0]['column1']
|
1010
990
|
end
|
1011
|
-
out_string.
|
1012
|
-
out_string.encoding.
|
991
|
+
expect( out_string ).to eq( '世界線航跡蔵'.encode('EUC-JP') )
|
992
|
+
expect( out_string.encoding ).to eq( Encoding::EUC_JP )
|
1013
993
|
end
|
1014
994
|
|
1015
995
|
it "returns the results in the correct encoding even if the client_encoding has " +
|
@@ -1022,75 +1002,61 @@ describe PG::Connection do
|
|
1022
1002
|
conn.internal_encoding = 'utf-8'
|
1023
1003
|
out_string = res[0]['column1']
|
1024
1004
|
end
|
1025
|
-
out_string.
|
1026
|
-
out_string.encoding.
|
1005
|
+
expect( out_string ).to eq( '世界線航跡蔵'.encode('EUC-JP') )
|
1006
|
+
expect( out_string.encoding ).to eq( Encoding::EUC_JP )
|
1027
1007
|
end
|
1028
1008
|
|
1029
1009
|
it "the connection should return ASCII-8BIT when it's set to SQL_ASCII" do
|
1030
1010
|
@conn.exec "SET client_encoding TO SQL_ASCII"
|
1031
|
-
@conn.internal_encoding.
|
1032
|
-
end
|
1033
|
-
|
1034
|
-
it "works around the unsupported JOHAB encoding by returning stuff in 'ASCII_8BIT'" do
|
1035
|
-
pending "figuring out how to create a string in the JOHAB encoding" do
|
1036
|
-
out_string = nil
|
1037
|
-
@conn.transaction do |conn|
|
1038
|
-
conn.exec( "set client_encoding = 'JOHAB';" )
|
1039
|
-
stmt = "VALUES ('foo')".encode('JOHAB')
|
1040
|
-
res = conn.exec( stmt, [], 0 )
|
1041
|
-
out_string = res[0]['column1']
|
1042
|
-
end
|
1043
|
-
out_string.should == 'foo'.encode( Encoding::ASCII_8BIT )
|
1044
|
-
out_string.encoding.should == Encoding::ASCII_8BIT
|
1045
|
-
end
|
1011
|
+
expect( @conn.internal_encoding ).to eq( Encoding::ASCII_8BIT )
|
1046
1012
|
end
|
1047
1013
|
|
1048
1014
|
it "uses the client encoding for escaped string" do
|
1049
1015
|
original = "string to\0 escape".force_encoding( "iso8859-1" )
|
1050
1016
|
@conn.set_client_encoding( "euc_jp" )
|
1051
1017
|
escaped = @conn.escape( original )
|
1052
|
-
escaped.encoding.
|
1053
|
-
escaped.
|
1018
|
+
expect( escaped.encoding ).to eq( Encoding::EUC_JP )
|
1019
|
+
expect( escaped ).to eq( "string to" )
|
1054
1020
|
end
|
1055
1021
|
|
1056
1022
|
it "uses the client encoding for escaped literal", :postgresql_90 do
|
1057
1023
|
original = "string to\0 escape".force_encoding( "iso8859-1" )
|
1058
1024
|
@conn.set_client_encoding( "euc_jp" )
|
1059
1025
|
escaped = @conn.escape_literal( original )
|
1060
|
-
escaped.encoding.
|
1061
|
-
escaped.
|
1026
|
+
expect( escaped.encoding ).to eq( Encoding::EUC_JP )
|
1027
|
+
expect( escaped ).to eq( "'string to'" )
|
1062
1028
|
end
|
1063
1029
|
|
1064
1030
|
it "uses the client encoding for escaped identifier", :postgresql_90 do
|
1065
1031
|
original = "string to\0 escape".force_encoding( "iso8859-1" )
|
1066
1032
|
@conn.set_client_encoding( "euc_jp" )
|
1067
1033
|
escaped = @conn.escape_identifier( original )
|
1068
|
-
escaped.encoding.
|
1069
|
-
escaped.
|
1034
|
+
expect( escaped.encoding ).to eq( Encoding::EUC_JP )
|
1035
|
+
expect( escaped ).to eq( "\"string to\"" )
|
1070
1036
|
end
|
1071
1037
|
|
1072
1038
|
it "uses the client encoding for quote_ident" do
|
1073
1039
|
original = "string to\0 escape".force_encoding( "iso8859-1" )
|
1074
1040
|
@conn.set_client_encoding( "euc_jp" )
|
1075
1041
|
escaped = @conn.quote_ident( original )
|
1076
|
-
escaped.encoding.
|
1077
|
-
escaped.
|
1042
|
+
expect( escaped.encoding ).to eq( Encoding::EUC_JP )
|
1043
|
+
expect( escaped ).to eq( "\"string to\"" )
|
1078
1044
|
end
|
1079
1045
|
|
1080
1046
|
it "uses the previous string encoding for escaped string" do
|
1081
1047
|
original = "string to\0 escape".force_encoding( "iso8859-1" )
|
1082
1048
|
@conn.set_client_encoding( "euc_jp" )
|
1083
1049
|
escaped = described_class.escape( original )
|
1084
|
-
escaped.encoding.
|
1085
|
-
escaped.
|
1050
|
+
expect( escaped.encoding ).to eq( Encoding::ISO8859_1 )
|
1051
|
+
expect( escaped ).to eq( "string to" )
|
1086
1052
|
end
|
1087
1053
|
|
1088
1054
|
it "uses the previous string encoding for quote_ident" do
|
1089
1055
|
original = "string to\0 escape".force_encoding( "iso8859-1" )
|
1090
1056
|
@conn.set_client_encoding( "euc_jp" )
|
1091
1057
|
escaped = described_class.quote_ident( original )
|
1092
|
-
escaped.encoding.
|
1093
|
-
escaped.
|
1058
|
+
expect( escaped.encoding ).to eq( Encoding::ISO8859_1 )
|
1059
|
+
expect( escaped ).to eq( "\"string to\"" )
|
1094
1060
|
end
|
1095
1061
|
|
1096
1062
|
end
|
@@ -1110,9 +1076,9 @@ describe PG::Connection do
|
|
1110
1076
|
Encoding.default_internal = Encoding::UTF_8
|
1111
1077
|
|
1112
1078
|
conn = PG.connect( @conninfo )
|
1113
|
-
conn.internal_encoding.
|
1079
|
+
expect( conn.internal_encoding ).to eq( Encoding::UTF_8 )
|
1114
1080
|
res = conn.exec( "SELECT foo FROM defaultinternaltest" )
|
1115
|
-
res[0]['foo'].encoding.
|
1081
|
+
expect( res[0]['foo'].encoding ).to eq( Encoding::UTF_8 )
|
1116
1082
|
ensure
|
1117
1083
|
conn.finish if conn
|
1118
1084
|
Encoding.default_internal = prev_encoding
|
@@ -1126,7 +1092,7 @@ describe PG::Connection do
|
|
1126
1092
|
|
1127
1093
|
@conn.set_default_encoding
|
1128
1094
|
|
1129
|
-
@conn.internal_encoding.
|
1095
|
+
expect( @conn.internal_encoding ).to eq( Encoding::KOI8_R )
|
1130
1096
|
ensure
|
1131
1097
|
Encoding.default_internal = prev_encoding
|
1132
1098
|
end
|
@@ -1147,7 +1113,7 @@ describe PG::Connection do
|
|
1147
1113
|
query = "INSERT INTO foo VALUES ('Côte d'Ivoire')".encode( 'iso-8859-15' )
|
1148
1114
|
conn.exec( query )
|
1149
1115
|
rescue => err
|
1150
|
-
err.message.encoding.
|
1116
|
+
expect( err.message.encoding ).to eq( Encoding::ISO8859_15 )
|
1151
1117
|
else
|
1152
1118
|
fail "No exception raised?!"
|
1153
1119
|
end
|
@@ -1174,10 +1140,10 @@ describe PG::Connection do
|
|
1174
1140
|
@conn.exec "do $$ BEGIN RAISE NOTICE '世界線航跡蔵'; END; $$ LANGUAGE plpgsql;"
|
1175
1141
|
end
|
1176
1142
|
|
1177
|
-
notices.length.
|
1143
|
+
expect( notices.length ).to eq( 3 )
|
1178
1144
|
notices.each do |notice|
|
1179
|
-
notice.
|
1180
|
-
notice.encoding.
|
1145
|
+
expect( notice ).to match( /^NOTICE:.*世界線航跡蔵/ )
|
1146
|
+
expect( notice.encoding ).to eq( Encoding::UTF_8 )
|
1181
1147
|
end
|
1182
1148
|
@conn.set_notice_receiver
|
1183
1149
|
@conn.set_notice_processor
|
@@ -1195,10 +1161,10 @@ describe PG::Connection do
|
|
1195
1161
|
end
|
1196
1162
|
@conn.exec( 'UNLISTEN "Möhre"' )
|
1197
1163
|
|
1198
|
-
event.
|
1199
|
-
event.encoding.
|
1200
|
-
msg.
|
1201
|
-
msg.encoding.
|
1164
|
+
expect( event ).to eq( "Möhre" )
|
1165
|
+
expect( event.encoding ).to eq( Encoding::UTF_8 )
|
1166
|
+
expect( msg ).to eq( '世界線航跡蔵' )
|
1167
|
+
expect( msg.encoding ).to eq( Encoding::UTF_8 )
|
1202
1168
|
end
|
1203
1169
|
|
1204
1170
|
it "returns properly encoded text from notifies", :postgresql_90 do
|
@@ -1209,11 +1175,11 @@ describe PG::Connection do
|
|
1209
1175
|
@conn.exec( 'UNLISTEN "Möhre"' )
|
1210
1176
|
|
1211
1177
|
notification = @conn.notifies
|
1212
|
-
notification[:relname].
|
1213
|
-
notification[:relname].encoding.
|
1214
|
-
notification[:extra].
|
1215
|
-
notification[:extra].encoding.
|
1216
|
-
notification[:be_pid].
|
1178
|
+
expect( notification[:relname] ).to eq( "Möhre" )
|
1179
|
+
expect( notification[:relname].encoding ).to eq( Encoding::UTF_8 )
|
1180
|
+
expect( notification[:extra] ).to eq( '世界線航跡蔵' )
|
1181
|
+
expect( notification[:extra].encoding ).to eq( Encoding::UTF_8 )
|
1182
|
+
expect( notification[:be_pid] ).to be > 0
|
1217
1183
|
end
|
1218
1184
|
end
|
1219
1185
|
|
@@ -1224,7 +1190,7 @@ describe PG::Connection do
|
|
1224
1190
|
end
|
1225
1191
|
|
1226
1192
|
sleep 0.5
|
1227
|
-
t.
|
1193
|
+
expect( t ).to be_alive()
|
1228
1194
|
t.join
|
1229
1195
|
end
|
1230
1196
|
|
@@ -1238,7 +1204,7 @@ describe PG::Connection do
|
|
1238
1204
|
end
|
1239
1205
|
|
1240
1206
|
sleep 0.5
|
1241
|
-
t.
|
1207
|
+
expect( t ).to be_alive()
|
1242
1208
|
serv.close
|
1243
1209
|
t.join
|
1244
1210
|
end
|