activerecord 5.0.7.2 → 6.0.3.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of activerecord might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/CHANGELOG.md +708 -2040
- data/MIT-LICENSE +3 -1
- data/README.rdoc +9 -7
- data/examples/performance.rb +31 -29
- data/examples/simple.rb +5 -3
- data/lib/active_record.rb +37 -22
- data/lib/active_record/advisory_lock_base.rb +18 -0
- data/lib/active_record/aggregations.rb +249 -247
- data/lib/active_record/association_relation.rb +18 -14
- data/lib/active_record/associations.rb +1603 -1592
- data/lib/active_record/associations/alias_tracker.rb +24 -34
- data/lib/active_record/associations/association.rb +114 -55
- data/lib/active_record/associations/association_scope.rb +94 -94
- data/lib/active_record/associations/belongs_to_association.rb +58 -42
- data/lib/active_record/associations/belongs_to_polymorphic_association.rb +8 -12
- data/lib/active_record/associations/builder/association.rb +18 -25
- data/lib/active_record/associations/builder/belongs_to.rb +43 -54
- data/lib/active_record/associations/builder/collection_association.rb +7 -18
- data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +41 -62
- data/lib/active_record/associations/builder/has_many.rb +4 -0
- data/lib/active_record/associations/builder/has_one.rb +37 -1
- data/lib/active_record/associations/builder/singular_association.rb +4 -0
- data/lib/active_record/associations/collection_association.rb +86 -254
- data/lib/active_record/associations/collection_proxy.rb +158 -122
- data/lib/active_record/associations/foreign_association.rb +9 -0
- data/lib/active_record/associations/has_many_association.rb +23 -30
- data/lib/active_record/associations/has_many_through_association.rb +58 -44
- data/lib/active_record/associations/has_one_association.rb +59 -54
- data/lib/active_record/associations/has_one_through_association.rb +20 -11
- data/lib/active_record/associations/join_dependency.rb +143 -176
- data/lib/active_record/associations/join_dependency/join_association.rb +38 -87
- data/lib/active_record/associations/join_dependency/join_base.rb +10 -9
- data/lib/active_record/associations/join_dependency/join_part.rb +12 -12
- data/lib/active_record/associations/preloader.rb +90 -103
- data/lib/active_record/associations/preloader/association.rb +86 -100
- 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 +26 -14
- data/lib/active_record/attribute_assignment.rb +54 -61
- data/lib/active_record/attribute_decorators.rb +38 -17
- data/lib/active_record/attribute_methods.rb +66 -106
- data/lib/active_record/attribute_methods/before_type_cast.rb +12 -8
- data/lib/active_record/attribute_methods/dirty.rb +179 -109
- data/lib/active_record/attribute_methods/primary_key.rb +85 -92
- data/lib/active_record/attribute_methods/query.rb +4 -3
- data/lib/active_record/attribute_methods/read.rb +20 -49
- data/lib/active_record/attribute_methods/serialization.rb +29 -7
- data/lib/active_record/attribute_methods/time_zone_conversion.rb +39 -66
- data/lib/active_record/attribute_methods/write.rb +34 -33
- data/lib/active_record/attributes.rb +38 -25
- data/lib/active_record/autosave_association.rb +54 -35
- data/lib/active_record/base.rb +27 -24
- data/lib/active_record/callbacks.rb +64 -35
- 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/abstract/connection_pool.rb +552 -323
- data/lib/active_record/connection_adapters/abstract/database_limits.rb +23 -5
- data/lib/active_record/connection_adapters/abstract/database_statements.rb +215 -94
- data/lib/active_record/connection_adapters/abstract/query_cache.rb +59 -35
- data/lib/active_record/connection_adapters/abstract/quoting.rb +119 -75
- data/lib/active_record/connection_adapters/abstract/savepoints.rb +2 -0
- data/lib/active_record/connection_adapters/abstract/schema_creation.rb +33 -28
- data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +228 -147
- data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +68 -80
- data/lib/active_record/connection_adapters/abstract/schema_statements.rb +400 -213
- data/lib/active_record/connection_adapters/abstract/transaction.rb +169 -79
- data/lib/active_record/connection_adapters/abstract_adapter.rb +367 -202
- data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +396 -562
- data/lib/active_record/connection_adapters/column.rb +41 -13
- data/lib/active_record/connection_adapters/connection_specification.rb +172 -139
- data/lib/active_record/connection_adapters/determine_if_preparable_visitor.rb +11 -4
- data/lib/active_record/connection_adapters/mysql/column.rb +8 -31
- data/lib/active_record/connection_adapters/mysql/database_statements.rb +137 -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 +49 -45
- data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +58 -56
- data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +70 -36
- data/lib/active_record/connection_adapters/mysql/schema_statements.rb +264 -0
- data/lib/active_record/connection_adapters/mysql/type_metadata.rb +12 -13
- data/lib/active_record/connection_adapters/mysql2_adapter.rb +48 -30
- data/lib/active_record/connection_adapters/postgresql/column.rb +19 -31
- data/lib/active_record/connection_adapters/postgresql/database_statements.rb +64 -54
- data/lib/active_record/connection_adapters/postgresql/explain_pretty_printer.rb +5 -3
- data/lib/active_record/connection_adapters/postgresql/oid.rb +24 -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 +3 -1
- data/lib/active_record/connection_adapters/postgresql/oid/date.rb +23 -0
- data/lib/active_record/connection_adapters/postgresql/oid/date_time.rb +4 -2
- 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/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/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 +34 -31
- 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 +8 -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 +95 -35
- data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +20 -26
- data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +76 -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 +378 -308
- data/lib/active_record/connection_adapters/postgresql/type_metadata.rb +26 -25
- data/lib/active_record/connection_adapters/postgresql/utils.rb +9 -6
- data/lib/active_record/connection_adapters/postgresql_adapter.rb +383 -275
- data/lib/active_record/connection_adapters/schema_cache.rb +46 -12
- data/lib/active_record/connection_adapters/sql_type_metadata.rb +13 -8
- data/lib/active_record/connection_adapters/sqlite3/database_statements.rb +119 -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 +3 -8
- 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 +259 -266
- data/lib/active_record/connection_adapters/statement_pool.rb +9 -8
- data/lib/active_record/connection_handling.rb +143 -40
- data/lib/active_record/core.rb +201 -163
- data/lib/active_record/counter_cache.rb +60 -28
- 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 +78 -0
- data/lib/active_record/define_callbacks.rb +22 -0
- data/lib/active_record/dynamic_matchers.rb +87 -87
- data/lib/active_record/enum.rb +60 -23
- data/lib/active_record/errors.rb +114 -18
- data/lib/active_record/explain.rb +4 -4
- 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 +13 -8
- 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 +152 -0
- data/lib/active_record/fixture_set/table_rows.rb +46 -0
- data/lib/active_record/fixtures.rb +194 -504
- data/lib/active_record/gem_version.rb +5 -3
- data/lib/active_record/inheritance.rb +150 -99
- data/lib/active_record/insert_all.rb +179 -0
- data/lib/active_record/integration.rb +116 -25
- data/lib/active_record/internal_metadata.rb +16 -19
- data/lib/active_record/legacy_yaml_adapter.rb +4 -2
- data/lib/active_record/locking/optimistic.rb +77 -87
- data/lib/active_record/locking/pessimistic.rb +18 -6
- data/lib/active_record/log_subscriber.rb +48 -29
- data/lib/active_record/middleware/database_selector.rb +74 -0
- data/lib/active_record/middleware/database_selector/resolver.rb +87 -0
- data/lib/active_record/middleware/database_selector/resolver/session.rb +45 -0
- data/lib/active_record/migration.rb +369 -302
- data/lib/active_record/migration/command_recorder.rb +134 -100
- data/lib/active_record/migration/compatibility.rb +174 -56
- data/lib/active_record/migration/join_table.rb +8 -7
- data/lib/active_record/model_schema.rb +131 -127
- data/lib/active_record/nested_attributes.rb +213 -202
- data/lib/active_record/no_touching.rb +12 -3
- data/lib/active_record/null_relation.rb +12 -34
- data/lib/active_record/persistence.rb +446 -77
- data/lib/active_record/query_cache.rb +13 -12
- data/lib/active_record/querying.rb +37 -24
- data/lib/active_record/railtie.rb +128 -36
- 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 +312 -177
- data/lib/active_record/readonly_attributes.rb +5 -4
- data/lib/active_record/reflection.rb +214 -252
- data/lib/active_record/relation.rb +440 -318
- data/lib/active_record/relation/batches.rb +98 -52
- data/lib/active_record/relation/batches/batch_enumerator.rb +3 -1
- data/lib/active_record/relation/calculations.rb +212 -173
- data/lib/active_record/relation/delegation.rb +72 -69
- data/lib/active_record/relation/finder_methods.rb +207 -247
- data/lib/active_record/relation/from_clause.rb +6 -8
- data/lib/active_record/relation/merger.rb +78 -62
- data/lib/active_record/relation/predicate_builder.rb +83 -105
- data/lib/active_record/relation/predicate_builder/array_handler.rb +20 -14
- data/lib/active_record/relation/predicate_builder/association_query_value.rb +43 -0
- data/lib/active_record/relation/predicate_builder/base_handler.rb +4 -3
- data/lib/active_record/relation/predicate_builder/basic_object_handler.rb +6 -4
- data/lib/active_record/relation/predicate_builder/polymorphic_array_value.rb +53 -0
- data/lib/active_record/relation/predicate_builder/range_handler.rb +7 -18
- data/lib/active_record/relation/predicate_builder/relation_handler.rb +6 -0
- data/lib/active_record/relation/query_attribute.rb +33 -2
- data/lib/active_record/relation/query_methods.rb +476 -334
- data/lib/active_record/relation/record_fetch_warning.rb +5 -3
- data/lib/active_record/relation/spawn_methods.rb +8 -8
- data/lib/active_record/relation/where_clause.rb +111 -96
- data/lib/active_record/relation/where_clause_factory.rb +6 -11
- data/lib/active_record/result.rb +69 -40
- data/lib/active_record/runtime_registry.rb +5 -3
- data/lib/active_record/sanitization.rb +83 -99
- data/lib/active_record/schema.rb +7 -14
- data/lib/active_record/schema_dumper.rb +71 -69
- data/lib/active_record/schema_migration.rb +16 -6
- data/lib/active_record/scoping.rb +20 -20
- data/lib/active_record/scoping/default.rb +92 -95
- data/lib/active_record/scoping/named.rb +47 -27
- data/lib/active_record/secure_token.rb +4 -2
- data/lib/active_record/serialization.rb +2 -0
- data/lib/active_record/statement_cache.rb +63 -28
- data/lib/active_record/store.rb +121 -41
- data/lib/active_record/suppressor.rb +6 -3
- data/lib/active_record/table_metadata.rb +39 -18
- data/lib/active_record/tasks/database_tasks.rb +271 -81
- data/lib/active_record/tasks/mysql_database_tasks.rb +54 -91
- data/lib/active_record/tasks/postgresql_database_tasks.rb +77 -47
- data/lib/active_record/tasks/sqlite_database_tasks.rb +33 -16
- data/lib/active_record/test_databases.rb +23 -0
- data/lib/active_record/test_fixtures.rb +225 -0
- data/lib/active_record/timestamp.rb +70 -36
- data/lib/active_record/touch_later.rb +8 -6
- data/lib/active_record/transactions.rb +141 -157
- data/lib/active_record/translation.rb +3 -1
- data/lib/active_record/type.rb +23 -18
- 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 +16 -9
- data/lib/active_record/type/text.rb +11 -0
- data/lib/active_record/type/time.rb +2 -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 -12
- data/lib/active_record/type_caster/map.rb +5 -4
- data/lib/active_record/validations.rb +7 -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/presence.rb +4 -2
- data/lib/active_record/validations/uniqueness.rb +29 -42
- data/lib/active_record/version.rb +3 -1
- data/lib/arel.rb +62 -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 +256 -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 +203 -0
- data/lib/arel/visitors/dot.rb +296 -0
- data/lib/arel/visitors/ibm_db.rb +34 -0
- data/lib/arel/visitors/informix.rb +62 -0
- data/lib/arel/visitors/mssql.rb +156 -0
- data/lib/arel/visitors/mysql.rb +83 -0
- data/lib/arel/visitors/oracle.rb +158 -0
- data/lib/arel/visitors/oracle12.rb +65 -0
- data/lib/arel/visitors/postgresql.rb +109 -0
- data/lib/arel/visitors/sqlite.rb +38 -0
- data/lib/arel/visitors/to_sql.rb +888 -0
- data/lib/arel/visitors/visitor.rb +45 -0
- data/lib/arel/visitors/where_sql.rb +22 -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 +17 -3
- data/lib/rails/generators/active_record/migration/migration_generator.rb +37 -35
- data/lib/rails/generators/active_record/migration/templates/{create_table_migration.rb → create_table_migration.rb.tt} +1 -1
- data/lib/rails/generators/active_record/migration/templates/{migration.rb → migration.rb.tt} +4 -2
- data/lib/rails/generators/active_record/model/model_generator.rb +9 -30
- 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 +137 -52
- 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_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/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/class_handler.rb +0 -27
- data/lib/active_record/relation/predicate_builder/polymorphic_array_handler.rb +0 -57
- data/lib/active_record/type/internal/abstract_json.rb +0 -33
@@ -1,16 +1,18 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module ActiveRecord
|
2
4
|
class Relation
|
3
5
|
module RecordFetchWarning
|
4
6
|
# When this module is prepended to ActiveRecord::Relation and
|
5
|
-
#
|
7
|
+
# +config.active_record.warn_on_records_fetched_greater_than+ is
|
6
8
|
# set to an integer, if the number of records a query returns is
|
7
|
-
# greater than the value of
|
9
|
+
# greater than the value of +warn_on_records_fetched_greater_than+,
|
8
10
|
# a warning is logged. This allows for the detection of queries that
|
9
11
|
# return a large number of records, which could cause memory bloat.
|
10
12
|
#
|
11
13
|
# In most cases, fetching large number of records can be performed
|
12
14
|
# efficiently using the ActiveRecord::Batches methods.
|
13
|
-
# See
|
15
|
+
# See ActiveRecord::Batches for more information.
|
14
16
|
def exec_queries
|
15
17
|
QueryRegistry.reset
|
16
18
|
|
@@ -1,13 +1,14 @@
|
|
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
14
|
# Merges in the conditions from <tt>other</tt>, if <tt>other</tt> is an ActiveRecord::Relation.
|
@@ -66,9 +67,8 @@ module ActiveRecord
|
|
66
67
|
end
|
67
68
|
|
68
69
|
private
|
69
|
-
|
70
|
-
|
71
|
-
result = Relation.create(klass, table, predicate_builder, values)
|
70
|
+
def relation_with(values)
|
71
|
+
result = Relation.create(klass, values: values)
|
72
72
|
result.extend(*extending_values) if extending_values.any?
|
73
73
|
result
|
74
74
|
end
|
@@ -1,68 +1,63 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module ActiveRecord
|
2
4
|
class Relation
|
3
5
|
class WhereClause # :nodoc:
|
4
|
-
attr_reader :binds
|
5
|
-
|
6
6
|
delegate :any?, :empty?, to: :predicates
|
7
7
|
|
8
|
-
def initialize(predicates
|
8
|
+
def initialize(predicates)
|
9
9
|
@predicates = predicates
|
10
|
-
@binds = binds
|
11
10
|
end
|
12
11
|
|
13
12
|
def +(other)
|
14
13
|
WhereClause.new(
|
15
14
|
predicates + other.predicates,
|
16
|
-
|
15
|
+
)
|
16
|
+
end
|
17
|
+
|
18
|
+
def -(other)
|
19
|
+
WhereClause.new(
|
20
|
+
predicates - other.predicates,
|
17
21
|
)
|
18
22
|
end
|
19
23
|
|
20
24
|
def merge(other)
|
21
25
|
WhereClause.new(
|
22
26
|
predicates_unreferenced_by(other) + other.predicates,
|
23
|
-
non_conflicting_binds(other) + other.binds,
|
24
27
|
)
|
25
28
|
end
|
26
29
|
|
27
30
|
def except(*columns)
|
28
|
-
WhereClause.new(
|
29
|
-
predicates_except(columns),
|
30
|
-
binds_except(columns),
|
31
|
-
)
|
31
|
+
WhereClause.new(except_predicates(columns))
|
32
32
|
end
|
33
33
|
|
34
34
|
def or(other)
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
35
|
+
left = self - other
|
36
|
+
common = self - left
|
37
|
+
right = other - common
|
38
|
+
|
39
|
+
if left.empty? || right.empty?
|
40
|
+
common
|
39
41
|
else
|
40
|
-
WhereClause.new(
|
41
|
-
[ast.or(
|
42
|
-
binds + other.binds
|
42
|
+
or_clause = WhereClause.new(
|
43
|
+
[left.ast.or(right.ast)],
|
43
44
|
)
|
45
|
+
common + or_clause
|
44
46
|
end
|
45
47
|
end
|
46
48
|
|
47
49
|
def to_h(table_name = nil)
|
48
|
-
equalities = predicates
|
50
|
+
equalities = equalities(predicates)
|
49
51
|
if table_name
|
50
52
|
equalities = equalities.select do |node|
|
51
53
|
node.left.relation.name == table_name
|
52
54
|
end
|
53
55
|
end
|
54
56
|
|
55
|
-
binds = self.binds.map { |attr| [attr.name, attr.value] }.to_h
|
56
|
-
|
57
57
|
equalities.map { |node|
|
58
|
-
name = node.left.name
|
59
|
-
|
60
|
-
|
61
|
-
when Array then node.right.map(&:val)
|
62
|
-
when Arel::Nodes::Casted, Arel::Nodes::Quoted
|
63
|
-
node.right.val
|
64
|
-
end
|
65
|
-
}]
|
58
|
+
name = node.left.name.to_s
|
59
|
+
value = extract_node_value(node.right)
|
60
|
+
[name, value]
|
66
61
|
}.to_h
|
67
62
|
end
|
68
63
|
|
@@ -72,103 +67,123 @@ module ActiveRecord
|
|
72
67
|
|
73
68
|
def ==(other)
|
74
69
|
other.is_a?(WhereClause) &&
|
75
|
-
predicates == other.predicates
|
76
|
-
binds == other.binds
|
70
|
+
predicates == other.predicates
|
77
71
|
end
|
78
72
|
|
79
|
-
def invert
|
80
|
-
|
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)
|
81
83
|
end
|
82
84
|
|
83
85
|
def self.empty
|
84
|
-
@empty ||= new([]
|
86
|
+
@empty ||= new([])
|
85
87
|
end
|
86
88
|
|
87
89
|
protected
|
90
|
+
attr_reader :predicates
|
88
91
|
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
Set.new(equality_nodes, &:left)
|
92
|
+
def referenced_columns
|
93
|
+
@referenced_columns ||= begin
|
94
|
+
equality_nodes = predicates.select { |n| equality_node?(n) }
|
95
|
+
Set.new(equality_nodes, &:left)
|
96
|
+
end
|
95
97
|
end
|
96
|
-
end
|
97
98
|
|
98
99
|
private
|
100
|
+
def equalities(predicates)
|
101
|
+
equalities = []
|
102
|
+
|
103
|
+
predicates.each do |node|
|
104
|
+
case node
|
105
|
+
when Arel::Nodes::Equality
|
106
|
+
equalities << node
|
107
|
+
when Arel::Nodes::And
|
108
|
+
equalities.concat equalities(node.children)
|
109
|
+
end
|
110
|
+
end
|
99
111
|
|
100
|
-
|
101
|
-
predicates.reject do |n|
|
102
|
-
equality_node?(n) && other.referenced_columns.include?(n.left)
|
112
|
+
equalities
|
103
113
|
end
|
104
|
-
end
|
105
114
|
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
conflicts = referenced_columns & other.referenced_columns
|
112
|
-
conflicts.map! { |node| node.name.to_s }
|
113
|
-
binds.reject { |attr| conflicts.include?(attr.name) }
|
114
|
-
end
|
115
|
-
|
116
|
-
def inverted_predicates
|
117
|
-
predicates.map { |node| invert_predicate(node) }
|
118
|
-
end
|
115
|
+
def predicates_unreferenced_by(other)
|
116
|
+
predicates.reject do |n|
|
117
|
+
equality_node?(n) && other.referenced_columns.include?(n.left)
|
118
|
+
end
|
119
|
+
end
|
119
120
|
|
120
|
-
|
121
|
-
|
122
|
-
when NilClass
|
123
|
-
raise ArgumentError, 'Invalid argument for .where.not(), got nil.'
|
124
|
-
when Arel::Nodes::In
|
125
|
-
Arel::Nodes::NotIn.new(node.left, node.right)
|
126
|
-
when Arel::Nodes::Equality
|
127
|
-
Arel::Nodes::NotEqual.new(node.left, node.right)
|
128
|
-
when String
|
129
|
-
Arel::Nodes::Not.new(Arel::Nodes::SqlLiteral.new(node))
|
130
|
-
else
|
131
|
-
Arel::Nodes::Not.new(node)
|
121
|
+
def equality_node?(node)
|
122
|
+
node.respond_to?(:operator) && node.operator == :==
|
132
123
|
end
|
133
|
-
end
|
134
124
|
|
135
|
-
|
136
|
-
predicates.reject do |node|
|
125
|
+
def invert_predicate(node)
|
137
126
|
case node
|
138
|
-
when
|
139
|
-
|
140
|
-
|
127
|
+
when NilClass
|
128
|
+
raise ArgumentError, "Invalid argument for .where.not(), got nil."
|
129
|
+
when Arel::Nodes::In
|
130
|
+
Arel::Nodes::NotIn.new(node.left, node.right)
|
131
|
+
when Arel::Nodes::IsNotDistinctFrom
|
132
|
+
Arel::Nodes::IsDistinctFrom.new(node.left, node.right)
|
133
|
+
when Arel::Nodes::IsDistinctFrom
|
134
|
+
Arel::Nodes::IsNotDistinctFrom.new(node.left, node.right)
|
135
|
+
when Arel::Nodes::Equality
|
136
|
+
Arel::Nodes::NotEqual.new(node.left, node.right)
|
137
|
+
when String
|
138
|
+
Arel::Nodes::Not.new(Arel::Nodes::SqlLiteral.new(node))
|
139
|
+
else
|
140
|
+
Arel::Nodes::Not.new(node)
|
141
141
|
end
|
142
142
|
end
|
143
|
-
end
|
144
143
|
|
145
|
-
|
146
|
-
|
147
|
-
|
144
|
+
def except_predicates(columns)
|
145
|
+
predicates.reject do |node|
|
146
|
+
Arel.fetch_attribute(node) { |attr| columns.include?(attr.name.to_s) }
|
147
|
+
end
|
148
148
|
end
|
149
|
-
end
|
150
149
|
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
150
|
+
def predicates_with_wrapped_sql_literals
|
151
|
+
non_empty_predicates.map do |node|
|
152
|
+
case node
|
153
|
+
when Arel::Nodes::SqlLiteral, ::String
|
154
|
+
wrap_sql_literal(node)
|
155
|
+
else node
|
156
|
+
end
|
157
157
|
end
|
158
158
|
end
|
159
|
-
end
|
160
159
|
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
160
|
+
ARRAY_WITH_EMPTY_STRING = [""]
|
161
|
+
def non_empty_predicates
|
162
|
+
predicates - ARRAY_WITH_EMPTY_STRING
|
163
|
+
end
|
165
164
|
|
166
|
-
|
167
|
-
|
168
|
-
|
165
|
+
def wrap_sql_literal(node)
|
166
|
+
if ::String === node
|
167
|
+
node = Arel.sql(node)
|
168
|
+
end
|
169
|
+
Arel::Nodes::Grouping.new(node)
|
170
|
+
end
|
171
|
+
|
172
|
+
def extract_node_value(node)
|
173
|
+
case node
|
174
|
+
when Array
|
175
|
+
node.map { |v| extract_node_value(v) }
|
176
|
+
when Arel::Nodes::Casted, Arel::Nodes::Quoted
|
177
|
+
node.val
|
178
|
+
when Arel::Nodes::BindParam
|
179
|
+
value = node.value
|
180
|
+
if value.respond_to?(:value_before_type_cast)
|
181
|
+
value.value_before_type_cast
|
182
|
+
else
|
183
|
+
value
|
184
|
+
end
|
185
|
+
end
|
169
186
|
end
|
170
|
-
Arel::Nodes::Grouping.new(node)
|
171
|
-
end
|
172
187
|
end
|
173
188
|
end
|
174
189
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module ActiveRecord
|
2
4
|
class Relation
|
3
5
|
class WhereClauseFactory # :nodoc:
|
@@ -7,32 +9,25 @@ module ActiveRecord
|
|
7
9
|
end
|
8
10
|
|
9
11
|
def build(opts, other)
|
10
|
-
binds = []
|
11
|
-
|
12
12
|
case opts
|
13
13
|
when String, Array
|
14
|
-
parts = [klass.
|
14
|
+
parts = [klass.sanitize_sql(other.empty? ? opts : ([opts] + other))]
|
15
15
|
when Hash
|
16
16
|
attributes = predicate_builder.resolve_column_aliases(opts)
|
17
|
-
attributes = klass.send(:expand_hash_conditions_for_aggregates, attributes)
|
18
17
|
attributes.stringify_keys!
|
19
18
|
|
20
|
-
attributes, binds = predicate_builder.create_binds(attributes)
|
21
|
-
|
22
19
|
parts = predicate_builder.build_from_hash(attributes)
|
23
20
|
when Arel::Nodes::Node
|
24
21
|
parts = [opts]
|
25
|
-
binds = other
|
26
22
|
else
|
27
23
|
raise ArgumentError, "Unsupported argument type: #{opts} (#{opts.class})"
|
28
24
|
end
|
29
25
|
|
30
|
-
WhereClause.new(parts
|
26
|
+
WhereClause.new(parts)
|
31
27
|
end
|
32
28
|
|
33
|
-
|
34
|
-
|
35
|
-
attr_reader :klass, :predicate_builder
|
29
|
+
private
|
30
|
+
attr_reader :klass, :predicate_builder
|
36
31
|
end
|
37
32
|
end
|
38
33
|
end
|
data/lib/active_record/result.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module ActiveRecord
|
2
4
|
###
|
3
5
|
# This class encapsulates a result returned from calling
|
@@ -19,7 +21,7 @@ module ActiveRecord
|
|
19
21
|
# ]
|
20
22
|
#
|
21
23
|
# # Get an array of hashes representing the result (column => value):
|
22
|
-
# result.
|
24
|
+
# result.to_a
|
23
25
|
# # => [{"id" => 1, "title" => "title_1", "body" => "body_1"},
|
24
26
|
# {"id" => 2, "title" => "title_2", "body" => "body_2"},
|
25
27
|
# ...
|
@@ -32,8 +34,6 @@ module ActiveRecord
|
|
32
34
|
class Result
|
33
35
|
include Enumerable
|
34
36
|
|
35
|
-
IDENTITY_TYPE = Type::Value.new # :nodoc:
|
36
|
-
|
37
37
|
attr_reader :columns, :rows, :column_types
|
38
38
|
|
39
39
|
def initialize(columns, rows, column_types = {})
|
@@ -43,10 +43,20 @@ module ActiveRecord
|
|
43
43
|
@column_types = column_types
|
44
44
|
end
|
45
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.
|
46
52
|
def length
|
47
53
|
@rows.length
|
48
54
|
end
|
49
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.
|
50
60
|
def each
|
51
61
|
if block_given?
|
52
62
|
hash_rows.each { |row| yield row }
|
@@ -56,42 +66,62 @@ module ActiveRecord
|
|
56
66
|
end
|
57
67
|
|
58
68
|
def to_hash
|
59
|
-
|
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
|
60
74
|
end
|
61
75
|
|
62
76
|
alias :map! :map
|
63
77
|
alias :collect! :map
|
64
78
|
|
65
|
-
# Returns true if there are no records.
|
79
|
+
# Returns true if there are no records, otherwise false.
|
66
80
|
def empty?
|
67
81
|
rows.empty?
|
68
82
|
end
|
69
83
|
|
84
|
+
# Returns an array of hashes representing each row record.
|
70
85
|
def to_ary
|
71
86
|
hash_rows
|
72
87
|
end
|
73
88
|
|
89
|
+
alias :to_a :to_ary
|
90
|
+
|
74
91
|
def [](idx)
|
75
92
|
hash_rows[idx]
|
76
93
|
end
|
77
94
|
|
95
|
+
# Returns the first record from the rows collection.
|
96
|
+
# If the rows collection is empty, returns +nil+.
|
78
97
|
def first
|
79
98
|
return nil if @rows.empty?
|
80
99
|
Hash[@columns.zip(@rows.first)]
|
81
100
|
end
|
82
101
|
|
102
|
+
# Returns the last record from the rows collection.
|
103
|
+
# If the rows collection is empty, returns +nil+.
|
83
104
|
def last
|
84
105
|
return nil if @rows.empty?
|
85
106
|
Hash[@columns.zip(@rows.last)]
|
86
107
|
end
|
87
108
|
|
88
109
|
def cast_values(type_overrides = {}) # :nodoc:
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
110
|
+
if columns.one?
|
111
|
+
# Separated to avoid allocating an array per row
|
112
|
+
|
113
|
+
type = column_type(columns.first, type_overrides)
|
93
114
|
|
94
|
-
|
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
|
95
125
|
end
|
96
126
|
|
97
127
|
def initialize_copy(other)
|
@@ -102,37 +132,36 @@ module ActiveRecord
|
|
102
132
|
end
|
103
133
|
|
104
134
|
private
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
135
|
+
def column_type(name, type_overrides = {})
|
136
|
+
type_overrides.fetch(name) do
|
137
|
+
column_types.fetch(name, Type.default_value)
|
138
|
+
end
|
109
139
|
end
|
110
|
-
end
|
111
140
|
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
141
|
+
def hash_rows
|
142
|
+
@hash_rows ||=
|
143
|
+
begin
|
144
|
+
# We freeze the strings to prevent them getting duped when
|
145
|
+
# used as keys in ActiveRecord::Base's @attributes hash
|
146
|
+
columns = @columns.map(&:-@)
|
147
|
+
length = columns.length
|
148
|
+
|
149
|
+
@rows.map { |row|
|
150
|
+
# In the past we used Hash[columns.zip(row)]
|
151
|
+
# though elegant, the verbose way is much more efficient
|
152
|
+
# both time and memory wise cause it avoids a big array allocation
|
153
|
+
# this method is called a lot and needs to be micro optimised
|
154
|
+
hash = {}
|
155
|
+
|
156
|
+
index = 0
|
157
|
+
while index < length
|
158
|
+
hash[columns[index]] = row[index]
|
159
|
+
index += 1
|
160
|
+
end
|
161
|
+
|
162
|
+
hash
|
163
|
+
}
|
164
|
+
end
|
165
|
+
end
|
137
166
|
end
|
138
167
|
end
|