declare_schema 0.5.0.pre.1 → 0.6.1
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.
- checksums.yaml +4 -4
- data/.github/workflows/declare_schema_build.yml +60 -0
- data/.gitignore +1 -0
- data/Appraisals +21 -4
- data/CHANGELOG.md +22 -1
- data/Gemfile +0 -2
- data/Gemfile.lock +1 -5
- data/README.md +4 -4
- data/Rakefile +17 -4
- data/bin/declare_schema +1 -1
- data/declare_schema.gemspec +1 -1
- data/gemfiles/rails_4_mysql.gemfile +22 -0
- data/gemfiles/{rails_4.gemfile → rails_4_sqlite.gemfile} +1 -2
- data/gemfiles/rails_5_mysql.gemfile +22 -0
- data/gemfiles/{rails_5.gemfile → rails_5_sqlite.gemfile} +1 -2
- data/gemfiles/rails_6_mysql.gemfile +22 -0
- data/gemfiles/{rails_6.gemfile → rails_6_sqlite.gemfile} +2 -3
- data/lib/declare_schema/command.rb +10 -3
- data/lib/declare_schema/model.rb +1 -1
- data/lib/declare_schema/model/field_spec.rb +21 -17
- data/lib/declare_schema/model/table_options_definition.rb +8 -6
- data/lib/declare_schema/version.rb +1 -1
- data/lib/generators/declare_schema/migration/migrator.rb +80 -30
- data/spec/lib/declare_schema/field_spec_spec.rb +69 -0
- data/spec/lib/declare_schema/generator_spec.rb +25 -10
- data/spec/lib/declare_schema/interactive_primary_key_spec.rb +8 -2
- data/spec/lib/declare_schema/migration_generator_spec.rb +285 -158
- data/spec/lib/declare_schema/model/index_definition_spec.rb +4 -5
- data/spec/lib/declare_schema/model/table_options_definition_spec.rb +19 -29
- data/spec/lib/generators/declare_schema/migration/migrator_spec.rb +17 -22
- data/spec/support/acceptance_spec_helpers.rb +3 -3
- metadata +14 -10
- data/.travis.yml +0 -37
| @@ -26,12 +26,14 @@ module DeclareSchema | |
| 26 26 |  | 
| 27 27 | 
             
                    def mysql_table_options(connection, table_name)
         | 
| 28 28 | 
             
                      database = connection.current_database
         | 
| 29 | 
            -
                      defaults = connection.select_one(<<~EOS)
         | 
| 29 | 
            +
                      defaults = connection.select_one(<<~EOS) or raise "no defaults found for table #{table_name}"
         | 
| 30 30 | 
             
                        SELECT CCSA.character_set_name, CCSA.collation_name
         | 
| 31 | 
            -
                        FROM information_schema | 
| 32 | 
            -
             | 
| 33 | 
            -
             | 
| 34 | 
            -
             | 
| 31 | 
            +
                        FROM information_schema.TABLES as T
         | 
| 32 | 
            +
                          JOIN information_schema.COLLATION_CHARACTER_SET_APPLICABILITY as CCSA
         | 
| 33 | 
            +
                            ON CCSA.collation_name = T.table_collation
         | 
| 34 | 
            +
                        WHERE
         | 
| 35 | 
            +
                          T.table_schema = '#{connection.quote_string(database)}' AND
         | 
| 36 | 
            +
                          T.table_name = '#{connection.quote_string(table_name)}'
         | 
| 35 37 | 
             
                      EOS
         | 
| 36 38 |  | 
| 37 39 | 
             
                      defaults["character_set_name"] or raise "character_set_name missing from #{defaults.inspect}"
         | 
| @@ -75,7 +77,7 @@ module DeclareSchema | |
| 75 77 | 
             
                  alias to_s settings
         | 
| 76 78 |  | 
| 77 79 | 
             
                  def alter_table_statement
         | 
| 78 | 
            -
                    statement = "ALTER TABLE #{ActiveRecord::Base.connection.quote_table_name(table_name)} #{to_s} | 
| 80 | 
            +
                    statement = "ALTER TABLE #{ActiveRecord::Base.connection.quote_table_name(table_name)} #{to_s}"
         | 
| 79 81 | 
             
                    "execute #{statement.inspect}"
         | 
| 80 82 | 
             
                  end
         | 
| 81 83 | 
             
                end
         | 
| @@ -23,6 +23,10 @@ module Generators | |
| 23 23 | 
             
                      end
         | 
| 24 24 | 
             
                    end
         | 
| 25 25 |  | 
| 26 | 
            +
                    def table_options
         | 
| 27 | 
            +
                      {}
         | 
| 28 | 
            +
                    end
         | 
| 29 | 
            +
             | 
| 26 30 | 
             
                    def table_name
         | 
| 27 31 | 
             
                      join_table
         | 
| 28 32 | 
             
                    end
         | 
| @@ -33,11 +37,9 @@ module Generators | |
| 33 37 |  | 
| 34 38 | 
             
                    def field_specs
         | 
| 35 39 | 
             
                      i = 0
         | 
| 36 | 
            -
                      foreign_keys. | 
| 37 | 
            -
                         | 
| 38 | 
            -
                        h[v] = ::DeclareSchema::Model::FieldSpec.new(self, v, :integer, position: i, null: false)
         | 
| 40 | 
            +
                      foreign_keys.each_with_object({}) do |v, result|
         | 
| 41 | 
            +
                        result[v] = ::DeclareSchema::Model::FieldSpec.new(self, v, :integer, position: i, null: false)
         | 
| 39 42 | 
             
                        i += 1
         | 
| 40 | 
            -
                        h
         | 
| 41 43 | 
             
                      end
         | 
| 42 44 | 
             
                    end
         | 
| 43 45 |  | 
| @@ -69,8 +71,8 @@ module Generators | |
| 69 71 | 
             
                  class Migrator
         | 
| 70 72 | 
             
                    class Error < RuntimeError; end
         | 
| 71 73 |  | 
| 72 | 
            -
                    DEFAULT_CHARSET   =  | 
| 73 | 
            -
                    DEFAULT_COLLATION =  | 
| 74 | 
            +
                    DEFAULT_CHARSET   = "utf8mb4"
         | 
| 75 | 
            +
                    DEFAULT_COLLATION = "utf8mb4_bin"
         | 
| 74 76 |  | 
| 75 77 | 
             
                    @ignore_models                        = []
         | 
| 76 78 | 
             
                    @ignore_tables                        = []
         | 
| @@ -80,9 +82,18 @@ module Generators | |
| 80 82 | 
             
                    @default_collation                    = DEFAULT_COLLATION
         | 
| 81 83 |  | 
| 82 84 | 
             
                    class << self
         | 
| 83 | 
            -
                      attr_accessor :ignore_models, :ignore_tables, :disable_indexing, :disable_constraints | 
| 84 | 
            -
             | 
| 85 | 
            -
             | 
| 85 | 
            +
                      attr_accessor :ignore_models, :ignore_tables, :disable_indexing, :disable_constraints
         | 
| 86 | 
            +
                      attr_reader :active_record_class, :default_charset, :default_collation, :before_generating_migration_callback
         | 
| 87 | 
            +
             | 
| 88 | 
            +
                      def default_charset=(charset)
         | 
| 89 | 
            +
                        charset.is_a?(String) or raise ArgumentError, "charset must be a string (got #{charset.inspect})"
         | 
| 90 | 
            +
                        @default_charset = charset
         | 
| 91 | 
            +
                      end
         | 
| 92 | 
            +
             | 
| 93 | 
            +
                      def default_collation=(collation)
         | 
| 94 | 
            +
                        collation.is_a?(String) or raise ArgumentError, "collation must be a string (got #{collation.inspect})"
         | 
| 95 | 
            +
                        @default_collation = collation
         | 
| 96 | 
            +
                      end
         | 
| 86 97 |  | 
| 87 98 | 
             
                      def active_record_class
         | 
| 88 99 | 
             
                        @active_record_class.is_a?(Class) or @active_record_class = @active_record_class.to_s.constantize
         | 
| @@ -423,7 +434,7 @@ module Generators | |
| 423 434 | 
             
                          else
         | 
| 424 435 | 
             
                            [":integer"]
         | 
| 425 436 | 
             
                          end
         | 
| 426 | 
            -
                        "add_column :#{new_table_name}, :#{c},  | 
| 437 | 
            +
                        ["add_column :#{new_table_name}, :#{c}", *args].join(', ')
         | 
| 427 438 | 
             
                      end
         | 
| 428 439 | 
             
                      undo_adds = to_add.map do |c|
         | 
| 429 440 | 
             
                        "remove_column :#{new_table_name}, :#{c}"
         | 
| @@ -452,8 +463,8 @@ module Generators | |
| 452 463 | 
             
                          change_spec[:scale]         = spec.scale         unless spec.scale.nil?
         | 
| 453 464 | 
             
                          change_spec[:null]          = spec.null          unless spec.null && col.null
         | 
| 454 465 | 
             
                          change_spec[:default]       = spec.default       unless spec.default.nil? && col.default.nil?
         | 
| 455 | 
            -
                          change_spec[:collation]     = spec.collation     unless spec.collation.nil?
         | 
| 456 466 | 
             
                          change_spec[:charset]       = spec.charset       unless spec.charset.nil?
         | 
| 467 | 
            +
                          change_spec[:collation]     = spec.collation     unless spec.collation.nil?
         | 
| 457 468 |  | 
| 458 469 | 
             
                          changes << "change_column :#{new_table_name}, :#{c}, " +
         | 
| 459 470 | 
             
                                     ([":#{spec.sql_type}"] + format_options(change_spec, spec.sql_type, changing: true)).join(", ")
         | 
| @@ -462,7 +473,7 @@ module Generators | |
| 462 473 | 
             
                        end
         | 
| 463 474 | 
             
                      end.compact
         | 
| 464 475 |  | 
| 465 | 
            -
                      index_changes, undo_index_changes = change_indexes(model, current_table_name)
         | 
| 476 | 
            +
                      index_changes, undo_index_changes = change_indexes(model, current_table_name, to_remove)
         | 
| 466 477 | 
             
                      fk_changes, undo_fk_changes = if ActiveRecord::Base.connection.class.name.match?(/SQLite3Adapter/)
         | 
| 467 478 | 
             
                                                      [[], []]
         | 
| 468 479 | 
             
                                                    else
         | 
| @@ -484,7 +495,7 @@ module Generators | |
| 484 495 | 
             
                       undo_table_options_changes * "\n"]
         | 
| 485 496 | 
             
                    end
         | 
| 486 497 |  | 
| 487 | 
            -
                    def change_indexes(model, old_table_name)
         | 
| 498 | 
            +
                    def change_indexes(model, old_table_name, to_remove)
         | 
| 488 499 | 
             
                      return [[], []] if Migrator.disable_constraints
         | 
| 489 500 |  | 
| 490 501 | 
             
                      new_table_name = model.table_name
         | 
| @@ -497,7 +508,10 @@ module Generators | |
| 497 508 | 
             
                          end
         | 
| 498 509 | 
             
                        end || i
         | 
| 499 510 | 
             
                      end
         | 
| 500 | 
            -
                      existing_has_primary_key = existing_indexes.any?  | 
| 511 | 
            +
                      existing_has_primary_key = existing_indexes.any? do |i|
         | 
| 512 | 
            +
                        i.name == ::DeclareSchema::Model::IndexDefinition::PRIMARY_KEY_NAME &&
         | 
| 513 | 
            +
                          !i.fields.all? { |f| to_remove.include?(f) } # if we're removing the primary key column(s), the primary key index will be removed too
         | 
| 514 | 
            +
                      end
         | 
| 501 515 | 
             
                      model_has_primary_key    = model_indexes.any?    { |i| i.name == ::DeclareSchema::Model::IndexDefinition::PRIMARY_KEY_NAME }
         | 
| 502 516 |  | 
| 503 517 | 
             
                      add_indexes_init = model_indexes - existing_indexes
         | 
| @@ -555,12 +569,13 @@ module Generators | |
| 555 569 |  | 
| 556 570 | 
             
                    def format_options(options, type, changing: false)
         | 
| 557 571 | 
             
                      options.map do |k, v|
         | 
| 558 | 
            -
                         | 
| 559 | 
            -
                          next | 
