activerecord 6.0.0.rc1 → 6.0.0.rc2
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 +39 -0
- data/lib/active_record/associations/builder/collection_association.rb +2 -2
- data/lib/active_record/associations/collection_proxy.rb +1 -1
- data/lib/active_record/associations/join_dependency.rb +10 -9
- data/lib/active_record/associations/join_dependency/join_association.rb +11 -2
- data/lib/active_record/associations/preloader/association.rb +3 -1
- data/lib/active_record/attribute_methods.rb +0 -51
- data/lib/active_record/attribute_methods/dirty.rb +6 -1
- data/lib/active_record/autosave_association.rb +1 -1
- data/lib/active_record/connection_adapters/abstract/connection_pool.rb +93 -11
- data/lib/active_record/connection_adapters/abstract/query_cache.rb +3 -3
- data/lib/active_record/connection_adapters/abstract/quoting.rb +53 -0
- data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +1 -1
- data/lib/active_record/connection_adapters/abstract/schema_statements.rb +8 -7
- data/lib/active_record/connection_adapters/abstract/transaction.rb +12 -4
- data/lib/active_record/connection_adapters/abstract_adapter.rb +40 -20
- data/lib/active_record/connection_adapters/determine_if_preparable_visitor.rb +2 -2
- data/lib/active_record/connection_adapters/mysql/quoting.rb +44 -7
- data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +3 -1
- data/lib/active_record/connection_adapters/mysql2_adapter.rb +10 -1
- data/lib/active_record/connection_adapters/postgresql/quoting.rb +39 -2
- data/lib/active_record/connection_adapters/postgresql_adapter.rb +8 -1
- data/lib/active_record/connection_adapters/sqlite3/quoting.rb +38 -2
- data/lib/active_record/connection_adapters/sqlite3_adapter.rb +12 -2
- data/lib/active_record/connection_handling.rb +6 -2
- data/lib/active_record/database_configurations.rb +6 -6
- data/lib/active_record/gem_version.rb +1 -1
- data/lib/active_record/middleware/database_selector.rb +3 -3
- data/lib/active_record/middleware/database_selector/resolver.rb +2 -2
- data/lib/active_record/migration.rb +26 -23
- data/lib/active_record/railtie.rb +0 -1
- data/lib/active_record/railties/databases.rake +57 -23
- data/lib/active_record/reflection.rb +1 -1
- data/lib/active_record/relation/calculations.rb +1 -1
- data/lib/active_record/relation/finder_methods.rb +4 -2
- data/lib/active_record/relation/merger.rb +6 -2
- data/lib/active_record/relation/query_methods.rb +32 -32
- data/lib/active_record/sanitization.rb +30 -2
- data/lib/active_record/schema.rb +1 -1
- data/lib/active_record/schema_dumper.rb +5 -1
- data/lib/active_record/table_metadata.rb +6 -10
- data/lib/active_record/tasks/database_tasks.rb +41 -8
- data/lib/active_record/tasks/mysql_database_tasks.rb +3 -1
- data/lib/active_record/timestamp.rb +26 -16
- data/lib/active_record/touch_later.rb +2 -0
- data/lib/active_record/transactions.rb +9 -10
- data/lib/active_record/type_caster/connection.rb +16 -10
- data/lib/arel/visitors/depth_first.rb +1 -1
- data/lib/arel/visitors/to_sql.rb +23 -26
- data/lib/arel/visitors/visitor.rb +9 -5
- metadata +8 -8
| @@ -477,7 +477,7 @@ module ActiveRecord | |
| 477 477 | 
             
                  def check_preloadable!
         | 
| 478 478 | 
             
                    return unless scope
         | 
| 479 479 |  | 
| 480 | 
            -
                     | 
| 480 | 
            +
                    unless scope.arity == 0
         | 
| 481 481 | 
             
                      raise ArgumentError, <<-MSG.squish
         | 
| 482 482 | 
             
                        The association scope '#{name}' is instance dependent (the scope
         | 
| 483 483 | 
             
                        block takes an argument). Preloading instance dependent scopes is
         | 
| @@ -340,7 +340,7 @@ module ActiveRecord | |
| 340 340 | 
             
                    }
         | 
| 341 341 |  | 
| 342 342 | 
             
                    relation = except(:group).distinct!(false)
         | 
| 343 | 
            -
                    relation.group_values  =  | 
| 343 | 
            +
                    relation.group_values  = group_fields
         | 
| 344 344 | 
             
                    relation.select_values = select_values
         | 
| 345 345 |  | 
| 346 346 | 
             
                    calculated_data = skip_query_cache_if_necessary { @klass.connection.select_all(relation.arel, nil) }
         | 
