activerecord 6.1.7 → 7.1.5
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 +2030 -1020
- data/MIT-LICENSE +1 -1
- data/README.rdoc +18 -18
- data/lib/active_record/aggregations.rb +17 -14
- data/lib/active_record/association_relation.rb +1 -11
- data/lib/active_record/associations/association.rb +51 -19
- data/lib/active_record/associations/association_scope.rb +17 -12
- data/lib/active_record/associations/belongs_to_association.rb +28 -9
- data/lib/active_record/associations/belongs_to_polymorphic_association.rb +10 -2
- data/lib/active_record/associations/builder/association.rb +11 -5
- data/lib/active_record/associations/builder/belongs_to.rb +40 -14
- data/lib/active_record/associations/builder/collection_association.rb +10 -3
- data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +1 -5
- data/lib/active_record/associations/builder/has_many.rb +3 -2
- data/lib/active_record/associations/builder/has_one.rb +2 -1
- data/lib/active_record/associations/builder/singular_association.rb +6 -2
- data/lib/active_record/associations/collection_association.rb +39 -35
- data/lib/active_record/associations/collection_proxy.rb +30 -15
- data/lib/active_record/associations/disable_joins_association_scope.rb +59 -0
- data/lib/active_record/associations/foreign_association.rb +10 -3
- data/lib/active_record/associations/has_many_association.rb +28 -18
- data/lib/active_record/associations/has_many_through_association.rb +12 -7
- data/lib/active_record/associations/has_one_association.rb +20 -10
- data/lib/active_record/associations/has_one_through_association.rb +1 -1
- data/lib/active_record/associations/join_dependency/join_association.rb +3 -2
- data/lib/active_record/associations/join_dependency.rb +28 -20
- data/lib/active_record/associations/preloader/association.rb +210 -52
- data/lib/active_record/associations/preloader/batch.rb +48 -0
- data/lib/active_record/associations/preloader/branch.rb +147 -0
- data/lib/active_record/associations/preloader/through_association.rb +50 -14
- data/lib/active_record/associations/preloader.rb +50 -121
- data/lib/active_record/associations/singular_association.rb +9 -3
- data/lib/active_record/associations/through_association.rb +25 -14
- data/lib/active_record/associations.rb +446 -306
- data/lib/active_record/asynchronous_queries_tracker.rb +60 -0
- data/lib/active_record/attribute_assignment.rb +1 -3
- data/lib/active_record/attribute_methods/before_type_cast.rb +24 -2
- data/lib/active_record/attribute_methods/dirty.rb +73 -22
- data/lib/active_record/attribute_methods/primary_key.rb +78 -26
- data/lib/active_record/attribute_methods/query.rb +31 -19
- data/lib/active_record/attribute_methods/read.rb +27 -12
- data/lib/active_record/attribute_methods/serialization.rb +194 -37
- data/lib/active_record/attribute_methods/time_zone_conversion.rb +8 -3
- data/lib/active_record/attribute_methods/write.rb +12 -15
- data/lib/active_record/attribute_methods.rb +161 -40
- data/lib/active_record/attributes.rb +27 -38
- data/lib/active_record/autosave_association.rb +65 -31
- data/lib/active_record/base.rb +25 -2
- data/lib/active_record/callbacks.rb +18 -34
- 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 -46
- data/lib/active_record/connection_adapters/abstract/connection_handler.rb +367 -0
- data/lib/active_record/connection_adapters/abstract/connection_pool/queue.rb +211 -0
- data/lib/active_record/connection_adapters/abstract/connection_pool/reaper.rb +78 -0
- data/lib/active_record/connection_adapters/abstract/connection_pool.rb +113 -597
- data/lib/active_record/connection_adapters/abstract/database_limits.rb +5 -17
- data/lib/active_record/connection_adapters/abstract/database_statements.rb +172 -50
- data/lib/active_record/connection_adapters/abstract/query_cache.rb +78 -27
- data/lib/active_record/connection_adapters/abstract/quoting.rb +87 -73
- data/lib/active_record/connection_adapters/abstract/savepoints.rb +4 -3
- data/lib/active_record/connection_adapters/abstract/schema_creation.rb +21 -20
- data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +186 -31
- data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +14 -1
- data/lib/active_record/connection_adapters/abstract/schema_statements.rb +367 -141
- data/lib/active_record/connection_adapters/abstract/transaction.rb +281 -59
- data/lib/active_record/connection_adapters/abstract_adapter.rb +631 -150
- data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +317 -164
- data/lib/active_record/connection_adapters/column.rb +13 -0
- data/lib/active_record/connection_adapters/mysql/column.rb +1 -0
- data/lib/active_record/connection_adapters/mysql/database_statements.rb +25 -134
- data/lib/active_record/connection_adapters/mysql/quoting.rb +56 -25
- data/lib/active_record/connection_adapters/mysql/schema_creation.rb +9 -0
- data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +10 -1
- data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +8 -2
- data/lib/active_record/connection_adapters/mysql/schema_statements.rb +39 -14
- data/lib/active_record/connection_adapters/mysql2/database_statements.rb +151 -0
- data/lib/active_record/connection_adapters/mysql2_adapter.rb +112 -55
- data/lib/active_record/connection_adapters/pool_config.rb +20 -11
- data/lib/active_record/connection_adapters/pool_manager.rb +19 -9
- data/lib/active_record/connection_adapters/postgresql/column.rb +30 -1
- data/lib/active_record/connection_adapters/postgresql/database_statements.rb +89 -52
- data/lib/active_record/connection_adapters/postgresql/oid/array.rb +1 -1
- data/lib/active_record/connection_adapters/postgresql/oid/cidr.rb +6 -0
- data/lib/active_record/connection_adapters/postgresql/oid/date.rb +8 -0
- data/lib/active_record/connection_adapters/postgresql/oid/date_time.rb +5 -0
- data/lib/active_record/connection_adapters/postgresql/oid/hstore.rb +53 -14
- data/lib/active_record/connection_adapters/postgresql/oid/money.rb +3 -2
- data/lib/active_record/connection_adapters/postgresql/oid/range.rb +12 -3
- data/lib/active_record/connection_adapters/postgresql/oid/timestamp.rb +15 -0
- data/lib/active_record/connection_adapters/postgresql/oid/timestamp_with_time_zone.rb +30 -0
- data/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb +18 -6
- data/lib/active_record/connection_adapters/postgresql/oid.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/quoting.rb +89 -56
- data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +28 -0
- data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +92 -2
- data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +153 -3
- data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +78 -0
- data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +397 -75
- data/lib/active_record/connection_adapters/postgresql/utils.rb +9 -10
- data/lib/active_record/connection_adapters/postgresql_adapter.rb +508 -246
- data/lib/active_record/connection_adapters/schema_cache.rb +319 -90
- data/lib/active_record/connection_adapters/sqlite3/column.rb +49 -0
- data/lib/active_record/connection_adapters/sqlite3/database_statements.rb +72 -53
- data/lib/active_record/connection_adapters/sqlite3/quoting.rb +37 -21
- data/lib/active_record/connection_adapters/sqlite3/schema_definitions.rb +7 -0
- data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +43 -22
- data/lib/active_record/connection_adapters/sqlite3_adapter.rb +296 -104
- 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 +9 -6
- data/lib/active_record/connection_handling.rb +108 -137
- data/lib/active_record/core.rb +242 -233
- data/lib/active_record/counter_cache.rb +52 -27
- data/lib/active_record/database_configurations/connection_url_resolver.rb +3 -2
- data/lib/active_record/database_configurations/database_config.rb +21 -12
- data/lib/active_record/database_configurations/hash_config.rb +88 -16
- data/lib/active_record/database_configurations/url_config.rb +18 -12
- data/lib/active_record/database_configurations.rb +95 -59
- data/lib/active_record/delegated_type.rb +66 -20
- data/lib/active_record/deprecator.rb +7 -0
- data/lib/active_record/destroy_association_async_job.rb +4 -2
- data/lib/active_record/disable_joins_association_relation.rb +39 -0
- data/lib/active_record/dynamic_matchers.rb +1 -1
- data/lib/active_record/encryption/auto_filtered_parameters.rb +66 -0
- data/lib/active_record/encryption/cipher/aes256_gcm.rb +101 -0
- data/lib/active_record/encryption/cipher.rb +53 -0
- data/lib/active_record/encryption/config.rb +68 -0
- data/lib/active_record/encryption/configurable.rb +60 -0
- data/lib/active_record/encryption/context.rb +42 -0
- data/lib/active_record/encryption/contexts.rb +76 -0
- data/lib/active_record/encryption/derived_secret_key_provider.rb +18 -0
- data/lib/active_record/encryption/deterministic_key_provider.rb +14 -0
- data/lib/active_record/encryption/encryptable_record.rb +230 -0
- data/lib/active_record/encryption/encrypted_attribute_type.rb +155 -0
- data/lib/active_record/encryption/encrypted_fixtures.rb +38 -0
- data/lib/active_record/encryption/encrypting_only_encryptor.rb +12 -0
- data/lib/active_record/encryption/encryptor.rb +155 -0
- data/lib/active_record/encryption/envelope_encryption_key_provider.rb +55 -0
- data/lib/active_record/encryption/errors.rb +15 -0
- data/lib/active_record/encryption/extended_deterministic_queries.rb +157 -0
- data/lib/active_record/encryption/extended_deterministic_uniqueness_validator.rb +28 -0
- data/lib/active_record/encryption/key.rb +28 -0
- data/lib/active_record/encryption/key_generator.rb +53 -0
- data/lib/active_record/encryption/key_provider.rb +46 -0
- data/lib/active_record/encryption/message.rb +33 -0
- data/lib/active_record/encryption/message_serializer.rb +92 -0
- data/lib/active_record/encryption/null_encryptor.rb +21 -0
- data/lib/active_record/encryption/properties.rb +76 -0
- data/lib/active_record/encryption/read_only_null_encryptor.rb +24 -0
- data/lib/active_record/encryption/scheme.rb +100 -0
- data/lib/active_record/encryption.rb +58 -0
- data/lib/active_record/enum.rb +154 -63
- data/lib/active_record/errors.rb +172 -15
- data/lib/active_record/explain.rb +23 -3
- data/lib/active_record/explain_registry.rb +11 -6
- data/lib/active_record/explain_subscriber.rb +1 -1
- data/lib/active_record/fixture_set/file.rb +15 -1
- 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 +70 -14
- data/lib/active_record/fixture_set/table_rows.rb +4 -4
- data/lib/active_record/fixtures.rb +147 -86
- data/lib/active_record/future_result.rb +174 -0
- data/lib/active_record/gem_version.rb +3 -3
- data/lib/active_record/inheritance.rb +81 -29
- data/lib/active_record/insert_all.rb +135 -22
- data/lib/active_record/integration.rb +11 -10
- data/lib/active_record/internal_metadata.rb +119 -33
- data/lib/active_record/legacy_yaml_adapter.rb +2 -39
- data/lib/active_record/locking/optimistic.rb +37 -22
- data/lib/active_record/locking/pessimistic.rb +15 -6
- data/lib/active_record/log_subscriber.rb +52 -19
- 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 +10 -10
- data/lib/active_record/middleware/database_selector.rb +23 -13
- data/lib/active_record/middleware/shard_selector.rb +62 -0
- data/lib/active_record/migration/command_recorder.rb +112 -14
- data/lib/active_record/migration/compatibility.rb +233 -46
- 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/join_table.rb +1 -1
- data/lib/active_record/migration/pending_migration_connection.rb +21 -0
- data/lib/active_record/migration.rb +361 -173
- data/lib/active_record/model_schema.rb +125 -101
- data/lib/active_record/nested_attributes.rb +50 -20
- data/lib/active_record/no_touching.rb +3 -3
- data/lib/active_record/normalization.rb +167 -0
- data/lib/active_record/persistence.rb +409 -88
- data/lib/active_record/promise.rb +84 -0
- data/lib/active_record/query_cache.rb +4 -22
- data/lib/active_record/query_logs.rb +174 -0
- data/lib/active_record/query_logs_formatter.rb +41 -0
- data/lib/active_record/querying.rb +29 -6
- data/lib/active_record/railtie.rb +220 -44
- data/lib/active_record/railties/controller_runtime.rb +15 -10
- data/lib/active_record/railties/databases.rake +188 -252
- data/lib/active_record/railties/job_runtime.rb +23 -0
- data/lib/active_record/readonly_attributes.rb +41 -3
- data/lib/active_record/reflection.rb +248 -81
- data/lib/active_record/relation/batches/batch_enumerator.rb +23 -7
- data/lib/active_record/relation/batches.rb +192 -63
- data/lib/active_record/relation/calculations.rb +246 -90
- data/lib/active_record/relation/delegation.rb +28 -14
- data/lib/active_record/relation/finder_methods.rb +108 -51
- data/lib/active_record/relation/merger.rb +22 -13
- data/lib/active_record/relation/predicate_builder/association_query_value.rb +31 -3
- 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 +27 -20
- data/lib/active_record/relation/query_attribute.rb +30 -12
- data/lib/active_record/relation/query_methods.rb +670 -129
- data/lib/active_record/relation/record_fetch_warning.rb +7 -9
- data/lib/active_record/relation/spawn_methods.rb +20 -3
- data/lib/active_record/relation/where_clause.rb +10 -19
- data/lib/active_record/relation.rb +287 -120
- data/lib/active_record/result.rb +37 -11
- data/lib/active_record/runtime_registry.rb +32 -13
- data/lib/active_record/sanitization.rb +65 -20
- data/lib/active_record/schema.rb +36 -22
- data/lib/active_record/schema_dumper.rb +73 -24
- data/lib/active_record/schema_migration.rb +68 -33
- data/lib/active_record/scoping/default.rb +72 -15
- data/lib/active_record/scoping/named.rb +5 -13
- data/lib/active_record/scoping.rb +65 -34
- data/lib/active_record/secure_password.rb +60 -0
- data/lib/active_record/secure_token.rb +21 -3
- data/lib/active_record/serialization.rb +6 -1
- data/lib/active_record/signed_id.rb +10 -8
- data/lib/active_record/store.rb +10 -10
- data/lib/active_record/suppressor.rb +13 -15
- data/lib/active_record/table_metadata.rb +16 -3
- data/lib/active_record/tasks/database_tasks.rb +251 -140
- data/lib/active_record/tasks/mysql_database_tasks.rb +16 -7
- data/lib/active_record/tasks/postgresql_database_tasks.rb +35 -26
- data/lib/active_record/tasks/sqlite_database_tasks.rb +15 -7
- data/lib/active_record/test_databases.rb +1 -1
- data/lib/active_record/test_fixtures.rb +117 -96
- data/lib/active_record/timestamp.rb +32 -19
- data/lib/active_record/token_for.rb +113 -0
- data/lib/active_record/touch_later.rb +11 -6
- data/lib/active_record/transactions.rb +48 -27
- data/lib/active_record/translation.rb +3 -3
- data/lib/active_record/type/adapter_specific_registry.rb +32 -14
- data/lib/active_record/type/hash_lookup_type_map.rb +34 -1
- data/lib/active_record/type/internal/timezone.rb +7 -2
- data/lib/active_record/type/serialized.rb +9 -5
- data/lib/active_record/type/time.rb +4 -0
- data/lib/active_record/type/type_map.rb +17 -20
- data/lib/active_record/type.rb +1 -2
- data/lib/active_record/validations/absence.rb +1 -1
- data/lib/active_record/validations/associated.rb +4 -4
- 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 +51 -6
- data/lib/active_record/validations.rb +8 -4
- data/lib/active_record/version.rb +1 -1
- data/lib/active_record.rb +335 -32
- data/lib/arel/attributes/attribute.rb +0 -8
- data/lib/arel/crud.rb +28 -22
- data/lib/arel/delete_manager.rb +18 -4
- data/lib/arel/errors.rb +10 -0
- data/lib/arel/factory_methods.rb +4 -0
- data/lib/arel/filter_predications.rb +9 -0
- data/lib/arel/insert_manager.rb +2 -3
- data/lib/arel/nodes/and.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/casted.rb +1 -1
- data/lib/arel/nodes/cte.rb +36 -0
- data/lib/arel/nodes/delete_statement.rb +12 -13
- data/lib/arel/nodes/filter.rb +10 -0
- data/lib/arel/nodes/fragments.rb +35 -0
- data/lib/arel/nodes/function.rb +1 -0
- data/lib/arel/nodes/homogeneous_in.rb +1 -9
- data/lib/arel/nodes/insert_statement.rb +2 -2
- data/lib/arel/nodes/leading_join.rb +8 -0
- data/lib/arel/nodes/node.rb +111 -2
- data/lib/arel/nodes/select_core.rb +2 -2
- data/lib/arel/nodes/select_statement.rb +2 -2
- data/lib/arel/nodes/sql_literal.rb +6 -0
- data/lib/arel/nodes/table_alias.rb +4 -0
- data/lib/arel/nodes/update_statement.rb +8 -3
- data/lib/arel/nodes.rb +5 -0
- data/lib/arel/predications.rb +13 -3
- data/lib/arel/select_manager.rb +10 -4
- data/lib/arel/table.rb +9 -6
- data/lib/arel/tree_manager.rb +5 -13
- data/lib/arel/update_manager.rb +18 -4
- data/lib/arel/visitors/dot.rb +80 -90
- data/lib/arel/visitors/mysql.rb +16 -3
- data/lib/arel/visitors/postgresql.rb +0 -10
- data/lib/arel/visitors/to_sql.rb +141 -20
- data/lib/arel/visitors/visitor.rb +2 -2
- data/lib/arel.rb +18 -3
- data/lib/rails/generators/active_record/application_record/USAGE +8 -0
- data/lib/rails/generators/active_record/application_record/templates/application_record.rb.tt +1 -1
- 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
- data/lib/rails/generators/active_record/model/templates/abstract_base_class.rb.tt +1 -1
- data/lib/rails/generators/active_record/model/templates/model.rb.tt +1 -1
- data/lib/rails/generators/active_record/model/templates/module.rb.tt +2 -2
- data/lib/rails/generators/active_record/multi_db/multi_db_generator.rb +16 -0
- data/lib/rails/generators/active_record/multi_db/templates/multi_db.rb.tt +44 -0
- metadata +96 -16
- data/lib/active_record/connection_adapters/legacy_pool_manager.rb +0 -35
- data/lib/active_record/null_relation.rb +0 -67
@@ -5,6 +5,10 @@ module ActiveRecord
|
|
5
5
|
module CounterCache
|
6
6
|
extend ActiveSupport::Concern
|
7
7
|
|
8
|
+
included do
|
9
|
+
class_attribute :_counter_cache_columns, instance_accessor: false, default: []
|
10
|
+
end
|
11
|
+
|
8
12
|
module ClassMethods
|
9
13
|
# Resets one or more counter caches to their correct value using an SQL
|
10
14
|
# count query. This is useful when adding new counter caches, or if the
|
@@ -29,6 +33,7 @@ module ActiveRecord
|
|
29
33
|
def reset_counters(id, *counters, touch: nil)
|
30
34
|
object = find(id)
|
31
35
|
|
36
|
+
updates = {}
|
32
37
|
counters.each do |counter_association|
|
33
38
|
has_many_association = _reflect_on_association(counter_association)
|
34
39
|
unless has_many_association
|
@@ -47,19 +52,21 @@ module ActiveRecord
|
|
47
52
|
reflection = child_class._reflections.values.find { |e| e.belongs_to? && e.foreign_key.to_s == foreign_key && e.options[:counter_cache].present? }
|
48
53
|
counter_name = reflection.counter_cache_column
|
49
54
|
|
50
|
-
|
51
|
-
|
52
|
-
if
|
53
|
-
|
54
|
-
names = Array.wrap(names)
|
55
|
-
options = names.extract_options!
|
56
|
-
touch_updates = touch_attributes_with_time(*names, **options)
|
57
|
-
updates.merge!(touch_updates)
|
58
|
-
end
|
55
|
+
count_was = object.send(counter_name)
|
56
|
+
count = object.send(counter_association).count(:all)
|
57
|
+
updates[counter_name] = count if count != count_was
|
58
|
+
end
|
59
59
|
|
60
|
-
|
60
|
+
if touch
|
61
|
+
names = touch if touch != true
|
62
|
+
names = Array.wrap(names)
|
63
|
+
options = names.extract_options!
|
64
|
+
touch_updates = touch_attributes_with_time(*names, **options)
|
65
|
+
updates.merge!(touch_updates)
|
61
66
|
end
|
62
67
|
|
68
|
+
unscoped.where(primary_key => [object.id]).update_all(updates) if updates.any?
|
69
|
+
|
63
70
|
true
|
64
71
|
end
|
65
72
|
|
@@ -80,31 +87,32 @@ module ActiveRecord
|
|
80
87
|
#
|
81
88
|
# ==== Examples
|
82
89
|
#
|
83
|
-
# # For the Post with id of 5, decrement the
|
84
|
-
# # increment the
|
85
|
-
# Post.update_counters 5,
|
90
|
+
# # For the Post with id of 5, decrement the comments_count by 1, and
|
91
|
+
# # increment the actions_count by 1
|
92
|
+
# Post.update_counters 5, comments_count: -1, actions_count: 1
|
86
93
|
# # Executes the following SQL:
|
87
94
|
# # UPDATE posts
|
88
|
-
# # SET
|
89
|
-
# #
|
95
|
+
# # SET comments_count = COALESCE(comments_count, 0) - 1,
|
96
|
+
# # actions_count = COALESCE(actions_count, 0) + 1
|
90
97
|
# # WHERE id = 5
|
91
98
|
#
|
92
|
-
# # For the Posts with id of 10 and 15, increment the
|
93
|
-
# Post.update_counters [10, 15],
|
99
|
+
# # For the Posts with id of 10 and 15, increment the comments_count by 1
|
100
|
+
# Post.update_counters [10, 15], comments_count: 1
|
94
101
|
# # Executes the following SQL:
|
95
102
|
# # UPDATE posts
|
96
|
-
# # SET
|
103
|
+
# # SET comments_count = COALESCE(comments_count, 0) + 1
|
97
104
|
# # WHERE id IN (10, 15)
|
98
105
|
#
|
99
|
-
# # For the Posts with id of 10 and 15, increment the
|
106
|
+
# # For the Posts with id of 10 and 15, increment the comments_count by 1
|
100
107
|
# # and update the updated_at value for each counter.
|
101
|
-
# Post.update_counters [10, 15],
|
108
|
+
# Post.update_counters [10, 15], comments_count: 1, touch: true
|
102
109
|
# # Executes the following SQL:
|
103
110
|
# # UPDATE posts
|
104
|
-
# # SET
|
111
|
+
# # SET comments_count = COALESCE(comments_count, 0) + 1,
|
105
112
|
# # `updated_at` = '2016-10-13T09:59:23-05:00'
|
106
113
|
# # WHERE id IN (10, 15)
|
107
114
|
def update_counters(id, counters)
|
115
|
+
id = [id] if composite_primary_key? && id.is_a?(Array) && !id[0].is_a?(Array)
|
108
116
|
unscoped.where!(primary_key => id).update_counters(counters)
|
109
117
|
end
|
110
118
|
|
@@ -119,6 +127,7 @@ module ActiveRecord
|
|
119
127
|
#
|
120
128
|
# * +counter_name+ - The name of the field that should be incremented.
|
121
129
|
# * +id+ - The id of the object that should be incremented or an array of ids.
|
130
|
+
# * <tt>:by</tt> - The amount by which to increment the value. Defaults to +1+.
|
122
131
|
# * <tt>:touch</tt> - Touch timestamp columns when updating.
|
123
132
|
# Pass +true+ to touch +updated_at+ and/or +updated_on+. Pass a symbol to
|
124
133
|
# touch that column or an array of symbols to touch just those ones.
|
@@ -129,10 +138,14 @@ module ActiveRecord
|
|
129
138
|
# DiscussionBoard.increment_counter(:posts_count, 5)
|
130
139
|
#
|
131
140
|
# # Increment the posts_count column for the record with an id of 5
|
141
|
+
# # by a specific amount.
|
142
|
+
# DiscussionBoard.increment_counter(:posts_count, 5, by: 3)
|
143
|
+
#
|
144
|
+
# # Increment the posts_count column for the record with an id of 5
|
132
145
|
# # and update the updated_at value.
|
133
146
|
# DiscussionBoard.increment_counter(:posts_count, 5, touch: true)
|
134
|
-
def increment_counter(counter_name, id, touch: nil)
|
135
|
-
update_counters(id, counter_name =>
|
147
|
+
def increment_counter(counter_name, id, by: 1, touch: nil)
|
148
|
+
update_counters(id, counter_name => by, touch: touch)
|
136
149
|
end
|
137
150
|
|
138
151
|
# Decrement a numeric field by one, via a direct SQL update.
|
@@ -144,6 +157,7 @@ module ActiveRecord
|
|
144
157
|
#
|
145
158
|
# * +counter_name+ - The name of the field that should be decremented.
|
146
159
|
# * +id+ - The id of the object that should be decremented or an array of ids.
|
160
|
+
# * <tt>:by</tt> - The amount by which to decrement the value. Defaults to +1+.
|
147
161
|
# * <tt>:touch</tt> - Touch timestamp columns when updating.
|
148
162
|
# Pass +true+ to touch +updated_at+ and/or +updated_on+. Pass a symbol to
|
149
163
|
# touch that column or an array of symbols to touch just those ones.
|
@@ -154,10 +168,18 @@ module ActiveRecord
|
|
154
168
|
# DiscussionBoard.decrement_counter(:posts_count, 5)
|
155
169
|
#
|
156
170
|
# # Decrement the posts_count column for the record with an id of 5
|
171
|
+
# by a specific amount.
|
172
|
+
# DiscussionBoard.decrement_counter(:posts_count, 5, by: 3)
|
173
|
+
#
|
174
|
+
# # Decrement the posts_count column for the record with an id of 5
|
157
175
|
# # and update the updated_at value.
|
158
176
|
# DiscussionBoard.decrement_counter(:posts_count, 5, touch: true)
|
159
|
-
def decrement_counter(counter_name, id, touch: nil)
|
160
|
-
update_counters(id, counter_name => -
|
177
|
+
def decrement_counter(counter_name, id, by: 1, touch: nil)
|
178
|
+
update_counters(id, counter_name => -by, touch: touch)
|
179
|
+
end
|
180
|
+
|
181
|
+
def counter_cache_column?(name) # :nodoc:
|
182
|
+
_counter_cache_columns.include?(name)
|
161
183
|
end
|
162
184
|
end
|
163
185
|
|
@@ -177,8 +199,7 @@ module ActiveRecord
|
|
177
199
|
|
178
200
|
if affected_rows > 0
|
179
201
|
each_counter_cached_associations do |association|
|
180
|
-
foreign_key
|
181
|
-
unless destroyed_by_association && destroyed_by_association.foreign_key.to_sym == foreign_key
|
202
|
+
unless destroyed_by_association && _foreign_keys_equal?(destroyed_by_association.foreign_key, association.reflection.foreign_key)
|
182
203
|
association.decrement_counters
|
183
204
|
end
|
184
205
|
end
|
@@ -192,5 +213,9 @@ module ActiveRecord
|
|
192
213
|
yield association(name.to_sym) if reflection.belongs_to? && reflection.counter_cache_column
|
193
214
|
end
|
194
215
|
end
|
216
|
+
|
217
|
+
def _foreign_keys_equal?(fkey1, fkey2)
|
218
|
+
fkey1 == fkey2 || Array(fkey1).map(&:to_sym) == Array(fkey2).map(&:to_sym)
|
219
|
+
end
|
195
220
|
end
|
196
221
|
end
|
@@ -2,6 +2,7 @@
|
|
2
2
|
|
3
3
|
require "uri"
|
4
4
|
require "active_support/core_ext/enumerable"
|
5
|
+
require "active_support/core_ext/hash/reverse_merge"
|
5
6
|
|
6
7
|
module ActiveRecord
|
7
8
|
class DatabaseConfigurations
|
@@ -45,7 +46,7 @@ module ActiveRecord
|
|
45
46
|
attr_reader :uri
|
46
47
|
|
47
48
|
def uri_parser
|
48
|
-
@uri_parser ||= URI::
|
49
|
+
@uri_parser ||= URI::RFC2396_Parser.new
|
49
50
|
end
|
50
51
|
|
51
52
|
# Converts the query parameters of the URI into a hash.
|
@@ -68,7 +69,7 @@ module ActiveRecord
|
|
68
69
|
database: uri.opaque
|
69
70
|
)
|
70
71
|
else
|
71
|
-
query_hash.
|
72
|
+
query_hash.reverse_merge(
|
72
73
|
adapter: @adapter,
|
73
74
|
username: uri.user,
|
74
75
|
password: uri.password,
|
@@ -3,31 +3,24 @@
|
|
3
3
|
module ActiveRecord
|
4
4
|
class DatabaseConfigurations
|
5
5
|
# ActiveRecord::Base.configurations will return either a HashConfig or
|
6
|
-
# UrlConfig respectively. It will never return a DatabaseConfig object,
|
6
|
+
# UrlConfig respectively. It will never return a +DatabaseConfig+ object,
|
7
7
|
# as this is the parent class for the types of database configuration objects.
|
8
8
|
class DatabaseConfig # :nodoc:
|
9
9
|
attr_reader :env_name, :name
|
10
10
|
|
11
|
-
attr_accessor :owner_name
|
12
|
-
|
13
11
|
def initialize(env_name, name)
|
14
12
|
@env_name = env_name
|
15
13
|
@name = name
|
16
14
|
end
|
17
15
|
|
18
|
-
def spec_name
|
19
|
-
@name
|
20
|
-
end
|
21
|
-
deprecate spec_name: "please use name instead"
|
22
|
-
|
23
|
-
def config
|
24
|
-
raise NotImplementedError
|
25
|
-
end
|
26
|
-
|
27
16
|
def adapter_method
|
28
17
|
"#{adapter}_connection"
|
29
18
|
end
|
30
19
|
|
20
|
+
def adapter_class_method
|
21
|
+
"#{adapter}_adapter_class"
|
22
|
+
end
|
23
|
+
|
31
24
|
def host
|
32
25
|
raise NotImplementedError
|
33
26
|
end
|
@@ -48,6 +41,22 @@ module ActiveRecord
|
|
48
41
|
raise NotImplementedError
|
49
42
|
end
|
50
43
|
|
44
|
+
def min_threads
|
45
|
+
raise NotImplementedError
|
46
|
+
end
|
47
|
+
|
48
|
+
def max_threads
|
49
|
+
raise NotImplementedError
|
50
|
+
end
|
51
|
+
|
52
|
+
def max_queue
|
53
|
+
raise NotImplementedError
|
54
|
+
end
|
55
|
+
|
56
|
+
def query_cache
|
57
|
+
raise NotImplementedError
|
58
|
+
end
|
59
|
+
|
51
60
|
def checkout_timeout
|
52
61
|
raise NotImplementedError
|
53
62
|
end
|
@@ -2,7 +2,9 @@
|
|
2
2
|
|
3
3
|
module ActiveRecord
|
4
4
|
class DatabaseConfigurations
|
5
|
-
#
|
5
|
+
# = Active Record Database Hash Config
|
6
|
+
#
|
7
|
+
# A +HashConfig+ object is created for each database configuration entry that
|
6
8
|
# is created from a hash.
|
7
9
|
#
|
8
10
|
# A hash config:
|
@@ -14,28 +16,28 @@ module ActiveRecord
|
|
14
16
|
# #<ActiveRecord::DatabaseConfigurations::HashConfig:0x00007fd1acbded10
|
15
17
|
# @env_name="development", @name="primary", @config={database: "db_name"}>
|
16
18
|
#
|
17
|
-
#
|
18
|
-
#
|
19
|
-
# * <tt>:env_name</tt> - The Rails environment, i.e. "development".
|
20
|
-
# * <tt>:name</tt> - The db config name. In a standard two-tier
|
21
|
-
# database configuration this will default to "primary". In a multiple
|
22
|
-
# database three-tier database configuration this corresponds to the name
|
23
|
-
# used in the second tier, for example "primary_readonly".
|
24
|
-
# * <tt>:config</tt> - The config hash. This is the hash that contains the
|
25
|
-
# database adapter, name, and other important information for database
|
26
|
-
# connections.
|
19
|
+
# See ActiveRecord::DatabaseConfigurations for more info.
|
27
20
|
class HashConfig < DatabaseConfig
|
28
21
|
attr_reader :configuration_hash
|
22
|
+
|
23
|
+
|
24
|
+
# Initialize a new +HashConfig+ object
|
25
|
+
#
|
26
|
+
# ==== Options
|
27
|
+
#
|
28
|
+
# * <tt>:env_name</tt> - The \Rails environment, i.e. "development".
|
29
|
+
# * <tt>:name</tt> - The db config name. In a standard two-tier
|
30
|
+
# database configuration this will default to "primary". In a multiple
|
31
|
+
# database three-tier database configuration this corresponds to the name
|
32
|
+
# used in the second tier, for example "primary_readonly".
|
33
|
+
# * <tt>:config</tt> - The config hash. This is the hash that contains the
|
34
|
+
# database adapter, name, and other important information for database
|
35
|
+
# connections.
|
29
36
|
def initialize(env_name, name, configuration_hash)
|
30
37
|
super(env_name, name)
|
31
38
|
@configuration_hash = configuration_hash.symbolize_keys.freeze
|
32
39
|
end
|
33
40
|
|
34
|
-
def config
|
35
|
-
ActiveSupport::Deprecation.warn("DatabaseConfig#config will be removed in 7.0.0 in favor of DatabaseConfig#configuration_hash which returns a hash with symbol keys")
|
36
|
-
configuration_hash.stringify_keys
|
37
|
-
end
|
38
|
-
|
39
41
|
# Determines whether a database configuration is for a replica / readonly
|
40
42
|
# connection. If the +replica+ key is present in the config, +replica?+ will
|
41
43
|
# return +true+.
|
@@ -54,6 +56,10 @@ module ActiveRecord
|
|
54
56
|
configuration_hash[:host]
|
55
57
|
end
|
56
58
|
|
59
|
+
def socket # :nodoc:
|
60
|
+
configuration_hash[:socket]
|
61
|
+
end
|
62
|
+
|
57
63
|
def database
|
58
64
|
configuration_hash[:database]
|
59
65
|
end
|
@@ -66,6 +72,22 @@ module ActiveRecord
|
|
66
72
|
(configuration_hash[:pool] || 5).to_i
|
67
73
|
end
|
68
74
|
|
75
|
+
def min_threads
|
76
|
+
(configuration_hash[:min_threads] || 0).to_i
|
77
|
+
end
|
78
|
+
|
79
|
+
def max_threads
|
80
|
+
(configuration_hash[:max_threads] || pool).to_i
|
81
|
+
end
|
82
|
+
|
83
|
+
def query_cache
|
84
|
+
configuration_hash[:query_cache]
|
85
|
+
end
|
86
|
+
|
87
|
+
def max_queue
|
88
|
+
max_threads * 4
|
89
|
+
end
|
90
|
+
|
69
91
|
def checkout_timeout
|
70
92
|
(configuration_hash[:checkout_timeout] || 5).to_f
|
71
93
|
end
|
@@ -91,6 +113,56 @@ module ActiveRecord
|
|
91
113
|
def schema_cache_path
|
92
114
|
configuration_hash[:schema_cache_path]
|
93
115
|
end
|
116
|
+
|
117
|
+
def default_schema_cache_path(db_dir = "db")
|
118
|
+
if primary?
|
119
|
+
File.join(db_dir, "schema_cache.yml")
|
120
|
+
else
|
121
|
+
File.join(db_dir, "#{name}_schema_cache.yml")
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
def lazy_schema_cache_path
|
126
|
+
schema_cache_path || default_schema_cache_path
|
127
|
+
end
|
128
|
+
|
129
|
+
def primary? # :nodoc:
|
130
|
+
Base.configurations.primary?(name)
|
131
|
+
end
|
132
|
+
|
133
|
+
# Determines whether to dump the schema/structure files and the
|
134
|
+
# filename that should be used.
|
135
|
+
#
|
136
|
+
# If +configuration_hash[:schema_dump]+ is set to +false+ or +nil+
|
137
|
+
# the schema will not be dumped.
|
138
|
+
#
|
139
|
+
# If the config option is set that will be used. Otherwise \Rails
|
140
|
+
# will generate the filename from the database config name.
|
141
|
+
def schema_dump(format = ActiveRecord.schema_format)
|
142
|
+
if configuration_hash.key?(:schema_dump)
|
143
|
+
if config = configuration_hash[:schema_dump]
|
144
|
+
config
|
145
|
+
end
|
146
|
+
elsif primary?
|
147
|
+
schema_file_type(format)
|
148
|
+
else
|
149
|
+
"#{name}_#{schema_file_type(format)}"
|
150
|
+
end
|
151
|
+
end
|
152
|
+
|
153
|
+
def database_tasks? # :nodoc:
|
154
|
+
!replica? && !!configuration_hash.fetch(:database_tasks, true)
|
155
|
+
end
|
156
|
+
|
157
|
+
private
|
158
|
+
def schema_file_type(format)
|
159
|
+
case format
|
160
|
+
when :ruby
|
161
|
+
"schema.rb"
|
162
|
+
when :sql
|
163
|
+
"structure.sql"
|
164
|
+
end
|
165
|
+
end
|
94
166
|
end
|
95
167
|
end
|
96
168
|
end
|
@@ -2,7 +2,9 @@
|
|
2
2
|
|
3
3
|
module ActiveRecord
|
4
4
|
class DatabaseConfigurations
|
5
|
-
#
|
5
|
+
# = Active Record Database Url Config
|
6
|
+
#
|
7
|
+
# A +UrlConfig+ object is created for each database configuration
|
6
8
|
# entry that is created from a URL. This can either be a URL string
|
7
9
|
# or a hash with a URL in place of the config hash.
|
8
10
|
#
|
@@ -17,20 +19,24 @@ module ActiveRecord
|
|
17
19
|
# @config={adapter: "postgresql", database: "foo", host: "localhost"},
|
18
20
|
# @url="postgres://localhost/foo">
|
19
21
|
#
|
20
|
-
#
|
22
|
+
# See ActiveRecord::DatabaseConfigurations for more info.
|
21
23
|
#
|
22
|
-
# * <tt>:env_name</tt> - The Rails environment, ie "development".
|
23
|
-
# * <tt>:name</tt> - The db config name. In a standard two-tier
|
24
|
-
# database configuration this will default to "primary". In a multiple
|
25
|
-
# database three-tier database configuration this corresponds to the name
|
26
|
-
# used in the second tier, for example "primary_readonly".
|
27
|
-
# * <tt>:url</tt> - The database URL.
|
28
|
-
# * <tt>:config</tt> - The config hash. This is the hash that contains the
|
29
|
-
# database adapter, name, and other important information for database
|
30
|
-
# connections.
|
31
24
|
class UrlConfig < HashConfig
|
32
25
|
attr_reader :url
|
33
26
|
|
27
|
+
# Initialize a new +UrlConfig+ object
|
28
|
+
#
|
29
|
+
# ==== Options
|
30
|
+
#
|
31
|
+
# * <tt>:env_name</tt> - The \Rails environment, i.e. "development".
|
32
|
+
# * <tt>:name</tt> - The db config name. In a standard two-tier
|
33
|
+
# database configuration this will default to "primary". In a multiple
|
34
|
+
# database three-tier database configuration this corresponds to the name
|
35
|
+
# used in the second tier, for example "primary_readonly".
|
36
|
+
# * <tt>:url</tt> - The database URL.
|
37
|
+
# * <tt>:config</tt> - The config hash. This is the hash that contains the
|
38
|
+
# database adapter, name, and other important information for database
|
39
|
+
# connections.
|
34
40
|
def initialize(env_name, name, url, configuration_hash = {})
|
35
41
|
super(env_name, name, configuration_hash)
|
36
42
|
|
@@ -42,7 +48,7 @@ module ActiveRecord
|
|
42
48
|
# Return a Hash that can be merged into the main config that represents
|
43
49
|
# the passed in url
|
44
50
|
def build_url_hash
|
45
|
-
if url.nil? ||
|
51
|
+
if url.nil? || url.start_with?("jdbc:", "http:", "https:")
|
46
52
|
{ url: url }
|
47
53
|
else
|
48
54
|
ConnectionUrlResolver.new(url).to_hash
|
@@ -7,24 +7,78 @@ require "active_record/database_configurations/url_config"
|
|
7
7
|
require "active_record/database_configurations/connection_url_resolver"
|
8
8
|
|
9
9
|
module ActiveRecord
|
10
|
-
#
|
11
|
-
#
|
12
|
-
#
|
10
|
+
# = Active Record Database Configurations
|
11
|
+
#
|
12
|
+
# +ActiveRecord::DatabaseConfigurations+ returns an array of +DatabaseConfig+
|
13
|
+
# objects that are constructed from the application's database
|
14
|
+
# configuration hash or URL string.
|
15
|
+
#
|
16
|
+
# The array of +DatabaseConfig+ objects in an application default to either a
|
17
|
+
# HashConfig or UrlConfig. You can retrieve your application's config by using
|
18
|
+
# ActiveRecord::Base.configurations.
|
19
|
+
#
|
20
|
+
# If you register a custom handler, objects will be created according to the
|
21
|
+
# conditions of the handler. See ::register_db_config_handler for more on
|
22
|
+
# registering custom handlers.
|
13
23
|
class DatabaseConfigurations
|
14
24
|
class InvalidConfigurationError < StandardError; end
|
15
25
|
|
16
26
|
attr_reader :configurations
|
17
27
|
delegate :any?, to: :configurations
|
18
28
|
|
29
|
+
singleton_class.attr_accessor :db_config_handlers # :nodoc:
|
30
|
+
self.db_config_handlers = [] # :nodoc:
|
31
|
+
|
32
|
+
# Allows an application to register a custom handler for database configuration
|
33
|
+
# objects. This is useful for creating a custom handler that responds to
|
34
|
+
# methods your application needs but Active Record doesn't implement. For
|
35
|
+
# example if you are using Vitess, you may want your Vitess configurations
|
36
|
+
# to respond to `sharded?`. To implement this define the following in an
|
37
|
+
# initializer:
|
38
|
+
#
|
39
|
+
# ActiveRecord::DatabaseConfigurations.register_db_config_handler do |env_name, name, url, config|
|
40
|
+
# next unless config.key?(:vitess)
|
41
|
+
# VitessConfig.new(env_name, name, config)
|
42
|
+
# end
|
43
|
+
#
|
44
|
+
# Note: applications must handle the condition in which custom config should be
|
45
|
+
# created in your handler registration otherwise all objects will use the custom
|
46
|
+
# handler.
|
47
|
+
#
|
48
|
+
# Then define your +VitessConfig+ to respond to the methods your application
|
49
|
+
# needs. It is recommended that you inherit from one of the existing
|
50
|
+
# database config classes to avoid having to reimplement all methods. Custom
|
51
|
+
# config handlers should only implement methods Active Record does not.
|
52
|
+
#
|
53
|
+
# class VitessConfig < ActiveRecord::DatabaseConfigurations::UrlConfig
|
54
|
+
# def sharded?
|
55
|
+
# configuration_hash.fetch("sharded", false)
|
56
|
+
# end
|
57
|
+
# end
|
58
|
+
#
|
59
|
+
# For configs that have a +:vitess+ key, a +VitessConfig+ object will be
|
60
|
+
# created instead of a +UrlConfig+.
|
61
|
+
def self.register_db_config_handler(&block)
|
62
|
+
db_config_handlers << block
|
63
|
+
end
|
64
|
+
|
65
|
+
register_db_config_handler do |env_name, name, url, config|
|
66
|
+
if url
|
67
|
+
UrlConfig.new(env_name, name, url, config)
|
68
|
+
else
|
69
|
+
HashConfig.new(env_name, name, config)
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
19
73
|
def initialize(configurations = {})
|
20
74
|
@configurations = build_configs(configurations)
|
21
75
|
end
|
22
76
|
|
23
77
|
# Collects the configs for the environment and optionally the specification
|
24
|
-
# name passed in. To include replica configurations pass <tt>
|
78
|
+
# name passed in. To include replica configurations pass <tt>include_hidden: true</tt>.
|
25
79
|
#
|
26
|
-
# If a name is provided a single DatabaseConfig object will be
|
27
|
-
# returned, otherwise an array of DatabaseConfig objects will be
|
80
|
+
# If a name is provided a single +DatabaseConfig+ object will be
|
81
|
+
# returned, otherwise an array of +DatabaseConfig+ objects will be
|
28
82
|
# returned that corresponds with the environment and type requested.
|
29
83
|
#
|
30
84
|
# ==== Options
|
@@ -34,22 +88,26 @@ module ActiveRecord
|
|
34
88
|
# * <tt>name:</tt> The db config name (i.e. primary, animals, etc.). Defaults
|
35
89
|
# to +nil+. If no +env_name+ is specified the config for the default env and the
|
36
90
|
# passed +name+ will be returned.
|
37
|
-
# * <tt>
|
38
|
-
#
|
39
|
-
#
|
40
|
-
#
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
end
|
46
|
-
|
91
|
+
# * <tt>config_key:</tt> Selects configs that contain a particular key in the configuration
|
92
|
+
# hash. Useful for selecting configs that use a custom db config handler or finding
|
93
|
+
# configs with hashes that contain a particular key.
|
94
|
+
# * <tt>include_hidden:</tt> Determines whether to include replicas and configurations
|
95
|
+
# hidden by <tt>database_tasks: false</tt> in the returned list. Most of the time we're only
|
96
|
+
# iterating over the primary connections (i.e. migrations don't need to run for the
|
97
|
+
# write and read connection). Defaults to +false+.
|
98
|
+
def configs_for(env_name: nil, name: nil, config_key: nil, include_hidden: false)
|
47
99
|
env_name ||= default_env if name
|
48
100
|
configs = env_with_configs(env_name)
|
49
101
|
|
50
|
-
unless
|
102
|
+
unless include_hidden
|
103
|
+
configs = configs.select do |db_config|
|
104
|
+
db_config.database_tasks?
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
if config_key
|
51
109
|
configs = configs.select do |db_config|
|
52
|
-
|
110
|
+
db_config.configuration_hash.key?(config_key)
|
53
111
|
end
|
54
112
|
end
|
55
113
|
|
@@ -62,30 +120,17 @@ module ActiveRecord
|
|
62
120
|
end
|
63
121
|
end
|
64
122
|
|
65
|
-
# Returns
|
66
|
-
#
|
67
|
-
# If the application has multiple databases +default_hash+ will
|
68
|
-
# return the first config hash for the environment.
|
69
|
-
#
|
70
|
-
# { database: "my_db", adapter: "mysql2" }
|
71
|
-
def default_hash(env = default_env)
|
72
|
-
default = find_db_config(env)
|
73
|
-
default.configuration_hash if default
|
74
|
-
end
|
75
|
-
alias :[] :default_hash
|
76
|
-
deprecate "[]": "Use configs_for", default_hash: "Use configs_for"
|
77
|
-
|
78
|
-
# Returns a single DatabaseConfig object based on the requested environment.
|
123
|
+
# Returns a single +DatabaseConfig+ object based on the requested environment.
|
79
124
|
#
|
80
125
|
# If the application has multiple databases +find_db_config+ will return
|
81
|
-
# the first DatabaseConfig for the environment.
|
126
|
+
# the first +DatabaseConfig+ for the environment.
|
82
127
|
def find_db_config(env)
|
83
|
-
|
84
|
-
|
85
|
-
.
|
86
|
-
|
87
|
-
|
88
|
-
|
128
|
+
env = env.to_s
|
129
|
+
configurations.find do |db_config|
|
130
|
+
db_config.for_current_env? && (db_config.env_name == env || db_config.name == env)
|
131
|
+
end || configurations.find do |db_config|
|
132
|
+
db_config.env_name == env
|
133
|
+
end
|
89
134
|
end
|
90
135
|
|
91
136
|
# A primary configuration is one that is named primary or if there is
|
@@ -101,17 +146,7 @@ module ActiveRecord
|
|
101
146
|
first_config && name == first_config.name
|
102
147
|
end
|
103
148
|
|
104
|
-
# Returns the DatabaseConfigurations object as a Hash.
|
105
|
-
def to_h
|
106
|
-
configurations.inject({}) do |memo, db_config|
|
107
|
-
memo.merge(db_config.env_name => db_config.configuration_hash.stringify_keys)
|
108
|
-
end
|
109
|
-
end
|
110
|
-
deprecate to_h: "You can use `ActiveRecord::Base.configurations.configs_for(env_name: 'env', name: 'primary').configuration_hash` to get the configuration hashes."
|
111
|
-
|
112
149
|
# Checks if the application's configurations are empty.
|
113
|
-
#
|
114
|
-
# Aliased to blank?
|
115
150
|
def empty?
|
116
151
|
configurations.empty?
|
117
152
|
end
|
@@ -167,7 +202,7 @@ module ActiveRecord
|
|
167
202
|
return configs if configs.is_a?(Array)
|
168
203
|
|
169
204
|
db_configs = configs.flat_map do |env_name, config|
|
170
|
-
if config.is_a?(Hash) && config.all?
|
205
|
+
if config.is_a?(Hash) && config.values.all?(Hash)
|
171
206
|
walk_configs(env_name.to_s, config)
|
172
207
|
else
|
173
208
|
build_db_config_from_raw_config(env_name.to_s, "primary", config)
|
@@ -194,7 +229,7 @@ module ActiveRecord
|
|
194
229
|
raise AdapterNotSpecified, <<~MSG
|
195
230
|
The `#{name}` database is not configured for the `#{default_env}` environment.
|
196
231
|
|
197
|
-
Available
|
232
|
+
Available database configurations are:
|
198
233
|
|
199
234
|
#{build_configuration_sentence}
|
200
235
|
MSG
|
@@ -202,7 +237,7 @@ module ActiveRecord
|
|
202
237
|
end
|
203
238
|
|
204
239
|
def build_configuration_sentence
|
205
|
-
configs = configs_for(
|
240
|
+
configs = configs_for(include_hidden: true)
|
206
241
|
|
207
242
|
configs.group_by(&:env_name).map do |env, config|
|
208
243
|
names = config.map(&:name)
|
@@ -236,15 +271,16 @@ module ActiveRecord
|
|
236
271
|
end
|
237
272
|
|
238
273
|
def build_db_config_from_hash(env_name, name, config)
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
config_without_url.delete :url
|
274
|
+
url = config[:url]
|
275
|
+
config_without_url = config.dup
|
276
|
+
config_without_url.delete :url
|
243
277
|
|
244
|
-
|
245
|
-
|
246
|
-
|
278
|
+
DatabaseConfigurations.db_config_handlers.reverse_each do |handler|
|
279
|
+
config = handler.call(env_name, name, url, config_without_url)
|
280
|
+
return config if config
|
247
281
|
end
|
282
|
+
|
283
|
+
nil
|
248
284
|
end
|
249
285
|
|
250
286
|
def merge_db_environment_variables(current_env, configs)
|