| 560 | 
            -
                          next if k == :null && v == true
         | 
| 572 | 
            +
                        if !changing && ((k == :limit && type == :decimal) || (k == :null && v == true))
         | 
| 573 | 
            +
                          next
         | 
| 561 574 | 
             
                        end
         | 
| 562 575 |  | 
| 563 | 
            -
                         | 
| 576 | 
            +
                        if !::DeclareSchema::Model::FieldSpec.mysql_text_limits? && k == :limit && type == :text
         | 
| 577 | 
            +
                          next
         | 
| 578 | 
            +
                        end
         | 
| 564 579 |  | 
| 565 580 | 
             
                        if k.is_a?(Symbol)
         | 
| 566 581 | 
             
                          "#{k}: #{v.inspect}"
         | 
| @@ -574,9 +589,9 @@ module Generators | |
| 574 589 | 
             
                      foreign_key = model.constraint_specs.find { |fk| field_name == fk.foreign_key.to_s }
         | 
| 575 590 | 
             
                      if foreign_key && (parent_table = foreign_key.parent_table_name)
         | 
| 576 591 | 
             
                        parent_columns = connection.columns(parent_table) rescue []
         | 
| 577 | 
            -
                        pk_limit | 
| 592 | 
            +
                        pk_limit =
         | 
| 578 593 | 
             
                          if (pk_column = parent_columns.find { |column| column.name.to_s == "id" }) # right now foreign keys assume id is the target
         | 
| 579 | 
            -
                            if Rails::VERSION::MAJOR  | 
| 594 | 
            +
                            if Rails::VERSION::MAJOR < 5
         | 
| 580 595 | 
             
                              pk_column.cast_type.limit
         | 
| 581 596 | 
             
                            else
         | 
| 582 597 | 
             
                              pk_column.limit
         | 
| @@ -605,6 +620,16 @@ module Generators | |
| 605 620 | 
             
                      end
         | 
| 606 621 | 
             
                    end
         | 
| 607 622 |  | 
| 623 | 
            +
                    # TODO: TECH-4814 remove all methods from here through end of file
         | 
| 624 | 
            +
                    def default_collation_from_charset(charset)
         | 
| 625 | 
            +
                      case charset
         | 
| 626 | 
            +
                      when "utf8"
         | 
| 627 | 
            +
                        "utf8_general_ci"
         | 
| 628 | 
            +
                      when "utf8mb4"
         | 
| 629 | 
            +
                        "utf8mb4_general_ci"
         | 
| 630 | 
            +
                      end
         | 
| 631 | 
            +
                    end
         | 
| 632 | 
            +
             | 
| 608 633 | 
             
                    def revert_table(table)
         | 
| 609 634 | 
             
                      res = StringIO.new
         | 
| 610 635 | 
             
                      schema_dumper_klass = case Rails::VERSION::MAJOR
         | 
| @@ -614,30 +639,55 @@ module Generators | |
| 614 639 | 
             
                                              ActiveRecord::ConnectionAdapters::SchemaDumper
         | 
| 615 640 | 
             
                                            end
         | 
| 616 641 | 
             
                      schema_dumper_klass.send(:new, ActiveRecord::Base.connection).send(:table, table, res)
         | 
| 617 | 
            -
             | 
| 642 | 
            +
             | 
| 643 | 
            +
                      result = res.string.strip.gsub("\n  ", "\n")
         | 
| 644 | 
            +
                      if connection.class.name.match?(/mysql/i)
         | 
| 645 | 
            +
                        if !result['options: ']
         | 
| 646 | 
            +
                          result = result.sub('",', "\", options: \"DEFAULT CHARSET=#{Generators::DeclareSchema::Migration::Migrator.default_charset} "+
         | 
| 647 | 
            +
                                               "COLLATE=#{Generators::DeclareSchema::Migration::Migrator.default_collation}\",")
         | 
| 648 | 
            +
                        end
         | 
| 649 | 
            +
                        default_charset   = result[/CHARSET=(\w+)/, 1]   or raise "unable to find charset in #{result.inspect}"
         | 
| 650 | 
            +
                        default_collation = result[/COLLATE=(\w+)/, 1] || default_collation_from_charset(default_charset) or
         | 
| 651 | 
            +
                          raise "unable to find collation in #{result.inspect} or charset #{default_charset.inspect}"
         | 
| 652 | 
            +
                        result = result.split("\n").map do |line|
         | 
| 653 | 
            +
                          if line['t.text'] || line['t.string']
         | 
| 654 | 
            +
                            if !line['charset: ']
         | 
| 655 | 
            +
                              if line['collation: ']
         | 
| 656 | 
            +
                                line = line.sub('collation: ', "charset: #{default_charset.inspect}, collation: ")
         | 
| 657 | 
            +
                              else
         | 
| 658 | 
            +
                                line += ", charset: #{default_charset.inspect}"
         | 
| 659 | 
            +
                              end
         | 
| 660 | 
            +
                            end
         | 
| 661 | 
            +
                            line['collation: '] or line += ", collation: #{default_collation.inspect}"
         | 
| 662 | 
            +
                          end
         | 
| 663 | 
            +
                          line
         | 
| 664 | 
            +
                        end.join("\n")
         | 
| 665 | 
            +
                      end
         | 
| 666 | 
            +
                      result
         | 
| 618 667 | 
             
                    end
         | 
