pg 1.1.4-x64-mingw32 → 1.2.0-x64-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.
Files changed (61) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data.tar.gz.sig +0 -0
  4. data/ChangeLog +0 -6595
  5. data/History.rdoc +63 -0
  6. data/Manifest.txt +3 -2
  7. data/README-Windows.rdoc +4 -4
  8. data/README.ja.rdoc +1 -2
  9. data/README.rdoc +43 -8
  10. data/Rakefile +3 -3
  11. data/Rakefile.cross +6 -3
  12. data/ext/errorcodes.def +64 -0
  13. data/ext/errorcodes.txt +18 -2
  14. data/ext/extconf.rb +6 -6
  15. data/ext/pg.c +132 -95
  16. data/ext/pg.h +20 -18
  17. data/ext/pg_binary_decoder.c +9 -9
  18. data/ext/pg_binary_encoder.c +13 -12
  19. data/ext/pg_coder.c +5 -5
  20. data/ext/pg_connection.c +388 -298
  21. data/ext/pg_copy_coder.c +5 -3
  22. data/ext/pg_record_coder.c +490 -0
  23. data/ext/pg_result.c +269 -123
  24. data/ext/pg_text_decoder.c +14 -8
  25. data/ext/pg_text_encoder.c +180 -48
  26. data/ext/pg_tuple.c +14 -6
  27. data/ext/pg_type_map.c +1 -1
  28. data/ext/pg_type_map_all_strings.c +4 -4
  29. data/ext/pg_type_map_by_class.c +4 -3
  30. data/ext/pg_type_map_by_column.c +7 -6
  31. data/ext/pg_type_map_by_mri_type.c +1 -1
  32. data/ext/pg_type_map_by_oid.c +3 -2
  33. data/ext/pg_type_map_in_ruby.c +1 -1
  34. data/ext/{util.c → pg_util.c} +5 -5
  35. data/ext/{util.h → pg_util.h} +0 -0
  36. data/lib/2.2/pg_ext.so +0 -0
  37. data/lib/2.3/pg_ext.so +0 -0
  38. data/lib/2.4/pg_ext.so +0 -0
  39. data/lib/2.5/pg_ext.so +0 -0
  40. data/lib/2.6/pg_ext.so +0 -0
  41. data/lib/libpq.dll +0 -0
  42. data/lib/pg.rb +2 -3
  43. data/lib/pg/basic_type_mapping.rb +79 -16
  44. data/lib/pg/binary_decoder.rb +1 -0
  45. data/lib/pg/coder.rb +22 -1
  46. data/lib/pg/connection.rb +2 -2
  47. data/lib/pg/constants.rb +1 -0
  48. data/lib/pg/exceptions.rb +1 -0
  49. data/lib/pg/result.rb +13 -1
  50. data/lib/pg/text_decoder.rb +2 -3
  51. data/lib/pg/text_encoder.rb +8 -18
  52. data/lib/pg/type_map_by_column.rb +2 -1
  53. data/spec/helpers.rb +10 -8
  54. data/spec/pg/basic_type_mapping_spec.rb +150 -13
  55. data/spec/pg/connection_spec.rb +89 -50
  56. data/spec/pg/result_spec.rb +193 -3
  57. data/spec/pg/tuple_spec.rb +55 -2
  58. data/spec/pg/type_map_by_column_spec.rb +5 -1
  59. data/spec/pg/type_spec.rb +180 -6
  60. metadata +27 -25
  61. metadata.gz.sig +2 -3
data/ext/pg_type_map.c CHANGED
@@ -1,6 +1,6 @@
1
1
  /*
2
2
  * pg_column_map.c - PG::ColumnMap class extension
3
- * $Id: pg_type_map.c,v 2af122820861 2017/01/14 19:56:36 lars $
3
+ * $Id$
4
4
  *
5
5
  */
6
6
 
