activerecord 4.2.8 → 6.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of activerecord might be problematic. Click here for more details.
- checksums.yaml +5 -5
- data/CHANGELOG.md +612 -1583
- data/MIT-LICENSE +4 -2
- data/README.rdoc +13 -12
- data/examples/performance.rb +33 -32
- data/examples/simple.rb +5 -4
- data/lib/active_record.rb +41 -22
- data/lib/active_record/aggregations.rb +267 -251
- data/lib/active_record/association_relation.rb +11 -6
- data/lib/active_record/associations.rb +1737 -1597
- data/lib/active_record/associations/alias_tracker.rb +29 -35
- data/lib/active_record/associations/association.rb +125 -58
- data/lib/active_record/associations/association_scope.rb +103 -132
- data/lib/active_record/associations/belongs_to_association.rb +65 -60
- data/lib/active_record/associations/belongs_to_polymorphic_association.rb +8 -12
- data/lib/active_record/associations/builder/association.rb +27 -40
- data/lib/active_record/associations/builder/belongs_to.rb +69 -55
- data/lib/active_record/associations/builder/collection_association.rb +10 -33
- data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +52 -66
- data/lib/active_record/associations/builder/has_many.rb +8 -4
- data/lib/active_record/associations/builder/has_one.rb +46 -5
- data/lib/active_record/associations/builder/singular_association.rb +16 -10
- data/lib/active_record/associations/collection_association.rb +134 -286
- data/lib/active_record/associations/collection_proxy.rb +241 -146
- data/lib/active_record/associations/foreign_association.rb +10 -1
- data/lib/active_record/associations/has_many_association.rb +34 -97
- data/lib/active_record/associations/has_many_through_association.rb +60 -87
- data/lib/active_record/associations/has_one_association.rb +61 -49
- data/lib/active_record/associations/has_one_through_association.rb +20 -11
- data/lib/active_record/associations/join_dependency.rb +137 -167
- data/lib/active_record/associations/join_dependency/join_association.rb +38 -88
- 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 +90 -92
- data/lib/active_record/associations/preloader/association.rb +90 -123
- data/lib/active_record/associations/preloader/through_association.rb +85 -65
- data/lib/active_record/associations/singular_association.rb +18 -39
- data/lib/active_record/associations/through_association.rb +38 -18
- data/lib/active_record/attribute_assignment.rb +56 -183
- data/lib/active_record/attribute_decorators.rb +39 -15
- data/lib/active_record/attribute_methods.rb +120 -135
- data/lib/active_record/attribute_methods/before_type_cast.rb +13 -8
- data/lib/active_record/attribute_methods/dirty.rb +174 -144
- data/lib/active_record/attribute_methods/primary_key.rb +91 -83
- data/lib/active_record/attribute_methods/query.rb +6 -5
- data/lib/active_record/attribute_methods/read.rb +20 -76
- data/lib/active_record/attribute_methods/serialization.rb +40 -20
- data/lib/active_record/attribute_methods/time_zone_conversion.rb +58 -36
- data/lib/active_record/attribute_methods/write.rb +32 -54
- data/lib/active_record/attributes.rb +214 -82
- data/lib/active_record/autosave_association.rb +91 -37
- data/lib/active_record/base.rb +57 -45
- data/lib/active_record/callbacks.rb +100 -74
- data/lib/active_record/coders/json.rb +3 -1
- data/lib/active_record/coders/yaml_column.rb +24 -12
- data/lib/active_record/connection_adapters/abstract/connection_pool.rb +796 -296
- data/lib/active_record/connection_adapters/abstract/database_limits.rb +26 -8
- data/lib/active_record/connection_adapters/abstract/database_statements.rb +234 -115
- data/lib/active_record/connection_adapters/abstract/query_cache.rb +82 -23
- data/lib/active_record/connection_adapters/abstract/quoting.rb +170 -53
- data/lib/active_record/connection_adapters/abstract/savepoints.rb +5 -3
- data/lib/active_record/connection_adapters/abstract/schema_creation.rb +74 -46
- data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +356 -227
- data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +79 -36
- data/lib/active_record/connection_adapters/abstract/schema_statements.rb +664 -244
- data/lib/active_record/connection_adapters/abstract/transaction.rb +191 -83
- data/lib/active_record/connection_adapters/abstract_adapter.rb +460 -204
- data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +510 -627
- data/lib/active_record/connection_adapters/column.rb +56 -43
- data/lib/active_record/connection_adapters/connection_specification.rb +174 -152
- data/lib/active_record/connection_adapters/determine_if_preparable_visitor.rb +29 -0
- data/lib/active_record/connection_adapters/mysql/column.rb +27 -0
- data/lib/active_record/connection_adapters/mysql/database_statements.rb +200 -0
- data/lib/active_record/connection_adapters/mysql/explain_pretty_printer.rb +72 -0
- data/lib/active_record/connection_adapters/mysql/quoting.rb +81 -0
- data/lib/active_record/connection_adapters/mysql/schema_creation.rb +72 -0
- data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +95 -0
- data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +88 -0
- data/lib/active_record/connection_adapters/mysql/schema_statements.rb +264 -0
- data/lib/active_record/connection_adapters/mysql/type_metadata.rb +31 -0
- data/lib/active_record/connection_adapters/mysql2_adapter.rb +58 -188
- data/lib/active_record/connection_adapters/postgresql/column.rb +21 -11
- data/lib/active_record/connection_adapters/postgresql/database_statements.rb +64 -114
- data/lib/active_record/connection_adapters/postgresql/explain_pretty_printer.rb +44 -0
- data/lib/active_record/connection_adapters/postgresql/oid.rb +23 -25
- data/lib/active_record/connection_adapters/postgresql/oid/array.rb +50 -58
- data/lib/active_record/connection_adapters/postgresql/oid/bit.rb +9 -8
- data/lib/active_record/connection_adapters/postgresql/oid/bit_varying.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/oid/bytea.rb +4 -2
- data/lib/active_record/connection_adapters/postgresql/oid/cidr.rb +5 -1
- data/lib/active_record/connection_adapters/postgresql/oid/date.rb +13 -1
- data/lib/active_record/connection_adapters/postgresql/oid/date_time.rb +9 -22
- data/lib/active_record/connection_adapters/postgresql/oid/decimal.rb +3 -1
- data/lib/active_record/connection_adapters/postgresql/oid/enum.rb +5 -3
- data/lib/active_record/connection_adapters/postgresql/oid/hstore.rb +31 -19
- data/lib/active_record/connection_adapters/postgresql/oid/inet.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/oid/jsonb.rb +3 -11
- data/lib/active_record/connection_adapters/postgresql/oid/legacy_point.rb +45 -0
- data/lib/active_record/connection_adapters/postgresql/oid/money.rb +7 -9
- data/lib/active_record/connection_adapters/postgresql/oid/{integer.rb → oid.rb} +6 -2
- data/lib/active_record/connection_adapters/postgresql/oid/point.rb +33 -11
- data/lib/active_record/connection_adapters/postgresql/oid/range.rb +52 -34
- data/lib/active_record/connection_adapters/postgresql/oid/specialized_string.rb +4 -5
- data/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb +58 -54
- data/lib/active_record/connection_adapters/postgresql/oid/uuid.rb +10 -5
- data/lib/active_record/connection_adapters/postgresql/oid/vector.rb +3 -1
- data/lib/active_record/connection_adapters/postgresql/oid/xml.rb +3 -1
- data/lib/active_record/connection_adapters/postgresql/quoting.rb +144 -47
- data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +27 -14
- data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +76 -0
- data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +178 -108
- data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +50 -0
- data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +470 -290
- data/lib/active_record/connection_adapters/postgresql/type_metadata.rb +36 -0
- data/lib/active_record/connection_adapters/postgresql/utils.rb +12 -8
- data/lib/active_record/connection_adapters/postgresql_adapter.rb +551 -356
- data/lib/active_record/connection_adapters/schema_cache.rb +72 -25
- data/lib/active_record/connection_adapters/sql_type_metadata.rb +37 -0
- data/lib/active_record/connection_adapters/sqlite3/database_statements.rb +118 -0
- data/lib/active_record/connection_adapters/sqlite3/explain_pretty_printer.rb +21 -0
- data/lib/active_record/connection_adapters/sqlite3/quoting.rb +103 -0
- data/lib/active_record/connection_adapters/sqlite3/schema_creation.rb +17 -0
- 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 +137 -0
- data/lib/active_record/connection_adapters/sqlite3_adapter.rb +290 -345
- data/lib/active_record/connection_adapters/statement_pool.rb +34 -13
- data/lib/active_record/connection_handling.rb +176 -41
- data/lib/active_record/core.rb +251 -231
- data/lib/active_record/counter_cache.rb +67 -49
- 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/define_callbacks.rb +22 -0
- data/lib/active_record/dynamic_matchers.rb +87 -105
- data/lib/active_record/enum.rb +163 -86
- data/lib/active_record/errors.rb +188 -53
- data/lib/active_record/explain.rb +23 -11
- data/lib/active_record/explain_registry.rb +4 -2
- data/lib/active_record/explain_subscriber.rb +10 -5
- data/lib/active_record/fixture_set/file.rb +35 -9
- 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 +228 -499
- data/lib/active_record/gem_version.rb +5 -3
- data/lib/active_record/inheritance.rb +158 -112
- data/lib/active_record/insert_all.rb +179 -0
- data/lib/active_record/integration.rb +123 -29
- data/lib/active_record/internal_metadata.rb +53 -0
- data/lib/active_record/legacy_yaml_adapter.rb +21 -3
- data/lib/active_record/locale/en.yml +3 -2
- data/lib/active_record/locking/optimistic.rb +87 -96
- data/lib/active_record/locking/pessimistic.rb +18 -6
- data/lib/active_record/log_subscriber.rb +76 -33
- data/lib/active_record/middleware/database_selector.rb +75 -0
- data/lib/active_record/middleware/database_selector/resolver.rb +92 -0
- data/lib/active_record/middleware/database_selector/resolver/session.rb +45 -0
- data/lib/active_record/migration.rb +626 -283
- data/lib/active_record/migration/command_recorder.rb +177 -90
- data/lib/active_record/migration/compatibility.rb +244 -0
- data/lib/active_record/migration/join_table.rb +8 -6
- data/lib/active_record/model_schema.rb +314 -112
- data/lib/active_record/nested_attributes.rb +264 -222
- data/lib/active_record/no_touching.rb +14 -1
- data/lib/active_record/null_relation.rb +24 -37
- data/lib/active_record/persistence.rb +557 -125
- data/lib/active_record/query_cache.rb +19 -23
- data/lib/active_record/querying.rb +43 -29
- data/lib/active_record/railtie.rb +147 -46
- data/lib/active_record/railties/collection_cache_association_loading.rb +34 -0
- 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 +330 -197
- data/lib/active_record/readonly_attributes.rb +5 -4
- data/lib/active_record/reflection.rb +428 -279
- data/lib/active_record/relation.rb +518 -341
- data/lib/active_record/relation/batches.rb +207 -55
- data/lib/active_record/relation/batches/batch_enumerator.rb +69 -0
- data/lib/active_record/relation/calculations.rb +267 -253
- data/lib/active_record/relation/delegation.rb +70 -80
- data/lib/active_record/relation/finder_methods.rb +277 -241
- data/lib/active_record/relation/from_clause.rb +26 -0
- data/lib/active_record/relation/merger.rb +78 -87
- data/lib/active_record/relation/predicate_builder.rb +114 -119
- data/lib/active_record/relation/predicate_builder/array_handler.rb +27 -26
- data/lib/active_record/relation/predicate_builder/association_query_value.rb +43 -0
- data/lib/active_record/relation/predicate_builder/base_handler.rb +18 -0
- data/lib/active_record/relation/predicate_builder/basic_object_handler.rb +19 -0
- data/lib/active_record/relation/predicate_builder/polymorphic_array_value.rb +53 -0
- data/lib/active_record/relation/predicate_builder/range_handler.rb +22 -0
- data/lib/active_record/relation/predicate_builder/relation_handler.rb +7 -1
- data/lib/active_record/relation/query_attribute.rb +50 -0
- data/lib/active_record/relation/query_methods.rb +575 -394
- data/lib/active_record/relation/record_fetch_warning.rb +51 -0
- data/lib/active_record/relation/spawn_methods.rb +11 -13
- data/lib/active_record/relation/where_clause.rb +190 -0
- data/lib/active_record/relation/where_clause_factory.rb +33 -0
- data/lib/active_record/result.rb +79 -42
- data/lib/active_record/runtime_registry.rb +6 -4
- data/lib/active_record/sanitization.rb +144 -121
- data/lib/active_record/schema.rb +21 -24
- data/lib/active_record/schema_dumper.rb +112 -93
- data/lib/active_record/schema_migration.rb +24 -17
- data/lib/active_record/scoping.rb +45 -26
- data/lib/active_record/scoping/default.rb +101 -85
- data/lib/active_record/scoping/named.rb +86 -33
- data/lib/active_record/secure_token.rb +40 -0
- data/lib/active_record/serialization.rb +5 -5
- data/lib/active_record/statement_cache.rb +73 -36
- data/lib/active_record/store.rb +127 -42
- data/lib/active_record/suppressor.rb +61 -0
- data/lib/active_record/table_metadata.rb +75 -0
- data/lib/active_record/tasks/database_tasks.rb +308 -99
- data/lib/active_record/tasks/mysql_database_tasks.rb +55 -99
- data/lib/active_record/tasks/postgresql_database_tasks.rb +81 -41
- data/lib/active_record/tasks/sqlite_database_tasks.rb +38 -16
- data/lib/active_record/test_databases.rb +23 -0
- data/lib/active_record/test_fixtures.rb +224 -0
- data/lib/active_record/timestamp.rb +86 -40
- data/lib/active_record/touch_later.rb +66 -0
- data/lib/active_record/transactions.rb +216 -150
- data/lib/active_record/translation.rb +3 -1
- data/lib/active_record/type.rb +78 -23
- data/lib/active_record/type/adapter_specific_registry.rb +129 -0
- data/lib/active_record/type/date.rb +4 -45
- data/lib/active_record/type/date_time.rb +4 -49
- data/lib/active_record/type/decimal_without_scale.rb +6 -2
- data/lib/active_record/type/hash_lookup_type_map.rb +5 -3
- data/lib/active_record/type/internal/timezone.rb +17 -0
- data/lib/active_record/type/json.rb +30 -0
- data/lib/active_record/type/serialized.rb +24 -15
- data/lib/active_record/type/text.rb +2 -2
- data/lib/active_record/type/time.rb +11 -16
- data/lib/active_record/type/type_map.rb +15 -17
- data/lib/active_record/type/unsigned_integer.rb +9 -7
- data/lib/active_record/type_caster.rb +9 -0
- data/lib/active_record/type_caster/connection.rb +34 -0
- data/lib/active_record/type_caster/map.rb +20 -0
- data/lib/active_record/validations.rb +39 -35
- data/lib/active_record/validations/absence.rb +25 -0
- data/lib/active_record/validations/associated.rb +13 -4
- data/lib/active_record/validations/length.rb +26 -0
- data/lib/active_record/validations/presence.rb +14 -13
- data/lib/active_record/validations/uniqueness.rb +42 -55
- data/lib/active_record/version.rb +3 -1
- data/lib/arel.rb +51 -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.rb +7 -5
- data/lib/rails/generators/active_record/application_record/application_record_generator.rb +27 -0
- data/lib/rails/generators/active_record/application_record/templates/application_record.rb.tt +5 -0
- data/lib/rails/generators/active_record/migration.rb +31 -1
- data/lib/rails/generators/active_record/migration/migration_generator.rb +42 -37
- data/lib/rails/generators/active_record/migration/templates/create_table_migration.rb.tt +24 -0
- data/lib/rails/generators/active_record/migration/templates/{migration.rb → migration.rb.tt} +11 -2
- data/lib/rails/generators/active_record/model/model_generator.rb +19 -22
- data/lib/rails/generators/active_record/model/templates/model.rb.tt +22 -0
- data/lib/rails/generators/active_record/model/templates/{module.rb → module.rb.tt} +0 -0
- metadata +164 -60
- data/lib/active_record/associations/preloader/belongs_to.rb +0 -17
- data/lib/active_record/associations/preloader/collection_association.rb +0 -24
- 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 -23
- data/lib/active_record/associations/preloader/has_one_through.rb +0 -9
- data/lib/active_record/associations/preloader/singular_association.rb +0 -21
- data/lib/active_record/attribute.rb +0 -163
- data/lib/active_record/attribute_set.rb +0 -81
- data/lib/active_record/attribute_set/builder.rb +0 -106
- data/lib/active_record/connection_adapters/mysql_adapter.rb +0 -491
- data/lib/active_record/connection_adapters/postgresql/array_parser.rb +0 -93
- data/lib/active_record/connection_adapters/postgresql/oid/float.rb +0 -21
- data/lib/active_record/connection_adapters/postgresql/oid/infinity.rb +0 -13
- data/lib/active_record/connection_adapters/postgresql/oid/json.rb +0 -35
- data/lib/active_record/connection_adapters/postgresql/oid/time.rb +0 -11
- data/lib/active_record/railties/jdbcmysql_error.rb +0 -16
- data/lib/active_record/serializers/xml_serializer.rb +0 -193
- data/lib/active_record/type/big_integer.rb +0 -13
- data/lib/active_record/type/binary.rb +0 -50
- data/lib/active_record/type/boolean.rb +0 -31
- data/lib/active_record/type/decimal.rb +0 -58
- data/lib/active_record/type/decorator.rb +0 -14
- data/lib/active_record/type/float.rb +0 -19
- data/lib/active_record/type/integer.rb +0 -59
- data/lib/active_record/type/mutable.rb +0 -16
- data/lib/active_record/type/numeric.rb +0 -36
- data/lib/active_record/type/string.rb +0 -40
- data/lib/active_record/type/time_value.rb +0 -38
- data/lib/active_record/type/value.rb +0 -110
- data/lib/rails/generators/active_record/migration/templates/create_table_migration.rb +0 -19
- data/lib/rails/generators/active_record/model/templates/model.rb +0 -10
@@ -0,0 +1,51 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ActiveRecord
|
4
|
+
class Relation
|
5
|
+
module RecordFetchWarning
|
6
|
+
# When this module is prepended to ActiveRecord::Relation and
|
7
|
+
# +config.active_record.warn_on_records_fetched_greater_than+ is
|
8
|
+
# set to an integer, if the number of records a query returns is
|
9
|
+
# greater than the value of +warn_on_records_fetched_greater_than+,
|
10
|
+
# a warning is logged. This allows for the detection of queries that
|
11
|
+
# return a large number of records, which could cause memory bloat.
|
12
|
+
#
|
13
|
+
# In most cases, fetching large number of records can be performed
|
14
|
+
# efficiently using the ActiveRecord::Batches methods.
|
15
|
+
# See ActiveRecord::Batches for more information.
|
16
|
+
def exec_queries
|
17
|
+
QueryRegistry.reset
|
18
|
+
|
19
|
+
super.tap do
|
20
|
+
if logger && warn_on_records_fetched_greater_than
|
21
|
+
if @records.length > warn_on_records_fetched_greater_than
|
22
|
+
logger.warn "Query fetched #{@records.size} #{@klass} records: #{QueryRegistry.queries.join(";")}"
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
# :stopdoc:
|
29
|
+
ActiveSupport::Notifications.subscribe("sql.active_record") do |*, payload|
|
30
|
+
QueryRegistry.queries << payload[:sql]
|
31
|
+
end
|
32
|
+
# :startdoc:
|
33
|
+
|
34
|
+
class QueryRegistry # :nodoc:
|
35
|
+
extend ActiveSupport::PerThreadRegistry
|
36
|
+
|
37
|
+
attr_reader :queries
|
38
|
+
|
39
|
+
def initialize
|
40
|
+
@queries = []
|
41
|
+
end
|
42
|
+
|
43
|
+
def reset
|
44
|
+
@queries.clear
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
ActiveRecord::Relation.prepend ActiveRecord::Relation::RecordFetchWarning
|
@@ -1,16 +1,17 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
require
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "active_support/core_ext/hash/except"
|
4
|
+
require "active_support/core_ext/hash/slice"
|
5
|
+
require "active_record/relation/merger"
|
4
6
|
|
5
7
|
module ActiveRecord
|
6
8
|
module SpawnMethods
|
7
|
-
|
8
9
|
# This is overridden by Associations::CollectionProxy
|
9
10
|
def spawn #:nodoc:
|
10
|
-
clone
|
11
|
+
already_in_scope? ? klass.all : clone
|
11
12
|
end
|
12
13
|
|
13
|
-
# Merges in the conditions from <tt>other</tt>, if <tt>other</tt> is an
|
14
|
+
# Merges in the conditions from <tt>other</tt>, if <tt>other</tt> is an ActiveRecord::Relation.
|
14
15
|
# Returns an array representing the intersection of the resulting records with <tt>other</tt>, if <tt>other</tt> is an array.
|
15
16
|
#
|
16
17
|
# Post.where(published: true).joins(:comments).merge( Comment.where(spam: false) )
|
@@ -29,11 +30,11 @@ module ActiveRecord
|
|
29
30
|
# This is mainly intended for sharing common conditions between multiple associations.
|
30
31
|
def merge(other)
|
31
32
|
if other.is_a?(Array)
|
32
|
-
|
33
|
+
records & other
|
33
34
|
elsif other
|
34
35
|
spawn.merge!(other)
|
35
36
|
else
|
36
|
-
|
37
|
+
raise ArgumentError, "invalid argument: #{other.inspect}."
|
37
38
|
end
|
38
39
|
end
|
39
40
|
|
@@ -62,16 +63,13 @@ module ActiveRecord
|
|
62
63
|
# Post.order('id asc').only(:where) # discards the order condition
|
63
64
|
# Post.order('id asc').only(:where, :order) # uses the specified order
|
64
65
|
def only(*onlies)
|
65
|
-
if onlies.any? { |o| o == :where }
|
66
|
-
onlies << :bind
|
67
|
-
end
|
68
66
|
relation_with values.slice(*onlies)
|
69
67
|
end
|
70
68
|
|
71
69
|
private
|
72
70
|
|
73
|
-
def relation_with(values)
|
74
|
-
result = Relation.create(klass,
|
71
|
+
def relation_with(values)
|
72
|
+
result = Relation.create(klass, values: values)
|
75
73
|
result.extend(*extending_values) if extending_values.any?
|
76
74
|
result
|
77
75
|
end
|
@@ -0,0 +1,190 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ActiveRecord
|
4
|
+
class Relation
|
5
|
+
class WhereClause # :nodoc:
|
6
|
+
delegate :any?, :empty?, to: :predicates
|
7
|
+
|
8
|
+
def initialize(predicates)
|
9
|
+
@predicates = predicates
|
10
|
+
end
|
11
|
+
|
12
|
+
def +(other)
|
13
|
+
WhereClause.new(
|
14
|
+
predicates + other.predicates,
|
15
|
+
)
|
16
|
+
end
|
17
|
+
|
18
|
+
def -(other)
|
19
|
+
WhereClause.new(
|
20
|
+
predicates - other.predicates,
|
21
|
+
)
|
22
|
+
end
|
23
|
+
|
24
|
+
def merge(other)
|
25
|
+
WhereClause.new(
|
26
|
+
predicates_unreferenced_by(other) + other.predicates,
|
27
|
+
)
|
28
|
+
end
|
29
|
+
|
30
|
+
def except(*columns)
|
31
|
+
WhereClause.new(except_predicates(columns))
|
32
|
+
end
|
33
|
+
|
34
|
+
def or(other)
|
35
|
+
left = self - other
|
36
|
+
common = self - left
|
37
|
+
right = other - common
|
38
|
+
|
39
|
+
if left.empty? || right.empty?
|
40
|
+
common
|
41
|
+
else
|
42
|
+
or_clause = WhereClause.new(
|
43
|
+
[left.ast.or(right.ast)],
|
44
|
+
)
|
45
|
+
common + or_clause
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def to_h(table_name = nil)
|
50
|
+
equalities = equalities(predicates)
|
51
|
+
if table_name
|
52
|
+
equalities = equalities.select do |node|
|
53
|
+
node.left.relation.name == table_name
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
equalities.map { |node|
|
58
|
+
name = node.left.name.to_s
|
59
|
+
value = extract_node_value(node.right)
|
60
|
+
[name, value]
|
61
|
+
}.to_h
|
62
|
+
end
|
63
|
+
|
64
|
+
def ast
|
65
|
+
Arel::Nodes::And.new(predicates_with_wrapped_sql_literals)
|
66
|
+
end
|
67
|
+
|
68
|
+
def ==(other)
|
69
|
+
other.is_a?(WhereClause) &&
|
70
|
+
predicates == other.predicates
|
71
|
+
end
|
72
|
+
|
73
|
+
def invert(as = :nand)
|
74
|
+
if predicates.size == 1
|
75
|
+
inverted_predicates = [ invert_predicate(predicates.first) ]
|
76
|
+
elsif as == :nor
|
77
|
+
inverted_predicates = predicates.map { |node| invert_predicate(node) }
|
78
|
+
else
|
79
|
+
inverted_predicates = [ Arel::Nodes::Not.new(ast) ]
|
80
|
+
end
|
81
|
+
|
82
|
+
WhereClause.new(inverted_predicates)
|
83
|
+
end
|
84
|
+
|
85
|
+
def self.empty
|
86
|
+
@empty ||= new([])
|
87
|
+
end
|
88
|
+
|
89
|
+
protected
|
90
|
+
|
91
|
+
attr_reader :predicates
|
92
|
+
|
93
|
+
def referenced_columns
|
94
|
+
@referenced_columns ||= begin
|
95
|
+
equality_nodes = predicates.select { |n| equality_node?(n) }
|
96
|
+
Set.new(equality_nodes, &:left)
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
private
|
101
|
+
def equalities(predicates)
|
102
|
+
equalities = []
|
103
|
+
|
104
|
+
predicates.each do |node|
|
105
|
+
case node
|
106
|
+
when Arel::Nodes::Equality
|
107
|
+
equalities << node
|
108
|
+
when Arel::Nodes::And
|
109
|
+
equalities.concat equalities(node.children)
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
equalities
|
114
|
+
end
|
115
|
+
|
116
|
+
def predicates_unreferenced_by(other)
|
117
|
+
predicates.reject do |n|
|
118
|
+
equality_node?(n) && other.referenced_columns.include?(n.left)
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
def equality_node?(node)
|
123
|
+
node.respond_to?(:operator) && node.operator == :==
|
124
|
+
end
|
125
|
+
|
126
|
+
def invert_predicate(node)
|
127
|
+
case node
|
128
|
+
when NilClass
|
129
|
+
raise ArgumentError, "Invalid argument for .where.not(), got nil."
|
130
|
+
when Arel::Nodes::In
|
131
|
+
Arel::Nodes::NotIn.new(node.left, node.right)
|
132
|
+
when Arel::Nodes::IsNotDistinctFrom
|
133
|
+
Arel::Nodes::IsDistinctFrom.new(node.left, node.right)
|
134
|
+
when Arel::Nodes::IsDistinctFrom
|
135
|
+
Arel::Nodes::IsNotDistinctFrom.new(node.left, node.right)
|
136
|
+
when Arel::Nodes::Equality
|
137
|
+
Arel::Nodes::NotEqual.new(node.left, node.right)
|
138
|
+
when String
|
139
|
+
Arel::Nodes::Not.new(Arel::Nodes::SqlLiteral.new(node))
|
140
|
+
else
|
141
|
+
Arel::Nodes::Not.new(node)
|
142
|
+
end
|
143
|
+
end
|
144
|
+
|
145
|
+
def except_predicates(columns)
|
146
|
+
predicates.reject do |node|
|
147
|
+
Arel.fetch_attribute(node) { |attr| columns.include?(attr.name.to_s) }
|
148
|
+
end
|
149
|
+
end
|
150
|
+
|
151
|
+
def predicates_with_wrapped_sql_literals
|
152
|
+
non_empty_predicates.map do |node|
|
153
|
+
case node
|
154
|
+
when Arel::Nodes::SqlLiteral, ::String
|
155
|
+
wrap_sql_literal(node)
|
156
|
+
else node
|
157
|
+
end
|
158
|
+
end
|
159
|
+
end
|
160
|
+
|
161
|
+
ARRAY_WITH_EMPTY_STRING = [""]
|
162
|
+
def non_empty_predicates
|
163
|
+
predicates - ARRAY_WITH_EMPTY_STRING
|
164
|
+
end
|
165
|
+
|
166
|
+
def wrap_sql_literal(node)
|
167
|
+
if ::String === node
|
168
|
+
node = Arel.sql(node)
|
169
|
+
end
|
170
|
+
Arel::Nodes::Grouping.new(node)
|
171
|
+
end
|
172
|
+
|
173
|
+
def extract_node_value(node)
|
174
|
+
case node
|
175
|
+
when Array
|
176
|
+
node.map { |v| extract_node_value(v) }
|
177
|
+
when Arel::Nodes::Casted, Arel::Nodes::Quoted
|
178
|
+
node.val
|
179
|
+
when Arel::Nodes::BindParam
|
180
|
+
value = node.value
|
181
|
+
if value.respond_to?(:value_before_type_cast)
|
182
|
+
value.value_before_type_cast
|
183
|
+
else
|
184
|
+
value
|
185
|
+
end
|
186
|
+
end
|
187
|
+
end
|
188
|
+
end
|
189
|
+
end
|
190
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ActiveRecord
|
4
|
+
class Relation
|
5
|
+
class WhereClauseFactory # :nodoc:
|
6
|
+
def initialize(klass, predicate_builder)
|
7
|
+
@klass = klass
|
8
|
+
@predicate_builder = predicate_builder
|
9
|
+
end
|
10
|
+
|
11
|
+
def build(opts, other)
|
12
|
+
case opts
|
13
|
+
when String, Array
|
14
|
+
parts = [klass.sanitize_sql(other.empty? ? opts : ([opts] + other))]
|
15
|
+
when Hash
|
16
|
+
attributes = predicate_builder.resolve_column_aliases(opts)
|
17
|
+
attributes.stringify_keys!
|
18
|
+
|
19
|
+
parts = predicate_builder.build_from_hash(attributes)
|
20
|
+
when Arel::Nodes::Node
|
21
|
+
parts = [opts]
|
22
|
+
else
|
23
|
+
raise ArgumentError, "Unsupported argument type: #{opts} (#{opts.class})"
|
24
|
+
end
|
25
|
+
|
26
|
+
WhereClause.new(parts)
|
27
|
+
end
|
28
|
+
|
29
|
+
private
|
30
|
+
attr_reader :klass, :predicate_builder
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
data/lib/active_record/result.rb
CHANGED
@@ -1,7 +1,10 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module ActiveRecord
|
2
4
|
###
|
3
|
-
# This class encapsulates a
|
4
|
-
#
|
5
|
+
# This class encapsulates a result returned from calling
|
6
|
+
# {#exec_query}[rdoc-ref:ConnectionAdapters::DatabaseStatements#exec_query]
|
7
|
+
# on any database connection adapter. For example:
|
5
8
|
#
|
6
9
|
# result = ActiveRecord::Base.connection.exec_query('SELECT id, title, body FROM posts')
|
7
10
|
# result # => #<ActiveRecord::Result:0xdeadbeef>
|
@@ -18,7 +21,7 @@ module ActiveRecord
|
|
18
21
|
# ]
|
19
22
|
#
|
20
23
|
# # Get an array of hashes representing the result (column => value):
|
21
|
-
# result.
|
24
|
+
# result.to_a
|
22
25
|
# # => [{"id" => 1, "title" => "title_1", "body" => "body_1"},
|
23
26
|
# {"id" => 2, "title" => "title_2", "body" => "body_2"},
|
24
27
|
# ...
|
@@ -31,8 +34,6 @@ module ActiveRecord
|
|
31
34
|
class Result
|
32
35
|
include Enumerable
|
33
36
|
|
34
|
-
IDENTITY_TYPE = Type::Value.new # :nodoc:
|
35
|
-
|
36
37
|
attr_reader :columns, :rows, :column_types
|
37
38
|
|
38
39
|
def initialize(columns, rows, column_types = {})
|
@@ -42,10 +43,20 @@ module ActiveRecord
|
|
42
43
|
@column_types = column_types
|
43
44
|
end
|
44
45
|
|
46
|
+
# Returns true if this result set includes the column named +name+
|
47
|
+
def includes_column?(name)
|
48
|
+
@columns.include? name
|
49
|
+
end
|
50
|
+
|
51
|
+
# Returns the number of elements in the rows array.
|
45
52
|
def length
|
46
53
|
@rows.length
|
47
54
|
end
|
48
55
|
|
56
|
+
# Calls the given block once for each element in row collection, passing
|
57
|
+
# row as parameter.
|
58
|
+
#
|
59
|
+
# Returns an +Enumerator+ if no block is given.
|
49
60
|
def each
|
50
61
|
if block_given?
|
51
62
|
hash_rows.each { |row| yield row }
|
@@ -55,36 +66,62 @@ module ActiveRecord
|
|
55
66
|
end
|
56
67
|
|
57
68
|
def to_hash
|
58
|
-
|
69
|
+
ActiveSupport::Deprecation.warn(<<-MSG.squish)
|
70
|
+
`ActiveRecord::Result#to_hash` has been renamed to `to_a`.
|
71
|
+
`to_hash` is deprecated and will be removed in Rails 6.1.
|
72
|
+
MSG
|
73
|
+
to_a
|
59
74
|
end
|
60
75
|
|
61
76
|
alias :map! :map
|
62
77
|
alias :collect! :map
|
63
78
|
|
64
|
-
# Returns true if there are no records.
|
79
|
+
# Returns true if there are no records, otherwise false.
|
65
80
|
def empty?
|
66
81
|
rows.empty?
|
67
82
|
end
|
68
83
|
|
84
|
+
# Returns an array of hashes representing each row record.
|
69
85
|
def to_ary
|
70
86
|
hash_rows
|
71
87
|
end
|
72
88
|
|
89
|
+
alias :to_a :to_ary
|
90
|
+
|
73
91
|
def [](idx)
|
74
92
|
hash_rows[idx]
|
75
93
|
end
|
76
94
|
|
95
|
+
# Returns the first record from the rows collection.
|
96
|
+
# If the rows collection is empty, returns +nil+.
|
97
|
+
def first
|
98
|
+
return nil if @rows.empty?
|
99
|
+
Hash[@columns.zip(@rows.first)]
|
100
|
+
end
|
101
|
+
|
102
|
+
# Returns the last record from the rows collection.
|
103
|
+
# If the rows collection is empty, returns +nil+.
|
77
104
|
def last
|
78
|
-
|
105
|
+
return nil if @rows.empty?
|
106
|
+
Hash[@columns.zip(@rows.last)]
|
79
107
|
end
|
80
108
|
|
81
109
|
def cast_values(type_overrides = {}) # :nodoc:
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
110
|
+
if columns.one?
|
111
|
+
# Separated to avoid allocating an array per row
|
112
|
+
|
113
|
+
type = column_type(columns.first, type_overrides)
|
86
114
|
|
87
|
-
|
115
|
+
rows.map do |(value)|
|
116
|
+
type.deserialize(value)
|
117
|
+
end
|
118
|
+
else
|
119
|
+
types = columns.map { |name| column_type(name, type_overrides) }
|
120
|
+
|
121
|
+
rows.map do |values|
|
122
|
+
Array.new(values.size) { |i| types[i].deserialize(values[i]) }
|
123
|
+
end
|
124
|
+
end
|
88
125
|
end
|
89
126
|
|
90
127
|
def initialize_copy(other)
|
@@ -96,36 +133,36 @@ module ActiveRecord
|
|
96
133
|
|
97
134
|
private
|
98
135
|
|
99
|
-
|
100
|
-
|
101
|
-
|
136
|
+
def column_type(name, type_overrides = {})
|
137
|
+
type_overrides.fetch(name) do
|
138
|
+
column_types.fetch(name, Type.default_value)
|
139
|
+
end
|
102
140
|
end
|
103
|
-
end
|
104
141
|
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
142
|
+
def hash_rows
|
143
|
+
@hash_rows ||=
|
144
|
+
begin
|
145
|
+
# We freeze the strings to prevent them getting duped when
|
146
|
+
# used as keys in ActiveRecord::Base's @attributes hash
|
147
|
+
columns = @columns.map(&:-@)
|
148
|
+
length = columns.length
|
149
|
+
|
150
|
+
@rows.map { |row|
|
151
|
+
# In the past we used Hash[columns.zip(row)]
|
152
|
+
# though elegant, the verbose way is much more efficient
|
153
|
+
# both time and memory wise cause it avoids a big array allocation
|
154
|
+
# this method is called a lot and needs to be micro optimised
|
155
|
+
hash = {}
|
156
|
+
|
157
|
+
index = 0
|
158
|
+
while index < length
|
159
|
+
hash[columns[index]] = row[index]
|
160
|
+
index += 1
|
161
|
+
end
|
162
|
+
|
163
|
+
hash
|
164
|
+
}
|
165
|
+
end
|
166
|
+
end
|
130
167
|
end
|
131
168
|
end
|