| 619 668 |  | 
| 620 | 
            -
                    def column_options_from_reverted_table(table,  | 
| 669 | 
            +
                    def column_options_from_reverted_table(table, column)
         | 
| 621 670 | 
             
                      revert = revert_table(table)
         | 
| 622 | 
            -
                      if (md = revert.match(/\s*t\.column\s+"#{ | 
| 671 | 
            +
                      if (md = revert.match(/\s*t\.column\s+"#{column}",\s+(:[a-zA-Z0-9_]+)(?:,\s+(.*?)$)?/m))
         | 
| 623 672 | 
             
                        # Ugly migration
         | 
| 624 673 | 
             
                        _, type, options = *md
         | 
| 625 | 
            -
                      elsif (md = revert.match(/\s*t\.([a-z_]+)\s+"#{ | 
| 674 | 
            +
                      elsif (md = revert.match(/\s*t\.([a-z_]+)\s+"#{column}"(?:,\s+(.*?)$)?/m))
         | 
| 626 675 | 
             
                        # Sexy migration
         | 
| 627 | 
            -
                        _,  | 
| 628 | 
            -
                        type = ":#{ | 
| 676 | 
            +
                        _, string_type, options = *md
         | 
| 677 | 
            +
                        type = ":#{string_type}"
         | 
| 629 678 | 
             
                      end
         | 
| 679 | 
            +
                      type or raise "unable to find column options for #{table}.#{column} in #{revert.inspect}"
         | 
| 630 680 | 
             
                      [type, options]
         | 
| 631 681 | 
             
                    end
         | 
| 632 682 |  | 
| 633 | 
            -
                    def change_column_back(table,  | 
| 634 | 
            -
                      type, options = column_options_from_reverted_table(table,  | 
| 635 | 
            -
                      "change_column :#{table}, :#{ | 
| 683 | 
            +
                    def change_column_back(table, column)
         | 
| 684 | 
            +
                      type, options = column_options_from_reverted_table(table, column)
         | 
| 685 | 
            +
                      ["change_column :#{table}, :#{column}, #{type}", options&.strip].compact.join(', ')
         | 
| 636 686 | 
             
                    end
         | 
| 637 687 |  | 
| 638 688 | 
             
                    def revert_column(table, column)
         | 
| 639 689 | 
             
                      type, options = column_options_from_reverted_table(table, column)
         | 
| 640 | 
            -
                      "add_column :#{table}, :#{column}, #{type} | 
| 690 | 
            +
                      ["add_column :#{table}, :#{column}, #{type}", options&.strip].compact.join(', ')
         | 
| 641 691 | 
             
                    end
         | 
| 642 692 | 
             
                  end
         | 
| 643 693 | 
             
                end
         | 
| @@ -0,0 +1,69 @@ | |
| 1 | 
            +
            # frozen_string_literal: true
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            RSpec.describe 'DeclareSchema Model FieldSpec' do
         | 
| 4 | 
            +
              before do
         | 
| 5 | 
            +
                load File.expand_path('prepare_testapp.rb', __dir__)
         | 
| 6 | 
            +
              end
         | 
| 7 | 
            +
             | 
| 8 | 
            +
              context 'There are no model columns to change' do
         | 
| 9 | 
            +
                it '#different_to should return false for int8 == int8' do
         | 
| 10 | 
            +
                  subject = DeclareSchema::Model::FieldSpec.new(Object, :price, :integer, limit: 8, null: false, position: 0)
         | 
| 11 | 
            +
             | 
| 12 | 
            +
                  case Rails::VERSION::MAJOR
         | 
| 13 | 
            +
                  when 4
         | 
| 14 | 
            +
                    cast_type = ActiveRecord::Type::Integer.new(limit: 8)
         | 
| 15 | 
            +
                    col = ActiveRecord::ConnectionAdapters::Column.new("price", nil, cast_type, "integer(8)", false)
         | 
| 16 | 
            +
                  else
         | 
| 17 | 
            +
                    sql_type_metadata = ActiveRecord::ConnectionAdapters::SqlTypeMetadata.new(sql_type: "integer(8)", type: :integer, limit: 8)
         | 
| 18 | 
            +
                    col = ActiveRecord::ConnectionAdapters::Column.new("price", nil, sql_type_metadata, false, "adverts")
         | 
| 19 | 
            +
                  end
         | 
| 20 | 
            +
             | 
| 21 | 
            +
                  expect(subject.different_to?(subject.name, col)).to eq(false)
         | 
| 22 | 
            +
                end
         | 
| 23 | 
            +
             | 
| 24 | 
            +
                it '#different_to should return false for bigint == bigint' do
         | 
| 25 | 
            +
                  subject = DeclareSchema::Model::FieldSpec.new(Object, :price, :bigint, null: false, position: 0)
         | 
| 26 | 
            +
             | 
| 27 | 
            +
                  case Rails::VERSION::MAJOR
         | 
| 28 | 
            +
                  when 4
         | 
| 29 | 
            +
                    cast_type = ActiveRecord::Type::BigInteger.new(limit: 8)
         | 
| 30 | 
            +
                    col = ActiveRecord::ConnectionAdapters::Column.new("price", nil, cast_type, "bigint(20)", false)
         | 
| 31 | 
            +
                  else
         | 
| 32 | 
            +
                    sql_type_metadata = ActiveRecord::ConnectionAdapters::SqlTypeMetadata.new(sql_type: "bigint(20)", type: :integer, limit: 8)
         | 
| 33 | 
            +
                    col = ActiveRecord::ConnectionAdapters::Column.new("price", nil, sql_type_metadata, false, "adverts")
         | 
| 34 | 
            +
                  end
         | 
| 35 | 
            +
             | 
| 36 | 
            +
                  expect(subject.different_to?(subject.name, col)).to eq(false)
         | 
| 37 | 
            +
                end
         | 
| 38 | 
            +
             | 
| 39 | 
            +
                it '#different_to should return false for int8 == bigint' do
         | 
| 40 | 
            +
                  subject = DeclareSchema::Model::FieldSpec.new(Object, :price, :integer, limit: 8, null: false, position: 0)
         | 
| 41 | 
            +
             | 
| 42 | 
            +
                  case Rails::VERSION::MAJOR
         | 
| 43 | 
            +
                  when 4
         | 
| 44 | 
            +
                    cast_type = ActiveRecord::Type::BigInteger.new(limit: 8)
         | 
| 45 | 
            +
                    col = ActiveRecord::ConnectionAdapters::Column.new("price", nil, cast_type, "bigint(20)", false)
         | 
| 46 | 
            +
                  else
         | 
| 47 | 
            +
                    sql_type_metadata = ActiveRecord::ConnectionAdapters::SqlTypeMetadata.new(sql_type: "bigint(20)", type: :integer, limit: 8)
         | 
| 48 | 
            +
                    col = ActiveRecord::ConnectionAdapters::Column.new("price", nil, sql_type_metadata, false, "adverts")
         | 
| 49 | 
            +
                  end
         | 
| 50 | 
            +
             | 
| 51 | 
            +
                  expect(subject.different_to?(subject.name, col)).to eq(false)
         | 
| 52 | 
            +
                end
         | 
| 53 | 
            +
             | 
| 54 | 
            +
                it '#different_to should return false for bigint == int8' do
         | 
| 55 | 
            +
                  subject = DeclareSchema::Model::FieldSpec.new(Object, :price, :bigint, null: false, position: 0)
         | 
| 56 | 
            +
             | 
| 57 | 
            +
                  case Rails::VERSION::MAJOR
         | 
| 58 | 
            +
                  when 4
         | 
| 59 | 
            +
                    cast_type = ActiveRecord::Type::Integer.new(limit: 8)
         | 
| 60 | 
            +
                    col = ActiveRecord::ConnectionAdapters::Column.new("price", nil, cast_type, "integer(8)", false)
         | 
| 61 | 
            +
                  else
         | 
| 62 | 
            +
                    sql_type_metadata = ActiveRecord::ConnectionAdapters::SqlTypeMetadata.new(sql_type: "integer(8)", type: :integer, limit: 8)
         | 
| 63 | 
            +
                    col = ActiveRecord::ConnectionAdapters::Column.new("price", nil, sql_type_metadata, false, "adverts")
         | 
| 64 | 
            +
                  end
         | 
| 65 | 
            +
             | 
| 66 | 
            +
                  expect(subject.different_to?(subject.name, col)).to eq(false)
         | 
| 67 | 
            +
                end
         | 
| 68 | 
            +
              end
         | 
| 69 | 
            +
            end
         | 
| @@ -27,15 +27,28 @@ RSpec.describe 'DeclareSchema Migration Generator' do | |
| 27 27 | 
             
                  end
         | 
| 28 28 | 
             
                EOS
         | 
| 29 29 |  | 
| 30 | 
            -
                 | 
| 31 | 
            -
             | 
| 32 | 
            -
             | 
| 33 | 
            -
             | 
| 34 | 
            -
             | 
| 35 | 
            -
                     | 
| 36 | 
            -
             | 
| 37 | 
            -
             | 
| 38 | 
            -
             | 
| 30 | 
            +
                case Rails::VERSION::MAJOR
         | 
| 31 | 
            +
                when 4, 5
         | 
| 32 | 
            +
                  expect_test_definition_to_eq('alpha/beta', <<~EOS)
         | 
| 33 | 
            +
                    require "test_helper"
         | 
| 34 | 
            +
             | 
| 35 | 
            +
                    class Alpha::BetaTest < ActiveSupport::TestCase
         | 
| 36 | 
            +
                      # test "the truth" do
         | 
| 37 | 
            +
                      #   assert true
         | 
| 38 | 
            +
                      # end
         | 
| 39 | 
            +
                    end
         | 
| 40 | 
            +
                  EOS
         | 
| 41 | 
            +
                else
         | 
| 42 | 
            +
                  expect_test_definition_to_eq('alpha/beta', <<~EOS)
         | 
| 43 | 
            +
                    require "test_helper"
         | 
| 44 | 
            +
             | 
| 45 | 
            +
                    class Alpha::BetaTest < ActiveSupport::TestCase
         | 
| 46 | 
            +
                      # test "the truth" do
         | 
| 47 | 
            +
                      #   assert true
         | 
| 48 | 
            +
                      # end
         | 
| 49 | 
            +
                    end
         | 
| 50 | 
            +
                  EOS
         | 
| 51 | 
            +
                end
         | 
| 39 52 |  | 
| 40 53 | 
             
                case Rails::VERSION::MAJOR
         | 
| 41 54 | 
             
                when 4
         | 
| @@ -88,7 +101,9 @@ RSpec.describe 'DeclareSchema Migration Generator' do | |
| 88 101 |  | 
| 89 102 | 
             
                expect(File.exist?('db/schema.rb')).to be_truthy
         | 
| 90 103 |  | 
| 91 | 
            -
                 | 
| 104 | 
            +
                if defined?(SQLite3)
         | 
| 105 | 
            +
                  expect(File.exist?("db/development.sqlite3") || File.exist?("db/test.sqlite3")).to be_truthy
         | 
| 106 | 
            +
                end
         | 
| 92 107 |  | 
| 93 108 | 
             
                module Alpha; end
         | 
| 94 109 | 
             
                require 'alpha/beta'
         | 
| @@ -1,5 +1,11 @@ | |
| 1 1 | 
             
            # frozen_string_literal: true
         | 
| 2 2 |  | 
| 3 | 
            +
            require 'rails'
         | 
| 4 | 
            +
            begin
         | 
| 5 | 
            +
              require 'mysql2'
         | 
| 6 | 
            +
            rescue LoadError
         | 
| 7 | 
            +
            end
         | 
| 8 | 
            +
             | 
| 3 9 | 
             
            RSpec.describe 'DeclareSchema Migration Generator interactive primary key' do
         | 
| 4 10 | 
             
              before do
         | 
| 5 11 | 
             
                load File.expand_path('prepare_testapp.rb', __dir__)
         | 
| @@ -31,8 +37,8 @@ RSpec.describe 'DeclareSchema Migration Generator interactive primary key' do | |
| 31 37 |  | 
| 32 38 | 
             
                ### migrate to
         | 
| 33 39 |  | 
| 34 | 
            -
                if Rails::VERSION::MAJOR >= 5
         | 
| 35 | 
            -
                  #  | 
| 40 | 
            +
                if Rails::VERSION::MAJOR >= 5 && !defined?(Mysql2) # TODO TECH-4814 Put this test back for Mysql2
         | 
| 41 | 
            +
                  # replace custom primary_key
         | 
| 36 42 | 
             
                  class Foo < ActiveRecord::Base
         | 
| 37 43 | 
             
                    fields do
         | 
| 38 44 | 
             
                    end
         | 
| @@ -1,12 +1,53 @@ | |
| 1 1 | 
             
            # frozen_string_literal: true
         | 
| 2 2 |  | 
| 3 3 | 
             
            require 'rails'
         | 
| 4 | 
            +
            begin
         | 
| 5 | 
            +
              require 'mysql2'
         | 
| 6 | 
            +
            rescue LoadError
         | 
| 7 | 
            +
            end
         | 
| 4 8 |  | 
| 5 9 | 
             
            RSpec.describe 'DeclareSchema Migration Generator' do
         | 
| 6 10 | 
             
              before do
         | 
| 7 11 | 
             
                load File.expand_path('prepare_testapp.rb', __dir__)
         | 
| 8 12 | 
             
              end
         | 
| 9 13 |  | 
| 14 | 
            +
              let(:charset_alter_table) do
         | 
| 15 | 
            +
                if defined?(Mysql2)
         | 
| 16 | 
            +
                  <<~EOS
         | 
| 17 | 
            +
             | 
| 18 | 
            +
             | 
| 19 | 
            +
                    execute "ALTER TABLE `adverts` CHARACTER SET utf8mb4 COLLATE utf8mb4_bin"
         | 
| 20 | 
            +
                  EOS
         | 
| 21 | 
            +
                end
         | 
| 22 | 
            +
              end
         | 
| 23 | 
            +
              let(:text_limit) do
         | 
| 24 | 
            +
                if defined?(Mysql2)
         | 
| 25 | 
            +
                  ", limit: 4294967295"
         | 
| 26 | 
            +
                end
         | 
| 27 | 
            +
              end
         | 
| 28 | 
            +
              let(:charset_and_collation) do
         | 
| 29 | 
            +
                if defined?(Mysql2)
         | 
| 30 | 
            +
                  ', charset: "utf8mb4", collation: "utf8mb4_bin"'
         | 
| 31 | 
            +
                end
         | 
| 32 | 
            +
              end
         | 
| 33 | 
            +
              let(:datetime_precision) do
         | 
| 34 | 
            +
                if defined?(Mysql2) && Rails::VERSION::MAJOR >= 5
         | 
| 35 | 
            +
                  ', precision: 0'
         | 
| 36 | 
            +
                end
         | 
| 37 | 
            +
              end
         | 
| 38 | 
            +
              let(:table_options) do
         | 
| 39 | 
            +
                if defined?(Mysql2)
         | 
| 40 | 
            +
                  ", options: \"#{'ENGINE=InnoDB ' if Rails::VERSION::MAJOR == 5}DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin\"" +
         | 
| 41 | 
            +
                    if Rails::VERSION::MAJOR >= 6
         | 
| 42 | 
            +
                      ', charset: "utf8mb4", collation: "utf8mb4_bin"'
         | 
| 43 | 
            +
                    else
         | 
| 44 | 
            +
                      ''
         | 
| 45 | 
            +
                    end
         | 
| 46 | 
            +
                else
         | 
| 47 | 
            +
                  ", id: :integer" unless Rails::VERSION::MAJOR < 5
         | 
| 48 | 
            +
                end
         | 
| 49 | 
            +
              end
         | 
| 50 | 
            +
             | 
| 10 51 | 
             
              # DeclareSchema - Migration Generator
         | 
| 11 52 | 
             
              it 'generates migrations' do
         | 
| 12 53 | 
             
                ## The migration generator -- introduction
         | 
| @@ -25,7 +66,7 @@ RSpec.describe 'DeclareSchema Migration Generator' do | |
| 25 66 |  | 
| 26 67 | 
             
                class Advert < ActiveRecord::Base
         | 
| 27 68 | 
             
                  fields do
         | 
| 28 | 
            -
                    name :string, limit:  | 
| 69 | 
            +
                    name :string, limit: 250, null: true
         | 
| 29 70 | 
             
                  end
         | 
| 30 71 | 
             
                end
         | 
| 31 72 |  | 
| @@ -33,8 +74,8 @@ RSpec.describe 'DeclareSchema Migration Generator' do | |
| 33 74 | 
             
                  expect(migrations).to(
         | 
| 34 75 | 
             
                    migrate_up(<<~EOS.strip)
         | 
| 35 76 | 
             
                      create_table :adverts, id: :bigint do |t|
         | 
| 36 | 
            -
                        t.string :name, limit:  | 
| 37 | 
            -
                      end
         | 
| 77 | 
            +
                        t.string :name, limit: 250#{charset_and_collation}
         | 
| 78 | 
            +
                      end#{charset_alter_table}
         | 
| 38 79 | 
             
                    EOS
         | 
| 39 80 | 
             
                    .and migrate_down("drop_table :adverts")
         | 
| 40 81 | 
             
                  )
         | 
| @@ -44,14 +85,18 @@ RSpec.describe 'DeclareSchema Migration Generator' do | |
| 44 85 | 
             
                expect(Advert.columns.map(&:name)).to eq(["id", "name"])
         | 
| 45 86 |  | 
| 46 87 | 
             
                if Rails::VERSION::MAJOR < 5
         | 
| 47 | 
            -
                  # Rails 4  | 
| 88 | 
            +
                  # Rails 4 drivers don't always create PK properly. Fix that by dropping and recreating.
         | 
| 48 89 | 
             
                  ActiveRecord::Base.connection.execute("drop table adverts")
         | 
| 49 | 
            -
                   | 
| 90 | 
            +
                  if defined?(Mysql2)
         | 
| 91 | 
            +
                    ActiveRecord::Base.connection.execute("CREATE TABLE adverts (id integer PRIMARY KEY AUTO_INCREMENT NOT NULL, name varchar(250)) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin")
         | 
| 92 | 
            +
                  else
         | 
| 93 | 
            +
                    ActiveRecord::Base.connection.execute("CREATE TABLE adverts (id integer PRIMARY KEY AUTOINCREMENT  NOT NULL, name varchar(250))")
         | 
| 94 | 
            +
                  end
         | 
| 50 95 | 
             
                end
         | 
| 51 96 |  | 
| 52 97 | 
             
                class Advert < ActiveRecord::Base
         | 
| 53 98 | 
             
                  fields do
         | 
| 54 | 
            -
                    name :string, limit:  | 
| 99 | 
            +
                    name :string, limit: 250, null: true
         | 
| 55 100 | 
             
                    body :text, null: true
         | 
| 56 101 | 
             
                    published_at :datetime, null: true
         | 
| 57 102 | 
             
                  end
         | 
| @@ -62,7 +107,7 @@ RSpec.describe 'DeclareSchema Migration Generator' do | |
| 62 107 |  | 
| 63 108 | 
             
                expect(migrate).to(
         | 
| 64 109 | 
             
                  migrate_up(<<~EOS.strip)
         | 
| 65 | 
            -
                    add_column :adverts, :body, :text
         | 
| 110 | 
            +
                    add_column :adverts, :body, :text#{text_limit}#{charset_and_collation}
         | 
| 66 111 | 
             
                    add_column :adverts, :published_at, :datetime
         | 
| 67 112 | 
             
                  EOS
         | 
| 68 113 | 
             
                  .and migrate_down(<<~EOS.strip)
         | 
| @@ -74,33 +119,33 @@ RSpec.describe 'DeclareSchema Migration Generator' do | |
| 74 119 | 
             
                Advert.field_specs.clear # not normally needed
         | 
| 75 120 | 
             
                class Advert < ActiveRecord::Base
         | 
| 76 121 | 
             
                  fields do
         | 
| 77 | 
            -
                    name :string, limit:  | 
| 122 | 
            +
                    name :string, limit: 250, null: true
         | 
| 78 123 | 
             
                    body :text, null: true
         | 
| 79 124 | 
             
                  end
         | 
| 80 125 | 
             
                end
         | 
| 81 126 |  | 
| 82 127 | 
             
                expect(migrate).to(
         | 
| 83 128 | 
             
                  migrate_up("remove_column :adverts, :published_at").and(
         | 
| 84 | 
            -
                    migrate_down("add_column :adverts, :published_at, :datetime")
         | 
| 129 | 
            +
                    migrate_down("add_column :adverts, :published_at, :datetime#{datetime_precision}")
         | 
| 85 130 | 
             
                  )
         | 
| 86 131 | 
             
                )
         | 
| 87 132 |  | 
| 88 133 | 
             
                nuke_model_class(Advert)
         | 
| 89 134 | 
             
                class Advert < ActiveRecord::Base
         | 
| 90 135 | 
             
                  fields do
         | 
| 91 | 
            -
                    title :string, limit:  | 
| 136 | 
            +
                    title :string, limit: 250, null: true
         | 
| 92 137 | 
             
                    body :text, null: true
         | 
| 93 138 | 
             
                  end
         | 
| 94 139 | 
             
                end
         | 
| 95 140 |  | 
| 96 141 | 
             
                expect(Generators::DeclareSchema::Migration::Migrator.run).to(
         | 
| 97 142 | 
             
                  migrate_up(<<~EOS.strip)
         | 
| 98 | 
            -
                    add_column :adverts, :title, :string, limit:  | 
| 143 | 
            +
                    add_column :adverts, :title, :string, limit: 250#{charset_and_collation}
         | 
| 99 144 | 
             
                    remove_column :adverts, :name
         | 
| 100 145 | 
             
                  EOS
         | 
| 101 146 | 
             
                  .and migrate_down(<<~EOS.strip)
         | 
| 102 147 | 
             
                    remove_column :adverts, :title
         | 
| 103 | 
            -
                    add_column :adverts, :name, :string, limit:  | 
| 148 | 
            +
                    add_column :adverts, :name, :string, limit: 250#{charset_and_collation}
         | 
| 104 149 | 
             
                  EOS
         | 
| 105 150 | 
             
                )
         | 
| 106 151 |  | 
| @@ -120,24 +165,24 @@ RSpec.describe 'DeclareSchema Migration Generator' do | |
| 120 165 | 
             
                end
         | 
| 121 166 |  | 
| 122 167 | 
             
                expect(Generators::DeclareSchema::Migration::Migrator.run).to(
         | 
| 123 | 
            -
                  migrate_up("change_column :adverts, :title, :text").and(
         | 
| 124 | 
            -
                    migrate_down("change_column :adverts, :title, :string, limit:  | 
| 168 | 
            +
                  migrate_up("change_column :adverts, :title, :text#{text_limit}#{charset_and_collation}").and(
         | 
| 169 | 
            +
                    migrate_down("change_column :adverts, :title, :string, limit: 250#{charset_and_collation}")
         | 
| 125 170 | 
             
                  )
         | 
| 126 171 | 
             
                )
         | 
| 127 172 |  | 
| 128 173 | 
             
                class Advert < ActiveRecord::Base
         | 
| 129 174 | 
             
                  fields do
         | 
| 130 | 
            -
                    title :string, default: "Untitled", limit:  | 
| 175 | 
            +
                    title :string, default: "Untitled", limit: 250, null: true
         | 
| 131 176 | 
             
                    body :text, null: true
         | 
| 132 177 | 
             
                  end
         | 
| 133 178 | 
             
                end
         | 
| 134 179 |  | 
| 135 180 | 
             
                expect(migrate).to(
         | 
| 136 181 | 
             
                  migrate_up(<<~EOS.strip)
         | 
| 137 | 
            -
                    change_column :adverts, :title, :string, limit:  | 
| 182 | 
            +
                    change_column :adverts, :title, :string, limit: 250, default: "Untitled"#{charset_and_collation}
         | 
| 138 183 | 
             
                  EOS
         | 
| 139 184 | 
             
                  .and migrate_down(<<~EOS.strip)
         | 
| 140 | 
            -
                    change_column :adverts, :title, :string, limit:  | 
| 185 | 
            +
                    change_column :adverts, :title, :string, limit: 250#{charset_and_collation}
         | 
| 141 186 | 
             
                  EOS
         | 
| 142 187 | 
             
                )
         | 
| 143 188 |  | 
| @@ -187,7 +232,10 @@ RSpec.describe 'DeclareSchema Migration Generator' do | |
| 187 232 | 
             
                # If a `limit` is given, it will only be used in MySQL, to choose the smallest TEXT field that will accommodate
         | 
| 188 233 | 
             
                # that limit (0xff for TINYTEXT, 0xffff for TEXT, 0xffffff for MEDIUMTEXT, 0xffffffff for LONGTEXT).
         | 
| 189 234 |  | 
| 190 | 
            -
                 | 
| 235 | 
            +
                if defined?(SQLite3)
         | 
| 236 | 
            +
                  expect(::DeclareSchema::Model::FieldSpec.mysql_text_limits?).to be_falsey
         | 
| 237 | 
            +
                end
         | 
| 238 | 
            +
             | 
| 191 239 | 
             
                class Advert < ActiveRecord::Base
         | 
| 192 240 | 
             
                  fields do
         | 
| 193 241 | 
             
                    notes :text
         | 
| @@ -198,113 +246,107 @@ RSpec.describe 'DeclareSchema Migration Generator' do | |
| 198 246 | 
             
                expect(Generators::DeclareSchema::Migration::Migrator.run).to(
         | 
| 199 247 | 
             
                  migrate_up(<<~EOS.strip)
         | 
| 200 248 | 
             
                    add_column :adverts, :price, :decimal
         | 
| 201 | 
            -
                    add_column :adverts, :notes, :text, null: false
         | 
| 202 | 
            -
                    add_column :adverts, :description, :text, null: false
         | 
| 249 | 
            +
                    add_column :adverts, :notes, :text, null: false#{text_limit}#{charset_and_collation}
         | 
| 250 | 
            +
                    add_column :adverts, :description, :text, null: false#{', limit: 65535' if defined?(Mysql2)}#{charset_and_collation}
         | 
| 203 251 | 
             
                  EOS
         | 
| 204 252 | 
             
                )
         | 
| 205 253 |  | 
| 206 | 
            -
                # (There is no limit on `add_column ... :description` above since these tests are run against SQLite.)
         | 
| 207 | 
            -
             | 
| 208 254 | 
             
                Advert.field_specs.delete :price
         | 
| 209 255 | 
             
                Advert.field_specs.delete :notes
         | 
| 210 256 | 
             
                Advert.field_specs.delete :description
         | 
| 211 257 |  | 
| 212 258 | 
             
                # In MySQL, limits are applied, rounded up:
         | 
| 213 259 |  | 
| 214 | 
            -
                 | 
| 215 | 
            -
             | 
| 216 | 
            -
                class Advert < ActiveRecord::Base
         | 
| 217 | 
            -
                  fields do
         | 
| 218 | 
            -
                    notes :text
         | 
| 219 | 
            -
                    description :text, limit: 200
         | 
| 220 | 
            -
                  end
         | 
| 221 | 
            -
                end
         | 
| 222 | 
            -
             | 
| 223 | 
            -
                expect(Generators::DeclareSchema::Migration::Migrator.run).to(
         | 
| 224 | 
            -
                  migrate_up(<<~EOS.strip)
         | 
| 225 | 
            -
                    add_column :adverts, :notes, :text, null: false, limit: 4294967295
         | 
| 226 | 
            -
                    add_column :adverts, :description, :text, null: false, limit: 255
         | 
| 227 | 
            -
                  EOS
         | 
| 228 | 
            -
                )
         | 
| 229 | 
            -
             | 
| 230 | 
            -
                Advert.field_specs.delete :notes
         | 
| 231 | 
            -
             | 
| 232 | 
            -
                # Limits that are too high for MySQL will raise an exception.
         | 
| 260 | 
            +
                if defined?(Mysql2)
         | 
| 261 | 
            +
                  expect(::DeclareSchema::Model::FieldSpec.mysql_text_limits?).to be_truthy
         | 
| 233 262 |  | 
| 234 | 
            -
                ::DeclareSchema::Model::FieldSpec::instance_variable_set(:@mysql_text_limits, true)
         | 
| 235 | 
            -
                expect(::DeclareSchema::Model::FieldSpec.mysql_text_limits?).to be_truthy
         | 
| 236 | 
            -
                expect do
         | 
| 237 263 | 
             
                  class Advert < ActiveRecord::Base
         | 
| 238 264 | 
             
                    fields do
         | 
| 239 265 | 
             
                      notes :text
         | 
| 240 | 
            -
                      description :text, limit:  | 
| 266 | 
            +
                      description :text, limit: 250
         | 
| 241 267 | 
             
                    end
         | 
| 242 268 | 
             
                  end
         | 
| 243 | 
            -
                end.to raise_exception(ArgumentError, "limit of 4294967296 is too large for MySQL")
         | 
| 244 269 |  | 
| 245 | 
            -
             | 
| 270 | 
            +
                  expect(Generators::DeclareSchema::Migration::Migrator.run).to(
         | 
| 271 | 
            +
                    migrate_up(<<~EOS.strip)
         | 
| 272 | 
            +
                      add_column :adverts, :notes, :text, null: false, limit: 4294967295#{charset_and_collation}
         | 
| 273 | 
            +
                      add_column :adverts, :description, :text, null: false, limit: 255#{charset_and_collation}
         | 
| 274 | 
            +
                    EOS
         | 
| 275 | 
            +
                  )
         | 
| 246 276 |  | 
| 247 | 
            -
             | 
| 277 | 
            +
                  Advert.field_specs.delete :notes
         | 
| 248 278 |  | 
| 249 | 
            -
             | 
| 279 | 
            +
                  # Limits that are too high for MySQL will raise an exception.
         | 
| 250 280 |  | 
| 251 | 
            -
             | 
| 252 | 
            -
             | 
| 253 | 
            -
             | 
| 254 | 
            -
             | 
| 255 | 
            -
             | 
| 256 | 
            -
             | 
| 257 | 
            -
             | 
| 281 | 
            +
                  expect do
         | 
| 282 | 
            +
                    class Advert < ActiveRecord::Base
         | 
| 283 | 
            +
                      fields do
         | 
| 284 | 
            +
                        notes :text
         | 
| 285 | 
            +
                        description :text, limit: 0x1_0000_0000
         | 
| 286 | 
            +
                      end
         | 
| 287 | 
            +
                    end
         | 
| 288 | 
            +
                  end.to raise_exception(ArgumentError, "limit of 4294967296 is too large for MySQL")
         | 
| 258 289 |  | 
| 259 | 
            -
             | 
| 290 | 
            +
                  Advert.field_specs.delete :notes
         | 
| 260 291 |  | 
| 261 | 
            -
             | 
| 262 | 
            -
                  fields do
         | 
| 263 | 
            -
                    description :text
         | 
| 264 | 
            -
                  end
         | 
| 265 | 
            -
                end
         | 
| 292 | 
            +
                  # And in MySQL, unstated text limits are treated as the maximum (LONGTEXT) limit.
         | 
| 266 293 |  | 
| 267 | 
            -
             | 
| 268 | 
            -
                  migrate_up(<<~EOS.strip)
         | 
| 269 | 
            -
                    change_column :adverts, :description, :text, limit: 4294967295, null: false
         | 
| 270 | 
            -
                  EOS
         | 
| 271 | 
            -
                  .and migrate_down(<<~EOS.strip)
         | 
| 272 | 
            -
                    change_column :adverts, :description, :text
         | 
| 273 | 
            -
                  EOS
         | 
| 274 | 
            -
                )
         | 
| 294 | 
            +
                  # To start, we'll set the database schema for `description` to match the above limit of 250.
         | 
| 275 295 |  | 
| 276 | 
            -
             | 
| 277 | 
            -
             | 
| 296 | 
            +
                  Advert.connection.execute "ALTER TABLE adverts ADD COLUMN description TINYTEXT"
         | 
| 297 | 
            +
                  Advert.connection.schema_cache.clear!
         | 
| 298 | 
            +
                  Advert.reset_column_information
         | 
| 299 | 
            +
                  expect(Advert.connection.tables - Generators::DeclareSchema::Migration::Migrator.always_ignore_tables).
         | 
| 300 | 
            +
                    to eq(["adverts"])
         | 
| 301 | 
            +
                  expect(Advert.columns.map(&:name)).to eq(["id", "body", "title", "description"])
         | 
| 278 302 |  | 
| 279 | 
            -
             | 
| 303 | 
            +
                  # Now migrate to an unstated text limit:
         | 
| 280 304 |  | 
| 281 | 
            -
             | 
| 282 | 
            -
             | 
| 283 | 
            -
             | 
| 305 | 
            +
                  class Advert < ActiveRecord::Base
         | 
| 306 | 
            +
                    fields do
         | 
| 307 | 
            +
                      description :text
         | 
| 308 | 
            +
                    end
         | 
| 284 309 | 
             
                  end
         | 
| 285 | 
            -
                end
         | 
| 286 310 |  | 
| 287 | 
            -
             | 
| 288 | 
            -
             | 
| 289 | 
            -
             | 
| 290 | 
            -
             | 
| 291 | 
            -
             | 
| 292 | 
            -
             | 
| 293 | 
            -
             | 
| 294 | 
            -
             | 
| 295 | 
            -
             | 
| 311 | 
            +
                  expect(Generators::DeclareSchema::Migration::Migrator.run).to(
         | 
| 312 | 
            +
                    migrate_up(<<~EOS.strip)
         | 
| 313 | 
            +
                      change_column :adverts, :description, :text, limit: 4294967295, null: false#{charset_and_collation}
         | 
| 314 | 
            +
                    EOS
         | 
| 315 | 
            +
                    .and migrate_down(<<~EOS.strip)
         | 
| 316 | 
            +
                      change_column :adverts, :description, :text#{', limit: 255' if defined?(Mysql2)}#{charset_and_collation}
         | 
| 317 | 
            +
                    EOS
         | 
| 318 | 
            +
                  )
         | 
| 319 | 
            +
             | 
| 320 | 
            +
                  # And migrate to a stated text limit that is the same as the unstated one:
         | 
| 321 | 
            +
             | 
| 322 | 
            +
                  class Advert < ActiveRecord::Base
         | 
| 323 | 
            +
                    fields do
         | 
| 324 | 
            +
                      description :text, limit: 0xffffffff
         | 
| 325 | 
            +
                    end
         | 
| 326 | 
            +
                  end
         | 
| 327 | 
            +
             | 
| 328 | 
            +
                  expect(Generators::DeclareSchema::Migration::Migrator.run).to(
         | 
| 329 | 
            +
                    migrate_up(<<~EOS.strip)
         | 
| 330 | 
            +
                      change_column :adverts, :description, :text, limit: 4294967295, null: false#{charset_and_collation}
         | 
| 331 | 
            +
                    EOS
         | 
| 332 | 
            +
                    .and migrate_down(<<~EOS.strip)
         | 
| 333 | 
            +
                      change_column :adverts, :description, :text#{', limit: 255' if defined?(Mysql2)}#{charset_and_collation}
         | 
| 334 | 
            +
                    EOS
         | 
| 335 | 
            +
                  )
         | 
| 336 | 
            +
                end
         | 
| 296 337 |  | 
| 297 338 | 
             
                Advert.field_specs.clear
         | 
| 298 339 | 
             
                Advert.connection.schema_cache.clear!
         | 
| 299 340 | 
             
                Advert.reset_column_information
         | 
| 300 341 | 
             
                class Advert < ActiveRecord::Base
         | 
| 301 342 | 
             
                  fields do
         | 
| 302 | 
            -
                    name :string, limit:  | 
| 343 | 
            +
                    name :string, limit: 250, null: true
         | 
| 303 344 | 
             
                  end
         | 
| 304 345 | 
             
                end
         | 
| 305 346 |  | 
| 306 347 | 
             
                up = Generators::DeclareSchema::Migration::Migrator.run.first
         | 
| 307 348 | 
             
                ActiveRecord::Migration.class_eval up
         | 
| 349 | 
            +
             | 
| 308 350 | 
             
                Advert.connection.schema_cache.clear!
         | 
| 309 351 | 
             
                Advert.reset_column_information
         | 
| 310 352 |  | 
| @@ -316,7 +358,7 @@ RSpec.describe 'DeclareSchema Migration Generator' do | |
| 316 358 | 
             
                class Category < ActiveRecord::Base; end
         | 
| 317 359 | 
             
                class Advert < ActiveRecord::Base
         | 
| 318 360 | 
             
                  fields do
         | 
| 319 | 
            -
                    name :string, limit:  | 
| 361 | 
            +
                    name :string, limit: 250, null: true
         | 
| 320 362 | 
             
                  end
         | 
| 321 363 | 
             
                  belongs_to :category
         | 
| 322 364 | 
             
                end
         | 
| @@ -326,11 +368,15 @@ RSpec.describe 'DeclareSchema Migration Generator' do | |
| 326 368 | 
             
                    add_column :adverts, :category_id, :integer, limit: 8, null: false
         | 
| 327 369 |  | 
| 328 370 | 
             
                    add_index :adverts, [:category_id], name: 'on_category_id'
         | 
| 371 | 
            +
             | 
| 372 | 
            +
                    #{"execute \"ALTER TABLE adverts ADD CONSTRAINT index_adverts_on_category_id FOREIGN KEY index_adverts_on_category_id(category_id) REFERENCES categories(id) \"\n" if defined?(Mysql2)}
         | 
| 329 373 | 
             
                  EOS
         | 
| 330 374 | 
             
                  .and migrate_down(<<~EOS.strip)
         | 
| 331 375 | 
             
                    remove_column :adverts, :category_id
         | 
| 332 376 |  | 
| 333 377 | 
             
                    remove_index :adverts, name: :on_category_id rescue ActiveRecord::StatementInvalid
         | 
| 378 | 
            +
             | 
| 379 | 
            +
                    #{"remove_foreign_key('adverts', name: '')\n" if defined?(Mysql2)}
         | 
| 334 380 | 
             
                  EOS
         | 
| 335 381 | 
             
                )
         | 
| 336 382 |  | 
| @@ -350,6 +396,9 @@ RSpec.describe 'DeclareSchema Migration Generator' do | |
| 350 396 | 
             
                    add_column :adverts, :c_id, :integer, limit: 8, null: false
         | 
| 351 397 |  | 
| 352 398 | 
             
                    add_index :adverts, [:c_id], name: 'on_c_id'
         | 
| 399 | 
            +
             | 
| 400 | 
            +
                    #{"execute \"ALTER TABLE adverts ADD CONSTRAINT index_adverts_on_category_id FOREIGN KEY index_adverts_on_category_id(category_id) REFERENCES categories(id) \"\n" +
         | 
| 401 | 
            +
                      "execute \"ALTER TABLE adverts ADD CONSTRAINT index_adverts_on_c_id FOREIGN KEY index_adverts_on_c_id(c_id) REFERENCES categories(id) \"" if defined?(Mysql2)}
         | 
| 353 402 | 
             
                  EOS
         | 
| 354 403 | 
             
                )
         | 
| 355 404 |  | 
| @@ -367,6 +416,9 @@ RSpec.describe 'DeclareSchema Migration Generator' do | |
| 367 416 | 
             
                expect(Generators::DeclareSchema::Migration::Migrator.run).to(
         | 
| 368 417 | 
             
                  migrate_up(<<~EOS.strip)
         | 
| 369 418 | 
             
                    add_column :adverts, :category_id, :integer, limit: 8, null: false
         | 
| 419 | 
            +
             | 
| 420 | 
            +
                    #{"execute \"ALTER TABLE adverts ADD CONSTRAINT index_adverts_on_category_id FOREIGN KEY index_adverts_on_category_id(category_id) REFERENCES categories(id) \"\n" +
         | 
| 421 | 
            +
                      "execute \"ALTER TABLE adverts ADD CONSTRAINT index_adverts_on_c_id FOREIGN KEY index_adverts_on_c_id(c_id) REFERENCES categories(id) \"" if defined?(Mysql2)}
         | 
| 370 422 | 
             
                  EOS
         | 
| 371 423 | 
             
                )
         | 
| 372 424 |  | 
| @@ -386,6 +438,9 @@ RSpec.describe 'DeclareSchema Migration Generator' do | |
| 386 438 | 
             
                    add_column :adverts, :category_id, :integer, limit: 8, null: false
         | 
| 387 439 |  | 
| 388 440 | 
             
                    add_index :adverts, [:category_id], name: 'my_index'
         | 
| 441 | 
            +
             | 
| 442 | 
            +
                    #{"execute \"ALTER TABLE adverts ADD CONSTRAINT index_adverts_on_category_id FOREIGN KEY index_adverts_on_category_id(category_id) REFERENCES categories(id) \"\n" +
         | 
| 443 | 
            +
                      "execute \"ALTER TABLE adverts ADD CONSTRAINT index_adverts_on_c_id FOREIGN KEY index_adverts_on_c_id(c_id) REFERENCES categories(id) \"" if defined?(Mysql2)}
         | 
| 389 444 | 
             
                  EOS
         | 
| 390 445 | 
             
                )
         | 
| 391 446 |  | 
| @@ -409,11 +464,17 @@ RSpec.describe 'DeclareSchema Migration Generator' do | |
| 409 464 | 
             
                    add_column :adverts, :created_at, :datetime
         | 
| 410 465 | 
             
                    add_column :adverts, :updated_at, :datetime
         | 
| 411 466 | 
             
                    add_column :adverts, :lock_version, :integer, null: false, default: 1
         | 
| 467 | 
            +
             | 
| 468 | 
            +
                    #{"execute \"ALTER TABLE adverts ADD CONSTRAINT index_adverts_on_category_id FOREIGN KEY index_adverts_on_category_id(category_id) REFERENCES categories(id) \"\n" +
         | 
| 469 | 
            +
                      "execute \"ALTER TABLE adverts ADD CONSTRAINT index_adverts_on_c_id FOREIGN KEY index_adverts_on_c_id(c_id) REFERENCES categories(id) \"" if defined?(Mysql2)}
         | 
| 412 470 | 
             
                  EOS
         | 
| 413 471 | 
             
                  .and migrate_down(<<~EOS.strip)
         | 
| 414 472 | 
             
                    remove_column :adverts, :created_at
         | 
| 415 473 | 
             
                    remove_column :adverts, :updated_at
         | 
| 416 474 | 
             
                    remove_column :adverts, :lock_version
         | 
| 475 | 
            +
             | 
| 476 | 
            +
                    #{"remove_foreign_key('adverts', name: '')\n" +
         | 
| 477 | 
            +
                      "remove_foreign_key('adverts', name: '')" if defined?(Mysql2)}
         | 
| 417 478 | 
             
                  EOS
         | 
| 418 479 | 
             
                )
         | 
