Module: ActiveRecord::ConnectionHandling

Included in:
Base
Defined in:
lib/active_record/connection_adapters/mysql2_adapter.rb,
lib/active_record/connection_handling.rb,
lib/active_record/connection_adapters/sqlite3_adapter.rb,
lib/active_record/connection_adapters/postgresql_adapter.rb
more...

Overview

:nodoc:

Defined Under Namespace

Classes: MergeAndResolveDefaultUrlConfig

Constant Summary collapse

RAILS_ENV =
-> { (Rails.env if defined?(Rails.env)) || ENV["RAILS_ENV"].presence || ENV["RACK_ENV"].presence }
DEFAULT_ENV =
-> { RAILS_ENV.call || "default_env" }

Instance Attribute Summary collapse

Instance Method Summary collapse

Instance Attribute Details

#connection_specification_nameObject

Return the specification name from the current class or its parent.


96
97
98
99
100
101
# File 'lib/active_record/connection_handling.rb', line 96

def connection_specification_name
  if !defined?(@connection_specification_name) || @connection_specification_name.nil?
    return self == Base ? "primary" : superclass.connection_specification_name
  end
  @connection_specification_name
end

Instance Method Details

#clear_cache!Object

:nodoc:

[View source]

138
139
140
# File 'lib/active_record/connection_handling.rb', line 138

def clear_cache! # :nodoc:
  connection.schema_cache.clear!
end

#connected?Boolean

Returns true if Active Record is connected.

Returns:

  • (Boolean)
[View source]

122
123
124
# File 'lib/active_record/connection_handling.rb', line 122

def connected?
  connection_handler.connected?(connection_specification_name)
end

#connectionObject

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.

[View source]

89
90
91
# File 'lib/active_record/connection_handling.rb', line 89

def connection
  retrieve_connection
end

#connection_configObject

Returns the configuration of the associated connection as a hash:

ActiveRecord::Base.connection_config
# => {pool: 5, timeout: 5000, database: "db/development.sqlite3", adapter: "sqlite3"}

Please use only for reading.

[View source]

109
110
111
# File 'lib/active_record/connection_handling.rb', line 109

def connection_config
  connection_pool.spec.config
end

#connection_poolObject

[View source]

113
114
115
# File 'lib/active_record/connection_handling.rb', line 113

def connection_pool
  connection_handler.retrieve_connection_pool(connection_specification_name) || raise(ConnectionNotEstablished)
end

#establish_connection(config = nil) ⇒ Object

Establishes the connection to the database. Accepts a hash as input where the :adapter 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:  "mysql2",
  host:     "localhost",
  username: "myuser",
  password: "mypass",
  database: "somedatabase"
)

Example for SQLite database:

ActiveRecord::Base.establish_connection(
  adapter:  "sqlite3",
  database: "path/to/dbfile"
)

Also accepts keys as strings (for parsing from YAML for example):

ActiveRecord::Base.establish_connection(
  "adapter"  => "sqlite3",
  "database" => "path/to/dbfile"
)

Or a URL:

ActiveRecord::Base.establish_connection(
  "postgres://myuser:mypass@localhost/somedatabase"
)

In case ActiveRecord::Base.configurations is set (Rails automatically loads the contents of config/database.yml into it), a symbol can also be given as argument, representing a key in the configuration hash:

ActiveRecord::Base.establish_connection(:production)

The exceptions AdapterNotSpecified, AdapterNotFound and ArgumentError may be returned on an error.

[View source]

49
50
51
52
53
54
55
56
57
58
59
60
61
# File 'lib/active_record/connection_handling.rb', line 49

def establish_connection(config = nil)
  raise "Anonymous class is not allowed." unless name

  config ||= DEFAULT_ENV.call.to_sym
  spec_name = self == Base ? "primary" : name
  self.connection_specification_name = spec_name

  resolver = ConnectionAdapters::ConnectionSpecification::Resolver.new(Base.configurations)
  spec = resolver.resolve(config).symbolize_keys
  spec[:name] = spec_name

  connection_handler.establish_connection(spec)
end

#mysql2_connection(config) ⇒ Object

Establishes a connection to the database that's used by all Active Record objects.

[View source]

12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
# File 'lib/active_record/connection_adapters/mysql2_adapter.rb', line 12

def mysql2_connection(config)
  config = config.symbolize_keys
  config[:flags] ||= 0

  if config[:flags].kind_of? Array
    config[:flags].push "FOUND_ROWS".freeze
  else
    config[:flags] |= Mysql2::Client::FOUND_ROWS
  end

  client = Mysql2::Client.new(config)
  ConnectionAdapters::Mysql2Adapter.new(client, logger, nil, config)
rescue Mysql2::Error => error
  if error.message.include?("Unknown database")
    raise ActiveRecord::NoDatabaseError
  else
    raise
  end
end

#postgresql_connection(config) ⇒ Object

Establishes a connection to the database that's used by all Active Record objects

[View source]

33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
# File 'lib/active_record/connection_adapters/postgresql_adapter.rb', line 33

def postgresql_connection(config)
  conn_params = config.symbolize_keys

  conn_params.delete_if { |_, v| v.nil? }

  # Map ActiveRecords param names to PGs.
  conn_params[:user] = conn_params.delete(:username) if conn_params[:username]
  conn_params[:dbname] = conn_params.delete(:database) if conn_params[:database]

  # Forward only valid config params to PG::Connection.connect.
  valid_conn_param_keys = PG::Connection.conndefaults_hash.keys + [:requiressl]
  conn_params.slice!(*valid_conn_param_keys)

  # The postgres drivers don't allow the creation of an unconnected PG::Connection object,
  # so just pass a nil connection object for the time being.
  ConnectionAdapters::PostgreSQLAdapter.new(nil, logger, conn_params, config)
end

#remove_connection(name = nil) ⇒ Object

[View source]

126
127
128
129
130
131
132
133
134
135
136
# File 'lib/active_record/connection_handling.rb', line 126

def remove_connection(name = nil)
  name ||= @connection_specification_name if defined?(@connection_specification_name)
  # if removing a connection that has a pool, we reset the
  # connection_specification_name so it will use the parent
  # pool.
  if connection_handler.retrieve_connection_pool(name)
    self.connection_specification_name = nil
  end

  connection_handler.remove_connection(name)
end

#retrieve_connectionObject

[View source]

117
118
119
# File 'lib/active_record/connection_handling.rb', line 117

def retrieve_connection
  connection_handler.retrieve_connection(connection_specification_name)
end

#sqlite3_connection(config) ⇒ Object

[View source]

17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
# File 'lib/active_record/connection_adapters/sqlite3_adapter.rb', line 17

def sqlite3_connection(config)
  # Require database.
  unless config[:database]
    raise ArgumentError, "No database file specified. Missing argument: database"
  end

  # Allow database path relative to Rails.root, but only if the database
  # path is not the special path that tells sqlite to build a database only
  # in memory.
  if ":memory:" != config[:database]
    config[:database] = File.expand_path(config[:database], Rails.root) if defined?(Rails.root)
    dirname = File.dirname(config[:database])
    Dir.mkdir(dirname) unless File.directory?(dirname)
  end

  db = SQLite3::Database.new(
    config[:database].to_s,
    results_as_hash: true
  )

  db.busy_timeout(ConnectionAdapters::SQLite3Adapter.type_cast_config_to_integer(config[:timeout])) if config[:timeout]

  ConnectionAdapters::SQLite3Adapter.new(db, logger, nil, config)
rescue Errno::ENOENT => error
  if error.message.include?("No such file or directory")
    raise ActiveRecord::NoDatabaseError
  else
    raise
  end
end