Skip to content

Commit

Permalink
Merge commit 'mainstream/master'
Browse files Browse the repository at this point in the history
  • Loading branch information
lifo committed May 7, 2008
2 parents acf5204 + 0a21193 commit d9db501
Show file tree
Hide file tree
Showing 5 changed files with 139 additions and 130 deletions.
13 changes: 1 addition & 12 deletions activerecord/lib/active_record/base.rb
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -1122,18 +1122,7 @@ def class_name(table_name = table_name) # :nodoc:


# Indicates whether the table associated with this class exists # Indicates whether the table associated with this class exists
def table_exists? def table_exists?
if connection.respond_to?(:tables) connection.table_exists?(table_name)
connection.tables.include? table_name
else
# if the connection adapter hasn't implemented tables, there are two crude tests that can be
# used - see if getting column info raises an error, or if the number of columns returned is zero
begin
reset_column_information
columns.size > 0
rescue ActiveRecord::StatementInvalid
false
end
end
end end


# Returns an array of column objects for the table associated with this class. # Returns an array of column objects for the table associated with this class.
Expand Down
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@ def table_alias_for(table_name)


# def tables(name = nil) end # def tables(name = nil) end


def table_exists?(table_name)
tables.include?(table_name.to_s)
end

# Returns an array of indexes for the given table. # Returns an array of indexes for the given table.
# def indexes(table_name, name = nil) end # def indexes(table_name, name = nil) end


Expand Down Expand Up @@ -93,8 +97,8 @@ def create_table(table_name, options = {})


yield table_definition yield table_definition


if options[:force] if options[:force] && table_exists?(table_name)
drop_table(table_name, options) rescue nil drop_table(table_name, options)
end end


create_sql = "CREATE#{' TEMPORARY' if options[:temporary]} TABLE " create_sql = "CREATE#{' TEMPORARY' if options[:temporary]} TABLE "
Expand Down
19 changes: 10 additions & 9 deletions activerecord/test/cases/adapter_test.rb
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -6,15 +6,16 @@ def setup
end end


def test_tables def test_tables
if @connection.respond_to?(:tables) tables = @connection.tables
tables = @connection.tables assert tables.include?("accounts")
assert tables.include?("accounts") assert tables.include?("authors")
assert tables.include?("authors") assert tables.include?("tasks")
assert tables.include?("tasks") assert tables.include?("topics")
assert tables.include?("topics") end
else
warn "#{@connection.class} does not respond to #tables" def test_table_exists?
end assert @connection.table_exists?("accounts")
assert !@connection.table_exists?("nonexistingtable")
end end


def test_indexes def test_indexes
Expand Down
18 changes: 18 additions & 0 deletions activerecord/test/cases/migration_test.rb
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -209,6 +209,24 @@ def test_create_table_with_primary_key_prefix_as_table_name
ActiveRecord::Base.primary_key_prefix_type = nil ActiveRecord::Base.primary_key_prefix_type = nil
end end


uses_mocha('test_create_table_with_force_true_does_not_drop_nonexisting_table') do
def test_create_table_with_force_true_does_not_drop_nonexisting_table
if Person.connection.table_exists?(:testings2)
Person.connection.drop_table :testings2
end

# using a copy as we need the drop_table method to
# continue to work for the ensure block of the test
temp_conn = Person.connection.dup
temp_conn.expects(:drop_table).never
temp_conn.create_table :testings2, :force => true do |t|
t.column :foo, :string
end
ensure
Person.connection.drop_table :testings2 rescue nil
end
end



# SQL Server, Sybase, and SQLite3 will not allow you to add a NOT NULL # SQL Server, Sybase, and SQLite3 will not allow you to add a NOT NULL
# column to a table without a default value. # column to a table without a default value.
Expand Down
211 changes: 104 additions & 107 deletions activerecord/test/cases/schema_dumper_test.rb
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -2,140 +2,137 @@
require 'active_record/schema_dumper' require 'active_record/schema_dumper'
require 'stringio' require 'stringio'


if ActiveRecord::Base.connection.respond_to?(:tables)


class SchemaDumperTest < ActiveRecord::TestCase class SchemaDumperTest < ActiveRecord::TestCase
def standard_dump def standard_dump
stream = StringIO.new stream = StringIO.new
ActiveRecord::SchemaDumper.ignore_tables = [] ActiveRecord::SchemaDumper.ignore_tables = []
ActiveRecord::SchemaDumper.dump(ActiveRecord::Base.connection, stream) ActiveRecord::SchemaDumper.dump(ActiveRecord::Base.connection, stream)
stream.string stream.string
end end


