activerecord 7.0.8 → 7.1.3.4
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 +1554 -1452
- 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 +15 -9
- 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.rb +10 -8
- 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 +313 -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 +52 -34
- 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 +18 -5
- data/lib/active_record/attribute_methods/serialization.rb +150 -31
- data/lib/active_record/attribute_methods/write.rb +3 -3
- data/lib/active_record/attribute_methods.rb +105 -21
- data/lib/active_record/attributes.rb +3 -3
- data/lib/active_record/autosave_association.rb +55 -9
- 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 +74 -51
- 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 +289 -124
- data/lib/active_record/connection_adapters/abstract/transaction.rb +287 -58
- data/lib/active_record/connection_adapters/abstract_adapter.rb +511 -91
- data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +207 -108
- 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 +18 -13
- data/lib/active_record/connection_adapters/mysql2/database_statements.rb +151 -0
- data/lib/active_record/connection_adapters/mysql2_adapter.rb +98 -53
- 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/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 +361 -60
- 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 +209 -79
- 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 +262 -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 +175 -153
- data/lib/active_record/counter_cache.rb +46 -25
- data/lib/active_record/database_configurations/database_config.rb +9 -3
- data/lib/active_record/database_configurations/hash_config.rb +22 -12
- 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 +9 -4
- data/lib/active_record/deprecator.rb +7 -0
- data/lib/active_record/destroy_association_async_job.rb +2 -0
- 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 +21 -6
- 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 +19 -22
- data/lib/active_record/encryption.rb +1 -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 +31 -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/pessimistic.rb +5 -2
- data/lib/active_record/log_subscriber.rb +29 -12
- data/lib/active_record/marshalling.rb +56 -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 +139 -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 +64 -44
- data/lib/active_record/nested_attributes.rb +24 -6
- 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 +3 -21
- 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 +109 -47
- data/lib/active_record/railties/controller_runtime.rb +12 -6
- data/lib/active_record/railties/databases.rake +142 -148
- 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 +174 -44
- 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 +4 -6
- 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 +352 -63
- data/lib/active_record/relation/spawn_methods.rb +18 -1
- data/lib/active_record/relation.rb +91 -35
- 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 +127 -105
- 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 +113 -96
- data/lib/active_record/timestamp.rb +27 -15
- 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 +121 -16
- 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/visitors/mysql.rb +8 -1
- data/lib/arel/visitors/to_sql.rb +81 -17
- 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 +48 -12
- 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,35 @@ 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
|
190
178
|
|
191
179
|
each_current_configuration(env) do |db_config|
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
if ActiveRecord.dump_schema_after_migration
|
199
|
-
dump_schema(db_config, ActiveRecord.schema_format)
|
180
|
+
with_temporary_pool(db_config) do
|
181
|
+
begin
|
182
|
+
database_initialized = migration_connection.schema_migration.table_exists?
|
183
|
+
rescue ActiveRecord::NoDatabaseError
|
184
|
+
create(db_config)
|
185
|
+
retry
|
200
186
|
end
|
201
|
-
rescue ActiveRecord::NoDatabaseError
|
202
|
-
create(db_config)
|
203
187
|
|
204
|
-
|
205
|
-
|
206
|
-
db_config,
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
else
|
211
|
-
migrate
|
188
|
+
unless database_initialized
|
189
|
+
if File.exist?(schema_dump_path(db_config))
|
190
|
+
load_schema(db_config, ActiveRecord.schema_format, nil)
|
191
|
+
end
|
192
|
+
|
193
|
+
seed = true
|
212
194
|
end
|
213
195
|
|
214
|
-
|
196
|
+
migrate
|
197
|
+
dump_schema(db_config) if ActiveRecord.dump_schema_after_migration
|
215
198
|
end
|
216
199
|
end
|
217
200
|
|
218
|
-
ActiveRecord::Base.establish_connection
|
219
201
|
load_seed if seed
|
220
202
|
end
|
221
203
|
|
@@ -240,10 +222,9 @@ module ActiveRecord
|
|
240
222
|
end
|
241
223
|
|
242
224
|
def truncate_tables(db_config)
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
connection.truncate_tables(*connection.tables)
|
225
|
+
with_temporary_connection(db_config) do |conn|
|
226
|
+
conn.truncate_tables(*conn.tables)
|
227
|
+
end
|
247
228
|
end
|
248
229
|
private :truncate_tables
|
249
230
|
|
@@ -254,12 +235,12 @@ module ActiveRecord
|
|
254
235
|
end
|
255
236
|
|
256
237
|
def migrate(version = nil)
|
257
|
-
check_target_version
|
258
|
-
|
259
238
|
scope = ENV["SCOPE"]
|
260
239
|
verbose_was, Migration.verbose = Migration.verbose, verbose?
|
261
240
|
|
262
|
-
|
241
|
+
check_target_version
|
242
|
+
|
243
|
+
migration_connection.migration_context.migrate(target_version) do |migration|
|
263
244
|
if version.blank?
|
264
245
|
scope.blank? || scope == migration.scope
|
265
246
|
else
|
@@ -269,7 +250,7 @@ module ActiveRecord
|
|
269
250
|
Migration.write("No migrations ran. (using #{scope} scope)") if scope.present? && migrations_ran.empty?
|
270
251
|
end
|
271
252
|
|
272
|
-
|
253
|
+
migration_connection.schema_cache.clear!
|
273
254
|
ensure
|
274
255
|
Migration.verbose = verbose_was
|
275
256
|
end
|
@@ -277,9 +258,9 @@ module ActiveRecord
|
|
277
258
|
def db_configs_with_versions(db_configs) # :nodoc:
|
278
259
|
db_configs_with_versions = Hash.new { |h, k| h[k] = [] }
|
279
260
|
|
280
|
-
|
281
|
-
|
282
|
-
versions_to_run =
|
261
|
+
with_temporary_connection_for_each do |conn|
|
262
|
+
db_config = conn.pool.db_config
|
263
|
+
versions_to_run = conn.migration_context.pending_migration_versions
|
283
264
|
target_version = ActiveRecord::Tasks::DatabaseTasks.target_version
|
284
265
|
|
285
266
|
versions_to_run.each do |version|
|
@@ -292,22 +273,22 @@ module ActiveRecord
|
|
292
273
|
end
|
293
274
|
|
294
275
|
def migrate_status
|
295
|
-
unless
|
276
|
+
unless migration_connection.schema_migration.table_exists?
|
296
277
|
Kernel.abort "Schema migrations table does not exist yet."
|
297
278
|
end
|
298
279
|
|
299
280
|
# output
|
300
|
-
puts "\ndatabase: #{
|
281
|
+
puts "\ndatabase: #{migration_connection.pool.db_config.database}\n\n"
|
301
282
|
puts "#{'Status'.center(8)} #{'Migration ID'.ljust(14)} Migration Name"
|
302
283
|
puts "-" * 50
|
303
|
-
|
284
|
+
migration_connection.migration_context.migrations_status.each do |status, version, name|
|
304
285
|
puts "#{status.center(8)} #{version.ljust(14)} #{name}"
|
305
286
|
end
|
306
287
|
puts
|
307
288
|
end
|
308
289
|
|
309
290
|
def check_target_version
|
310
|
-
if target_version && !
|
291
|
+
if target_version && !Migration.valid_version_format?(ENV["VERSION"])
|
311
292
|
raise "Invalid format of target version: `VERSION=#{ENV['VERSION']}`"
|
312
293
|
end
|
313
294
|
end
|
@@ -347,7 +328,8 @@ module ActiveRecord
|
|
347
328
|
|
348
329
|
def purge_current(environment = env)
|
349
330
|
each_current_configuration(environment) { |db_config| purge(db_config) }
|
350
|
-
|
331
|
+
|
332
|
+
migration_class.establish_connection(environment.to_sym)
|
351
333
|
end
|
352
334
|
|
353
335
|
def structure_dump(configuration, *arguments)
|
@@ -370,7 +352,6 @@ module ActiveRecord
|
|
370
352
|
|
371
353
|
verbose_was, Migration.verbose = Migration.verbose, verbose? && ENV["VERBOSE"]
|
372
354
|
check_schema_file(file)
|
373
|
-
ActiveRecord::Base.establish_connection(db_config)
|
374
355
|
|
375
356
|
case format
|
376
357
|
when :ruby
|
@@ -380,9 +361,8 @@ module ActiveRecord
|
|
380
361
|
else
|
381
362
|
raise ArgumentError, "unknown format #{format.inspect}"
|
382
363
|
end
|
383
|
-
|
384
|
-
|
385
|
-
ActiveRecord::InternalMetadata[:schema_sha1] = schema_sha1(file)
|
364
|
+
|
365
|
+
migration_connection.internal_metadata.create_table_and_set_flags(db_config.env_name, schema_sha1(file))
|
386
366
|
ensure
|
387
367
|
Migration.verbose = verbose_was
|
388
368
|
end
|
@@ -394,12 +374,12 @@ module ActiveRecord
|
|
394
374
|
|
395
375
|
return true unless file && File.exist?(file)
|
396
376
|
|
397
|
-
|
398
|
-
|
399
|
-
|
400
|
-
return false unless ActiveRecord::InternalMetadata.table_exists?
|
377
|
+
with_temporary_connection(db_config) do |connection|
|
378
|
+
return false unless connection.internal_metadata.enabled?
|
379
|
+
return false unless connection.internal_metadata.table_exists?
|
401
380
|
|
402
|
-
|
381
|
+
connection.internal_metadata[:schema_sha1] == schema_sha1(file)
|
382
|
+
end
|
403
383
|
end
|
404
384
|
|
405
385
|
def reconstruct_from_schema(db_config, format = ActiveRecord.schema_format, file = nil) # :nodoc:
|
@@ -407,53 +387,43 @@ module ActiveRecord
|
|
407
387
|
|
408
388
|
check_schema_file(file) if file
|
409
389
|
|
410
|
-
|
411
|
-
|
412
|
-
|
413
|
-
|
414
|
-
|
415
|
-
|
390
|
+
with_temporary_pool(db_config, clobber: true) do
|
391
|
+
if schema_up_to_date?(db_config, format, file)
|
392
|
+
truncate_tables(db_config)
|
393
|
+
else
|
394
|
+
purge(db_config)
|
395
|
+
load_schema(db_config, format, file)
|
396
|
+
end
|
397
|
+
rescue ActiveRecord::NoDatabaseError
|
398
|
+
create(db_config)
|
416
399
|
load_schema(db_config, format, file)
|
417
400
|
end
|
418
|
-
rescue ActiveRecord::NoDatabaseError
|
419
|
-
create(db_config)
|
420
|
-
load_schema(db_config, format, file)
|
421
401
|
end
|
422
402
|
|
423
403
|
def dump_schema(db_config, format = ActiveRecord.schema_format) # :nodoc:
|
404
|
+
return unless db_config.schema_dump
|
405
|
+
|
424
406
|
require "active_record/schema_dumper"
|
425
407
|
filename = schema_dump_path(db_config, format)
|
426
408
|
return unless filename
|
427
409
|
|
428
|
-
connection = ActiveRecord::Base.connection
|
429
|
-
|
430
410
|
FileUtils.mkdir_p(db_dir)
|
431
411
|
case format
|
432
412
|
when :ruby
|
433
413
|
File.open(filename, "w:utf-8") do |file|
|
434
|
-
ActiveRecord::SchemaDumper.dump(
|
414
|
+
ActiveRecord::SchemaDumper.dump(migration_connection, file)
|
435
415
|
end
|
436
416
|
when :sql
|
437
417
|
structure_dump(db_config, filename)
|
438
|
-
if
|
418
|
+
if migration_connection.schema_migration.table_exists?
|
439
419
|
File.open(filename, "a") do |f|
|
440
|
-
f.puts
|
420
|
+
f.puts migration_connection.dump_schema_information
|
441
421
|
f.print "\n"
|
442
422
|
end
|
443
423
|
end
|
444
424
|
end
|
445
425
|
end
|
446
426
|
|
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
427
|
def schema_dump_path(db_config, format = ActiveRecord.schema_format)
|
458
428
|
return ENV["SCHEMA"] if ENV["SCHEMA"]
|
459
429
|
|
@@ -479,9 +449,10 @@ module ActiveRecord
|
|
479
449
|
|
480
450
|
def load_schema_current(format = ActiveRecord.schema_format, file = nil, environment = env)
|
481
451
|
each_current_configuration(environment) do |db_config|
|
482
|
-
|
452
|
+
with_temporary_connection(db_config) do
|
453
|
+
load_schema(db_config, format, file)
|
454
|
+
end
|
483
455
|
end
|
484
|
-
ActiveRecord::Base.establish_connection(environment.to_sym)
|
485
456
|
end
|
486
457
|
|
487
458
|
def check_schema_file(filename)
|
@@ -504,7 +475,7 @@ module ActiveRecord
|
|
504
475
|
|
505
476
|
# Dumps the schema cache in YAML format for the connection into the file
|
506
477
|
#
|
507
|
-
# ==== Examples
|
478
|
+
# ==== Examples
|
508
479
|
# ActiveRecord::Tasks::DatabaseTasks.dump_schema_cache(ActiveRecord::Base.connection, "tmp/schema_dump.yaml")
|
509
480
|
def dump_schema_cache(conn, filename)
|
510
481
|
conn.schema_cache.dump_to(filename)
|
@@ -514,7 +485,41 @@ module ActiveRecord
|
|
514
485
|
FileUtils.rm_f filename, verbose: false
|
515
486
|
end
|
516
487
|
|
488
|
+
def with_temporary_connection_for_each(env: ActiveRecord::Tasks::DatabaseTasks.env, name: nil, clobber: false, &block) # :nodoc:
|
489
|
+
if name
|
490
|
+
db_config = ActiveRecord::Base.configurations.configs_for(env_name: env, name: name)
|
491
|
+
with_temporary_connection(db_config, clobber: clobber, &block)
|
492
|
+
else
|
493
|
+
ActiveRecord::Base.configurations.configs_for(env_name: env, name: name).each do |db_config|
|
494
|
+
with_temporary_connection(db_config, clobber: clobber, &block)
|
495
|
+
end
|
496
|
+
end
|
497
|
+
end
|
498
|
+
|
499
|
+
def with_temporary_connection(db_config, clobber: false) # :nodoc:
|
500
|
+
with_temporary_pool(db_config, clobber: clobber) do |pool|
|
501
|
+
yield pool.connection
|
502
|
+
end
|
503
|
+
end
|
504
|
+
|
505
|
+
def migration_class # :nodoc:
|
506
|
+
ActiveRecord::Base
|
507
|
+
end
|
508
|
+
|
509
|
+
def migration_connection # :nodoc:
|
510
|
+
migration_class.connection
|
511
|
+
end
|
512
|
+
|
517
513
|
private
|
514
|
+
def with_temporary_pool(db_config, clobber: false)
|
515
|
+
original_db_config = migration_class.connection_db_config
|
516
|
+
pool = migration_class.connection_handler.establish_connection(db_config, clobber: clobber)
|
517
|
+
|
518
|
+
yield pool
|
519
|
+
ensure
|
520
|
+
migration_class.connection_handler.establish_connection(original_db_config, clobber: clobber)
|
521
|
+
end
|
522
|
+
|
518
523
|
def configs_for(**options)
|
519
524
|
Base.configurations.configs_for(**options)
|
520
525
|
end
|
@@ -595,6 +600,23 @@ module ActiveRecord
|
|
595
600
|
structure_load_flags
|
596
601
|
end
|
597
602
|
end
|
603
|
+
|
604
|
+
def check_current_protected_environment!(db_config)
|
605
|
+
with_temporary_pool(db_config) do |pool|
|
606
|
+
connection = pool.connection
|
607
|
+
current = connection.migration_context.current_environment
|
608
|
+
stored = connection.migration_context.last_stored_environment
|
609
|
+
|
610
|
+
if connection.migration_context.protected_environment?
|
611
|
+
raise ActiveRecord::ProtectedEnvironmentError.new(stored)
|
612
|
+
end
|
613
|
+
|
614
|
+
if stored && stored != current
|
615
|
+
raise ActiveRecord::EnvironmentMismatchError.new(current: current, stored: stored)
|
616
|
+
end
|
617
|
+
rescue ActiveRecord::NoDatabaseError
|
618
|
+
end
|
619
|
+
end
|
598
620
|
end
|
599
621
|
end
|
600
622
|
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
|