rails-dbd-mysql 0.1.0

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,281 @@
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
+ # just to be sure..
81
+ assert_nothing_raised do
82
+ @sth = @dbh.prepare("select name, age from names order by age")
83
+ @sth.execute
84
+ @sth.bind_coltype(2, DBI::Type::Float)
85
+ @sth.fetch_all.collect { |x| assert_kind_of(Float, x[1]) }
86
+ @sth.finish
87
+ end
88
+
89
+ # now, let's check some failure cases
90
+ @sth = @dbh.prepare("select name, age from names order by age")
91
+
92
+ # can't bind_coltype before execute
93
+ assert_raises(DBI::InterfaceError) { @sth.bind_coltype(1, DBI::Type::Float) }
94
+ # can't index < 1
95
+ assert_raises(DBI::InterfaceError) { @sth.bind_coltype(0, DBI::Type::Float) }
96
+ end
97
+
98
+ def test_noconv
99
+ # XXX this test will fail the whole test suite miserably if it fails at any point.
100
+ assert(DBI.convert_types)
101
+
102
+ DBI.convert_types = false
103
+ @sth.finish rescue nil
104
+ @dbh.disconnect
105
+ set_base_dbh
106
+
107
+ assert(!@dbh.convert_types)
108
+
109
+ assert_nothing_raised do
110
+ @sth = @dbh.prepare("select * from names order by age")
111
+ assert(!@sth.convert_types)
112
+ @sth.execute
113
+ assert_equal(
114
+ [
115
+ ["Joe", "19"],
116
+ ["Bob", "21"],
117
+ ["Jim", "30"],
118
+ ], @sth.fetch_all
119
+ )
120
+ @sth.finish
121
+ end
122
+
123
+ DBI.convert_types = true
124
+ @sth.finish rescue nil
125
+ @dbh.disconnect
126
+ set_base_dbh
127
+
128
+ assert(DBI.convert_types)
129
+ assert(@dbh.convert_types)
130
+
131
+ assert_nothing_raised do
132
+ @sth = @dbh.prepare("select * from names order by age")
133
+ assert(@sth.convert_types)
134
+ @sth.execute
135
+ assert_equal(
136
+ [
137
+ ["Joe", 19],
138
+ ["Bob", 21],
139
+ ["Jim", 30],
140
+ ], @sth.fetch_all
141
+ )
142
+ @sth.finish
143
+ end
144
+
145
+ @dbh.convert_types = false
146
+
147
+ assert_nothing_raised do
148
+ @sth = @dbh.prepare("select * from names order by age")
149
+ assert(!@sth.convert_types)
150
+ @sth.execute
151
+ assert_equal(
152
+ [
153
+ ["Joe", "19"],
154
+ ["Bob", "21"],
155
+ ["Jim", "30"],
156
+ ], @sth.fetch_all
157
+ )
158
+ @sth.finish
159
+ end
160
+
161
+ @dbh.convert_types = true
162
+
163
+ assert_nothing_raised do
164
+ @sth = @dbh.prepare("select * from names order by age")
165
+ assert(@sth.convert_types)
166
+ @sth.convert_types = false
167
+ @sth.execute
168
+ assert_equal(
169
+ [
170
+ ["Joe", "19"],
171
+ ["Bob", "21"],
172
+ ["Jim", "30"],
173
+ ], @sth.fetch_all
174
+ )
175
+ @sth.finish
176
+ end
177
+ rescue Exception => e
178
+ DBI.convert_types = true
179
+ @sth.finish
180
+ @dbh.disconnect
181
+ set_base_dbh
182
+ raise e
183
+ end
184
+
185
+ def test_null
186
+ assert_nothing_raised do
187
+ @sth = @dbh.prepare('insert into names (name, age) values (?, ?)')
188
+ @sth.execute("'NULL'", 201)
189
+ @sth.execute(nil, 202)
190
+ @sth.execute("NULL", 203)
191
+ @sth.finish
192
+ end
193
+
194
+ assert_nothing_raised do
195
+ @sth = @dbh.prepare('select * from names where age > 200 order by age')
196
+ @sth.execute
197
+ assert_equal(["'NULL'", 201], @sth.fetch)
198
+ assert_equal([nil, 202], @sth.fetch)
199
+ assert_equal(["NULL", 203], @sth.fetch)
200
+ @sth.finish
201
+ end
202
+ end
203
+
204
+ def test_time
205
+ @sth = nil
206
+ t = nil
207
+ assert_nothing_raised do
208
+ @sth = @dbh.prepare("insert into time_test (mytime) values (?)")
209
+ t = Time.now
210
+ @sth.execute(t)
211
+ @sth.finish
212
+ end
213
+
214
+ assert_nothing_raised do
215
+ @sth = @dbh.prepare("select * from time_test")
216
+ @sth.execute
217
+ row = @sth.fetch
218
+ assert_kind_of DateTime, row[0]
219
+ assert_equal t.hour, row[0].hour
220
+ assert_equal t.min, row[0].min
221
+ assert_equal t.sec, row[0].sec
222
+ @sth.finish
223
+ end
224
+ end
225
+
226
+ def test_timestamp
227
+ @sth = nil
228
+ # We omit fractional second testing here -- timestamp precision
229
+ # is a very slippery, dependent on driver and driver version.
230
+ t = DBI::Timestamp.new(2008, 3, 8, 10, 39, 1)
231
+ assert_nothing_raised do
232
+ @sth = @dbh.prepare("insert into timestamp_test (mytimestamp) values (?)")
233
+ @sth.execute(t)
234
+ @sth.finish
235
+ end
236
+
237
+ assert_nothing_raised do
238
+ @sth = @dbh.prepare("select * from timestamp_test")
239
+ @sth.execute
240
+ row = @sth.fetch
241
+ assert_kind_of DateTime, row[0]
242
+ assert_equal t.year, row[0].year
243
+ assert_equal t.month, row[0].month
244
+ assert_equal t.day, row[0].day
245
+ assert_equal t.hour, row[0].hour
246
+ assert_equal t.min, row[0].min
247
+ assert_equal t.sec, row[0].sec
248
+ # omit fractional tests
249
+ @sth.finish
250
+ end
251
+ end
252
+
253
+ def test_boolean_return
254
+ @sth = nil
255
+
256
+ unless dbtype == "odbc" # ODBC has no boolean type
257
+ assert_nothing_raised do
258
+ @sth = @dbh.prepare("insert into boolean_test (num, mybool) values (?, ?)")
259
+ @sth.execute(1, true)
260
+ @sth.execute(2, false)
261
+ @sth.finish
262
+ end
263
+
264
+ assert_nothing_raised do
265
+ @sth = @dbh.prepare("select * from boolean_test order by num")
266
+ @sth.execute
267
+
268
+ pairs = @sth.fetch_all
269
+
270
+ assert_equal(
271
+ [
272
+ [1, true],
273
+ [2, false],
274
+ ], pairs
275
+ )
276
+
277
+ @sth.finish
278
+ end
279
+ end
280
+ end
281
+ end