ydbd-pg 0.5.1

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,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