pg 1.4.5 → 1.5.3
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/.appveyor.yml +15 -9
- data/.github/workflows/binary-gems.yml +41 -10
- data/.github/workflows/source-gem.yml +18 -12
- data/.gitignore +11 -2
- data/.travis.yml +2 -2
- data/{History.rdoc → History.md} +240 -153
- data/README.ja.md +276 -0
- data/README.md +286 -0
- data/Rakefile +12 -3
- data/Rakefile.cross +7 -11
- data/certs/larskanis-2023.pem +24 -0
- data/ext/pg.c +10 -28
- data/ext/pg.h +10 -5
- data/ext/pg_binary_decoder.c +79 -0
- data/ext/pg_binary_encoder.c +224 -0
- data/ext/pg_coder.c +16 -7
- data/ext/pg_connection.c +156 -60
- data/ext/pg_copy_coder.c +306 -17
- data/ext/pg_record_coder.c +5 -4
- data/ext/pg_result.c +91 -17
- data/ext/pg_text_decoder.c +28 -10
- data/ext/pg_text_encoder.c +22 -9
- data/ext/pg_tuple.c +34 -31
- data/ext/pg_type_map.c +3 -2
- data/ext/pg_type_map_all_strings.c +2 -2
- data/ext/pg_type_map_by_class.c +5 -3
- data/ext/pg_type_map_by_column.c +7 -3
- data/ext/pg_type_map_by_oid.c +7 -4
- data/ext/pg_type_map_in_ruby.c +5 -2
- data/lib/pg/basic_type_map_based_on_result.rb +21 -1
- data/lib/pg/basic_type_map_for_queries.rb +13 -8
- data/lib/pg/basic_type_map_for_results.rb +26 -3
- data/lib/pg/basic_type_registry.rb +30 -32
- data/lib/pg/binary_decoder/date.rb +9 -0
- data/lib/pg/binary_decoder/timestamp.rb +26 -0
- data/lib/pg/binary_encoder/timestamp.rb +20 -0
- data/lib/pg/coder.rb +15 -13
- data/lib/pg/connection.rb +103 -30
- data/lib/pg/exceptions.rb +7 -0
- data/lib/pg/text_decoder/date.rb +18 -0
- data/lib/pg/text_decoder/inet.rb +9 -0
- data/lib/pg/text_decoder/json.rb +14 -0
- data/lib/pg/text_decoder/numeric.rb +9 -0
- data/lib/pg/text_decoder/timestamp.rb +30 -0
- data/lib/pg/text_encoder/date.rb +12 -0
- data/lib/pg/text_encoder/inet.rb +28 -0
- data/lib/pg/text_encoder/json.rb +14 -0
- data/lib/pg/text_encoder/numeric.rb +9 -0
- data/lib/pg/text_encoder/timestamp.rb +24 -0
- data/lib/pg/version.rb +1 -1
- data/lib/pg.rb +55 -15
- data/pg.gemspec +4 -2
- data/rakelib/task_extension.rb +1 -1
- data/translation/.po4a-version +7 -0
- data/translation/po/all.pot +910 -0
- data/translation/po/ja.po +1047 -0
- data/translation/po4a.cfg +12 -0
- data.tar.gz.sig +0 -0
- metadata +109 -34
- metadata.gz.sig +0 -0
- data/README.ja.rdoc +0 -13
- data/README.rdoc +0 -233
- data/lib/pg/binary_decoder.rb +0 -23
- data/lib/pg/constants.rb +0 -12
- data/lib/pg/text_decoder.rb +0 -46
- data/lib/pg/text_encoder.rb +0 -59
data/lib/pg/connection.rb
CHANGED
@@ -2,8 +2,7 @@
|
|
2
2
|
# frozen_string_literal: true
|
3
3
|
|
4
4
|
require 'pg' unless defined?( PG )
|
5
|
-
require '
|
6
|
-
require 'io/wait'
|
5
|
+
require 'io/wait' unless ::IO.public_instance_methods(false).include?(:wait_readable)
|
7
6
|
require 'socket'
|
8
7
|
|
9
8
|
# The PostgreSQL connection class. The interface for this class is based on
|
@@ -31,8 +30,8 @@ require 'socket'
|
|
31
30
|
class PG::Connection
|
32
31
|
|
33
32
|
# The order the options are passed to the ::connect method.
|
34
|
-
CONNECT_ARGUMENT_ORDER = %w[host port options tty dbname user password]
|
35
|
-
|
33
|
+
CONNECT_ARGUMENT_ORDER = %w[host port options tty dbname user password].freeze
|
34
|
+
private_constant :CONNECT_ARGUMENT_ORDER
|
36
35
|
|
37
36
|
### Quote a single +value+ for use in a connection-parameter string.
|
38
37
|
def self.quote_connstr( value )
|
@@ -46,6 +45,10 @@ class PG::Connection
|
|
46
45
|
hash.map { |k,v| "#{k}=#{quote_connstr(v)}" }.join( ' ' )
|
47
46
|
end
|
48
47
|
|
48
|
+
# Shareable program name for Ractor
|
49
|
+
PROGRAM_NAME = $PROGRAM_NAME.dup.freeze
|
50
|
+
private_constant :PROGRAM_NAME
|
51
|
+
|
49
52
|
# Parse the connection +args+ into a connection-parameter string.
|
50
53
|
# See PG::Connection.new for valid arguments.
|
51
54
|
#
|
@@ -63,8 +66,8 @@ class PG::Connection
|
|
63
66
|
iopts = {}
|
64
67
|
|
65
68
|
if args.length == 1
|
66
|
-
case args.first
|
67
|
-
when
|
69
|
+
case args.first.to_s
|
70
|
+
when /=/, /:\/\//
|
68
71
|
# Option or URL string style
|
69
72
|
conn_string = args.first.to_s
|
70
73
|
iopts = PG::Connection.conninfo_parse(conn_string).each_with_object({}){|h, o| o[h[:keyword].to_sym] = h[:val] if h[:val] }
|
@@ -87,7 +90,7 @@ class PG::Connection
|
|
87
90
|
iopts.merge!( hash_arg )
|
88
91
|
|
89
92
|
if !iopts[:fallback_application_name]
|
90
|
-
iopts[:fallback_application_name] =
|
93
|
+
iopts[:fallback_application_name] = PROGRAM_NAME.sub( /^(.{30}).{4,}(.{30})$/ ){ $1+"..."+$2 }
|
91
94
|
end
|
92
95
|
|
93
96
|
return connect_hash_to_string(iopts)
|
@@ -114,6 +117,9 @@ class PG::Connection
|
|
114
117
|
return str
|
115
118
|
end
|
116
119
|
|
120
|
+
BinarySignature = "PGCOPY\n\377\r\n\0".b
|
121
|
+
private_constant :BinarySignature
|
122
|
+
|
117
123
|
# call-seq:
|
118
124
|
# conn.copy_data( sql [, coder] ) {|sql_result| ... } -> PG::Result
|
119
125
|
#
|
@@ -160,6 +166,14 @@ class PG::Connection
|
|
160
166
|
# conn.put_copy_data ['more', 'data', 'to', 'copy']
|
161
167
|
# end
|
162
168
|
#
|
169
|
+
# Also PG::BinaryEncoder::CopyRow can be used to send data in binary format to the server.
|
170
|
+
# In this case copy_data generates the header and trailer data automatically:
|
171
|
+
# enco = PG::BinaryEncoder::CopyRow.new
|
172
|
+
# conn.copy_data "COPY my_table FROM STDIN (FORMAT binary)", enco do
|
173
|
+
# conn.put_copy_data ['some', 'data', 'to', 'copy']
|
174
|
+
# conn.put_copy_data ['more', 'data', 'to', 'copy']
|
175
|
+
# end
|
176
|
+
#
|
163
177
|
# Example with CSV output format:
|
164
178
|
# conn.copy_data "COPY my_table TO STDOUT CSV" do
|
165
179
|
# while row=conn.get_copy_data
|
@@ -181,6 +195,18 @@ class PG::Connection
|
|
181
195
|
# This receives all rows of +my_table+ as ruby array:
|
182
196
|
# ["some", "data", "to", "copy"]
|
183
197
|
# ["more", "data", "to", "copy"]
|
198
|
+
#
|
199
|
+
# Also PG::BinaryDecoder::CopyRow can be used to retrieve data in binary format from the server.
|
200
|
+
# In this case the header and trailer data is processed by the decoder and the remaining +nil+ from get_copy_data is processed by copy_data, so that binary data can be processed equally to text data:
|
201
|
+
# deco = PG::BinaryDecoder::CopyRow.new
|
202
|
+
# conn.copy_data "COPY my_table TO STDOUT (FORMAT binary)", deco do
|
203
|
+
# while row=conn.get_copy_data
|
204
|
+
# p row
|
205
|
+
# end
|
206
|
+
# end
|
207
|
+
# This receives all rows of +my_table+ as ruby array:
|
208
|
+
# ["some", "data", "to", "copy"]
|
209
|
+
# ["more", "data", "to", "copy"]
|
184
210
|
|
185
211
|
def copy_data( sql, coder=nil )
|
186
212
|
raise PG::NotInBlockingMode.new("copy_data can not be used in nonblocking mode", connection: self) if nonblocking?
|
@@ -189,18 +215,38 @@ class PG::Connection
|
|
189
215
|
case res.result_status
|
190
216
|
when PGRES_COPY_IN
|
191
217
|
begin
|
218
|
+
if coder && res.binary_tuples == 1
|
219
|
+
# Binary file header (11 byte signature, 32 bit flags and 32 bit extension length)
|
220
|
+
put_copy_data(BinarySignature + ("\x00" * 8))
|
221
|
+
end
|
222
|
+
|
192
223
|
if coder
|
193
224
|
old_coder = self.encoder_for_put_copy_data
|
194
225
|
self.encoder_for_put_copy_data = coder
|
195
226
|
end
|
227
|
+
|
196
228
|
yield res
|
197
229
|
rescue Exception => err
|
198
230
|
errmsg = "%s while copy data: %s" % [ err.class.name, err.message ]
|
199
|
-
|
200
|
-
|
201
|
-
|
231
|
+
begin
|
232
|
+
put_copy_end( errmsg )
|
233
|
+
rescue PG::Error
|
234
|
+
# Ignore error in cleanup to avoid losing original exception
|
235
|
+
end
|
236
|
+
discard_results
|
237
|
+
raise err
|
202
238
|
else
|
203
|
-
|
239
|
+
begin
|
240
|
+
self.encoder_for_put_copy_data = old_coder if coder
|
241
|
+
|
242
|
+
if coder && res.binary_tuples == 1
|
243
|
+
put_copy_data("\xFF\xFF") # Binary file trailer 16 bit "-1"
|
244
|
+
end
|
245
|
+
|
246
|
+
put_copy_end
|
247
|
+
rescue PG::Error => err
|
248
|
+
raise PG::LostCopyState.new("#{err} (probably by executing another SQL query while running a COPY command)", connection: self)
|
249
|
+
end
|
204
250
|
get_last_result
|
205
251
|
ensure
|
206
252
|
self.encoder_for_put_copy_data = old_coder if coder
|
@@ -213,24 +259,25 @@ class PG::Connection
|
|
213
259
|
self.decoder_for_get_copy_data = coder
|
214
260
|
end
|
215
261
|
yield res
|
216
|
-
rescue Exception
|
262
|
+
rescue Exception
|
217
263
|
cancel
|
218
|
-
|
219
|
-
|
264
|
+
discard_results
|
265
|
+
raise
|
266
|
+
else
|
267
|
+
if coder && res.binary_tuples == 1
|
268
|
+
# There are two end markers in binary mode: file trailer and the final nil.
|
269
|
+
# The file trailer is expected to be processed by BinaryDecoder::CopyRow and already returns nil, so that the remaining NULL from PQgetCopyData is retrieved here:
|
270
|
+
if get_copy_data
|
271
|
+
discard_results
|
272
|
+
raise PG::NotAllCopyDataRetrieved.new("Not all binary COPY data retrieved", connection: self)
|
220
273
|
end
|
221
|
-
rescue PG::Error
|
222
|
-
# Ignore error in cleanup to avoid losing original exception
|
223
|
-
end
|
224
|
-
while get_result
|
225
274
|
end
|
226
|
-
raise err
|
227
|
-
else
|
228
275
|
res = get_last_result
|
229
|
-
if !res
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
276
|
+
if !res
|
277
|
+
discard_results
|
278
|
+
raise PG::LostCopyState.new("Lost COPY state (probably by executing another SQL query while running a COPY command)", connection: self)
|
279
|
+
elsif res.result_status != PGRES_COMMAND_OK
|
280
|
+
discard_results
|
234
281
|
raise PG::NotAllCopyDataRetrieved.new("Not all COPY data retrieved", connection: self)
|
235
282
|
end
|
236
283
|
res
|
@@ -319,6 +366,23 @@ class PG::Connection
|
|
319
366
|
end
|
320
367
|
end
|
321
368
|
|
369
|
+
# Read all pending socket input to internal memory and raise an exception in case of errors.
|
370
|
+
#
|
371
|
+
# This verifies that the connection socket is in a usable state and not aborted in any way.
|
372
|
+
# No communication is done with the server.
|
373
|
+
# Only pending data is read from the socket - the method doesn't wait for any outstanding server answers.
|
374
|
+
#
|
375
|
+
# Raises a kind of PG::Error if there was an error reading the data or if the socket is in a failure state.
|
376
|
+
#
|
377
|
+
# The method doesn't verify that the server is still responding.
|
378
|
+
# To verify that the communication to the server works, it is recommended to use something like <tt>conn.exec('')</tt> instead.
|
379
|
+
def check_socket
|
380
|
+
while socket_io.wait_readable(0)
|
381
|
+
consume_input
|
382
|
+
end
|
383
|
+
nil
|
384
|
+
end
|
385
|
+
|
322
386
|
# call-seq:
|
323
387
|
# conn.get_result() -> PG::Result
|
324
388
|
# conn.get_result() {|pg_result| block }
|
@@ -773,7 +837,10 @@ class PG::Connection
|
|
773
837
|
# PG::Connection.ping(connection_string) -> Integer
|
774
838
|
# PG::Connection.ping(host, port, options, tty, dbname, login, password) -> Integer
|
775
839
|
#
|
776
|
-
#
|
840
|
+
# PQpingParams reports the status of the server.
|
841
|
+
#
|
842
|
+
# It accepts connection parameters identical to those of PQ::Connection.new .
|
843
|
+
# It is not necessary to supply correct user name, password, or database name values to obtain the server status; however, if incorrect values are provided, the server will log a failed connection attempt.
|
777
844
|
#
|
778
845
|
# See PG::Connection.new for a description of the parameters.
|
779
846
|
#
|
@@ -786,6 +853,8 @@ class PG::Connection
|
|
786
853
|
# could not establish connection
|
787
854
|
# [+PQPING_NO_ATTEMPT+]
|
788
855
|
# connection not attempted (bad params)
|
856
|
+
#
|
857
|
+
# See also check_socket for a way to check the connection without doing any server communication.
|
789
858
|
def ping(*args)
|
790
859
|
if Fiber.respond_to?(:scheduler) && Fiber.scheduler
|
791
860
|
# Run PQping in a second thread to avoid blocking of the scheduler.
|
@@ -797,23 +866,25 @@ class PG::Connection
|
|
797
866
|
end
|
798
867
|
alias async_ping ping
|
799
868
|
|
800
|
-
REDIRECT_CLASS_METHODS = {
|
869
|
+
REDIRECT_CLASS_METHODS = PG.make_shareable({
|
801
870
|
:new => [:async_connect, :sync_connect],
|
802
871
|
:connect => [:async_connect, :sync_connect],
|
803
872
|
:open => [:async_connect, :sync_connect],
|
804
873
|
:setdb => [:async_connect, :sync_connect],
|
805
874
|
:setdblogin => [:async_connect, :sync_connect],
|
806
875
|
:ping => [:async_ping, :sync_ping],
|
807
|
-
}
|
876
|
+
})
|
877
|
+
private_constant :REDIRECT_CLASS_METHODS
|
808
878
|
|
809
879
|
# These methods are affected by PQsetnonblocking
|
810
|
-
REDIRECT_SEND_METHODS = {
|
880
|
+
REDIRECT_SEND_METHODS = PG.make_shareable({
|
811
881
|
:isnonblocking => [:async_isnonblocking, :sync_isnonblocking],
|
812
882
|
:nonblocking? => [:async_isnonblocking, :sync_isnonblocking],
|
813
883
|
:put_copy_data => [:async_put_copy_data, :sync_put_copy_data],
|
814
884
|
:put_copy_end => [:async_put_copy_end, :sync_put_copy_end],
|
815
885
|
:flush => [:async_flush, :sync_flush],
|
816
|
-
}
|
886
|
+
})
|
887
|
+
private_constant :REDIRECT_SEND_METHODS
|
817
888
|
REDIRECT_METHODS = {
|
818
889
|
:exec => [:async_exec, :sync_exec],
|
819
890
|
:query => [:async_exec, :sync_exec],
|
@@ -831,12 +902,14 @@ class PG::Connection
|
|
831
902
|
:client_encoding= => [:async_set_client_encoding, :sync_set_client_encoding],
|
832
903
|
:cancel => [:async_cancel, :sync_cancel],
|
833
904
|
}
|
905
|
+
private_constant :REDIRECT_METHODS
|
834
906
|
|
835
907
|
if PG::Connection.instance_methods.include? :async_encrypt_password
|
836
908
|
REDIRECT_METHODS.merge!({
|
837
909
|
:encrypt_password => [:async_encrypt_password, :sync_encrypt_password],
|
838
910
|
})
|
839
911
|
end
|
912
|
+
PG.make_shareable(REDIRECT_METHODS)
|
840
913
|
|
841
914
|
def async_send_api=(enable)
|
842
915
|
REDIRECT_SEND_METHODS.each do |ali, (async, sync)|
|
data/lib/pg/exceptions.rb
CHANGED
@@ -0,0 +1,18 @@
|
|
1
|
+
# -*- ruby -*-
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
require 'date'
|
5
|
+
|
6
|
+
module PG
|
7
|
+
module TextDecoder
|
8
|
+
class Date < SimpleDecoder
|
9
|
+
def decode(string, tuple=nil, field=nil)
|
10
|
+
if string =~ /\A(\d{4})-(\d\d)-(\d\d)\z/
|
11
|
+
::Date.new $1.to_i, $2.to_i, $3.to_i
|
12
|
+
else
|
13
|
+
string
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end # module PG
|
@@ -0,0 +1,14 @@
|
|
1
|
+
# -*- ruby -*-
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
require 'json'
|
5
|
+
|
6
|
+
module PG
|
7
|
+
module TextDecoder
|
8
|
+
class JSON < SimpleDecoder
|
9
|
+
def decode(string, tuple=nil, field=nil)
|
10
|
+
::JSON.parse(string, quirks_mode: true)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end # module PG
|
@@ -0,0 +1,30 @@
|
|
1
|
+
# -*- ruby -*-
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
module PG
|
5
|
+
module TextDecoder
|
6
|
+
# Convenience classes for timezone options
|
7
|
+
class TimestampUtc < Timestamp
|
8
|
+
def initialize(hash={}, **kwargs)
|
9
|
+
warn("PG::Coder.new(hash) is deprecated. Please use keyword arguments instead! Called from #{caller.first}", category: :deprecated) unless hash.empty?
|
10
|
+
super(**hash, **kwargs, flags: PG::Coder::TIMESTAMP_DB_UTC | PG::Coder::TIMESTAMP_APP_UTC)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
class TimestampUtcToLocal < Timestamp
|
14
|
+
def initialize(hash={}, **kwargs)
|
15
|
+
warn("PG::Coder.new(hash) is deprecated. Please use keyword arguments instead! Called from #{caller.first}", category: :deprecated) unless hash.empty?
|
16
|
+
super(**hash, **kwargs, flags: PG::Coder::TIMESTAMP_DB_UTC | PG::Coder::TIMESTAMP_APP_LOCAL)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
class TimestampLocal < Timestamp
|
20
|
+
def initialize(hash={}, **kwargs)
|
21
|
+
warn("PG::Coder.new(hash) is deprecated. Please use keyword arguments instead! Called from #{caller.first}", category: :deprecated) unless hash.empty?
|
22
|
+
super(**hash, **kwargs, flags: PG::Coder::TIMESTAMP_DB_LOCAL | PG::Coder::TIMESTAMP_APP_LOCAL)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
# For backward compatibility:
|
27
|
+
TimestampWithoutTimeZone = TimestampLocal
|
28
|
+
TimestampWithTimeZone = Timestamp
|
29
|
+
end
|
30
|
+
end # module PG
|
@@ -0,0 +1,28 @@
|
|
1
|
+
# -*- ruby -*-
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
require 'ipaddr'
|
5
|
+
|
6
|
+
module PG
|
7
|
+
module TextEncoder
|
8
|
+
class Inet < SimpleEncoder
|
9
|
+
def encode(value)
|
10
|
+
case value
|
11
|
+
when IPAddr
|
12
|
+
default_prefix = (value.family == Socket::AF_INET ? 32 : 128)
|
13
|
+
s = value.to_s
|
14
|
+
if value.respond_to?(:prefix)
|
15
|
+
prefix = value.prefix
|
16
|
+
else
|
17
|
+
range = value.to_range
|
18
|
+
prefix = default_prefix - Math.log(((range.end.to_i - range.begin.to_i) + 1), 2).to_i
|
19
|
+
end
|
20
|
+
s << "/" << prefix.to_s if prefix != default_prefix
|
21
|
+
s
|
22
|
+
else
|
23
|
+
value
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end # module PG
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# -*- ruby -*-
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
module PG
|
5
|
+
module TextEncoder
|
6
|
+
class TimestampWithoutTimeZone < SimpleEncoder
|
7
|
+
def encode(value)
|
8
|
+
value.respond_to?(:strftime) ? value.strftime("%Y-%m-%d %H:%M:%S.%N") : value
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
class TimestampUtc < SimpleEncoder
|
13
|
+
def encode(value)
|
14
|
+
value.respond_to?(:utc) ? value.utc.strftime("%Y-%m-%d %H:%M:%S.%N") : value
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
class TimestampWithTimeZone < SimpleEncoder
|
19
|
+
def encode(value)
|
20
|
+
value.respond_to?(:strftime) ? value.strftime("%Y-%m-%d %H:%M:%S.%N %:z") : value
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end # module PG
|
data/lib/pg/version.rb
CHANGED
data/lib/pg.rb
CHANGED
@@ -50,12 +50,6 @@ module PG
|
|
50
50
|
end
|
51
51
|
end
|
52
52
|
|
53
|
-
|
54
|
-
class NotAllCopyDataRetrieved < PG::Error
|
55
|
-
end
|
56
|
-
class NotInBlockingMode < PG::Error
|
57
|
-
end
|
58
|
-
|
59
53
|
# Get the PG library version.
|
60
54
|
#
|
61
55
|
# +include_buildnum+ is no longer used and any value passed will be ignored.
|
@@ -69,21 +63,67 @@ module PG
|
|
69
63
|
Connection.new( *args, &block )
|
70
64
|
end
|
71
65
|
|
66
|
+
if defined?(Ractor.make_shareable)
|
67
|
+
def self.make_shareable(obj)
|
68
|
+
Ractor.make_shareable(obj)
|
69
|
+
end
|
70
|
+
else
|
71
|
+
def self.make_shareable(obj)
|
72
|
+
obj.freeze
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
module BinaryDecoder
|
77
|
+
%i[ TimestampUtc TimestampUtcToLocal TimestampLocal ].each do |klass|
|
78
|
+
autoload klass, 'pg/binary_decoder/timestamp'
|
79
|
+
end
|
80
|
+
autoload :Date, 'pg/binary_decoder/date'
|
81
|
+
end
|
82
|
+
module BinaryEncoder
|
83
|
+
%i[ TimestampUtc TimestampLocal ].each do |klass|
|
84
|
+
autoload klass, 'pg/binary_encoder/timestamp'
|
85
|
+
end
|
86
|
+
end
|
87
|
+
module TextDecoder
|
88
|
+
%i[ TimestampUtc TimestampUtcToLocal TimestampLocal TimestampWithoutTimeZone TimestampWithTimeZone ].each do |klass|
|
89
|
+
autoload klass, 'pg/text_decoder/timestamp'
|
90
|
+
end
|
91
|
+
autoload :Date, 'pg/text_decoder/date'
|
92
|
+
autoload :Inet, 'pg/text_decoder/inet'
|
93
|
+
autoload :JSON, 'pg/text_decoder/json'
|
94
|
+
autoload :Numeric, 'pg/text_decoder/numeric'
|
95
|
+
end
|
96
|
+
module TextEncoder
|
97
|
+
%i[ TimestampUtc TimestampWithoutTimeZone TimestampWithTimeZone ].each do |klass|
|
98
|
+
autoload klass, 'pg/text_encoder/timestamp'
|
99
|
+
end
|
100
|
+
autoload :Date, 'pg/text_encoder/date'
|
101
|
+
autoload :Inet, 'pg/text_encoder/inet'
|
102
|
+
autoload :JSON, 'pg/text_encoder/json'
|
103
|
+
autoload :Numeric, 'pg/text_encoder/numeric'
|
104
|
+
end
|
72
105
|
|
106
|
+
autoload :BasicTypeMapBasedOnResult, 'pg/basic_type_map_based_on_result'
|
107
|
+
autoload :BasicTypeMapForQueries, 'pg/basic_type_map_for_queries'
|
108
|
+
autoload :BasicTypeMapForResults, 'pg/basic_type_map_for_results'
|
109
|
+
autoload :BasicTypeRegistry, 'pg/basic_type_registry'
|
73
110
|
require 'pg/exceptions'
|
74
|
-
require 'pg/constants'
|
75
111
|
require 'pg/coder'
|
76
|
-
require 'pg/binary_decoder'
|
77
|
-
require 'pg/text_encoder'
|
78
|
-
require 'pg/text_decoder'
|
79
|
-
require 'pg/basic_type_registry'
|
80
|
-
require 'pg/basic_type_map_based_on_result'
|
81
|
-
require 'pg/basic_type_map_for_queries'
|
82
|
-
require 'pg/basic_type_map_for_results'
|
83
112
|
require 'pg/type_map_by_column'
|
84
113
|
require 'pg/connection'
|
85
114
|
require 'pg/result'
|
86
115
|
require 'pg/tuple'
|
87
|
-
|
116
|
+
autoload :VERSION, 'pg/version'
|
117
|
+
|
118
|
+
|
119
|
+
# Avoid "uninitialized constant Truffle::WarningOperations" on Truffleruby up to 22.3.1
|
120
|
+
if RUBY_ENGINE=="truffleruby" && !defined?(Truffle::WarningOperations)
|
121
|
+
module TruffleFixWarn
|
122
|
+
def warn(str, category=nil)
|
123
|
+
super(str)
|
124
|
+
end
|
125
|
+
end
|
126
|
+
Warning.extend(TruffleFixWarn)
|
127
|
+
end
|
88
128
|
|
89
129
|
end # module PG
|
data/pg.gemspec
CHANGED
@@ -17,7 +17,7 @@ Gem::Specification.new do |spec|
|
|
17
17
|
|
18
18
|
spec.metadata["homepage_uri"] = spec.homepage
|
19
19
|
spec.metadata["source_code_uri"] = "https://github.com/ged/ruby-pg"
|
20
|
-
spec.metadata["changelog_uri"] = "https://github.com/ged/ruby-pg/blob/master/History.
|
20
|
+
spec.metadata["changelog_uri"] = "https://github.com/ged/ruby-pg/blob/master/History.md"
|
21
21
|
spec.metadata["documentation_uri"] = "http://deveiate.org/code/pg"
|
22
22
|
|
23
23
|
# Specify which files should be added to the gem when it is released.
|
@@ -28,5 +28,7 @@ Gem::Specification.new do |spec|
|
|
28
28
|
spec.extensions = ["ext/extconf.rb"]
|
29
29
|
spec.require_paths = ["lib"]
|
30
30
|
spec.cert_chain = ["certs/ged.pem"]
|
31
|
-
spec.rdoc_options = ["--main", "README.
|
31
|
+
spec.rdoc_options = ["--main", "README.md",
|
32
|
+
"--title", "PG: The Ruby PostgreSQL Driver"]
|
33
|
+
spec.extra_rdoc_files = `git ls-files -z *.rdoc *.md lib/*.rb lib/*/*.rb lib/*/*/*.rb ext/*.c ext/*.h`.split("\x0")
|
32
34
|
end
|
data/rakelib/task_extension.rb
CHANGED
@@ -0,0 +1,7 @@
|
|
1
|
+
po4a version 0.69.
|
2
|
+
Written by Martin Quinson and Denis Barbier.
|
3
|
+
|
4
|
+
Copyright © 2002-2022 Software in the Public Interest, Inc.
|
5
|
+
This is free software; see source code for copying
|
6
|
+
conditions. There is NO warranty; not even for
|
7
|
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|