@@ -1,6 +1,6 @@
1
1
  /*
2
2
  * pg_type_map_all_strings.c - PG::TypeMapAllStrings class extension
3
- * $Id: pg_type_map_all_strings.c,v c53f993a4254 2014/12/12 21:57:29 lars $
3
+ * $Id$
4
4
  *
5
5
  * This is the default typemap.
6
6
  *
@@ -33,9 +33,9 @@ pg_tmas_result_value( t_typemap *p_typemap, VALUE result, int tuple, int field )
33
33
  len = PQgetlength( p_result->pgresult, tuple, field );
34
34
 
35
35
  if ( 0 == PQfformat(p_result->pgresult, field) ) {
36
- ret = pg_text_dec_string(NULL, val, len, tuple, field, ENCODING_GET(result));
36
+ ret = pg_text_dec_string(NULL, val, len, tuple, field, p_result->enc_idx);
37
37
  } else {
38
- ret = pg_bin_dec_bytea(NULL, val, len, tuple, field, ENCODING_GET(result));
38
+ ret = pg_bin_dec_bytea(NULL, val, len, tuple, field, p_result->enc_idx);
39
39
  }
40
40
 
41
41
  return ret;
@@ -99,7 +99,7 @@ init_pg_type_map_all_strings()
99
99
  * This type map casts all values received from the database server to Strings
100
100
  * and sends all values to the server after conversion to String by +#to_s+ .
101
101
  * That means, it is hard coded to PG::TextEncoder::String for value encoding
102
- * and to PG::TextDecoder::String for text format respectivly PG::BinaryDecoder::Bytea
102
+ * and to PG::TextDecoder::String for text format respectively PG::BinaryDecoder::Bytea
103
103
  * for binary format received from the server.
104
104
  *
105
105
  * It is suitable for type casting query bind parameters, result values and
@@ -1,6 +1,6 @@
1
1
  /*
2
2
  * pg_type_map_by_class.c - PG::TypeMapByClass class extension
3
- * $Id: pg_type_map_by_class.c,v eeb8a82c5328 2014/11/10 19:34:02 lars $
3
+ * $Id$
4
4
  *
5
5
  * This type map can be used to select value encoders based on the class
6
6
  * of the given value to be send.
@@ -28,7 +28,7 @@ typedef struct {
28
28
  * We use 8 Bits of the klass object id as index to a 256 entry cache.
29
29
  * This avoids full lookups in most cases.
30
30
  */
31
- #define CACHE_LOOKUP(this, klass) ( &this->cache_row[(klass >> 8) & 0xff] )
31
+ #define CACHE_LOOKUP(this, klass) ( &this->cache_row[(((unsigned long)klass) >> 8) & 0xff] )
32
32
 
33
33
 
34
34
  static t_pg_coder *
@@ -66,7 +66,7 @@ pg_tmbk_lookup_klass(t_tmbk *this, VALUE klass, VALUE param_value)
66
66
  Data_Get_Struct(obj, t_pg_coder, p_coder);
