Skip to content

Commit

Permalink
Add an :if_exists option to drop_table
Browse files Browse the repository at this point in the history
If set to `if_exists: true`, it generates a statement like:

    DROP TABLE IF EXISTS posts

This syntax is supported in the popular SQL servers, that is (at least)
SQLite, PostgreSQL, MySQL, Oracle and MS SQL Sever.

Closes #16366.
  • Loading branch information
skanev authored and kamipo committed Jan 19, 2015
1 parent 53919bb commit 48e99a4
Show file tree
Hide file tree
Showing 5 changed files with 29 additions and 3 deletions.
15 changes: 15 additions & 0 deletions activerecord/CHANGELOG.md
@@ -1,3 +1,18 @@
* Introduce the `:if_exists` option for `drop_table`.

Example:

drop_table(:posts, if_exists: true)

That would execute:

DROP TABLE IF EXISTS posts

If the table doesn't exist, `if_exists: false` (the default) raises an
exception whereas `if_exists: true` does nothing.

*Cody Cutrer*, *Stefan Kanev*, *Ryuta Kamizono*

* Don't run SQL if attribute value is not changed for update_attribute method.

*Prathamesh Sonpatki*
Expand Down
Expand Up @@ -380,7 +380,7 @@ def rename_table(table_name, new_name)
# it can be helpful to provide these in a migration's +change+ method so it can be reverted.
# In that case, +options+ and the block will be used by create_table.
def drop_table(table_name, options = {})
execute "DROP TABLE #{quote_table_name(table_name)}"
execute "DROP TABLE#{' IF EXISTS' if options[:if_exists]} #{quote_table_name(table_name)}"
end

# Adds a new column to the named table.
Expand Down
Expand Up @@ -502,7 +502,7 @@ def rename_table(table_name, new_name)
end

def drop_table(table_name, options = {})
execute "DROP#{' TEMPORARY' if options[:temporary]} TABLE #{quote_table_name(table_name)}#{' CASCADE' if options[:force] == :cascade}"
execute "DROP#{' TEMPORARY' if options[:temporary]} TABLE#{' IF EXISTS' if options[:if_exists]} #{quote_table_name(table_name)}#{' CASCADE' if options[:force] == :cascade}"
end

def rename_index(table_name, old_name, new_name)
Expand Down
Expand Up @@ -112,7 +112,7 @@ def table_exists?(name)
end

def drop_table(table_name, options = {})
execute "DROP TABLE #{quote_table_name(table_name)}#{' CASCADE' if options[:force] == :cascade}"
execute "DROP TABLE#{' IF EXISTS' if options[:if_exists]} #{quote_table_name(table_name)}#{' CASCADE' if options[:force] == :cascade}"
end

# Returns true if schema exists.
Expand Down
11 changes: 11 additions & 0 deletions activerecord/test/cases/migration/change_schema_test.rb
Expand Up @@ -403,6 +403,17 @@ def test_column_exists_on_table_with_no_options_parameter_supplied
end
end

def test_drop_table_if_exists
connection.create_table(:testings)
assert connection.table_exists?(:testings)
connection.drop_table(:testings, if_exists: true)
assert_not connection.table_exists?(:testings)
end

def test_drop_table_if_exists_nothing_raised
assert_nothing_raised { connection.drop_table(:nonexistent, if_exists: true) }
end

private
def testing_table_with_only_foo_attribute
connection.create_table :testings, :id => false do |t|
Expand Down

0 comments on commit 48e99a4

Please sign in to comment.