aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord/lib/active_record/connection_handling.rb
diff options
context:
space:
mode:
authorArthur Neves <arthurnn@gmail.com>2016-05-04 00:46:38 -0500
committerArthur Neves <arthurnn@gmail.com>2016-05-05 15:29:11 -0500
commitb83fb847337b690ebbc96c55414157f71bbf8aa2 (patch)
tree63dbbbcdcad26fc4b69925578bd8a7e2d3a1f687 /activerecord/lib/active_record/connection_handling.rb
parent3bed679670dd8348ffc348509a653677c6ecb7f3 (diff)
downloadrails-b83fb847337b690ebbc96c55414157f71bbf8aa2.tar.gz
rails-b83fb847337b690ebbc96c55414157f71bbf8aa2.tar.bz2
rails-b83fb847337b690ebbc96c55414157f71bbf8aa2.zip
Refactor connection handler
ConnectionHandler will not have any knowlodge of AR models now, it will only know about the specs. Like that we can decouple the two, and allow the same model to use more than one connection. Historically, folks used to create abstract AR classes on the fly in order to have multiple connections for the same model, and override the connection methods. With this, now we can override the `specificiation_id` method in the model, to return a key, that will be used to find the connection_pool from the handler.
Diffstat (limited to 'activerecord/lib/active_record/connection_handling.rb')
-rw-r--r--activerecord/lib/active_record/connection_handling.rb34
1 files changed, 27 insertions, 7 deletions
diff --git a/activerecord/lib/active_record/connection_handling.rb b/activerecord/lib/active_record/connection_handling.rb
index a8b3d03ba5..c54b8adc4e 100644
--- a/activerecord/lib/active_record/connection_handling.rb
+++ b/activerecord/lib/active_record/connection_handling.rb
@@ -45,16 +45,19 @@ module ActiveRecord
# The exceptions AdapterNotSpecified, AdapterNotFound and +ArgumentError+
# may be returned on an error.
def establish_connection(spec = nil)
+ raise RuntimeError, "Anonymous class is not allowed." unless name
+
spec ||= DEFAULT_ENV.call.to_sym
resolver = ConnectionAdapters::ConnectionSpecification::Resolver.new configurations
- spec = resolver.spec(spec)
+ spec = resolver.spec(spec, self == Base ? "primary" : name)
+ self.specification_id = spec.id
unless respond_to?(spec.adapter_method)
raise AdapterNotFound, "database configuration specifies nonexistent #{spec.config[:adapter]} adapter"
end
remove_connection
- connection_handler.establish_connection self, spec
+ connection_handler.establish_connection spec
end
class MergeAndResolveDefaultUrlConfig # :nodoc:
@@ -87,6 +90,23 @@ module ActiveRecord
retrieve_connection
end
+ def specification_id=(value)
+ @specification_id = value
+ end
+
+ def specification_id(fallback = true)
+ return @specification_id if defined?(@specification_id)
+ find_legacy_spec_id(self) if fallback
+ end
+
+ def find_legacy_spec_id(klass)
+ return "primary" if klass == Base
+ if id = klass.specification_id(false)
+ return id
+ end
+ find_legacy_spec_id(klass.superclass)
+ end
+
def connection_id
ActiveRecord::RuntimeRegistry.connection_id ||= Thread.current.object_id
end
@@ -106,20 +126,20 @@ module ActiveRecord
end
def connection_pool
- connection_handler.retrieve_connection_pool(self) or raise ConnectionNotEstablished
+ connection_handler.retrieve_connection_pool(specification_id) or raise ConnectionNotEstablished
end
def retrieve_connection
- connection_handler.retrieve_connection(self)
+ connection_handler.retrieve_connection(specification_id)
end
# Returns +true+ if Active Record is connected.
def connected?
- connection_handler.connected?(self)
+ connection_handler.connected?(specification_id)
end
- def remove_connection(klass = self)
- connection_handler.remove_connection(klass)
+ def remove_connection(id = specification_id)
+ connection_handler.remove_connection(id)
end
def clear_cache! # :nodoc: