schema_dumper.rb 2.4 KB
Newer Older
1 2 3
module ActiveRecord
  # This class is used to dump the database schema for some connection to some
  # output format (i.e., ActiveRecord::Schema).
4
  class SchemaDumper #:nodoc:
5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
    private_class_method :new

    def self.dump(connection=ActiveRecord::Base.connection, stream=STDOUT)
      new(connection).dump(stream)
      stream
    end

    def dump(stream)
      header(stream)
      tables(stream)
      trailer(stream)
      stream
    end

    private

      def initialize(connection)
        @connection = connection
        @types = @connection.native_database_types
        @info = @connection.select_one("SELECT * FROM schema_info") rescue nil
      end

      def header(stream)
        define_params = @info ? ":version => #{@info['version']}" : ""

        stream.puts <<HEADER
# This file is autogenerated. Instead of editing this file, please use the
# migrations feature of ActiveRecord to incrementally modify your database, and
# then regenerate this schema definition.

ActiveRecord::Schema.define(#{define_params}) do
36

37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55
HEADER
      end

      def trailer(stream)
        stream.puts "end"
      end

      def tables(stream)
        @connection.tables.sort.each do |tbl|
          next if tbl == "schema_info"
          table(tbl, stream)
        end
      end

      def table(table, stream)
        columns = @connection.columns(table)

        stream.print "  create_table #{table.inspect}"
        stream.print ", :id => false" if !columns.detect { |c| c.name == "id" }
56
        stream.print ", :force => true"
57 58 59 60 61
        stream.puts " do |t|"

        columns.each do |column|
          next if column.name == "id"
          stream.print "    t.column #{column.name.inspect}, #{column.type.inspect}"
62
          stream.print ", :limit => #{column.limit.inspect}" if column.limit != @types[column.type][:limit] 
63
          stream.print ", :default => #{column.default.inspect}" if !column.default.nil?
64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83
          stream.print ", :null => false" if !column.null
          stream.puts
        end

        stream.puts "  end"
        stream.puts

        indexes(table, stream)
      end

      def indexes(table, stream)
        indexes = @connection.indexes(table)
        indexes.each do |index|
          stream.print "  add_index #{index.table.inspect}, #{index.columns.inspect}, :name => #{index.name.inspect}"
          stream.print ", :unique => true" if index.unique
          stream.puts
        end
        stream.puts unless indexes.empty?
      end
  end
84
end