activerecord 5.0.7.2 → 6.1.1
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of activerecord might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/CHANGELOG.md +829 -2015
- data/MIT-LICENSE +3 -1
- data/README.rdoc +11 -9
- data/examples/performance.rb +31 -29
- data/examples/simple.rb +5 -3
- data/lib/active_record.rb +37 -29
- data/lib/active_record/aggregations.rb +249 -247
- data/lib/active_record/association_relation.rb +30 -18
- data/lib/active_record/associations.rb +1714 -1596
- data/lib/active_record/associations/alias_tracker.rb +36 -42
- data/lib/active_record/associations/association.rb +143 -68
- data/lib/active_record/associations/association_scope.rb +98 -94
- data/lib/active_record/associations/belongs_to_association.rb +76 -46
- data/lib/active_record/associations/belongs_to_polymorphic_association.rb +13 -12
- data/lib/active_record/associations/builder/association.rb +27 -28
- data/lib/active_record/associations/builder/belongs_to.rb +52 -60
- data/lib/active_record/associations/builder/collection_association.rb +12 -22
- data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +40 -62
- data/lib/active_record/associations/builder/has_many.rb +10 -2
- data/lib/active_record/associations/builder/has_one.rb +35 -2
- data/lib/active_record/associations/builder/singular_association.rb +5 -1
- data/lib/active_record/associations/collection_association.rb +104 -259
- data/lib/active_record/associations/collection_proxy.rb +169 -125
- data/lib/active_record/associations/foreign_association.rb +22 -0
- data/lib/active_record/associations/has_many_association.rb +46 -31
- data/lib/active_record/associations/has_many_through_association.rb +66 -46
- data/lib/active_record/associations/has_one_association.rb +71 -52
- data/lib/active_record/associations/has_one_through_association.rb +20 -11
- data/lib/active_record/associations/join_dependency.rb +169 -180
- data/lib/active_record/associations/join_dependency/join_association.rb +53 -79
- data/lib/active_record/associations/join_dependency/join_base.rb +10 -9
- data/lib/active_record/associations/join_dependency/join_part.rb +14 -14
- data/lib/active_record/associations/preloader.rb +97 -104
- data/lib/active_record/associations/preloader/association.rb +109 -97
- data/lib/active_record/associations/preloader/through_association.rb +77 -76
- data/lib/active_record/associations/singular_association.rb +12 -45
- data/lib/active_record/associations/through_association.rb +27 -15
- data/lib/active_record/attribute_assignment.rb +55 -60
- data/lib/active_record/attribute_methods.rb +111 -141
- data/lib/active_record/attribute_methods/before_type_cast.rb +17 -9
- data/lib/active_record/attribute_methods/dirty.rb +172 -112
- data/lib/active_record/attribute_methods/primary_key.rb +88 -91
- data/lib/active_record/attribute_methods/query.rb +6 -8
- data/lib/active_record/attribute_methods/read.rb +18 -50
- data/lib/active_record/attribute_methods/serialization.rb +38 -10
- data/lib/active_record/attribute_methods/time_zone_conversion.rb +38 -66
- data/lib/active_record/attribute_methods/write.rb +25 -32
- data/lib/active_record/attributes.rb +69 -31
- data/lib/active_record/autosave_association.rb +102 -66
- data/lib/active_record/base.rb +16 -25
- data/lib/active_record/callbacks.rb +202 -43
- data/lib/active_record/coders/json.rb +2 -0
- data/lib/active_record/coders/yaml_column.rb +11 -12
- data/lib/active_record/connection_adapters.rb +50 -0
- data/lib/active_record/connection_adapters/abstract/connection_pool.rb +661 -375
- data/lib/active_record/connection_adapters/abstract/database_limits.rb +14 -38
- data/lib/active_record/connection_adapters/abstract/database_statements.rb +269 -105
- data/lib/active_record/connection_adapters/abstract/query_cache.rb +54 -35
- data/lib/active_record/connection_adapters/abstract/quoting.rb +137 -93
- data/lib/active_record/connection_adapters/abstract/savepoints.rb +5 -3
- data/lib/active_record/connection_adapters/abstract/schema_creation.rb +155 -113
- data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +328 -162
- data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +68 -80
- data/lib/active_record/connection_adapters/abstract/schema_statements.rb +591 -259
- data/lib/active_record/connection_adapters/abstract/transaction.rb +229 -91
- data/lib/active_record/connection_adapters/abstract_adapter.rb +392 -244
- data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +457 -582
- data/lib/active_record/connection_adapters/column.rb +55 -13
- data/lib/active_record/connection_adapters/deduplicable.rb +29 -0
- data/lib/active_record/connection_adapters/legacy_pool_manager.rb +31 -0
- data/lib/active_record/connection_adapters/mysql/column.rb +8 -31
- data/lib/active_record/connection_adapters/mysql/database_statements.rb +135 -49
- data/lib/active_record/connection_adapters/mysql/explain_pretty_printer.rb +24 -23
- data/lib/active_record/connection_adapters/mysql/quoting.rb +50 -20
- data/lib/active_record/connection_adapters/mysql/schema_creation.rb +79 -49
- data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +66 -56
- data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +70 -36
- data/lib/active_record/connection_adapters/mysql/schema_statements.rb +268 -0
- data/lib/active_record/connection_adapters/mysql/type_metadata.rb +20 -12
- data/lib/active_record/connection_adapters/mysql2_adapter.rb +74 -37
- data/lib/active_record/connection_adapters/pool_config.rb +63 -0
- data/lib/active_record/connection_adapters/pool_manager.rb +43 -0
- data/lib/active_record/connection_adapters/postgresql/column.rb +39 -28
- data/lib/active_record/connection_adapters/postgresql/database_statements.rb +70 -101
- data/lib/active_record/connection_adapters/postgresql/explain_pretty_printer.rb +5 -3
- data/lib/active_record/connection_adapters/postgresql/oid.rb +26 -21
- data/lib/active_record/connection_adapters/postgresql/oid/array.rb +22 -11
- data/lib/active_record/connection_adapters/postgresql/oid/bit.rb +6 -5
- data/lib/active_record/connection_adapters/postgresql/oid/bit_varying.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/oid/bytea.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/oid/cidr.rb +6 -6
- data/lib/active_record/connection_adapters/postgresql/oid/date.rb +23 -0
- data/lib/active_record/connection_adapters/postgresql/oid/date_time.rb +14 -4
- data/lib/active_record/connection_adapters/postgresql/oid/decimal.rb +3 -1
- data/lib/active_record/connection_adapters/postgresql/oid/enum.rb +5 -4
- data/lib/active_record/connection_adapters/postgresql/oid/hstore.rb +19 -18
- data/lib/active_record/connection_adapters/postgresql/oid/inet.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/oid/interval.rb +49 -0
- data/lib/active_record/connection_adapters/postgresql/oid/jsonb.rb +3 -11
- data/lib/active_record/connection_adapters/postgresql/oid/legacy_point.rb +44 -0
- data/lib/active_record/connection_adapters/postgresql/oid/macaddr.rb +25 -0
- data/lib/active_record/connection_adapters/postgresql/oid/money.rb +7 -5
- data/lib/active_record/connection_adapters/postgresql/oid/{json.rb → oid.rb} +6 -1
- data/lib/active_record/connection_adapters/postgresql/oid/point.rb +30 -9
- data/lib/active_record/connection_adapters/postgresql/oid/range.rb +52 -30
- data/lib/active_record/connection_adapters/postgresql/oid/specialized_string.rb +4 -1
- data/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb +58 -54
- data/lib/active_record/connection_adapters/postgresql/oid/uuid.rb +18 -4
- data/lib/active_record/connection_adapters/postgresql/oid/vector.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/oid/xml.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/quoting.rb +98 -38
- data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +21 -27
- data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +80 -0
- data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +147 -105
- data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +34 -32
- data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +426 -324
- data/lib/active_record/connection_adapters/postgresql/type_metadata.rb +32 -23
- data/lib/active_record/connection_adapters/postgresql/utils.rb +9 -6
- data/lib/active_record/connection_adapters/postgresql_adapter.rb +418 -293
- data/lib/active_record/connection_adapters/schema_cache.rb +135 -18
- data/lib/active_record/connection_adapters/sql_type_metadata.rb +22 -7
- data/lib/active_record/connection_adapters/sqlite3/database_statements.rb +144 -0
- data/lib/active_record/connection_adapters/sqlite3/explain_pretty_printer.rb +3 -1
- data/lib/active_record/connection_adapters/sqlite3/quoting.rb +72 -18
- data/lib/active_record/connection_adapters/sqlite3/schema_creation.rb +5 -6
- data/lib/active_record/connection_adapters/sqlite3/schema_definitions.rb +19 -0
- data/lib/active_record/connection_adapters/sqlite3/schema_dumper.rb +18 -0
- data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +170 -0
- data/lib/active_record/connection_adapters/sqlite3_adapter.rb +282 -290
- data/lib/active_record/connection_adapters/statement_pool.rb +9 -8
- data/lib/active_record/connection_handling.rb +287 -45
- data/lib/active_record/core.rb +385 -181
- data/lib/active_record/counter_cache.rb +60 -28
- data/lib/active_record/database_configurations.rb +272 -0
- data/lib/active_record/database_configurations/connection_url_resolver.rb +98 -0
- data/lib/active_record/database_configurations/database_config.rb +80 -0
- data/lib/active_record/database_configurations/hash_config.rb +96 -0
- data/lib/active_record/database_configurations/url_config.rb +53 -0
- data/lib/active_record/delegated_type.rb +209 -0
- data/lib/active_record/destroy_association_async_job.rb +36 -0
- data/lib/active_record/dynamic_matchers.rb +87 -87
- data/lib/active_record/enum.rb +122 -47
- data/lib/active_record/errors.rb +153 -22
- data/lib/active_record/explain.rb +13 -8
- data/lib/active_record/explain_registry.rb +3 -1
- data/lib/active_record/explain_subscriber.rb +9 -4
- data/lib/active_record/fixture_set/file.rb +20 -22
- data/lib/active_record/fixture_set/model_metadata.rb +32 -0
- data/lib/active_record/fixture_set/render_context.rb +17 -0
- data/lib/active_record/fixture_set/table_row.rb +152 -0
- data/lib/active_record/fixture_set/table_rows.rb +46 -0
- data/lib/active_record/fixtures.rb +246 -507
- data/lib/active_record/gem_version.rb +6 -4
- data/lib/active_record/inheritance.rb +168 -95
- data/lib/active_record/insert_all.rb +208 -0
- data/lib/active_record/integration.rb +114 -25
- data/lib/active_record/internal_metadata.rb +30 -24
- data/lib/active_record/legacy_yaml_adapter.rb +11 -5
- data/lib/active_record/locking/optimistic.rb +81 -85
- data/lib/active_record/locking/pessimistic.rb +22 -6
- data/lib/active_record/log_subscriber.rb +68 -31
- data/lib/active_record/middleware/database_selector.rb +77 -0
- data/lib/active_record/middleware/database_selector/resolver.rb +92 -0
- data/lib/active_record/middleware/database_selector/resolver/session.rb +48 -0
- data/lib/active_record/migration.rb +439 -342
- data/lib/active_record/migration/command_recorder.rb +152 -98
- data/lib/active_record/migration/compatibility.rb +229 -60
- data/lib/active_record/migration/join_table.rb +8 -7
- data/lib/active_record/model_schema.rb +230 -122
- data/lib/active_record/nested_attributes.rb +213 -203
- data/lib/active_record/no_touching.rb +11 -2
- data/lib/active_record/null_relation.rb +12 -34
- data/lib/active_record/persistence.rb +471 -97
- data/lib/active_record/query_cache.rb +23 -12
- data/lib/active_record/querying.rb +43 -25
- data/lib/active_record/railtie.rb +155 -43
- data/lib/active_record/railties/console_sandbox.rb +2 -0
- data/lib/active_record/railties/controller_runtime.rb +34 -33
- data/lib/active_record/railties/databases.rake +507 -195
- data/lib/active_record/readonly_attributes.rb +9 -4
- data/lib/active_record/reflection.rb +245 -269
- data/lib/active_record/relation.rb +475 -324
- data/lib/active_record/relation/batches.rb +125 -72
- data/lib/active_record/relation/batches/batch_enumerator.rb +28 -10
- data/lib/active_record/relation/calculations.rb +267 -171
- data/lib/active_record/relation/delegation.rb +73 -69
- data/lib/active_record/relation/finder_methods.rb +238 -248
- data/lib/active_record/relation/from_clause.rb +7 -9
- data/lib/active_record/relation/merger.rb +95 -77
- data/lib/active_record/relation/predicate_builder.rb +109 -110
- data/lib/active_record/relation/predicate_builder/array_handler.rb +22 -17
- data/lib/active_record/relation/predicate_builder/association_query_value.rb +42 -0
- data/lib/active_record/relation/predicate_builder/basic_object_handler.rb +6 -4
- data/lib/active_record/relation/predicate_builder/polymorphic_array_value.rb +55 -0
- data/lib/active_record/relation/predicate_builder/range_handler.rb +7 -18
- data/lib/active_record/relation/predicate_builder/relation_handler.rb +7 -1
- data/lib/active_record/relation/query_attribute.rb +33 -2
- data/lib/active_record/relation/query_methods.rb +654 -374
- data/lib/active_record/relation/record_fetch_warning.rb +8 -6
- data/lib/active_record/relation/spawn_methods.rb +15 -14
- data/lib/active_record/relation/where_clause.rb +171 -109
- data/lib/active_record/result.rb +88 -51
- data/lib/active_record/runtime_registry.rb +5 -3
- data/lib/active_record/sanitization.rb +73 -100
- data/lib/active_record/schema.rb +7 -14
- data/lib/active_record/schema_dumper.rb +101 -69
- data/lib/active_record/schema_migration.rb +16 -12
- data/lib/active_record/scoping.rb +20 -20
- data/lib/active_record/scoping/default.rb +92 -95
- data/lib/active_record/scoping/named.rb +39 -30
- data/lib/active_record/secure_token.rb +19 -9
- data/lib/active_record/serialization.rb +7 -3
- data/lib/active_record/signed_id.rb +116 -0
- data/lib/active_record/statement_cache.rb +80 -29
- data/lib/active_record/store.rb +122 -42
- data/lib/active_record/suppressor.rb +6 -3
- data/lib/active_record/table_metadata.rb +51 -39
- data/lib/active_record/tasks/database_tasks.rb +332 -115
- data/lib/active_record/tasks/mysql_database_tasks.rb +66 -104
- data/lib/active_record/tasks/postgresql_database_tasks.rb +84 -56
- data/lib/active_record/tasks/sqlite_database_tasks.rb +40 -19
- data/lib/active_record/test_databases.rb +24 -0
- data/lib/active_record/test_fixtures.rb +246 -0
- data/lib/active_record/timestamp.rb +70 -38
- data/lib/active_record/touch_later.rb +26 -24
- data/lib/active_record/transactions.rb +121 -184
- data/lib/active_record/translation.rb +3 -1
- data/lib/active_record/type.rb +29 -17
- data/lib/active_record/type/adapter_specific_registry.rb +44 -48
- data/lib/active_record/type/date.rb +2 -0
- data/lib/active_record/type/date_time.rb +2 -0
- data/lib/active_record/type/decimal_without_scale.rb +15 -0
- data/lib/active_record/type/hash_lookup_type_map.rb +5 -4
- data/lib/active_record/type/internal/timezone.rb +2 -0
- data/lib/active_record/type/json.rb +30 -0
- data/lib/active_record/type/serialized.rb +20 -9
- data/lib/active_record/type/text.rb +11 -0
- data/lib/active_record/type/time.rb +12 -1
- data/lib/active_record/type/type_map.rb +14 -17
- data/lib/active_record/type/unsigned_integer.rb +16 -0
- data/lib/active_record/type_caster.rb +4 -2
- data/lib/active_record/type_caster/connection.rb +17 -13
- data/lib/active_record/type_caster/map.rb +10 -6
- data/lib/active_record/validations.rb +8 -5
- data/lib/active_record/validations/absence.rb +2 -0
- data/lib/active_record/validations/associated.rb +4 -3
- data/lib/active_record/validations/length.rb +2 -0
- data/lib/active_record/validations/numericality.rb +35 -0
- data/lib/active_record/validations/presence.rb +4 -2
- data/lib/active_record/validations/uniqueness.rb +52 -45
- data/lib/active_record/version.rb +3 -1
- data/lib/arel.rb +54 -0
- data/lib/arel/alias_predication.rb +9 -0
- data/lib/arel/attributes/attribute.rb +41 -0
- data/lib/arel/collectors/bind.rb +29 -0
- data/lib/arel/collectors/composite.rb +39 -0
- data/lib/arel/collectors/plain_string.rb +20 -0
- data/lib/arel/collectors/sql_string.rb +27 -0
- data/lib/arel/collectors/substitute_binds.rb +35 -0
- data/lib/arel/crud.rb +42 -0
- data/lib/arel/delete_manager.rb +18 -0
- data/lib/arel/errors.rb +9 -0
- data/lib/arel/expressions.rb +29 -0
- data/lib/arel/factory_methods.rb +49 -0
- data/lib/arel/insert_manager.rb +49 -0
- data/lib/arel/math.rb +45 -0
- data/lib/arel/nodes.rb +70 -0
- data/lib/arel/nodes/and.rb +32 -0
- data/lib/arel/nodes/ascending.rb +23 -0
- data/lib/arel/nodes/binary.rb +126 -0
- data/lib/arel/nodes/bind_param.rb +44 -0
- data/lib/arel/nodes/case.rb +55 -0
- data/lib/arel/nodes/casted.rb +62 -0
- data/lib/arel/nodes/comment.rb +29 -0
- data/lib/arel/nodes/count.rb +12 -0
- data/lib/arel/nodes/delete_statement.rb +45 -0
- data/lib/arel/nodes/descending.rb +23 -0
- data/lib/arel/nodes/equality.rb +15 -0
- data/lib/arel/nodes/extract.rb +24 -0
- data/lib/arel/nodes/false.rb +16 -0
- data/lib/arel/nodes/full_outer_join.rb +8 -0
- data/lib/arel/nodes/function.rb +44 -0
- data/lib/arel/nodes/grouping.rb +11 -0
- data/lib/arel/nodes/homogeneous_in.rb +72 -0
- data/lib/arel/nodes/in.rb +15 -0
- data/lib/arel/nodes/infix_operation.rb +92 -0
- data/lib/arel/nodes/inner_join.rb +8 -0
- data/lib/arel/nodes/insert_statement.rb +37 -0
- data/lib/arel/nodes/join_source.rb +20 -0
- data/lib/arel/nodes/matches.rb +18 -0
- data/lib/arel/nodes/named_function.rb +23 -0
- data/lib/arel/nodes/node.rb +51 -0
- data/lib/arel/nodes/node_expression.rb +13 -0
- data/lib/arel/nodes/ordering.rb +27 -0
- data/lib/arel/nodes/outer_join.rb +8 -0
- data/lib/arel/nodes/over.rb +15 -0
- data/lib/arel/nodes/regexp.rb +16 -0
- data/lib/arel/nodes/right_outer_join.rb +8 -0
- data/lib/arel/nodes/select_core.rb +67 -0
- data/lib/arel/nodes/select_statement.rb +41 -0
- data/lib/arel/nodes/sql_literal.rb +19 -0
- data/lib/arel/nodes/string_join.rb +11 -0
- data/lib/arel/nodes/table_alias.rb +31 -0
- data/lib/arel/nodes/terminal.rb +16 -0
- data/lib/arel/nodes/true.rb +16 -0
- data/lib/arel/nodes/unary.rb +44 -0
- data/lib/arel/nodes/unary_operation.rb +20 -0
- data/lib/arel/nodes/unqualified_column.rb +22 -0
- data/lib/arel/nodes/update_statement.rb +41 -0
- data/lib/arel/nodes/values_list.rb +9 -0
- data/lib/arel/nodes/window.rb +126 -0
- data/lib/arel/nodes/with.rb +11 -0
- data/lib/arel/order_predications.rb +13 -0
- data/lib/arel/predications.rb +250 -0
- data/lib/arel/select_manager.rb +270 -0
- data/lib/arel/table.rb +118 -0
- data/lib/arel/tree_manager.rb +72 -0
- data/lib/arel/update_manager.rb +34 -0
- data/lib/arel/visitors.rb +13 -0
- data/lib/arel/visitors/dot.rb +308 -0
- data/lib/arel/visitors/mysql.rb +93 -0
- data/lib/arel/visitors/postgresql.rb +120 -0
- data/lib/arel/visitors/sqlite.rb +38 -0
- data/lib/arel/visitors/to_sql.rb +899 -0
- data/lib/arel/visitors/visitor.rb +45 -0
- data/lib/arel/window_predications.rb +9 -0
- data/lib/rails/generators/active_record.rb +7 -5
- data/lib/rails/generators/active_record/application_record/application_record_generator.rb +26 -0
- data/lib/rails/generators/active_record/{model/templates/application_record.rb → application_record/templates/application_record.rb.tt} +0 -0
- data/lib/rails/generators/active_record/migration.rb +22 -3
- data/lib/rails/generators/active_record/migration/migration_generator.rb +38 -35
- data/lib/rails/generators/active_record/migration/templates/{create_table_migration.rb → create_table_migration.rb.tt} +3 -1
- data/lib/rails/generators/active_record/migration/templates/{migration.rb → migration.rb.tt} +7 -5
- data/lib/rails/generators/active_record/model/model_generator.rb +41 -25
- data/lib/rails/generators/active_record/model/templates/abstract_base_class.rb.tt +7 -0
- data/lib/rails/generators/active_record/model/templates/{model.rb → model.rb.tt} +10 -1
- data/lib/rails/generators/active_record/model/templates/{module.rb → module.rb.tt} +0 -0
- metadata +141 -57
- data/lib/active_record/associations/preloader/belongs_to.rb +0 -17
- data/lib/active_record/associations/preloader/collection_association.rb +0 -17
- data/lib/active_record/associations/preloader/has_many.rb +0 -17
- data/lib/active_record/associations/preloader/has_many_through.rb +0 -19
- data/lib/active_record/associations/preloader/has_one.rb +0 -15
- data/lib/active_record/associations/preloader/has_one_through.rb +0 -9
- data/lib/active_record/associations/preloader/singular_association.rb +0 -20
- data/lib/active_record/attribute.rb +0 -213
- data/lib/active_record/attribute/user_provided_default.rb +0 -28
- data/lib/active_record/attribute_decorators.rb +0 -67
- data/lib/active_record/attribute_mutation_tracker.rb +0 -70
- data/lib/active_record/attribute_set.rb +0 -110
- data/lib/active_record/attribute_set/builder.rb +0 -132
- data/lib/active_record/collection_cache_key.rb +0 -50
- data/lib/active_record/connection_adapters/connection_specification.rb +0 -263
- data/lib/active_record/connection_adapters/determine_if_preparable_visitor.rb +0 -22
- data/lib/active_record/connection_adapters/postgresql/oid/rails_5_1_point.rb +0 -50
- data/lib/active_record/railties/jdbcmysql_error.rb +0 -16
- data/lib/active_record/relation/predicate_builder/association_query_handler.rb +0 -88
- data/lib/active_record/relation/predicate_builder/base_handler.rb +0 -17
- data/lib/active_record/relation/predicate_builder/class_handler.rb +0 -27
- data/lib/active_record/relation/predicate_builder/polymorphic_array_handler.rb +0 -57
- data/lib/active_record/relation/where_clause_factory.rb +0 -38
- data/lib/active_record/type/internal/abstract_json.rb +0 -33
@@ -1,9 +1,14 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "concurrent/map"
|
4
|
+
|
1
5
|
module ActiveRecord
|
2
6
|
module ConnectionAdapters # :nodoc:
|
3
7
|
module QueryCache
|
4
8
|
class << self
|
5
9
|
def included(base) #:nodoc:
|
6
|
-
dirties_query_cache base, :insert, :update, :delete, :
|
10
|
+
dirties_query_cache base, :insert, :update, :delete, :truncate, :truncate_tables,
|
11
|
+
:rollback_to_savepoint, :rollback_db_transaction, :exec_insert_all
|
7
12
|
|
8
13
|
base.set_callback :checkout, :after, :configure_query_cache!
|
9
14
|
base.set_callback :checkin, :after, :disable_query_cache!
|
@@ -13,7 +18,7 @@ module ActiveRecord
|
|
13
18
|
method_names.each do |method_name|
|
14
19
|
base.class_eval <<-end_code, __FILE__, __LINE__ + 1
|
15
20
|
def #{method_name}(*)
|
16
|
-
|
21
|
+
ActiveRecord::Base.clear_query_caches_for_current_thread
|
17
22
|
super
|
18
23
|
end
|
19
24
|
end_code
|
@@ -28,17 +33,17 @@ module ActiveRecord
|
|
28
33
|
end
|
29
34
|
|
30
35
|
def enable_query_cache!
|
31
|
-
@query_cache_enabled[connection_cache_key(
|
36
|
+
@query_cache_enabled[connection_cache_key(current_thread)] = true
|
32
37
|
connection.enable_query_cache! if active_connection?
|
33
38
|
end
|
34
39
|
|
35
40
|
def disable_query_cache!
|
36
|
-
@query_cache_enabled.delete connection_cache_key(
|
41
|
+
@query_cache_enabled.delete connection_cache_key(current_thread)
|
37
42
|
connection.disable_query_cache! if active_connection?
|
38
43
|
end
|
39
44
|
|
40
45
|
def query_cache_enabled
|
41
|
-
@query_cache_enabled[connection_cache_key(
|
46
|
+
@query_cache_enabled[connection_cache_key(current_thread)]
|
42
47
|
end
|
43
48
|
end
|
44
49
|
|
@@ -46,7 +51,7 @@ module ActiveRecord
|
|
46
51
|
|
47
52
|
def initialize(*)
|
48
53
|
super
|
49
|
-
@query_cache = Hash.new { |h,sql| h[sql] = {} }
|
54
|
+
@query_cache = Hash.new { |h, sql| h[sql] = {} }
|
50
55
|
@query_cache_enabled = false
|
51
56
|
end
|
52
57
|
|
@@ -83,48 +88,62 @@ module ActiveRecord
|
|
83
88
|
# the same SQL query and repeatedly return the same result each time, silently
|
84
89
|
# undermining the randomness you were expecting.
|
85
90
|
def clear_query_cache
|
86
|
-
@
|
91
|
+
@lock.synchronize do
|
92
|
+
@query_cache.clear
|
93
|
+
end
|
87
94
|
end
|
88
95
|
|
89
96
|
def select_all(arel, name = nil, binds = [], preparable: nil)
|
90
97
|
if @query_cache_enabled && !locked?(arel)
|
91
|
-
arel
|
92
|
-
sql =
|
93
|
-
|
98
|
+
arel = arel_from_relation(arel)
|
99
|
+
sql, binds, preparable = to_sql_and_binds(arel, binds, preparable)
|
100
|
+
|
101
|
+
cache_sql(sql, name, binds) { super(sql, name, binds, preparable: preparable) }
|
94
102
|
else
|
95
103
|
super
|
96
104
|
end
|
97
105
|
end
|
98
106
|
|
99
107
|
private
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
else
|
114
|
-
@query_cache[sql][binds] = yield
|
108
|
+
def cache_sql(sql, name, binds)
|
109
|
+
@lock.synchronize do
|
110
|
+
result =
|
111
|
+
if @query_cache[sql].key?(binds)
|
112
|
+
ActiveSupport::Notifications.instrument(
|
113
|
+
"sql.active_record",
|
114
|
+
cache_notification_info(sql, name, binds)
|
115
|
+
)
|
116
|
+
@query_cache[sql][binds]
|
117
|
+
else
|
118
|
+
@query_cache[sql][binds] = yield
|
119
|
+
end
|
120
|
+
result.dup
|
115
121
|
end
|
116
|
-
|
117
|
-
end
|
122
|
+
end
|
118
123
|
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
+
# Database adapters can override this method to
|
125
|
+
# provide custom cache information.
|
126
|
+
def cache_notification_info(sql, name, binds)
|
127
|
+
{
|
128
|
+
sql: sql,
|
129
|
+
binds: binds,
|
130
|
+
type_casted_binds: -> { type_casted_binds(binds) },
|
131
|
+
name: name,
|
132
|
+
connection: self,
|
133
|
+
cached: true
|
134
|
+
}
|
135
|
+
end
|
124
136
|
|
125
|
-
|
126
|
-
|
127
|
-
|
137
|
+
# If arel is locked this is a SELECT ... FOR UPDATE or somesuch. Such
|
138
|
+
# queries should not be cached.
|
139
|
+
def locked?(arel)
|
140
|
+
arel = arel.arel if arel.is_a?(Relation)
|
141
|
+
arel.respond_to?(:locked) && arel.locked
|
142
|
+
end
|
143
|
+
|
144
|
+
def configure_query_cache!
|
145
|
+
enable_query_cache! if pool.query_cache_enabled
|
146
|
+
end
|
128
147
|
end
|
129
148
|
end
|
130
149
|
end
|
@@ -1,23 +1,20 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "active_support/core_ext/big_decimal/conversions"
|
2
4
|
require "active_support/multibyte/chars"
|
3
5
|
|
4
6
|
module ActiveRecord
|
5
7
|
module ConnectionAdapters # :nodoc:
|
6
8
|
module Quoting
|
7
9
|
# Quotes the column value to help prevent
|
8
|
-
# {SQL injection attacks}[
|
9
|
-
def quote(value
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
ActiveSupport::Deprecation.warn(<<-MSG.squish)
|
15
|
-
Passing a column to `quote` has been deprecated. It is only used
|
16
|
-
for type casting, which should be handled elsewhere. See
|
17
|
-
https://github.com/rails/arel/commit/6160bfbda1d1781c3b08a33ec4955f170e95be11
|
18
|
-
for more information.
|
10
|
+
# {SQL injection attacks}[https://en.wikipedia.org/wiki/SQL_injection].
|
11
|
+
def quote(value)
|
12
|
+
if value.is_a?(Base)
|
13
|
+
ActiveSupport::Deprecation.warn(<<~MSG)
|
14
|
+
Passing an Active Record object to `quote` directly is deprecated
|
15
|
+
and will be no longer quoted as id value in Rails 6.2.
|
19
16
|
MSG
|
20
|
-
value =
|
17
|
+
value = value.id_for_database
|
21
18
|
end
|
22
19
|
|
23
20
|
_quote(value)
|
@@ -27,18 +24,23 @@ module ActiveRecord
|
|
27
24
|
# SQLite does not understand dates, so this method will convert a Date
|
28
25
|
# to a String.
|
29
26
|
def type_cast(value, column = nil)
|
30
|
-
if value.
|
31
|
-
|
27
|
+
if value.is_a?(Base)
|
28
|
+
ActiveSupport::Deprecation.warn(<<~MSG)
|
29
|
+
Passing an Active Record object to `type_cast` directly is deprecated
|
30
|
+
and will be no longer type casted as id value in Rails 6.2.
|
31
|
+
MSG
|
32
|
+
value = value.id_for_database
|
32
33
|
end
|
33
34
|
|
34
35
|
if column
|
35
|
-
|
36
|
+
ActiveSupport::Deprecation.warn(<<~MSG)
|
37
|
+
Passing a column to `type_cast` is deprecated and will be removed in Rails 6.2.
|
38
|
+
MSG
|
39
|
+
type = lookup_cast_type_from_column(column)
|
40
|
+
value = type.serialize(value)
|
36
41
|
end
|
37
42
|
|
38
43
|
_type_cast(value)
|
39
|
-
rescue TypeError
|
40
|
-
to_type = column ? " to #{column.type}" : ""
|
41
|
-
raise TypeError, "can't cast #{value.class}#{to_type}"
|
42
44
|
end
|
43
45
|
|
44
46
|
# If you are having to call this function, you are likely doing something
|
@@ -50,35 +52,14 @@ module ActiveRecord
|
|
50
52
|
# represent the type doesn't sufficiently reflect the differences
|
51
53
|
# (varchar vs binary) for example. The type used to get this primitive
|
52
54
|
# should have been provided before reaching the connection adapter.
|
53
|
-
def type_cast_from_column(column, value) # :nodoc:
|
54
|
-
if column
|
55
|
-
type = lookup_cast_type_from_column(column)
|
56
|
-
type.serialize(value)
|
57
|
-
else
|
58
|
-
value
|
59
|
-
end
|
60
|
-
end
|
61
|
-
|
62
|
-
# See docs for #type_cast_from_column
|
63
55
|
def lookup_cast_type_from_column(column) # :nodoc:
|
64
56
|
lookup_cast_type(column.sql_type)
|
65
57
|
end
|
66
58
|
|
67
|
-
def fetch_type_metadata(sql_type)
|
68
|
-
cast_type = lookup_cast_type(sql_type)
|
69
|
-
SqlTypeMetadata.new(
|
70
|
-
sql_type: sql_type,
|
71
|
-
type: cast_type.type,
|
72
|
-
limit: cast_type.limit,
|
73
|
-
precision: cast_type.precision,
|
74
|
-
scale: cast_type.scale,
|
75
|
-
)
|
76
|
-
end
|
77
|
-
|
78
59
|
# Quotes a string, escaping any ' (single quote) and \ (backslash)
|
79
60
|
# characters.
|
80
61
|
def quote_string(s)
|
81
|
-
s.gsub('\\'
|
62
|
+
s.gsub('\\', '\&\&').gsub("'", "''") # ' (for ruby-mode)
|
82
63
|
end
|
83
64
|
|
84
65
|
# Quotes the column name. Defaults to no quoting.
|
@@ -113,95 +94,158 @@ module ActiveRecord
|
|
113
94
|
end
|
114
95
|
|
115
96
|
def quoted_true
|
116
|
-
"
|
97
|
+
"TRUE"
|
117
98
|
end
|
118
99
|
|
119
100
|
def unquoted_true
|
120
|
-
|
101
|
+
true
|
121
102
|
end
|
122
103
|
|
123
104
|
def quoted_false
|
124
|
-
"
|
105
|
+
"FALSE"
|
125
106
|
end
|
126
107
|
|
127
108
|
def unquoted_false
|
128
|
-
|
109
|
+
false
|
129
110
|
end
|
130
111
|
|
131
112
|
# Quote date/time values for use in SQL input. Includes microseconds
|
132
113
|
# if the value is a Time responding to usec.
|
133
114
|
def quoted_date(value)
|
134
115
|
if value.acts_like?(:time)
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
value = value.
|
116
|
+
if ActiveRecord::Base.default_timezone == :utc
|
117
|
+
value = value.getutc if value.respond_to?(:getutc) && !value.utc?
|
118
|
+
else
|
119
|
+
value = value.getlocal if value.respond_to?(:getlocal)
|
139
120
|
end
|
140
121
|
end
|
141
122
|
|
142
123
|
result = value.to_s(:db)
|
143
124
|
if value.respond_to?(:usec) && value.usec > 0
|
144
|
-
"
|
125
|
+
result << "." << sprintf("%06d", value.usec)
|
145
126
|
else
|
146
127
|
result
|
147
128
|
end
|
148
129
|
end
|
149
130
|
|
150
131
|
def quoted_time(value) # :nodoc:
|
151
|
-
|
132
|
+
value = value.change(year: 2000, month: 1, day: 1)
|
133
|
+
quoted_date(value).sub(/\A\d\d\d\d-\d\d-\d\d /, "")
|
152
134
|
end
|
153
135
|
|
154
|
-
def
|
155
|
-
|
136
|
+
def quoted_binary(value) # :nodoc:
|
137
|
+
"'#{quote_string(value.to_s)}'"
|
156
138
|
end
|
157
139
|
|
158
|
-
def
|
159
|
-
|
160
|
-
binds.map { |column, value| type_cast(value, column) }
|
161
|
-
else
|
162
|
-
binds.map { |attr| type_cast(attr.value_for_database) }
|
163
|
-
end
|
140
|
+
def sanitize_as_sql_comment(value) # :nodoc:
|
141
|
+
value.to_s.gsub(%r{ (/ (?: | \g<1>) \*) \+? \s* | \s* (\* (?: | \g<2>) /) }x, "")
|
164
142
|
end
|
165
143
|
|
144
|
+
def column_name_matcher # :nodoc:
|
145
|
+
COLUMN_NAME
|
146
|
+
end
|
147
|
+
|
148
|
+
def column_name_with_order_matcher # :nodoc:
|
149
|
+
COLUMN_NAME_WITH_ORDER
|
150
|
+
end
|
151
|
+
|
152
|
+
# Regexp for column names (with or without a table name prefix).
|
153
|
+
# Matches the following:
|
154
|
+
#
|
155
|
+
# "#{table_name}.#{column_name}"
|
156
|
+
# "#{column_name}"
|
157
|
+
COLUMN_NAME = /
|
158
|
+
\A
|
159
|
+
(
|
160
|
+
(?:
|
161
|
+
# table_name.column_name | function(one or no argument)
|
162
|
+
((?:\w+\.)?\w+) | \w+\((?:|\g<2>)\)
|
163
|
+
)
|
164
|
+
(?:(?:\s+AS)?\s+\w+)?
|
165
|
+
)
|
166
|
+
(?:\s*,\s*\g<1>)*
|
167
|
+
\z
|
168
|
+
/ix
|
169
|
+
|
170
|
+
# Regexp for column names with order (with or without a table name prefix,
|
171
|
+
# with or without various order modifiers). Matches the following:
|
172
|
+
#
|
173
|
+
# "#{table_name}.#{column_name}"
|
174
|
+
# "#{table_name}.#{column_name} #{direction}"
|
175
|
+
# "#{table_name}.#{column_name} #{direction} NULLS FIRST"
|
176
|
+
# "#{table_name}.#{column_name} NULLS LAST"
|
177
|
+
# "#{column_name}"
|
178
|
+
# "#{column_name} #{direction}"
|
179
|
+
# "#{column_name} #{direction} NULLS FIRST"
|
180
|
+
# "#{column_name} NULLS LAST"
|
181
|
+
COLUMN_NAME_WITH_ORDER = /
|
182
|
+
\A
|
183
|
+
(
|
184
|
+
(?:
|
185
|
+
# table_name.column_name | function(one or no argument)
|
186
|
+
((?:\w+\.)?\w+) | \w+\((?:|\g<2>)\)
|
187
|
+
)
|
188
|
+
(?:\s+ASC|\s+DESC)?
|
189
|
+
(?:\s+NULLS\s+(?:FIRST|LAST))?
|
190
|
+
)
|
191
|
+
(?:\s*,\s*\g<1>)*
|
192
|
+
\z
|
193
|
+
/ix
|
194
|
+
|
195
|
+
private_constant :COLUMN_NAME, :COLUMN_NAME_WITH_ORDER
|
196
|
+
|
166
197
|
private
|
198
|
+
def type_casted_binds(binds)
|
199
|
+
case binds.first
|
200
|
+
when Array
|
201
|
+
binds.map { |column, value| type_cast(value, column) }
|
202
|
+
else
|
203
|
+
binds.map do |value|
|
204
|
+
if ActiveModel::Attribute === value
|
205
|
+
type_cast(value.value_for_database)
|
206
|
+
else
|
207
|
+
type_cast(value)
|
208
|
+
end
|
209
|
+
end
|
210
|
+
end
|
211
|
+
end
|
167
212
|
|
168
|
-
|
169
|
-
|
170
|
-
end
|
171
|
-
|
172
|
-
def _quote(value)
|
173
|
-
case value
|
174
|
-
when String, ActiveSupport::Multibyte::Chars, Type::Binary::Data
|
175
|
-
"'#{quote_string(value.to_s)}'"
|
176
|
-
when true then quoted_true
|
177
|
-
when false then quoted_false
|
178
|
-
when nil then "NULL"
|
179
|
-
# BigDecimals need to be put in a non-normalized form and quoted.
|
180
|
-
when BigDecimal then value.to_s('F')
|
181
|
-
when Numeric, ActiveSupport::Duration then value.to_s
|
182
|
-
when Type::Time::Value then "'#{quoted_time(value)}'"
|
183
|
-
when Date, Time then "'#{quoted_date(value)}'"
|
184
|
-
when Symbol then "'#{quote_string(value.to_s)}'"
|
185
|
-
when Class then "'#{value}'"
|
186
|
-
else raise TypeError, "can't quote #{value.class.name}"
|
213
|
+
def lookup_cast_type(sql_type)
|
214
|
+
type_map.lookup(sql_type)
|
187
215
|
end
|
188
|
-
end
|
189
216
|
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
value
|
202
|
-
|
217
|
+
def _quote(value)
|
218
|
+
case value
|
219
|
+
when String, Symbol, ActiveSupport::Multibyte::Chars
|
220
|
+
"'#{quote_string(value.to_s)}'"
|
221
|
+
when true then quoted_true
|
222
|
+
when false then quoted_false
|
223
|
+
when nil then "NULL"
|
224
|
+
# BigDecimals need to be put in a non-normalized form and quoted.
|
225
|
+
when BigDecimal then value.to_s("F")
|
226
|
+
when Numeric, ActiveSupport::Duration then value.to_s
|
227
|
+
when Type::Binary::Data then quoted_binary(value)
|
228
|
+
when Type::Time::Value then "'#{quoted_time(value)}'"
|
229
|
+
when Date, Time then "'#{quoted_date(value)}'"
|
230
|
+
when Class then "'#{value}'"
|
231
|
+
else raise TypeError, "can't quote #{value.class.name}"
|
232
|
+
end
|
233
|
+
end
|
234
|
+
|
235
|
+
def _type_cast(value)
|
236
|
+
case value
|
237
|
+
when Symbol, ActiveSupport::Multibyte::Chars, Type::Binary::Data
|
238
|
+
value.to_s
|
239
|
+
when true then unquoted_true
|
240
|
+
when false then unquoted_false
|
241
|
+
# BigDecimals need to be put in a non-normalized form and quoted.
|
242
|
+
when BigDecimal then value.to_s("F")
|
243
|
+
when nil, Numeric, String then value
|
244
|
+
when Type::Time::Value then quoted_time(value)
|
245
|
+
when Date, Time then quoted_date(value)
|
246
|
+
else raise TypeError, "can't cast #{value.class.name}"
|
247
|
+
end
|
203
248
|
end
|
204
|
-
end
|
205
249
|
end
|
206
250
|
end
|
207
251
|
end
|