diff options
author | Jon Leighton <j@jonathanleighton.com> | 2011-12-18 23:35:25 +0000 |
---|---|---|
committer | Jon Leighton <j@jonathanleighton.com> | 2011-12-24 11:08:15 +0000 |
commit | 6af7192af59602e1cbb341b8bf3452afb344eff2 (patch) | |
tree | 7e02050aedff7fbd8cb916b20b9a27f71a0a559f /activerecord/lib | |
parent | b2c9ce341a1c907041f55461aefebb0321280cb5 (diff) | |
download | rails-6af7192af59602e1cbb341b8bf3452afb344eff2.tar.gz rails-6af7192af59602e1cbb341b8bf3452afb344eff2.tar.bz2 rails-6af7192af59602e1cbb341b8bf3452afb344eff2.zip |
I herd you like modules.
Diffstat (limited to 'activerecord/lib')
11 files changed, 99 insertions, 70 deletions
diff --git a/activerecord/lib/active_record/base.rb b/activerecord/lib/active_record/base.rb index 914709e761..e461e2ecc6 100644 --- a/activerecord/lib/active_record/base.rb +++ b/activerecord/lib/active_record/base.rb @@ -328,5 +328,7 @@ module ActiveRecord #:nodoc: # instances in the current object space. class Base include ActiveRecord::Model + + self.connection_handler = ConnectionAdapters::ConnectionHandler.new 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 401398c56b..f69a14f740 100644 --- a/activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb +++ b/activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb @@ -371,7 +371,12 @@ connection. For example: ActiveRecord::Base.connection.close pool = @class_to_pool[klass.name] return pool if pool return nil if ActiveRecord::Base == klass - retrieve_connection_pool klass.superclass + + if klass.superclass && klass.superclass < Model + retrieve_connection_pool klass.superclass + else + retrieve_connection_pool ActiveRecord::Base + end end end 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 7145dc0692..63e4020113 100644 --- a/activerecord/lib/active_record/connection_adapters/abstract/connection_specification.rb +++ b/activerecord/lib/active_record/connection_adapters/abstract/connection_specification.rb @@ -1,5 +1,7 @@ +require 'active_support/core_ext/module/delegation' + module ActiveRecord - class Base + module Core class ConnectionSpecification #:nodoc: attr_reader :config, :adapter_method def initialize (config, adapter_method) @@ -75,12 +77,6 @@ module ActiveRecord end end - ## - # :singleton-method: - # The connection handler - class_attribute :connection_handler, :instance_writer => false - self.connection_handler = ConnectionAdapters::ConnectionHandler.new - # Returns the connection currently associated with the class. This can # also be used to "borrow" the connection to do database work that isn't # easily done without going straight to SQL. @@ -88,53 +84,53 @@ module ActiveRecord self.class.connection end - # Establishes the connection to the database. Accepts a hash as input where - # the <tt>:adapter</tt> key must be specified with the name of a database adapter (in lower-case) - # example for regular databases (MySQL, Postgresql, etc): - # - # ActiveRecord::Base.establish_connection( - # :adapter => "mysql", - # :host => "localhost", - # :username => "myuser", - # :password => "mypass", - # :database => "somedatabase" - # ) - # - # Example for SQLite database: - # - # ActiveRecord::Base.establish_connection( - # :adapter => "sqlite", - # :database => "path/to/dbfile" - # ) - # - # Also accepts keys as strings (for parsing from YAML for example): - # - # ActiveRecord::Base.establish_connection( - # "adapter" => "sqlite", - # "database" => "path/to/dbfile" - # ) - # - # Or a URL: - # - # ActiveRecord::Base.establish_connection( - # "postgres://myuser:mypass@localhost/somedatabase" - # ) - # - # The exceptions AdapterNotSpecified, AdapterNotFound and ArgumentError - # may be returned on an error. - def self.establish_connection(spec = ENV["DATABASE_URL"]) - resolver = ConnectionSpecification::Resolver.new spec, configurations - spec = resolver.spec - - unless respond_to?(spec.adapter_method) - raise AdapterNotFound, "database configuration specifies nonexistent #{spec.config[:adapter]} adapter" - end + module ClassMethods + # Establishes the connection to the database. Accepts a hash as input where + # the <tt>:adapter</tt> key must be specified with the name of a database adapter (in lower-case) + # example for regular databases (MySQL, Postgresql, etc): + # + # ActiveRecord::Base.establish_connection( + # :adapter => "mysql", + # :host => "localhost", + # :username => "myuser", + # :password => "mypass", + # :database => "somedatabase" + # ) + # + # Example for SQLite database: + # + # ActiveRecord::Base.establish_connection( + # :adapter => "sqlite", + # :database => "path/to/dbfile" + # ) + # + # Also accepts keys as strings (for parsing from YAML for example): + # + # ActiveRecord::Base.establish_connection( + # "adapter" => "sqlite", + # "database" => "path/to/dbfile" + # ) + # + # Or a URL: + # + # ActiveRecord::Base.establish_connection( + # "postgres://myuser:mypass@localhost/somedatabase" + # ) + # + # The exceptions AdapterNotSpecified, AdapterNotFound and ArgumentError + # may be returned on an error. + def establish_connection(spec = ENV["DATABASE_URL"]) + resolver = ConnectionSpecification::Resolver.new spec, configurations + spec = resolver.spec + + unless respond_to?(spec.adapter_method) + raise AdapterNotFound, "database configuration specifies nonexistent #{spec.config[:adapter]} adapter" + end - remove_connection - connection_handler.establish_connection name, spec - end + remove_connection + connection_handler.establish_connection name, spec + end - class << self # Returns the connection currently associated with the class. This can # also be used to "borrow" the connection to do database work unrelated # to any of the specific Active Records. diff --git a/activerecord/lib/active_record/connection_adapters/mysql2_adapter.rb b/activerecord/lib/active_record/connection_adapters/mysql2_adapter.rb index 626571a948..e51796871a 100644 --- a/activerecord/lib/active_record/connection_adapters/mysql2_adapter.rb +++ b/activerecord/lib/active_record/connection_adapters/mysql2_adapter.rb @@ -4,9 +4,9 @@ gem 'mysql2', '~> 0.3.10' require 'mysql2' module ActiveRecord - class Base + module Core::ClassMethods # Establishes a connection to the database that's used by all Active Record objects. - def self.mysql2_connection(config) + def mysql2_connection(config) config[:username] = 'root' if config[:username].nil? if Mysql2::Client.const_defined? :FOUND_ROWS diff --git a/activerecord/lib/active_record/connection_adapters/mysql_adapter.rb b/activerecord/lib/active_record/connection_adapters/mysql_adapter.rb index f092edecda..3eec59b5a4 100644 --- a/activerecord/lib/active_record/connection_adapters/mysql_adapter.rb +++ b/activerecord/lib/active_record/connection_adapters/mysql_adapter.rb @@ -18,9 +18,9 @@ class Mysql end module ActiveRecord - class Base + module Core::ClassMethods # Establishes a connection to the database that's used by all Active Record objects. - def self.mysql_connection(config) # :nodoc: + def mysql_connection(config) # :nodoc: config = config.symbolize_keys host = config[:host] port = config[:port] diff --git a/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb b/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb index d7adcdc5d4..74a9be99bd 100644 --- a/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb +++ b/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb @@ -7,9 +7,9 @@ gem 'pg', '~> 0.11' require 'pg' module ActiveRecord - class Base + module Core::ClassMethods # Establishes a connection to the database that's used by all Active Record objects - def self.postgresql_connection(config) # :nodoc: + def postgresql_connection(config) # :nodoc: config = config.symbolize_keys host = config[:host] port = config[:port] || 5432 @@ -876,7 +876,7 @@ module ActiveRecord # add info on sort order for columns (only desc order is explicitly specified, asc is the default) desc_order_columns = inddef.scan(/(\w+) DESC/).flatten orders = desc_order_columns.any? ? Hash[desc_order_columns.map {|order_column| [order_column, :desc]}] : {} - + column_names.empty? ? nil : IndexDefinition.new(table_name, index_name, unique, column_names, [], orders) end.compact end diff --git a/activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb b/activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb index 11bb457d03..ac3fb72b6e 100644 --- a/activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb +++ b/activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb @@ -4,9 +4,9 @@ gem 'sqlite3', '~> 1.3.5' require 'sqlite3' module ActiveRecord - class Base + module Core::ClassMethods # sqlite3 adapter reuses sqlite_connection. - def self.sqlite3_connection(config) # :nodoc: + def sqlite3_connection(config) # :nodoc: # Require database. unless config[:database] raise ArgumentError, "No database file specified. Missing argument: database" diff --git a/activerecord/lib/active_record/core.rb b/activerecord/lib/active_record/core.rb index dfd239a998..84ac6dd93d 100644 --- a/activerecord/lib/active_record/core.rb +++ b/activerecord/lib/active_record/core.rb @@ -65,6 +65,11 @@ module ActiveRecord # Specify whether or not to use timestamps for migration versions cattr_accessor :timestamped_migrations , :instance_writer => false self.timestamped_migrations = true + + ## + # :singleton-method: + # The connection handler + class_attribute :connection_handler, :instance_writer => false end module ClassMethods @@ -111,7 +116,13 @@ module ActiveRecord if self == ActiveRecord::Base ActiveRecord::Base else - connection_handler.connection_pools[name] ? self : superclass.arel_engine + if connection_handler.connection_pools[name] + self + elsif superclass < ActiveRecord::Model + superclass.arel_engine + else + ActiveRecord::Base + end end end end diff --git a/activerecord/lib/active_record/inheritance.rb b/activerecord/lib/active_record/inheritance.rb index de9461982a..9b73c0d33c 100644 --- a/activerecord/lib/active_record/inheritance.rb +++ b/activerecord/lib/active_record/inheritance.rb @@ -13,7 +13,9 @@ module ActiveRecord module ClassMethods # True if this isn't a concrete subclass needing a STI type condition. def descends_from_active_record? - if superclass.abstract_class? + if !(superclass < Model) + true + elsif superclass.abstract_class? superclass.descends_from_active_record? else superclass == Base || !columns_hash.include?(inheritance_column) @@ -84,10 +86,14 @@ module ActiveRecord # Returns the class descending directly from ActiveRecord::Base or an # abstract class, if any, in the inheritance hierarchy. def class_of_active_record_descendant(klass) - if klass == Base || klass.superclass == Base || klass.superclass.abstract_class? - klass - elsif klass.superclass.nil? + unless klass < Model::Tag raise ActiveRecordError, "#{name} doesn't belong in a hierarchy descending from ActiveRecord" + end + + if klass == Base || klass.superclass == Base || + klass.superclass < Model::Tag && klass.superclass.abstract_class? || + !(klass.superclass < Model::Tag) + klass else class_of_active_record_descendant(klass.superclass) end diff --git a/activerecord/lib/active_record/model.rb b/activerecord/lib/active_record/model.rb index 6643c3bf5a..9a8f7a93b6 100644 --- a/activerecord/lib/active_record/model.rb +++ b/activerecord/lib/active_record/model.rb @@ -1,7 +1,14 @@ module ActiveRecord module Model + # So we can recognise an AR class even while self.included is being + # executed. (At that time, klass < Model == false.) + module Tag #:nodoc: + end + def self.included(base) base.class_eval do + include Tag + include ActiveRecord::Persistence extend ActiveModel::Naming extend QueryCache::ClassMethods @@ -35,10 +42,12 @@ module ActiveRecord include Aggregations, Transactions, Reflection, Serialization, Store include Core + + self.connection_handler = ActiveRecord::Base.connection_handler end end end end require 'active_record/connection_adapters/abstract/connection_specification' -ActiveSupport.run_load_hooks(:active_record, ActiveRecord::Base) +ActiveSupport.run_load_hooks(:active_record, ActiveRecord::Model) diff --git a/activerecord/lib/active_record/model_schema.rb b/activerecord/lib/active_record/model_schema.rb index 1de820b3a6..5fd0b12706 100644 --- a/activerecord/lib/active_record/model_schema.rb +++ b/activerecord/lib/active_record/model_schema.rb @@ -128,7 +128,7 @@ module ActiveRecord # Computes the table name, (re)sets it internally, and returns it. def reset_table_name #:nodoc: - if superclass.abstract_class? + if (superclass < ActiveRecord::Model) && superclass.abstract_class? self.table_name = superclass.table_name || compute_table_name elsif abstract_class? self.table_name = superclass == Base ? nil : superclass.table_name @@ -143,7 +143,7 @@ module ActiveRecord # The name of the column containing the object's class when Single Table Inheritance is used def inheritance_column - if self == Base + if self == Base || !(superclass < Model) 'type' else (@inheritance_column ||= nil) || superclass.inheritance_column |