activerecord 5.0.7.2 → 6.0.6.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 +844 -1944
- data/MIT-LICENSE +3 -1
- data/README.rdoc +9 -7
- data/examples/performance.rb +31 -29
- data/examples/simple.rb +5 -3
- data/lib/active_record/advisory_lock_base.rb +18 -0
- data/lib/active_record/aggregations.rb +249 -247
- data/lib/active_record/association_relation.rb +18 -14
- data/lib/active_record/associations/alias_tracker.rb +24 -34
- data/lib/active_record/associations/association.rb +113 -55
- data/lib/active_record/associations/association_scope.rb +102 -96
- data/lib/active_record/associations/belongs_to_association.rb +58 -42
- data/lib/active_record/associations/belongs_to_polymorphic_association.rb +8 -12
- data/lib/active_record/associations/builder/association.rb +18 -25
- data/lib/active_record/associations/builder/belongs_to.rb +43 -54
- data/lib/active_record/associations/builder/collection_association.rb +7 -18
- data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +41 -62
- data/lib/active_record/associations/builder/has_many.rb +4 -0
- data/lib/active_record/associations/builder/has_one.rb +37 -1
- data/lib/active_record/associations/builder/singular_association.rb +4 -0
- data/lib/active_record/associations/collection_association.rb +93 -254
- data/lib/active_record/associations/collection_proxy.rb +159 -122
- data/lib/active_record/associations/foreign_association.rb +9 -0
- data/lib/active_record/associations/has_many_association.rb +23 -30
- data/lib/active_record/associations/has_many_through_association.rb +58 -44
- data/lib/active_record/associations/has_one_association.rb +59 -54
- data/lib/active_record/associations/has_one_through_association.rb +20 -11
- data/lib/active_record/associations/join_dependency/join_association.rb +43 -85
- 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/join_dependency.rb +152 -177
- data/lib/active_record/associations/preloader/association.rb +101 -97
- data/lib/active_record/associations/preloader/through_association.rb +77 -76
- data/lib/active_record/associations/preloader.rb +94 -103
- data/lib/active_record/associations/singular_association.rb +12 -45
- data/lib/active_record/associations/through_association.rb +27 -15
- data/lib/active_record/associations.rb +1603 -1592
- data/lib/active_record/attribute_assignment.rb +54 -61
- data/lib/active_record/attribute_decorators.rb +38 -17
- data/lib/active_record/attribute_methods/before_type_cast.rb +12 -8
- data/lib/active_record/attribute_methods/dirty.rb +179 -109
- data/lib/active_record/attribute_methods/primary_key.rb +85 -92
- data/lib/active_record/attribute_methods/query.rb +4 -3
- data/lib/active_record/attribute_methods/read.rb +20 -49
- data/lib/active_record/attribute_methods/serialization.rb +29 -7
- data/lib/active_record/attribute_methods/time_zone_conversion.rb +39 -66
- data/lib/active_record/attribute_methods/write.rb +34 -33
- data/lib/active_record/attribute_methods.rb +66 -106
- data/lib/active_record/attributes.rb +38 -25
- data/lib/active_record/autosave_association.rb +58 -39
- data/lib/active_record/base.rb +27 -24
- data/lib/active_record/callbacks.rb +64 -35
- data/lib/active_record/coders/json.rb +2 -0
- data/lib/active_record/coders/yaml_column.rb +34 -13
- data/lib/active_record/connection_adapters/abstract/connection_pool.rb +558 -323
- data/lib/active_record/connection_adapters/abstract/database_limits.rb +23 -5
- data/lib/active_record/connection_adapters/abstract/database_statements.rb +215 -94
- data/lib/active_record/connection_adapters/abstract/query_cache.rb +59 -35
- data/lib/active_record/connection_adapters/abstract/quoting.rb +128 -75
- data/lib/active_record/connection_adapters/abstract/savepoints.rb +2 -0
- data/lib/active_record/connection_adapters/abstract/schema_creation.rb +33 -28
- data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +233 -147
- data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +68 -80
- data/lib/active_record/connection_adapters/abstract/schema_statements.rb +400 -213
- data/lib/active_record/connection_adapters/abstract/transaction.rb +169 -79
- data/lib/active_record/connection_adapters/abstract_adapter.rb +373 -202
- data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +401 -562
- data/lib/active_record/connection_adapters/column.rb +41 -13
- data/lib/active_record/connection_adapters/connection_specification.rb +172 -139
- data/lib/active_record/connection_adapters/determine_if_preparable_visitor.rb +11 -4
- data/lib/active_record/connection_adapters/mysql/column.rb +8 -31
- data/lib/active_record/connection_adapters/mysql/database_statements.rb +137 -49
- data/lib/active_record/connection_adapters/mysql/explain_pretty_printer.rb +24 -23
- data/lib/active_record/connection_adapters/mysql/quoting.rb +50 -20
- data/lib/active_record/connection_adapters/mysql/schema_creation.rb +49 -45
- data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +58 -56
- data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +70 -36
- data/lib/active_record/connection_adapters/mysql/schema_statements.rb +268 -0
- data/lib/active_record/connection_adapters/mysql/type_metadata.rb +12 -13
- data/lib/active_record/connection_adapters/mysql2_adapter.rb +48 -30
- data/lib/active_record/connection_adapters/postgresql/column.rb +19 -31
- data/lib/active_record/connection_adapters/postgresql/database_statements.rb +64 -54
- data/lib/active_record/connection_adapters/postgresql/explain_pretty_printer.rb +5 -3
- data/lib/active_record/connection_adapters/postgresql/oid/array.rb +22 -11
- data/lib/active_record/connection_adapters/postgresql/oid/bit.rb +6 -5
- data/lib/active_record/connection_adapters/postgresql/oid/bit_varying.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/oid/bytea.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/oid/cidr.rb +3 -1
- data/lib/active_record/connection_adapters/postgresql/oid/date.rb +23 -0
- data/lib/active_record/connection_adapters/postgresql/oid/date_time.rb +12 -2
- data/lib/active_record/connection_adapters/postgresql/oid/decimal.rb +3 -1
- data/lib/active_record/connection_adapters/postgresql/oid/enum.rb +5 -4
- data/lib/active_record/connection_adapters/postgresql/oid/hstore.rb +19 -18
- data/lib/active_record/connection_adapters/postgresql/oid/inet.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/oid/jsonb.rb +3 -11
- data/lib/active_record/connection_adapters/postgresql/oid/legacy_point.rb +44 -0
- data/lib/active_record/connection_adapters/postgresql/oid/money.rb +7 -5
- data/lib/active_record/connection_adapters/postgresql/oid/{json.rb → oid.rb} +6 -1
- data/lib/active_record/connection_adapters/postgresql/oid/point.rb +30 -9
- data/lib/active_record/connection_adapters/postgresql/oid/range.rb +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 +8 -4
- data/lib/active_record/connection_adapters/postgresql/oid/vector.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/oid/xml.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/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 +20 -26
- data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +76 -0
- data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +147 -105
- data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +34 -32
- data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +378 -308
- data/lib/active_record/connection_adapters/postgresql/type_metadata.rb +26 -25
- data/lib/active_record/connection_adapters/postgresql/utils.rb +9 -6
- data/lib/active_record/connection_adapters/postgresql_adapter.rb +383 -275
- data/lib/active_record/connection_adapters/schema_cache.rb +46 -12
- data/lib/active_record/connection_adapters/sql_type_metadata.rb +13 -8
- data/lib/active_record/connection_adapters/sqlite3/database_statements.rb +119 -0
- data/lib/active_record/connection_adapters/sqlite3/explain_pretty_printer.rb +3 -1
- data/lib/active_record/connection_adapters/sqlite3/quoting.rb +72 -18
- data/lib/active_record/connection_adapters/sqlite3/schema_creation.rb +3 -8
- data/lib/active_record/connection_adapters/sqlite3/schema_definitions.rb +19 -0
- data/lib/active_record/connection_adapters/sqlite3/schema_dumper.rb +18 -0
- data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +137 -0
- data/lib/active_record/connection_adapters/sqlite3_adapter.rb +261 -267
- data/lib/active_record/connection_adapters/statement_pool.rb +9 -8
- data/lib/active_record/connection_handling.rb +143 -40
- data/lib/active_record/core.rb +207 -160
- data/lib/active_record/counter_cache.rb +60 -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 +78 -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 -87
- data/lib/active_record/enum.rb +67 -23
- data/lib/active_record/errors.rb +114 -18
- data/lib/active_record/explain.rb +4 -4
- data/lib/active_record/explain_registry.rb +3 -1
- data/lib/active_record/explain_subscriber.rb +9 -4
- data/lib/active_record/fixture_set/file.rb +13 -8
- data/lib/active_record/fixture_set/model_metadata.rb +33 -0
- data/lib/active_record/fixture_set/render_context.rb +17 -0
- data/lib/active_record/fixture_set/table_row.rb +152 -0
- data/lib/active_record/fixture_set/table_rows.rb +46 -0
- data/lib/active_record/fixtures.rb +194 -504
- data/lib/active_record/gem_version.rb +5 -3
- data/lib/active_record/inheritance.rb +150 -99
- data/lib/active_record/insert_all.rb +179 -0
- data/lib/active_record/integration.rb +116 -25
- data/lib/active_record/internal_metadata.rb +16 -19
- data/lib/active_record/legacy_yaml_adapter.rb +4 -2
- data/lib/active_record/locking/optimistic.rb +85 -86
- 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 +87 -0
- data/lib/active_record/middleware/database_selector.rb +74 -0
- data/lib/active_record/migration/command_recorder.rb +134 -100
- data/lib/active_record/migration/compatibility.rb +174 -56
- data/lib/active_record/migration/join_table.rb +8 -7
- data/lib/active_record/migration.rb +369 -302
- data/lib/active_record/model_schema.rb +160 -127
- data/lib/active_record/nested_attributes.rb +213 -202
- data/lib/active_record/no_touching.rb +12 -3
- data/lib/active_record/null_relation.rb +12 -34
- data/lib/active_record/persistence.rb +446 -77
- data/lib/active_record/query_cache.rb +13 -12
- data/lib/active_record/querying.rb +37 -24
- data/lib/active_record/railtie.rb +128 -36
- data/lib/active_record/railties/collection_cache_association_loading.rb +34 -0
- data/lib/active_record/railties/console_sandbox.rb +2 -0
- data/lib/active_record/railties/controller_runtime.rb +34 -33
- data/lib/active_record/railties/databases.rake +312 -177
- data/lib/active_record/readonly_attributes.rb +5 -4
- data/lib/active_record/reflection.rb +214 -254
- data/lib/active_record/relation/batches/batch_enumerator.rb +3 -1
- data/lib/active_record/relation/batches.rb +98 -52
- data/lib/active_record/relation/calculations.rb +212 -173
- data/lib/active_record/relation/delegation.rb +73 -69
- data/lib/active_record/relation/finder_methods.rb +207 -247
- data/lib/active_record/relation/from_clause.rb +6 -8
- data/lib/active_record/relation/merger.rb +82 -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 +83 -105
- data/lib/active_record/relation/query_attribute.rb +33 -2
- data/lib/active_record/relation/query_methods.rb +488 -332
- data/lib/active_record/relation/record_fetch_warning.rb +5 -3
- data/lib/active_record/relation/spawn_methods.rb +8 -8
- data/lib/active_record/relation/where_clause.rb +111 -96
- data/lib/active_record/relation/where_clause_factory.rb +6 -11
- data/lib/active_record/relation.rb +443 -318
- data/lib/active_record/result.rb +69 -40
- data/lib/active_record/runtime_registry.rb +5 -3
- data/lib/active_record/sanitization.rb +83 -99
- data/lib/active_record/schema.rb +7 -14
- data/lib/active_record/schema_dumper.rb +71 -69
- data/lib/active_record/schema_migration.rb +16 -6
- data/lib/active_record/scoping/default.rb +92 -95
- data/lib/active_record/scoping/named.rb +51 -26
- data/lib/active_record/scoping.rb +20 -20
- data/lib/active_record/secure_token.rb +4 -2
- data/lib/active_record/serialization.rb +2 -0
- data/lib/active_record/statement_cache.rb +63 -28
- data/lib/active_record/store.rb +121 -41
- data/lib/active_record/suppressor.rb +6 -3
- data/lib/active_record/table_metadata.rb +39 -18
- data/lib/active_record/tasks/database_tasks.rb +271 -81
- data/lib/active_record/tasks/mysql_database_tasks.rb +54 -91
- data/lib/active_record/tasks/postgresql_database_tasks.rb +77 -47
- data/lib/active_record/tasks/sqlite_database_tasks.rb +33 -16
- data/lib/active_record/test_databases.rb +23 -0
- data/lib/active_record/test_fixtures.rb +243 -0
- data/lib/active_record/timestamp.rb +70 -36
- data/lib/active_record/touch_later.rb +8 -6
- data/lib/active_record/transactions.rb +141 -157
- data/lib/active_record/translation.rb +3 -1
- data/lib/active_record/type/adapter_specific_registry.rb +44 -48
- data/lib/active_record/type/date.rb +2 -0
- data/lib/active_record/type/date_time.rb +2 -0
- data/lib/active_record/type/decimal_without_scale.rb +15 -0
- data/lib/active_record/type/hash_lookup_type_map.rb +5 -4
- data/lib/active_record/type/internal/timezone.rb +2 -0
- data/lib/active_record/type/json.rb +30 -0
- data/lib/active_record/type/serialized.rb +16 -9
- data/lib/active_record/type/text.rb +11 -0
- data/lib/active_record/type/time.rb +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.rb +23 -18
- 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 -2
- 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 -5
- data/lib/active_record/version.rb +3 -1
- data/lib/active_record.rb +37 -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 +256 -0
- data/lib/arel/select_manager.rb +271 -0
- data/lib/arel/table.rb +110 -0
- data/lib/arel/tree_manager.rb +72 -0
- data/lib/arel/update_manager.rb +34 -0
- data/lib/arel/visitors/depth_first.rb +203 -0
- data/lib/arel/visitors/dot.rb +296 -0
- data/lib/arel/visitors/ibm_db.rb +34 -0
- data/lib/arel/visitors/informix.rb +62 -0
- data/lib/arel/visitors/mssql.rb +156 -0
- data/lib/arel/visitors/mysql.rb +83 -0
- data/lib/arel/visitors/oracle.rb +158 -0
- data/lib/arel/visitors/oracle12.rb +65 -0
- data/lib/arel/visitors/postgresql.rb +109 -0
- data/lib/arel/visitors/sqlite.rb +38 -0
- data/lib/arel/visitors/to_sql.rb +888 -0
- data/lib/arel/visitors/visitor.rb +45 -0
- data/lib/arel/visitors/where_sql.rb +22 -0
- data/lib/arel/visitors.rb +20 -0
- data/lib/arel/window_predications.rb +9 -0
- data/lib/arel.rb +62 -0
- data/lib/rails/generators/active_record/application_record/application_record_generator.rb +26 -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 -3
- data/lib/rails/generators/active_record/model/model_generator.rb +9 -30
- data/lib/rails/generators/active_record/model/templates/{model.rb → model.rb.tt} +10 -1
- data/lib/rails/generators/active_record.rb +7 -5
- metadata +138 -52
- data/lib/active_record/associations/preloader/belongs_to.rb +0 -17
- data/lib/active_record/associations/preloader/collection_association.rb +0 -17
- data/lib/active_record/associations/preloader/has_many.rb +0 -17
- data/lib/active_record/associations/preloader/has_many_through.rb +0 -19
- data/lib/active_record/associations/preloader/has_one.rb +0 -15
- data/lib/active_record/associations/preloader/has_one_through.rb +0 -9
- data/lib/active_record/associations/preloader/singular_association.rb +0 -20
- data/lib/active_record/attribute/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 -132
- 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/rails/generators/active_record/{model/templates/application_record.rb → application_record/templates/application_record.rb.tt} +0 -0
- /data/lib/rails/generators/active_record/model/templates/{module.rb → module.rb.tt} +0 -0
@@ -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 if @query_cache_enabled
|
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,67 @@ 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 = to_sql_and_binds(arel, binds)
|
100
|
+
|
101
|
+
if preparable.nil?
|
102
|
+
preparable = prepared_statements ? visitor.preparable : false
|
103
|
+
end
|
104
|
+
|
105
|
+
cache_sql(sql, name, binds) { super(sql, name, binds, preparable: preparable) }
|
94
106
|
else
|
95
107
|
super
|
96
108
|
end
|
97
109
|
end
|
98
110
|
|
99
111
|
private
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
else
|
114
|
-
@query_cache[sql][binds] = yield
|
112
|
+
def cache_sql(sql, name, binds)
|
113
|
+
@lock.synchronize do
|
114
|
+
result =
|
115
|
+
if @query_cache[sql].key?(binds)
|
116
|
+
ActiveSupport::Notifications.instrument(
|
117
|
+
"sql.active_record",
|
118
|
+
cache_notification_info(sql, name, binds)
|
119
|
+
)
|
120
|
+
@query_cache[sql][binds]
|
121
|
+
else
|
122
|
+
@query_cache[sql][binds] = yield
|
123
|
+
end
|
124
|
+
result.dup
|
115
125
|
end
|
116
|
-
|
117
|
-
end
|
126
|
+
end
|
118
127
|
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
128
|
+
# Database adapters can override this method to
|
129
|
+
# provide custom cache information.
|
130
|
+
def cache_notification_info(sql, name, binds)
|
131
|
+
{
|
132
|
+
sql: sql,
|
133
|
+
binds: binds,
|
134
|
+
type_casted_binds: -> { type_casted_binds(binds) },
|
135
|
+
name: name,
|
136
|
+
connection_id: object_id,
|
137
|
+
connection: self,
|
138
|
+
cached: true
|
139
|
+
}
|
140
|
+
end
|
124
141
|
|
125
|
-
|
126
|
-
|
127
|
-
|
142
|
+
# If arel is locked this is a SELECT ... FOR UPDATE or somesuch. Such
|
143
|
+
# queries should not be cached.
|
144
|
+
def locked?(arel)
|
145
|
+
arel = arel.arel if arel.is_a?(Relation)
|
146
|
+
arel.respond_to?(:locked) && arel.locked
|
147
|
+
end
|
148
|
+
|
149
|
+
def configure_query_cache!
|
150
|
+
enable_query_cache! if pool.query_cache_enabled
|
151
|
+
end
|
128
152
|
end
|
129
153
|
end
|
130
154
|
end
|
@@ -1,23 +1,18 @@
|
|
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
|
-
return value.quoted_id if value.respond_to?(:quoted_id)
|
10
|
+
# {SQL injection attacks}[https://en.wikipedia.org/wiki/SQL_injection].
|
11
|
+
def quote(value)
|
12
|
+
value = id_value_for_database(value) if value.is_a?(Base)
|
12
13
|
|
13
|
-
if
|
14
|
-
|
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.
|
19
|
-
MSG
|
20
|
-
value = type_cast_from_column(column, value)
|
14
|
+
if value.respond_to?(:value_for_database)
|
15
|
+
value = value.value_for_database
|
21
16
|
end
|
22
17
|
|
23
18
|
_quote(value)
|
@@ -27,9 +22,7 @@ module ActiveRecord
|
|
27
22
|
# SQLite does not understand dates, so this method will convert a Date
|
28
23
|
# to a String.
|
29
24
|
def type_cast(value, column = nil)
|
30
|
-
|
31
|
-
return value.id
|
32
|
-
end
|
25
|
+
value = id_value_for_database(value) if value.is_a?(Base)
|
33
26
|
|
34
27
|
if column
|
35
28
|
value = type_cast_from_column(column, value)
|
@@ -64,21 +57,10 @@ module ActiveRecord
|
|
64
57
|
lookup_cast_type(column.sql_type)
|
65
58
|
end
|
66
59
|
|
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
60
|
# Quotes a string, escaping any ' (single quote) and \ (backslash)
|
79
61
|
# characters.
|
80
62
|
def quote_string(s)
|
81
|
-
s.gsub('\\'
|
63
|
+
s.gsub('\\', '\&\&').gsub("'", "''") # ' (for ruby-mode)
|
82
64
|
end
|
83
65
|
|
84
66
|
# Quotes the column name. Defaults to no quoting.
|
@@ -113,19 +95,19 @@ module ActiveRecord
|
|
113
95
|
end
|
114
96
|
|
115
97
|
def quoted_true
|
116
|
-
"
|
98
|
+
"TRUE"
|
117
99
|
end
|
118
100
|
|
119
101
|
def unquoted_true
|
120
|
-
|
102
|
+
true
|
121
103
|
end
|
122
104
|
|
123
105
|
def quoted_false
|
124
|
-
"
|
106
|
+
"FALSE"
|
125
107
|
end
|
126
108
|
|
127
109
|
def unquoted_false
|
128
|
-
|
110
|
+
false
|
129
111
|
end
|
130
112
|
|
131
113
|
# Quote date/time values for use in SQL input. Includes microseconds
|
@@ -148,60 +130,131 @@ module ActiveRecord
|
|
148
130
|
end
|
149
131
|
|
150
132
|
def quoted_time(value) # :nodoc:
|
151
|
-
|
133
|
+
value = value.change(year: 2000, month: 1, day: 1)
|
134
|
+
quoted_date(value).sub(/\A\d\d\d\d-\d\d-\d\d /, "")
|
152
135
|
end
|
153
136
|
|
154
|
-
def
|
155
|
-
|
137
|
+
def quoted_binary(value) # :nodoc:
|
138
|
+
"'#{quote_string(value.to_s)}'"
|
156
139
|
end
|
157
140
|
|
158
|
-
def
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
141
|
+
def sanitize_as_sql_comment(value) # :nodoc:
|
142
|
+
# Sanitize a string to appear within a SQL comment
|
143
|
+
# For compatibility, this also surrounding "/*+", "/*", and "*/"
|
144
|
+
# charcacters, possibly with single surrounding space.
|
145
|
+
# Then follows that by replacing any internal "*/" or "/ *" with
|
146
|
+
# "* /" or "/ *"
|
147
|
+
comment = value.to_s.dup
|
148
|
+
comment.gsub!(%r{\A\s*/\*\+?\s?|\s?\*/\s*\Z}, "")
|
149
|
+
comment.gsub!("*/", "* /")
|
150
|
+
comment.gsub!("/*", "/ *")
|
151
|
+
comment
|
152
|
+
end
|
153
|
+
|
154
|
+
def column_name_matcher # :nodoc:
|
155
|
+
COLUMN_NAME
|
156
|
+
end
|
157
|
+
|
158
|
+
def column_name_with_order_matcher # :nodoc:
|
159
|
+
COLUMN_NAME_WITH_ORDER
|
164
160
|
end
|
165
161
|
|
162
|
+
# Regexp for column names (with or without a table name prefix).
|
163
|
+
# Matches the following:
|
164
|
+
#
|
165
|
+
# "#{table_name}.#{column_name}"
|
166
|
+
# "#{column_name}"
|
167
|
+
COLUMN_NAME = /
|
168
|
+
\A
|
169
|
+
(
|
170
|
+
(?:
|
171
|
+
# table_name.column_name | function(one or no argument)
|
172
|
+
((?:\w+\.)?\w+) | \w+\((?:|\g<2>)\)
|
173
|
+
)
|
174
|
+
(?:\s+AS\s+\w+)?
|
175
|
+
)
|
176
|
+
(?:\s*,\s*\g<1>)*
|
177
|
+
\z
|
178
|
+
/ix
|
179
|
+
|
180
|
+
# Regexp for column names with order (with or without a table name prefix,
|
181
|
+
# with or without various order modifiers). Matches the following:
|
182
|
+
#
|
183
|
+
# "#{table_name}.#{column_name}"
|
184
|
+
# "#{table_name}.#{column_name} #{direction}"
|
185
|
+
# "#{table_name}.#{column_name} #{direction} NULLS FIRST"
|
186
|
+
# "#{table_name}.#{column_name} NULLS LAST"
|
187
|
+
# "#{column_name}"
|
188
|
+
# "#{column_name} #{direction}"
|
189
|
+
# "#{column_name} #{direction} NULLS FIRST"
|
190
|
+
# "#{column_name} NULLS LAST"
|
191
|
+
COLUMN_NAME_WITH_ORDER = /
|
192
|
+
\A
|
193
|
+
(
|
194
|
+
(?:
|
195
|
+
# table_name.column_name | function(one or no argument)
|
196
|
+
((?:\w+\.)?\w+) | \w+\((?:|\g<2>)\)
|
197
|
+
)
|
198
|
+
(?:\s+ASC|\s+DESC)?
|
199
|
+
(?:\s+NULLS\s+(?:FIRST|LAST))?
|
200
|
+
)
|
201
|
+
(?:\s*,\s*\g<1>)*
|
202
|
+
\z
|
203
|
+
/ix
|
204
|
+
|
205
|
+
private_constant :COLUMN_NAME, :COLUMN_NAME_WITH_ORDER
|
206
|
+
|
166
207
|
private
|
208
|
+
def type_casted_binds(binds)
|
209
|
+
if binds.first.is_a?(Array)
|
210
|
+
binds.map { |column, value| type_cast(value, column) }
|
211
|
+
else
|
212
|
+
binds.map { |attr| type_cast(attr.value_for_database) }
|
213
|
+
end
|
214
|
+
end
|
167
215
|
|
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}"
|
216
|
+
def lookup_cast_type(sql_type)
|
217
|
+
type_map.lookup(sql_type)
|
187
218
|
end
|
188
|
-
end
|
189
219
|
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
220
|
+
def id_value_for_database(value)
|
221
|
+
if primary_key = value.class.primary_key
|
222
|
+
value.instance_variable_get(:@attributes)[primary_key].value_for_database
|
223
|
+
end
|
224
|
+
end
|
225
|
+
|
226
|
+
def _quote(value)
|
227
|
+
case value
|
228
|
+
when String, Symbol, ActiveSupport::Multibyte::Chars
|
229
|
+
"'#{quote_string(value.to_s)}'"
|
230
|
+
when true then quoted_true
|
231
|
+
when false then quoted_false
|
232
|
+
when nil then "NULL"
|
233
|
+
# BigDecimals need to be put in a non-normalized form and quoted.
|
234
|
+
when BigDecimal then value.to_s("F")
|
235
|
+
when Numeric, ActiveSupport::Duration then value.to_s
|
236
|
+
when Type::Binary::Data then quoted_binary(value)
|
237
|
+
when Type::Time::Value then "'#{quoted_time(value)}'"
|
238
|
+
when Date, Time then "'#{quoted_date(value)}'"
|
239
|
+
when Class then "'#{value}'"
|
240
|
+
else raise TypeError, "can't quote #{value.class.name}"
|
241
|
+
end
|
242
|
+
end
|
243
|
+
|
244
|
+
def _type_cast(value)
|
245
|
+
case value
|
246
|
+
when Symbol, ActiveSupport::Multibyte::Chars, Type::Binary::Data
|
247
|
+
value.to_s
|
248
|
+
when true then unquoted_true
|
249
|
+
when false then unquoted_false
|
250
|
+
# BigDecimals need to be put in a non-normalized form and quoted.
|
251
|
+
when BigDecimal then value.to_s("F")
|
252
|
+
when nil, Numeric, String then value
|
253
|
+
when Type::Time::Value then quoted_time(value)
|
254
|
+
when Date, Time then quoted_date(value)
|
255
|
+
else raise TypeError
|
256
|
+
end
|
203
257
|
end
|
204
|
-
end
|
205
258
|
end
|
206
259
|
end
|
207
260
|
end
|
@@ -1,4 +1,4 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module ActiveRecord
|
4
4
|
module ConnectionAdapters
|
@@ -15,32 +15,32 @@ module ActiveRecord
|
|
15
15
|
end
|
16
16
|
|
17
17
|
delegate :quote_column_name, :quote_table_name, :quote_default_expression, :type_to_sql,
|
18
|
-
:options_include_default?, :supports_indexes_in_create?, :supports_foreign_keys?, :foreign_key_options,
|
19
|
-
|
20
|
-
:options_include_default?, :supports_indexes_in_create?, :supports_foreign_keys?, :foreign_key_options
|
18
|
+
:options_include_default?, :supports_indexes_in_create?, :supports_foreign_keys?, :foreign_key_options,
|
19
|
+
to: :@conn, private: true
|
21
20
|
|
22
21
|
private
|
23
|
-
|
24
22
|
def visit_AlterTable(o)
|
25
|
-
sql = "ALTER TABLE #{quote_table_name(o.name)} "
|
26
|
-
sql << o.adds.map { |col| accept col }.join(
|
27
|
-
sql << o.foreign_key_adds.map { |fk| visit_AddForeignKey fk }.join(
|
28
|
-
sql << o.foreign_key_drops.map { |fk| visit_DropForeignKey fk }.join(
|
23
|
+
sql = +"ALTER TABLE #{quote_table_name(o.name)} "
|
24
|
+
sql << o.adds.map { |col| accept col }.join(" ")
|
25
|
+
sql << o.foreign_key_adds.map { |fk| visit_AddForeignKey fk }.join(" ")
|
26
|
+
sql << o.foreign_key_drops.map { |fk| visit_DropForeignKey fk }.join(" ")
|
29
27
|
end
|
30
28
|
|
31
29
|
def visit_ColumnDefinition(o)
|
32
|
-
o.sql_type
|
33
|
-
column_sql = "#{quote_column_name(o.name)} #{o.sql_type}"
|
30
|
+
o.sql_type = type_to_sql(o.type, **o.options)
|
31
|
+
column_sql = +"#{quote_column_name(o.name)} #{o.sql_type}"
|
34
32
|
add_column_options!(column_sql, column_options(o)) unless o.type == :primary_key
|
35
33
|
column_sql
|
36
34
|
end
|
37
35
|
|
38
36
|
def visit_AddColumnDefinition(o)
|
39
|
-
"ADD #{accept(o.column)}"
|
37
|
+
+"ADD #{accept(o.column)}"
|
40
38
|
end
|
41
39
|
|
42
40
|
def visit_TableDefinition(o)
|
43
|
-
create_sql = "CREATE#{
|
41
|
+
create_sql = +"CREATE#{table_modifier_in_create(o)} TABLE "
|
42
|
+
create_sql << "IF NOT EXISTS " if o.if_not_exists
|
43
|
+
create_sql << "#{quote_table_name(o.name)} "
|
44
44
|
|
45
45
|
statements = o.columns.map { |c| accept c }
|
46
46
|
statements << accept(o.primary_keys) if o.primary_keys
|
@@ -55,16 +55,16 @@ module ActiveRecord
|
|
55
55
|
|
56
56
|
create_sql << "(#{statements.join(', ')})" if statements.present?
|
57
57
|
add_table_options!(create_sql, table_options(o))
|
58
|
-
create_sql << " AS #{
|
58
|
+
create_sql << " AS #{to_sql(o.as)}" if o.as
|
59
59
|
create_sql
|
60
60
|
end
|
61
61
|
|
62
62
|
def visit_PrimaryKeyDefinition(o)
|
63
|
-
"PRIMARY KEY (#{o.name.join(', ')})"
|
63
|
+
"PRIMARY KEY (#{o.name.map { |name| quote_column_name(name) }.join(', ')})"
|
64
64
|
end
|
65
65
|
|
66
66
|
def visit_ForeignKeyDefinition(o)
|
67
|
-
sql =
|
67
|
+
sql = +<<~SQL
|
68
68
|
CONSTRAINT #{quote_column_name(o.name)}
|
69
69
|
FOREIGN KEY (#{quote_column_name(o.column)})
|
70
70
|
REFERENCES #{quote_table_name(o.to_table)} (#{quote_column_name(o.primary_key)})
|
@@ -93,20 +93,11 @@ module ActiveRecord
|
|
93
93
|
if options_sql = options[:options]
|
94
94
|
create_sql << " #{options_sql}"
|
95
95
|
end
|
96
|
+
create_sql
|
96
97
|
end
|
97
98
|
|
98
99
|
def column_options(o)
|
99
|
-
|
100
|
-
column_options[:null] = o.null unless o.null.nil?
|
101
|
-
column_options[:default] = o.default unless o.default.nil?
|
102
|
-
column_options[:column] = o
|
103
|
-
column_options[:first] = o.first
|
104
|
-
column_options[:after] = o.after
|
105
|
-
column_options[:auto_increment] = o.auto_increment
|
106
|
-
column_options[:primary_key] = o.primary_key
|
107
|
-
column_options[:collation] = o.collation
|
108
|
-
column_options[:comment] = o.comment
|
109
|
-
column_options
|
100
|
+
o.options.merge(column: o)
|
110
101
|
end
|
111
102
|
|
112
103
|
def add_column_options!(sql, options)
|
@@ -124,7 +115,20 @@ module ActiveRecord
|
|
124
115
|
sql
|
125
116
|
end
|
126
117
|
|
118
|
+
def to_sql(sql)
|
119
|
+
sql = sql.to_sql if sql.respond_to?(:to_sql)
|
120
|
+
sql
|
121
|
+
end
|
122
|
+
|
123
|
+
# Returns any SQL string to go between CREATE and TABLE. May be nil.
|
124
|
+
def table_modifier_in_create(o)
|
125
|
+
" TEMPORARY" if o.temporary
|
126
|
+
end
|
127
|
+
|
127
128
|
def foreign_key_in_create(from_table, to_table, options)
|
129
|
+
prefix = ActiveRecord::Base.table_name_prefix
|
130
|
+
suffix = ActiveRecord::Base.table_name_suffix
|
131
|
+
to_table = "#{prefix}#{to_table}#{suffix}"
|
128
132
|
options = foreign_key_options(from_table, to_table, options)
|
129
133
|
accept ForeignKeyDefinition.new(from_table, to_table, options)
|
130
134
|
end
|
@@ -135,7 +139,7 @@ module ActiveRecord
|
|
135
139
|
when :cascade then "ON #{action} CASCADE"
|
136
140
|
when :restrict then "ON #{action} RESTRICT"
|
137
141
|
else
|
138
|
-
raise ArgumentError,
|
142
|
+
raise ArgumentError, <<~MSG
|
139
143
|
'#{dependency}' is not supported for :on_update or :on_delete.
|
140
144
|
Supported values are: :nullify, :cascade, :restrict
|
141
145
|
MSG
|
@@ -143,5 +147,6 @@ module ActiveRecord
|
|
143
147
|
end
|
144
148
|
end
|
145
149
|
end
|
150
|
+
SchemaCreation = AbstractAdapter::SchemaCreation # :nodoc:
|
146
151
|
end
|
147
152
|
end
|