activerecord 4.2.0 → 6.0.5.1
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of activerecord might be problematic. Click here for more details.
- checksums.yaml +5 -5
- data/CHANGELOG.md +852 -801
- data/MIT-LICENSE +4 -2
- data/README.rdoc +14 -13
- data/examples/performance.rb +33 -32
- data/examples/simple.rb +5 -4
- data/lib/active_record/advisory_lock_base.rb +18 -0
- data/lib/active_record/aggregations.rb +267 -249
- data/lib/active_record/association_relation.rb +26 -6
- data/lib/active_record/associations/alias_tracker.rb +29 -36
- data/lib/active_record/associations/association.rb +137 -55
- data/lib/active_record/associations/association_scope.rb +110 -132
- 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 +58 -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 +150 -275
- data/lib/active_record/associations/collection_proxy.rb +253 -152
- data/lib/active_record/associations/foreign_association.rb +20 -0
- data/lib/active_record/associations/has_many_association.rb +35 -84
- 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 +43 -78
- 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 +159 -162
- data/lib/active_record/associations/preloader/association.rb +102 -113
- data/lib/active_record/associations/preloader/through_association.rb +85 -65
- data/lib/active_record/associations/preloader.rb +96 -95
- data/lib/active_record/associations/singular_association.rb +18 -45
- data/lib/active_record/associations/through_association.rb +49 -24
- data/lib/active_record/associations.rb +1737 -1596
- data/lib/active_record/attribute_assignment.rb +57 -185
- data/lib/active_record/attribute_decorators.rb +39 -17
- data/lib/active_record/attribute_methods/before_type_cast.rb +14 -5
- data/lib/active_record/attribute_methods/dirty.rb +174 -134
- data/lib/active_record/attribute_methods/primary_key.rb +90 -84
- data/lib/active_record/attribute_methods/query.rb +6 -5
- data/lib/active_record/attribute_methods/read.rb +20 -77
- data/lib/active_record/attribute_methods/serialization.rb +40 -21
- data/lib/active_record/attribute_methods/time_zone_conversion.rb +61 -37
- data/lib/active_record/attribute_methods/write.rb +33 -56
- data/lib/active_record/attribute_methods.rb +124 -143
- data/lib/active_record/attributes.rb +213 -74
- data/lib/active_record/autosave_association.rb +125 -54
- data/lib/active_record/base.rb +60 -49
- data/lib/active_record/callbacks.rb +101 -76
- data/lib/active_record/coders/json.rb +3 -1
- data/lib/active_record/coders/yaml_column.rb +36 -13
- data/lib/active_record/connection_adapters/abstract/connection_pool.rb +810 -291
- data/lib/active_record/connection_adapters/abstract/database_limits.rb +26 -8
- data/lib/active_record/connection_adapters/abstract/database_statements.rb +253 -108
- data/lib/active_record/connection_adapters/abstract/query_cache.rb +83 -24
- 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 -47
- data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +383 -239
- data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +79 -36
- data/lib/active_record/connection_adapters/abstract/schema_statements.rb +736 -235
- data/lib/active_record/connection_adapters/abstract/transaction.rb +190 -87
- data/lib/active_record/connection_adapters/abstract_adapter.rb +487 -192
- data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +536 -600
- data/lib/active_record/connection_adapters/column.rb +56 -43
- data/lib/active_record/connection_adapters/connection_specification.rb +174 -153
- 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 +196 -0
- data/lib/active_record/connection_adapters/mysql/explain_pretty_printer.rb +71 -0
- data/lib/active_record/connection_adapters/mysql/quoting.rb +81 -0
- data/lib/active_record/connection_adapters/mysql/schema_creation.rb +71 -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 +268 -0
- data/lib/active_record/connection_adapters/mysql/type_metadata.rb +31 -0
- data/lib/active_record/connection_adapters/mysql2_adapter.rb +59 -196
- data/lib/active_record/connection_adapters/postgresql/column.rb +21 -11
- data/lib/active_record/connection_adapters/postgresql/database_statements.rb +71 -115
- data/lib/active_record/connection_adapters/postgresql/explain_pretty_printer.rb +44 -0
- data/lib/active_record/connection_adapters/postgresql/oid/array.rb +49 -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 +17 -13
- data/lib/active_record/connection_adapters/postgresql/oid/decimal.rb +3 -1
- data/lib/active_record/connection_adapters/postgresql/oid/enum.rb +6 -3
- data/lib/active_record/connection_adapters/postgresql/oid/hstore.rb +31 -20
- 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 -9
- data/lib/active_record/connection_adapters/postgresql/oid/{infinity.rb → oid.rb} +5 -3
- data/lib/active_record/connection_adapters/postgresql/oid/point.rb +32 -11
- data/lib/active_record/connection_adapters/postgresql/oid/range.rb +70 -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 +9 -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 +49 -0
- data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +465 -291
- data/lib/active_record/connection_adapters/postgresql/type_metadata.rb +36 -0
- data/lib/active_record/connection_adapters/postgresql/utils.rb +11 -8
- data/lib/active_record/connection_adapters/postgresql_adapter.rb +565 -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 +119 -0
- data/lib/active_record/connection_adapters/sqlite3/explain_pretty_printer.rb +21 -0
- data/lib/active_record/connection_adapters/sqlite3/quoting.rb +102 -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 +299 -364
- data/lib/active_record/connection_adapters/statement_pool.rb +33 -13
- data/lib/active_record/connection_handling.rb +167 -41
- data/lib/active_record/core.rb +277 -233
- data/lib/active_record/counter_cache.rb +71 -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 +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 -106
- data/lib/active_record/enum.rb +172 -89
- data/lib/active_record/errors.rb +189 -53
- data/lib/active_record/explain.rb +22 -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 +152 -0
- data/lib/active_record/fixture_set/table_rows.rb +46 -0
- data/lib/active_record/fixtures.rb +225 -497
- data/lib/active_record/gem_version.rb +6 -4
- data/lib/active_record/inheritance.rb +158 -115
- 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 +99 -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 +87 -0
- data/lib/active_record/middleware/database_selector.rb +74 -0
- data/lib/active_record/migration/command_recorder.rb +166 -91
- data/lib/active_record/migration/compatibility.rb +244 -0
- data/lib/active_record/migration/join_table.rb +8 -7
- data/lib/active_record/migration.rb +636 -290
- data/lib/active_record/model_schema.rb +344 -112
- data/lib/active_record/nested_attributes.rb +265 -215
- data/lib/active_record/no_touching.rb +15 -2
- data/lib/active_record/null_relation.rb +24 -38
- data/lib/active_record/persistence.rb +559 -125
- data/lib/active_record/query_cache.rb +19 -23
- data/lib/active_record/querying.rb +44 -30
- data/lib/active_record/railtie.rb +166 -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 +341 -202
- data/lib/active_record/readonly_attributes.rb +5 -4
- data/lib/active_record/reflection.rb +461 -302
- data/lib/active_record/relation/batches/batch_enumerator.rb +69 -0
- data/lib/active_record/relation/batches.rb +206 -55
- data/lib/active_record/relation/calculations.rb +270 -249
- data/lib/active_record/relation/delegation.rb +76 -84
- data/lib/active_record/relation/finder_methods.rb +287 -255
- data/lib/active_record/relation/from_clause.rb +30 -0
- data/lib/active_record/relation/merger.rb +86 -68
- 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 +112 -92
- data/lib/active_record/relation/query_attribute.rb +50 -0
- data/lib/active_record/relation/query_methods.rb +612 -392
- data/lib/active_record/relation/record_fetch_warning.rb +51 -0
- data/lib/active_record/relation/spawn_methods.rb +18 -17
- data/lib/active_record/relation/where_clause.rb +189 -0
- data/lib/active_record/relation/where_clause_factory.rb +33 -0
- data/lib/active_record/relation.rb +533 -340
- data/lib/active_record/result.rb +79 -43
- 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 +98 -82
- data/lib/active_record/scoping/named.rb +91 -33
- data/lib/active_record/scoping.rb +45 -27
- 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 +90 -0
- data/lib/active_record/tasks/database_tasks.rb +309 -99
- data/lib/active_record/tasks/mysql_database_tasks.rb +58 -89
- data/lib/active_record/tasks/postgresql_database_tasks.rb +81 -31
- data/lib/active_record/tasks/sqlite_database_tasks.rb +37 -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 +86 -41
- data/lib/active_record/touch_later.rb +65 -0
- data/lib/active_record/transactions.rb +222 -146
- data/lib/active_record/translation.rb +3 -1
- data/lib/active_record/type/adapter_specific_registry.rb +126 -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 +12 -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 +29 -15
- data/lib/active_record/type/text.rb +2 -2
- data/lib/active_record/type/time.rb +21 -16
- data/lib/active_record/type/type_map.rb +16 -19
- data/lib/active_record/type/unsigned_integer.rb +9 -8
- data/lib/active_record/type.rb +77 -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 +12 -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 +38 -35
- data/lib/active_record/version.rb +3 -1
- data/lib/active_record.rb +44 -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 +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/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 +30 -1
- data/lib/rails/generators/active_record/model/model_generator.rb +18 -22
- data/lib/rails/generators/active_record/model/templates/model.rb.tt +22 -0
- data/lib/rails/generators/active_record.rb +7 -5
- metadata +174 -63
- 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/integer.rb +0 -11
- 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,31 +1,81 @@
|
|
1
|
-
|
2
|
-
require 'set'
|
3
|
-
require 'bigdecimal'
|
4
|
-
require 'bigdecimal/util'
|
1
|
+
# frozen_string_literal: true
|
5
2
|
|
6
3
|
module ActiveRecord
|
7
4
|
module ConnectionAdapters #:nodoc:
|
8
5
|
# Abstract representation of an index definition on a table. Instances of
|
9
6
|
# this type are typically created and returned by methods in database
|
10
|
-
# adapters. e.g. ActiveRecord::ConnectionAdapters::
|
11
|
-
class IndexDefinition
|
7
|
+
# adapters. e.g. ActiveRecord::ConnectionAdapters::MySQL::SchemaStatements#indexes
|
8
|
+
class IndexDefinition # :nodoc:
|
9
|
+
attr_reader :table, :name, :unique, :columns, :lengths, :orders, :opclasses, :where, :type, :using, :comment
|
10
|
+
|
11
|
+
def initialize(
|
12
|
+
table, name,
|
13
|
+
unique = false,
|
14
|
+
columns = [],
|
15
|
+
lengths: {},
|
16
|
+
orders: {},
|
17
|
+
opclasses: {},
|
18
|
+
where: nil,
|
19
|
+
type: nil,
|
20
|
+
using: nil,
|
21
|
+
comment: nil
|
22
|
+
)
|
23
|
+
@table = table
|
24
|
+
@name = name
|
25
|
+
@unique = unique
|
26
|
+
@columns = columns
|
27
|
+
@lengths = concise_options(lengths)
|
28
|
+
@orders = concise_options(orders)
|
29
|
+
@opclasses = concise_options(opclasses)
|
30
|
+
@where = where
|
31
|
+
@type = type
|
32
|
+
@using = using
|
33
|
+
@comment = comment
|
34
|
+
end
|
35
|
+
|
36
|
+
private
|
37
|
+
def concise_options(options)
|
38
|
+
if columns.size == options.size && options.values.uniq.size == 1
|
39
|
+
options.values.first
|
40
|
+
else
|
41
|
+
options
|
42
|
+
end
|
43
|
+
end
|
12
44
|
end
|
13
45
|
|
14
46
|
# Abstract representation of a column definition. Instances of this type
|
15
47
|
# are typically created by methods in TableDefinition, and added to the
|
16
48
|
# +columns+ attribute of said TableDefinition object, in order to be used
|
17
49
|
# for generating a number of table creation or table changing SQL statements.
|
18
|
-
|
19
|
-
|
50
|
+
ColumnDefinition = Struct.new(:name, :type, :options, :sql_type) do # :nodoc:
|
20
51
|
def primary_key?
|
21
|
-
|
52
|
+
options[:primary_key]
|
22
53
|
end
|
23
|
-
end
|
24
54
|
|
25
|
-
|
55
|
+
[:limit, :precision, :scale, :default, :null, :collation, :comment].each do |option_name|
|
56
|
+
module_eval <<-CODE, __FILE__, __LINE__ + 1
|
57
|
+
def #{option_name}
|
58
|
+
options[:#{option_name}]
|
59
|
+
end
|
60
|
+
|
61
|
+
def #{option_name}=(value)
|
62
|
+
options[:#{option_name}] = value
|
63
|
+
end
|
64
|
+
CODE
|
65
|
+
end
|
66
|
+
|
67
|
+
def aliased_types(name, fallback)
|
68
|
+
"timestamp" == name ? :datetime : fallback
|
69
|
+
end
|
26
70
|
end
|
27
71
|
|
28
|
-
|
72
|
+
AddColumnDefinition = Struct.new(:column) # :nodoc:
|
73
|
+
|
74
|
+
ChangeColumnDefinition = Struct.new(:column, :name) #:nodoc:
|
75
|
+
|
76
|
+
PrimaryKeyDefinition = Struct.new(:name) # :nodoc:
|
77
|
+
|
78
|
+
ForeignKeyDefinition = Struct.new(:from_table, :to_table, :options) do #:nodoc:
|
29
79
|
def name
|
30
80
|
options[:name]
|
31
81
|
end
|
@@ -50,31 +100,153 @@ module ActiveRecord
|
|
50
100
|
options[:primary_key] != default_primary_key
|
51
101
|
end
|
52
102
|
|
103
|
+
def validate?
|
104
|
+
options.fetch(:validate, true)
|
105
|
+
end
|
106
|
+
alias validated? validate?
|
107
|
+
|
108
|
+
def export_name_on_schema_dump?
|
109
|
+
!ActiveRecord::SchemaDumper.fk_ignore_pattern.match?(name) if name
|
110
|
+
end
|
111
|
+
|
112
|
+
def defined_for?(to_table: nil, validate: nil, **options)
|
113
|
+
(to_table.nil? || to_table.to_s == self.to_table) &&
|
114
|
+
(validate.nil? || validate == options.fetch(:validate, validate)) &&
|
115
|
+
options.all? { |k, v| self.options[k].to_s == v.to_s }
|
116
|
+
end
|
117
|
+
|
53
118
|
private
|
54
|
-
|
55
|
-
|
119
|
+
def default_primary_key
|
120
|
+
"id"
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
class ReferenceDefinition # :nodoc:
|
125
|
+
def initialize(
|
126
|
+
name,
|
127
|
+
polymorphic: false,
|
128
|
+
index: true,
|
129
|
+
foreign_key: false,
|
130
|
+
type: :bigint,
|
131
|
+
**options
|
132
|
+
)
|
133
|
+
@name = name
|
134
|
+
@polymorphic = polymorphic
|
135
|
+
@index = index
|
136
|
+
@foreign_key = foreign_key
|
137
|
+
@type = type
|
138
|
+
@options = options
|
139
|
+
|
140
|
+
if polymorphic && foreign_key
|
141
|
+
raise ArgumentError, "Cannot add a foreign key to a polymorphic relation"
|
142
|
+
end
|
143
|
+
end
|
144
|
+
|
145
|
+
def add_to(table)
|
146
|
+
columns.each do |column_options|
|
147
|
+
kwargs = column_options.extract_options!
|
148
|
+
table.column(*column_options, **kwargs)
|
149
|
+
end
|
150
|
+
|
151
|
+
if index
|
152
|
+
table.index(column_names, index_options)
|
153
|
+
end
|
154
|
+
|
155
|
+
if foreign_key
|
156
|
+
table.foreign_key(foreign_table_name, **foreign_key_options)
|
157
|
+
end
|
56
158
|
end
|
159
|
+
|
160
|
+
private
|
161
|
+
attr_reader :name, :polymorphic, :index, :foreign_key, :type, :options
|
162
|
+
|
163
|
+
def as_options(value)
|
164
|
+
value.is_a?(Hash) ? value : {}
|
165
|
+
end
|
166
|
+
|
167
|
+
def polymorphic_options
|
168
|
+
as_options(polymorphic).merge(options.slice(:null, :first, :after))
|
169
|
+
end
|
170
|
+
|
171
|
+
def index_options
|
172
|
+
as_options(index)
|
173
|
+
end
|
174
|
+
|
175
|
+
def foreign_key_options
|
176
|
+
as_options(foreign_key).merge(column: column_name)
|
177
|
+
end
|
178
|
+
|
179
|
+
def columns
|
180
|
+
result = [[column_name, type, options]]
|
181
|
+
if polymorphic
|
182
|
+
result.unshift(["#{name}_type", :string, polymorphic_options])
|
183
|
+
end
|
184
|
+
result
|
185
|
+
end
|
186
|
+
|
187
|
+
def column_name
|
188
|
+
"#{name}_id"
|
189
|
+
end
|
190
|
+
|
191
|
+
def column_names
|
192
|
+
columns.map(&:first)
|
193
|
+
end
|
194
|
+
|
195
|
+
def foreign_table_name
|
196
|
+
foreign_key_options.fetch(:to_table) do
|
197
|
+
Base.pluralize_table_names ? name.to_s.pluralize : name
|
198
|
+
end
|
199
|
+
end
|
57
200
|
end
|
58
201
|
|
59
|
-
module
|
60
|
-
|
61
|
-
|
202
|
+
module ColumnMethods
|
203
|
+
extend ActiveSupport::Concern
|
204
|
+
|
205
|
+
# Appends a primary key definition to the table definition.
|
206
|
+
# Can be called multiple times, but this is probably not a good idea.
|
207
|
+
def primary_key(name, type = :primary_key, **options)
|
208
|
+
column(name, type, **options.merge(primary_key: true))
|
209
|
+
end
|
210
|
+
|
211
|
+
##
|
212
|
+
# :method: column
|
213
|
+
# :call-seq: column(name, type, **options)
|
214
|
+
#
|
215
|
+
# Appends a column or columns of a specified type.
|
216
|
+
#
|
217
|
+
# t.string(:goat)
|
218
|
+
# t.string(:goat, :sheep)
|
219
|
+
#
|
220
|
+
# See TableDefinition#column
|
221
|
+
|
222
|
+
included do
|
223
|
+
define_column_methods :bigint, :binary, :boolean, :date, :datetime, :decimal,
|
224
|
+
:float, :integer, :json, :string, :text, :time, :timestamp, :virtual
|
62
225
|
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
226
|
+
alias :numeric :decimal
|
227
|
+
end
|
228
|
+
|
229
|
+
class_methods do
|
230
|
+
private def define_column_methods(*column_types) # :nodoc:
|
231
|
+
column_types.each do |column_type|
|
232
|
+
module_eval <<-RUBY, __FILE__, __LINE__ + 1
|
233
|
+
def #{column_type}(*names, **options)
|
234
|
+
raise ArgumentError, "Missing column name(s) for #{column_type}" if names.empty?
|
235
|
+
names.each { |name| column(name, :#{column_type}, **options) }
|
236
|
+
end
|
237
|
+
RUBY
|
238
|
+
end
|
239
|
+
end
|
68
240
|
end
|
69
241
|
end
|
70
242
|
|
71
243
|
# Represents the schema of an SQL table in an abstract way. This class
|
72
244
|
# provides methods for manipulating the schema representation.
|
73
245
|
#
|
74
|
-
# Inside migration files, the +t+ object in
|
246
|
+
# Inside migration files, the +t+ object in {create_table}[rdoc-ref:SchemaStatements#create_table]
|
75
247
|
# is actually of this type:
|
76
248
|
#
|
77
|
-
# class SomeMigration < ActiveRecord::Migration
|
249
|
+
# class SomeMigration < ActiveRecord::Migration[5.0]
|
78
250
|
# def up
|
79
251
|
# create_table :foo do |t|
|
80
252
|
# puts t.class # => "ActiveRecord::ConnectionAdapters::TableDefinition"
|
@@ -86,124 +258,65 @@ module ActiveRecord
|
|
86
258
|
# end
|
87
259
|
# end
|
88
260
|
#
|
89
|
-
# The table definitions
|
90
|
-
# The Columns are stored as a ColumnDefinition in the +columns+ attribute.
|
91
261
|
class TableDefinition
|
92
|
-
include
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
262
|
+
include ColumnMethods
|
263
|
+
|
264
|
+
attr_reader :name, :temporary, :if_not_exists, :options, :as, :comment, :indexes, :foreign_keys
|
265
|
+
|
266
|
+
def initialize(
|
267
|
+
conn,
|
268
|
+
name,
|
269
|
+
temporary: false,
|
270
|
+
if_not_exists: false,
|
271
|
+
options: nil,
|
272
|
+
as: nil,
|
273
|
+
comment: nil,
|
274
|
+
**
|
275
|
+
)
|
276
|
+
@conn = conn
|
100
277
|
@columns_hash = {}
|
101
|
-
@indexes =
|
102
|
-
@
|
278
|
+
@indexes = []
|
279
|
+
@foreign_keys = []
|
280
|
+
@primary_keys = nil
|
103
281
|
@temporary = temporary
|
282
|
+
@if_not_exists = if_not_exists
|
104
283
|
@options = options
|
105
284
|
@as = as
|
106
285
|
@name = name
|
286
|
+
@comment = comment
|
107
287
|
end
|
108
288
|
|
109
|
-
def
|
110
|
-
|
111
|
-
|
112
|
-
# Can be called multiple times, but this is probably not a good idea.
|
113
|
-
def primary_key(name, type = :primary_key, options = {})
|
114
|
-
column(name, type, options.merge(:primary_key => true))
|
289
|
+
def primary_keys(name = nil) # :nodoc:
|
290
|
+
@primary_keys = PrimaryKeyDefinition.new(name) if name
|
291
|
+
@primary_keys
|
115
292
|
end
|
116
293
|
|
294
|
+
# Returns an array of ColumnDefinition objects for the columns of the table.
|
295
|
+
def columns; @columns_hash.values; end
|
296
|
+
|
117
297
|
# Returns a ColumnDefinition for the column with name +name+.
|
118
298
|
def [](name)
|
119
299
|
@columns_hash[name.to_s]
|
120
300
|
end
|
121
301
|
|
122
302
|
# Instantiates a new column for the table.
|
123
|
-
#
|
124
|
-
#
|
125
|
-
#
|
126
|
-
#
|
127
|
-
# <tt>:datetime</tt>, <tt>:time</tt>, <tt>:date</tt>,
|
128
|
-
# <tt>:binary</tt>, <tt>:boolean</tt>.
|
129
|
-
#
|
130
|
-
# You may use a type not in this list as long as it is supported by your
|
131
|
-
# database (for example, "polygon" in MySQL), but this will not be database
|
132
|
-
# agnostic and should usually be avoided.
|
133
|
-
#
|
134
|
-
# Available options are (none of these exists by default):
|
135
|
-
# * <tt>:limit</tt> -
|
136
|
-
# Requests a maximum column length. This is number of characters for <tt>:string</tt> and
|
137
|
-
# <tt>:text</tt> columns and number of bytes for <tt>:binary</tt> and <tt>:integer</tt> columns.
|
138
|
-
# * <tt>:default</tt> -
|
139
|
-
# The column's default value. Use nil for NULL.
|
140
|
-
# * <tt>:null</tt> -
|
141
|
-
# Allows or disallows +NULL+ values in the column. This option could
|
142
|
-
# have been named <tt>:null_allowed</tt>.
|
143
|
-
# * <tt>:precision</tt> -
|
144
|
-
# Specifies the precision for a <tt>:decimal</tt> column.
|
145
|
-
# * <tt>:scale</tt> -
|
146
|
-
# Specifies the scale for a <tt>:decimal</tt> column.
|
303
|
+
# See {connection.add_column}[rdoc-ref:ConnectionAdapters::SchemaStatements#add_column]
|
304
|
+
# for available options.
|
305
|
+
#
|
306
|
+
# Additional options are:
|
147
307
|
# * <tt>:index</tt> -
|
148
308
|
# Create an index for the column. Can be either <tt>true</tt> or an options hash.
|
149
309
|
#
|
150
|
-
# Note: The precision is the total number of significant digits
|
151
|
-
# and the scale is the number of digits that can be stored following
|
152
|
-
# the decimal point. For example, the number 123.45 has a precision of 5
|
153
|
-
# and a scale of 2. A decimal with a precision of 5 and a scale of 2 can
|
154
|
-
# range from -999.99 to 999.99.
|
155
|
-
#
|
156
|
-
# Please be aware of different RDBMS implementations behavior with
|
157
|
-
# <tt>:decimal</tt> columns:
|
158
|
-
# * The SQL standard says the default scale should be 0, <tt>:scale</tt> <=
|
159
|
-
# <tt>:precision</tt>, and makes no comments about the requirements of
|
160
|
-
# <tt>:precision</tt>.
|
161
|
-
# * MySQL: <tt>:precision</tt> [1..63], <tt>:scale</tt> [0..30].
|
162
|
-
# Default is (10,0).
|
163
|
-
# * PostgreSQL: <tt>:precision</tt> [1..infinity],
|
164
|
-
# <tt>:scale</tt> [0..infinity]. No default.
|
165
|
-
# * SQLite2: Any <tt>:precision</tt> and <tt>:scale</tt> may be used.
|
166
|
-
# Internal storage as strings. No default.
|
167
|
-
# * SQLite3: No restrictions on <tt>:precision</tt> and <tt>:scale</tt>,
|
168
|
-
# but the maximum supported <tt>:precision</tt> is 16. No default.
|
169
|
-
# * Oracle: <tt>:precision</tt> [1..38], <tt>:scale</tt> [-84..127].
|
170
|
-
# Default is (38,0).
|
171
|
-
# * DB2: <tt>:precision</tt> [1..63], <tt>:scale</tt> [0..62].
|
172
|
-
# Default unknown.
|
173
|
-
# * SqlServer?: <tt>:precision</tt> [1..38], <tt>:scale</tt> [0..38].
|
174
|
-
# Default (38,0).
|
175
|
-
#
|
176
310
|
# This method returns <tt>self</tt>.
|
177
311
|
#
|
178
312
|
# == Examples
|
179
|
-
# # Assuming +td+ is an instance of TableDefinition
|
180
|
-
# td.column(:granted, :boolean)
|
181
|
-
# # granted BOOLEAN
|
182
313
|
#
|
183
|
-
# td
|
184
|
-
#
|
185
|
-
#
|
186
|
-
# td.column(:sales_stage, :string, limit: 20, default: 'new', null: false)
|
187
|
-
# # => sales_stage VARCHAR(20) DEFAULT 'new' NOT NULL
|
188
|
-
#
|
189
|
-
# td.column(:bill_gates_money, :decimal, precision: 15, scale: 2)
|
190
|
-
# # => bill_gates_money DECIMAL(15,2)
|
191
|
-
#
|
192
|
-
# td.column(:sensor_reading, :decimal, precision: 30, scale: 20)
|
193
|
-
# # => sensor_reading DECIMAL(30,20)
|
194
|
-
#
|
195
|
-
# # While <tt>:scale</tt> defaults to zero on most databases, it
|
196
|
-
# # probably wouldn't hurt to include it.
|
197
|
-
# td.column(:huge_integer, :decimal, precision: 30)
|
198
|
-
# # => huge_integer DECIMAL(30)
|
199
|
-
#
|
200
|
-
# # Defines a column with a database-specific type.
|
201
|
-
# td.column(:foo, 'polygon')
|
202
|
-
# # => foo polygon
|
314
|
+
# # Assuming +td+ is an instance of TableDefinition
|
315
|
+
# td.column(:granted, :boolean, index: true)
|
203
316
|
#
|
204
317
|
# == Short-hand examples
|
205
318
|
#
|
206
|
-
# Instead of calling
|
319
|
+
# Instead of calling #column directly, you can also work with the short-hand definitions for the default types.
|
207
320
|
# They use the type as the method name instead of as a parameter and allow for multiple columns to be defined
|
208
321
|
# in a single statement.
|
209
322
|
#
|
@@ -235,7 +348,8 @@ module ActiveRecord
|
|
235
348
|
# TableDefinition#references will add an appropriately-named _id column, plus a corresponding _type
|
236
349
|
# column if the <tt>:polymorphic</tt> option is supplied. If <tt>:polymorphic</tt> is a hash of
|
237
350
|
# options, these will be used when creating the <tt>_type</tt> column. The <tt>:index</tt> option
|
238
|
-
# will also create an index, similar to calling
|
351
|
+
# will also create an index, similar to calling {add_index}[rdoc-ref:ConnectionAdapters::SchemaStatements#add_index].
|
352
|
+
# So what can be written like this:
|
239
353
|
#
|
240
354
|
# create_table :taggings do |t|
|
241
355
|
# t.integer :tag_id, :tagger_id, :taggable_id
|
@@ -249,106 +363,100 @@ module ActiveRecord
|
|
249
363
|
#
|
250
364
|
# create_table :taggings do |t|
|
251
365
|
# t.references :tag, index: { name: 'index_taggings_on_tag_id' }
|
252
|
-
# t.references :tagger, polymorphic: true
|
253
|
-
# t.references :taggable, polymorphic: { default: 'Photo' }
|
366
|
+
# t.references :tagger, polymorphic: true
|
367
|
+
# t.references :taggable, polymorphic: { default: 'Photo' }, index: false
|
254
368
|
# end
|
255
|
-
def column(name, type, options
|
369
|
+
def column(name, type, **options)
|
256
370
|
name = name.to_s
|
257
|
-
type = type.to_sym
|
371
|
+
type = type.to_sym if type
|
258
372
|
|
259
|
-
if @columns_hash[name]
|
260
|
-
|
373
|
+
if @columns_hash[name]
|
374
|
+
if @columns_hash[name].primary_key?
|
375
|
+
raise ArgumentError, "you can't redefine the primary key column '#{name}'. To define a custom primary key, pass { id: false } to create_table."
|
376
|
+
else
|
377
|
+
raise ArgumentError, "you can't define an already defined column '#{name}'."
|
378
|
+
end
|
261
379
|
end
|
262
380
|
|
263
381
|
index_options = options.delete(:index)
|
264
382
|
index(name, index_options.is_a?(Hash) ? index_options : {}) if index_options
|
265
|
-
@columns_hash[name] = new_column_definition(name, type, options)
|
383
|
+
@columns_hash[name] = new_column_definition(name, type, **options)
|
266
384
|
self
|
267
385
|
end
|
268
386
|
|
387
|
+
# remove the column +name+ from the table.
|
388
|
+
# remove_column(:account_id)
|
269
389
|
def remove_column(name)
|
270
390
|
@columns_hash.delete name.to_s
|
271
391
|
end
|
272
392
|
|
273
|
-
[:string, :text, :integer, :bigint, :float, :decimal, :datetime, :timestamp, :time, :date, :binary, :boolean].each do |column_type|
|
274
|
-
define_method column_type do |*args|
|
275
|
-
options = args.extract_options!
|
276
|
-
column_names = args
|
277
|
-
column_names.each { |name| column(name, column_type, options) }
|
278
|
-
end
|
279
|
-
end
|
280
|
-
|
281
393
|
# Adds index options to the indexes hash, keyed by column name
|
282
394
|
# This is primarily used to track indexes that need to be created after the table
|
283
395
|
#
|
284
396
|
# index(:account_id, name: 'index_projects_on_account_id')
|
285
397
|
def index(column_name, options = {})
|
286
|
-
indexes[column_name
|
398
|
+
indexes << [column_name, options]
|
399
|
+
end
|
400
|
+
|
401
|
+
def foreign_key(table_name, **options) # :nodoc:
|
402
|
+
foreign_keys << [table_name, options]
|
287
403
|
end
|
288
404
|
|
289
405
|
# Appends <tt>:datetime</tt> columns <tt>:created_at</tt> and
|
290
|
-
# <tt>:updated_at</tt> to the table. See SchemaStatements#add_timestamps
|
406
|
+
# <tt>:updated_at</tt> to the table. See {connection.add_timestamps}[rdoc-ref:SchemaStatements#add_timestamps]
|
291
407
|
#
|
292
408
|
# t.timestamps null: false
|
293
|
-
def timestamps(
|
294
|
-
options =
|
295
|
-
|
296
|
-
|
297
|
-
|
409
|
+
def timestamps(**options)
|
410
|
+
options[:null] = false if options[:null].nil?
|
411
|
+
|
412
|
+
if !options.key?(:precision) && @conn.supports_datetime_with_precision?
|
413
|
+
options[:precision] = 6
|
414
|
+
end
|
415
|
+
|
416
|
+
column(:created_at, :datetime, **options)
|
417
|
+
column(:updated_at, :datetime, **options)
|
298
418
|
end
|
299
419
|
|
300
|
-
# Adds a reference.
|
301
|
-
# <tt>references</tt> and <tt>belongs_to</tt> are acceptable. The reference column will be an +integer+
|
302
|
-
# by default, the <tt>:type</tt> option can be used to specify a different type.
|
420
|
+
# Adds a reference.
|
303
421
|
#
|
304
422
|
# t.references(:user)
|
305
|
-
# t.
|
306
|
-
# t.belongs_to(:supplier,
|
423
|
+
# t.belongs_to(:supplier, foreign_key: true)
|
424
|
+
# t.belongs_to(:supplier, foreign_key: true, type: :integer)
|
307
425
|
#
|
308
|
-
# See SchemaStatements#add_reference
|
309
|
-
def references(*args)
|
310
|
-
|
311
|
-
|
312
|
-
index_options = options.delete(:index)
|
313
|
-
type = options.delete(:type) || :integer
|
314
|
-
args.each do |col|
|
315
|
-
column("#{col}_id", type, options)
|
316
|
-
column("#{col}_type", :string, polymorphic.is_a?(Hash) ? polymorphic : options) if polymorphic
|
317
|
-
index(polymorphic ? %w(type id).map { |t| "#{col}_#{t}" } : "#{col}_id", index_options.is_a?(Hash) ? index_options : {}) if index_options
|
426
|
+
# See {connection.add_reference}[rdoc-ref:SchemaStatements#add_reference] for details of the options you can use.
|
427
|
+
def references(*args, **options)
|
428
|
+
args.each do |ref_name|
|
429
|
+
ReferenceDefinition.new(ref_name, **options).add_to(self)
|
318
430
|
end
|
319
431
|
end
|
320
432
|
alias :belongs_to :references
|
321
433
|
|
322
|
-
def new_column_definition(name, type, options) # :nodoc:
|
323
|
-
|
324
|
-
|
325
|
-
limit = options.fetch(:limit) do
|
326
|
-
native[type][:limit] if native[type].is_a?(Hash)
|
434
|
+
def new_column_definition(name, type, **options) # :nodoc:
|
435
|
+
if integer_like_primary_key?(type, options)
|
436
|
+
type = integer_like_primary_key_type(type, options)
|
327
437
|
end
|
328
|
-
|
329
|
-
|
330
|
-
|
331
|
-
|
332
|
-
column.default = options[:default]
|
333
|
-
column.null = options[:null]
|
334
|
-
column.first = options[:first]
|
335
|
-
column.after = options[:after]
|
336
|
-
column.primary_key = type == :primary_key || options[:primary_key]
|
337
|
-
column
|
438
|
+
type = aliased_types(type.to_s, type)
|
439
|
+
options[:primary_key] ||= type == :primary_key
|
440
|
+
options[:null] = false if options[:primary_key]
|
441
|
+
create_column_definition(name, type, options)
|
338
442
|
end
|
339
443
|
|
340
444
|
private
|
341
|
-
|
342
|
-
|
343
|
-
|
445
|
+
def create_column_definition(name, type, options)
|
446
|
+
ColumnDefinition.new(name, type, options)
|
447
|
+
end
|
344
448
|
|
345
|
-
|
346
|
-
|
347
|
-
|
449
|
+
def aliased_types(name, fallback)
|
450
|
+
"timestamp" == name ? :datetime : fallback
|
451
|
+
end
|
348
452
|
|
349
|
-
|
350
|
-
|
351
|
-
|
453
|
+
def integer_like_primary_key?(type, options)
|
454
|
+
options[:primary_key] && [:integer, :bigint].include?(type) && !options.key?(:default)
|
455
|
+
end
|
456
|
+
|
457
|
+
def integer_like_primary_key_type(type, options)
|
458
|
+
type
|
459
|
+
end
|
352
460
|
end
|
353
461
|
|
354
462
|
class AlterTable # :nodoc:
|
@@ -373,19 +481,20 @@ module ActiveRecord
|
|
373
481
|
@foreign_key_drops << name
|
374
482
|
end
|
375
483
|
|
376
|
-
def add_column(name, type, options)
|
484
|
+
def add_column(name, type, **options)
|
377
485
|
name = name.to_s
|
378
486
|
type = type.to_sym
|
379
|
-
@adds << @td.new_column_definition(name, type, options)
|
487
|
+
@adds << AddColumnDefinition.new(@td.new_column_definition(name, type, **options))
|
380
488
|
end
|
381
489
|
end
|
382
490
|
|
383
491
|
# Represents an SQL table in an abstract way for updating a table.
|
384
|
-
# Also see TableDefinition and SchemaStatements#create_table
|
492
|
+
# Also see TableDefinition and {connection.create_table}[rdoc-ref:SchemaStatements#create_table]
|
385
493
|
#
|
386
494
|
# Available transformations are:
|
387
495
|
#
|
388
496
|
# change_table :table do |t|
|
497
|
+
# t.primary_key
|
389
498
|
# t.column
|
390
499
|
# t.index
|
391
500
|
# t.rename_index
|
@@ -398,15 +507,21 @@ module ActiveRecord
|
|
398
507
|
# t.string
|
399
508
|
# t.text
|
400
509
|
# t.integer
|
510
|
+
# t.bigint
|
401
511
|
# t.float
|
402
512
|
# t.decimal
|
513
|
+
# t.numeric
|
403
514
|
# t.datetime
|
404
515
|
# t.timestamp
|
405
516
|
# t.time
|
406
517
|
# t.date
|
407
518
|
# t.binary
|
408
519
|
# t.boolean
|
520
|
+
# t.foreign_key
|
521
|
+
# t.json
|
522
|
+
# t.virtual
|
409
523
|
# t.remove
|
524
|
+
# t.remove_foreign_key
|
410
525
|
# t.remove_references
|
411
526
|
# t.remove_belongs_to
|
412
527
|
# t.remove_index
|
@@ -414,6 +529,8 @@ module ActiveRecord
|
|
414
529
|
# end
|
415
530
|
#
|
416
531
|
class Table
|
532
|
+
include ColumnMethods
|
533
|
+
|
417
534
|
attr_reader :name
|
418
535
|
|
419
536
|
def initialize(table_name, base)
|
@@ -422,33 +539,44 @@ module ActiveRecord
|
|
422
539
|
end
|
423
540
|
|
424
541
|
# Adds a new column to the named table.
|
425
|
-
# See TableDefinition#column for details of the options you can use.
|
426
542
|
#
|
427
|
-
# ====== Creating a simple column
|
428
543
|
# t.column(:name, :string)
|
429
|
-
|
430
|
-
|
544
|
+
#
|
545
|
+
# See TableDefinition#column for details of the options you can use.
|
546
|
+
def column(column_name, type, **options)
|
547
|
+
index_options = options.delete(:index)
|
548
|
+
@base.add_column(name, column_name, type, **options)
|
549
|
+
index(column_name, index_options.is_a?(Hash) ? index_options : {}) if index_options
|
431
550
|
end
|
432
551
|
|
433
|
-
# Checks to see if a column exists.
|
434
|
-
|
435
|
-
|
552
|
+
# Checks to see if a column exists.
|
553
|
+
#
|
554
|
+
# t.string(:name) unless t.column_exists?(:name, :string)
|
555
|
+
#
|
556
|
+
# See {connection.column_exists?}[rdoc-ref:SchemaStatements#column_exists?]
|
557
|
+
def column_exists?(column_name, type = nil, **options)
|
558
|
+
@base.column_exists?(name, column_name, type, **options)
|
436
559
|
end
|
437
560
|
|
438
561
|
# Adds a new index to the table. +column_name+ can be a single Symbol, or
|
439
|
-
# an Array of Symbols.
|
562
|
+
# an Array of Symbols.
|
440
563
|
#
|
441
|
-
# ====== Creating a simple index
|
442
564
|
# t.index(:name)
|
443
|
-
# ====== Creating a unique index
|
444
565
|
# t.index([:branch_id, :party_id], unique: true)
|
445
|
-
# ====== Creating a named index
|
446
566
|
# t.index([:branch_id, :party_id], unique: true, name: 'by_branch_party')
|
567
|
+
#
|
568
|
+
# See {connection.add_index}[rdoc-ref:SchemaStatements#add_index] for details of the options you can use.
|
447
569
|
def index(column_name, options = {})
|
448
570
|
@base.add_index(name, column_name, options)
|
449
571
|
end
|
450
572
|
|
451
|
-
# Checks to see if an index exists.
|
573
|
+
# Checks to see if an index exists.
|
574
|
+
#
|
575
|
+
# unless t.index_exists?(:branch_id)
|
576
|
+
# t.index(:branch_id)
|
577
|
+
# end
|
578
|
+
#
|
579
|
+
# See {connection.index_exists?}[rdoc-ref:SchemaStatements#index_exists?]
|
452
580
|
def index_exists?(column_name, options = {})
|
453
581
|
@base.index_exists?(name, column_name, options)
|
454
582
|
end
|
@@ -456,52 +584,59 @@ module ActiveRecord
|
|
456
584
|
# Renames the given index on the table.
|
457
585
|
#
|
458
586
|
# t.rename_index(:user_id, :account_id)
|
587
|
+
#
|
588
|
+
# See {connection.rename_index}[rdoc-ref:SchemaStatements#rename_index]
|
459
589
|
def rename_index(index_name, new_index_name)
|
460
590
|
@base.rename_index(name, index_name, new_index_name)
|
461
591
|
end
|
462
592
|
|
463
|
-
# Adds timestamps (+created_at+ and +updated_at+) columns to the table.
|
593
|
+
# Adds timestamps (+created_at+ and +updated_at+) columns to the table.
|
594
|
+
#
|
595
|
+
# t.timestamps(null: false)
|
464
596
|
#
|
465
|
-
#
|
466
|
-
def timestamps(options
|
467
|
-
@base.add_timestamps(name, options)
|
597
|
+
# See {connection.add_timestamps}[rdoc-ref:SchemaStatements#add_timestamps]
|
598
|
+
def timestamps(**options)
|
599
|
+
@base.add_timestamps(name, **options)
|
468
600
|
end
|
469
601
|
|
470
602
|
# Changes the column's definition according to the new options.
|
471
|
-
# See TableDefinition#column for details of the options you can use.
|
472
603
|
#
|
473
604
|
# t.change(:name, :string, limit: 80)
|
474
605
|
# t.change(:description, :text)
|
606
|
+
#
|
607
|
+
# See TableDefinition#column for details of the options you can use.
|
475
608
|
def change(column_name, type, options = {})
|
476
609
|
@base.change_column(name, column_name, type, options)
|
477
610
|
end
|
478
611
|
|
479
|
-
# Sets a new default value for a column.
|
612
|
+
# Sets a new default value for a column.
|
480
613
|
#
|
481
614
|
# t.change_default(:qualification, 'new')
|
482
615
|
# t.change_default(:authorized, 1)
|
483
|
-
|
484
|
-
|
616
|
+
# t.change_default(:status, from: nil, to: "draft")
|
617
|
+
#
|
618
|
+
# See {connection.change_column_default}[rdoc-ref:SchemaStatements#change_column_default]
|
619
|
+
def change_default(column_name, default_or_changes)
|
620
|
+
@base.change_column_default(name, column_name, default_or_changes)
|
485
621
|
end
|
486
622
|
|
487
623
|
# Removes the column(s) from the table definition.
|
488
624
|
#
|
489
625
|
# t.remove(:qualification)
|
490
626
|
# t.remove(:qualification, :experience)
|
627
|
+
#
|
628
|
+
# See {connection.remove_columns}[rdoc-ref:SchemaStatements#remove_columns]
|
491
629
|
def remove(*column_names)
|
492
630
|
@base.remove_columns(name, *column_names)
|
493
631
|
end
|
494
632
|
|
495
633
|
# Removes the given index from the table.
|
496
634
|
#
|
497
|
-
#
|
498
|
-
# t.remove_index :
|
499
|
-
#
|
500
|
-
#
|
501
|
-
#
|
502
|
-
# t.remove_index column: [:branch_id, :party_id]
|
503
|
-
# ====== Remove the index named by_branch_party in the table_name table
|
504
|
-
# t.remove_index name: :by_branch_party
|
635
|
+
# t.remove_index(:branch_id)
|
636
|
+
# t.remove_index(column: [:branch_id, :party_id])
|
637
|
+
# t.remove_index(name: :by_branch_party)
|
638
|
+
#
|
639
|
+
# See {connection.remove_index}[rdoc-ref:SchemaStatements#remove_index]
|
505
640
|
def remove_index(options = {})
|
506
641
|
@base.remove_index(name, options)
|
507
642
|
end
|
@@ -509,66 +644,75 @@ module ActiveRecord
|
|
509
644
|
# Removes the timestamp columns (+created_at+ and +updated_at+) from the table.
|
510
645
|
#
|
511
646
|
# t.remove_timestamps
|
512
|
-
|
513
|
-
|
647
|
+
#
|
648
|
+
# See {connection.remove_timestamps}[rdoc-ref:SchemaStatements#remove_timestamps]
|
649
|
+
def remove_timestamps(**options)
|
650
|
+
@base.remove_timestamps(name, **options)
|
514
651
|
end
|
515
652
|
|
516
653
|
# Renames a column.
|
517
654
|
#
|
518
655
|
# t.rename(:description, :name)
|
656
|
+
#
|
657
|
+
# See {connection.rename_column}[rdoc-ref:SchemaStatements#rename_column]
|
519
658
|
def rename(column_name, new_column_name)
|
520
659
|
@base.rename_column(name, column_name, new_column_name)
|
521
660
|
end
|
522
661
|
|
523
|
-
# Adds a reference.
|
524
|
-
# <tt>references</tt> and <tt>belongs_to</tt> are acceptable. The reference column will be an +integer+
|
525
|
-
# by default, the <tt>:type</tt> option can be used to specify a different type.
|
662
|
+
# Adds a reference.
|
526
663
|
#
|
527
664
|
# t.references(:user)
|
528
|
-
# t.
|
529
|
-
# t.belongs_to(:supplier, polymorphic: true)
|
665
|
+
# t.belongs_to(:supplier, foreign_key: true)
|
530
666
|
#
|
531
|
-
# See SchemaStatements#add_reference
|
532
|
-
def references(*args)
|
533
|
-
options = args.extract_options!
|
667
|
+
# See {connection.add_reference}[rdoc-ref:SchemaStatements#add_reference] for details of the options you can use.
|
668
|
+
def references(*args, **options)
|
534
669
|
args.each do |ref_name|
|
535
|
-
@base.add_reference(name, ref_name, options)
|
670
|
+
@base.add_reference(name, ref_name, **options)
|
536
671
|
end
|
537
672
|
end
|
538
673
|
alias :belongs_to :references
|
539
674
|
|
540
675
|
# Removes a reference. Optionally removes a +type+ column.
|
541
|
-
# <tt>remove_references</tt> and <tt>remove_belongs_to</tt> are acceptable.
|
542
676
|
#
|
543
677
|
# t.remove_references(:user)
|
544
678
|
# t.remove_belongs_to(:supplier, polymorphic: true)
|
545
679
|
#
|
546
|
-
# See SchemaStatements#remove_reference
|
547
|
-
def remove_references(*args)
|
548
|
-
options = args.extract_options!
|
680
|
+
# See {connection.remove_reference}[rdoc-ref:SchemaStatements#remove_reference]
|
681
|
+
def remove_references(*args, **options)
|
549
682
|
args.each do |ref_name|
|
550
|
-
@base.remove_reference(name, ref_name, options)
|
683
|
+
@base.remove_reference(name, ref_name, **options)
|
551
684
|
end
|
552
685
|
end
|
553
686
|
alias :remove_belongs_to :remove_references
|
554
687
|
|
555
|
-
# Adds a
|
688
|
+
# Adds a foreign key to the table using a supplied table name.
|
556
689
|
#
|
557
|
-
# t.
|
558
|
-
# t.
|
559
|
-
|
560
|
-
|
561
|
-
|
562
|
-
|
563
|
-
@base.add_column(name, column_name, column_type, options)
|
564
|
-
end
|
565
|
-
end
|
690
|
+
# t.foreign_key(:authors)
|
691
|
+
# t.foreign_key(:authors, column: :author_id, primary_key: "id")
|
692
|
+
#
|
693
|
+
# See {connection.add_foreign_key}[rdoc-ref:SchemaStatements#add_foreign_key]
|
694
|
+
def foreign_key(*args, **options)
|
695
|
+
@base.add_foreign_key(name, *args, **options)
|
566
696
|
end
|
567
697
|
|
568
|
-
|
569
|
-
|
570
|
-
|
571
|
-
|
698
|
+
# Removes the given foreign key from the table.
|
699
|
+
#
|
700
|
+
# t.remove_foreign_key(:authors)
|
701
|
+
# t.remove_foreign_key(column: :author_id)
|
702
|
+
#
|
703
|
+
# See {connection.remove_foreign_key}[rdoc-ref:SchemaStatements#remove_foreign_key]
|
704
|
+
def remove_foreign_key(*args, **options)
|
705
|
+
@base.remove_foreign_key(name, *args, **options)
|
706
|
+
end
|
707
|
+
|
708
|
+
# Checks to see if a foreign key exists.
|
709
|
+
#
|
710
|
+
# t.foreign_key(:authors) unless t.foreign_key_exists?(:authors)
|
711
|
+
#
|
712
|
+
# See {connection.foreign_key_exists?}[rdoc-ref:SchemaStatements#foreign_key_exists?]
|
713
|
+
def foreign_key_exists?(*args, **options)
|
714
|
+
@base.foreign_key_exists?(name, *args, **options)
|
715
|
+
end
|
572
716
|
end
|
573
717
|
end
|
574
718
|
end
|