ydbi 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (122) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +6 -0
  3. data/ChangeLog +3699 -0
  4. data/Gemfile +4 -0
  5. data/LICENSE +25 -0
  6. data/Rakefile +8 -0
  7. data/TODO +44 -0
  8. data/bench/bench.rb +79 -0
  9. data/bin/dbi +518 -0
  10. data/bin/test_broken_dbi +37 -0
  11. data/build/Rakefile.dbi.rb +60 -0
  12. data/build/rake_task_lib.rb +187 -0
  13. data/doc/DBD_SPEC.rdoc +88 -0
  14. data/doc/DBI_SPEC.rdoc +157 -0
  15. data/doc/homepage/contact.html +62 -0
  16. data/doc/homepage/development.html +124 -0
  17. data/doc/homepage/index.html +83 -0
  18. data/doc/homepage/ruby-dbi.css +91 -0
  19. data/examples/test1.pl +39 -0
  20. data/examples/test1.rb +20 -0
  21. data/examples/xmltest.rb +8 -0
  22. data/lib/dbd/Mysql.rb +137 -0
  23. data/lib/dbd/ODBC.rb +89 -0
  24. data/lib/dbd/Pg.rb +188 -0
  25. data/lib/dbd/SQLite.rb +97 -0
  26. data/lib/dbd/SQLite3.rb +124 -0
  27. data/lib/dbd/mysql/database.rb +405 -0
  28. data/lib/dbd/mysql/driver.rb +125 -0
  29. data/lib/dbd/mysql/statement.rb +188 -0
  30. data/lib/dbd/odbc/database.rb +128 -0
  31. data/lib/dbd/odbc/driver.rb +38 -0
  32. data/lib/dbd/odbc/statement.rb +137 -0
  33. data/lib/dbd/pg/database.rb +516 -0
  34. data/lib/dbd/pg/exec.rb +47 -0
  35. data/lib/dbd/pg/statement.rb +160 -0
  36. data/lib/dbd/pg/tuples.rb +121 -0
  37. data/lib/dbd/pg/type.rb +209 -0
  38. data/lib/dbd/sqlite/database.rb +151 -0
  39. data/lib/dbd/sqlite/statement.rb +125 -0
  40. data/lib/dbd/sqlite3/database.rb +201 -0
  41. data/lib/dbd/sqlite3/statement.rb +78 -0
  42. data/lib/dbi.rb +336 -0
  43. data/lib/dbi/base_classes.rb +12 -0
  44. data/lib/dbi/base_classes/database.rb +135 -0
  45. data/lib/dbi/base_classes/driver.rb +47 -0
  46. data/lib/dbi/base_classes/statement.rb +171 -0
  47. data/lib/dbi/binary.rb +25 -0
  48. data/lib/dbi/columninfo.rb +107 -0
  49. data/lib/dbi/exceptions.rb +65 -0
  50. data/lib/dbi/handles.rb +49 -0
  51. data/lib/dbi/handles/database.rb +241 -0
  52. data/lib/dbi/handles/driver.rb +60 -0
  53. data/lib/dbi/handles/statement.rb +408 -0
  54. data/lib/dbi/row.rb +269 -0
  55. data/lib/dbi/sql.rb +22 -0
  56. data/lib/dbi/sql/preparedstatement.rb +115 -0
  57. data/lib/dbi/sql_type_constants.rb +75 -0
  58. data/lib/dbi/trace.rb +91 -0
  59. data/lib/dbi/types.rb +218 -0
  60. data/lib/dbi/typeutil.rb +109 -0
  61. data/lib/dbi/utils.rb +60 -0
  62. data/lib/dbi/utils/date.rb +59 -0
  63. data/lib/dbi/utils/tableformatter.rb +112 -0
  64. data/lib/dbi/utils/time.rb +52 -0
  65. data/lib/dbi/utils/timestamp.rb +96 -0
  66. data/lib/dbi/utils/xmlformatter.rb +73 -0
  67. data/lib/dbi/version.rb +3 -0
  68. data/prototypes/types2.rb +237 -0
  69. data/readme.md +274 -0
  70. data/setup.rb +1585 -0
  71. data/test/DBD_TESTS +50 -0
  72. data/test/TESTING +16 -0
  73. data/test/dbd/general/test_database.rb +206 -0
  74. data/test/dbd/general/test_statement.rb +326 -0
  75. data/test/dbd/general/test_types.rb +296 -0
  76. data/test/dbd/mysql/base.rb +26 -0
  77. data/test/dbd/mysql/down.sql +19 -0
  78. data/test/dbd/mysql/test_blob.rb +18 -0
  79. data/test/dbd/mysql/test_new_methods.rb +7 -0
  80. data/test/dbd/mysql/test_patches.rb +111 -0
  81. data/test/dbd/mysql/up.sql +28 -0
  82. data/test/dbd/odbc/base.rb +30 -0
  83. data/test/dbd/odbc/down.sql +19 -0
  84. data/test/dbd/odbc/test_new_methods.rb +12 -0
  85. data/test/dbd/odbc/test_ping.rb +10 -0
  86. data/test/dbd/odbc/test_statement.rb +44 -0
  87. data/test/dbd/odbc/test_transactions.rb +58 -0
  88. data/test/dbd/odbc/up.sql +33 -0
  89. data/test/dbd/postgresql/base.rb +31 -0
  90. data/test/dbd/postgresql/down.sql +31 -0
  91. data/test/dbd/postgresql/test_arrays.rb +179 -0
  92. data/test/dbd/postgresql/test_async.rb +121 -0
  93. data/test/dbd/postgresql/test_blob.rb +36 -0
  94. data/test/dbd/postgresql/test_bytea.rb +87 -0
  95. data/test/dbd/postgresql/test_ping.rb +10 -0
  96. data/test/dbd/postgresql/test_timestamp.rb +77 -0
  97. data/test/dbd/postgresql/test_transactions.rb +58 -0
  98. data/test/dbd/postgresql/testdbipg.rb +307 -0
  99. data/test/dbd/postgresql/up.sql +60 -0
  100. data/test/dbd/sqlite/base.rb +32 -0
  101. data/test/dbd/sqlite/test_database.rb +30 -0
  102. data/test/dbd/sqlite/test_driver.rb +68 -0
  103. data/test/dbd/sqlite/test_statement.rb +112 -0
  104. data/test/dbd/sqlite/up.sql +25 -0
  105. data/test/dbd/sqlite3/base.rb +32 -0
  106. data/test/dbd/sqlite3/test_database.rb +77 -0
  107. data/test/dbd/sqlite3/test_driver.rb +67 -0
  108. data/test/dbd/sqlite3/test_statement.rb +88 -0
  109. data/test/dbd/sqlite3/up.sql +33 -0
  110. data/test/dbi/tc_columninfo.rb +94 -0
  111. data/test/dbi/tc_date.rb +88 -0
  112. data/test/dbi/tc_dbi.rb +184 -0
  113. data/test/dbi/tc_row.rb +256 -0
  114. data/test/dbi/tc_sqlbind.rb +168 -0
  115. data/test/dbi/tc_statementhandle.rb +29 -0
  116. data/test/dbi/tc_time.rb +77 -0
  117. data/test/dbi/tc_timestamp.rb +142 -0
  118. data/test/dbi/tc_types.rb +268 -0
  119. data/test/ts_dbd.rb +131 -0
  120. data/test/ts_dbi.rb +16 -0
  121. data/ydbi.gemspec +24 -0
  122. metadata +224 -0
