aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord
diff options
context:
space:
mode:
authorTarmo Tänav <tarmo@itech.ee>2008-07-31 22:18:14 +0300
committerMichael Koziarski <michael@koziarski.com>2008-07-31 21:33:11 +0200
commitf7eaab96d332528253d14581f747dd4b1b378a06 (patch)
tree4b4b55a06722611bfcc939dca8944f8982562297 /activerecord
parentf3da46effae9f23f6ea473f7296e9c0c9bb49fce (diff)
downloadrails-f7eaab96d332528253d14581f747dd4b1b378a06.tar.gz
rails-f7eaab96d332528253d14581f747dd4b1b378a06.tar.bz2
rails-f7eaab96d332528253d14581f747dd4b1b378a06.zip
validates_uniqueness_of uses database case sensitivity support instead of using ruby
Signed-off-by: Michael Koziarski <michael@koziarski.com>
Diffstat (limited to 'activerecord')
-rw-r--r--activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb4
-rwxr-xr-xactiverecord/lib/active_record/connection_adapters/mysql_adapter.rb4
-rwxr-xr-xactiverecord/lib/active_record/validations.rb42
3 files changed, 23 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 5358491cde..aaf9e2e73f 100644
--- a/activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb
+++ b/activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb
@@ -149,6 +149,10 @@ module ActiveRecord
"INSERT INTO #{quote_table_name(table_name)} VALUES(DEFAULT)"
end
+ def case_sensitive_equality_operator
+ "="
+ end
+
protected
# Returns an array of record hashes with the column names as keys and
# column values as values.
diff --git a/activerecord/lib/active_record/connection_adapters/mysql_adapter.rb b/activerecord/lib/active_record/connection_adapters/mysql_adapter.rb
index 35b9ed4746..204ebaa2e2 100755
--- a/activerecord/lib/active_record/connection_adapters/mysql_adapter.rb
+++ b/activerecord/lib/active_record/connection_adapters/mysql_adapter.rb
@@ -511,6 +511,10 @@ module ActiveRecord
keys.length == 1 ? [keys.first, nil] : nil
end
+ def case_sensitive_equality_operator
+ "= BINARY"
+ end
+
private
def connect
@connection.reconnect = true if @connection.respond_to?(:reconnect=)
diff --git a/activerecord/lib/active_record/validations.rb b/activerecord/lib/active_record/validations.rb
index 52f674847e..e7a9676394 100755
--- a/activerecord/lib/active_record/validations.rb
+++ b/activerecord/lib/active_record/validations.rb
@@ -627,17 +627,23 @@ module ActiveRecord
is_text_column = finder_class.columns_hash[attr_name.to_s].text?
- if !value.nil? && is_text_column
- value = value.to_s
+ if value.nil?
+ comparison_operator = "IS ?"
+ else
+ comparison_operator = "#{connection.case_sensitive_equality_operator} ?"
+
+ if is_text_column
+ value = value.to_s
+ end
end
+ sql_attribute = "#{record.class.quoted_table_name}.#{connection.quote_column_name(attr_name)}"
+
if value.nil? || (configuration[:case_sensitive] || !is_text_column)
- condition_sql = "#{record.class.quoted_table_name}.#{attr_name} #{attribute_condition(value)}"
+ condition_sql = "#{sql_attribute} #{comparison_operator}"
condition_params = [value]
else
- # sqlite has case sensitive SELECT query, while MySQL/Postgresql don't.
- # Hence, this is needed only for sqlite.
- condition_sql = "LOWER(#{record.class.quoted_table_name}.#{attr_name}) #{attribute_condition(value)}"
+ condition_sql = "LOWER(#{sql_attribute}) #{comparison_operator}"
condition_params = [value.downcase]
end
@@ -654,28 +660,10 @@ module ActiveRecord
condition_params << record.send(:id)
end
- results = finder_class.with_exclusive_scope do
- connection.select_all(
- construct_finder_sql(
- :select => "#{connection.quote_column_name(attr_name)}",
- :from => "#{finder_class.quoted_table_name}",
- :conditions => [condition_sql, *condition_params]
- )
- )
- end
-
- unless results.length.zero?
- found = true
-
- # As MySQL/Postgres don't have case sensitive SELECT queries, we try to find duplicate
- # column in ruby when case sensitive option
- if configuration[:case_sensitive] && finder_class.columns_hash[attr_name.to_s].text?
- found = results.any? { |a| a[attr_name.to_s] == value.to_s }
- end
-
- if found
+ finder_class.with_exclusive_scope do
+ if finder_class.exists?([condition_sql, *condition_params])
message = record.errors.generate_message(attr_name, :taken, :default => configuration[:message])
- record.errors.add(attr_name, message)
+ record.errors.add(attr_name, message)
end
end
end