diff options
Diffstat (limited to 'activerecord')
14 files changed, 86 insertions, 50 deletions
diff --git a/activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb b/activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb index a609867898..46c7fc71ac 100644 --- a/activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb +++ b/activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb @@ -286,12 +286,10 @@ module ActiveRecord private def release(conn) - thread_id = nil - - if @reserved_connections[current_connection_id] == conn - thread_id = current_connection_id + thread_id = if @reserved_connections[current_connection_id] == conn + current_connection_id else - thread_id = @reserved_connections.keys.find { |k| + @reserved_connections.keys.find { |k| @reserved_connections[k] == conn } end diff --git a/activerecord/lib/active_record/persistence.rb b/activerecord/lib/active_record/persistence.rb index 12e232a97f..4a987c2343 100644 --- a/activerecord/lib/active_record/persistence.rb +++ b/activerecord/lib/active_record/persistence.rb @@ -268,7 +268,13 @@ module ActiveRecord clear_aggregation_cache clear_association_cache - fresh_object = self.class.unscoped { self.class.find(id, options) } + fresh_object = + if options && options[:lock] + self.class.unscoped { self.class.lock.find(id) } + else + self.class.unscoped { self.class.find(id) } + end + @attributes.update(fresh_object.instance_variable_get('@attributes')) @columns_hash = fresh_object.instance_variable_get('@columns_hash') diff --git a/activerecord/lib/active_record/querying.rb b/activerecord/lib/active_record/querying.rb index 95565b503a..29b8b2fb73 100644 --- a/activerecord/lib/active_record/querying.rb +++ b/activerecord/lib/active_record/querying.rb @@ -11,7 +11,7 @@ module ActiveRecord delegate :select, :group, :order, :except, :reorder, :limit, :offset, :joins, :where, :preload, :eager_load, :includes, :from, :lock, :readonly, :having, :create_with, :uniq, :references, :none, :to => :scoped - delegate :count, :average, :minimum, :maximum, :sum, :calculate, :pluck, :to => :scoped + delegate :count, :average, :minimum, :maximum, :sum, :calculate, :pluck, :ids, :to => :scoped # Executes a custom SQL query against your database and returns all the results. The results will # be returned as an array with columns requested encapsulated as attributes of the model you call diff --git a/activerecord/lib/active_record/relation/calculations.rb b/activerecord/lib/active_record/relation/calculations.rb index db894c8aa9..f388b75c05 100644 --- a/activerecord/lib/active_record/relation/calculations.rb +++ b/activerecord/lib/active_record/relation/calculations.rb @@ -139,6 +139,16 @@ module ActiveRecord end end + # Pluck all the ID's for the relation using the table's primary key + # + # Examples: + # + # Person.ids # SELECT people.id FROM people + # Person.joins(:companies).ids # SELECT people.id FROM PEOPLE INNER JOIN companies ON companies.person_id = people.id + def ids + pluck primary_key + end + private def perform_calculation(operation, column_name, options = {}) diff --git a/activerecord/lib/active_record/relation/finder_methods.rb b/activerecord/lib/active_record/relation/finder_methods.rb index 416b55f5c5..1ceb1949a4 100644 --- a/activerecord/lib/active_record/relation/finder_methods.rb +++ b/activerecord/lib/active_record/relation/finder_methods.rb @@ -217,8 +217,11 @@ module ActiveRecord if match.bang? && result.blank? raise RecordNotFound, "Couldn't find #{@klass.name} with #{conditions.to_a.collect {|p| p.join(' = ')}.join(', ')}" else - yield(result) if block_given? - result + if block_given? && result + yield(result) + else + result + end end end diff --git a/activerecord/test/cases/associations/eager_load_nested_include_test.rb b/activerecord/test/cases/associations/eager_load_nested_include_test.rb index 861a395c58..bb0d6bc70b 100644 --- a/activerecord/test/cases/associations/eager_load_nested_include_test.rb +++ b/activerecord/test/cases/associations/eager_load_nested_include_test.rb @@ -92,7 +92,6 @@ class EagerLoadPolyAssocsTest < ActiveRecord::TestCase end def test_include_query - res = 0 res = ShapeExpression.scoped(:includes => [ :shape, { :paint => :non_poly } ]).all assert_equal NUM_SHAPE_EXPRESSIONS, res.size assert_queries(0) do diff --git a/activerecord/test/cases/attribute_methods_test.rb b/activerecord/test/cases/attribute_methods_test.rb index ab44dc8811..1093fedea1 100644 --- a/activerecord/test/cases/attribute_methods_test.rb +++ b/activerecord/test/cases/attribute_methods_test.rb @@ -481,7 +481,7 @@ class AttributeMethodsTest < ActiveRecord::TestCase end def test_typecast_attribute_from_select_to_false - topic = Topic.create(:title => 'Budget') + Topic.create(:title => 'Budget') # Oracle does not support boolean expressions in SELECT if current_adapter?(:OracleAdapter) topic = Topic.scoped(:select => "topics.*, 0 as is_test").first @@ -492,7 +492,7 @@ class AttributeMethodsTest < ActiveRecord::TestCase end def test_typecast_attribute_from_select_to_true - topic = Topic.create(:title => 'Budget') + Topic.create(:title => 'Budget') # Oracle does not support boolean expressions in SELECT if current_adapter?(:OracleAdapter) topic = Topic.scoped(:select => "topics.*, 1 as is_test").first diff --git a/activerecord/test/cases/base_test.rb b/activerecord/test/cases/base_test.rb index 5887782cad..35e0045e4c 100644 --- a/activerecord/test/cases/base_test.rb +++ b/activerecord/test/cases/base_test.rb @@ -125,20 +125,13 @@ class BasicsTest < ActiveRecord::TestCase unless current_adapter?(:PostgreSQLAdapter,:OracleAdapter,:SQLServerAdapter) def test_limit_with_comma - assert_nothing_raised do - Topic.limit("1,2").all - end + assert Topic.limit("1,2").all end end def test_limit_without_comma - assert_nothing_raised do - assert_equal 1, Topic.limit("1").all.length - end - - assert_nothing_raised do - assert_equal 1, Topic.limit(1).all.length - end + assert_equal 1, Topic.limit("1").all.length + assert_equal 1, Topic.limit(1).all.length end def test_invalid_limit @@ -175,6 +168,24 @@ class BasicsTest < ActiveRecord::TestCase assert Topic.table_exists? end + def test_finder_block + t = Topic.first + found = nil + Topic.find_by_id(t.id) { |f| found = f } + assert_equal t, found + end + + def test_finder_block_nothing_found + bad_id = Topic.maximum(:id) + 1 + assert_nil Topic.find_by_id(bad_id) { |f| raise } + end + + def test_find_returns_block_value + t = Topic.first + x = Topic.find_by_id(t.id) { |f| "hi mom!" } + assert_equal "hi mom!", x + end + def test_preserving_date_objects if current_adapter?(:SybaseAdapter) # Sybase ctlib does not (yet?) support the date type; use datetime instead. @@ -478,7 +489,7 @@ class BasicsTest < ActiveRecord::TestCase if current_adapter?(:MysqlAdapter) or current_adapter?(:Mysql2Adapter) def test_update_all_with_order_and_limit - assert_equal 1, Topic.update_all("content = 'bulk updated!'", nil, :limit => 1, :order => 'id DESC') + assert_equal 1, Topic.limit(1).order('id DESC').update_all(:content => 'bulk updated!') end end diff --git a/activerecord/test/cases/calculations_test.rb b/activerecord/test/cases/calculations_test.rb index 2e566ff873..e096585f62 100644 --- a/activerecord/test/cases/calculations_test.rb +++ b/activerecord/test/cases/calculations_test.rb @@ -465,4 +465,8 @@ class CalculationsTest < ActiveRecord::TestCase Company.create!(:name => "test", :contracts => [Contract.new(:developer_id => 7)]) assert_equal [7], Company.joins(:contracts).pluck(:developer_id) end + + def test_plucks_with_ids + assert_equal Company.all.map(&:id).sort, Company.ids.sort + end end diff --git a/activerecord/test/cases/invalid_date_test.rb b/activerecord/test/cases/invalid_date_test.rb index 98cda010ae..426a350379 100644 --- a/activerecord/test/cases/invalid_date_test.rb +++ b/activerecord/test/cases/invalid_date_test.rb @@ -7,8 +7,6 @@ class InvalidDateTest < ActiveRecord::TestCase invalid_dates = [[2007, 11, 31], [1993, 2, 29], [2007, 2, 29]] - topic = Topic.new - valid_dates.each do |date_src| topic = Topic.new("last_read(1i)" => date_src[0].to_s, "last_read(2i)" => date_src[1].to_s, "last_read(3i)" => date_src[2].to_s) # Oracle DATE columns are datetime columns and Oracle adapter returns Time value diff --git a/activerecord/test/cases/lifecycle_test.rb b/activerecord/test/cases/lifecycle_test.rb index 75e5dfa49b..0b78f2e46b 100644 --- a/activerecord/test/cases/lifecycle_test.rb +++ b/activerecord/test/cases/lifecycle_test.rb @@ -137,7 +137,7 @@ class LifecycleTest < ActiveRecord::TestCase def test_auto_observer topic_observer = TopicaAuditor.instance assert_nil TopicaAuditor.observed_class - assert_equal [Topic], TopicaAuditor.instance.observed_classes.to_a + assert_equal [Topic], TopicaAuditor.observed_classes.to_a topic = Topic.find(1) assert_equal topic.title, topic_observer.topic.title diff --git a/activerecord/test/cases/locking_test.rb b/activerecord/test/cases/locking_test.rb index ee180e4154..afb0bd6fd9 100644 --- a/activerecord/test/cases/locking_test.rb +++ b/activerecord/test/cases/locking_test.rb @@ -358,7 +358,7 @@ unless current_adapter?(:SybaseAdapter, :OpenBaseAdapter) || in_memory_db? def test_sane_find_with_lock assert_nothing_raised do Person.transaction do - Person.find 1, :lock => true + Person.lock.find(1) end end end @@ -369,7 +369,7 @@ unless current_adapter?(:SybaseAdapter, :OpenBaseAdapter) || in_memory_db? def test_eager_find_with_lock assert_nothing_raised do Person.transaction do - Person.find 1, :include => :readers, :lock => true + Person.includes(:readers).lock.find(1) end end end diff --git a/activerecord/test/cases/persistence_test.rb b/activerecord/test/cases/persistence_test.rb index 3bc59560f0..0933a4ff3d 100644 --- a/activerecord/test/cases/persistence_test.rb +++ b/activerecord/test/cases/persistence_test.rb @@ -405,7 +405,6 @@ class PersistencesTest < ActiveRecord::TestCase def test_update_attribute_with_one_updated t = Topic.first - title = t.title t.update_attribute(:title, 'super_title') assert_equal 'super_title', t.title assert !t.changed?, "topic should not have changed" diff --git a/activerecord/test/schema/postgresql_specific_schema.rb b/activerecord/test/schema/postgresql_specific_schema.rb index 84228cdd0a..e51db50ae3 100644 --- a/activerecord/test/schema/postgresql_specific_schema.rb +++ b/activerecord/test/schema/postgresql_specific_schema.rb @@ -127,28 +127,36 @@ _SQL ); _SQL - execute <<_SQL - CREATE TABLE postgresql_partitioned_table_parent ( - id SERIAL PRIMARY KEY, - number integer - ); - CREATE TABLE postgresql_partitioned_table ( ) - INHERITS (postgresql_partitioned_table_parent); - - CREATE OR REPLACE FUNCTION partitioned_insert_trigger() - RETURNS TRIGGER AS $$ - BEGIN - INSERT INTO postgresql_partitioned_table VALUES (NEW.*); - RETURN NULL; - END; - $$ - LANGUAGE plpgsql; - - CREATE TRIGGER insert_partitioning_trigger - BEFORE INSERT ON postgresql_partitioned_table_parent - FOR EACH ROW EXECUTE PROCEDURE partitioned_insert_trigger(); +begin + execute <<_SQL + CREATE TABLE postgresql_partitioned_table_parent ( + id SERIAL PRIMARY KEY, + number integer + ); + CREATE TABLE postgresql_partitioned_table ( ) + INHERITS (postgresql_partitioned_table_parent); + + CREATE OR REPLACE FUNCTION partitioned_insert_trigger() + RETURNS TRIGGER AS $$ + BEGIN + INSERT INTO postgresql_partitioned_table VALUES (NEW.*); + RETURN NULL; + END; + $$ + LANGUAGE plpgsql; + + CREATE TRIGGER insert_partitioning_trigger + BEFORE INSERT ON postgresql_partitioned_table_parent + FOR EACH ROW EXECUTE PROCEDURE partitioned_insert_trigger(); _SQL - +rescue ActiveRecord::StatementInvalid => e + if e.message =~ /language "plpgsql" does not exist/ + execute "CREATE LANGUAGE 'plpgsql';" + retry + else + raise e + end +end begin execute <<_SQL |