rails-dbd-mysql 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,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