diff options
Diffstat (limited to 'activerecord')
15 files changed, 98 insertions, 29 deletions
diff --git a/activerecord/CHANGELOG b/activerecord/CHANGELOG index 4ca062b535..c2299b56ad 100644 --- a/activerecord/CHANGELOG +++ b/activerecord/CHANGELOG @@ -1,4 +1,4 @@ -*2.2.1 [RC2 or 2.2 final]* +*2.2.1 [RC2] (November 14th, 2008)* * Ensure indices don't flip order in schema.rb #1266 [Jordi Bunster] diff --git a/activerecord/lib/active_record/association_preload.rb b/activerecord/lib/active_record/association_preload.rb index 6e194ab9b4..69300e5ce5 100644 --- a/activerecord/lib/active_record/association_preload.rb +++ b/activerecord/lib/active_record/association_preload.rb @@ -312,7 +312,7 @@ module ActiveRecord table_name = klass.quoted_table_name primary_key = klass.primary_key column_type = klass.columns.detect{|c| c.name == primary_key}.type - ids = id_map.keys.uniq.map do |id| + ids = id_map.keys.map do |id| if column_type == :integer id.to_i elsif column_type == :float diff --git a/activerecord/lib/active_record/associations.rb b/activerecord/lib/active_record/associations.rb index c7cb6eb966..7f7819115c 100755 --- a/activerecord/lib/active_record/associations.rb +++ b/activerecord/lib/active_record/associations.rb @@ -1609,7 +1609,7 @@ module ActiveRecord :class_name, :table_name, :join_table, :foreign_key, :association_foreign_key, :select, :conditions, :include, :order, :group, :limit, :offset, :uniq, - :finder_sql, :delete_sql, :insert_sql, + :finder_sql, :counter_sql, :delete_sql, :insert_sql, :before_add, :after_add, :before_remove, :after_remove, :extend, :readonly, :validate diff --git a/activerecord/lib/active_record/base.rb b/activerecord/lib/active_record/base.rb index a36a137f0d..ff3ef6ed06 100755 --- a/activerecord/lib/active_record/base.rb +++ b/activerecord/lib/active_record/base.rb @@ -389,6 +389,8 @@ module ActiveRecord #:nodoc: # So it's possible to assign a logger to the class through <tt>Base.logger=</tt> which will then be used by all # instances in the current object space. class Base + ## + # :singleton-method: # Accepts a logger conforming to the interface of Log4r or the default Ruby 1.8+ Logger class, which is then passed # on to any new database connections made and which can be retrieved on both a class and instance level by calling +logger+. cattr_accessor :logger, :instance_writer => false @@ -414,7 +416,9 @@ module ActiveRecord #:nodoc: end @@subclasses = {} - + + ## + # :singleton-method: # Contains the database configuration - as is typically stored in config/database.yml - # as a Hash. # @@ -443,6 +447,8 @@ module ActiveRecord #:nodoc: cattr_accessor :configurations, :instance_writer => false @@configurations = {} + ## + # :singleton-method: # Accessor for the prefix type that will be prepended to every primary key column name. The options are :table_name and # :table_name_with_underscore. If the first is specified, the Product class will look for "productid" instead of "id" as # the primary column. If the latter is specified, the Product class will look for "product_id" instead of "id". Remember @@ -450,34 +456,46 @@ module ActiveRecord #:nodoc: cattr_accessor :primary_key_prefix_type, :instance_writer => false @@primary_key_prefix_type = nil + ## + # :singleton-method: # Accessor for the name of the prefix string to prepend to every table name. So if set to "basecamp_", all # table names will be named like "basecamp_projects", "basecamp_people", etc. This is a convenient way of creating a namespace # for tables in a shared database. By default, the prefix is the empty string. cattr_accessor :table_name_prefix, :instance_writer => false @@table_name_prefix = "" + ## + # :singleton-method: # Works like +table_name_prefix+, but appends instead of prepends (set to "_basecamp" gives "projects_basecamp", # "people_basecamp"). By default, the suffix is the empty string. cattr_accessor :table_name_suffix, :instance_writer => false @@table_name_suffix = "" + ## + # :singleton-method: # Indicates whether table names should be the pluralized versions of the corresponding class names. # If true, the default table name for a Product class will be +products+. If false, it would just be +product+. # See table_name for the full rules on table/class naming. This is true, by default. cattr_accessor :pluralize_table_names, :instance_writer => false @@pluralize_table_names = true + ## + # :singleton-method: # Determines whether to use ANSI codes to colorize the logging statements committed by the connection adapter. These colors # make it much easier to overview things during debugging (when used through a reader like +tail+ and on a black background), but # may complicate matters if you use software like syslog. This is true, by default. cattr_accessor :colorize_logging, :instance_writer => false @@colorize_logging = true + ## + # :singleton-method: # Determines whether to use Time.local (using :local) or Time.utc (using :utc) when pulling dates and times from the database. # This is set to :local by default. cattr_accessor :default_timezone, :instance_writer => false @@default_timezone = :local + ## + # :singleton-method: # Specifies the format to use when dumping the database schema with Rails' # Rakefile. If :sql, the schema is dumped as (potentially database- # specific) SQL statements. If :ruby, the schema is dumped as an @@ -487,6 +505,8 @@ module ActiveRecord #:nodoc: cattr_accessor :schema_format , :instance_writer => false @@schema_format = :ruby + ## + # :singleton-method: # Specify whether or not to use timestamps for migration numbers cattr_accessor :timestamped_migrations , :instance_writer => false @@timestamped_migrations = true @@ -2023,8 +2043,7 @@ module ActiveRecord #:nodoc: end def scoped_methods #:nodoc: - scoped_methods = (Thread.current[:scoped_methods] ||= {}) - scoped_methods[self] ||= [] + Thread.current[:"#{self}_scoped_methods"] ||= [] end def current_scoped_methods #:nodoc: diff --git a/activerecord/lib/active_record/calculations.rb b/activerecord/lib/active_record/calculations.rb index 5e33cf1bd4..65512d534a 100644 --- a/activerecord/lib/active_record/calculations.rb +++ b/activerecord/lib/active_record/calculations.rb @@ -286,7 +286,7 @@ module ActiveRecord case operation when 'count' then value.to_i when 'sum' then type_cast_using_column(value || '0', column) - when 'avg' then value && value.to_d + when 'avg' then value && (value.is_a?(Fixnum) ? value.to_f : value).to_d else type_cast_using_column(value, column) end end 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 3016c329bd..901b17124c 100644 --- a/activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb +++ b/activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb @@ -65,15 +65,23 @@ module ActiveRecord # The default ConnectionPool maximum size is 5. def initialize(spec) @spec = spec + # The cache of reserved connections mapped to threads @reserved_connections = {} + # The mutex used to synchronize pool access @connection_mutex = Monitor.new @queue = @connection_mutex.new_cond - # default 5 second timeout - @timeout = spec.config[:wait_timeout] || 5 + + # default 5 second timeout unless on ruby 1.9 + @timeout = + if RUBY_VERSION < '1.9' + spec.config[:wait_timeout] || 5 + end + # default max pool size to 5 @size = (spec.config[:pool] && spec.config[:pool].to_i) || 5 + @connections = [] @checked_out = [] end @@ -187,7 +195,7 @@ module ActiveRecord # try looting dead threads clear_stale_cached_connections! if @size == @checked_out.size - raise ConnectionTimeoutError, "could not obtain a database connection within #{@timeout} seconds. The pool size is currently #{@size}, perhaps you need to increase it?" + raise ConnectionTimeoutError, "could not obtain a database connection#{" within #{@timeout} seconds" if @timeout}. The max pool size is currently #{@size}; consider increasing it." end end end @@ -292,10 +300,7 @@ module ActiveRecord # and also returns connections to the pool cached by threads that are no # longer alive. def clear_active_connections! - @connection_pools.each_value do |pool| - pool.release_connection - pool.clear_stale_cached_connections! - end + @connection_pools.each_value {|pool| pool.release_connection } end # Clears the cache which maps classes @@ -324,7 +329,8 @@ module ActiveRecord # Returns true if a connection that's accessible to this class has # already been opened. def connected?(klass) - conn = retrieve_connection_pool(klass) ? conn.connected? : false + conn = retrieve_connection_pool(klass) + conn ? conn.connected? : false end # Remove the connection for this class. This will close the active diff --git a/activerecord/lib/active_record/connection_adapters/abstract/connection_specification.rb b/activerecord/lib/active_record/connection_adapters/abstract/connection_specification.rb index a968fc0fd3..ccb79f547a 100644 --- a/activerecord/lib/active_record/connection_adapters/abstract/connection_specification.rb +++ b/activerecord/lib/active_record/connection_adapters/abstract/connection_specification.rb @@ -7,6 +7,8 @@ module ActiveRecord end end + ## + # :singleton-method: # The connection handler cattr_accessor :connection_handler, :instance_writer => false @@connection_handler = ConnectionAdapters::ConnectionHandler.new diff --git a/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb b/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb index c5183357a1..f8fa969dc3 100755 --- a/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb +++ b/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb @@ -125,9 +125,8 @@ module ActiveRecord end # Returns true if its safe to reload the connection between requests for development mode. - # This is not the case for Ruby/MySQL and it's not necessary for any adapters except SQLite. def requires_reloading? - false + true end # Checks whether the connection to the database is still active (i.e. not stale). diff --git a/activerecord/lib/active_record/connection_adapters/mysql_adapter.rb b/activerecord/lib/active_record/connection_adapters/mysql_adapter.rb index 1e452ae88a..c3cbdc8c2f 100644 --- a/activerecord/lib/active_record/connection_adapters/mysql_adapter.rb +++ b/activerecord/lib/active_record/connection_adapters/mysql_adapter.rb @@ -156,13 +156,16 @@ module ActiveRecord # * <tt>:sslcapath</tt> - Necessary to use MySQL with an SSL connection. # * <tt>:sslcipher</tt> - Necessary to use MySQL with an SSL connection. # - # By default, the MysqlAdapter will consider all columns of type <tt>tinyint(1)</tt> - # as boolean. If you wish to disable this emulation (which was the default - # behavior in versions 0.13.1 and earlier) you can add the following line - # to your environment.rb file: - # - # ActiveRecord::ConnectionAdapters::MysqlAdapter.emulate_booleans = false class MysqlAdapter < AbstractAdapter + + ## + # :singleton-method: + # By default, the MysqlAdapter will consider all columns of type <tt>tinyint(1)</tt> + # as boolean. If you wish to disable this emulation (which was the default + # behavior in versions 0.13.1 and earlier) you can add the following line + # to your environment.rb file: + # + # ActiveRecord::ConnectionAdapters::MysqlAdapter.emulate_booleans = false cattr_accessor :emulate_booleans self.emulate_booleans = true diff --git a/activerecord/lib/active_record/migration.rb b/activerecord/lib/active_record/migration.rb index 1d843fff28..15350cf1e1 100644 --- a/activerecord/lib/active_record/migration.rb +++ b/activerecord/lib/active_record/migration.rb @@ -130,7 +130,9 @@ module ActiveRecord # To run migrations against the currently configured database, use # <tt>rake db:migrate</tt>. This will update the database by running all of the # pending migrations, creating the <tt>schema_migrations</tt> table - # (see "About the schema_migrations table" section below) if missing. + # (see "About the schema_migrations table" section below) if missing. It will also + # invoke the db:schema:dump task, which will update your db/schema.rb file + # to match the structure of your database. # # To roll the database back to a previous migration version, use # <tt>rake db:migrate VERSION=X</tt> where <tt>X</tt> is the version to which diff --git a/activerecord/lib/active_record/schema_dumper.rb b/activerecord/lib/active_record/schema_dumper.rb index 2181bdf2dd..557a554966 100644 --- a/activerecord/lib/active_record/schema_dumper.rb +++ b/activerecord/lib/active_record/schema_dumper.rb @@ -7,6 +7,8 @@ module ActiveRecord class SchemaDumper #:nodoc: private_class_method :new + ## + # :singleton-method: # A list of tables which should not be dumped to the schema. # Acceptable values are strings as well as regexp. # This setting is only used if ActiveRecord::Base.schema_format == :ruby diff --git a/activerecord/lib/active_record/version.rb b/activerecord/lib/active_record/version.rb index 2479b75789..3c5a9b7df8 100644 --- a/activerecord/lib/active_record/version.rb +++ b/activerecord/lib/active_record/version.rb @@ -2,7 +2,7 @@ module ActiveRecord module VERSION #:nodoc: MAJOR = 2 MINOR = 2 - TINY = 0 + TINY = 1 STRING = [MAJOR, MINOR, TINY].join('.') end diff --git a/activerecord/test/cases/associations/has_and_belongs_to_many_associations_test.rb b/activerecord/test/cases/associations/has_and_belongs_to_many_associations_test.rb index 2949f1d304..b5bedf3704 100644 --- a/activerecord/test/cases/associations/has_and_belongs_to_many_associations_test.rb +++ b/activerecord/test/cases/associations/has_and_belongs_to_many_associations_test.rb @@ -68,6 +68,16 @@ class DeveloperWithSymbolsForKeys < ActiveRecord::Base :foreign_key => "developer_id" end +class DeveloperWithCounterSQL < ActiveRecord::Base + set_table_name 'developers' + has_and_belongs_to_many :projects, + :class_name => "DeveloperWithCounterSQL", + :join_table => "developers_projects", + :association_foreign_key => "project_id", + :foreign_key => "developer_id", + :counter_sql => 'SELECT COUNT(*) AS count_all FROM projects INNER JOIN developers_projects ON projects.id = developers_projects.project_id WHERE developers_projects.developer_id =#{id}' +end + class HasAndBelongsToManyAssociationsTest < ActiveRecord::TestCase fixtures :accounts, :companies, :categories, :posts, :categories_posts, :developers, :projects, :developers_projects, :parrots, :pirates, :treasures, :price_estimates, :tags, :taggings @@ -739,6 +749,19 @@ class HasAndBelongsToManyAssociationsTest < ActiveRecord::TestCase assert_nothing_raised { david.projects.count(:all, :conditions => '1=1') } end + def test_count + david = Developer.find(1) + assert_equal 2, david.projects.count + end + + def test_count_with_counter_sql + developer = DeveloperWithCounterSQL.create(:name => 'tekin') + developer.project_ids = [projects(:active_record).id] + developer.save + developer.reload + assert_equal 1, developer.projects.count + end + uses_mocha 'mocking Post.transaction' do def test_association_proxy_transaction_method_starts_transaction_in_association_class Post.expects(:transaction) diff --git a/activerecord/test/cases/calculations_test.rb b/activerecord/test/cases/calculations_test.rb index 0fa61500c0..8bd0dd0f6e 100644 --- a/activerecord/test/cases/calculations_test.rb +++ b/activerecord/test/cases/calculations_test.rb @@ -25,6 +25,11 @@ class CalculationsTest < ActiveRecord::TestCase def test_should_return_nil_as_average assert_nil NumericData.average(:bank_balance) end + + def test_type_cast_calculated_value_should_convert_db_averages_of_fixnum_class_to_decimal + assert_equal 0, NumericData.send(:type_cast_calculated_value, 0, nil, 'avg') + assert_equal 53.0, NumericData.send(:type_cast_calculated_value, 53, nil, 'avg') + end def test_should_get_maximum_of_field assert_equal 60, Account.maximum(:credit_limit) diff --git a/activerecord/test/cases/pooled_connections_test.rb b/activerecord/test/cases/pooled_connections_test.rb index 3e8c617a89..2649a9358a 100644 --- a/activerecord/test/cases/pooled_connections_test.rb +++ b/activerecord/test/cases/pooled_connections_test.rb @@ -28,10 +28,13 @@ class PooledConnectionsTest < ActiveRecord::TestCase end end - def test_pooled_connection_checkout - checkout_connections - assert_equal @connections.length, 2 - assert_equal @timed_out, 2 + # Will deadlock due to lack of Monitor timeouts in 1.9 + if RUBY_VERSION < '1.9' + def test_pooled_connection_checkout + checkout_connections + assert_equal @connections.length, 2 + assert_equal @timed_out, 2 + end end def checkout_checkin_connections(pool_size, threads) @@ -74,6 +77,11 @@ class PooledConnectionsTest < ActiveRecord::TestCase conn_pool.checkin(conn) end + def test_not_connected_defined_connection_returns_false + ActiveRecord::Base.establish_connection(@connection) + assert ! ActiveRecord::Base.connected? + end + def test_undefined_connection_returns_false old_handler = ActiveRecord::Base.connection_handler ActiveRecord::Base.connection_handler = ActiveRecord::ConnectionAdapters::ConnectionHandler.new |