pg 0.17.1-x86-mingw32 → 0.18.0.pre20141017160319-x86-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 (52) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data.tar.gz.sig +0 -0
  4. data/ChangeLog +1885 -169
  5. data/History.rdoc +6 -0
  6. data/Manifest.txt +25 -1
  7. data/README.rdoc +47 -0
  8. data/Rakefile +21 -12
  9. data/Rakefile.cross +39 -33
  10. data/ext/extconf.rb +27 -26
  11. data/ext/pg.c +73 -19
  12. data/ext/pg.h +194 -6
  13. data/ext/pg_binary_decoder.c +160 -0
  14. data/ext/pg_binary_encoder.c +160 -0
  15. data/ext/pg_coder.c +473 -0
  16. data/ext/pg_connection.c +872 -534
  17. data/ext/pg_copy_coder.c +557 -0
  18. data/ext/pg_result.c +266 -111
  19. data/ext/pg_text_decoder.c +424 -0
  20. data/ext/pg_text_encoder.c +631 -0
  21. data/ext/pg_type_map.c +113 -0
  22. data/ext/pg_type_map_all_strings.c +113 -0
  23. data/ext/pg_type_map_by_column.c +254 -0
  24. data/ext/pg_type_map_by_mri_type.c +266 -0
  25. data/ext/pg_type_map_by_oid.c +341 -0
  26. data/ext/util.c +149 -0
  27. data/ext/util.h +65 -0
  28. data/lib/1.9/pg_ext.so +0 -0
  29. data/lib/2.0/pg_ext.so +0 -0
  30. data/lib/2.1/pg_ext.so +0 -0
  31. data/lib/i386-mingw32/libpq.dll +0 -0
  32. data/lib/pg.rb +11 -1
  33. data/lib/pg/basic_type_mapping.rb +377 -0
  34. data/lib/pg/coder.rb +74 -0
  35. data/lib/pg/connection.rb +43 -1
  36. data/lib/pg/result.rb +13 -3
  37. data/lib/pg/text_decoder.rb +42 -0
  38. data/lib/pg/text_encoder.rb +27 -0
  39. data/lib/pg/type_map_by_column.rb +15 -0
  40. data/spec/{lib/helpers.rb → helpers.rb} +95 -35
  41. data/spec/pg/basic_type_mapping_spec.rb +251 -0
  42. data/spec/pg/connection_spec.rb +416 -214
  43. data/spec/pg/result_spec.rb +146 -116
  44. data/spec/pg/type_map_by_column_spec.rb +135 -0
  45. data/spec/pg/type_map_by_mri_type_spec.rb +122 -0
  46. data/spec/pg/type_map_by_oid_spec.rb +133 -0
  47. data/spec/pg/type_map_spec.rb +39 -0
  48. data/spec/pg/type_spec.rb +649 -0
  49. data/spec/pg_spec.rb +10 -18
  50. metadata +130 -52
  51. metadata.gz.sig +0 -0
  52. data/lib/1.8/pg_ext.so +0 -0
@@ -1,59 +1,29 @@
1
1
  #!/usr/bin/env rspec
2
2
  # encoding: utf-8
3
3
 
4
- BEGIN {
5
- require 'pathname'
4
+ require_relative '../helpers'
6
5
 
7
- basedir = Pathname( __FILE__ ).dirname.parent.parent
8
- libdir = basedir + 'lib'
9
-
10
- $LOAD_PATH.unshift( basedir.to_s ) unless $LOAD_PATH.include?( basedir.to_s )
11
- $LOAD_PATH.unshift( libdir.to_s ) unless $LOAD_PATH.include?( libdir.to_s )
12
- }
13
-
14
- require 'rspec'
15
- require 'spec/lib/helpers'
16
6
  require 'pg'
17
7
 
18
- describe PG::Result do
19
-
20
- before( :all ) do
21
- @conn = setup_testing_db( "PG_Result" )
22
- end
23
-
24
- before( :each ) do
25
- @conn.exec( 'BEGIN' )
26
- end
27
-
28
- after( :each ) do
29
- @conn.exec( 'ROLLBACK' )
30
- end
31
-
32
- after( :all ) do
33
- teardown_testing_db( @conn )
34
- end
35
-
36
8
 
37
- #
38
- # Examples
39
- #
9
+ describe PG::Result do
40
10
 