def test_schema_dump def test_schema_dump
output = standard_dump output = standard_dump
assert_match %r{create_table "accounts"}, output assert_match %r{create_table "accounts"}, output
assert_match %r{create_table "authors"}, output assert_match %r{create_table "authors"}, output
assert_no_match %r{create_table "schema_migrations"}, output assert_no_match %r{create_table "schema_migrations"}, output
end end


def test_schema_dump_excludes_sqlite_sequence def test_schema_dump_excludes_sqlite_sequence
output = standard_dump output = standard_dump
assert_no_match %r{create_table "sqlite_sequence"}, output assert_no_match %r{create_table "sqlite_sequence"}, output
end end


def assert_line_up(lines, pattern, required = false) def assert_line_up(lines, pattern, required = false)
return assert(true) if lines.empty? return assert(true) if lines.empty?
matches = lines.map { |line| line.match(pattern) } matches = lines.map { |line| line.match(pattern) }
assert matches.all? if required assert matches.all? if required
matches.compact! matches.compact!
return assert(true) if matches.empty? return assert(true) if matches.empty?
assert_equal 1, matches.map{ |match| match.offset(0).first }.uniq.length assert_equal 1, matches.map{ |match| match.offset(0).first }.uniq.length
end end


def column_definition_lines(output = standard_dump) def column_definition_lines(output = standard_dump)
output.scan(/^( *)create_table.*?\n(.*?)^\1end/m).map{ |m| m.last.split(/\n/) } output.scan(/^( *)create_table.*?\n(.*?)^\1end/m).map{ |m| m.last.split(/\n/) }
end end


def test_types_line_up def test_types_line_up
column_definition_lines.each do |column_set| column_definition_lines.each do |column_set|
next if column_set.empty? next if column_set.empty?


lengths = column_set.map do |column| lengths = column_set.map do |column|
if match = column.match(/t\.(?:integer|decimal|float|datetime|timestamp|time|date|text|binary|string|boolean)\s+"/) if match = column.match(/t\.(?:integer|decimal|float|datetime|timestamp|time|date|text|binary|string|boolean)\s+"/)
match[0].length match[0].length
end
end end

assert_equal 1, lengths.uniq.length
end end
end


def test_arguments_line_up assert_equal 1, lengths.uniq.length
column_definition_lines.each do |column_set|
assert_line_up(column_set, /:default => /)
assert_line_up(column_set, /:limit => /)
assert_line_up(column_set, /:null => /)
end
end end
end


