mirror of https://github.com/rails/rails
Refactor lookup of connection adapters
Right now adapters have to expose a rather byzantine API: - They must be defined in `active_record/connection_adapters/<name>_adapter` - They must define `ConnectionHandling.<name>_adapter_class` - They must define `ConnectionHandling.<name>_connection` All this is not very DRY and a bit annoying. Additionally it makes it very hard to define aliases (e.g. `mysql` => `trilogy`), or to substitute a default adapter for a specialized one. This refactor aims at making all this easier by exposing a simple `register` method, that third party adapters can call from a Railtie.
This commit is contained in:
parent
f98bb7ed41
commit
009c7e7411
|
@ -4,6 +4,65 @@ module ActiveRecord
|
|||
module ConnectionAdapters
|
||||
extend ActiveSupport::Autoload
|
||||
|
||||
@adapters = {}
|
||||
|
||||
class << self
|
||||
# Registers a custom database adapter.
|
||||
#
|
||||
# Can also be used to define aliases.
|
||||
#
|
||||
# == Example
|
||||
#
|
||||
# ActiveRecord::ConnectionAdapters.register("megadb", "MegaDB::ActiveRecordAdapter", "mega_db/active_record_adapter")
|
||||
#
|
||||
# ActiveRecord::ConnectionAdapters.register("mysql", "ActiveRecord::ConnectionAdapters::TrilogyAdapter", "active_record/connection_adapters/trilogy_adapter")
|
||||
#
|
||||
def register(name, class_name, path = class_name.underscore)
|
||||
@adapters[name] = [class_name, path]
|
||||
end
|
||||
|
||||
def resolve(adapter_name) # :nodoc:
|
||||
# Require the adapter itself and give useful feedback about
|
||||
# 1. Missing adapter gems and
|
||||
# 2. Adapter gems' missing dependencies.
|
||||
class_name, path_to_adapter = @adapters[adapter_name]
|
||||
|
||||
unless class_name
|
||||
raise AdapterNotFound, "database configuration specifies nonexistent '#{adapter_name}' adapter. Ensure that the adapter is spelled correctly in config/database.yml and that you've added the necessary adapter gem to your Gemfile."
|
||||
end
|
||||
|
||||
unless Object.const_defined?(class_name)
|
||||
begin
|
||||
require path_to_adapter
|
||||
rescue LoadError => error
|
||||
# We couldn't require the adapter itself. Raise an exception that
|
||||
# points out config typos and missing gems.
|
||||
if error.path == path_to_adapter
|
||||
# We can assume that a non-builtin adapter was specified, so it's
|
||||
# either misspelled or missing from Gemfile.
|
||||
raise LoadError, "Error loading the '#{adapter_name}' Active Record adapter. Ensure that the necessary adapter gem is in the Gemfile. #{error.message}", error.backtrace
|
||||
|
||||
# Bubbled up from the adapter require. Prefix the exception message
|
||||
# with some guidance about how to address it and reraise.
|
||||
else
|
||||
raise LoadError, "Error loading the '#{adapter_name}' Active Record adapter. Missing a gem it depends on? #{error.message}", error.backtrace
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
begin
|
||||
Object.const_get(class_name)
|
||||
rescue NameError => error
|
||||
raise AdapterNotFound, "Could not load the #{class_name} Active Record adapter (#{error.message})."
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
register "sqlite3", "ActiveRecord::ConnectionAdapters::SQLite3Adapter", "active_record/connection_adapters/sqlite3_adapter"
|
||||
register "mysql2", "ActiveRecord::ConnectionAdapters::Mysql2Adapter", "active_record/connection_adapters/mysql2_adapter"
|
||||
register "trilogy", "ActiveRecord::ConnectionAdapters::TrilogyAdapter", "active_record/connection_adapters/trilogy_adapter"
|
||||
register "postgresql", "ActiveRecord::ConnectionAdapters::PostgreSQLAdapter", "active_record/connection_adapters/postgresql_adapter"
|
||||
|
||||
eager_autoload do
|
||||
autoload :AbstractAdapter
|
||||
end
|
||||
|
|
|
@ -324,32 +324,6 @@ module ActiveRecord
|
|||
db_config = Base.configurations.resolve(config)
|
||||
|
||||
raise(AdapterNotSpecified, "database configuration does not specify adapter") unless db_config.adapter
|
||||
|
||||
# Require the adapter itself and give useful feedback about
|
||||
# 1. Missing adapter gems and
|
||||
# 2. Adapter gems' missing dependencies.
|
||||
path_to_adapter = "active_record/connection_adapters/#{db_config.adapter}_adapter"
|
||||
begin
|
||||
require path_to_adapter
|
||||
rescue LoadError => e
|
||||
# We couldn't require the adapter itself. Raise an exception that
|
||||
# points out config typos and missing gems.
|
||||
if e.path == path_to_adapter
|
||||
# We can assume that a non-builtin adapter was specified, so it's
|
||||
# either misspelled or missing from Gemfile.
|
||||
raise LoadError, "Could not load the '#{db_config.adapter}' Active Record adapter. Ensure that the adapter is spelled correctly in config/database.yml and that you've added the necessary adapter gem to your Gemfile.", e.backtrace
|
||||
|
||||
# Bubbled up from the adapter require. Prefix the exception message
|
||||
# with some guidance about how to address it and reraise.
|
||||
else
|
||||
raise LoadError, "Error loading the '#{db_config.adapter}' Active Record adapter. Missing a gem it depends on? #{e.message}", e.backtrace
|
||||
end
|
||||
end
|
||||
|
||||
unless ActiveRecord::Base.respond_to?(db_config.adapter_method)
|
||||
raise AdapterNotFound, "database configuration specifies nonexistent #{db_config.adapter} adapter"
|
||||
end
|
||||
|
||||
ConnectionAdapters::PoolConfig.new(connection_name, db_config, role, shard)
|
||||
end
|
||||
|
||||
|
|
|
@ -682,7 +682,7 @@ module ActiveRecord
|
|||
alias_method :release, :remove_connection_from_thread_cache
|
||||
|
||||
def new_connection
|
||||
connection = Base.public_send(db_config.adapter_method, db_config.configuration_hash)
|
||||
connection = db_config.new_connection
|
||||
connection.pool = self
|
||||
connection
|
||||
rescue ConnectionNotEstablished => ex
|
||||
|
|
|
@ -7,17 +7,6 @@ gem "mysql2", "~> 0.5"
|
|||
require "mysql2"
|
||||
|
||||
module ActiveRecord
|
||||
module ConnectionHandling # :nodoc:
|
||||
def mysql2_adapter_class
|
||||
ConnectionAdapters::Mysql2Adapter
|
||||
end
|
||||
|
||||
# Establishes a connection to the database that's used by all Active Record objects.
|
||||
def mysql2_connection(config)
|
||||
mysql2_adapter_class.new(config)
|
||||
end
|
||||
end
|
||||
|
||||
module ConnectionAdapters
|
||||
# = Active Record MySQL2 Adapter
|
||||
class Mysql2Adapter < AbstractMysqlAdapter
|
||||
|
|
|
@ -20,17 +20,6 @@ require "active_record/connection_adapters/postgresql/type_metadata"
|
|||
require "active_record/connection_adapters/postgresql/utils"
|
||||
|
||||
module ActiveRecord
|
||||
module ConnectionHandling # :nodoc:
|
||||
def postgresql_adapter_class
|
||||
ConnectionAdapters::PostgreSQLAdapter
|
||||
end
|
||||
|
||||
# Establishes a connection to the database that's used by all Active Record objects
|
||||
def postgresql_connection(config)
|
||||
postgresql_adapter_class.new(config)
|
||||
end
|
||||
end
|
||||
|
||||
module ConnectionAdapters
|
||||
# = Active Record PostgreSQL Adapter
|
||||
#
|
||||
|
|
|
@ -15,16 +15,6 @@ gem "sqlite3", "~> 1.4"
|
|||
require "sqlite3"
|
||||
|
||||
module ActiveRecord
|
||||
module ConnectionHandling # :nodoc:
|
||||
def sqlite3_adapter_class
|
||||
ConnectionAdapters::SQLite3Adapter
|
||||
end
|
||||
|
||||
def sqlite3_connection(config)
|
||||
sqlite3_adapter_class.new(config)
|
||||
end
|
||||
end
|
||||
|
||||
module ConnectionAdapters # :nodoc:
|
||||
# = Active Record SQLite3 Adapter
|
||||
#
|
||||
|
|
|
@ -8,23 +8,6 @@ require "trilogy"
|
|||
require "active_record/connection_adapters/trilogy/database_statements"
|
||||
|
||||
module ActiveRecord
|
||||
module ConnectionHandling # :nodoc:
|
||||
def trilogy_adapter_class
|
||||
ConnectionAdapters::TrilogyAdapter
|
||||
end
|
||||
|
||||
# Establishes a connection to the database that's used by all Active Record objects.
|
||||
def trilogy_connection(config)
|
||||
configuration = config.dup
|
||||
|
||||
# Set FOUND_ROWS capability on the connection so UPDATE queries returns number of rows
|
||||
# matched rather than number of rows updated.
|
||||
configuration[:found_rows] = true
|
||||
|
||||
trilogy_adapter_class.new(configuration)
|
||||
end
|
||||
end
|
||||
|
||||
module ConnectionAdapters
|
||||
class TrilogyAdapter < AbstractMysqlAdapter
|
||||
ER_BAD_DB_ERROR = 1049
|
||||
|
@ -90,6 +73,16 @@ module ActiveRecord
|
|||
end
|
||||
end
|
||||
|
||||
def initialize(config, *)
|
||||
config = config.dup
|
||||
|
||||
# Set FOUND_ROWS capability on the connection so UPDATE queries returns number of rows
|
||||
# matched rather than number of rows updated.
|
||||
config[:found_rows] = true
|
||||
|
||||
super
|
||||
end
|
||||
|
||||
TYPE_MAP = Type::TypeMap.new.tap { |m| initialize_type_map(m) }
|
||||
|
||||
def supports_json?
|
||||
|
|
|
@ -8,17 +8,24 @@ module ActiveRecord
|
|||
class DatabaseConfig # :nodoc:
|
||||
attr_reader :env_name, :name
|
||||
|
||||
def self.new(...)
|
||||
instance = super
|
||||
instance.adapter_class # Ensure resolution happens early
|
||||
instance
|
||||
end
|
||||
|
||||
def initialize(env_name, name)
|
||||
@env_name = env_name
|
||||
@name = name
|
||||
@adapter_class = nil
|
||||
end
|
||||
|
||||
def adapter_method
|
||||
"#{adapter}_connection"
|
||||
def adapter_class
|
||||
@adapter_class ||= ActiveRecord::ConnectionAdapters.resolve(adapter)
|
||||
end
|
||||
|
||||
def adapter_class_method
|
||||
"#{adapter}_adapter_class"
|
||||
def new_connection
|
||||
adapter_class.new(configuration_hash)
|
||||
end
|
||||
|
||||
def host
|
||||
|
|
|
@ -104,7 +104,7 @@ module ActiveRecord
|
|||
end
|
||||
|
||||
def adapter
|
||||
configuration_hash[:adapter]
|
||||
configuration_hash[:adapter]&.to_s
|
||||
end
|
||||
|
||||
# The path to the schema cache dump file for a database.
|
||||
|
|
|
@ -1,52 +0,0 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module ActiveRecord
|
||||
module ConnectionHandling
|
||||
def fake_connection(config)
|
||||
ConnectionAdapters::FakeAdapter.new nil, logger
|
||||
end
|
||||
end
|
||||
|
||||
module ConnectionAdapters
|
||||
class FakeAdapter < AbstractAdapter
|
||||
attr_accessor :data_sources, :primary_keys
|
||||
|
||||
@columns = Hash.new { |h, k| h[k] = [] }
|
||||
class << self
|
||||
attr_reader :columns
|
||||
end
|
||||
|
||||
def initialize(connection, logger)
|
||||
super
|
||||
@data_sources = []
|
||||
@primary_keys = {}
|
||||
@columns = self.class.columns
|
||||
end
|
||||
|
||||
def primary_key(table)
|
||||
@primary_keys[table] || "id"
|
||||
end
|
||||
|
||||
def merge_column(table_name, name, sql_type = nil, options = {})
|
||||
@columns[table_name] << ActiveRecord::ConnectionAdapters::Column.new(
|
||||
name.to_s,
|
||||
options[:default],
|
||||
fetch_type_metadata(sql_type),
|
||||
options[:null],
|
||||
)
|
||||
end
|
||||
|
||||
def columns(table_name)
|
||||
@columns[table_name]
|
||||
end
|
||||
|
||||
def data_source_exists?(*)
|
||||
true
|
||||
end
|
||||
|
||||
def active?
|
||||
true
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -23,9 +23,9 @@ class ConnectionTest < ActiveRecord::AbstractMysqlTestCase
|
|||
db_config = ActiveRecord::Base.configurations.configs_for(env_name: "arunit", name: "primary")
|
||||
configuration = db_config.configuration_hash.merge(database: "inexistent_activerecord_unittest")
|
||||
connection = if current_adapter?(:Mysql2Adapter)
|
||||
ActiveRecord::Base.mysql2_connection(configuration)
|
||||
ActiveRecord::ConnectionAdapters::Mysql2Adapter.new(configuration)
|
||||
else
|
||||
ActiveRecord::Base.trilogy_connection(configuration)
|
||||
ActiveRecord::ConnectionAdapters::TrilogyAdapter.new(configuration)
|
||||
end
|
||||
connection.drop_table "ex", if_exists: true
|
||||
end
|
||||
|
|
|
@ -15,7 +15,7 @@ class Mysql2AdapterTest < ActiveRecord::Mysql2TestCase
|
|||
|
||||
def test_connection_error
|
||||
error = assert_raises ActiveRecord::ConnectionNotEstablished do
|
||||
ActiveRecord::Base.mysql2_connection(socket: File::NULL, prepared_statements: false).connect!
|
||||
ActiveRecord::ConnectionAdapters::Mysql2Adapter.new(socket: File::NULL, prepared_statements: false).connect!
|
||||
end
|
||||
assert_kind_of ActiveRecord::ConnectionAdapters::NullPool, error.connection_pool
|
||||
end
|
||||
|
|
|
@ -20,7 +20,7 @@ module ActiveRecord
|
|||
|
||||
def test_connection_error
|
||||
error = assert_raises ActiveRecord::ConnectionNotEstablished do
|
||||
ActiveRecord::Base.postgresql_connection(host: File::NULL).connect!
|
||||
ActiveRecord::ConnectionAdapters::PostgreSQLAdapter.new(host: File::NULL).connect!
|
||||
end
|
||||
assert_kind_of ActiveRecord::ConnectionAdapters::NullPool, error.connection_pool
|
||||
end
|
||||
|
@ -75,7 +75,7 @@ module ActiveRecord
|
|||
assert_raise ActiveRecord::NoDatabaseError do
|
||||
db_config = ActiveRecord::Base.configurations.configs_for(env_name: "arunit", name: "primary")
|
||||
configuration = db_config.configuration_hash.merge(database: "should_not_exist-cinco-dog-db")
|
||||
connection = ActiveRecord::Base.postgresql_connection(configuration)
|
||||
connection = ActiveRecord::ConnectionAdapters::PostgreSQLAdapter.new(configuration)
|
||||
connection.exec_query("SELECT 1")
|
||||
end
|
||||
end
|
||||
|
@ -87,7 +87,7 @@ module ActiveRecord
|
|||
error = assert_raises ActiveRecord::ConnectionNotEstablished do
|
||||
db_config = ActiveRecord::Base.configurations.configs_for(env_name: "arunit", name: "primary")
|
||||
configuration = db_config.configuration_hash.merge(database: "postgres")
|
||||
connection = ActiveRecord::Base.postgresql_connection(configuration)
|
||||
connection = ActiveRecord::ConnectionAdapters::PostgreSQLAdapter.new(configuration)
|
||||
connection.exec_query("SELECT 1")
|
||||
end
|
||||
assert_not_nil connection
|
||||
|
@ -640,7 +640,7 @@ module ActiveRecord
|
|||
|
||||
def connection_without_insert_returning
|
||||
db_config = ActiveRecord::Base.configurations.configs_for(env_name: "arunit", name: "primary")
|
||||
ActiveRecord::Base.postgresql_connection(db_config.configuration_hash.merge(insert_returning: false))
|
||||
ActiveRecord::ConnectionAdapters::PostgreSQLAdapter.new(db_config.configuration_hash.merge(insert_returning: false))
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -16,14 +16,16 @@ module ActiveRecord
|
|||
end
|
||||
|
||||
def setup
|
||||
@conn = Base.sqlite3_connection database: ":memory:",
|
||||
adapter: "sqlite3",
|
||||
timeout: 100
|
||||
@conn = SQLite3Adapter.new(
|
||||
database: ":memory:",
|
||||
adapter: "sqlite3",
|
||||
timeout: 100,
|
||||
)
|
||||
end
|
||||
|
||||
def test_bad_connection
|
||||
error = assert_raise ActiveRecord::NoDatabaseError do
|
||||
connection = ActiveRecord::Base.sqlite3_connection(adapter: "sqlite3", database: "/tmp/should/_not/_exist/-cinco-dog.db")
|
||||
connection = SQLite3Adapter.new(adapter: "sqlite3", database: "/tmp/should/_not/_exist/-cinco-dog.db")
|
||||
connection.drop_table "ex", if_exists: true
|
||||
end
|
||||
assert_kind_of ActiveRecord::ConnectionAdapters::NullPool, error.connection_pool
|
||||
|
@ -117,15 +119,17 @@ module ActiveRecord
|
|||
|
||||
def test_connection_no_db
|
||||
assert_raises(ArgumentError) do
|
||||
Base.sqlite3_connection({})
|
||||
SQLite3Adapter.new({})
|
||||
end
|
||||
end
|
||||
|
||||
def test_bad_timeout
|
||||
exception = assert_raises(ActiveRecord::StatementInvalid) do
|
||||
Base.sqlite3_connection(database: ":memory:",
|
||||
adapter: "sqlite3",
|
||||
timeout: "usa").connect!
|
||||
SQLite3Adapter.new(
|
||||
database: ":memory:",
|
||||
adapter: "sqlite3",
|
||||
timeout: "usa",
|
||||
).connect!
|
||||
end
|
||||
assert_match("TypeError", exception.message)
|
||||
assert_kind_of ActiveRecord::ConnectionAdapters::NullPool, exception.connection_pool
|
||||
|
@ -133,9 +137,11 @@ module ActiveRecord
|
|||
|
||||
# connection is OK with a nil timeout
|
||||
def test_nil_timeout
|
||||
conn = Base.sqlite3_connection database: ":memory:",
|
||||
adapter: "sqlite3",
|
||||
timeout: nil
|
||||
conn = SQLite3Adapter.new(
|
||||
database: ":memory:",
|
||||
adapter: "sqlite3",
|
||||
timeout: nil,
|
||||
)
|
||||
conn.connect!
|
||||
assert conn, "made a connection"
|
||||
end
|
||||
|
@ -277,9 +283,11 @@ module ActiveRecord
|
|||
|
||||
def test_exec_insert_with_returning_disabled
|
||||
original_conn = @conn
|
||||
@conn = Base.sqlite3_connection database: ":memory:",
|
||||
adapter: "sqlite3",
|
||||
insert_returning: false
|
||||
@conn = SQLite3Adapter.new(
|
||||
database: ":memory:",
|
||||
adapter: "sqlite3",
|
||||
insert_returning: false,
|
||||
)
|
||||
with_example_table do
|
||||
result = @conn.exec_insert("insert into ex (number) VALUES ('foo')", nil, [], "id")
|
||||
expect = @conn.query("select max(id) from ex").first.first
|
||||
|
@ -290,9 +298,11 @@ module ActiveRecord
|
|||
|
||||
def test_exec_insert_default_values_with_returning_disabled
|
||||
original_conn = @conn
|
||||
@conn = Base.sqlite3_connection database: ":memory:",
|
||||
adapter: "sqlite3",
|
||||
insert_returning: false
|
||||
@conn = SQLite3Adapter.new(
|
||||
database: ":memory:",
|
||||
adapter: "sqlite3",
|
||||
insert_returning: false,
|
||||
)
|
||||
with_example_table do
|
||||
result = @conn.exec_insert("insert into ex DEFAULT VALUES", nil, [], "id")
|
||||
expect = @conn.query("select max(id) from ex").first.first
|
||||
|
@ -689,35 +699,43 @@ module ActiveRecord
|
|||
end
|
||||
|
||||
def test_db_is_not_readonly_when_readonly_option_is_false
|
||||
conn = Base.sqlite3_connection database: ":memory:",
|
||||
adapter: "sqlite3",
|
||||
readonly: false
|
||||
conn = SQLite3Adapter.new(
|
||||
database: ":memory:",
|
||||
adapter: "sqlite3",
|
||||
readonly: false,
|
||||
)
|
||||
conn.connect!
|
||||
|
||||
assert_not_predicate conn.raw_connection, :readonly?
|
||||
end
|
||||
|
||||
def test_db_is_not_readonly_when_readonly_option_is_unspecified
|
||||
conn = Base.sqlite3_connection database: ":memory:",
|
||||
adapter: "sqlite3"
|
||||
conn = SQLite3Adapter.new(
|
||||
database: ":memory:",
|
||||
adapter: "sqlite3",
|
||||
)
|
||||
conn.connect!
|
||||
|
||||
assert_not_predicate conn.raw_connection, :readonly?
|
||||
end
|
||||
|
||||
def test_db_is_readonly_when_readonly_option_is_true
|
||||
conn = Base.sqlite3_connection database: ":memory:",
|
||||
adapter: "sqlite3",
|
||||
readonly: true
|
||||
conn = SQLite3Adapter.new(
|
||||
database: ":memory:",
|
||||
adapter: "sqlite3",
|
||||
readonly: true,
|
||||
)
|
||||
conn.connect!
|
||||
|
||||
assert_predicate conn.raw_connection, :readonly?
|
||||
end
|
||||
|
||||
def test_writes_are_not_permitted_to_readonly_databases
|
||||
conn = Base.sqlite3_connection database: ":memory:",
|
||||
adapter: "sqlite3",
|
||||
readonly: true
|
||||
conn = SQLite3Adapter.new(
|
||||
database: ":memory:",
|
||||
adapter: "sqlite3",
|
||||
readonly: true,
|
||||
)
|
||||
conn.connect!
|
||||
|
||||
exception = assert_raises(ActiveRecord::StatementInvalid) do
|
||||
|
@ -728,7 +746,7 @@ module ActiveRecord
|
|||
end
|
||||
|
||||
def test_strict_strings_by_default
|
||||
conn = Base.sqlite3_connection(database: ":memory:", adapter: "sqlite3")
|
||||
conn = SQLite3Adapter.new(database: ":memory:", adapter: "sqlite3")
|
||||
conn.create_table :testings
|
||||
|
||||
assert_nothing_raised do
|
||||
|
@ -736,7 +754,7 @@ module ActiveRecord
|
|||
end
|
||||
|
||||
with_strict_strings_by_default do
|
||||
conn = Base.sqlite3_connection(database: ":memory:", adapter: "sqlite3")
|
||||
conn = SQLite3Adapter.new(database: ":memory:", adapter: "sqlite3")
|
||||
conn.create_table :testings
|
||||
|
||||
error = assert_raises(StandardError) do
|
||||
|
@ -748,7 +766,7 @@ module ActiveRecord
|
|||
end
|
||||
|
||||
def test_strict_strings_by_default_and_true_in_database_yml
|
||||
conn = Base.sqlite3_connection(database: ":memory:", adapter: "sqlite3", strict: true)
|
||||
conn = SQLite3Adapter.new(database: ":memory:", adapter: "sqlite3", strict: true)
|
||||
conn.create_table :testings
|
||||
|
||||
error = assert_raises(StandardError) do
|
||||
|
@ -758,7 +776,7 @@ module ActiveRecord
|
|||
assert_equal conn.pool, error.connection_pool
|
||||
|
||||
with_strict_strings_by_default do
|
||||
conn = Base.sqlite3_connection(database: ":memory:", adapter: "sqlite3", strict: true)
|
||||
conn = SQLite3Adapter.new(database: ":memory:", adapter: "sqlite3", strict: true)
|
||||
conn.create_table :testings
|
||||
|
||||
error = assert_raises(StandardError) do
|
||||
|
@ -770,7 +788,7 @@ module ActiveRecord
|
|||
end
|
||||
|
||||
def test_strict_strings_by_default_and_false_in_database_yml
|
||||
conn = Base.sqlite3_connection(database: ":memory:", adapter: "sqlite3", strict: false)
|
||||
conn = SQLite3Adapter.new(database: ":memory:", adapter: "sqlite3", strict: false)
|
||||
conn.create_table :testings
|
||||
|
||||
assert_nothing_raised do
|
||||
|
@ -778,7 +796,7 @@ module ActiveRecord
|
|||
end
|
||||
|
||||
with_strict_strings_by_default do
|
||||
conn = Base.sqlite3_connection(database: ":memory:", adapter: "sqlite3", strict: false)
|
||||
conn = SQLite3Adapter.new(database: ":memory:", adapter: "sqlite3", strict: false)
|
||||
conn.create_table :testings
|
||||
|
||||
assert_nothing_raised do
|
||||
|
@ -852,7 +870,7 @@ module ActiveRecord
|
|||
options = options.dup
|
||||
db_config = ActiveRecord::Base.configurations.configurations.find { |config| !config.database.include?(":memory:") }
|
||||
options[:database] ||= db_config.database
|
||||
conn = ActiveRecord::Base.sqlite3_connection(options)
|
||||
conn = SQLite3Adapter.new(options)
|
||||
|
||||
yield(conn)
|
||||
ensure
|
||||
|
|
|
@ -9,9 +9,11 @@ module ActiveRecord
|
|||
def test_sqlite_creates_directory
|
||||
Dir.mktmpdir do |dir|
|
||||
dir = Pathname.new(dir)
|
||||
@conn = Base.sqlite3_connection database: dir.join("db/foo.sqlite3"),
|
||||
adapter: "sqlite3",
|
||||
timeout: 100
|
||||
@conn = SQLite3Adapter.new(
|
||||
database: dir.join("db/foo.sqlite3"),
|
||||
adapter: "sqlite3",
|
||||
timeout: 100,
|
||||
)
|
||||
@conn.connect!
|
||||
|
||||
assert Dir.exist? dir.join("db")
|
||||
|
|
|
@ -117,7 +117,7 @@ class SQLite3TransactionTest < ActiveRecord::SQLite3TestCase
|
|||
db_config = ActiveRecord::Base.configurations.configs_for(env_name: "arunit", name: "primary")
|
||||
options[:database] ||= db_config.database
|
||||
end
|
||||
conn = ActiveRecord::Base.sqlite3_connection(options)
|
||||
conn = ActiveRecord::ConnectionAdapters::SQLite3Adapter.new(options)
|
||||
|
||||
yield(conn)
|
||||
ensure
|
||||
|
|
|
@ -14,7 +14,7 @@ class TrilogyAdapterTest < ActiveRecord::TrilogyTestCase
|
|||
|
||||
test "connection_error" do
|
||||
error = assert_raises ActiveRecord::ConnectionNotEstablished do
|
||||
ActiveRecord::Base.trilogy_connection(host: "invalid", port: 12345).connect!
|
||||
ActiveRecord::ConnectionAdapters::TrilogyAdapter.new(host: "invalid", port: 12345).connect!
|
||||
end
|
||||
assert_kind_of ActiveRecord::ConnectionAdapters::NullPool, error.connection_pool
|
||||
end
|
||||
|
|
|
@ -39,7 +39,7 @@ module ActiveRecord
|
|||
end
|
||||
|
||||
def test_close
|
||||
db_config = ActiveRecord::DatabaseConfigurations::HashConfig.new("test", "primary", {})
|
||||
db_config = ActiveRecord::DatabaseConfigurations::HashConfig.new("test", "primary", adapter: "abstract")
|
||||
pool_config = ActiveRecord::ConnectionAdapters::PoolConfig.new(ActiveRecord::Base, db_config, :writing, :default)
|
||||
pool = Pool.new(pool_config)
|
||||
pool.insert_connection_for_test! @adapter
|
||||
|
|
|
@ -9,12 +9,14 @@ module ActiveRecord
|
|||
@previous_database_url = ENV.delete("DATABASE_URL")
|
||||
@previous_rack_env = ENV.delete("RACK_ENV")
|
||||
@previous_rails_env = ENV.delete("RAILS_ENV")
|
||||
@adapters_was = ActiveRecord::ConnectionAdapters.instance_variable_get(:@adapters).dup
|
||||
end
|
||||
|
||||
teardown do
|
||||
ENV["DATABASE_URL"] = @previous_database_url
|
||||
ENV["RACK_ENV"] = @previous_rack_env
|
||||
ENV["RAILS_ENV"] = @previous_rails_env
|
||||
ActiveRecord::ConnectionAdapters.instance_variable_set(:@adapters, @adapters_was)
|
||||
end
|
||||
|
||||
def resolve_config(config, env_name = ActiveRecord::ConnectionHandling::DEFAULT_ENV.call)
|
||||
|
@ -45,7 +47,7 @@ module ActiveRecord
|
|||
|
||||
def test_resolver_with_database_uri_and_current_env_symbol_key
|
||||
ENV["DATABASE_URL"] = "postgres://localhost/foo"
|
||||
config = { "not_production" => { "adapter" => "not_postgres", "database" => "not_foo" } }
|
||||
config = { "not_production" => { "adapter" => "abstract", "database" => "not_foo" } }
|
||||
actual = resolve_db_config(:default_env, config)
|
||||
expected = { adapter: "postgresql", database: "foo", host: "localhost" }
|
||||
|
||||
|
@ -56,7 +58,7 @@ module ActiveRecord
|
|||
ENV["DATABASE_URL"] = "postgres://localhost/foo"
|
||||
ENV["RAILS_ENV"] = "foo"
|
||||
|
||||
config = { "not_production" => { "adapter" => "not_postgres", "database" => "not_foo" } }
|
||||
config = { "not_production" => { "adapter" => "abstract", "database" => "not_foo" } }
|
||||
actual = resolve_db_config(:foo, config)
|
||||
expected = { adapter: "postgresql", database: "foo", host: "localhost" }
|
||||
|
||||
|
@ -65,9 +67,9 @@ module ActiveRecord
|
|||
|
||||
def test_resolver_with_nil_database_url_and_current_env
|
||||
ENV["RAILS_ENV"] = "foo"
|
||||
config = { "foo" => { "adapter" => "postgres", "url" => ENV["DATABASE_URL"] } }
|
||||
config = { "foo" => { "adapter" => "postgresql", "url" => ENV["DATABASE_URL"] } }
|
||||
actual = resolve_db_config(:foo, config)
|
||||
expected_config = { adapter: "postgres" }
|
||||
expected_config = { adapter: "postgresql" }
|
||||
|
||||
assert_equal expected_config, actual.configuration_hash
|
||||
end
|
||||
|
@ -76,7 +78,7 @@ module ActiveRecord
|
|||
ENV["DATABASE_URL"] = "postgres://localhost/foo"
|
||||
ENV["RACK_ENV"] = "foo"
|
||||
|
||||
config = { "not_production" => { "adapter" => "not_postgres", "database" => "not_foo" } }
|
||||
config = { "not_production" => { "adapter" => "abstract", "database" => "not_foo" } }
|
||||
actual = resolve_db_config(:foo, config)
|
||||
expected = { adapter: "postgresql", database: "foo", host: "localhost" }
|
||||
|
||||
|
@ -85,9 +87,9 @@ module ActiveRecord
|
|||
|
||||
def test_resolver_with_database_uri_and_known_key
|
||||
ENV["DATABASE_URL"] = "postgres://localhost/foo"
|
||||
config = { "production" => { "adapter" => "not_postgres", "database" => "not_foo", "host" => "localhost" } }
|
||||
config = { "production" => { "adapter" => "abstract", "database" => "not_foo", "host" => "localhost" } }
|
||||
actual = resolve_db_config(:production, config)
|
||||
expected = { adapter: "not_postgres", database: "not_foo", host: "localhost" }
|
||||
expected = { adapter: "abstract", database: "not_foo", host: "localhost" }
|
||||
|
||||
assert_equal expected, actual.configuration_hash
|
||||
end
|
||||
|
@ -105,15 +107,15 @@ module ActiveRecord
|
|||
|
||||
def test_resolver_with_database_uri_and_unknown_symbol_key
|
||||
ENV["DATABASE_URL"] = "postgres://localhost/foo"
|
||||
config = { "not_production" => { "adapter" => "not_postgres", "database" => "not_foo" } }
|
||||
config = { "not_production" => { "adapter" => "abstract", "database" => "not_foo" } }
|
||||
assert_raises AdapterNotSpecified do
|
||||
resolve_db_config(:production, config)
|
||||
end
|
||||
end
|
||||
|
||||
def test_resolver_with_database_uri_and_supplied_url
|
||||
ENV["DATABASE_URL"] = "not-postgres://not-localhost/not_foo"
|
||||
config = { "production" => { "adapter" => "also_not_postgres", "database" => "also_not_foo" } }
|
||||
ENV["DATABASE_URL"] = "abstract://not-localhost/not_foo"
|
||||
config = { "production" => { "adapter" => "abstract", "database" => "also_not_foo" } }
|
||||
actual = resolve_db_config("postgres://localhost/foo", config)
|
||||
expected = { adapter: "postgresql", database: "foo", host: "localhost" }
|
||||
|
||||
|
@ -121,26 +123,26 @@ module ActiveRecord
|
|||
end
|
||||
|
||||
def test_jdbc_url
|
||||
config = { "production" => { "url" => "jdbc:postgres://localhost/foo" } }
|
||||
config = { "production" => { "adapter" => "abstract", "url" => "jdbc:postgres://localhost/foo" } }
|
||||
actual = resolve_config(config, "production")
|
||||
assert_equal config["production"].symbolize_keys, actual
|
||||
end
|
||||
|
||||
def test_http_url
|
||||
config = { "production" => { "url" => "http://example.com/path" } }
|
||||
config = { "production" => { "adapter" => "abstract", "url" => "http://example.com/path" } }
|
||||
actual = resolve_config(config, "production")
|
||||
assert_equal config["production"].symbolize_keys, actual
|
||||
end
|
||||
|
||||
def test_https_url
|
||||
config = { "production" => { "url" => "https://example.com" } }
|
||||
config = { "production" => { "adapter" => "abstract", "url" => "https://example.com" } }
|
||||
actual = resolve_config(config, "production")
|
||||
assert_equal config["production"].symbolize_keys, actual
|
||||
end
|
||||
|
||||
def test_environment_does_not_exist_in_config_url_does_exist
|
||||
ENV["DATABASE_URL"] = "postgres://localhost/foo"
|
||||
config = { "not_default_env" => { "adapter" => "not_postgres", "database" => "not_foo" } }
|
||||
config = { "not_default_env" => { "adapter" => "abstract", "database" => "not_foo" } }
|
||||
actual = resolve_config(config, "default_env")
|
||||
expect_prod = {
|
||||
adapter: "postgresql",
|
||||
|
@ -152,8 +154,9 @@ module ActiveRecord
|
|||
end
|
||||
|
||||
def test_url_with_hyphenated_scheme
|
||||
ActiveRecord::ConnectionAdapters.register("ibm_db", "ActiveRecord::ConnectionAdapters::AbstractAdapter", "active_record/connection_adapters/abstract_adapter")
|
||||
ENV["DATABASE_URL"] = "ibm-db://localhost/foo"
|
||||
config = { "default_env" => { "adapter" => "not_postgres", "database" => "not_foo", "host" => "localhost" } }
|
||||
config = { "default_env" => { "adapter" => "abstract", "database" => "not_foo", "host" => "localhost" } }
|
||||
actual = resolve_db_config(:default_env, config)
|
||||
expected = { adapter: "ibm_db", database: "foo", host: "localhost" }
|
||||
|
||||
|
@ -199,7 +202,7 @@ module ActiveRecord
|
|||
end
|
||||
|
||||
def test_hash
|
||||
config = { "production" => { "adapter" => "postgres", "database" => "foo" } }
|
||||
config = { "production" => { "adapter" => "postgresql", "database" => "foo" } }
|
||||
actual = resolve_config(config, "production")
|
||||
assert_equal config["production"].symbolize_keys, actual
|
||||
end
|
||||
|
@ -270,7 +273,7 @@ module ActiveRecord
|
|||
end
|
||||
|
||||
def test_url_sub_key_with_database_url
|
||||
ENV["DATABASE_URL"] = "NOT-POSTGRES://localhost/NOT_FOO"
|
||||
ENV["DATABASE_URL"] = "abstract://localhost/NOT_FOO"
|
||||
|
||||
config = { "default_env" => { "url" => "postgres://localhost/foo" } }
|
||||
actual = resolve_config(config)
|
||||
|
@ -286,7 +289,7 @@ module ActiveRecord
|
|||
def test_no_url_sub_key_with_database_url_doesnt_trample_other_envs
|
||||
ENV["DATABASE_URL"] = "postgres://localhost/baz"
|
||||
|
||||
config = { "default_env" => { "database" => "foo" }, "other_env" => { "url" => "postgres://foohost/bardb" } }
|
||||
config = { "default_env" => { "adapter" => "abstract", "database" => "foo" }, "other_env" => { "url" => "postgres://foohost/bardb" } }
|
||||
expected = {
|
||||
default_env: {
|
||||
database: "baz",
|
||||
|
@ -307,7 +310,7 @@ module ActiveRecord
|
|||
def test_merge_no_conflicts_with_database_url
|
||||
ENV["DATABASE_URL"] = "postgres://localhost/foo"
|
||||
|
||||
config = { "default_env" => { "pool" => "5" } }
|
||||
config = { "default_env" => { "adapter" => "abstract", "pool" => "5" } }
|
||||
actual = resolve_config(config)
|
||||
expected = {
|
||||
adapter: "postgresql",
|
||||
|
@ -322,7 +325,7 @@ module ActiveRecord
|
|||
def test_merge_conflicts_with_database_url
|
||||
ENV["DATABASE_URL"] = "postgres://localhost/foo"
|
||||
|
||||
config = { "default_env" => { "adapter" => "NOT-POSTGRES", "database" => "NOT-FOO", "pool" => "5" } }
|
||||
config = { "default_env" => { "adapter" => "abstract", "database" => "NOT-FOO", "pool" => "5" } }
|
||||
actual = resolve_config(config)
|
||||
expected = {
|
||||
adapter: "postgresql",
|
||||
|
@ -352,7 +355,7 @@ module ActiveRecord
|
|||
def test_merge_no_conflicts_with_database_url_and_numeric_pool
|
||||
ENV["DATABASE_URL"] = "postgres://localhost/foo"
|
||||
|
||||
config = { "default_env" => { "pool" => 5 } }
|
||||
config = { "default_env" => { "adapter" => "abstract", "pool" => 5 } }
|
||||
actual = resolve_config(config)
|
||||
expected = {
|
||||
adapter: "postgresql",
|
||||
|
@ -369,8 +372,8 @@ module ActiveRecord
|
|||
|
||||
config = {
|
||||
"default_env" => {
|
||||
"primary" => { "pool" => 5 },
|
||||
"animals" => { "pool" => 5 }
|
||||
"primary" => { "adapter" => "abstract", "pool" => 5 },
|
||||
"animals" => { "adapter" => "abstract", "pool" => 5 }
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -387,7 +390,7 @@ module ActiveRecord
|
|||
|
||||
configs = ActiveRecord::DatabaseConfigurations.new(config)
|
||||
actual = configs.configs_for(env_name: "default_env", name: "animals").configuration_hash
|
||||
expected = { pool: 5 }
|
||||
expected = { adapter: "abstract", pool: 5 }
|
||||
|
||||
assert_equal expected, actual
|
||||
end
|
||||
|
@ -399,8 +402,8 @@ module ActiveRecord
|
|||
|
||||
config = {
|
||||
"default_env" => {
|
||||
"primary" => { "pool" => 5 },
|
||||
"animals" => { "pool" => 5 }
|
||||
"primary" => { "adapter" => "abstract", "pool" => 5 },
|
||||
"animals" => { "adapter" => "abstract", "pool" => 5 }
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -418,7 +421,7 @@ module ActiveRecord
|
|||
|
||||
def test_does_not_change_other_environments
|
||||
ENV["DATABASE_URL"] = "postgres://localhost/foo"
|
||||
config = { "production" => { "adapter" => "not_postgres", "database" => "not_foo", "host" => "localhost" }, "default_env" => {} }
|
||||
config = { "production" => { "adapter" => "abstract", "database" => "not_foo", "host" => "localhost" }, "default_env" => {} }
|
||||
|
||||
actual = resolve_db_config(:production, config)
|
||||
assert_equal config["production"].symbolize_keys, actual.configuration_hash
|
||||
|
|
|
@ -10,7 +10,7 @@ module ActiveRecord
|
|||
super
|
||||
|
||||
db_config = ActiveRecord::Base.configurations.configs_for(env_name: "arunit", name: "primary")
|
||||
@connection = ActiveRecord::Base.public_send(db_config.adapter_method, db_config.configuration_hash)
|
||||
@connection = db_config.new_connection
|
||||
end
|
||||
|
||||
def test_can_query
|
||||
|
|
|
@ -6,143 +6,143 @@ module ActiveRecord
|
|||
class DatabaseConfigurations
|
||||
class HashConfigTest < ActiveRecord::TestCase
|
||||
def test_pool_default_when_nil
|
||||
config = HashConfig.new("default_env", "primary", pool: nil)
|
||||
config = HashConfig.new("default_env", "primary", pool: nil, adapter: "abstract")
|
||||
assert_equal 5, config.pool
|
||||
end
|
||||
|
||||
def test_pool_overrides_with_value
|
||||
config = HashConfig.new("default_env", "primary", pool: "0")
|
||||
config = HashConfig.new("default_env", "primary", pool: "0", adapter: "abstract")
|
||||
assert_equal 0, config.pool
|
||||
end
|
||||
|
||||
def test_when_no_pool_uses_default
|
||||
config = HashConfig.new("default_env", "primary", {})
|
||||
config = HashConfig.new("default_env", "primary", adapter: "abstract")
|
||||
assert_equal 5, config.pool
|
||||
end
|
||||
|
||||
def test_min_threads_with_value
|
||||
config = HashConfig.new("default_env", "primary", min_threads: "1")
|
||||
config = HashConfig.new("default_env", "primary", min_threads: "1", adapter: "abstract")
|
||||
assert_equal 1, config.min_threads
|
||||
end
|
||||
|
||||
def test_min_threads_default
|
||||
config = HashConfig.new("default_env", "primary", {})
|
||||
config = HashConfig.new("default_env", "primary", adapter: "abstract")
|
||||
assert_equal 0, config.min_threads
|
||||
end
|
||||
|
||||
def test_max_threads_with_value
|
||||
config = HashConfig.new("default_env", "primary", max_threads: "10")
|
||||
config = HashConfig.new("default_env", "primary", max_threads: "10", adapter: "abstract")
|
||||
assert_equal 10, config.max_threads
|
||||
end
|
||||
|
||||
def test_max_threads_default_uses_pool_default
|
||||
config = HashConfig.new("default_env", "primary", {})
|
||||
config = HashConfig.new("default_env", "primary", adapter: "abstract")
|
||||
assert_equal 5, config.pool
|
||||
assert_equal 5, config.max_threads
|
||||
end
|
||||
|
||||
def test_max_threads_uses_pool_when_set
|
||||
config = HashConfig.new("default_env", "primary", pool: 1)
|
||||
config = HashConfig.new("default_env", "primary", pool: 1, adapter: "abstract")
|
||||
assert_equal 1, config.pool
|
||||
assert_equal 1, config.max_threads
|
||||
end
|
||||
|
||||
def test_max_queue_is_pool_multiplied_by_4
|
||||
config = HashConfig.new("default_env", "primary", {})
|
||||
config = HashConfig.new("default_env", "primary", adapter: "abstract")
|
||||
assert_equal 5, config.max_threads
|
||||
assert_equal config.max_threads * 4, config.max_queue
|
||||
end
|
||||
|
||||
def test_checkout_timeout_default_when_nil
|
||||
config = HashConfig.new("default_env", "primary", checkout_timeout: nil)
|
||||
config = HashConfig.new("default_env", "primary", checkout_timeout: nil, adapter: "abstract")
|
||||
assert_equal 5.0, config.checkout_timeout
|
||||
end
|
||||
|
||||
def test_checkout_timeout_overrides_with_value
|
||||
config = HashConfig.new("default_env", "primary", checkout_timeout: "0")
|
||||
config = HashConfig.new("default_env", "primary", checkout_timeout: "0", adapter: "abstract")
|
||||
assert_equal 0.0, config.checkout_timeout
|
||||
end
|
||||
|
||||
def test_when_no_checkout_timeout_uses_default
|
||||
config = HashConfig.new("default_env", "primary", {})
|
||||
config = HashConfig.new("default_env", "primary", adapter: "abstract")
|
||||
assert_equal 5.0, config.checkout_timeout
|
||||
end
|
||||
|
||||
def test_reaping_frequency_default_when_nil
|
||||
config = HashConfig.new("default_env", "primary", reaping_frequency: nil)
|
||||
config = HashConfig.new("default_env", "primary", reaping_frequency: nil, adapter: "abstract")
|
||||
assert_nil config.reaping_frequency
|
||||
end
|
||||
|
||||
def test_reaping_frequency_overrides_with_value
|
||||
config = HashConfig.new("default_env", "primary", reaping_frequency: "0")
|
||||
config = HashConfig.new("default_env", "primary", reaping_frequency: "0", adapter: "abstract")
|
||||
assert_equal 0.0, config.reaping_frequency
|
||||
end
|
||||
|
||||
def test_when_no_reaping_frequency_uses_default
|
||||
config = HashConfig.new("default_env", "primary", {})
|
||||
config = HashConfig.new("default_env", "primary", adapter: "abstract")
|
||||
assert_equal 60.0, config.reaping_frequency
|
||||
end
|
||||
|
||||
def test_idle_timeout_default_when_nil
|
||||
config = HashConfig.new("default_env", "primary", idle_timeout: nil)
|
||||
config = HashConfig.new("default_env", "primary", idle_timeout: nil, adapter: "abstract")
|
||||
assert_nil config.idle_timeout
|
||||
end
|
||||
|
||||
def test_idle_timeout_overrides_with_value
|
||||
config = HashConfig.new("default_env", "primary", idle_timeout: "1")
|
||||
config = HashConfig.new("default_env", "primary", idle_timeout: "1", adapter: "abstract")
|
||||
assert_equal 1.0, config.idle_timeout
|
||||
end
|
||||
|
||||
def test_when_no_idle_timeout_uses_default
|
||||
config = HashConfig.new("default_env", "primary", {})
|
||||
config = HashConfig.new("default_env", "primary", adapter: "abstract")
|
||||
assert_equal 300.0, config.idle_timeout
|
||||
end
|
||||
|
||||
def test_idle_timeout_nil_when_less_than_or_equal_to_zero
|
||||
config = HashConfig.new("default_env", "primary", idle_timeout: "0")
|
||||
config = HashConfig.new("default_env", "primary", idle_timeout: "0", adapter: "abstract")
|
||||
assert_nil config.idle_timeout
|
||||
end
|
||||
|
||||
def test_default_schema_dump_value
|
||||
config = HashConfig.new("default_env", "primary", {})
|
||||
config = HashConfig.new("default_env", "primary", adapter: "abstract")
|
||||
assert_equal "schema.rb", config.schema_dump
|
||||
end
|
||||
|
||||
def test_schema_dump_value_set_to_filename
|
||||
config = HashConfig.new("default_env", "primary", { schema_dump: "my_schema.rb" })
|
||||
config = HashConfig.new("default_env", "primary", { schema_dump: "my_schema.rb", adapter: "abstract" })
|
||||
assert_equal "my_schema.rb", config.schema_dump
|
||||
end
|
||||
|
||||
def test_schema_dump_value_set_to_nil
|
||||
config = HashConfig.new("default_env", "primary", { schema_dump: nil })
|
||||
config = HashConfig.new("default_env", "primary", { schema_dump: nil, adapter: "abstract" })
|
||||
assert_nil config.schema_dump
|
||||
end
|
||||
|
||||
def test_schema_dump_value_set_to_false
|
||||
config = HashConfig.new("default_env", "primary", { schema_dump: false })
|
||||
config = HashConfig.new("default_env", "primary", { schema_dump: false, adapter: "abstract" })
|
||||
assert_nil config.schema_dump
|
||||
end
|
||||
|
||||
def test_database_tasks_defaults_to_true
|
||||
config = HashConfig.new("default_env", "primary", {})
|
||||
config = HashConfig.new("default_env", "primary", adapter: "abstract")
|
||||
assert_equal true, config.database_tasks?
|
||||
end
|
||||
|
||||
def test_database_tasks_overrides_with_value
|
||||
config = HashConfig.new("default_env", "primary", database_tasks: false)
|
||||
config = HashConfig.new("default_env", "primary", database_tasks: false, adapter: "abstract")
|
||||
assert_equal false, config.database_tasks?
|
||||
|
||||
config = HashConfig.new("default_env", "primary", database_tasks: "str")
|
||||
config = HashConfig.new("default_env", "primary", database_tasks: "str", adapter: "abstract")
|
||||
assert_equal true, config.database_tasks?
|
||||
end
|
||||
|
||||
def test_schema_cache_path_default_for_primary
|
||||
config = HashConfig.new("default_env", "primary", {})
|
||||
config = HashConfig.new("default_env", "primary", adapter: "abstract")
|
||||
assert_equal "db/schema_cache.yml", config.default_schema_cache_path
|
||||
end
|
||||
|
||||
def test_schema_cache_path_configuration_hash
|
||||
config = HashConfig.new("default_env", "primary", { schema_cache_path: "db/config_schema_cache.yml" })
|
||||
config = HashConfig.new("default_env", "primary", { schema_cache_path: "db/config_schema_cache.yml", adapter: "abstract" })
|
||||
assert_equal "db/config_schema_cache.yml", config.schema_cache_path
|
||||
end
|
||||
end
|
||||
|
|
|
@ -12,19 +12,11 @@ module ActiveRecord
|
|||
end
|
||||
|
||||
def test_url_invalid_adapter
|
||||
error = assert_raises(LoadError) do
|
||||
error = assert_raises(AdapterNotFound) do
|
||||
Base.connection_handler.establish_connection "ridiculous://foo?encoding=utf8"
|
||||
end
|
||||
|
||||
assert_match "Could not load the 'ridiculous' Active Record adapter. Ensure that the adapter is spelled correctly in config/database.yml and that you've added the necessary adapter gem to your Gemfile.", error.message
|
||||
end
|
||||
|
||||
def test_error_if_no_adapter_method
|
||||
error = assert_raises(AdapterNotFound) do
|
||||
Base.connection_handler.establish_connection "abstract://foo?encoding=utf8"
|
||||
end
|
||||
|
||||
assert_match "database configuration specifies nonexistent abstract adapter", error.message
|
||||
assert_match "database configuration specifies nonexistent 'ridiculous' adapter. Ensure that the adapter is spelled correctly in config/database.yml and that you've added the necessary adapter gem to your Gemfile.", error.message
|
||||
end
|
||||
|
||||
# The abstract adapter is used simply to bypass the bit of code that
|
||||
|
|
|
@ -57,12 +57,15 @@ class DatabaseConfigurationsTest < ActiveRecord::TestCase
|
|||
config = ActiveRecord::DatabaseConfigurations.new({
|
||||
"test" => {
|
||||
"config_1" => {
|
||||
"adapter" => "abstract",
|
||||
"database" => "db"
|
||||
},
|
||||
"config_2" => {
|
||||
"adapter" => "abstract",
|
||||
"database" => "db"
|
||||
},
|
||||
"config_3" => {
|
||||
"adapter" => "abstract",
|
||||
"database" => "db"
|
||||
},
|
||||
}
|
||||
|
@ -81,7 +84,7 @@ class DatabaseConfigurationsTest < ActiveRecord::TestCase
|
|||
def test_find_db_config_prioritize_db_config_object_for_the_current_env
|
||||
config = ActiveRecord::DatabaseConfigurations.new({
|
||||
"primary" => {
|
||||
"adapter" => "randomadapter"
|
||||
"adapter" => "abstract",
|
||||
},
|
||||
ActiveRecord::ConnectionHandling::DEFAULT_ENV.call => {
|
||||
"primary" => {
|
||||
|
@ -118,12 +121,14 @@ class DatabaseConfigurationsTest < ActiveRecord::TestCase
|
|||
configs = ActiveRecord::DatabaseConfigurations.new({
|
||||
"test" => {
|
||||
"config_1" => {
|
||||
"adapter" => "abstract",
|
||||
"database" => "db",
|
||||
"custom_config" => {
|
||||
"sharded" => 1
|
||||
}
|
||||
},
|
||||
"config_2" => {
|
||||
"adapter" => "abstract",
|
||||
"database" => "db"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -31,6 +31,9 @@ QUOTED_TYPE = ActiveRecord::Base.connection.quote_column_name("type")
|
|||
ActiveRecord.raise_on_assign_to_attr_readonly = true
|
||||
ActiveRecord.belongs_to_required_validates_foreign_key = false
|
||||
|
||||
ActiveRecord::ConnectionAdapters.register("abstract", "ActiveRecord::ConnectionAdapters::AbstractAdapter", "active_record/connection_adapters/abstract_adapter")
|
||||
ActiveRecord::ConnectionAdapters.register("fake", "FakeActiveRecordAdapter", File.expand_path("../support/fake_adapter.rb", __dir__))
|
||||
|
||||
class SQLSubscriber
|
||||
attr_reader :logged
|
||||
attr_reader :payloads
|
||||
|
|
|
@ -605,7 +605,7 @@ if ActiveRecord::Base.connection.supports_foreign_keys?
|
|||
|
||||
def test_does_not_create_foreign_keys_when_bypassed_by_config
|
||||
require "active_record/connection_adapters/sqlite3_adapter"
|
||||
connection = ActiveRecord::Base.sqlite3_connection(
|
||||
connection = ActiveRecord::ConnectionAdapters::SQLite3Adapter.new(
|
||||
adapter: "sqlite3",
|
||||
database: ":memory:",
|
||||
foreign_keys: false,
|
||||
|
|
|
@ -221,6 +221,16 @@ module ActiveRecord
|
|||
end
|
||||
|
||||
class DatabaseTasksRegisterTask < ActiveRecord::TestCase
|
||||
setup do
|
||||
@tasks_was = ActiveRecord::Tasks::DatabaseTasks.instance_variable_get(:@tasks).dup
|
||||
@adapters_was = ActiveRecord::ConnectionAdapters.instance_variable_get(:@adapters).dup
|
||||
end
|
||||
|
||||
teardown do
|
||||
ActiveRecord::Tasks::DatabaseTasks.instance_variable_set(:@tasks, @tasks_was)
|
||||
ActiveRecord::ConnectionAdapters.instance_variable_set(:@adapters, @adapters_was)
|
||||
end
|
||||
|
||||
def test_register_task
|
||||
klazz = Class.new do
|
||||
def initialize(*arguments); end
|
||||
|
@ -230,8 +240,8 @@ module ActiveRecord
|
|||
|
||||
klazz.stub(:new, instance) do
|
||||
assert_called_with(instance, :structure_dump, ["awesome-file.sql", nil]) do
|
||||
ActiveRecord::Tasks::DatabaseTasks.register_task(/foo/, klazz)
|
||||
ActiveRecord::Tasks::DatabaseTasks.structure_dump({ "adapter" => :foo }, "awesome-file.sql")
|
||||
ActiveRecord::Tasks::DatabaseTasks.register_task(/abstract/, klazz)
|
||||
ActiveRecord::Tasks::DatabaseTasks.structure_dump({ "adapter" => "abstract" }, "awesome-file.sql")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -245,6 +255,7 @@ module ActiveRecord
|
|||
|
||||
klazz.stub(:new, instance) do
|
||||
assert_called_with(instance, :structure_dump, ["awesome-file.sql", nil]) do
|
||||
ActiveRecord::ConnectionAdapters.register("custom_mysql", "ActiveRecord::ConnectionAdapters::Mysql2Adapter", "active_record/connection_adapters/mysql2_adapter")
|
||||
ActiveRecord::Tasks::DatabaseTasks.register_task(/custom_mysql/, klazz)
|
||||
ActiveRecord::Tasks::DatabaseTasks.structure_dump({ "adapter" => :custom_mysql }, "awesome-file.sql")
|
||||
end
|
||||
|
@ -253,7 +264,7 @@ module ActiveRecord
|
|||
|
||||
def test_unregistered_task
|
||||
assert_raise(ActiveRecord::Tasks::DatabaseNotSupported) do
|
||||
ActiveRecord::Tasks::DatabaseTasks.structure_dump({ "adapter" => :bar }, "awesome-file.sql")
|
||||
ActiveRecord::Tasks::DatabaseTasks.structure_dump({ "adapter" => "abstract" }, "awesome-file.sql")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -391,7 +402,7 @@ module ActiveRecord
|
|||
|
||||
class DatabaseTasksCreateAllTest < ActiveRecord::TestCase
|
||||
def setup
|
||||
@configurations = { "development" => { "database" => "my-db" } }
|
||||
@configurations = { "development" => { "adapter" => "abstract", "database" => "my-db" } }
|
||||
|
||||
$stdout, @original_stdout = StringIO.new, $stdout
|
||||
$stderr, @original_stderr = StringIO.new, $stderr
|
||||
|
@ -480,8 +491,8 @@ module ActiveRecord
|
|||
|
||||
def setup
|
||||
@configurations = {
|
||||
"development" => { "database" => "dev-db" },
|
||||
"test" => { "database" => "test-db" },
|
||||
"development" => { "adapter" => "abstract", "database" => "dev-db" },
|
||||
"test" => { "adapter" => "abstract", "database" => "test-db" },
|
||||
"production" => { "url" => "abstract://prod-db-host/prod-db" }
|
||||
}
|
||||
end
|
||||
|
@ -603,9 +614,17 @@ module ActiveRecord
|
|||
|
||||
def setup
|
||||
@configurations = {
|
||||
"development" => { "primary" => { "database" => "dev-db" }, "secondary" => { "database" => "secondary-dev-db" } },
|
||||
"test" => { "primary" => { "database" => "test-db" }, "secondary" => { "database" => "secondary-test-db" } },
|
||||
"production" => { "primary" => { "url" => "abstract://prod-db-host/prod-db" }, "secondary" => { "url" => "abstract://secondary-prod-db-host/secondary-prod-db" } }
|
||||
"development" => {
|
||||
"primary" => { "adapter" => "abstract", "database" => "dev-db" },
|
||||
"secondary" => { "adapter" => "abstract", "database" => "secondary-dev-db" },
|
||||
},
|
||||
"test" => {
|
||||
"primary" => { "adapter" => "abstract", "database" => "test-db" },
|
||||
"secondary" => { "adapter" => "abstract", "database" => "secondary-test-db" },
|
||||
},
|
||||
"production" => {
|
||||
"primary" => { "url" => "abstract://prod-db-host/prod-db" },
|
||||
"secondary" => { "url" => "abstract://secondary-prod-db-host/secondary-prod-db" } }
|
||||
}
|
||||
end
|
||||
|
||||
|
@ -727,7 +746,7 @@ module ActiveRecord
|
|||
|
||||
class DatabaseTasksDropAllTest < ActiveRecord::TestCase
|
||||
def setup
|
||||
@configurations = { development: { "database" => "my-db" } }
|
||||
@configurations = { development: { "adapter" => "abstract", "database" => "my-db" } }
|
||||
|
||||
$stdout, @original_stdout = StringIO.new, $stdout
|
||||
$stderr, @original_stderr = StringIO.new, $stderr
|
||||
|
@ -814,8 +833,8 @@ module ActiveRecord
|
|||
|
||||
def setup
|
||||
@configurations = {
|
||||
"development" => { "database" => "dev-db" },
|
||||
"test" => { "database" => "test-db" },
|
||||
"development" => { "adapter" => "abstract", "database" => "dev-db" },
|
||||
"test" => { "adapter" => "abstract", "database" => "test-db" },
|
||||
"production" => { "url" => "abstract://prod-db-host/prod-db" }
|
||||
}
|
||||
end
|
||||
|
@ -905,9 +924,18 @@ module ActiveRecord
|
|||
|
||||
def setup
|
||||
@configurations = {
|
||||
"development" => { "primary" => { "database" => "dev-db" }, "secondary" => { "database" => "secondary-dev-db" } },
|
||||
"test" => { "primary" => { "database" => "test-db" }, "secondary" => { "database" => "secondary-test-db" } },
|
||||
"production" => { "primary" => { "url" => "abstract://prod-db-host/prod-db" }, "secondary" => { "url" => "abstract://secondary-prod-db-host/secondary-prod-db" } }
|
||||
"development" => {
|
||||
"primary" => { "adapter" => "abstract", "database" => "dev-db" },
|
||||
"secondary" => { "adapter" => "abstract", "database" => "secondary-dev-db" },
|
||||
},
|
||||
"test" => {
|
||||
"primary" => { "adapter" => "abstract", "database" => "test-db" },
|
||||
"secondary" => { "adapter" => "abstract", "database" => "secondary-test-db" },
|
||||
},
|
||||
"production" => {
|
||||
"primary" => { "url" => "abstract://prod-db-host/prod-db" },
|
||||
"secondary" => { "url" => "abstract://secondary-prod-db-host/secondary-prod-db" },
|
||||
},
|
||||
}
|
||||
end
|
||||
|
||||
|
@ -1231,9 +1259,9 @@ module ActiveRecord
|
|||
def test_purges_current_environment_database
|
||||
old_configurations = ActiveRecord::Base.configurations
|
||||
configurations = {
|
||||
"development" => { "database" => "dev-db" },
|
||||
"test" => { "database" => "test-db" },
|
||||
"production" => { "database" => "prod-db" }
|
||||
"development" => { "adapter" => "abstract", "database" => "dev-db" },
|
||||
"test" => { "adapter" => "abstract", "database" => "test-db" },
|
||||
"production" => { "adapter" => "abstract", "database" => "prod-db" },
|
||||
}
|
||||
|
||||
ActiveRecord::Base.configurations = configurations
|
||||
|
@ -1255,7 +1283,7 @@ module ActiveRecord
|
|||
class DatabaseTasksPurgeAllTest < ActiveRecord::TestCase
|
||||
def test_purge_all_local_configurations
|
||||
old_configurations = ActiveRecord::Base.configurations
|
||||
configurations = { development: { "database" => "my-db" } }
|
||||
configurations = { development: { "adapter" => "abstract", "database" => "my-db" } }
|
||||
ActiveRecord::Base.configurations = configurations
|
||||
|
||||
assert_called_with(
|
||||
|
@ -1345,9 +1373,18 @@ module ActiveRecord
|
|||
|
||||
def setup
|
||||
@configurations = {
|
||||
"development" => { "primary" => { "database" => "dev-db" }, "secondary" => { "database" => "secondary-dev-db" } },
|
||||
"test" => { "primary" => { "database" => "test-db" }, "secondary" => { "database" => "secondary-test-db" } },
|
||||
"production" => { "primary" => { "url" => "abstract://prod-db-host/prod-db" }, "secondary" => { "url" => "abstract://secondary-prod-db-host/secondary-prod-db" } }
|
||||
"development" => {
|
||||
"primary" => { "adapter" => "abstract", "database" => "dev-db" },
|
||||
"secondary" => { "adapter" => "abstract", "database" => "secondary-dev-db" },
|
||||
},
|
||||
"test" => {
|
||||
"primary" => { "adapter" => "abstract", "database" => "test-db" },
|
||||
"secondary" => { "adapter" => "abstract", "database" => "secondary-test-db" },
|
||||
},
|
||||
"production" => {
|
||||
"primary" => { "url" => "abstract://prod-db-host/prod-db" },
|
||||
"secondary" => { "url" => "abstract://secondary-prod-db-host/secondary-prod-db" },
|
||||
}
|
||||
}
|
||||
end
|
||||
|
||||
|
@ -1451,7 +1488,7 @@ module ActiveRecord
|
|||
def test_charset_current
|
||||
old_configurations = ActiveRecord::Base.configurations
|
||||
configurations = {
|
||||
"production" => { "database" => "prod-db" }
|
||||
"production" => { "adapter" => "abstract", "database" => "prod-db" }
|
||||
}
|
||||
|
||||
ActiveRecord::Base.configurations = configurations
|
||||
|
@ -1484,7 +1521,7 @@ module ActiveRecord
|
|||
def test_collation_current
|
||||
old_configurations = ActiveRecord::Base.configurations
|
||||
configurations = {
|
||||
"production" => { "database" => "prod-db" }
|
||||
"production" => { "adapter" => "abstract", "database" => "prod-db" }
|
||||
}
|
||||
|
||||
ActiveRecord::Base.configurations = configurations
|
||||
|
@ -1654,7 +1691,7 @@ module ActiveRecord
|
|||
|
||||
class DatabaseTasksCheckSchemaFileMethods < ActiveRecord::TestCase
|
||||
setup do
|
||||
@configurations = { "development" => { "database" => "my-db" } }
|
||||
@configurations = { "development" => { "adapter" => "abstract", "database" => "my-db" } }
|
||||
end
|
||||
|
||||
def test_check_dump_filename_defaults
|
||||
|
@ -1690,7 +1727,10 @@ module ActiveRecord
|
|||
def test_check_dump_filename_defaults_for_non_primary_databases
|
||||
ActiveRecord::Tasks::DatabaseTasks.stub(:db_dir, "/tmp") do
|
||||
configurations = {
|
||||
"development" => { "primary" => { "database" => "dev-db" }, "secondary" => { "database" => "secondary-dev-db" } },
|
||||
"development" => {
|
||||
"primary" => { "adapter" => "abstract", "database" => "dev-db" },
|
||||
"secondary" => { "adapter" => "abstract", "database" => "secondary-dev-db" },
|
||||
},
|
||||
}
|
||||
with_stubbed_configurations(configurations) do
|
||||
assert_equal "/tmp/secondary_schema.rb", ActiveRecord::Tasks::DatabaseTasks.schema_dump_path(config_for("development", "secondary"))
|
||||
|
@ -1701,7 +1741,7 @@ module ActiveRecord
|
|||
def test_setting_schema_dump_to_nil
|
||||
ActiveRecord::Tasks::DatabaseTasks.stub(:db_dir, "/tmp") do
|
||||
configurations = {
|
||||
"development" => { "primary" => { "database" => "dev-db", "schema_dump" => false } },
|
||||
"development" => { "primary" => { "adapter" => "abstract", "database" => "dev-db", "schema_dump" => false } },
|
||||
}
|
||||
with_stubbed_configurations(configurations) do
|
||||
assert_nil ActiveRecord::Tasks::DatabaseTasks.schema_dump_path(config_for("development", "primary"))
|
||||
|
@ -1714,7 +1754,10 @@ module ActiveRecord
|
|||
ENV["SCHEMA"] = "schema_path"
|
||||
ActiveRecord::Tasks::DatabaseTasks.stub(:db_dir, "/tmp") do
|
||||
configurations = {
|
||||
"development" => { "primary" => { "database" => "dev-db" }, "secondary" => { "database" => "secondary-dev-db" } },
|
||||
"development" => {
|
||||
"primary" => { "adapter" => "abstract", "database" => "dev-db" },
|
||||
"secondary" => { "adapter" => "abstract", "database" => "secondary-dev-db" },
|
||||
},
|
||||
}
|
||||
with_stubbed_configurations(configurations) do
|
||||
assert_equal "schema_path", ActiveRecord::Tasks::DatabaseTasks.schema_dump_path(config_for("development", "secondary"))
|
||||
|
@ -1728,7 +1771,10 @@ module ActiveRecord
|
|||
define_method("test_check_dump_filename_for_#{fmt}_format_with_non_primary_databases") do
|
||||
ActiveRecord::Tasks::DatabaseTasks.stub(:db_dir, "/tmp") do
|
||||
configurations = {
|
||||
"development" => { "primary" => { "database" => "dev-db" }, "secondary" => { "database" => "secondary-dev-db" } },
|
||||
"development" => {
|
||||
"primary" => { "adapter" => "abstract", "database" => "dev-db" },
|
||||
"secondary" => { "adapter" => "abstract", "database" => "secondary-dev-db" },
|
||||
},
|
||||
}
|
||||
with_stubbed_configurations(configurations) do
|
||||
assert_equal "/tmp/secondary_#{filename}", ActiveRecord::Tasks::DatabaseTasks.schema_dump_path(config_for("development", "secondary"), fmt)
|
||||
|
|
|
@ -33,7 +33,7 @@ module ARTest
|
|||
end
|
||||
|
||||
connection[name]["database"] ||= dbname
|
||||
connection[name]["adapter"] ||= adapter
|
||||
connection[name]["adapter"] ||= adapter == "sqlite3_mem" ? "sqlite3" : adapter
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -0,0 +1,42 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class FakeActiveRecordAdapter < ActiveRecord::ConnectionAdapters::AbstractAdapter
|
||||
attr_accessor :data_sources, :primary_keys
|
||||
|
||||
@columns = Hash.new { |h, k| h[k] = [] }
|
||||
class << self
|
||||
attr_reader :columns
|
||||
end
|
||||
|
||||
def initialize(...)
|
||||
super
|
||||
@data_sources = []
|
||||
@primary_keys = {}
|
||||
@columns = self.class.columns
|
||||
end
|
||||
|
||||
def primary_key(table)
|
||||
@primary_keys[table] || "id"
|
||||
end
|
||||
|
||||
def merge_column(table_name, name, sql_type = nil, options = {})
|
||||
@columns[table_name] << ActiveRecord::ConnectionAdapters::Column.new(
|
||||
name.to_s,
|
||||
options[:default],
|
||||
fetch_type_metadata(sql_type),
|
||||
options[:null],
|
||||
)
|
||||
end
|
||||
|
||||
def columns(table_name)
|
||||
@columns[table_name]
|
||||
end
|
||||
|
||||
def data_source_exists?(*)
|
||||
true
|
||||
end
|
||||
|
||||
def active?
|
||||
true
|
||||
end
|
||||
end
|
|
@ -16,8 +16,8 @@ module Rails
|
|||
|
||||
def start
|
||||
adapter_class.dbconsole(db_config, @options)
|
||||
rescue NotImplementedError
|
||||
abort "Unknown command-line client for #{db_config.database}."
|
||||
rescue NotImplementedError, ActiveRecord::AdapterNotFound, LoadError => error
|
||||
abort error.message
|
||||
end
|
||||
|
||||
def db_config
|
||||
|
@ -50,11 +50,9 @@ module Rails
|
|||
|
||||
private
|
||||
def adapter_class
|
||||
if ActiveRecord::Base.respond_to?(db_config.adapter_class_method)
|
||||
ActiveRecord::Base.public_send(db_config.adapter_class_method)
|
||||
else
|
||||
ActiveRecord::ConnectionAdapters::AbstractAdapter
|
||||
end
|
||||
ActiveRecord::ConnectionAdapters.resolve(db_config.adapter)
|
||||
rescue LoadError, ActiveRecord::AdapterNotFound
|
||||
ActiveRecord::ConnectionAdapters::AbstractAdapter
|
||||
end
|
||||
|
||||
def configurations # :doc:
|
||||
|
|
|
@ -120,7 +120,7 @@ class Rails::DBConsoleTest < ActiveSupport::TestCase
|
|||
def test_unknown_command_line_client
|
||||
start(adapter: "unknown", database: "db")
|
||||
assert aborted
|
||||
assert_match(/Unknown command-line client for db/, output)
|
||||
assert_match(/database configuration specifies nonexistent 'unknown' adapter/, output)
|
||||
end
|
||||
|
||||
def test_primary_is_automatically_picked_with_3_level_configuration
|
||||
|
@ -153,9 +153,10 @@ class Rails::DBConsoleTest < ActiveSupport::TestCase
|
|||
|
||||
sample_config = {
|
||||
"test" => {
|
||||
"primary" => {},
|
||||
"primary" => { "adapter" => "sqlite3" },
|
||||
"primary_replica" => {
|
||||
"replica" => true
|
||||
"adapter" => "sqlite3",
|
||||
"replica" => true,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -210,10 +211,9 @@ class Rails::DBConsoleTest < ActiveSupport::TestCase
|
|||
attr_reader :dbconsole
|
||||
|
||||
def start(config = {}, argv = [])
|
||||
hash_config = ActiveRecord::DatabaseConfigurations::HashConfig.new("test", "primary", config)
|
||||
|
||||
@dbconsole = Rails::DBConsole.new(parse_arguments(argv))
|
||||
@dbconsole.stub(:db_config, hash_config) do
|
||||
hash_config = nil
|
||||
@dbconsole.stub(:db_config, -> { hash_config ||= ActiveRecord::DatabaseConfigurations::HashConfig.new("test", "primary", config) }) do
|
||||
capture_abort { @dbconsole.start }
|
||||
end
|
||||
end
|
||||
|
|
|
@ -49,6 +49,7 @@ module GeneratorsTestHelper
|
|||
ActiveRecord::Base.configurations = {
|
||||
test: {
|
||||
"#{database_name}": {
|
||||
adapter: "sqlite3",
|
||||
database: "db/#{database_name}.sqlite3",
|
||||
migrations_paths: "db/#{database_name}_migrate",
|
||||
},
|
||||
|
|
Loading…
Reference in New Issue