activerecord 5.0.7.2 → 6.1.1
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 +829 -2015
- data/MIT-LICENSE +3 -1
- data/README.rdoc +11 -9
- data/examples/performance.rb +31 -29
- data/examples/simple.rb +5 -3
- data/lib/active_record.rb +37 -29
- data/lib/active_record/aggregations.rb +249 -247
- data/lib/active_record/association_relation.rb +30 -18
- data/lib/active_record/associations.rb +1714 -1596
- data/lib/active_record/associations/alias_tracker.rb +36 -42
- data/lib/active_record/associations/association.rb +143 -68
- data/lib/active_record/associations/association_scope.rb +98 -94
- data/lib/active_record/associations/belongs_to_association.rb +76 -46
- data/lib/active_record/associations/belongs_to_polymorphic_association.rb +13 -12
- data/lib/active_record/associations/builder/association.rb +27 -28
- data/lib/active_record/associations/builder/belongs_to.rb +52 -60
- data/lib/active_record/associations/builder/collection_association.rb +12 -22
- data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +40 -62
- data/lib/active_record/associations/builder/has_many.rb +10 -2
- data/lib/active_record/associations/builder/has_one.rb +35 -2
- data/lib/active_record/associations/builder/singular_association.rb +5 -1
- data/lib/active_record/associations/collection_association.rb +104 -259
- data/lib/active_record/associations/collection_proxy.rb +169 -125
- data/lib/active_record/associations/foreign_association.rb +22 -0
- data/lib/active_record/associations/has_many_association.rb +46 -31
- data/lib/active_record/associations/has_many_through_association.rb +66 -46
- data/lib/active_record/associations/has_one_association.rb +71 -52
- data/lib/active_record/associations/has_one_through_association.rb +20 -11
- data/lib/active_record/associations/join_dependency.rb +169 -180
- data/lib/active_record/associations/join_dependency/join_association.rb +53 -79
- data/lib/active_record/associations/join_dependency/join_base.rb +10 -9
- data/lib/active_record/associations/join_dependency/join_part.rb +14 -14
- data/lib/active_record/associations/preloader.rb +97 -104
- data/lib/active_record/associations/preloader/association.rb +109 -97
- data/lib/active_record/associations/preloader/through_association.rb +77 -76
- data/lib/active_record/associations/singular_association.rb +12 -45
- data/lib/active_record/associations/through_association.rb +27 -15
- data/lib/active_record/attribute_assignment.rb +55 -60
- data/lib/active_record/attribute_methods.rb +111 -141
- data/lib/active_record/attribute_methods/before_type_cast.rb +17 -9
- data/lib/active_record/attribute_methods/dirty.rb +172 -112
- data/lib/active_record/attribute_methods/primary_key.rb +88 -91
- data/lib/active_record/attribute_methods/query.rb +6 -8
- data/lib/active_record/attribute_methods/read.rb +18 -50
- data/lib/active_record/attribute_methods/serialization.rb +38 -10
- data/lib/active_record/attribute_methods/time_zone_conversion.rb +38 -66
- data/lib/active_record/attribute_methods/write.rb +25 -32
- data/lib/active_record/attributes.rb +69 -31
- data/lib/active_record/autosave_association.rb +102 -66
- data/lib/active_record/base.rb +16 -25
- data/lib/active_record/callbacks.rb +202 -43
- data/lib/active_record/coders/json.rb +2 -0
- data/lib/active_record/coders/yaml_column.rb +11 -12
- data/lib/active_record/connection_adapters.rb +50 -0
- data/lib/active_record/connection_adapters/abstract/connection_pool.rb +661 -375
- data/lib/active_record/connection_adapters/abstract/database_limits.rb +14 -38
- data/lib/active_record/connection_adapters/abstract/database_statements.rb +269 -105
- data/lib/active_record/connection_adapters/abstract/query_cache.rb +54 -35
- data/lib/active_record/connection_adapters/abstract/quoting.rb +137 -93
- data/lib/active_record/connection_adapters/abstract/savepoints.rb +5 -3
- data/lib/active_record/connection_adapters/abstract/schema_creation.rb +155 -113
- data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +328 -162
- data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +68 -80
- data/lib/active_record/connection_adapters/abstract/schema_statements.rb +591 -259
- data/lib/active_record/connection_adapters/abstract/transaction.rb +229 -91
- data/lib/active_record/connection_adapters/abstract_adapter.rb +392 -244
- data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +457 -582
- data/lib/active_record/connection_adapters/column.rb +55 -13
- data/lib/active_record/connection_adapters/deduplicable.rb +29 -0
- data/lib/active_record/connection_adapters/legacy_pool_manager.rb +31 -0
- data/lib/active_record/connection_adapters/mysql/column.rb +8 -31
- data/lib/active_record/connection_adapters/mysql/database_statements.rb +135 -49
- data/lib/active_record/connection_adapters/mysql/explain_pretty_printer.rb +24 -23
- data/lib/active_record/connection_adapters/mysql/quoting.rb +50 -20
- data/lib/active_record/connection_adapters/mysql/schema_creation.rb +79 -49
- data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +66 -56
- data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +70 -36
- data/lib/active_record/connection_adapters/mysql/schema_statements.rb +268 -0
- data/lib/active_record/connection_adapters/mysql/type_metadata.rb +20 -12
- data/lib/active_record/connection_adapters/mysql2_adapter.rb +74 -37
- data/lib/active_record/connection_adapters/pool_config.rb +63 -0
- data/lib/active_record/connection_adapters/pool_manager.rb +43 -0
- data/lib/active_record/connection_adapters/postgresql/column.rb +39 -28
- data/lib/active_record/connection_adapters/postgresql/database_statements.rb +70 -101
- data/lib/active_record/connection_adapters/postgresql/explain_pretty_printer.rb +5 -3
- data/lib/active_record/connection_adapters/postgresql/oid.rb +26 -21
- data/lib/active_record/connection_adapters/postgresql/oid/array.rb +22 -11
- data/lib/active_record/connection_adapters/postgresql/oid/bit.rb +6 -5
- data/lib/active_record/connection_adapters/postgresql/oid/bit_varying.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/oid/bytea.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/oid/cidr.rb +6 -6
- data/lib/active_record/connection_adapters/postgresql/oid/date.rb +23 -0
- data/lib/active_record/connection_adapters/postgresql/oid/date_time.rb +14 -4
- data/lib/active_record/connection_adapters/postgresql/oid/decimal.rb +3 -1
- data/lib/active_record/connection_adapters/postgresql/oid/enum.rb +5 -4
- data/lib/active_record/connection_adapters/postgresql/oid/hstore.rb +19 -18
- data/lib/active_record/connection_adapters/postgresql/oid/inet.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/oid/interval.rb +49 -0
- data/lib/active_record/connection_adapters/postgresql/oid/jsonb.rb +3 -11
- data/lib/active_record/connection_adapters/postgresql/oid/legacy_point.rb +44 -0
- data/lib/active_record/connection_adapters/postgresql/oid/macaddr.rb +25 -0
- data/lib/active_record/connection_adapters/postgresql/oid/money.rb +7 -5
- data/lib/active_record/connection_adapters/postgresql/oid/{json.rb → oid.rb} +6 -1
- data/lib/active_record/connection_adapters/postgresql/oid/point.rb +30 -9
- data/lib/active_record/connection_adapters/postgresql/oid/range.rb +52 -30
- data/lib/active_record/connection_adapters/postgresql/oid/specialized_string.rb +4 -1
- data/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb +58 -54
- data/lib/active_record/connection_adapters/postgresql/oid/uuid.rb +18 -4
- data/lib/active_record/connection_adapters/postgresql/oid/vector.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/oid/xml.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/quoting.rb +98 -38
- data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +21 -27
- data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +80 -0
- data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +147 -105
- data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +34 -32
- data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +426 -324
- data/lib/active_record/connection_adapters/postgresql/type_metadata.rb +32 -23
- data/lib/active_record/connection_adapters/postgresql/utils.rb +9 -6
- data/lib/active_record/connection_adapters/postgresql_adapter.rb +418 -293
- data/lib/active_record/connection_adapters/schema_cache.rb +135 -18
- data/lib/active_record/connection_adapters/sql_type_metadata.rb +22 -7
- data/lib/active_record/connection_adapters/sqlite3/database_statements.rb +144 -0
- data/lib/active_record/connection_adapters/sqlite3/explain_pretty_printer.rb +3 -1
- data/lib/active_record/connection_adapters/sqlite3/quoting.rb +72 -18
- data/lib/active_record/connection_adapters/sqlite3/schema_creation.rb +5 -6
- data/lib/active_record/connection_adapters/sqlite3/schema_definitions.rb +19 -0
- data/lib/active_record/connection_adapters/sqlite3/schema_dumper.rb +18 -0
- data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +170 -0
- data/lib/active_record/connection_adapters/sqlite3_adapter.rb +282 -290
- data/lib/active_record/connection_adapters/statement_pool.rb +9 -8
- data/lib/active_record/connection_handling.rb +287 -45
- data/lib/active_record/core.rb +385 -181
- data/lib/active_record/counter_cache.rb +60 -28
- data/lib/active_record/database_configurations.rb +272 -0
- data/lib/active_record/database_configurations/connection_url_resolver.rb +98 -0
- data/lib/active_record/database_configurations/database_config.rb +80 -0
- data/lib/active_record/database_configurations/hash_config.rb +96 -0
- data/lib/active_record/database_configurations/url_config.rb +53 -0
- data/lib/active_record/delegated_type.rb +209 -0
- data/lib/active_record/destroy_association_async_job.rb +36 -0
- data/lib/active_record/dynamic_matchers.rb +87 -87
- data/lib/active_record/enum.rb +122 -47
- data/lib/active_record/errors.rb +153 -22
- data/lib/active_record/explain.rb +13 -8
- data/lib/active_record/explain_registry.rb +3 -1
- data/lib/active_record/explain_subscriber.rb +9 -4
- data/lib/active_record/fixture_set/file.rb +20 -22
- data/lib/active_record/fixture_set/model_metadata.rb +32 -0
- data/lib/active_record/fixture_set/render_context.rb +17 -0
- data/lib/active_record/fixture_set/table_row.rb +152 -0
- data/lib/active_record/fixture_set/table_rows.rb +46 -0
- data/lib/active_record/fixtures.rb +246 -507
- data/lib/active_record/gem_version.rb +6 -4
- data/lib/active_record/inheritance.rb +168 -95
- data/lib/active_record/insert_all.rb +208 -0
- data/lib/active_record/integration.rb +114 -25
- data/lib/active_record/internal_metadata.rb +30 -24
- data/lib/active_record/legacy_yaml_adapter.rb +11 -5
- data/lib/active_record/locking/optimistic.rb +81 -85
- data/lib/active_record/locking/pessimistic.rb +22 -6
- data/lib/active_record/log_subscriber.rb +68 -31
- data/lib/active_record/middleware/database_selector.rb +77 -0
- data/lib/active_record/middleware/database_selector/resolver.rb +92 -0
- data/lib/active_record/middleware/database_selector/resolver/session.rb +48 -0
- data/lib/active_record/migration.rb +439 -342
- data/lib/active_record/migration/command_recorder.rb +152 -98
- data/lib/active_record/migration/compatibility.rb +229 -60
- data/lib/active_record/migration/join_table.rb +8 -7
- data/lib/active_record/model_schema.rb +230 -122
- data/lib/active_record/nested_attributes.rb +213 -203
- data/lib/active_record/no_touching.rb +11 -2
- data/lib/active_record/null_relation.rb +12 -34
- data/lib/active_record/persistence.rb +471 -97
- data/lib/active_record/query_cache.rb +23 -12
- data/lib/active_record/querying.rb +43 -25
- data/lib/active_record/railtie.rb +155 -43
- data/lib/active_record/railties/console_sandbox.rb +2 -0
- data/lib/active_record/railties/controller_runtime.rb +34 -33
- data/lib/active_record/railties/databases.rake +507 -195
- data/lib/active_record/readonly_attributes.rb +9 -4
- data/lib/active_record/reflection.rb +245 -269
- data/lib/active_record/relation.rb +475 -324
- data/lib/active_record/relation/batches.rb +125 -72
- data/lib/active_record/relation/batches/batch_enumerator.rb +28 -10
- data/lib/active_record/relation/calculations.rb +267 -171
- data/lib/active_record/relation/delegation.rb +73 -69
- data/lib/active_record/relation/finder_methods.rb +238 -248
- data/lib/active_record/relation/from_clause.rb +7 -9
- data/lib/active_record/relation/merger.rb +95 -77
- data/lib/active_record/relation/predicate_builder.rb +109 -110
- data/lib/active_record/relation/predicate_builder/array_handler.rb +22 -17
- data/lib/active_record/relation/predicate_builder/association_query_value.rb +42 -0
- data/lib/active_record/relation/predicate_builder/basic_object_handler.rb +6 -4
- data/lib/active_record/relation/predicate_builder/polymorphic_array_value.rb +55 -0
- data/lib/active_record/relation/predicate_builder/range_handler.rb +7 -18
- data/lib/active_record/relation/predicate_builder/relation_handler.rb +7 -1
- data/lib/active_record/relation/query_attribute.rb +33 -2
- data/lib/active_record/relation/query_methods.rb +654 -374
- data/lib/active_record/relation/record_fetch_warning.rb +8 -6
- data/lib/active_record/relation/spawn_methods.rb +15 -14
- data/lib/active_record/relation/where_clause.rb +171 -109
- data/lib/active_record/result.rb +88 -51
- data/lib/active_record/runtime_registry.rb +5 -3
- data/lib/active_record/sanitization.rb +73 -100
- data/lib/active_record/schema.rb +7 -14
- data/lib/active_record/schema_dumper.rb +101 -69
- data/lib/active_record/schema_migration.rb +16 -12
- data/lib/active_record/scoping.rb +20 -20
- data/lib/active_record/scoping/default.rb +92 -95
- data/lib/active_record/scoping/named.rb +39 -30
- data/lib/active_record/secure_token.rb +19 -9
- data/lib/active_record/serialization.rb +7 -3
- data/lib/active_record/signed_id.rb +116 -0
- data/lib/active_record/statement_cache.rb +80 -29
- data/lib/active_record/store.rb +122 -42
- data/lib/active_record/suppressor.rb +6 -3
- data/lib/active_record/table_metadata.rb +51 -39
- data/lib/active_record/tasks/database_tasks.rb +332 -115
- data/lib/active_record/tasks/mysql_database_tasks.rb +66 -104
- data/lib/active_record/tasks/postgresql_database_tasks.rb +84 -56
- data/lib/active_record/tasks/sqlite_database_tasks.rb +40 -19
- data/lib/active_record/test_databases.rb +24 -0
- data/lib/active_record/test_fixtures.rb +246 -0
- data/lib/active_record/timestamp.rb +70 -38
- data/lib/active_record/touch_later.rb +26 -24
- data/lib/active_record/transactions.rb +121 -184
- data/lib/active_record/translation.rb +3 -1
- data/lib/active_record/type.rb +29 -17
- data/lib/active_record/type/adapter_specific_registry.rb +44 -48
- data/lib/active_record/type/date.rb +2 -0
- data/lib/active_record/type/date_time.rb +2 -0
- data/lib/active_record/type/decimal_without_scale.rb +15 -0
- data/lib/active_record/type/hash_lookup_type_map.rb +5 -4
- data/lib/active_record/type/internal/timezone.rb +2 -0
- data/lib/active_record/type/json.rb +30 -0
- data/lib/active_record/type/serialized.rb +20 -9
- data/lib/active_record/type/text.rb +11 -0
- data/lib/active_record/type/time.rb +12 -1
- data/lib/active_record/type/type_map.rb +14 -17
- data/lib/active_record/type/unsigned_integer.rb +16 -0
- data/lib/active_record/type_caster.rb +4 -2
- data/lib/active_record/type_caster/connection.rb +17 -13
- data/lib/active_record/type_caster/map.rb +10 -6
- data/lib/active_record/validations.rb +8 -5
- data/lib/active_record/validations/absence.rb +2 -0
- data/lib/active_record/validations/associated.rb +4 -3
- data/lib/active_record/validations/length.rb +2 -0
- data/lib/active_record/validations/numericality.rb +35 -0
- data/lib/active_record/validations/presence.rb +4 -2
- data/lib/active_record/validations/uniqueness.rb +52 -45
- data/lib/active_record/version.rb +3 -1
- data/lib/arel.rb +54 -0
- data/lib/arel/alias_predication.rb +9 -0
- data/lib/arel/attributes/attribute.rb +41 -0
- data/lib/arel/collectors/bind.rb +29 -0
- data/lib/arel/collectors/composite.rb +39 -0
- data/lib/arel/collectors/plain_string.rb +20 -0
- data/lib/arel/collectors/sql_string.rb +27 -0
- data/lib/arel/collectors/substitute_binds.rb +35 -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 +70 -0
- data/lib/arel/nodes/and.rb +32 -0
- data/lib/arel/nodes/ascending.rb +23 -0
- data/lib/arel/nodes/binary.rb +126 -0
- data/lib/arel/nodes/bind_param.rb +44 -0
- data/lib/arel/nodes/case.rb +55 -0
- data/lib/arel/nodes/casted.rb +62 -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 +15 -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 +11 -0
- data/lib/arel/nodes/homogeneous_in.rb +72 -0
- data/lib/arel/nodes/in.rb +15 -0
- data/lib/arel/nodes/infix_operation.rb +92 -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 +51 -0
- data/lib/arel/nodes/node_expression.rb +13 -0
- data/lib/arel/nodes/ordering.rb +27 -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 +19 -0
- data/lib/arel/nodes/string_join.rb +11 -0
- data/lib/arel/nodes/table_alias.rb +31 -0
- data/lib/arel/nodes/terminal.rb +16 -0
- data/lib/arel/nodes/true.rb +16 -0
- data/lib/arel/nodes/unary.rb +44 -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 +250 -0
- data/lib/arel/select_manager.rb +270 -0
- data/lib/arel/table.rb +118 -0
- data/lib/arel/tree_manager.rb +72 -0
- data/lib/arel/update_manager.rb +34 -0
- data/lib/arel/visitors.rb +13 -0
- data/lib/arel/visitors/dot.rb +308 -0
- data/lib/arel/visitors/mysql.rb +93 -0
- data/lib/arel/visitors/postgresql.rb +120 -0
- data/lib/arel/visitors/sqlite.rb +38 -0
- data/lib/arel/visitors/to_sql.rb +899 -0
- data/lib/arel/visitors/visitor.rb +45 -0
- data/lib/arel/window_predications.rb +9 -0
- data/lib/rails/generators/active_record.rb +7 -5
- data/lib/rails/generators/active_record/application_record/application_record_generator.rb +26 -0
- data/lib/rails/generators/active_record/{model/templates/application_record.rb → application_record/templates/application_record.rb.tt} +0 -0
- data/lib/rails/generators/active_record/migration.rb +22 -3
- data/lib/rails/generators/active_record/migration/migration_generator.rb +38 -35
- data/lib/rails/generators/active_record/migration/templates/{create_table_migration.rb → create_table_migration.rb.tt} +3 -1
- data/lib/rails/generators/active_record/migration/templates/{migration.rb → migration.rb.tt} +7 -5
- data/lib/rails/generators/active_record/model/model_generator.rb +41 -25
- data/lib/rails/generators/active_record/model/templates/abstract_base_class.rb.tt +7 -0
- data/lib/rails/generators/active_record/model/templates/{model.rb → model.rb.tt} +10 -1
- data/lib/rails/generators/active_record/model/templates/{module.rb → module.rb.tt} +0 -0
- metadata +141 -57
- data/lib/active_record/associations/preloader/belongs_to.rb +0 -17
- data/lib/active_record/associations/preloader/collection_association.rb +0 -17
- data/lib/active_record/associations/preloader/has_many.rb +0 -17
- data/lib/active_record/associations/preloader/has_many_through.rb +0 -19
- data/lib/active_record/associations/preloader/has_one.rb +0 -15
- data/lib/active_record/associations/preloader/has_one_through.rb +0 -9
- data/lib/active_record/associations/preloader/singular_association.rb +0 -20
- data/lib/active_record/attribute.rb +0 -213
- data/lib/active_record/attribute/user_provided_default.rb +0 -28
- data/lib/active_record/attribute_decorators.rb +0 -67
- data/lib/active_record/attribute_mutation_tracker.rb +0 -70
- data/lib/active_record/attribute_set.rb +0 -110
- data/lib/active_record/attribute_set/builder.rb +0 -132
- data/lib/active_record/collection_cache_key.rb +0 -50
- data/lib/active_record/connection_adapters/connection_specification.rb +0 -263
- data/lib/active_record/connection_adapters/determine_if_preparable_visitor.rb +0 -22
- data/lib/active_record/connection_adapters/postgresql/oid/rails_5_1_point.rb +0 -50
- data/lib/active_record/railties/jdbcmysql_error.rb +0 -16
- data/lib/active_record/relation/predicate_builder/association_query_handler.rb +0 -88
- data/lib/active_record/relation/predicate_builder/base_handler.rb +0 -17
- data/lib/active_record/relation/predicate_builder/class_handler.rb +0 -27
- data/lib/active_record/relation/predicate_builder/polymorphic_array_handler.rb +0 -57
- data/lib/active_record/relation/where_clause_factory.rb +0 -38
- data/lib/active_record/type/internal/abstract_json.rb +0 -33
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module ActiveRecord
|
2
4
|
# ActiveRecord::Suppressor prevents the receiver from being saved during
|
3
5
|
# a given block.
|
@@ -30,18 +32,19 @@ module ActiveRecord
|
|
30
32
|
|
31
33
|
module ClassMethods
|
32
34
|
def suppress(&block)
|
35
|
+
previous_state = SuppressorRegistry.suppressed[name]
|
33
36
|
SuppressorRegistry.suppressed[name] = true
|
34
37
|
yield
|
35
38
|
ensure
|
36
|
-
SuppressorRegistry.suppressed[name] =
|
39
|
+
SuppressorRegistry.suppressed[name] = previous_state
|
37
40
|
end
|
38
41
|
end
|
39
42
|
|
40
|
-
def save(
|
43
|
+
def save(**) # :nodoc:
|
41
44
|
SuppressorRegistry.suppressed[self.class.name] ? true : super
|
42
45
|
end
|
43
46
|
|
44
|
-
def save!(
|
47
|
+
def save!(**) # :nodoc:
|
45
48
|
SuppressorRegistry.suppressed[self.class.name] ? true : super
|
46
49
|
end
|
47
50
|
end
|
@@ -1,69 +1,81 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module ActiveRecord
|
2
4
|
class TableMetadata # :nodoc:
|
3
|
-
delegate :
|
4
|
-
delegate :association_primary_key, to: :association
|
5
|
+
delegate :join_primary_key, :join_foreign_key, :join_foreign_type, to: :reflection
|
5
6
|
|
6
|
-
def initialize(klass, arel_table,
|
7
|
+
def initialize(klass, arel_table, reflection = nil)
|
7
8
|
@klass = klass
|
8
9
|
@arel_table = arel_table
|
9
|
-
@
|
10
|
+
@reflection = reflection
|
10
11
|
end
|
11
12
|
|
12
|
-
def
|
13
|
-
|
14
|
-
# https://bugs.ruby-lang.org/issues/7166
|
15
|
-
new_hash = Hash[hash]
|
16
|
-
hash.each do |key, _|
|
17
|
-
if (key.is_a?(Symbol)) && klass.attribute_alias?(key)
|
18
|
-
new_hash[klass.attribute_alias(key)] = new_hash.delete(key)
|
19
|
-
end
|
20
|
-
end
|
21
|
-
new_hash
|
13
|
+
def primary_key
|
14
|
+
klass&.primary_key
|
22
15
|
end
|
23
16
|
|
24
|
-
def
|
25
|
-
|
26
|
-
klass.arel_attribute(column_name, arel_table)
|
27
|
-
else
|
28
|
-
arel_table[column_name]
|
29
|
-
end
|
17
|
+
def type(column_name)
|
18
|
+
arel_table.type_for_attribute(column_name)
|
30
19
|
end
|
31
20
|
|
32
|
-
def
|
33
|
-
|
34
|
-
klass.type_for_attribute(column_name.to_s)
|
35
|
-
else
|
36
|
-
Type::Value.new
|
37
|
-
end
|
21
|
+
def has_column?(column_name)
|
22
|
+
klass&.columns_hash.key?(column_name)
|
38
23
|
end
|
39
24
|
|
40
|
-
def associated_with?(
|
41
|
-
klass
|
25
|
+
def associated_with?(table_name)
|
26
|
+
klass&._reflect_on_association(table_name) || klass&._reflect_on_association(table_name.singularize)
|
42
27
|
end
|
43
28
|
|
44
29
|
def associated_table(table_name)
|
45
|
-
|
30
|
+
reflection = klass._reflect_on_association(table_name) || klass._reflect_on_association(table_name.singularize)
|
46
31
|
|
47
|
-
if !
|
32
|
+
if !reflection && table_name == arel_table.name
|
48
33
|
return self
|
49
|
-
|
50
|
-
|
51
|
-
|
34
|
+
end
|
35
|
+
|
36
|
+
if reflection
|
37
|
+
association_klass = reflection.klass unless reflection.polymorphic?
|
38
|
+
elsif block_given?
|
39
|
+
association_klass = yield table_name
|
40
|
+
end
|
41
|
+
|
42
|
+
if association_klass
|
43
|
+
arel_table = association_klass.arel_table
|
44
|
+
arel_table = arel_table.alias(table_name) if arel_table.name != table_name
|
45
|
+
TableMetadata.new(association_klass, arel_table, reflection)
|
52
46
|
else
|
53
47
|
type_caster = TypeCaster::Connection.new(klass, table_name)
|
54
|
-
association_klass = nil
|
55
48
|
arel_table = Arel::Table.new(table_name, type_caster: type_caster)
|
49
|
+
TableMetadata.new(nil, arel_table, reflection)
|
56
50
|
end
|
57
|
-
|
58
|
-
TableMetadata.new(association_klass, arel_table, association)
|
59
51
|
end
|
60
52
|
|
61
53
|
def polymorphic_association?
|
62
|
-
|
54
|
+
reflection&.polymorphic?
|
55
|
+
end
|
56
|
+
|
57
|
+
def through_association?
|
58
|
+
reflection&.through_reflection?
|
59
|
+
end
|
60
|
+
|
61
|
+
def reflect_on_aggregation(aggregation_name)
|
62
|
+
klass&.reflect_on_aggregation(aggregation_name)
|
63
|
+
end
|
64
|
+
alias :aggregated_with? :reflect_on_aggregation
|
65
|
+
|
66
|
+
def predicate_builder
|
67
|
+
if klass
|
68
|
+
predicate_builder = klass.predicate_builder.dup
|
69
|
+
predicate_builder.instance_variable_set(:@table, self)
|
70
|
+
predicate_builder
|
71
|
+
else
|
72
|
+
PredicateBuilder.new(self)
|
73
|
+
end
|
63
74
|
end
|
64
75
|
|
65
|
-
|
76
|
+
attr_reader :arel_table
|
66
77
|
|
67
|
-
|
78
|
+
private
|
79
|
+
attr_reader :klass, :reflection
|
68
80
|
end
|
69
81
|
end
|
@@ -1,14 +1,15 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "active_record/database_configurations"
|
2
4
|
|
3
5
|
module ActiveRecord
|
4
6
|
module Tasks # :nodoc:
|
5
|
-
class DatabaseAlreadyExists < StandardError; end # :nodoc:
|
6
7
|
class DatabaseNotSupported < StandardError; end # :nodoc:
|
7
8
|
|
8
9
|
# ActiveRecord::Tasks::DatabaseTasks is a utility class, which encapsulates
|
9
10
|
# logic behind common tasks used to manage database and migrations.
|
10
11
|
#
|
11
|
-
# The tasks defined here are used with
|
12
|
+
# The tasks defined here are used with Rails commands provided by Active Record.
|
12
13
|
#
|
13
14
|
# In order to use DatabaseTasks, a few config values need to be set. All the needed
|
14
15
|
# config values are set by Rails already, so it's necessary to do it only if you
|
@@ -35,19 +36,30 @@ module ActiveRecord
|
|
35
36
|
#
|
36
37
|
# DatabaseTasks.create_current('production')
|
37
38
|
module DatabaseTasks
|
39
|
+
##
|
40
|
+
# :singleton-method:
|
41
|
+
# Extra flags passed to database CLI tool (mysqldump/pg_dump) when calling db:schema:dump
|
42
|
+
mattr_accessor :structure_dump_flags, instance_accessor: false
|
43
|
+
|
44
|
+
##
|
45
|
+
# :singleton-method:
|
46
|
+
# Extra flags passed to database CLI tool when calling db:schema:load
|
47
|
+
mattr_accessor :structure_load_flags, instance_accessor: false
|
48
|
+
|
38
49
|
extend self
|
39
50
|
|
40
51
|
attr_writer :current_config, :db_dir, :migrations_paths, :fixtures_path, :root, :env, :seed_loader
|
52
|
+
deprecate :current_config=
|
41
53
|
attr_accessor :database_configuration
|
42
54
|
|
43
|
-
LOCAL_HOSTS
|
55
|
+
LOCAL_HOSTS = ["127.0.0.1", "localhost"]
|
44
56
|
|
45
57
|
def check_protected_environments!
|
46
|
-
unless ENV[
|
47
|
-
current = ActiveRecord::
|
48
|
-
stored = ActiveRecord::
|
58
|
+
unless ENV["DISABLE_DATABASE_ENVIRONMENT_CHECK"]
|
59
|
+
current = ActiveRecord::Base.connection.migration_context.current_environment
|
60
|
+
stored = ActiveRecord::Base.connection.migration_context.last_stored_environment
|
49
61
|
|
50
|
-
if ActiveRecord::
|
62
|
+
if ActiveRecord::Base.connection.migration_context.protected_environment?
|
51
63
|
raise ActiveRecord::ProtectedEnvironmentError.new(stored)
|
52
64
|
end
|
53
65
|
|
@@ -63,24 +75,24 @@ module ActiveRecord
|
|
63
75
|
@tasks[pattern] = task
|
64
76
|
end
|
65
77
|
|
66
|
-
register_task(/mysql/, ActiveRecord::Tasks::MySQLDatabaseTasks)
|
67
|
-
register_task(/postgresql/, ActiveRecord::Tasks::PostgreSQLDatabaseTasks)
|
68
|
-
register_task(/sqlite/, ActiveRecord::Tasks::SQLiteDatabaseTasks)
|
78
|
+
register_task(/mysql/, "ActiveRecord::Tasks::MySQLDatabaseTasks")
|
79
|
+
register_task(/postgresql/, "ActiveRecord::Tasks::PostgreSQLDatabaseTasks")
|
80
|
+
register_task(/sqlite/, "ActiveRecord::Tasks::SQLiteDatabaseTasks")
|
69
81
|
|
70
82
|
def db_dir
|
71
83
|
@db_dir ||= Rails.application.config.paths["db"].first
|
72
84
|
end
|
73
85
|
|
74
86
|
def migrations_paths
|
75
|
-
@migrations_paths ||= Rails.application.paths[
|
87
|
+
@migrations_paths ||= Rails.application.paths["db/migrate"].to_a
|
76
88
|
end
|
77
89
|
|
78
90
|
def fixtures_path
|
79
|
-
@fixtures_path ||= if ENV[
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
91
|
+
@fixtures_path ||= if ENV["FIXTURES_PATH"]
|
92
|
+
File.join(root, ENV["FIXTURES_PATH"])
|
93
|
+
else
|
94
|
+
File.join(root, "test", "fixtures")
|
95
|
+
end
|
84
96
|
end
|
85
97
|
|
86
98
|
def root
|
@@ -91,175 +103,343 @@ module ActiveRecord
|
|
91
103
|
@env ||= Rails.env
|
92
104
|
end
|
93
105
|
|
106
|
+
def spec
|
107
|
+
@spec ||= "primary"
|
108
|
+
end
|
109
|
+
deprecate spec: "please use name instead"
|
110
|
+
|
111
|
+
def name
|
112
|
+
@name ||= "primary"
|
113
|
+
end
|
114
|
+
|
94
115
|
def seed_loader
|
95
116
|
@seed_loader ||= Rails.application
|
96
117
|
end
|
97
118
|
|
98
119
|
def current_config(options = {})
|
99
|
-
options.reverse_merge! :env => env
|
100
120
|
if options.has_key?(:config)
|
101
121
|
@current_config = options[:config]
|
102
122
|
else
|
103
|
-
|
123
|
+
env_name = options[:env] || env
|
124
|
+
name = options[:spec] || "primary"
|
125
|
+
|
126
|
+
@current_config ||= ActiveRecord::Base.configurations.configs_for(env_name: env_name, name: name)&.configuration_hash
|
104
127
|
end
|
105
128
|
end
|
129
|
+
deprecate :current_config
|
106
130
|
|
107
|
-
def create(*arguments)
|
108
|
-
|
109
|
-
|
110
|
-
$stdout.puts "Created database '#{
|
131
|
+
def create(configuration, *arguments)
|
132
|
+
db_config = resolve_configuration(configuration)
|
133
|
+
database_adapter_for(db_config, *arguments).create
|
134
|
+
$stdout.puts "Created database '#{db_config.database}'" if verbose?
|
111
135
|
rescue DatabaseAlreadyExists
|
112
|
-
$stderr.puts "Database '#{
|
136
|
+
$stderr.puts "Database '#{db_config.database}' already exists" if verbose?
|
113
137
|
rescue Exception => error
|
114
138
|
$stderr.puts error
|
115
|
-
$stderr.puts "Couldn't create database
|
139
|
+
$stderr.puts "Couldn't create '#{db_config.database}' database. Please check your configuration."
|
116
140
|
raise
|
117
141
|
end
|
118
142
|
|
119
143
|
def create_all
|
120
144
|
old_pool = ActiveRecord::Base.connection_handler.retrieve_connection_pool(ActiveRecord::Base.connection_specification_name)
|
121
|
-
each_local_configuration { |
|
145
|
+
each_local_configuration { |db_config| create(db_config) }
|
122
146
|
if old_pool
|
123
|
-
ActiveRecord::Base.connection_handler.establish_connection(old_pool.
|
147
|
+
ActiveRecord::Base.connection_handler.establish_connection(old_pool.db_config)
|
148
|
+
end
|
149
|
+
end
|
150
|
+
|
151
|
+
def setup_initial_database_yaml
|
152
|
+
return {} unless defined?(Rails)
|
153
|
+
|
154
|
+
begin
|
155
|
+
Rails.application.config.load_database_yaml
|
156
|
+
rescue
|
157
|
+
unless ActiveRecord::Base.suppress_multiple_database_warning
|
158
|
+
$stderr.puts "Rails couldn't infer whether you are using multiple databases from your database.yml and can't generate the tasks for the non-primary databases. If you'd like to use this feature, please simplify your ERB."
|
159
|
+
end
|
160
|
+
|
161
|
+
{}
|
162
|
+
end
|
163
|
+
end
|
164
|
+
|
165
|
+
def for_each(databases)
|
166
|
+
return {} unless defined?(Rails)
|
167
|
+
|
168
|
+
database_configs = ActiveRecord::DatabaseConfigurations.new(databases).configs_for(env_name: Rails.env)
|
169
|
+
|
170
|
+
# if this is a single database application we don't want tasks for each primary database
|
171
|
+
return if database_configs.count == 1
|
172
|
+
|
173
|
+
database_configs.each do |db_config|
|
174
|
+
yield db_config.name
|
175
|
+
end
|
176
|
+
end
|
177
|
+
|
178
|
+
def raise_for_multi_db(environment = env, command:)
|
179
|
+
db_configs = ActiveRecord::Base.configurations.configs_for(env_name: environment)
|
180
|
+
|
181
|
+
if db_configs.count > 1
|
182
|
+
dbs_list = []
|
183
|
+
|
184
|
+
db_configs.each do |db|
|
185
|
+
dbs_list << "#{command}:#{db.name}"
|
186
|
+
end
|
187
|
+
|
188
|
+
raise "You're using a multiple database application. To use `#{command}` you must run the namespaced task with a VERSION. Available tasks are #{dbs_list.to_sentence}."
|
124
189
|
end
|
125
190
|
end
|
126
191
|
|
127
|
-
def create_current(environment = env)
|
128
|
-
each_current_configuration(environment) { |
|
129
|
-
create configuration
|
130
|
-
}
|
192
|
+
def create_current(environment = env, name = nil)
|
193
|
+
each_current_configuration(environment, name) { |db_config| create(db_config) }
|
131
194
|
ActiveRecord::Base.establish_connection(environment.to_sym)
|
132
195
|
end
|
133
196
|
|
134
|
-
def drop(*arguments)
|
135
|
-
|
136
|
-
|
137
|
-
$stdout.puts "Dropped database '#{
|
197
|
+
def drop(configuration, *arguments)
|
198
|
+
db_config = resolve_configuration(configuration)
|
199
|
+
database_adapter_for(db_config, *arguments).drop
|
200
|
+
$stdout.puts "Dropped database '#{db_config.database}'" if verbose?
|
138
201
|
rescue ActiveRecord::NoDatabaseError
|
139
|
-
$stderr.puts "Database '#{
|
202
|
+
$stderr.puts "Database '#{db_config.database}' does not exist"
|
140
203
|
rescue Exception => error
|
141
204
|
$stderr.puts error
|
142
|
-
$stderr.puts "Couldn't drop database '#{
|
205
|
+
$stderr.puts "Couldn't drop database '#{db_config.database}'"
|
143
206
|
raise
|
144
207
|
end
|
145
208
|
|
146
209
|
def drop_all
|
147
|
-
each_local_configuration { |
|
210
|
+
each_local_configuration { |db_config| drop(db_config) }
|
148
211
|
end
|
149
212
|
|
150
213
|
def drop_current(environment = env)
|
151
|
-
each_current_configuration(environment) { |
|
152
|
-
|
153
|
-
|
214
|
+
each_current_configuration(environment) { |db_config| drop(db_config) }
|
215
|
+
end
|
216
|
+
|
217
|
+
def truncate_tables(db_config)
|
218
|
+
ActiveRecord::Base.establish_connection(db_config)
|
219
|
+
|
220
|
+
connection = ActiveRecord::Base.connection
|
221
|
+
connection.truncate_tables(*connection.tables)
|
222
|
+
end
|
223
|
+
private :truncate_tables
|
224
|
+
|
225
|
+
def truncate_all(environment = env)
|
226
|
+
ActiveRecord::Base.configurations.configs_for(env_name: environment).each do |db_config|
|
227
|
+
truncate_tables(db_config)
|
228
|
+
end
|
154
229
|
end
|
155
230
|
|
156
231
|
def migrate
|
157
|
-
|
232
|
+
check_target_version
|
233
|
+
|
234
|
+
scope = ENV["SCOPE"]
|
235
|
+
verbose_was, Migration.verbose = Migration.verbose, verbose?
|
158
236
|
|
159
|
-
|
160
|
-
version = ENV["VERSION"] ? ENV["VERSION"].to_i : nil
|
161
|
-
scope = ENV['SCOPE']
|
162
|
-
verbose_was, Migration.verbose = Migration.verbose, verbose
|
163
|
-
Migrator.migrate(migrations_paths, version) do |migration|
|
237
|
+
Base.connection.migration_context.migrate(target_version) do |migration|
|
164
238
|
scope.blank? || scope == migration.scope
|
165
239
|
end
|
240
|
+
|
166
241
|
ActiveRecord::Base.clear_cache!
|
167
242
|
ensure
|
168
243
|
Migration.verbose = verbose_was
|
169
244
|
end
|
170
245
|
|
171
|
-
def
|
172
|
-
|
246
|
+
def migrate_status
|
247
|
+
unless ActiveRecord::Base.connection.schema_migration.table_exists?
|
248
|
+
Kernel.abort "Schema migrations table does not exist yet."
|
249
|
+
end
|
250
|
+
|
251
|
+
# output
|
252
|
+
puts "\ndatabase: #{ActiveRecord::Base.connection_db_config.database}\n\n"
|
253
|
+
puts "#{'Status'.center(8)} #{'Migration ID'.ljust(14)} Migration Name"
|
254
|
+
puts "-" * 50
|
255
|
+
ActiveRecord::Base.connection.migration_context.migrations_status.each do |status, version, name|
|
256
|
+
puts "#{status.center(8)} #{version.ljust(14)} #{name}"
|
257
|
+
end
|
258
|
+
puts
|
173
259
|
end
|
174
260
|
|
175
|
-
def
|
176
|
-
|
177
|
-
|
261
|
+
def check_target_version
|
262
|
+
if target_version && !(Migration::MigrationFilenameRegexp.match?(ENV["VERSION"]) || /\A\d+\z/.match?(ENV["VERSION"]))
|
263
|
+
raise "Invalid format of target version: `VERSION=#{ENV['VERSION']}`"
|
264
|
+
end
|
178
265
|
end
|
179
266
|
|
180
|
-
def
|
181
|
-
|
267
|
+
def target_version
|
268
|
+
ENV["VERSION"].to_i if ENV["VERSION"] && !ENV["VERSION"].empty?
|
182
269
|
end
|
183
270
|
|
184
|
-
def
|
185
|
-
|
186
|
-
|
271
|
+
def charset_current(env_name = env, db_name = name)
|
272
|
+
db_config = ActiveRecord::Base.configurations.configs_for(env_name: env_name, name: db_name)
|
273
|
+
charset(db_config)
|
274
|
+
end
|
275
|
+
|
276
|
+
def charset(configuration, *arguments)
|
277
|
+
db_config = resolve_configuration(configuration)
|
278
|
+
database_adapter_for(db_config, *arguments).charset
|
279
|
+
end
|
280
|
+
|
281
|
+
def collation_current(env_name = env, db_name = name)
|
282
|
+
db_config = ActiveRecord::Base.configurations.configs_for(env_name: env_name, name: db_name)
|
283
|
+
collation(db_config)
|
284
|
+
end
|
285
|
+
|
286
|
+
def collation(configuration, *arguments)
|
287
|
+
db_config = resolve_configuration(configuration)
|
288
|
+
database_adapter_for(db_config, *arguments).collation
|
187
289
|
end
|
188
290
|
|
189
291
|
def purge(configuration)
|
190
|
-
|
292
|
+
db_config = resolve_configuration(configuration)
|
293
|
+
database_adapter_for(db_config).purge
|
191
294
|
end
|
192
295
|
|
193
296
|
def purge_all
|
194
|
-
each_local_configuration { |
|
195
|
-
purge configuration
|
196
|
-
}
|
297
|
+
each_local_configuration { |db_config| purge(db_config) }
|
197
298
|
end
|
198
299
|
|
199
300
|
def purge_current(environment = env)
|
200
|
-
each_current_configuration(environment) { |
|
201
|
-
purge configuration
|
202
|
-
}
|
301
|
+
each_current_configuration(environment) { |db_config| purge(db_config) }
|
203
302
|
ActiveRecord::Base.establish_connection(environment.to_sym)
|
204
303
|
end
|
205
304
|
|
206
|
-
def structure_dump(*arguments)
|
207
|
-
|
208
|
-
filename = arguments.delete_at
|
209
|
-
|
305
|
+
def structure_dump(configuration, *arguments)
|
306
|
+
db_config = resolve_configuration(configuration)
|
307
|
+
filename = arguments.delete_at(0)
|
308
|
+
database_adapter_for(db_config, *arguments).structure_dump(filename, structure_dump_flags)
|
210
309
|
end
|
211
310
|
|
212
|
-
def structure_load(*arguments)
|
213
|
-
|
214
|
-
filename = arguments.delete_at
|
215
|
-
|
311
|
+
def structure_load(configuration, *arguments)
|
312
|
+
db_config = resolve_configuration(configuration)
|
313
|
+
filename = arguments.delete_at(0)
|
314
|
+
database_adapter_for(db_config, *arguments).structure_load(filename, structure_load_flags)
|
216
315
|
end
|
217
316
|
|
218
|
-
def load_schema(
|
219
|
-
file ||=
|
317
|
+
def load_schema(db_config, format = ActiveRecord::Base.schema_format, file = nil) # :nodoc:
|
318
|
+
file ||= dump_filename(db_config.name, format)
|
220
319
|
|
320
|
+
verbose_was, Migration.verbose = Migration.verbose, verbose? && ENV["VERBOSE"]
|
221
321
|
check_schema_file(file)
|
222
|
-
ActiveRecord::Base.establish_connection(
|
322
|
+
ActiveRecord::Base.establish_connection(db_config)
|
223
323
|
|
224
324
|
case format
|
225
325
|
when :ruby
|
226
326
|
load(file)
|
227
327
|
when :sql
|
228
|
-
structure_load(
|
328
|
+
structure_load(db_config, file)
|
229
329
|
else
|
230
330
|
raise ArgumentError, "unknown format #{format.inspect}"
|
231
331
|
end
|
232
332
|
ActiveRecord::InternalMetadata.create_table
|
233
|
-
ActiveRecord::InternalMetadata[:environment] =
|
333
|
+
ActiveRecord::InternalMetadata[:environment] = db_config.env_name
|
334
|
+
ActiveRecord::InternalMetadata[:schema_sha1] = schema_sha1(file)
|
335
|
+
ensure
|
336
|
+
Migration.verbose = verbose_was
|
234
337
|
end
|
235
338
|
|
236
|
-
def
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
339
|
+
def schema_up_to_date?(configuration, format = ActiveRecord::Base.schema_format, file = nil, environment = nil, name = nil)
|
340
|
+
db_config = resolve_configuration(configuration)
|
341
|
+
|
342
|
+
if environment || name
|
343
|
+
ActiveSupport::Deprecation.warn("`environment` and `name` will be removed as parameters in 6.2.0, you may now pass an ActiveRecord::DatabaseConfigurations::DatabaseConfig as `configuration` instead.")
|
344
|
+
end
|
345
|
+
|
346
|
+
name ||= db_config.name
|
347
|
+
|
348
|
+
file ||= dump_filename(name, format)
|
349
|
+
|
350
|
+
return true unless File.exist?(file)
|
351
|
+
|
352
|
+
ActiveRecord::Base.establish_connection(db_config)
|
353
|
+
|
354
|
+
return false unless ActiveRecord::InternalMetadata.enabled?
|
355
|
+
return false unless ActiveRecord::InternalMetadata.table_exists?
|
356
|
+
|
357
|
+
ActiveRecord::InternalMetadata[:schema_sha1] == schema_sha1(file)
|
358
|
+
end
|
359
|
+
|
360
|
+
def reconstruct_from_schema(db_config, format = ActiveRecord::Base.schema_format, file = nil) # :nodoc:
|
361
|
+
file ||= dump_filename(db_config.name, format)
|
362
|
+
|
363
|
+
check_schema_file(file)
|
364
|
+
|
365
|
+
ActiveRecord::Base.establish_connection(db_config)
|
366
|
+
|
367
|
+
if schema_up_to_date?(db_config, format, file)
|
368
|
+
truncate_tables(db_config)
|
369
|
+
else
|
370
|
+
purge(db_config)
|
371
|
+
load_schema(db_config, format, file)
|
372
|
+
end
|
373
|
+
rescue ActiveRecord::NoDatabaseError
|
374
|
+
create(db_config)
|
375
|
+
load_schema(db_config, format, file)
|
376
|
+
end
|
377
|
+
|
378
|
+
def dump_schema(db_config, format = ActiveRecord::Base.schema_format) # :nodoc:
|
379
|
+
require "active_record/schema_dumper"
|
380
|
+
filename = dump_filename(db_config.name, format)
|
381
|
+
connection = ActiveRecord::Base.connection
|
382
|
+
|
383
|
+
FileUtils.mkdir_p(db_dir)
|
384
|
+
case format
|
385
|
+
when :ruby
|
386
|
+
File.open(filename, "w:utf-8") do |file|
|
387
|
+
ActiveRecord::SchemaDumper.dump(ActiveRecord::Base.connection, file)
|
388
|
+
end
|
389
|
+
when :sql
|
390
|
+
structure_dump(db_config, filename)
|
391
|
+
if connection.schema_migration.table_exists?
|
392
|
+
File.open(filename, "a") do |f|
|
393
|
+
f.puts connection.dump_schema_information
|
394
|
+
f.print "\n"
|
395
|
+
end
|
396
|
+
end
|
397
|
+
end
|
242
398
|
end
|
243
399
|
|
244
400
|
def schema_file(format = ActiveRecord::Base.schema_format)
|
401
|
+
File.join(db_dir, schema_file_type(format))
|
402
|
+
end
|
403
|
+
|
404
|
+
def schema_file_type(format = ActiveRecord::Base.schema_format)
|
245
405
|
case format
|
246
406
|
when :ruby
|
247
|
-
|
407
|
+
"schema.rb"
|
248
408
|
when :sql
|
249
|
-
|
409
|
+
"structure.sql"
|
250
410
|
end
|
251
411
|
end
|
252
412
|
|
413
|
+
def dump_filename(db_config_name, format = ActiveRecord::Base.schema_format)
|
414
|
+
filename = if ActiveRecord::Base.configurations.primary?(db_config_name)
|
415
|
+
schema_file_type(format)
|
416
|
+
else
|
417
|
+
"#{db_config_name}_#{schema_file_type(format)}"
|
418
|
+
end
|
419
|
+
|
420
|
+
ENV["SCHEMA"] || File.join(ActiveRecord::Tasks::DatabaseTasks.db_dir, filename)
|
421
|
+
end
|
422
|
+
|
423
|
+
def cache_dump_filename(db_config_name, schema_cache_path: nil)
|
424
|
+
filename = if ActiveRecord::Base.configurations.primary?(db_config_name)
|
425
|
+
"schema_cache.yml"
|
426
|
+
else
|
427
|
+
"#{db_config_name}_schema_cache.yml"
|
428
|
+
end
|
429
|
+
|
430
|
+
schema_cache_path || ENV["SCHEMA_CACHE"] || File.join(ActiveRecord::Tasks::DatabaseTasks.db_dir, filename)
|
431
|
+
end
|
432
|
+
|
253
433
|
def load_schema_current(format = ActiveRecord::Base.schema_format, file = nil, environment = env)
|
254
|
-
each_current_configuration(environment)
|
255
|
-
load_schema
|
256
|
-
|
434
|
+
each_current_configuration(environment) do |db_config|
|
435
|
+
load_schema(db_config, format, file)
|
436
|
+
end
|
257
437
|
ActiveRecord::Base.establish_connection(environment.to_sym)
|
258
438
|
end
|
259
439
|
|
260
440
|
def check_schema_file(filename)
|
261
441
|
unless File.exist?(filename)
|
262
|
-
message =
|
442
|
+
message = +%{#{filename} doesn't exist yet. Run `bin/rails db:migrate` to create it, then try again.}
|
263
443
|
message << %{ If you do not intend to use a database, you should instead alter #{Rails.root}/config/application.rb to limit the frameworks that will be loaded.} if defined?(::Rails.root)
|
264
444
|
Kernel.abort message
|
265
445
|
end
|
@@ -269,48 +449,85 @@ module ActiveRecord
|
|
269
449
|
if seed_loader
|
270
450
|
seed_loader.load_seed
|
271
451
|
else
|
272
|
-
raise "You tried to load seed data, but no seed loader is specified. Please specify seed "
|
273
|
-
"loader with ActiveRecord::Tasks::DatabaseTasks.seed_loader = your_seed_loader\n"
|
452
|
+
raise "You tried to load seed data, but no seed loader is specified. Please specify seed " \
|
453
|
+
"loader with ActiveRecord::Tasks::DatabaseTasks.seed_loader = your_seed_loader\n" \
|
274
454
|
"Seed loader should respond to load_seed method"
|
275
455
|
end
|
276
456
|
end
|
277
457
|
|
458
|
+
# Dumps the schema cache in YAML format for the connection into the file
|
459
|
+
#
|
460
|
+
# ==== Examples:
|
461
|
+
# ActiveRecord::Tasks::DatabaseTasks.dump_schema_cache(ActiveRecord::Base.connection, "tmp/schema_dump.yaml")
|
462
|
+
def dump_schema_cache(conn, filename)
|
463
|
+
conn.schema_cache.dump_to(filename)
|
464
|
+
end
|
465
|
+
|
466
|
+
def clear_schema_cache(filename)
|
467
|
+
FileUtils.rm_f filename, verbose: false
|
468
|
+
end
|
469
|
+
|
278
470
|
private
|
471
|
+
def resolve_configuration(configuration)
|
472
|
+
Base.configurations.resolve(configuration)
|
473
|
+
end
|
279
474
|
|
280
|
-
|
281
|
-
|
282
|
-
unless key
|
283
|
-
raise DatabaseNotSupported, "Rake tasks not supported by '#{adapter}' adapter"
|
475
|
+
def verbose?
|
476
|
+
ENV["VERBOSE"] ? ENV["VERBOSE"] != "false" : true
|
284
477
|
end
|
285
|
-
@tasks[key]
|
286
|
-
end
|
287
478
|
|
288
|
-
|
289
|
-
|
290
|
-
|
479
|
+
# Create a new instance for the specified db configuration object
|
480
|
+
# For classes that have been converted to use db_config objects, pass a
|
481
|
+
# `DatabaseConfig`, otherwise pass a `Hash`
|
482
|
+
def database_adapter_for(db_config, *arguments)
|
483
|
+
klass = class_for_adapter(db_config.adapter)
|
484
|
+
converted = klass.respond_to?(:using_database_configurations?) && klass.using_database_configurations?
|
291
485
|
|
292
|
-
|
293
|
-
|
486
|
+
config = converted ? db_config : db_config.configuration_hash
|
487
|
+
klass.new(config, *arguments)
|
488
|
+
end
|
294
489
|
|
295
|
-
|
490
|
+
def class_for_adapter(adapter)
|
491
|
+
_key, task = @tasks.each_pair.detect { |pattern, _task| adapter[pattern] }
|
492
|
+
unless task
|
493
|
+
raise DatabaseNotSupported, "Rake tasks not supported by '#{adapter}' adapter"
|
494
|
+
end
|
495
|
+
task.is_a?(String) ? task.constantize : task
|
296
496
|
end
|
297
|
-
end
|
298
497
|
|
299
|
-
|
300
|
-
|
301
|
-
|
498
|
+
def each_current_configuration(environment, name = nil)
|
499
|
+
environments = [environment]
|
500
|
+
environments << "test" if environment == "development" && !ENV["SKIP_TEST_DATABASE"] && !ENV["DATABASE_URL"]
|
501
|
+
|
502
|
+
environments.each do |env|
|
503
|
+
ActiveRecord::Base.configurations.configs_for(env_name: env).each do |db_config|
|
504
|
+
next if name && name != db_config.name
|
302
505
|
|
303
|
-
|
304
|
-
|
305
|
-
else
|
306
|
-
$stderr.puts "This task only modifies local databases. #{configuration['database']} is on a remote host."
|
506
|
+
yield db_config
|
507
|
+
end
|
307
508
|
end
|
308
509
|
end
|
309
|
-
end
|
310
510
|
|
311
|
-
|
312
|
-
|
313
|
-
|
511
|
+
def each_local_configuration
|
512
|
+
ActiveRecord::Base.configurations.configs_for.each do |db_config|
|
513
|
+
next unless db_config.database
|
514
|
+
|
515
|
+
if local_database?(db_config)
|
516
|
+
yield db_config
|
517
|
+
else
|
518
|
+
$stderr.puts "This task only modifies local databases. #{db_config.database} is on a remote host."
|
519
|
+
end
|
520
|
+
end
|
521
|
+
end
|
522
|
+
|
523
|
+
def local_database?(db_config)
|
524
|
+
host = db_config.host
|
525
|
+
host.blank? || LOCAL_HOSTS.include?(host)
|
526
|
+
end
|
527
|
+
|
528
|
+
def schema_sha1(file)
|
529
|
+
Digest::SHA1.hexdigest(File.read(file))
|
530
|
+
end
|
314
531
|
end
|
315
532
|
end
|
316
533
|
end
|