From f7eaab96d332528253d14581f747dd4b1b378a06 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tarmo=20T=C3=A4nav?= Date: Thu, 31 Jul 2008 22:18:14 +0300 Subject: validates_uniqueness_of uses database case sensitivity support instead of using ruby Signed-off-by: Michael Koziarski --- activerecord/lib/active_record/validations.rb | 42 ++++++++++----------------- 1 file changed, 15 insertions(+), 27 deletions(-) (limited to 'activerecord/lib/active_record/validations.rb') 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 -- cgit v1.2.3