activerecord 5.0.6 → 6.0.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 +5 -5
- data/CHANGELOG.md +638 -2023
- data/MIT-LICENSE +3 -1
- data/README.rdoc +8 -6
- data/examples/performance.rb +31 -29
- data/examples/simple.rb +5 -3
- data/lib/active_record/aggregations.rb +249 -246
- data/lib/active_record/association_relation.rb +24 -13
- data/lib/active_record/associations/alias_tracker.rb +24 -33
- data/lib/active_record/associations/association.rb +119 -56
- 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 +42 -61
- 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 +80 -252
- data/lib/active_record/associations/collection_proxy.rb +158 -121
- data/lib/active_record/associations/foreign_association.rb +9 -0
- data/lib/active_record/associations/has_many_association.rb +23 -29
- 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/join_association.rb +38 -90
- 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/join_dependency.rb +134 -176
- data/lib/active_record/associations/preloader/association.rb +84 -125
- data/lib/active_record/associations/preloader/through_association.rb +82 -75
- data/lib/active_record/associations/preloader.rb +90 -102
- data/lib/active_record/associations/singular_association.rb +12 -45
- data/lib/active_record/associations/through_association.rb +26 -14
- data/lib/active_record/associations.rb +1603 -1592
- data/lib/active_record/attribute_assignment.rb +54 -60
- data/lib/active_record/attribute_decorators.rb +38 -15
- data/lib/active_record/attribute_methods/before_type_cast.rb +12 -7
- data/lib/active_record/attribute_methods/dirty.rb +179 -109
- data/lib/active_record/attribute_methods/primary_key.rb +86 -91
- data/lib/active_record/attribute_methods/query.rb +4 -3
- data/lib/active_record/attribute_methods/read.rb +21 -49
- data/lib/active_record/attribute_methods/serialization.rb +30 -7
- data/lib/active_record/attribute_methods/time_zone_conversion.rb +39 -64
- data/lib/active_record/attribute_methods/write.rb +35 -33
- data/lib/active_record/attribute_methods.rb +66 -106
- data/lib/active_record/attributes.rb +38 -24
- data/lib/active_record/autosave_association.rb +53 -32
- data/lib/active_record/base.rb +27 -24
- data/lib/active_record/callbacks.rb +63 -33
- data/lib/active_record/coders/json.rb +2 -0
- data/lib/active_record/coders/yaml_column.rb +11 -11
- data/lib/active_record/connection_adapters/abstract/connection_pool.rb +553 -321
- data/lib/active_record/connection_adapters/abstract/database_limits.rb +23 -5
- data/lib/active_record/connection_adapters/abstract/database_statements.rb +213 -94
- data/lib/active_record/connection_adapters/abstract/query_cache.rb +59 -28
- 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 -27
- data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +207 -126
- data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +68 -80
- data/lib/active_record/connection_adapters/abstract/schema_statements.rb +369 -199
- data/lib/active_record/connection_adapters/abstract/transaction.rb +169 -78
- data/lib/active_record/connection_adapters/abstract_adapter.rb +363 -202
- data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +405 -551
- data/lib/active_record/connection_adapters/column.rb +41 -13
- data/lib/active_record/connection_adapters/connection_specification.rb +172 -138
- 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 +143 -49
- data/lib/active_record/connection_adapters/mysql/explain_pretty_printer.rb +24 -22
- data/lib/active_record/connection_adapters/mysql/quoting.rb +50 -20
- data/lib/active_record/connection_adapters/mysql/schema_creation.rb +50 -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 +49 -30
- data/lib/active_record/connection_adapters/postgresql/column.rb +22 -7
- data/lib/active_record/connection_adapters/postgresql/database_statements.rb +60 -54
- data/lib/active_record/connection_adapters/postgresql/explain_pretty_printer.rb +5 -3
- data/lib/active_record/connection_adapters/postgresql/oid/array.rb +22 -10
- 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 -3
- data/lib/active_record/connection_adapters/postgresql/oid/hstore.rb +19 -17
- 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 -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 +31 -9
- data/lib/active_record/connection_adapters/postgresql/oid/range.rb +34 -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 +9 -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/oid.rb +24 -21
- data/lib/active_record/connection_adapters/postgresql/quoting.rb +95 -35
- data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +19 -25
- 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 +35 -32
- data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +380 -300
- data/lib/active_record/connection_adapters/postgresql/type_metadata.rb +26 -25
- data/lib/active_record/connection_adapters/postgresql/utils.rb +10 -6
- data/lib/active_record/connection_adapters/postgresql_adapter.rb +382 -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 +120 -0
- data/lib/active_record/connection_adapters/sqlite3/explain_pretty_printer.rb +3 -1
- data/lib/active_record/connection_adapters/sqlite3/quoting.rb +74 -19
- 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 +254 -262
- data/lib/active_record/connection_adapters/statement_pool.rb +9 -7
- data/lib/active_record/connection_handling.rb +159 -40
- data/lib/active_record/core.rb +202 -162
- data/lib/active_record/counter_cache.rb +57 -28
- 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/database_configurations.rb +233 -0
- data/lib/active_record/define_callbacks.rb +22 -0
- data/lib/active_record/dynamic_matchers.rb +87 -86
- data/lib/active_record/enum.rb +60 -23
- data/lib/active_record/errors.rb +114 -18
- data/lib/active_record/explain.rb +4 -3
- 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 +153 -0
- data/lib/active_record/fixture_set/table_rows.rb +47 -0
- data/lib/active_record/fixtures.rb +195 -502
- data/lib/active_record/gem_version.rb +4 -2
- data/lib/active_record/inheritance.rb +151 -97
- data/lib/active_record/insert_all.rb +179 -0
- data/lib/active_record/integration.rb +116 -25
- data/lib/active_record/internal_metadata.rb +15 -18
- data/lib/active_record/legacy_yaml_adapter.rb +4 -2
- data/lib/active_record/locking/optimistic.rb +78 -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/resolver/session.rb +45 -0
- data/lib/active_record/middleware/database_selector/resolver.rb +88 -0
- data/lib/active_record/middleware/database_selector.rb +75 -0
- data/lib/active_record/migration/command_recorder.rb +143 -97
- data/lib/active_record/migration/compatibility.rb +174 -56
- data/lib/active_record/migration/join_table.rb +8 -6
- data/lib/active_record/migration.rb +367 -300
- data/lib/active_record/model_schema.rb +145 -139
- data/lib/active_record/nested_attributes.rb +214 -201
- data/lib/active_record/no_touching.rb +10 -1
- data/lib/active_record/null_relation.rb +13 -34
- data/lib/active_record/persistence.rb +442 -72
- data/lib/active_record/query_cache.rb +15 -14
- data/lib/active_record/querying.rb +36 -23
- 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 +309 -177
- data/lib/active_record/readonly_attributes.rb +5 -4
- data/lib/active_record/reflection.rb +211 -249
- data/lib/active_record/relation/batches/batch_enumerator.rb +3 -1
- data/lib/active_record/relation/batches.rb +99 -52
- data/lib/active_record/relation/calculations.rb +211 -172
- data/lib/active_record/relation/delegation.rb +67 -65
- data/lib/active_record/relation/finder_methods.rb +208 -247
- data/lib/active_record/relation/from_clause.rb +2 -8
- data/lib/active_record/relation/merger.rb +78 -61
- 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/predicate_builder.rb +86 -104
- data/lib/active_record/relation/query_attribute.rb +33 -2
- data/lib/active_record/relation/query_methods.rb +458 -329
- data/lib/active_record/relation/record_fetch_warning.rb +5 -3
- data/lib/active_record/relation/spawn_methods.rb +8 -7
- data/lib/active_record/relation/where_clause.rb +111 -95
- data/lib/active_record/relation/where_clause_factory.rb +6 -11
- data/lib/active_record/relation.rb +429 -318
- data/lib/active_record/result.rb +69 -39
- 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 +15 -5
- data/lib/active_record/scoping/default.rb +93 -95
- data/lib/active_record/scoping/named.rb +45 -25
- data/lib/active_record/scoping.rb +20 -19
- 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 +4 -1
- data/lib/active_record/table_metadata.rb +26 -20
- data/lib/active_record/tasks/database_tasks.rb +276 -85
- data/lib/active_record/tasks/mysql_database_tasks.rb +54 -90
- data/lib/active_record/tasks/postgresql_database_tasks.rb +78 -47
- data/lib/active_record/tasks/sqlite_database_tasks.rb +34 -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 +70 -35
- data/lib/active_record/touch_later.rb +7 -4
- data/lib/active_record/transactions.rb +133 -149
- data/lib/active_record/translation.rb +3 -1
- data/lib/active_record/type/adapter_specific_registry.rb +44 -45
- 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 -3
- 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 -8
- 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 +13 -15
- data/lib/active_record/type/unsigned_integer.rb +17 -0
- data/lib/active_record/type.rb +23 -17
- data/lib/active_record/type_caster/connection.rb +17 -12
- data/lib/active_record/type_caster/map.rb +5 -4
- data/lib/active_record/type_caster.rb +4 -2
- data/lib/active_record/validations/absence.rb +2 -0
- data/lib/active_record/validations/associated.rb +3 -1
- 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/validations.rb +7 -4
- data/lib/active_record/version.rb +3 -1
- data/lib/active_record.rb +36 -22
- data/lib/arel/alias_predication.rb +9 -0
- data/lib/arel/attributes/attribute.rb +37 -0
- data/lib/arel/attributes.rb +22 -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/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/nodes.rb +68 -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/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/visitors.rb +20 -0
- data/lib/arel/window_predications.rb +9 -0
- data/lib/arel.rb +58 -0
- data/lib/rails/generators/active_record/application_record/application_record_generator.rb +27 -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/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/migration.rb +17 -2
- data/lib/rails/generators/active_record/model/model_generator.rb +9 -29
- 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
- data/lib/rails/generators/active_record.rb +7 -5
- metadata +133 -50
- 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/user_provided_default.rb +0 -28
- data/lib/active_record/attribute.rb +0 -213
- data/lib/active_record/attribute_mutation_tracker.rb +0 -70
- data/lib/active_record/attribute_set/builder.rb +0 -130
- data/lib/active_record/attribute_set.rb +0 -110
- 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,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module ActiveRecord
|
2
4
|
module Batches
|
3
5
|
class BatchEnumerator
|
@@ -7,7 +9,7 @@ module ActiveRecord
|
|
7
9
|
@of = of
|
8
10
|
@relation = relation
|
9
11
|
@start = start
|
10
|
-
@finish
|
12
|
+
@finish = finish
|
11
13
|
end
|
12
14
|
|
13
15
|
# Looping through a collection of records from the database (using the
|
@@ -1,8 +1,10 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require "active_record/relation/batches/batch_enumerator"
|
2
4
|
|
3
5
|
module ActiveRecord
|
4
6
|
module Batches
|
5
|
-
|
7
|
+
ORDER_IGNORE_MESSAGE = "Scoped order is ignored, it's forced to be batch order."
|
6
8
|
|
7
9
|
# Looping through a collection of records from the database
|
8
10
|
# (using the Scoping::Named::ClassMethods.all method, for example)
|
@@ -34,15 +36,24 @@ module ActiveRecord
|
|
34
36
|
# * <tt>:start</tt> - Specifies the primary key value to start from, inclusive of the value.
|
35
37
|
# * <tt>:finish</tt> - Specifies the primary key value to end at, inclusive of the value.
|
36
38
|
# * <tt>:error_on_ignore</tt> - Overrides the application config to specify if an error should be raised when
|
37
|
-
#
|
39
|
+
# an order is present in the relation.
|
40
|
+
#
|
41
|
+
# Limits are honored, and if present there is no requirement for the batch
|
42
|
+
# size: it can be less than, equal to, or greater than the limit.
|
43
|
+
#
|
44
|
+
# The options +start+ and +finish+ are especially useful if you want
|
45
|
+
# multiple workers dealing with the same processing queue. You can make
|
46
|
+
# worker 1 handle all the records between id 1 and 9999 and worker 2
|
47
|
+
# handle from 10000 and beyond by setting the +:start+ and +:finish+
|
48
|
+
# option on each worker.
|
38
49
|
#
|
39
|
-
#
|
40
|
-
#
|
41
|
-
#
|
42
|
-
#
|
50
|
+
# # In worker 1, let's process until 9999 records.
|
51
|
+
# Person.find_each(finish: 9_999) do |person|
|
52
|
+
# person.party_all_night!
|
53
|
+
# end
|
43
54
|
#
|
44
|
-
# #
|
45
|
-
# Person.find_each(start:
|
55
|
+
# # In worker 2, let's process from record 10_000 and onwards.
|
56
|
+
# Person.find_each(start: 10_000) do |person|
|
46
57
|
# person.party_all_night!
|
47
58
|
# end
|
48
59
|
#
|
@@ -51,8 +62,8 @@ module ActiveRecord
|
|
51
62
|
# work. This also means that this method only works when the primary key is
|
52
63
|
# orderable (e.g. an integer or string).
|
53
64
|
#
|
54
|
-
# NOTE:
|
55
|
-
# the
|
65
|
+
# NOTE: By its nature, batch processing is subject to race conditions if
|
66
|
+
# other processes are modifying the database.
|
56
67
|
def find_each(start: nil, finish: nil, batch_size: 1000, error_on_ignore: nil)
|
57
68
|
if block_given?
|
58
69
|
find_in_batches(start: start, finish: finish, batch_size: batch_size, error_on_ignore: error_on_ignore) do |records|
|
@@ -89,15 +100,19 @@ module ActiveRecord
|
|
89
100
|
# * <tt>:start</tt> - Specifies the primary key value to start from, inclusive of the value.
|
90
101
|
# * <tt>:finish</tt> - Specifies the primary key value to end at, inclusive of the value.
|
91
102
|
# * <tt>:error_on_ignore</tt> - Overrides the application config to specify if an error should be raised when
|
92
|
-
#
|
103
|
+
# an order is present in the relation.
|
104
|
+
#
|
105
|
+
# Limits are honored, and if present there is no requirement for the batch
|
106
|
+
# size: it can be less than, equal to, or greater than the limit.
|
93
107
|
#
|
94
|
-
#
|
95
|
-
# the same processing queue. You can make
|
96
|
-
# between id
|
97
|
-
#
|
108
|
+
# The options +start+ and +finish+ are especially useful if you want
|
109
|
+
# multiple workers dealing with the same processing queue. You can make
|
110
|
+
# worker 1 handle all the records between id 1 and 9999 and worker 2
|
111
|
+
# handle from 10000 and beyond by setting the +:start+ and +:finish+
|
112
|
+
# option on each worker.
|
98
113
|
#
|
99
|
-
# # Let's process
|
100
|
-
# Person.find_in_batches(start:
|
114
|
+
# # Let's process from record 10_000 on.
|
115
|
+
# Person.find_in_batches(start: 10_000) do |group|
|
101
116
|
# group.each { |person| person.party_all_night! }
|
102
117
|
# end
|
103
118
|
#
|
@@ -106,8 +121,8 @@ module ActiveRecord
|
|
106
121
|
# work. This also means that this method only works when the primary key is
|
107
122
|
# orderable (e.g. an integer or string).
|
108
123
|
#
|
109
|
-
# NOTE:
|
110
|
-
# the
|
124
|
+
# NOTE: By its nature, batch processing is subject to race conditions if
|
125
|
+
# other processes are modifying the database.
|
111
126
|
def find_in_batches(start: nil, finish: nil, batch_size: 1000, error_on_ignore: nil)
|
112
127
|
relation = self
|
113
128
|
unless block_given?
|
@@ -149,17 +164,19 @@ module ActiveRecord
|
|
149
164
|
# * <tt>:start</tt> - Specifies the primary key value to start from, inclusive of the value.
|
150
165
|
# * <tt>:finish</tt> - Specifies the primary key value to end at, inclusive of the value.
|
151
166
|
# * <tt>:error_on_ignore</tt> - Overrides the application config to specify if an error should be raised when
|
152
|
-
#
|
167
|
+
# an order is present in the relation.
|
153
168
|
#
|
154
|
-
#
|
155
|
-
#
|
156
|
-
# you want multiple workers dealing with the same processing queue. You can
|
157
|
-
# make worker 1 handle all the records between id 0 and 10,000 and worker 2
|
158
|
-
# handle from 10,000 and beyond (by setting the +:start+ and +:finish+
|
159
|
-
# option on each worker).
|
169
|
+
# Limits are honored, and if present there is no requirement for the batch
|
170
|
+
# size, it can be less than, equal, or greater than the limit.
|
160
171
|
#
|
161
|
-
#
|
162
|
-
#
|
172
|
+
# The options +start+ and +finish+ are especially useful if you want
|
173
|
+
# multiple workers dealing with the same processing queue. You can make
|
174
|
+
# worker 1 handle all the records between id 1 and 9999 and worker 2
|
175
|
+
# handle from 10000 and beyond by setting the +:start+ and +:finish+
|
176
|
+
# option on each worker.
|
177
|
+
#
|
178
|
+
# # Let's process from record 10_000 on.
|
179
|
+
# Person.in_batches(start: 10_000).update_all(awesome: true)
|
163
180
|
#
|
164
181
|
# An example of calling where query method on the relation:
|
165
182
|
#
|
@@ -179,31 +196,38 @@ module ActiveRecord
|
|
179
196
|
# consistent. Therefore the primary key must be orderable, e.g. an integer
|
180
197
|
# or a string.
|
181
198
|
#
|
182
|
-
# NOTE:
|
183
|
-
#
|
199
|
+
# NOTE: By its nature, batch processing is subject to race conditions if
|
200
|
+
# other processes are modifying the database.
|
184
201
|
def in_batches(of: 1000, start: nil, finish: nil, load: false, error_on_ignore: nil)
|
185
202
|
relation = self
|
186
203
|
unless block_given?
|
187
204
|
return BatchEnumerator.new(of: of, start: start, finish: finish, relation: self)
|
188
205
|
end
|
189
206
|
|
190
|
-
if arel.orders.present?
|
191
|
-
|
207
|
+
if arel.orders.present?
|
208
|
+
act_on_ignored_order(error_on_ignore)
|
209
|
+
end
|
210
|
+
|
211
|
+
batch_limit = of
|
212
|
+
if limit_value
|
213
|
+
remaining = limit_value
|
214
|
+
batch_limit = remaining if remaining < batch_limit
|
192
215
|
end
|
193
216
|
|
194
|
-
relation = relation.reorder(batch_order).limit(
|
217
|
+
relation = relation.reorder(batch_order).limit(batch_limit)
|
195
218
|
relation = apply_limits(relation, start, finish)
|
219
|
+
relation.skip_query_cache! # Retaining the results in the query cache would undermine the point of batching
|
196
220
|
batch_relation = relation
|
197
221
|
|
198
222
|
loop do
|
199
223
|
if load
|
200
224
|
records = batch_relation.records
|
201
225
|
ids = records.map(&:id)
|
202
|
-
yielded_relation =
|
226
|
+
yielded_relation = where(primary_key => ids)
|
203
227
|
yielded_relation.load_records(records)
|
204
228
|
else
|
205
229
|
ids = batch_relation.pluck(primary_key)
|
206
|
-
yielded_relation =
|
230
|
+
yielded_relation = where(primary_key => ids)
|
207
231
|
end
|
208
232
|
|
209
233
|
break if ids.empty?
|
@@ -213,31 +237,54 @@ module ActiveRecord
|
|
213
237
|
|
214
238
|
yield yielded_relation
|
215
239
|
|
216
|
-
break if ids.length <
|
217
|
-
|
240
|
+
break if ids.length < batch_limit
|
241
|
+
|
242
|
+
if limit_value
|
243
|
+
remaining -= ids.length
|
244
|
+
|
245
|
+
if remaining == 0
|
246
|
+
# Saves a useless iteration when the limit is a multiple of the
|
247
|
+
# batch size.
|
248
|
+
break
|
249
|
+
elsif remaining < batch_limit
|
250
|
+
relation = relation.limit(remaining)
|
251
|
+
end
|
252
|
+
end
|
253
|
+
|
254
|
+
batch_relation = relation.where(
|
255
|
+
bind_attribute(primary_key, primary_key_offset) { |attr, bind| attr.gt(bind) }
|
256
|
+
)
|
218
257
|
end
|
219
258
|
end
|
220
259
|
|
221
260
|
private
|
222
261
|
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
262
|
+
def apply_limits(relation, start, finish)
|
263
|
+
relation = apply_start_limit(relation, start) if start
|
264
|
+
relation = apply_finish_limit(relation, finish) if finish
|
265
|
+
relation
|
266
|
+
end
|
228
267
|
|
229
|
-
|
230
|
-
|
231
|
-
|
268
|
+
def apply_start_limit(relation, start)
|
269
|
+
relation.where(bind_attribute(primary_key, start) { |attr, bind| attr.gteq(bind) })
|
270
|
+
end
|
232
271
|
|
233
|
-
|
234
|
-
|
272
|
+
def apply_finish_limit(relation, finish)
|
273
|
+
relation.where(bind_attribute(primary_key, finish) { |attr, bind| attr.lteq(bind) })
|
274
|
+
end
|
235
275
|
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
276
|
+
def batch_order
|
277
|
+
arel_attribute(primary_key).asc
|
278
|
+
end
|
279
|
+
|
280
|
+
def act_on_ignored_order(error_on_ignore)
|
281
|
+
raise_error = (error_on_ignore.nil? ? klass.error_on_ignored_order : error_on_ignore)
|
282
|
+
|
283
|
+
if raise_error
|
284
|
+
raise ArgumentError.new(ORDER_IGNORE_MESSAGE)
|
285
|
+
elsif logger
|
286
|
+
logger.warn(ORDER_IGNORE_MESSAGE)
|
287
|
+
end
|
240
288
|
end
|
241
|
-
end
|
242
289
|
end
|
243
290
|
end
|