| 419 480 |  | 
| @@ -427,15 +488,18 @@ RSpec.describe 'DeclareSchema Migration Generator' do | |
| 427 488 |  | 
| 428 489 | 
             
                class Advert < ActiveRecord::Base
         | 
| 429 490 | 
             
                  fields do
         | 
| 430 | 
            -
                    title :string, index: true, limit:  | 
| 491 | 
            +
                    title :string, index: true, limit: 250, null: true
         | 
| 431 492 | 
             
                  end
         | 
| 432 493 | 
             
                end
         | 
| 433 494 |  | 
| 434 495 | 
             
                expect(Generators::DeclareSchema::Migration::Migrator.run).to(
         | 
| 435 496 | 
             
                  migrate_up(<<~EOS.strip)
         | 
| 436 | 
            -
                    add_column :adverts, :title, :string, limit:  | 
| 497 | 
            +
                    add_column :adverts, :title, :string, limit: 250#{charset_and_collation}
         | 
| 437 498 |  | 
| 438 499 | 
             
                    add_index :adverts, [:title], name: 'on_title'
         | 
| 500 | 
            +
             | 
| 501 | 
            +
                    #{"execute \"ALTER TABLE adverts ADD CONSTRAINT index_adverts_on_category_id FOREIGN KEY index_adverts_on_category_id(category_id) REFERENCES categories(id) \"\n" +
         | 
| 502 | 
            +
                      "execute \"ALTER TABLE adverts ADD CONSTRAINT index_adverts_on_c_id FOREIGN KEY index_adverts_on_c_id(c_id) REFERENCES categories(id) \"" if defined?(Mysql2)}
         | 
