rails-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.
Files changed (45) hide show
  1. data/ChangeLog +3694 -0
  2. data/LICENSE +25 -0
  3. data/README +271 -0
  4. data/bin/dbi +518 -0
  5. data/bin/test_broken_dbi +37 -0
  6. data/build/Rakefile.dbi.rb +60 -0
  7. data/examples/test1.pl +39 -0
  8. data/examples/test1.rb +20 -0
  9. data/examples/xmltest.rb +8 -0
  10. data/lib/dbi/base_classes/database.rb +135 -0
  11. data/lib/dbi/base_classes/driver.rb +47 -0
  12. data/lib/dbi/base_classes/statement.rb +171 -0
  13. data/lib/dbi/base_classes.rb +12 -0
  14. data/lib/dbi/binary.rb +25 -0
  15. data/lib/dbi/columninfo.rb +107 -0
  16. data/lib/dbi/exceptions.rb +65 -0
  17. data/lib/dbi/handles/database.rb +241 -0
  18. data/lib/dbi/handles/driver.rb +60 -0
  19. data/lib/dbi/handles/statement.rb +408 -0
  20. data/lib/dbi/handles.rb +49 -0
  21. data/lib/dbi/row.rb +270 -0
  22. data/lib/dbi/sql/preparedstatement.rb +115 -0
  23. data/lib/dbi/sql.rb +22 -0
  24. data/lib/dbi/sql_type_constants.rb +75 -0
  25. data/lib/dbi/trace.rb +91 -0
  26. data/lib/dbi/types.rb +218 -0
  27. data/lib/dbi/typeutil.rb +109 -0
  28. data/lib/dbi/utils/date.rb +59 -0
  29. data/lib/dbi/utils/tableformatter.rb +112 -0
  30. data/lib/dbi/utils/time.rb +52 -0
  31. data/lib/dbi/utils/timestamp.rb +96 -0
  32. data/lib/dbi/utils/xmlformatter.rb +73 -0
  33. data/lib/dbi/utils.rb +60 -0
  34. data/lib/dbi.rb +337 -0
  35. data/test/dbi/tc_columninfo.rb +94 -0
  36. data/test/dbi/tc_date.rb +88 -0
  37. data/test/dbi/tc_dbi.rb +184 -0
  38. data/test/dbi/tc_row.rb +256 -0
  39. data/test/dbi/tc_sqlbind.rb +168 -0
  40. data/test/dbi/tc_statementhandle.rb +29 -0
  41. data/test/dbi/tc_time.rb +77 -0
  42. data/test/dbi/tc_timestamp.rb +142 -0
  43. data/test/dbi/tc_types.rb +268 -0
  44. data/test/ts_dbi.rb +15 -0
  45. metadata +132 -0
