ydbd-pg 0.5.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,326 @@
1
+ @class = Class.new(DBDConfig.testbase(DBDConfig.current_dbtype)) do
2
+
3
+ def prep_status_statement
4
+ @sth.finish if (@sth and !@sth.finished?)
5
+ @sth = @dbh.prepare("select * from names order by age")
6
+ @sth.raise_error = true
7
+ end
8
+
9
+ def test_status
10
+ names_rc = 3
11
+
12
+ [:fetch, :fetch_hash, :each, :fetch_all].each do |call|
13
+ assert_raise(DBI::InterfaceError, DBI::NotSupportedError) do
14
+ prep_status_statement
15
+ @sth.send(call)
16
+ end
17
+ end
18
+
19
+ # for these next three, it doesn't really matter what the args are, it should fail
20
+ assert_raises(DBI::InterfaceError, DBI::NotSupportedError) do
21
+ prep_status_statement
22
+ @sth.fetch_many(1)
23
+ end
24
+
25
+ assert_raises(DBI::InterfaceError, DBI::NotSupportedError) do
26
+ prep_status_statement
27
+ @sth.fetch_scroll(0, 0)
28
+ end
29
+
30
+ assert_raises(DBI::InterfaceError, DBI::NotSupportedError) do
31
+ prep_status_statement
32
+ @sth.each { |x| }
33
+ end
34
+
35
+ assert_raises(DBI::InterfaceError) do
36
+ prep_status_statement
37
+ @sth.execute
38
+ 2.times { @sth.fetch_all }
39
+ end
40
+
41
+ assert_raises(DBI::InterfaceError) do
42
+ prep_status_statement
43
+ @sth.execute
44
+ # XXX fetch_many won't know it can't fetch anything until the third time around.
45
+ 3.times { @sth.fetch_many(names_rc) }
46
+ end
47
+ end
48
+
49
+ def test_execute
50
+ assert_nothing_raised do
51
+ @dbh.execute("select * from names order by age") do |sth|
52
+ assert_equal([["Joe", 19], ["Bob", 21], ["Jim", 30]], sth.fetch_all)
53
+ end
54
+ end
55
+ end
56
+
57
+ def test_quoting # FIXME breaks sqlite-ruby to a segfault - research
58
+ @sth = nil
59
+
60
+ assert_nothing_raised do
61
+ if dbtype == "postgresql"
62
+ @sth = @dbh.prepare('select E\'\\\\\'')
63
+ else
64
+ @sth = @dbh.prepare('select \'\\\\\'')
65
+ end
66
+ @sth.execute
67
+ row = @sth.fetch
68
+ assert_equal ['\\'], row
69
+ @sth.finish
70
+ end
71
+ end
72
+
73
+ def test_duplicate_columns
74
+ assert_nothing_raised do
75
+ @sth = @dbh.prepare("select name, name from names where name = ?")
76
+ @sth.execute("Bob")
77
+ assert_equal [["Bob", "Bob"]], @sth.fetch_all
78
+ @sth.finish
79
+ end
80
+ end
81
+
82
+ def test_columninfo
83
+ @sth = nil
84
+
85
+ assert_nothing_raised do
86
+ @sth = @dbh.prepare("select * from precision_test")
87
+ @sth.execute
88
+
89
+ cols = @sth.column_info
90
+
91
+ assert(cols)
92
+ assert_kind_of(Array, cols)
93
+ assert_equal(4, cols.length)
94
+
95
+ # the first column should always be "text_field" and have the following
96
+ # properties:
97
+ assert_equal("text_field", cols[0]["name"])
98
+ assert_equal(20, cols[0]["precision"])
99
+ # scale can be either nil or 0 for character types.
100
+ case cols[0]["scale"]
101
+ when nil
102
+ assert_equal(nil, cols[0]["scale"])
103
+ when 0
104
+ assert_equal(0, cols[0]["scale"])
105
+ else
106
+ flunk "scale can be either 0 or nil for character types"
107
+ end
108
+
109
+ assert_equal(
110
+ DBI::Type::Varchar.object_id,
111
+ DBI::TypeUtil.type_name_to_module(cols[0]["type_name"]).object_id
112
+ )
113
+
114
+ # the second column should always be "integer_field" and have the following
115
+ # properties:
116
+ assert_equal("integer_field", cols[1]["name"])
117
+ # if these aren't set on the field, they should not exist
118
+ # FIXME mysql does not follow this rule, neither does ODBC
119
+ if dbtype == "mysql"
120
+ assert_equal(0, cols[1]["scale"])
121
+ assert_equal(11, cols[1]["precision"])
122
+ elsif dbtype == "odbc"
123
+ assert_equal(0, cols[1]["scale"])
124
+ assert_equal(10, cols[1]["precision"])
125
+ else
126
+ assert(!cols[1]["scale"])
127
+ assert(!cols[1]["precision"])
128
+ end
129
+
130
+ assert_equal(
131
+ DBI::Type::Integer.object_id,
132
+ DBI::TypeUtil.type_name_to_module(cols[1]["type_name"]).object_id
133
+ )
134
+
135
+ # the second column should always be "integer_field" and have the following
136
+ # properties:
137
+ assert_equal("decimal_field", cols[2]["name"])
138
+ assert_equal(1, cols[2]["scale"])
139
+ assert_equal(2, cols[2]["precision"])
140
+ assert_equal(
141
+ DBI::Type::Decimal.object_id,
142
+ DBI::TypeUtil.type_name_to_module(cols[2]["type_name"]).object_id
143
+ )
144
+
145
+ # the second column should always be "numeric_field" and have the following
146
+ # properties:
147
+ assert_equal("numeric_field", cols[3]["name"])
148
+ assert_equal(6, cols[3]["scale"])
149
+ assert_equal(30, cols[3]["precision"])
150
+ assert_equal(
151
+ DBI::Type::Decimal.object_id,
152
+ DBI::TypeUtil.type_name_to_module(cols[3]["type_name"]).object_id
153
+ )
154
+
155
+ cols.each { |col| assert_kind_of(DBI::ColumnInfo, col) }
156
+ @sth.finish
157
+ end
158
+ end
159
+
160
+ def test_duplicate_columns
161
+ assert_nothing_raised do
162
+ @sth = @dbh.prepare("select name, name from names where name = ?")
163
+ @sth.execute("Bob")
164
+ assert_equal [["Bob", "Bob"]], @sth.fetch_all
165
+ @sth.finish
166
+ end
167
+ end
168
+
169
+ def test_rows
170
+ @sth = nil
171
+
172
+ assert_nothing_raised do
173
+ @sth = @dbh.prepare("insert into names (name, age) values (?, ?)")
174
+ @sth.execute("Bill", 22);
175
+ end
176
+
177
+ assert 1, @sth.rows
178
+
179
+ @sth.finish
180
+ @sth = nil
181
+
182
+ assert_nothing_raised do
183
+ @sth = @dbh.prepare("delete from names where name = ?")
184
+ @sth.execute("Bill");
185
+ end
186
+
187
+ assert 1, @sth.rows
188
+
189
+ @sth.finish
190
+
191
+ assert_nothing_raised do
192
+ @sth = @dbh.prepare("select * from names")
193
+ @sth.execute
194
+ end
195
+
196
+ assert_equal 0, @sth.rows
197
+ assert @sth.fetchable?
198
+ assert @sth.any?
199
+ assert @sth.rows.zero?
200
+ @sth.finish
201
+ end
202
+
203
+ def test_prepare_execute
204
+ assert_nothing_raised do
205
+ @sth = @dbh.prepare("select * from names")
206
+ @sth.execute
207
+ @sth.finish
208
+ end
209
+
210
+ assert_nothing_raised do
211
+ @sth = @dbh.prepare("select * from names where name = ?")
212
+ @sth.execute("Bob")
213
+ @sth.finish
214
+ end
215
+
216
+ assert_nothing_raised do
217
+ @sth = @dbh.prepare("insert into names (name, age) values (?, ?)")
218
+ @sth.execute("Bill", 22);
219
+ @sth.finish
220
+ end
221
+ end
222
+
223
+ def test_prepare_execute_with_transactions
224
+ @dbh["AutoCommit"] = false
225
+ config = DBDConfig.get_config['sqlite3']
226
+
227
+ # rollback 1 (the right way)
228
+ @sth = nil
229
+ @sth2 = nil
230
+
231
+ assert_nothing_raised do
232
+ @sth = @dbh.prepare("insert into names (name, age) values (?, ?)")
233
+ @sth.execute("Billy", 23)
234
+ @sth2 = @dbh.prepare("select * from names where name = ?")
235
+ @sth2.execute("Billy")
236
+ end
237
+ assert_equal ["Billy", 23 ], @sth2.fetch
238
+ @sth2.finish
239
+ @sth.finish
240
+ assert_nothing_raised { @dbh.rollback }
241
+
242
+ @sth = @dbh.prepare("select * from names where name = ?")
243
+ @sth.execute("Billy")
244
+ assert_nil @sth.fetch
245
+ @sth.finish
246
+
247
+ # rollback 2 (without closing statements first)
248
+
249
+ @sth = nil
250
+ @sth2 = nil
251
+
252
+ assert_nothing_raised do
253
+ @sth = @dbh.prepare("insert into names (name, age) values (?, ?)")
254
+ @sth.execute("Billy", 23)
255
+ @sth2 = @dbh.prepare("select * from names where name = ?")
256
+ @sth2.execute("Billy")
257
+ end
258
+
259
+ assert_equal ["Billy", 23], @sth2.fetch
260
+
261
+ # FIXME some throw here, some don't. we should probably normalize this
262
+ @dbh.rollback rescue true
263
+
264
+ @sth2.finish
265
+ @sth.finish
266
+ assert_nothing_raised { @dbh.rollback }
267
+
268
+ @sth = @dbh.prepare("select * from names where name = ?")
269
+ @sth.execute("Billy")
270
+ assert_nil @sth.fetch
271
+ @sth.finish
272
+
273
+ # commit
274
+
275
+ @sth = nil
276
+ @sth2 = nil
277
+
278
+ assert_nothing_raised do
279
+ @sth = @dbh.prepare("insert into names (name, age) values (?, ?)")
280
+ @sth.execute("Billy", 23)
281
+ @sth2 = @dbh.prepare("select * from names where name = ?")
282
+ @sth2.execute("Billy")
283
+ end
284
+ assert_equal ["Billy", 23 ], @sth2.fetch
285
+ @sth2.finish
286
+ @sth.finish
287
+ assert_nothing_raised { @dbh.commit }
288
+
289
+ @sth = @dbh.prepare("select * from names where name = ?")
290
+ @sth.execute("Billy")
291
+ assert_equal ["Billy", 23 ], @sth.fetch
292
+ @sth.finish
293
+ end
294
+
295
+ def test_fetch
296
+ @sth = nil
297
+ assert_nothing_raised do
298
+ @sth = @dbh.prepare("select * from names order by age")
299
+ @sth.execute
300
+ end
301
+
302
+ # this tests that we're getting the rows in the right order,
303
+ # and that the types are being converted.
304
+ assert_equal ["Joe", 19], @sth.fetch
305
+ assert_equal ["Bob", 21], @sth.fetch
306
+ assert_equal ["Jim", 30], @sth.fetch
307
+ assert_nil @sth.fetch
308
+
309
+ @sth.finish
310
+ end
311
+
312
+ def test_transaction_block
313
+ @dbh["AutoCommit"] = false
314
+ # this transaction should not fail because it called return early
315
+ @dbh.transaction do |dbh|
316
+ dbh.do('INSERT INTO names (name, age) VALUES (?, ?)', "Cooter", 69)
317
+ return 42
318
+ end
319
+ @sth = @dbh.prepare("select * from names where name = ?")
320
+ @sth.execute("Cooter")
321
+ row = @sth.fetch
322
+ assert row
323
+ assert_equal ["Cooter", 69], row
324
+ @sth.finish
325
+ end
326
+ end
@@ -0,0 +1,296 @@
1
+ @class = Class.new(DBDConfig.testbase(DBDConfig.current_dbtype)) do
2
+ def skip_bit
3
+ # FIXME this test fails because DBI's type system blows goats.
4
+ @sth = nil
5
+
6
+ assert_nothing_raised do
7
+ @sth = @dbh.prepare("insert into bit_test (mybit) values (?)")
8
+ @sth.bind_param(1, 0, DBI::SQL_TINYINT)
9
+ @sth.execute
10
+ # if dbtype == "postgresql"
11
+ # @sth.execute("0")
12
+ # else
13
+ # @sth.execute(0)
14
+ # end
15
+ @sth.finish
16
+ end
17
+
18
+ assert_nothing_raised do
19
+ @sth = @dbh.prepare("select * from bit_test")
20
+ @sth.execute
21
+ row = @sth.fetch
22
+ @sth.finish
23
+
24
+ assert_equal [0], row
25
+ end
26
+ end
27
+
28
+ def test_numeric_types
29
+ assert(@dbh.convert_types)
30
+
31
+ @sth = @dbh.prepare("insert into precision_test (text_field, integer_field, decimal_field, numeric_field) values (?, ?, ?, ?)")
32
+ assert(@sth.convert_types)
33
+ 1.step(5) do |x|
34
+ @sth.execute("poop#{x}", x, x + 0.123, x + 0.234)
35
+ end
36
+
37
+ @sth.finish
38
+
39
+ @sth = @dbh.prepare("select integer_field, decimal_field, numeric_field from precision_test")
40
+ @sth.execute
41
+ col_info = @sth.column_info
42
+ 1.step(5) do |x|
43
+ row = @sth.fetch
44
+
45
+ assert_kind_of(Integer, row[0])
46
+ assert_kind_of(BigDecimal, row[1])
47
+ assert_kind_of(BigDecimal, row[2])
48
+
49
+ # FIXME BigDecimal requires a string and some databases will pad
50
+ # decimal/numeric with constrained precision. We should account for
51
+ # this, but I'm not quite sure how yet.
52
+ end
53
+ @sth.finish
54
+ end
55
+
56
+ # FIXME
57
+ # Ideally, this test should be split across the DBI tests and DBD, but for
58
+ # now testing against the DBDs really doesn't cost us anything other than
59
+ # debugging time if something breaks.
60
+ def test_bind_coltype
61
+ # ensure type conv didn't get turned off somewhere.
62
+ assert(DBI.convert_types)
63
+ assert(@dbh.convert_types)
64
+
65
+ assert_nothing_raised do
66
+ @sth = @dbh.prepare("select name, age from names order by age")
67
+ assert(@sth.convert_types) # again
68
+ @sth.execute
69
+ @sth.bind_coltype(2, DBI::Type::Varchar)
70
+ assert_equal(
71
+ [
72
+ ["Joe", "19"],
73
+ ["Bob", "21"],
74
+ ["Jim", "30"],
75
+ ], @sth.fetch_all
76
+ )
77
+ @sth.finish
78
+ end
79
+
80
+ assert_nothing_raised do
81
+ @sth = @dbh.prepare("select age, name from names order by age")
82
+ assert(@sth.convert_types) # again
83
+ @sth.execute
84
+ @sth.bind_coltype(1, DBI::Type::Varchar)
85
+ assert_equal(
86
+ [
87
+ ["19", "Joe"],
88
+ ["21", "Bob"],
89
+ ["30", "Jim"],
90
+ ], @sth.fetch_all
91
+ )
92
+ @sth.finish
93
+ end
94
+
95
+ # just to be sure..
96
+ assert_nothing_raised do
97
+ @sth = @dbh.prepare("select name, age from names order by age")
98
+ @sth.execute
99
+ @sth.bind_coltype(2, DBI::Type::Float)
100
+ @sth.fetch_all.collect { |x| assert_kind_of(Float, x[1]) }
101
+ @sth.finish
102
+ end
103
+
104
+ # now, let's check some failure cases
105
+ @sth = @dbh.prepare("select name, age from names order by age")
106
+
107
+ # can't bind_coltype before execute
108
+ assert_raises(DBI::InterfaceError) { @sth.bind_coltype(1, DBI::Type::Float) }
109
+ # can't index < 1
110
+ assert_raises(DBI::InterfaceError) { @sth.bind_coltype(0, DBI::Type::Float) }
111
+ end
112
+
113
+ def test_noconv
114
+ # XXX this test will fail the whole test suite miserably if it fails at any point.
115
+ assert(DBI.convert_types)
116
+
117
+ DBI.convert_types = false
118
+ @sth.finish rescue nil
119
+ @dbh.disconnect
120
+ set_base_dbh
121
+
122
+ assert(!@dbh.convert_types)
123
+
124
+ assert_nothing_raised do
125
+ @sth = @dbh.prepare("select * from names order by age")
126
+ assert(!@sth.convert_types)
127
+ @sth.execute
128
+ assert_equal(
129
+ [
130
+ ["Joe", "19"],
131
+ ["Bob", "21"],
132
+ ["Jim", "30"],
133
+ ], @sth.fetch_all
134
+ )
135
+ @sth.finish
136
+ end
137
+
138
+ DBI.convert_types = true
139
+ @sth.finish rescue nil
140
+ @dbh.disconnect
141
+ set_base_dbh
142
+
143
+ assert(DBI.convert_types)
144
+ assert(@dbh.convert_types)
145
+
146
+ assert_nothing_raised do
147
+ @sth = @dbh.prepare("select * from names order by age")
148
+ assert(@sth.convert_types)
149
+ @sth.execute
150
+ assert_equal(
151
+ [
152
+ ["Joe", 19],
153
+ ["Bob", 21],
154
+ ["Jim", 30],
155
+ ], @sth.fetch_all
156
+ )
157
+ @sth.finish
158
+ end
159
+
160
+ @dbh.convert_types = false
161
+
162
+ assert_nothing_raised do
163
+ @sth = @dbh.prepare("select * from names order by age")
164
+ assert(!@sth.convert_types)
165
+ @sth.execute
166
+ assert_equal(
167
+ [
168
+ ["Joe", "19"],
169
+ ["Bob", "21"],
170
+ ["Jim", "30"],
171
+ ], @sth.fetch_all
172
+ )
173
+ @sth.finish
174
+ end
175
+
176
+ @dbh.convert_types = true
177
+
178
+ assert_nothing_raised do
179
+ @sth = @dbh.prepare("select * from names order by age")
180
+ assert(@sth.convert_types)
181
+ @sth.convert_types = false
182
+ @sth.execute
183
+ assert_equal(
184
+ [
185
+ ["Joe", "19"],
186
+ ["Bob", "21"],
187
+ ["Jim", "30"],
188
+ ], @sth.fetch_all
189
+ )
190
+ @sth.finish
191
+ end
192
+ rescue Exception => e
193
+ DBI.convert_types = true
194
+ @sth.finish
195
+ @dbh.disconnect
196
+ set_base_dbh
197
+ raise e
198
+ end
199
+
200
+ def test_null
201
+ assert_nothing_raised do
202
+ @sth = @dbh.prepare('insert into names (name, age) values (?, ?)')
203
+ @sth.execute("'NULL'", 201)
204
+ @sth.execute(nil, 202)
205
+ @sth.execute("NULL", 203)
206
+ @sth.finish
207
+ end
208
+
209
+ assert_nothing_raised do
210
+ @sth = @dbh.prepare('select * from names where age > 200 order by age')
211
+ @sth.execute
212
+ assert_equal(["'NULL'", 201], @sth.fetch)
213
+ assert_equal([nil, 202], @sth.fetch)
214
+ assert_equal(["NULL", 203], @sth.fetch)
215
+ @sth.finish
216
+ end
217
+ end
218
+
219
+ def test_time
220
+ @sth = nil
221
+ t = nil
222
+ assert_nothing_raised do
223
+ @sth = @dbh.prepare("insert into time_test (mytime) values (?)")
224
+ t = Time.now
225
+ @sth.execute(t)
226
+ @sth.finish
227
+ end
228
+
229
+ assert_nothing_raised do
230
+ @sth = @dbh.prepare("select * from time_test")
231
+ @sth.execute
232
+ row = @sth.fetch
233
+ assert_kind_of DateTime, row[0]
234
+ assert_equal t.hour, row[0].hour
235
+ assert_equal t.min, row[0].min
236
+ assert_equal t.sec, row[0].sec
237
+ @sth.finish
238
+ end
239
+ end
240
+
241
+ def test_timestamp
242
+ @sth = nil
243
+ # We omit fractional second testing here -- timestamp precision
244
+ # is a very slippery, dependent on driver and driver version.
245
+ t = DBI::Timestamp.new(2008, 3, 8, 10, 39, 1)
246
+ assert_nothing_raised do
247
+ @sth = @dbh.prepare("insert into timestamp_test (mytimestamp) values (?)")
248
+ @sth.execute(t)
249
+ @sth.finish
250
+ end
251
+
252
+ assert_nothing_raised do
253
+ @sth = @dbh.prepare("select * from timestamp_test")
254
+ @sth.execute
255
+ row = @sth.fetch
256
+ assert_kind_of DateTime, row[0]
257
+ assert_equal t.year, row[0].year
258
+ assert_equal t.month, row[0].month
259
+ assert_equal t.day, row[0].day
260
+ assert_equal t.hour, row[0].hour
261
+ assert_equal t.min, row[0].min
262
+ assert_equal t.sec, row[0].sec
263
+ # omit fractional tests
264
+ @sth.finish
265
+ end
266
+ end
267
+
268
+ def test_boolean_return
269
+ @sth = nil
270
+
271
+ unless dbtype == "odbc" # ODBC has no boolean type
272
+ assert_nothing_raised do
273
+ @sth = @dbh.prepare("insert into boolean_test (num, mybool) values (?, ?)")
274
+ @sth.execute(1, true)
275
+ @sth.execute(2, false)
276
+ @sth.finish
277
+ end
278
+
279
+ assert_nothing_raised do
280
+ @sth = @dbh.prepare("select * from boolean_test order by num")
281
+ @sth.execute
282
+
283
+ pairs = @sth.fetch_all
284
+
285
+ assert_equal(
286
+ [
287
+ [1, true],
288
+ [2, false],
289
+ ], pairs
290
+ )
291
+
292
+ @sth.finish
293
+ end
294
+ end
295
+ end
296
+ end