lib/rdbi/driver/odbc.rb in rdbi-driver-odbc-0.1.0 vs lib/rdbi/driver/odbc.rb in rdbi-driver-odbc-0.1.1
- old
+ new
@@ -1,17 +1,49 @@
require 'rdbi'
require 'rubygems'
gem 'ruby-odbc', '= 0.99992'
require 'odbc'
+require 'time'
class RDBI::Driver::ODBC < RDBI::Driver
def initialize(*args)
super Database, *args
end
end
class RDBI::Driver::ODBC < RDBI::Driver
+
+ SQL_TYPES = {
+ 1 => {:type => "CHAR", :ruby_type => :default},
+ 2 => {:type => "NUMERIC", :ruby_type => :decimal},
+ 3 => {:type => "DECIMAL", :ruby_type => :decimal},
+ 4 => {:type => "INTEGER", :ruby_type => :integer},
+ 5 => {:type => "SMALLINT", :ruby_type => :integer},
+ 6 => {:type => "FLOAT", :ruby_type => :decimal},
+ 7 => {:type => "REAL", :ruby_type => :decimal},
+ 8 => {:type => "DOUBLE", :ruby_type => :decimal},
+ 9 => {:type => "DATE", :ruby_type => :date},
+ 10 => {:type => "TIME", :ruby_type => :time},
+ 11 => {:type => "TIMESTAMP", :ruby_type => :timestamp},
+ 12 => {:type => "VARCHAR", :ruby_type => :default},
+ 13 => {:type => "BOOLEAN", :ruby_type => :boolean},
+ 91 => {:type => "DATE", :ruby_type => :date},
+ 92 => {:type => "TIME", :ruby_type => :time},
+ 93 => {:type => "TIMESTAMP", :ruby_type => :timestamp},
+ 100 => {:type => nil, :ruby_type => :default},
+ -1 => {:type => "LONG VARCHAR", :ruby_type => :default},
+ -2 => {:type => "BINARY", :ruby_type => :default},
+ -3 => {:type => "VARBINARY", :ruby_type => :default},
+ -4 => {:type => "LONG VARBINARY", :ruby_type => :default},
+ -5 => {:type => "BIGINT", :ruby_type => :integer},
+ -6 => {:type => "TINYINT", :ruby_type => :integer},
+ -7 => {:type => "BIT", :ruby_type => :default},
+ -8 => {:type => "CHAR", :ruby_type => :default},
+ -10 => {:type => "BLOB", :ruby_type => :default},
+ -11 => {:type => "CLOB", :ruby_type => :default},
+ }
+
class Database < RDBI::Database
attr_accessor :handle
def initialize(*args)
@@ -75,10 +107,11 @@
@rs << r
end
end
def next_row
+ return nil if last_row?
val = @rs[@index]
@index += 1
val
end
@@ -97,11 +130,11 @@
def last
@rs.last
end
def rest
- @rs[@index+1..-1]
+ @rs[@index..-1]
end
def all
@rs
end
@@ -147,24 +180,46 @@
def initialize(query, dbh)
super
@handle = @dbh.handle.prepare(query)
@output_type_map = RDBI::Type.create_type_hash(RDBI::Type::Out)
+
+ @output_type_map[:date] = TypeLib::Filter.new(
+ proc{|obj| obj.is_a?(::ODBC::Date)},
+ proc{|obj| Date.parse(obj.to_s)}
+ )
+
+ @output_type_map[:time] = TypeLib::Filter.new(
+ proc{|obj| obj.is_a?(::ODBC::Time)},
+ proc{|obj| Time.parse(obj.to_s)}
+ )
+
+ @output_type_map[:timestamp] = TypeLib::Filter.new(
+ proc{|obj| obj.is_a?(::ODBC::TimeStamp)},
+ proc{|obj| DateTime.parse(obj.to_s)}
+ )
end
def new_execution(*binds)
@handle.execute(*binds)
columns = @handle.columns(true).collect do |col|
newcol = RDBI::Column.new
- newcol.name = col.name.to_sym
+ newcol.name = col.name.to_sym
+ newcol.type = SQL_TYPES[col.type][:type]
+ newcol.ruby_type = SQL_TYPES[col.type][:ruby_type]
+ newcol.precision = col.precision
+ newcol.scale = col.scale
+ newcol.nullable = col.nullable
+ newcol.table = col.table
newcol
end
return Cursor.new(@handle), RDBI::Schema.new(columns), @output_type_map
end
def finish
@handle.drop
+ super
end
end
end