@@ -0,0 +1,73 @@
1
+ module DBI
2
+ module Utils
3
+ # Formats results in XML.
4
+ module XMLFormatter
5
+ # Generate XML for a row. The column names will surround the the values as tags.
6
+ #
7
+ # * +dbrow+: the array of the result row.
8
+ # * +rowtag+: the name of the tag that encapsulates a row.
9
+ # * +output+: Object that responds to `<<`.
10
+ #
11
+ def self.row(dbrow, rowtag="row", output=STDOUT)
12
+ #XMLFormatter.extended_row(dbrow, "row", [],
13
+ output << "<#{rowtag}>\n"
14
+ dbrow.each_with_name do |val, name|
15
+ output << " <#{name}>" + textconv(val) + "</#{name}>\n"
16
+ end
17
+ output << "</#{rowtag}>\n"
18
+ end
19
+
20
+ # good lord, what a mess.
21
+ #
22
+ # nil in cols_as_tag, means "all columns expect those listed in cols_in_row_tag"
23
+ # add_row_tag_attrs are additional attributes which are inserted into the row-tag
24
+ def self.extended_row(dbrow, rowtag="row", cols_in_row_tag=[], cols_as_tag=nil, add_row_tag_attrs={}, output=STDOUT)
25
+ if cols_as_tag.nil?
26
+ cols_as_tag = dbrow.column_names - cols_in_row_tag
27
+ end
28
+
29
+ output << "<#{rowtag}"
30
+ add_row_tag_attrs.each do |key, val|
31
+ # TODO: use textconv ? " substitution?
32
+ output << %{ #{key}="#{textconv(val)}"}
33
+ end
34
+ cols_in_row_tag.each do |key|
35
+ # TODO: use textconv ? " substitution?
36
+ output << %{ #{key}="#{dbrow[key]}"}
37
+ end
38
+ output << ">\n"
39
+
40
+ cols_as_tag.each do |key|
41
+ output << " <#{key}>" + textconv(dbrow[key]) + "</#{key}>\n"
42
+ end
43
+ output << "</#{rowtag}>\n"
44
+ end
45
+
46
+ # generate a full XML representation of the table.
47
+ #
48
+ # Arguments and output are similar to #row, with the exception of
49
+ # +roottag+, which is a container for the individual row tags.
50
+ #
51
+ def self.table(rows, roottag = "rows", rowtag = "row", output=STDOUT)
52
+ output << '<?xml version="1.0" encoding="UTF-8" ?>'
53
+ output << "\n<#{roottag}>\n"
54
+ rows.each do |row|
55
+ row(row, rowtag, output)
56
+ end
57
+ output << "</#{roottag}>\n"
58
+ end
59
+
60
+ class << self
61
+ private
62
+ # Your standard XML entity conversions.
63
+ def textconv(str)
64
+ str = str.to_s.gsub('&', "&#38;")
65
+ str = str.gsub('\'', "&#39;")
66
+ str = str.gsub('"', "&#34;")
67
+ str = str.gsub('<', "&#60;")
68
+ str.gsub('>', "&#62;")
69
+ end
70
+ end # class self
71
+ end # module XMLFormatter
72
+ end
73
+ end
data/lib/dbi/utils.rb ADDED
@@ -0,0 +1,60 @@
1
+ #
2
+ # $Id: utils.rb,v 1.5 2006/01/29 06:14:19 djberg96 Exp $
3
+ #
4
+
5
+ module DBI
6
+ #
7
+ # Utility classes and methods for use by both DBDs and consumers.
8
+ #
9
+ module Utils
10
+ #
11
+ # Given a block, returns the execution time for the block.
12
+ #
13
+ def self.measure
14
+ start = ::Time.now
15
+ yield
16
+ ::Time.now - start
17
+ end
18
+
19
+ #
20
+ # parse a string of the form "database=xxx;key=val;..."
21
+ # or database:host and return hash of key/value pairs
22
+ #
23
+ # Used in DBI.connect and offspring.
24
+ #
25
+ def self.parse_params(str)
26
+ # improved by John Gorman <jgorman@webbysoft.com>
27
+ params = str.split(";")
28
+ hash = {}
29
+ params.each do |param|
30
+ key, val = param.split("=")
31
+ hash[key] = val if key and val
32
+ end
33
+ if hash.empty?
34
+ database, host = str.split(":")
35
+ hash['database'] = database if database
36
+ hash['host'] = host if host
37
+ end
38
+ hash
39
+ end
40
+ end # module Utils
41
+ end # module DBI
42
+
43
+ #
44
+ # Type converter.
45
+ #
46
+ # FIXME this really needs to go into DBI::TypeUtil or similar
47
+ module DBI::Utils::ConvParam
48
+ #
49
+ # Wrapper to convert arrays of bound objects via DBI::TypeUtil#convert.
50
+ #
51
+ def self.conv_param(driver_name, *params)
52
+ params.collect { |param| DBI::TypeUtil.convert(driver_name, param) }
53
+ end
54
+ end
55
+
56
+ require 'dbi/utils/date'
57
+ require 'dbi/utils/time'
58
+ require 'dbi/utils/timestamp'
59
+ require 'dbi/utils/xmlformatter'
60
+ require 'dbi/utils/tableformatter'
data/lib/dbi.rb ADDED
@@ -0,0 +1,337 @@
1
+ $LOAD_PATH.unshift(File.dirname(__FILE__)) unless $LOAD_PATH.include?(File.dirname(__FILE__))
2
+ #
3
+ # DBI - Database Interface for Ruby. Please see the files README, DBI_SPEC,
4
+ # DBD_SPEC for more information.
5
+ #
6
+ module DBI; end
7
+ #--
8
+ # Ruby/DBI
9
+ #
10
+ # Copyright (c) 2001, 2002, 2003 Michael Neumann <mneumann@ntecs.de>
11
+ # Copyright (c) 2008 Erik Hollensbe <erik@hollensbe.org>
12
+ #
13
+ # All rights reserved.
14
+ #
15
+ # Redistribution and use in source and binary forms, with or without
16
+ # modification, are permitted provided that the following conditions
17
+ # are met:
18
+ # 1. Redistributions of source code must retain the above copyright
19
+ # notice, this list of conditions and the following disclaimer.
20
+ # 2. Redistributions in binary form must reproduce the above copyright
21
+ # notice, this list of conditions and the following disclaimer in the
22
+ # documentation and/or other materials provided with the distribution.
23
+ # 3. The name of the author may not be used to endorse or promote products
24
+ # derived from this software without specific prior written permission.
25
+ #
26
+ # THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
27
+ # INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
28
+ # AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
29
+ # THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
30
+ # EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
31
+ # PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
32
+ # OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
33
+ # WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
34
+ # OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
35
+ # ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36
+ #
37
+
38
+ begin
39
+ require "rubygems"
40
+ gem "deprecated", "= 2.0.1"
41
+ rescue LoadError
42
+ end
43
+
44
+ #
45
+ # NOTE see the end of the file for requires that live in the DBI namespace.
46
+ #
47
+
48
+ require "deprecated"
49
+ require "dbi/row"
50
+ require "dbi/utils"
51
+ require "dbi/sql"
52
+ require "dbi/columninfo"
53
+ require 'dbi/types'
54
+ require 'dbi/typeutil'
55
+ require 'dbi/sql_type_constants'
56
+ require 'dbi/exceptions'
57
+ require 'dbi/binary'
58
+ require 'dbi/handles'
59
+ require 'dbi/base_classes'
60
+ require "date"
61
+ require "thread"
62
+ require 'monitor'
63
+
64
+ class Class
65
+ # Given a Class, returns if the object's (another Class) ancestors contain
66
+ # that class.
67
+ def inherits_from?(klass)
68
+ self.ancestors.include?(klass)
69
+ end
70
+ end
71
+
72
+ Deprecate.set_action(
73
+ proc do |call|
74
+ klass, meth = call.split(/[#.]/)
75
+ klass = klass.split(/::/).inject(Module) { |a,x| a.const_get(x) }
76
+
77
+ case klass
78
+ when DBI::Date, DBI::Time, DBI::Timestamp
79
+ warn "DBI::Date/Time/Timestamp are deprecated and will eventually be removed."
80
+ end
81
+
82
+ if klass.inherits_from?(DBI::ColumnInfo)
83
+ warn "ColumnInfo methods that do not match a component are deprecated and will eventually be removed"
84
+ end
85
+
86
+ warn "You may change the result of calling deprecated code via Deprecate.set_action; Trace follows:"
87
+ warn caller[2..-1].join("\n")
88
+ end
89
+ )
90
+
91
+ #++
92
+ module DBI
93
+ VERSION = "0.4.5"
94
+
95
+ module DBD # :nodoc:
96
+ API_VERSION = "0.3"
97
+ end
98
+
99
+ # Module functions (of DBI)
100
+ DEFAULT_TRACE_MODE = 2
101
+ DEFAULT_TRACE_OUTPUT = STDERR
102
+
103
+ # TODO: Is using class variables within a module such a wise idea? - Dan B.
104
+ @@driver_map = Hash.new
105
+ @@driver_monitor = ::Monitor.new()
106
+ @@trace_mode = DEFAULT_TRACE_MODE
107
+ @@trace_output = DEFAULT_TRACE_OUTPUT
108
+ @@caseless_driver_name_map = nil
109
+ @@convert_types = true
110
+ @@last_connection = nil
111
+
112
+ # Return the last connection attempted.
113
+ def self.last_connection
114
+ @@last_connection
115
+ end
116
+
117
+ # Return the current status of type conversion at this level. This status
118
+ # will be propogated to any new DatabaseHandles created.
119
+ def self.convert_types
120
+ @@convert_types
121
+ end
122
+
123
+ # Set the current status of type conversion at this level. This status
124
+ # will be propogated to any new DatabaseHandles created.
125
+ def self.convert_types=(bool)
126
+ @@convert_types = bool
127
+ end
128
+
129
+ class << self
130
+
131
+ # Establish a database connection.
132
+ #
133
+ # Format goes as such: "dbi:Driver:database_conn_args"
134
+ #
135
+ # * "dbi" is the literal string "dbi". Case is unimportant.
136
+ # * "Driver" is the case-dependent name of your database driver class.
137
+ # The file "dbd/#{Driver}" will be required. If you are using rubygems to
138
+ # control your DBDs and DBI, you must make the gem's file path available
139
+ # via the "gem" command before this will work.
140
+ # * database_conn_args can be:
141
+ # * The database name.
142
+ # * A more complex key/value association (to indicate host, etc). This
143
+ # is driver dependent; you should consult your DBD documentation.
144
+ def connect(driver_url, user=nil, auth=nil, params=nil, &p)
145
+ dr, db_args = _get_full_driver(driver_url)
146
+ dh = dr[0] # driver-handle
147
+ dh.convert_types = @@convert_types
148
+ @@last_connection = dh.connect(db_args, user, auth, params, &p)
149
+ end
150
+
151
+ # Load a DBD and returns the DriverHandle object
152
+ def get_driver(driver_url) #:nodoc:
153
+ _get_full_driver(driver_url)[0][0] # return DriverHandle
154
+ end
155
+
156
+ # Extracts the db_args from driver_url and returns the correspondeing
157
+ # entry of the @@driver_map.
158
+ def _get_full_driver(driver_url) #:nodoc:
159
+ db_driver, db_args = parse_url(driver_url)
160
+ db_driver = load_driver(db_driver)
161
+ dr = @@driver_map[db_driver]
162
+ [dr, db_args]
163
+ end
164
+
165
+ #
166
+ # Enable tracing mode. Requires that 'dbi/trace' be required before it does anything.
167
+ #
168
+ # As of 0.4.0, this mode does not do anything either way, so this currently just
169
+ # throws an InterfaceError. This issue is expected to be resolved in the next release.
170
+ #
171
+ def trace(mode=nil, output=nil)
172
+ # FIXME trace
173
+ raise InterfaceError, "the trace module has been removed until it actually works."
174
+ @@trace_mode = mode || @@trace_mode || DBI::DEFAULT_TRACE_MODE
175
+ @@trace_output = output || @@trace_output || DBI::DEFAULT_TRACE_OUTPUT
176
+ end
177
+
178
+ #
179
+ # Return a list (of String) of the available drivers.
180
+ #
181
+ # NOTE:: This is non-functional for gem installations, due to the
182
+ # nature of how it currently works. A better solution for
183
+ # this will be provided in DBI 0.6.0.
184
+ def collect_drivers
185
+ drivers = { }
186
+ # FIXME rewrite this to leverage require and be more intelligent
187
+ path = File.join(File.dirname(__FILE__), "dbd", "*.rb")
188
+ Dir[path].each do |f|
189
+ if File.file?(f)
190
+ driver = File.basename(f, ".rb")
191
+ drivers[driver] = f
192
+ end
193
+ end
194
+
195
+ return drivers
196
+ end
197
+
198
+ # Returns a list (of String) of the currently available drivers on your system in
199
+ # 'dbi:driver:' format.
200
+ #
201
+ # This currently does not work for rubygems installations, please see
202
+ # DBI.collect_drivers for reasons.
203
+ def available_drivers
204
+ drivers = []
205
+ collect_drivers.each do |key, value|
206
+ drivers.push("dbi:#{key}:")
207
+ end
208
+ return drivers
209
+ end
210
+
211
+ # Attempt to collect the available data sources to the driver,
212
+ # specified in DBI.connect format.
213
+ #
214
+ # The result is heavily dependent on the driver's ability to enumerate
215
+ # these sources, and results will vary.
216
+ def data_sources(driver)
217
+ db_driver, = parse_url(driver)
218
+ db_driver = load_driver(db_driver)
219
+ dh = @@driver_map[db_driver][0]
220
+ dh.data_sources
221
+ end
222
+
223
+ #
224
+ # Attempt to disconnect all database handles. If a driver is provided,
225
+ # disconnections will happen under that scope. Otherwise, all loaded
226
+ # drivers (and their handles) will be attempted.
227
+ #
228
+ def disconnect_all( driver = nil )
229
+ if driver.nil?
230
+ @@driver_map.each {|k,v| v[0].disconnect_all}
231
+ else
232
+ db_driver, = parse_url(driver)
233
+ @@driver_map[db_driver][0].disconnect_all
234
+ end
235
+ end
236
+
237
+ private
238
+
239
+ # Given a driver name, locate and load the associated DBD package,
240
+ # generate a DriverHandle and return it.
241
+ def load_driver(driver_name)
242
+ @@driver_monitor.synchronize do
243
+ unless @@driver_map[driver_name]
244
+ dc = driver_name.downcase
245
+
246
+ # caseless look for drivers already loaded
247
+ found = @@driver_map.keys.find {|key| key.downcase == dc}
248
+ return found if found
249
+
250
+ begin
251
+ require "dbd/#{driver_name}"
252
+ rescue LoadError => e1
253
+ # see if you can find it in the path
254
+ unless @@caseless_driver_name_map
255
+ @@caseless_driver_name_map = { }
256
+ collect_drivers.each do |key, value|
257
+ @@caseless_driver_name_map[key.downcase] = value
258
+ end
259
+ end
260
+
261
+ begin
262
+ require @@caseless_driver_name_map[dc] if @@caseless_driver_name_map[dc]
263
+ rescue LoadError => e2
264
+ raise e1.class, "Could not find driver #{driver_name} or #{driver_name.downcase} (error: #{e1.message})"
265
+ end
266
+ end
267
+
268
+ # On a filesystem that is not case-sensitive (e.g., HFS+ on Mac OS X),
269
+ # the initial require attempt that loads the driver may succeed even
270
+ # though the lettercase of driver_name doesn't match the actual
271
+ # filename. If that happens, const_get will fail and it become
272
+ # necessary to look though the list of constants and look for a
273
+ # caseless match. The result of this match provides the constant
274
+ # with the proper lettercase -- which can be used to generate the
275
+ # driver handle.
276
+
277
+ dr = nil
278
+ dr_error = nil
279
+ begin
280
+ dr = DBI::DBD.const_get(driver_name.intern)
281
+ rescue NameError => dr_error
282
+ # caseless look for constants to find actual constant
283
+ dc = driver_name.downcase
284
+ found = DBI::DBD.constants.find { |e| e.downcase == dc }
285
+ dr = DBI::DBD.const_get(found.intern) unless found.nil?
286
+ end
287
+
288
+ # If dr is nil at this point, it means the underlying driver
289
+ # failed to load. This usually means it's not installed, but
290
+ # can fail for other reasons.
291
+ if dr.nil?
292
+ err = "Unable to load driver '#{driver_name}'"
293
+
294
+ if dr_error
295
+ err += " (underlying error: #{dr_error.message})"
296
+ else
297
+ err += " (BUG: could not determine underlying error)"
298
+ end
299
+
300
+ raise DBI::InterfaceError, err
301
+ end
302
+
303
+ dbd_dr = dr::Driver.new
304
+ drh = DBI::DriverHandle.new(dbd_dr, @@convert_types)
305
+ drh.driver_name = dr.driver_name
306
+ # FIXME trace
307
+ # drh.trace(@@trace_mode, @@trace_output)
308
+ @@driver_map[driver_name] = [drh, dbd_dr]
309
+ return driver_name
310
+ else
311
+ return driver_name
312
+ end
313
+ end
314
+ rescue LoadError, NameError
315
+ if $SAFE >= 1
316
+ raise InterfaceError, "Could not load driver (#{$!.message}). Note that in SAFE mode >= 1, driver URLs have to be case sensitive!"
317
+ else
318
+ raise InterfaceError, "Could not load driver (#{$!.message})"
319
+ end
320
+ end
321
+
322
+ # Splits a DBI URL into two components - the database driver name
323
+ # and the datasource (along with any options, if any) and returns
324
+ # a two element array, e.g. 'dbi:foo:bar' would return ['foo','bar'].
325
+ #
326
+ # A regular expression is used instead of a simple split to validate
327
+ # the proper format for the URL. If it isn't correct, an Interface
328
+ # error is raised.
329
+ def parse_url(driver_url)
330
+ if driver_url =~ /^(DBI|dbi):([^:]+)(:(.*))$/
331
+ [$2, $4]
332
+ else
333
+ raise InterfaceError, "Invalid Data Source Name"
334
+ end
335
+ end
336
+ end # self
337
+ end # module DBI
@@ -0,0 +1,94 @@
1
+ ############################################################
2
+ # tc_columninfo.rb
3
+ #
4
+ # Test case for the DBI::ColumnInfo 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 "dbi/columninfo"
13
+ require "test/unit"
14
+
15
+ class TC_DBI_ColumnInfo < Test::Unit::TestCase
16
+ def setup
17
+ @colinfo = DBI::ColumnInfo.new(
18
+ "name" => "test",
19
+ "sql_type" => "numeric",
20
+ "type_name" => "test_type_name",
21
+ "precision" => 2,
22
+ "scale" => 2,
23
+ "default" => 100.00,
24
+ "nullable" => false,
25
+ "indexed" => true,
26
+ "primary" => true,
27
+ "unique" => false
28
+ )
29
+ @keys = %w/name sql_type type_name precision scale default nullable
30
+ indexed primary unique
31
+ /
32
+ end
33
+
34
+ def test_constructor
35
+ assert_nothing_raised{ DBI::ColumnInfo.new }
36
+
37
+ assert_nothing_raised do
38
+ DBI::ColumnInfo.new({"foo" => "bar", "baz" => "quux"})
39
+ DBI::ColumnInfo.new({:foo => "bar", :baz => "quux"})
40
+ end
41
+
42
+ assert_raises(TypeError) do
43
+ DBI::ColumnInfo.new({"foo" => "bar", :foo => "quux"})
44
+ end
45
+ end
46
+
47
+ def test_accessors
48
+ assert_nothing_raised do
49
+ @keys.each do |x|
50
+ assert_equal(@colinfo[x], @colinfo[x.to_sym])
51
+ assert_equal(@colinfo.send(x.to_sym), @colinfo[x.to_sym])
52
+ @colinfo[x] = "poop"
53
+ assert_equal("poop", @colinfo[x])
54
+ assert_equal("poop", @colinfo[x.to_sym])
55
+ end
56
+ end
57
+ end
58
+
59
+ def test_precision_basic
60
+ assert_respond_to(@colinfo, :size)
61
+ assert_respond_to(@colinfo, :size=)
62
+ assert_respond_to(@colinfo, :length)
63
+ assert_respond_to(@colinfo, :length=)
64
+ end
65
+
66
+ def test_scale_basic
67
+ assert_respond_to(@colinfo, :decimal_digits)
68
+ assert_respond_to(@colinfo, :decimal_digits=)
69
+ end
70
+
71
+ def test_default_value_basic
72
+ assert_respond_to(@colinfo, :default_value)
73
+ assert_respond_to(@colinfo, :default_value=)
74
+ end
75
+
76
+ def test_unique_basic
77
+ assert_respond_to(@colinfo, :is_unique)
78
+ end
79
+
80
+ def test_keys
81
+ assert_respond_to(@colinfo, :keys)
82
+ assert_equal(@keys.sort, @colinfo.keys.collect { |x| x.to_s }.sort)
83
+ end
84
+
85
+ def test_respond_to_hash_methods
86
+ assert_respond_to(@colinfo, :each)
87
+ assert_respond_to(@colinfo, :empty?)
88
+ assert_respond_to(@colinfo, :has_key?)
89
+ end
90
+
91
+ def teardown
92
+ @colinfo = nil
93
+ end
94
+ end
@@ -0,0 +1,88 @@
1
+ ##############################################################################
2
+ # tc_date.rb
3
+ #
4
+ # Test case for the DBI::Date class (currently) located in the utils.rb file.
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 'date'
13
+ require 'dbi'
14
+ require 'test/unit'
15
+
16
+ Deprecate.set_action(proc { })
17
+
18
+ class TC_DBI_Date < Test::Unit::TestCase
19
+ def setup
20
+ @date = Date.new
21
+ @time = Time.now
22
+ @dbi_date = DBI::Date.new
23
+ end
24
+
25
+ def test_constructor
26
+ assert_nothing_raised{ DBI::Date.new(2006) }
27
+ assert_nothing_raised{ DBI::Date.new(2006, 1) }
28
+ assert_nothing_raised{ DBI::Date.new(2006, 1, 20) }
29
+ assert_nothing_raised{ DBI::Date.new(Date.new) }
30
+ assert_nothing_raised{ DBI::Date.new(Time.now) }
31
+ end
32
+
33
+ def test_year
34
+ assert_respond_to(@dbi_date, :year)
35
+ assert_respond_to(@dbi_date, :year=)
36
+ assert_equal(0, @dbi_date.year)
37
+ end
38
+
39
+ def test_month
40
+ assert_respond_to(@dbi_date, :month)
41
+ assert_respond_to(@dbi_date, :month=)
42
+ end
43
+
44
+ # An alias for :month, :month=
45
+ def test_mon
46
+ assert_respond_to(@dbi_date, :mon)
47
+ assert_respond_to(@dbi_date, :mon=)
48
+ assert_equal(0, @dbi_date.mon)
49
+ end
50
+
51
+ def test_day
52
+ assert_respond_to(@dbi_date, :day)
53
+ assert_respond_to(@dbi_date, :day=)
54
+ assert_equal(0, @dbi_date.day)
55
+ end
56
+
57
+ # An alias for :day, :day=
58
+ def test_mday
59
+ assert_respond_to(@dbi_date, :mday)
60
+ assert_respond_to(@dbi_date, :mday=)
61
+ end
62
+
63
+ def test_to_time
64
+ assert_respond_to(@dbi_date, :to_time)
65
+ assert_equal(@time, DBI::Date.new(@time).to_time)
66
+ assert_equal(@time.object_id, DBI::Date.new(@time).to_time.object_id)
67
+ end
68
+
69
+ def test_to_date
70
+ assert_respond_to(@dbi_date, :to_date)
71
+ assert_equal(@date, DBI::Date.new(@date).to_date)
72
+ assert_equal(@date.object_id, DBI::Date.new(@date).to_date.object_id)
73
+ end
74
+
75
+ # We test .to_s because it has an explicit implementation
76
+ def test_to_s
77
+ assert_respond_to(@dbi_date, :to_s)
78
+ assert_nothing_raised{ @dbi_date.to_s }
79
+ assert_kind_of(String, @dbi_date.to_s)
80
+ assert_equal("0000-00-00", @dbi_date.to_s)
81
+ end
82
+
83
+ def teardown
84
+ @date = nil
85
+ @time = nil
86
+ @dbi_date = nil
87
+ end
88
+ end