41
- it "should act as an array of hashes" do
11
+ it "acts as an array of hashes" do
42
12
  res = @conn.exec("SELECT 1 AS a, 2 AS b")
43
- res[0]['a'].should== '1'
44
- res[0]['b'].should== '2'
13
+ expect( res[0]['a'] ).to eq( '1' )
14
+ expect( res[0]['b'] ).to eq( '2' )
45
15
  end
46
16
 
47
- it "should yield a row as an array" do
17
+ it "yields a row as an array" do
48
18
  res = @conn.exec("SELECT 1 AS a, 2 AS b")
49
19
  list = []
50
20
  res.each_row { |r| list << r }
51
- list.should eq [['1', '2']]
21
+ expect( list ).to eq [['1', '2']]
52
22
  end
53
23
 
54
- it "should insert nil AS NULL and return NULL as nil" do
24
+ it "inserts nil AS NULL and return NULL as nil" do
55
25
  res = @conn.exec("SELECT $1::int AS n", [nil])
56
- res[0]['n'].should be_nil()
26
+ expect( res[0]['n'] ).to be_nil()
57
27
  end
58
28
 
59
29
  it "encapsulates errors in a PGError object" do
@@ -66,20 +36,25 @@ describe PG::Result do
66
36
 
67
37
  result = exception.result
68
38
 
69
- result.should be_a( described_class() )
70
- result.error_field( PG::PG_DIAG_SEVERITY ).should == 'ERROR'
71
- result.error_field( PG::PG_DIAG_SQLSTATE ).should == '42P01'
72
- result.error_field( PG::PG_DIAG_MESSAGE_PRIMARY ).
73
- should == 'relation "nonexistant_table" does not exist'
74
- result.error_field( PG::PG_DIAG_MESSAGE_DETAIL ).should be_nil()
75
- result.error_field( PG::PG_DIAG_MESSAGE_HINT ).should be_nil()
76
- result.error_field( PG::PG_DIAG_STATEMENT_POSITION ).should == '15'
77
- result.error_field( PG::PG_DIAG_INTERNAL_POSITION ).should be_nil()
78
- result.error_field( PG::PG_DIAG_INTERNAL_QUERY ).should be_nil()
79
- result.error_field( PG::PG_DIAG_CONTEXT ).should be_nil()
80
- result.error_field( PG::PG_DIAG_SOURCE_FILE ).should =~ /parse_relation\.c$|namespace\.c$/
81
- result.error_field( PG::PG_DIAG_SOURCE_LINE ).should =~ /^\d+$/
82
- result.error_field( PG::PG_DIAG_SOURCE_FUNCTION ).should =~ /^parserOpenTable$|^RangeVarGetRelid$/
39
+ expect( result ).to be_a( described_class() )
40
+ expect( result.error_field(PG::PG_DIAG_SEVERITY) ).to eq( 'ERROR' )
41
+ expect( result.error_field(PG::PG_DIAG_SQLSTATE) ).to eq( '42P01' )
42
+ expect(
43
+ result.error_field(PG::PG_DIAG_MESSAGE_PRIMARY)
44
+ ).to eq( 'relation "nonexistant_table" does not exist' )
45
+ expect( result.error_field(PG::PG_DIAG_MESSAGE_DETAIL) ).to be_nil()
46
+ expect( result.error_field(PG::PG_DIAG_MESSAGE_HINT) ).to be_nil()
47
+ expect( result.error_field(PG::PG_DIAG_STATEMENT_POSITION) ).to eq( '15' )
48
+ expect( result.error_field(PG::PG_DIAG_INTERNAL_POSITION) ).to be_nil()
49
+ expect( result.error_field(PG::PG_DIAG_INTERNAL_QUERY) ).to be_nil()
50
+ expect( result.error_field(PG::PG_DIAG_CONTEXT) ).to be_nil()
51
+ expect(
52
+ result.error_field(PG::PG_DIAG_SOURCE_FILE)
53
+ ).to match( /parse_relation\.c$|namespace\.c$/ )
54
+ expect( result.error_field(PG::PG_DIAG_SOURCE_LINE) ).to match( /^\d+$/ )
55
+ expect(
56
+ result.error_field(PG::PG_DIAG_SOURCE_FUNCTION)
57
+ ).to match( /^parserOpenTable$|^RangeVarGetRelid$/ )
83
58
  end
