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
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)
|
114
|
+
|
115
|
+
rows.map do |(value)|
|
116
|
+
type.deserialize(value)
|
117
|
+
end
|
118
|
+
else
|
119
|
+
types = columns.map { |name| column_type(name, type_overrides) }
|
93
120
|
|
94
|
-
|
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)
|
@@ -103,36 +133,36 @@ module ActiveRecord
|
|
103
133
|
|
104
134
|
private
|
105
135
|
|
106
|
-
|
107
|
-
|
108
|
-
|
136
|
+
def column_type(name, type_overrides = {})
|
137
|
+
type_overrides.fetch(name) do
|
138
|
+
column_types.fetch(name, Type.default_value)
|
139
|
+
end
|
109
140
|
end
|
110
|
-
end
|
111
141
|
|
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
|
-
|
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
|
137
167
|
end
|
138
168
|
end
|
@@ -1,4 +1,6 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "active_support/per_thread_registry"
|
2
4
|
|
3
5
|
module ActiveRecord
|
4
6
|
# This is a thread locals registry for Active Record. For example:
|
@@ -12,9 +14,9 @@ module ActiveRecord
|
|
12
14
|
class RuntimeRegistry # :nodoc:
|
13
15
|
extend ActiveSupport::PerThreadRegistry
|
14
16
|
|
15
|
-
attr_accessor :connection_handler, :sql_runtime
|
17
|
+
attr_accessor :connection_handler, :sql_runtime
|
16
18
|
|
17
|
-
[:connection_handler, :sql_runtime
|
19
|
+
[:connection_handler, :sql_runtime].each do |val|
|
18
20
|
class_eval %{ def self.#{val}; instance.#{val}; end }, __FILE__, __LINE__
|
19
21
|
class_eval %{ def self.#{val}=(x); instance.#{val}=x; end }, __FILE__, __LINE__
|
20
22
|
end
|
@@ -1,17 +1,10 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module ActiveRecord
|
2
4
|
module Sanitization
|
3
5
|
extend ActiveSupport::Concern
|
4
6
|
|
5
7
|
module ClassMethods
|
6
|
-
# Used to sanitize objects before they're used in an SQL SELECT statement.
|
7
|
-
# Delegates to {connection.quote}[rdoc-ref:ConnectionAdapters::Quoting#quote].
|
8
|
-
def sanitize(object) # :nodoc:
|
9
|
-
connection.quote(object)
|
10
|
-
end
|
11
|
-
alias_method :quote_value, :sanitize
|
12
|
-
|
13
|
-
protected
|
14
|
-
|
15
8
|
# Accepts an array or string of SQL conditions and sanitizes
|
16
9
|
# them into a valid SQL fragment for a WHERE clause.
|
17
10
|
#
|
@@ -34,8 +27,7 @@ module ActiveRecord
|
|
34
27
|
else condition
|
35
28
|
end
|
36
29
|
end
|
37
|
-
|
38
|
-
alias_method :sanitize_conditions, :sanitize_sql
|
30
|
+
alias :sanitize_sql :sanitize_sql_for_conditions
|
39
31
|
|
40
32
|
# Accepts an array, hash, or string of SQL conditions and sanitizes
|
41
33
|
# them into a valid SQL fragment for a SET clause.
|
@@ -46,12 +38,12 @@ module ActiveRecord
|
|
46
38
|
# sanitize_sql_for_assignment(["name=:name and group_id=:group_id", name: nil, group_id: 4])
|
47
39
|
# # => "name=NULL and group_id=4"
|
48
40
|
#
|
49
|
-
# Post.
|
41
|
+
# Post.sanitize_sql_for_assignment({ name: nil, group_id: 4 })
|
50
42
|
# # => "`posts`.`name` = NULL, `posts`.`group_id` = 4"
|
51
43
|
#
|
52
44
|
# sanitize_sql_for_assignment("name=NULL and group_id='4'")
|
53
45
|
# # => "name=NULL and group_id='4'"
|
54
|
-
def sanitize_sql_for_assignment(assignments, default_table_name =
|
46
|
+
def sanitize_sql_for_assignment(assignments, default_table_name = table_name)
|
55
47
|
case assignments
|
56
48
|
when Array; sanitize_sql_array(assignments)
|
57
49
|
when Hash; sanitize_sql_hash_for_assignment(assignments, default_table_name)
|
@@ -68,47 +60,24 @@ module ActiveRecord
|
|
68
60
|
# sanitize_sql_for_order("id ASC")
|
69
61
|
# # => "id ASC"
|
70
62
|
def sanitize_sql_for_order(condition)
|
71
|
-
if condition.is_a?(Array) && condition.first.to_s.include?(
|
72
|
-
|
63
|
+
if condition.is_a?(Array) && condition.first.to_s.include?("?")
|
64
|
+
disallow_raw_sql!(
|
65
|
+
[condition.first],
|
66
|
+
permit: connection.column_name_with_order_matcher
|
67
|
+
)
|
68
|
+
|
69
|
+
# Ensure we aren't dealing with a subclass of String that might
|
70
|
+
# override methods we use (eg. Arel::Nodes::SqlLiteral).
|
71
|
+
if condition.first.kind_of?(String) && !condition.first.instance_of?(String)
|
72
|
+
condition = [String.new(condition.first), *condition[1..-1]]
|
73
|
+
end
|
74
|
+
|
75
|
+
Arel.sql(sanitize_sql_array(condition))
|
73
76
|
else
|
74
77
|
condition
|
75
78
|
end
|
76
79
|
end
|
77
80
|
|
78
|
-
# Accepts a hash of SQL conditions and replaces those attributes
|
79
|
-
# that correspond to a {#composed_of}[rdoc-ref:Aggregations::ClassMethods#composed_of]
|
80
|
-
# relationship with their expanded aggregate attribute values.
|
81
|
-
#
|
82
|
-
# Given:
|
83
|
-
#
|
84
|
-
# class Person < ActiveRecord::Base
|
85
|
-
# composed_of :address, class_name: "Address",
|
86
|
-
# mapping: [%w(address_street street), %w(address_city city)]
|
87
|
-
# end
|
88
|
-
#
|
89
|
-
# Then:
|
90
|
-
#
|
91
|
-
# { address: Address.new("813 abc st.", "chicago") }
|
92
|
-
# # => { address_street: "813 abc st.", address_city: "chicago" }
|
93
|
-
def expand_hash_conditions_for_aggregates(attrs)
|
94
|
-
expanded_attrs = {}
|
95
|
-
attrs.each do |attr, value|
|
96
|
-
if aggregation = reflect_on_aggregation(attr.to_sym)
|
97
|
-
mapping = aggregation.mapping
|
98
|
-
mapping.each do |field_attr, aggregate_attr|
|
99
|
-
if mapping.size == 1 && !value.respond_to?(aggregate_attr)
|
100
|
-
expanded_attrs[field_attr] = value
|
101
|
-
else
|
102
|
-
expanded_attrs[field_attr] = value.send(aggregate_attr)
|
103
|
-
end
|
104
|
-
end
|
105
|
-
else
|
106
|
-
expanded_attrs[attr] = value
|
107
|
-
end
|
108
|
-
end
|
109
|
-
expanded_attrs
|
110
|
-
end
|
111
|
-
|
112
81
|
# Sanitizes a hash of attribute/value pairs into SQL conditions for a SET clause.
|
113
82
|
#
|
114
83
|
# sanitize_sql_hash_for_assignment({ status: nil, group_id: 1 }, "posts")
|
@@ -116,19 +85,10 @@ module ActiveRecord
|
|
116
85
|
def sanitize_sql_hash_for_assignment(attrs, table)
|
117
86
|
c = connection
|
118
87
|
attrs.map do |attr, value|
|
119
|
-
|
120
|
-
|
121
|
-
ActiveSupport::Deprecation.warn(<<-WARNING.squish)
|
122
|
-
Passing `ActiveRecord::Base` objects to
|
123
|
-
`sanitize_sql_hash_for_assignment` (or methods which call it,
|
124
|
-
such as `update_all`) is deprecated. Please pass the id directly,
|
125
|
-
instead.
|
126
|
-
WARNING
|
127
|
-
else
|
128
|
-
value = type_for_attribute(attr.to_s).serialize(value)
|
129
|
-
end
|
88
|
+
type = type_for_attribute(attr)
|
89
|
+
value = type.serialize(type.cast(value))
|
130
90
|
"#{c.quote_table_name_for_assignment(table, attr)} = #{c.quote(value)}"
|
131
|
-
end.join(
|
91
|
+
end.join(", ")
|
132
92
|
end
|
133
93
|
|
134
94
|
# Sanitizes a +string+ so that it is safe to use within an SQL
|
@@ -163,9 +123,9 @@ module ActiveRecord
|
|
163
123
|
# # => "name='foo''bar' and group_id='4'"
|
164
124
|
def sanitize_sql_array(ary)
|
165
125
|
statement, *values = ary
|
166
|
-
if values.first.is_a?(Hash) &&
|
126
|
+
if values.first.is_a?(Hash) && /:\w+/.match?(statement)
|
167
127
|
replace_named_bind_variables(statement, values.first)
|
168
|
-
elsif statement.include?(
|
128
|
+
elsif statement.include?("?")
|
169
129
|
replace_bind_variables(statement, values)
|
170
130
|
elsif statement.blank?
|
171
131
|
statement
|
@@ -174,57 +134,81 @@ module ActiveRecord
|
|
174
134
|
end
|
175
135
|
end
|
176
136
|
|
177
|
-
def
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
replace_bind_variable(bound.shift, c)
|
137
|
+
def disallow_raw_sql!(args, permit: connection.column_name_matcher) # :nodoc:
|
138
|
+
unexpected = nil
|
139
|
+
args.each do |arg|
|
140
|
+
next if arg.is_a?(Symbol) || Arel.arel_node?(arg) || permit.match?(arg.to_s)
|
141
|
+
(unexpected ||= []) << arg
|
183
142
|
end
|
184
|
-
end
|
185
143
|
|
186
|
-
|
187
|
-
|
188
|
-
|
144
|
+
return unless unexpected
|
145
|
+
|
146
|
+
if allow_unsafe_raw_sql == :deprecated
|
147
|
+
ActiveSupport::Deprecation.warn(
|
148
|
+
"Dangerous query method (method whose arguments are used as raw " \
|
149
|
+
"SQL) called with non-attribute argument(s): " \
|
150
|
+
"#{unexpected.map(&:inspect).join(", ")}. Non-attribute " \
|
151
|
+
"arguments will be disallowed in Rails 6.1. This method should " \
|
152
|
+
"not be called with user-provided values, such as request " \
|
153
|
+
"parameters or model attributes. Known-safe values can be passed " \
|
154
|
+
"by wrapping them in Arel.sql()."
|
155
|
+
)
|
189
156
|
else
|
190
|
-
|
157
|
+
raise(ActiveRecord::UnknownAttributeReference,
|
158
|
+
"Query method called with non-attribute argument(s): " +
|
159
|
+
unexpected.map(&:inspect).join(", ")
|
160
|
+
)
|
191
161
|
end
|
192
162
|
end
|
193
163
|
|
194
|
-
|
195
|
-
statement
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
raise PreparedStatementInvalid, "missing value for :#{match} in #{statement}"
|
164
|
+
private
|
165
|
+
def replace_bind_variables(statement, values)
|
166
|
+
raise_if_bind_arity_mismatch(statement, statement.count("?"), values.size)
|
167
|
+
bound = values.dup
|
168
|
+
c = connection
|
169
|
+
statement.gsub(/\?/) do
|
170
|
+
replace_bind_variable(bound.shift, c)
|
202
171
|
end
|
203
172
|
end
|
204
|
-
end
|
205
173
|
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
c.quote(nil)
|
174
|
+
def replace_bind_variable(value, c = connection)
|
175
|
+
if ActiveRecord::Relation === value
|
176
|
+
value.to_sql
|
210
177
|
else
|
211
|
-
value
|
178
|
+
quote_bound_value(value, c)
|
212
179
|
end
|
213
|
-
else
|
214
|
-
c.quote(value)
|
215
180
|
end
|
216
|
-
end
|
217
181
|
|
218
|
-
|
219
|
-
|
220
|
-
|
182
|
+
def replace_named_bind_variables(statement, bind_vars)
|
183
|
+
statement.gsub(/(:?):([a-zA-Z]\w*)/) do |match|
|
184
|
+
if $1 == ":" # skip postgresql casts
|
185
|
+
match # return the whole match
|
186
|
+
elsif bind_vars.include?(match = $2.to_sym)
|
187
|
+
replace_bind_variable(bind_vars[match])
|
188
|
+
else
|
189
|
+
raise PreparedStatementInvalid, "missing value for :#{match} in #{statement}"
|
190
|
+
end
|
191
|
+
end
|
221
192
|
end
|
222
|
-
end
|
223
|
-
end
|
224
193
|
|
225
|
-
|
226
|
-
|
227
|
-
|
194
|
+
def quote_bound_value(value, c = connection)
|
195
|
+
if value.respond_to?(:map) && !value.acts_like?(:string)
|
196
|
+
quoted = value.map { |v| c.quote(v) }
|
197
|
+
if quoted.empty?
|
198
|
+
c.quote(nil)
|
199
|
+
else
|
200
|
+
quoted.join(",")
|
201
|
+
end
|
202
|
+
else
|
203
|
+
c.quote(value)
|
204
|
+
end
|
205
|
+
end
|
206
|
+
|
207
|
+
def raise_if_bind_arity_mismatch(statement, expected, provided)
|
208
|
+
unless expected == provided
|
209
|
+
raise PreparedStatementInvalid, "wrong number of bind variables (#{provided} for #{expected}) in: #{statement}"
|
210
|
+
end
|
211
|
+
end
|
228
212
|
end
|
229
213
|
end
|
230
214
|
end
|
data/lib/active_record/schema.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module ActiveRecord
|
2
4
|
# = Active Record \Schema
|
3
5
|
#
|
@@ -37,10 +39,10 @@ module ActiveRecord
|
|
37
39
|
# The +info+ hash is optional, and if given is used to define metadata
|
38
40
|
# about the current schema (currently, only the schema's version):
|
39
41
|
#
|
40
|
-
# ActiveRecord::Schema.define(version:
|
42
|
+
# ActiveRecord::Schema.define(version: 2038_01_19_000001) do
|
41
43
|
# ...
|
42
44
|
# end
|
43
|
-
def self.define(info={}, &block)
|
45
|
+
def self.define(info = {}, &block)
|
44
46
|
new.define(info, &block)
|
45
47
|
end
|
46
48
|
|
@@ -48,21 +50,12 @@ module ActiveRecord
|
|
48
50
|
instance_eval(&block)
|
49
51
|
|
50
52
|
if info[:version].present?
|
51
|
-
|
52
|
-
connection.assume_migrated_upto_version(info[:version]
|
53
|
+
connection.schema_migration.create_table
|
54
|
+
connection.assume_migrated_upto_version(info[:version])
|
53
55
|
end
|
54
56
|
|
55
57
|
ActiveRecord::InternalMetadata.create_table
|
56
|
-
ActiveRecord::InternalMetadata[:environment] =
|
58
|
+
ActiveRecord::InternalMetadata[:environment] = connection.migration_context.current_environment
|
57
59
|
end
|
58
|
-
|
59
|
-
private
|
60
|
-
# Returns the migrations paths.
|
61
|
-
#
|
62
|
-
# ActiveRecord::Schema.new.migrations_paths
|
63
|
-
# # => ["db/migrate"] # Rails migration path by default.
|
64
|
-
def migrations_paths # :nodoc:
|
65
|
-
ActiveRecord::Migrator.migrations_paths
|
66
|
-
end
|
67
60
|
end
|
68
61
|
end
|