pg 1.1.4 → 1.2.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 (57) 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 +86 -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 +44 -9
  10. data/Rakefile +8 -6
  11. data/Rakefile.cross +57 -56
  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 +21 -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 +21 -9
  20. data/ext/pg_connection.c +388 -298
  21. data/ext/pg_copy_coder.c +6 -3
  22. data/ext/pg_record_coder.c +491 -0
  23. data/ext/pg_result.c +279 -127
  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 +9 -4
  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/pg.rb +4 -4
  37. data/lib/pg/basic_type_mapping.rb +81 -18
  38. data/lib/pg/binary_decoder.rb +1 -0
  39. data/lib/pg/coder.rb +22 -1
  40. data/lib/pg/connection.rb +2 -2
  41. data/lib/pg/constants.rb +1 -0
  42. data/lib/pg/exceptions.rb +1 -0
  43. data/lib/pg/result.rb +13 -1
  44. data/lib/pg/text_decoder.rb +2 -3
  45. data/lib/pg/text_encoder.rb +8 -18
  46. data/lib/pg/type_map_by_column.rb +2 -1
  47. data/spec/helpers.rb +11 -11
  48. data/spec/pg/basic_type_mapping_spec.rb +140 -18
  49. data/spec/pg/connection_spec.rb +166 -89
  50. data/spec/pg/result_spec.rb +194 -4
  51. data/spec/pg/tuple_spec.rb +55 -2
  52. data/spec/pg/type_map_by_class_spec.rb +1 -1
  53. data/spec/pg/type_map_by_column_spec.rb +5 -1
  54. data/spec/pg/type_map_by_oid_spec.rb +2 -2
  55. data/spec/pg/type_spec.rb +180 -6
  56. metadata +31 -30
  57. metadata.gz.sig +0 -0
@@ -4,16 +4,65 @@
4
4
  require_relative '../helpers'
5
5
 
6
6
  require 'pg'
7
+ require 'objspace'
7
8
 
8
9
 
9
10
  describe PG::Result do
10
11
 
12
+ describe :field_name_type do
13
+ let!(:res) { @conn.exec('SELECT 1 AS a, 2 AS "B"') }
14
+
15
+ it "uses string field names per default" do
16
+ expect(res.field_name_type).to eq(:string)
17
+ end
18
+
19
+ it "can set string field names" do
20
+ res.field_name_type = :string
21
+ expect(res.field_name_type).to eq(:string)
22
+ end
23
+
24
+ it "can set symbol field names" do
25
+ res.field_name_type = :symbol
26
+ expect(res.field_name_type).to eq(:symbol)
27
+ end
28
+
29
+ it "can set static_symbol field names" do
30
+ res.field_name_type = :static_symbol
31
+ expect(res.field_name_type).to eq(:static_symbol)
32
+ end
33
+
34
+ it "can't set symbol field names after #fields" do
35
+ res.fields
36
+ expect{ res.field_name_type = :symbol }.to raise_error(ArgumentError, /already materialized/)
37
+ expect(res.field_name_type).to eq(:string)
38
+ end
39
+
40
+ it "can't set invalid values" do
41
+ expect{ res.field_name_type = :sym }.to raise_error(ArgumentError, /invalid argument :sym/)
42
+ expect{ res.field_name_type = "symbol" }.to raise_error(ArgumentError, /invalid argument "symbol"/)
43
+ end
44
+ end
45
+
11
46
  it "acts as an array of hashes" do
12
47
  res = @conn.exec("SELECT 1 AS a, 2 AS b")
13
48
  expect( res[0]['a'] ).to eq( '1' )
14
49
  expect( res[0]['b'] ).to eq( '2' )
15
50
  end
16
51
 
52
+ it "acts as an array of hashes with symbols" do
53
+ res = @conn.exec("SELECT 1 AS a, 2 AS b")
54
+ res.field_name_type = :symbol
55
+ expect( res[0][:a] ).to eq( '1' )
56
+ expect( res[0][:b] ).to eq( '2' )
57
+ end
58
+
59
+ it "acts as an array of hashes with static_symbols" do
60
+ res = @conn.exec("SELECT 1 AS a, 2 AS b")
61
+ res.field_name_type = :static_symbol
62
+ expect( res[0][:a] ).to eq( '1' )
63
+ expect( res[0][:b] ).to eq( '2' )
64
+ end
65
+
17
66
  it "yields a row as an array" do
18
67
  res = @conn.exec("SELECT 1 AS a, 2 AS b")
19
68
  list = []
@@ -25,7 +74,6 @@ describe PG::Result do
25
74
  res = @conn.exec("SELECT 1 AS a, 2 AS b")
26
75
  e = res.each_row
