Extract #build_create_index_definition

Exposes CreateIndex schema definition through new API, and stores ddl
on the schema definition. Refactors existing #add_index methods to use
this as an intermediate method to build the create index definition.
This commit is contained in:
Adrianna Chang 2022-07-20 14:49:39 -04:00
parent 69078b0820
commit 54b45ff8e2
7 changed files with 62 additions and 9 deletions

View File

@ -106,7 +106,8 @@ module ActiveRecord
sql << "(#{quoted_columns(index)})"
sql << "WHERE #{index.where}" if supports_partial_index? && index.where
sql.join(" ")
sql = sql.join(" ")
o.ddl = sql
end
def visit_CheckConstraintDefinition(o)

View File

@ -94,7 +94,7 @@ module ActiveRecord
ChangeColumnDefinition = Struct.new(:column, :name) # :nodoc:
CreateIndexDefinition = Struct.new(:index, :algorithm, :if_not_exists) # :nodoc:
CreateIndexDefinition = Struct.new(:index, :algorithm, :if_not_exists, :ddl) # :nodoc:
PrimaryKeyDefinition = Struct.new(:name) # :nodoc:

View File

@ -834,10 +834,21 @@ module ActiveRecord
#
# For more information see the {"Transactional Migrations" section}[rdoc-ref:Migration].
def add_index(table_name, column_name, **options)
create_index = build_create_index_definition(table_name, column_name, **options)
execute(create_index.ddl)
end
# Builds a CreateIndexDefinition object.
#
# This definition object contains information about the index that would be created
# if the same arguments were passed to #add_index. See #add_index for information about
# passing a +table_name+, +column_name+, and other additional options that can be passed.
def build_create_index_definition(table_name, column_name, **options) # :nodoc:
index, algorithm, if_not_exists = add_index_options(table_name, column_name, **options)
create_index = CreateIndexDefinition.new(index, algorithm, if_not_exists)
execute schema_creation.accept(create_index)
schema_creation.accept(create_index)
create_index
end
# Removes the given index from the table.

View File

@ -377,12 +377,20 @@ module ActiveRecord
end
def add_index(table_name, column_name, **options) # :nodoc:
create_index = build_create_index_definition(table_name, column_name, **options)
return unless create_index
execute(create_index.ddl)
end
def build_create_index_definition(table_name, column_name, **options) # :nodoc:
index, algorithm, if_not_exists = add_index_options(table_name, column_name, **options)
return if if_not_exists && index_exists?(table_name, column_name, name: index.name)
create_index = CreateIndexDefinition.new(index, algorithm)
execute schema_creation.accept(create_index)
schema_creation.accept(create_index)
create_index
end
def add_sql_comment!(sql, comment) # :nodoc:

View File

@ -27,7 +27,7 @@ module ActiveRecord
def visit_CreateIndexDefinition(o)
sql = visit_IndexDefinition(o.index, true)
sql << " #{o.algorithm}" if o.algorithm
sql
o.ddl = sql
end
def visit_IndexDefinition(o, create = false)

View File

@ -447,13 +447,20 @@ module ActiveRecord
end
def add_index(table_name, column_name, **options) # :nodoc:
create_index = build_create_index_definition(table_name, column_name, **options)
result = execute(create_index.ddl)
index = create_index.index
execute "COMMENT ON INDEX #{quote_column_name(index.name)} IS #{quote(index.comment)}" if index.comment
result
end
def build_create_index_definition(table_name, column_name, **options) # :nodoc:
index, algorithm, if_not_exists = add_index_options(table_name, column_name, **options)
create_index = CreateIndexDefinition.new(index, algorithm, if_not_exists)
result = execute schema_creation.accept(create_index)
execute "COMMENT ON INDEX #{quote_column_name(index.name)} IS #{quote(index.comment)}" if index.comment
result
schema_creation.accept(create_index)
create_index
end
def remove_index(table_name, column_name = nil, **options) # :nodoc:

View File

@ -35,6 +35,32 @@ module ActiveRecord
assert id_column.type
assert id_column.sql_type
end
def test_build_create_index_definition
connection.create_table(:test) do |t|
t.column :foo, :string
end
create_index = connection.build_create_index_definition(:test, :foo)
assert_match "CREATE INDEX", create_index.ddl
assert_equal "index_test_on_foo", create_index.index.name
ensure
connection.drop_table(:test) if connection.table_exists?(:test)
end
if current_adapter?(:Mysql2Adapter)
def test_build_create_index_definition_for_existing_index
connection.create_table(:test) do |t|
t.column :foo, :string
end
connection.add_index(:test, :foo)
create_index = connection.build_create_index_definition(:test, :foo, if_not_exists: true)
assert_nil create_index
ensure
connection.drop_table(:test) if connection.table_exists?(:test)
end
end
end
end
end