| @@ -355,7 +355,7 @@ module ActiveRecord | |
| 355 355 | 
             
                    conditions = sanitize_forbidden_attributes(conditions)
         | 
| 356 356 |  | 
| 357 357 | 
             
                    if distinct_value && offset_value
         | 
| 358 | 
            -
                      relation = limit(1)
         | 
| 358 | 
            +
                      relation = except(:order).limit!(1)
         | 
| 359 359 | 
             
                    else
         | 
| 360 360 | 
             
                      relation = except(:select, :distinct, :order)._select!(ONE_AS_ONE).limit!(1)
         | 
| 361 361 | 
             
                    end
         | 
| @@ -371,7 +371,9 @@ module ActiveRecord | |
| 371 371 | 
             
                  end
         | 
| 372 372 |  | 
| 373 373 | 
             
                  def apply_join_dependency(eager_loading: group_values.empty?)
         | 
| 374 | 
            -
                    join_dependency = construct_join_dependency( | 
| 374 | 
            +
                    join_dependency = construct_join_dependency(
         | 
| 375 | 
            +
                      eager_load_values + includes_values, Arel::Nodes::OuterJoin
         | 
| 376 | 
            +
                    )
         | 
| 375 377 | 
             
                    relation = except(:includes, :eager_load, :preload).joins!(join_dependency)
         | 
| 376 378 |  | 
| 377 379 | 
             
                    if eager_loading && !using_limitable_reflections?(join_dependency.reflections)
         | 
| @@ -123,7 +123,9 @@ module ActiveRecord | |
| 123 123 | 
             
                          end
         | 
| 124 124 | 
             
                        end
         | 
| 125 125 |  | 
| 126 | 
            -
                        join_dependency = other.construct_join_dependency( | 
| 126 | 
            +
                        join_dependency = other.construct_join_dependency(
         | 
| 127 | 
            +
                          associations, Arel::Nodes::InnerJoin
         | 
| 128 | 
            +
                        )
         | 
| 127 129 | 
             
                        relation.joins!(join_dependency, *others)
         | 
| 128 130 | 
             
                      end
         | 
| 129 131 | 
             
                    end
         | 
| @@ -135,7 +137,9 @@ module ActiveRecord | |
| 135 137 | 
             
                        relation.left_outer_joins!(*other.left_outer_joins_values)
         | 
| 136 138 | 
             
                      else
         | 
| 137 139 | 
             
                        associations = other.left_outer_joins_values
         | 
| 138 | 
            -
                        join_dependency = other.construct_join_dependency( | 
| 140 | 
            +
                        join_dependency = other.construct_join_dependency(
         | 
| 141 | 
            +
                          associations, Arel::Nodes::OuterJoin
         | 
| 142 | 
            +
                        )
         | 
| 139 143 | 
             
                        relation.joins!(join_dependency)
         | 
| 140 144 | 
             
                      end
         | 
| 141 145 | 
             
                    end
         | 
| @@ -952,7 +952,7 @@ module ActiveRecord | |
| 952 952 | 
             
                def optimizer_hints!(*args) # :nodoc:
         | 
| 953 953 | 
             
                  args.flatten!
         | 
| 954 954 |  | 
| 955 | 
            -
                  self.optimizer_hints_values  | 
| 955 | 
            +
                  self.optimizer_hints_values |= args
         | 
| 956 956 | 
             
                  self
         | 
| 957 957 | 
             
                end
         | 
| 958 958 |  | 
| @@ -1005,9 +1005,9 @@ module ActiveRecord | |
| 1005 1005 | 
             
                  @arel ||= build_arel(aliases)
         | 
| 1006 1006 | 
             
                end
         | 
| 1007 1007 |  | 
| 1008 | 
            -
                def construct_join_dependency(associations) # :nodoc:
         | 
| 1008 | 
            +
                def construct_join_dependency(associations, join_type) # :nodoc:
         | 
| 1009 1009 | 
             
                  ActiveRecord::Associations::JoinDependency.new(
         | 
| 1010 | 
            -
                    klass, table, associations
         | 
| 1010 | 
            +
                    klass, table, associations, join_type
         | 
| 1011 1011 | 
             
                  )
         | 
| 1012 1012 | 
             
                end
         | 
| 1013 1013 |  | 
| @@ -1102,7 +1102,7 @@ module ActiveRecord | |
| 1102 1102 | 
             
                  def build_joins(manager, joins, aliases)
         | 
| 1103 1103 | 
             
                    unless left_outer_joins_values.empty?
         | 
| 1104 1104 | 
             
                      left_joins = valid_association_list(left_outer_joins_values.flatten)
         | 
| 1105 | 
            -
                      joins  | 
| 1105 | 
            +
                      joins.unshift construct_join_dependency(left_joins, Arel::Nodes::OuterJoin)
         | 
| 1106 1106 | 
             
                    end
         | 
| 1107 1107 |  | 
| 1108 1108 | 
             
                    buckets = joins.group_by do |join|
         | 
| @@ -1128,27 +1128,21 @@ module ActiveRecord | |
| 1128 1128 |  | 
| 1129 1129 | 
             
                    association_joins = buckets[:association_join]
         | 
| 1130 1130 | 
             
                    stashed_joins     = buckets[:stashed_join]
         | 
| 1131 | 
            -
                    join_nodes        = buckets[:join_node].uniq
         | 
| 1132 | 
            -
                    string_joins      = buckets[:string_join].map(&:strip).uniq
         | 
| 1131 | 
            +
                    join_nodes        = buckets[:join_node].tap(&:uniq!)
         | 
| 1132 | 
            +
                    string_joins      = buckets[:string_join].delete_if(&:blank?).map!(&:strip).tap(&:uniq!)
         | 
| 1133 1133 |  | 
| 1134 | 
            -
                     | 
| 1135 | 
            -
                    alias_tracker = alias_tracker(join_list, aliases)
         | 
| 1134 | 
            +
                    string_joins.map! { |join| table.create_string_join(Arel.sql(join)) }
         | 
| 1136 1135 |  | 
| 1137 | 
            -
                     | 
| 1136 | 
            +
                    join_sources = manager.join_sources
         | 
| 1137 | 
            +
                    join_sources.concat(join_nodes) unless join_nodes.empty?
         | 
| 1138 1138 |  | 
| 1139 | 
            -
                     | 
| 1140 | 
            -
             | 
| 1141 | 
            -
             | 
| 1142 | 
            -
             | 
| 1143 | 
            -
             | 
| 1144 | 
            -
                    alias_tracker.aliases
         | 
| 1145 | 
            -
                  end
         | 
| 1139 | 
            +
                    unless association_joins.empty? && stashed_joins.empty?
         | 
| 1140 | 
            +
                      alias_tracker = alias_tracker(join_nodes + string_joins, aliases)
         | 
| 1141 | 
            +
                      join_dependency = construct_join_dependency(association_joins, join_type)
         | 
| 1142 | 
            +
                      join_sources.concat(join_dependency.join_constraints(stashed_joins, alias_tracker))
         | 
| 1143 | 
            +
                    end
         | 
| 1146 1144 |  | 
| 1147 | 
            -
             | 
| 1148 | 
            -
                    joins
         | 
| 1149 | 
            -
                      .flatten
         | 
| 1150 | 
            -
                      .reject(&:blank?)
         | 
| 1151 | 
            -
                      .map { |join| table.create_string_join(Arel.sql(join)) }
         | 
| 1145 | 
            +
                    join_sources.concat(string_joins) unless string_joins.empty?
         | 
| 1152 1146 | 
             
                  end
         | 
| 1153 1147 |  | 
| 1154 1148 | 
             
                  def build_select(arel)
         | 
| @@ -1165,8 +1159,9 @@ module ActiveRecord | |
| 1165 1159 | 
             
                    columns.flat_map do |field|
         | 
| 1166 1160 | 
             
                      case field
         | 
| 1167 1161 | 
             
                      when Symbol
         | 
| 1168 | 
            -
                        field  | 
| 1169 | 
            -
             | 
| 1162 | 
            +
                        arel_column(field.to_s) do |attr_name|
         | 
| 1163 | 
            +
                          connection.quote_table_name(attr_name)
         | 
| 1164 | 
            +
                        end
         | 
| 1170 1165 | 
             
                      when String
         | 
| 1171 1166 | 
             
                        arel_column(field, &:itself)
         | 
| 1172 1167 | 
             
                      when Proc
         | 
| @@ -1253,6 +1248,7 @@ module ActiveRecord | |
| 1253 1248 | 
             
                  end
         | 
| 1254 1249 |  | 
| 1255 1250 | 
             
                  def preprocess_order_args(order_args)
         | 
| 1251 | 
            +
                    order_args.reject!(&:blank?)
         | 
| 1256 1252 | 
             
                    order_args.map! do |arg|
         | 
| 1257 1253 | 
             
                      klass.sanitize_sql_for_order(arg)
         | 
| 1258 1254 | 
             
                    end
         | 
| @@ -1260,7 +1256,7 @@ module ActiveRecord | |
| 1260 1256 |  | 
| 1261 1257 | 
             
                    @klass.disallow_raw_sql!(
         | 
| 1262 1258 | 
             
                      order_args.flat_map { |a| a.is_a?(Hash) ? a.keys : a },
         | 
| 1263 | 
            -
                      permit:  | 
| 1259 | 
            +
                      permit: connection.column_name_with_order_matcher
         | 
| 1264 1260 | 
             
                    )
         | 
| 1265 1261 |  | 
| 1266 1262 | 
             
                    validate_order_args(order_args)
         | 
| @@ -1273,20 +1269,14 @@ module ActiveRecord | |
| 1273 1269 | 
             
                    order_args.map! do |arg|
         | 
| 1274 1270 | 
             
                      case arg
         | 
| 1275 1271 | 
             
                      when Symbol
         | 
| 1276 | 
            -
                        arg | 
| 1277 | 
            -
                        arel_column(arg) {
         | 
| 1278 | 
            -
                          Arel.sql(connection.quote_table_name(arg))
         | 
| 1279 | 
            -
                        }.asc
         | 
| 1272 | 
            +
                        order_column(arg.to_s).asc
         | 
| 1280 1273 | 
             
                      when Hash
         | 
| 1281 1274 | 
             
                        arg.map { |field, dir|
         | 
| 1282 1275 | 
             
                          case field
         | 
| 1283 1276 | 
             
                          when Arel::Nodes::SqlLiteral
         | 
| 1284 1277 | 
             
                            field.send(dir.downcase)
         | 
| 1285 1278 | 
             
                          else
         | 
| 1286 | 
            -
                            field | 
| 1287 | 
            -
                            arel_column(field) {
         | 
| 1288 | 
            -
                              Arel.sql(connection.quote_table_name(field))
         | 
| 1289 | 
            -
                            }.send(dir.downcase)
         | 
| 1279 | 
            +
                            order_column(field.to_s).send(dir.downcase)
         | 
| 1290 1280 | 
             
                          end
         | 
| 1291 1281 | 
             
                        }
         | 
| 1292 1282 | 
             
                      else
         | 
| @@ -1295,6 +1285,16 @@ module ActiveRecord | |
| 1295 1285 | 
             
                    end.flatten!
         | 
| 1296 1286 | 
             
                  end
         | 
| 1297 1287 |  | 
| 1288 | 
            +
                  def order_column(field)
         | 
| 1289 | 
            +
                    arel_column(field) do |attr_name|
         | 
| 1290 | 
            +
                      if attr_name == "count" && !group_values.empty?
         | 
| 1291 | 
            +
                        arel_attribute(attr_name)
         | 
| 1292 | 
            +
                      else
         | 
| 1293 | 
            +
                        Arel.sql(connection.quote_table_name(attr_name))
         | 
| 1294 | 
            +
                      end
         | 
| 1295 | 
            +
                    end
         | 
| 1296 | 
            +
                  end
         | 
| 1297 | 
            +
             | 
| 1298 1298 | 
             
                  # Checks to make sure that the arguments are not blank. Note that if some
         | 
| 1299 1299 | 
             
                  # blank-like object were initially passed into the query method, then this
         | 
| 1300 1300 | 
             
                  # method will not raise an error.
         | 
| @@ -61,8 +61,9 @@ module ActiveRecord | |
| 61 61 | 
             
                  #   # => "id ASC"
         | 
| 62 62 | 
             
                  def sanitize_sql_for_order(condition)
         | 
| 63 63 | 
             
                    if condition.is_a?(Array) && condition.first.to_s.include?("?")
         | 
| 64 | 
            -
                      disallow_raw_sql!( | 
| 65 | 
            -
                         | 
| 64 | 
            +
                      disallow_raw_sql!(
         | 
| 65 | 
            +
                        [condition.first],
         | 
| 66 | 
            +
                        permit: connection.column_name_with_order_matcher
         | 
| 66 67 | 
             
                      )
         | 
| 67 68 |  | 
| 68 69 | 
             
                      # Ensure we aren't dealing with a subclass of String that might
         | 
| @@ -133,6 +134,33 @@ module ActiveRecord | |
| 133 134 | 
             
                    end
         | 
| 134 135 | 
             
                  end
         | 
| 135 136 |  | 
| 137 | 
            +
                  def disallow_raw_sql!(args, permit: connection.column_name_matcher) # :nodoc:
         | 
| 138 | 
            +
                    unexpected = nil
         | 
| 139 | 
            +
                    args.each do |arg|
         | 
| 140 | 
            +
                      next if arg.is_a?(Symbol) || Arel.arel_node?(arg) || permit.match?(arg.to_s)
         | 
| 141 | 
            +
                      (unexpected ||= []) << arg
         | 
| 142 | 
            +
                    end
         | 
| 143 | 
            +
             | 
| 144 | 
            +
                    return unless unexpected
         | 
| 145 | 
            +
             | 
| 146 | 
            +
                    if allow_unsafe_raw_sql == :deprecated
         | 
| 147 | 
            +
                      ActiveSupport::Deprecation.warn(
         | 
| 148 | 
            +
                        "Dangerous query method (method whose arguments are used as raw " \
         | 
| 149 | 
            +
                        "SQL) called with non-attribute argument(s): " \
         | 
| 150 | 
            +
                        "#{unexpected.map(&:inspect).join(", ")}. Non-attribute " \
         | 
| 151 | 
            +
                        "arguments will be disallowed in Rails 6.1. This method should " \
         | 
| 152 | 
            +
                        "not be called with user-provided values, such as request " \
         | 
| 153 | 
            +
                        "parameters or model attributes. Known-safe values can be passed " \
         | 
| 154 | 
            +
                        "by wrapping them in Arel.sql()."
         | 
| 155 | 
            +
                      )
         | 
| 156 | 
            +
                    else
         | 
| 157 | 
            +
                      raise(ActiveRecord::UnknownAttributeReference,
         | 
| 158 | 
            +
                        "Query method called with non-attribute argument(s): " +
         | 
| 159 | 
            +
                        unexpected.map(&:inspect).join(", ")
         | 
| 160 | 
            +
                      )
         | 
| 161 | 
            +
                    end
         | 
| 162 | 
            +
                  end
         | 
| 163 | 
            +
             | 
| 136 164 | 
             
                  private
         | 
| 137 165 | 
             
                    def replace_bind_variables(statement, values)
         | 
| 138 166 | 
             
                      raise_if_bind_arity_mismatch(statement, statement.count("?"), values.size)
         | 
    
        data/lib/active_record/schema.rb
    CHANGED
    
    
| @@ -146,7 +146,11 @@ HEADER | |
| 146 146 | 
             
                        raise StandardError, "Unknown type '#{column.sql_type}' for column '#{column.name}'" unless @connection.valid_type?(column.type)
         | 
| 147 147 | 
             
                        next if column.name == pk
         | 
| 148 148 | 
             
                        type, colspec = column_spec(column)
         | 
| 149 | 
            -
                         | 
| 149 | 
            +
                        if type.is_a?(Symbol)
         | 
| 150 | 
            +
                          tbl.print "    t.#{type} #{column.name.inspect}"
         | 
| 151 | 
            +
                        else
         | 
| 152 | 
            +
                          tbl.print "    t.column #{column.name.inspect}, #{type.inspect}"
         | 
| 153 | 
            +
                        end
         | 
| 150 154 | 
             
                        tbl.print ", #{format_colspec(colspec)}" if colspec.present?
         | 
| 151 155 | 
             
                        tbl.puts
         | 
| 152 156 | 
             
                      end
         | 
| @@ -4,8 +4,9 @@ module ActiveRecord | |
| 4 4 | 
             
              class TableMetadata # :nodoc:
         | 
| 5 5 | 
             
                delegate :foreign_type, :foreign_key, :join_primary_key, :join_foreign_key, to: :association, prefix: true
         | 
| 6 6 |  | 
| 7 | 
            -
                def initialize(klass, arel_table, association = nil)
         | 
| 7 | 
            +
                def initialize(klass, arel_table, association = nil, types = klass)
         | 
| 8 8 | 
             
                  @klass = klass
         | 
| 9 | 
            +
                  @types = types
         | 
| 9 10 | 
             
                  @arel_table = arel_table
         | 
| 10 11 | 
             
                  @association = association
         | 
| 11 12 | 
             
                end
         | 
| @@ -29,11 +30,7 @@ module ActiveRecord | |
| 29 30 | 
             
                end
         | 
| 30 31 |  | 
| 31 32 | 
             
                def type(column_name)
         | 
| 32 | 
            -
                   | 
| 33 | 
            -
                    klass.type_for_attribute(column_name)
         | 
| 34 | 
            -
                  else
         | 
| 35 | 
            -
                    Type.default_value
         | 
| 36 | 
            -
                  end
         | 
| 33 | 
            +
                  types.type_for_attribute(column_name)
         | 
| 37 34 | 
             
                end
         | 
| 38 35 |  | 
| 39 36 | 
             
                def has_column?(column_name)
         | 
| @@ -52,13 +49,12 @@ module ActiveRecord | |
| 52 49 | 
             
                  elsif association && !association.polymorphic?
         | 
| 53 50 | 
             
                    association_klass = association.klass
         | 
| 54 51 | 
             
                    arel_table = association_klass.arel_table.alias(table_name)
         | 
| 52 | 
            +
                    TableMetadata.new(association_klass, arel_table, association)
         | 
| 55 53 | 
             
                  else
         | 
| 56 54 | 
             
                    type_caster = TypeCaster::Connection.new(klass, table_name)
         | 
| 57 | 
            -
                    association_klass = nil
         | 
| 58 55 | 
             
                    arel_table = Arel::Table.new(table_name, type_caster: type_caster)
         | 
| 56 | 
            +
                    TableMetadata.new(nil, arel_table, association, type_caster)
         | 
| 59 57 | 
             
                  end
         | 
| 60 | 
            -
             | 
| 61 | 
            -
                  TableMetadata.new(association_klass, arel_table, association)
         | 
| 62 58 | 
             
                end
         | 
| 63 59 |  | 
| 64 60 | 
             
                def polymorphic_association?
         | 
| @@ -74,6 +70,6 @@ module ActiveRecord | |
| 74 70 | 
             
                end
         | 
| 75 71 |  | 
| 76 72 | 
             
                private
         | 
| 77 | 
            -
                  attr_reader :klass, :arel_table, :association
         | 
| 73 | 
            +
                  attr_reader :klass, :types, :arel_table, :association
         | 
| 78 74 | 
             
              end
         | 
| 79 75 | 
             
            end
         | 
| @@ -141,10 +141,19 @@ module ActiveRecord | |
| 141 141 | 
             
                    end
         | 
| 142 142 | 
             
                  end
         | 
| 143 143 |  | 
| 144 | 
            -
                  def  | 
| 144 | 
            +
                  def setup_initial_database_yaml
         | 
| 145 145 | 
             
                    return {} unless defined?(Rails)
         | 
| 146 146 |  | 
| 147 | 
            -
                     | 
| 147 | 
            +
                    begin
         | 
| 148 | 
            +
                      Rails.application.config.load_database_yaml
         | 
| 149 | 
            +
                    rescue
         | 
| 150 | 
            +
                      $stderr.puts "Rails couldn't infer whether you are using multiple databases from your database.yml and can't generate the tasks for the non-primary databases. If you'd like to use this feature, please simplify your ERB."
         | 
| 151 | 
            +
             | 
| 152 | 
            +
                      {}
         | 
| 153 | 
            +
                    end
         | 
| 154 | 
            +
                  end
         | 
| 155 | 
            +
             | 
| 156 | 
            +
                  def for_each(databases)
         | 
| 148 157 | 
             
                    database_configs = ActiveRecord::DatabaseConfigurations.new(databases).configs_for(env_name: Rails.env)
         | 
| 149 158 |  | 
| 150 159 | 
             
                    # if this is a single database application we don't want tasks for each primary database
         | 
| @@ -169,8 +178,8 @@ module ActiveRecord | |
| 169 178 | 
             
                    end
         | 
| 170 179 | 
             
                  end
         | 
| 171 180 |  | 
| 172 | 
            -
                  def create_current(environment = env)
         | 
| 173 | 
            -
                    each_current_configuration(environment) { |configuration|
         | 
| 181 | 
            +
                  def create_current(environment = env, spec_name = nil)
         | 
| 182 | 
            +
                    each_current_configuration(environment, spec_name) { |configuration|
         | 
| 174 183 | 
             
                      create configuration
         | 
| 175 184 | 
             
                    }
         | 
| 176 185 | 
             
                    ActiveRecord::Base.establish_connection(environment.to_sym)
         | 
| @@ -200,9 +209,10 @@ module ActiveRecord | |
| 200 209 |  | 
| 201 210 | 
             
                  def truncate_tables(configuration)
         | 
| 202 211 | 
             
                    ActiveRecord::Base.connected_to(database: { truncation: configuration }) do
         | 
| 203 | 
            -
                       | 
| 212 | 
            +
                      conn = ActiveRecord::Base.connection
         | 
| 213 | 
            +
                      table_names = conn.tables
         | 
| 204 214 | 
             
                      table_names -= [
         | 
| 205 | 
            -
                         | 
| 215 | 
            +
                        conn.schema_migration.table_name,
         | 
| 206 216 | 
             
                        InternalMetadata.table_name
         | 
| 207 217 | 
             
                      ]
         | 
| 208 218 |  | 
| @@ -233,7 +243,7 @@ module ActiveRecord | |
| 233 243 | 
             
                  end
         | 
| 234 244 |  | 
| 235 245 | 
             
                  def migrate_status
         | 
| 236 | 
            -
                    unless ActiveRecord:: | 
| 246 | 
            +
                    unless ActiveRecord::Base.connection.schema_migration.table_exists?
         | 
| 237 247 | 
             
                      Kernel.abort "Schema migrations table does not exist yet."
         | 
| 238 248 | 
             
                    end
         | 
| 239 249 |  | 
| @@ -325,6 +335,27 @@ module ActiveRecord | |
| 325 335 | 
             
                    Migration.verbose = verbose_was
         | 
| 326 336 | 
             
                  end
         | 
| 327 337 |  | 
| 338 | 
            +
                  def dump_schema(configuration, format = ActiveRecord::Base.schema_format, spec_name = "primary") # :nodoc:
         | 
| 339 | 
            +
                    require "active_record/schema_dumper"
         | 
| 340 | 
            +
                    filename = dump_filename(spec_name, format)
         | 
| 341 | 
            +
                    connection = ActiveRecord::Base.connection
         | 
| 342 | 
            +
             | 
| 343 | 
            +
                    case format
         | 
| 344 | 
            +
                    when :ruby
         | 
| 345 | 
            +
                      File.open(filename, "w:utf-8") do |file|
         | 
| 346 | 
            +
                        ActiveRecord::SchemaDumper.dump(ActiveRecord::Base.connection, file)
         | 
| 347 | 
            +
                      end
         | 
| 348 | 
            +
                    when :sql
         | 
| 349 | 
            +
                      structure_dump(configuration, filename)
         | 
| 350 | 
            +
                      if connection.schema_migration.table_exists?
         | 
| 351 | 
            +
                        File.open(filename, "a") do |f|
         | 
| 352 | 
            +
                          f.puts connection.dump_schema_information
         | 
| 353 | 
            +
                          f.print "\n"
         | 
| 354 | 
            +
                        end
         | 
| 355 | 
            +
                      end
         | 
| 356 | 
            +
                    end
         | 
| 357 | 
            +
                  end
         | 
| 358 | 
            +
             | 
| 328 359 | 
             
                  def schema_file(format = ActiveRecord::Base.schema_format)
         | 
| 329 360 | 
             
                    File.join(db_dir, schema_file_type(format))
         | 
| 330 361 | 
             
                  end
         | 
| @@ -406,12 +437,14 @@ module ActiveRecord | |
| 406 437 | 
             
                      task.is_a?(String) ? task.constantize : task
         | 
| 407 438 | 
             
                    end
         | 
| 408 439 |  | 
| 409 | 
            -
                    def each_current_configuration(environment)
         | 
| 440 | 
            +
                    def each_current_configuration(environment, spec_name = nil)
         | 
| 410 441 | 
             
                      environments = [environment]
         | 
| 411 442 | 
             
                      environments << "test" if environment == "development"
         | 
| 412 443 |  | 
| 413 444 | 
             
                      environments.each do |env|
         | 
| 414 445 | 
             
                        ActiveRecord::Base.configurations.configs_for(env_name: env).each do |db_config|
         | 
| 446 | 
            +
                          next if spec_name && spec_name != db_config.spec_name
         | 
| 447 | 
            +
             | 
| 415 448 | 
             
                          yield db_config.config, db_config.spec_name, env
         | 
| 416 449 | 
             
                        end
         | 
| 417 450 | 
             
                      end
         | 
| @@ -3,6 +3,8 @@ | |
| 3 3 | 
             
            module ActiveRecord
         | 
| 4 4 | 
             
              module Tasks # :nodoc:
         | 
| 5 5 | 
             
                class MySQLDatabaseTasks # :nodoc:
         | 
| 6 | 
            +
                  ER_DB_CREATE_EXISTS = 1007
         | 
| 7 | 
            +
             | 
| 6 8 | 
             
                  delegate :connection, :establish_connection, to: ActiveRecord::Base
         | 
| 7 9 |  | 
| 8 10 | 
             
                  def initialize(configuration)
         | 
| @@ -14,7 +16,7 @@ module ActiveRecord | |
| 14 16 | 
             
                    connection.create_database configuration["database"], creation_options
         | 
| 15 17 | 
             
                    establish_connection configuration
         | 
| 16 18 | 
             
                  rescue ActiveRecord::StatementInvalid => error
         | 
| 17 | 
            -
                    if error. | 
| 19 | 
            +
                    if error.cause.error_number == ER_DB_CREATE_EXISTS
         | 
| 18 20 | 
             
                      raise DatabaseAlreadyExists
         | 
| 19 21 | 
             
                    else
         | 
| 20 22 | 
             
                      raise
         | 
| @@ -59,19 +59,26 @@ module ActiveRecord | |
| 59 59 | 
             
                    attribute_names.index_with(time || current_time_from_proper_timezone)
         | 
| 60 60 | 
             
                  end
         | 
| 61 61 |  | 
| 62 | 
            -
                   | 
| 63 | 
            -
                     | 
| 64 | 
            -
                      timestamp_attributes_for_create | 
| 65 | 
            -
             | 
| 62 | 
            +
                  def timestamp_attributes_for_create_in_model
         | 
| 63 | 
            +
                    @timestamp_attributes_for_create_in_model ||=
         | 
| 64 | 
            +
                      (timestamp_attributes_for_create & column_names).freeze
         | 
| 65 | 
            +
                  end
         | 
| 66 66 |  | 
| 67 | 
            -
             | 
| 68 | 
            -
             | 
| 69 | 
            -
             | 
| 67 | 
            +
                  def timestamp_attributes_for_update_in_model
         | 
| 68 | 
            +
                    @timestamp_attributes_for_update_in_model ||=
         | 
| 69 | 
            +
                      (timestamp_attributes_for_update & column_names).freeze
         | 
| 70 | 
            +
                  end
         | 
| 70 71 |  | 
| 71 | 
            -
             | 
| 72 | 
            -
             | 
| 73 | 
            -
             | 
| 72 | 
            +
                  def all_timestamp_attributes_in_model
         | 
| 73 | 
            +
                    @all_timestamp_attributes_in_model ||=
         | 
| 74 | 
            +
                      (timestamp_attributes_for_create_in_model + timestamp_attributes_for_update_in_model).freeze
         | 
| 75 | 
            +
                  end
         | 
| 74 76 |  | 
| 77 | 
            +
                  def current_time_from_proper_timezone
         | 
| 78 | 
            +
                    default_timezone == :utc ? Time.now.utc : Time.now
         | 
| 79 | 
            +
                  end
         | 
| 80 | 
            +
             | 
| 81 | 
            +
                  private
         | 
| 75 82 | 
             
                    def timestamp_attributes_for_create
         | 
| 76 83 | 
             
                      ["created_at", "created_on"]
         | 
| 77 84 | 
             
                    end
         | 
| @@ -80,8 +87,11 @@ module ActiveRecord | |
| 80 87 | 
             
                      ["updated_at", "updated_on"]
         | 
| 81 88 | 
             
                    end
         | 
| 82 89 |  | 
| 83 | 
            -
                    def  | 
| 84 | 
            -
                       | 
| 90 | 
            +
                    def reload_schema_from_cache
         | 
| 91 | 
            +
                      @timestamp_attributes_for_create_in_model = nil
         | 
| 92 | 
            +
                      @timestamp_attributes_for_update_in_model = nil
         | 
| 93 | 
            +
                      @all_timestamp_attributes_in_model = nil
         | 
| 94 | 
            +
                      super
         | 
| 85 95 | 
             
                    end
         | 
| 86 96 | 
             
                end
         | 
| 87 97 |  | 
| @@ -124,19 +134,19 @@ module ActiveRecord | |
| 124 134 | 
             
                end
         | 
| 125 135 |  | 
| 126 136 | 
             
                def timestamp_attributes_for_create_in_model
         | 
| 127 | 
            -
                  self.class. | 
| 137 | 
            +
                  self.class.timestamp_attributes_for_create_in_model
         | 
| 128 138 | 
             
                end
         | 
| 129 139 |  | 
| 130 140 | 
             
                def timestamp_attributes_for_update_in_model
         | 
| 131 | 
            -
                  self.class. | 
| 141 | 
            +
                  self.class.timestamp_attributes_for_update_in_model
         | 
| 132 142 | 
             
                end
         | 
| 133 143 |  | 
| 134 144 | 
             
                def all_timestamp_attributes_in_model
         | 
| 135 | 
            -
                  self.class. | 
| 145 | 
            +
                  self.class.all_timestamp_attributes_in_model
         | 
| 136 146 | 
             
                end
         | 
| 137 147 |  | 
| 138 148 | 
             
                def current_time_from_proper_timezone
         | 
| 139 | 
            -
                  self.class. | 
| 149 | 
            +
                  self.class.current_time_from_proper_timezone
         | 
| 140 150 | 
             
                end
         | 
| 141 151 |  | 
| 142 152 | 
             
                def max_updated_column_timestamp
         |