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.
- 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
|