mirror of
https://github.com/rails/rails.git
synced 2022-11-09 12:12:34 -05:00
Add index length support for MySQL [#1852 state:resolved]
Example: add_index(:accounts, :name, :name => 'by_name', :length => 10) => CREATE INDEX by_name ON accounts(name(10)) add_index(:accounts, [:name, :surname], :name => 'by_name_surname', :length => {:name => 10, :surname => 15}) => CREATE INDEX by_name_surname ON accounts(name(10), surname(15)) Signed-off-by: Pratik Naik <pratiknaik@gmail.com>
This commit is contained in:
parent
9aaef59356
commit
5b95730edc
7 changed files with 73 additions and 3 deletions
|
@ -1,5 +1,15 @@
|
|||
*Rails 3.0.0 [beta 4/release candidate] (unreleased)*
|
||||
|
||||
* Add index length support for MySQL. #1852 [Emili Parreno, Pratik Naik]
|
||||
|
||||
Example:
|
||||
|
||||
add_index(:accounts, :name, :name => 'by_name', :length => 10)
|
||||
=> CREATE INDEX by_name ON accounts(name(10))
|
||||
|
||||
add_index(:accounts, [:name, :surname], :name => 'by_name_surname', :length => {:name => 10, :surname => 15})
|
||||
=> CREATE INDEX by_name_surname ON accounts(name(10), surname(15))
|
||||
|
||||
* find_or_create_by_attr(value, ...) works when attr is protected. #4457 [Santiago Pastorino, Marc-André Lafortune]
|
||||
|
||||
* New callbacks: after_commit and after_rollback. Do expensive operations like image thumbnailing after_commit instead of after_save. #2991 [Brian Durand]
|
||||
|
|
|
@ -258,7 +258,7 @@ module ActiveRecord
|
|||
end
|
||||
end
|
||||
|
||||
class IndexDefinition < Struct.new(:table, :name, :unique, :columns) #:nodoc:
|
||||
class IndexDefinition < Struct.new(:table, :name, :unique, :columns, :lengths) #:nodoc:
|
||||
end
|
||||
|
||||
# Abstract representation of a column definition. Instances of this type
|
||||
|
|
|
@ -256,18 +256,32 @@ module ActiveRecord
|
|||
# name.
|
||||
#
|
||||
# ===== Examples
|
||||
#
|
||||
# ====== Creating a simple index
|
||||
# add_index(:suppliers, :name)
|
||||
# generates
|
||||
# CREATE INDEX suppliers_name_index ON suppliers(name)
|
||||
#
|
||||
# ====== Creating a unique index
|
||||
# add_index(:accounts, [:branch_id, :party_id], :unique => true)
|
||||
# generates
|
||||
# CREATE UNIQUE INDEX accounts_branch_id_party_id_index ON accounts(branch_id, party_id)
|
||||
#
|
||||
# ====== Creating a named index
|
||||
# add_index(:accounts, [:branch_id, :party_id], :unique => true, :name => 'by_branch_party')
|
||||
# generates
|
||||
# CREATE UNIQUE INDEX by_branch_party ON accounts(branch_id, party_id)
|
||||
#
|
||||
# ====== Creating an index with specific key length
|
||||
# add_index(:accounts, :name, :name => 'by_name', :length => 10)
|
||||
# generates
|
||||
# CREATE INDEX by_name ON accounts(name(10))
|
||||
#
|
||||
# add_index(:accounts, [:name, :surname], :name => 'by_name_surname', :length => {:name => 10, :surname => 15})
|
||||
# generates
|
||||
# CREATE INDEX by_name_surname ON accounts(name(10), surname(15))
|
||||
#
|
||||
# Note: SQLite doesn't support index length
|
||||
def add_index(table_name, column_name, options = {})
|
||||
column_names = Array.wrap(column_name)
|
||||
index_name = index_name(table_name, :column => column_names)
|
||||
|
@ -278,7 +292,9 @@ module ActiveRecord
|
|||
else
|
||||
index_type = options
|
||||
end
|
||||
quoted_column_names = column_names.map { |e| quote_column_name(e) }.join(", ")
|
||||
|
||||
quoted_column_names = quoted_columns_for_index(column_names, options).join(", ")
|
||||
|
||||
execute "CREATE #{index_type} INDEX #{quote_column_name(index_name)} ON #{quote_table_name(table_name)} (#{quoted_column_names})"
|
||||
end
|
||||
|
||||
|
@ -430,6 +446,11 @@ module ActiveRecord
|
|||
end
|
||||
|
||||
protected
|
||||
# Overridden by the mysql adapter for supporting index lengths
|
||||
def quoted_columns_for_index(column_names, options = {})
|
||||
column_names.map {|name| quote_column_name(name) }
|
||||
end
|
||||
|
||||
def options_include_default?(options)
|
||||
options.include?(:default) && !(options[:null] == false && options[:default].nil?)
|
||||
end
|
||||
|
|
|
@ -461,10 +461,11 @@ module ActiveRecord
|
|||
if current_index != row[2]
|
||||
next if row[2] == "PRIMARY" # skip the primary key
|
||||
current_index = row[2]
|
||||
indexes << IndexDefinition.new(row[0], row[2], row[1] == "0", [])
|
||||
indexes << IndexDefinition.new(row[0], row[2], row[1] == "0", [], [])
|
||||
end
|
||||
|
||||
indexes.last.columns << row[4]
|
||||
indexes.last.lengths << row[7]
|
||||
end
|
||||
result.free
|
||||
indexes
|
||||
|
@ -594,6 +595,18 @@ module ActiveRecord
|
|||
end
|
||||
|
||||
protected
|
||||
def quoted_columns_for_index(column_names, options = {})
|
||||
length = options[:length] if options.is_a?(Hash)
|
||||
|
||||
quoted_column_names = case length
|
||||
when Hash
|
||||
column_names.map {|name| length[name] ? "#{quote_column_name(name)}(#{length[name]})" : quote_column_name(name) }
|
||||
when Fixnum
|
||||
column_names.map {|name| "#{quote_column_name(name)}(#{length})"}
|
||||
else
|
||||
column_names.map {|name| quote_column_name(name) }
|
||||
end
|
||||
end
|
||||
|
||||
def translate_exception(exception, message)
|
||||
return super unless exception.respond_to?(:errno)
|
||||
|
|
|
@ -177,6 +177,7 @@ HEADER
|
|||
statment_parts << index.columns.inspect
|
||||
statment_parts << (':name => ' + index.name.inspect)
|
||||
statment_parts << ':unique => true' if index.unique
|
||||
statment_parts << (':length => ' + Hash[*index.columns.zip(index.lengths).flatten].inspect) if index.lengths.compact.present?
|
||||
|
||||
' ' + statment_parts.join(', ')
|
||||
end
|
||||
|
|
|
@ -15,6 +15,23 @@ class ActiveSchemaTest < ActiveRecord::TestCase
|
|||
end
|
||||
end
|
||||
|
||||
def test_add_index
|
||||
expected = "CREATE INDEX `index_people_on_last_name` ON `people` (`last_name`)"
|
||||
assert_equal expected, add_index(:people, :last_name, :length => nil)
|
||||
|
||||
expected = "CREATE INDEX `index_people_on_last_name` ON `people` (`last_name`(10))"
|
||||
assert_equal expected, add_index(:people, :last_name, :length => 10)
|
||||
|
||||
expected = "CREATE INDEX `index_people_on_last_name_and_first_name` ON `people` (`last_name`(15), `first_name`(15))"
|
||||
assert_equal expected, add_index(:people, [:last_name, :first_name], :length => 15)
|
||||
|
||||
expected = "CREATE INDEX `index_people_on_last_name_and_first_name` ON `people` (`last_name`(15), `first_name`)"
|
||||
assert_equal expected, add_index(:people, [:last_name, :first_name], :length => {:last_name => 15})
|
||||
|
||||
expected = "CREATE INDEX `index_people_on_last_name_and_first_name` ON `people` (`last_name`(15), `first_name`(10))"
|
||||
assert_equal expected, add_index(:people, [:last_name, :first_name], :length => {:last_name => 15, :first_name => 10})
|
||||
end
|
||||
|
||||
def test_drop_table
|
||||
assert_equal "DROP TABLE `people`", drop_table(:people)
|
||||
end
|
||||
|
|
|
@ -92,6 +92,14 @@ if ActiveRecord::Base.connection.supports_migrations?
|
|||
assert_nothing_raised { Person.connection.remove_index("people", "last_name_and_first_name") }
|
||||
assert_nothing_raised { Person.connection.add_index("people", ["last_name", "first_name"]) }
|
||||
assert_nothing_raised { Person.connection.remove_index("people", ["last_name", "first_name"]) }
|
||||
assert_nothing_raised { Person.connection.add_index("people", ["last_name"], :length => 10) }
|
||||
assert_nothing_raised { Person.connection.remove_index("people", "last_name") }
|
||||
assert_nothing_raised { Person.connection.add_index("people", ["last_name"], :length => {:last_name => 10}) }
|
||||
assert_nothing_raised { Person.connection.remove_index("people", ["last_name"]) }
|
||||
assert_nothing_raised { Person.connection.add_index("people", ["last_name", "first_name"], :length => 10) }
|
||||
assert_nothing_raised { Person.connection.remove_index("people", ["last_name", "first_name"]) }
|
||||
assert_nothing_raised { Person.connection.add_index("people", ["last_name", "first_name"], :length => {:last_name => 10, :first_name => 20}) }
|
||||
assert_nothing_raised { Person.connection.remove_index("people", ["last_name", "first_name"]) }
|
||||
end
|
||||
|
||||
# quoting
|
||||
|
|
Loading…
Reference in a new issue