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.
Files changed (68) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data/.appveyor.yml +15 -9
  4. data/.github/workflows/binary-gems.yml +41 -10
  5. data/.github/workflows/source-gem.yml +18 -12
  6. data/.gitignore +11 -2
  7. data/.travis.yml +2 -2
  8. data/{History.rdoc → History.md} +240 -153
  9. data/README.ja.md +276 -0
  10. data/README.md +286 -0
  11. data/Rakefile +12 -3
  12. data/Rakefile.cross +7 -11
  13. data/certs/larskanis-2023.pem +24 -0
  14. data/ext/pg.c +10 -28
  15. data/ext/pg.h +10 -5
  16. data/ext/pg_binary_decoder.c +79 -0
  17. data/ext/pg_binary_encoder.c +224 -0
  18. data/ext/pg_coder.c +16 -7
  19. data/ext/pg_connection.c +156 -60
  20. data/ext/pg_copy_coder.c +306 -17
  21. data/ext/pg_record_coder.c +5 -4
  22. data/ext/pg_result.c +91 -17
  23. data/ext/pg_text_decoder.c +28 -10
  24. data/ext/pg_text_encoder.c +22 -9
  25. data/ext/pg_tuple.c +34 -31
  26. data/ext/pg_type_map.c +3 -2
  27. data/ext/pg_type_map_all_strings.c +2 -2
  28. data/ext/pg_type_map_by_class.c +5 -3
  29. data/ext/pg_type_map_by_column.c +7 -3
  30. data/ext/pg_type_map_by_oid.c +7 -4
  31. data/ext/pg_type_map_in_ruby.c +5 -2
  32. data/lib/pg/basic_type_map_based_on_result.rb +21 -1
  33. data/lib/pg/basic_type_map_for_queries.rb +13 -8
  34. data/lib/pg/basic_type_map_for_results.rb +26 -3
  35. data/lib/pg/basic_type_registry.rb +30 -32
  36. data/lib/pg/binary_decoder/date.rb +9 -0
  37. data/lib/pg/binary_decoder/timestamp.rb +26 -0
  38. data/lib/pg/binary_encoder/timestamp.rb +20 -0
  39. data/lib/pg/coder.rb +15 -13
  40. data/lib/pg/connection.rb +103 -30
  41. data/lib/pg/exceptions.rb +7 -0
  42. data/lib/pg/text_decoder/date.rb +18 -0
  43. data/lib/pg/text_decoder/inet.rb +9 -0
  44. data/lib/pg/text_decoder/json.rb +14 -0
  45. data/lib/pg/text_decoder/numeric.rb +9 -0
  46. data/lib/pg/text_decoder/timestamp.rb +30 -0
  47. data/lib/pg/text_encoder/date.rb +12 -0
  48. data/lib/pg/text_encoder/inet.rb +28 -0
  49. data/lib/pg/text_encoder/json.rb +14 -0
  50. data/lib/pg/text_encoder/numeric.rb +9 -0
  51. data/lib/pg/text_encoder/timestamp.rb +24 -0
  52. data/lib/pg/version.rb +1 -1
  53. data/lib/pg.rb +55 -15
  54. data/pg.gemspec +4 -2
  55. data/rakelib/task_extension.rb +1 -1
  56. data/translation/.po4a-version +7 -0
  57. data/translation/po/all.pot +910 -0
  58. data/translation/po/ja.po +1047 -0
  59. data/translation/po4a.cfg +12 -0
  60. data.tar.gz.sig +0 -0
  61. metadata +109 -34
  62. metadata.gz.sig +0 -0
  63. data/README.ja.rdoc +0 -13
  64. data/README.rdoc +0 -233
  65. data/lib/pg/binary_decoder.rb +0 -23
  66. data/lib/pg/constants.rb +0 -12
  67. data/lib/pg/text_decoder.rb +0 -46
  68. 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 'uri'
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 URI, /=/, /:\/\//
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] = $0.sub( /^(.{30}).{4,}(.{30})$/ ){ $1+"..."+$2 }
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
- put_copy_end( errmsg )
200
- get_result
201
- raise
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
- put_copy_end
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 => err
262
+ rescue Exception
217
263
  cancel
218
- begin
219
- while get_copy_data
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 || res.result_status != PGRES_COMMAND_OK
230
- while get_copy_data
231
- end
232
- while get_result
233
- end
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
- # Check server status.
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
@@ -14,5 +14,12 @@ module PG
14
14
  end
15
15
  end
16
16
 
17
+ class NotAllCopyDataRetrieved < PG::Error
18
+ end
19
+ class LostCopyState < PG::Error
20
+ end
21
+ class NotInBlockingMode < PG::Error
22
+ end
23
+
17
24
  end # module PG
18
25
 
@@ -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,9 @@
1
+ # -*- ruby -*-
2
+ # frozen_string_literal: true
3
+
4
+ module PG
5
+ module TextDecoder
6
+ # Init C part of the decoder
7
+ init_inet
8
+ end
9
+ 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,9 @@
1
+ # -*- ruby -*-
2
+ # frozen_string_literal: true
3
+
4
+ module PG
5
+ module TextDecoder
6
+ # Init C part of the decoder
7
+ init_numeric
8
+ end
9
+ 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,12 @@
1
+ # -*- ruby -*-
2
+ # frozen_string_literal: true
3
+
4
+ module PG
5
+ module TextEncoder
6
+ class Date < SimpleEncoder
7
+ def encode(value)
8
+ value.respond_to?(:strftime) ? value.strftime("%Y-%m-%d") : value
9
+ end
10
+ end
11
+ end
12
+ 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,14 @@
1
+ # -*- ruby -*-
2
+ # frozen_string_literal: true
3
+
4
+ require 'json'
5
+
6
+ module PG
7
+ module TextEncoder
8
+ class JSON < SimpleEncoder
9
+ def encode(value)
10
+ ::JSON.generate(value, quirks_mode: true)
11
+ end
12
+ end
13
+ end
14
+ end # module PG
@@ -0,0 +1,9 @@
1
+ # -*- ruby -*-
2
+ # frozen_string_literal: true
3
+
4
+ module PG
5
+ module TextEncoder
6
+ # Init C part of the decoder
7
+ init_numeric
8
+ end
9
+ 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
@@ -1,4 +1,4 @@
1
1
  module PG
2
2
  # Library version
3
- VERSION = '1.4.5'
3
+ VERSION = '1.5.3'
4
4
  end
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
- require 'pg/version'
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.rdoc"
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.rdoc"]
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
@@ -9,7 +9,7 @@ module TaskExtension
9
9
  def file(name, *args, &block)
10
10
  task_once(name, block) do
11
11
  super(name, *args) do |ta|
12
- block.call(ta).tap do
12
+ block&.call(ta).tap do
13
13
  raise "file #{ta.name} is missing after task executed" unless File.exist?(ta.name)
14
14
  end
15
15
  end
@@ -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.