27
76
  expect( e ).to be_a_kind_of(Enumerator)
28
- pending "Rubinius doesn't define RETURN_SIZED_ENUMERATOR()" if RUBY_ENGINE=='rbx'
29
77
  expect( e.size ).to eq( 1 )
30
78
  expect( e.to_a ).to eq [['1', '2']]
31
79
  end
@@ -34,12 +82,19 @@ describe PG::Result do
34
82
  res = @conn.exec("SELECT 1 AS a, 2 AS b")
35
83
  e = res.each
36
84
  expect( e ).to be_a_kind_of(Enumerator)
37
- pending "Rubinius doesn't define RETURN_SIZED_ENUMERATOR()" if RUBY_ENGINE=='rbx'
38
85
  expect( e.size ).to eq( 1 )
39
86
  expect( e.to_a ).to eq [{'a'=>'1', 'b'=>'2'}]
40
87
  end
41
88
 
89
+ it "yields a row as an Enumerator of hashs with symbols" do
90
+ res = @conn.exec("SELECT 1 AS a, 2 AS b")
91
+ res.field_name_type = :symbol
92
+ expect( res.each.to_a ).to eq [{:a=>'1', :b=>'2'}]
93
+ end
94
+
42
95
  context "result streaming in single row mode" do
96
+ let!(:textdec_int){ PG::TextDecoder::Integer.new name: 'INT4', oid: 23 }
97
+
43
98
  it "can iterate over all rows as Hash" do
44
99
  @conn.send_query( "SELECT generate_series(2,4) AS a; SELECT 1 AS b, generate_series(5,6) AS c" )
45
100
  @conn.set_single_row_mode
@@ -56,6 +111,31 @@ describe PG::Result do
56
111
  expect( @conn.get_result ).to be_nil
57
112
  end
58
113
 
114
+ it "can iterate over all rows as Hash with symbols and typemap" do
115
+ @conn.send_query( "SELECT generate_series(2,4) AS a" )
116
+ @conn.set_single_row_mode
117
+ res = @conn.get_result.field_names_as(:symbol)
118
+ res.type_map = PG::TypeMapByColumn.new [textdec_int]
119
+ expect(
120
+ res.stream_each.to_a
121
+ ).to eq(
122
+ [{:a=>2}, {:a=>3}, {:a=>4}]
123
+ )
124
+ expect( @conn.get_result ).to be_nil
125
+ end
126
+
127
+ it "keeps last result on error while iterating stream_each" do
128
+ @conn.send_query( "SELECT generate_series(2,4) AS a" )
129
+ @conn.set_single_row_mode
130
+ res = @conn.get_result
131
+ expect do
132
+ res.stream_each_row do
133
+ raise ZeroDivisionError
134
+ end
135
+ end.to raise_error(ZeroDivisionError)
136
+ expect( res.values ).to eq([["2"]])
137
+ end
138
+
59
139
  it "can iterate over all rows as Array" do
60
140
  @conn.send_query( "SELECT generate_series(2,4) AS a; SELECT 1 AS b, generate_series(5,6) AS c" )
61
141
  @conn.set_single_row_mode
@@ -72,6 +152,18 @@ describe PG::Result do
72
152
  expect( @conn.get_result ).to be_nil
73
153
  end
74
154
 
155
+ it "keeps last result on error while iterating stream_each_row" do
156
+ @conn.send_query( "SELECT generate_series(2,4) AS a" )
157
+ @conn.set_single_row_mode
158
+ res = @conn.get_result
159
+ expect do
160
+ res.stream_each_row do
161
+ raise ZeroDivisionError
162
+ end
163
+ end.to raise_error(ZeroDivisionError)
164
+ expect( res.values ).to eq([["2"]])
165
+ end
166
+
75
167
  it "can iterate over all rows as PG::Tuple" do
76
168
  @conn.send_query( "SELECT generate_series(2,4) AS a; SELECT 1 AS b, generate_series(5,6) AS c" )
77
169
  @conn.set_single_row_mode
@@ -88,6 +180,36 @@ describe PG::Result do
88
180
  expect( @conn.get_result ).to be_nil
89
181
  end
90
182
 
