pg 0.17.1-x86-mingw32 → 0.18.0.pre20141017160319-x86-mingw32

Sign up to get free protection for your applications and to get access to all the features.
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