84
59
 
85
60
  it "encapsulates database object names for integrity constraint violations", :postgresql_93 do
@@ -92,54 +67,54 @@ describe PG::Result do
92
67
  end
93
68
  result = exception.result
94
69
 
95
- result.error_field( PG::PG_DIAG_SCHEMA_NAME ).should == 'public'
96
- result.error_field( PG::PG_DIAG_TABLE_NAME ).should == 'integrity'
97
- result.error_field( PG::PG_DIAG_COLUMN_NAME ).should == 'id'
98
- result.error_field( PG::PG_DIAG_DATATYPE_NAME ).should be_nil
99
- result.error_field( PG::PG_DIAG_CONSTRAINT_NAME ).should be_nil
70
+ expect( result.error_field(PG::PG_DIAG_SCHEMA_NAME) ).to eq( 'public' )
71
+ expect( result.error_field(PG::PG_DIAG_TABLE_NAME) ).to eq( 'integrity' )
72
+ expect( result.error_field(PG::PG_DIAG_COLUMN_NAME) ).to eq( 'id' )
73
+ expect( result.error_field(PG::PG_DIAG_DATATYPE_NAME) ).to be_nil
74
+ expect( result.error_field(PG::PG_DIAG_CONSTRAINT_NAME) ).to be_nil
100
75
  end
101
76
 
102
- it "should detect division by zero as SQLSTATE 22012" do
77
+ it "detects division by zero as SQLSTATE 22012" do
103
78
  sqlstate = nil
104
79
  begin
105
80
  res = @conn.exec("SELECT 1/0")
106
81
  rescue PGError => e
107
82
  sqlstate = e.result.result_error_field( PG::PG_DIAG_SQLSTATE ).to_i
108
83
  end
109
- sqlstate.should == 22012
84
+ expect( sqlstate ).to eq( 22012 )
110
85
  end
111
86
 
112
- it "should return the same bytes in binary format that are sent in binary format" do
87
+ it "returns the same bytes in binary format that are sent in binary format" do
113
88
  binary_file = File.join(Dir.pwd, 'spec/data', 'random_binary_data')
114
89
  bytes = File.open(binary_file, 'rb').read
115
90
  res = @conn.exec('VALUES ($1::bytea)',
116
91
  [ { :value => bytes, :format => 1 } ], 1)
117
- res[0]['column1'].should== bytes
118
- res.getvalue(0,0).should == bytes
119
- res.values[0][0].should == bytes
120
- res.column_values(0)[0].should == bytes
92
+ expect( res[0]['column1'] ).to eq( bytes )
93
+ expect( res.getvalue(0,0) ).to eq( bytes )
94
+ expect( res.values[0][0] ).to eq( bytes )
95
+ expect( res.column_values(0)[0] ).to eq( bytes )
121
96
  end
122
97
 
123
- it "should return the same bytes in binary format that are sent as inline text" do
98
+ it "returns the same bytes in binary format that are sent as inline text" do
124
99
  binary_file = File.join(Dir.pwd, 'spec/data', 'random_binary_data')
125
100
  bytes = File.open(binary_file, 'rb').read
126
101
  @conn.exec("SET standard_conforming_strings=on")
127
102
  res = @conn.exec("VALUES ('#{PG::Connection.escape_bytea(bytes)}'::bytea)", [], 1)
128
- res[0]['column1'].should == bytes
129
- res.getvalue(0,0).should == bytes
130
- res.values[0][0].should == bytes
131
- res.column_values(0)[0].should == bytes
103
+ expect( res[0]['column1'] ).to eq( bytes )
104
+ expect( res.getvalue(0,0) ).to eq( bytes )
105
+ expect( res.values[0][0] ).to eq( bytes )
106
+ expect( res.column_values(0)[0] ).to eq( bytes )
132
107
  end
133
108
 
134
- it "should return the same bytes in text format that are sent in binary format" do
109
+ it "returns the same bytes in text format that are sent in binary format" do
135
110
  binary_file = File.join(Dir.pwd, 'spec/data', 'random_binary_data')
136
111
  bytes = File.open(binary_file, 'rb').read
137
112
  res = @conn.exec('VALUES ($1::bytea)',
138
113
  [ { :value => bytes, :format => 1 } ])
