class HerokuExternalDb::Configuration
Represents an ActiveRecord database configuration to be used in a Heroku app. This configuration consists of at least one environment variable, and possibly several:
-
[PREFIX]_DATABASE_URL
- the Heroku-style DATABASE_URL to connect to. Required. -
[PREFIX]_DATABASE_CA
- the filename of a SSL certificate file which will be configured as the :sslca for the database. Useful for encrypted MySQL, e.g.
Attributes
The ActiveRecord configuration that will be set up. Typically this should be the same as your RAILS_ENV
environment variable, but some apps may have multiple database connections with different names.
Each HerokuExternalDb
must have a unique prefix for its environment variables. For example, if the prefix was set to CRAZY
, then the database URL would be taken from CRAZY_DATABASE_URL
, and the CA filename would be taken from CRAZY_DATABASE_CA
, if it existed.
In typical usage, the prefix will be EXTERNAL
by default.
Public Class Methods
# File lib/heroku_external_db.rb, line 43 def initialize(env_prefix, configuration_name) @env_prefix = env_prefix @configuration_name = configuration_name end
Public Instance Methods
The path in which your SSL CA certificates are stored. By default, this is +[Rails app root]/config/ca+.
# File lib/heroku_external_db.rb, line 50 def ca_path @ca_path ||= ca_path_from_rails_root end
Returns an ActiveRecord configuration hash based on the environment variables.
# File lib/heroku_external_db.rb, line 103 def db_config @db_config ||= begin raise "ENV['#{env_prefix}_DATABASE_URL'] expected but not found!" unless ENV["#{env_prefix}_DATABASE_URL"] config = parse_db_uri(ENV["#{env_prefix}_DATABASE_URL"]) if ENV["#{env_prefix}_DATABASE_CA"] config.merge!(db_configuration({ :sslca => ENV["#{env_prefix}_DATABASE_CA"], :sslcert => ENV["#{env_prefix}_DATABASE_CERT"], :sslkey => ENV["#{env_prefix}_DATABASE_KEY"], })) end config end end
Returns a partial ActiveRecord configuration hash for the given SSL CA certificate. Checks to make sure the given filename actually exists, and raises an error if it does not.
# File lib/heroku_external_db.rb, line 79 def db_configuration(opts) return {} unless opts raise "ca_path for #{opts.inspect} cannot be determined from Rails root; please set it explicitly" unless ca_path config = {} [ :sslca, # Needed when using X.509 :sslcert, :sslkey, ].each do |k| if value = opts[k] filepath = File.join(ca_path, value) raise "File #{filepath.inspect} does not exist!" unless File.exists?(filepath) config[k] = filepath end end return config end
Parse a Heroku-style database URI and return an ActiveRecord configuration hash based on it. Format is as follows:
<adapter>://[<username>[:<password>]]@<host>[:<port>]/<database>
# File lib/heroku_external_db.rb, line 58 def parse_db_uri(db_uri) uri = URI.parse(db_uri) db_config = { :adapter => uri.scheme, :database => uri.path[1..-1], :host => uri.host } if uri.user db_config[:username] = uri.user db_config[:password] = uri.password if uri.password end db_config[:port] = uri.port if uri.port db_config end
Installs an ActiveRecord configuration based on the environment variables, and makes an initial connection to the database. (This flushes out the connection pool if a different connection has already been established, and tests to make sure we can actually connect.)
# File lib/heroku_external_db.rb, line 124 def setup! ActiveRecord::Base.configurations[configuration_name] = db_config ActiveRecord::Base.establish_connection(configuration_name).connection self end
Protected Instance Methods
# File lib/heroku_external_db.rb, line 131 def ca_path_from_rails_root if defined?(Rails) && Rails.respond_to?(:root) && Rails.root File.join(Rails.root, 'config', 'ca') end end