| 439 503 | 
             
                  EOS
         | 
| 440 504 | 
             
                )
         | 
| 441 505 |  | 
| @@ -445,15 +509,18 @@ RSpec.describe 'DeclareSchema Migration Generator' do | |
| 445 509 |  | 
| 446 510 | 
             
                class Advert < ActiveRecord::Base
         | 
| 447 511 | 
             
                  fields do
         | 
| 448 | 
            -
                    title :string, index: true, unique: true, null: true, limit:  | 
| 512 | 
            +
                    title :string, index: true, unique: true, null: true, limit: 250
         | 
| 449 513 | 
             
                  end
         | 
| 450 514 | 
             
                end
         | 
| 451 515 |  | 
| 452 516 | 
             
                expect(Generators::DeclareSchema::Migration::Migrator.run).to(
         | 
| 453 517 | 
             
                  migrate_up(<<~EOS.strip)
         | 
| 454 | 
            -
                    add_column :adverts, :title, :string, limit:  | 
| 518 | 
            +
                    add_column :adverts, :title, :string, limit: 250#{charset_and_collation}
         | 
| 455 519 |  | 
| 456 520 | 
             
                    add_index :adverts, [:title], unique: true, name: 'on_title'
         | 
| 521 | 
            +
             | 
| 522 | 
            +
                    #{"execute \"ALTER TABLE adverts ADD CONSTRAINT index_adverts_on_category_id FOREIGN KEY index_adverts_on_category_id(category_id) REFERENCES categories(id) \"\n" +
         | 
| 523 | 
            +
                      "execute \"ALTER TABLE adverts ADD CONSTRAINT index_adverts_on_c_id FOREIGN KEY index_adverts_on_c_id(c_id) REFERENCES categories(id) \"" if defined?(Mysql2)}
         | 
