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
This commit is contained in:
Tobias Lütke 2005-12-24 16:55:55 +00:00
parent ac963f0623
commit 87535f50e9
5 changed files with 80 additions and 17 deletions

View File

@ -1,5 +1,9 @@
*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]

View File

@ -332,6 +332,12 @@ module ActiveRecord #:nodoc:
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:
#

View File

@ -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 @@ module ActiveRecord
# +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?

View File

@ -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 @@ HEADER
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)
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|"
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|
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
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
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)

View File

@ -14,6 +14,38 @@ if ActiveRecord::Base.connection.respond_to?(:tables)
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