ironruby-dbi 0.1.0

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