| 457 524 | 
             
                  EOS
         | 
| 458 525 | 
             
                )
         | 
| 459 526 |  | 
| @@ -463,15 +530,18 @@ RSpec.describe 'DeclareSchema Migration Generator' do | |
| 463 530 |  | 
| 464 531 | 
             
                class Advert < ActiveRecord::Base
         | 
| 465 532 | 
             
                  fields do
         | 
| 466 | 
            -
                    title :string, index: 'my_index', limit:  | 
| 533 | 
            +
                    title :string, index: 'my_index', limit: 250, null: true
         | 
| 467 534 | 
             
                  end
         | 
| 468 535 | 
             
                end
         | 
| 469 536 |  | 
| 470 537 | 
             
                expect(Generators::DeclareSchema::Migration::Migrator.run).to(
         | 
| 471 538 | 
             
                  migrate_up(<<~EOS.strip)
         | 
| 472 | 
            -
                    add_column :adverts, :title, :string, limit:  | 
| 539 | 
            +
                    add_column :adverts, :title, :string, limit: 250#{charset_and_collation}
         | 
| 473 540 |  | 
| 474 541 | 
             
                    add_index :adverts, [:title], name: 'my_index'
         | 
| 542 | 
            +
             | 
| 543 | 
            +
                    #{"execute \"ALTER TABLE adverts ADD CONSTRAINT index_adverts_on_category_id FOREIGN KEY index_adverts_on_category_id(category_id) REFERENCES categories(id) \"\n" +
         | 
| 544 | 
            +
                      "execute \"ALTER TABLE adverts ADD CONSTRAINT index_adverts_on_c_id FOREIGN KEY index_adverts_on_c_id(c_id) REFERENCES categories(id) \"" if defined?(Mysql2)}
         | 
| 475 545 | 
             
                  EOS
         | 
| 476 546 | 
             
                )
         | 
| 477 547 |  | 
| @@ -485,9 +555,12 @@ RSpec.describe 'DeclareSchema Migration Generator' do | |
| 485 555 |  | 
| 486 556 | 
             
                expect(Generators::DeclareSchema::Migration::Migrator.run).to(
         | 
| 487 557 | 
             
                  migrate_up(<<~EOS.strip)
         | 
| 488 | 
            -
                    add_column :adverts, :title, :string, limit:  | 
| 558 | 
            +
                    add_column :adverts, :title, :string, limit: 250#{charset_and_collation}
         | 
| 489 559 |  | 
| 490 560 | 
             
                    add_index :adverts, [:title], name: 'on_title'
         | 
| 561 | 
            +
             | 
| 562 | 
            +
                    #{"execute \"ALTER TABLE adverts ADD CONSTRAINT index_adverts_on_category_id FOREIGN KEY index_adverts_on_category_id(category_id) REFERENCES categories(id) \"\n" +
         | 
| 563 | 
            +
                      "execute \"ALTER TABLE adverts ADD CONSTRAINT index_adverts_on_c_id FOREIGN KEY index_adverts_on_c_id(c_id) REFERENCES categories(id) \"" if defined?(Mysql2)}
         | 
| 491 564 | 
             
                  EOS
         | 
| 492 565 | 
             
                )
         | 
| 493 566 |  | 
| @@ -501,9 +574,12 @@ RSpec.describe 'DeclareSchema Migration Generator' do | |
| 501 574 |  | 
| 502 575 | 
             
                expect(Generators::DeclareSchema::Migration::Migrator.run).to(
         | 
| 503 576 | 
             
                  migrate_up(<<~EOS.strip)
         | 
| 504 | 
            -
                    add_column :adverts, :title, :string, limit:  | 
| 577 | 
            +
                    add_column :adverts, :title, :string, limit: 250#{charset_and_collation}
         | 
| 505 578 |  | 
| 506 579 | 
             
                    add_index :adverts, [:title], unique: true, name: 'my_index'
         | 
| 580 | 
            +
             | 
| 581 | 
            +
                    #{"execute \"ALTER TABLE adverts ADD CONSTRAINT index_adverts_on_category_id FOREIGN KEY index_adverts_on_category_id(category_id) REFERENCES categories(id) \"\n" +
         | 
| 582 | 
            +
                      "execute \"ALTER TABLE adverts ADD CONSTRAINT index_adverts_on_c_id FOREIGN KEY index_adverts_on_c_id(c_id) REFERENCES categories(id) \"" if defined?(Mysql2)}
         | 
| 507 583 | 
             
                  EOS
         | 
| 508 584 | 
             
                )
         | 
| 509 585 |  | 
| @@ -517,9 +593,12 @@ RSpec.describe 'DeclareSchema Migration Generator' do | |
| 517 593 |  | 
| 518 594 | 
             
                expect(Generators::DeclareSchema::Migration::Migrator.run).to(
         | 
| 519 595 | 
             
                  migrate_up(<<~EOS.strip)
         | 
| 520 | 
            -
                    add_column :adverts, :title, :string, limit:  | 
| 596 | 
            +
                    add_column :adverts, :title, :string, limit: 250#{charset_and_collation}
         | 
| 521 597 |  | 
| 522 598 | 
             
                    add_index :adverts, [:title, :category_id], name: 'on_title_and_category_id'
         | 
| 599 | 
            +
             | 
| 600 | 
            +
                    #{"execute \"ALTER TABLE adverts ADD CONSTRAINT index_adverts_on_category_id FOREIGN KEY index_adverts_on_category_id(category_id) REFERENCES categories(id) \"\n" +
         | 
| 601 | 
            +
                      "execute \"ALTER TABLE adverts ADD CONSTRAINT index_adverts_on_c_id FOREIGN KEY index_adverts_on_c_id(c_id) REFERENCES categories(id) \"" if defined?(Mysql2)}
         | 
| 523 602 | 
             
                  EOS
         | 
| 524 603 | 
             
                )
         | 
| 525 604 |  | 
| @@ -536,7 +615,7 @@ RSpec.describe 'DeclareSchema Migration Generator' do | |
| 536 615 | 
             
                class Advert < ActiveRecord::Base
         | 
| 537 616 | 
             
                  self.table_name = "ads"
         | 
| 538 617 | 
             
                  fields do
         | 
| 539 | 
            -
                    title :string, limit:  | 
| 618 | 
            +
                    title :string, limit: 250, null: true
         | 
| 540 619 | 
             
                    body :text, null: true
         | 
| 541 620 | 
             
                  end
         | 
| 542 621 | 
             
                end
         | 
| @@ -548,10 +627,15 @@ RSpec.describe 'DeclareSchema Migration Generator' do | |
| 548 627 | 
             
                  migrate_up(<<~EOS.strip)
         | 
| 549 628 | 
             
                    rename_table :adverts, :ads
         | 
| 550 629 |  | 
| 551 | 
            -
                    add_column :ads, :title, :string, limit:  | 
| 552 | 
            -
                    add_column :ads, :body, :text
         | 
| 630 | 
            +
                    add_column :ads, :title, :string, limit: 250#{charset_and_collation}
         | 
| 631 | 
            +
                    add_column :ads, :body, :text#{', limit: 4294967295' if defined?(Mysql2)}#{charset_and_collation}
         | 
| 553 632 |  | 
| 554 | 
            -
                     | 
| 633 | 
            +
                    #{if defined?(SQLite3)
         | 
| 634 | 
            +
                        "add_index :ads, [:id], unique: true, name: 'PRIMARY'\n"
         | 
| 635 | 
            +
                      elsif defined?(Mysql2)
         | 
| 636 | 
            +
                        "execute \"ALTER TABLE ads DROP PRIMARY KEY, ADD PRIMARY KEY (id)\"\n\n" +
         | 
| 637 | 
            +
                        "execute \"ALTER TABLE adverts ADD CONSTRAINT index_adverts_on_category_id FOREIGN KEY index_adverts_on_category_id(category_id) REFERENCES categories(id) \"\nexecute \"ALTER TABLE adverts ADD CONSTRAINT index_adverts_on_c_id FOREIGN KEY index_adverts_on_c_id(c_id) REFERENCES categories(id) \""
         | 
| 638 | 
            +
                      end}
         | 
| 555 639 | 
             
                  EOS
         | 
| 556 640 | 
             
                  .and migrate_down(<<~EOS.strip)
         | 
| 557 641 | 
             
                    remove_column :ads, :title
         | 
| @@ -559,14 +643,20 @@ RSpec.describe 'DeclareSchema Migration Generator' do | |
| 559 643 |  | 
| 560 644 | 
             
                    rename_table :ads, :adverts
         | 
| 561 645 |  | 
| 562 | 
            -
                     | 
| 646 | 
            +
                    #{if defined?(SQLite3)
         | 
| 647 | 
            +
                        "add_index :adverts, [:id], unique: true, name: 'PRIMARY'\n"
         | 
| 648 | 
            +
                      elsif defined?(Mysql2)
         | 
| 649 | 
            +
                        "execute \"ALTER TABLE adverts DROP PRIMARY KEY, ADD PRIMARY KEY (id)\"\n\n" +
         | 
| 650 | 
            +
                        "remove_foreign_key('adverts', name: '')\n" +
         | 
| 651 | 
            +
                        "remove_foreign_key('adverts', name: '')"
         | 
| 652 | 
            +
                      end}
         | 
| 563 653 | 
             
                  EOS
         | 
| 564 654 | 
             
                )
         | 
