pg 0.17.1 → 0.18.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +0 -0
- data/ChangeLog +2407 -2
- data/History.rdoc +68 -0
- data/Manifest.txt +29 -1
- data/README-Windows.rdoc +15 -26
- data/README.rdoc +52 -2
- data/Rakefile +56 -18
- data/Rakefile.cross +77 -49
- data/ext/extconf.rb +33 -26
- data/ext/pg.c +142 -21
- data/ext/pg.h +242 -6
- data/ext/pg_binary_decoder.c +162 -0
- data/ext/pg_binary_encoder.c +162 -0
- data/ext/pg_coder.c +479 -0
- data/ext/pg_connection.c +858 -553
- data/ext/pg_copy_coder.c +561 -0
- data/ext/pg_errors.c +6 -0
- data/ext/pg_result.c +479 -128
- data/ext/pg_text_decoder.c +421 -0
- data/ext/pg_text_encoder.c +663 -0
- data/ext/pg_type_map.c +159 -0
- data/ext/pg_type_map_all_strings.c +116 -0
- data/ext/pg_type_map_by_class.c +239 -0
- data/ext/pg_type_map_by_column.c +312 -0
- data/ext/pg_type_map_by_mri_type.c +284 -0
- data/ext/pg_type_map_by_oid.c +355 -0
- data/ext/pg_type_map_in_ruby.c +299 -0
- data/ext/util.c +149 -0
- data/ext/util.h +65 -0
- data/lib/pg/basic_type_mapping.rb +399 -0
- data/lib/pg/coder.rb +83 -0
- data/lib/pg/connection.rb +81 -29
- data/lib/pg/result.rb +13 -3
- data/lib/pg/text_decoder.rb +44 -0
- data/lib/pg/text_encoder.rb +27 -0
- data/lib/pg/type_map_by_column.rb +15 -0
- data/lib/pg.rb +12 -2
- data/spec/{lib/helpers.rb → helpers.rb} +101 -39
- data/spec/pg/basic_type_mapping_spec.rb +251 -0
- data/spec/pg/connection_spec.rb +516 -218
- data/spec/pg/result_spec.rb +216 -112
- data/spec/pg/type_map_by_class_spec.rb +138 -0
- data/spec/pg/type_map_by_column_spec.rb +222 -0
- data/spec/pg/type_map_by_mri_type_spec.rb +136 -0
- data/spec/pg/type_map_by_oid_spec.rb +149 -0
- data/spec/pg/type_map_in_ruby_spec.rb +164 -0
- data/spec/pg/type_map_spec.rb +22 -0
- data/spec/pg/type_spec.rb +697 -0
- data/spec/pg_spec.rb +24 -18
- data.tar.gz.sig +0 -0
- metadata +111 -45
- metadata.gz.sig +0 -0
data/lib/pg/connection.rb
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
|
3
3
|
require 'pg' unless defined?( PG )
|
4
|
+
require 'uri'
|
4
5
|
|
5
6
|
# The PostgreSQL connection class. The interface for this class is based on
|
6
7
|
# {libpq}[http://www.postgresql.org/docs/9.2/interactive/libpq.html], the C
|
@@ -34,46 +35,55 @@ class PG::Connection
|
|
34
35
|
def self::parse_connect_args( *args )
|
35
36
|
return '' if args.empty?
|
36
37
|
|
37
|
-
|
38
|
-
|
39
|
-
|
38
|
+
hash_arg = args.last.is_a?( Hash ) ? args.pop : {}
|
39
|
+
option_string = ''
|
40
|
+
options = {}
|
40
41
|
|
41
42
|
# Parameter 'fallback_application_name' was introduced in PostgreSQL 9.0
|
42
43
|
# together with PQescapeLiteral().
|
43
|
-
if PG::Connection.instance_methods.find{|m| m.to_sym == :escape_literal }
|
44
|
-
|
45
|
-
appname = PG::Connection.quote_connstr( appname )
|
46
|
-
connopts = ["fallback_application_name=#{appname}"]
|
47
|
-
else
|
48
|
-
connopts = []
|
44
|
+
if PG::Connection.instance_methods.find {|m| m.to_sym == :escape_literal }
|
45
|
+
options[:fallback_application_name] = $0.sub( /^(.{30}).{4,}(.{30})$/ ){ $1+"..."+$2 }
|
49
46
|
end
|
50
47
|
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
48
|
+
if args.length == 1
|
49
|
+
case args.first
|
50
|
+
when URI, URI.regexp
|
51
|
+
uri = URI(args.first)
|
52
|
+
options.merge!( Hash[URI.decode_www_form( uri.query )] ) if uri.query
|
53
|
+
when /=/
|
54
|
+
# Option string style
|
55
|
+
option_string = args.first.to_s
|
56
|
+
else
|
57
|
+
# Positional parameters
|
58
|
+
options[CONNECT_ARGUMENT_ORDER.first.to_sym] = args.first
|
56
59
|
end
|
57
|
-
end
|
58
|
-
|
59
|
-
# Option string style
|
60
|
-
if args.length == 1 && args.first.to_s.index( '=' )
|
61
|
-
connopts.unshift( args.first )
|
62
|
-
|
63
|
-
# Append positional parameters
|
64
60
|
else
|
65
|
-
|
66
|
-
|
61
|
+
max = CONNECT_ARGUMENT_ORDER.length
|
62
|
+
raise ArgumentError,
|
63
|
+
"Extra positional parameter %d: %p" % [ max + 1, args[max] ] if args.length > max
|
67
64
|
|
68
|
-
|
69
|
-
|
70
|
-
connopts.push( "%s=%s" % [key, PG::Connection.quote_connstr(val.to_s)] )
|
65
|
+
CONNECT_ARGUMENT_ORDER.zip( args ) do |(k,v)|
|
66
|
+
options[ k.to_sym ] = v if v
|
71
67
|
end
|
72
68
|
end
|
73
69
|
|
74
|
-
|
70
|
+
options.merge!( hash_arg )
|
71
|
+
|
72
|
+
if uri
|
73
|
+
uri.host = nil if options[:host]
|
74
|
+
uri.port = nil if options[:port]
|
75
|
+
uri.user = nil if options[:user]
|
76
|
+
uri.password = nil if options[:password]
|
77
|
+
uri.path = '' if options[:dbname]
|
78
|
+
uri.query = URI.encode_www_form( options )
|
79
|
+
return uri.to_s.sub( /^#{uri.scheme}:(?!\/\/)/, "#{uri.scheme}://" )
|
80
|
+
else
|
81
|
+
option_string += ' ' unless option_string.empty? && options.empty?
|
82
|
+
return option_string + options.map { |k,v| "#{k}=#{quote_connstr(v)}" }.join( ' ' )
|
83
|
+
end
|
75
84
|
end
|
76
85
|
|
86
|
+
|
77
87
|
# call-seq:
|
78
88
|
# conn.copy_data( sql ) {|sql_result| ... } -> PG::Result
|
79
89
|
#
|
@@ -101,7 +111,7 @@ class PG::Connection
|
|
101
111
|
#
|
102
112
|
# Example with CSV input format:
|
103
113
|
# conn.exec "create table my_table (a text,b text,c text,d text,e text)"
|
104
|
-
# conn.copy_data "COPY my_table FROM
|
114
|
+
# conn.copy_data "COPY my_table FROM STDIN CSV" do
|
105
115
|
# conn.put_copy_data "some,csv,data,to,copy\n"
|
106
116
|
# conn.put_copy_data "more,csv,data,to,copy\n"
|
107
117
|
# end
|
@@ -116,12 +126,16 @@ class PG::Connection
|
|
116
126
|
# This prints all rows of +my_table+ to stdout:
|
117
127
|
# "some,csv,data,to,copy\n"
|
118
128
|
# "more,csv,data,to,copy\n"
|
119
|
-
def copy_data( sql )
|
129
|
+
def copy_data( sql, coder=nil )
|
120
130
|
res = exec( sql )
|
121
131
|
|
122
132
|
case res.result_status
|
123
133
|
when PGRES_COPY_IN
|
124
134
|
begin
|
135
|
+
if coder
|
136
|
+
old_coder = self.encoder_for_put_copy_data
|
137
|
+
self.encoder_for_put_copy_data = coder
|
138
|
+
end
|
125
139
|
yield res
|
126
140
|
rescue Exception => err
|
127
141
|
errmsg = "%s while copy data: %s" % [ err.class.name, err.message ]
|
@@ -131,10 +145,16 @@ class PG::Connection
|
|
131
145
|
else
|
132
146
|
put_copy_end
|
133
147
|
get_last_result
|
148
|
+
ensure
|
149
|
+
self.encoder_for_put_copy_data = old_coder if coder
|
134
150
|
end
|
135
151
|
|
136
152
|
when PGRES_COPY_OUT
|
137
153
|
begin
|
154
|
+
if coder
|
155
|
+
old_coder = self.decoder_for_get_copy_data
|
156
|
+
self.decoder_for_get_copy_data = coder
|
157
|
+
end
|
138
158
|
yield res
|
139
159
|
rescue Exception => err
|
140
160
|
cancel
|
@@ -153,6 +173,8 @@ class PG::Connection
|
|
153
173
|
raise PG::NotAllCopyDataRetrieved, "Not all COPY data retrieved"
|
154
174
|
end
|
155
175
|
res
|
176
|
+
ensure
|
177
|
+
self.decoder_for_get_copy_data = old_coder if coder
|
156
178
|
end
|
157
179
|
|
158
180
|
else
|
@@ -172,6 +194,36 @@ class PG::Connection
|
|
172
194
|
return self.class.conndefaults
|
173
195
|
end
|
174
196
|
|
197
|
+
### Return the Postgres connection defaults structure as a Hash keyed by option
|
198
|
+
### keyword (as a Symbol).
|
199
|
+
###
|
200
|
+
### See also #conndefaults
|
201
|
+
def self.conndefaults_hash
|
202
|
+
return self.conndefaults.each_with_object({}) do |info, hash|
|
203
|
+
hash[ info[:keyword].to_sym ] = info[:val]
|
204
|
+
end
|
205
|
+
end
|
206
|
+
|
207
|
+
### Returns a Hash with connection defaults. See ::conndefaults_hash
|
208
|
+
### for details.
|
209
|
+
def conndefaults_hash
|
210
|
+
return self.class.conndefaults_hash
|
211
|
+
end
|
212
|
+
|
213
|
+
# Method 'conninfo' was introduced in PostgreSQL 9.3.
|
214
|
+
if self.instance_methods.find{|m| m.to_sym == :conninfo }
|
215
|
+
|
216
|
+
### Return the Postgres connection info structure as a Hash keyed by option
|
217
|
+
### keyword (as a Symbol).
|
218
|
+
###
|
219
|
+
### See also #conninfo
|
220
|
+
def conninfo_hash
|
221
|
+
return self.conninfo.each_with_object({}) do |info, hash|
|
222
|
+
hash[ info[:keyword].to_sym ] = info[:val]
|
223
|
+
end
|
224
|
+
end
|
225
|
+
end
|
226
|
+
|
175
227
|
end # class PG::Connection
|
176
228
|
|
177
229
|
# Backward-compatible alias
|
data/lib/pg/result.rb
CHANGED
@@ -5,11 +5,21 @@ require 'pg' unless defined?( PG )
|
|
5
5
|
|
6
6
|
class PG::Result
|
7
7
|
|
8
|
-
|
9
|
-
|
10
|
-
|
8
|
+
# Apply a type map for all value retrieving methods.
|
9
|
+
#
|
10
|
+
# +type_map+: a PG::TypeMap instance.
|
11
|
+
#
|
12
|
+
# See PG::BasicTypeMapForResults
|
13
|
+
def map_types!(type_map)
|
14
|
+
self.type_map = type_map
|
15
|
+
self
|
11
16
|
end
|
12
17
|
|
18
|
+
def inspect
|
19
|
+
str = self.to_s
|
20
|
+
str[-1,0] = " status=#{res_status(result_status)} ntuples=#{ntuples} nfields=#{nfields} cmd_tuples=#{cmd_tuples}"
|
21
|
+
str
|
22
|
+
end
|
13
23
|
end # class PG::Result
|
14
24
|
|
15
25
|
# Backward-compatible alias
|
@@ -0,0 +1,44 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'date'
|
4
|
+
|
5
|
+
module PG
|
6
|
+
module TextDecoder
|
7
|
+
class Date < SimpleDecoder
|
8
|
+
ISO_DATE = /\A(\d{4})-(\d\d)-(\d\d)\z/
|
9
|
+
|
10
|
+
def decode(string, tuple=nil, field=nil)
|
11
|
+
if string =~ ISO_DATE
|
12
|
+
::Date.new $1.to_i, $2.to_i, $3.to_i
|
13
|
+
else
|
14
|
+
string
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
class TimestampWithoutTimeZone < SimpleDecoder
|
20
|
+
ISO_DATETIME_WITHOUT_TIMEZONE = /\A(\d{4})-(\d\d)-(\d\d) (\d\d):(\d\d):(\d\d)(\.\d+)?\z/
|
21
|
+
|
22
|
+
def decode(string, tuple=nil, field=nil)
|
23
|
+
if string =~ ISO_DATETIME_WITHOUT_TIMEZONE
|
24
|
+
Time.new $1.to_i, $2.to_i, $3.to_i, $4.to_i, $5.to_i, "#{$6}#{$7}".to_r
|
25
|
+
else
|
26
|
+
string
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
class TimestampWithTimeZone < SimpleDecoder
|
32
|
+
ISO_DATETIME_WITH_TIMEZONE = /\A(\d{4})-(\d\d)-(\d\d) (\d\d):(\d\d):(\d\d)(\.\d+)?([-\+]\d\d):?(\d\d)?:?(\d\d)?\z/
|
33
|
+
|
34
|
+
def decode(string, tuple=nil, field=nil)
|
35
|
+
if string =~ ISO_DATETIME_WITH_TIMEZONE
|
36
|
+
Time.new $1.to_i, $2.to_i, $3.to_i, $4.to_i, $5.to_i, "#{$6}#{$7}".to_r, "#{$8}:#{$9 || '00'}:#{$10 || '00'}"
|
37
|
+
else
|
38
|
+
string
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end # module PG
|
44
|
+
|
@@ -0,0 +1,27 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
module PG
|
4
|
+
module TextEncoder
|
5
|
+
class Date < SimpleEncoder
|
6
|
+
STRFTIME_ISO_DATE = "%Y-%m-%d".freeze
|
7
|
+
def encode(value)
|
8
|
+
value.respond_to?(:strftime) ? value.strftime(STRFTIME_ISO_DATE) : value
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
class TimestampWithoutTimeZone < SimpleEncoder
|
13
|
+
STRFTIME_ISO_DATETIME_WITHOUT_TIMEZONE = "%Y-%m-%d %H:%M:%S.%N".freeze
|
14
|
+
def encode(value)
|
15
|
+
value.respond_to?(:strftime) ? value.strftime(STRFTIME_ISO_DATETIME_WITHOUT_TIMEZONE) : value
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
class TimestampWithTimeZone < SimpleEncoder
|
20
|
+
STRFTIME_ISO_DATETIME_WITH_TIMEZONE = "%Y-%m-%d %H:%M:%S.%N %:z".freeze
|
21
|
+
def encode(value)
|
22
|
+
value.respond_to?(:strftime) ? value.strftime(STRFTIME_ISO_DATETIME_WITH_TIMEZONE) : value
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end # module PG
|
27
|
+
|
@@ -0,0 +1,15 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'pg' unless defined?( PG )
|
4
|
+
|
5
|
+
class PG::TypeMapByColumn
|
6
|
+
# Returns the type oids of the assigned coders.
|
7
|
+
def oids
|
8
|
+
coders.map{|c| c.oid if c }
|
9
|
+
end
|
10
|
+
|
11
|
+
def inspect
|
12
|
+
type_strings = coders.map{|c| c ? "#{c.name}:#{c.format}" : 'nil' }
|
13
|
+
"#<#{self.class} #{type_strings.join(' ')}>"
|
14
|
+
end
|
15
|
+
end
|
data/lib/pg.rb
CHANGED
@@ -7,7 +7,12 @@ rescue LoadError
|
|
7
7
|
if RUBY_PLATFORM =~/(mswin|mingw)/i
|
8
8
|
major_minor = RUBY_VERSION[ /^(\d+\.\d+)/ ] or
|
9
9
|
raise "Oops, can't extract the major/minor version from #{RUBY_VERSION.dump}"
|
10
|
+
|
11
|
+
# Set the PATH environment variable, so that libpq.dll can be found.
|
12
|
+
old_path = ENV['PATH']
|
13
|
+
ENV['PATH'] = "#{File.expand_path("../#{RUBY_PLATFORM}", __FILE__)};#{old_path}"
|
10
14
|
require "#{major_minor}/pg_ext"
|
15
|
+
ENV['PATH'] = old_path
|
11
16
|
else
|
12
17
|
raise
|
13
18
|
end
|
@@ -19,10 +24,10 @@ end
|
|
19
24
|
module PG
|
20
25
|
|
21
26
|
# Library version
|
22
|
-
VERSION = '0.
|
27
|
+
VERSION = '0.18.4'
|
23
28
|
|
24
29
|
# VCS revision
|
25
|
-
REVISION = %q$Revision:
|
30
|
+
REVISION = %q$Revision: da42b972b5ab $
|
26
31
|
|
27
32
|
class NotAllCopyDataRetrieved < PG::Error
|
28
33
|
end
|
@@ -43,6 +48,11 @@ module PG
|
|
43
48
|
|
44
49
|
require 'pg/exceptions'
|
45
50
|
require 'pg/constants'
|
51
|
+
require 'pg/coder'
|
52
|
+
require 'pg/text_encoder'
|
53
|
+
require 'pg/text_decoder'
|
54
|
+
require 'pg/basic_type_mapping'
|
55
|
+
require 'pg/type_map_by_column'
|
46
56
|
require 'pg/connection'
|
47
57
|
require 'pg/result'
|
48
58
|
|
@@ -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 ? described_class.name : mod.description) }
|
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
|
@@ -242,35 +255,82 @@ module PG::TestingHelpers
|
|
242
255
|
unless conns.empty?
|
243
256
|
puts "Lingering connections remain:"
|
244
257
|
conns.each do |row|
|
245
|
-
puts " [%
|
258
|
+
puts " [%s] {%s} %s -- %s" % row.values_at( 'pid', 'state', 'application_name', 'query' )
|
246
259
|
end
|
247
260
|
end
|
248
261
|
end
|
249
262
|
end
|
250
263
|
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
|
264
|
+
|
265
|
+
# Retrieve the names of the column types of a given result set.
|
266
|
+
def result_typenames(res)
|
267
|
+
@conn.exec( "SELECT " + res.nfields.times.map{|i| "format_type($#{i*2+1},$#{i*2+2})"}.join(","),
|
268
|
+
res.nfields.times.map{|i| [res.ftype(i), res.fmod(i)] }.flatten ).
|
269
|
+
values[0]
|
270
|
+
end
|
271
|
+
|
272
|
+
|
273
|
+
# A matcher for checking the status of a PG::Connection to ensure it's still
|
274
|
+
# usable.
|
275
|
+
class ConnStillUsableMatcher
|
276
|
+
|
277
|
+
def initialize
|
278
|
+
@conn = nil
|
279
|
+
@problem = nil
|
280
|
+
end
|
281
|
+
|
282
|
+
def matches?( conn )
|
283
|
+
@conn = conn
|
284
|
+
@problem = self.check_for_problems
|
285
|
+
return @problem.nil?
|
286
|
+
end
|
287
|
+
|
288
|
+
def check_for_problems
|
289
|
+
return "is finished" if @conn.finished?
|
290
|
+
return "has bad status" unless @conn.status == PG::CONNECTION_OK
|
291
|
+
return "has bad transaction status (%d)" % [ @conn.transaction_status ] unless
|
292
|
+
@conn.transaction_status.between?( PG::PQTRANS_IDLE, PG::PQTRANS_INTRANS )
|
293
|
+
return "is not usable." unless self.can_exec_query?
|
294
|
+
return nil
|
295
|
+
end
|
296
|
+
|
297
|
+
def can_exec_query?
|
298
|
+
@conn.send_query( "VALUES (1)" )
|
299
|
+
@conn.get_last_result.values == [["1"]]
|
300
|
+
end
|
301
|
+
|
302
|
+
def failure_message
|
303
|
+
return "expected %p to be usable, but it %s" % [ @conn, @problem ]
|
304
|
+
end
|
305
|
+
|
306
|
+
def failure_message_when_negated
|
307
|
+
"expected %p not to be usable, but it still is" % [ @conn ]
|
308
|
+
end
|
309
|
+
|
256
310
|
end
|
257
311
|
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
312
|
+
|
313
|
+
### Return a ConnStillUsableMatcher to be used like:
|
314
|
+
###
|
315
|
+
### expect( pg_conn ).to still_be_usable
|
316
|
+
###
|
317
|
+
def still_be_usable
|
318
|
+
return ConnStillUsableMatcher.new
|
262
319
|
end
|
320
|
+
|
263
321
|
end
|
264
322
|
|
265
323
|
|
266
324
|
RSpec.configure do |config|
|
267
|
-
ruby_version_vec = RUBY_VERSION.split('.').map {|c| c.to_i }.pack( "N*" )
|
268
|
-
|
269
325
|
config.include( PG::TestingHelpers )
|
270
|
-
config.treat_symbols_as_metadata_keys_with_true_values = true
|
271
326
|
|
272
|
-
config.
|
273
|
-
config.
|
327
|
+
config.run_all_when_everything_filtered = true
|
328
|
+
config.filter_run :focus
|
329
|
+
config.order = 'random'
|
330
|
+
config.mock_with( :rspec ) do |mock|
|
331
|
+
mock.syntax = :expect
|
332
|
+
end
|
333
|
+
|
274
334
|
if RUBY_PLATFORM =~ /mingw|mswin/
|
275
335
|
config.filter_run_excluding :unix
|
276
336
|
else
|
@@ -283,11 +343,13 @@ RSpec.configure do |config|
|
|
283
343
|
PG::Connection.instance_methods.map( &:to_sym ).include?( :escape_literal )
|
284
344
|
|
285
345
|
if !PG.respond_to?( :library_version )
|
286
|
-
config.filter_run_excluding( :postgresql_91, :postgresql_92, :postgresql_93 )
|
346
|
+
config.filter_run_excluding( :postgresql_91, :postgresql_92, :postgresql_93, :postgresql_94 )
|
287
347
|
elsif PG.library_version < 90200
|
288
|
-
config.filter_run_excluding( :postgresql_92, :postgresql_93 )
|
348
|
+
config.filter_run_excluding( :postgresql_92, :postgresql_93, :postgresql_94 )
|
289
349
|
elsif PG.library_version < 90300
|
290
|
-
config.filter_run_excluding( :postgresql_93 )
|
350
|
+
config.filter_run_excluding( :postgresql_93, :postgresql_94 )
|
351
|
+
elsif PG.library_version < 90400
|
352
|
+
config.filter_run_excluding( :postgresql_94 )
|
291
353
|
end
|
292
354
|
end
|
293
355
|
|