139
- PG::Connection.unescape_bytea(res[0]['column1']).should== bytes
114
+ expect( PG::Connection.unescape_bytea(res[0]['column1']) ).to eq( bytes )
140
115
  end
141
116
 
142
- it "should return the same bytes in text format that are sent as inline text" do
117
+ it "returns the same bytes in text format that are sent as inline text" do
143
118
  binary_file = File.join(Dir.pwd, 'spec/data', 'random_binary_data')
144
119
  in_bytes = File.open(binary_file, 'rb').read
145
120
 
@@ -147,73 +122,76 @@ describe PG::Result do
147
122
  @conn.exec("SET standard_conforming_strings=on")
148
123
  res = @conn.exec("VALUES ('#{PG::Connection.escape_bytea(in_bytes)}'::bytea)", [], 0)
149
124
  out_bytes = PG::Connection.unescape_bytea(res[0]['column1'])
150
- out_bytes.should == in_bytes
125
+ expect( out_bytes ).to eq( in_bytes )
151
126
  end
152
127
 
153
- it "should return the parameter type of the specified prepared statement parameter", :postgresql_92 do
128
+ it "returns the parameter type of the specified prepared statement parameter", :postgresql_92 do
154
129
  query = 'SELECT * FROM pg_stat_activity WHERE user = $1::name AND query = $2::text'
155
130
  @conn.prepare( 'queryfinder', query )
156
131
  res = @conn.describe_prepared( 'queryfinder' )
157
132
 
158
- @conn.exec( 'SELECT format_type($1, -1)', [res.paramtype(0)] ).getvalue( 0, 0 ).
159
- should == 'name'
160
- @conn.exec( 'SELECT format_type($1, -1)', [res.paramtype(1)] ).getvalue( 0, 0 ).
161
- should == 'text'
133
+ expect(
134
+ @conn.exec( 'SELECT format_type($1, -1)', [res.paramtype(0)] ).getvalue( 0, 0 )
135
+ ).to eq( 'name' )
136
+ expect(
137
+ @conn.exec( 'SELECT format_type($1, -1)', [res.paramtype(1)] ).getvalue( 0, 0 )
138
+ ).to eq( 'text' )
162
139
  end
163
140
 
164
- it "should raise an exception when a negative index is given to #fformat" do
141
+ it "raises an exception when a negative index is given to #fformat" do
165
142
  res = @conn.exec('SELECT * FROM pg_stat_activity')
166
143
  expect {
167
144
  res.fformat( -1 )
168
145
  }.to raise_error( ArgumentError, /column number/i )
169
146
  end
170
147
 
171
- it "should raise an exception when a negative index is given to #fmod" do
148
+ it "raises an exception when a negative index is given to #fmod" do
172
149
  res = @conn.exec('SELECT * FROM pg_stat_activity')
173
150
  expect {
174
151
  res.fmod( -1 )
175
152
  }.to raise_error( ArgumentError, /column number/i )
176
153
  end
177
154
 
178
- it "should raise an exception when a negative index is given to #[]" do
155
+ it "raises an exception when a negative index is given to #[]" do
179
156
  res = @conn.exec('SELECT * FROM pg_stat_activity')
180
157
  expect {
181
158
  res[ -1 ]
182
159
  }.to raise_error( IndexError, /-1 is out of range/i )
183
160
  end
184
161
 
185
- it "should raise allow for conversion to an array of arrays" do
162
+ it "raises allow for conversion to an array of arrays" do
186
163
  @conn.exec( 'CREATE TABLE valuestest ( foo varchar(33) )' )
187
164
  @conn.exec( 'INSERT INTO valuestest ("foo") values (\'bar\')' )
188
165
  @conn.exec( 'INSERT INTO valuestest ("foo") values (\'bar2\')' )
189
166
 
190
167
  res = @conn.exec( 'SELECT * FROM valuestest' )
191
- res.values.should == [ ["bar"], ["bar2"] ]
168
+ expect( res.values ).to eq( [ ["bar"], ["bar2"] ] )
192
169
  end
193
170
 
194
171
  # PQfmod
195
172
  it "can return the type modifier for a result column" do
196
173
  @conn.exec( 'CREATE TABLE fmodtest ( foo varchar(33) )' )
197
174
  res = @conn.exec( 'SELECT * FROM fmodtest' )
