pg 1.3.5-x86-mingw32 → 1.4.2-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.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +0 -0
- data/History.rdoc +40 -0
- data/Rakefile.cross +2 -2
- data/ext/extconf.rb +0 -31
- data/ext/pg_connection.c +205 -177
- data/ext/pg_result.c +2 -2
- data/lib/2.5/pg_ext.so +0 -0
- data/lib/2.6/pg_ext.so +0 -0
- data/lib/2.7/pg_ext.so +0 -0
- data/lib/3.0/pg_ext.so +0 -0
- data/lib/3.1/pg_ext.so +0 -0
- data/lib/pg/connection.rb +174 -118
- data/lib/pg/exceptions.rb +7 -1
- data/lib/pg/version.rb +1 -1
- data/lib/pg.rb +4 -4
- data/lib/x86-mingw32/libpq.dll +0 -0
- data.tar.gz.sig +0 -0
- metadata +2 -2
- metadata.gz.sig +0 -0
data/ext/pg_result.c
CHANGED
@@ -1476,10 +1476,10 @@ pgresult_stream_any(VALUE self, void (*yielder)(VALUE, int, int, void*), void* d
|
|
1476
1476
|
|
1477
1477
|
pgresult = gvl_PQgetResult(pgconn);
|
1478
1478
|
if( pgresult == NULL )
|
1479
|
-
rb_raise( rb_eNoResultError, "no result received - possibly an intersection with another
|
1479
|
+
rb_raise( rb_eNoResultError, "no result received - possibly an intersection with another query");
|
1480
1480
|
|
1481
1481
|
if( nfields != PQnfields(pgresult) )
|
1482
|
-
rb_raise( rb_eInvalidChangeOfResultFields, "number of fields
|
1482
|
+
rb_raise( rb_eInvalidChangeOfResultFields, "number of fields changed in single row mode from %d to %d - this is a sign for intersection with another query", nfields, PQnfields(pgresult));
|
1483
1483
|
|
1484
1484
|
this->pgresult = pgresult;
|
1485
1485
|
}
|
data/lib/2.5/pg_ext.so
CHANGED
Binary file
|
data/lib/2.6/pg_ext.so
CHANGED
Binary file
|
data/lib/2.7/pg_ext.so
CHANGED
Binary file
|
data/lib/3.0/pg_ext.so
CHANGED
Binary file
|
data/lib/3.1/pg_ext.so
CHANGED
Binary file
|
data/lib/pg/connection.rb
CHANGED
@@ -46,37 +46,6 @@ class PG::Connection
|
|
46
46
|
hash.map { |k,v| "#{k}=#{quote_connstr(v)}" }.join( ' ' )
|
47
47
|
end
|
48
48
|
|
49
|
-
# Decode a connection string to Hash options
|
50
|
-
#
|
51
|
-
# Value are properly unquoted and unescaped.
|
52
|
-
def self.connect_string_to_hash( str )
|
53
|
-
options = {}
|
54
|
-
key = nil
|
55
|
-
value = String.new
|
56
|
-
str.scan(/\G\s*(?>([^\s\\\']+)\s*=\s*|([^\s\\\']+)|'((?:[^\'\\]|\\.)*)'|(\\.?)|(\S))(\s|\z)?/m) do
|
57
|
-
|k, word, sq, esc, garbage, sep|
|
58
|
-
raise ArgumentError, "unterminated quoted string in connection info string: #{str.inspect}" if garbage
|
59
|
-
if k
|
60
|
-
key = k
|
61
|
-
else
|
62
|
-
value << (word || (sq || esc).gsub(/\\(.)/, '\\1'))
|
63
|
-
end
|
64
|
-
if sep
|
65
|
-
raise ArgumentError, "missing = after #{value.inspect}" unless key
|
66
|
-
options[key.to_sym] = value
|
67
|
-
key = nil
|
68
|
-
value = String.new
|
69
|
-
end
|
70
|
-
end
|
71
|
-
options
|
72
|
-
end
|
73
|
-
|
74
|
-
# URI defined in RFC3986
|
75
|
-
# This regexp is modified to allow host to specify multiple comma separated components captured as <hostports> and to disallow comma in hostnames.
|
76
|
-
# Taken from: https://github.com/ruby/ruby/blob/be04006c7d2f9aeb7e9d8d09d945b3a9c7850202/lib/uri/rfc3986_parser.rb#L6
|
77
|
-
HOST_AND_PORT = /(?<hostport>(?<host>(?<IP-literal>\[(?:(?<IPv6address>(?:\h{1,4}:){6}(?<ls32>\h{1,4}:\h{1,4}|(?<IPv4address>(?<dec-octet>[1-9]\d|1\d{2}|2[0-4]\d|25[0-5]|\d)\.\g<dec-octet>\.\g<dec-octet>\.\g<dec-octet>))|::(?:\h{1,4}:){5}\g<ls32>|\h{1,4}?::(?:\h{1,4}:){4}\g<ls32>|(?:(?:\h{1,4}:)?\h{1,4})?::(?:\h{1,4}:){3}\g<ls32>|(?:(?:\h{1,4}:){,2}\h{1,4})?::(?:\h{1,4}:){2}\g<ls32>|(?:(?:\h{1,4}:){,3}\h{1,4})?::\h{1,4}:\g<ls32>|(?:(?:\h{1,4}:){,4}\h{1,4})?::\g<ls32>|(?:(?:\h{1,4}:){,5}\h{1,4})?::\h{1,4}|(?:(?:\h{1,4}:){,6}\h{1,4})?::)|(?<IPvFuture>v\h+\.[!$&-.0-;=A-Z_a-z~]+))\])|\g<IPv4address>|(?<reg-name>(?:%\h\h|[-\.!$&-+0-9;=A-Z_a-z~])+))?(?::(?<port>\d*))?)/
|
78
|
-
POSTGRESQL_URI = /\A(?<URI>(?<scheme>[A-Za-z][+\-.0-9A-Za-z]*):(?<hier-part>\/\/(?<authority>(?:(?<userinfo>(?:%\h\h|[!$&-.0-;=A-Z_a-z~])*)@)?(?<hostports>#{HOST_AND_PORT}(?:,\g<hostport>)*))(?<path-abempty>(?:\/(?<segment>(?:%\h\h|[!$&-.0-;=@-Z_a-z~])*))*)|(?<path-absolute>\/(?:(?<segment-nz>(?:%\h\h|[!$&-.0-;=@-Z_a-z~])+)(?:\/\g<segment>)*)?)|(?<path-rootless>\g<segment-nz>(?:\/\g<segment>)*)|(?<path-empty>))(?:\?(?<query>[^#]*))?(?:\#(?<fragment>(?:%\h\h|[!$&-.0-;=@-Z_a-z~\/?])*))?)\z/
|
79
|
-
|
80
49
|
# Parse the connection +args+ into a connection-parameter string.
|
81
50
|
# See PG::Connection.new for valid arguments.
|
82
51
|
#
|
@@ -87,91 +56,43 @@ class PG::Connection
|
|
87
56
|
# * URI object
|
88
57
|
# * positional arguments
|
89
58
|
#
|
90
|
-
# The method adds the option "
|
91
|
-
#
|
92
|
-
|
93
|
-
def self::parse_connect_args( *args )
|
59
|
+
# The method adds the option "fallback_application_name" if it isn't already set.
|
60
|
+
# It returns a connection string with "key=value" pairs.
|
61
|
+
def self.parse_connect_args( *args )
|
94
62
|
hash_arg = args.last.is_a?( Hash ) ? args.pop.transform_keys(&:to_sym) : {}
|
95
|
-
option_string = ""
|
96
63
|
iopts = {}
|
97
64
|
|
98
65
|
if args.length == 1
|
99
66
|
case args.first
|
100
|
-
when URI,
|
101
|
-
|
102
|
-
|
103
|
-
if
|
104
|
-
iopts = URI.decode_www_form(uri_match['query']).to_h.transform_keys(&:to_sym)
|
105
|
-
end
|
106
|
-
# extract "host1,host2" from "host1:5432,host2:5432"
|
107
|
-
iopts[:host] = uri_match['hostports'].split(',', -1).map do |hostport|
|
108
|
-
hostmatch = /\A#{HOST_AND_PORT}\z/.match(hostport)
|
109
|
-
hostmatch['IPv6address'] || hostmatch['IPv4address'] || hostmatch['reg-name']&.gsub(/%(\h\h)/){ $1.hex.chr }
|
110
|
-
end.join(',')
|
111
|
-
oopts = {}
|
112
|
-
when /=/
|
113
|
-
# Option string style
|
114
|
-
option_string = args.first.to_s
|
115
|
-
iopts = connect_string_to_hash(option_string)
|
116
|
-
oopts = {}
|
67
|
+
when URI, /=/, /:\/\//
|
68
|
+
# Option or URL string style
|
69
|
+
conn_string = args.first.to_s
|
70
|
+
iopts = PG::Connection.conninfo_parse(conn_string).each_with_object({}){|h, o| o[h[:keyword].to_sym] = h[:val] if h[:val] }
|
117
71
|
else
|
118
72
|
# Positional parameters (only host given)
|
119
73
|
iopts[CONNECT_ARGUMENT_ORDER.first.to_sym] = args.first
|
120
|
-
oopts = iopts.dup
|
121
74
|
end
|
122
75
|
else
|
123
|
-
# Positional parameters
|
76
|
+
# Positional parameters with host and more
|
124
77
|
max = CONNECT_ARGUMENT_ORDER.length
|
125
78
|
raise ArgumentError,
|
126
|
-
|
79
|
+
"Extra positional parameter %d: %p" % [ max + 1, args[max] ] if args.length > max
|
127
80
|
|
128
81
|
CONNECT_ARGUMENT_ORDER.zip( args ) do |(k,v)|
|
129
82
|
iopts[ k.to_sym ] = v if v
|
130
83
|
end
|
131
84
|
iopts.delete(:tty) # ignore obsolete tty parameter
|
132
|
-
oopts = iopts.dup
|
133
85
|
end
|
134
86
|
|
135
87
|
iopts.merge!( hash_arg )
|
136
|
-
oopts.merge!( hash_arg )
|
137
|
-
|
138
|
-
# Resolve DNS in Ruby to avoid blocking state while connecting, when it ...
|
139
|
-
if (host=iopts[:host]) && !iopts[:hostaddr]
|
140
|
-
hostaddrs = host.split(",", -1).map do |mhost|
|
141
|
-
if !mhost.empty? && !mhost.start_with?("/") && # isn't UnixSocket
|
142
|
-
# isn't a path on Windows
|
143
|
-
(RUBY_PLATFORM !~ /mingw|mswin/ || mhost !~ /\A\w:[\/\\]/)
|
144
|
-
|
145
|
-
if Fiber.respond_to?(:scheduler) &&
|
146
|
-
Fiber.scheduler &&
|
147
|
-
RUBY_VERSION < '3.1.'
|
148
|
-
|
149
|
-
# Use a second thread to avoid blocking of the scheduler.
|
150
|
-
# `IPSocket.getaddress` isn't fiber aware before ruby-3.1.
|
151
|
-
Thread.new{ IPSocket.getaddress(mhost) rescue '' }.value
|
152
|
-
else
|
153
|
-
IPSocket.getaddress(mhost) rescue ''
|
154
|
-
end
|
155
|
-
end
|
156
|
-
end
|
157
|
-
oopts[:hostaddr] = hostaddrs.join(",") if hostaddrs.any?
|
158
|
-
end
|
159
88
|
|
160
89
|
if !iopts[:fallback_application_name]
|
161
|
-
|
90
|
+
iopts[:fallback_application_name] = $0.sub( /^(.{30}).{4,}(.{30})$/ ){ $1+"..."+$2 }
|
162
91
|
end
|
163
92
|
|
164
|
-
|
165
|
-
uri += uri_match['query'] ? "&" : "?"
|
166
|
-
uri += URI.encode_www_form( oopts )
|
167
|
-
return uri
|
168
|
-
else
|
169
|
-
option_string += ' ' unless option_string.empty? && oopts.empty?
|
170
|
-
return option_string + connect_hash_to_string(oopts)
|
171
|
-
end
|
93
|
+
return connect_hash_to_string(iopts)
|
172
94
|
end
|
173
95
|
|
174
|
-
|
175
96
|
# call-seq:
|
176
97
|
# conn.copy_data( sql [, coder] ) {|sql_result| ... } -> PG::Result
|
177
98
|
#
|
@@ -241,7 +162,7 @@ class PG::Connection
|
|
241
162
|
# ["more", "data", "to", "copy"]
|
242
163
|
|
243
164
|
def copy_data( sql, coder=nil )
|
244
|
-
raise PG::NotInBlockingMode
|
165
|
+
raise PG::NotInBlockingMode.new("copy_data can not be used in nonblocking mode", connection: self) if nonblocking?
|
245
166
|
res = exec( sql )
|
246
167
|
|
247
168
|
case res.result_status
|
@@ -273,11 +194,15 @@ class PG::Connection
|
|
273
194
|
yield res
|
274
195
|
rescue Exception => err
|
275
196
|
cancel
|
276
|
-
|
197
|
+
begin
|
198
|
+
while get_copy_data
|
199
|
+
end
|
200
|
+
rescue PG::Error
|
201
|
+
# Ignore error in cleanup to avoid losing original exception
|
277
202
|
end
|
278
203
|
while get_result
|
279
204
|
end
|
280
|
-
raise
|
205
|
+
raise err
|
281
206
|
else
|
282
207
|
res = get_last_result
|
283
208
|
if !res || res.result_status != PGRES_COMMAND_OK
|
@@ -285,7 +210,7 @@ class PG::Connection
|
|
285
210
|
end
|
286
211
|
while get_result
|
287
212
|
end
|
288
|
-
raise PG::NotAllCopyDataRetrieved
|
213
|
+
raise PG::NotAllCopyDataRetrieved.new("Not all COPY data retrieved", connection: self)
|
289
214
|
end
|
290
215
|
res
|
291
216
|
ensure
|
@@ -310,16 +235,17 @@ class PG::Connection
|
|
310
235
|
# and a +COMMIT+ at the end of the block, or
|
311
236
|
# +ROLLBACK+ if any exception occurs.
|
312
237
|
def transaction
|
238
|
+
rollback = false
|
313
239
|
exec "BEGIN"
|
314
|
-
|
240
|
+
yield(self)
|
315
241
|
rescue Exception
|
242
|
+
rollback = true
|
316
243
|
cancel if transaction_status == PG::PQTRANS_ACTIVE
|
317
244
|
block
|
318
245
|
exec "ROLLBACK"
|
319
246
|
raise
|
320
|
-
|
321
|
-
exec "COMMIT"
|
322
|
-
res
|
247
|
+
ensure
|
248
|
+
exec "COMMIT" unless rollback
|
323
249
|
end
|
324
250
|
|
325
251
|
### Returns an array of Hashes with connection defaults. See ::conndefaults
|
@@ -482,10 +408,10 @@ class PG::Connection
|
|
482
408
|
# See also #copy_data.
|
483
409
|
#
|
484
410
|
def put_copy_data(buffer, encoder=nil)
|
485
|
-
until sync_put_copy_data(buffer, encoder)
|
486
|
-
flush
|
411
|
+
until res=sync_put_copy_data(buffer, encoder)
|
412
|
+
res = flush
|
487
413
|
end
|
488
|
-
|
414
|
+
res
|
489
415
|
end
|
490
416
|
alias async_put_copy_data put_copy_data
|
491
417
|
|
@@ -545,6 +471,7 @@ class PG::Connection
|
|
545
471
|
def reset
|
546
472
|
reset_start
|
547
473
|
async_connect_or_reset(:reset_poll)
|
474
|
+
self
|
548
475
|
end
|
549
476
|
alias async_reset reset
|
550
477
|
|
@@ -613,28 +540,62 @@ class PG::Connection
|
|
613
540
|
|
614
541
|
private def async_connect_or_reset(poll_meth)
|
615
542
|
# Track the progress of the connection, waiting for the socket to become readable/writable before polling it
|
543
|
+
|
544
|
+
if (timeo = conninfo_hash[:connect_timeout].to_i) && timeo > 0
|
545
|
+
# Lowest timeout is 2 seconds - like in libpq
|
546
|
+
timeo = [timeo, 2].max
|
547
|
+
stop_time = timeo + Process.clock_gettime(Process::CLOCK_MONOTONIC)
|
548
|
+
end
|
549
|
+
|
616
550
|
poll_status = PG::PGRES_POLLING_WRITING
|
617
551
|
until poll_status == PG::PGRES_POLLING_OK ||
|
618
552
|
poll_status == PG::PGRES_POLLING_FAILED
|
619
553
|
|
620
|
-
|
621
|
-
|
622
|
-
|
623
|
-
|
554
|
+
timeout = stop_time&.-(Process.clock_gettime(Process::CLOCK_MONOTONIC))
|
555
|
+
event = if !timeout || timeout >= 0
|
556
|
+
# If the socket needs to read, wait 'til it becomes readable to poll again
|
557
|
+
case poll_status
|
558
|
+
when PG::PGRES_POLLING_READING
|
559
|
+
if defined?(IO::READABLE) # ruby-3.0+
|
560
|
+
socket_io.wait(IO::READABLE | IO::PRIORITY, timeout)
|
561
|
+
else
|
562
|
+
IO.select([socket_io], nil, [socket_io], timeout)
|
563
|
+
end
|
624
564
|
|
625
|
-
|
626
|
-
|
627
|
-
|
565
|
+
# ...and the same for when the socket needs to write
|
566
|
+
when PG::PGRES_POLLING_WRITING
|
567
|
+
if defined?(IO::WRITABLE) # ruby-3.0+
|
568
|
+
# Use wait instead of wait_readable, since connection errors are delivered as
|
569
|
+
# exceptional/priority events on Windows.
|
570
|
+
socket_io.wait(IO::WRITABLE | IO::PRIORITY, timeout)
|
571
|
+
else
|
572
|
+
# io#wait on ruby-2.x doesn't wait for priority, so fallback to IO.select
|
573
|
+
IO.select(nil, [socket_io], [socket_io], timeout)
|
574
|
+
end
|
575
|
+
end
|
576
|
+
end
|
577
|
+
# connection to server at "localhost" (127.0.0.1), port 5433 failed: timeout expired (PG::ConnectionBad)
|
578
|
+
# connection to server on socket "/var/run/postgresql/.s.PGSQL.5433" failed: No such file or directory
|
579
|
+
unless event
|
580
|
+
if self.class.send(:host_is_named_pipe?, host)
|
581
|
+
connhost = "on socket \"#{host}\""
|
582
|
+
elsif respond_to?(:hostaddr)
|
583
|
+
connhost = "at \"#{host}\" (#{hostaddr}), port #{port}"
|
584
|
+
else
|
585
|
+
connhost = "at \"#{host}\", port #{port}"
|
586
|
+
end
|
587
|
+
raise PG::ConnectionBad.new("connection to server #{connhost} failed: timeout expired", connection: self)
|
628
588
|
end
|
629
589
|
|
630
590
|
# Check to see if it's finished or failed yet
|
631
591
|
poll_status = send( poll_meth )
|
592
|
+
@last_status = status unless [PG::CONNECTION_BAD, PG::CONNECTION_OK].include?(status)
|
632
593
|
end
|
633
594
|
|
634
595
|
unless status == PG::CONNECTION_OK
|
635
596
|
msg = error_message
|
636
597
|
finish
|
637
|
-
raise PG::ConnectionBad,
|
598
|
+
raise PG::ConnectionBad.new(msg, connection: self)
|
638
599
|
end
|
639
600
|
|
640
601
|
# Set connection to nonblocking to handle all blocking states in ruby.
|
@@ -642,8 +603,6 @@ class PG::Connection
|
|
642
603
|
sync_setnonblocking(true)
|
643
604
|
self.flush_data = true
|
644
605
|
set_default_encoding
|
645
|
-
|
646
|
-
self
|
647
606
|
end
|
648
607
|
|
649
608
|
class << self
|
@@ -698,13 +657,17 @@ class PG::Connection
|
|
698
657
|
# connection will have its +client_encoding+ set accordingly.
|
699
658
|
#
|
700
659
|
# Raises a PG::Error if the connection fails.
|
701
|
-
def new(*args
|
702
|
-
conn =
|
703
|
-
|
704
|
-
|
705
|
-
|
706
|
-
|
707
|
-
|
660
|
+
def new(*args)
|
661
|
+
conn = connect_to_hosts(*args)
|
662
|
+
|
663
|
+
if block_given?
|
664
|
+
begin
|
665
|
+
return yield conn
|
666
|
+
ensure
|
667
|
+
conn.finish
|
668
|
+
end
|
669
|
+
end
|
670
|
+
conn
|
708
671
|
end
|
709
672
|
alias async_connect new
|
710
673
|
alias connect new
|
@@ -712,6 +675,99 @@ class PG::Connection
|
|
712
675
|
alias setdb new
|
713
676
|
alias setdblogin new
|
714
677
|
|
678
|
+
private def connect_to_hosts(*args)
|
679
|
+
option_string = parse_connect_args(*args)
|
680
|
+
iopts = PG::Connection.conninfo_parse(option_string).each_with_object({}){|h, o| o[h[:keyword].to_sym] = h[:val] if h[:val] }
|
681
|
+
iopts = PG::Connection.conndefaults.each_with_object({}){|h, o| o[h[:keyword].to_sym] = h[:val] if h[:val] }.merge(iopts)
|
682
|
+
|
683
|
+
errors = []
|
684
|
+
if iopts[:hostaddr]
|
685
|
+
# hostaddr is provided -> no need to resolve hostnames
|
686
|
+
ihostaddrs = iopts[:hostaddr].split(",", -1)
|
687
|
+
|
688
|
+
ihosts = iopts[:host].split(",", -1) if iopts[:host]
|
689
|
+
raise PG::ConnectionBad, "could not match #{ihosts.size} host names to #{ihostaddrs.size} hostaddr values" if ihosts && ihosts.size != ihostaddrs.size
|
690
|
+
|
691
|
+
iports = iopts[:port].split(",", -1)
|
692
|
+
iports = iports * ihostaddrs.size if iports.size == 1
|
693
|
+
raise PG::ConnectionBad, "could not match #{iports.size} port numbers to #{ihostaddrs.size} hosts" if iports.size != ihostaddrs.size
|
694
|
+
|
695
|
+
# Try to connect to each hostaddr with separate timeout
|
696
|
+
ihostaddrs.each_with_index do |ihostaddr, idx|
|
697
|
+
oopts = iopts.merge(hostaddr: ihostaddr, port: iports[idx])
|
698
|
+
oopts[:host] = ihosts[idx] if ihosts
|
699
|
+
c = connect_internal(oopts, errors)
|
700
|
+
return c if c
|
701
|
+
end
|
702
|
+
elsif iopts[:host] && !iopts[:host].empty?
|
703
|
+
# Resolve DNS in Ruby to avoid blocking state while connecting, when it ...
|
704
|
+
ihosts = iopts[:host].split(",", -1)
|
705
|
+
|
706
|
+
iports = iopts[:port].split(",", -1)
|
707
|
+
iports = iports * ihosts.size if iports.size == 1
|
708
|
+
raise PG::ConnectionBad, "could not match #{iports.size} port numbers to #{ihosts.size} hosts" if iports.size != ihosts.size
|
709
|
+
|
710
|
+
ihosts.each_with_index do |mhost, idx|
|
711
|
+
unless host_is_named_pipe?(mhost)
|
712
|
+
addrs = if Fiber.respond_to?(:scheduler) &&
|
713
|
+
Fiber.scheduler &&
|
714
|
+
RUBY_VERSION < '3.1.'
|
715
|
+
|
716
|
+
# Use a second thread to avoid blocking of the scheduler.
|
717
|
+
# `TCPSocket.gethostbyname` isn't fiber aware before ruby-3.1.
|
718
|
+
Thread.new{ Addrinfo.getaddrinfo(mhost, nil, nil, :STREAM).map(&:ip_address) rescue [''] }.value
|
719
|
+
else
|
720
|
+
Addrinfo.getaddrinfo(mhost, nil, nil, :STREAM).map(&:ip_address) rescue ['']
|
721
|
+
end
|
722
|
+
|
723
|
+
# Try to connect to each host with separate timeout
|
724
|
+
addrs.each do |addr|
|
725
|
+
oopts = iopts.merge(hostaddr: addr, host: mhost, port: iports[idx])
|
726
|
+
c = connect_internal(oopts, errors)
|
727
|
+
return c if c
|
728
|
+
end
|
729
|
+
else
|
730
|
+
# No hostname to resolve (UnixSocket)
|
731
|
+
oopts = iopts.merge(host: mhost, port: iports[idx])
|
732
|
+
c = connect_internal(oopts, errors)
|
733
|
+
return c if c
|
734
|
+
end
|
735
|
+
end
|
736
|
+
else
|
737
|
+
# No host given
|
738
|
+
return connect_internal(iopts)
|
739
|
+
end
|
740
|
+
raise PG::ConnectionBad, errors.join("\n")
|
741
|
+
end
|
742
|
+
|
743
|
+
private def connect_internal(opts, errors=nil)
|
744
|
+
begin
|
745
|
+
conn = self.connect_start(opts) or
|
746
|
+
raise(PG::Error, "Unable to create a new connection")
|
747
|
+
|
748
|
+
raise PG::ConnectionBad.new(conn.error_message, connection: self) if conn.status == PG::CONNECTION_BAD
|
749
|
+
|
750
|
+
conn.send(:async_connect_or_reset, :connect_poll)
|
751
|
+
rescue PG::ConnectionBad => err
|
752
|
+
if errors && !(conn && [PG::CONNECTION_AWAITING_RESPONSE].include?(conn.instance_variable_get(:@last_status)))
|
753
|
+
# Seems to be no authentication error -> try next host
|
754
|
+
errors << err
|
755
|
+
return nil
|
756
|
+
else
|
757
|
+
# Probably an authentication error
|
758
|
+
raise
|
759
|
+
end
|
760
|
+
end
|
761
|
+
conn
|
762
|
+
end
|
763
|
+
|
764
|
+
private def host_is_named_pipe?(host_string)
|
765
|
+
host_string.empty? || host_string.start_with?("/") || # it's UnixSocket?
|
766
|
+
host_string.start_with?("@") || # it's UnixSocket in the abstract namespace?
|
767
|
+
# it's a path on Windows?
|
768
|
+
(RUBY_PLATFORM =~ /mingw|mswin/ && host_string =~ /\A([\/\\]|\w:[\/\\])/)
|
769
|
+
end
|
770
|
+
|
715
771
|
# call-seq:
|
716
772
|
# PG::Connection.ping(connection_hash) -> Integer
|
717
773
|
# PG::Connection.ping(connection_string) -> Integer
|
data/lib/pg/exceptions.rb
CHANGED
@@ -6,7 +6,13 @@ require 'pg' unless defined?( PG )
|
|
6
6
|
|
7
7
|
module PG
|
8
8
|
|
9
|
-
class Error < StandardError
|
9
|
+
class Error < StandardError
|
10
|
+
def initialize(msg=nil, connection: nil, result: nil)
|
11
|
+
@connection = connection
|
12
|
+
@result = result
|
13
|
+
super(msg)
|
14
|
+
end
|
15
|
+
end
|
10
16
|
|
11
17
|
end # module PG
|
12
18
|
|
data/lib/pg/version.rb
CHANGED
data/lib/pg.rb
CHANGED
@@ -59,14 +59,14 @@ module PG
|
|
59
59
|
# Get the PG library version.
|
60
60
|
#
|
61
61
|
# +include_buildnum+ is no longer used and any value passed will be ignored.
|
62
|
-
def self
|
63
|
-
|
62
|
+
def self.version_string( include_buildnum=nil )
|
63
|
+
"%s %s" % [ self.name, VERSION ]
|
64
64
|
end
|
65
65
|
|
66
66
|
|
67
67
|
### Convenience alias for PG::Connection.new.
|
68
|
-
def self
|
69
|
-
|
68
|
+
def self.connect( *args, &block )
|
69
|
+
Connection.new( *args, &block )
|
70
70
|
end
|
71
71
|
|
72
72
|
|
data/lib/x86-mingw32/libpq.dll
CHANGED
Binary file
|
data.tar.gz.sig
CHANGED
Binary file
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: pg
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.4.2
|
5
5
|
platform: x86-mingw32
|
6
6
|
authors:
|
7
7
|
- Michael Granger
|
@@ -36,7 +36,7 @@ cert_chain:
|
|
36
36
|
oL1mUdzB8KrZL4/WbG5YNX6UTtJbIOu9qEFbBAy4/jtIkJX+dlNoFwd4GXQW1YNO
|
37
37
|
nA==
|
38
38
|
-----END CERTIFICATE-----
|
39
|
-
date: 2022-
|
39
|
+
date: 2022-07-27 00:00:00.000000000 Z
|
40
40
|
dependencies: []
|
41
41
|
description: Pg is the Ruby interface to the PostgreSQL RDBMS. It works with PostgreSQL
|
42
42
|
9.3 and later.
|
metadata.gz.sig
CHANGED
Binary file
|