activerecord 4.2.11.3 → 5.0.7.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of activerecord might be problematic. Click here for more details.
- checksums.yaml +4 -4
 - data/CHANGELOG.md +1638 -1132
 - data/MIT-LICENSE +2 -2
 - data/README.rdoc +7 -8
 - data/examples/performance.rb +2 -3
 - data/examples/simple.rb +0 -1
 - data/lib/active_record.rb +7 -2
 - data/lib/active_record/aggregations.rb +34 -21
 - data/lib/active_record/association_relation.rb +7 -4
 - data/lib/active_record/associations.rb +347 -218
 - data/lib/active_record/associations/alias_tracker.rb +19 -16
 - data/lib/active_record/associations/association.rb +22 -10
 - data/lib/active_record/associations/association_scope.rb +75 -104
 - data/lib/active_record/associations/belongs_to_association.rb +21 -32
 - data/lib/active_record/associations/builder/association.rb +28 -34
 - data/lib/active_record/associations/builder/belongs_to.rb +43 -18
 - data/lib/active_record/associations/builder/collection_association.rb +7 -19
 - data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +16 -11
 - data/lib/active_record/associations/builder/has_many.rb +4 -4
 - data/lib/active_record/associations/builder/has_one.rb +11 -6
 - data/lib/active_record/associations/builder/singular_association.rb +13 -11
 - data/lib/active_record/associations/collection_association.rb +85 -69
 - data/lib/active_record/associations/collection_proxy.rb +104 -46
 - data/lib/active_record/associations/foreign_association.rb +1 -1
 - data/lib/active_record/associations/has_many_association.rb +21 -78
 - data/lib/active_record/associations/has_many_through_association.rb +6 -47
 - data/lib/active_record/associations/has_one_association.rb +12 -5
 - data/lib/active_record/associations/join_dependency.rb +38 -22
 - data/lib/active_record/associations/join_dependency/join_association.rb +15 -14
 - data/lib/active_record/associations/join_dependency/join_part.rb +2 -2
 - data/lib/active_record/associations/preloader.rb +14 -4
 - data/lib/active_record/associations/preloader/association.rb +52 -71
 - data/lib/active_record/associations/preloader/collection_association.rb +0 -7
 - data/lib/active_record/associations/preloader/has_many_through.rb +1 -1
 - data/lib/active_record/associations/preloader/has_one.rb +0 -8
 - data/lib/active_record/associations/preloader/singular_association.rb +0 -1
 - data/lib/active_record/associations/preloader/through_association.rb +36 -17
 - data/lib/active_record/associations/singular_association.rb +13 -1
 - data/lib/active_record/associations/through_association.rb +12 -4
 - data/lib/active_record/attribute.rb +69 -19
 - data/lib/active_record/attribute/user_provided_default.rb +28 -0
 - data/lib/active_record/attribute_assignment.rb +19 -140
 - data/lib/active_record/attribute_decorators.rb +6 -5
 - data/lib/active_record/attribute_methods.rb +69 -44
 - data/lib/active_record/attribute_methods/before_type_cast.rb +1 -1
 - data/lib/active_record/attribute_methods/dirty.rb +46 -86
 - data/lib/active_record/attribute_methods/primary_key.rb +16 -3
 - data/lib/active_record/attribute_methods/query.rb +2 -2
 - data/lib/active_record/attribute_methods/read.rb +31 -59
 - data/lib/active_record/attribute_methods/serialization.rb +13 -16
 - data/lib/active_record/attribute_methods/time_zone_conversion.rb +61 -14
 - data/lib/active_record/attribute_methods/write.rb +13 -37
 - data/lib/active_record/attribute_mutation_tracker.rb +70 -0
 - data/lib/active_record/attribute_set.rb +32 -3
 - data/lib/active_record/attribute_set/builder.rb +42 -16
 - data/lib/active_record/attributes.rb +199 -81
 - data/lib/active_record/autosave_association.rb +54 -17
 - data/lib/active_record/base.rb +32 -23
 - data/lib/active_record/callbacks.rb +39 -43
 - data/lib/active_record/coders/json.rb +1 -1
 - data/lib/active_record/coders/yaml_column.rb +20 -8
 - data/lib/active_record/collection_cache_key.rb +50 -0
 - data/lib/active_record/connection_adapters/abstract/connection_pool.rb +467 -189
 - data/lib/active_record/connection_adapters/abstract/database_limits.rb +3 -3
 - data/lib/active_record/connection_adapters/abstract/database_statements.rb +66 -62
 - data/lib/active_record/connection_adapters/abstract/query_cache.rb +39 -4
 - data/lib/active_record/connection_adapters/abstract/quoting.rb +86 -13
 - data/lib/active_record/connection_adapters/abstract/savepoints.rb +3 -3
 - data/lib/active_record/connection_adapters/abstract/schema_creation.rb +61 -39
 - data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +236 -188
 - data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +72 -17
 - data/lib/active_record/connection_adapters/abstract/schema_statements.rb +407 -156
 - data/lib/active_record/connection_adapters/abstract/transaction.rb +51 -34
 - data/lib/active_record/connection_adapters/abstract_adapter.rb +177 -71
 - data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +433 -399
 - data/lib/active_record/connection_adapters/column.rb +28 -43
 - data/lib/active_record/connection_adapters/connection_specification.rb +15 -27
 - data/lib/active_record/connection_adapters/determine_if_preparable_visitor.rb +22 -0
 - data/lib/active_record/connection_adapters/mysql/column.rb +50 -0
 - data/lib/active_record/connection_adapters/mysql/database_statements.rb +108 -0
 - data/lib/active_record/connection_adapters/mysql/explain_pretty_printer.rb +70 -0
 - data/lib/active_record/connection_adapters/mysql/quoting.rb +51 -0
 - data/lib/active_record/connection_adapters/mysql/schema_creation.rb +67 -0
 - data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +93 -0
 - data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +54 -0
 - data/lib/active_record/connection_adapters/mysql/type_metadata.rb +32 -0
 - data/lib/active_record/connection_adapters/mysql2_adapter.rb +25 -166
 - data/lib/active_record/connection_adapters/postgresql/column.rb +33 -11
 - data/lib/active_record/connection_adapters/postgresql/database_statements.rb +18 -72
 - data/lib/active_record/connection_adapters/postgresql/explain_pretty_printer.rb +42 -0
 - data/lib/active_record/connection_adapters/postgresql/oid.rb +1 -6
 - data/lib/active_record/connection_adapters/postgresql/oid/array.rb +37 -57
 - data/lib/active_record/connection_adapters/postgresql/oid/bit.rb +3 -3
 - data/lib/active_record/connection_adapters/postgresql/oid/bytea.rb +2 -2
 - data/lib/active_record/connection_adapters/postgresql/oid/cidr.rb +3 -1
 - data/lib/active_record/connection_adapters/postgresql/oid/date_time.rb +7 -22
 - data/lib/active_record/connection_adapters/postgresql/oid/hstore.rb +13 -3
 - data/lib/active_record/connection_adapters/postgresql/oid/json.rb +1 -26
 - data/lib/active_record/connection_adapters/postgresql/oid/jsonb.rb +2 -2
 - data/lib/active_record/connection_adapters/postgresql/oid/money.rb +0 -4
 - data/lib/active_record/connection_adapters/postgresql/oid/point.rb +4 -4
 - data/lib/active_record/connection_adapters/postgresql/oid/rails_5_1_point.rb +50 -0
 - data/lib/active_record/connection_adapters/postgresql/oid/range.rb +31 -17
 - data/lib/active_record/connection_adapters/postgresql/oid/specialized_string.rb +0 -4
 - data/lib/active_record/connection_adapters/postgresql/oid/uuid.rb +2 -2
 - data/lib/active_record/connection_adapters/postgresql/oid/vector.rb +1 -1
 - data/lib/active_record/connection_adapters/postgresql/oid/xml.rb +1 -1
 - data/lib/active_record/connection_adapters/postgresql/quoting.rb +56 -19
 - data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +29 -10
 - data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +107 -79
 - data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +47 -0
 - data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +250 -154
 - data/lib/active_record/connection_adapters/postgresql/type_metadata.rb +35 -0
 - data/lib/active_record/connection_adapters/postgresql/utils.rb +2 -2
 - data/lib/active_record/connection_adapters/postgresql_adapter.rb +264 -170
 - data/lib/active_record/connection_adapters/schema_cache.rb +36 -23
 - data/lib/active_record/connection_adapters/sql_type_metadata.rb +32 -0
 - data/lib/active_record/connection_adapters/sqlite3/explain_pretty_printer.rb +19 -0
 - data/lib/active_record/connection_adapters/sqlite3/quoting.rb +48 -0
 - data/lib/active_record/connection_adapters/sqlite3/schema_creation.rb +22 -0
 - data/lib/active_record/connection_adapters/sqlite3_adapter.rb +151 -194
 - data/lib/active_record/connection_adapters/statement_pool.rb +31 -12
 - data/lib/active_record/connection_handling.rb +37 -14
 - data/lib/active_record/core.rb +92 -108
 - data/lib/active_record/counter_cache.rb +13 -24
 - data/lib/active_record/dynamic_matchers.rb +1 -20
 - data/lib/active_record/enum.rb +116 -76
 - data/lib/active_record/errors.rb +87 -48
 - data/lib/active_record/explain.rb +20 -9
 - data/lib/active_record/explain_registry.rb +1 -1
 - data/lib/active_record/explain_subscriber.rb +1 -1
 - data/lib/active_record/fixture_set/file.rb +26 -5
 - data/lib/active_record/fixtures.rb +77 -41
 - data/lib/active_record/gem_version.rb +4 -4
 - data/lib/active_record/inheritance.rb +32 -40
 - data/lib/active_record/integration.rb +17 -14
 - data/lib/active_record/internal_metadata.rb +56 -0
 - data/lib/active_record/legacy_yaml_adapter.rb +18 -2
 - data/lib/active_record/locale/en.yml +3 -2
 - data/lib/active_record/locking/optimistic.rb +15 -15
 - data/lib/active_record/locking/pessimistic.rb +1 -1
 - data/lib/active_record/log_subscriber.rb +48 -24
 - data/lib/active_record/migration.rb +362 -111
 - data/lib/active_record/migration/command_recorder.rb +59 -18
 - data/lib/active_record/migration/compatibility.rb +126 -0
 - data/lib/active_record/model_schema.rb +270 -73
 - data/lib/active_record/nested_attributes.rb +58 -29
 - data/lib/active_record/no_touching.rb +4 -0
 - data/lib/active_record/null_relation.rb +16 -8
 - data/lib/active_record/persistence.rb +152 -90
 - data/lib/active_record/query_cache.rb +18 -23
 - data/lib/active_record/querying.rb +12 -11
 - data/lib/active_record/railtie.rb +23 -16
 - data/lib/active_record/railties/controller_runtime.rb +1 -1
 - data/lib/active_record/railties/databases.rake +52 -41
 - data/lib/active_record/readonly_attributes.rb +1 -1
 - data/lib/active_record/reflection.rb +302 -115
 - data/lib/active_record/relation.rb +187 -120
 - data/lib/active_record/relation/batches.rb +141 -36
 - data/lib/active_record/relation/batches/batch_enumerator.rb +67 -0
 - data/lib/active_record/relation/calculations.rb +92 -117
 - data/lib/active_record/relation/delegation.rb +8 -20
 - data/lib/active_record/relation/finder_methods.rb +173 -89
 - data/lib/active_record/relation/from_clause.rb +32 -0
 - data/lib/active_record/relation/merger.rb +16 -42
 - data/lib/active_record/relation/predicate_builder.rb +120 -107
 - data/lib/active_record/relation/predicate_builder/array_handler.rb +11 -16
 - data/lib/active_record/relation/predicate_builder/association_query_handler.rb +88 -0
 - data/lib/active_record/relation/predicate_builder/base_handler.rb +17 -0
 - data/lib/active_record/relation/predicate_builder/basic_object_handler.rb +17 -0
 - data/lib/active_record/relation/predicate_builder/class_handler.rb +27 -0
 - data/lib/active_record/relation/predicate_builder/polymorphic_array_handler.rb +57 -0
 - data/lib/active_record/relation/predicate_builder/range_handler.rb +33 -0
 - data/lib/active_record/relation/predicate_builder/relation_handler.rb +1 -1
 - data/lib/active_record/relation/query_attribute.rb +19 -0
 - data/lib/active_record/relation/query_methods.rb +308 -244
 - data/lib/active_record/relation/record_fetch_warning.rb +49 -0
 - data/lib/active_record/relation/spawn_methods.rb +4 -7
 - data/lib/active_record/relation/where_clause.rb +174 -0
 - data/lib/active_record/relation/where_clause_factory.rb +38 -0
 - data/lib/active_record/result.rb +11 -4
 - data/lib/active_record/runtime_registry.rb +1 -1
 - data/lib/active_record/sanitization.rb +105 -66
 - data/lib/active_record/schema.rb +26 -22
 - data/lib/active_record/schema_dumper.rb +54 -37
 - data/lib/active_record/schema_migration.rb +11 -14
 - data/lib/active_record/scoping.rb +34 -16
 - data/lib/active_record/scoping/default.rb +28 -10
 - data/lib/active_record/scoping/named.rb +59 -26
 - data/lib/active_record/secure_token.rb +38 -0
 - data/lib/active_record/serialization.rb +3 -5
 - data/lib/active_record/statement_cache.rb +17 -15
 - data/lib/active_record/store.rb +8 -3
 - data/lib/active_record/suppressor.rb +58 -0
 - data/lib/active_record/table_metadata.rb +69 -0
 - data/lib/active_record/tasks/database_tasks.rb +66 -49
 - data/lib/active_record/tasks/mysql_database_tasks.rb +6 -14
 - data/lib/active_record/tasks/postgresql_database_tasks.rb +12 -3
 - data/lib/active_record/tasks/sqlite_database_tasks.rb +5 -1
 - data/lib/active_record/timestamp.rb +20 -9
 - data/lib/active_record/touch_later.rb +63 -0
 - data/lib/active_record/transactions.rb +139 -57
 - data/lib/active_record/type.rb +66 -17
 - data/lib/active_record/type/adapter_specific_registry.rb +130 -0
 - data/lib/active_record/type/date.rb +2 -45
 - data/lib/active_record/type/date_time.rb +2 -49
 - data/lib/active_record/type/internal/abstract_json.rb +33 -0
 - data/lib/active_record/type/internal/timezone.rb +15 -0
 - data/lib/active_record/type/serialized.rb +15 -14
 - data/lib/active_record/type/time.rb +10 -16
 - data/lib/active_record/type/type_map.rb +4 -4
 - data/lib/active_record/type_caster.rb +7 -0
 - data/lib/active_record/type_caster/connection.rb +29 -0
 - data/lib/active_record/type_caster/map.rb +19 -0
 - data/lib/active_record/validations.rb +33 -32
 - data/lib/active_record/validations/absence.rb +23 -0
 - data/lib/active_record/validations/associated.rb +10 -3
 - data/lib/active_record/validations/length.rb +24 -0
 - data/lib/active_record/validations/presence.rb +11 -12
 - data/lib/active_record/validations/uniqueness.rb +33 -33
 - data/lib/rails/generators/active_record/migration.rb +15 -0
 - data/lib/rails/generators/active_record/migration/migration_generator.rb +8 -5
 - data/lib/rails/generators/active_record/migration/templates/create_table_migration.rb +8 -3
 - data/lib/rails/generators/active_record/migration/templates/migration.rb +8 -1
 - data/lib/rails/generators/active_record/model/model_generator.rb +33 -16
 - data/lib/rails/generators/active_record/model/templates/application_record.rb +5 -0
 - data/lib/rails/generators/active_record/model/templates/model.rb +3 -0
 - metadata +58 -34
 - data/lib/active_record/connection_adapters/mysql_adapter.rb +0 -498
 - data/lib/active_record/connection_adapters/postgresql/array_parser.rb +0 -93
 - data/lib/active_record/connection_adapters/postgresql/oid/date.rb +0 -11
 - 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/integer.rb +0 -11
 - data/lib/active_record/connection_adapters/postgresql/oid/time.rb +0 -11
 - 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 -31
 - data/lib/active_record/type/decimal.rb +0 -64
 - data/lib/active_record/type/decimal_without_scale.rb +0 -11
 - 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 -59
 - 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 -40
 - data/lib/active_record/type/text.rb +0 -11
 - data/lib/active_record/type/time_value.rb +0 -38
 - data/lib/active_record/type/unsigned_integer.rb +0 -15
 - data/lib/active_record/type/value.rb +0 -110
 
