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.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +0 -0
- data.tar.gz.sig +0 -0
- data/ChangeLog +1885 -169
- data/History.rdoc +6 -0
- data/Manifest.txt +25 -1
- data/README.rdoc +47 -0
- data/Rakefile +21 -12
- data/Rakefile.cross +39 -33
- data/ext/extconf.rb +27 -26
- data/ext/pg.c +73 -19
- data/ext/pg.h +194 -6
- data/ext/pg_binary_decoder.c +160 -0
- data/ext/pg_binary_encoder.c +160 -0
- data/ext/pg_coder.c +473 -0
- data/ext/pg_connection.c +872 -534
- data/ext/pg_copy_coder.c +557 -0
- data/ext/pg_result.c +266 -111
- data/ext/pg_text_decoder.c +424 -0
- data/ext/pg_text_encoder.c +631 -0
- data/ext/pg_type_map.c +113 -0
- data/ext/pg_type_map_all_strings.c +113 -0
- data/ext/pg_type_map_by_column.c +254 -0
- data/ext/pg_type_map_by_mri_type.c +266 -0
- data/ext/pg_type_map_by_oid.c +341 -0
- data/ext/util.c +149 -0
- data/ext/util.h +65 -0
- data/lib/1.9/pg_ext.so +0 -0
- data/lib/2.0/pg_ext.so +0 -0
- data/lib/2.1/pg_ext.so +0 -0
- data/lib/i386-mingw32/libpq.dll +0 -0
- data/lib/pg.rb +11 -1
- data/lib/pg/basic_type_mapping.rb +377 -0
- data/lib/pg/coder.rb +74 -0
- data/lib/pg/connection.rb +43 -1
- data/lib/pg/result.rb +13 -3
- data/lib/pg/text_decoder.rb +42 -0
- data/lib/pg/text_encoder.rb +27 -0
- data/lib/pg/type_map_by_column.rb +15 -0
- data/spec/{lib/helpers.rb → helpers.rb} +95 -35
- data/spec/pg/basic_type_mapping_spec.rb +251 -0
- data/spec/pg/connection_spec.rb +416 -214
- data/spec/pg/result_spec.rb +146 -116
- data/spec/pg/type_map_by_column_spec.rb +135 -0
- data/spec/pg/type_map_by_mri_type_spec.rb +122 -0
- data/spec/pg/type_map_by_oid_spec.rb +133 -0
- data/spec/pg/type_map_spec.rb +39 -0
- data/spec/pg/type_spec.rb +649 -0
- data/spec/pg_spec.rb +10 -18
- metadata +130 -52
- metadata.gz.sig +0 -0
- data/lib/1.8/pg_ext.so +0 -0
data/spec/pg/result_spec.rb
CHANGED
@@ -1,59 +1,29 @@
|
|
1
1
|
#!/usr/bin/env rspec
|
2
2
|
# encoding: utf-8
|
3
3
|
|
4
|
-
|
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 "
|
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'].
|
44
|
-
res[0]['b'].
|
13
|
+
expect( res[0]['a'] ).to eq( '1' )
|
14
|
+
expect( res[0]['b'] ).to eq( '2' )
|
45
15
|
end
|
46
16
|
|
47
|
-
it "
|
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.
|
21
|
+
expect( list ).to eq [['1', '2']]
|
52
22
|
end
|
53
23
|
|
54
|
-
it "
|
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'].
|
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.
|
70
|
-
result.error_field(
|
71
|
-
result.error_field(
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
result.error_field(
|
76
|
-
result.error_field(
|
77
|
-
result.error_field(
|
78
|
-
result.error_field(
|
79
|
-
result.error_field(
|
80
|
-
result.error_field(
|
81
|
-
|
82
|
-
|
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(
|
96
|
-
result.error_field(
|
97
|
-
result.error_field(
|
98
|
-
result.error_field(
|
99
|
-
result.error_field(
|
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 "
|
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.
|
84
|
+
expect( sqlstate ).to eq( 22012 )
|
110
85
|
end
|
111
86
|
|
112
|
-
it "
|
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'].
|
118
|
-
res.getvalue(0,0).
|
119
|
-
res.values[0][0].
|
120
|
-
res.column_values(0)[0].
|
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 "
|
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'].
|
129
|
-
res.getvalue(0,0).
|
130
|
-
res.values[0][0].
|
131
|
-
res.column_values(0)[0].
|
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 "
|
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']).
|
114
|
+
expect( PG::Connection.unescape_bytea(res[0]['column1']) ).to eq( bytes )
|
140
115
|
end
|
141
116
|
|
142
|
-
it "
|
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.
|
125
|
+
expect( out_bytes ).to eq( in_bytes )
|
151
126
|
end
|
152
127
|
|
153
|
-
it "
|
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
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
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 "
|
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 "
|
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 "
|
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 "
|
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.
|
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(
|
175
|
+
expect( res.fmod(0) ).to eq( 33 + 4 ) # Column length + varlena size (4)
|
199
176
|
end
|
200
177
|
|
201
|
-
it "
|
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 "
|
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 "
|
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(
|
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(
|
202
|
+
expect( res.ftable(0) ).to be_nonzero()
|
225
203
|
end
|
226
204
|
|
227
|
-
it "
|
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 "
|
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 "
|
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(
|
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(
|
254
|
-
res.ftablecol(
|
231
|
+
expect( res.ftablecol(0) ).to eq( 1 )
|
232
|
+
expect( res.ftablecol(1) ).to eq( 2 )
|
255
233
|
end
|
256
234
|
|
257
|
-
it "
|
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 "
|
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 "
|
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).
|
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(
|
289
|
-
res.field_values(
|
290
|
-
expect{ res.field_values(
|
291
|
-
expect{ res.field_values(
|
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 "
|
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 "
|
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.
|
307
|
-
error.to_s.
|
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 "
|
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.
|
322
|
-
error.to_s.
|
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 "
|
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
|
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.
|
342
|
-
error.result.
|
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
|