Ruby on Rails | Screencasts | Download | Documentation | Weblog | Community | Source

Changeset 8320

Show
Ignore:
Timestamp:
12/06/07 02:26:08 (1 year ago)
Author:
santana
Message:

Merging with Rails/Informix 1.1.0.

Features:

  • DECIMAL support

Bugs fixed:

  • db/schema.rb was not being generated.
  • After DECIMAL support was added to ActiveRecord, all DECIMAL columns
    were being converted to integers.
    Noticed by Andres Rafael Aguilar Albores <aandresrafael at gmail>
Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • adapters/informix/lib/active_record/connection_adapters/informix_adapter.rb

    r7982 r8320  
    1 # $Id: informix_adapter.rb,v 1.14 2007/10/18 00:34:10 santana Exp $ 
     1# $Id: informix_adapter.rb,v 1.15 2007/12/06 01:43:11 santana Exp $ 
    22 
    33# Copyright (c) 2006-2007, Gerardo Santana Gomez Garrido <gerardo.santana@gmail.com> 
     
    4747    after_save :write_lobs 
    4848    private 
    49     def write_lobs 
    50       if connection.is_a?(ConnectionAdapters::InformixAdapter) 
    51         self.class.columns.select { |c| [:text, :binary].include?(c.type) }.each { |c| 
     49      def write_lobs 
     50        return if !connection.is_a?(ConnectionAdapters::InformixAdapter) 
     51        self.class.columns.each do |c| 
    5252          value = self[c.name] 
    53           next if value.nil?  || value == '' 
    54           qry = "update #{self.class.table_name} set #{c.name} = ? where #{self.class.primary_key} = #{quote(id)}" 
    55           stmt = connection.prepare(qry) 
    56           stmt.execute(StringIO.new(value)) 
    57           stmt.drop 
    58         } 
    59       end 
     53          next if ![:text, :binary].include? c.type || value.nil? || value == '' 
     54          connection.raw_connection.prepare(<<-end_sql) do |stmt| 
     55              UPDATE #{self.class.table_name} SET #{c.name} = ? 
     56              WHERE #{self.class.primary_key} = #{quote_value(id)} 
     57            end_sql 
     58            stmt.execute(StringIO.new(value)) 
     59          end 
     60        end 
     61      end 
     62  end # class Base 
     63 
     64  module ConnectionAdapters 
     65    class InformixColumn < Column 
     66      def initialize(column) 
     67        sql_type = make_type(column[:stype], column[:length], 
     68                             column[:precision], column[:scale]) 
     69        super(column[:name], column[:default], sql_type, column[:nullable]) 
     70      end 
     71 
     72      private 
     73        IFX_TYPES_SUBSET = %w(CHAR CHARACTER CHARACTER\ VARYING DECIMAL FLOAT 
     74                              LIST LVARCHAR MONEY MULTISET NCHAR NUMERIC 
     75                              NVARCHAR SERIAL SERIAL8 VARCHAR).freeze 
     76 
     77        def make_type(type, limit, prec, scale) 
     78          type.sub!(/money/i, 'DECIMAL') 
     79          if IFX_TYPES_SUBSET.include? type.upcase 
     80            if prec == 0 
     81              "#{type}(#{limit})"  
     82            else 
     83              "#{type}(#{prec},#{scale})" 
     84            end 
     85          elsif type =~ /datetime/i 
     86            type = "time" if prec == 6 
     87            type 
     88          elsif type =~ /byte/i 
     89            "binary" 
     90          else 
     91            type 
     92          end 
     93        end 
     94 
     95        def simplified_type(sql_type) 
     96          if sql_type =~ /serial/i 
     97            :primary_key 
     98          else 
     99            super 
     100          end 
     101        end 
    60102    end 
    61   end # class Base 
    62  
    63   module ConnectionAdapters 
     103 
    64104    # This adapter requires the Informix driver for Ruby 
    65105    # http://ruby-informix.rubyforge.org 
     
    74114      def initialize(db, logger) 
    75115        super 
    76         stmt = db.prepare("select dbinfo('version', 'major') version from systables where tabid = 1") 
    77         @ifx_version = stmt.execute['version'].to_i 
    78         stmt.drop 
     116        @ifx_version = db.prepare(<<-end_sql) do |stmt| 
     117            SELECT dbinfo('version', 'major') version FROM systables 
     118            WHERE tabid = 1 
     119          end_sql 
     120          stmt.execute['version'].to_i 
     121        end 
    79122      end 
    80123 
     
    86129          :integer     => { :name => "integer" }, 
    87130          :float       => { :name => "float" }, 
     131          :decimal     => { :name => "decimal" }, 
    88132          :datetime    => { :name => "datetime year to second" }, 
    89133          :timestamp   => { :name => "datetime year to second" }, 
     
    181225      # SCHEMA STATEMENTS ===================================== 
    182226      def tables(name = nil) 
    183         c = @connection.cursor("SELECT tabname from systables WHERE tabid > 99") 
    184         tables = c.open.fetch_all 
    185         c.drop 
    186         tables.flatten 
     227        @connection.cursor(<<-end_sql) do |cur| 
     228            SELECT tabname FROM systables WHERE tabid > 99 AND tabtype != 'Q' 
     229          end_sql 
     230          cur.open.fetch_all.flatten 
     231        end 
    187232      end 
    188233 
    189234      def columns(table_name, name = nil) 
    190         result = @connection.columns(table_name) 
    191         columns = [] 
    192         result.each { |column| 
    193           columns << Column.new(column[:name], column[:default], 
    194             make_type(column[:stype], column[:precision]), column[:nullable]) 
    195         } 
    196         columns 
    197       end 
    198  
    199       def make_type(type, prec) 
    200         types = %w(CHAR CHARACTER CHARACTER\ VARYING DECIMAL FLOAT LIST 
    201           LVARCHAR MONEY MULTISET NCHAR NUMERIC NVARCHAR SERIAL SERIAL8 
    202           VARCHAR) 
    203         type.sub!(/money/i, 'decimal') 
    204         if types.include? type.upcase 
    205           "#{type}(#{prec})"  
    206         elsif type =~ /datetime/i 
    207           type = "time" if prec == 6 
    208           type 
    209         elsif type =~ /byte/i 
    210           "binary" 
    211         else 
    212           type 
    213         end 
     235        @connection.columns(table_name).map {|col| InformixColumn.new(col) } 
    214236      end 
    215237 
     
    231253      def indexes(table_name, name = nil) 
    232254        indexes = [] 
    233         indexes 
    234255      end 
    235256