# RSI: oracle_adapter patch for Rails 2.0

# RSI: OracleAdapter patch - treat columns which end with 'date' as ruby date type
# and primary key and foreign key columns as ruby integer type
module ActiveRecord
  module ConnectionAdapters

    class OracleColumn
      def simplified_type(field_type)
        return :boolean if OracleAdapter.emulate_booleans && field_type == 'NUMBER(1)'
        case self.name
          # RSI: treat columns which end with 'date' as ruby date columns
          when /date$/i then :date
          # RSI: removed 'date' from regex
          when /time/i then :datetime
          # RSI: treat id columns (primary key) as integer
          when /^id$/i then :integer
          # RSI: do not do anything with session_id column (defined in sessions table as string)
          when /^session_id$/i then super
          # RSI: treat _id columns (foreign key) as integer
          when /_id$/i then :integer
          else super
        end
      end
    end
  
    # RSI: patch to change selected results NUMBER to integer for primary and foreign keys
    class OracleAdapter
      def select(sql, name = nil)
        cursor = execute(sql, name)
        cols = cursor.get_col_names.map { |x| oracle_downcase(x) }
        rows = []

        while row = cursor.fetch
          hash = Hash.new

          cols.each_with_index do |col, i|
            hash[col] =
              case row[i]
              when OCI8::LOB
                name == 'Writable Large Object' ? row[i]: row[i].read
              when OraDate
                d = row[i]
                if d.hour == 0 && d.minute == 0 && d.second == 0
                  d.to_date
                else
                  # see string_to_time; Time overflowing to DateTime, respecting the default timezone
                  time_array = [d.year, d.month, d.day, d.hour, d.minute, d.second]
                  begin
                    Time.send(Base.default_timezone, *time_array)
                  rescue
                    zone_offset = if Base.default_timezone == :local then DateTime.now.offset else 0 end
                    # Append zero calendar reform start to account for dates skipped by calendar reform
                    DateTime.new(*time_array[0..5] << zone_offset << 0) rescue nil
                  end
                end
              else row[i]
              end unless col == 'raw_rnum_'
            # RSI: patch - convert to integer if column is ID or ends with _ID
            if (col !~ /^session_id$/i) && (col =~ /^id$/i || col =~ /_id$/i) && hash[col]
              hash[col] = hash[col].to_i
            end
          end

          rows << hash
        end

        rows
      ensure
        cursor.close if cursor
      end
    
      # RSI: patch for Rails 2.0
      # Returns an array of arrays containing the field values.
      # Order is the same as that returned by #columns.
      def select_rows(sql, name = nil)
        result = select(sql, name)
        result.map{ |v| v.values}
      end    

      # RSI: patch to make finding of all user tables faster on databases which have a lot of tables
      # in other schemas
      def tables(name = nil) #:nodoc:
        select_all("select lower(table_name) from all_tables where owner = sys_context('userenv','session_user')").inject([]) do | tabs, t |
          tabs << t.to_a.first.last
        end
      end
    
    end

  end
  
end

