pg 0.17.1 → 0.18.4
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/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
|
|