Permalink
Browse files

SchemaDumper now doesn't fail anymore when there are unknown column t…

…ypes 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
  • Loading branch information...
1 parent ac963f0 commit 87535f50e92f7567d817b455e4f7f4a44371710f Tobias Lütke committed Dec 24, 2005
View
@@ -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]
@@ -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

0 comments on commit 87535f5

Please sign in to comment.