183
+ it "clears result on error while iterating stream_each_tuple" do
184
+ @conn.send_query( "SELECT generate_series(2,4) AS a" )
185
+ @conn.set_single_row_mode
186
+ res = @conn.get_result
187
+ expect do
188
+ res.stream_each_tuple do
189
+ raise ZeroDivisionError
190
+ end
191
+ end.to raise_error(ZeroDivisionError)
192
+ expect( res.cleared? ).to eq(true)
193
+ end
194
+
195
+ it "should reuse field names in stream_each_tuple" do
196
+ @conn.send_query( "SELECT generate_series(2,3) AS a" )
197
+ @conn.set_single_row_mode
198
+ tuple1, tuple2 = *@conn.get_result.stream_each_tuple.to_a
199
+ expect( tuple1.keys[0].object_id ).to eq(tuple2.keys[0].object_id)
200
+ end
201
+
202
+ it "can iterate over all rows as PG::Tuple with symbols and typemap" do
203
+ @conn.send_query( "SELECT generate_series(2,4) AS a" )
204
+ @conn.set_single_row_mode
205
+ res = @conn.get_result.field_names_as(:symbol)
206
+ res.type_map = PG::TypeMapByColumn.new [textdec_int]
207
+ tuples = res.stream_each_tuple.to_a
208
+ expect( tuples[0][0] ).to eq( 2 )
209
+ expect( tuples[1][:a] ).to eq( 3 )
210
+ expect( @conn.get_result ).to be_nil
211
+ end
212
+
91
213
  it "complains when not in single row mode" do
92
214
  @conn.send_query( "SELECT generate_series(2,4)" )
93
215
  expect{
@@ -147,6 +269,17 @@ describe PG::Result do
147
269
  ).to match( /^parserOpenTable$|^RangeVarGetRelid$/ )
148
270
  end
149
271
 
272
+ it "encapsulates PG_DIAG_SEVERITY_NONLOCALIZED error in a PG::Error object", :postgresql_96 do
273
+ result = nil
274
+ begin
275
+ @conn.exec( "SELECT * FROM nonexistant_table" )
276
+ rescue PG::Error => err
277
+ result = err.result
278
+ end
279
+
280
+ expect( result.error_field(PG::PG_DIAG_SEVERITY_NONLOCALIZED) ).to eq( 'ERROR' )
281
+ end
282
+
150
283
  it "encapsulates database object names for integrity constraint violations", :postgresql_93 do
151
284
  @conn.exec( "CREATE TABLE integrity (id SERIAL PRIMARY KEY)" )
152
285
  exception = nil
@@ -167,13 +300,35 @@ describe PG::Result do
167
300
  it "detects division by zero as SQLSTATE 22012" do
168
301
  sqlstate = nil
169
302
  begin
170
- res = @conn.exec("SELECT 1/0")
303
+ @conn.exec("SELECT 1/0")
171
304
  rescue PG::Error => e
172
305
  sqlstate = e.result.result_error_field( PG::PG_DIAG_SQLSTATE ).to_i
173
306
  end
174
307
  expect( sqlstate ).to eq( 22012 )
175
308
  end
176
309
 
310
+ it "provides the error message" do
311
+ @conn.send_query("SELECT xyz")
312
+ res = @conn.get_result; @conn.get_result
313
+ expect( res.error_message ).to match(/"xyz"/)
314
+ expect( res.result_error_message ).to match(/"xyz"/)
315
+ end
316
+
317
+ it "provides a verbose error message", :postgresql_96 do
318
+ @conn.send_query("SELECT xyz")
319
+ res = @conn.get_result; @conn.get_result
320
+ # PQERRORS_TERSE should give a single line result
321
+ expect( res.verbose_error_message(PG::PQERRORS_TERSE, PG::PQSHOW_CONTEXT_ALWAYS) ).to match(/\A.*\n\z/)
322
+ # PQERRORS_VERBOSE should give a multi line result
323
+ expect( res.result_verbose_error_message(PG::PQERRORS_VERBOSE, PG::PQSHOW_CONTEXT_NEVER) ).to match(/\n.*\n/)
324
+ end
325
+
326
+ it "provides a verbose error message with SQLSTATE", :postgresql_12 do
327
+ @conn.send_query("SELECT xyz")
328
+ res = @conn.get_result; @conn.get_result
329
+ expect( res.verbose_error_message(PG::PQERRORS_SQLSTATE, PG::PQSHOW_CONTEXT_NEVER) ).to match(/42703/)
330
+ end
331
+
177
332
  it "returns the same bytes in binary format that are sent in binary format" do
178
333
  binary_file = File.join(Dir.pwd, 'spec/data', 'random_binary_data')
179
334
  bytes = File.open(binary_file, 'rb').read
@@ -258,6 +413,32 @@ describe PG::Result do
258
413
  expect( res.values ).to eq( [ ["bar"], ["bar2"] ] )
259
414
  end
260
415
 
