diff options
author | Stefan Kanev <stefan.kanev@gmail.com> | 2014-08-01 16:13:38 +0200 |
---|---|---|
committer | Ryuta Kamizono <kamipo@gmail.com> | 2015-01-19 13:40:13 +0900 |
commit | 48e99a45310f5fec515305e90ff8ee2a6a61bada (patch) | |
tree | fe3354e0de2cf67944349db3b94ac7a4136ae8ec | |
parent | 53919bbfd2b3232ec66e0cdea7b387725653ab43 (diff) | |
download | rails-48e99a45310f5fec515305e90ff8ee2a6a61bada.tar.gz rails-48e99a45310f5fec515305e90ff8ee2a6a61bada.tar.bz2 rails-48e99a45310f5fec515305e90ff8ee2a6a61bada.zip |
Add an `:if_exists` option to `drop_table`
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.
5 files changed, 29 insertions, 3 deletions
diff --git a/activerecord/CHANGELOG.md b/activerecord/CHANGELOG.md index d8f29a77b4..faa0aecebb 100644 --- a/activerecord/CHANGELOG.md +++ b/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* diff --git a/activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb b/activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb index 0f44c332ae..f905669a24 100644 --- a/activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb +++ b/activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb @@ -380,7 +380,7 @@ module ActiveRecord # 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. diff --git a/activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb b/activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb index e9a3c26c32..b61b717a61 100644 --- a/activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +++ b/activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb @@ -502,7 +502,7 @@ module ActiveRecord 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) diff --git a/activerecord/lib/active_record/connection_adapters/postgresql/schema_statements.rb b/activerecord/lib/active_record/connection_adapters/postgresql/schema_statements.rb index a90adcf4aa..afd7a17c03 100644 --- a/activerecord/lib/active_record/connection_adapters/postgresql/schema_statements.rb +++ b/activerecord/lib/active_record/connection_adapters/postgresql/schema_statements.rb @@ -112,7 +112,7 @@ module ActiveRecord 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. diff --git a/activerecord/test/cases/migration/change_schema_test.rb b/activerecord/test/cases/migration/change_schema_test.rb index b3129a8984..c84e65effc 100644 --- a/activerecord/test/cases/migration/change_schema_test.rb +++ b/activerecord/test/cases/migration/change_schema_test.rb @@ -403,6 +403,17 @@ module ActiveRecord 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| |