aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord/lib/active_record/connection_adapters/abstract
diff options
context:
space:
mode:
Diffstat (limited to 'activerecord/lib/active_record/connection_adapters/abstract')
-rw-r--r--activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb12
-rw-r--r--activerecord/lib/active_record/connection_adapters/abstract/quoting.rb2
-rw-r--r--activerecord/lib/active_record/connection_adapters/abstract/schema_dumper.rb4
-rw-r--r--activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb43
4 files changed, 34 insertions, 27 deletions
diff --git a/activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb b/activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb
index 848aeb821c..d3bc378bea 100644
--- a/activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb
+++ b/activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb
@@ -208,7 +208,7 @@ module ActiveRecord
# * You are joining an existing open transaction
# * You are creating a nested (savepoint) transaction
#
- # The mysql, mysql2 and postgresql adapters support setting the transaction
+ # The mysql2 and postgresql adapters support setting the transaction
# isolation level. However, support is disabled for MySQL versions below 5,
# because they are affected by a bug[http://bugs.mysql.com/bug.php?id=39170]
# which means the isolation level gets persisted outside the transaction.
@@ -344,18 +344,12 @@ module ActiveRecord
# The default strategy for an UPDATE with joins is to use a subquery. This doesn't work
# on MySQL (even when aliasing the tables), but MySQL allows using JOIN directly in
# an UPDATE statement, so in the MySQL adapters we redefine this to do that.
- def join_to_update(update, select) #:nodoc:
- key = update.key
+ def join_to_update(update, select, key) # :nodoc:
subselect = subquery_for(key, select)
update.where key.in(subselect)
end
-
- def join_to_delete(delete, select, key) #:nodoc:
- subselect = subquery_for(key, select)
-
- delete.where key.in(subselect)
- end
+ alias join_to_delete join_to_update
protected
diff --git a/activerecord/lib/active_record/connection_adapters/abstract/quoting.rb b/activerecord/lib/active_record/connection_adapters/abstract/quoting.rb
index 9ec0a67c8f..bcc41acaa1 100644
--- a/activerecord/lib/active_record/connection_adapters/abstract/quoting.rb
+++ b/activerecord/lib/active_record/connection_adapters/abstract/quoting.rb
@@ -93,7 +93,7 @@ module ActiveRecord
# Override to return the quoted table name for assignment. Defaults to
# table quoting.
#
- # This works for mysql and mysql2 where table.column can be used to
+ # This works for mysql2 where table.column can be used to
# resolve ambiguity.
#
# We override this in the sqlite3 and postgresql adapters to use only
diff --git a/activerecord/lib/active_record/connection_adapters/abstract/schema_dumper.rb b/activerecord/lib/active_record/connection_adapters/abstract/schema_dumper.rb
index e252ddb4cf..797662d07c 100644
--- a/activerecord/lib/active_record/connection_adapters/abstract/schema_dumper.rb
+++ b/activerecord/lib/active_record/connection_adapters/abstract/schema_dumper.rb
@@ -61,8 +61,8 @@ module ActiveRecord
end
def schema_limit(column)
- limit = column.limit || native_database_types[column.type][:limit]
- limit.inspect if limit
+ limit = column.limit
+ limit.inspect if limit && limit != native_database_types[column.type][:limit]
end
def schema_precision(column)
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 b50d28862c..7bf548fcba 100644
--- a/activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb
+++ b/activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb
@@ -82,11 +82,10 @@ module ActiveRecord
#
def index_exists?(table_name, column_name, options = {})
column_names = Array(column_name).map(&:to_s)
- index_name = options.key?(:name) ? options[:name].to_s : index_name(table_name, column: column_names)
checks = []
- checks << lambda { |i| i.name == index_name }
checks << lambda { |i| i.columns == column_names }
checks << lambda { |i| i.unique } if options[:unique]
+ checks << lambda { |i| i.name == options[:name].to_s } if options[:name]
indexes(table_name).any? { |i| checks.all? { |check| check[i] } }
end
@@ -700,15 +699,15 @@ module ActiveRecord
# Removes the given index from the table.
#
- # Removes the +index_accounts_on_column+ in the +accounts+ table.
+ # Removes the index on +branch_id+ in the +accounts+ table if exactly one such index exists.
#
# remove_index :accounts, :branch_id
#
- # Removes the index named +index_accounts_on_branch_id+ in the +accounts+ table.
+ # Removes the index on +branch_id+ in the +accounts+ table if exactly one such index exists.
#
# remove_index :accounts, column: :branch_id
#
- # Removes the index named +index_accounts_on_branch_id_and_party_id+ in the +accounts+ table.
+ # Removes the index on +branch_id+ and +party_id+ in the +accounts+ table if exactly one such index exists.
#
# remove_index :accounts, column: [:branch_id, :party_id]
#
@@ -1127,21 +1126,35 @@ module ActiveRecord
end
def index_name_for_remove(table_name, options = {})
- index_name = index_name(table_name, options)
+ # if the adapter doesn't support the indexes call the best we can do
+ # is return the default index name for the options provided
+ return index_name(table_name, options) unless respond_to?(:indexes)
- unless index_name_exists?(table_name, index_name, true)
- if options.is_a?(Hash) && options.has_key?(:name)
- options_without_column = options.dup
- options_without_column.delete :column
- index_name_without_column = index_name(table_name, options_without_column)
+ checks = []
- return index_name_without_column if index_name_exists?(table_name, index_name_without_column, false)
- end
+ if options.is_a?(Hash)
+ checks << lambda { |i| i.name == options[:name].to_s } if options.has_key?(:name)
+ column_names = Array(options[:column]).map(&:to_s)
+ else
+ column_names = Array(options).map(&:to_s)
+ end
- raise ArgumentError, "Index name '#{index_name}' on table '#{table_name}' does not exist"
+ if column_names.any?
+ checks << lambda { |i| i.columns.join('_and_') == column_names.join('_and_') }
end
- index_name
+ raise ArgumentError "No name or columns specified" if checks.none?
+
+ matching_indexes = indexes(table_name).select { |i| checks.all? { |check| check[i] } }
+
+ if matching_indexes.count > 1
+ raise ArgumentError, "Multiple indexes found on #{table_name} columns #{column_names}. " \
+ "Specify an index name from #{matching_indexes.map(&:name).join(', ')}"
+ elsif matching_indexes.none?
+ raise ArgumentError, "No indexes found on #{table_name} with the options provided."
+ else
+ matching_indexes.first.name
+ end
end
def rename_table_indexes(table_name, new_name)