From 2076dca63fde71693e4b8e23c4b1ace0a35b964f Mon Sep 17 00:00:00 2001 From: Jeremy Kemper Date: Wed, 16 Nov 2005 08:16:54 +0000 Subject: r3095@asus: jeremy | 2005-11-15 22:40:51 -0800 Ticket #1874 - Firebird adapter r3107@asus: jeremy | 2005-11-16 00:06:14 -0800 quote column aliases r3108@asus: jeremy | 2005-11-16 00:08:12 -0800 quote columns in construct_conditions_from_arguments. update sequence_name docs. introduce prefetched primary keys. r3109@asus: jeremy | 2005-11-16 00:09:08 -0800 double-quote rather than single-quote sqlite columns r3110@asus: jeremy | 2005-11-16 00:09:56 -0800 quote column names and use attribute_condition in validates_uniqueness_of r3111@asus: jeremy | 2005-11-16 00:12:24 -0800 Use QUOTED_TYPE constant in tests r3112@asus: jeremy | 2005-11-16 00:13:28 -0800 restrict test_inserts_with_pre_and_suffix to those adapters which support migrations r3113@asus: jeremy | 2005-11-16 00:14:09 -0800 Use QUOTED_TYPE constant in tests r3114@asus: jeremy | 2005-11-16 00:14:30 -0800 Use QUOTED_TYPE constant in tests git-svn-id: http://svn-commit.rubyonrails.org/rails/trunk@3051 5ecf4fe2-1ee6-0310-87b1-e25e094e27de --- activerecord/lib/active_record/associations.rb | 2 +- activerecord/lib/active_record/base.rb | 19 +++++++++++++------ .../connection_adapters/abstract_adapter.rb | 8 ++++++++ .../connection_adapters/sqlite_adapter.rb | 2 +- activerecord/lib/active_record/validations.rb | 19 +++++++++++++------ 5 files changed, 36 insertions(+), 14 deletions(-) (limited to 'activerecord/lib') diff --git a/activerecord/lib/active_record/associations.rb b/activerecord/lib/active_record/associations.rb index a4c440f4b4..d4b7f88907 100755 --- a/activerecord/lib/active_record/associations.rb +++ b/activerecord/lib/active_record/associations.rb @@ -999,7 +999,7 @@ module ActiveRecord end def column_aliases(schema_abbreviations) - schema_abbreviations.collect { |cn, tc| "#{tc.join(".")} AS #{cn}" }.join(", ") + schema_abbreviations.collect { |cn, tc| "#{tc[0]}.#{connection.quote_column_name tc[1]} AS #{cn}" }.join(", ") end def association_join(reflection) diff --git a/activerecord/lib/active_record/base.rb b/activerecord/lib/active_record/base.rb index 06902a6927..550b657102 100755 --- a/activerecord/lib/active_record/base.rb +++ b/activerecord/lib/active_record/base.rb @@ -706,9 +706,11 @@ module ActiveRecord #:nodoc: # given block. This is required for Oracle and is useful for any # database which relies on sequences for primary key generation. # - # Setting the sequence name when using other dbs will have no effect. - # If a sequence name is not explicitly set when using Oracle, it will - # default to the commonly used pattern of: #{table_name}_seq + # If a sequence name is not explicitly set when using Oracle or Firebird, + # it will default to the commonly used pattern of: #{table_name}_seq + # + # If a sequence name is not explicitly set when using PostgreSQL, it + # will discover the sequence corresponding to your primary key for you. # # Example: # @@ -962,8 +964,9 @@ module ActiveRecord #:nodoc: end def type_condition - type_condition = subclasses.inject("#{table_name}.#{inheritance_column} = '#{name.demodulize}' ") do |condition, subclass| - condition << "OR #{table_name}.#{inheritance_column} = '#{subclass.name.demodulize}' " + quoted_inheritance_column = connection.quote_column_name(inheritance_column) + type_condition = subclasses.inject("#{table_name}.#{quoted_inheritance_column} = '#{name.demodulize}' ") do |condition, subclass| + condition << "OR #{table_name}.#{quoted_inheritance_column} = '#{subclass.name.demodulize}' " end " (#{type_condition}) " @@ -1017,7 +1020,7 @@ module ActiveRecord #:nodoc: def construct_conditions_from_arguments(attribute_names, arguments) conditions = [] - attribute_names.each_with_index { |name, idx| conditions << "#{table_name}.#{name} #{attribute_condition(arguments[idx])} " } + attribute_names.each_with_index { |name, idx| conditions << "#{table_name}.#{connection.quote_column_name(name)} #{attribute_condition(arguments[idx])} " } [ conditions.join(" AND "), *arguments[0...attribute_names.length] ] end @@ -1457,6 +1460,10 @@ module ActiveRecord #:nodoc: # Creates a new record with values matching those of the instance attributes. def create + if self.id.nil? and connection.prefetch_primary_key?(self.class.table_name) + self.id = connection.next_sequence_value(self.class.sequence_name) + end + self.id = connection.insert( "INSERT INTO #{self.class.table_name} " + "(#{quoted_column_names.join(', ')}) " + diff --git a/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb b/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb index 9dbfe93cdf..ef835ff022 100755 --- a/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb +++ b/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb @@ -45,6 +45,14 @@ module ActiveRecord false end + # Should primary key values be selected from their corresponding + # sequence before the insert statement? If true, next_sequence_value + # is called before each insert to set the record's primary key. + # This is false for all adapters but Firebird. + def prefetch_primary_key? + false + end + def reset_runtime #:nodoc: rt, @runtime = @runtime, 0 rt diff --git a/activerecord/lib/active_record/connection_adapters/sqlite_adapter.rb b/activerecord/lib/active_record/connection_adapters/sqlite_adapter.rb index 2c302d7414..2c87d78fc8 100644 --- a/activerecord/lib/active_record/connection_adapters/sqlite_adapter.rb +++ b/activerecord/lib/active_record/connection_adapters/sqlite_adapter.rb @@ -123,7 +123,7 @@ module ActiveRecord end def quote_column_name(name) #:nodoc: - "'#{name}'" + %Q("#{name}") end diff --git a/activerecord/lib/active_record/validations.rb b/activerecord/lib/active_record/validations.rb index 904153bf24..b6c9647b78 100755 --- a/activerecord/lib/active_record/validations.rb +++ b/activerecord/lib/active_record/validations.rb @@ -487,13 +487,20 @@ module ActiveRecord configuration = { :message => ActiveRecord::Errors.default_error_messages[:taken] } configuration.update(attr_names.pop) if attr_names.last.is_a?(Hash) - if scope = configuration[:scope] - validates_each(attr_names,configuration) do |record, attr_name, value| - record.errors.add(attr_name, configuration[:message]) if record.class.find(:first, :conditions => (record.new_record? ? ["#{attr_name} = ? AND #{scope} = ?", record.send(attr_name), record.send(scope)] : ["#{attr_name} = ? AND #{record.class.primary_key} <> ? AND #{scope} = ?", record.send(attr_name), record.send(:id), record.send(scope)])) + validates_each(attr_names,configuration) do |record, attr_name, value| + condition_sql = "#{attr_name} #{attribute_condition(value)}" + condition_params = [value] + if scope = configuration[:scope] + scope_value = record.send(scope) + condition_sql << " AND #{scope} #{attribute_condition(scope_value)}" + condition_params << scope_value end - else - validates_each(attr_names,configuration) do |record, attr_name, value| - record.errors.add(attr_name, configuration[:message]) if record.class.find(:first, :conditions => (record.new_record? ? ["#{attr_name} = ?", record.send(attr_name)] : ["#{attr_name} = ? AND #{record.class.primary_key} <> ?", record.send(attr_name), record.send(:id) ] )) + unless record.new_record? + condition_sql << " AND #{record.class.primary_key} <> ?" + condition_params << record.send(:id) + end + if record.class.find(:first, :conditions => [condition_sql, *condition_params]) + record.errors.add(attr_name, configuration[:message]) end end end -- cgit v1.2.3