| 
         @@ -6,45 +6,100 @@ module ActiveRecord 
     | 
|
| 
       6 
6 
     | 
    
         
             
                # We can then redefine how certain data types may be handled in the schema dumper on the
         
     | 
| 
       7 
7 
     | 
    
         
             
                # Adapter level by over-writing this code inside the database specific adapters
         
     | 
| 
       8 
8 
     | 
    
         
             
                module ColumnDumper
         
     | 
| 
       9 
     | 
    
         
            -
                  def column_spec(column 
     | 
| 
       10 
     | 
    
         
            -
                    spec = prepare_column_options(column,  
     | 
| 
       11 
     | 
    
         
            -
                     
     | 
| 
      
 9 
     | 
    
         
            +
                  def column_spec(column)
         
     | 
| 
      
 10 
     | 
    
         
            +
                    spec = Hash[prepare_column_options(column).map { |k, v| [k, "#{k}: #{v}"] }]
         
     | 
| 
      
 11 
     | 
    
         
            +
                    spec[:name] = column.name.inspect
         
     | 
| 
      
 12 
     | 
    
         
            +
                    spec[:type] = schema_type(column).to_s
         
     | 
| 
       12 
13 
     | 
    
         
             
                    spec
         
     | 
| 
       13 
14 
     | 
    
         
             
                  end
         
     | 
| 
       14 
15 
     | 
    
         | 
| 
       15 
     | 
    
         
            -
                   
     | 
| 
      
 16 
     | 
    
         
            +
                  def column_spec_for_primary_key(column)
         
     | 
| 
      
 17 
     | 
    
         
            +
                    return {} if default_primary_key?(column)
         
     | 
| 
      
 18 
     | 
    
         
            +
                    spec = { id: schema_type(column).inspect }
         
     | 
| 
      
 19 
     | 
    
         
            +
                    spec.merge!(prepare_column_options(column).except!(:null))
         
     | 
| 
      
 20 
     | 
    
         
            +
                  end
         
     | 
| 
      
 21 
     | 
    
         
            +
             
     | 
| 
      
 22 
     | 
    
         
            +
                  # This can be overridden on an Adapter level basis to support other
         
     | 
| 
       16 
23 
     | 
    
         
             
                  # extended datatypes (Example: Adding an array option in the
         
     | 
| 
       17 
     | 
    
         
            -
                  #  
     | 
| 
       18 
     | 
    
         
            -
                  def prepare_column_options(column 
     | 
| 
      
 24 
     | 
    
         
            +
                  # PostgreSQL::ColumnDumper)
         
     | 
| 
      
 25 
     | 
    
         
            +
                  def prepare_column_options(column)
         
     | 
| 
       19 
26 
     | 
    
         
             
                    spec = {}
         
     | 
| 
       20 
     | 
    
         
            -
                    spec[:name]      = column.name.inspect
         
     | 
| 
       21 
     | 
    
         
            -
                    spec[:type]      = column.type.to_s
         
     | 
| 
       22 
     | 
    
         
            -
                    spec[:null]      = 'false' unless column.null
         
     | 
| 
       23 
27 
     | 
    
         | 
| 
       24 
     | 
    
         
            -
                    limit = column 
     | 
| 
       25 
     | 
    
         
            -
             
     | 
| 
       26 
     | 
    
         
            -
                     
     | 
| 
       27 
     | 
    
         
            -
             
     | 
| 
      
 28 
     | 
    
         
            +
                    if limit = schema_limit(column)
         
     | 
| 
      
 29 
     | 
    
         
            +
                      spec[:limit] = limit
         
     | 
| 
      
 30 
     | 
    
         
            +
                    end
         
     | 
| 
      
 31 
     | 
    
         
            +
             
     | 
| 
      
 32 
     | 
    
         
            +
                    if precision = schema_precision(column)
         
     | 
| 
      
 33 
     | 
    
         
            +
                      spec[:precision] = precision
         
     | 
| 
      
 34 
     | 
    
         
            +
                    end
         
     | 
| 
      
 35 
     | 
    
         
            +
             
     | 
| 
      
 36 
     | 
    
         
            +
                    if scale = schema_scale(column)
         
     | 
| 
      
 37 
     | 
    
         
            +
                      spec[:scale] = scale
         
     | 
| 
      
 38 
     | 
    
         
            +
                    end
         
     | 
| 
       28 
39 
     | 
    
         | 
| 
       29 
40 
     | 
    
         
             
                    default = schema_default(column) if column.has_default?
         
     | 
| 
       30 
41 
     | 
    
         
             
                    spec[:default]   = default unless default.nil?
         
     | 
| 
       31 
42 
     | 
    
         | 
| 
      
 43 
     | 
    
         
            +
                    spec[:null] = 'false' unless column.null
         
     | 
| 
      
 44 
     | 
    
         
            +
             
     | 
| 
      
 45 
     | 
    
         
            +
                    if collation = schema_collation(column)
         
     | 
| 
      
 46 
     | 
    
         
            +
                      spec[:collation] = collation
         
     | 
| 
      
 47 
     | 
    
         
            +
                    end
         
     | 
| 
      
 48 
     | 
    
         
            +
             
     | 
| 
      
 49 
     | 
    
         
            +
                    spec[:comment] = column.comment.inspect if column.comment.present?
         
     | 
| 
      
 50 
     | 
    
         
            +
             
     | 
| 
       32 
51 
     | 
    
         
             
                    spec
         
     | 
| 
       33 
52 
     | 
    
         
             
                  end
         
     | 
| 
       34 
53 
     | 
    
         | 
| 
       35 
54 
     | 
    
         
             
                  # Lists the valid migration options
         
     | 
| 
       36 
55 
     | 
    
         
             
                  def migration_keys
         
     | 
| 
       37 
     | 
    
         
            -
                    [:name, :limit, :precision, :scale, :default, :null]
         
     | 
| 
      
 56 
     | 
    
         
            +
                    [:name, :limit, :precision, :scale, :default, :null, :collation, :comment]
         
     | 
| 
       38 
57 
     | 
    
         
             
                  end
         
     | 
| 
       39 
58 
     | 
    
         | 
| 
       40 
59 
     | 
    
         
             
                  private
         
     | 
| 
       41 
60 
     | 
    
         | 
| 
      
 61 
     | 
    
         
            +
                  def default_primary_key?(column)
         
     | 
| 
      
 62 
     | 
    
         
            +
                    schema_type(column) == :integer
         
     | 
| 
      
 63 
     | 
    
         
            +
                  end
         
     | 
| 
      
 64 
     | 
    
         
            +
             
     | 
| 
      
 65 
     | 
    
         
            +
                  def schema_type(column)
         
     | 
| 
      
 66 
     | 
    
         
            +
                    if column.bigint?
         
     | 
| 
      
 67 
     | 
    
         
            +
                      :bigint
         
     | 
| 
      
 68 
     | 
    
         
            +
                    else
         
     | 
| 
      
 69 
     | 
    
         
            +
                      column.type
         
     | 
| 
      
 70 
     | 
    
         
            +
                    end
         
     | 
| 
      
 71 
     | 
    
         
            +
                  end
         
     | 
| 
      
 72 
     | 
    
         
            +
             
     | 
| 
      
 73 
     | 
    
         
            +
                  def schema_limit(column)
         
     | 
| 
      
 74 
     | 
    
         
            +
                    limit = column.limit unless column.bigint?
         
     | 
| 
      
 75 
     | 
    
         
            +
                    limit.inspect if limit && limit != native_database_types[column.type][:limit]
         
     | 
| 
      
 76 
     | 
    
         
            +
                  end
         
     | 
| 
      
 77 
     | 
    
         
            +
             
     | 
| 
      
 78 
     | 
    
         
            +
                  def schema_precision(column)
         
     | 
| 
      
 79 
     | 
    
         
            +
                    column.precision.inspect if column.precision
         
     | 
| 
      
 80 
     | 
    
         
            +
                  end
         
     | 
| 
      
 81 
     | 
    
         
            +
             
     | 
| 
      
 82 
     | 
    
         
            +
                  def schema_scale(column)
         
     | 
| 
      
 83 
     | 
    
         
            +
                    column.scale.inspect if column.scale
         
     | 
| 
      
 84 
     | 
    
         
            +
                  end
         
     | 
| 
      
 85 
     | 
    
         
            +
             
     | 
| 
       42 
86 
     | 
    
         
             
                  def schema_default(column)
         
     | 
| 
       43 
     | 
    
         
            -
                     
     | 
| 
       44 
     | 
    
         
            -
                     
     | 
| 
       45 
     | 
    
         
            -
             
     | 
| 
      
 87 
     | 
    
         
            +
                    type = lookup_cast_type_from_column(column)
         
     | 
| 
      
 88 
     | 
    
         
            +
                    default = type.deserialize(column.default)
         
     | 
| 
      
 89 
     | 
    
         
            +
                    if default.nil?
         
     | 
| 
      
 90 
     | 
    
         
            +
                      schema_expression(column)
         
     | 
| 
      
 91 
     | 
    
         
            +
                    else
         
     | 
| 
      
 92 
     | 
    
         
            +
                      type.type_cast_for_schema(default)
         
     | 
| 
       46 
93 
     | 
    
         
             
                    end
         
     | 
| 
       47 
94 
     | 
    
         
             
                  end
         
     | 
| 
      
 95 
     | 
    
         
            +
             
     | 
| 
      
 96 
     | 
    
         
            +
                  def schema_expression(column)
         
     | 
| 
      
 97 
     | 
    
         
            +
                    "-> { #{column.default_function.inspect} }" if column.default_function
         
     | 
| 
      
 98 
     | 
    
         
            +
                  end
         
     | 
| 
      
 99 
     | 
    
         
            +
             
     | 
| 
      
 100 
     | 
    
         
            +
                  def schema_collation(column)
         
     | 
| 
      
 101 
     | 
    
         
            +
                    column.collation.inspect if column.collation
         
     | 
| 
      
 102 
     | 
    
         
            +
                  end
         
     | 
| 
       48 
103 
     | 
    
         
             
                end
         
     | 
| 
       49 
104 
     | 
    
         
             
              end
         
     | 
| 
       50 
105 
     | 
    
         
             
            end
         
     | 
| 
         @@ -14,15 +14,24 @@ module ActiveRecord 
     | 
|
| 
       14 
14 
     | 
    
         
             
                    {}
         
     | 
| 
       15 
15 
     | 
    
         
             
                  end
         
     | 
| 
       16 
16 
     | 
    
         | 
| 
      
 17 
     | 
    
         
            +
                  def table_options(table_name)
         
     | 
| 
      
 18 
     | 
    
         
            +
                    nil
         
     | 
| 
      
 19 
     | 
    
         
            +
                  end
         
     | 
| 
      
 20 
     | 
    
         
            +
             
     | 
| 
      
 21 
     | 
    
         
            +
                  # Returns the table comment that's stored in database metadata.
         
     | 
| 
      
 22 
     | 
    
         
            +
                  def table_comment(table_name)
         
     | 
| 
      
 23 
     | 
    
         
            +
                    nil
         
     | 
| 
      
 24 
     | 
    
         
            +
                  end
         
     | 
| 
      
 25 
     | 
    
         
            +
             
     | 
| 
       17 
26 
     | 
    
         
             
                  # Truncates a table alias according to the limits of the current adapter.
         
     | 
| 
       18 
27 
     | 
    
         
             
                  def table_alias_for(table_name)
         
     | 
| 
       19 
28 
     | 
    
         
             
                    table_name[0...table_alias_length].tr('.', '_')
         
     | 
| 
       20 
29 
     | 
    
         
             
                  end
         
     | 
| 
       21 
30 
     | 
    
         | 
| 
       22 
31 
     | 
    
         
             
                  # Returns the relation names useable to back Active Record models.
         
     | 
| 
       23 
     | 
    
         
            -
                  # For most adapters this means all tables and views.
         
     | 
| 
      
 32 
     | 
    
         
            +
                  # For most adapters this means all #tables and #views.
         
     | 
| 
       24 
33 
     | 
    
         
             
                  def data_sources
         
     | 
| 
       25 
     | 
    
         
            -
                    tables
         
     | 
| 
      
 34 
     | 
    
         
            +
                    tables | views
         
     | 
| 
       26 
35 
     | 
    
         
             
                  end
         
     | 
| 
       27 
36 
     | 
    
         | 
| 
       28 
37 
     | 
    
         
             
                  # Checks to see if the data source +name+ exists on the database.
         
     | 
| 
         @@ -33,6 +42,11 @@ module ActiveRecord 
     | 
|
| 
       33 
42 
     | 
    
         
             
                    data_sources.include?(name.to_s)
         
     | 
| 
       34 
43 
     | 
    
         
             
                  end
         
     | 
| 
       35 
44 
     | 
    
         | 
| 
      
 45 
     | 
    
         
            +
                  # Returns an array of table names defined in the database.
         
     | 
| 
      
 46 
     | 
    
         
            +
                  def tables(name = nil)
         
     | 
| 
      
 47 
     | 
    
         
            +
                    raise NotImplementedError, "#tables is not implemented"
         
     | 
| 
      
 48 
     | 
    
         
            +
                  end
         
     | 
| 
      
 49 
     | 
    
         
            +
             
     | 
| 
       36 
50 
     | 
    
         
             
                  # Checks to see if the table +table_name+ exists on the database.
         
     | 
| 
       37 
51 
     | 
    
         
             
                  #
         
     | 
| 
       38 
52 
     | 
    
         
             
                  #   table_exists?(:developers)
         
     | 
| 
         @@ -41,6 +55,19 @@ module ActiveRecord 
     | 
|
| 
       41 
55 
     | 
    
         
             
                    tables.include?(table_name.to_s)
         
     | 
| 
       42 
56 
     | 
    
         
             
                  end
         
     | 
| 
       43 
57 
     | 
    
         | 
| 
      
 58 
     | 
    
         
            +
                  # Returns an array of view names defined in the database.
         
     | 
| 
      
 59 
     | 
    
         
            +
                  def views
         
     | 
| 
      
 60 
     | 
    
         
            +
                    raise NotImplementedError, "#views is not implemented"
         
     | 
| 
      
 61 
     | 
    
         
            +
                  end
         
     | 
| 
      
 62 
     | 
    
         
            +
             
     | 
| 
      
 63 
     | 
    
         
            +
                  # Checks to see if the view +view_name+ exists on the database.
         
     | 
| 
      
 64 
     | 
    
         
            +
                  #
         
     | 
| 
      
 65 
     | 
    
         
            +
                  #   view_exists?(:ebooks)
         
     | 
| 
      
 66 
     | 
    
         
            +
                  #
         
     | 
| 
      
 67 
     | 
    
         
            +
                  def view_exists?(view_name)
         
     | 
| 
      
 68 
     | 
    
         
            +
                    views.include?(view_name.to_s)
         
     | 
| 
      
 69 
     | 
    
         
            +
                  end
         
     | 
| 
      
 70 
     | 
    
         
            +
             
     | 
| 
       44 
71 
     | 
    
         
             
                  # Returns an array of indexes for the given table.
         
     | 
| 
       45 
72 
     | 
    
         
             
                  # def indexes(table_name, name = nil) end
         
     | 
| 
       46 
73 
     | 
    
         | 
| 
         @@ -60,18 +87,19 @@ module ActiveRecord 
     | 
|
| 
       60 
87 
     | 
    
         
             
                  #
         
     | 
| 
       61 
88 
     | 
    
         
             
                  def index_exists?(table_name, column_name, options = {})
         
     | 
| 
       62 
89 
     | 
    
         
             
                    column_names = Array(column_name).map(&:to_s)
         
     | 
| 
       63 
     | 
    
         
            -
                    index_name = options.key?(:name) ? options[:name].to_s : index_name(table_name, column: column_names)
         
     | 
| 
       64 
90 
     | 
    
         
             
                    checks = []
         
     | 
| 
       65 
     | 
    
         
            -
                    checks << lambda { |i| i.name == index_name }
         
     | 
| 
       66 
91 
     | 
    
         
             
                    checks << lambda { |i| i.columns == column_names }
         
     | 
| 
       67 
92 
     | 
    
         
             
                    checks << lambda { |i| i.unique } if options[:unique]
         
     | 
| 
      
 93 
     | 
    
         
            +
                    checks << lambda { |i| i.name == options[:name].to_s } if options[:name]
         
     | 
| 
       68 
94 
     | 
    
         | 
| 
       69 
95 
     | 
    
         
             
                    indexes(table_name).any? { |i| checks.all? { |check| check[i] } }
         
     | 
| 
       70 
96 
     | 
    
         
             
                  end
         
     | 
| 
       71 
97 
     | 
    
         | 
| 
       72 
98 
     | 
    
         
             
                  # Returns an array of Column objects for the table specified by +table_name+.
         
     | 
| 
       73 
99 
     | 
    
         
             
                  # See the concrete implementation for details on the expected parameter values.
         
     | 
| 
       74 
     | 
    
         
            -
                  def columns(table_name) 
     | 
| 
      
 100 
     | 
    
         
            +
                  def columns(table_name)
         
     | 
| 
      
 101 
     | 
    
         
            +
                    raise NotImplementedError, "#columns is not implemented"
         
     | 
| 
      
 102 
     | 
    
         
            +
                  end
         
     | 
| 
       75 
103 
     | 
    
         | 
| 
       76 
104 
     | 
    
         
             
                  # Checks to see if a column exists in a given table.
         
     | 
| 
       77 
105 
     | 
    
         
             
                  #
         
     | 
| 
         @@ -89,19 +117,27 @@ module ActiveRecord 
     | 
|
| 
       89 
117 
     | 
    
         
             
                  #
         
     | 
| 
       90 
118 
     | 
    
         
             
                  def column_exists?(table_name, column_name, type = nil, options = {})
         
     | 
| 
       91 
119 
     | 
    
         
             
                    column_name = column_name.to_s
         
     | 
| 
       92 
     | 
    
         
            -
                     
     | 
| 
       93 
     | 
    
         
            -
             
     | 
| 
       94 
     | 
    
         
            -
             
     | 
| 
       95 
     | 
    
         
            -
             
     | 
| 
       96 
     | 
    
         
            -
             
     | 
| 
       97 
     | 
    
         
            -
             
     | 
| 
       98 
     | 
    
         
            -
             
     | 
| 
      
 120 
     | 
    
         
            +
                    checks = []
         
     | 
| 
      
 121 
     | 
    
         
            +
                    checks << lambda { |c| c.name == column_name }
         
     | 
| 
      
 122 
     | 
    
         
            +
                    checks << lambda { |c| c.type == type } if type
         
     | 
| 
      
 123 
     | 
    
         
            +
                    (migration_keys - [:name]).each do |attr|
         
     | 
| 
      
 124 
     | 
    
         
            +
                      checks << lambda { |c| c.send(attr) == options[attr] } if options.key?(attr)
         
     | 
| 
      
 125 
     | 
    
         
            +
                    end
         
     | 
| 
      
 126 
     | 
    
         
            +
             
     | 
| 
      
 127 
     | 
    
         
            +
                    columns(table_name).any? { |c| checks.all? { |check| check[c] } }
         
     | 
| 
      
 128 
     | 
    
         
            +
                  end
         
     | 
| 
      
 129 
     | 
    
         
            +
             
     | 
| 
      
 130 
     | 
    
         
            +
                  # Returns just a table's primary key
         
     | 
| 
      
 131 
     | 
    
         
            +
                  def primary_key(table_name)
         
     | 
| 
      
 132 
     | 
    
         
            +
                    pk = primary_keys(table_name)
         
     | 
| 
      
 133 
     | 
    
         
            +
                    pk = pk.first unless pk.size > 1
         
     | 
| 
      
 134 
     | 
    
         
            +
                    pk
         
     | 
| 
       99 
135 
     | 
    
         
             
                  end
         
     | 
| 
       100 
136 
     | 
    
         | 
| 
       101 
137 
     | 
    
         
             
                  # Creates a new table with the name +table_name+. +table_name+ may either
         
     | 
| 
       102 
138 
     | 
    
         
             
                  # be a String or a Symbol.
         
     | 
| 
       103 
139 
     | 
    
         
             
                  #
         
     | 
| 
       104 
     | 
    
         
            -
                  # There are two ways to work with  
     | 
| 
      
 140 
     | 
    
         
            +
                  # There are two ways to work with #create_table. You can use the block
         
     | 
| 
       105 
141 
     | 
    
         
             
                  # form or the regular form, like this:
         
     | 
| 
       106 
142 
     | 
    
         
             
                  #
         
     | 
| 
       107 
143 
     | 
    
         
             
                  # === Block form
         
     | 
| 
         @@ -133,13 +169,16 @@ module ActiveRecord 
     | 
|
| 
       133 
169 
     | 
    
         
             
                  # The +options+ hash can include the following keys:
         
     | 
| 
       134 
170 
     | 
    
         
             
                  # [<tt>:id</tt>]
         
     | 
| 
       135 
171 
     | 
    
         
             
                  #   Whether to automatically add a primary key column. Defaults to true.
         
     | 
| 
       136 
     | 
    
         
            -
                  #   Join tables for  
     | 
| 
      
 172 
     | 
    
         
            +
                  #   Join tables for {ActiveRecord::Base.has_and_belongs_to_many}[rdoc-ref:Associations::ClassMethods#has_and_belongs_to_many] should set it to false.
         
     | 
| 
      
 173 
     | 
    
         
            +
                  #
         
     | 
| 
      
 174 
     | 
    
         
            +
                  #   A Symbol can be used to specify the type of the generated primary key column.
         
     | 
| 
       137 
175 
     | 
    
         
             
                  # [<tt>:primary_key</tt>]
         
     | 
| 
       138 
176 
     | 
    
         
             
                  #   The name of the primary key, if one is to be added automatically.
         
     | 
| 
       139 
177 
     | 
    
         
             
                  #   Defaults to +id+. If <tt>:id</tt> is false this option is ignored.
         
     | 
| 
       140 
178 
     | 
    
         
             
                  #
         
     | 
| 
       141 
179 
     | 
    
         
             
                  #   Note that Active Record models will automatically detect their
         
     | 
| 
       142 
     | 
    
         
            -
                  #   primary key. This can be avoided by using 
     | 
| 
      
 180 
     | 
    
         
            +
                  #   primary key. This can be avoided by using
         
     | 
| 
      
 181 
     | 
    
         
            +
                  #   {self.primary_key=}[rdoc-ref:AttributeMethods::PrimaryKey::ClassMethods#primary_key=] on the model
         
     | 
| 
       143 
182 
     | 
    
         
             
                  #   to define the key explicitly.
         
     | 
| 
       144 
183 
     | 
    
         
             
                  #
         
     | 
| 
       145 
184 
     | 
    
         
             
                  # [<tt>:options</tt>]
         
     | 
| 
         @@ -161,7 +200,7 @@ module ActiveRecord 
     | 
|
| 
       161 
200 
     | 
    
         
             
                  # generates:
         
     | 
| 
       162 
201 
     | 
    
         
             
                  #
         
     | 
| 
       163 
202 
     | 
    
         
             
                  #   CREATE TABLE suppliers (
         
     | 
| 
       164 
     | 
    
         
            -
                  #     id int 
     | 
| 
      
 203 
     | 
    
         
            +
                  #     id int auto_increment PRIMARY KEY
         
     | 
| 
       165 
204 
     | 
    
         
             
                  #   ) ENGINE=InnoDB DEFAULT CHARSET=utf8
         
     | 
| 
       166 
205 
     | 
    
         
             
                  #
         
     | 
| 
       167 
206 
     | 
    
         
             
                  # ====== Rename the primary key column
         
     | 
| 
         @@ -173,10 +212,23 @@ module ActiveRecord 
     | 
|
| 
       173 
212 
     | 
    
         
             
                  # generates:
         
     | 
| 
       174 
213 
     | 
    
         
             
                  #
         
     | 
| 
       175 
214 
     | 
    
         
             
                  #   CREATE TABLE objects (
         
     | 
| 
       176 
     | 
    
         
            -
                  #     guid int 
     | 
| 
      
 215 
     | 
    
         
            +
                  #     guid int auto_increment PRIMARY KEY,
         
     | 
| 
       177 
216 
     | 
    
         
             
                  #     name varchar(80)
         
     | 
| 
       178 
217 
     | 
    
         
             
                  #   )
         
     | 
| 
       179 
218 
     | 
    
         
             
                  #
         
     | 
| 
      
 219 
     | 
    
         
            +
                  # ====== Change the primary key column type
         
     | 
| 
      
 220 
     | 
    
         
            +
                  #
         
     | 
| 
      
 221 
     | 
    
         
            +
                  #   create_table(:tags, id: :string) do |t|
         
     | 
| 
      
 222 
     | 
    
         
            +
                  #     t.column :label, :string
         
     | 
| 
      
 223 
     | 
    
         
            +
                  #   end
         
     | 
| 
      
 224 
     | 
    
         
            +
                  #
         
     | 
| 
      
 225 
     | 
    
         
            +
                  # generates:
         
     | 
| 
      
 226 
     | 
    
         
            +
                  #
         
     | 
| 
      
 227 
     | 
    
         
            +
                  #   CREATE TABLE tags (
         
     | 
| 
      
 228 
     | 
    
         
            +
                  #     id varchar PRIMARY KEY,
         
     | 
| 
      
 229 
     | 
    
         
            +
                  #     label varchar
         
     | 
| 
      
 230 
     | 
    
         
            +
                  #   )
         
     | 
| 
      
 231 
     | 
    
         
            +
                  #
         
     | 
| 
       180 
232 
     | 
    
         
             
                  # ====== Do not add a primary key column
         
     | 
| 
       181 
233 
     | 
    
         
             
                  #
         
     | 
| 
       182 
234 
     | 
    
         
             
                  #   create_table(:categories_suppliers, id: false) do |t|
         
     | 
| 
         @@ -202,33 +254,41 @@ module ActiveRecord 
     | 
|
| 
       202 
254 
     | 
    
         
             
                  #     SELECT * FROM orders INNER JOIN line_items ON order_id=orders.id
         
     | 
| 
       203 
255 
     | 
    
         
             
                  #
         
     | 
| 
       204 
256 
     | 
    
         
             
                  # See also TableDefinition#column for details on how to create columns.
         
     | 
| 
       205 
     | 
    
         
            -
                  def create_table(table_name,  
     | 
| 
       206 
     | 
    
         
            -
                    td = create_table_definition table_name, options[:temporary], options[:options], options[:as]
         
     | 
| 
      
 257 
     | 
    
         
            +
                  def create_table(table_name, comment: nil, **options)
         
     | 
| 
      
 258 
     | 
    
         
            +
                    td = create_table_definition table_name, options[:temporary], options[:options], options[:as], comment: comment
         
     | 
| 
       207 
259 
     | 
    
         | 
| 
       208 
260 
     | 
    
         
             
                    if options[:id] != false && !options[:as]
         
     | 
| 
       209 
261 
     | 
    
         
             
                      pk = options.fetch(:primary_key) do
         
     | 
| 
       210 
262 
     | 
    
         
             
                        Base.get_primary_key table_name.to_s.singularize
         
     | 
| 
       211 
263 
     | 
    
         
             
                      end
         
     | 
| 
       212 
264 
     | 
    
         | 
| 
       213 
     | 
    
         
            -
                       
     | 
| 
      
 265 
     | 
    
         
            +
                      if pk.is_a?(Array)
         
     | 
| 
      
 266 
     | 
    
         
            +
                        td.primary_keys pk
         
     | 
| 
      
 267 
     | 
    
         
            +
                      else
         
     | 
| 
      
 268 
     | 
    
         
            +
                        td.primary_key pk, options.fetch(:id, :primary_key), options
         
     | 
| 
      
 269 
     | 
    
         
            +
                      end
         
     | 
| 
       214 
270 
     | 
    
         
             
                    end
         
     | 
| 
       215 
271 
     | 
    
         | 
| 
       216 
272 
     | 
    
         
             
                    yield td if block_given?
         
     | 
| 
       217 
273 
     | 
    
         | 
| 
       218 
     | 
    
         
            -
                    if options[:force] &&  
     | 
| 
      
 274 
     | 
    
         
            +
                    if options[:force] && data_source_exists?(table_name)
         
     | 
| 
       219 
275 
     | 
    
         
             
                      drop_table(table_name, options)
         
     | 
| 
       220 
276 
     | 
    
         
             
                    end
         
     | 
| 
       221 
277 
     | 
    
         | 
| 
       222 
278 
     | 
    
         
             
                    result = execute schema_creation.accept td
         
     | 
| 
       223 
279 
     | 
    
         | 
| 
       224 
280 
     | 
    
         
             
                    unless supports_indexes_in_create?
         
     | 
| 
       225 
     | 
    
         
            -
                      td.indexes. 
     | 
| 
      
 281 
     | 
    
         
            +
                      td.indexes.each do |column_name, index_options|
         
     | 
| 
       226 
282 
     | 
    
         
             
                        add_index(table_name, column_name, index_options)
         
     | 
| 
       227 
283 
     | 
    
         
             
                      end
         
     | 
| 
       228 
284 
     | 
    
         
             
                    end
         
     | 
| 
       229 
285 
     | 
    
         | 
| 
       230 
     | 
    
         
            -
                     
     | 
| 
       231 
     | 
    
         
            -
                       
     | 
| 
      
 286 
     | 
    
         
            +
                    if supports_comments? && !supports_comments_in_create?
         
     | 
| 
      
 287 
     | 
    
         
            +
                      change_table_comment(table_name, comment) if comment.present?
         
     | 
| 
      
 288 
     | 
    
         
            +
             
     | 
| 
      
 289 
     | 
    
         
            +
                      td.columns.each do |column|
         
     | 
| 
      
 290 
     | 
    
         
            +
                        change_column_comment(table_name, column.name, column.comment) if column.comment.present?
         
     | 
| 
      
 291 
     | 
    
         
            +
                      end
         
     | 
| 
       232 
292 
     | 
    
         
             
                    end
         
     | 
| 
       233 
293 
     | 
    
         | 
| 
       234 
294 
     | 
    
         
             
                    result
         
     | 
| 
         @@ -253,7 +313,7 @@ module ActiveRecord 
     | 
|
| 
       253 
313 
     | 
    
         
             
                  #   Set to true to drop the table before creating it.
         
     | 
| 
       254 
314 
     | 
    
         
             
                  #   Defaults to false.
         
     | 
| 
       255 
315 
     | 
    
         
             
                  #
         
     | 
| 
       256 
     | 
    
         
            -
                  # Note that  
     | 
| 
      
 316 
     | 
    
         
            +
                  # Note that #create_join_table does not create any indices by default; you can use
         
     | 
| 
       257 
317 
     | 
    
         
             
                  # its block form to do so yourself:
         
     | 
| 
       258 
318 
     | 
    
         
             
                  #
         
     | 
| 
       259 
319 
     | 
    
         
             
                  #   create_join_table :products, :categories do |t|
         
     | 
| 
         @@ -277,22 +337,23 @@ module ActiveRecord 
     | 
|
| 
       277 
337 
     | 
    
         | 
| 
       278 
338 
     | 
    
         
             
                    column_options = options.delete(:column_options) || {}
         
     | 
| 
       279 
339 
     | 
    
         
             
                    column_options.reverse_merge!(null: false)
         
     | 
| 
      
 340 
     | 
    
         
            +
                    type = column_options.delete(:type) || :integer
         
     | 
| 
       280 
341 
     | 
    
         | 
| 
       281 
342 
     | 
    
         
             
                    t1_column, t2_column = [table_1, table_2].map{ |t| t.to_s.singularize.foreign_key }
         
     | 
| 
       282 
343 
     | 
    
         | 
| 
       283 
344 
     | 
    
         
             
                    create_table(join_table_name, options.merge!(id: false)) do |td|
         
     | 
| 
       284 
     | 
    
         
            -
                      td. 
     | 
| 
       285 
     | 
    
         
            -
                      td. 
     | 
| 
      
 345 
     | 
    
         
            +
                      td.send type, t1_column, column_options
         
     | 
| 
      
 346 
     | 
    
         
            +
                      td.send type, t2_column, column_options
         
     | 
| 
       286 
347 
     | 
    
         
             
                      yield td if block_given?
         
     | 
| 
       287 
348 
     | 
    
         
             
                    end
         
     | 
| 
       288 
349 
     | 
    
         
             
                  end
         
     | 
| 
       289 
350 
     | 
    
         | 
| 
       290 
351 
     | 
    
         
             
                  # Drops the join table specified by the given arguments.
         
     | 
| 
       291 
     | 
    
         
            -
                  # See  
     | 
| 
      
 352 
     | 
    
         
            +
                  # See #create_join_table for details.
         
     | 
| 
       292 
353 
     | 
    
         
             
                  #
         
     | 
| 
       293 
354 
     | 
    
         
             
                  # Although this command ignores the block if one is given, it can be helpful
         
     | 
| 
       294 
355 
     | 
    
         
             
                  # to provide one in a migration's +change+ method so it can be reverted.
         
     | 
| 
       295 
     | 
    
         
            -
                  # In that case, the block will be used by create_join_table.
         
     | 
| 
      
 356 
     | 
    
         
            +
                  # In that case, the block will be used by #create_join_table.
         
     | 
| 
       296 
357 
     | 
    
         
             
                  def drop_join_table(table_1, table_2, options = {})
         
     | 
| 
       297 
358 
     | 
    
         
             
                    join_table_name = find_join_table_name(table_1, table_2, options)
         
     | 
| 
       298 
359 
     | 
    
         
             
                    drop_table(join_table_name)
         
     | 
| 
         @@ -310,7 +371,7 @@ module ActiveRecord 
     | 
|
| 
       310 
371 
     | 
    
         
             
                  # [<tt>:bulk</tt>]
         
     | 
| 
       311 
372 
     | 
    
         
             
                  #   Set this to true to make this a bulk alter query, such as
         
     | 
| 
       312 
373 
     | 
    
         
             
                  #
         
     | 
| 
       313 
     | 
    
         
            -
                  #     ALTER TABLE `users` ADD COLUMN age INT 
     | 
| 
      
 374 
     | 
    
         
            +
                  #     ALTER TABLE `users` ADD COLUMN age INT, ADD COLUMN birthdate DATETIME ...
         
     | 
| 
       314 
375 
     | 
    
         
             
                  #
         
     | 
| 
       315 
376 
     | 
    
         
             
                  #   Defaults to false.
         
     | 
| 
       316 
377 
     | 
    
         
             
                  #
         
     | 
| 
         @@ -391,16 +452,90 @@ module ActiveRecord 
     | 
|
| 
       391 
452 
     | 
    
         
             
                  # [<tt>:force</tt>]
         
     | 
| 
       392 
453 
     | 
    
         
             
                  #   Set to +:cascade+ to drop dependent objects as well.
         
     | 
| 
       393 
454 
     | 
    
         
             
                  #   Defaults to false.
         
     | 
| 
      
 455 
     | 
    
         
            +
                  # [<tt>:if_exists</tt>]
         
     | 
| 
      
 456 
     | 
    
         
            +
                  #   Set to +true+ to only drop the table if it exists.
         
     | 
| 
      
 457 
     | 
    
         
            +
                  #   Defaults to false.
         
     | 
| 
       394 
458 
     | 
    
         
             
                  #
         
     | 
| 
       395 
459 
     | 
    
         
             
                  # Although this command ignores most +options+ and the block if one is given,
         
     | 
| 
       396 
460 
     | 
    
         
             
                  # it can be helpful to provide these in a migration's +change+ method so it can be reverted.
         
     | 
| 
       397 
     | 
    
         
            -
                  # In that case, +options+ and the block will be used by create_table.
         
     | 
| 
      
 461 
     | 
    
         
            +
                  # In that case, +options+ and the block will be used by #create_table.
         
     | 
| 
       398 
462 
     | 
    
         
             
                  def drop_table(table_name, options = {})
         
     | 
| 
       399 
     | 
    
         
            -
                    execute "DROP TABLE #{quote_table_name(table_name)}"
         
     | 
| 
      
 463 
     | 
    
         
            +
                    execute "DROP TABLE#{' IF EXISTS' if options[:if_exists]} #{quote_table_name(table_name)}"
         
     | 
| 
       400 
464 
     | 
    
         
             
                  end
         
     | 
| 
       401 
465 
     | 
    
         | 
| 
       402 
     | 
    
         
            -
                  #  
     | 
| 
       403 
     | 
    
         
            -
                  # 
     | 
| 
      
 466 
     | 
    
         
            +
                  # Add a new +type+ column named +column_name+ to +table_name+.
         
     | 
| 
      
 467 
     | 
    
         
            +
                  #
         
     | 
| 
      
 468 
     | 
    
         
            +
                  # The +type+ parameter is normally one of the migrations native types,
         
     | 
| 
      
 469 
     | 
    
         
            +
                  # which is one of the following:
         
     | 
| 
      
 470 
     | 
    
         
            +
                  # <tt>:primary_key</tt>, <tt>:string</tt>, <tt>:text</tt>,
         
     | 
| 
      
 471 
     | 
    
         
            +
                  # <tt>:integer</tt>, <tt>:bigint</tt>, <tt>:float</tt>, <tt>:decimal</tt>, <tt>:numeric</tt>,
         
     | 
| 
      
 472 
     | 
    
         
            +
                  # <tt>:datetime</tt>, <tt>:time</tt>, <tt>:date</tt>,
         
     | 
| 
      
 473 
     | 
    
         
            +
                  # <tt>:binary</tt>, <tt>:boolean</tt>.
         
     | 
| 
      
 474 
     | 
    
         
            +
                  #
         
     | 
| 
      
 475 
     | 
    
         
            +
                  # You may use a type not in this list as long as it is supported by your
         
     | 
| 
      
 476 
     | 
    
         
            +
                  # database (for example, "polygon" in MySQL), but this will not be database
         
     | 
| 
      
 477 
     | 
    
         
            +
                  # agnostic and should usually be avoided.
         
     | 
| 
      
 478 
     | 
    
         
            +
                  #
         
     | 
| 
      
 479 
     | 
    
         
            +
                  # Available options are (none of these exists by default):
         
     | 
| 
      
 480 
     | 
    
         
            +
                  # * <tt>:limit</tt> -
         
     | 
| 
      
 481 
     | 
    
         
            +
                  #   Requests a maximum column length. This is number of characters for a <tt>:string</tt> column
         
     | 
| 
      
 482 
     | 
    
         
            +
                  #   and number of bytes for <tt>:text</tt>, <tt>:binary</tt> and <tt>:integer</tt> columns.
         
     | 
| 
      
 483 
     | 
    
         
            +
                  # * <tt>:default</tt> -
         
     | 
| 
      
 484 
     | 
    
         
            +
                  #   The column's default value. Use nil for NULL.
         
     | 
| 
      
 485 
     | 
    
         
            +
                  # * <tt>:null</tt> -
         
     | 
| 
      
 486 
     | 
    
         
            +
                  #   Allows or disallows +NULL+ values in the column. This option could
         
     | 
| 
      
 487 
     | 
    
         
            +
                  #   have been named <tt>:null_allowed</tt>.
         
     | 
| 
      
 488 
     | 
    
         
            +
                  # * <tt>:precision</tt> -
         
     | 
| 
      
 489 
     | 
    
         
            +
                  #   Specifies the precision for the <tt>:decimal</tt> and <tt>:numeric</tt> columns.
         
     | 
| 
      
 490 
     | 
    
         
            +
                  # * <tt>:scale</tt> -
         
     | 
| 
      
 491 
     | 
    
         
            +
                  #   Specifies the scale for the <tt>:decimal</tt> and <tt>:numeric</tt> columns.
         
     | 
| 
      
 492 
     | 
    
         
            +
                  #
         
     | 
| 
      
 493 
     | 
    
         
            +
                  # Note: The precision is the total number of significant digits
         
     | 
| 
      
 494 
     | 
    
         
            +
                  # and the scale is the number of digits that can be stored following
         
     | 
| 
      
 495 
     | 
    
         
            +
                  # the decimal point. For example, the number 123.45 has a precision of 5
         
     | 
| 
      
 496 
     | 
    
         
            +
                  # and a scale of 2. A decimal with a precision of 5 and a scale of 2 can
         
     | 
| 
      
 497 
     | 
    
         
            +
                  # range from -999.99 to 999.99.
         
     | 
| 
      
 498 
     | 
    
         
            +
                  #
         
     | 
| 
      
 499 
     | 
    
         
            +
                  # Please be aware of different RDBMS implementations behavior with
         
     | 
| 
      
 500 
     | 
    
         
            +
                  # <tt>:decimal</tt> columns:
         
     | 
| 
      
 501 
     | 
    
         
            +
                  # * The SQL standard says the default scale should be 0, <tt>:scale</tt> <=
         
     | 
| 
      
 502 
     | 
    
         
            +
                  #   <tt>:precision</tt>, and makes no comments about the requirements of
         
     | 
| 
      
 503 
     | 
    
         
            +
                  #   <tt>:precision</tt>.
         
     | 
| 
      
 504 
     | 
    
         
            +
                  # * MySQL: <tt>:precision</tt> [1..63], <tt>:scale</tt> [0..30].
         
     | 
| 
      
 505 
     | 
    
         
            +
                  #   Default is (10,0).
         
     | 
| 
      
 506 
     | 
    
         
            +
                  # * PostgreSQL: <tt>:precision</tt> [1..infinity],
         
     | 
| 
      
 507 
     | 
    
         
            +
                  #   <tt>:scale</tt> [0..infinity]. No default.
         
     | 
| 
      
 508 
     | 
    
         
            +
                  # * SQLite3: No restrictions on <tt>:precision</tt> and <tt>:scale</tt>,
         
     | 
| 
      
 509 
     | 
    
         
            +
                  #   but the maximum supported <tt>:precision</tt> is 16. No default.
         
     | 
| 
      
 510 
     | 
    
         
            +
                  # * Oracle: <tt>:precision</tt> [1..38], <tt>:scale</tt> [-84..127].
         
     | 
| 
      
 511 
     | 
    
         
            +
                  #   Default is (38,0).
         
     | 
| 
      
 512 
     | 
    
         
            +
                  # * DB2: <tt>:precision</tt> [1..63], <tt>:scale</tt> [0..62].
         
     | 
| 
      
 513 
     | 
    
         
            +
                  #   Default unknown.
         
     | 
| 
      
 514 
     | 
    
         
            +
                  # * SqlServer?: <tt>:precision</tt> [1..38], <tt>:scale</tt> [0..38].
         
     | 
| 
      
 515 
     | 
    
         
            +
                  #   Default (38,0).
         
     | 
| 
      
 516 
     | 
    
         
            +
                  #
         
     | 
| 
      
 517 
     | 
    
         
            +
                  # == Examples
         
     | 
| 
      
 518 
     | 
    
         
            +
                  #
         
     | 
| 
      
 519 
     | 
    
         
            +
                  #  add_column(:users, :picture, :binary, limit: 2.megabytes)
         
     | 
| 
      
 520 
     | 
    
         
            +
                  #  # ALTER TABLE "users" ADD "picture" blob(2097152)
         
     | 
| 
      
 521 
     | 
    
         
            +
                  #
         
     | 
| 
      
 522 
     | 
    
         
            +
                  #  add_column(:articles, :status, :string, limit: 20, default: 'draft', null: false)
         
     | 
| 
      
 523 
     | 
    
         
            +
                  #  # ALTER TABLE "articles" ADD "status" varchar(20) DEFAULT 'draft' NOT NULL
         
     | 
| 
      
 524 
     | 
    
         
            +
                  #
         
     | 
| 
      
 525 
     | 
    
         
            +
                  #  add_column(:answers, :bill_gates_money, :decimal, precision: 15, scale: 2)
         
     | 
| 
      
 526 
     | 
    
         
            +
                  #  # ALTER TABLE "answers" ADD "bill_gates_money" decimal(15,2)
         
     | 
| 
      
 527 
     | 
    
         
            +
                  #
         
     | 
| 
      
 528 
     | 
    
         
            +
                  #  add_column(:measurements, :sensor_reading, :decimal, precision: 30, scale: 20)
         
     | 
| 
      
 529 
     | 
    
         
            +
                  #  # ALTER TABLE "measurements" ADD "sensor_reading" decimal(30,20)
         
     | 
| 
      
 530 
     | 
    
         
            +
                  #
         
     | 
| 
      
 531 
     | 
    
         
            +
                  #  # While :scale defaults to zero on most databases, it
         
     | 
| 
      
 532 
     | 
    
         
            +
                  #  # probably wouldn't hurt to include it.
         
     | 
| 
      
 533 
     | 
    
         
            +
                  #  add_column(:measurements, :huge_integer, :decimal, precision: 30)
         
     | 
| 
      
 534 
     | 
    
         
            +
                  #  # ALTER TABLE "measurements" ADD "huge_integer" decimal(30)
         
     | 
| 
      
 535 
     | 
    
         
            +
                  #
         
     | 
| 
      
 536 
     | 
    
         
            +
                  #  # Defines a column with a database-specific type.
         
     | 
| 
      
 537 
     | 
    
         
            +
                  #  add_column(:shapes, :triangle, 'polygon')
         
     | 
| 
      
 538 
     | 
    
         
            +
                  #  # ALTER TABLE "shapes" ADD "triangle" polygon
         
     | 
| 
       404 
539 
     | 
    
         
             
                  def add_column(table_name, column_name, type, options = {})
         
     | 
| 
       405 
540 
     | 
    
         
             
                    at = create_alter_table table_name
         
     | 
| 
       406 
541 
     | 
    
         
             
                    at.add_column(column_name, type, options)
         
     | 
| 
         @@ -448,11 +583,16 @@ module ActiveRecord 
     | 
|
| 
       448 
583 
     | 
    
         
             
                  #
         
     | 
| 
       449 
584 
     | 
    
         
             
                  #   change_column_default(:users, :email, nil)
         
     | 
| 
       450 
585 
     | 
    
         
             
                  #
         
     | 
| 
       451 
     | 
    
         
            -
                   
     | 
| 
      
 586 
     | 
    
         
            +
                  # Passing a hash containing +:from+ and +:to+ will make this change
         
     | 
| 
      
 587 
     | 
    
         
            +
                  # reversible in migration:
         
     | 
| 
      
 588 
     | 
    
         
            +
                  #
         
     | 
| 
      
 589 
     | 
    
         
            +
                  #   change_column_default(:posts, :state, from: nil, to: "draft")
         
     | 
| 
      
 590 
     | 
    
         
            +
                  #
         
     | 
| 
      
 591 
     | 
    
         
            +
                  def change_column_default(table_name, column_name, default_or_changes)
         
     | 
| 
       452 
592 
     | 
    
         
             
                    raise NotImplementedError, "change_column_default is not implemented"
         
     | 
| 
       453 
593 
     | 
    
         
             
                  end
         
     | 
| 
       454 
594 
     | 
    
         | 
| 
       455 
     | 
    
         
            -
                  # Sets or removes a  
     | 
| 
      
 595 
     | 
    
         
            +
                  # Sets or removes a <tt>NOT NULL</tt> constraint on a column. The +null+ flag
         
     | 
| 
       456 
596 
     | 
    
         
             
                  # indicates whether the value can be +NULL+. For example
         
     | 
| 
       457 
597 
     | 
    
         
             
                  #
         
     | 
| 
       458 
598 
     | 
    
         
             
                  #   change_column_null(:users, :nickname, false)
         
     | 
| 
         @@ -464,7 +604,7 @@ module ActiveRecord 
     | 
|
| 
       464 
604 
     | 
    
         
             
                  # allows them to be +NULL+ (drops the constraint).
         
     | 
| 
       465 
605 
     | 
    
         
             
                  #
         
     | 
| 
       466 
606 
     | 
    
         
             
                  # The method accepts an optional fourth argument to replace existing
         
     | 
| 
       467 
     | 
    
         
            -
                  #  
     | 
| 
      
 607 
     | 
    
         
            +
                  # <tt>NULL</tt>s with some other value. Use that one when enabling the
         
     | 
| 
       468 
608 
     | 
    
         
             
                  # constraint if needed, since otherwise those rows would not be valid.
         
     | 
| 
       469 
609 
     | 
    
         
             
                  #
         
     | 
| 
       470 
610 
     | 
    
         
             
                  # Please note the fourth argument does not set a column's default.
         
     | 
| 
         @@ -518,6 +658,8 @@ module ActiveRecord 
     | 
|
| 
       518 
658 
     | 
    
         
             
                  #
         
     | 
| 
       519 
659 
     | 
    
         
             
                  #   CREATE INDEX by_name ON accounts(name(10))
         
     | 
| 
       520 
660 
     | 
    
         
             
                  #
         
     | 
| 
      
 661 
     | 
    
         
            +
                  # ====== Creating an index with specific key lengths for multiple keys
         
     | 
| 
      
 662 
     | 
    
         
            +
                  #
         
     | 
| 
       521 
663 
     | 
    
         
             
                  #   add_index(:accounts, [:name, :surname], name: 'by_name_surname', length: {name: 10, surname: 15})
         
     | 
| 
       522 
664 
     | 
    
         
             
                  #
         
     | 
| 
       523 
665 
     | 
    
         
             
                  # generates:
         
     | 
| 
         @@ -565,7 +707,7 @@ module ActiveRecord 
     | 
|
| 
       565 
707 
     | 
    
         
             
                  #
         
     | 
| 
       566 
708 
     | 
    
         
             
                  #   CREATE FULLTEXT INDEX index_developers_on_name ON developers (name) -- MySQL
         
     | 
| 
       567 
709 
     | 
    
         
             
                  #
         
     | 
| 
       568 
     | 
    
         
            -
                  # Note: only supported by MySQL. 
     | 
| 
      
 710 
     | 
    
         
            +
                  # Note: only supported by MySQL.
         
     | 
| 
       569 
711 
     | 
    
         
             
                  def add_index(table_name, column_name, options = {})
         
     | 
| 
       570 
712 
     | 
    
         
             
                    index_name, index_type, index_columns, index_options = add_index_options(table_name, column_name, options)
         
     | 
| 
       571 
713 
     | 
    
         
             
                    execute "CREATE #{index_type} INDEX #{quote_column_name(index_name)} ON #{quote_table_name(table_name)} (#{index_columns})#{index_options}"
         
     | 
| 
         @@ -573,15 +715,15 @@ module ActiveRecord 
     | 
|
| 
       573 
715 
     | 
    
         | 
| 
       574 
716 
     | 
    
         
             
                  # Removes the given index from the table.
         
     | 
| 
       575 
717 
     | 
    
         
             
                  #
         
     | 
| 
       576 
     | 
    
         
            -
                  # Removes the + 
     | 
| 
      
 718 
     | 
    
         
            +
                  # Removes the index on +branch_id+ in the +accounts+ table if exactly one such index exists.
         
     | 
| 
       577 
719 
     | 
    
         
             
                  #
         
     | 
| 
       578 
     | 
    
         
            -
                  #   remove_index :accounts, : 
     | 
| 
      
 720 
     | 
    
         
            +
                  #   remove_index :accounts, :branch_id
         
     | 
| 
       579 
721 
     | 
    
         
             
                  #
         
     | 
| 
       580 
     | 
    
         
            -
                  # Removes the index  
     | 
| 
      
 722 
     | 
    
         
            +
                  # Removes the index on +branch_id+ in the +accounts+ table if exactly one such index exists.
         
     | 
| 
       581 
723 
     | 
    
         
             
                  #
         
     | 
| 
       582 
724 
     | 
    
         
             
                  #   remove_index :accounts, column: :branch_id
         
     | 
| 
       583 
725 
     | 
    
         
             
                  #
         
     | 
| 
       584 
     | 
    
         
            -
                  # Removes the index  
     | 
| 
      
 726 
     | 
    
         
            +
                  # Removes the index on +branch_id+ and +party_id+ in the +accounts+ table if exactly one such index exists.
         
     | 
| 
       585 
727 
     | 
    
         
             
                  #
         
     | 
| 
       586 
728 
     | 
    
         
             
                  #   remove_index :accounts, column: [:branch_id, :party_id]
         
     | 
| 
       587 
729 
     | 
    
         
             
                  #
         
     | 
| 
         @@ -590,10 +732,7 @@ module ActiveRecord 
     | 
|
| 
       590 
732 
     | 
    
         
             
                  #   remove_index :accounts, name: :by_branch_party
         
     | 
| 
       591 
733 
     | 
    
         
             
                  #
         
     | 
| 
       592 
734 
     | 
    
         
             
                  def remove_index(table_name, options = {})
         
     | 
| 
       593 
     | 
    
         
            -
                     
     | 
| 
       594 
     | 
    
         
            -
                  end
         
     | 
| 
       595 
     | 
    
         
            -
             
     | 
| 
       596 
     | 
    
         
            -
                  def remove_index!(table_name, index_name) #:nodoc:
         
     | 
| 
      
 735 
     | 
    
         
            +
                    index_name = index_name_for_remove(table_name, options)
         
     | 
| 
       597 
736 
     | 
    
         
             
                    execute "DROP INDEX #{quote_column_name(index_name)} ON #{quote_table_name(table_name)}"
         
     | 
| 
       598 
737 
     | 
    
         
             
                  end
         
     | 
| 
       599 
738 
     | 
    
         | 
| 
         @@ -623,7 +762,7 @@ module ActiveRecord 
     | 
|
| 
       623 
762 
     | 
    
         
             
                        raise ArgumentError, "You must specify the index name"
         
     | 
| 
       624 
763 
     | 
    
         
             
                      end
         
     | 
| 
       625 
764 
     | 
    
         
             
                    else
         
     | 
| 
       626 
     | 
    
         
            -
                      index_name(table_name,  
     | 
| 
      
 765 
     | 
    
         
            +
                      index_name(table_name, index_name_options(options))
         
     | 
| 
       627 
766 
     | 
    
         
             
                    end
         
     | 
| 
       628 
767 
     | 
    
         
             
                  end
         
     | 
| 
       629 
768 
     | 
    
         | 
| 
         @@ -640,17 +779,20 @@ module ActiveRecord 
     | 
|
| 
       640 
779 
     | 
    
         
             
                  # Adds a reference. The reference column is an integer by default,
         
     | 
| 
       641 
780 
     | 
    
         
             
                  # the <tt>:type</tt> option can be used to specify a different type.
         
     | 
| 
       642 
781 
     | 
    
         
             
                  # Optionally adds a +_type+ column, if <tt>:polymorphic</tt> option is provided.
         
     | 
| 
       643 
     | 
    
         
            -
                  #  
     | 
| 
      
 782 
     | 
    
         
            +
                  # #add_reference and #add_belongs_to are acceptable.
         
     | 
| 
       644 
783 
     | 
    
         
             
                  #
         
     | 
| 
       645 
784 
     | 
    
         
             
                  # The +options+ hash can include the following keys:
         
     | 
| 
       646 
785 
     | 
    
         
             
                  # [<tt>:type</tt>]
         
     | 
| 
       647 
786 
     | 
    
         
             
                  #   The reference column type. Defaults to +:integer+.
         
     | 
| 
       648 
787 
     | 
    
         
             
                  # [<tt>:index</tt>]
         
     | 
| 
       649 
     | 
    
         
            -
                  #   Add an appropriate index. Defaults to  
     | 
| 
      
 788 
     | 
    
         
            +
                  #   Add an appropriate index. Defaults to true.
         
     | 
| 
      
 789 
     | 
    
         
            +
                  #   See #add_index for usage of this option.
         
     | 
| 
       650 
790 
     | 
    
         
             
                  # [<tt>:foreign_key</tt>]
         
     | 
| 
       651 
     | 
    
         
            -
                  #   Add an appropriate foreign key. Defaults to false.
         
     | 
| 
      
 791 
     | 
    
         
            +
                  #   Add an appropriate foreign key constraint. Defaults to false.
         
     | 
| 
       652 
792 
     | 
    
         
             
                  # [<tt>:polymorphic</tt>]
         
     | 
| 
       653 
     | 
    
         
            -
                  #    
     | 
| 
      
 793 
     | 
    
         
            +
                  #   Whether an additional +_type+ column should be added. Defaults to false.
         
     | 
| 
      
 794 
     | 
    
         
            +
                  # [<tt>:null</tt>]
         
     | 
| 
      
 795 
     | 
    
         
            +
                  #   Whether the column allows nulls. Defaults to true.
         
     | 
| 
       654 
796 
     | 
    
         
             
                  #
         
     | 
| 
       655 
797 
     | 
    
         
             
                  # ====== Create a user_id integer column
         
     | 
| 
       656 
798 
     | 
    
         
             
                  #
         
     | 
| 
         @@ -664,28 +806,29 @@ module ActiveRecord 
     | 
|
| 
       664 
806 
     | 
    
         
             
                  #
         
     | 
| 
       665 
807 
     | 
    
         
             
                  #   add_reference(:products, :supplier, polymorphic: true, index: true)
         
     | 
| 
       666 
808 
     | 
    
         
             
                  #
         
     | 
| 
       667 
     | 
    
         
            -
                   
     | 
| 
       668 
     | 
    
         
            -
             
     | 
| 
       669 
     | 
    
         
            -
             
     | 
| 
       670 
     | 
    
         
            -
             
     | 
| 
       671 
     | 
    
         
            -
             
     | 
| 
       672 
     | 
    
         
            -
             
     | 
| 
       673 
     | 
    
         
            -
             
     | 
| 
       674 
     | 
    
         
            -
             
     | 
| 
       675 
     | 
    
         
            -
             
     | 
| 
       676 
     | 
    
         
            -
             
     | 
| 
       677 
     | 
    
         
            -
             
     | 
| 
       678 
     | 
    
         
            -
             
     | 
| 
       679 
     | 
    
         
            -
             
     | 
| 
       680 
     | 
    
         
            -
             
     | 
| 
       681 
     | 
    
         
            -
             
     | 
| 
       682 
     | 
    
         
            -
             
     | 
| 
       683 
     | 
    
         
            -
             
     | 
| 
      
 809 
     | 
    
         
            +
                  # ====== Create a supplier_id column with a unique index
         
     | 
| 
      
 810 
     | 
    
         
            +
                  #
         
     | 
| 
      
 811 
     | 
    
         
            +
                  #   add_reference(:products, :supplier, index: { unique: true })
         
     | 
| 
      
 812 
     | 
    
         
            +
                  #
         
     | 
| 
      
 813 
     | 
    
         
            +
                  # ====== Create a supplier_id column with a named index
         
     | 
| 
      
 814 
     | 
    
         
            +
                  #
         
     | 
| 
      
 815 
     | 
    
         
            +
                  #   add_reference(:products, :supplier, index: { name: "my_supplier_index" })
         
     | 
| 
      
 816 
     | 
    
         
            +
                  #
         
     | 
| 
      
 817 
     | 
    
         
            +
                  # ====== Create a supplier_id column and appropriate foreign key
         
     | 
| 
      
 818 
     | 
    
         
            +
                  #
         
     | 
| 
      
 819 
     | 
    
         
            +
                  #   add_reference(:products, :supplier, foreign_key: true)
         
     | 
| 
      
 820 
     | 
    
         
            +
                  #
         
     | 
| 
      
 821 
     | 
    
         
            +
                  # ====== Create a supplier_id column and a foreign key to the firms table
         
     | 
| 
      
 822 
     | 
    
         
            +
                  #
         
     | 
| 
      
 823 
     | 
    
         
            +
                  #   add_reference(:products, :supplier, foreign_key: {to_table: :firms})
         
     | 
| 
      
 824 
     | 
    
         
            +
                  #
         
     | 
| 
      
 825 
     | 
    
         
            +
                  def add_reference(table_name, *args)
         
     | 
| 
      
 826 
     | 
    
         
            +
                    ReferenceDefinition.new(*args).add_to(update_table_definition(table_name, self))
         
     | 
| 
       684 
827 
     | 
    
         
             
                  end
         
     | 
| 
       685 
828 
     | 
    
         
             
                  alias :add_belongs_to :add_reference
         
     | 
| 
       686 
829 
     | 
    
         | 
| 
       687 
830 
     | 
    
         
             
                  # Removes the reference(s). Also removes a +type+ column if one exists.
         
     | 
| 
       688 
     | 
    
         
            -
                  #  
     | 
| 
      
 831 
     | 
    
         
            +
                  # #remove_reference and #remove_belongs_to are acceptable.
         
     | 
| 
       689 
832 
     | 
    
         
             
                  #
         
     | 
| 
       690 
833 
     | 
    
         
             
                  # ====== Remove the reference
         
     | 
| 
       691 
834 
     | 
    
         
             
                  #
         
     | 
| 
         @@ -699,19 +842,24 @@ module ActiveRecord 
     | 
|
| 
       699 
842 
     | 
    
         
             
                  #
         
     | 
| 
       700 
843 
     | 
    
         
             
                  #   remove_reference(:products, :user, index: true, foreign_key: true)
         
     | 
| 
       701 
844 
     | 
    
         
             
                  #
         
     | 
| 
       702 
     | 
    
         
            -
                  def remove_reference(table_name, ref_name,  
     | 
| 
       703 
     | 
    
         
            -
                    if  
     | 
| 
       704 
     | 
    
         
            -
                       
     | 
| 
       705 
     | 
    
         
            -
                       
     | 
| 
      
 845 
     | 
    
         
            +
                  def remove_reference(table_name, ref_name, foreign_key: false, polymorphic: false, **options)
         
     | 
| 
      
 846 
     | 
    
         
            +
                    if foreign_key
         
     | 
| 
      
 847 
     | 
    
         
            +
                      reference_name = Base.pluralize_table_names ? ref_name.to_s.pluralize : ref_name
         
     | 
| 
      
 848 
     | 
    
         
            +
                      if foreign_key.is_a?(Hash)
         
     | 
| 
      
 849 
     | 
    
         
            +
                        foreign_key_options = foreign_key
         
     | 
| 
      
 850 
     | 
    
         
            +
                      else
         
     | 
| 
      
 851 
     | 
    
         
            +
                        foreign_key_options = { to_table: reference_name }
         
     | 
| 
      
 852 
     | 
    
         
            +
                      end
         
     | 
| 
      
 853 
     | 
    
         
            +
                      remove_foreign_key(table_name, **foreign_key_options)
         
     | 
| 
       706 
854 
     | 
    
         
             
                    end
         
     | 
| 
       707 
855 
     | 
    
         | 
| 
       708 
856 
     | 
    
         
             
                    remove_column(table_name, "#{ref_name}_id")
         
     | 
| 
       709 
     | 
    
         
            -
                    remove_column(table_name, "#{ref_name}_type") if  
     | 
| 
      
 857 
     | 
    
         
            +
                    remove_column(table_name, "#{ref_name}_type") if polymorphic
         
     | 
| 
       710 
858 
     | 
    
         
             
                  end
         
     | 
| 
       711 
859 
     | 
    
         
             
                  alias :remove_belongs_to :remove_reference
         
     | 
| 
       712 
860 
     | 
    
         | 
| 
       713 
861 
     | 
    
         
             
                  # Returns an array of foreign keys for the given table.
         
     | 
| 
       714 
     | 
    
         
            -
                  # The foreign keys are represented as  
     | 
| 
      
 862 
     | 
    
         
            +
                  # The foreign keys are represented as ForeignKeyDefinition objects.
         
     | 
| 
       715 
863 
     | 
    
         
             
                  def foreign_keys(table_name)
         
     | 
| 
       716 
864 
     | 
    
         
             
                    raise NotImplementedError, "foreign_keys is not implemented"
         
     | 
| 
       717 
865 
     | 
    
         
             
                  end
         
     | 
| 
         @@ -729,11 +877,11 @@ module ActiveRecord 
     | 
|
| 
       729 
877 
     | 
    
         
             
                  #
         
     | 
| 
       730 
878 
     | 
    
         
             
                  # generates:
         
     | 
| 
       731 
879 
     | 
    
         
             
                  #
         
     | 
| 
       732 
     | 
    
         
            -
                  #   ALTER TABLE "articles" ADD CONSTRAINT  
     | 
| 
      
 880 
     | 
    
         
            +
                  #   ALTER TABLE "articles" ADD CONSTRAINT fk_rails_e74ce85cbc FOREIGN KEY ("author_id") REFERENCES "authors" ("id")
         
     | 
| 
       733 
881 
     | 
    
         
             
                  #
         
     | 
| 
       734 
882 
     | 
    
         
             
                  # ====== Creating a foreign key on a specific column
         
     | 
| 
       735 
883 
     | 
    
         
             
                  #
         
     | 
| 
       736 
     | 
    
         
            -
                  #   add_foreign_key :articles, :users, column: :author_id, primary_key:  
     | 
| 
      
 884 
     | 
    
         
            +
                  #   add_foreign_key :articles, :users, column: :author_id, primary_key: "lng_id"
         
     | 
| 
       737 
885 
     | 
    
         
             
                  #
         
     | 
| 
       738 
886 
     | 
    
         
             
                  # generates:
         
     | 
| 
       739 
887 
     | 
    
         
             
                  #
         
     | 
| 
         @@ -745,7 +893,7 @@ module ActiveRecord 
     | 
|
| 
       745 
893 
     | 
    
         
             
                  #
         
     | 
| 
       746 
894 
     | 
    
         
             
                  # generates:
         
     | 
| 
       747 
895 
     | 
    
         
             
                  #
         
     | 
| 
       748 
     | 
    
         
            -
                  #   ALTER TABLE "articles" ADD CONSTRAINT  
     | 
| 
      
 896 
     | 
    
         
            +
                  #   ALTER TABLE "articles" ADD CONSTRAINT fk_rails_e74ce85cbc FOREIGN KEY ("author_id") REFERENCES "authors" ("id") ON DELETE CASCADE
         
     | 
| 
       749 
897 
     | 
    
         
             
                  #
         
     | 
| 
       750 
898 
     | 
    
         
             
                  # The +options+ hash can include the following keys:
         
     | 
| 
       751 
899 
     | 
    
         
             
                  # [<tt>:column</tt>]
         
     | 
| 
         @@ -755,28 +903,23 @@ module ActiveRecord 
     | 
|
| 
       755 
903 
     | 
    
         
             
                  # [<tt>:name</tt>]
         
     | 
| 
       756 
904 
     | 
    
         
             
                  #   The constraint name. Defaults to <tt>fk_rails_<identifier></tt>.
         
     | 
| 
       757 
905 
     | 
    
         
             
                  # [<tt>:on_delete</tt>]
         
     | 
| 
       758 
     | 
    
         
            -
                  #   Action that happens <tt>ON DELETE</tt>. Valid values are +:nullify+, +:cascade 
     | 
| 
      
 906 
     | 
    
         
            +
                  #   Action that happens <tt>ON DELETE</tt>. Valid values are +:nullify+, +:cascade+ and +:restrict+
         
     | 
| 
       759 
907 
     | 
    
         
             
                  # [<tt>:on_update</tt>]
         
     | 
| 
       760 
     | 
    
         
            -
                  #   Action that happens <tt>ON UPDATE</tt>. Valid values are +:nullify+, +:cascade 
     | 
| 
      
 908 
     | 
    
         
            +
                  #   Action that happens <tt>ON UPDATE</tt>. Valid values are +:nullify+, +:cascade+ and +:restrict+
         
     | 
| 
       761 
909 
     | 
    
         
             
                  def add_foreign_key(from_table, to_table, options = {})
         
     | 
| 
       762 
910 
     | 
    
         
             
                    return unless supports_foreign_keys?
         
     | 
| 
       763 
911 
     | 
    
         | 
| 
       764 
     | 
    
         
            -
                    options 
     | 
| 
       765 
     | 
    
         
            -
             
     | 
| 
       766 
     | 
    
         
            -
                    options = {
         
     | 
| 
       767 
     | 
    
         
            -
                      column: options[:column],
         
     | 
| 
       768 
     | 
    
         
            -
                      primary_key: options[:primary_key],
         
     | 
| 
       769 
     | 
    
         
            -
                      name: foreign_key_name(from_table, options),
         
     | 
| 
       770 
     | 
    
         
            -
                      on_delete: options[:on_delete],
         
     | 
| 
       771 
     | 
    
         
            -
                      on_update: options[:on_update]
         
     | 
| 
       772 
     | 
    
         
            -
                    }
         
     | 
| 
      
 912 
     | 
    
         
            +
                    options = foreign_key_options(from_table, to_table, options)
         
     | 
| 
       773 
913 
     | 
    
         
             
                    at = create_alter_table from_table
         
     | 
| 
       774 
914 
     | 
    
         
             
                    at.add_foreign_key to_table, options
         
     | 
| 
       775 
915 
     | 
    
         | 
| 
       776 
916 
     | 
    
         
             
                    execute schema_creation.accept(at)
         
     | 
| 
       777 
917 
     | 
    
         
             
                  end
         
     | 
| 
       778 
918 
     | 
    
         | 
| 
       779 
     | 
    
         
            -
                  # Removes the given foreign key from the table.
         
     | 
| 
      
 919 
     | 
    
         
            +
                  # Removes the given foreign key from the table. Any option parameters provided
         
     | 
| 
      
 920 
     | 
    
         
            +
                  # will be used to re-add the foreign key in case of a migration rollback.
         
     | 
| 
      
 921 
     | 
    
         
            +
                  # It is recommended that you provide any options used when creating the foreign
         
     | 
| 
      
 922 
     | 
    
         
            +
                  # key so that the migration can be reverted properly.
         
     | 
| 
       780 
923 
     | 
    
         
             
                  #
         
     | 
| 
       781 
924 
     | 
    
         
             
                  # Removes the foreign key on +accounts.branch_id+.
         
     | 
| 
       782 
925 
     | 
    
         
             
                  #
         
     | 
| 
         @@ -790,24 +933,11 @@ module ActiveRecord 
     | 
|
| 
       790 
933 
     | 
    
         
             
                  #
         
     | 
| 
       791 
934 
     | 
    
         
             
                  #   remove_foreign_key :accounts, name: :special_fk_name
         
     | 
| 
       792 
935 
     | 
    
         
             
                  #
         
     | 
| 
      
 936 
     | 
    
         
            +
                  # The +options+ hash accepts the same keys as SchemaStatements#add_foreign_key.
         
     | 
| 
       793 
937 
     | 
    
         
             
                  def remove_foreign_key(from_table, options_or_to_table = {})
         
     | 
| 
       794 
938 
     | 
    
         
             
                    return unless supports_foreign_keys?
         
     | 
| 
       795 
939 
     | 
    
         | 
| 
       796 
     | 
    
         
            -
                     
     | 
| 
       797 
     | 
    
         
            -
                      options = options_or_to_table
         
     | 
| 
       798 
     | 
    
         
            -
                    else
         
     | 
| 
       799 
     | 
    
         
            -
                      options = { column: foreign_key_column_for(options_or_to_table) }
         
     | 
| 
       800 
     | 
    
         
            -
                    end
         
     | 
| 
       801 
     | 
    
         
            -
             
     | 
| 
       802 
     | 
    
         
            -
                    fk_name_to_delete = options.fetch(:name) do
         
     | 
| 
       803 
     | 
    
         
            -
                      fk_to_delete = foreign_keys(from_table).detect {|fk| fk.column == options[:column].to_s }
         
     | 
| 
       804 
     | 
    
         
            -
             
     | 
| 
       805 
     | 
    
         
            -
                      if fk_to_delete
         
     | 
| 
       806 
     | 
    
         
            -
                        fk_to_delete.name
         
     | 
| 
       807 
     | 
    
         
            -
                      else
         
     | 
| 
       808 
     | 
    
         
            -
                        raise ArgumentError, "Table '#{from_table}' has no foreign key on column '#{options[:column]}'"
         
     | 
| 
       809 
     | 
    
         
            -
                      end
         
     | 
| 
       810 
     | 
    
         
            -
                    end
         
     | 
| 
      
 940 
     | 
    
         
            +
                    fk_name_to_delete = foreign_key_for!(from_table, options_or_to_table).name
         
     | 
| 
       811 
941 
     | 
    
         | 
| 
       812 
942 
     | 
    
         
             
                    at = create_alter_table from_table
         
     | 
| 
       813 
943 
     | 
    
         
             
                    at.drop_foreign_key fk_name_to_delete
         
     | 
| 
         @@ -815,6 +945,31 @@ module ActiveRecord 
     | 
|
| 
       815 
945 
     | 
    
         
             
                    execute schema_creation.accept(at)
         
     | 
| 
       816 
946 
     | 
    
         
             
                  end
         
     | 
| 
       817 
947 
     | 
    
         | 
| 
      
 948 
     | 
    
         
            +
                  # Checks to see if a foreign key exists on a table for a given foreign key definition.
         
     | 
| 
      
 949 
     | 
    
         
            +
                  #
         
     | 
| 
      
 950 
     | 
    
         
            +
                  #   # Check a foreign key exists
         
     | 
| 
      
 951 
     | 
    
         
            +
                  #   foreign_key_exists?(:accounts, :branches)
         
     | 
| 
      
 952 
     | 
    
         
            +
                  #
         
     | 
| 
      
 953 
     | 
    
         
            +
                  #   # Check a foreign key on a specified column exists
         
     | 
| 
      
 954 
     | 
    
         
            +
                  #   foreign_key_exists?(:accounts, column: :owner_id)
         
     | 
| 
      
 955 
     | 
    
         
            +
                  #
         
     | 
| 
      
 956 
     | 
    
         
            +
                  #   # Check a foreign key with a custom name exists
         
     | 
| 
      
 957 
     | 
    
         
            +
                  #   foreign_key_exists?(:accounts, name: "special_fk_name")
         
     | 
| 
      
 958 
     | 
    
         
            +
                  #
         
     | 
| 
      
 959 
     | 
    
         
            +
                  def foreign_key_exists?(from_table, options_or_to_table = {})
         
     | 
| 
      
 960 
     | 
    
         
            +
                    foreign_key_for(from_table, options_or_to_table).present?
         
     | 
| 
      
 961 
     | 
    
         
            +
                  end
         
     | 
| 
      
 962 
     | 
    
         
            +
             
     | 
| 
      
 963 
     | 
    
         
            +
                  def foreign_key_for(from_table, options_or_to_table = {}) # :nodoc:
         
     | 
| 
      
 964 
     | 
    
         
            +
                    return unless supports_foreign_keys?
         
     | 
| 
      
 965 
     | 
    
         
            +
                    foreign_keys(from_table).detect {|fk| fk.defined_for? options_or_to_table }
         
     | 
| 
      
 966 
     | 
    
         
            +
                  end
         
     | 
| 
      
 967 
     | 
    
         
            +
             
     | 
| 
      
 968 
     | 
    
         
            +
                  def foreign_key_for!(from_table, options_or_to_table = {}) # :nodoc:
         
     | 
| 
      
 969 
     | 
    
         
            +
                    foreign_key_for(from_table, options_or_to_table) or \
         
     | 
| 
      
 970 
     | 
    
         
            +
                      raise ArgumentError, "Table '#{from_table}' has no foreign key for #{options_or_to_table}"
         
     | 
| 
      
 971 
     | 
    
         
            +
                  end
         
     | 
| 
      
 972 
     | 
    
         
            +
             
     | 
| 
       818 
973 
     | 
    
         
             
                  def foreign_key_column_for(table_name) # :nodoc:
         
     | 
| 
       819 
974 
     | 
    
         
             
                    prefix = Base.table_name_prefix
         
     | 
| 
       820 
975 
     | 
    
         
             
                    suffix = Base.table_name_suffix
         
     | 
| 
         @@ -822,12 +977,29 @@ module ActiveRecord 
     | 
|
| 
       822 
977 
     | 
    
         
             
                    "#{name.singularize}_id"
         
     | 
| 
       823 
978 
     | 
    
         
             
                  end
         
     | 
| 
       824 
979 
     | 
    
         | 
| 
      
 980 
     | 
    
         
            +
                  def foreign_key_options(from_table, to_table, options) # :nodoc:
         
     | 
| 
      
 981 
     | 
    
         
            +
                    options = options.dup
         
     | 
| 
      
 982 
     | 
    
         
            +
                    options[:column] ||= foreign_key_column_for(to_table)
         
     | 
| 
      
 983 
     | 
    
         
            +
                    options[:name]   ||= foreign_key_name(from_table, options)
         
     | 
| 
      
 984 
     | 
    
         
            +
                    options
         
     | 
| 
      
 985 
     | 
    
         
            +
                  end
         
     | 
| 
      
 986 
     | 
    
         
            +
             
     | 
| 
       825 
987 
     | 
    
         
             
                  def dump_schema_information #:nodoc:
         
     | 
| 
       826 
     | 
    
         
            -
                     
     | 
| 
      
 988 
     | 
    
         
            +
                    versions = ActiveRecord::SchemaMigration.order('version').pluck(:version)
         
     | 
| 
      
 989 
     | 
    
         
            +
                    insert_versions_sql(versions) if versions.any?
         
     | 
| 
      
 990 
     | 
    
         
            +
                  end
         
     | 
| 
       827 
991 
     | 
    
         | 
| 
       828 
     | 
    
         
            -
             
     | 
| 
       829 
     | 
    
         
            -
             
     | 
| 
       830 
     | 
    
         
            -
             
     | 
| 
      
 992 
     | 
    
         
            +
                  def insert_versions_sql(versions) # :nodoc:
         
     | 
| 
      
 993 
     | 
    
         
            +
                    sm_table = quote_table_name(ActiveRecord::Migrator.schema_migrations_table_name)
         
     | 
| 
      
 994 
     | 
    
         
            +
             
     | 
| 
      
 995 
     | 
    
         
            +
                    if versions.is_a?(Array)
         
     | 
| 
      
 996 
     | 
    
         
            +
                      sql = "INSERT INTO #{sm_table} (version) VALUES\n"
         
     | 
| 
      
 997 
     | 
    
         
            +
                      sql << versions.map { |v| "(#{quote(v)})" }.join(",\n")
         
     | 
| 
      
 998 
     | 
    
         
            +
                      sql << ";\n\n"
         
     | 
| 
      
 999 
     | 
    
         
            +
                      sql
         
     | 
| 
      
 1000 
     | 
    
         
            +
                    else
         
     | 
| 
      
 1001 
     | 
    
         
            +
                      "INSERT INTO #{sm_table} (version) VALUES (#{quote(versions)});"
         
     | 
| 
      
 1002 
     | 
    
         
            +
                    end
         
     | 
| 
       831 
1003 
     | 
    
         
             
                  end
         
     | 
| 
       832 
1004 
     | 
    
         | 
| 
       833 
1005 
     | 
    
         
             
                  # Should not be called normally, but this operation is non-destructive.
         
     | 
| 
         @@ -836,7 +1008,15 @@ module ActiveRecord 
     | 
|
| 
       836 
1008 
     | 
    
         
             
                    ActiveRecord::SchemaMigration.create_table
         
     | 
| 
       837 
1009 
     | 
    
         
             
                  end
         
     | 
| 
       838 
1010 
     | 
    
         | 
| 
       839 
     | 
    
         
            -
                  def  
     | 
| 
      
 1011 
     | 
    
         
            +
                  def initialize_internal_metadata_table
         
     | 
| 
      
 1012 
     | 
    
         
            +
                    ActiveRecord::InternalMetadata.create_table
         
     | 
| 
      
 1013 
     | 
    
         
            +
                  end
         
     | 
| 
      
 1014 
     | 
    
         
            +
             
     | 
| 
      
 1015 
     | 
    
         
            +
                  def internal_string_options_for_primary_key # :nodoc:
         
     | 
| 
      
 1016 
     | 
    
         
            +
                    { primary_key: true }
         
     | 
| 
      
 1017 
     | 
    
         
            +
                  end
         
     | 
| 
      
 1018 
     | 
    
         
            +
             
     | 
| 
      
 1019 
     | 
    
         
            +
                  def assume_migrated_upto_version(version, migrations_paths)
         
     | 
| 
       840 
1020 
     | 
    
         
             
                    migrations_paths = Array(migrations_paths)
         
     | 
| 
       841 
1021 
     | 
    
         
             
                    version = version.to_i
         
     | 
| 
       842 
1022 
     | 
    
         
             
                    sm_table = quote_table_name(ActiveRecord::Migrator.schema_migrations_table_name)
         
     | 
| 
         @@ -847,22 +1027,27 @@ module ActiveRecord 
     | 
|
| 
       847 
1027 
     | 
    
         
             
                    end
         
     | 
| 
       848 
1028 
     | 
    
         | 
| 
       849 
1029 
     | 
    
         
             
                    unless migrated.include?(version)
         
     | 
| 
       850 
     | 
    
         
            -
                      execute "INSERT INTO #{sm_table} (version) VALUES ( 
     | 
| 
      
 1030 
     | 
    
         
            +
                      execute "INSERT INTO #{sm_table} (version) VALUES (#{quote(version)})"
         
     | 
| 
       851 
1031 
     | 
    
         
             
                    end
         
     | 
| 
       852 
1032 
     | 
    
         | 
| 
       853 
     | 
    
         
            -
                     
     | 
| 
       854 
     | 
    
         
            -
                     
     | 
| 
       855 
     | 
    
         
            -
                      if  
     | 
| 
       856 
     | 
    
         
            -
                        raise "Duplicate migration #{ 
     | 
| 
       857 
     | 
    
         
            -
                       
     | 
| 
       858 
     | 
    
         
            -
             
     | 
| 
       859 
     | 
    
         
            -
                         
     | 
| 
      
 1033 
     | 
    
         
            +
                    inserting = (versions - migrated).select {|v| v < version}
         
     | 
| 
      
 1034 
     | 
    
         
            +
                    if inserting.any?
         
     | 
| 
      
 1035 
     | 
    
         
            +
                      if (duplicate = inserting.detect {|v| inserting.count(v) > 1})
         
     | 
| 
      
 1036 
     | 
    
         
            +
                        raise "Duplicate migration #{duplicate}. Please renumber your migrations to resolve the conflict."
         
     | 
| 
      
 1037 
     | 
    
         
            +
                      end
         
     | 
| 
      
 1038 
     | 
    
         
            +
                      if supports_multi_insert?
         
     | 
| 
      
 1039 
     | 
    
         
            +
                        execute insert_versions_sql(inserting)
         
     | 
| 
      
 1040 
     | 
    
         
            +
                      else
         
     | 
| 
      
 1041 
     | 
    
         
            +
                        inserting.each do |v|
         
     | 
| 
      
 1042 
     | 
    
         
            +
                          execute insert_versions_sql(v)
         
     | 
| 
      
 1043 
     | 
    
         
            +
                        end
         
     | 
| 
       860 
1044 
     | 
    
         
             
                      end
         
     | 
| 
       861 
1045 
     | 
    
         
             
                    end
         
     | 
| 
       862 
1046 
     | 
    
         
             
                  end
         
     | 
| 
       863 
1047 
     | 
    
         | 
| 
       864 
1048 
     | 
    
         
             
                  def type_to_sql(type, limit = nil, precision = nil, scale = nil) #:nodoc:
         
     | 
| 
       865 
     | 
    
         
            -
                     
     | 
| 
      
 1049 
     | 
    
         
            +
                    type = type.to_sym if type
         
     | 
| 
      
 1050 
     | 
    
         
            +
                    if native = native_database_types[type]
         
     | 
| 
       866 
1051 
     | 
    
         
             
                      column_type_sql = (native.is_a?(Hash) ? native[:name] : native).dup
         
     | 
| 
       867 
1052 
     | 
    
         | 
| 
       868 
1053 
     | 
    
         
             
                      if type == :decimal # ignore limit, use precision and scale
         
     | 
| 
         @@ -878,6 +1063,12 @@ module ActiveRecord 
     | 
|
| 
       878 
1063 
     | 
    
         
             
                          raise ArgumentError, "Error adding decimal column: precision cannot be empty if scale is specified"
         
     | 
| 
       879 
1064 
     | 
    
         
             
                        end
         
     | 
| 
       880 
1065 
     | 
    
         | 
| 
      
 1066 
     | 
    
         
            +
                      elsif [:datetime, :time].include?(type) && precision ||= native[:precision]
         
     | 
| 
      
 1067 
     | 
    
         
            +
                        if (0..6) === precision
         
     | 
| 
      
 1068 
     | 
    
         
            +
                          column_type_sql << "(#{precision})"
         
     | 
| 
      
 1069 
     | 
    
         
            +
                        else
         
     | 
| 
      
 1070 
     | 
    
         
            +
                          raise(ActiveRecordError, "No #{native[:name]} type has precision of #{precision}. The allowed range of precision is from 0 to 6")
         
     | 
| 
      
 1071 
     | 
    
         
            +
                        end
         
     | 
| 
       881 
1072 
     | 
    
         
             
                      elsif (type != :primary_key) && (limit ||= native.is_a?(Hash) && native[:limit])
         
     | 
| 
       882 
1073 
     | 
    
         
             
                        column_type_sql << "(#{limit})"
         
     | 
| 
       883 
1074 
     | 
    
         
             
                      end
         
     | 
| 
         @@ -898,14 +1089,14 @@ module ActiveRecord 
     | 
|
| 
       898 
1089 
     | 
    
         
             
                    columns
         
     | 
| 
       899 
1090 
     | 
    
         
             
                  end
         
     | 
| 
       900 
1091 
     | 
    
         | 
| 
       901 
     | 
    
         
            -
                  include TimestampDefaultDeprecation
         
     | 
| 
       902 
1092 
     | 
    
         
             
                  # Adds timestamps (+created_at+ and +updated_at+) columns to +table_name+.
         
     | 
| 
       903 
     | 
    
         
            -
                  # Additional options (like  
     | 
| 
      
 1093 
     | 
    
         
            +
                  # Additional options (like +:null+) are forwarded to #add_column.
         
     | 
| 
       904 
1094 
     | 
    
         
             
                  #
         
     | 
| 
       905 
     | 
    
         
            -
                  #   add_timestamps(:suppliers, null:  
     | 
| 
      
 1095 
     | 
    
         
            +
                  #   add_timestamps(:suppliers, null: true)
         
     | 
| 
       906 
1096 
     | 
    
         
             
                  #
         
     | 
| 
       907 
1097 
     | 
    
         
             
                  def add_timestamps(table_name, options = {})
         
     | 
| 
       908 
     | 
    
         
            -
                     
     | 
| 
      
 1098 
     | 
    
         
            +
                    options[:null] = false if options[:null].nil?
         
     | 
| 
      
 1099 
     | 
    
         
            +
             
     | 
| 
       909 
1100 
     | 
    
         
             
                    add_column table_name, :created_at, :datetime, options
         
     | 
| 
       910 
1101 
     | 
    
         
             
                    add_column table_name, :updated_at, :datetime, options
         
     | 
| 
       911 
1102 
     | 
    
         
             
                  end
         
     | 
| 
         @@ -923,15 +1114,15 @@ module ActiveRecord 
     | 
|
| 
       923 
1114 
     | 
    
         
             
                    Table.new(table_name, base)
         
     | 
| 
       924 
1115 
     | 
    
         
             
                  end
         
     | 
| 
       925 
1116 
     | 
    
         | 
| 
       926 
     | 
    
         
            -
                  def add_index_options(table_name, column_name,  
     | 
| 
       927 
     | 
    
         
            -
                    column_names =  
     | 
| 
       928 
     | 
    
         
            -
                    index_name   = index_name(table_name, column: column_names)
         
     | 
| 
      
 1117 
     | 
    
         
            +
                  def add_index_options(table_name, column_name, comment: nil, **options) # :nodoc:
         
     | 
| 
      
 1118 
     | 
    
         
            +
                    column_names = index_column_names(column_name)
         
     | 
| 
       929 
1119 
     | 
    
         | 
| 
       930 
1120 
     | 
    
         
             
                    options.assert_valid_keys(:unique, :order, :name, :where, :length, :internal, :using, :algorithm, :type)
         
     | 
| 
       931 
1121 
     | 
    
         | 
| 
       932 
     | 
    
         
            -
                    index_type = options[:unique] ? "UNIQUE" : ""
         
     | 
| 
       933 
1122 
     | 
    
         
             
                    index_type = options[:type].to_s if options.key?(:type)
         
     | 
| 
      
 1123 
     | 
    
         
            +
                    index_type ||= options[:unique] ? "UNIQUE" : ""
         
     | 
| 
       934 
1124 
     | 
    
         
             
                    index_name = options[:name].to_s if options.key?(:name)
         
     | 
| 
      
 1125 
     | 
    
         
            +
                    index_name ||= index_name(table_name, column_names)
         
     | 
| 
       935 
1126 
     | 
    
         
             
                    max_index_length = options.fetch(:internal, false) ? index_name_length : allowed_index_name_length
         
     | 
| 
       936 
1127 
     | 
    
         | 
| 
       937 
1128 
     | 
    
         
             
                    if options.key?(:algorithm)
         
     | 
| 
         @@ -949,60 +1140,92 @@ module ActiveRecord 
     | 
|
| 
       949 
1140 
     | 
    
         
             
                    if index_name.length > max_index_length
         
     | 
| 
       950 
1141 
     | 
    
         
             
                      raise ArgumentError, "Index name '#{index_name}' on table '#{table_name}' is too long; the limit is #{max_index_length} characters"
         
     | 
| 
       951 
1142 
     | 
    
         
             
                    end
         
     | 
| 
       952 
     | 
    
         
            -
                    if  
     | 
| 
      
 1143 
     | 
    
         
            +
                    if data_source_exists?(table_name) && index_name_exists?(table_name, index_name, false)
         
     | 
| 
       953 
1144 
     | 
    
         
             
                      raise ArgumentError, "Index name '#{index_name}' on table '#{table_name}' already exists"
         
     | 
| 
       954 
1145 
     | 
    
         
             
                    end
         
     | 
| 
       955 
1146 
     | 
    
         
             
                    index_columns = quoted_columns_for_index(column_names, options).join(", ")
         
     | 
| 
       956 
1147 
     | 
    
         | 
| 
       957 
     | 
    
         
            -
                    [index_name, index_type, index_columns, index_options, algorithm, using]
         
     | 
| 
      
 1148 
     | 
    
         
            +
                    [index_name, index_type, index_columns, index_options, algorithm, using, comment]
         
     | 
| 
      
 1149 
     | 
    
         
            +
                  end
         
     | 
| 
      
 1150 
     | 
    
         
            +
             
     | 
| 
      
 1151 
     | 
    
         
            +
                  def options_include_default?(options)
         
     | 
| 
      
 1152 
     | 
    
         
            +
                    options.include?(:default) && !(options[:null] == false && options[:default].nil?)
         
     | 
| 
      
 1153 
     | 
    
         
            +
                  end
         
     | 
| 
      
 1154 
     | 
    
         
            +
             
     | 
| 
      
 1155 
     | 
    
         
            +
                  # Changes the comment for a table or removes it if +nil+.
         
     | 
| 
      
 1156 
     | 
    
         
            +
                  def change_table_comment(table_name, comment)
         
     | 
| 
      
 1157 
     | 
    
         
            +
                    raise NotImplementedError, "#{self.class} does not support changing table comments"
         
     | 
| 
      
 1158 
     | 
    
         
            +
                  end
         
     | 
| 
      
 1159 
     | 
    
         
            +
             
     | 
| 
      
 1160 
     | 
    
         
            +
                  # Changes the comment for a column or removes it if +nil+.
         
     | 
| 
      
 1161 
     | 
    
         
            +
                  def change_column_comment(table_name, column_name, comment) #:nodoc:
         
     | 
| 
      
 1162 
     | 
    
         
            +
                    raise NotImplementedError, "#{self.class} does not support changing column comments"
         
     | 
| 
       958 
1163 
     | 
    
         
             
                  end
         
     | 
| 
       959 
1164 
     | 
    
         | 
| 
       960 
1165 
     | 
    
         
             
                  protected
         
     | 
| 
       961 
     | 
    
         
            -
             
     | 
| 
       962 
     | 
    
         
            -
             
     | 
| 
      
 1166 
     | 
    
         
            +
             
     | 
| 
      
 1167 
     | 
    
         
            +
                    def add_index_sort_order(quoted_columns, **options)
         
     | 
| 
      
 1168 
     | 
    
         
            +
                      if order = options[:order]
         
     | 
| 
       963 
1169 
     | 
    
         
             
                        case order
         
     | 
| 
       964 
1170 
     | 
    
         
             
                        when Hash
         
     | 
| 
       965 
     | 
    
         
            -
                           
     | 
| 
      
 1171 
     | 
    
         
            +
                          order = order.symbolize_keys
         
     | 
| 
      
 1172 
     | 
    
         
            +
                          quoted_columns.each { |name, column| column << " #{order[name].upcase}" if order[name].present? }
         
     | 
| 
       966 
1173 
     | 
    
         
             
                        when String
         
     | 
| 
       967 
     | 
    
         
            -
                           
     | 
| 
      
 1174 
     | 
    
         
            +
                          quoted_columns.each { |name, column| column << " #{order.upcase}" if order.present? }
         
     | 
| 
       968 
1175 
     | 
    
         
             
                        end
         
     | 
| 
       969 
1176 
     | 
    
         
             
                      end
         
     | 
| 
       970 
1177 
     | 
    
         | 
| 
       971 
     | 
    
         
            -
                       
     | 
| 
      
 1178 
     | 
    
         
            +
                      quoted_columns
         
     | 
| 
       972 
1179 
     | 
    
         
             
                    end
         
     | 
| 
       973 
1180 
     | 
    
         | 
| 
       974 
1181 
     | 
    
         
             
                    # Overridden by the MySQL adapter for supporting index lengths
         
     | 
| 
       975 
     | 
    
         
            -
                    def  
     | 
| 
       976 
     | 
    
         
            -
                      option_strings = Hash[column_names.map {|name| [name, '']}]
         
     | 
| 
       977 
     | 
    
         
            -
             
     | 
| 
       978 
     | 
    
         
            -
                      # add index sort order if supported
         
     | 
| 
      
 1182 
     | 
    
         
            +
                    def add_options_for_index_columns(quoted_columns, **options)
         
     | 
| 
       979 
1183 
     | 
    
         
             
                      if supports_index_sort_order?
         
     | 
| 
       980 
     | 
    
         
            -
                         
     | 
| 
      
 1184 
     | 
    
         
            +
                        quoted_columns = add_index_sort_order(quoted_columns, options)
         
     | 
| 
       981 
1185 
     | 
    
         
             
                      end
         
     | 
| 
       982 
1186 
     | 
    
         | 
| 
       983 
     | 
    
         
            -
                       
     | 
| 
      
 1187 
     | 
    
         
            +
                      quoted_columns
         
     | 
| 
       984 
1188 
     | 
    
         
             
                    end
         
     | 
| 
       985 
1189 
     | 
    
         | 
| 
       986 
     | 
    
         
            -
                    def  
     | 
| 
       987 
     | 
    
         
            -
                       
     | 
| 
      
 1190 
     | 
    
         
            +
                    def quoted_columns_for_index(column_names, **options)
         
     | 
| 
      
 1191 
     | 
    
         
            +
                      return [column_names] if column_names.is_a?(String)
         
     | 
| 
      
 1192 
     | 
    
         
            +
             
     | 
| 
      
 1193 
     | 
    
         
            +
                      quoted_columns = Hash[column_names.map { |name| [name.to_sym, quote_column_name(name).dup] }]
         
     | 
| 
      
 1194 
     | 
    
         
            +
                      add_options_for_index_columns(quoted_columns, options).values
         
     | 
| 
       988 
1195 
     | 
    
         
             
                    end
         
     | 
| 
       989 
1196 
     | 
    
         | 
| 
       990 
1197 
     | 
    
         
             
                    def index_name_for_remove(table_name, options = {})
         
     | 
| 
       991 
     | 
    
         
            -
                       
     | 
| 
      
 1198 
     | 
    
         
            +
                      return options[:name] if can_remove_index_by_name?(options)
         
     | 
| 
       992 
1199 
     | 
    
         | 
| 
       993 
     | 
    
         
            -
                       
     | 
| 
       994 
     | 
    
         
            -
             
     | 
| 
       995 
     | 
    
         
            -
             
     | 
| 
       996 
     | 
    
         
            -
                          options_without_column.delete :column
         
     | 
| 
       997 
     | 
    
         
            -
                          index_name_without_column = index_name(table_name, options_without_column)
         
     | 
| 
      
 1200 
     | 
    
         
            +
                      # if the adapter doesn't support the indexes call the best we can do
         
     | 
| 
      
 1201 
     | 
    
         
            +
                      # is return the default index name for the options provided
         
     | 
| 
      
 1202 
     | 
    
         
            +
                      return index_name(table_name, options) unless respond_to?(:indexes)
         
     | 
| 
       998 
1203 
     | 
    
         | 
| 
       999 
     | 
    
         
            -
             
     | 
| 
       1000 
     | 
    
         
            -
                        end
         
     | 
| 
      
 1204 
     | 
    
         
            +
                      checks = []
         
     | 
| 
       1001 
1205 
     | 
    
         | 
| 
       1002 
     | 
    
         
            -
             
     | 
| 
      
 1206 
     | 
    
         
            +
                      if options.is_a?(Hash)
         
     | 
| 
      
 1207 
     | 
    
         
            +
                        checks << lambda { |i| i.name == options[:name].to_s } if options.key?(:name)
         
     | 
| 
      
 1208 
     | 
    
         
            +
                        column_names = index_column_names(options[:column])
         
     | 
| 
      
 1209 
     | 
    
         
            +
                      else
         
     | 
| 
      
 1210 
     | 
    
         
            +
                        column_names = index_column_names(options)
         
     | 
| 
      
 1211 
     | 
    
         
            +
                      end
         
     | 
| 
      
 1212 
     | 
    
         
            +
             
     | 
| 
      
 1213 
     | 
    
         
            +
                      if column_names.present?
         
     | 
| 
      
 1214 
     | 
    
         
            +
                        checks << lambda { |i| index_name(table_name, i.columns) == index_name(table_name, column_names) }
         
     | 
| 
       1003 
1215 
     | 
    
         
             
                      end
         
     | 
| 
       1004 
1216 
     | 
    
         | 
| 
       1005 
     | 
    
         
            -
                       
     | 
| 
      
 1217 
     | 
    
         
            +
                      raise ArgumentError, "No name or columns specified" if checks.none?
         
     | 
| 
      
 1218 
     | 
    
         
            +
             
     | 
| 
      
 1219 
     | 
    
         
            +
                      matching_indexes = indexes(table_name).select { |i| checks.all? { |check| check[i] } }
         
     | 
| 
      
 1220 
     | 
    
         
            +
             
     | 
| 
      
 1221 
     | 
    
         
            +
                      if matching_indexes.count > 1
         
     | 
| 
      
 1222 
     | 
    
         
            +
                        raise ArgumentError, "Multiple indexes found on #{table_name} columns #{column_names}. " \
         
     | 
| 
      
 1223 
     | 
    
         
            +
                                             "Specify an index name from #{matching_indexes.map(&:name).join(', ')}"
         
     | 
| 
      
 1224 
     | 
    
         
            +
                      elsif matching_indexes.none?
         
     | 
| 
      
 1225 
     | 
    
         
            +
                        raise ArgumentError, "No indexes found on #{table_name} with the options provided."
         
     | 
| 
      
 1226 
     | 
    
         
            +
                      else
         
     | 
| 
      
 1227 
     | 
    
         
            +
                        matching_indexes.first.name
         
     | 
| 
      
 1228 
     | 
    
         
            +
                      end
         
     | 
| 
       1006 
1229 
     | 
    
         
             
                    end
         
     | 
| 
       1007 
1230 
     | 
    
         | 
| 
       1008 
1231 
     | 
    
         
             
                    def rename_table_indexes(table_name, new_name)
         
     | 
| 
         @@ -1028,12 +1251,28 @@ module ActiveRecord 
     | 
|
| 
       1028 
1251 
     | 
    
         
             
                    end
         
     | 
| 
       1029 
1252 
     | 
    
         | 
| 
       1030 
1253 
     | 
    
         
             
                  private
         
     | 
| 
       1031 
     | 
    
         
            -
                  def create_table_definition( 
     | 
| 
       1032 
     | 
    
         
            -
                    TableDefinition.new 
     | 
| 
      
 1254 
     | 
    
         
            +
                  def create_table_definition(*args)
         
     | 
| 
      
 1255 
     | 
    
         
            +
                    TableDefinition.new(*args)
         
     | 
| 
       1033 
1256 
     | 
    
         
             
                  end
         
     | 
| 
       1034 
1257 
     | 
    
         | 
| 
       1035 
1258 
     | 
    
         
             
                  def create_alter_table(name)
         
     | 
| 
       1036 
     | 
    
         
            -
                    AlterTable.new create_table_definition(name 
     | 
| 
      
 1259 
     | 
    
         
            +
                    AlterTable.new create_table_definition(name)
         
     | 
| 
      
 1260 
     | 
    
         
            +
                  end
         
     | 
| 
      
 1261 
     | 
    
         
            +
             
     | 
| 
      
 1262 
     | 
    
         
            +
                  def index_column_names(column_names)
         
     | 
| 
      
 1263 
     | 
    
         
            +
                    if column_names.is_a?(String) && /\W/ === column_names
         
     | 
| 
      
 1264 
     | 
    
         
            +
                      column_names
         
     | 
| 
      
 1265 
     | 
    
         
            +
                    else
         
     | 
| 
      
 1266 
     | 
    
         
            +
                      Array(column_names)
         
     | 
| 
      
 1267 
     | 
    
         
            +
                    end
         
     | 
| 
      
 1268 
     | 
    
         
            +
                  end
         
     | 
| 
      
 1269 
     | 
    
         
            +
             
     | 
| 
      
 1270 
     | 
    
         
            +
                  def index_name_options(column_names) # :nodoc:
         
     | 
| 
      
 1271 
     | 
    
         
            +
                    if column_names.is_a?(String) && /\W/ === column_names
         
     | 
| 
      
 1272 
     | 
    
         
            +
                      column_names = column_names.scan(/\w+/).join('_')
         
     | 
| 
      
 1273 
     | 
    
         
            +
                    end
         
     | 
| 
      
 1274 
     | 
    
         
            +
             
     | 
| 
      
 1275 
     | 
    
         
            +
                    { column: column_names }
         
     | 
| 
       1037 
1276 
     | 
    
         
             
                  end
         
     | 
| 
       1038 
1277 
     | 
    
         | 
| 
       1039 
1278 
     | 
    
         
             
                  def foreign_key_name(table_name, options) # :nodoc:
         
     | 
| 
         @@ -1044,11 +1283,23 @@ module ActiveRecord 
     | 
|
| 
       1044 
1283 
     | 
    
         
             
                    end
         
     | 
| 
       1045 
1284 
     | 
    
         
             
                  end
         
     | 
| 
       1046 
1285 
     | 
    
         | 
| 
       1047 
     | 
    
         
            -
                  def validate_index_length!(table_name, new_name)
         
     | 
| 
      
 1286 
     | 
    
         
            +
                  def validate_index_length!(table_name, new_name) # :nodoc:
         
     | 
| 
       1048 
1287 
     | 
    
         
             
                    if new_name.length > allowed_index_name_length
         
     | 
| 
       1049 
1288 
     | 
    
         
             
                      raise ArgumentError, "Index name '#{new_name}' on table '#{table_name}' is too long; the limit is #{allowed_index_name_length} characters"
         
     | 
| 
       1050 
1289 
     | 
    
         
             
                    end
         
     | 
| 
       1051 
1290 
     | 
    
         
             
                  end
         
     | 
| 
      
 1291 
     | 
    
         
            +
             
     | 
| 
      
 1292 
     | 
    
         
            +
                  def extract_new_default_value(default_or_changes)
         
     | 
| 
      
 1293 
     | 
    
         
            +
                    if default_or_changes.is_a?(Hash) && default_or_changes.has_key?(:from) && default_or_changes.has_key?(:to)
         
     | 
| 
      
 1294 
     | 
    
         
            +
                      default_or_changes[:to]
         
     | 
| 
      
 1295 
     | 
    
         
            +
                    else
         
     | 
| 
      
 1296 
     | 
    
         
            +
                      default_or_changes
         
     | 
| 
      
 1297 
     | 
    
         
            +
                    end
         
     | 
| 
      
 1298 
     | 
    
         
            +
                  end
         
     | 
| 
      
 1299 
     | 
    
         
            +
             
     | 
| 
      
 1300 
     | 
    
         
            +
                  def can_remove_index_by_name?(options)
         
     | 
| 
      
 1301 
     | 
    
         
            +
                    options.is_a?(Hash) && options.key?(:name) && options.except(:name, :algorithm).empty?
         
     | 
| 
      
 1302 
     | 
    
         
            +
                  end
         
     | 
| 
       1052 
1303 
     | 
    
         
             
                end
         
     | 
| 
       1053 
1304 
     | 
    
         
             
              end
         
     | 
| 
       1054 
1305 
     | 
    
         
             
            end
         
     |