Ticket #10698: 10698.2.diff
| File 10698.2.diff, 20.3 kB (added by lotswholetime, 8 months ago) |
|---|
-
activerecord/test/base_test.rb
old new 12 12 require 'fixtures/keyboard' 13 13 require 'fixtures/post' 14 14 require 'fixtures/minimalistic' 15 require 'fixtures/warehouse_thing' 15 16 require 'rexml/document' 16 17 17 18 class Category < ActiveRecord::Base; end … … 71 72 end 72 73 73 74 class BasicsTest < Test::Unit::TestCase 74 fixtures :topics, :companies, :developers, :projects, :computers, :accounts, :minimalistics 75 fixtures :topics, :companies, :developers, :projects, :computers, :accounts, :minimalistics, 'warehouse-things' 75 76 76 77 def test_table_exists 77 78 assert !NonExistentTable.table_exists? … … 590 591 assert_nil Topic.find(2).last_read 591 592 end 592 593 594 def test_update_all_with_non_standard_table_name 595 assert_equal 1, WarehouseThing.update_all(['value = ?', 0], ['id = ?', 1]) 596 assert_equal 0, WarehouseThing.find(1).value 597 end 598 593 599 if current_adapter?(:MysqlAdapter) 594 600 def test_update_all_with_order_and_limit 595 601 assert_equal 1, Topic.update_all("content = 'bulk updated!'", nil, :limit => 1, :order => 'id DESC') -
activerecord/test/associations/inner_join_association_test.rb
old new 10 10 11 11 def test_construct_finder_sql_creates_inner_joins 12 12 sql = Author.send(:construct_finder_sql, :joins => :posts) 13 assert_match /INNER JOIN `?posts`? ON `?posts`?.author_id = authors.id/, sql13 assert_match /INNER JOIN [`"]?posts[`"]? ON [`"]?posts[`"]?.author_id = authors.id/, sql 14 14 end 15 15 16 16 def test_construct_finder_sql_cascades_inner_joins 17 17 sql = Author.send(:construct_finder_sql, :joins => {:posts => :comments}) 18 assert_match /INNER JOIN `?posts`? ON `?posts`?.author_id = authors.id/, sql19 assert_match /INNER JOIN `?comments`? ON `?comments`?.post_id = posts.id/, sql18 assert_match /INNER JOIN [`"]?posts[`"]? ON [`"]?posts[`"]?.author_id = authors.id/, sql 19 assert_match /INNER JOIN [`"]?comments[`"]? ON [`"]?comments[`"]?.post_id = posts.id/, sql 20 20 end 21 21 22 22 def test_construct_finder_sql_inner_joins_through_associations 23 23 sql = Author.send(:construct_finder_sql, :joins => :categorized_posts) 24 assert_match /INNER JOIN `?categorizations`?.*INNER JOIN `?posts`?/, sql24 assert_match /INNER JOIN [`"]?categorizations[`"]?.*INNER JOIN [`"]?posts[`"]?/, sql 25 25 end 26 26 27 27 def test_construct_finder_sql_applies_association_conditions 28 28 sql = Author.send(:construct_finder_sql, :joins => :categories_like_general, :conditions => "TERMINATING_MARKER") 29 assert_match /INNER JOIN `?categories`? ON.*AND.*`?General`?.*TERMINATING_MARKER/, sql29 assert_match /INNER JOIN [`"]?categories[`"]? ON.*AND.*[`"]?General[`"]?.*TERMINATING_MARKER/, sql 30 30 end 31 31 32 32 def test_construct_finder_sql_unpacks_nested_joins 33 33 sql = Author.send(:construct_finder_sql, :joins => {:posts => [[:comments]]}) 34 34 assert_no_match /inner join.*inner join.*inner join/i, sql, "only two join clauses should be present" 35 assert_match /INNER JOIN `?posts`? ON `?posts`?.author_id = authors.id/, sql36 assert_match /INNER JOIN `?comments`? ON `?comments`?.post_id = `?posts`?.id/, sql35 assert_match /INNER JOIN [`"]?posts[`"]? ON [`"]?posts[`"]?.author_id = authors.id/, sql 36 assert_match /INNER JOIN [`"]?comments[`"]? ON [`"]?comments[`"]?.post_id = [`"]?posts[`"]?.id/, sql 37 37 end 38 38 39 39 def test_construct_finder_sql_ignores_empty_joins_hash -
activerecord/test/fixtures/warehouse-things.yml
old new 1 one: 2 id: 1 3 value: 1000 4 one: 5 id: 1 6 value: 1000 -
activerecord/test/fixtures/db_definitions/schema.rb
old new 351 351 t.datetime :updated_at 352 352 t.datetime :updated_on 353 353 end 354 355 create_table 'warehouse-things', :force => true do |t| 356 t.integer :value 357 end 354 358 end -
activerecord/test/fixtures/warehouse_thing.rb
old new 1 class WarehouseThing < ActiveRecord::Base 2 set_table_name "warehouse-things" 3 4 validates_uniqueness_of :value 5 end 6 class WarehouseThing < ActiveRecord::Base 7 set_table_name "warehouse-things" 8 9 validates_uniqueness_of :value 10 end -
activerecord/test/validations_test.rb
old new 3 3 require 'fixtures/reply' 4 4 require 'fixtures/person' 5 5 require 'fixtures/developer' 6 require 'fixtures/warehouse_thing' 6 7 7 8 # The following methods in Topic are used in test_conditional_validation_* 8 9 class Topic … … 54 55 end 55 56 56 57 class ValidationsTest < Test::Unit::TestCase 57 fixtures :topics, :developers 58 fixtures :topics, :developers, 'warehouse-things' 58 59 59 60 def setup 60 61 Topic.write_inheritable_attribute(:validate, nil) … … 435 436 assert t2.save, "should save with nil" 436 437 end 437 438 439 def test_validate_uniqueness_with_non_standard_table_names 440 i1 = WarehouseThing.create(:value => 1000) 441 assert !i1.valid?, "i1 should not be valid" 442 assert i1.errors.on(:value), "Should not be empty" 443 end 444 445 438 446 def test_validate_straight_inheritance_uniqueness 439 447 w1 = IneptWizard.create(:name => "Rincewind", :city => "Ankh-Morpork") 440 448 assert w1.valid?, "Saving w1" -
activerecord/lib/active_record/validations.rb
old new 653 653 654 654 validates_each(attr_names,configuration) do |record, attr_name, value| 655 655 if value.nil? || (configuration[:case_sensitive] || !columns_hash[attr_name.to_s].text?) 656 condition_sql = "#{record.class. table_name}.#{attr_name} #{attribute_condition(value)}"656 condition_sql = "#{record.class.quoted_table_name}.#{attr_name} #{attribute_condition(value)}" 657 657 condition_params = [value] 658 658 else 659 condition_sql = "LOWER(#{record.class. table_name}.#{attr_name}) #{attribute_condition(value)}"659 condition_sql = "LOWER(#{record.class.quoted_table_name}.#{attr_name}) #{attribute_condition(value)}" 660 660 condition_params = [value.downcase] 661 661 end 662 662 663 663 if scope = configuration[:scope] 664 664 Array(scope).map do |scope_item| 665 665 scope_value = record.send(scope_item) 666 condition_sql << " AND #{record.class. table_name}.#{scope_item} #{attribute_condition(scope_value)}"666 condition_sql << " AND #{record.class.quoted_table_name}.#{scope_item} #{attribute_condition(scope_value)}" 667 667 condition_params << scope_value 668 668 end 669 669 end 670 670 671 671 unless record.new_record? 672 condition_sql << " AND #{record.class. table_name}.#{record.class.primary_key} <> ?"672 condition_sql << " AND #{record.class.quoted_table_name}.#{record.class.primary_key} <> ?" 673 673 condition_params << record.send(:id) 674 674 end 675 675 -
activerecord/lib/active_record/connection_adapters/sqlite_adapter.rb
old new 192 192 end 193 193 194 194 def indexes(table_name, name = nil) #:nodoc: 195 execute("PRAGMA index_list(#{ table_name})", name).map do |row|195 execute("PRAGMA index_list(#{quote_table_name(table_name)})", name).map do |row| 196 196 index = IndexDefinition.new(table_name, row['name']) 197 197 index.unique = row['unique'] != '0' 198 198 index.columns = execute("PRAGMA index_info('#{index.name}')").map { |col| col['name'] } -
activerecord/lib/active_record/connection_adapters/abstract_adapter.rb
old new 64 64 rt 65 65 end 66 66 67 # QUOTING ==================================================68 69 # Override to return the quoted table name if the database needs it70 def quote_table_name(name)71 name72 end73 74 67 # REFERENTIAL INTEGRITY ==================================== 75 68 76 69 # Override to turn off referential integrity while executing +&block+ -
activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb
old new 25 25 module ConnectionAdapters #:nodoc: 26 26 class SQLite3Adapter < SQLiteAdapter # :nodoc: 27 27 def table_structure(table_name) 28 returning structure = @connection.table_info( table_name) do28 returning structure = @connection.table_info(quote_table_name(table_name)) do 29 29 raise(ActiveRecord::StatementInvalid, "Could not find table '#{table_name}'") if structure.empty? 30 30 end 31 31 end -
activerecord/lib/active_record/reflection.rb
old new 129 129 @table_name ||= klass.table_name 130 130 end 131 131 132 def quoted_table_name 133 @quoted_table_name ||= klass.quoted_table_name 134 end 135 132 136 def primary_key_name 133 137 @primary_key_name ||= options[:foreign_key] || derive_primary_key_name 134 138 end -
activerecord/lib/active_record/associations/has_and_belongs_to_many_association.rb
old new 100 100 end 101 101 102 102 sql = 103 "INSERT INTO #{@ reflection.options[:join_table]} (#{@owner.send(:quoted_column_names, attributes).join(', ')}) " +103 "INSERT INTO #{@owner.connection.quote_table_name @reflection.options[:join_table]} (#{@owner.send(:quoted_column_names, attributes).join(', ')}) " + 104 104 "VALUES (#{attributes.values.join(', ')})" 105 105 106 106 @owner.connection.execute(sql) … … 114 114 records.each { |record| @owner.connection.execute(interpolate_sql(sql, record)) } 115 115 else 116 116 ids = quoted_record_ids(records) 117 sql = "DELETE FROM #{@ reflection.options[:join_table]} WHERE #{@reflection.primary_key_name} = #{@owner.quoted_id} AND #{@reflection.association_foreign_key} IN (#{ids})"117 sql = "DELETE FROM #{@owner.connection.quote_table_name @reflection.options[:join_table]} WHERE #{@reflection.primary_key_name} = #{@owner.quoted_id} AND #{@reflection.association_foreign_key} IN (#{ids})" 118 118 @owner.connection.execute(sql) 119 119 end 120 120 end … … 125 125 if @reflection.options[:finder_sql] 126 126 @finder_sql = @reflection.options[:finder_sql] 127 127 else 128 @finder_sql = "#{@ reflection.options[:join_table]}.#{@reflection.primary_key_name} = #{@owner.quoted_id} "128 @finder_sql = "#{@owner.connection.quote_table_name @reflection.options[:join_table]}.#{@reflection.primary_key_name} = #{@owner.quoted_id} " 129 129 @finder_sql << " AND (#{conditions})" if conditions 130 130 end 131 131 132 @join_sql = "INNER JOIN #{@ reflection.options[:join_table]} ON #{@reflection.klass.table_name}.#{@reflection.klass.primary_key} = #{@reflection.options[:join_table]}.#{@reflection.association_foreign_key}"132 @join_sql = "INNER JOIN #{@owner.connection.quote_table_name @reflection.options[:join_table]} ON #{@reflection.quoted_table_name}.#{@reflection.klass.primary_key} = #{@owner.connection.quote_table_name @reflection.options[:join_table]}.#{@reflection.association_foreign_key}" 133 133 end 134 134 135 135 def construct_scope -
activerecord/lib/active_record/associations/has_one_association.rb
old new 61 61 case 62 62 when @reflection.options[:as] 63 63 @finder_sql = 64 "#{@reflection. klass.table_name}.#{@reflection.options[:as]}_id = #{@owner.quoted_id} AND " +65 "#{@reflection. klass.table_name}.#{@reflection.options[:as]}_type = #{@owner.class.quote_value(@owner.class.base_class.name.to_s)}"64 "#{@reflection.quoted_table_name}.#{@reflection.options[:as]}_id = #{@owner.quoted_id} AND " + 65 "#{@reflection.quoted_table_name}.#{@reflection.options[:as]}_type = #{@owner.class.quote_value(@owner.class.base_class.name.to_s)}" 66 66 else 67 @finder_sql = "#{@reflection. table_name}.#{@reflection.primary_key_name} = #{@owner.quoted_id}"67 @finder_sql = "#{@reflection.quoted_table_name}.#{@reflection.primary_key_name} = #{@owner.quoted_id}" 68 68 end 69 69 @finder_sql << " AND (#{conditions})" if conditions 70 70 end -
activerecord/lib/active_record/associations/has_many_association.rb
old new 144 144 145 145 when @reflection.options[:as] 146 146 @finder_sql = 147 "#{@reflection. klass.table_name}.#{@reflection.options[:as]}_id = #{@owner.quoted_id} AND " +148 "#{@reflection. klass.table_name}.#{@reflection.options[:as]}_type = #{@owner.class.quote_value(@owner.class.base_class.name.to_s)}"147 "#{@reflection.quoted_table_name}.#{@reflection.options[:as]}_id = #{@owner.quoted_id} AND " + 148 "#{@reflection.quoted_table_name}.#{@reflection.options[:as]}_type = #{@owner.class.quote_value(@owner.class.base_class.name.to_s)}" 149 149 @finder_sql << " AND (#{conditions})" if conditions 150 150 151 151 else 152 @finder_sql = "#{@reflection. klass.table_name}.#{@reflection.primary_key_name} = #{@owner.quoted_id}"152 @finder_sql = "#{@reflection.quoted_table_name}.#{@reflection.primary_key_name} = #{@owner.quoted_id}" 153 153 @finder_sql << " AND (#{conditions})" if conditions 154 154 end 155 155 -
activerecord/lib/active_record/associations/has_many_through_association.rb
old new 121 121 column_name, options = @reflection.klass.send(:construct_count_options_from_args, *args) 122 122 if @reflection.options[:uniq] 123 123 # This is needed because 'SELECT count(DISTINCT *)..' is not valid sql statement. 124 column_name = "#{@reflection. klass.table_name}.#{@reflection.klass.primary_key}" if column_name == :all124 column_name = "#{@reflection.quoted_table_name}.#{@reflection.klass.primary_key}" if column_name == :all 125 125 options.merge!(:distinct => true) 126 126 end 127 127 @reflection.klass.send(:with_scope, construct_scope) { @reflection.klass.count(column_name, options) } … … 185 185 186 186 # Build SQL conditions from attributes, qualified by table name. 187 187 def construct_conditions 188 table_name = @reflection.through_reflection. table_name188 table_name = @reflection.through_reflection.quoted_table_name 189 189 conditions = construct_quoted_owner_attributes(@reflection.through_reflection).map do |attr, value| 190 190 "#{table_name}.#{attr} = #{value}" 191 191 end … … 194 194 end 195 195 196 196 def construct_from 197 @reflection. table_name197 @reflection.quoted_table_name 198 198 end 199 199 200 200 def construct_select(custom_select = nil) 201 selected = custom_select || @reflection.options[:select] || "#{@reflection. table_name}.*"201 selected = custom_select || @reflection.options[:select] || "#{@reflection.quoted_table_name}.*" 202 202 end 203 203 204 204 def construct_joins(custom_joins = nil) … … 208 208 source_primary_key = @reflection.source_reflection.primary_key_name 209 209 if @reflection.options[:source_type] 210 210 polymorphic_join = "AND %s.%s = %s" % [ 211 @reflection.through_reflection. table_name, "#{@reflection.source_reflection.options[:foreign_type]}",211 @reflection.through_reflection.quoted_table_name, "#{@reflection.source_reflection.options[:foreign_type]}", 212 212 @owner.class.quote_value(@reflection.options[:source_type]) 213 213 ] 214 214 end … … 217 217 source_primary_key = @reflection.klass.primary_key 218 218 if @reflection.source_reflection.options[:as] 219 219 polymorphic_join = "AND %s.%s = %s" % [ 220 @reflection. table_name, "#{@reflection.source_reflection.options[:as]}_type",220 @reflection.quoted_table_name, "#{@reflection.source_reflection.options[:as]}_type", 221 221 @owner.class.quote_value(@reflection.through_reflection.klass.name) 222 222 ] 223 223 end … … 246 246 when @reflection.options[:finder_sql] 247 247 @finder_sql = interpolate_sql(@reflection.options[:finder_sql]) 248 248 249 @finder_sql = "#{@reflection. klass.table_name}.#{@reflection.primary_key_name} = #{@owner.quoted_id}"249 @finder_sql = "#{@reflection.quoted_table_name}.#{@reflection.primary_key_name} = #{@owner.quoted_id}" 250 250 @finder_sql << " AND (#{conditions})" if conditions 251 251 end 252 252 … … 286 286 end 287 287 288 288 def build_sti_condition 289 "#{@reflection.through_reflection. table_name}.#{@reflection.through_reflection.klass.inheritance_column} = #{@reflection.klass.quote_value(@reflection.through_reflection.klass.name.demodulize)}"289 "#{@reflection.through_reflection.quoted_table_name}.#{@reflection.through_reflection.klass.inheritance_column} = #{@reflection.klass.quote_value(@reflection.through_reflection.klass.name.demodulize)}" 290 290 end 291 291 292 292 alias_method :sql_conditions, :conditions -
activerecord/lib/active_record/base.rb
old new 677 677 # Billing.update_all( "author = 'David'", "title LIKE '%Rails%'", 678 678 # :order => 'created_at', :limit => 5 ) 679 679 def update_all(updates, conditions = nil, options = {}) 680 sql = "UPDATE #{ table_name} SET #{sanitize_sql_for_assignment(updates)} "680 sql = "UPDATE #{quoted_table_name} SET #{sanitize_sql_for_assignment(updates)} " 681 681 scope = scope(:find) 682 682 add_conditions!(sql, conditions, scope) 683 683 add_order!(sql, options[:order], nil)