Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Newer
Older
100644 189 lines (161 sloc) 6.119 kb
b3df959 @dhh Refactored the AbstractAdapter to be a lot less scary. Cleaned up the do...
dhh authored
1 module ActiveRecord
2 class Base
3 class ConnectionSpecification #:nodoc:
4 attr_reader :config, :adapter_method
5 def initialize (config, adapter_method)
6 @config, @adapter_method = config, adapter_method
7 end
dde2113 @tenderlove Move connection resoluion logic to it's own testable class.
tenderlove authored
8
9 ##
10 # Builds a ConnectionSpecification from user input
11 class Resolver # :nodoc:
12 attr_reader :config, :klass, :configurations
13
f73f534 @tenderlove respond_to? information of AR is not the responsibility of the spec
tenderlove authored
14 def initialize(config, configurations)
dde2113 @tenderlove Move connection resoluion logic to it's own testable class.
tenderlove authored
15 @config = config
16 @configurations = configurations
17 end
18
19 def spec
20 case config
21 when nil
22 raise AdapterNotSpecified unless defined?(Rails.env)
23 resolve_string_connection Rails.env
24 when Symbol, String
25 resolve_string_connection config.to_s
26 when Hash
27 resolve_hash_connection config
28 end
29 end
30
31 private
32 def resolve_string_connection(spec) # :nodoc:
33 hash = configurations.fetch(spec) do |k|
34 connection_url_to_hash(k)
35 end
36
37 raise(AdapterNotSpecified, "#{spec} database is not configured") unless hash
38
39 resolve_hash_connection hash
40 end
41
42 def resolve_hash_connection(spec) # :nodoc:
43 spec = spec.symbolize_keys
44
45 raise(AdapterNotSpecified, "database configuration does not specify adapter") unless spec.key?(:adapter)
46
47 begin
48 require "active_record/connection_adapters/#{spec[:adapter]}_adapter"
49 rescue LoadError => e
50 raise LoadError, "Please install the #{spec[:adapter]} adapter: `gem install activerecord-#{spec[:adapter]}-adapter` (#{e.message})", e.backtrace
51 end
52
53 adapter_method = "#{spec[:adapter]}_connection"
54
55 ConnectionSpecification.new(spec, adapter_method)
56 end
57
58 def connection_url_to_hash(url) # :nodoc:
59 config = URI.parse url
60 adapter = config.scheme
61 adapter = "postgresql" if adapter == "postgres"
62 spec = { :adapter => adapter,
63 :username => config.user,
64 :password => config.password,
65 :port => config.port,
66 :database => config.path.sub(%r{^/},""),
67 :host => config.host }
68 spec.reject!{ |_,value| !value }
69 if config.query
70 options = Hash[config.query.split("&").map{ |pair| pair.split("=") }].symbolize_keys
71 spec.merge!(options)
72 end
73 spec
74 end
75 end
b3df959 @dhh Refactored the AbstractAdapter to be a lot less scary. Cleaned up the do...
dhh authored
76 end
77
dbbae5e @lifo Merge with docrails
lifo authored
78 ##
79 # :singleton-method:
ff97e9d @nicksieger Connection handling methods extracted out into separate ConnectionHandle...
nicksieger authored
80 # The connection handler
788684d @rubys get the rescue error page back [#4536 state:resolved]
rubys authored
81 class_attribute :connection_handler, :instance_writer => false
841c01f @lifo Use class_inheritable_accessor for connection_handler
lifo authored
82 self.connection_handler = ConnectionAdapters::ConnectionHandler.new
7568f18 @jeremy Clear stale, cached connections left behind by defunct threads. Eliminat...
jeremy authored
83
3ed6675 @jeremy Clear the connection cache entry when a new connection is established on...
jeremy authored
84 # Returns the connection currently associated with the class. This can
85 # also be used to "borrow" the connection to do database work that isn't
86 # easily done without going straight to SQL.
87 def connection
88 self.class.connection
89 end
90
b3df959 @dhh Refactored the AbstractAdapter to be a lot less scary. Cleaned up the do...
dhh authored
91 # Establishes the connection to the database. Accepts a hash as input where
64092de @fxn Improve documentation coverage and markup
fxn authored
92 # the <tt>:adapter</tt> key must be specified with the name of a database adapter (in lower-case)
b3df959 @dhh Refactored the AbstractAdapter to be a lot less scary. Cleaned up the do...
dhh authored
93 # example for regular databases (MySQL, Postgresql, etc):
94 #
95 # ActiveRecord::Base.establish_connection(
96 # :adapter => "mysql",
97 # :host => "localhost",
98 # :username => "myuser",
99 # :password => "mypass",
100 # :database => "somedatabase"
101 # )
102 #
103 # Example for SQLite database:
104 #
105 # ActiveRecord::Base.establish_connection(
106 # :adapter => "sqlite",
c21fdf3 @dhh Changed :dbfile to :database for SQLite adapter for consistency (old key...
dhh authored
107 # :database => "path/to/dbfile"
b3df959 @dhh Refactored the AbstractAdapter to be a lot less scary. Cleaned up the do...
dhh authored
108 # )
109 #
98dc582 @lifo Merge docrails.
lifo authored
110 # Also accepts keys as strings (for parsing from YAML for example):
64092de @fxn Improve documentation coverage and markup
fxn authored
111 #
b3df959 @dhh Refactored the AbstractAdapter to be a lot less scary. Cleaned up the do...
dhh authored
112 # ActiveRecord::Base.establish_connection(
113 # "adapter" => "sqlite",
c21fdf3 @dhh Changed :dbfile to :database for SQLite adapter for consistency (old key...
dhh authored
114 # "database" => "path/to/dbfile"
b3df959 @dhh Refactored the AbstractAdapter to be a lot less scary. Cleaned up the do...
dhh authored
115 # )
116 #
1f427b5 @glenngillen Add documentation for URL connection strings.
glenngillen authored
117 # Or a URL:
118 #
a277886 @vijaydev Fixes typo
vijaydev authored
119 # ActiveRecord::Base.establish_connection(
1f427b5 @glenngillen Add documentation for URL connection strings.
glenngillen authored
120 # "postgres://myuser:mypass@localhost/somedatabase"
121 # )
122 #
b3df959 @dhh Refactored the AbstractAdapter to be a lot less scary. Cleaned up the do...
dhh authored
123 # The exceptions AdapterNotSpecified, AdapterNotFound and ArgumentError
124 # may be returned on an error.
4605b56 @glenngillen Simplify the way default DATABASE_URL works.
glenngillen authored
125 def self.establish_connection(spec = ENV["DATABASE_URL"])
f73f534 @tenderlove respond_to? information of AR is not the responsibility of the spec
tenderlove authored
126 resolver = ConnectionSpecification::Resolver.new spec, configurations
127 spec = resolver.spec
128
129 unless respond_to?(spec.adapter_method)
8c26cd5 @tenderlove Exceptions should read from the spec configu
tenderlove authored
130 raise AdapterNotFound, "database configuration specifies nonexistent #{spec.config[:adapter]} adapter"
f73f534 @tenderlove respond_to? information of AR is not the responsibility of the spec
tenderlove authored
131 end
132
2a9a8ad @tenderlove break establish_connection to smaller methods
tenderlove authored
133 remove_connection
f73f534 @tenderlove respond_to? information of AR is not the responsibility of the spec
tenderlove authored
134 connection_handler.establish_connection name, spec
89357c8 @glenngillen Provide database connection settings as a URL.
glenngillen authored
135 end
136
ff97e9d @nicksieger Connection handling methods extracted out into separate ConnectionHandle...
nicksieger authored
137 class << self
138 # Returns the connection currently associated with the class. This can
139 # also be used to "borrow" the connection to do database work unrelated
140 # to any of the specific Active Records.
141 def connection
142 retrieve_connection
143 end
7568f18 @jeremy Clear stale, cached connections left behind by defunct threads. Eliminat...
jeremy authored
144
f41b58d @mjtko use thread locals and an instance variable within QueryCache#BodyProxy t...
mjtko authored
145 def connection_id
146 Thread.current['ActiveRecord::Base.connection_id']
147 end
148
149 def connection_id=(connection_id)
150 Thread.current['ActiveRecord::Base.connection_id'] = connection_id
151 end
152
3b10b8a @fxn implements ActiveRecord::Base.connection_config to be able to check the ...
fxn authored
153 # Returns the configuration of the associated connection as a hash:
154 #
155 # ActiveRecord::Base.connection_config
156 # # => {:pool=>5, :timeout=>5000, :database=>"db/development.sqlite3", :adapter=>"sqlite3"}
157 #
158 # Please use only for reading.
159 def connection_config
160 connection_pool.spec.config
161 end
162
fe575dd @nicksieger Nearing the finish line. Initial fixed-size connection pool implemented,...
nicksieger authored
163 def connection_pool
4edf6ea @tenderlove Merge pull request #2897 from rsutphin/ar31-remove_connection
tenderlove authored
164 connection_handler.retrieve_connection_pool(self) or raise ConnectionNotEstablished
fe575dd @nicksieger Nearing the finish line. Initial fixed-size connection pool implemented,...
nicksieger authored
165 end
166
ff97e9d @nicksieger Connection handling methods extracted out into separate ConnectionHandle...
nicksieger authored
167 def retrieve_connection
168 connection_handler.retrieve_connection(self)
169 end
b3df959 @dhh Refactored the AbstractAdapter to be a lot less scary. Cleaned up the do...
dhh authored
170
f17159b @fxn edit pass: the names of Rails components have a space, ie, "Active Recor...
fxn authored
171 # Returns true if Active Record is connected.
ff97e9d @nicksieger Connection handling methods extracted out into separate ConnectionHandle...
nicksieger authored
172 def connected?
173 connection_handler.connected?(self)
174 end
b3df959 @dhh Refactored the AbstractAdapter to be a lot less scary. Cleaned up the do...
dhh authored
175
72d959d @nicksieger Split connection handler into single- and multiple-thread versions.
nicksieger authored
176 def remove_connection(klass = self)
ff97e9d @nicksieger Connection handling methods extracted out into separate ConnectionHandle...
nicksieger authored
177 connection_handler.remove_connection(klass)
178 end
50cd4bd @nicksieger Introduce synchronization around connection pool access
nicksieger authored
179
aea1477 @tenderlove make sure we have an active database connection before running each conn...
tenderlove authored
180 def clear_active_connections!
181 connection_handler.clear_active_connections!
182 end
183
184 delegate :clear_reloadable_connections!,
d07a6b1 @nicksieger Make clear_active_connections! also return stale connections back to the...
nicksieger authored
185 :clear_all_connections!,:verify_active_connections!, :to => :connection_handler
50cd4bd @nicksieger Introduce synchronization around connection pool access
nicksieger authored
186 end
b3df959 @dhh Refactored the AbstractAdapter to be a lot less scary. Cleaned up the do...
dhh authored
187 end
f98ec35 @jeremy Get rid of old symbolize_strings_in_hash.
jeremy authored
188 end
Something went wrong with that request. Please try again.