67
67
  }else{
68
68
  if( RB_TYPE_P(obj, T_SYMBOL) ){
69
- /* A Proc object (or something that responds to #call). */
69
+ /* A Symbol: Call the method with this name. */
70
70
  obj = rb_funcall(this->self, SYM2ID(obj), 1, param_value);
71
71
  }else{
72
72
  /* A Proc object (or something that responds to #call). */
@@ -235,5 +235,6 @@ init_pg_type_map_by_class()
235
235
  rb_define_method( rb_cTypeMapByClass, "[]=", pg_tmbk_aset, 2 );
236
236
  rb_define_method( rb_cTypeMapByClass, "[]", pg_tmbk_aref, 1 );
237
237
  rb_define_method( rb_cTypeMapByClass, "coders", pg_tmbk_coders, 0 );
238
+ /* rb_mDefaultTypeMappable = rb_define_module_under( rb_cTypeMap, "DefaultTypeMappable"); */
238
239
  rb_include_module( rb_cTypeMapByClass, rb_mDefaultTypeMappable );
239
240
  }
@@ -1,6 +1,6 @@
1
1
  /*
2
2
  * pg_column_map.c - PG::ColumnMap class extension
3
- * $Id: pg_type_map_by_column.c,v fcf731d3dff7 2015/09/08 12:25:06 jfali $
3
+ * $Id$
4
4
  *
5
5
  */
6
6
 
@@ -99,11 +99,11 @@ pg_tmbc_result_value( t_typemap *p_typemap, VALUE result, int tuple, int field )
99
99
  int len = PQgetlength( p_result->pgresult, tuple, field );
100
100
 
101
101
  if( p_coder->dec_func ){
102
- return p_coder->dec_func(p_coder, val, len, tuple, field, ENCODING_GET(result));
102
+ return p_coder->dec_func(p_coder, val, len, tuple, field, p_result->enc_idx);
103
103
  } else {
104
104
  t_pg_coder_dec_func dec_func;
105
105
  dec_func = pg_coder_dec_func( p_coder, PQfformat(p_result->pgresult, field) );
106
- return dec_func(p_coder, val, len, tuple, field, ENCODING_GET(result));
106
+ return dec_func(p_coder, val, len, tuple, field, p_result->enc_idx);
107
107
  }
108
108
  }
109
109
 
@@ -292,13 +292,13 @@ init_pg_type_map_by_column()
292
292
  *
293
293
  * This type map casts values by a coder assigned per field/column.
294
294
  *
295
- * Each PG:TypeMapByColumn has a fixed list of either encoders or decoders,
296
- * that is defined at #new . A type map with encoders is usable for type casting
295
+ * Each PG::TypeMapByColumn has a fixed list of either encoders or decoders,
296
+ * that is defined at TypeMapByColumn.new . A type map with encoders is usable for type casting
297
297
  * query bind parameters and COPY data for PG::Connection#put_copy_data .
298
298
  * A type map with decoders is usable for type casting of result values and
299
299
  * COPY data from PG::Connection#get_copy_data .
300
300
  *
301
- * PG::TypeMapByColumns are in particular useful in conjunction with prepared statements,
301
+ * PG::TypeMapByColumn objects are in particular useful in conjunction with prepared statements,
302
302
  * since they can be cached alongside with the statement handle.
303
303
  *
304
304
  * This type map strategy is also used internally by PG::TypeMapByOid, when the
@@ -308,5 +308,6 @@ init_pg_type_map_by_column()
308
308
  rb_define_alloc_func( rb_cTypeMapByColumn, pg_tmbc_s_allocate );
309
309
  rb_define_method( rb_cTypeMapByColumn, "initialize", pg_tmbc_init, 1 );
310
310
  rb_define_method( rb_cTypeMapByColumn, "coders", pg_tmbc_coders, 0 );
311
+ /* rb_mDefaultTypeMappable = rb_define_module_under( rb_cTypeMap, "DefaultTypeMappable"); */
311
312
  rb_include_module( rb_cTypeMapByColumn, rb_mDefaultTypeMappable );
312
313
  }
@@ -1,6 +1,6 @@
1
1
  /*
2
2
  * pg_type_map_by_mri_type.c - PG::TypeMapByMriType class extension
3
- * $Id: pg_type_map_by_mri_type.c,v 1269b8ad77b8 2015/02/06 16:38:23 lars $
3
+ * $Id$
4
4
  *
5
5
  * This type map can be used to select value encoders based on the MRI-internal
6
6
  * value type code.
@@ -1,6 +1,6 @@
1
1
  /*
2
2
  * pg_type_map_by_oid.c - PG::TypeMapByOid class extension
3
- * $Id: pg_type_map_by_oid.c,v c99d26015e3c 2014/12/12 20:58:25 lars $
3
+ * $Id$
4
4
  *
5
5
  */
6
6
 
