declare_schema 0.6.0 → 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 +21 -5
- data/Appraisals +21 -4
- data/CHANGELOG.md +9 -0
- data/Gemfile +0 -2
- data/Gemfile.lock +1 -5
- data/README.md +3 -3
- 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/field_spec.rb +11 -11
- 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 +74 -26
- data/spec/lib/declare_schema/generator_spec.rb +4 -2
- data/spec/lib/declare_schema/interactive_primary_key_spec.rb +8 -2
- data/spec/lib/declare_schema/migration_generator_spec.rb +260 -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 +12 -9
@@ -71,8 +71,8 @@ module Generators
|
|
71
71
|
class Migrator
|
72
72
|
class Error < RuntimeError; end
|
73
73
|
|
74
|
-
DEFAULT_CHARSET =
|
75
|
-
DEFAULT_COLLATION =
|
74
|
+
DEFAULT_CHARSET = "utf8mb4"
|
75
|
+
DEFAULT_COLLATION = "utf8mb4_bin"
|
76
76
|
|
77
77
|
@ignore_models = []
|
78
78
|
@ignore_tables = []
|
@@ -82,9 +82,18 @@ module Generators
|
|
82
82
|
@default_collation = DEFAULT_COLLATION
|
83
83
|
|
84
84
|
class << self
|
85
|
-
attr_accessor :ignore_models, :ignore_tables, :disable_indexing, :disable_constraints
|
86
|
-
|
87
|
-
|
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
|
88
97
|
|
89
98
|
def active_record_class
|
90
99
|
@active_record_class.is_a?(Class) or @active_record_class = @active_record_class.to_s.constantize
|
@@ -425,7 +434,7 @@ module Generators
|
|
425
434
|
else
|
426
435
|
[":integer"]
|
427
436
|
end
|
428
|
-
"add_column :#{new_table_name}, :#{c},
|
437
|
+
["add_column :#{new_table_name}, :#{c}", *args].join(', ')
|
429
438
|
end
|
430
439
|
undo_adds = to_add.map do |c|
|
431
440
|
"remove_column :#{new_table_name}, :#{c}"
|
@@ -454,8 +463,8 @@ module Generators
|
|
454
463
|
change_spec[:scale] = spec.scale unless spec.scale.nil?
|
455
464
|
change_spec[:null] = spec.null unless spec.null && col.null
|
456
465
|
change_spec[:default] = spec.default unless spec.default.nil? && col.default.nil?
|
457
|
-
change_spec[:collation] = spec.collation unless spec.collation.nil?
|
458
466
|
change_spec[:charset] = spec.charset unless spec.charset.nil?
|
467
|
+
change_spec[:collation] = spec.collation unless spec.collation.nil?
|
459
468
|
|
460
469
|
changes << "change_column :#{new_table_name}, :#{c}, " +
|
461
470
|
([":#{spec.sql_type}"] + format_options(change_spec, spec.sql_type, changing: true)).join(", ")
|
@@ -464,7 +473,7 @@ module Generators
|
|
464
473
|
end
|
465
474
|
end.compact
|
466
475
|
|
467
|
-
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)
|
468
477
|
fk_changes, undo_fk_changes = if ActiveRecord::Base.connection.class.name.match?(/SQLite3Adapter/)
|
469
478
|
[[], []]
|
470
479
|
else
|
@@ -486,7 +495,7 @@ module Generators
|
|
486
495
|
undo_table_options_changes * "\n"]
|
487
496
|
end
|
488
497
|
|
489
|
-
def change_indexes(model, old_table_name)
|
498
|
+
def change_indexes(model, old_table_name, to_remove)
|
490
499
|
return [[], []] if Migrator.disable_constraints
|
491
500
|
|
492
501
|
new_table_name = model.table_name
|
@@ -499,7 +508,10 @@ module Generators
|
|
499
508
|
end
|
500
509
|
end || i
|
501
510
|
end
|
502
|
-
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
|
503
515
|
model_has_primary_key = model_indexes.any? { |i| i.name == ::DeclareSchema::Model::IndexDefinition::PRIMARY_KEY_NAME }
|
504
516
|
|
505
517
|
add_indexes_init = model_indexes - existing_indexes
|
@@ -557,12 +569,13 @@ module Generators
|
|
557
569
|
|
558
570
|
def format_options(options, type, changing: false)
|
559
571
|
options.map do |k, v|
|
560
|
-
|
561
|
-
next
|
562
|
-
next if k == :null && v == true
|
572
|
+
if !changing && ((k == :limit && type == :decimal) || (k == :null && v == true))
|
573
|
+
next
|
563
574
|
end
|
564
575
|
|
565
|
-
|
576
|
+
if !::DeclareSchema::Model::FieldSpec.mysql_text_limits? && k == :limit && type == :text
|
577
|
+
next
|
578
|
+
end
|
566
579
|
|
567
580
|
if k.is_a?(Symbol)
|
568
581
|
"#{k}: #{v.inspect}"
|
@@ -576,9 +589,9 @@ module Generators
|
|
576
589
|
foreign_key = model.constraint_specs.find { |fk| field_name == fk.foreign_key.to_s }
|
577
590
|
if foreign_key && (parent_table = foreign_key.parent_table_name)
|
578
591
|
parent_columns = connection.columns(parent_table) rescue []
|
579
|
-
pk_limit
|
592
|
+
pk_limit =
|
580
593
|
if (pk_column = parent_columns.find { |column| column.name.to_s == "id" }) # right now foreign keys assume id is the target
|
581
|
-
if Rails::VERSION::MAJOR
|
594
|
+
if Rails::VERSION::MAJOR < 5
|
582
595
|
pk_column.cast_type.limit
|
583
596
|
else
|
584
597
|
pk_column.limit
|
@@ -607,6 +620,16 @@ module Generators
|
|
607
620
|
end
|
608
621
|
end
|
609
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
|
+
|
610
633
|
def revert_table(table)
|
611
634
|
res = StringIO.new
|
612
635
|
schema_dumper_klass = case Rails::VERSION::MAJOR
|
@@ -616,30 +639,55 @@ module Generators
|
|
616
639
|
ActiveRecord::ConnectionAdapters::SchemaDumper
|
617
640
|
end
|
618
641
|
schema_dumper_klass.send(:new, ActiveRecord::Base.connection).send(:table, table, res)
|
619
|
-
|
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
|
620
667
|
end
|
621
668
|
|
622
|
-
def column_options_from_reverted_table(table,
|
669
|
+
def column_options_from_reverted_table(table, column)
|
623
670
|
revert = revert_table(table)
|
624
|
-
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))
|
625
672
|
# Ugly migration
|
626
673
|
_, type, options = *md
|
627
|
-
elsif (md = revert.match(/\s*t\.([a-z_]+)\s+"#{
|
674
|
+
elsif (md = revert.match(/\s*t\.([a-z_]+)\s+"#{column}"(?:,\s+(.*?)$)?/m))
|
628
675
|
# Sexy migration
|
629
|
-
_,
|
630
|
-
type = ":#{
|
676
|
+
_, string_type, options = *md
|
677
|
+
type = ":#{string_type}"
|
631
678
|
end
|
679
|
+
type or raise "unable to find column options for #{table}.#{column} in #{revert.inspect}"
|
632
680
|
[type, options]
|
633
681
|
end
|
634
682
|
|
635
|
-
def change_column_back(table,
|
636
|
-
type, options = column_options_from_reverted_table(table,
|
637
|
-
"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(', ')
|
638
686
|
end
|
639
687
|
|
640
688
|
def revert_column(table, column)
|
641
689
|
type, options = column_options_from_reverted_table(table, column)
|
642
|
-
"add_column :#{table}, :#{column}, #{type}
|
690
|
+
["add_column :#{table}, :#{column}, #{type}", options&.strip].compact.join(', ')
|
643
691
|
end
|
644
692
|
end
|
645
693
|
end
|
@@ -30,7 +30,7 @@ RSpec.describe 'DeclareSchema Migration Generator' do
|
|
30
30
|
case Rails::VERSION::MAJOR
|
31
31
|
when 4, 5
|
32
32
|
expect_test_definition_to_eq('alpha/beta', <<~EOS)
|
33
|
-
require
|
33
|
+
require "test_helper"
|
34
34
|
|
35
35
|
class Alpha::BetaTest < ActiveSupport::TestCase
|
36
36
|
# test "the truth" do
|
@@ -101,7 +101,9 @@ RSpec.describe 'DeclareSchema Migration Generator' do
|
|
101
101
|
|
102
102
|
expect(File.exist?('db/schema.rb')).to be_truthy
|
103
103
|
|
104
|
-
|
104
|
+
if defined?(SQLite3)
|
105
|
+
expect(File.exist?("db/development.sqlite3") || File.exist?("db/test.sqlite3")).to be_truthy
|
106
|
+
end
|
105
107
|
|
106
108
|
module Alpha; end
|
107
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
|
260
|
+
if defined?(Mysql2)
|
261
|
+
expect(::DeclareSchema::Model::FieldSpec.mysql_text_limits?).to be_truthy
|
222
262
|
|
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.
|
233
|
-
|
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
|
@@ -1108,6 +1206,10 @@ RSpec.describe 'DeclareSchema Migration Generator' do
|
|
1108
1206
|
migrations = Dir.glob('db/migrate/*declare_schema_migration*.rb')
|
1109
1207
|
expect(migrations.size).to eq(1), migrations.inspect
|
1110
1208
|
|
1209
|
+
if defined?(Mysql2) && Rails::VERSION::MAJOR < 5
|
1210
|
+
ActiveRecord::Base.connection.execute("ALTER TABLE adverts ADD PRIMARY KEY (id)")
|
1211
|
+
end
|
1212
|
+
|
1111
1213
|
class Advert < active_record_base_class.constantize
|
1112
1214
|
fields do
|
1113
1215
|
price :integer, limit: 8
|