pg 1.1.3 → 1.2.0
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 +70 -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 +4 -4
- data/Rakefile.cross +7 -4
- data/ext/errorcodes.def +68 -0
- data/ext/errorcodes.txt +19 -2
- data/ext/extconf.rb +6 -6
- data/ext/pg.c +132 -95
- data/ext/pg.h +24 -17
- data/ext/pg_binary_decoder.c +20 -16
- data/ext/pg_binary_encoder.c +13 -12
- data/ext/pg_coder.c +5 -5
- data/ext/pg_connection.c +395 -301
- data/ext/pg_copy_coder.c +5 -3
- data/ext/pg_record_coder.c +490 -0
- data/ext/pg_result.c +272 -124
- 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/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 +17 -16
- data/spec/pg/basic_type_mapping_spec.rb +151 -14
- data/spec/pg/connection_spec.rb +117 -55
- 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 +40 -45
- metadata.gz.sig +0 -0
data/spec/pg/tuple_spec.rb
CHANGED
@@ -8,10 +8,22 @@ require 'objspace'
|
|
8
8
|
describe PG::Tuple do
|
9
9
|
let!(:typemap) { PG::BasicTypeMapForResults.new(@conn) }
|
10
10
|
let!(:result2x2) { @conn.exec( "VALUES(1, 'a'), (2, 'b')" ) }
|
11
|
-
let!(:
|
11
|
+
let!(:result2x2sym) { @conn.exec( "VALUES(1, 'a'), (2, 'b')" ).field_names_as(:symbol) }
|
12
|
+
let!(:result2x3cast) do
|
13
|
+
@conn.exec( "SELECT * FROM (VALUES(1, TRUE, '3'), (2, FALSE, '4')) AS m (a, b, b)" )
|
14
|
+
.map_types!(typemap)
|
15
|
+
end
|
16
|
+
let!(:result2x3symcast) do
|
17
|
+
@conn.exec( "SELECT * FROM (VALUES(1, TRUE, '3'), (2, FALSE, '4')) AS m (a, b, b)" )
|
18
|
+
.map_types!(typemap)
|
19
|
+
.field_names_as(:symbol)
|
20
|
+
end
|
12
21
|
let!(:tuple0) { result2x2.tuple(0) }
|
22
|
+
let!(:tuple0sym) { result2x2sym.tuple(0) }
|
13
23
|
let!(:tuple1) { result2x2.tuple(1) }
|
24
|
+
let!(:tuple1sym) { result2x2sym.tuple(1) }
|
14
25
|
let!(:tuple2) { result2x3cast.tuple(0) }
|
26
|
+
let!(:tuple2sym) { result2x3symcast.tuple(0) }
|
15
27
|
let!(:tuple3) { str = Marshal.dump(result2x3cast.tuple(1)); Marshal.load(str) }
|
16
28
|
let!(:tuple_empty) { PG::Tuple.new }
|
17
29
|
|
@@ -51,9 +63,19 @@ describe PG::Tuple do
|
|
51
63
|
expect( tuple0["column2"] ).to eq( "a" )
|
52
64
|
expect( tuple2["a"] ).to eq( 1 )
|
53
65
|
expect( tuple2["b"] ).to eq( "3" )
|
66
|
+
expect( tuple0[:b] ).to be_nil
|
54
67
|
expect( tuple0["x"] ).to be_nil
|
55
68
|
end
|
56
69
|
|
70
|
+
it "supports hash like access with symbols" do
|
71
|
+
expect( tuple0sym[:column1] ).to eq( "1" )
|
72
|
+
expect( tuple0sym[:column2] ).to eq( "a" )
|
73
|
+
expect( tuple2sym[:a] ).to eq( 1 )
|
74
|
+
expect( tuple2sym[:b] ).to eq( "3" )
|
75
|
+
expect( tuple2sym["b"] ).to be_nil
|
76
|
+
expect( tuple0sym[:x] ).to be_nil
|
77
|
+
end
|
78
|
+
|
57
79
|
it "casts lazy and caches result" do
|
58
80
|
a = []
|
59
81
|
deco = Class.new(PG::SimpleDecoder) do
|
@@ -138,6 +160,12 @@ describe PG::Tuple do
|
|
138
160
|
expect{ tuple_empty.each }.to raise_error(TypeError)
|
139
161
|
end
|
140
162
|
|
163
|
+
it "can be used as an enumerator with symbols" do
|
164
|
+
expect( tuple0sym.each ).to be_kind_of(Enumerator)
|
165
|
+
expect( tuple0sym.each.to_a ).to eq( [[:column1, "1"], [:column2, "a"]] )
|
166
|
+
expect( tuple2sym.each.to_a ).to eq( [[:a, 1], [:b, true], [:b, "3"]] )
|
167
|
+
end
|
168
|
+
|
141
169
|
it "can be used with block" do
|
142
170
|
a = []
|
143
171
|
tuple0.each do |*v|
|
@@ -174,16 +202,30 @@ describe PG::Tuple do
|
|
174
202
|
|
175
203
|
it "responds to key?" do
|
176
204
|
expect( tuple1.key?("column1") ).to eq( true )
|
205
|
+
expect( tuple1.key?(:column1) ).to eq( false )
|
177
206
|
expect( tuple1.key?("other") ).to eq( false )
|
178
207
|
expect( tuple1.has_key?("column1") ).to eq( true )
|
179
208
|
expect( tuple1.has_key?("other") ).to eq( false )
|
180
209
|
end
|
181
210
|
|
211
|
+
it "responds to key? as symbol" do
|
212
|
+
expect( tuple1sym.key?(:column1) ).to eq( true )
|
213
|
+
expect( tuple1sym.key?("column1") ).to eq( false )
|
214
|
+
expect( tuple1sym.key?(:other) ).to eq( false )
|
215
|
+
expect( tuple1sym.has_key?(:column1) ).to eq( true )
|
216
|
+
expect( tuple1sym.has_key?(:other) ).to eq( false )
|
217
|
+
end
|
218
|
+
|
182
219
|
it "responds to keys" do
|
183
220
|
expect( tuple0.keys ).to eq( ["column1", "column2"] )
|
184
221
|
expect( tuple2.keys ).to eq( ["a", "b", "b"] )
|
185
222
|
end
|
186
223
|
|
224
|
+
it "responds to keys as symbol" do
|
225
|
+
expect( tuple0sym.keys ).to eq( [:column1, :column2] )
|
226
|
+
expect( tuple2sym.keys ).to eq( [:a, :b, :b] )
|
227
|
+
end
|
228
|
+
|
187
229
|
describe "each_key" do
|
188
230
|
it "can be used as an enumerator" do
|
189
231
|
expect( tuple0.each_key ).to be_kind_of(Enumerator)
|
@@ -208,12 +250,22 @@ describe PG::Tuple do
|
|
208
250
|
|
209
251
|
it "responds to index" do
|
210
252
|
expect( tuple0.index("column1") ).to eq( 0 )
|
253
|
+
expect( tuple0.index(:column1) ).to eq( nil )
|
211
254
|
expect( tuple0.index("column2") ).to eq( 1 )
|
212
255
|
expect( tuple0.index("x") ).to eq( nil )
|
213
256
|
expect( tuple2.index("a") ).to eq( 0 )
|
214
257
|
expect( tuple2.index("b") ).to eq( 2 )
|
215
258
|
end
|
216
259
|
|
260
|
+
it "responds to index with symbol" do
|
261
|
+
expect( tuple0sym.index(:column1) ).to eq( 0 )
|
262
|
+
expect( tuple0sym.index("column1") ).to eq( nil )
|
263
|
+
expect( tuple0sym.index(:column2) ).to eq( 1 )
|
264
|
+
expect( tuple0sym.index(:x) ).to eq( nil )
|
265
|
+
expect( tuple2sym.index(:a) ).to eq( 0 )
|
266
|
+
expect( tuple2sym.index(:b) ).to eq( 2 )
|
267
|
+
end
|
268
|
+
|
217
269
|
it "can be used as Enumerable" do
|
218
270
|
expect( tuple0.to_a ).to eq( [["column1", "1"], ["column2", "a"]] )
|
219
271
|
expect( tuple1.to_a ).to eq( [["column1", "2"], ["column2", "b"]] )
|
@@ -222,7 +274,7 @@ describe PG::Tuple do
|
|
222
274
|
end
|
223
275
|
|
224
276
|
it "can be marshaled" do
|
225
|
-
[tuple0, tuple1, tuple2, tuple3].each do |t1|
|
277
|
+
[tuple0, tuple1, tuple2, tuple3, tuple0sym, tuple2sym].each do |t1|
|
226
278
|
str = Marshal.dump(t1)
|
227
279
|
t2 = Marshal.load(str)
|
228
280
|
|
@@ -253,6 +305,7 @@ describe PG::Tuple do
|
|
253
305
|
it "should override #inspect" do
|
254
306
|
expect( tuple1.inspect ).to eq('#<PG::Tuple column1: "2", column2: "b">')
|
255
307
|
expect( tuple2.inspect ).to eq('#<PG::Tuple a: 1, b: true, b: "3">')
|
308
|
+
expect( tuple2sym.inspect ).to eq('#<PG::Tuple a: 1, b: true, b: "3">')
|
256
309
|
expect{ tuple_empty.inspect }.to raise_error(TypeError)
|
257
310
|
end
|
258
311
|
|
@@ -38,7 +38,11 @@ describe PG::TypeMapByColumn do
|
|
38
38
|
pass_through_type,
|
39
39
|
nil
|
40
40
|
] )
|
41
|
-
|
41
|
+
end
|
42
|
+
|
43
|
+
it "should respond to inspect" do
|
44
|
+
cm = PG::TypeMapByColumn.new( [textdec_int, textenc_string, textdec_float, pass_through_type, PG::TextEncoder::Float.new, nil] )
|
45
|
+
expect( cm.inspect ).to eq( "#<PG::TypeMapByColumn INT4:TD TEXT:TE FLOAT4:TD pass_through:BD PG::TextEncoder::Float:TE nil>" )
|
42
46
|
end
|
43
47
|
|
44
48
|
it "should retrieve it's oids" do
|
data/spec/pg/type_spec.rb
CHANGED
@@ -12,6 +12,7 @@ describe "PG::Type derivations" do
|
|
12
12
|
let!(:textdec_boolean) { PG::TextDecoder::Boolean.new }
|
13
13
|
let!(:textenc_float) { PG::TextEncoder::Float.new }
|
14
14
|
let!(:textdec_float) { PG::TextDecoder::Float.new }
|
15
|
+
let!(:textenc_numeric) { PG::TextEncoder::Numeric.new }
|
15
16
|
let!(:textenc_string) { PG::TextEncoder::String.new }
|
16
17
|
let!(:textdec_string) { PG::TextDecoder::String.new }
|
17
18
|
let!(:textenc_timestamp) { PG::TextEncoder::TimestampWithoutTimeZone.new }
|
@@ -254,6 +255,11 @@ describe "PG::Type derivations" do
|
|
254
255
|
expect( textdec_string.decode( nil )).to be_nil
|
255
256
|
expect( textdec_int.decode( nil )).to be_nil
|
256
257
|
end
|
258
|
+
|
259
|
+
it "should be defined on an encoder but not on a decoder instance" do
|
260
|
+
expect( textdec_int.respond_to?(:decode) ).to be_truthy
|
261
|
+
expect( textenc_int.respond_to?(:decode) ).to be_falsey
|
262
|
+
end
|
257
263
|
end
|
258
264
|
|
259
265
|
describe '#encode' do
|
@@ -304,12 +310,73 @@ describe "PG::Type derivations" do
|
|
304
310
|
end
|
305
311
|
end
|
306
312
|
|
313
|
+
it "should encode floats" do
|
314
|
+
expect( textenc_float.encode(0) ).to eq( "0.0" )
|
315
|
+
expect( textenc_float.encode(-1) ).to eq( "-1.0" )
|
316
|
+
expect( textenc_float.encode(-1.234567890123456789) ).to eq( "-1.234567890123457" )
|
317
|
+
expect( textenc_float.encode(9) ).to eq( "9.0" )
|
318
|
+
expect( textenc_float.encode(10) ).to eq( "10.0" )
|
319
|
+
expect( textenc_float.encode(-99) ).to eq( "-99.0" )
|
320
|
+
expect( textenc_float.encode(-100) ).to eq( "-100.0" )
|
321
|
+
expect( textenc_float.encode(999) ).to eq( "999.0" )
|
322
|
+
expect( textenc_float.encode(-1000) ).to eq( "-1000.0" )
|
323
|
+
expect( textenc_float.encode(1234.567890123456789) ).to eq( "1234.567890123457" )
|
324
|
+
expect( textenc_float.encode(-9999) ).to eq( "-9999.0" )
|
325
|
+
expect( textenc_float.encode(10000) ).to eq( "10000.0" )
|
326
|
+
expect( textenc_float.encode(99999) ).to eq( "99999.0" )
|
327
|
+
expect( textenc_float.encode(-100000) ).to eq( "-100000.0" )
|
328
|
+
expect( textenc_float.encode(-999999) ).to eq( "-999999.0" )
|
329
|
+
expect( textenc_float.encode(1000000) ).to eq( "1000000.0" )
|
330
|
+
expect( textenc_float.encode(9999999) ).to eq( "9999999.0" )
|
331
|
+
expect( textenc_float.encode(-100000000000000) ).to eq( "-100000000000000.0" )
|
332
|
+
expect( textenc_float.encode(123456789012345) ).to eq( "123456789012345.0" )
|
333
|
+
expect( textenc_float.encode(-999999999999999) ).to eq( "-999999999999999.0" )
|
334
|
+
expect( textenc_float.encode(1000000000000000) ).to eq( "1e15" )
|
335
|
+
expect( textenc_float.encode(-1234567890123456) ).to eq( "-1.234567890123456e15" )
|
336
|
+
expect( textenc_float.encode(9999999999999999) ).to eq( "1e16" )
|
337
|
+
|
338
|
+
expect( textenc_float.encode(-0.0) ).to eq( "0.0" )
|
339
|
+
expect( textenc_float.encode(0.1) ).to eq( "0.1" )
|
340
|
+
expect( textenc_float.encode(0.1234567890123456789) ).to eq( "0.1234567890123457" )
|
341
|
+
expect( textenc_float.encode(-0.9) ).to eq( "-0.9" )
|
342
|
+
expect( textenc_float.encode(-0.01234567890123456789) ).to eq( "-0.01234567890123457" )
|
343
|
+
expect( textenc_float.encode(0.09) ).to eq( "0.09" )
|
344
|
+
expect( textenc_float.encode(0.001234567890123456789) ).to eq( "0.001234567890123457" )
|
345
|
+
expect( textenc_float.encode(-0.009) ).to eq( "-0.009" )
|
346
|
+
expect( textenc_float.encode(-0.0001234567890123456789) ).to eq( "-0.0001234567890123457" )
|
347
|
+
expect( textenc_float.encode(0.0009) ).to eq( "0.0009" )
|
348
|
+
expect( textenc_float.encode(0.00001) ).to eq( "1e-5" )
|
349
|
+
expect( textenc_float.encode(0.00001234567890123456789) ).to eq( "1.234567890123457e-5" )
|
350
|
+
expect( textenc_float.encode(-0.00009) ).to eq( "-9e-5" )
|
351
|
+
expect( textenc_float.encode(-0.11) ).to eq( "-0.11" )
|
352
|
+
expect( textenc_float.encode(10.11) ).to eq( "10.11" )
|
353
|
+
expect( textenc_float.encode(-1.234567890123456789E-280) ).to eq( "-1.234567890123457e-280" )
|
354
|
+
expect( textenc_float.encode(-1.234567890123456789E280) ).to eq( "-1.234567890123457e280" )
|
355
|
+
expect( textenc_float.encode(9876543210987654321E280) ).to eq( "9.87654321098765e298" )
|
356
|
+
expect( textenc_float.encode(9876543210987654321E-400) ).to eq( "0.0" )
|
357
|
+
expect( textenc_float.encode(9876543210987654321E400) ).to eq( "Infinity" )
|
358
|
+
end
|
359
|
+
|
307
360
|
it "should encode special floats equally to Float#to_s" do
|
308
361
|
expect( textenc_float.encode(Float::INFINITY) ).to eq( Float::INFINITY.to_s )
|
309
362
|
expect( textenc_float.encode(-Float::INFINITY) ).to eq( (-Float::INFINITY).to_s )
|
310
363
|
expect( textenc_float.encode(-Float::NAN) ).to eq( Float::NAN.to_s )
|
311
364
|
end
|
312
365
|
|
366
|
+
it "should encode various inputs to numeric format" do
|
367
|
+
expect( textenc_numeric.encode(0) ).to eq( "0" )
|
368
|
+
expect( textenc_numeric.encode(1) ).to eq( "1" )
|
369
|
+
expect( textenc_numeric.encode(-12345678901234567890123) ).to eq( "-12345678901234567890123" )
|
370
|
+
expect( textenc_numeric.encode(0.0) ).to eq( "0.0" )
|
371
|
+
expect( textenc_numeric.encode(1.0) ).to eq( "1.0" )
|
372
|
+
expect( textenc_numeric.encode(-1.23456789012e45) ).to eq( "-1.23456789012e45" )
|
373
|
+
expect( textenc_numeric.encode(Float::NAN) ).to eq( Float::NAN.to_s )
|
374
|
+
expect( textenc_numeric.encode(BigDecimal(0)) ).to eq( "0.0" )
|
375
|
+
expect( textenc_numeric.encode(BigDecimal(1)) ).to eq( "1.0" )
|
376
|
+
expect( textenc_numeric.encode(BigDecimal("-12345678901234567890.1234567")) ).to eq( "-12345678901234567890.1234567" )
|
377
|
+
expect( textenc_numeric.encode(" 123 ") ).to eq( " 123 " )
|
378
|
+
end
|
379
|
+
|
313
380
|
it "encodes binary string to bytea" do
|
314
381
|
expect( textenc_bytea.encode("\x00\x01\x02\x03\xef".b) ).to eq( "\\x00010203ef" )
|
315
382
|
end
|
@@ -376,6 +443,11 @@ describe "PG::Type derivations" do
|
|
376
443
|
expect( textenc_string.encode( nil )).to be_nil
|
377
444
|
expect( textenc_int.encode( nil )).to be_nil
|
378
445
|
end
|
446
|
+
|
447
|
+
it "should be defined on a decoder but not on an encoder instance" do
|
448
|
+
expect( textenc_int.respond_to?(:encode) ).to be_truthy
|
449
|
+
expect( textdec_int.respond_to?(:encode) ).to be_falsey
|
450
|
+
end
|
379
451
|
end
|
380
452
|
|
381
453
|
it "should be possible to marshal encoders" do
|
@@ -392,7 +464,7 @@ describe "PG::Type derivations" do
|
|
392
464
|
|
393
465
|
it "should respond to to_h" do
|
394
466
|
expect( textenc_int.to_h ).to eq( {
|
395
|
-
name: 'Integer', oid: 23, format: 0
|
467
|
+
name: 'Integer', oid: 23, format: 0, flags: 0
|
396
468
|
} )
|
397
469
|
end
|
398
470
|
|
@@ -624,7 +696,7 @@ describe "PG::Type derivations" do
|
|
624
696
|
expect( textenc_int_array.encode(['1',['2'],'3']) ).to eq( %[{1,{2},3}] )
|
625
697
|
end
|
626
698
|
it 'encodes an array of float8 with sub arrays' do
|
627
|
-
expect( textenc_float_array.encode([1000.11,[-0.
|
699
|
+
expect( textenc_float_array.encode([1000.11,[-0.00000221,[3.31,-441]],[nil,6.61],-7.71]) ).to match(Regexp.new(%[^{1000.1*,{-2.2*e-*6,{3.3*,-441.0}},{NULL,6.6*},-7.7*}$].gsub(/([\.\+\{\}\,])/, "\\\\\\1").gsub(/\*/, "\\d*")))
|
628
700
|
end
|
629
701
|
end
|
630
702
|
context 'two dimensional arrays' do
|
@@ -712,15 +784,15 @@ describe "PG::Type derivations" do
|
|
712
784
|
expect( lt.to_h ).to eq( textenc_int_array.to_h )
|
713
785
|
end
|
714
786
|
|
715
|
-
it "should be possible to marshal
|
716
|
-
mt = Marshal.dump(
|
787
|
+
it "should be possible to marshal decoders" do
|
788
|
+
mt = Marshal.dump(textdec_string_array_raise)
|
717
789
|
lt = Marshal.load(mt)
|
718
|
-
expect( lt.to_h ).to eq(
|
790
|
+
expect( lt.to_h ).to eq( textdec_string_array_raise.to_h )
|
719
791
|
end
|
720
792
|
|
721
793
|
it "should respond to to_h" do
|
722
794
|
expect( textenc_int_array.to_h ).to eq( {
|
723
|
-
name: nil, oid: 0, format: 0,
|
795
|
+
name: nil, oid: 0, format: 0, flags: 0,
|
724
796
|
elements_type: textenc_int, needs_quotation: false, delimiter: ','
|
725
797
|
} )
|
726
798
|
end
|
@@ -946,4 +1018,106 @@ describe "PG::Type derivations" do
|
|
946
1018
|
end
|
947
1019
|
end
|
948
1020
|
end
|
1021
|
+
|
1022
|
+
describe PG::RecordCoder do
|
1023
|
+
describe PG::TextEncoder::Record do
|
1024
|
+
context "with default typemap" do
|
1025
|
+
let!(:encoder) do
|
1026
|
+
PG::TextEncoder::Record.new
|
1027
|
+
end
|
1028
|
+
|
1029
|
+
it "should encode different types of Ruby objects" do
|
1030
|
+
expect( encoder.encode([:xyz, 123, 2456, 34567, 456789, 5678901, [1,2,3], 12.1, "abcdefg", nil]) ).
|
1031
|
+
to eq('("xyz","123","2456","34567","456789","5678901","[1, 2, 3]","12.1","abcdefg",)')
|
1032
|
+
end
|
1033
|
+
|
1034
|
+
it 'should output a string with correct character encoding' do
|
1035
|
+
v = encoder.encode(["Héllo"], "iso-8859-1")
|
1036
|
+
expect( v.encoding ).to eq( Encoding::ISO_8859_1 )
|
1037
|
+
expect( v ).to eq( '("Héllo")'.encode(Encoding::ISO_8859_1) )
|
1038
|
+
end
|
1039
|
+
end
|
1040
|
+
|
1041
|
+
context "with TypeMapByClass" do
|
1042
|
+
let!(:tm) do
|
1043
|
+
tm = PG::TypeMapByClass.new
|
1044
|
+
tm[Integer] = textenc_int
|
1045
|
+
tm[Float] = intenc_incrementer
|
1046
|
+
tm[Array] = PG::TextEncoder::Array.new elements_type: textenc_string
|
1047
|
+
tm
|
1048
|
+
end
|
1049
|
+
let!(:encoder) do
|
1050
|
+
PG::TextEncoder::Record.new type_map: tm
|
1051
|
+
end
|
1052
|
+
|
1053
|
+
it "should have reasonable default values" do
|
1054
|
+
expect( encoder.name ).to be_nil
|
1055
|
+
end
|
1056
|
+
|
1057
|
+
it "copies all attributes with #dup" do
|
1058
|
+
encoder.name = "test"
|
1059
|
+
encoder.type_map = PG::TypeMapByColumn.new []
|
1060
|
+
encoder2 = encoder.dup
|
1061
|
+
expect( encoder.object_id ).to_not eq( encoder2.object_id )
|
1062
|
+
expect( encoder2.name ).to eq( "test" )
|
1063
|
+
expect( encoder2.type_map ).to be_a_kind_of( PG::TypeMapByColumn )
|
1064
|
+
end
|
1065
|
+
|
1066
|
+
describe '#encode' do
|
1067
|
+
it "should encode different types of Ruby objects" do
|
1068
|
+
expect( encoder.encode([]) ).to eq("()")
|
1069
|
+
expect( encoder.encode(["a"]) ).to eq('("a")')
|
1070
|
+
expect( encoder.encode([:xyz, 123, 2456, 34567, 456789, 5678901, [1,2,3], 12.1, "abcdefg", nil]) ).
|
1071
|
+
to eq('("xyz","123","2456","34567","456789","5678901","{1,2,3}","13 ","abcdefg",)')
|
1072
|
+
end
|
1073
|
+
|
1074
|
+
it "should escape special characters" do
|
1075
|
+
expect( encoder.encode([" \"\t\n\\\r"]) ).to eq("(\" \"\"\t\n##\r\")".gsub("#", "\\"))
|
1076
|
+
end
|
1077
|
+
end
|
1078
|
+
end
|
1079
|
+
end
|
1080
|
+
|
1081
|
+
describe PG::TextDecoder::Record do
|
1082
|
+
context "with default typemap" do
|
1083
|
+
let!(:decoder) do
|
1084
|
+
PG::TextDecoder::Record.new
|
1085
|
+
end
|
1086
|
+
|
1087
|
+
describe '#decode' do
|
1088
|
+
it "should decode composite text format to array of strings" do
|
1089
|
+
expect( decoder.decode('("fuzzy dice",,"",42,)') ).to eq( ["fuzzy dice",nil, "", "42", nil] )
|
1090
|
+
end
|
1091
|
+
|
1092
|
+
it 'should respect input character encoding' do
|
1093
|
+
v = decoder.decode("(Héllo)".encode("iso-8859-1")).first
|
1094
|
+
expect( v.encoding ).to eq(Encoding::ISO_8859_1)
|
1095
|
+
expect( v ).to eq("Héllo".encode("iso-8859-1"))
|
1096
|
+
end
|
1097
|
+
|
1098
|
+
it 'should raise an error on malformed input' do
|
1099
|
+
expect{ decoder.decode('') }.to raise_error(ArgumentError, /"" - Missing left parenthesis/)
|
1100
|
+
expect{ decoder.decode('(') }.to raise_error(ArgumentError, /"\(" - Unexpected end of input/)
|
1101
|
+
expect{ decoder.decode('(\\') }.to raise_error(ArgumentError, /"\(\\" - Unexpected end of input/)
|
1102
|
+
expect{ decoder.decode('()x') }.to raise_error(ArgumentError, /"\(\)x" - Junk after right parenthesis/)
|
1103
|
+
end
|
1104
|
+
end
|
1105
|
+
end
|
1106
|
+
|
1107
|
+
context "with TypeMapByColumn" do
|
1108
|
+
let!(:tm) do
|
1109
|
+
PG::TypeMapByColumn.new [textdec_int, textdec_string, intdec_incrementer, nil]
|
1110
|
+
end
|
1111
|
+
let!(:decoder) do
|
1112
|
+
PG::TextDecoder::Record.new type_map: tm
|
1113
|
+
end
|
1114
|
+
|
1115
|
+
describe '#decode' do
|
1116
|
+
it "should decode different types of Ruby objects" do
|
1117
|
+
expect( decoder.decode("(123,\" #,#\n#\r#\\ \",234,#\x01#\002)".gsub("#", "\\"))).to eq( [123, " ,\n\r\\ ", 235, "\x01\x02"] )
|
1118
|
+
end
|
1119
|
+
end
|
1120
|
+
end
|
1121
|
+
end
|
1122
|
+
end
|
949
1123
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: pg
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Michael Granger
|
@@ -11,32 +11,31 @@ bindir: bin
|
|
11
11
|
cert_chain:
|
12
12
|
- |
|
13
13
|
-----BEGIN CERTIFICATE-----
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
+
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
OMKv6pWsoS81vw5KAGBmfX8nht/Py90DQrbRvakATGI=
|
14
|
+
MIIENDCCApygAwIBAgIBATANBgkqhkiG9w0BAQsFADAiMSAwHgYDVQQDDBdnZWQv
|
15
|
+
REM9RmFlcmllTVVEL0RDPW9yZzAeFw0xODExMjAxODI5NTlaFw0xOTExMjAxODI5
|
16
|
+
NTlaMCIxIDAeBgNVBAMMF2dlZC9EQz1GYWVyaWVNVUQvREM9b3JnMIIBojANBgkq
|
17
|
+
hkiG9w0BAQEFAAOCAY8AMIIBigKCAYEAvyVhkRzvlEs0fe7145BYLfN6njX9ih5H
|
18
|
+
L60U0p0euIurpv84op9CNKF9tx+1WKwyQvQP7qFGuZxkSUuWcP/sFhDXL1lWUuIl
|
19
|
+
M4uHbGCRmOshDrF4dgnBeOvkHr1fIhPlJm5FO+Vew8tSQmlDsosxLUx+VB7DrVFO
|
20
|
+
5PU2AEbf04GGSrmqADGWXeaslaoRdb1fu/0M5qfPTRn5V39sWD9umuDAF9qqil/x
|
21
|
+
Sl6phTvgBrG8GExHbNZpLARd3xrBYLEFsX7RvBn2UPfgsrtvpdXjsHGfpT3IPN+B
|
22
|
+
vQ66lts4alKC69TE5cuKasWBm+16A4aEe3XdZBRNmtOu/g81gvwA7fkJHKllJuaI
|
23
|
+
dXzdHqq+zbGZVSQ7pRYHYomD0IiDe1DbIouFnPWmagaBnGHwXkDT2bKKP+s2v21m
|
24
|
+
ozilJg4aar2okb/RA6VS87o+d7g6LpDDMMQjH4G9OPnJENLdhu8KnPw/ivSVvQw7
|
25
|
+
N2I4L/ZOIe2DIVuYH7aLHfjZDQv/mNgpAgMBAAGjdTBzMAkGA1UdEwQCMAAwCwYD
|
26
|
+
VR0PBAQDAgSwMB0GA1UdDgQWBBRyjf55EbrHagiRLqt5YAd3yb8k4DAcBgNVHREE
|
27
|
+
FTATgRFnZWRARmFlcmllTVVELm9yZzAcBgNVHRIEFTATgRFnZWRARmFlcmllTVVE
|
28
|
+
Lm9yZzANBgkqhkiG9w0BAQsFAAOCAYEAP9Ffkvg4e8CjIWi8SykQ8oJSS8jbmbgF
|
29
|
+
abke3vXWLG6V9kFiObuJd5wZRBluJANu7bEtjgc3fFaGVP2XxVdCpVjNbmMDg4Qp
|
30
|
+
ovvczP53X6pQP2RSZgxF6Lblvy8y11RziUTVRG/Z2aJHsElo6gI7vQznE/OSDrhC
|
31
|
+
gEhr8uaIUt7D+HZWRbU0+MkKPpL5uMqaFuJbqXEvSwPTuUuYkDfNfsjQO7ruWBac
|
32
|
+
bxHCrvpZ6Tijc0nrlyXi6gPOCLeaqhau2xFnlvKgELwsGYSoKBJyDwqtQ5kwrOlU
|
33
|
+
tkSyLrfZ+RZcH535Hyvif7ZxB0v5OxXXoec+N2vrUsEUMRDL9dg4/WFdN8hIOixF
|
34
|
+
3IPKpZ1ho0Ya5q7yhygtBK9/NBFHw+nbJjcltfPDBXleRe8u73gnQo8AZIhStYSP
|
35
|
+
v4qqqa27Bs468d6SoPxjSm8a2mM9HZ4OdWhq4tFsbTeXDVquCfi64OTEaTt2xQdR
|
36
|
+
JnC4lpJfCP6aCXa5h2XAQfPSH636cQap
|
38
37
|
-----END CERTIFICATE-----
|
39
|
-
date:
|
38
|
+
date: 2019-12-24 00:00:00.000000000 Z
|
40
39
|
dependencies:
|
41
40
|
- !ruby/object:Gem::Dependency
|
42
41
|
name: hoe-mercurial
|
@@ -100,20 +99,14 @@ dependencies:
|
|
100
99
|
requirements:
|
101
100
|
- - "~>"
|
102
101
|
- !ruby/object:Gem::Version
|
103
|
-
version:
|
104
|
-
- - ">="
|
105
|
-
- !ruby/object:Gem::Version
|
106
|
-
version: 0.6.2
|
102
|
+
version: 0.7.0
|
107
103
|
type: :development
|
108
104
|
prerelease: false
|
109
105
|
version_requirements: !ruby/object:Gem::Requirement
|
110
106
|
requirements:
|
111
107
|
- - "~>"
|
112
108
|
- !ruby/object:Gem::Version
|
113
|
-
version:
|
114
|
-
- - ">="
|
115
|
-
- !ruby/object:Gem::Version
|
116
|
-
version: 0.6.2
|
109
|
+
version: 0.7.0
|
117
110
|
- !ruby/object:Gem::Dependency
|
118
111
|
name: hoe-bundler
|
119
112
|
requirement: !ruby/object:Gem::Requirement
|
@@ -162,14 +155,14 @@ dependencies:
|
|
162
155
|
requirements:
|
163
156
|
- - "~>"
|
164
157
|
- !ruby/object:Gem::Version
|
165
|
-
version: '3.
|
158
|
+
version: '3.20'
|
166
159
|
type: :development
|
167
160
|
prerelease: false
|
168
161
|
version_requirements: !ruby/object:Gem::Requirement
|
169
162
|
requirements:
|
170
163
|
- - "~>"
|
171
164
|
- !ruby/object:Gem::Version
|
172
|
-
version: '3.
|
165
|
+
version: '3.20'
|
173
166
|
description: |-
|
174
167
|
Pg is the Ruby interface to the {PostgreSQL RDBMS}[http://www.postgresql.org/].
|
175
168
|
|
@@ -215,6 +208,7 @@ extra_rdoc_files:
|
|
215
208
|
- ext/pg_connection.c
|
216
209
|
- ext/pg_copy_coder.c
|
217
210
|
- ext/pg_errors.c
|
211
|
+
- ext/pg_record_coder.c
|
218
212
|
- ext/pg_result.c
|
219
213
|
- ext/pg_text_decoder.c
|
220
214
|
- ext/pg_text_encoder.c
|
@@ -226,7 +220,7 @@ extra_rdoc_files:
|
|
226
220
|
- ext/pg_type_map_by_mri_type.c
|
227
221
|
- ext/pg_type_map_by_oid.c
|
228
222
|
- ext/pg_type_map_in_ruby.c
|
229
|
-
- ext/
|
223
|
+
- ext/pg_util.c
|
230
224
|
files:
|
231
225
|
- ".gemtest"
|
232
226
|
- BSDL
|
@@ -256,6 +250,7 @@ files:
|
|
256
250
|
- ext/pg_connection.c
|
257
251
|
- ext/pg_copy_coder.c
|
258
252
|
- ext/pg_errors.c
|
253
|
+
- ext/pg_record_coder.c
|
259
254
|
- ext/pg_result.c
|
260
255
|
- ext/pg_text_decoder.c
|
261
256
|
- ext/pg_text_encoder.c
|
@@ -267,8 +262,8 @@ files:
|
|
267
262
|
- ext/pg_type_map_by_mri_type.c
|
268
263
|
- ext/pg_type_map_by_oid.c
|
269
264
|
- ext/pg_type_map_in_ruby.c
|
270
|
-
- ext/
|
271
|
-
- ext/
|
265
|
+
- ext/pg_util.c
|
266
|
+
- ext/pg_util.h
|
272
267
|
- ext/vc/pg.sln
|
273
268
|
- ext/vc/pg_18/pg.vcproj
|
274
269
|
- ext/vc/pg_19/pg_19.vcproj
|
@@ -300,10 +295,11 @@ files:
|
|
300
295
|
- spec/pg/type_map_spec.rb
|
301
296
|
- spec/pg/type_spec.rb
|
302
297
|
- spec/pg_spec.rb
|
303
|
-
homepage: https://
|
298
|
+
homepage: https://github.com/ged/ruby-pg
|
304
299
|
licenses:
|
305
|
-
- BSD-
|
306
|
-
metadata:
|
300
|
+
- BSD-2-Clause
|
301
|
+
metadata:
|
302
|
+
homepage_uri: https://github.com/ged/ruby-pg
|
307
303
|
post_install_message:
|
308
304
|
rdoc_options:
|
309
305
|
- "--main"
|
@@ -314,15 +310,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
314
310
|
requirements:
|
315
311
|
- - ">="
|
316
312
|
- !ruby/object:Gem::Version
|
317
|
-
version: 2.
|
313
|
+
version: '2.2'
|
318
314
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
319
315
|
requirements:
|
320
316
|
- - ">="
|
321
317
|
- !ruby/object:Gem::Version
|
322
318
|
version: '0'
|
323
319
|
requirements: []
|
324
|
-
|
325
|
-
rubygems_version: 2.7.6
|
320
|
+
rubygems_version: 3.0.6
|
326
321
|
signing_key:
|
327
322
|
specification_version: 4
|
328
323
|
summary: Pg is the Ruby interface to the {PostgreSQL RDBMS}[http://www.postgresql.org/]
|