416
+ it "can retrieve field names" do
417
+ res = @conn.exec('SELECT 1 AS a, 2 AS "B"')
418
+ expect(res.fields).to eq(["a", "B"])
419
+ end
420
+
421
+ it "can retrieve field names as symbols" do
422
+ res = @conn.exec('SELECT 1 AS a, 2 AS "B"')
423
+ res.field_name_type = :symbol
424
+ expect(res.fields).to eq([:a, :B])
425
+ end
426
+
427
+ it "can retrieve single field names" do
428
+ res = @conn.exec('SELECT 1 AS a, 2 AS "B"')
429
+ expect(res.fname(0)).to eq("a")
430
+ expect(res.fname(1)).to eq("B")
431
+ expect{res.fname(2)}.to raise_error(ArgumentError)
432
+ end
433
+
434
+ it "can retrieve single field names as symbol" do
435
+ res = @conn.exec('SELECT 1 AS a, 2 AS "B"')
436
+ res.field_name_type = :symbol
437
+ expect(res.fname(0)).to eq(:a)
438
+ expect(res.fname(1)).to eq(:B)
439
+ expect{res.fname(2)}.to raise_error(ArgumentError)
440
+ end
441
+
261
442
  # PQfmod
262
443
  it "can return the type modifier for a result column" do
263
444
  @conn.exec( 'CREATE TABLE fmodtest ( foo varchar(33) )' )
@@ -355,8 +536,9 @@ describe PG::Result do
355
536
  res = @conn.exec( "SELECT 1 AS x, 'a' AS y UNION ALL SELECT 2, 'b'" )
356
537
  expect( res.field_values('x') ).to eq( ['1', '2'] )
357
538
  expect( res.field_values('y') ).to eq( ['a', 'b'] )
539
+ expect( res.field_values(:x) ).to eq( ['1', '2'] )
358
540
  expect{ res.field_values('') }.to raise_error(IndexError)
359
- expect{ res.field_values(:x) }.to raise_error(TypeError)
541
+ expect{ res.field_values(0) }.to raise_error(TypeError)
360
542
  end
361
543
 
362
544
  it "can return the values of a single tuple" do
@@ -444,6 +626,13 @@ describe PG::Result do
444
626
  expect( r.inspect ).to match(/cleared/)
445
627
  end
446
628
 
629
+ it "should give account about memory usage" do
630
+ r = @conn.exec "select 1"
631
+ expect( ObjectSpace.memsize_of(r) ).to be > 1000
632
+ r.clear
633
+ expect( ObjectSpace.memsize_of(r) ).to be < 100
634
+ end
635
+
447
636
  context 'result value conversions with TypeMapByColumn' do
448
637
  let!(:textdec_int){ PG::TextDecoder::Integer.new name: 'INT4', oid: 23 }
449
638
  let!(:textdec_float){ PG::TextDecoder::Float.new name: 'FLOAT4', oid: 700 }
@@ -470,6 +659,7 @@ describe PG::Result do
470
659
  expect( res.enum_for(:each).to_a ).to eq( [{'f' => 123}] )
471
660
  expect( res.column_values(0) ).to eq( [123] )
472
661
  expect( res.field_values('f') ).to eq( [123] )
662
+ expect( res.field_values(:f) ).to eq( [123] )
473
663
  expect( res.tuple_values(0) ).to eq( [123] )
474
664
  end
475
665
 
@@ -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!(:result2x3cast) { @conn.exec( "SELECT * FROM (VALUES(1, TRUE, '3'), (2, FALSE, '4')) AS m (a, b, b)" ).map_types!(typemap) }
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
 
@@ -132,7 +132,7 @@ describe PG::TypeMapByClass do
132
132
  it "should raise error on invalid coder object" do
133
133
  tm[TrueClass] = "dummy"
134
134
  expect{
135
- res = @conn.exec_params( "SELECT $1", [true], 0, tm )
135
+ @conn.exec_params( "SELECT $1", [true], 0, tm )
136
136
  }.to raise_error(NoMethodError, /undefined method.*call/)
137
137
  end
138
138
  end
@@ -38,7 +38,11 @@ describe PG::TypeMapByColumn do
38
38
  pass_through_type,
39
39
  nil
40
40
  ] )
41
- expect( cm.inspect ).to eq( "#<PG::TypeMapByColumn INT4:0 TEXT:0 FLOAT4:0 pass_through:1 nil>" )
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
@@ -54,8 +54,8 @@ describe PG::TypeMapByOid do
54
54
  end
55
55
 
56
56
  it "should check format when deleting coders" do
57
- expect{ tm.rm_coder 2, 123 }.to raise_error(ArgumentError)
58
- expect{ tm.rm_coder -1, 123 }.to raise_error(ArgumentError)
57
+ expect{ tm.rm_coder(2, 123) }.to raise_error(ArgumentError)
58
+ expect{ tm.rm_coder(-1, 123) }.to raise_error(ArgumentError)
59
59
  end
60
60
 
61
61
  it "should check format when adding coders" do