activerecord 4.2.0 → 6.0.0
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 +612 -971
- data/MIT-LICENSE +4 -2
- data/README.rdoc +13 -12
- data/examples/performance.rb +33 -32
- data/examples/simple.rb +5 -4
- data/lib/active_record/aggregations.rb +267 -248
- data/lib/active_record/association_relation.rb +24 -6
- data/lib/active_record/associations/alias_tracker.rb +29 -35
- data/lib/active_record/associations/association.rb +135 -56
- data/lib/active_record/associations/association_scope.rb +103 -131
- data/lib/active_record/associations/belongs_to_association.rb +67 -54
- data/lib/active_record/associations/belongs_to_polymorphic_association.rb +8 -12
- data/lib/active_record/associations/builder/association.rb +27 -40
- data/lib/active_record/associations/builder/belongs_to.rb +69 -55
- data/lib/active_record/associations/builder/collection_association.rb +10 -29
- data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +60 -70
- data/lib/active_record/associations/builder/has_many.rb +8 -4
- data/lib/active_record/associations/builder/has_one.rb +46 -5
- data/lib/active_record/associations/builder/singular_association.rb +16 -10
- data/lib/active_record/associations/collection_association.rb +138 -274
- data/lib/active_record/associations/collection_proxy.rb +252 -151
- data/lib/active_record/associations/foreign_association.rb +20 -0
- data/lib/active_record/associations/has_many_association.rb +35 -83
- data/lib/active_record/associations/has_many_through_association.rb +62 -80
- data/lib/active_record/associations/has_one_association.rb +62 -49
- data/lib/active_record/associations/has_one_through_association.rb +20 -11
- data/lib/active_record/associations/join_dependency/join_association.rb +38 -80
- 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 +138 -162
- data/lib/active_record/associations/preloader/association.rb +90 -119
- data/lib/active_record/associations/preloader/through_association.rb +85 -65
- data/lib/active_record/associations/preloader.rb +92 -94
- data/lib/active_record/associations/singular_association.rb +18 -45
- data/lib/active_record/associations/through_association.rb +48 -23
- data/lib/active_record/associations.rb +1737 -1596
- data/lib/active_record/attribute_assignment.rb +56 -183
- data/lib/active_record/attribute_decorators.rb +39 -15
- data/lib/active_record/attribute_methods/before_type_cast.rb +15 -5
- data/lib/active_record/attribute_methods/dirty.rb +174 -134
- data/lib/active_record/attribute_methods/primary_key.rb +91 -83
- data/lib/active_record/attribute_methods/query.rb +6 -5
- data/lib/active_record/attribute_methods/read.rb +20 -76
- data/lib/active_record/attribute_methods/serialization.rb +40 -20
- data/lib/active_record/attribute_methods/time_zone_conversion.rb +62 -36
- data/lib/active_record/attribute_methods/write.rb +33 -55
- data/lib/active_record/attribute_methods.rb +124 -143
- data/lib/active_record/attributes.rb +214 -74
- data/lib/active_record/autosave_association.rb +115 -46
- data/lib/active_record/base.rb +60 -49
- data/lib/active_record/callbacks.rb +100 -74
- data/lib/active_record/coders/json.rb +3 -1
- data/lib/active_record/coders/yaml_column.rb +24 -12
- data/lib/active_record/connection_adapters/abstract/connection_pool.rb +796 -290
- data/lib/active_record/connection_adapters/abstract/database_limits.rb +26 -8
- data/lib/active_record/connection_adapters/abstract/database_statements.rb +247 -108
- data/lib/active_record/connection_adapters/abstract/query_cache.rb +82 -23
- data/lib/active_record/connection_adapters/abstract/quoting.rb +171 -53
- data/lib/active_record/connection_adapters/abstract/savepoints.rb +6 -4
- data/lib/active_record/connection_adapters/abstract/schema_creation.rb +74 -46
- data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +366 -227
- data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +79 -36
- data/lib/active_record/connection_adapters/abstract/schema_statements.rb +706 -222
- data/lib/active_record/connection_adapters/abstract/transaction.rb +191 -87
- data/lib/active_record/connection_adapters/abstract_adapter.rb +468 -194
- data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +535 -597
- data/lib/active_record/connection_adapters/column.rb +56 -43
- data/lib/active_record/connection_adapters/connection_specification.rb +174 -152
- data/lib/active_record/connection_adapters/determine_if_preparable_visitor.rb +29 -0
- data/lib/active_record/connection_adapters/mysql/column.rb +27 -0
- data/lib/active_record/connection_adapters/mysql/database_statements.rb +200 -0
- data/lib/active_record/connection_adapters/mysql/explain_pretty_printer.rb +72 -0
- data/lib/active_record/connection_adapters/mysql/quoting.rb +81 -0
- data/lib/active_record/connection_adapters/mysql/schema_creation.rb +72 -0
- data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +95 -0
- data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +88 -0
- data/lib/active_record/connection_adapters/mysql/schema_statements.rb +264 -0
- data/lib/active_record/connection_adapters/mysql/type_metadata.rb +31 -0
- data/lib/active_record/connection_adapters/mysql2_adapter.rb +59 -195
- data/lib/active_record/connection_adapters/postgresql/column.rb +21 -11
- data/lib/active_record/connection_adapters/postgresql/database_statements.rb +65 -115
- data/lib/active_record/connection_adapters/postgresql/explain_pretty_printer.rb +44 -0
- data/lib/active_record/connection_adapters/postgresql/oid/array.rb +50 -57
- data/lib/active_record/connection_adapters/postgresql/oid/bit.rb +9 -8
- data/lib/active_record/connection_adapters/postgresql/oid/bit_varying.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/oid/bytea.rb +5 -2
- data/lib/active_record/connection_adapters/postgresql/oid/cidr.rb +5 -1
- data/lib/active_record/connection_adapters/postgresql/oid/date.rb +13 -1
- data/lib/active_record/connection_adapters/postgresql/oid/date_time.rb +9 -13
- data/lib/active_record/connection_adapters/postgresql/oid/decimal.rb +3 -1
- data/lib/active_record/connection_adapters/postgresql/oid/enum.rb +7 -3
- data/lib/active_record/connection_adapters/postgresql/oid/hstore.rb +31 -19
- 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 -9
- data/lib/active_record/connection_adapters/postgresql/oid/{integer.rb → oid.rb} +6 -2
- data/lib/active_record/connection_adapters/postgresql/oid/point.rb +33 -11
- data/lib/active_record/connection_adapters/postgresql/oid/range.rb +52 -34
- 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 +67 -51
- data/lib/active_record/connection_adapters/postgresql/oid/uuid.rb +10 -5
- data/lib/active_record/connection_adapters/postgresql/oid/vector.rb +3 -1
- data/lib/active_record/connection_adapters/postgresql/oid/xml.rb +3 -1
- data/lib/active_record/connection_adapters/postgresql/oid.rb +23 -25
- data/lib/active_record/connection_adapters/postgresql/quoting.rb +144 -47
- data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +27 -14
- data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +76 -0
- data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +178 -108
- data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +50 -0
- data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +474 -286
- data/lib/active_record/connection_adapters/postgresql/type_metadata.rb +36 -0
- data/lib/active_record/connection_adapters/postgresql/utils.rb +12 -8
- data/lib/active_record/connection_adapters/postgresql_adapter.rb +558 -363
- data/lib/active_record/connection_adapters/schema_cache.rb +72 -25
- data/lib/active_record/connection_adapters/sql_type_metadata.rb +37 -0
- data/lib/active_record/connection_adapters/sqlite3/database_statements.rb +118 -0
- data/lib/active_record/connection_adapters/sqlite3/explain_pretty_printer.rb +21 -0
- data/lib/active_record/connection_adapters/sqlite3/quoting.rb +103 -0
- data/lib/active_record/connection_adapters/sqlite3/schema_creation.rb +17 -0
- 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 +288 -359
- data/lib/active_record/connection_adapters/statement_pool.rb +34 -13
- data/lib/active_record/connection_handling.rb +176 -41
- data/lib/active_record/core.rb +266 -233
- data/lib/active_record/counter_cache.rb +68 -50
- 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 -105
- data/lib/active_record/enum.rb +164 -88
- data/lib/active_record/errors.rb +189 -53
- data/lib/active_record/explain.rb +23 -11
- data/lib/active_record/explain_registry.rb +4 -2
- data/lib/active_record/explain_subscriber.rb +11 -6
- data/lib/active_record/fixture_set/file.rb +35 -9
- 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 +226 -495
- data/lib/active_record/gem_version.rb +4 -2
- data/lib/active_record/inheritance.rb +158 -112
- data/lib/active_record/insert_all.rb +179 -0
- data/lib/active_record/integration.rb +123 -29
- data/lib/active_record/internal_metadata.rb +53 -0
- data/lib/active_record/legacy_yaml_adapter.rb +48 -0
- data/lib/active_record/locale/en.yml +3 -2
- data/lib/active_record/locking/optimistic.rb +91 -98
- data/lib/active_record/locking/pessimistic.rb +18 -6
- data/lib/active_record/log_subscriber.rb +76 -33
- data/lib/active_record/middleware/database_selector/resolver/session.rb +45 -0
- data/lib/active_record/middleware/database_selector/resolver.rb +92 -0
- data/lib/active_record/middleware/database_selector.rb +75 -0
- data/lib/active_record/migration/command_recorder.rb +177 -90
- data/lib/active_record/migration/compatibility.rb +244 -0
- data/lib/active_record/migration/join_table.rb +8 -6
- data/lib/active_record/migration.rb +634 -288
- data/lib/active_record/model_schema.rb +314 -112
- data/lib/active_record/nested_attributes.rb +266 -214
- data/lib/active_record/no_touching.rb +15 -2
- data/lib/active_record/null_relation.rb +24 -37
- data/lib/active_record/persistence.rb +559 -124
- data/lib/active_record/query_cache.rb +19 -23
- data/lib/active_record/querying.rb +43 -29
- data/lib/active_record/railtie.rb +148 -47
- 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 +338 -202
- data/lib/active_record/readonly_attributes.rb +5 -4
- data/lib/active_record/reflection.rb +460 -299
- data/lib/active_record/relation/batches/batch_enumerator.rb +69 -0
- data/lib/active_record/relation/batches.rb +207 -55
- data/lib/active_record/relation/calculations.rb +269 -248
- data/lib/active_record/relation/delegation.rb +70 -80
- data/lib/active_record/relation/finder_methods.rb +279 -255
- data/lib/active_record/relation/from_clause.rb +26 -0
- data/lib/active_record/relation/merger.rb +83 -69
- data/lib/active_record/relation/predicate_builder/array_handler.rb +27 -25
- data/lib/active_record/relation/predicate_builder/association_query_value.rb +43 -0
- data/lib/active_record/relation/predicate_builder/base_handler.rb +18 -0
- data/lib/active_record/relation/predicate_builder/basic_object_handler.rb +19 -0
- data/lib/active_record/relation/predicate_builder/polymorphic_array_value.rb +53 -0
- data/lib/active_record/relation/predicate_builder/range_handler.rb +22 -0
- data/lib/active_record/relation/predicate_builder/relation_handler.rb +7 -1
- data/lib/active_record/relation/predicate_builder.rb +116 -92
- data/lib/active_record/relation/query_attribute.rb +50 -0
- data/lib/active_record/relation/query_methods.rb +574 -391
- data/lib/active_record/relation/record_fetch_warning.rb +51 -0
- data/lib/active_record/relation/spawn_methods.rb +18 -16
- data/lib/active_record/relation/where_clause.rb +190 -0
- data/lib/active_record/relation/where_clause_factory.rb +33 -0
- data/lib/active_record/relation.rb +518 -340
- data/lib/active_record/result.rb +79 -42
- data/lib/active_record/runtime_registry.rb +6 -4
- data/lib/active_record/sanitization.rb +144 -121
- data/lib/active_record/schema.rb +21 -24
- data/lib/active_record/schema_dumper.rb +112 -93
- data/lib/active_record/schema_migration.rb +24 -20
- data/lib/active_record/scoping/default.rb +101 -84
- data/lib/active_record/scoping/named.rb +86 -33
- data/lib/active_record/scoping.rb +45 -26
- data/lib/active_record/secure_token.rb +40 -0
- data/lib/active_record/serialization.rb +5 -5
- data/lib/active_record/statement_cache.rb +73 -36
- data/lib/active_record/store.rb +127 -42
- data/lib/active_record/suppressor.rb +61 -0
- data/lib/active_record/table_metadata.rb +75 -0
- data/lib/active_record/tasks/database_tasks.rb +309 -99
- data/lib/active_record/tasks/mysql_database_tasks.rb +58 -88
- data/lib/active_record/tasks/postgresql_database_tasks.rb +82 -31
- data/lib/active_record/tasks/sqlite_database_tasks.rb +38 -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 +86 -40
- data/lib/active_record/touch_later.rb +66 -0
- data/lib/active_record/transactions.rb +215 -139
- data/lib/active_record/translation.rb +3 -1
- data/lib/active_record/type/adapter_specific_registry.rb +129 -0
- data/lib/active_record/type/date.rb +4 -41
- data/lib/active_record/type/date_time.rb +4 -38
- data/lib/active_record/type/decimal_without_scale.rb +6 -2
- data/lib/active_record/type/hash_lookup_type_map.rb +13 -5
- data/lib/active_record/type/internal/timezone.rb +17 -0
- data/lib/active_record/type/json.rb +30 -0
- data/lib/active_record/type/serialized.rb +30 -15
- data/lib/active_record/type/text.rb +2 -2
- data/lib/active_record/type/time.rb +11 -16
- data/lib/active_record/type/type_map.rb +15 -17
- data/lib/active_record/type/unsigned_integer.rb +9 -7
- data/lib/active_record/type.rb +78 -23
- data/lib/active_record/type_caster/connection.rb +34 -0
- data/lib/active_record/type_caster/map.rb +20 -0
- data/lib/active_record/type_caster.rb +9 -0
- data/lib/active_record/validations/absence.rb +25 -0
- data/lib/active_record/validations/associated.rb +13 -4
- data/lib/active_record/validations/length.rb +26 -0
- data/lib/active_record/validations/presence.rb +14 -13
- data/lib/active_record/validations/uniqueness.rb +43 -46
- data/lib/active_record/validations.rb +39 -35
- data/lib/active_record/version.rb +3 -1
- data/lib/active_record.rb +43 -21
- 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 +51 -0
- data/lib/rails/generators/active_record/application_record/application_record_generator.rb +27 -0
- data/lib/rails/generators/active_record/application_record/templates/application_record.rb.tt +5 -0
- data/lib/rails/generators/active_record/migration/migration_generator.rb +42 -37
- data/lib/rails/generators/active_record/migration/templates/create_table_migration.rb.tt +24 -0
- data/lib/rails/generators/active_record/migration/templates/{migration.rb → migration.rb.tt} +11 -8
- data/lib/rails/generators/active_record/migration.rb +31 -1
- data/lib/rails/generators/active_record/model/model_generator.rb +19 -22
- data/lib/rails/generators/active_record/model/templates/model.rb.tt +22 -0
- data/lib/rails/generators/active_record.rb +7 -5
- metadata +166 -60
- data/lib/active_record/associations/preloader/belongs_to.rb +0 -17
- data/lib/active_record/associations/preloader/collection_association.rb +0 -24
- 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 -23
- data/lib/active_record/associations/preloader/has_one_through.rb +0 -9
- data/lib/active_record/associations/preloader/singular_association.rb +0 -21
- data/lib/active_record/attribute.rb +0 -149
- data/lib/active_record/attribute_set/builder.rb +0 -86
- data/lib/active_record/attribute_set.rb +0 -77
- data/lib/active_record/connection_adapters/mysql_adapter.rb +0 -491
- data/lib/active_record/connection_adapters/postgresql/array_parser.rb +0 -93
- data/lib/active_record/connection_adapters/postgresql/oid/float.rb +0 -21
- data/lib/active_record/connection_adapters/postgresql/oid/infinity.rb +0 -13
- data/lib/active_record/connection_adapters/postgresql/oid/json.rb +0 -35
- data/lib/active_record/connection_adapters/postgresql/oid/time.rb +0 -11
- data/lib/active_record/railties/jdbcmysql_error.rb +0 -16
- data/lib/active_record/serializers/xml_serializer.rb +0 -193
- data/lib/active_record/type/big_integer.rb +0 -13
- data/lib/active_record/type/binary.rb +0 -50
- data/lib/active_record/type/boolean.rb +0 -30
- data/lib/active_record/type/decimal.rb +0 -40
- data/lib/active_record/type/decorator.rb +0 -14
- data/lib/active_record/type/float.rb +0 -19
- data/lib/active_record/type/integer.rb +0 -55
- data/lib/active_record/type/mutable.rb +0 -16
- data/lib/active_record/type/numeric.rb +0 -36
- data/lib/active_record/type/string.rb +0 -36
- data/lib/active_record/type/time_value.rb +0 -38
- data/lib/active_record/type/value.rb +0 -101
- data/lib/rails/generators/active_record/migration/templates/create_table_migration.rb +0 -22
- data/lib/rails/generators/active_record/model/templates/model.rb +0 -10
- /data/lib/rails/generators/active_record/model/templates/{module.rb → module.rb.tt} +0 -0
@@ -1,16 +1,24 @@
|
|
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
|
12
|
+
|
13
|
+
base.set_callback :checkout, :after, :configure_query_cache!
|
14
|
+
base.set_callback :checkin, :after, :disable_query_cache!
|
7
15
|
end
|
8
16
|
|
9
17
|
def dirties_query_cache(base, *method_names)
|
10
18
|
method_names.each do |method_name|
|
11
19
|
base.class_eval <<-end_code, __FILE__, __LINE__ + 1
|
12
20
|
def #{method_name}(*)
|
13
|
-
|
21
|
+
ActiveRecord::Base.clear_query_caches_for_current_thread if @query_cache_enabled
|
14
22
|
super
|
15
23
|
end
|
16
24
|
end_code
|
@@ -18,11 +26,32 @@ module ActiveRecord
|
|
18
26
|
end
|
19
27
|
end
|
20
28
|
|
29
|
+
module ConnectionPoolConfiguration
|
30
|
+
def initialize(*)
|
31
|
+
super
|
32
|
+
@query_cache_enabled = Concurrent::Map.new { false }
|
33
|
+
end
|
34
|
+
|
35
|
+
def enable_query_cache!
|
36
|
+
@query_cache_enabled[connection_cache_key(current_thread)] = true
|
37
|
+
connection.enable_query_cache! if active_connection?
|
38
|
+
end
|
39
|
+
|
40
|
+
def disable_query_cache!
|
41
|
+
@query_cache_enabled.delete connection_cache_key(current_thread)
|
42
|
+
connection.disable_query_cache! if active_connection?
|
43
|
+
end
|
44
|
+
|
45
|
+
def query_cache_enabled
|
46
|
+
@query_cache_enabled[connection_cache_key(current_thread)]
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
21
50
|
attr_reader :query_cache, :query_cache_enabled
|
22
51
|
|
23
52
|
def initialize(*)
|
24
53
|
super
|
25
|
-
@query_cache = Hash.new { |h,sql| h[sql] = {} }
|
54
|
+
@query_cache = Hash.new { |h, sql| h[sql] = {} }
|
26
55
|
@query_cache_enabled = false
|
27
56
|
end
|
28
57
|
|
@@ -41,6 +70,7 @@ module ActiveRecord
|
|
41
70
|
|
42
71
|
def disable_query_cache!
|
43
72
|
@query_cache_enabled = false
|
73
|
+
clear_query_cache
|
44
74
|
end
|
45
75
|
|
46
76
|
# Disable the query cache within the block.
|
@@ -58,14 +88,21 @@ module ActiveRecord
|
|
58
88
|
# the same SQL query and repeatedly return the same result each time, silently
|
59
89
|
# undermining the randomness you were expecting.
|
60
90
|
def clear_query_cache
|
61
|
-
@
|
91
|
+
@lock.synchronize do
|
92
|
+
@query_cache.clear
|
93
|
+
end
|
62
94
|
end
|
63
95
|
|
64
|
-
def select_all(arel, name = nil, binds = [])
|
96
|
+
def select_all(arel, name = nil, binds = [], preparable: nil)
|
65
97
|
if @query_cache_enabled && !locked?(arel)
|
66
|
-
arel
|
67
|
-
sql =
|
68
|
-
|
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) }
|
69
106
|
else
|
70
107
|
super
|
71
108
|
end
|
@@ -73,23 +110,45 @@ module ActiveRecord
|
|
73
110
|
|
74
111
|
private
|
75
112
|
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
113
|
+
def cache_sql(sql, name, binds)
|
114
|
+
@lock.synchronize do
|
115
|
+
result =
|
116
|
+
if @query_cache[sql].key?(binds)
|
117
|
+
ActiveSupport::Notifications.instrument(
|
118
|
+
"sql.active_record",
|
119
|
+
cache_notification_info(sql, name, binds)
|
120
|
+
)
|
121
|
+
@query_cache[sql][binds]
|
122
|
+
else
|
123
|
+
@query_cache[sql][binds] = yield
|
124
|
+
end
|
125
|
+
result.dup
|
84
126
|
end
|
85
|
-
|
86
|
-
end
|
127
|
+
end
|
87
128
|
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
129
|
+
# Database adapters can override this method to
|
130
|
+
# provide custom cache information.
|
131
|
+
def cache_notification_info(sql, name, binds)
|
132
|
+
{
|
133
|
+
sql: sql,
|
134
|
+
binds: binds,
|
135
|
+
type_casted_binds: -> { type_casted_binds(binds) },
|
136
|
+
name: name,
|
137
|
+
connection_id: object_id,
|
138
|
+
cached: true
|
139
|
+
}
|
140
|
+
end
|
141
|
+
|
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
|
93
152
|
end
|
94
153
|
end
|
95
154
|
end
|
@@ -1,16 +1,18 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "active_support/core_ext/big_decimal/conversions"
|
4
|
+
require "active_support/multibyte/chars"
|
2
5
|
|
3
6
|
module ActiveRecord
|
4
7
|
module ConnectionAdapters # :nodoc:
|
5
8
|
module Quoting
|
6
9
|
# Quotes the column value to help prevent
|
7
|
-
# {SQL injection attacks}[
|
8
|
-
def quote(value
|
9
|
-
|
10
|
-
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)
|
11
13
|
|
12
|
-
if
|
13
|
-
value =
|
14
|
+
if value.respond_to?(:value_for_database)
|
15
|
+
value = value.value_for_database
|
14
16
|
end
|
15
17
|
|
16
18
|
_quote(value)
|
@@ -19,13 +21,11 @@ module ActiveRecord
|
|
19
21
|
# Cast a +value+ to a type that the database understands. For example,
|
20
22
|
# SQLite does not understand dates, so this method will convert a Date
|
21
23
|
# to a String.
|
22
|
-
def type_cast(value, column)
|
23
|
-
|
24
|
-
return value.id
|
25
|
-
end
|
24
|
+
def type_cast(value, column = nil)
|
25
|
+
value = id_value_for_database(value) if value.is_a?(Base)
|
26
26
|
|
27
27
|
if column
|
28
|
-
value = column
|
28
|
+
value = type_cast_from_column(column, value)
|
29
29
|
end
|
30
30
|
|
31
31
|
_type_cast(value)
|
@@ -34,15 +34,38 @@ module ActiveRecord
|
|
34
34
|
raise TypeError, "can't cast #{value.class}#{to_type}"
|
35
35
|
end
|
36
36
|
|
37
|
+
# If you are having to call this function, you are likely doing something
|
38
|
+
# wrong. The column does not have sufficient type information if the user
|
39
|
+
# provided a custom type on the class level either explicitly (via
|
40
|
+
# Attributes::ClassMethods#attribute) or implicitly (via
|
41
|
+
# AttributeMethods::Serialization::ClassMethods#serialize, +time_zone_aware_attributes+).
|
42
|
+
# In almost all cases, the sql type should only be used to change quoting behavior, when the primitive to
|
43
|
+
# represent the type doesn't sufficiently reflect the differences
|
44
|
+
# (varchar vs binary) for example. The type used to get this primitive
|
45
|
+
# should have been provided before reaching the connection adapter.
|
46
|
+
def type_cast_from_column(column, value) # :nodoc:
|
47
|
+
if column
|
48
|
+
type = lookup_cast_type_from_column(column)
|
49
|
+
type.serialize(value)
|
50
|
+
else
|
51
|
+
value
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
# See docs for #type_cast_from_column
|
56
|
+
def lookup_cast_type_from_column(column) # :nodoc:
|
57
|
+
lookup_cast_type(column.sql_type)
|
58
|
+
end
|
59
|
+
|
37
60
|
# Quotes a string, escaping any ' (single quote) and \ (backslash)
|
38
61
|
# characters.
|
39
62
|
def quote_string(s)
|
40
|
-
s.gsub(
|
63
|
+
s.gsub('\\', '\&\&').gsub("'", "''") # ' (for ruby-mode)
|
41
64
|
end
|
42
65
|
|
43
66
|
# Quotes the column name. Defaults to no quoting.
|
44
67
|
def quote_column_name(column_name)
|
45
|
-
column_name
|
68
|
+
column_name.to_s
|
46
69
|
end
|
47
70
|
|
48
71
|
# Quotes the table name. Defaults to column name quoting.
|
@@ -53,7 +76,7 @@ module ActiveRecord
|
|
53
76
|
# Override to return the quoted table name for assignment. Defaults to
|
54
77
|
# table quoting.
|
55
78
|
#
|
56
|
-
# This works for
|
79
|
+
# This works for mysql2 where table.column can be used to
|
57
80
|
# resolve ambiguity.
|
58
81
|
#
|
59
82
|
# We override this in the sqlite3 and postgresql adapters to use only
|
@@ -62,22 +85,33 @@ module ActiveRecord
|
|
62
85
|
quote_table_name("#{table}.#{attr}")
|
63
86
|
end
|
64
87
|
|
88
|
+
def quote_default_expression(value, column) # :nodoc:
|
89
|
+
if value.is_a?(Proc)
|
90
|
+
value.call
|
91
|
+
else
|
92
|
+
value = lookup_cast_type(column.sql_type).serialize(value)
|
93
|
+
quote(value)
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
65
97
|
def quoted_true
|
66
|
-
"
|
98
|
+
"TRUE"
|
67
99
|
end
|
68
100
|
|
69
101
|
def unquoted_true
|
70
|
-
|
102
|
+
true
|
71
103
|
end
|
72
104
|
|
73
105
|
def quoted_false
|
74
|
-
"
|
106
|
+
"FALSE"
|
75
107
|
end
|
76
108
|
|
77
109
|
def unquoted_false
|
78
|
-
|
110
|
+
false
|
79
111
|
end
|
80
112
|
|
113
|
+
# Quote date/time values for use in SQL input. Includes microseconds
|
114
|
+
# if the value is a Time responding to usec.
|
81
115
|
def quoted_date(value)
|
82
116
|
if value.acts_like?(:time)
|
83
117
|
zone_conversion_method = ActiveRecord::Base.default_timezone == :utc ? :getutc : :getlocal
|
@@ -87,47 +121,131 @@ module ActiveRecord
|
|
87
121
|
end
|
88
122
|
end
|
89
123
|
|
90
|
-
value.to_s(:db)
|
124
|
+
result = value.to_s(:db)
|
125
|
+
if value.respond_to?(:usec) && value.usec > 0
|
126
|
+
"#{result}.#{sprintf("%06d", value.usec)}"
|
127
|
+
else
|
128
|
+
result
|
129
|
+
end
|
91
130
|
end
|
92
131
|
|
132
|
+
def quoted_time(value) # :nodoc:
|
133
|
+
value = value.change(year: 2000, month: 1, day: 1)
|
134
|
+
quoted_date(value).sub(/\A\d\d\d\d-\d\d-\d\d /, "")
|
135
|
+
end
|
136
|
+
|
137
|
+
def quoted_binary(value) # :nodoc:
|
138
|
+
"'#{quote_string(value.to_s)}'"
|
139
|
+
end
|
140
|
+
|
141
|
+
def sanitize_as_sql_comment(value) # :nodoc:
|
142
|
+
value.to_s.gsub(%r{ (/ (?: | \g<1>) \*) \+? \s* | \s* (\* (?: | \g<2>) /) }x, "")
|
143
|
+
end
|
144
|
+
|
145
|
+
def column_name_matcher # :nodoc:
|
146
|
+
COLUMN_NAME
|
147
|
+
end
|
148
|
+
|
149
|
+
def column_name_with_order_matcher # :nodoc:
|
150
|
+
COLUMN_NAME_WITH_ORDER
|
151
|
+
end
|
152
|
+
|
153
|
+
# Regexp for column names (with or without a table name prefix).
|
154
|
+
# Matches the following:
|
155
|
+
#
|
156
|
+
# "#{table_name}.#{column_name}"
|
157
|
+
# "#{column_name}"
|
158
|
+
COLUMN_NAME = /
|
159
|
+
\A
|
160
|
+
(
|
161
|
+
(?:
|
162
|
+
# table_name.column_name | function(one or no argument)
|
163
|
+
((?:\w+\.)?\w+) | \w+\((?:|\g<2>)\)
|
164
|
+
)
|
165
|
+
(?:\s+AS\s+\w+)?
|
166
|
+
)
|
167
|
+
(?:\s*,\s*\g<1>)*
|
168
|
+
\z
|
169
|
+
/ix
|
170
|
+
|
171
|
+
# Regexp for column names with order (with or without a table name prefix,
|
172
|
+
# with or without various order modifiers). Matches the following:
|
173
|
+
#
|
174
|
+
# "#{table_name}.#{column_name}"
|
175
|
+
# "#{table_name}.#{column_name} #{direction}"
|
176
|
+
# "#{table_name}.#{column_name} #{direction} NULLS FIRST"
|
177
|
+
# "#{table_name}.#{column_name} NULLS LAST"
|
178
|
+
# "#{column_name}"
|
179
|
+
# "#{column_name} #{direction}"
|
180
|
+
# "#{column_name} #{direction} NULLS FIRST"
|
181
|
+
# "#{column_name} NULLS LAST"
|
182
|
+
COLUMN_NAME_WITH_ORDER = /
|
183
|
+
\A
|
184
|
+
(
|
185
|
+
(?:
|
186
|
+
# table_name.column_name | function(one or no argument)
|
187
|
+
((?:\w+\.)?\w+) | \w+\((?:|\g<2>)\)
|
188
|
+
)
|
189
|
+
(?:\s+ASC|\s+DESC)?
|
190
|
+
(?:\s+NULLS\s+(?:FIRST|LAST))?
|
191
|
+
)
|
192
|
+
(?:\s*,\s*\g<1>)*
|
193
|
+
\z
|
194
|
+
/ix
|
195
|
+
|
196
|
+
private_constant :COLUMN_NAME, :COLUMN_NAME_WITH_ORDER
|
197
|
+
|
93
198
|
private
|
199
|
+
def type_casted_binds(binds)
|
200
|
+
if binds.first.is_a?(Array)
|
201
|
+
binds.map { |column, value| type_cast(value, column) }
|
202
|
+
else
|
203
|
+
binds.map { |attr| type_cast(attr.value_for_database) }
|
204
|
+
end
|
205
|
+
end
|
94
206
|
|
95
|
-
|
96
|
-
|
97
|
-
end
|
98
|
-
|
99
|
-
def _quote(value)
|
100
|
-
case value
|
101
|
-
when String, ActiveSupport::Multibyte::Chars, Type::Binary::Data
|
102
|
-
"'#{quote_string(value.to_s)}'"
|
103
|
-
when true then quoted_true
|
104
|
-
when false then quoted_false
|
105
|
-
when nil then "NULL"
|
106
|
-
# BigDecimals need to be put in a non-normalized form and quoted.
|
107
|
-
when BigDecimal then value.to_s('F')
|
108
|
-
when Numeric, ActiveSupport::Duration then value.to_s
|
109
|
-
when Date, Time then "'#{quoted_date(value)}'"
|
110
|
-
when Symbol then "'#{quote_string(value.to_s)}'"
|
111
|
-
when Class then "'#{value}'"
|
112
|
-
else
|
113
|
-
"'#{quote_string(YAML.dump(value))}'"
|
207
|
+
def lookup_cast_type(sql_type)
|
208
|
+
type_map.lookup(sql_type)
|
114
209
|
end
|
115
|
-
end
|
116
210
|
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
211
|
+
def id_value_for_database(value)
|
212
|
+
if primary_key = value.class.primary_key
|
213
|
+
value.instance_variable_get(:@attributes)[primary_key].value_for_database
|
214
|
+
end
|
215
|
+
end
|
216
|
+
|
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
|
247
|
+
end
|
129
248
|
end
|
130
|
-
end
|
131
249
|
end
|
132
250
|
end
|
133
251
|
end
|
@@ -1,15 +1,17 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module ActiveRecord
|
2
4
|
module ConnectionAdapters
|
3
|
-
module Savepoints
|
4
|
-
def
|
5
|
-
|
5
|
+
module Savepoints
|
6
|
+
def current_savepoint_name
|
7
|
+
current_transaction.savepoint_name
|
6
8
|
end
|
7
9
|
|
8
10
|
def create_savepoint(name = current_savepoint_name)
|
9
11
|
execute("SAVEPOINT #{name}")
|
10
12
|
end
|
11
13
|
|
12
|
-
def
|
14
|
+
def exec_rollback_to_savepoint(name = current_savepoint_name)
|
13
15
|
execute("ROLLBACK TO SAVEPOINT #{name}")
|
14
16
|
end
|
15
17
|
|
@@ -1,4 +1,4 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module ActiveRecord
|
4
4
|
module ConnectionAdapters
|
@@ -14,38 +14,59 @@ module ActiveRecord
|
|
14
14
|
send m, o
|
15
15
|
end
|
16
16
|
|
17
|
-
|
18
|
-
|
19
|
-
|
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
|
+
to: :@conn, private: true
|
20
20
|
|
21
21
|
private
|
22
22
|
|
23
23
|
def visit_AlterTable(o)
|
24
|
-
sql = "ALTER TABLE #{quote_table_name(o.name)} "
|
25
|
-
sql << o.adds.map { |col|
|
26
|
-
sql << o.foreign_key_adds.map { |fk| visit_AddForeignKey fk }.join(
|
27
|
-
sql << o.foreign_key_drops.map { |fk| visit_DropForeignKey fk }.join(
|
24
|
+
sql = +"ALTER TABLE #{quote_table_name(o.name)} "
|
25
|
+
sql << o.adds.map { |col| accept col }.join(" ")
|
26
|
+
sql << o.foreign_key_adds.map { |fk| visit_AddForeignKey fk }.join(" ")
|
27
|
+
sql << o.foreign_key_drops.map { |fk| visit_DropForeignKey fk }.join(" ")
|
28
28
|
end
|
29
29
|
|
30
30
|
def visit_ColumnDefinition(o)
|
31
|
-
sql_type = type_to_sql(o.type, o.
|
32
|
-
column_sql = "#{quote_column_name(o.name)} #{sql_type}"
|
33
|
-
add_column_options!(column_sql, column_options(o)) unless o.primary_key
|
31
|
+
o.sql_type = type_to_sql(o.type, o.options)
|
32
|
+
column_sql = +"#{quote_column_name(o.name)} #{o.sql_type}"
|
33
|
+
add_column_options!(column_sql, column_options(o)) unless o.type == :primary_key
|
34
34
|
column_sql
|
35
35
|
end
|
36
36
|
|
37
|
+
def visit_AddColumnDefinition(o)
|
38
|
+
+"ADD #{accept(o.column)}"
|
39
|
+
end
|
40
|
+
|
37
41
|
def visit_TableDefinition(o)
|
38
|
-
create_sql = "CREATE#{
|
42
|
+
create_sql = +"CREATE#{table_modifier_in_create(o)} TABLE "
|
43
|
+
create_sql << "IF NOT EXISTS " if o.if_not_exists
|
39
44
|
create_sql << "#{quote_table_name(o.name)} "
|
40
|
-
|
41
|
-
|
42
|
-
|
45
|
+
|
46
|
+
statements = o.columns.map { |c| accept c }
|
47
|
+
statements << accept(o.primary_keys) if o.primary_keys
|
48
|
+
|
49
|
+
if supports_indexes_in_create?
|
50
|
+
statements.concat(o.indexes.map { |column_name, options| index_in_create(o.name, column_name, options) })
|
51
|
+
end
|
52
|
+
|
53
|
+
if supports_foreign_keys?
|
54
|
+
statements.concat(o.foreign_keys.map { |to_table, options| foreign_key_in_create(o.name, to_table, options) })
|
55
|
+
end
|
56
|
+
|
57
|
+
create_sql << "(#{statements.join(', ')})" if statements.present?
|
58
|
+
add_table_options!(create_sql, table_options(o))
|
59
|
+
create_sql << " AS #{to_sql(o.as)}" if o.as
|
43
60
|
create_sql
|
44
61
|
end
|
45
62
|
|
46
|
-
def
|
47
|
-
|
48
|
-
|
63
|
+
def visit_PrimaryKeyDefinition(o)
|
64
|
+
"PRIMARY KEY (#{o.name.map { |name| quote_column_name(name) }.join(', ')})"
|
65
|
+
end
|
66
|
+
|
67
|
+
def visit_ForeignKeyDefinition(o)
|
68
|
+
sql = +<<~SQL
|
69
|
+
CONSTRAINT #{quote_column_name(o.name)}
|
49
70
|
FOREIGN KEY (#{quote_column_name(o.column)})
|
50
71
|
REFERENCES #{quote_table_name(o.to_table)} (#{quote_column_name(o.primary_key)})
|
51
72
|
SQL
|
@@ -54,34 +75,34 @@ module ActiveRecord
|
|
54
75
|
sql
|
55
76
|
end
|
56
77
|
|
57
|
-
def
|
58
|
-
"
|
78
|
+
def visit_AddForeignKey(o)
|
79
|
+
"ADD #{accept(o)}"
|
59
80
|
end
|
60
81
|
|
61
|
-
def
|
62
|
-
|
63
|
-
column_options[:null] = o.null unless o.null.nil?
|
64
|
-
column_options[:default] = o.default unless o.default.nil?
|
65
|
-
column_options[:column] = o
|
66
|
-
column_options[:first] = o.first
|
67
|
-
column_options[:after] = o.after
|
68
|
-
column_options
|
82
|
+
def visit_DropForeignKey(name)
|
83
|
+
"DROP CONSTRAINT #{quote_column_name(name)}"
|
69
84
|
end
|
70
85
|
|
71
|
-
def
|
72
|
-
|
86
|
+
def table_options(o)
|
87
|
+
table_options = {}
|
88
|
+
table_options[:comment] = o.comment
|
89
|
+
table_options[:options] = o.options
|
90
|
+
table_options
|
73
91
|
end
|
74
92
|
|
75
|
-
def
|
76
|
-
|
93
|
+
def add_table_options!(create_sql, options)
|
94
|
+
if options_sql = options[:options]
|
95
|
+
create_sql << " #{options_sql}"
|
96
|
+
end
|
97
|
+
create_sql
|
77
98
|
end
|
78
99
|
|
79
|
-
def
|
80
|
-
|
100
|
+
def column_options(o)
|
101
|
+
o.options.merge(column: o)
|
81
102
|
end
|
82
103
|
|
83
104
|
def add_column_options!(sql, options)
|
84
|
-
sql << " DEFAULT #{
|
105
|
+
sql << " DEFAULT #{quote_default_expression(options[:default], options[:column])}" if options_include_default?(options)
|
85
106
|
# must explicitly check for :null to allow change_column to work on migrations
|
86
107
|
if options[:null] == false
|
87
108
|
sql << " NOT NULL"
|
@@ -89,18 +110,28 @@ module ActiveRecord
|
|
89
110
|
if options[:auto_increment] == true
|
90
111
|
sql << " AUTO_INCREMENT"
|
91
112
|
end
|
113
|
+
if options[:primary_key] == true
|
114
|
+
sql << " PRIMARY KEY"
|
115
|
+
end
|
92
116
|
sql
|
93
117
|
end
|
94
118
|
|
95
|
-
def
|
96
|
-
|
97
|
-
|
119
|
+
def to_sql(sql)
|
120
|
+
sql = sql.to_sql if sql.respond_to?(:to_sql)
|
121
|
+
sql
|
122
|
+
end
|
98
123
|
|
99
|
-
|
124
|
+
# Returns any SQL string to go between CREATE and TABLE. May be nil.
|
125
|
+
def table_modifier_in_create(o)
|
126
|
+
" TEMPORARY" if o.temporary
|
100
127
|
end
|
101
128
|
|
102
|
-
def
|
103
|
-
|
129
|
+
def foreign_key_in_create(from_table, to_table, options)
|
130
|
+
prefix = ActiveRecord::Base.table_name_prefix
|
131
|
+
suffix = ActiveRecord::Base.table_name_suffix
|
132
|
+
to_table = "#{prefix}#{to_table}#{suffix}"
|
133
|
+
options = foreign_key_options(from_table, to_table, options)
|
134
|
+
accept ForeignKeyDefinition.new(from_table, to_table, options)
|
104
135
|
end
|
105
136
|
|
106
137
|
def action_sql(action, dependency)
|
@@ -109,17 +140,14 @@ module ActiveRecord
|
|
109
140
|
when :cascade then "ON #{action} CASCADE"
|
110
141
|
when :restrict then "ON #{action} RESTRICT"
|
111
142
|
else
|
112
|
-
raise ArgumentError,
|
143
|
+
raise ArgumentError, <<~MSG
|
113
144
|
'#{dependency}' is not supported for :on_update or :on_delete.
|
114
145
|
Supported values are: :nullify, :cascade, :restrict
|
115
146
|
MSG
|
116
147
|
end
|
117
148
|
end
|
118
|
-
|
119
|
-
def type_for_column(column)
|
120
|
-
@conn.lookup_cast_type(column.sql_type)
|
121
|
-
end
|
122
149
|
end
|
123
150
|
end
|
151
|
+
SchemaCreation = AbstractAdapter::SchemaCreation # :nodoc:
|
124
152
|
end
|
125
153
|
end
|