198
- res.fmod( 0 ).should == 33 + 4 # Column length + varlena size (4)
175
+ expect( res.fmod(0) ).to eq( 33 + 4 ) # Column length + varlena size (4)
199
176
  end
200
177
 
201
- it "should raise an exception when an invalid index is passed to PG::Result#fmod" do
178
+ it "raises an exception when an invalid index is passed to PG::Result#fmod" do
202
179
  @conn.exec( 'CREATE TABLE fmodtest ( foo varchar(33) )' )
203
180
  res = @conn.exec( 'SELECT * FROM fmodtest' )
204
181
  expect { res.fmod(1) }.to raise_error( ArgumentError )
205
182
  end
206
183
 
207
- it "should raise an exception when an invalid (negative) index is passed to PG::Result#fmod" do
184
+ it "raises an exception when an invalid (negative) index is passed to PG::Result#fmod" do
208
185
  @conn.exec( 'CREATE TABLE fmodtest ( foo varchar(33) )' )
209
186
  res = @conn.exec( 'SELECT * FROM fmodtest' )
210
187
  expect { res.fmod(-11) }.to raise_error( ArgumentError )
211
188
  end
212
189
 
213
- it "shouldn't raise an exception when a valid index is passed to PG::Result#fmod for a column with no typemod" do
190
+ it "doesn't raise an exception when a valid index is passed to PG::Result#fmod for a" +
191
+ " column with no typemod" do
214
192
  @conn.exec( 'CREATE TABLE fmodtest ( foo text )' )
215
193
  res = @conn.exec( 'SELECT * FROM fmodtest' )
216
- res.fmod( 0 ).should == -1 # and it shouldn't raise an exception, either
194
+ expect( res.fmod(0) ).to eq( -1 )
217
195
  end
218
196
 
219
197
  # PQftable
@@ -221,28 +199,28 @@ describe PG::Result do
221
199
  @conn.exec( 'CREATE TABLE ftabletest ( foo text )' )
222
200
  res = @conn.exec( 'SELECT * FROM ftabletest' )
223
201
 
224
- res.ftable( 0 ).should == be_nonzero()
202
+ expect( res.ftable(0) ).to be_nonzero()
225
203
  end
226
204
 
227
- it "should raise an exception when an invalid index is passed to PG::Result#ftable" do
205
+ it "raises an exception when an invalid index is passed to PG::Result#ftable" do
228
206
  @conn.exec( 'CREATE TABLE ftabletest ( foo text )' )
229
207
  res = @conn.exec( 'SELECT * FROM ftabletest' )
230
208
 
231
209
  expect { res.ftable(18) }.to raise_error( ArgumentError )
232
210
  end
233
211
 
234
- it "should raise an exception when an invalid (negative) index is passed to PG::Result#ftable" do
212
+ it "raises an exception when an invalid (negative) index is passed to PG::Result#ftable" do
235
213
  @conn.exec( 'CREATE TABLE ftabletest ( foo text )' )
236
214
  res = @conn.exec( 'SELECT * FROM ftabletest' )
237
215
 
238
216
  expect { res.ftable(-2) }.to raise_error( ArgumentError )
239
217
  end
240
218
 
241
- it "shouldn't raise an exception when a valid index is passed to PG::Result#ftable for a " +
219
+ it "doesn't raise an exception when a valid index is passed to PG::Result#ftable for a " +
242
220
  "column with no corresponding table" do
243
221
  @conn.exec( 'CREATE TABLE ftabletest ( foo text )' )
244
222
  res = @conn.exec( 'SELECT foo, LENGTH(foo) as length FROM ftabletest' )
245
- res.ftable( 1 ).should == PG::INVALID_OID # and it shouldn't raise an exception, either
223
+ expect( res.ftable(1) ).to eq( PG::INVALID_OID )
246
224
  end
247
225
 
248
226
  # PQftablecol
@@ -250,29 +228,29 @@ describe PG::Result do
250
228
  @conn.exec( 'CREATE TABLE ftablecoltest ( foo text, bar numeric )' )
251
229
  res = @conn.exec( 'SELECT * FROM ftablecoltest' )
252
230
 
253
- res.ftablecol( 0 ).should == 1
254
- res.ftablecol( 1 ).should == 2
231
+ expect( res.ftablecol(0) ).to eq( 1 )
232
+ expect( res.ftablecol(1) ).to eq( 2 )
255
233
  end
256
234
 
