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