activerecord 7.0.8.7 → 7.1.5.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +1795 -1424
- data/MIT-LICENSE +1 -1
- data/README.rdoc +16 -16
- data/lib/active_record/aggregations.rb +16 -13
- data/lib/active_record/association_relation.rb +1 -1
- data/lib/active_record/associations/association.rb +20 -4
- data/lib/active_record/associations/association_scope.rb +16 -9
- data/lib/active_record/associations/belongs_to_association.rb +14 -6
- data/lib/active_record/associations/builder/association.rb +3 -3
- data/lib/active_record/associations/builder/belongs_to.rb +21 -8
- data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +1 -5
- data/lib/active_record/associations/builder/singular_association.rb +4 -0
- data/lib/active_record/associations/collection_association.rb +19 -13
- data/lib/active_record/associations/collection_proxy.rb +15 -10
- data/lib/active_record/associations/foreign_association.rb +10 -3
- data/lib/active_record/associations/has_many_association.rb +20 -13
- data/lib/active_record/associations/has_many_through_association.rb +10 -6
- data/lib/active_record/associations/has_one_association.rb +10 -3
- data/lib/active_record/associations/join_dependency/join_association.rb +3 -2
- data/lib/active_record/associations/join_dependency.rb +10 -10
- data/lib/active_record/associations/preloader/association.rb +31 -7
- data/lib/active_record/associations/preloader.rb +13 -10
- data/lib/active_record/associations/singular_association.rb +1 -1
- data/lib/active_record/associations/through_association.rb +22 -11
- data/lib/active_record/associations.rb +319 -217
- data/lib/active_record/attribute_assignment.rb +0 -2
- data/lib/active_record/attribute_methods/before_type_cast.rb +17 -0
- data/lib/active_record/attribute_methods/dirty.rb +53 -35
- data/lib/active_record/attribute_methods/primary_key.rb +76 -24
- data/lib/active_record/attribute_methods/query.rb +28 -16
- data/lib/active_record/attribute_methods/read.rb +21 -8
- data/lib/active_record/attribute_methods/serialization.rb +150 -31
- data/lib/active_record/attribute_methods/time_zone_conversion.rb +4 -0
- data/lib/active_record/attribute_methods/write.rb +6 -6
- data/lib/active_record/attribute_methods.rb +145 -21
- data/lib/active_record/attributes.rb +3 -3
- data/lib/active_record/autosave_association.rb +59 -10
- data/lib/active_record/base.rb +7 -2
- data/lib/active_record/callbacks.rb +10 -24
- data/lib/active_record/coders/column_serializer.rb +61 -0
- data/lib/active_record/coders/json.rb +1 -1
- data/lib/active_record/coders/yaml_column.rb +70 -42
- data/lib/active_record/connection_adapters/abstract/connection_handler.rb +163 -88
- data/lib/active_record/connection_adapters/abstract/connection_pool/queue.rb +2 -0
- data/lib/active_record/connection_adapters/abstract/connection_pool/reaper.rb +3 -1
- data/lib/active_record/connection_adapters/abstract/connection_pool.rb +80 -50
- data/lib/active_record/connection_adapters/abstract/database_limits.rb +5 -0
- data/lib/active_record/connection_adapters/abstract/database_statements.rb +129 -31
- data/lib/active_record/connection_adapters/abstract/query_cache.rb +62 -23
- data/lib/active_record/connection_adapters/abstract/quoting.rb +41 -6
- data/lib/active_record/connection_adapters/abstract/savepoints.rb +4 -3
- data/lib/active_record/connection_adapters/abstract/schema_creation.rb +18 -4
- data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +137 -11
- data/lib/active_record/connection_adapters/abstract/schema_statements.rb +296 -127
- data/lib/active_record/connection_adapters/abstract/transaction.rb +287 -58
- data/lib/active_record/connection_adapters/abstract_adapter.rb +511 -92
- data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +244 -121
- data/lib/active_record/connection_adapters/column.rb +9 -0
- data/lib/active_record/connection_adapters/mysql/column.rb +1 -0
- data/lib/active_record/connection_adapters/mysql/database_statements.rb +22 -143
- data/lib/active_record/connection_adapters/mysql/quoting.rb +16 -12
- data/lib/active_record/connection_adapters/mysql/schema_creation.rb +9 -0
- data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +6 -0
- data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +1 -1
- data/lib/active_record/connection_adapters/mysql/schema_statements.rb +19 -13
- data/lib/active_record/connection_adapters/mysql2/database_statements.rb +151 -0
- data/lib/active_record/connection_adapters/mysql2_adapter.rb +106 -55
- data/lib/active_record/connection_adapters/pool_config.rb +14 -5
- data/lib/active_record/connection_adapters/pool_manager.rb +19 -9
- data/lib/active_record/connection_adapters/postgresql/column.rb +14 -3
- data/lib/active_record/connection_adapters/postgresql/database_statements.rb +74 -40
- data/lib/active_record/connection_adapters/postgresql/oid/cidr.rb +6 -0
- data/lib/active_record/connection_adapters/postgresql/oid/money.rb +3 -2
- data/lib/active_record/connection_adapters/postgresql/oid/range.rb +11 -2
- data/lib/active_record/connection_adapters/postgresql/oid/timestamp_with_time_zone.rb +1 -1
- data/lib/active_record/connection_adapters/postgresql/quoting.rb +10 -6
- data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +3 -9
- data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +76 -6
- data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +131 -2
- data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +53 -0
- data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +364 -61
- data/lib/active_record/connection_adapters/postgresql_adapter.rb +353 -192
- data/lib/active_record/connection_adapters/schema_cache.rb +287 -59
- data/lib/active_record/connection_adapters/sqlite3/column.rb +49 -0
- data/lib/active_record/connection_adapters/sqlite3/database_statements.rb +52 -39
- data/lib/active_record/connection_adapters/sqlite3/quoting.rb +4 -3
- data/lib/active_record/connection_adapters/sqlite3/schema_definitions.rb +1 -0
- data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +26 -7
- data/lib/active_record/connection_adapters/sqlite3_adapter.rb +211 -81
- data/lib/active_record/connection_adapters/statement_pool.rb +7 -0
- data/lib/active_record/connection_adapters/trilogy/database_statements.rb +99 -0
- data/lib/active_record/connection_adapters/trilogy_adapter.rb +258 -0
- data/lib/active_record/connection_adapters.rb +3 -1
- data/lib/active_record/connection_handling.rb +72 -95
- data/lib/active_record/core.rb +181 -154
- data/lib/active_record/counter_cache.rb +52 -27
- data/lib/active_record/database_configurations/connection_url_resolver.rb +1 -1
- data/lib/active_record/database_configurations/database_config.rb +9 -3
- data/lib/active_record/database_configurations/hash_config.rb +28 -14
- data/lib/active_record/database_configurations/url_config.rb +17 -11
- data/lib/active_record/database_configurations.rb +86 -33
- data/lib/active_record/delegated_type.rb +15 -10
- data/lib/active_record/deprecator.rb +7 -0
- data/lib/active_record/destroy_association_async_job.rb +3 -1
- data/lib/active_record/encryption/auto_filtered_parameters.rb +66 -0
- data/lib/active_record/encryption/cipher/aes256_gcm.rb +4 -1
- data/lib/active_record/encryption/config.rb +25 -1
- data/lib/active_record/encryption/configurable.rb +12 -19
- data/lib/active_record/encryption/context.rb +10 -3
- data/lib/active_record/encryption/contexts.rb +5 -1
- data/lib/active_record/encryption/derived_secret_key_provider.rb +8 -2
- data/lib/active_record/encryption/encryptable_record.rb +42 -18
- data/lib/active_record/encryption/encrypted_attribute_type.rb +23 -8
- data/lib/active_record/encryption/extended_deterministic_queries.rb +66 -69
- data/lib/active_record/encryption/extended_deterministic_uniqueness_validator.rb +3 -3
- data/lib/active_record/encryption/key_generator.rb +12 -1
- data/lib/active_record/encryption/message_serializer.rb +2 -0
- data/lib/active_record/encryption/properties.rb +3 -3
- data/lib/active_record/encryption/scheme.rb +22 -21
- data/lib/active_record/encryption.rb +3 -0
- data/lib/active_record/enum.rb +112 -28
- data/lib/active_record/errors.rb +112 -18
- data/lib/active_record/explain.rb +23 -3
- data/lib/active_record/fixture_set/model_metadata.rb +14 -4
- data/lib/active_record/fixture_set/render_context.rb +2 -0
- data/lib/active_record/fixture_set/table_row.rb +29 -8
- data/lib/active_record/fixtures.rb +135 -71
- data/lib/active_record/future_result.rb +40 -5
- data/lib/active_record/gem_version.rb +4 -4
- data/lib/active_record/inheritance.rb +30 -16
- data/lib/active_record/insert_all.rb +57 -10
- data/lib/active_record/integration.rb +8 -8
- data/lib/active_record/internal_metadata.rb +120 -30
- data/lib/active_record/locking/optimistic.rb +1 -1
- data/lib/active_record/locking/pessimistic.rb +5 -2
- data/lib/active_record/log_subscriber.rb +29 -12
- data/lib/active_record/marshalling.rb +59 -0
- data/lib/active_record/message_pack.rb +124 -0
- data/lib/active_record/middleware/database_selector/resolver.rb +4 -0
- data/lib/active_record/middleware/database_selector.rb +6 -8
- data/lib/active_record/middleware/shard_selector.rb +3 -1
- data/lib/active_record/migration/command_recorder.rb +104 -5
- data/lib/active_record/migration/compatibility.rb +145 -5
- data/lib/active_record/migration/default_strategy.rb +23 -0
- data/lib/active_record/migration/execution_strategy.rb +19 -0
- data/lib/active_record/migration/pending_migration_connection.rb +21 -0
- data/lib/active_record/migration.rb +219 -111
- data/lib/active_record/model_schema.rb +69 -44
- data/lib/active_record/nested_attributes.rb +37 -8
- data/lib/active_record/normalization.rb +167 -0
- data/lib/active_record/persistence.rb +188 -37
- data/lib/active_record/promise.rb +84 -0
- data/lib/active_record/query_cache.rb +4 -22
- data/lib/active_record/query_logs.rb +77 -52
- data/lib/active_record/query_logs_formatter.rb +41 -0
- data/lib/active_record/querying.rb +15 -2
- data/lib/active_record/railtie.rb +107 -45
- data/lib/active_record/railties/controller_runtime.rb +12 -6
- data/lib/active_record/railties/databases.rake +144 -150
- data/lib/active_record/railties/job_runtime.rb +23 -0
- data/lib/active_record/readonly_attributes.rb +32 -5
- data/lib/active_record/reflection.rb +181 -45
- data/lib/active_record/relation/batches/batch_enumerator.rb +5 -3
- data/lib/active_record/relation/batches.rb +190 -61
- data/lib/active_record/relation/calculations.rb +187 -63
- data/lib/active_record/relation/delegation.rb +23 -9
- data/lib/active_record/relation/finder_methods.rb +77 -16
- data/lib/active_record/relation/merger.rb +2 -0
- data/lib/active_record/relation/predicate_builder/association_query_value.rb +11 -2
- data/lib/active_record/relation/predicate_builder/polymorphic_array_value.rb +10 -7
- data/lib/active_record/relation/predicate_builder/relation_handler.rb +5 -1
- data/lib/active_record/relation/predicate_builder.rb +26 -14
- data/lib/active_record/relation/query_attribute.rb +2 -1
- data/lib/active_record/relation/query_methods.rb +371 -68
- data/lib/active_record/relation/spawn_methods.rb +18 -1
- data/lib/active_record/relation.rb +103 -37
- data/lib/active_record/result.rb +19 -5
- data/lib/active_record/runtime_registry.rb +24 -1
- data/lib/active_record/sanitization.rb +51 -11
- data/lib/active_record/schema.rb +2 -3
- data/lib/active_record/schema_dumper.rb +46 -7
- data/lib/active_record/schema_migration.rb +68 -33
- data/lib/active_record/scoping/default.rb +15 -5
- data/lib/active_record/scoping/named.rb +2 -2
- data/lib/active_record/scoping.rb +2 -1
- data/lib/active_record/secure_password.rb +60 -0
- data/lib/active_record/secure_token.rb +21 -3
- data/lib/active_record/signed_id.rb +7 -5
- data/lib/active_record/store.rb +8 -8
- data/lib/active_record/suppressor.rb +3 -1
- data/lib/active_record/table_metadata.rb +10 -1
- data/lib/active_record/tasks/database_tasks.rb +152 -108
- data/lib/active_record/tasks/mysql_database_tasks.rb +15 -6
- data/lib/active_record/tasks/postgresql_database_tasks.rb +16 -13
- data/lib/active_record/tasks/sqlite_database_tasks.rb +15 -7
- data/lib/active_record/test_fixtures.rb +114 -96
- data/lib/active_record/timestamp.rb +30 -16
- data/lib/active_record/token_for.rb +113 -0
- data/lib/active_record/touch_later.rb +11 -6
- data/lib/active_record/transactions.rb +36 -10
- data/lib/active_record/type/adapter_specific_registry.rb +1 -8
- data/lib/active_record/type/internal/timezone.rb +7 -2
- data/lib/active_record/type/time.rb +4 -0
- data/lib/active_record/validations/absence.rb +1 -1
- data/lib/active_record/validations/numericality.rb +5 -4
- data/lib/active_record/validations/presence.rb +5 -28
- data/lib/active_record/validations/uniqueness.rb +47 -2
- data/lib/active_record/validations.rb +8 -4
- data/lib/active_record/version.rb +1 -1
- data/lib/active_record.rb +122 -17
- data/lib/arel/errors.rb +10 -0
- data/lib/arel/factory_methods.rb +4 -0
- data/lib/arel/nodes/binary.rb +6 -1
- data/lib/arel/nodes/bound_sql_literal.rb +61 -0
- data/lib/arel/nodes/cte.rb +36 -0
- data/lib/arel/nodes/fragments.rb +35 -0
- data/lib/arel/nodes/homogeneous_in.rb +1 -9
- data/lib/arel/nodes/leading_join.rb +8 -0
- data/lib/arel/nodes/node.rb +111 -2
- data/lib/arel/nodes/sql_literal.rb +6 -0
- data/lib/arel/nodes/table_alias.rb +4 -0
- data/lib/arel/nodes.rb +4 -0
- data/lib/arel/predications.rb +2 -0
- data/lib/arel/table.rb +9 -5
- data/lib/arel/tree_manager.rb +5 -1
- data/lib/arel/visitors/mysql.rb +8 -1
- data/lib/arel/visitors/to_sql.rb +83 -18
- data/lib/arel/visitors/visitor.rb +2 -2
- data/lib/arel.rb +16 -2
- data/lib/rails/generators/active_record/application_record/USAGE +8 -0
- data/lib/rails/generators/active_record/migration.rb +3 -1
- data/lib/rails/generators/active_record/model/USAGE +113 -0
- data/lib/rails/generators/active_record/model/model_generator.rb +15 -6
- metadata +46 -10
- data/lib/active_record/connection_adapters/legacy_pool_manager.rb +0 -35
- data/lib/active_record/null_relation.rb +0 -63
@@ -6,14 +6,16 @@ module ActiveRecord
|
|
6
6
|
module Tasks # :nodoc:
|
7
7
|
class DatabaseNotSupported < StandardError; end # :nodoc:
|
8
8
|
|
9
|
+
# = Active Record \DatabaseTasks
|
10
|
+
#
|
9
11
|
# ActiveRecord::Tasks::DatabaseTasks is a utility class, which encapsulates
|
10
12
|
# logic behind common tasks used to manage database and migrations.
|
11
13
|
#
|
12
|
-
# The tasks defined here are used with Rails commands provided by Active Record.
|
14
|
+
# The tasks defined here are used with \Rails commands provided by Active Record.
|
13
15
|
#
|
14
16
|
# In order to use DatabaseTasks, a few config values need to be set. All the needed
|
15
|
-
# config values are set by Rails already, so it's necessary to do it only if you
|
16
|
-
# want to change the defaults or when you want to use Active Record outside of Rails
|
17
|
+
# config values are set by \Rails already, so it's necessary to do it only if you
|
18
|
+
# want to change the defaults or when you want to use Active Record outside of \Rails
|
17
19
|
# (in such case after configuring the database tasks, you can also use the rake tasks
|
18
20
|
# defined in Active Record).
|
19
21
|
#
|
@@ -27,7 +29,7 @@ module ActiveRecord
|
|
27
29
|
# * +seed_loader+: an object which will load seeds, it needs to respond to the +load_seed+ method.
|
28
30
|
# * +root+: a path to the root of the application.
|
29
31
|
#
|
30
|
-
# Example usage of DatabaseTasks outside Rails could look as such:
|
32
|
+
# Example usage of DatabaseTasks outside \Rails could look as such:
|
31
33
|
#
|
32
34
|
# include ActiveRecord::Tasks
|
33
35
|
# DatabaseTasks.database_configuration = YAML.load_file('my_database_config.yml')
|
@@ -60,20 +62,12 @@ module ActiveRecord
|
|
60
62
|
|
61
63
|
LOCAL_HOSTS = ["127.0.0.1", "localhost"]
|
62
64
|
|
63
|
-
def check_protected_environments!
|
64
|
-
|
65
|
-
current = ActiveRecord::Base.connection.migration_context.current_environment
|
66
|
-
stored = ActiveRecord::Base.connection.migration_context.last_stored_environment
|
67
|
-
|
68
|
-
if ActiveRecord::Base.connection.migration_context.protected_environment?
|
69
|
-
raise ActiveRecord::ProtectedEnvironmentError.new(stored)
|
70
|
-
end
|
65
|
+
def check_protected_environments!(environment = env)
|
66
|
+
return if ENV["DISABLE_DATABASE_ENVIRONMENT_CHECK"]
|
71
67
|
|
72
|
-
|
73
|
-
|
74
|
-
end
|
68
|
+
configs_for(env_name: environment).each do |db_config|
|
69
|
+
check_current_protected_environment!(db_config)
|
75
70
|
end
|
76
|
-
rescue ActiveRecord::NoDatabaseError
|
77
71
|
end
|
78
72
|
|
79
73
|
def register_task(pattern, task)
|
@@ -82,6 +76,7 @@ module ActiveRecord
|
|
82
76
|
end
|
83
77
|
|
84
78
|
register_task(/mysql/, "ActiveRecord::Tasks::MySQLDatabaseTasks")
|
79
|
+
register_task(/trilogy/, "ActiveRecord::Tasks::MySQLDatabaseTasks")
|
85
80
|
register_task(/postgresql/, "ActiveRecord::Tasks::PostgreSQLDatabaseTasks")
|
86
81
|
register_task(/sqlite/, "ActiveRecord::Tasks::SQLiteDatabaseTasks")
|
87
82
|
|
@@ -130,28 +125,20 @@ module ActiveRecord
|
|
130
125
|
end
|
131
126
|
|
132
127
|
def create_all
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
128
|
+
each_local_configuration do |db_config|
|
129
|
+
with_temporary_connection(db_config) do
|
130
|
+
create(db_config)
|
131
|
+
end
|
137
132
|
end
|
138
133
|
end
|
139
134
|
|
140
|
-
def setup_initial_database_yaml
|
135
|
+
def setup_initial_database_yaml # :nodoc:
|
141
136
|
return {} unless defined?(Rails)
|
142
137
|
|
143
|
-
|
144
|
-
Rails.application.config.load_database_yaml
|
145
|
-
rescue
|
146
|
-
unless ActiveRecord.suppress_multiple_database_warning
|
147
|
-
$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."
|
148
|
-
end
|
149
|
-
|
150
|
-
{}
|
151
|
-
end
|
138
|
+
Rails.application.config.load_database_yaml
|
152
139
|
end
|
153
140
|
|
154
|
-
def for_each(databases)
|
141
|
+
def for_each(databases) # :nodoc:
|
155
142
|
return {} unless defined?(Rails)
|
156
143
|
|
157
144
|
database_configs = ActiveRecord::DatabaseConfigurations.new(databases).configs_for(env_name: Rails.env)
|
@@ -166,7 +153,7 @@ module ActiveRecord
|
|
166
153
|
end
|
167
154
|
end
|
168
155
|
|
169
|
-
def raise_for_multi_db(environment = env, command:)
|
156
|
+
def raise_for_multi_db(environment = env, command:) # :nodoc:
|
170
157
|
db_configs = configs_for(env_name: environment)
|
171
158
|
|
172
159
|
if db_configs.count > 1
|
@@ -182,40 +169,54 @@ module ActiveRecord
|
|
182
169
|
|
183
170
|
def create_current(environment = env, name = nil)
|
184
171
|
each_current_configuration(environment, name) { |db_config| create(db_config) }
|
185
|
-
|
172
|
+
|
173
|
+
migration_class.establish_connection(environment.to_sym)
|
186
174
|
end
|
187
175
|
|
188
176
|
def prepare_all
|
189
177
|
seed = false
|
178
|
+
dump_db_configs = []
|
190
179
|
|
191
180
|
each_current_configuration(env) do |db_config|
|
192
|
-
|
181
|
+
with_temporary_pool(db_config) do
|
182
|
+
begin
|
183
|
+
database_initialized = migration_connection.schema_migration.table_exists?
|
184
|
+
rescue ActiveRecord::NoDatabaseError
|
185
|
+
create(db_config)
|
186
|
+
retry
|
187
|
+
end
|
193
188
|
|
194
|
-
|
195
|
-
|
196
|
-
|
189
|
+
unless database_initialized
|
190
|
+
if File.exist?(schema_dump_path(db_config))
|
191
|
+
load_schema(db_config, ActiveRecord.schema_format, nil)
|
192
|
+
end
|
197
193
|
|
198
|
-
|
199
|
-
dump_schema(db_config, ActiveRecord.schema_format)
|
194
|
+
seed = true
|
200
195
|
end
|
201
|
-
|
202
|
-
|
196
|
+
end
|
197
|
+
end
|
203
198
|
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
)
|
210
|
-
|
211
|
-
|
199
|
+
each_current_environment(env) do |environment|
|
200
|
+
db_configs_with_versions(environment).sort.each do |version, db_configs|
|
201
|
+
dump_db_configs |= db_configs
|
202
|
+
|
203
|
+
db_configs.each do |db_config|
|
204
|
+
with_temporary_pool(db_config) do
|
205
|
+
migrate(version)
|
206
|
+
end
|
212
207
|
end
|
208
|
+
end
|
209
|
+
end
|
213
210
|
|
214
|
-
|
211
|
+
# Dump schema for databases that were migrated.
|
212
|
+
if ActiveRecord.dump_schema_after_migration
|
213
|
+
dump_db_configs.each do |db_config|
|
214
|
+
with_temporary_pool(db_config) do
|
215
|
+
dump_schema(db_config)
|
216
|
+
end
|
215
217
|
end
|
216
218
|
end
|
217
219
|
|
218
|
-
ActiveRecord::Base.establish_connection
|
219
220
|
load_seed if seed
|
220
221
|
end
|
221
222
|
|
@@ -240,10 +241,9 @@ module ActiveRecord
|
|
240
241
|
end
|
241
242
|
|
242
243
|
def truncate_tables(db_config)
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
connection.truncate_tables(*connection.tables)
|
244
|
+
with_temporary_connection(db_config) do |conn|
|
245
|
+
conn.truncate_tables(*conn.tables)
|
246
|
+
end
|
247
247
|
end
|
248
248
|
private :truncate_tables
|
249
249
|
|
@@ -254,12 +254,12 @@ module ActiveRecord
|
|
254
254
|
end
|
255
255
|
|
256
256
|
def migrate(version = nil)
|
257
|
-
check_target_version
|
258
|
-
|
259
257
|
scope = ENV["SCOPE"]
|
260
258
|
verbose_was, Migration.verbose = Migration.verbose, verbose?
|
261
259
|
|
262
|
-
|
260
|
+
check_target_version
|
261
|
+
|
262
|
+
migration_connection.migration_context.migrate(target_version) do |migration|
|
263
263
|
if version.blank?
|
264
264
|
scope.blank? || scope == migration.scope
|
265
265
|
else
|
@@ -269,17 +269,17 @@ module ActiveRecord
|
|
269
269
|
Migration.write("No migrations ran. (using #{scope} scope)") if scope.present? && migrations_ran.empty?
|
270
270
|
end
|
271
271
|
|
272
|
-
|
272
|
+
migration_connection.schema_cache.clear!
|
273
273
|
ensure
|
274
274
|
Migration.verbose = verbose_was
|
275
275
|
end
|
276
276
|
|
277
|
-
def db_configs_with_versions(
|
277
|
+
def db_configs_with_versions(environment = env) # :nodoc:
|
278
278
|
db_configs_with_versions = Hash.new { |h, k| h[k] = [] }
|
279
279
|
|
280
|
-
|
281
|
-
|
282
|
-
versions_to_run =
|
280
|
+
with_temporary_connection_for_each(env: environment) do |conn|
|
281
|
+
db_config = conn.pool.db_config
|
282
|
+
versions_to_run = conn.migration_context.pending_migration_versions
|
283
283
|
target_version = ActiveRecord::Tasks::DatabaseTasks.target_version
|
284
284
|
|
285
285
|
versions_to_run.each do |version|
|
@@ -292,22 +292,22 @@ module ActiveRecord
|
|
292
292
|
end
|
293
293
|
|
294
294
|
def migrate_status
|
295
|
-
unless
|
295
|
+
unless migration_connection.schema_migration.table_exists?
|
296
296
|
Kernel.abort "Schema migrations table does not exist yet."
|
297
297
|
end
|
298
298
|
|
299
299
|
# output
|
300
|
-
puts "\ndatabase: #{
|
300
|
+
puts "\ndatabase: #{migration_connection.pool.db_config.database}\n\n"
|
301
301
|
puts "#{'Status'.center(8)} #{'Migration ID'.ljust(14)} Migration Name"
|
302
302
|
puts "-" * 50
|
303
|
-
|
303
|
+
migration_connection.migration_context.migrations_status.each do |status, version, name|
|
304
304
|
puts "#{status.center(8)} #{version.ljust(14)} #{name}"
|
305
305
|
end
|
306
306
|
puts
|
307
307
|
end
|
308
308
|
|
309
309
|
def check_target_version
|
310
|
-
if target_version && !
|
310
|
+
if target_version && !Migration.valid_version_format?(ENV["VERSION"])
|
311
311
|
raise "Invalid format of target version: `VERSION=#{ENV['VERSION']}`"
|
312
312
|
end
|
313
313
|
end
|
@@ -347,7 +347,8 @@ module ActiveRecord
|
|
347
347
|
|
348
348
|
def purge_current(environment = env)
|
349
349
|
each_current_configuration(environment) { |db_config| purge(db_config) }
|
350
|
-
|
350
|
+
|
351
|
+
migration_class.establish_connection(environment.to_sym)
|
351
352
|
end
|
352
353
|
|
353
354
|
def structure_dump(configuration, *arguments)
|
@@ -370,7 +371,6 @@ module ActiveRecord
|
|
370
371
|
|
371
372
|
verbose_was, Migration.verbose = Migration.verbose, verbose? && ENV["VERBOSE"]
|
372
373
|
check_schema_file(file)
|
373
|
-
ActiveRecord::Base.establish_connection(db_config)
|
374
374
|
|
375
375
|
case format
|
376
376
|
when :ruby
|
@@ -380,9 +380,8 @@ module ActiveRecord
|
|
380
380
|
else
|
381
381
|
raise ArgumentError, "unknown format #{format.inspect}"
|
382
382
|
end
|
383
|
-
|
384
|
-
|
385
|
-
ActiveRecord::InternalMetadata[:schema_sha1] = schema_sha1(file)
|
383
|
+
|
384
|
+
migration_connection.internal_metadata.create_table_and_set_flags(db_config.env_name, schema_sha1(file))
|
386
385
|
ensure
|
387
386
|
Migration.verbose = verbose_was
|
388
387
|
end
|
@@ -394,12 +393,12 @@ module ActiveRecord
|
|
394
393
|
|
395
394
|
return true unless file && File.exist?(file)
|
396
395
|
|
397
|
-
|
396
|
+
with_temporary_connection(db_config) do |connection|
|
397
|
+
return false unless connection.internal_metadata.enabled?
|
398
|
+
return false unless connection.internal_metadata.table_exists?
|
398
399
|
|
399
|
-
|
400
|
-
|
401
|
-
|
402
|
-
ActiveRecord::InternalMetadata[:schema_sha1] == schema_sha1(file)
|
400
|
+
connection.internal_metadata[:schema_sha1] == schema_sha1(file)
|
401
|
+
end
|
403
402
|
end
|
404
403
|
|
405
404
|
def reconstruct_from_schema(db_config, format = ActiveRecord.schema_format, file = nil) # :nodoc:
|
@@ -407,53 +406,43 @@ module ActiveRecord
|
|
407
406
|
|
408
407
|
check_schema_file(file) if file
|
409
408
|
|
410
|
-
|
411
|
-
|
412
|
-
|
413
|
-
|
414
|
-
|
415
|
-
|
409
|
+
with_temporary_pool(db_config, clobber: true) do
|
410
|
+
if schema_up_to_date?(db_config, format, file)
|
411
|
+
truncate_tables(db_config)
|
412
|
+
else
|
413
|
+
purge(db_config)
|
414
|
+
load_schema(db_config, format, file)
|
415
|
+
end
|
416
|
+
rescue ActiveRecord::NoDatabaseError
|
417
|
+
create(db_config)
|
416
418
|
load_schema(db_config, format, file)
|
417
419
|
end
|
418
|
-
rescue ActiveRecord::NoDatabaseError
|
419
|
-
create(db_config)
|
420
|
-
load_schema(db_config, format, file)
|
421
420
|
end
|
422
421
|
|
423
422
|
def dump_schema(db_config, format = ActiveRecord.schema_format) # :nodoc:
|
423
|
+
return unless db_config.schema_dump
|
424
|
+
|
424
425
|
require "active_record/schema_dumper"
|
425
426
|
filename = schema_dump_path(db_config, format)
|
426
427
|
return unless filename
|
427
428
|
|
428
|
-
connection = ActiveRecord::Base.connection
|
429
|
-
|
430
429
|
FileUtils.mkdir_p(db_dir)
|
431
430
|
case format
|
432
431
|
when :ruby
|
433
432
|
File.open(filename, "w:utf-8") do |file|
|
434
|
-
ActiveRecord::SchemaDumper.dump(
|
433
|
+
ActiveRecord::SchemaDumper.dump(migration_connection, file)
|
435
434
|
end
|
436
435
|
when :sql
|
437
436
|
structure_dump(db_config, filename)
|
438
|
-
if
|
437
|
+
if migration_connection.schema_migration.table_exists?
|
439
438
|
File.open(filename, "a") do |f|
|
440
|
-
f.puts
|
439
|
+
f.puts migration_connection.dump_schema_information
|
441
440
|
f.print "\n"
|
442
441
|
end
|
443
442
|
end
|
444
443
|
end
|
445
444
|
end
|
446
445
|
|
447
|
-
def schema_file_type(format = ActiveRecord.schema_format)
|
448
|
-
case format
|
449
|
-
when :ruby
|
450
|
-
"schema.rb"
|
451
|
-
when :sql
|
452
|
-
"structure.sql"
|
453
|
-
end
|
454
|
-
end
|
455
|
-
deprecate :schema_file_type
|
456
|
-
|
457
446
|
def schema_dump_path(db_config, format = ActiveRecord.schema_format)
|
458
447
|
return ENV["SCHEMA"] if ENV["SCHEMA"]
|
459
448
|
|
@@ -479,9 +468,10 @@ module ActiveRecord
|
|
479
468
|
|
480
469
|
def load_schema_current(format = ActiveRecord.schema_format, file = nil, environment = env)
|
481
470
|
each_current_configuration(environment) do |db_config|
|
482
|
-
|
471
|
+
with_temporary_connection(db_config) do
|
472
|
+
load_schema(db_config, format, file)
|
473
|
+
end
|
483
474
|
end
|
484
|
-
ActiveRecord::Base.establish_connection(environment.to_sym)
|
485
475
|
end
|
486
476
|
|
487
477
|
def check_schema_file(filename)
|
@@ -504,7 +494,7 @@ module ActiveRecord
|
|
504
494
|
|
505
495
|
# Dumps the schema cache in YAML format for the connection into the file
|
506
496
|
#
|
507
|
-
# ==== Examples
|
497
|
+
# ==== Examples
|
508
498
|
# ActiveRecord::Tasks::DatabaseTasks.dump_schema_cache(ActiveRecord::Base.connection, "tmp/schema_dump.yaml")
|
509
499
|
def dump_schema_cache(conn, filename)
|
510
500
|
conn.schema_cache.dump_to(filename)
|
@@ -514,7 +504,41 @@ module ActiveRecord
|
|
514
504
|
FileUtils.rm_f filename, verbose: false
|
515
505
|
end
|
516
506
|
|
507
|
+
def with_temporary_connection_for_each(env: ActiveRecord::Tasks::DatabaseTasks.env, name: nil, clobber: false, &block) # :nodoc:
|
508
|
+
if name
|
509
|
+
db_config = ActiveRecord::Base.configurations.configs_for(env_name: env, name: name)
|
510
|
+
with_temporary_connection(db_config, clobber: clobber, &block)
|
511
|
+
else
|
512
|
+
ActiveRecord::Base.configurations.configs_for(env_name: env, name: name).each do |db_config|
|
513
|
+
with_temporary_connection(db_config, clobber: clobber, &block)
|
514
|
+
end
|
515
|
+
end
|
516
|
+
end
|
517
|
+
|
518
|
+
def with_temporary_connection(db_config, clobber: false) # :nodoc:
|
519
|
+
with_temporary_pool(db_config, clobber: clobber) do |pool|
|
520
|
+
yield pool.connection
|
521
|
+
end
|
522
|
+
end
|
523
|
+
|
524
|
+
def migration_class # :nodoc:
|
525
|
+
ActiveRecord::Base
|
526
|
+
end
|
527
|
+
|
528
|
+
def migration_connection # :nodoc:
|
529
|
+
migration_class.connection
|
530
|
+
end
|
531
|
+
|
517
532
|
private
|
533
|
+
def with_temporary_pool(db_config, clobber: false)
|
534
|
+
original_db_config = migration_class.connection_db_config
|
535
|
+
pool = migration_class.connection_handler.establish_connection(db_config, clobber: clobber)
|
536
|
+
|
537
|
+
yield pool
|
538
|
+
ensure
|
539
|
+
migration_class.connection_handler.establish_connection(original_db_config, clobber: clobber)
|
540
|
+
end
|
541
|
+
|
518
542
|
def configs_for(**options)
|
519
543
|
Base.configurations.configs_for(**options)
|
520
544
|
end
|
@@ -547,10 +571,7 @@ module ActiveRecord
|
|
547
571
|
end
|
548
572
|
|
549
573
|
def each_current_configuration(environment, name = nil)
|
550
|
-
|
551
|
-
environments << "test" if environment == "development" && !ENV["SKIP_TEST_DATABASE"] && !ENV["DATABASE_URL"]
|
552
|
-
|
553
|
-
environments.each do |env|
|
574
|
+
each_current_environment(environment) do |env|
|
554
575
|
configs_for(env_name: env).each do |db_config|
|
555
576
|
next if name && name != db_config.name
|
556
577
|
|
@@ -559,6 +580,12 @@ module ActiveRecord
|
|
559
580
|
end
|
560
581
|
end
|
561
582
|
|
583
|
+
def each_current_environment(environment, &block)
|
584
|
+
environments = [environment]
|
585
|
+
environments << "test" if environment == "development" && !ENV["SKIP_TEST_DATABASE"] && !ENV["DATABASE_URL"]
|
586
|
+
environments.each(&block)
|
587
|
+
end
|
588
|
+
|
562
589
|
def each_local_configuration
|
563
590
|
configs_for.each do |db_config|
|
564
591
|
next unless db_config.database
|
@@ -595,6 +622,23 @@ module ActiveRecord
|
|
595
622
|
structure_load_flags
|
596
623
|
end
|
597
624
|
end
|
625
|
+
|
626
|
+
def check_current_protected_environment!(db_config)
|
627
|
+
with_temporary_pool(db_config) do |pool|
|
628
|
+
connection = pool.connection
|
629
|
+
current = connection.migration_context.current_environment
|
630
|
+
stored = connection.migration_context.last_stored_environment
|
631
|
+
|
632
|
+
if connection.migration_context.protected_environment?
|
633
|
+
raise ActiveRecord::ProtectedEnvironmentError.new(stored)
|
634
|
+
end
|
635
|
+
|
636
|
+
if stored && stored != current
|
637
|
+
raise ActiveRecord::EnvironmentMismatchError.new(current: current, stored: stored)
|
638
|
+
end
|
639
|
+
rescue ActiveRecord::NoDatabaseError
|
640
|
+
end
|
641
|
+
end
|
598
642
|
end
|
599
643
|
end
|
600
644
|
end
|
@@ -5,8 +5,6 @@ module ActiveRecord
|
|
5
5
|
class MySQLDatabaseTasks # :nodoc:
|
6
6
|
ER_DB_CREATE_EXISTS = 1007
|
7
7
|
|
8
|
-
delegate :connection, :establish_connection, to: ActiveRecord::Base
|
9
|
-
|
10
8
|
def self.using_database_configurations?
|
11
9
|
true
|
12
10
|
end
|
@@ -19,17 +17,18 @@ module ActiveRecord
|
|
19
17
|
def create
|
20
18
|
establish_connection(configuration_hash_without_database)
|
21
19
|
connection.create_database(db_config.database, creation_options)
|
22
|
-
establish_connection
|
20
|
+
establish_connection
|
23
21
|
end
|
24
22
|
|
25
23
|
def drop
|
26
|
-
establish_connection
|
24
|
+
establish_connection
|
27
25
|
connection.drop_database(db_config.database)
|
28
26
|
end
|
29
27
|
|
30
28
|
def purge
|
31
|
-
establish_connection(
|
29
|
+
establish_connection(configuration_hash_without_database)
|
32
30
|
connection.recreate_database(db_config.database, creation_options)
|
31
|
+
establish_connection
|
33
32
|
end
|
34
33
|
|
35
34
|
def charset
|
@@ -49,6 +48,7 @@ module ActiveRecord
|
|
49
48
|
|
50
49
|
ignore_tables = ActiveRecord::SchemaDumper.ignore_tables
|
51
50
|
if ignore_tables.any?
|
51
|
+
ignore_tables = connection.data_sources.select { |table| ignore_tables.any? { |pattern| pattern === table } }
|
52
52
|
args += ignore_tables.map { |table| "--ignore-table=#{db_config.database}.#{table}" }
|
53
53
|
end
|
54
54
|
|
@@ -70,6 +70,14 @@ module ActiveRecord
|
|
70
70
|
private
|
71
71
|
attr_reader :db_config, :configuration_hash
|
72
72
|
|
73
|
+
def connection
|
74
|
+
ActiveRecord::Base.connection
|
75
|
+
end
|
76
|
+
|
77
|
+
def establish_connection(config = db_config)
|
78
|
+
ActiveRecord::Base.establish_connection(config)
|
79
|
+
end
|
80
|
+
|
73
81
|
def configuration_hash_without_database
|
74
82
|
configuration_hash.merge(database: nil)
|
75
83
|
end
|
@@ -93,7 +101,8 @@ module ActiveRecord
|
|
93
101
|
sslcert: "--ssl-cert",
|
94
102
|
sslcapath: "--ssl-capath",
|
95
103
|
sslcipher: "--ssl-cipher",
|
96
|
-
sslkey: "--ssl-key"
|
104
|
+
sslkey: "--ssl-key",
|
105
|
+
ssl_mode: "--ssl-mode"
|
97
106
|
}.filter_map { |opt, arg| "#{arg}=#{configuration_hash[opt]}" if configuration_hash[opt] }
|
98
107
|
|
99
108
|
args
|
@@ -9,9 +9,6 @@ module ActiveRecord
|
|
9
9
|
ON_ERROR_STOP_1 = "ON_ERROR_STOP=1"
|
10
10
|
SQL_COMMENT_BEGIN = "--"
|
11
11
|
|
12
|
-
delegate :connection, :establish_connection, :clear_active_connections!,
|
13
|
-
to: ActiveRecord::Base
|
14
|
-
|
15
12
|
def self.using_database_configurations?
|
16
13
|
true
|
17
14
|
end
|
@@ -21,14 +18,14 @@ module ActiveRecord
|
|
21
18
|
@configuration_hash = db_config.configuration_hash
|
22
19
|
end
|
23
20
|
|
24
|
-
def create(
|
25
|
-
|
21
|
+
def create(connection_already_established = false)
|
22
|
+
establish_connection(public_schema_config) unless connection_already_established
|
26
23
|
connection.create_database(db_config.database, configuration_hash.merge(encoding: encoding))
|
27
|
-
establish_connection
|
24
|
+
establish_connection
|
28
25
|
end
|
29
26
|
|
30
27
|
def drop
|
31
|
-
|
28
|
+
establish_connection(public_schema_config)
|
32
29
|
connection.drop_database(db_config.database)
|
33
30
|
end
|
34
31
|
|
@@ -41,7 +38,7 @@ module ActiveRecord
|
|
41
38
|
end
|
42
39
|
|
43
40
|
def purge
|
44
|
-
clear_active_connections!
|
41
|
+
ActiveRecord::Base.connection_handler.clear_active_connections!(:all)
|
45
42
|
drop
|
46
43
|
create true
|
47
44
|
end
|
@@ -70,6 +67,7 @@ module ActiveRecord
|
|
70
67
|
|
71
68
|
ignore_tables = ActiveRecord::SchemaDumper.ignore_tables
|
72
69
|
if ignore_tables.any?
|
70
|
+
ignore_tables = connection.data_sources.select { |table| ignore_tables.any? { |pattern| pattern === table } }
|
73
71
|
args += ignore_tables.flat_map { |table| ["-T", table] }
|
74
72
|
end
|
75
73
|
|
@@ -89,15 +87,20 @@ module ActiveRecord
|
|
89
87
|
private
|
90
88
|
attr_reader :db_config, :configuration_hash
|
91
89
|
|
90
|
+
def connection
|
91
|
+
ActiveRecord::Base.connection
|
92
|
+
end
|
93
|
+
|
94
|
+
def establish_connection(config = db_config)
|
95
|
+
ActiveRecord::Base.establish_connection(config)
|
96
|
+
end
|
97
|
+
|
92
98
|
def encoding
|
93
99
|
configuration_hash[:encoding] || DEFAULT_ENCODING
|
94
100
|
end
|
95
101
|
|
96
|
-
def
|
97
|
-
|
98
|
-
database: "postgres",
|
99
|
-
schema_search_path: "public"
|
100
|
-
)
|
102
|
+
def public_schema_config
|
103
|
+
configuration_hash.merge(database: "postgres", schema_search_path: "public")
|
101
104
|
end
|
102
105
|
|
103
106
|
def psql_env
|
@@ -3,8 +3,6 @@
|
|
3
3
|
module ActiveRecord
|
4
4
|
module Tasks # :nodoc:
|
5
5
|
class SQLiteDatabaseTasks # :nodoc:
|
6
|
-
delegate :connection, :establish_connection, to: ActiveRecord::Base
|
7
|
-
|
8
6
|
def self.using_database_configurations?
|
9
7
|
true
|
10
8
|
end
|
@@ -17,25 +15,26 @@ module ActiveRecord
|
|
17
15
|
def create
|
18
16
|
raise DatabaseAlreadyExists if File.exist?(db_config.database)
|
19
17
|
|
20
|
-
establish_connection
|
18
|
+
establish_connection
|
21
19
|
connection
|
22
20
|
end
|
23
21
|
|
24
22
|
def drop
|
25
|
-
|
26
|
-
|
27
|
-
file = path.absolute? ? path.to_s : File.join(root, path)
|
28
|
-
|
23
|
+
db_path = db_config.database
|
24
|
+
file = File.absolute_path?(db_path) ? db_path : File.join(root, db_path)
|
29
25
|
FileUtils.rm(file)
|
26
|
+
FileUtils.rm_f(["#{file}-shm", "#{file}-wal"])
|
30
27
|
rescue Errno::ENOENT => error
|
31
28
|
raise NoDatabaseError.new(error.message)
|
32
29
|
end
|
33
30
|
|
34
31
|
def purge
|
32
|
+
connection.disconnect!
|
35
33
|
drop
|
36
34
|
rescue NoDatabaseError
|
37
35
|
ensure
|
38
36
|
create
|
37
|
+
connection.reconnect!
|
39
38
|
end
|
40
39
|
|
41
40
|
def charset
|
@@ -49,6 +48,7 @@ module ActiveRecord
|
|
49
48
|
|
50
49
|
ignore_tables = ActiveRecord::SchemaDumper.ignore_tables
|
51
50
|
if ignore_tables.any?
|
51
|
+
ignore_tables = connection.data_sources.select { |table| ignore_tables.any? { |pattern| pattern === table } }
|
52
52
|
condition = ignore_tables.map { |table| connection.quote(table) }.join(", ")
|
53
53
|
args << "SELECT sql FROM sqlite_master WHERE tbl_name NOT IN (#{condition}) ORDER BY tbl_name, type DESC, name"
|
54
54
|
else
|
@@ -65,6 +65,14 @@ module ActiveRecord
|
|
65
65
|
private
|
66
66
|
attr_reader :db_config, :root
|
67
67
|
|
68
|
+
def connection
|
69
|
+
ActiveRecord::Base.connection
|
70
|
+
end
|
71
|
+
|
72
|
+
def establish_connection(config = db_config)
|
73
|
+
ActiveRecord::Base.establish_connection(config)
|
74
|
+
end
|
75
|
+
|
68
76
|
def run_cmd(cmd, args, out)
|
69
77
|
fail run_cmd_error(cmd, args) unless Kernel.system(cmd, *args, out: out)
|
70
78
|
end
|