| 565 655 |  | 
| 566 656 | 
             
                # Set the table name back to what it should be and confirm we're in sync:
         | 
| 567 657 |  | 
| 568 | 
            -
                Advert | 
| 569 | 
            -
             | 
| 658 | 
            +
                nuke_model_class(Advert)
         | 
| 659 | 
            +
             | 
| 570 660 | 
             
                class Advert < ActiveRecord::Base
         | 
| 571 661 | 
             
                  self.table_name = "adverts"
         | 
| 572 662 | 
             
                end
         | 
| @@ -581,7 +671,7 @@ RSpec.describe 'DeclareSchema Migration Generator' do | |
| 581 671 |  | 
| 582 672 | 
             
                class Advertisement < ActiveRecord::Base
         | 
| 583 673 | 
             
                  fields do
         | 
| 584 | 
            -
                    title :string, limit:  | 
| 674 | 
            +
                    title :string, limit: 250, null: true
         | 
| 585 675 | 
             
                    body :text, null: true
         | 
| 586 676 | 
             
                  end
         | 
| 587 677 | 
             
                end
         | 
| @@ -590,20 +680,28 @@ RSpec.describe 'DeclareSchema Migration Generator' do | |
| 590 680 | 
             
                  migrate_up(<<~EOS.strip)
         | 
| 591 681 | 
             
                    rename_table :adverts, :advertisements
         | 
| 592 682 |  | 
| 593 | 
            -
                    add_column :advertisements, :title, :string, limit:  | 
| 594 | 
            -
                    add_column :advertisements, :body, :text
         | 
| 683 | 
            +
                    add_column :advertisements, :title, :string, limit: 250#{charset_and_collation}
         | 
| 684 | 
            +
                    add_column :advertisements, :body, :text#{', limit: 4294967295' if defined?(Mysql2)}#{charset_and_collation}
         | 
| 595 685 | 
             
                    remove_column :advertisements, :name
         | 
| 596 686 |  | 
| 597 | 
            -
                     | 
| 687 | 
            +
                    #{if defined?(SQLite3)
         | 
| 688 | 
            +
                        "add_index :advertisements, [:id], unique: true, name: 'PRIMARY'"
         | 
| 689 | 
            +
                      elsif defined?(Mysql2)
         | 
| 690 | 
            +
                        "execute \"ALTER TABLE advertisements DROP PRIMARY KEY, ADD PRIMARY KEY (id)\""
         | 
| 691 | 
            +
                      end}
         | 
| 598 692 | 
             
                  EOS
         | 
| 599 693 | 
             
                  .and migrate_down(<<~EOS.strip)
         | 
| 600 694 | 
             
                    remove_column :advertisements, :title
         | 
| 601 695 | 
             
                    remove_column :advertisements, :body
         | 
| 602 | 
            -
                    add_column :adverts, :name, :string, limit:  | 
| 696 | 
            +
                    add_column :adverts, :name, :string, limit: 250#{charset_and_collation}
         | 
| 603 697 |  | 
| 604 698 | 
             
                    rename_table :advertisements, :adverts
         | 
| 605 699 |  | 
| 606 | 
            -
                     | 
| 700 | 
            +
                    #{if defined?(SQLite3)
         | 
| 701 | 
            +
                        "add_index :adverts, [:id], unique: true, name: 'PRIMARY'"
         | 
| 702 | 
            +
                      elsif defined?(Mysql2)
         | 
| 703 | 
            +
                        "execute \"ALTER TABLE adverts DROP PRIMARY KEY, ADD PRIMARY KEY (id)\""
         | 
| 704 | 
            +
                      end}
         | 
| 607 705 | 
             
                  EOS
         | 
| 608 706 | 
             
                )
         | 
| 609 707 |  | 
| @@ -615,23 +713,15 @@ RSpec.describe 'DeclareSchema Migration Generator' do | |
| 615 713 |  | 
| 616 714 | 
             
                # Dropping tables is where the automatic down-migration really comes in handy:
         | 
| 617 715 |  | 
| 618 | 
            -
                rails4_table_create = <<~EOS.strip
         | 
| 619 | 
            -
                  create_table "adverts", force: :cascade do |t|
         | 
| 620 | 
            -
                    t.string "name", limit: 255
         | 
| 621 | 
            -
                  end
         | 
| 622 | 
            -
                EOS
         | 
| 623 | 
            -
             | 
| 624 | 
            -
                rails5_table_create = <<~EOS.strip
         | 
| 625 | 
            -
                  create_table "adverts", id: :integer, force: :cascade do |t|
         | 
| 626 | 
            -
                    t.string "name", limit: 255
         | 
| 627 | 
            -
                  end
         | 
| 628 | 
            -
                EOS
         | 
| 629 | 
            -
             | 
| 630 716 | 
             
                expect(Generators::DeclareSchema::Migration::Migrator.run).to(
         | 
| 631 717 | 
             
                  migrate_up(<<~EOS.strip)
         | 
| 632 718 | 
             
                    drop_table :adverts
         | 
| 633 719 | 
             
                  EOS
         | 
| 634 | 
            -
                  .and migrate_down( | 
| 720 | 
            +
                  .and migrate_down(<<~EOS.strip)
         | 
| 721 | 
            +
                    create_table "adverts"#{table_options}, force: :cascade do |t|
         | 
| 722 | 
            +
                      t.string "name", limit: 250#{charset_and_collation}
         | 
| 723 | 
            +
                    end
         | 
| 724 | 
            +
                  EOS
         | 
| 635 725 | 
             
                )
         | 
| 636 726 |  | 
| 637 727 | 
             
                ## STI
         | 
| @@ -643,7 +733,7 @@ RSpec.describe 'DeclareSchema Migration Generator' do | |
| 643 733 | 
             
                class Advert < ActiveRecord::Base
         | 
| 644 734 | 
             
                  fields do
         | 
| 645 735 | 
             
                    body :text, null: true
         | 
| 646 | 
            -
                    title :string, default: "Untitled", limit:  | 
| 736 | 
            +
                    title :string, default: "Untitled", limit: 250, null: true
         | 
| 647 737 | 
             
                  end
         | 
| 648 738 | 
             
                end
         | 
| 649 739 | 
             
                up = Generators::DeclareSchema::Migration::Migrator.run.first
         | 
| @@ -657,7 +747,7 @@ RSpec.describe 'DeclareSchema Migration Generator' do | |
| 657 747 | 
             
                up, _ = Generators::DeclareSchema::Migration::Migrator.run do |migrations|
         | 
| 658 748 | 
             
                  expect(migrations).to(
         | 
| 659 749 | 
             
                    migrate_up(<<~EOS.strip)
         | 
| 660 | 
            -
                      add_column :adverts, :type, :string, limit:  | 
| 750 | 
            +
                      add_column :adverts, :type, :string, limit: 250#{charset_and_collation}
         | 
| 661 751 |  | 
| 662 752 | 
             
                      add_index :adverts, [:type], name: 'on_type'
         | 
| 663 753 | 
             
                    EOS
         | 
| @@ -696,7 +786,7 @@ RSpec.describe 'DeclareSchema Migration Generator' do | |
| 696 786 |  | 
| 697 787 | 
             
                class Advert < ActiveRecord::Base
         | 
| 698 788 | 
             
                  fields do
         | 
| 699 | 
            -
                    name :string, default: "No Name", limit:  | 
| 789 | 
            +
                    name :string, default: "No Name", limit: 250, null: true
         | 
| 700 790 | 
             
                    body :text, null: true
         | 
| 701 791 | 
             
                  end
         | 
| 702 792 | 
             
                end
         | 
| @@ -704,11 +794,11 @@ RSpec.describe 'DeclareSchema Migration Generator' do | |
| 704 794 | 
             
                expect(Generators::DeclareSchema::Migration::Migrator.run(adverts: { title: :name })).to(
         | 
| 705 795 | 
             
                  migrate_up(<<~EOS.strip)
         | 
| 706 796 | 
             
                    rename_column :adverts, :title, :name
         | 
| 707 | 
            -
                    change_column :adverts, :name, :string, limit:  | 
| 797 | 
            +
                    change_column :adverts, :name, :string, limit: 250, default: "No Name"#{charset_and_collation}
         | 
| 708 798 | 
             
                  EOS
         | 
| 709 799 | 
             
                  .and migrate_down(<<~EOS.strip)
         | 
| 710 800 | 
             
                    rename_column :adverts, :name, :title
         | 
| 711 | 
            -
                    change_column :adverts, :title, :string, limit:  | 
| 801 | 
            +
                    change_column :adverts, :title, :string, limit: 250, default: "Untitled"#{charset_and_collation}
         | 
| 712 802 | 
             
                  EOS
         | 
| 713 803 | 
             
                )
         | 
| 714 804 |  | 
| @@ -717,7 +807,7 @@ RSpec.describe 'DeclareSchema Migration Generator' do | |
| 717 807 | 
             
                nuke_model_class(Advert)
         | 
| 718 808 | 
             
                class Ad < ActiveRecord::Base
         | 
| 719 809 | 
             
                  fields do
         | 
| 720 | 
            -
                    title      :string, default: "Untitled", limit:  | 
| 810 | 
            +
                    title      :string, default: "Untitled", limit: 250
         | 
| 721 811 | 
             
                    body       :text, null: true
         | 
| 722 812 | 
             
                    created_at :datetime
         | 
| 723 813 | 
             
                  end
         | 
| @@ -728,16 +818,20 @@ RSpec.describe 'DeclareSchema Migration Generator' do | |
| 728 818 | 
             
                    rename_table :adverts, :ads
         | 
| 729 819 |  | 
| 730 820 | 
             
                    add_column :ads, :created_at, :datetime, null: false
         | 
| 731 | 
            -
                    change_column :ads, :title, :string, limit:  | 
| 821 | 
            +
                    change_column :ads, :title, :string, limit: 250, null: false, default: \"Untitled\"#{charset_and_collation}
         | 
| 732 822 |  | 
| 733 | 
            -
                     | 
| 823 | 
            +
                    #{if defined?(SQLite3)
         | 
| 824 | 
            +
                        "add_index :ads, [:id], unique: true, name: 'PRIMARY'"
         | 
| 825 | 
            +
                      elsif defined?(Mysql2)
         | 
| 826 | 
            +
                        'execute "ALTER TABLE ads DROP PRIMARY KEY, ADD PRIMARY KEY (id)"'
         | 
| 827 | 
            +
                      end}
         | 
| 734 828 | 
             
                  EOS
         | 
| 735 829 | 
             
                )
         | 
| 736 830 |  | 
| 737 831 | 
             
                class Advert < ActiveRecord::Base
         | 
| 738 832 | 
             
                  fields do
         | 
| 739 833 | 
             
                    body :text, null: true
         | 
| 740 | 
            -
                    title :string, default: "Untitled", limit:  | 
| 834 | 
            +
                    title :string, default: "Untitled", limit: 250, null: true
         | 
| 741 835 | 
             
                  end
         | 
| 742 836 | 
             
                end
         | 
| 743 837 |  | 
| @@ -758,7 +852,11 @@ RSpec.describe 'DeclareSchema Migration Generator' do | |
| 758 852 | 
             
                  migrate_up(<<~EOS.strip)
         | 
| 759 853 | 
             
                    rename_column :adverts, :id, :advert_id
         | 
| 760 854 |  | 
| 761 | 
            -
                     | 
| 855 | 
            +
                    #{if defined?(SQLite3)
         | 
| 856 | 
            +
                        "add_index :adverts, [:advert_id], unique: true, name: 'PRIMARY'"
         | 
| 857 | 
            +
                      elsif defined?(Mysql2)
         | 
| 858 | 
            +
                      'execute "ALTER TABLE adverts DROP PRIMARY KEY, ADD PRIMARY KEY (advert_id)"'
         | 
| 859 | 
            +
                      end}
         | 
| 762 860 | 
             
                  EOS
         | 
| 763 861 | 
             
                )
         | 
| 764 862 |  | 
| @@ -771,7 +869,7 @@ RSpec.describe 'DeclareSchema Migration Generator' do | |
| 771 869 |  | 
| 772 870 | 
             
                class User < ActiveRecord::Base
         | 
| 773 871 | 
             
                  fields do
         | 
| 774 | 
            -
                    company :string, limit:  | 
