mirror of
https://github.com/rails/rails.git
synced 2022-11-09 12:12:34 -05:00
Add an :if_not_exists option to create_table
[fatkodima & Stefan Kanev]
This commit is contained in:
parent
7f7e7e8b39
commit
6e0ff00537
5 changed files with 59 additions and 4 deletions
|
@ -1,3 +1,22 @@
|
|||
* Add an `:if_not_exists` option to `create_table`.
|
||||
|
||||
Example:
|
||||
|
||||
create_table :posts, if_not_exists: true do |t|
|
||||
t.string :title
|
||||
end
|
||||
|
||||
That would execute:
|
||||
|
||||
CREATE TABLE IF NOT EXISTS posts (
|
||||
...
|
||||
)
|
||||
|
||||
If the table already exists, `if_not_exists: false` (the default) raises an
|
||||
exception whereas `if_not_exists: true` does nothing.
|
||||
|
||||
*fatkodima*, *Stefan Kanev*
|
||||
|
||||
* Defining an Enum as a Hash with blank key, or as an Array with a blank value, now raises an `ArgumentError`.
|
||||
|
||||
*Christophe Maximin*
|
||||
|
|
|
@ -39,7 +39,9 @@ module ActiveRecord
|
|||
end
|
||||
|
||||
def visit_TableDefinition(o)
|
||||
create_sql = +"CREATE#{' TEMPORARY' if o.temporary} TABLE #{quote_table_name(o.name)} "
|
||||
create_sql = +"CREATE#{' TEMPORARY' if o.temporary} TABLE "
|
||||
create_sql << "IF NOT EXISTS " if o.if_not_exists
|
||||
create_sql << "#{quote_table_name(o.name)} "
|
||||
|
||||
statements = o.columns.map { |c| accept c }
|
||||
statements << accept(o.primary_keys) if o.primary_keys
|
||||
|
|
|
@ -257,14 +257,15 @@ module ActiveRecord
|
|||
include ColumnMethods
|
||||
|
||||
attr_accessor :indexes
|
||||
attr_reader :name, :temporary, :options, :as, :foreign_keys, :comment
|
||||
attr_reader :name, :temporary, :if_not_exists, :options, :as, :foreign_keys, :comment
|
||||
|
||||
def initialize(name, temporary = false, options = nil, as = nil, comment: nil)
|
||||
def initialize(name, temporary = false, if_not_exists = false, options = nil, as = nil, comment: nil)
|
||||
@columns_hash = {}
|
||||
@indexes = []
|
||||
@foreign_keys = []
|
||||
@primary_keys = nil
|
||||
@temporary = temporary
|
||||
@if_not_exists = if_not_exists
|
||||
@options = options
|
||||
@as = as
|
||||
@name = name
|
||||
|
|
|
@ -205,6 +205,9 @@ module ActiveRecord
|
|||
# Set to true to drop the table before creating it.
|
||||
# Set to +:cascade+ to drop dependent objects as well.
|
||||
# Defaults to false.
|
||||
# [<tt>:if_not_exists</tt>]
|
||||
# Set to true to avoid raising an error when the table already exists.
|
||||
# Defaults to false.
|
||||
# [<tt>:as</tt>]
|
||||
# SQL to use to generate the table. When this option is used, the block is
|
||||
# ignored, as are the <tt>:id</tt> and <tt>:primary_key</tt> options.
|
||||
|
@ -288,7 +291,7 @@ module ActiveRecord
|
|||
#
|
||||
# See also TableDefinition#column for details on how to create columns.
|
||||
def create_table(table_name, comment: nil, **options)
|
||||
td = create_table_definition table_name, options[:temporary], options[:options], options[:as], comment: comment
|
||||
td = create_table_definition table_name, options[:temporary], options[:if_not_exists], options[:options], options[:as], comment: comment
|
||||
|
||||
if options[:id] != false && !options[:as]
|
||||
pk = options.fetch(:primary_key) do
|
||||
|
|
|
@ -127,6 +127,36 @@ class MigrationTest < ActiveRecord::TestCase
|
|||
assert_equal 20131219224947, migrator.current_version
|
||||
end
|
||||
|
||||
def test_create_table_raises_if_already_exists
|
||||
connection = Person.connection
|
||||
connection.create_table :testings, force: true do |t|
|
||||
t.string :foo
|
||||
end
|
||||
|
||||
assert_raise(ActiveRecord::StatementInvalid) do
|
||||
connection.create_table :testings do |t|
|
||||
t.string :foo
|
||||
end
|
||||
end
|
||||
ensure
|
||||
connection.drop_table :testings, if_exists: true
|
||||
end
|
||||
|
||||
def test_create_table_with_if_not_exists_true
|
||||
connection = Person.connection
|
||||
connection.create_table :testings, force: true do |t|
|
||||
t.string :foo
|
||||
end
|
||||
|
||||
assert_nothing_raised do
|
||||
connection.create_table :testings, if_not_exists: true do |t|
|
||||
t.string :foo
|
||||
end
|
||||
end
|
||||
ensure
|
||||
connection.drop_table :testings, if_exists: true
|
||||
end
|
||||
|
||||
def test_create_table_with_force_true_does_not_drop_nonexisting_table
|
||||
# using a copy as we need the drop_table method to
|
||||
# continue to work for the ensure block of the test
|
||||
|
|
Loading…
Reference in a new issue