def test_no_dump_errors def test_arguments_line_up
output = standard_dump column_definition_lines.each do |column_set|
assert_no_match %r{\# Could not dump table}, output assert_line_up(column_set, /:default => /)
assert_line_up(column_set, /:limit => /)
assert_line_up(column_set, /:null => /)
end end
end


def test_schema_dump_includes_not_null_columns def test_no_dump_errors
stream = StringIO.new output = standard_dump
assert_no_match %r{\# Could not dump table}, output
end


ActiveRecord::SchemaDumper.ignore_tables = [/^[^r]/] def test_schema_dump_includes_not_null_columns
ActiveRecord::SchemaDumper.dump(ActiveRecord::Base.connection, stream) stream = StringIO.new
output = stream.string
assert_match %r{:null => false}, output
end


def test_schema_dump_with_string_ignored_table ActiveRecord::SchemaDumper.ignore_tables = [/^[^r]/]
stream = StringIO.new ActiveRecord::SchemaDumper.dump(ActiveRecord::Base.connection, stream)
output = stream.string
assert_match %r{:null => false}, output
end


ActiveRecord::SchemaDumper.ignore_tables = ['accounts'] def test_schema_dump_with_string_ignored_table
ActiveRecord::SchemaDumper.dump(ActiveRecord::Base.connection, stream) stream = StringIO.new
output = stream.string
assert_no_match %r{create_table "accounts"}, output ActiveRecord::SchemaDumper.ignore_tables = ['accounts']
assert_match %r{create_table "authors"}, output ActiveRecord::SchemaDumper.dump(ActiveRecord::Base.connection, stream)
assert_no_match %r{create_table "schema_migrations"}, output output = stream.string
end assert_no_match %r{create_table "accounts"}, output
assert_match %r{create_table "authors"}, output
assert_no_match %r{create_table "schema_migrations"}, output
end

def test_schema_dump_with_regexp_ignored_table
stream = StringIO.new


def test_schema_dump_with_regexp_ignored_table ActiveRecord::SchemaDumper.ignore_tables = [/^account/]
stream = StringIO.new 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_migrations"}, output
end


ActiveRecord::SchemaDumper.ignore_tables = [/^account/] def test_schema_dump_illegal_ignored_table_value
stream = StringIO.new
ActiveRecord::SchemaDumper.ignore_tables = [5]
assert_raise(StandardError) do
ActiveRecord::SchemaDumper.dump(ActiveRecord::Base.connection, stream) 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_migrations"}, output
end end
end


def test_schema_dump_illegal_ignored_table_value if current_adapter?(:MysqlAdapter)
stream = StringIO.new def test_schema_dump_should_not_add_default_value_for_mysql_text_field
ActiveRecord::SchemaDumper.ignore_tables = [5] output = standard_dump
assert_raise(StandardError) do assert_match %r{t.text\s+"body",\s+:null => false$}, output
ActiveRecord::SchemaDumper.dump(ActiveRecord::Base.connection, stream)
end
end end


if current_adapter?(:MysqlAdapter) def test_mysql_schema_dump_should_honor_nonstandard_primary_keys
def test_schema_dump_should_not_add_default_value_for_mysql_text_field output = standard_dump
output = standard_dump match = output.match(%r{create_table "movies"(.*)do})
assert_match %r{t.text\s+"body",\s+:null => false$}, output assert_not_nil(match, "nonstandardpk table not found")
end assert_match %r(:primary_key => "movieid"), match[1], "non-standard primary key not preserved"

def test_mysql_schema_dump_should_honor_nonstandard_primary_keys
output = standard_dump
match = output.match(%r{create_table "movies"(.*)do})
assert_not_nil(match, "nonstandardpk table not found")
assert_match %r(:primary_key => "movieid"), match[1], "non-standard primary key not preserved"
end

def test_schema_dump_includes_length_for_mysql_blob_and_text_fields
output = standard_dump
assert_match %r{t.binary\s+"tiny_blob",\s+:limit => 255$}, output
assert_match %r{t.binary\s+"normal_blob"$}, output
assert_match %r{t.binary\s+"medium_blob",\s+:limit => 16777215$}, output
assert_match %r{t.binary\s+"long_blob",\s+:limit => 2147483647$}, output
assert_match %r{t.text\s+"tiny_text",\s+:limit => 255$}, output
assert_match %r{t.text\s+"normal_text"$}, output
assert_match %r{t.text\s+"medium_text",\s+:limit => 16777215$}, output
assert_match %r{t.text\s+"long_text",\s+:limit => 2147483647$}, output
end
end end


def test_schema_dump_includes_decimal_options def test_schema_dump_includes_length_for_mysql_blob_and_text_fields
stream = StringIO.new output = standard_dump
ActiveRecord::SchemaDumper.ignore_tables = [/^[^n]/] assert_match %r{t.binary\s+"tiny_blob",\s+:limit => 255$}, output
ActiveRecord::SchemaDumper.dump(ActiveRecord::Base.connection, stream) assert_match %r{t.binary\s+"normal_blob"$}, output
output = stream.string assert_match %r{t.binary\s+"medium_blob",\s+:limit => 16777215$}, output
assert_match %r{:precision => 3,[[:space:]]+:scale => 2,[[:space:]]+:default => 2.78}, output assert_match %r{t.binary\s+"long_blob",\s+:limit => 2147483647$}, output
assert_match %r{t.text\s+"tiny_text",\s+:limit => 255$}, output
assert_match %r{t.text\s+"normal_text"$}, output
assert_match %r{t.text\s+"medium_text",\s+:limit => 16777215$}, output
assert_match %r{t.text\s+"long_text",\s+:limit => 2147483647$}, output
end end
end end


def test_schema_dump_includes_decimal_options
stream = StringIO.new
ActiveRecord::SchemaDumper.ignore_tables = [/^[^n]/]
ActiveRecord::SchemaDumper.dump(ActiveRecord::Base.connection, stream)
output = stream.string
assert_match %r{:precision => 3,[[:space:]]+:scale => 2,[[:space:]]+:default => 2.78}, output
end
end end

0 comments on commit d9db501

Please sign in to comment.