| 872 | 
            +
                    company :string, limit: 250, ruby_default: -> { "BigCorp" }
         | 
| 775 873 | 
             
                  end
         | 
| 776 874 | 
             
                end
         | 
| 777 875 | 
             
                expect(User.field_specs.keys).to eq(['company'])
         | 
| @@ -790,7 +888,7 @@ RSpec.describe 'DeclareSchema Migration Generator' do | |
| 790 888 | 
             
                expect(Ad).to receive(:validates).with(:company, presence: true, uniqueness: { case_sensitive: false })
         | 
| 791 889 | 
             
                class Ad < ActiveRecord::Base
         | 
| 792 890 | 
             
                  fields do
         | 
| 793 | 
            -
                    company :string, limit:  | 
| 891 | 
            +
                    company :string, limit: 250, index: true, unique: true, validates: { presence: true, uniqueness: { case_sensitive: false } }
         | 
| 794 892 | 
             
                  end
         | 
| 795 893 | 
             
                  self.primary_key = "advert_id"
         | 
| 796 894 | 
             
                end
         | 
| @@ -828,10 +926,10 @@ RSpec.describe 'DeclareSchema Migration Generator' do | |
| 828 926 | 
             
                  it 'converts defaults with .to_yaml' do
         | 
| 829 927 | 
             
                    class Ad < ActiveRecord::Base
         | 
| 830 928 | 
             
                      fields do
         | 
| 831 | 
            -
                        allow_list :string, limit:  | 
| 832 | 
            -
                        allow_hash :string, limit:  | 
| 833 | 
            -
                        allow_string :string, limit:  | 
| 834 | 
            -
                        allow_null :string, limit:  | 
| 929 | 
            +
                        allow_list :string, limit: 250, serialize: true, null: true, default: []
         | 
| 930 | 
            +
                        allow_hash :string, limit: 250, serialize: true, null: true, default: {}
         | 
| 931 | 
            +
                        allow_string :string, limit: 250, serialize: true, null: true, default: ['abc']
         | 
| 932 | 
            +
                        allow_null :string, limit: 250, serialize: true, null: true, default: nil
         | 
| 835 933 | 
             
                      end
         | 
| 836 934 | 
             
                    end
         | 
| 837 935 |  | 
| @@ -846,7 +944,7 @@ RSpec.describe 'DeclareSchema Migration Generator' do | |
| 846 944 | 
             
                  it 'allows serialize: Array' do
         | 
| 847 945 | 
             
                    class Ad < ActiveRecord::Base
         | 
| 848 946 | 
             
                      fields do
         | 
| 849 | 
            -
                        allow_list :string, limit:  | 
| 947 | 
            +
                        allow_list :string, limit: 250, serialize: Array, null: true
         | 
| 850 948 | 
             
                      end
         | 
| 851 949 | 
             
                    end
         | 
| 852 950 |  | 
| @@ -856,10 +954,10 @@ RSpec.describe 'DeclareSchema Migration Generator' do | |
| 856 954 | 
             
                  it 'allows Array defaults' do
         | 
| 857 955 | 
             
                    class Ad < ActiveRecord::Base
         | 
| 858 956 | 
             
                      fields do
         | 
| 859 | 
            -
                        allow_list :string, limit:  | 
| 860 | 
            -
                        allow_string :string, limit:  | 
| 861 | 
            -
                        allow_empty :string, limit:  | 
| 862 | 
            -
                        allow_null :string, limit:  | 
| 957 | 
            +
                        allow_list :string, limit: 250, serialize: Array, null: true, default: [2]
         | 
| 958 | 
            +
                        allow_string :string, limit: 250, serialize: Array, null: true, default: ['abc']
         | 
| 959 | 
            +
                        allow_empty :string, limit: 250, serialize: Array, null: true, default: []
         | 
| 960 | 
            +
                        allow_null :string, limit: 250, serialize: Array, null: true, default: nil
         | 
| 863 961 | 
             
                      end
         | 
| 864 962 | 
             
                    end
         | 
| 865 963 |  | 
| @@ -874,7 +972,7 @@ RSpec.describe 'DeclareSchema Migration Generator' do | |
| 874 972 | 
             
                  it 'allows serialize: Hash' do
         | 
| 875 973 | 
             
                    class Ad < ActiveRecord::Base
         | 
| 876 974 | 
             
                      fields do
         | 
| 877 | 
            -
                        allow_list :string, limit:  | 
| 975 | 
            +
                        allow_list :string, limit: 250, serialize: Hash, null: true
         | 
| 878 976 | 
             
                      end
         | 
| 879 977 | 
             
                    end
         | 
| 880 978 |  | 
| @@ -884,9 +982,9 @@ RSpec.describe 'DeclareSchema Migration Generator' do | |
| 884 982 | 
             
                  it 'allows Hash defaults' do
         | 
| 885 983 | 
             
                    class Ad < ActiveRecord::Base
         | 
| 886 984 | 
             
                      fields do
         | 
| 887 | 
            -
                        allow_loc :string, limit:  | 
| 888 | 
            -
                        allow_hash :string, limit:  | 
| 889 | 
            -
                        allow_null :string, limit:  | 
| 985 | 
            +
                        allow_loc :string, limit: 250, serialize: Hash, null: true, default: { 'state' => 'CA' }
         | 
| 986 | 
            +
                        allow_hash :string, limit: 250, serialize: Hash, null: true, default: {}
         | 
| 987 | 
            +
                        allow_null :string, limit: 250, serialize: Hash, null: true, default: nil
         | 
| 890 988 | 
             
                      end
         | 
| 891 989 | 
             
                    end
         | 
| 892 990 |  | 
| @@ -900,7 +998,7 @@ RSpec.describe 'DeclareSchema Migration Generator' do | |
| 900 998 | 
             
                  it 'allows serialize: JSON' do
         | 
| 901 999 | 
             
                    class Ad < ActiveRecord::Base
         | 
| 902 1000 | 
             
                      fields do
         | 
| 903 | 
            -
                        allow_list :string, limit:  | 
| 1001 | 
            +
                        allow_list :string, limit: 250, serialize: JSON
         | 
| 904 1002 | 
             
                      end
         | 
| 905 1003 | 
             
                    end
         | 
| 906 1004 |  | 
| @@ -910,10 +1008,10 @@ RSpec.describe 'DeclareSchema Migration Generator' do | |
| 910 1008 | 
             
                  it 'allows JSON defaults' do
         | 
| 911 1009 | 
             
                    class Ad < ActiveRecord::Base
         | 
| 912 1010 | 
             
                      fields do
         | 
| 913 | 
            -
                        allow_hash :string, limit:  | 
| 914 | 
            -
                        allow_empty_array :string, limit:  | 
| 915 | 
            -
                        allow_empty_hash :string, limit:  | 
| 916 | 
            -
                        allow_null :string, limit:  | 
| 1011 | 
            +
                        allow_hash :string, limit: 250, serialize: JSON, null: true, default: { 'state' => 'CA' }
         | 
| 1012 | 
            +
                        allow_empty_array :string, limit: 250, serialize: JSON, null: true, default: []
         | 
| 1013 | 
            +
                        allow_empty_hash :string, limit: 250, serialize: JSON, null: true, default: {}
         | 
| 1014 | 
            +
                        allow_null :string, limit: 250, serialize: JSON, null: true, default: nil
         | 
| 917 1015 | 
             
                      end
         | 
| 918 1016 | 
             
                    end
         | 
| 919 1017 |  | 
| @@ -950,7 +1048,7 @@ RSpec.describe 'DeclareSchema Migration Generator' do | |
| 950 1048 | 
             
                  it 'allows serialize: ValueClass' do
         | 
| 951 1049 | 
             
                    class Ad < ActiveRecord::Base
         | 
| 952 1050 | 
             
                      fields do
         | 
| 953 | 
            -
                        allow_list :string, limit:  | 
| 1051 | 
            +
                        allow_list :string, limit: 250, serialize: ValueClass
         | 
| 954 1052 | 
             
                      end
         | 
| 955 1053 | 
             
                    end
         | 
| 956 1054 |  | 
| @@ -960,9 +1058,9 @@ RSpec.describe 'DeclareSchema Migration Generator' do | |
| 960 1058 | 
             
                  it 'allows ValueClass defaults' do
         | 
| 961 1059 | 
             
                    class Ad < ActiveRecord::Base
         | 
| 962 1060 | 
             
                      fields do
         | 
| 963 | 
            -
                        allow_hash :string, limit:  | 
| 964 | 
            -
                        allow_empty_array :string, limit:  | 
| 965 | 
            -
                        allow_null :string, limit:  | 
| 1061 | 
            +
                        allow_hash :string, limit: 250, serialize: ValueClass, null: true, default: ValueClass.new([2])
         | 
| 1062 | 
            +
                        allow_empty_array :string, limit: 250, serialize: ValueClass, null: true, default: ValueClass.new([])
         | 
| 1063 | 
            +
                        allow_null :string, limit: 250, serialize: ValueClass, null: true, default: nil
         | 
| 966 1064 | 
             
                      end
         | 
| 967 1065 | 
             
                    end
         | 
| 968 1066 |  | 
| @@ -1003,7 +1101,7 @@ RSpec.describe 'DeclareSchema Migration Generator' do | |
| 1003 1101 |  | 
| 1004 1102 | 
             
                    class Advert < ActiveRecord::Base
         | 
| 1005 1103 | 
             
                      fields do
         | 
| 1006 | 
            -
                        name :string, limit:  | 
| 1104 | 
            +
                        name :string, limit: 250, null: true
         | 
| 1007 1105 | 
             
                        category_id :integer, limit: 8
         | 
| 1008 1106 | 
             
                        nullable_category_id :integer, limit: 8, null: true
         | 
| 1009 1107 | 
             
                      end
         | 
| @@ -1093,4 +1191,33 @@ RSpec.describe 'DeclareSchema Migration Generator' do | |
| 1093 1191 | 
             
                  expect(base_class).to eq("(Rails::VERSION::MAJOR >= 5 ? ActiveRecord::Migration[4.2] : ActiveRecord::Migration)")
         | 
| 1094 1192 | 
             
                end
         | 
| 1095 1193 | 
             
              end
         | 
| 1194 | 
            +
             | 
| 1195 | 
            +
              context 'Does not generate migrations' do
         | 
| 1196 | 
            +
                it 'for aliased fields bigint -> integer limit 8' do
         | 
| 1197 | 
            +
                  if Rails::VERSION::MAJOR >= 5 || !ActiveRecord::Base.connection.class.name.match?(/SQLite3Adapter/)
         | 
| 1198 | 
            +
                    class Advert < active_record_base_class.constantize
         | 
| 1199 | 
            +
                      fields do
         | 
| 1200 | 
            +
                        price :bigint
         | 
| 1201 | 
            +
                      end
         | 
| 1202 | 
            +
                    end
         | 
| 1203 | 
            +
             | 
| 1204 | 
            +
                    generate_migrations '-n', '-m'
         | 
| 1205 | 
            +
             | 
| 1206 | 
            +
                    migrations = Dir.glob('db/migrate/*declare_schema_migration*.rb')
         | 
| 1207 | 
            +
                    expect(migrations.size).to eq(1), migrations.inspect
         | 
| 1208 | 
            +
             | 
| 1209 | 
            +
                    if defined?(Mysql2) && Rails::VERSION::MAJOR < 5
         | 
| 1210 | 
            +
                      ActiveRecord::Base.connection.execute("ALTER TABLE adverts ADD PRIMARY KEY (id)")
         | 
| 1211 | 
            +
                    end
         | 
| 1212 | 
            +
             | 
| 1213 | 
            +
                    class Advert < active_record_base_class.constantize
         | 
| 1214 | 
            +
                      fields do
         | 
| 1215 | 
            +
                        price :integer, limit: 8
         | 
| 1216 | 
            +
                      end
         | 
| 1217 | 
            +
                    end
         | 
| 1218 | 
            +
             | 
| 1219 | 
            +
                    expect { generate_migrations '-n', '-g' }.to output("Database and models match -- nothing to change\n").to_stdout
         | 
| 1220 | 
            +
                  end
         | 
| 1221 | 
            +
                end
         | 
| 1222 | 
            +
              end
         | 
| 1096 1223 | 
             
            end
         |