@@ -0,0 +1,256 @@
1
+ ######################################################################
2
+ # tc_row.rb
3
+ #
4
+ # Test case for the DBI::Row class.
5
+ ######################################################################
6
+ $LOAD_PATH.unshift(Dir.pwd)
7
+ $LOAD_PATH.unshift(File.dirname(Dir.pwd))
8
+ $LOAD_PATH.unshift("../../lib")
9
+ $LOAD_PATH.unshift("../../lib/dbi")
10
+ $LOAD_PATH.unshift("lib")
11
+
12
+ require 'test/unit'
13
+ require 'dbi'
14
+
15
+ class TC_DBI_Row < Test::Unit::TestCase
16
+ def setup
17
+ @data = %w/Daniel Berger 36/
18
+ @cols = %w/first last age/
19
+ @coltypes = [DBI::Type::Varchar, DBI::Type::Varchar, DBI::Type::Integer]
20
+ @row = DBI::Row.new(@cols, @coltypes, @data.clone)
21
+ @row_noconv = DBI::Row.new(@cols, @coltypes, @data.clone, false)
22
+ end
23
+
24
+ def teardown
25
+ @data = nil
26
+ @cols = nil
27
+ @row = nil
28
+ end
29
+
30
+ def test_row_multiassign # this should only be an issue in 1.8.7 and up, if at all.
31
+ first, last, age = @row
32
+ assert_equal("Daniel", first)
33
+ assert_equal("Berger", last)
34
+ assert_equal(36, age)
35
+ end
36
+
37
+ def test_row_noconv
38
+ assert_nothing_raised do
39
+ assert_equal(
40
+ [
41
+ 'Daniel',
42
+ 'Berger',
43
+ 36
44
+ ], @row
45
+ )
46
+ assert_equal(@data, @row_noconv)
47
+ end
48
+ end
49
+
50
+ # Ensure that constructor only allows Integers or Arrays (or nil)
51
+ def test_row_constructor
52
+ assert_nothing_raised{ DBI::Row.new(@cols, @coltypes) }
53
+ assert_nothing_raised{ DBI::Row.new(@cols, @coltypes, 1) }
54
+ assert_nothing_raised{ DBI::Row.new(@cols, @coltypes, nil) }
55
+ assert_nothing_raised{ DBI::Row.new(@cols, @coltypes, [1,2,3])}
56
+ assert_raises(ArgumentError){ DBI::Row.new }
57
+ assert_raises(ArgumentError){ DBI::Row.new(@cols) }
58
+ assert_raises(TypeError){ DBI::Row.new(@cols, @coltypes, {}) }
59
+ end
60
+
61
+ # Test added to ensure that Row#at is equivalent to Row#by_index. When the
62
+ # latter method is (hopefully) removed, this test can be removed as well.
63
+ def test_at
64
+ assert_respond_to(@row, :at)
65
+ assert_equal(@data[0].to_s, @row.at(0).to_s)
66
+ assert_equal(@data[1].to_s, @row.at(1).to_s)
67
+ assert_equal(@data[2].to_s, @row.at(2).to_s)
68
+ assert_equal(@data[99].to_s, @row.at(99).to_s)
69
+ end
70
+
71
+ # Should respond to Array and Enumerable methods
72
+ def test_row_delegate
73
+ assert_respond_to(@row, :length)
74
+ assert_respond_to(@row, :each)
75
+ assert_respond_to(@row, :grep)
76
+ end
77
+
78
+ def test_row_length
79
+ assert_equal(3, @row.length)
80
+ assert_equal(3, DBI::Row.new(@cols, @coltypes).length)
81
+ end
82
+
83
+ def test_row_data_by_index
84
+ assert_equal(@data[0], @row.by_index(0))
85
+ assert_equal(@data[1], @row.by_index(1))
86
+ assert_equal(@data[2], @row.by_index(2).to_s)
87
+ assert_nil(@row.by_index(3))
88
+ end
89
+
90
+ def test_row_data_by_field
91
+ assert_equal @data[0], @row.by_field('first')
92
+ assert_equal @data[1], @row.by_field('last')
93
+ assert_equal @data[2], @row.by_field('age').to_s
94
+ assert_equal nil, @row.by_field('unknown')
95
+ end
96
+
97
+ def test_row_set_values
98
+ assert_respond_to(@row, :set_values)
99
+ assert_nothing_raised{ @row.set_values(["John", "Doe", 23]) }
100
+ assert_equal("John", @row.by_index(0))
101
+ assert_equal("Doe", @row.by_index(1))
102
+ assert_equal(23, @row.by_index(2))
103
+ end
104
+
105
+ def test_row_to_h
106
+ assert_respond_to(@row, :to_h)
107
+ assert_nothing_raised{ @row.to_h }
108
+ assert_kind_of(Hash, @row.to_h)
109
+ assert_equal({"first"=>"Daniel", "last"=>"Berger", "age"=>36}, @row.to_h)
110
+ end
111
+
112
+ def test_row_column_names
113
+ assert_respond_to(@row, :column_names)
114
+ assert_nothing_raised{ @row.column_names }
115
+ assert_kind_of(Array, @row.column_names)
116
+ assert_equal(["first", "last", "age"], @row.column_names)
117
+ end
118
+
119
+ # An alias for column_names
120
+ def test_row_field_names
121
+ assert_respond_to(@row, :column_names)
122
+ assert_nothing_raised{ @row.column_names }
123
+ assert_kind_of(Array, @row.column_names)
124
+ assert_equal(["first", "last", "age"], @row.column_names)
125
+ end
126
+
127
+ def test_indexing_numeric
128
+ assert_equal(@data[0], @row[0])
129
+ assert_equal(@data[1], @row[1])
130
+ assert_equal(@data[2], @row[2].to_s)
131
+ end
132
+
133
+ def test_indexing_string_or_symbol
134
+ assert_equal(@data[0], @row['first'])
135
+ assert_equal(@data[0], @row[:first])
136
+ assert_equal(@data[1], @row['last'])
137
+ assert_equal(@data[2], @row['age'].to_s)
138
+ assert_equal(nil, @row['unknown'])
139
+ end
140
+
141
+ def test_indexing_regexp
142
+ assert_equal(["Daniel"], @row[/first/])
143
+ assert_equal(["Berger"], @row[/last/])
144
+ assert_equal([36], @row[/age/])
145
+ assert_equal(["Daniel", "Berger"], @row[/first|last/])
146
+ assert_equal([], @row[/bogus/])
147
+ end
148
+
149
+ def test_indexing_array
150
+ assert_equal(["Daniel"], @row[[0]])
151
+ assert_equal(["Daniel"], @row[["first"]])
152
+ assert_equal(["Berger"], @row[[1]])
153
+ assert_equal([36], @row[[2]])
154
+ assert_equal([nil], @row[[3]])
155
+ assert_equal(["Daniel", 36], @row[[0,2]])
156
+ assert_equal(["Daniel", 36], @row[[0,:age]])
157
+ end
158
+
159
+ def test_indexing_range
160
+ assert_equal(["Daniel","Berger"], @row[0..1])
161
+ assert_equal(["Berger",36], @row[1..2])
162
+ assert_equal(["Berger",36], @row[1..99])
163
+ assert_equal(nil, @row[90..100])
164
+ end
165
+
166
+ # The two argument reference should behave like the second form of Array#[]
167
+ def test_indexing_two_args
168
+ assert_equal([], @row[0,0])
169
+ assert_equal(["Daniel"], @row[0,1])
170
+ assert_equal(["Daniel", "Berger"], @row[0,2])
171
+ assert_equal(["Daniel", "Berger", 36], @row[0,3])
172
+ assert_equal(["Daniel", "Berger", 36], @row[0,99])
173
+ end
174
+
175
+ def test_indexing_multiple_args
176
+ assert_equal(["Berger", 36, "Daniel"], @row[:last, :age, :first])
177
+ assert_equal(["Berger", 36, "Daniel"], @row[1, :age, :first])
178
+ assert_equal(["Berger", 36, "Daniel"], @row[1, 2, :first])
179
+ assert_equal(["Berger", 36, "Daniel"], @row[1, 2, 0])
180
+ assert_equal(["Berger", 36, "Daniel", nil], @row[1, 2, 0, 9])
181
+ assert_equal(["Berger", 36, "Daniel", nil], @row[1, 2, 0, :bogus])
182
+ end
183
+
184
+ def test_indexing_assignment
185
+ assert_nothing_raised{ @row[0] = "kirk" }
186
+ assert_equal("kirk", @row[0])
187
+
188
+ assert_nothing_raised{ @row[:age] = 29 }
189
+ assert_equal(29, @row[:age])
190
+
191
+ assert_nothing_raised{ @row[1,2] = "francis" }
192
+ assert_equal("francis", @row[:last])
193
+ assert_nil(@row[:age])
194
+ end
195
+
196
+ def test_clone_with
197
+ another_row = @row.clone_with(["Jane", "Smith", 33])
198
+ assert_kind_of(DBI::Row, another_row)
199
+ assert_equal "Jane", another_row.by_index(0)
200
+ assert_equal "Smith", another_row.by_index(1)
201
+ assert_equal 33, another_row.by_index(2)
202
+ assert(@row != another_row)
203
+ end
204
+
205
+ def test_iteration
206
+ expect = @data.clone
207
+ @row.each { |value|
208
+ assert_equal(expect.shift, value.to_s)
209
+ }
210
+ assert_equal([], expect)
211
+ @row.collect { |value| "Field=#{value}" }
212
+ end
213
+
214
+ def test_row_each_with_name
215
+ assert_respond_to(@row, :each_with_name)
216
+ assert_nothing_raised{ @row.each_with_name{ } }
217
+
218
+ @row.each_with_name{ |value, column|
219
+ assert(@cols.include?(column))
220
+ assert(@data.include?(value.to_s))
221
+ }
222
+ end
223
+
224
+ def test_to_a
225
+ assert_respond_to(@row, :to_a)
226
+ assert_equal(@data, DBI::Row.new(@cols, @coltypes, @data).to_a.collect { |x| x.to_s })
227
+ end
228
+
229
+ def test_dup_clone
230
+ dupped = nil
231
+ cloned = nil
232
+
233
+ assert_nothing_raised{ dupped = @row.dup }
234
+ assert_nothing_raised{ cloned = @row.clone }
235
+ assert_nothing_raised{ @row.set_values(["Bill", "Jones", 16])}
236
+
237
+ assert_equal(@data, dupped.to_a.collect { |x| x.to_s })
238
+ assert_equal(@data, cloned.to_a.collect { |x| x.to_s })
239
+
240
+ assert(dupped.object_id != @row.object_id)
241
+ assert(cloned.object_id != @row.object_id)
242
+ end
243
+
244
+ def test_dup_ruby18
245
+ res = []
246
+ r = DBI::Row.new(["col1","col2"],[nil,nil])
247
+
248
+ [["one",1],["two",2],["three",3]].each do |x,y|
249
+ r["col1"] = x
250
+ r["col2"] = y
251
+ res << r.dup
252
+ end
253
+
254
+ assert_equal res, [["one", 1], ["two", 2], ["three", 3]]
255
+ end
256
+ end
@@ -0,0 +1,168 @@
1
+ $: << 'lib'
2
+ require 'test/unit'
3
+ require "dbi/sql"
4
+
5
+ # ====================================================================
6
+ class TestSqlBind < Test::Unit::TestCase
7
+
8
+ def bind(quoter, sql, args)
9
+ ps = DBI::SQL::PreparedStatement.new(quoter, sql)
10
+ ps.bind(DBI::Utils::ConvParam.conv_param('default', *args))
11
+ end
12
+
13
+ def test_one
14
+ assert_equal "10", bind(self, "?", [10])
15
+ assert_equal "'hi'", bind(self, "?", ["hi"])
16
+ assert_equal "I 'don''t' know", bind(self, "I ? know", ["don't"])
17
+ end
18
+
19
+ def test_many
20
+ assert_equal "WHERE age=12 AND name='Jim'",
21
+ bind(self, "WHERE age=? AND name=?", [12, 'Jim'])
22
+ end
23
+
24
+ def test_too_many
25
+ assert_raises (RuntimeError) {
26
+ bind(self, "age=?", [10, 11])
27
+ }
28
+ end
29
+
30
+ def test_too_few
31
+ assert_raises (RuntimeError) {
32
+ bind(self, "age in (?, ?, ?)", [10, 11])
33
+ }
34
+ end
35
+
36
+ def test_embedded_questions
37
+ assert_equal "10 ? 11", bind(self, "? ?? ?", [10, 11])
38
+ assert_equal "????", bind(self, "????????", [])
39
+ end
40
+
41
+ def test_questions_in_param
42
+ assert_equal "WHERE c='connected?'",
43
+ bind(self, "WHERE c=?", ["connected?"])
44
+
45
+ assert_equal "WHERE c='connected?' AND d='???'",
46
+ bind(self, "WHERE c=? AND d=?", ["connected?", "???"])
47
+ end
48
+
49
+ def test_questions_in_quotes
50
+ assert_equal "WHERE c='connected?' AND d=10",
51
+ bind(self, "WHERE c='connected?' AND d=?", [10])
52
+ end
53
+
54
+ def test_comment_dan
55
+ sql = %{--Dan's query\n--random comment\nselect column1, column2\nfrom table1\nwhere somevalue = ?}
56
+ res = %{--Dan's query\n--random comment\nselect column1, column2\nfrom table1\nwhere somevalue = 10}
57
+ assert_equal res, bind(self, sql, [10])
58
+ end
59
+
60
+ def test_minus_bug
61
+ sql = "SELECT 1 - 3"
62
+ res = "SELECT 1 - 3"
63
+ assert_equal res, bind(self, sql, [])
64
+ end
65
+
66
+ def test_minus2
67
+ sql = "SELECT * from test --Dan's query"
68
+ assert_equal sql, bind(self, sql, [])
69
+ end
70
+
71
+ def test_slash
72
+ sql = "SELECT 5 / 4"
73
+ res = "SELECT 5 / 4"
74
+ assert_equal res, bind(self, sql, [])
75
+ end
76
+
77
+ def test_much
78
+ sql = <<ENDSQL
79
+ SELECT s.id, cwajga_magic_number((cwajga_product(r.rating) ^ (1 / 1)), MAX(lastplay.lastheard), 5) as magic
80
+ INTO TEMP magic_order
81
+ FROM song AS s LEFT OUTER JOIN rating AS r ON s.id = r.song LEFT OUTER JOIN last play ON lastplay.song = s.id
82
+ WHERE r.name ILIKE 'omega697'
83
+ GROUP BY s.id;
84
+
85
+ SELECT SUM(magic) as total INTO TEMP magic_tot FROM magic_order;
86
+
87
+ SELECT id, 100.0*magic/total as percent
88
+ FROM magic_order, magic_tot
89
+ order by percent;
90
+ ENDSQL
91
+ res = sql
92
+ assert_equal res, bind(self, sql, [])
93
+ end
94
+
95
+ def test_nested_insert
96
+ sql = "insert into logins (user_id, hostmask) values ((select id from users where username = ?), ?)"
97
+ res = sql.sub(/\?/, "1")
98
+ res.sub!(/\?/, "'foo@bar'")
99
+ assert_equal res, bind(self, sql, [1, "foo@bar"])
100
+ end
101
+
102
+ end
103
+
104
+ ######################################################################
105
+ class TestLex < Test::Unit::TestCase
106
+
107
+ def tokens(sql)
108
+ DBI::SQL::PreparedStatement.tokens(sql)
109
+ end
110
+
111
+ def test_non_strings
112
+ assert_equal ['This is _a t35t'],
113
+ tokens("This is _a t35t")
114
+ end
115
+
116
+ def test_simple_strings
117
+ assert_equal ["hi ", "'hello world'"],
118
+ tokens("hi 'hello world'")
119
+ assert_equal ["c = ", "''"],
120
+ tokens("c = ''")
121
+ end
122
+
123
+ def test_strings_with_quotes
124
+ assert_equal ["hi ", "'''lo world'"],
125
+ tokens("hi '''lo world'")
126
+ assert_equal ['a', "''''", 'b'],
127
+ tokens("a''''b")
128
+ end
129
+
130
+ def test_strings_with_escaped_quotes
131
+ assert_equal ["hi ", "'don\\'t do that'"],
132
+ tokens("hi 'don\\'t do that'")
133
+ assert_equal ['a', "'\\''", 'b'],
134
+ tokens("a'\\''b")
135
+ end
136
+
137
+ def test_simple_dq_strings
138
+ assert_equal ["hi ", '"hello world"'],
139
+ tokens('hi "hello world"')
140
+ assert_equal ["c = ", '""'],
141
+ tokens('c = ""')
142
+ end
143
+
144
+ def test_dq_strings_with_quotes
145
+ assert_equal ["hi ", '"""lo world"'],
146
+ tokens('hi """lo world"')
147
+ assert_equal ['a', '""""', 'b'],
148
+ tokens('a""""b')
149
+ end
150
+
151
+ def test_dq_strings_with_escaped_quotes
152
+ assert_equal ["hi ", '"don\"t do that"'],
153
+ tokens('hi "don\"t do that"')
154
+ assert_equal ['a', '"\""', 'b'],
155
+ tokens('a"\""b')
156
+ end
157
+
158
+ def test_qmarks
159
+ assert_equal ["a = ", "?"],
160
+ tokens("a = ?")
161
+ assert_equal ["'?'", " = ", "?"],
162
+ tokens("'?' = ?")
163
+ assert_equal ["'?'", " = ", "??"],
164
+ tokens("'?' = ??")
165
+ end
166
+
167
+ end
168
+
@@ -0,0 +1,29 @@
1
+ $: << 'lib'
2
+ require 'test/unit'
3
+ require 'dbi'
4
+
5
+ class TC_DBI_StatementHandle < Test::Unit::TestCase
6
+ def test_fetch
7
+ mock_handle = 'any_object'
8
+ def mock_handle.cancel; end
9
+ def mock_handle.column_info; {}; end
10
+ def mock_handle.fetch; nil; end
11
+ sth = DBI::StatementHandle.new( mock_handle, true, true, false, true)
12
+
13
+ 10.times do
14
+ assert_nil sth.fetch
15
+ end
16
+
17
+ sth.raise_error = true
18
+
19
+ assert_raises(DBI::InterfaceError) do
20
+ sth.fetch
21
+ end
22
+
23
+ sth.raise_error = false
24
+
25
+ 10.times do
26
+ assert_nil sth.fetch
27
+ end
28
+ end
29
+ end