pg 1.1.4-x64-mingw32 → 1.2.0-x64-mingw32
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +0 -0
- data.tar.gz.sig +0 -0
- data/ChangeLog +0 -6595
- data/History.rdoc +63 -0
- data/Manifest.txt +3 -2
- data/README-Windows.rdoc +4 -4
- data/README.ja.rdoc +1 -2
- data/README.rdoc +43 -8
- data/Rakefile +3 -3
- data/Rakefile.cross +6 -3
- data/ext/errorcodes.def +64 -0
- data/ext/errorcodes.txt +18 -2
- data/ext/extconf.rb +6 -6
- data/ext/pg.c +132 -95
- data/ext/pg.h +20 -18
- data/ext/pg_binary_decoder.c +9 -9
- data/ext/pg_binary_encoder.c +13 -12
- data/ext/pg_coder.c +5 -5
- data/ext/pg_connection.c +388 -298
- data/ext/pg_copy_coder.c +5 -3
- data/ext/pg_record_coder.c +490 -0
- data/ext/pg_result.c +269 -123
- data/ext/pg_text_decoder.c +14 -8
- data/ext/pg_text_encoder.c +180 -48
- data/ext/pg_tuple.c +14 -6
- data/ext/pg_type_map.c +1 -1
- data/ext/pg_type_map_all_strings.c +4 -4
- data/ext/pg_type_map_by_class.c +4 -3
- data/ext/pg_type_map_by_column.c +7 -6
- data/ext/pg_type_map_by_mri_type.c +1 -1
- data/ext/pg_type_map_by_oid.c +3 -2
- data/ext/pg_type_map_in_ruby.c +1 -1
- data/ext/{util.c → pg_util.c} +5 -5
- data/ext/{util.h → pg_util.h} +0 -0
- data/lib/2.2/pg_ext.so +0 -0
- data/lib/2.3/pg_ext.so +0 -0
- data/lib/2.4/pg_ext.so +0 -0
- data/lib/2.5/pg_ext.so +0 -0
- data/lib/2.6/pg_ext.so +0 -0
- data/lib/libpq.dll +0 -0
- data/lib/pg.rb +2 -3
- data/lib/pg/basic_type_mapping.rb +79 -16
- data/lib/pg/binary_decoder.rb +1 -0
- data/lib/pg/coder.rb +22 -1
- data/lib/pg/connection.rb +2 -2
- data/lib/pg/constants.rb +1 -0
- data/lib/pg/exceptions.rb +1 -0
- data/lib/pg/result.rb +13 -1
- data/lib/pg/text_decoder.rb +2 -3
- data/lib/pg/text_encoder.rb +8 -18
- data/lib/pg/type_map_by_column.rb +2 -1
- data/spec/helpers.rb +10 -8
- data/spec/pg/basic_type_mapping_spec.rb +150 -13
- data/spec/pg/connection_spec.rb +89 -50
- data/spec/pg/result_spec.rb +193 -3
- data/spec/pg/tuple_spec.rb +55 -2
- data/spec/pg/type_map_by_column_spec.rb +5 -1
- data/spec/pg/type_spec.rb +180 -6
- metadata +27 -25
- metadata.gz.sig +2 -3
data/ext/pg_type_map.c
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
/*
|
2
2
|
* pg_type_map_all_strings.c - PG::TypeMapAllStrings class extension
|
3
|
-
* $Id
|
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,
|
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,
|
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
|
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
|
data/ext/pg_type_map_by_class.c
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
/*
|
2
2
|
* pg_type_map_by_class.c - PG::TypeMapByClass class extension
|
3
|
-
* $Id
|
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
|
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
|
}
|
data/ext/pg_type_map_by_column.c
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
/*
|
2
2
|
* pg_column_map.c - PG::ColumnMap class extension
|
3
|
-
* $Id
|
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,
|
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,
|
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
|
296
|
-
* that is defined at
|
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::
|
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
|
}
|
data/ext/pg_type_map_by_oid.c
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
/*
|
2
2
|
* pg_type_map_by_oid.c - PG::TypeMapByOid class extension
|
3
|
-
* $Id
|
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,
|
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
|
}
|
data/ext/pg_type_map_in_ruby.c
CHANGED
data/ext/{util.c → pg_util.c}
RENAMED
@@ -1,11 +1,11 @@
|
|
1
1
|
/*
|
2
|
-
*
|
3
|
-
* $Id
|
2
|
+
* pg_util.c - Utils for ruby-pg
|
3
|
+
* $Id$
|
4
4
|
*
|
5
5
|
*/
|
6
6
|
|
7
7
|
#include "pg.h"
|
8
|
-
#include "
|
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 =
|
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 =
|
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];
|
data/ext/{util.h → pg_util.h}
RENAMED
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.
|
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
|
-
|
158
|
-
|
159
|
-
#
|
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
|
-
|
163
|
-
|
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#
|
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
|
-
|
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
|
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
|
-
@
|
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
|
-
|
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
|
-
@
|
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
|
data/lib/pg/binary_decoder.rb
CHANGED
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
|