activerecord 5.2.4.2 → 6.0.2.2
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of activerecord might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/CHANGELOG.md +715 -566
- data/MIT-LICENSE +3 -1
- data/README.rdoc +4 -2
- data/examples/performance.rb +1 -1
- data/lib/active_record.rb +9 -2
- data/lib/active_record/aggregations.rb +4 -2
- data/lib/active_record/association_relation.rb +15 -6
- data/lib/active_record/associations.rb +20 -15
- data/lib/active_record/associations/association.rb +61 -20
- data/lib/active_record/associations/association_scope.rb +4 -6
- data/lib/active_record/associations/belongs_to_association.rb +36 -42
- data/lib/active_record/associations/belongs_to_polymorphic_association.rb +0 -4
- data/lib/active_record/associations/builder/association.rb +14 -18
- data/lib/active_record/associations/builder/belongs_to.rb +19 -52
- data/lib/active_record/associations/builder/collection_association.rb +3 -13
- data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +17 -38
- data/lib/active_record/associations/builder/has_many.rb +2 -0
- data/lib/active_record/associations/builder/has_one.rb +35 -1
- data/lib/active_record/associations/builder/singular_association.rb +2 -0
- data/lib/active_record/associations/collection_association.rb +12 -23
- data/lib/active_record/associations/collection_proxy.rb +12 -15
- data/lib/active_record/associations/foreign_association.rb +7 -0
- data/lib/active_record/associations/has_many_association.rb +2 -10
- data/lib/active_record/associations/has_many_through_association.rb +14 -14
- data/lib/active_record/associations/has_one_association.rb +28 -30
- data/lib/active_record/associations/has_one_through_association.rb +5 -5
- data/lib/active_record/associations/join_dependency.rb +28 -28
- data/lib/active_record/associations/join_dependency/join_association.rb +9 -10
- data/lib/active_record/associations/join_dependency/join_part.rb +2 -2
- data/lib/active_record/associations/preloader.rb +39 -31
- data/lib/active_record/associations/preloader/association.rb +38 -36
- data/lib/active_record/associations/preloader/through_association.rb +48 -39
- data/lib/active_record/associations/singular_association.rb +2 -16
- data/lib/active_record/attribute_assignment.rb +7 -10
- data/lib/active_record/attribute_methods.rb +28 -100
- data/lib/active_record/attribute_methods/before_type_cast.rb +4 -1
- data/lib/active_record/attribute_methods/dirty.rb +111 -40
- data/lib/active_record/attribute_methods/primary_key.rb +15 -22
- data/lib/active_record/attribute_methods/query.rb +2 -3
- data/lib/active_record/attribute_methods/read.rb +15 -53
- data/lib/active_record/attribute_methods/serialization.rb +1 -1
- data/lib/active_record/attribute_methods/time_zone_conversion.rb +1 -1
- data/lib/active_record/attribute_methods/write.rb +17 -24
- data/lib/active_record/attributes.rb +13 -0
- data/lib/active_record/autosave_association.rb +2 -2
- data/lib/active_record/base.rb +2 -3
- data/lib/active_record/callbacks.rb +5 -19
- data/lib/active_record/connection_adapters/abstract/connection_pool.rb +104 -16
- data/lib/active_record/connection_adapters/abstract/database_limits.rb +17 -4
- data/lib/active_record/connection_adapters/abstract/database_statements.rb +99 -123
- data/lib/active_record/connection_adapters/abstract/query_cache.rb +18 -8
- data/lib/active_record/connection_adapters/abstract/quoting.rb +68 -17
- data/lib/active_record/connection_adapters/abstract/schema_creation.rb +19 -12
- data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +76 -48
- data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +1 -3
- data/lib/active_record/connection_adapters/abstract/schema_statements.rb +132 -53
- data/lib/active_record/connection_adapters/abstract/transaction.rb +96 -56
- data/lib/active_record/connection_adapters/abstract_adapter.rb +187 -43
- data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +138 -195
- data/lib/active_record/connection_adapters/column.rb +17 -13
- data/lib/active_record/connection_adapters/connection_specification.rb +53 -43
- data/lib/active_record/connection_adapters/determine_if_preparable_visitor.rb +6 -10
- data/lib/active_record/connection_adapters/mysql/database_statements.rb +75 -13
- data/lib/active_record/connection_adapters/mysql/quoting.rb +44 -7
- data/lib/active_record/connection_adapters/mysql/schema_creation.rb +3 -4
- data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +40 -32
- data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +14 -6
- data/lib/active_record/connection_adapters/mysql/schema_statements.rb +129 -13
- data/lib/active_record/connection_adapters/mysql/type_metadata.rb +6 -10
- data/lib/active_record/connection_adapters/mysql2_adapter.rb +26 -9
- data/lib/active_record/connection_adapters/postgresql/column.rb +17 -31
- data/lib/active_record/connection_adapters/postgresql/database_statements.rb +22 -1
- data/lib/active_record/connection_adapters/postgresql/oid/array.rb +1 -1
- data/lib/active_record/connection_adapters/postgresql/oid/bit.rb +1 -4
- data/lib/active_record/connection_adapters/postgresql/oid/hstore.rb +1 -1
- data/lib/active_record/connection_adapters/postgresql/oid/legacy_point.rb +1 -1
- data/lib/active_record/connection_adapters/postgresql/oid/money.rb +2 -2
- data/lib/active_record/connection_adapters/postgresql/oid/point.rb +1 -1
- data/lib/active_record/connection_adapters/postgresql/oid/range.rb +1 -1
- data/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb +9 -7
- data/lib/active_record/connection_adapters/postgresql/oid/uuid.rb +6 -3
- data/lib/active_record/connection_adapters/postgresql/quoting.rb +44 -7
- data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +12 -1
- data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +107 -91
- data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +55 -53
- data/lib/active_record/connection_adapters/postgresql/type_metadata.rb +24 -27
- data/lib/active_record/connection_adapters/postgresql_adapter.rb +164 -74
- data/lib/active_record/connection_adapters/schema_cache.rb +37 -14
- data/lib/active_record/connection_adapters/sql_type_metadata.rb +11 -8
- data/lib/active_record/connection_adapters/sqlite3/database_statements.rb +120 -0
- data/lib/active_record/connection_adapters/sqlite3/quoting.rb +42 -6
- data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +42 -11
- data/lib/active_record/connection_adapters/sqlite3_adapter.rb +129 -141
- data/lib/active_record/connection_handling.rb +155 -26
- data/lib/active_record/core.rb +103 -59
- data/lib/active_record/counter_cache.rb +4 -29
- data/lib/active_record/database_configurations.rb +233 -0
- data/lib/active_record/database_configurations/database_config.rb +37 -0
- data/lib/active_record/database_configurations/hash_config.rb +50 -0
- data/lib/active_record/database_configurations/url_config.rb +79 -0
- data/lib/active_record/dynamic_matchers.rb +1 -1
- data/lib/active_record/enum.rb +37 -7
- data/lib/active_record/errors.rb +15 -7
- data/lib/active_record/explain.rb +1 -1
- data/lib/active_record/fixture_set/model_metadata.rb +33 -0
- data/lib/active_record/fixture_set/render_context.rb +17 -0
- data/lib/active_record/fixture_set/table_row.rb +153 -0
- data/lib/active_record/fixture_set/table_rows.rb +47 -0
- data/lib/active_record/fixtures.rb +145 -472
- data/lib/active_record/gem_version.rb +3 -3
- data/lib/active_record/inheritance.rb +13 -3
- data/lib/active_record/insert_all.rb +179 -0
- data/lib/active_record/integration.rb +68 -16
- data/lib/active_record/internal_metadata.rb +10 -2
- data/lib/active_record/locking/optimistic.rb +5 -6
- data/lib/active_record/locking/pessimistic.rb +3 -3
- data/lib/active_record/log_subscriber.rb +7 -26
- data/lib/active_record/middleware/database_selector.rb +75 -0
- data/lib/active_record/middleware/database_selector/resolver.rb +88 -0
- data/lib/active_record/middleware/database_selector/resolver/session.rb +45 -0
- data/lib/active_record/migration.rb +100 -81
- data/lib/active_record/migration/command_recorder.rb +50 -6
- data/lib/active_record/migration/compatibility.rb +76 -49
- data/lib/active_record/model_schema.rb +33 -9
- data/lib/active_record/nested_attributes.rb +2 -2
- data/lib/active_record/no_touching.rb +7 -0
- data/lib/active_record/persistence.rb +228 -24
- data/lib/active_record/query_cache.rb +11 -4
- data/lib/active_record/querying.rb +32 -20
- data/lib/active_record/railtie.rb +80 -43
- data/lib/active_record/railties/collection_cache_association_loading.rb +34 -0
- data/lib/active_record/railties/controller_runtime.rb +30 -35
- data/lib/active_record/railties/databases.rake +199 -46
- data/lib/active_record/reflection.rb +32 -30
- data/lib/active_record/relation.rb +311 -80
- data/lib/active_record/relation/batches.rb +13 -10
- data/lib/active_record/relation/calculations.rb +53 -47
- data/lib/active_record/relation/delegation.rb +26 -43
- data/lib/active_record/relation/finder_methods.rb +23 -27
- data/lib/active_record/relation/merger.rb +11 -20
- data/lib/active_record/relation/predicate_builder.rb +4 -6
- data/lib/active_record/relation/predicate_builder/array_handler.rb +5 -4
- data/lib/active_record/relation/predicate_builder/association_query_value.rb +1 -4
- data/lib/active_record/relation/predicate_builder/base_handler.rb +1 -2
- data/lib/active_record/relation/predicate_builder/basic_object_handler.rb +1 -2
- data/lib/active_record/relation/predicate_builder/polymorphic_array_value.rb +1 -4
- data/lib/active_record/relation/predicate_builder/range_handler.rb +3 -23
- data/lib/active_record/relation/query_attribute.rb +13 -8
- data/lib/active_record/relation/query_methods.rb +213 -64
- data/lib/active_record/relation/spawn_methods.rb +1 -1
- data/lib/active_record/relation/where_clause.rb +14 -10
- data/lib/active_record/relation/where_clause_factory.rb +1 -2
- data/lib/active_record/result.rb +30 -11
- data/lib/active_record/sanitization.rb +32 -40
- data/lib/active_record/schema.rb +2 -11
- data/lib/active_record/schema_dumper.rb +22 -7
- data/lib/active_record/schema_migration.rb +5 -1
- data/lib/active_record/scoping.rb +8 -8
- data/lib/active_record/scoping/default.rb +4 -5
- data/lib/active_record/scoping/named.rb +20 -15
- data/lib/active_record/statement_cache.rb +30 -3
- data/lib/active_record/store.rb +87 -8
- data/lib/active_record/table_metadata.rb +10 -17
- data/lib/active_record/tasks/database_tasks.rb +194 -25
- data/lib/active_record/tasks/mysql_database_tasks.rb +5 -5
- data/lib/active_record/tasks/postgresql_database_tasks.rb +5 -7
- data/lib/active_record/tasks/sqlite_database_tasks.rb +2 -8
- data/lib/active_record/test_databases.rb +23 -0
- data/lib/active_record/test_fixtures.rb +225 -0
- data/lib/active_record/timestamp.rb +39 -25
- data/lib/active_record/touch_later.rb +4 -2
- data/lib/active_record/transactions.rb +56 -65
- data/lib/active_record/translation.rb +1 -1
- data/lib/active_record/type.rb +3 -4
- data/lib/active_record/type/adapter_specific_registry.rb +1 -8
- data/lib/active_record/type_caster/connection.rb +15 -14
- data/lib/active_record/type_caster/map.rb +1 -4
- data/lib/active_record/validations.rb +1 -0
- data/lib/active_record/validations/uniqueness.rb +15 -27
- data/lib/arel.rb +58 -0
- data/lib/arel/alias_predication.rb +9 -0
- data/lib/arel/attributes.rb +22 -0
- data/lib/arel/attributes/attribute.rb +37 -0
- data/lib/arel/collectors/bind.rb +24 -0
- data/lib/arel/collectors/composite.rb +31 -0
- data/lib/arel/collectors/plain_string.rb +20 -0
- data/lib/arel/collectors/sql_string.rb +20 -0
- data/lib/arel/collectors/substitute_binds.rb +28 -0
- data/lib/arel/crud.rb +42 -0
- data/lib/arel/delete_manager.rb +18 -0
- data/lib/arel/errors.rb +9 -0
- data/lib/arel/expressions.rb +29 -0
- data/lib/arel/factory_methods.rb +49 -0
- data/lib/arel/insert_manager.rb +49 -0
- data/lib/arel/math.rb +45 -0
- data/lib/arel/nodes.rb +68 -0
- data/lib/arel/nodes/and.rb +32 -0
- data/lib/arel/nodes/ascending.rb +23 -0
- data/lib/arel/nodes/binary.rb +52 -0
- data/lib/arel/nodes/bind_param.rb +36 -0
- data/lib/arel/nodes/case.rb +55 -0
- data/lib/arel/nodes/casted.rb +50 -0
- data/lib/arel/nodes/comment.rb +29 -0
- data/lib/arel/nodes/count.rb +12 -0
- data/lib/arel/nodes/delete_statement.rb +45 -0
- data/lib/arel/nodes/descending.rb +23 -0
- data/lib/arel/nodes/equality.rb +18 -0
- data/lib/arel/nodes/extract.rb +24 -0
- data/lib/arel/nodes/false.rb +16 -0
- data/lib/arel/nodes/full_outer_join.rb +8 -0
- data/lib/arel/nodes/function.rb +44 -0
- data/lib/arel/nodes/grouping.rb +8 -0
- data/lib/arel/nodes/in.rb +8 -0
- data/lib/arel/nodes/infix_operation.rb +80 -0
- data/lib/arel/nodes/inner_join.rb +8 -0
- data/lib/arel/nodes/insert_statement.rb +37 -0
- data/lib/arel/nodes/join_source.rb +20 -0
- data/lib/arel/nodes/matches.rb +18 -0
- data/lib/arel/nodes/named_function.rb +23 -0
- data/lib/arel/nodes/node.rb +50 -0
- data/lib/arel/nodes/node_expression.rb +13 -0
- data/lib/arel/nodes/outer_join.rb +8 -0
- data/lib/arel/nodes/over.rb +15 -0
- data/lib/arel/nodes/regexp.rb +16 -0
- data/lib/arel/nodes/right_outer_join.rb +8 -0
- data/lib/arel/nodes/select_core.rb +67 -0
- data/lib/arel/nodes/select_statement.rb +41 -0
- data/lib/arel/nodes/sql_literal.rb +16 -0
- data/lib/arel/nodes/string_join.rb +11 -0
- data/lib/arel/nodes/table_alias.rb +27 -0
- data/lib/arel/nodes/terminal.rb +16 -0
- data/lib/arel/nodes/true.rb +16 -0
- data/lib/arel/nodes/unary.rb +45 -0
- data/lib/arel/nodes/unary_operation.rb +20 -0
- data/lib/arel/nodes/unqualified_column.rb +22 -0
- data/lib/arel/nodes/update_statement.rb +41 -0
- data/lib/arel/nodes/values_list.rb +9 -0
- data/lib/arel/nodes/window.rb +126 -0
- data/lib/arel/nodes/with.rb +11 -0
- data/lib/arel/order_predications.rb +13 -0
- data/lib/arel/predications.rb +257 -0
- data/lib/arel/select_manager.rb +271 -0
- data/lib/arel/table.rb +110 -0
- data/lib/arel/tree_manager.rb +72 -0
- data/lib/arel/update_manager.rb +34 -0
- data/lib/arel/visitors.rb +20 -0
- data/lib/arel/visitors/depth_first.rb +204 -0
- data/lib/arel/visitors/dot.rb +297 -0
- data/lib/arel/visitors/ibm_db.rb +34 -0
- data/lib/arel/visitors/informix.rb +62 -0
- data/lib/arel/visitors/mssql.rb +157 -0
- data/lib/arel/visitors/mysql.rb +83 -0
- data/lib/arel/visitors/oracle.rb +159 -0
- data/lib/arel/visitors/oracle12.rb +66 -0
- data/lib/arel/visitors/postgresql.rb +110 -0
- data/lib/arel/visitors/sqlite.rb +39 -0
- data/lib/arel/visitors/to_sql.rb +889 -0
- data/lib/arel/visitors/visitor.rb +46 -0
- data/lib/arel/visitors/where_sql.rb +23 -0
- data/lib/arel/window_predications.rb +9 -0
- data/lib/rails/generators/active_record/migration.rb +14 -1
- data/lib/rails/generators/active_record/migration/migration_generator.rb +2 -5
- data/lib/rails/generators/active_record/migration/templates/create_table_migration.rb.tt +1 -1
- data/lib/rails/generators/active_record/migration/templates/migration.rb.tt +4 -2
- data/lib/rails/generators/active_record/model/model_generator.rb +1 -0
- data/lib/rails/generators/active_record/model/templates/model.rb.tt +10 -1
- metadata +109 -24
- data/lib/active_record/collection_cache_key.rb +0 -53
@@ -26,15 +26,22 @@ module ActiveRecord
|
|
26
26
|
end
|
27
27
|
|
28
28
|
def self.run
|
29
|
-
|
30
|
-
|
29
|
+
pools = []
|
30
|
+
|
31
|
+
ActiveRecord::Base.connection_handlers.each do |key, handler|
|
32
|
+
pools << handler.connection_pool_list.reject { |p| p.query_cache_enabled }.each { |p| p.enable_query_cache! }
|
33
|
+
end
|
34
|
+
|
35
|
+
pools.flatten
|
31
36
|
end
|
32
37
|
|
33
38
|
def self.complete(pools)
|
34
39
|
pools.each { |pool| pool.disable_query_cache! }
|
35
40
|
|
36
|
-
ActiveRecord::Base.
|
37
|
-
|
41
|
+
ActiveRecord::Base.connection_handlers.each do |_, handler|
|
42
|
+
handler.connection_pool_list.each do |pool|
|
43
|
+
pool.release_connection if pool.active_connection? && !pool.connection.transaction_open?
|
44
|
+
end
|
38
45
|
end
|
39
46
|
end
|
40
47
|
|
@@ -2,31 +2,36 @@
|
|
2
2
|
|
3
3
|
module ActiveRecord
|
4
4
|
module Querying
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
5
|
+
QUERYING_METHODS = [
|
6
|
+
:find, :find_by, :find_by!, :take, :take!, :first, :first!, :last, :last!,
|
7
|
+
:second, :second!, :third, :third!, :fourth, :fourth!, :fifth, :fifth!,
|
8
|
+
:forty_two, :forty_two!, :third_to_last, :third_to_last!, :second_to_last, :second_to_last!,
|
9
|
+
:exists?, :any?, :many?, :none?, :one?,
|
10
|
+
:first_or_create, :first_or_create!, :first_or_initialize,
|
11
|
+
:find_or_create_by, :find_or_create_by!, :find_or_initialize_by,
|
12
|
+
:create_or_find_by, :create_or_find_by!,
|
13
|
+
:destroy_all, :delete_all, :update_all, :touch_all, :destroy_by, :delete_by,
|
14
|
+
:find_each, :find_in_batches, :in_batches,
|
15
|
+
:select, :reselect, :order, :reorder, :group, :limit, :offset, :joins, :left_joins, :left_outer_joins,
|
16
|
+
:where, :rewhere, :preload, :extract_associated, :eager_load, :includes, :from, :lock, :readonly, :extending, :or,
|
17
|
+
:having, :create_with, :distinct, :references, :none, :unscope, :optimizer_hints, :merge, :except, :only,
|
18
|
+
:count, :average, :minimum, :maximum, :sum, :calculate, :annotate,
|
19
|
+
:pluck, :pick, :ids
|
20
|
+
].freeze # :nodoc:
|
21
|
+
delegate(*QUERYING_METHODS, to: :all)
|
17
22
|
|
18
23
|
# Executes a custom SQL query against your database and returns all the results. The results will
|
19
|
-
# be returned as an array with
|
20
|
-
# this method from.
|
24
|
+
# be returned as an array, with the requested columns encapsulated as attributes of the model you call
|
25
|
+
# this method from. For example, if you call <tt>Product.find_by_sql</tt>, then the results will be returned in
|
21
26
|
# a +Product+ object with the attributes you specified in the SQL query.
|
22
27
|
#
|
23
|
-
# If you call a complicated SQL query which spans multiple tables the columns specified by the
|
28
|
+
# If you call a complicated SQL query which spans multiple tables, the columns specified by the
|
24
29
|
# SELECT will be attributes of the model, whether or not they are columns of the corresponding
|
25
30
|
# table.
|
26
31
|
#
|
27
|
-
# The +sql+ parameter is a full SQL query as a string. It will be called as is
|
28
|
-
# no database agnostic conversions performed. This should be a last resort because using
|
29
|
-
#
|
32
|
+
# The +sql+ parameter is a full SQL query as a string. It will be called as is; there will be
|
33
|
+
# no database agnostic conversions performed. This should be a last resort because using
|
34
|
+
# database-specific terms will lock you into using that particular database engine, or require you to
|
30
35
|
# change your call if you switch engines.
|
31
36
|
#
|
32
37
|
# # A simple SQL query spanning multiple tables
|
@@ -49,13 +54,20 @@ module ActiveRecord
|
|
49
54
|
}
|
50
55
|
|
51
56
|
message_bus.instrument("instantiation.active_record", payload) do
|
52
|
-
result_set.
|
57
|
+
if result_set.includes_column?(inheritance_column)
|
58
|
+
result_set.map { |record| instantiate(record, column_types, &block) }
|
59
|
+
else
|
60
|
+
# Instantiate a homogeneous set
|
61
|
+
result_set.map { |record| instantiate_instance_of(self, record, column_types, &block) }
|
62
|
+
end
|
53
63
|
end
|
54
64
|
end
|
55
65
|
|
56
66
|
# Returns the result of an SQL statement that should only include a COUNT(*) in the SELECT part.
|
57
67
|
# The use of this method should be restricted to complicated SQL queries that can't be executed
|
58
|
-
# using the ActiveRecord::Calculations class methods. Look into those before using this
|
68
|
+
# using the ActiveRecord::Calculations class methods. Look into those before using this method,
|
69
|
+
# as it could lock you into a specific database engine or require a code change to switch
|
70
|
+
# database engines.
|
59
71
|
#
|
60
72
|
# Product.count_by_sql "SELECT COUNT(*) FROM sales s, customers c WHERE s.customer_id = c.id"
|
61
73
|
# # => 12
|
@@ -77,6 +77,10 @@ module ActiveRecord
|
|
77
77
|
ActiveSupport.on_load(:active_record) { self.logger ||= ::Rails.logger }
|
78
78
|
end
|
79
79
|
|
80
|
+
initializer "active_record.backtrace_cleaner" do
|
81
|
+
ActiveSupport.on_load(:active_record) { LogSubscriber.backtrace_cleaner = ::Rails.backtrace_cleaner }
|
82
|
+
end
|
83
|
+
|
80
84
|
initializer "active_record.migration_error" do
|
81
85
|
if config.active_record.delete(:migration_error) == :page_load
|
82
86
|
config.app_middleware.insert_after ::ActionDispatch::Callbacks,
|
@@ -84,6 +88,39 @@ module ActiveRecord
|
|
84
88
|
end
|
85
89
|
end
|
86
90
|
|
91
|
+
initializer "active_record.database_selector" do
|
92
|
+
if options = config.active_record.delete(:database_selector)
|
93
|
+
resolver = config.active_record.delete(:database_resolver)
|
94
|
+
operations = config.active_record.delete(:database_resolver_context)
|
95
|
+
config.app_middleware.use ActiveRecord::Middleware::DatabaseSelector, resolver, operations, options
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
initializer "Check for cache versioning support" do
|
100
|
+
config.after_initialize do |app|
|
101
|
+
ActiveSupport.on_load(:active_record) do
|
102
|
+
if app.config.active_record.cache_versioning && Rails.cache
|
103
|
+
unless Rails.cache.class.try(:supports_cache_versioning?)
|
104
|
+
raise <<-end_error
|
105
|
+
|
106
|
+
You're using a cache store that doesn't support native cache versioning.
|
107
|
+
Your best option is to upgrade to a newer version of #{Rails.cache.class}
|
108
|
+
that supports cache versioning (#{Rails.cache.class}.supports_cache_versioning? #=> true).
|
109
|
+
|
110
|
+
Next best, switch to a different cache store that does support cache versioning:
|
111
|
+
https://guides.rubyonrails.org/caching_with_rails.html#cache-stores.
|
112
|
+
|
113
|
+
To keep using the current cache store, you can turn off cache versioning entirely:
|
114
|
+
|
115
|
+
config.active_record.cache_versioning = false
|
116
|
+
|
117
|
+
end_error
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
87
124
|
initializer "active_record.check_schema_cache_dump" do
|
88
125
|
if config.active_record.delete(:use_schema_cache_dump)
|
89
126
|
config.after_initialize do |app|
|
@@ -97,7 +134,6 @@ module ActiveRecord
|
|
97
134
|
|
98
135
|
cache = YAML.load(File.read(filename))
|
99
136
|
if cache.version == current_version
|
100
|
-
connection.schema_cache = cache
|
101
137
|
connection_pool.schema_cache = cache.dup
|
102
138
|
else
|
103
139
|
warn "Ignoring db/schema_cache.yml because it has expired. The current schema version is #{current_version}, but the one in the cache is #{cache.version}."
|
@@ -108,6 +144,26 @@ module ActiveRecord
|
|
108
144
|
end
|
109
145
|
end
|
110
146
|
|
147
|
+
initializer "active_record.define_attribute_methods" do |app|
|
148
|
+
config.after_initialize do
|
149
|
+
ActiveSupport.on_load(:active_record) do
|
150
|
+
if app.config.eager_load
|
151
|
+
descendants.each do |model|
|
152
|
+
# SchemaMigration and InternalMetadata both override `table_exists?`
|
153
|
+
# to bypass the schema cache, so skip them to avoid the extra queries.
|
154
|
+
next if model._internal?
|
155
|
+
|
156
|
+
# If there's no connection yet, or the schema cache doesn't have the columns
|
157
|
+
# hash for the model cached, `define_attribute_methods` would trigger a query.
|
158
|
+
next unless model.connected? && model.connection.schema_cache.columns_hash?(model.table_name)
|
159
|
+
|
160
|
+
model.define_attribute_methods
|
161
|
+
end
|
162
|
+
end
|
163
|
+
end
|
164
|
+
end
|
165
|
+
end
|
166
|
+
|
111
167
|
initializer "active_record.warn_on_records_fetched_greater_than" do
|
112
168
|
if config.active_record.warn_on_records_fetched_greater_than
|
113
169
|
ActiveSupport.on_load(:active_record) do
|
@@ -118,8 +174,18 @@ module ActiveRecord
|
|
118
174
|
|
119
175
|
initializer "active_record.set_configs" do |app|
|
120
176
|
ActiveSupport.on_load(:active_record) do
|
121
|
-
configs = app.config.active_record
|
177
|
+
configs = app.config.active_record
|
178
|
+
|
179
|
+
represent_boolean_as_integer = configs.sqlite3.delete(:represent_boolean_as_integer)
|
180
|
+
|
181
|
+
unless represent_boolean_as_integer.nil?
|
182
|
+
ActiveSupport.on_load(:active_record_sqlite3adapter) do
|
183
|
+
ActiveRecord::ConnectionAdapters::SQLite3Adapter.represent_boolean_as_integer = represent_boolean_as_integer
|
184
|
+
end
|
185
|
+
end
|
186
|
+
|
122
187
|
configs.delete(:sqlite3)
|
188
|
+
|
123
189
|
configs.each do |k, v|
|
124
190
|
send "#{k}=", v
|
125
191
|
end
|
@@ -130,22 +196,9 @@ module ActiveRecord
|
|
130
196
|
# and then establishes the connection.
|
131
197
|
initializer "active_record.initialize_database" do
|
132
198
|
ActiveSupport.on_load(:active_record) do
|
199
|
+
self.connection_handlers = { writing_role => ActiveRecord::Base.default_connection_handler }
|
133
200
|
self.configurations = Rails.application.config.database_configuration
|
134
|
-
|
135
|
-
begin
|
136
|
-
establish_connection
|
137
|
-
rescue ActiveRecord::NoDatabaseError
|
138
|
-
warn <<-end_warning
|
139
|
-
Oops - You have a database configured, but it doesn't exist yet!
|
140
|
-
|
141
|
-
Here's how to get started:
|
142
|
-
|
143
|
-
1. Configure your database in config/database.yml.
|
144
|
-
2. Run `bin/rails db:create` to create the database.
|
145
|
-
3. Run `bin/rails db:setup` to load your database schema.
|
146
|
-
end_warning
|
147
|
-
raise
|
148
|
-
end
|
201
|
+
establish_connection
|
149
202
|
end
|
150
203
|
end
|
151
204
|
|
@@ -157,6 +210,13 @@ end_warning
|
|
157
210
|
end
|
158
211
|
end
|
159
212
|
|
213
|
+
initializer "active_record.collection_cache_association_loading" do
|
214
|
+
require "active_record/railties/collection_cache_association_loading"
|
215
|
+
ActiveSupport.on_load(:action_view) do
|
216
|
+
ActionView::PartialRenderer.prepend(ActiveRecord::Railties::CollectionCacheAssociationLoading)
|
217
|
+
end
|
218
|
+
end
|
219
|
+
|
160
220
|
initializer "active_record.set_reloader_hooks" do
|
161
221
|
ActiveSupport.on_load(:active_record) do
|
162
222
|
ActiveSupport::Reloader.before_class_unload do
|
@@ -194,32 +254,9 @@ end_warning
|
|
194
254
|
end
|
195
255
|
end
|
196
256
|
|
197
|
-
initializer "active_record.
|
198
|
-
|
199
|
-
|
200
|
-
represent_boolean_as_integer = Rails.application.config.active_record.sqlite3.delete(:represent_boolean_as_integer)
|
201
|
-
unless represent_boolean_as_integer.nil?
|
202
|
-
ActiveRecord::ConnectionAdapters::SQLite3Adapter.represent_boolean_as_integer = represent_boolean_as_integer
|
203
|
-
end
|
204
|
-
|
205
|
-
unless ActiveRecord::ConnectionAdapters::SQLite3Adapter.represent_boolean_as_integer
|
206
|
-
ActiveSupport::Deprecation.warn <<-MSG
|
207
|
-
Leaving `ActiveRecord::ConnectionAdapters::SQLite3Adapter.represent_boolean_as_integer`
|
208
|
-
set to false is deprecated. SQLite databases have used 't' and 'f' to serialize
|
209
|
-
boolean values and must have old data converted to 1 and 0 (its native boolean
|
210
|
-
serialization) before setting this flag to true. Conversion can be accomplished
|
211
|
-
by setting up a rake task which runs
|
212
|
-
|
213
|
-
ExampleModel.where("boolean_column = 't'").update_all(boolean_column: 1)
|
214
|
-
ExampleModel.where("boolean_column = 'f'").update_all(boolean_column: 0)
|
215
|
-
|
216
|
-
for all models and all boolean columns, after which the flag must be set to
|
217
|
-
true by adding the following to your application.rb file:
|
218
|
-
|
219
|
-
Rails.application.config.active_record.sqlite3.represent_boolean_as_integer = true
|
220
|
-
MSG
|
221
|
-
end
|
222
|
-
end
|
257
|
+
initializer "active_record.set_filter_attributes" do
|
258
|
+
ActiveSupport.on_load(:active_record) do
|
259
|
+
self.filter_attributes += Rails.application.config.filter_parameters
|
223
260
|
end
|
224
261
|
end
|
225
262
|
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ActiveRecord
|
4
|
+
module Railties # :nodoc:
|
5
|
+
module CollectionCacheAssociationLoading #:nodoc:
|
6
|
+
def setup(context, options, as, block)
|
7
|
+
@relation = relation_from_options(options)
|
8
|
+
|
9
|
+
super
|
10
|
+
end
|
11
|
+
|
12
|
+
def relation_from_options(cached: nil, partial: nil, collection: nil, **_)
|
13
|
+
return unless cached
|
14
|
+
|
15
|
+
relation = partial if partial.is_a?(ActiveRecord::Relation)
|
16
|
+
relation ||= collection if collection.is_a?(ActiveRecord::Relation)
|
17
|
+
|
18
|
+
if relation && !relation.loaded?
|
19
|
+
relation.skip_preloading!
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def collection_without_template(*)
|
24
|
+
@relation.preload_associations(@collection) if @relation
|
25
|
+
super
|
26
|
+
end
|
27
|
+
|
28
|
+
def collection_with_template(*)
|
29
|
+
@relation.preload_associations(@collection) if @relation
|
30
|
+
super
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -8,49 +8,44 @@ module ActiveRecord
|
|
8
8
|
module ControllerRuntime #:nodoc:
|
9
9
|
extend ActiveSupport::Concern
|
10
10
|
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
private
|
18
|
-
|
19
|
-
def process_action(action, *args)
|
20
|
-
# We also need to reset the runtime before each action
|
21
|
-
# because of queries in middleware or in cases we are streaming
|
22
|
-
# and it won't be cleaned up by the method below.
|
23
|
-
ActiveRecord::LogSubscriber.reset_runtime
|
24
|
-
super
|
11
|
+
module ClassMethods # :nodoc:
|
12
|
+
def log_process_action(payload)
|
13
|
+
messages, db_runtime = super, payload[:db_runtime]
|
14
|
+
messages << ("ActiveRecord: %.1fms" % db_runtime.to_f) if db_runtime
|
15
|
+
messages
|
16
|
+
end
|
25
17
|
end
|
26
18
|
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
runtime
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
else
|
19
|
+
private
|
20
|
+
attr_internal :db_runtime
|
21
|
+
|
22
|
+
def process_action(action, *args)
|
23
|
+
# We also need to reset the runtime before each action
|
24
|
+
# because of queries in middleware or in cases we are streaming
|
25
|
+
# and it won't be cleaned up by the method below.
|
26
|
+
ActiveRecord::LogSubscriber.reset_runtime
|
36
27
|
super
|
37
28
|
end
|
38
|
-
end
|
39
29
|
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
30
|
+
def cleanup_view_runtime
|
31
|
+
if logger && logger.info? && ActiveRecord::Base.connected?
|
32
|
+
db_rt_before_render = ActiveRecord::LogSubscriber.reset_runtime
|
33
|
+
self.db_runtime = (db_runtime || 0) + db_rt_before_render
|
34
|
+
runtime = super
|
35
|
+
db_rt_after_render = ActiveRecord::LogSubscriber.reset_runtime
|
36
|
+
self.db_runtime += db_rt_after_render
|
37
|
+
runtime - db_rt_after_render
|
38
|
+
else
|
39
|
+
super
|
40
|
+
end
|
44
41
|
end
|
45
|
-
end
|
46
42
|
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
43
|
+
def append_info_to_payload(payload)
|
44
|
+
super
|
45
|
+
if ActiveRecord::Base.connected?
|
46
|
+
payload[:db_runtime] = (db_runtime || 0) + ActiveRecord::LogSubscriber.reset_runtime
|
47
|
+
end
|
52
48
|
end
|
53
|
-
end
|
54
49
|
end
|
55
50
|
end
|
56
51
|
end
|
@@ -2,6 +2,8 @@
|
|
2
2
|
|
3
3
|
require "active_record"
|
4
4
|
|
5
|
+
databases = ActiveRecord::Tasks::DatabaseTasks.setup_initial_database_yaml
|
6
|
+
|
5
7
|
db_namespace = namespace :db do
|
6
8
|
desc "Set the environment value for the database"
|
7
9
|
task "environment:set" => :load_config do
|
@@ -22,6 +24,14 @@ db_namespace = namespace :db do
|
|
22
24
|
task all: :load_config do
|
23
25
|
ActiveRecord::Tasks::DatabaseTasks.create_all
|
24
26
|
end
|
27
|
+
|
28
|
+
ActiveRecord::Tasks::DatabaseTasks.for_each(databases) do |spec_name|
|
29
|
+
desc "Create #{spec_name} database for current environment"
|
30
|
+
task spec_name => :load_config do
|
31
|
+
db_config = ActiveRecord::Base.configurations.configs_for(env_name: Rails.env, spec_name: spec_name)
|
32
|
+
ActiveRecord::Tasks::DatabaseTasks.create(db_config.config)
|
33
|
+
end
|
34
|
+
end
|
25
35
|
end
|
26
36
|
|
27
37
|
desc "Creates the database from DATABASE_URL or config/database.yml for the current RAILS_ENV (use db:create:all to create all databases in the config). Without RAILS_ENV or when RAILS_ENV is development, it defaults to creating the development and test databases."
|
@@ -33,6 +43,14 @@ db_namespace = namespace :db do
|
|
33
43
|
task all: [:load_config, :check_protected_environments] do
|
34
44
|
ActiveRecord::Tasks::DatabaseTasks.drop_all
|
35
45
|
end
|
46
|
+
|
47
|
+
ActiveRecord::Tasks::DatabaseTasks.for_each(databases) do |spec_name|
|
48
|
+
desc "Drop #{spec_name} database for current environment"
|
49
|
+
task spec_name => [:load_config, :check_protected_environments] do
|
50
|
+
db_config = ActiveRecord::Base.configurations.configs_for(env_name: Rails.env, spec_name: spec_name)
|
51
|
+
ActiveRecord::Tasks::DatabaseTasks.drop(db_config.config)
|
52
|
+
end
|
53
|
+
end
|
36
54
|
end
|
37
55
|
|
38
56
|
desc "Drops the database from DATABASE_URL or config/database.yml for the current RAILS_ENV (use db:drop:all to drop all databases in the config). Without RAILS_ENV or when RAILS_ENV is development, it defaults to dropping the development and test databases."
|
@@ -50,6 +68,11 @@ db_namespace = namespace :db do
|
|
50
68
|
end
|
51
69
|
end
|
52
70
|
|
71
|
+
# desc "Truncates tables of each database for current environment"
|
72
|
+
task truncate_all: [:load_config, :check_protected_environments] do
|
73
|
+
ActiveRecord::Tasks::DatabaseTasks.truncate_all
|
74
|
+
end
|
75
|
+
|
53
76
|
# desc "Empty the database from DATABASE_URL or config/database.yml for the current RAILS_ENV (use db:purge:all to purge all databases in the config). Without RAILS_ENV it defaults to purging the development and test databases."
|
54
77
|
task purge: [:load_config, :check_protected_environments] do
|
55
78
|
ActiveRecord::Tasks::DatabaseTasks.purge_current
|
@@ -57,8 +80,14 @@ db_namespace = namespace :db do
|
|
57
80
|
|
58
81
|
desc "Migrate the database (options: VERSION=x, VERBOSE=false, SCOPE=blog)."
|
59
82
|
task migrate: :load_config do
|
60
|
-
ActiveRecord::
|
83
|
+
original_config = ActiveRecord::Base.connection_config
|
84
|
+
ActiveRecord::Base.configurations.configs_for(env_name: ActiveRecord::Tasks::DatabaseTasks.env).each do |db_config|
|
85
|
+
ActiveRecord::Base.establish_connection(db_config.config)
|
86
|
+
ActiveRecord::Tasks::DatabaseTasks.migrate
|
87
|
+
end
|
61
88
|
db_namespace["_dump"].invoke
|
89
|
+
ensure
|
90
|
+
ActiveRecord::Base.establish_connection(original_config)
|
62
91
|
end
|
63
92
|
|
64
93
|
# IMPORTANT: This task won't dump the schema if ActiveRecord::Base.dump_schema_after_migration is set to false
|
@@ -77,6 +106,15 @@ db_namespace = namespace :db do
|
|
77
106
|
end
|
78
107
|
|
79
108
|
namespace :migrate do
|
109
|
+
ActiveRecord::Tasks::DatabaseTasks.for_each(databases) do |spec_name|
|
110
|
+
desc "Migrate #{spec_name} database for current environment"
|
111
|
+
task spec_name => :load_config do
|
112
|
+
db_config = ActiveRecord::Base.configurations.configs_for(env_name: Rails.env, spec_name: spec_name)
|
113
|
+
ActiveRecord::Base.establish_connection(db_config.config)
|
114
|
+
ActiveRecord::Tasks::DatabaseTasks.migrate
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
80
118
|
# desc 'Rollbacks the database one migration and re migrate up (options: STEP=x, VERSION=x).'
|
81
119
|
task redo: :load_config do
|
82
120
|
raise "Empty VERSION provided" if ENV["VERSION"] && ENV["VERSION"].empty?
|
@@ -95,6 +133,8 @@ db_namespace = namespace :db do
|
|
95
133
|
|
96
134
|
# desc 'Runs the "up" for a given migration VERSION.'
|
97
135
|
task up: :load_config do
|
136
|
+
ActiveRecord::Tasks::DatabaseTasks.raise_for_multi_db(command: "db:migrate:up")
|
137
|
+
|
98
138
|
raise "VERSION is required" if !ENV["VERSION"] || ENV["VERSION"].empty?
|
99
139
|
|
100
140
|
ActiveRecord::Tasks::DatabaseTasks.check_target_version
|
@@ -106,8 +146,29 @@ db_namespace = namespace :db do
|
|
106
146
|
db_namespace["_dump"].invoke
|
107
147
|
end
|
108
148
|
|
149
|
+
namespace :up do
|
150
|
+
ActiveRecord::Tasks::DatabaseTasks.for_each(databases) do |spec_name|
|
151
|
+
task spec_name => :load_config do
|
152
|
+
raise "VERSION is required" if !ENV["VERSION"] || ENV["VERSION"].empty?
|
153
|
+
|
154
|
+
db_config = ActiveRecord::Base.configurations.configs_for(env_name: Rails.env, spec_name: spec_name)
|
155
|
+
|
156
|
+
ActiveRecord::Base.establish_connection(db_config.config)
|
157
|
+
ActiveRecord::Tasks::DatabaseTasks.check_target_version
|
158
|
+
ActiveRecord::Base.connection.migration_context.run(
|
159
|
+
:up,
|
160
|
+
ActiveRecord::Tasks::DatabaseTasks.target_version
|
161
|
+
)
|
162
|
+
|
163
|
+
db_namespace["_dump"].invoke
|
164
|
+
end
|
165
|
+
end
|
166
|
+
end
|
167
|
+
|
109
168
|
# desc 'Runs the "down" for a given migration VERSION.'
|
110
169
|
task down: :load_config do
|
170
|
+
ActiveRecord::Tasks::DatabaseTasks.raise_for_multi_db(command: "db:migrate:down")
|
171
|
+
|
111
172
|
raise "VERSION is required - To go down one migration, use db:rollback" if !ENV["VERSION"] || ENV["VERSION"].empty?
|
112
173
|
|
113
174
|
ActiveRecord::Tasks::DatabaseTasks.check_target_version
|
@@ -119,20 +180,42 @@ db_namespace = namespace :db do
|
|
119
180
|
db_namespace["_dump"].invoke
|
120
181
|
end
|
121
182
|
|
183
|
+
namespace :down do
|
184
|
+
ActiveRecord::Tasks::DatabaseTasks.for_each(databases) do |spec_name|
|
185
|
+
task spec_name => :load_config do
|
186
|
+
raise "VERSION is required" if !ENV["VERSION"] || ENV["VERSION"].empty?
|
187
|
+
|
188
|
+
db_config = ActiveRecord::Base.configurations.configs_for(env_name: Rails.env, spec_name: spec_name)
|
189
|
+
|
190
|
+
ActiveRecord::Base.establish_connection(db_config.config)
|
191
|
+
ActiveRecord::Tasks::DatabaseTasks.check_target_version
|
192
|
+
ActiveRecord::Base.connection.migration_context.run(
|
193
|
+
:down,
|
194
|
+
ActiveRecord::Tasks::DatabaseTasks.target_version
|
195
|
+
)
|
196
|
+
|
197
|
+
db_namespace["_dump"].invoke
|
198
|
+
end
|
199
|
+
end
|
200
|
+
end
|
201
|
+
|
122
202
|
desc "Display status of migrations"
|
123
203
|
task status: :load_config do
|
124
|
-
|
125
|
-
|
204
|
+
ActiveRecord::Base.configurations.configs_for(env_name: ActiveRecord::Tasks::DatabaseTasks.env).each do |db_config|
|
205
|
+
ActiveRecord::Base.establish_connection(db_config.config)
|
206
|
+
ActiveRecord::Tasks::DatabaseTasks.migrate_status
|
126
207
|
end
|
208
|
+
end
|
127
209
|
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
210
|
+
namespace :status do
|
211
|
+
ActiveRecord::Tasks::DatabaseTasks.for_each(databases) do |spec_name|
|
212
|
+
desc "Display status of migrations for #{spec_name} database"
|
213
|
+
task spec_name => :load_config do
|
214
|
+
db_config = ActiveRecord::Base.configurations.configs_for(env_name: Rails.env, spec_name: spec_name)
|
215
|
+
ActiveRecord::Base.establish_connection(db_config.config)
|
216
|
+
ActiveRecord::Tasks::DatabaseTasks.migrate_status
|
217
|
+
end
|
134
218
|
end
|
135
|
-
puts
|
136
219
|
end
|
137
220
|
end
|
138
221
|
|
@@ -160,11 +243,9 @@ db_namespace = namespace :db do
|
|
160
243
|
|
161
244
|
# desc "Retrieves the collation for the current environment's database"
|
162
245
|
task collation: :load_config do
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
$stderr.puts "Sorry, your database adapter is not supported yet. Feel free to submit a patch."
|
167
|
-
end
|
246
|
+
puts ActiveRecord::Tasks::DatabaseTasks.collation_current
|
247
|
+
rescue NoMethodError
|
248
|
+
$stderr.puts "Sorry, your database adapter is not supported yet. Feel free to submit a patch."
|
168
249
|
end
|
169
250
|
|
170
251
|
desc "Retrieves the current schema version number"
|
@@ -174,7 +255,11 @@ db_namespace = namespace :db do
|
|
174
255
|
|
175
256
|
# desc "Raises an error if there are pending migrations"
|
176
257
|
task abort_if_pending_migrations: :load_config do
|
177
|
-
pending_migrations = ActiveRecord::Base.
|
258
|
+
pending_migrations = ActiveRecord::Base.configurations.configs_for(env_name: ActiveRecord::Tasks::DatabaseTasks.env).flat_map do |db_config|
|
259
|
+
ActiveRecord::Base.establish_connection(db_config.config)
|
260
|
+
|
261
|
+
ActiveRecord::Base.connection.migration_context.open.pending_migrations
|
262
|
+
end
|
178
263
|
|
179
264
|
if pending_migrations.any?
|
180
265
|
puts "You have #{pending_migrations.size} pending #{pending_migrations.size > 1 ? 'migrations:' : 'migration:'}"
|
@@ -183,17 +268,74 @@ db_namespace = namespace :db do
|
|
183
268
|
end
|
184
269
|
abort %{Run `rails db:migrate` to update your database then try again.}
|
185
270
|
end
|
271
|
+
ensure
|
272
|
+
ActiveRecord::Base.establish_connection(ActiveRecord::Tasks::DatabaseTasks.env.to_sym)
|
273
|
+
end
|
274
|
+
|
275
|
+
namespace :abort_if_pending_migrations do
|
276
|
+
ActiveRecord::Tasks::DatabaseTasks.for_each(databases) do |spec_name|
|
277
|
+
# desc "Raises an error if there are pending migrations for #{spec_name} database"
|
278
|
+
task spec_name => :load_config do
|
279
|
+
db_config = ActiveRecord::Base.configurations.configs_for(env_name: Rails.env, spec_name: spec_name)
|
280
|
+
ActiveRecord::Base.establish_connection(db_config.config)
|
281
|
+
|
282
|
+
pending_migrations = ActiveRecord::Base.connection.migration_context.open.pending_migrations
|
283
|
+
|
284
|
+
if pending_migrations.any?
|
285
|
+
puts "You have #{pending_migrations.size} pending #{pending_migrations.size > 1 ? 'migrations:' : 'migration:'}"
|
286
|
+
pending_migrations.each do |pending_migration|
|
287
|
+
puts " %4d %s" % [pending_migration.version, pending_migration.name]
|
288
|
+
end
|
289
|
+
abort %{Run `rails db:migrate:#{spec_name}` to update your database then try again.}
|
290
|
+
end
|
291
|
+
end
|
292
|
+
end
|
186
293
|
end
|
187
294
|
|
188
295
|
desc "Creates the database, loads the schema, and initializes with the seed data (use db:reset to also drop the database first)"
|
189
296
|
task setup: ["db:schema:load_if_ruby", "db:structure:load_if_sql", :seed]
|
190
297
|
|
298
|
+
desc "Runs setup if database does not exist, or runs migrations if it does"
|
299
|
+
task prepare: :load_config do
|
300
|
+
seed = false
|
301
|
+
|
302
|
+
ActiveRecord::Base.configurations.configs_for(env_name: ActiveRecord::Tasks::DatabaseTasks.env).each do |db_config|
|
303
|
+
ActiveRecord::Base.establish_connection(db_config.config)
|
304
|
+
|
305
|
+
# Skipped when no database
|
306
|
+
ActiveRecord::Tasks::DatabaseTasks.migrate
|
307
|
+
if ActiveRecord::Base.dump_schema_after_migration
|
308
|
+
ActiveRecord::Tasks::DatabaseTasks.dump_schema(db_config.config, ActiveRecord::Base.schema_format, db_config.spec_name)
|
309
|
+
end
|
310
|
+
|
311
|
+
rescue ActiveRecord::NoDatabaseError
|
312
|
+
ActiveRecord::Tasks::DatabaseTasks.create_current(db_config.env_name, db_config.spec_name)
|
313
|
+
ActiveRecord::Tasks::DatabaseTasks.load_schema(
|
314
|
+
db_config.config,
|
315
|
+
ActiveRecord::Base.schema_format,
|
316
|
+
nil,
|
317
|
+
db_config.env_name,
|
318
|
+
db_config.spec_name
|
319
|
+
)
|
320
|
+
|
321
|
+
seed = true
|
322
|
+
end
|
323
|
+
|
324
|
+
ActiveRecord::Base.establish_connection
|
325
|
+
ActiveRecord::Tasks::DatabaseTasks.load_seed if seed
|
326
|
+
end
|
327
|
+
|
191
328
|
desc "Loads the seed data from db/seeds.rb"
|
192
|
-
task :
|
329
|
+
task seed: :load_config do
|
193
330
|
db_namespace["abort_if_pending_migrations"].invoke
|
194
331
|
ActiveRecord::Tasks::DatabaseTasks.load_seed
|
195
332
|
end
|
196
333
|
|
334
|
+
namespace :seed do
|
335
|
+
desc "Truncates tables of each database for current environment and loads the seeds"
|
336
|
+
task replant: [:load_config, :truncate_all, :seed]
|
337
|
+
end
|
338
|
+
|
197
339
|
namespace :fixtures do
|
198
340
|
desc "Loads fixtures into the current environment's database. Load specific fixtures using FIXTURES=x,y. Load from subdirectory in test/fixtures using FIXTURES_DIR=z. Specify an alternative path (eg. spec/fixtures) using FIXTURES_PATH=spec/fixtures."
|
199
341
|
task load: :load_config do
|
@@ -245,11 +387,11 @@ db_namespace = namespace :db do
|
|
245
387
|
namespace :schema do
|
246
388
|
desc "Creates a db/schema.rb file that is portable against any DB supported by Active Record"
|
247
389
|
task dump: :load_config do
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
ActiveRecord::SchemaDumper.dump(ActiveRecord::Base.connection, file)
|
390
|
+
ActiveRecord::Base.configurations.configs_for(env_name: ActiveRecord::Tasks::DatabaseTasks.env).each do |db_config|
|
391
|
+
ActiveRecord::Base.establish_connection(db_config.config)
|
392
|
+
ActiveRecord::Tasks::DatabaseTasks.dump_schema(db_config.config, :ruby, db_config.spec_name)
|
252
393
|
end
|
394
|
+
|
253
395
|
db_namespace["schema:dump"].reenable
|
254
396
|
end
|
255
397
|
|
@@ -265,33 +407,34 @@ db_namespace = namespace :db do
|
|
265
407
|
namespace :cache do
|
266
408
|
desc "Creates a db/schema_cache.yml file."
|
267
409
|
task dump: :load_config do
|
268
|
-
|
269
|
-
|
270
|
-
|
410
|
+
ActiveRecord::Base.configurations.configs_for(env_name: ActiveRecord::Tasks::DatabaseTasks.env).each do |db_config|
|
411
|
+
ActiveRecord::Base.establish_connection(db_config.config)
|
412
|
+
filename = ActiveRecord::Tasks::DatabaseTasks.cache_dump_filename(db_config.spec_name)
|
413
|
+
ActiveRecord::Tasks::DatabaseTasks.dump_schema_cache(
|
414
|
+
ActiveRecord::Base.connection,
|
415
|
+
filename,
|
416
|
+
)
|
417
|
+
end
|
271
418
|
end
|
272
419
|
|
273
420
|
desc "Clears a db/schema_cache.yml file."
|
274
421
|
task clear: :load_config do
|
275
|
-
|
276
|
-
|
422
|
+
ActiveRecord::Base.configurations.configs_for(env_name: ActiveRecord::Tasks::DatabaseTasks.env).each do |db_config|
|
423
|
+
filename = ActiveRecord::Tasks::DatabaseTasks.cache_dump_filename(db_config.spec_name)
|
424
|
+
rm_f filename, verbose: false
|
425
|
+
end
|
277
426
|
end
|
278
427
|
end
|
279
|
-
|
280
428
|
end
|
281
429
|
|
282
430
|
namespace :structure do
|
283
431
|
desc "Dumps the database structure to db/structure.sql. Specify another file with SCHEMA=db/my_structure.sql"
|
284
432
|
task dump: :load_config do
|
285
|
-
|
286
|
-
|
287
|
-
|
288
|
-
|
289
|
-
if ActiveRecord::SchemaMigration.table_exists?
|
290
|
-
File.open(filename, "a") do |f|
|
291
|
-
f.puts ActiveRecord::Base.connection.dump_schema_information
|
292
|
-
f.print "\n"
|
293
|
-
end
|
433
|
+
ActiveRecord::Base.configurations.configs_for(env_name: ActiveRecord::Tasks::DatabaseTasks.env).each do |db_config|
|
434
|
+
ActiveRecord::Base.establish_connection(db_config.config)
|
435
|
+
ActiveRecord::Tasks::DatabaseTasks.dump_schema(db_config.config, :sql, db_config.spec_name)
|
294
436
|
end
|
437
|
+
|
295
438
|
db_namespace["structure:dump"].reenable
|
296
439
|
end
|
297
440
|
|
@@ -318,25 +461,31 @@ db_namespace = namespace :db do
|
|
318
461
|
|
319
462
|
# desc "Recreate the test database from an existent schema.rb file"
|
320
463
|
task load_schema: %w(db:test:purge) do
|
321
|
-
|
322
|
-
|
323
|
-
|
324
|
-
ActiveRecord::Tasks::DatabaseTasks.
|
325
|
-
|
326
|
-
|
327
|
-
|
328
|
-
|
464
|
+
should_reconnect = ActiveRecord::Base.connection_pool.active_connection?
|
465
|
+
ActiveRecord::Schema.verbose = false
|
466
|
+
ActiveRecord::Base.configurations.configs_for(env_name: "test").each do |db_config|
|
467
|
+
filename = ActiveRecord::Tasks::DatabaseTasks.dump_filename(db_config.spec_name, :ruby)
|
468
|
+
ActiveRecord::Tasks::DatabaseTasks.load_schema(db_config.config, :ruby, filename, "test")
|
469
|
+
end
|
470
|
+
ensure
|
471
|
+
if should_reconnect
|
472
|
+
ActiveRecord::Base.establish_connection(ActiveRecord::Base.configurations.default_hash(ActiveRecord::Tasks::DatabaseTasks.env))
|
329
473
|
end
|
330
474
|
end
|
331
475
|
|
332
476
|
# desc "Recreate the test database from an existent structure.sql file"
|
333
477
|
task load_structure: %w(db:test:purge) do
|
334
|
-
ActiveRecord::
|
478
|
+
ActiveRecord::Base.configurations.configs_for(env_name: "test").each do |db_config|
|
479
|
+
filename = ActiveRecord::Tasks::DatabaseTasks.dump_filename(db_config.spec_name, :sql)
|
480
|
+
ActiveRecord::Tasks::DatabaseTasks.load_schema(db_config.config, :sql, filename, "test")
|
481
|
+
end
|
335
482
|
end
|
336
483
|
|
337
484
|
# desc "Empty the test database"
|
338
485
|
task purge: %w(load_config check_protected_environments) do
|
339
|
-
ActiveRecord::
|
486
|
+
ActiveRecord::Base.configurations.configs_for(env_name: "test").each do |db_config|
|
487
|
+
ActiveRecord::Tasks::DatabaseTasks.purge(db_config.config)
|
488
|
+
end
|
340
489
|
end
|
341
490
|
|
342
491
|
# desc 'Load the test schema'
|
@@ -360,6 +509,10 @@ namespace :railties do
|
|
360
509
|
if railtie.respond_to?(:paths) && (path = railtie.paths["db/migrate"].first)
|
361
510
|
railties[railtie.railtie_name] = path
|
362
511
|
end
|
512
|
+
|
513
|
+
unless ENV["MIGRATIONS_PATH"].blank?
|
514
|
+
railties[railtie.railtie_name] = railtie.root + ENV["MIGRATIONS_PATH"]
|
515
|
+
end
|
363
516
|
end
|
364
517
|
|
365
518
|
on_skip = Proc.new do |name, migration|
|