提交 87535f50 编写于 作者: T Tobias Lütke

SchemaDumper now doesn't fail anymore when there are unknown column types in...

SchemaDumper now doesn't fail anymore when there are unknown column types in the schema. Instead the table is ignored and a Comment is left in the schema.rb also added ActiveRecord::Base.schema_ignore_tables for dealing with funky tables like the tesearch2 ones.


git-svn-id: http://svn-commit.rubyonrails.org/rails/trunk@3346 5ecf4fe2-1ee6-0310-87b1-e25e094e27de
上级 ac963f06
*SVN*
* Added ActiveRecord::Base.schema_ignore_tables which tells SchemaDumper which tables to ignore. Useful for tables with funky column like the ones required for tsearch2. [TobiasLuetke]
* SchemaDumper now doesn't fail anymore when there are unknown column types in the schema. Instead the table is ignored and a Comment is left in the schema.rb. [TobiasLuetke]
* Fixed that saving a model with multiple habtm associations would only save the first one. #3244 [yanowitz-rubyonrails@quantumfoam.org, Florian Weber]
* Fix change_column to work with PostgreSQL 7.x and 8.x. #3141 [wejn@box.cz, Rick Olson, Scott Barron]
......
......@@ -332,6 +332,12 @@ def self.reset_subclasses
cattr_accessor :schema_format
@@schema_format = :sql
# A list of tables which should not be dumped to the schema.
# Acceptable values are strings as well as regexp.
# This setting is only used if schema_format == :ruby
cattr_accessor :schema_ignore_tables
@@schema_ignore_tables = []
class << self # Class methods
# Find operates with three different retrieval approaches:
#
......
......@@ -4,7 +4,7 @@ module ActiveRecord
module ConnectionAdapters #:nodoc:
# An abstract definition of a column in a table.
class Column
attr_reader :name, :default, :type, :limit, :null
attr_reader :name, :default, :type, :limit, :null, :sql_type
attr_accessor :primary
# Instantiates a new column in the table.
......@@ -15,6 +15,7 @@ class Column
# +null+ determines if this column allows +NULL+ values.
def initialize(name, default, sql_type = nil, null = true)
@name, @type, @null = name, simplified_type(sql_type), null
@sql_type = sql_type
# have to do this one separately because type_cast depends on #type
@default = type_cast(default)
@limit = extract_limit(sql_type) unless sql_type.nil?
......
......@@ -3,6 +3,7 @@ module ActiveRecord
# output format (i.e., ActiveRecord::Schema).
class SchemaDumper #:nodoc:
private_class_method :new
def self.dump(connection=ActiveRecord::Base.connection, stream=STDOUT)
new(connection).dump(stream)
......@@ -43,32 +44,51 @@ def trailer(stream)
def tables(stream)
@connection.tables.sort.each do |tbl|
next if tbl == "schema_info"
next if ["schema_info", Base.schema_ignore_tables].flatten.any? do |ignored|
case ignored
when String: tbl == ignored
when Regexp: tbl =~ ignored
else
raise StandardError, 'ActiveRecord::Base.schema_ignore_tables accepts an array of String and / or Regexp values.'
end
end
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" }
stream.print ", :force => true"
stream.puts " do |t|"
columns.each do |column|
next if column.name == "id"
stream.print " t.column #{column.name.inspect}, #{column.type.inspect}"
stream.print ", :limit => #{column.limit.inspect}" if column.limit != @types[column.type][:limit]
stream.print ", :default => #{column.default.inspect}" if !column.default.nil?
stream.print ", :null => false" if !column.null
begin
tbl = StringIO.new
tbl.print " create_table #{table.inspect}"
tbl.print ", :id => false" if !columns.detect { |c| c.name == "id" }
tbl.print ", :force => true"
tbl.puts " do |t|"
columns.each do |column|
raise StandardError, "Unknown type '#{column.sql_type}' for column '#{column.name}'" if @types[column.type].nil?
next if column.name == "id"
tbl.print " t.column #{column.name.inspect}, #{column.type.inspect}"
tbl.print ", :limit => #{column.limit.inspect}" if column.limit != @types[column.type][:limit]
tbl.print ", :default => #{column.default.inspect}" if !column.default.nil?
tbl.print ", :null => false" if !column.null
tbl.puts
end
tbl.puts " end"
tbl.puts
indexes(table, tbl)
tbl.rewind
stream.print tbl.read
rescue => e
stream.puts "# Could not dump table #{table.inspect} because of following #{e.class}"
stream.puts "# #{e.message}"
stream.puts
end
stream.puts " end"
stream.puts
indexes(table, stream)
stream
end
def indexes(table, stream)
......
......@@ -14,6 +14,38 @@ def test_schema_dump
assert_match %r{create_table "authors"}, output
assert_no_match %r{create_table "schema_info"}, output
end
def test_schema_dump_with_string_ignored_table
stream = StringIO.new
ActiveRecord::Base.schema_ignore_tables = ['accounts']
ActiveRecord::SchemaDumper.dump(ActiveRecord::Base.connection, stream)
output = stream.string
assert_no_match %r{create_table "accounts"}, output
assert_match %r{create_table "authors"}, output
assert_no_match %r{create_table "schema_info"}, output
end
def test_schema_dump_with_regexp_ignored_table
stream = StringIO.new
ActiveRecord::Base.schema_ignore_tables = [/^account/]
ActiveRecord::SchemaDumper.dump(ActiveRecord::Base.connection, stream)
output = stream.string
assert_no_match %r{create_table "accounts"}, output
assert_match %r{create_table "authors"}, output
assert_no_match %r{create_table "schema_info"}, output
end
def test_schema_dump_illegal_ignored_table_value
stream = StringIO.new
ActiveRecord::Base.schema_ignore_tables = [5]
assert_raise(StandardError) do
ActiveRecord::SchemaDumper.dump(ActiveRecord::Base.connection, stream)
end
end
end
end
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册