@@ -110,7 +110,7 @@ pg_tmbo_result_value(t_typemap *p_typemap, VALUE result, int tuple, int field)
110
110
  char * val = PQgetvalue( p_result->pgresult, tuple, field );
111
111
  int len = PQgetlength( p_result->pgresult, tuple, field );
112
112
  t_pg_coder_dec_func dec_func = pg_coder_dec_func( p_coder, format );
113
- return dec_func( p_coder, val, len, tuple, field, ENCODING_GET(result) );
113
+ return dec_func( p_coder, val, len, tuple, field, p_result->enc_idx );
114
114
  }
115
115
 
116
116
  default_tm = DATA_PTR( this->typemap.default_typemap );
@@ -351,5 +351,6 @@ init_pg_type_map_by_oid()
351
351
  rb_define_method( rb_cTypeMapByOid, "max_rows_for_online_lookup=", pg_tmbo_max_rows_for_online_lookup_set, 1 );
352
352
  rb_define_method( rb_cTypeMapByOid, "max_rows_for_online_lookup", pg_tmbo_max_rows_for_online_lookup_get, 0 );
353
353
  rb_define_method( rb_cTypeMapByOid, "build_column_map", pg_tmbo_build_column_map, 1 );
354
+ /* rb_mDefaultTypeMappable = rb_define_module_under( rb_cTypeMap, "DefaultTypeMappable"); */
354
355
  rb_include_module( rb_cTypeMapByOid, rb_mDefaultTypeMappable );
355
356
  }
@@ -1,6 +1,6 @@
1
1
  /*
2
2
  * pg_type_map_in_ruby.c - PG::TypeMapInRuby class extension
3
- * $Id: pg_type_map_in_ruby.c,v 3d89d3aae4fd 2015/01/05 16:19:41 kanis $
3
+ * $Id$
4
4
  *
5
5
  */
6
6
 
@@ -1,11 +1,11 @@
1
1
  /*
2
- * util.c - Utils for ruby-pg
3
- * $Id: util.c,v fc1c4deb1398 2018/06/25 12:02:09 kanis $
2
+ * pg_util.c - Utils for ruby-pg
3
+ * $Id$
4
4
  *
5
5
  */
6
6
 
7
7
  #include "pg.h"
8
- #include "util.h"
8
+ #include "pg_util.h"
9
9
 
