pg 0.17.1-x64-mingw32 → 0.18.0.pre20141017160319-x64-mingw32
Sign up to get free protection for your applications and to get access to all the features.
- 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/2.0/pg_ext.so +0 -0
- data/lib/2.1/pg_ext.so +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/lib/x64-mingw32/libpq.dll +0 -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 +129 -50
- metadata.gz.sig +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
|