activerecord 6.0.1 → 6.1.0
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of activerecord might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/CHANGELOG.md +843 -626
- data/MIT-LICENSE +1 -1
- data/README.rdoc +3 -3
- data/lib/active_record/aggregations.rb +1 -2
- data/lib/active_record/association_relation.rb +18 -17
- data/lib/active_record/associations/alias_tracker.rb +19 -16
- data/lib/active_record/associations/association.rb +49 -37
- data/lib/active_record/associations/association_scope.rb +17 -15
- data/lib/active_record/associations/belongs_to_association.rb +15 -5
- data/lib/active_record/associations/belongs_to_polymorphic_association.rb +1 -1
- data/lib/active_record/associations/builder/association.rb +9 -3
- data/lib/active_record/associations/builder/belongs_to.rb +10 -7
- data/lib/active_record/associations/builder/collection_association.rb +5 -4
- data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +0 -3
- data/lib/active_record/associations/builder/has_many.rb +6 -2
- data/lib/active_record/associations/builder/has_one.rb +11 -14
- data/lib/active_record/associations/builder/singular_association.rb +1 -1
- data/lib/active_record/associations/collection_association.rb +25 -8
- data/lib/active_record/associations/collection_proxy.rb +14 -7
- data/lib/active_record/associations/foreign_association.rb +13 -0
- data/lib/active_record/associations/has_many_association.rb +24 -3
- data/lib/active_record/associations/has_many_through_association.rb +10 -4
- data/lib/active_record/associations/has_one_association.rb +15 -1
- data/lib/active_record/associations/join_dependency/join_association.rb +36 -14
- data/lib/active_record/associations/join_dependency/join_part.rb +3 -3
- data/lib/active_record/associations/join_dependency.rb +73 -42
- data/lib/active_record/associations/preloader/association.rb +51 -25
- data/lib/active_record/associations/preloader/through_association.rb +2 -2
- data/lib/active_record/associations/preloader.rb +12 -7
- data/lib/active_record/associations/singular_association.rb +1 -1
- data/lib/active_record/associations/through_association.rb +1 -1
- data/lib/active_record/associations.rb +115 -12
- data/lib/active_record/attribute_assignment.rb +10 -9
- data/lib/active_record/attribute_methods/before_type_cast.rb +13 -10
- data/lib/active_record/attribute_methods/dirty.rb +3 -13
- data/lib/active_record/attribute_methods/primary_key.rb +6 -4
- data/lib/active_record/attribute_methods/query.rb +3 -6
- data/lib/active_record/attribute_methods/read.rb +8 -12
- data/lib/active_record/attribute_methods/serialization.rb +11 -6
- data/lib/active_record/attribute_methods/time_zone_conversion.rb +12 -15
- data/lib/active_record/attribute_methods/write.rb +12 -21
- data/lib/active_record/attribute_methods.rb +64 -54
- data/lib/active_record/attributes.rb +32 -8
- data/lib/active_record/autosave_association.rb +56 -41
- data/lib/active_record/base.rb +2 -14
- data/lib/active_record/callbacks.rb +153 -24
- data/lib/active_record/coders/yaml_column.rb +1 -2
- data/lib/active_record/connection_adapters/abstract/connection_pool.rb +190 -136
- data/lib/active_record/connection_adapters/abstract/database_limits.rb +2 -44
- data/lib/active_record/connection_adapters/abstract/database_statements.rb +82 -37
- data/lib/active_record/connection_adapters/abstract/query_cache.rb +2 -8
- data/lib/active_record/connection_adapters/abstract/quoting.rb +34 -34
- data/lib/active_record/connection_adapters/abstract/savepoints.rb +3 -3
- data/lib/active_record/connection_adapters/abstract/schema_creation.rb +152 -116
- data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +137 -52
- data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +3 -3
- data/lib/active_record/connection_adapters/abstract/schema_statements.rb +263 -107
- data/lib/active_record/connection_adapters/abstract/transaction.rb +82 -35
- data/lib/active_record/connection_adapters/abstract_adapter.rb +60 -73
- data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +136 -111
- data/lib/active_record/connection_adapters/column.rb +15 -1
- data/lib/active_record/connection_adapters/deduplicable.rb +29 -0
- data/lib/active_record/connection_adapters/legacy_pool_manager.rb +31 -0
- data/lib/active_record/connection_adapters/mysql/column.rb +1 -1
- data/lib/active_record/connection_adapters/mysql/database_statements.rb +28 -36
- data/lib/active_record/connection_adapters/mysql/explain_pretty_printer.rb +1 -2
- data/lib/active_record/connection_adapters/mysql/quoting.rb +1 -1
- data/lib/active_record/connection_adapters/mysql/schema_creation.rb +32 -7
- data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +8 -0
- data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +1 -1
- data/lib/active_record/connection_adapters/mysql/schema_statements.rb +17 -13
- data/lib/active_record/connection_adapters/mysql/type_metadata.rb +10 -1
- data/lib/active_record/connection_adapters/mysql2_adapter.rb +31 -13
- data/lib/active_record/connection_adapters/pool_config.rb +63 -0
- data/lib/active_record/connection_adapters/pool_manager.rb +43 -0
- data/lib/active_record/connection_adapters/postgresql/column.rb +24 -1
- data/lib/active_record/connection_adapters/postgresql/database_statements.rb +19 -56
- data/lib/active_record/connection_adapters/postgresql/oid/array.rb +0 -1
- data/lib/active_record/connection_adapters/postgresql/oid/cidr.rb +3 -5
- data/lib/active_record/connection_adapters/postgresql/oid/date.rb +2 -2
- data/lib/active_record/connection_adapters/postgresql/oid/date_time.rb +10 -2
- data/lib/active_record/connection_adapters/postgresql/oid/enum.rb +0 -1
- data/lib/active_record/connection_adapters/postgresql/oid/hstore.rb +0 -1
- data/lib/active_record/connection_adapters/postgresql/oid/interval.rb +49 -0
- data/lib/active_record/connection_adapters/postgresql/oid/legacy_point.rb +2 -3
- data/lib/active_record/connection_adapters/postgresql/oid/macaddr.rb +25 -0
- data/lib/active_record/connection_adapters/postgresql/oid/oid.rb +1 -1
- data/lib/active_record/connection_adapters/postgresql/oid/point.rb +2 -3
- data/lib/active_record/connection_adapters/postgresql/oid/range.rb +24 -6
- data/lib/active_record/connection_adapters/postgresql/oid/specialized_string.rb +1 -1
- data/lib/active_record/connection_adapters/postgresql/oid/uuid.rb +11 -2
- data/lib/active_record/connection_adapters/postgresql/oid.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/quoting.rb +4 -4
- data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +2 -2
- data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +7 -3
- data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +1 -1
- data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +0 -1
- data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +72 -54
- data/lib/active_record/connection_adapters/postgresql/type_metadata.rb +8 -0
- data/lib/active_record/connection_adapters/postgresql/utils.rb +0 -1
- data/lib/active_record/connection_adapters/postgresql_adapter.rb +77 -57
- data/lib/active_record/connection_adapters/schema_cache.rb +98 -15
- data/lib/active_record/connection_adapters/sql_type_metadata.rb +10 -0
- data/lib/active_record/connection_adapters/sqlite3/database_statements.rb +36 -12
- data/lib/active_record/connection_adapters/sqlite3/quoting.rb +1 -2
- data/lib/active_record/connection_adapters/sqlite3/schema_creation.rb +5 -1
- data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +38 -5
- data/lib/active_record/connection_adapters/sqlite3_adapter.rb +57 -57
- data/lib/active_record/connection_adapters/statement_pool.rb +0 -1
- data/lib/active_record/connection_adapters.rb +50 -0
- data/lib/active_record/connection_handling.rb +210 -87
- data/lib/active_record/core.rb +229 -65
- data/lib/active_record/counter_cache.rb +4 -1
- data/lib/active_record/database_configurations/connection_url_resolver.rb +98 -0
- data/lib/active_record/database_configurations/database_config.rb +52 -9
- data/lib/active_record/database_configurations/hash_config.rb +54 -8
- data/lib/active_record/database_configurations/url_config.rb +15 -41
- data/lib/active_record/database_configurations.rb +124 -85
- data/lib/active_record/delegated_type.rb +209 -0
- data/lib/active_record/destroy_association_async_job.rb +36 -0
- data/lib/active_record/dynamic_matchers.rb +2 -3
- data/lib/active_record/enum.rb +40 -16
- data/lib/active_record/errors.rb +47 -12
- data/lib/active_record/explain.rb +9 -5
- data/lib/active_record/explain_subscriber.rb +1 -1
- data/lib/active_record/fixture_set/file.rb +10 -17
- data/lib/active_record/fixture_set/model_metadata.rb +1 -2
- data/lib/active_record/fixture_set/render_context.rb +1 -1
- data/lib/active_record/fixture_set/table_row.rb +2 -3
- data/lib/active_record/fixture_set/table_rows.rb +0 -1
- data/lib/active_record/fixtures.rb +54 -11
- data/lib/active_record/gem_version.rb +2 -2
- data/lib/active_record/inheritance.rb +40 -21
- data/lib/active_record/insert_all.rb +38 -9
- data/lib/active_record/integration.rb +3 -5
- data/lib/active_record/internal_metadata.rb +16 -7
- data/lib/active_record/legacy_yaml_adapter.rb +7 -3
- data/lib/active_record/locking/optimistic.rb +22 -17
- data/lib/active_record/locking/pessimistic.rb +6 -2
- data/lib/active_record/log_subscriber.rb +27 -9
- data/lib/active_record/middleware/database_selector/resolver/session.rb +3 -0
- data/lib/active_record/middleware/database_selector/resolver.rb +6 -2
- data/lib/active_record/middleware/database_selector.rb +4 -2
- data/lib/active_record/migration/command_recorder.rb +53 -45
- data/lib/active_record/migration/compatibility.rb +70 -20
- data/lib/active_record/migration/join_table.rb +0 -1
- data/lib/active_record/migration.rb +114 -84
- data/lib/active_record/model_schema.rb +117 -15
- data/lib/active_record/nested_attributes.rb +2 -5
- data/lib/active_record/no_touching.rb +1 -1
- data/lib/active_record/null_relation.rb +0 -1
- data/lib/active_record/persistence.rb +50 -46
- data/lib/active_record/query_cache.rb +15 -5
- data/lib/active_record/querying.rb +12 -7
- data/lib/active_record/railtie.rb +65 -45
- data/lib/active_record/railties/databases.rake +267 -93
- data/lib/active_record/readonly_attributes.rb +4 -0
- data/lib/active_record/reflection.rb +77 -63
- data/lib/active_record/relation/batches/batch_enumerator.rb +25 -9
- data/lib/active_record/relation/batches.rb +38 -32
- data/lib/active_record/relation/calculations.rb +102 -45
- data/lib/active_record/relation/delegation.rb +9 -7
- data/lib/active_record/relation/finder_methods.rb +45 -16
- data/lib/active_record/relation/from_clause.rb +5 -1
- data/lib/active_record/relation/merger.rb +27 -26
- data/lib/active_record/relation/predicate_builder/array_handler.rb +8 -9
- data/lib/active_record/relation/predicate_builder/association_query_value.rb +4 -5
- data/lib/active_record/relation/predicate_builder/polymorphic_array_value.rb +3 -3
- data/lib/active_record/relation/predicate_builder/relation_handler.rb +1 -1
- data/lib/active_record/relation/predicate_builder.rb +55 -35
- data/lib/active_record/relation/query_methods.rb +335 -187
- data/lib/active_record/relation/record_fetch_warning.rb +3 -3
- data/lib/active_record/relation/spawn_methods.rb +8 -8
- data/lib/active_record/relation/where_clause.rb +104 -58
- data/lib/active_record/relation.rb +108 -68
- data/lib/active_record/result.rb +41 -34
- data/lib/active_record/runtime_registry.rb +2 -2
- data/lib/active_record/sanitization.rb +6 -17
- data/lib/active_record/schema_dumper.rb +34 -4
- data/lib/active_record/schema_migration.rb +2 -8
- data/lib/active_record/scoping/default.rb +0 -1
- data/lib/active_record/scoping/named.rb +7 -18
- data/lib/active_record/scoping.rb +0 -1
- data/lib/active_record/secure_token.rb +16 -8
- data/lib/active_record/serialization.rb +5 -3
- data/lib/active_record/signed_id.rb +116 -0
- data/lib/active_record/statement_cache.rb +20 -4
- data/lib/active_record/store.rb +3 -3
- data/lib/active_record/suppressor.rb +2 -2
- data/lib/active_record/table_metadata.rb +39 -36
- data/lib/active_record/tasks/database_tasks.rb +139 -113
- data/lib/active_record/tasks/mysql_database_tasks.rb +34 -36
- data/lib/active_record/tasks/postgresql_database_tasks.rb +24 -27
- data/lib/active_record/tasks/sqlite_database_tasks.rb +13 -10
- data/lib/active_record/test_databases.rb +5 -4
- data/lib/active_record/test_fixtures.rb +38 -16
- data/lib/active_record/timestamp.rb +4 -7
- data/lib/active_record/touch_later.rb +20 -21
- data/lib/active_record/transactions.rb +21 -70
- data/lib/active_record/type/adapter_specific_registry.rb +2 -5
- data/lib/active_record/type/hash_lookup_type_map.rb +0 -1
- data/lib/active_record/type/serialized.rb +6 -3
- data/lib/active_record/type/time.rb +10 -0
- data/lib/active_record/type/type_map.rb +0 -1
- data/lib/active_record/type/unsigned_integer.rb +0 -1
- data/lib/active_record/type.rb +8 -2
- data/lib/active_record/type_caster/connection.rb +0 -1
- data/lib/active_record/type_caster/map.rb +8 -5
- data/lib/active_record/validations/associated.rb +1 -2
- data/lib/active_record/validations/numericality.rb +35 -0
- data/lib/active_record/validations/uniqueness.rb +24 -4
- data/lib/active_record/validations.rb +3 -3
- data/lib/active_record.rb +7 -13
- data/lib/arel/attributes/attribute.rb +4 -0
- data/lib/arel/collectors/bind.rb +5 -0
- data/lib/arel/collectors/composite.rb +8 -0
- data/lib/arel/collectors/sql_string.rb +7 -0
- data/lib/arel/collectors/substitute_binds.rb +7 -0
- data/lib/arel/nodes/binary.rb +82 -8
- data/lib/arel/nodes/bind_param.rb +8 -0
- data/lib/arel/nodes/casted.rb +21 -9
- data/lib/arel/nodes/equality.rb +6 -9
- data/lib/arel/nodes/grouping.rb +3 -0
- data/lib/arel/nodes/homogeneous_in.rb +72 -0
- data/lib/arel/nodes/in.rb +8 -1
- data/lib/arel/nodes/infix_operation.rb +13 -1
- data/lib/arel/nodes/join_source.rb +1 -1
- data/lib/arel/nodes/node.rb +7 -6
- data/lib/arel/nodes/ordering.rb +27 -0
- data/lib/arel/nodes/sql_literal.rb +3 -0
- data/lib/arel/nodes/table_alias.rb +7 -3
- data/lib/arel/nodes/unary.rb +0 -1
- data/lib/arel/nodes.rb +3 -1
- data/lib/arel/predications.rb +17 -24
- data/lib/arel/select_manager.rb +1 -2
- data/lib/arel/table.rb +13 -5
- data/lib/arel/visitors/dot.rb +14 -3
- data/lib/arel/visitors/mysql.rb +11 -1
- data/lib/arel/visitors/postgresql.rb +15 -5
- data/lib/arel/visitors/sqlite.rb +0 -1
- data/lib/arel/visitors/to_sql.rb +89 -79
- data/lib/arel/visitors/visitor.rb +0 -1
- data/lib/arel/visitors.rb +0 -7
- data/lib/arel.rb +5 -9
- data/lib/rails/generators/active_record/application_record/application_record_generator.rb +0 -1
- data/lib/rails/generators/active_record/migration/migration_generator.rb +1 -0
- data/lib/rails/generators/active_record/migration/templates/create_table_migration.rb.tt +2 -0
- data/lib/rails/generators/active_record/migration/templates/migration.rb.tt +4 -4
- data/lib/rails/generators/active_record/migration.rb +6 -2
- data/lib/rails/generators/active_record/model/model_generator.rb +38 -2
- data/lib/rails/generators/active_record/model/templates/abstract_base_class.rb.tt +7 -0
- metadata +26 -26
- data/lib/active_record/attribute_decorators.rb +0 -90
- data/lib/active_record/connection_adapters/connection_specification.rb +0 -297
- data/lib/active_record/connection_adapters/determine_if_preparable_visitor.rb +0 -29
- data/lib/active_record/define_callbacks.rb +0 -22
- data/lib/active_record/railties/collection_cache_association_loading.rb +0 -34
- data/lib/active_record/relation/predicate_builder/base_handler.rb +0 -18
- data/lib/active_record/relation/where_clause_factory.rb +0 -33
- data/lib/arel/attributes.rb +0 -22
- data/lib/arel/visitors/depth_first.rb +0 -204
- data/lib/arel/visitors/ibm_db.rb +0 -34
- data/lib/arel/visitors/informix.rb +0 -62
- data/lib/arel/visitors/mssql.rb +0 -157
- data/lib/arel/visitors/oracle.rb +0 -159
- data/lib/arel/visitors/oracle12.rb +0 -66
- data/lib/arel/visitors/where_sql.rb +0 -23
@@ -4,7 +4,6 @@ require "active_record/database_configurations"
|
|
4
4
|
|
5
5
|
module ActiveRecord
|
6
6
|
module Tasks # :nodoc:
|
7
|
-
class DatabaseAlreadyExists < StandardError; end # :nodoc:
|
8
7
|
class DatabaseNotSupported < StandardError; end # :nodoc:
|
9
8
|
|
10
9
|
# ActiveRecord::Tasks::DatabaseTasks is a utility class, which encapsulates
|
@@ -39,17 +38,18 @@ module ActiveRecord
|
|
39
38
|
module DatabaseTasks
|
40
39
|
##
|
41
40
|
# :singleton-method:
|
42
|
-
# Extra flags passed to database CLI tool (mysqldump/pg_dump) when calling db:
|
41
|
+
# Extra flags passed to database CLI tool (mysqldump/pg_dump) when calling db:schema:dump
|
43
42
|
mattr_accessor :structure_dump_flags, instance_accessor: false
|
44
43
|
|
45
44
|
##
|
46
45
|
# :singleton-method:
|
47
|
-
# Extra flags passed to database CLI tool when calling db:
|
46
|
+
# Extra flags passed to database CLI tool when calling db:schema:load
|
48
47
|
mattr_accessor :structure_load_flags, instance_accessor: false
|
49
48
|
|
50
49
|
extend self
|
51
50
|
|
52
51
|
attr_writer :current_config, :db_dir, :migrations_paths, :fixtures_path, :root, :env, :seed_loader
|
52
|
+
deprecate :current_config=
|
53
53
|
attr_accessor :database_configuration
|
54
54
|
|
55
55
|
LOCAL_HOSTS = ["127.0.0.1", "localhost"]
|
@@ -106,38 +106,45 @@ module ActiveRecord
|
|
106
106
|
def spec
|
107
107
|
@spec ||= "primary"
|
108
108
|
end
|
109
|
+
deprecate spec: "please use name instead"
|
110
|
+
|
111
|
+
def name
|
112
|
+
@name ||= "primary"
|
113
|
+
end
|
109
114
|
|
110
115
|
def seed_loader
|
111
116
|
@seed_loader ||= Rails.application
|
112
117
|
end
|
113
118
|
|
114
119
|
def current_config(options = {})
|
115
|
-
options.reverse_merge! env: env
|
116
|
-
options[:spec] ||= "primary"
|
117
120
|
if options.has_key?(:config)
|
118
121
|
@current_config = options[:config]
|
119
122
|
else
|
120
|
-
|
123
|
+
env_name = options[:env] || env
|
124
|
+
name = options[:spec] || "primary"
|
125
|
+
|
126
|
+
@current_config ||= ActiveRecord::Base.configurations.configs_for(env_name: env_name, name: name)&.configuration_hash
|
121
127
|
end
|
122
128
|
end
|
129
|
+
deprecate :current_config
|
123
130
|
|
124
|
-
def create(*arguments)
|
125
|
-
|
126
|
-
|
127
|
-
$stdout.puts "Created database '#{
|
131
|
+
def create(configuration, *arguments)
|
132
|
+
db_config = resolve_configuration(configuration)
|
133
|
+
database_adapter_for(db_config, *arguments).create
|
134
|
+
$stdout.puts "Created database '#{db_config.database}'" if verbose?
|
128
135
|
rescue DatabaseAlreadyExists
|
129
|
-
$stderr.puts "Database '#{
|
136
|
+
$stderr.puts "Database '#{db_config.database}' already exists" if verbose?
|
130
137
|
rescue Exception => error
|
131
138
|
$stderr.puts error
|
132
|
-
$stderr.puts "Couldn't create '#{
|
139
|
+
$stderr.puts "Couldn't create '#{db_config.database}' database. Please check your configuration."
|
133
140
|
raise
|
134
141
|
end
|
135
142
|
|
136
143
|
def create_all
|
137
144
|
old_pool = ActiveRecord::Base.connection_handler.retrieve_connection_pool(ActiveRecord::Base.connection_specification_name)
|
138
|
-
each_local_configuration { |
|
145
|
+
each_local_configuration { |db_config| create(db_config) }
|
139
146
|
if old_pool
|
140
|
-
ActiveRecord::Base.connection_handler.establish_connection(old_pool.
|
147
|
+
ActiveRecord::Base.connection_handler.establish_connection(old_pool.db_config)
|
141
148
|
end
|
142
149
|
end
|
143
150
|
|
@@ -147,7 +154,9 @@ module ActiveRecord
|
|
147
154
|
begin
|
148
155
|
Rails.application.config.load_database_yaml
|
149
156
|
rescue
|
150
|
-
|
157
|
+
unless ActiveRecord::Base.suppress_multiple_database_warning
|
158
|
+
$stderr.puts "Rails couldn't infer whether you are using multiple databases from your database.yml and can't generate the tasks for the non-primary databases. If you'd like to use this feature, please simplify your ERB."
|
159
|
+
end
|
151
160
|
|
152
161
|
{}
|
153
162
|
end
|
@@ -162,7 +171,7 @@ module ActiveRecord
|
|
162
171
|
return if database_configs.count == 1
|
163
172
|
|
164
173
|
database_configs.each do |db_config|
|
165
|
-
yield db_config.
|
174
|
+
yield db_config.name
|
166
175
|
end
|
167
176
|
end
|
168
177
|
|
@@ -173,59 +182,49 @@ module ActiveRecord
|
|
173
182
|
dbs_list = []
|
174
183
|
|
175
184
|
db_configs.each do |db|
|
176
|
-
dbs_list << "#{command}:#{db.
|
185
|
+
dbs_list << "#{command}:#{db.name}"
|
177
186
|
end
|
178
187
|
|
179
188
|
raise "You're using a multiple database application. To use `#{command}` you must run the namespaced task with a VERSION. Available tasks are #{dbs_list.to_sentence}."
|
180
189
|
end
|
181
190
|
end
|
182
191
|
|
183
|
-
def create_current(environment = env,
|
184
|
-
each_current_configuration(environment,
|
185
|
-
create configuration
|
186
|
-
}
|
192
|
+
def create_current(environment = env, name = nil)
|
193
|
+
each_current_configuration(environment, name) { |db_config| create(db_config) }
|
187
194
|
ActiveRecord::Base.establish_connection(environment.to_sym)
|
188
195
|
end
|
189
196
|
|
190
|
-
def drop(*arguments)
|
191
|
-
|
192
|
-
|
193
|
-
$stdout.puts "Dropped database '#{
|
197
|
+
def drop(configuration, *arguments)
|
198
|
+
db_config = resolve_configuration(configuration)
|
199
|
+
database_adapter_for(db_config, *arguments).drop
|
200
|
+
$stdout.puts "Dropped database '#{db_config.database}'" if verbose?
|
194
201
|
rescue ActiveRecord::NoDatabaseError
|
195
|
-
$stderr.puts "Database '#{
|
202
|
+
$stderr.puts "Database '#{db_config.database}' does not exist"
|
196
203
|
rescue Exception => error
|
197
204
|
$stderr.puts error
|
198
|
-
$stderr.puts "Couldn't drop database '#{
|
205
|
+
$stderr.puts "Couldn't drop database '#{db_config.database}'"
|
199
206
|
raise
|
200
207
|
end
|
201
208
|
|
202
209
|
def drop_all
|
203
|
-
each_local_configuration { |
|
210
|
+
each_local_configuration { |db_config| drop(db_config) }
|
204
211
|
end
|
205
212
|
|
206
213
|
def drop_current(environment = env)
|
207
|
-
each_current_configuration(environment) { |
|
208
|
-
drop configuration
|
209
|
-
}
|
214
|
+
each_current_configuration(environment) { |db_config| drop(db_config) }
|
210
215
|
end
|
211
216
|
|
212
|
-
def truncate_tables(
|
213
|
-
ActiveRecord::Base.
|
214
|
-
conn = ActiveRecord::Base.connection
|
215
|
-
table_names = conn.tables
|
216
|
-
table_names -= [
|
217
|
-
conn.schema_migration.table_name,
|
218
|
-
InternalMetadata.table_name
|
219
|
-
]
|
217
|
+
def truncate_tables(db_config)
|
218
|
+
ActiveRecord::Base.establish_connection(db_config)
|
220
219
|
|
221
|
-
|
222
|
-
|
220
|
+
connection = ActiveRecord::Base.connection
|
221
|
+
connection.truncate_tables(*connection.tables)
|
223
222
|
end
|
224
223
|
private :truncate_tables
|
225
224
|
|
226
225
|
def truncate_all(environment = env)
|
227
226
|
ActiveRecord::Base.configurations.configs_for(env_name: environment).each do |db_config|
|
228
|
-
truncate_tables
|
227
|
+
truncate_tables(db_config)
|
229
228
|
end
|
230
229
|
end
|
231
230
|
|
@@ -250,7 +249,7 @@ module ActiveRecord
|
|
250
249
|
end
|
251
250
|
|
252
251
|
# output
|
253
|
-
puts "\ndatabase: #{ActiveRecord::Base.
|
252
|
+
puts "\ndatabase: #{ActiveRecord::Base.connection_db_config.database}\n\n"
|
254
253
|
puts "#{'Status'.center(8)} #{'Migration ID'.ljust(14)} Migration Name"
|
255
254
|
puts "-" * 50
|
256
255
|
ActiveRecord::Base.connection.migration_context.migrations_status.each do |status, version, name|
|
@@ -269,106 +268,116 @@ module ActiveRecord
|
|
269
268
|
ENV["VERSION"].to_i if ENV["VERSION"] && !ENV["VERSION"].empty?
|
270
269
|
end
|
271
270
|
|
272
|
-
def charset_current(
|
273
|
-
|
271
|
+
def charset_current(env_name = env, db_name = name)
|
272
|
+
db_config = ActiveRecord::Base.configurations.configs_for(env_name: env_name, name: db_name)
|
273
|
+
charset(db_config)
|
274
274
|
end
|
275
275
|
|
276
|
-
def charset(*arguments)
|
277
|
-
|
278
|
-
|
276
|
+
def charset(configuration, *arguments)
|
277
|
+
db_config = resolve_configuration(configuration)
|
278
|
+
database_adapter_for(db_config, *arguments).charset
|
279
279
|
end
|
280
280
|
|
281
|
-
def collation_current(
|
282
|
-
|
281
|
+
def collation_current(env_name = env, db_name = name)
|
282
|
+
db_config = ActiveRecord::Base.configurations.configs_for(env_name: env_name, name: db_name)
|
283
|
+
collation(db_config)
|
283
284
|
end
|
284
285
|
|
285
|
-
def collation(*arguments)
|
286
|
-
|
287
|
-
|
286
|
+
def collation(configuration, *arguments)
|
287
|
+
db_config = resolve_configuration(configuration)
|
288
|
+
database_adapter_for(db_config, *arguments).collation
|
288
289
|
end
|
289
290
|
|
290
291
|
def purge(configuration)
|
291
|
-
|
292
|
+
db_config = resolve_configuration(configuration)
|
293
|
+
database_adapter_for(db_config).purge
|
292
294
|
end
|
293
295
|
|
294
296
|
def purge_all
|
295
|
-
each_local_configuration { |
|
296
|
-
purge configuration
|
297
|
-
}
|
297
|
+
each_local_configuration { |db_config| purge(db_config) }
|
298
298
|
end
|
299
299
|
|
300
300
|
def purge_current(environment = env)
|
301
|
-
each_current_configuration(environment) { |
|
302
|
-
purge configuration
|
303
|
-
}
|
301
|
+
each_current_configuration(environment) { |db_config| purge(db_config) }
|
304
302
|
ActiveRecord::Base.establish_connection(environment.to_sym)
|
305
303
|
end
|
306
304
|
|
307
|
-
def structure_dump(*arguments)
|
308
|
-
|
309
|
-
filename = arguments.delete_at
|
310
|
-
|
305
|
+
def structure_dump(configuration, *arguments)
|
306
|
+
db_config = resolve_configuration(configuration)
|
307
|
+
filename = arguments.delete_at(0)
|
308
|
+
database_adapter_for(db_config, *arguments).structure_dump(filename, structure_dump_flags)
|
311
309
|
end
|
312
310
|
|
313
|
-
def structure_load(*arguments)
|
314
|
-
|
315
|
-
filename = arguments.delete_at
|
316
|
-
|
311
|
+
def structure_load(configuration, *arguments)
|
312
|
+
db_config = resolve_configuration(configuration)
|
313
|
+
filename = arguments.delete_at(0)
|
314
|
+
database_adapter_for(db_config, *arguments).structure_load(filename, structure_load_flags)
|
317
315
|
end
|
318
316
|
|
319
|
-
def load_schema(
|
320
|
-
file ||= dump_filename(
|
317
|
+
def load_schema(db_config, format = ActiveRecord::Base.schema_format, file = nil) # :nodoc:
|
318
|
+
file ||= dump_filename(db_config.name, format)
|
321
319
|
|
322
320
|
verbose_was, Migration.verbose = Migration.verbose, verbose? && ENV["VERBOSE"]
|
323
321
|
check_schema_file(file)
|
324
|
-
ActiveRecord::Base.establish_connection(
|
322
|
+
ActiveRecord::Base.establish_connection(db_config)
|
325
323
|
|
326
324
|
case format
|
327
325
|
when :ruby
|
328
326
|
load(file)
|
329
327
|
when :sql
|
330
|
-
structure_load(
|
328
|
+
structure_load(db_config, file)
|
331
329
|
else
|
332
330
|
raise ArgumentError, "unknown format #{format.inspect}"
|
333
331
|
end
|
334
332
|
ActiveRecord::InternalMetadata.create_table
|
335
|
-
ActiveRecord::InternalMetadata[:environment] =
|
333
|
+
ActiveRecord::InternalMetadata[:environment] = db_config.env_name
|
336
334
|
ActiveRecord::InternalMetadata[:schema_sha1] = schema_sha1(file)
|
337
335
|
ensure
|
338
336
|
Migration.verbose = verbose_was
|
339
337
|
end
|
340
338
|
|
341
|
-
def schema_up_to_date?(configuration, format = ActiveRecord::Base.schema_format, file = nil, environment =
|
342
|
-
|
339
|
+
def schema_up_to_date?(configuration, format = ActiveRecord::Base.schema_format, file = nil, environment = nil, name = nil)
|
340
|
+
db_config = resolve_configuration(configuration)
|
341
|
+
|
342
|
+
if environment || name
|
343
|
+
ActiveSupport::Deprecation.warn("`environment` and `name` will be removed as parameters in 6.2.0, you may now pass an ActiveRecord::DatabaseConfigurations::DatabaseConfig as `configuration` instead.")
|
344
|
+
end
|
345
|
+
|
346
|
+
name ||= db_config.name
|
347
|
+
|
348
|
+
file ||= dump_filename(name, format)
|
343
349
|
|
344
350
|
return true unless File.exist?(file)
|
345
351
|
|
346
|
-
ActiveRecord::Base.establish_connection(
|
352
|
+
ActiveRecord::Base.establish_connection(db_config)
|
353
|
+
|
354
|
+
return false unless ActiveRecord::InternalMetadata.enabled?
|
347
355
|
return false unless ActiveRecord::InternalMetadata.table_exists?
|
356
|
+
|
348
357
|
ActiveRecord::InternalMetadata[:schema_sha1] == schema_sha1(file)
|
349
358
|
end
|
350
359
|
|
351
|
-
def reconstruct_from_schema(
|
352
|
-
file ||= dump_filename(
|
360
|
+
def reconstruct_from_schema(db_config, format = ActiveRecord::Base.schema_format, file = nil) # :nodoc:
|
361
|
+
file ||= dump_filename(db_config.name, format)
|
353
362
|
|
354
363
|
check_schema_file(file)
|
355
364
|
|
356
|
-
ActiveRecord::Base.establish_connection(
|
365
|
+
ActiveRecord::Base.establish_connection(db_config)
|
357
366
|
|
358
|
-
if schema_up_to_date?(
|
359
|
-
truncate_tables(
|
367
|
+
if schema_up_to_date?(db_config, format, file)
|
368
|
+
truncate_tables(db_config)
|
360
369
|
else
|
361
|
-
purge(
|
362
|
-
load_schema(
|
370
|
+
purge(db_config)
|
371
|
+
load_schema(db_config, format, file)
|
363
372
|
end
|
364
373
|
rescue ActiveRecord::NoDatabaseError
|
365
|
-
create(
|
366
|
-
load_schema(
|
374
|
+
create(db_config)
|
375
|
+
load_schema(db_config, format, file)
|
367
376
|
end
|
368
377
|
|
369
|
-
def dump_schema(
|
378
|
+
def dump_schema(db_config, format = ActiveRecord::Base.schema_format) # :nodoc:
|
370
379
|
require "active_record/schema_dumper"
|
371
|
-
filename = dump_filename(
|
380
|
+
filename = dump_filename(db_config.name, format)
|
372
381
|
connection = ActiveRecord::Base.connection
|
373
382
|
|
374
383
|
case format
|
@@ -377,7 +386,7 @@ module ActiveRecord
|
|
377
386
|
ActiveRecord::SchemaDumper.dump(ActiveRecord::Base.connection, file)
|
378
387
|
end
|
379
388
|
when :sql
|
380
|
-
structure_dump(
|
389
|
+
structure_dump(db_config, filename)
|
381
390
|
if connection.schema_migration.table_exists?
|
382
391
|
File.open(filename, "a") do |f|
|
383
392
|
f.puts connection.dump_schema_information
|
@@ -400,36 +409,36 @@ module ActiveRecord
|
|
400
409
|
end
|
401
410
|
end
|
402
411
|
|
403
|
-
def dump_filename(
|
404
|
-
filename = if
|
412
|
+
def dump_filename(db_config_name, format = ActiveRecord::Base.schema_format)
|
413
|
+
filename = if ActiveRecord::Base.configurations.primary?(db_config_name)
|
405
414
|
schema_file_type(format)
|
406
415
|
else
|
407
|
-
"#{
|
416
|
+
"#{db_config_name}_#{schema_file_type(format)}"
|
408
417
|
end
|
409
418
|
|
410
419
|
ENV["SCHEMA"] || File.join(ActiveRecord::Tasks::DatabaseTasks.db_dir, filename)
|
411
420
|
end
|
412
421
|
|
413
|
-
def cache_dump_filename(
|
414
|
-
filename = if
|
422
|
+
def cache_dump_filename(db_config_name, schema_cache_path: nil)
|
423
|
+
filename = if ActiveRecord::Base.configurations.primary?(db_config_name)
|
415
424
|
"schema_cache.yml"
|
416
425
|
else
|
417
|
-
"#{
|
426
|
+
"#{db_config_name}_schema_cache.yml"
|
418
427
|
end
|
419
428
|
|
420
|
-
ENV["SCHEMA_CACHE"] || File.join(ActiveRecord::Tasks::DatabaseTasks.db_dir, filename)
|
429
|
+
schema_cache_path || ENV["SCHEMA_CACHE"] || File.join(ActiveRecord::Tasks::DatabaseTasks.db_dir, filename)
|
421
430
|
end
|
422
431
|
|
423
432
|
def load_schema_current(format = ActiveRecord::Base.schema_format, file = nil, environment = env)
|
424
|
-
each_current_configuration(environment)
|
425
|
-
load_schema(
|
426
|
-
|
433
|
+
each_current_configuration(environment) do |db_config|
|
434
|
+
load_schema(db_config, format, file)
|
435
|
+
end
|
427
436
|
ActiveRecord::Base.establish_connection(environment.to_sym)
|
428
437
|
end
|
429
438
|
|
430
439
|
def check_schema_file(filename)
|
431
440
|
unless File.exist?(filename)
|
432
|
-
message = +%{#{filename} doesn't exist yet. Run `rails db:migrate` to create it, then try again.}
|
441
|
+
message = +%{#{filename} doesn't exist yet. Run `bin/rails db:migrate` to create it, then try again.}
|
433
442
|
message << %{ If you do not intend to use a database, you should instead alter #{Rails.root}/config/application.rb to limit the frameworks that will be loaded.} if defined?(::Rails.root)
|
434
443
|
Kernel.abort message
|
435
444
|
end
|
@@ -450,16 +459,33 @@ module ActiveRecord
|
|
450
459
|
# ==== Examples:
|
451
460
|
# ActiveRecord::Tasks::DatabaseTasks.dump_schema_cache(ActiveRecord::Base.connection, "tmp/schema_dump.yaml")
|
452
461
|
def dump_schema_cache(conn, filename)
|
453
|
-
conn.schema_cache.
|
454
|
-
|
455
|
-
|
462
|
+
conn.schema_cache.dump_to(filename)
|
463
|
+
end
|
464
|
+
|
465
|
+
def clear_schema_cache(filename)
|
466
|
+
FileUtils.rm_f filename, verbose: false
|
456
467
|
end
|
457
468
|
|
458
469
|
private
|
470
|
+
def resolve_configuration(configuration)
|
471
|
+
Base.configurations.resolve(configuration)
|
472
|
+
end
|
473
|
+
|
459
474
|
def verbose?
|
460
475
|
ENV["VERBOSE"] ? ENV["VERBOSE"] != "false" : true
|
461
476
|
end
|
462
477
|
|
478
|
+
# Create a new instance for the specified db configuration object
|
479
|
+
# For classes that have been converted to use db_config objects, pass a
|
480
|
+
# `DatabaseConfig`, otherwise pass a `Hash`
|
481
|
+
def database_adapter_for(db_config, *arguments)
|
482
|
+
klass = class_for_adapter(db_config.adapter)
|
483
|
+
converted = klass.respond_to?(:using_database_configurations?) && klass.using_database_configurations?
|
484
|
+
|
485
|
+
config = converted ? db_config : db_config.configuration_hash
|
486
|
+
klass.new(config, *arguments)
|
487
|
+
end
|
488
|
+
|
463
489
|
def class_for_adapter(adapter)
|
464
490
|
_key, task = @tasks.each_pair.detect { |pattern, _task| adapter[pattern] }
|
465
491
|
unless task
|
@@ -468,34 +494,34 @@ module ActiveRecord
|
|
468
494
|
task.is_a?(String) ? task.constantize : task
|
469
495
|
end
|
470
496
|
|
471
|
-
def each_current_configuration(environment,
|
497
|
+
def each_current_configuration(environment, name = nil)
|
472
498
|
environments = [environment]
|
473
|
-
environments << "test" if environment == "development"
|
499
|
+
environments << "test" if environment == "development" && !ENV["SKIP_TEST_DATABASE"] && !ENV["DATABASE_URL"]
|
474
500
|
|
475
501
|
environments.each do |env|
|
476
502
|
ActiveRecord::Base.configurations.configs_for(env_name: env).each do |db_config|
|
477
|
-
next if
|
503
|
+
next if name && name != db_config.name
|
478
504
|
|
479
|
-
yield db_config
|
505
|
+
yield db_config
|
480
506
|
end
|
481
507
|
end
|
482
508
|
end
|
483
509
|
|
484
510
|
def each_local_configuration
|
485
511
|
ActiveRecord::Base.configurations.configs_for.each do |db_config|
|
486
|
-
|
487
|
-
next unless configuration["database"]
|
512
|
+
next unless db_config.database
|
488
513
|
|
489
|
-
if local_database?(
|
490
|
-
yield
|
514
|
+
if local_database?(db_config)
|
515
|
+
yield db_config
|
491
516
|
else
|
492
|
-
$stderr.puts "This task only modifies local databases. #{
|
517
|
+
$stderr.puts "This task only modifies local databases. #{db_config.database} is on a remote host."
|
493
518
|
end
|
494
519
|
end
|
495
520
|
end
|
496
521
|
|
497
|
-
def local_database?(
|
498
|
-
|
522
|
+
def local_database?(db_config)
|
523
|
+
host = db_config.host
|
524
|
+
host.blank? || LOCAL_HOSTS.include?(host)
|
499
525
|
end
|
500
526
|
|
501
527
|
def schema_sha1(file)
|
@@ -7,30 +7,29 @@ module ActiveRecord
|
|
7
7
|
|
8
8
|
delegate :connection, :establish_connection, to: ActiveRecord::Base
|
9
9
|
|
10
|
-
def
|
11
|
-
|
10
|
+
def self.using_database_configurations?
|
11
|
+
true
|
12
|
+
end
|
13
|
+
|
14
|
+
def initialize(db_config)
|
15
|
+
@db_config = db_config
|
16
|
+
@configuration_hash = db_config.configuration_hash
|
12
17
|
end
|
13
18
|
|
14
19
|
def create
|
15
|
-
establish_connection
|
16
|
-
connection.create_database
|
17
|
-
establish_connection
|
18
|
-
rescue ActiveRecord::StatementInvalid => error
|
19
|
-
if connection.error_number(error.cause) == ER_DB_CREATE_EXISTS
|
20
|
-
raise DatabaseAlreadyExists
|
21
|
-
else
|
22
|
-
raise
|
23
|
-
end
|
20
|
+
establish_connection(configuration_hash_without_database)
|
21
|
+
connection.create_database(db_config.database, creation_options)
|
22
|
+
establish_connection(db_config)
|
24
23
|
end
|
25
24
|
|
26
25
|
def drop
|
27
|
-
establish_connection
|
28
|
-
connection.drop_database
|
26
|
+
establish_connection(db_config)
|
27
|
+
connection.drop_database(db_config.database)
|
29
28
|
end
|
30
29
|
|
31
30
|
def purge
|
32
|
-
establish_connection
|
33
|
-
connection.recreate_database
|
31
|
+
establish_connection(db_config)
|
32
|
+
connection.recreate_database(db_config.database, creation_options)
|
34
33
|
end
|
35
34
|
|
36
35
|
def charset
|
@@ -50,10 +49,10 @@ module ActiveRecord
|
|
50
49
|
|
51
50
|
ignore_tables = ActiveRecord::SchemaDumper.ignore_tables
|
52
51
|
if ignore_tables.any?
|
53
|
-
args += ignore_tables.map { |table| "--ignore-table=#{
|
52
|
+
args += ignore_tables.map { |table| "--ignore-table=#{db_config.database}.#{table}" }
|
54
53
|
end
|
55
54
|
|
56
|
-
args.concat([
|
55
|
+
args.concat([db_config.database.to_s])
|
57
56
|
args.unshift(*extra_flags) if extra_flags
|
58
57
|
|
59
58
|
run_cmd("mysqldump", args, "dumping")
|
@@ -62,41 +61,40 @@ module ActiveRecord
|
|
62
61
|
def structure_load(filename, extra_flags)
|
63
62
|
args = prepare_command_options
|
64
63
|
args.concat(["--execute", %{SET FOREIGN_KEY_CHECKS = 0; SOURCE #{filename}; SET FOREIGN_KEY_CHECKS = 1}])
|
65
|
-
args.concat(["--database",
|
64
|
+
args.concat(["--database", db_config.database.to_s])
|
66
65
|
args.unshift(*extra_flags) if extra_flags
|
67
66
|
|
68
67
|
run_cmd("mysql", args, "loading")
|
69
68
|
end
|
70
69
|
|
71
70
|
private
|
71
|
+
attr_reader :db_config, :configuration_hash
|
72
72
|
|
73
|
-
|
74
|
-
|
75
|
-
def configuration_without_database
|
76
|
-
configuration.merge("database" => nil)
|
73
|
+
def configuration_hash_without_database
|
74
|
+
configuration_hash.merge(database: nil)
|
77
75
|
end
|
78
76
|
|
79
77
|
def creation_options
|
80
78
|
Hash.new.tap do |options|
|
81
|
-
options[:charset] =
|
82
|
-
options[:collation] =
|
79
|
+
options[:charset] = configuration_hash[:encoding] if configuration_hash.include?(:encoding)
|
80
|
+
options[:collation] = configuration_hash[:collation] if configuration_hash.include?(:collation)
|
83
81
|
end
|
84
82
|
end
|
85
83
|
|
86
84
|
def prepare_command_options
|
87
85
|
args = {
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
}.map { |opt, arg| "#{arg}=#{
|
86
|
+
host: "--host",
|
87
|
+
port: "--port",
|
88
|
+
socket: "--socket",
|
89
|
+
username: "--user",
|
90
|
+
password: "--password",
|
91
|
+
encoding: "--default-character-set",
|
92
|
+
sslca: "--ssl-ca",
|
93
|
+
sslcert: "--ssl-cert",
|
94
|
+
sslcapath: "--ssl-capath",
|
95
|
+
sslcipher: "--ssl-cipher",
|
96
|
+
sslkey: "--ssl-key"
|
97
|
+
}.map { |opt, arg| "#{arg}=#{configuration_hash[opt]}" if configuration_hash[opt] }.compact
|
100
98
|
|
101
99
|
args
|
102
100
|
end
|