257
- it "should raise an exception when an invalid index is passed to PG::Result#ftablecol" do
235
+ it "raises an exception when an invalid index is passed to PG::Result#ftablecol" do
258
236
  @conn.exec( 'CREATE TABLE ftablecoltest ( foo text, bar numeric )' )
259
237
  res = @conn.exec( 'SELECT * FROM ftablecoltest' )
260
238
 
261
239
  expect { res.ftablecol(32) }.to raise_error( ArgumentError )
262
240
  end
263
241
 
264
- it "should raise an exception when an invalid (negative) index is passed to PG::Result#ftablecol" do
242
+ it "raises an exception when an invalid (negative) index is passed to PG::Result#ftablecol" do
265
243
  @conn.exec( 'CREATE TABLE ftablecoltest ( foo text, bar numeric )' )
266
244
  res = @conn.exec( 'SELECT * FROM ftablecoltest' )
267
245
 
268
246
  expect { res.ftablecol(-1) }.to raise_error( ArgumentError )
269
247
  end
270
248
 
271
- it "shouldn't raise an exception when a valid index is passed to PG::Result#ftablecol for a " +
249
+ it "doesnn't raise an exception when a valid index is passed to PG::Result#ftablecol for a " +
272
250
  "column with no corresponding table" do
273
251
  @conn.exec( 'CREATE TABLE ftablecoltest ( foo text )' )
274
252
  res = @conn.exec( 'SELECT foo, LENGTH(foo) as length FROM ftablecoltest' )
275
- res.ftablecol(1).should == 0 # and it shouldn't raise an exception, either
253
+ expect( res.ftablecol(1) ).to eq( 0 )
276
254
  end
277
255
 
278
256
  it "can be manually checked for failed result status (async API)" do
@@ -285,41 +263,41 @@ describe PG::Result do
285
263
 
286
264
  it "can return the values of a single field" do
287
265
  res = @conn.exec( "SELECT 1 AS x, 'a' AS y UNION ALL SELECT 2, 'b'" )
288
- res.field_values( 'x' ).should == ['1', '2']
289
- res.field_values( 'y' ).should == ['a', 'b']
290
- expect{ res.field_values( '' ) }.to raise_error(IndexError)
291
- expect{ res.field_values( :x ) }.to raise_error(TypeError)
266
+ expect( res.field_values('x') ).to eq( ['1', '2'] )
267
+ expect( res.field_values('y') ).to eq( ['a', 'b'] )
268
+ expect{ res.field_values('') }.to raise_error(IndexError)
269
+ expect{ res.field_values(:x) }.to raise_error(TypeError)
292
270
  end
293
271
 
294
- it "should raise a proper exception for a nonexistant table" do
272
+ it "raises a proper exception for a nonexistant table" do
295
273
  expect {
296
274
  @conn.exec( "SELECT * FROM nonexistant_table" )
297
275
  }.to raise_error( PG::UndefinedTable, /relation "nonexistant_table" does not exist/ )
298
276
  end
299
277
 
300
- it "should raise a more generic exception for an unknown SQLSTATE" do
278
+ it "raises a more generic exception for an unknown SQLSTATE" do
301
279
  old_error = PG::ERROR_CLASSES.delete('42P01')
302
280
  begin
303
281
  expect {
304
282
  @conn.exec( "SELECT * FROM nonexistant_table" )
305
283
  }.to raise_error{|error|
306
- error.should be_an_instance_of(PG::SyntaxErrorOrAccessRuleViolation)
307
- error.to_s.should match(/relation "nonexistant_table" does not exist/)
284
+ expect( error ).to be_an_instance_of(PG::SyntaxErrorOrAccessRuleViolation)
285
+ expect( error.to_s ).to match(/relation "nonexistant_table" does not exist/)
308
286
  }
309
287
  ensure
310
288
  PG::ERROR_CLASSES['42P01'] = old_error
311
289
  end
312
290
  end
313
291
 
314
- it "should raise a ServerError for an unknown SQLSTATE class" do
292
+ it "raises a ServerError for an unknown SQLSTATE class" do
315
293
  old_error1 = PG::ERROR_CLASSES.delete('42P01')
316
294
  old_error2 = PG::ERROR_CLASSES.delete('42')
317
295
  begin
