Skip to content
Browse files

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
  • Loading branch information...
1 parent 1cc8ab8 commit 2076dca63fde71693e4b8e23c4b1ace0a35b964f @jeremy jeremy committed Nov 16, 2005
View
2 activerecord/lib/active_record/associations.rb
@@ -999,7 +999,7 @@ def add_sti_conditions!(sql, reflections)
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)
View
19 activerecord/lib/active_record/base.rb
@@ -706,9 +706,11 @@ def set_inheritance_column( value=nil, &block )
# 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 @@ def add_conditions!(sql, conditions)
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 @@ def extract_attribute_names_from_match(match)
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 @@ def update
# 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(', ')}) " +
View
8 activerecord/lib/active_record/connection_adapters/abstract_adapter.rb
@@ -45,6 +45,14 @@ def supports_migrations?
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
View
2 activerecord/lib/active_record/connection_adapters/sqlite_adapter.rb
@@ -123,7 +123,7 @@ def quote_string(s) #:nodoc:
end
def quote_column_name(name) #:nodoc:
- "'#{name}'"
+ %Q("#{name}")
end
View
19 activerecord/lib/active_record/validations.rb
@@ -487,13 +487,20 @@ def validates_uniqueness_of(*attr_names)
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
View
2 activerecord/test/abstract_unit.rb
@@ -8,6 +8,8 @@
require 'active_support/breakpoint'
require 'connection'
+QUOTED_TYPE = ActiveRecord::Base.connection.quote_column_name('type') unless Object.const_defined?(:QUOTED_TYPE)
+
class Test::Unit::TestCase #:nodoc:
self.fixture_path = File.dirname(__FILE__) + "/fixtures/"
self.use_instantiated_fixtures = false
View
4 activerecord/test/associations_go_eager_test.rb
@@ -21,7 +21,7 @@ def test_loading_with_one_association
end
def test_loading_conditions_with_or
- posts = authors(:david).posts.find(:all, :include => :comments, :conditions => "comments.body like 'Normal%' OR comments.type = 'SpecialComment'")
+ posts = authors(:david).posts.find(:all, :include => :comments, :conditions => "comments.body like 'Normal%' OR comments.#{QUOTED_TYPE} = 'SpecialComment'")
assert_nil posts.detect { |p| p.author_id != authors(:david).id },
"expected to find only david's posts"
end
@@ -120,7 +120,7 @@ def test_eager_with_has_many_and_limit_and_conditions_on_the_eagers
assert_raises(ArgumentError) do
posts = authors(:david).posts.find(:all,
:include => :comments,
- :conditions => "comments.body like 'Normal%' OR comments.type = 'SpecialComment'",
+ :conditions => "comments.body like 'Normal%' OR comments.#{QUOTED_TYPE}= 'SpecialComment'",
:limit => 2
)
end
View
12 activerecord/test/associations_test.rb
@@ -357,7 +357,7 @@ def test_find_ids
def test_find_all
firm = Firm.find_first
assert_equal firm.clients, firm.clients.find_all
- assert_equal 2, firm.clients.find(:all, :conditions => "type = 'Client'").length
+ assert_equal 2, firm.clients.find(:all, :conditions => "#{QUOTED_TYPE} = 'Client'").length
assert_equal 1, firm.clients.find(:all, :conditions => "name = 'Summit'").length
end
@@ -373,16 +373,16 @@ def test_find_first
firm = Firm.find_first
client2 = Client.find(2)
assert_equal firm.clients.first, firm.clients.find_first
- assert_equal client2, firm.clients.find_first("type = 'Client'")
- assert_equal client2, firm.clients.find(:first, :conditions => "type = 'Client'")
+ assert_equal client2, firm.clients.find_first("#{QUOTED_TYPE} = 'Client'")
+ assert_equal client2, firm.clients.find(:first, :conditions => "#{QUOTED_TYPE} = 'Client'")
end
def test_find_first_sanitized
firm = Firm.find_first
client2 = Client.find(2)
- assert_equal client2, firm.clients.find_first(["type = ?", "Client"])
- assert_equal client2, firm.clients.find(:first, :conditions => ['type = ?', 'Client'])
- assert_equal client2, firm.clients.find(:first, :conditions => ['type = :type', { :type => 'Client' }])
+ assert_equal client2, firm.clients.find_first(["#{QUOTED_TYPE} = ?", "Client"])
+ assert_equal client2, firm.clients.find(:first, :conditions => ["#{QUOTED_TYPE} = ?", 'Client'])
+ assert_equal client2, firm.clients.find(:first, :conditions => ["#{QUOTED_TYPE} = :type", { :type => 'Client' }])
end
def test_find_in_collection
View
6 activerecord/test/base_test.rb
@@ -505,7 +505,7 @@ def test_default_values_on_empty_strings
assert_nil topic.last_read
assert_nil topic.approved
end
-
+
def test_equality
assert_equal Topic.find(1), Topic.find(2).parent
end
@@ -1003,10 +1003,10 @@ def test_set_inheritance_column_with_block
end
def test_count_with_join
- res = Post.count_by_sql "SELECT COUNT(*) FROM posts LEFT JOIN comments ON posts.id=comments.post_id WHERE posts.type = 'Post'"
+ res = Post.count_by_sql "SELECT COUNT(*) FROM posts LEFT JOIN comments ON posts.id=comments.post_id WHERE posts.#{QUOTED_TYPE} = 'Post'"
res2 = res + 1
assert_nothing_raised do
- res2 = Post.count("posts.type = 'Post'",
+ res2 = Post.count("posts.#{QUOTED_TYPE} = 'Post'",
"LEFT JOIN comments ON posts.id=comments.post_id")
end
assert_equal res, res2
View
2 activerecord/test/deprecated_associations_test.rb
@@ -312,7 +312,7 @@ def test_storing_in_pstore
end
def test_has_many_find_all
- assert_equal 2, Firm.find_first.find_all_in_clients("type = 'Client'").length
+ assert_equal 2, Firm.find_first.find_all_in_clients("#{QUOTED_TYPE} = 'Client'").length
assert_equal 1, Firm.find_first.find_all_in_clients("name = 'Summit'").length
end
View
2 activerecord/test/finder_test.rb
@@ -350,7 +350,7 @@ def test_find_all_with_join
def test_find_by_id_with_conditions_with_or
assert_nothing_raised do
Post.find([1,2,3],
- :conditions => "posts.id <= 3 OR posts.type = 'Post'")
+ :conditions => "posts.id <= 3 OR posts.#{QUOTED_TYPE} = 'Post'")
end
end
View
2 activerecord/test/fixtures/comment.rb
@@ -6,7 +6,7 @@ def self.what_are_you
end
def self.search_by_type(q)
- self.find(:all, :conditions => ['type = ?', q])
+ self.find(:all, :conditions => ["#{QUOTED_TYPE} = ?", q])
end
end
View
4 activerecord/test/fixtures/company.rb
@@ -7,7 +7,9 @@ class Company < ActiveRecord::Base
class Firm < Company
- has_many :clients, :order => "id", :dependent => true, :counter_sql => "SELECT COUNT(*) FROM companies WHERE firm_id = 1 AND (type = 'Client' OR type = 'SpecialClient' OR type = 'VerySpecialClient' )"
+ has_many :clients, :order => "id", :dependent => true, :counter_sql =>
+ "SELECT COUNT(*) FROM companies WHERE firm_id = 1 " +
+ "AND (#{QUOTED_TYPE} = 'Client' OR #{QUOTED_TYPE} = 'SpecialClient' OR #{QUOTED_TYPE} = 'VerySpecialClient' )"
has_many :clients_sorted_desc, :class_name => "Client", :order => "id DESC"
has_many :clients_of_firm, :foreign_key => "client_of", :class_name => "Client", :order => "id"
has_many :dependent_clients_of_firm, :foreign_key => "client_of", :class_name => "Client", :order => "id", :dependent => true
View
62 activerecord/test/fixtures_test.rb
@@ -51,42 +51,44 @@ def test_inserts
assert_nil(secondRow["author_email_address"])
end
- def test_inserts_with_pre_and_suffix
- ActiveRecord::Base.connection.create_table :prefix_topics_suffix do |t|
- t.column :title, :string
- t.column :author_name, :string
- t.column :author_email_address, :string
- t.column :written_on, :datetime
- t.column :bonus_time, :time
- t.column :last_read, :date
- t.column :content, :text
- t.column :approved, :boolean, :default => true
- t.column :replies_count, :integer, :default => 0
- t.column :parent_id, :integer
- t.column :type, :string, :limit => 50
- end
+ if ActiveRecord::Base.connection.supports_migrations?
+ def test_inserts_with_pre_and_suffix
+ ActiveRecord::Base.connection.create_table :prefix_topics_suffix do |t|
+ t.column :title, :string
+ t.column :author_name, :string
+ t.column :author_email_address, :string
+ t.column :written_on, :datetime
+ t.column :bonus_time, :time
+ t.column :last_read, :date
+ t.column :content, :text
+ t.column :approved, :boolean, :default => true
+ t.column :replies_count, :integer, :default => 0
+ t.column :parent_id, :integer
+ t.column :type, :string, :limit => 50
+ end
- # Store existing prefix/suffix
- old_prefix = ActiveRecord::Base.table_name_prefix
- old_suffix = ActiveRecord::Base.table_name_suffix
+ # Store existing prefix/suffix
+ old_prefix = ActiveRecord::Base.table_name_prefix
+ old_suffix = ActiveRecord::Base.table_name_suffix
- # Set a prefix/suffix we can test against
- ActiveRecord::Base.table_name_prefix = 'prefix_'
- ActiveRecord::Base.table_name_suffix = '_suffix'
+ # Set a prefix/suffix we can test against
+ ActiveRecord::Base.table_name_prefix = 'prefix_'
+ ActiveRecord::Base.table_name_suffix = '_suffix'
- topics = create_fixtures("topics")
+ topics = create_fixtures("topics")
- # Restore prefix/suffix to its previous values
- ActiveRecord::Base.table_name_prefix = old_prefix
- ActiveRecord::Base.table_name_suffix = old_suffix
+ # Restore prefix/suffix to its previous values
+ ActiveRecord::Base.table_name_prefix = old_prefix
+ ActiveRecord::Base.table_name_suffix = old_suffix
- firstRow = ActiveRecord::Base.connection.select_one("SELECT * FROM prefix_topics_suffix WHERE author_name = 'David'")
- assert_equal("The First Topic", firstRow["title"])
+ firstRow = ActiveRecord::Base.connection.select_one("SELECT * FROM prefix_topics_suffix WHERE author_name = 'David'")
+ assert_equal("The First Topic", firstRow["title"])
- secondRow = ActiveRecord::Base.connection.select_one("SELECT * FROM prefix_topics_suffix WHERE author_name = 'Mary'")
- assert_nil(secondRow["author_email_address"])
- ensure
- ActiveRecord::Base.connection.drop_table :prefix_topics_suffix rescue nil
+ secondRow = ActiveRecord::Base.connection.select_one("SELECT * FROM prefix_topics_suffix WHERE author_name = 'Mary'")
+ assert_nil(secondRow["author_email_address"])
+ ensure
+ ActiveRecord::Base.connection.drop_table :prefix_topics_suffix rescue nil
+ end
end
def test_insert_with_datetime
View
2 activerecord/test/inheritance_test.rb
@@ -11,7 +11,7 @@ def test_a_bad_type_column
if current_adapter?(:SQLServerAdapter)
Company.connection.execute "SET IDENTITY_INSERT companies ON"
end
- Company.connection.insert "INSERT INTO companies (id, type, name) VALUES(100, 'bad_class!', 'Not happening')"
+ Company.connection.insert "INSERT INTO companies (id, #{QUOTED_TYPE}, name) VALUES(100, 'bad_class!', 'Not happening')"
#We then need to turn it back Off before continuing.
if current_adapter?(:SQLServerAdapter)

0 comments on commit 2076dca

Please sign in to comment.
Something went wrong with that request. Please try again.