10
10
  static const char base64_encode_table[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
11
11
 
@@ -22,12 +22,12 @@ base64_encode( char *out, const char *in, int len)
22
22
  int part_len = len % 3;
23
23
 
24
24
  if( part_len > 0 ){
25
- long byte2 = part_len > 2 ? *--in_ptr : 0;
25
+ long byte2 = 0;
26
26
  long byte1 = part_len > 1 ? *--in_ptr : 0;
27
27
  long byte0 = *--in_ptr;
28
28
  long triple = (byte0 << 16) + (byte1 << 8) + byte2;
29
29
 
30
- *--out_ptr = part_len > 2 ? base64_encode_table[(triple >> 0 * 6) & 0x3F] : '=';
30
+ *--out_ptr = '=';
31
31
  *--out_ptr = part_len > 1 ? base64_encode_table[(triple >> 1 * 6) & 0x3F] : '=';
32
32
  *--out_ptr = base64_encode_table[(triple >> 2 * 6) & 0x3F];
33
33
  *--out_ptr = base64_encode_table[(triple >> 3 * 6) & 0x3F];
File without changes
data/lib/2.2/pg_ext.so CHANGED
Binary file
data/lib/2.3/pg_ext.so CHANGED
Binary file
data/lib/2.4/pg_ext.so CHANGED
Binary file
data/lib/2.5/pg_ext.so CHANGED
Binary file
data/lib/2.6/pg_ext.so CHANGED
Binary file
data/lib/libpq.dll CHANGED
Binary file
data/lib/pg.rb CHANGED
@@ -1,4 +1,5 @@
1
1
  # -*- ruby -*-
2
+ # frozen_string_literal: true
2
3
 
3
4
  begin
4
5
  require 'pg_ext'
@@ -35,7 +36,7 @@ end
35
36
  module PG
36
37
 
37
38
  # Library version
38
- VERSION = '1.1.4'
39
+ VERSION = '1.2.0'
39
40
 
40
41
  # VCS revision
41
42
  REVISION = %q$Revision: 6f611e78845a $
@@ -70,5 +71,3 @@ module PG
70
71
  require 'pg/tuple'
71
72
 
72
73
  end # module PG
73
-
74
-
@@ -1,4 +1,5 @@
1
1
  # -*- ruby -*-
2
+ # frozen_string_literal: true
2
3
 
3
4
  require 'pg' unless defined?( PG )
4
5
 
@@ -154,14 +155,26 @@ module PG::BasicTypeRegistry
154
155
  # objects as values.
155
156
  CODERS_BY_NAME = []
156
157
 
157
- # Register an OID type named +name+ with a typecasting encoder and decoder object in
158
- # +type+. +name+ should correspond to the `typname` column in
159
- # the `pg_type` table.
158
+ public
159
+
160
+ # Register an encoder or decoder instance for casting a PostgreSQL type.
161
+ #
162
+ # Coder#name must correspond to the +typname+ column in the +pg_type+ table.
163
+ # Coder#format can be 0 for text format and 1 for binary.
164
+ def self.register_coder(coder)
165
+ h = CODERS_BY_NAME[coder.format] ||= { encoder: {}, decoder: {} }
166
+ name = coder.name || raise(ArgumentError, "name of #{coder.inspect} must be defined")
167
+ h[:encoder][name] = coder if coder.respond_to?(:encode)
168
+ h[:decoder][name] = coder if coder.respond_to?(:decode)
169
+ end
170
+
171
+ # Register the given +encoder_class+ and/or +decoder_class+ for casting a PostgreSQL type.
172
+ #
173
+ # +name+ must correspond to the +typname+ column in the +pg_type+ table.
160
174
  # +format+ can be 0 for text format and 1 for binary.
161
175
  def self.register_type(format, name, encoder_class, decoder_class)
162
- CODERS_BY_NAME[format] ||= { encoder: {}, decoder: {} }
163
- CODERS_BY_NAME[format][:encoder][name] = encoder_class.new(name: name, format: format) if encoder_class
164
- CODERS_BY_NAME[format][:decoder][name] = decoder_class.new(name: name, format: format) if decoder_class
176
+ register_coder(encoder_class.new(name: name, format: format)) if encoder_class
177
+ register_coder(decoder_class.new(name: name, format: format)) if decoder_class
165
178
  end
166
179
 
167
180
  # Alias the +old+ type to the +new+ type.
@@ -247,7 +260,7 @@ end
247
260
  # Simple set of rules for type casting common PostgreSQL types to Ruby.
248
261
  #
249
262
  # OIDs of supported type casts are not hard-coded in the sources, but are retrieved from the
250
- # PostgreSQL's pg_type table in PG::BasicTypeMapForResults.new .
263
+ # PostgreSQL's +pg_type+ table in PG::BasicTypeMapForResults.new .
251
264
  #
252
265
  # Result values are type casted based on the type OID of the given result column.
253
266
  #
@@ -264,7 +277,7 @@ end
264
277
  # # is done by PG::TextDecoder::Integer internally for all value retrieval methods.
265
278
  # res.values # => [[5]]
266
279
  #
267
- # PG::TypeMapByOid#fit_to_result(result, false) can be used to generate
280
+ # PG::TypeMapByOid#build_column_map(result) can be used to generate
268
281
  # a result independent PG::TypeMapByColumn type map, which can subsequently be used
269
282
  # to cast #get_copy_data fields:
270
283
  #
@@ -301,7 +314,7 @@ class PG::BasicTypeMapForResults < PG::TypeMapByOid
301
314
  format = result.fformat(field)
302
315
  oid = result.ftype(field)
303
316
  unless @already_warned[format][oid]
304
- STDERR.puts "Warning: no type cast defined for type #{@typenames_by_oid[format][oid].inspect} with oid #{oid}. Please cast this type explicitly to TEXT to be safe for future changes."
317
+ $stderr.puts "Warning: no type cast defined for type #{@typenames_by_oid[format][oid].inspect} with oid #{oid}. Please cast this type explicitly to TEXT to be safe for future changes."
305
318
  @already_warned[format][oid] = true
306
319
  end
307
320
  super
@@ -325,7 +338,7 @@ end
325
338
  # to PostgreSQL.
326
339
  #
327
340
  # OIDs of supported type casts are not hard-coded in the sources, but are retrieved from the
328
- # PostgreSQL's pg_type table in PG::BasicTypeMapBasedOnResult.new .
341
+ # PostgreSQL's +pg_type+ table in PG::BasicTypeMapBasedOnResult.new .
329
342
  #
330
343
  # This class works equal to PG::BasicTypeMapForResults, but does not define decoders for
331
344
  # the given result OIDs, but encoders. So it can be used to type cast field values based on
@@ -380,21 +393,54 @@ end
380
393
  # # Assign a default ruleset for type casts of input and output values.
381
394
  # conn.type_map_for_queries = PG::BasicTypeMapForQueries.new(conn)
382
395
  # # Execute a query. The Integer param value is typecasted internally by PG::BinaryEncoder::Int8.
383
- # # The format of the parameter is set to 1 (binary) and the OID of this parameter is set to 20 (int8).
396
+ # # The format of the parameter is set to 0 (text) and the OID of this parameter is set to 20 (int8).
384
397
  # res = conn.exec_params( "SELECT $1", [5] )
385
398
  class PG::BasicTypeMapForQueries < PG::TypeMapByClass
386
399
  include PG::BasicTypeRegistry
387
400
 
388
401
  def initialize(connection)
389
402
  @coder_maps = build_coder_maps(connection)
390
-
391
- populate_encoder_list
392
403
  @array_encoders_by_klass = array_encoders_by_klass
393
- @anyarray_encoder = coder_by_name(0, :encoder, '_any')
404
+ @encode_array_as = :array
405
+ init_encoders
406
+ end
407
+
408
+ # Change the mechanism that is used to encode ruby array values
409
+ #
410
+ # Possible values:
411
+ # * +:array+ : Encode the ruby array as a PostgreSQL array.
412
+ # The array element type is inferred from the class of the first array element. This is the default.
413
+ # * +:json+ : Encode the ruby array as a JSON document.
414
+ # * +:record+ : Encode the ruby array as a composite type row.
415
+ # * <code>"_type"</code> : Encode the ruby array as a particular PostgreSQL type.
416
+ # All PostgreSQL array types are supported.
417
+ # If there's an encoder registered for the elements +type+, it will be used.
418
+ # Otherwise a string conversion (by +value.to_s+) is done.
419
+ def encode_array_as=(pg_type)
420
+ case pg_type
421
+ when :array
422
+ when :json
423
+ when :record
424
+ when /\A_/
425
+ else
426
+ raise ArgumentError, "invalid pg_type #{pg_type.inspect}"
427
+ end
428
+
429
+ @encode_array_as = pg_type
430
+
431
+ init_encoders
394
432
  end
395
433
 
434
+ attr_reader :encode_array_as
435
+
396
436
  private
397
437
 
438
+ def init_encoders
439
+ coders.each { |kl, c| self[kl] = nil } # Clear type map
440
+ populate_encoder_list
441
+ @textarray_encoder = coder_by_name(0, :encoder, '_text')
442
+ end
443
+
398
444
  def coder_by_name(format, direction, name)
399
445
  check_format_and_direction(format, direction)
400
446
  @coder_maps[format][direction].coder_by_name(name)
@@ -412,7 +458,19 @@ class PG::BasicTypeMapForQueries < PG::TypeMapByClass
412
458
  end
413
459
  self[klass] = coder
414
460
  else
415
- self[klass] = selector
461
+
462
+ case @encode_array_as
463
+ when :array
464
+ self[klass] = selector
465
+ when :json
466
+ self[klass] = PG::TextEncoder::JSON.new
467
+ when :record
468
+ self[klass] = PG::TextEncoder::Record.new type_map: self
469
+ when /\A_/
470
+ self[klass] = coder_by_name(0, :encoder, @encode_array_as) || raise(ArgumentError, "unknown array type #{@encode_array_as.inspect}")
471
+ else
472
+ raise ArgumentError, "invalid pg_type #{@encode_array_as.inspect}"
473
+ end
416
474
  end
417
475
  end
418
476
  end
@@ -431,7 +489,7 @@ class PG::BasicTypeMapForQueries < PG::TypeMapByClass
431
489
  end
432
490
  @array_encoders_by_klass[elem.class] ||
433
491
  elem.class.ancestors.lazy.map{|ancestor| @array_encoders_by_klass[ancestor] }.find{|a| a } ||
434
- @anyarray_encoder
492
+ @textarray_encoder
435
493
  end
436
494
 
437
495
  DEFAULT_TYPE_MAP = {
@@ -442,9 +500,11 @@ class PG::BasicTypeMapForQueries < PG::TypeMapByClass
442
500
  Integer => [0, 'int8'],
443
501
  Float => [0, 'float8'],
444
502
  BigDecimal => [0, 'numeric'],
503
+ Time => [0, 'timestamptz'],
445
504
  # We use text format and no type OID for IPAddr, because setting the OID can lead
446
505
  # to unnecessary inet/cidr conversions on the server side.
447
506
  IPAddr => [0, 'inet'],
507
+ Hash => [0, 'json'],
448
508
  Array => :get_array_type,
449
509
  }
450
510
 
@@ -454,6 +514,9 @@ class PG::BasicTypeMapForQueries < PG::TypeMapByClass
454
514
  Integer => [0, '_int8'],
455
515
  String => [0, '_text'],
456
516
  Float => [0, '_float8'],
517
+ BigDecimal => [0, '_numeric'],
518
+ Time => [0, '_timestamptz'],
519
+ IPAddr => [0, '_inet'],
457
520
  }
458
521
 
459
522
  end
@@ -1,4 +1,5 @@
1
1
  # -*- ruby -*-
2
+ # frozen_string_literal: true
2
3
 
3
4
  module PG
4
5
  module BinaryDecoder
data/lib/pg/coder.rb CHANGED
@@ -1,4 +1,5 @@
1
1
  # -*- ruby -*-
2
+ # frozen_string_literal: true
2
3
 
3
4
  module PG
4
5
 
@@ -28,6 +29,7 @@ module PG
28
29
  {
29
30
  oid: oid,
30
31
  format: format,
32
+ flags: flags,
31
33
  name: name,
32
34
  }
33
35
  end
@@ -52,6 +54,18 @@ module PG
52
54
  str[-1,0] = "#{name_str} #{oid_str}#{format_str}"
53
55
  str
54
56
  end
57
+
58
+ def inspect_short
59
+ str = case format
60
+ when 0 then "T"
61
+ when 1 then "B"
62
+ else format.to_s
63
+ end
64
+ str += "E" if respond_to?(:encode)
65
+ str += "D" if respond_to?(:decode)
66
+
67
+ "#{name || self.class.name}:#{str}"
68
+ end
55
69
  end
56
70
 
57
71
  class CompositeCoder < Coder
@@ -79,5 +93,12 @@ module PG
79
93
  })
80
94
  end
81
95
  end
82
- end # module PG
83
96
 
97
+ class RecordCoder < Coder
98
+ def to_h
99
+ super.merge!({
100
+ type_map: type_map,
101
+ })
102
+ end
103
+ end
104
+ end # module PG