318
296
  expect {
319
297
  @conn.exec( "SELECT * FROM nonexistant_table" )
320
298
  }.to raise_error{|error|
321
- error.should be_an_instance_of(PG::ServerError)
322
- error.to_s.should match(/relation "nonexistant_table" does not exist/)
299
+ expect( error ).to be_an_instance_of(PG::ServerError)
300
+ expect( error.to_s ).to match(/relation "nonexistant_table" does not exist/)
323
301
  }
324
302
  ensure
325
303
  PG::ERROR_CLASSES['42P01'] = old_error1
@@ -327,19 +305,71 @@ describe PG::Result do
327
305
  end
328
306
  end
329
307
 
330
- it "should raise a proper exception for a nonexistant schema" do
308
+ it "raises a proper exception for a nonexistant schema" do
331
309
  expect {
332
310
  @conn.exec( "DROP SCHEMA nonexistant_schema" )
333
311
  }.to raise_error( PG::InvalidSchemaName, /schema "nonexistant_schema" does not exist/ )
334
312
  end
335
313
 
336
- it "the raised result should be nil in case of a connection error" do
314
+ it "the raised result is nil in case of a connection error" do
337
315
  c = PGconn.connect_start( '127.0.0.1', 54320, "", "", "me", "xxxx", "somedb" )
338
316
  expect {
339
317
  c.exec "select 1"
340
- }.to raise_error{|error|
341
- error.should be_an_instance_of(PG::UnableToSend)
342
- error.result.should == nil
318
+ }.to raise_error {|error|
319
+ expect( error ).to be_an_instance_of(PG::UnableToSend)
320
+ expect( error.result ).to eq( nil )
343
321
  }
344
322
  end
323
+
324
+ it "does not clear the result itself" do
325
+ r = @conn.exec "select 1"
326
+ expect( r.autoclear? ).to eq(false)
327
+ expect( r.cleared? ).to eq(false)
328
+ r.clear
329
+ expect( r.cleared? ).to eq(true)
330
+ end
331
+
332
+ context 'result value conversions with TypeMapByColumn' do
333
+ let!(:textdec_int){ PG::TextDecoder::Integer.new name: 'INT4', oid: 23 }
334
+ let!(:textdec_float){ PG::TextDecoder::Float.new name: 'FLOAT4', oid: 700 }
335
+
336
+ it "should allow reading, assigning and diabling type conversions" do
337
+ res = @conn.exec( "SELECT 123" )
338
+ expect( res.type_map ).to be_nil
339
+ res.type_map = PG::TypeMapByColumn.new [textdec_int]
340
+ expect( res.type_map ).to be_an_instance_of(PG::TypeMapByColumn)
341
+ expect( res.type_map.coders ).to eq( [textdec_int] )
342
+ res.type_map = PG::TypeMapByColumn.new [textdec_float]
343
+ expect( res.type_map.coders ).to eq( [textdec_float] )
344
+ res.type_map = nil
345
+ expect( res.type_map ).to be_nil
346
+ end
347
+
348
+ it "should be applied to all value retrieving methods" do
349
+ res = @conn.exec( "SELECT 123 as f" )
350
+ res.type_map = PG::TypeMapByColumn.new [textdec_int]
351
+ expect( res.values ).to eq( [[123]] )
352
+ expect( res.getvalue(0,0) ).to eq( 123 )
353
+ expect( res[0] ).to eq( {'f' => 123 } )
354
+ expect( res.enum_for(:each_row).to_a ).to eq( [[123]] )
355
+ expect( res.enum_for(:each).to_a ).to eq( [{'f' => 123}] )
356
+ expect( res.column_values(0) ).to eq( [123] )
357
+ expect( res.field_values('f') ).to eq( [123] )
358
+ end
359
+
360
+ it "should be usable for several querys" do
361
+ colmap = PG::TypeMapByColumn.new [textdec_int]
362
+ res = @conn.exec( "SELECT 123" )
363
+ res.type_map = colmap
364
+ expect( res.values ).to eq( [[123]] )
365
+ res = @conn.exec( "SELECT 456" )
366
+ res.type_map = colmap
367
+ expect( res.values ).to eq( [[456]] )
368
+ end
369
+
370
+ it "shouldn't allow invalid type maps" do
371
+ res = @conn.exec( "SELECT 1" )
372
+ expect{ res.type_map = 1 }.to raise_error(TypeError)
373
+ end
374
+ end
345
375
  end