convergence 1.0.6 → 1.2.0

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.
Files changed (77) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ruby.yml +35 -4
  3. data/.gitignore +1 -0
  4. data/CHANGELOG.md +57 -0
  5. data/CONTRIBUTING.md +80 -0
  6. data/Gemfile.lock +25 -9
  7. data/README.md +160 -1
  8. data/Rakefile +45 -2
  9. data/convergence.gemspec +5 -1
  10. data/lib/convergence/cli.rb +10 -2
  11. data/lib/convergence/column.rb +3 -2
  12. data/lib/convergence/command/apply.rb +38 -9
  13. data/lib/convergence/command/dryrun.rb +5 -5
  14. data/lib/convergence/command/export.rb +19 -1
  15. data/lib/convergence/command.rb +6 -0
  16. data/lib/convergence/database_connector/postgres_connector.rb +25 -0
  17. data/lib/convergence/database_connector/sqlite_connector.rb +22 -0
  18. data/lib/convergence/database_connector.rb +6 -0
  19. data/lib/convergence/default_parameter/mysql_default_parameter.rb +1 -1
  20. data/lib/convergence/default_parameter/postgres_default_parameter.rb +57 -0
  21. data/lib/convergence/default_parameter/sqlite_default_parameter.rb +57 -0
  22. data/lib/convergence/default_parameter.rb +6 -0
  23. data/lib/convergence/diff.rb +46 -3
  24. data/lib/convergence/dsl.rb +18 -3
  25. data/lib/convergence/dumper/mysql_schema_dumper.rb +37 -9
  26. data/lib/convergence/dumper/postgres_schema_dumper.rb +193 -0
  27. data/lib/convergence/dumper/sqlite_schema_dumper.rb +132 -0
  28. data/lib/convergence/dumper.rb +113 -0
  29. data/lib/convergence/sql_generator/mysql_generator.rb +32 -3
  30. data/lib/convergence/sql_generator/postgres_generator.rb +270 -0
  31. data/lib/convergence/sql_generator/sqlite_generator.rb +192 -0
  32. data/lib/convergence/table.rb +3 -2
  33. data/lib/convergence/version.rb +1 -1
  34. data/spec/config/spec_database.yml +12 -0
  35. data/spec/convergence/config_spec.rb +75 -0
  36. data/spec/convergence/diff_spec.rb +291 -44
  37. data/spec/convergence/dsl_spec.rb +26 -0
  38. data/spec/convergence/dumper/mysql_schema_dumper_spec.rb +25 -2
  39. data/spec/convergence/dumper/postgres_schema_dumper_spec.rb +103 -0
  40. data/spec/convergence/dumper/sqlite_schema_dumper_spec.rb +85 -0
  41. data/spec/convergence/dumper_spec.rb +110 -16
  42. data/spec/convergence/foreign_key_spec.rb +33 -0
  43. data/spec/convergence/index_spec.rb +52 -0
  44. data/spec/convergence/pretty_diff_spec.rb +85 -0
  45. data/spec/convergence/table_spec.rb +46 -0
  46. data/spec/fixtures/add_table_with_enum_set.schema +5 -0
  47. data/spec/fixtures/change_table_comment_to_paper.schema +2 -0
  48. data/spec/fixtures/execute_raw_sql.schema +28 -0
  49. data/spec/fixtures/postgres/add_columns_to_paper.schema +29 -0
  50. data/spec/fixtures/postgres/add_table.schema +32 -0
  51. data/spec/fixtures/postgres/change_comment_columns_to_paper.schema +28 -0
  52. data/spec/fixtures/postgres/change_table_comment_to_paper.schema +28 -0
  53. data/spec/fixtures/postgres/drop_foreign_key.schema +25 -0
  54. data/spec/fixtures/postgres/drop_table.schema +19 -0
  55. data/spec/fixtures/postgres/remove_columns_to_paper.schema +27 -0
  56. data/spec/fixtures/postgres/rename_column_on_paper.schema +28 -0
  57. data/spec/fixtures/postgres/rename_table.schema +28 -0
  58. data/spec/fixtures/postgres_test_db.sql +41 -0
  59. data/spec/fixtures/rename_column_to_author.schema +26 -0
  60. data/spec/fixtures/rename_table.schema +26 -0
  61. data/spec/fixtures/sqlite/add_columns_to_paper.schema +29 -0
  62. data/spec/fixtures/sqlite/add_table.schema +32 -0
  63. data/spec/fixtures/sqlite/change_columns_to_paper.schema +28 -0
  64. data/spec/fixtures/sqlite/drop_foreign_key.schema +25 -0
  65. data/spec/fixtures/sqlite/drop_table.schema +19 -0
  66. data/spec/fixtures/sqlite/remove_columns_to_paper.schema +27 -0
  67. data/spec/fixtures/sqlite/rename_column_on_paper.schema +28 -0
  68. data/spec/fixtures/sqlite/rename_table.schema +27 -0
  69. data/spec/fixtures/sqlite_test_db.sql +31 -0
  70. data/spec/fixtures/test_db.sql +10 -0
  71. data/spec/integrations/command_diff.rb +35 -0
  72. data/spec/integrations/command_dryrun.rb +59 -2
  73. data/spec/integrations/command_export.rb +28 -0
  74. data/spec/postgres_integrations/command_dryrun.rb +101 -0
  75. data/spec/spec_helper.rb +13 -0
  76. data/spec/sqlite_integrations/command_dryrun.rb +92 -0
  77. metadata +135 -7
@@ -0,0 +1,85 @@
1
+ require 'spec_helper'
2
+ require 'convergence/dumper/sqlite_schema_dumper'
3
+ require 'convergence/database_connector'
4
+
5
+ describe Convergence::Dumper::SqliteSchemaDumper do
6
+ let(:connector) do
7
+ Convergence::DatabaseConnector.new(sqlite_settings)
8
+ end
9
+ let(:dumper) do
10
+ Convergence::Dumper::SqliteSchemaDumper.new(connector)
11
+ end
12
+
13
+ describe '#dump' do
14
+ subject { dumper.dump }
15
+
16
+ it 'should be dump tables' do
17
+ expect(subject['papers']).not_to be_nil
18
+ expect(subject['authors']).not_to be_nil
19
+ expect(subject['paper_authors']).not_to be_nil
20
+ end
21
+
22
+ describe 'table columns' do
23
+ it 'should be dump table columns' do
24
+ papers = subject['papers']
25
+ expect(papers.columns['id']).not_to be_nil
26
+ expect(papers.columns['slug']).not_to be_nil
27
+ expect(papers.columns['title1']).not_to be_nil
28
+ expect(papers.columns['title2']).not_to be_nil
29
+ expect(papers.columns['description']).not_to be_nil
30
+ expect(papers.columns['edition_number']).not_to be_nil
31
+ expect(papers.columns['published_at']).not_to be_nil
32
+ end
33
+
34
+ describe 'table column options' do
35
+ it 'should be dump primary key as auto_increment' do
36
+ expect(subject['papers'].columns['id'].options[:primary_key]).to be_truthy
37
+ expect(subject['papers'].columns['id'].options[:extra]).to eq('auto_increment')
38
+ expect(subject['papers'].columns['id'].options[:null]).to be_falsy
39
+ end
40
+
41
+ it 'should be dump limit' do
42
+ expect(subject['papers'].columns['title1'].options[:limit]).to eq('300')
43
+ end
44
+
45
+ it 'should be dump not null definition' do
46
+ expect(subject['papers'].columns['title1'].options[:null]).to be_falsy
47
+ expect(subject['authors'].columns['created_at'].options[:null]).to be_truthy
48
+ end
49
+
50
+ it 'should be dump default' do
51
+ expect(subject['papers'].columns['edition_number'].options[:default]).to eq('0')
52
+ expect(subject['papers'].columns['published_at'].options[:default])
53
+ .to be_a(Proc)
54
+ .and have_attributes(call: 'CURRENT_TIMESTAMP')
55
+ end
56
+ end
57
+ end
58
+
59
+ describe 'indexes' do
60
+ it 'should be dump index of authors' do
61
+ index = subject['authors'].indexes['index_authors_on_created_at']
62
+ expect(index).not_to be_nil
63
+ expect(index.index_columns).to eq(['created_at'])
64
+ expect(index.options[:unique]).to eq(false)
65
+ end
66
+
67
+ it 'should be dump unique index of papers' do
68
+ index = subject['papers'].indexes['index_papers_on_slug']
69
+ expect(index).not_to be_nil
70
+ expect(index.index_columns).to eq(['slug'])
71
+ expect(index.options[:unique]).to eq(true)
72
+ end
73
+ end
74
+
75
+ describe 'foreign keys' do
76
+ it 'should be dump the foreign key with its original constraint name' do
77
+ foreign_key = subject['paper_authors'].foreign_keys['paper_authors_author_id_fk']
78
+ expect(foreign_key).not_to be_nil
79
+ expect(foreign_key.from_columns).to eq(['author_id'])
80
+ expect(foreign_key.to_table).to eq('authors')
81
+ expect(foreign_key.to_columns).to eq(['id'])
82
+ end
83
+ end
84
+ end
85
+ end
@@ -13,15 +13,15 @@ describe Convergence::Dumper do
13
13
  end
14
14
  end
15
15
  let(:table1_dsl) do
16
- dsl = <<-DSL
17
- create_table :dummy_table, engine: "MyISAM" do |t|
18
- t.int :id, limit: 11
19
- t.varchar :name, limit: 100, null: true, comment: "name"
16
+ dsl = <<~DSL
17
+ create_table :dummy_table, engine: "MyISAM" do |t|
18
+ t.int :id, limit: 11
19
+ t.varchar :name, limit: 100, null: true, comment: "name"
20
20
 
21
- t.index :name, name: "idx_name"
22
- t.foreign_key :id, reference: :dummy_ref, reference_column: :id, name: "dummy_table_id_fk"
23
- end
24
- DSL
21
+ t.index :name, name: "idx_name"
22
+ t.foreign_key :id, reference: :dummy_ref, reference_column: :id, name: "dummy_table_id_fk"
23
+ end
24
+ DSL
25
25
  dsl.strip
26
26
  end
27
27
 
@@ -51,15 +51,15 @@ end
51
51
  end
52
52
 
53
53
  let(:table1_dsl) do
54
- dsl = <<-DSL
55
- create_table :"dummy-table", engine: "MyISAM" do |t|
56
- t.int :id, limit: 11
57
- t.varchar :"column-1", limit: 100, null: true, comment: "column 1"
54
+ dsl = <<~DSL
55
+ create_table :"dummy-table", engine: "MyISAM" do |t|
56
+ t.int :id, limit: 11
57
+ t.varchar :"column-1", limit: 100, null: true, comment: "column 1"
58
58
 
59
- t.index :"column-1", name: "idx_column-1"
60
- t.foreign_key :"column-1", reference: :"dummy-ref", reference_column: :"dummy-column", name: "dummy-table_column-1_fk"
61
- end
62
- DSL
59
+ t.index :"column-1", name: "idx_column-1"
60
+ t.foreign_key :"column-1", reference: :"dummy-ref", reference_column: :"dummy-column", name: "dummy-table_column-1_fk"
61
+ end
62
+ DSL
63
63
  dsl.strip
64
64
  end
65
65
 
@@ -68,5 +68,99 @@ end
68
68
  expect(dsl).to eq(table1_dsl)
69
69
  end
70
70
  end
71
+
72
+ context "when the table column has default option with proc" do
73
+ let(:table1) do
74
+ Convergence::Table.new('dummy_table').tap do |t|
75
+ t.int :edition_number, default: 0
76
+ t.datetime :created_at, default: -> { "CURRENT_TIMESTAMP" }
77
+ end
78
+ end
79
+
80
+ let(:table1_dsl) do
81
+ dsl = <<~DSL
82
+ create_table :dummy_table do |t|
83
+ t.int :edition_number, default: 0
84
+ t.datetime :created_at, default: -> { "CURRENT_TIMESTAMP" }
85
+ end
86
+ DSL
87
+ dsl.strip
88
+ end
89
+
90
+ it 'should be able to dump dsl' do
91
+ dsl = Convergence::Dumper.new.dump_table_dsl(table1)
92
+ expect(dsl).to eq(table1_dsl)
93
+ end
94
+ end
95
+ end
96
+
97
+ describe '#dump_rails_migration' do
98
+ let(:table1) do
99
+ Convergence::Table.new('dummy_table', engine: 'MyISAM').tap do |t|
100
+ t.int :id, primary_key: true, extra: 'auto_increment'
101
+ t.varchar :name, limit: 100, null: true, comment: 'name'
102
+ t.datetime :created_at, null: false
103
+ t.datetime :updated_at, null: false
104
+
105
+ t.index :name, name: 'idx_name'
106
+ t.foreign_key :id, reference: 'dummy_ref', reference_column: :id
107
+ end
108
+ end
109
+
110
+ let(:migration_dsl) do
111
+ dsl = <<~DSL
112
+ class DummyMigration < ActiveRecord::Migration[7.0]
113
+ def change
114
+ create_table :dummy_table do |t|
115
+ t.string :name, limit: 100, null: true, comment: "name"
116
+ t.timestamps null: false
117
+ t.index :name, name: "idx_name"
118
+ t.foreign_key :dummy_ref, column: :id, name: "dummy_table_id_fk"
119
+ end
120
+ end
121
+ end
122
+ DSL
123
+ dsl.strip
124
+ end
125
+
126
+ it 'omits the implicit auto-increment id column' do
127
+ migration = Convergence::Dumper.new.dump_rails_migration({ 'dummy_table' => table1 }, 'DummyMigration')
128
+ expect(migration).to eq(migration_dsl)
129
+ end
130
+
131
+ it 'collapses created_at/updated_at into t.timestamps' do
132
+ migration = Convergence::Dumper.new.dump_rails_migration({ 'dummy_table' => table1 }, 'DummyMigration')
133
+ expect(migration).to be_include('t.timestamps null: false')
134
+ expect(migration).not_to be_include('t.datetime :created_at')
135
+ end
136
+
137
+ context 'when the column is a MySQL tinyint(1) boolean' do
138
+ let(:table1) do
139
+ Convergence::Table.new('dummy_table').tap do |t|
140
+ t.boolean :active, default: true
141
+ end
142
+ end
143
+
144
+ it 'maps it to a native boolean column' do
145
+ migration = Convergence::Dumper.new.dump_rails_migration({ 'dummy_table' => table1 }, 'DummyMigration')
146
+ expect(migration).to be_include('t.boolean :active, default: true')
147
+ end
148
+ end
149
+
150
+ context 'when created_at/updated_at have mismatched null options' do
151
+ let(:table1) do
152
+ Convergence::Table.new('dummy_table').tap do |t|
153
+ t.datetime :created_at, null: false
154
+ t.datetime :updated_at, null: true
155
+ end
156
+ end
157
+
158
+ it 'keeps them as separate columns instead of collapsing into t.timestamps' do
159
+ migration = Convergence::Dumper.new.dump_rails_migration({ 'dummy_table' => table1 }, 'DummyMigration')
160
+ expect(migration).not_to be_include('t.timestamps')
161
+ expect(migration).to be_include('t.datetime :created_at, null: false')
162
+ expect(migration).to be_include('t.datetime :updated_at, null: true')
163
+ end
164
+ end
71
165
  end
72
166
  end
@@ -0,0 +1,33 @@
1
+ require 'spec_helper'
2
+ require 'convergence/foreign_key'
3
+
4
+ describe Convergence::ForeignKey do
5
+ describe '#initialize' do
6
+ it 'wraps a single from_column/to_column into an array of strings' do
7
+ fk = Convergence::ForeignKey.new('fk_name', :author_id, 'authors', :id, {})
8
+ expect(fk.from_columns).to eq(['author_id'])
9
+ expect(fk.to_columns).to eq(['id'])
10
+ end
11
+
12
+ it 'wraps multiple from_columns/to_columns into arrays of strings' do
13
+ fk = Convergence::ForeignKey.new('fk_name', [:a_id, :b_id], 'targets', [:a, :b], {})
14
+ expect(fk.from_columns).to eq(['a_id', 'b_id'])
15
+ expect(fk.to_columns).to eq(['a', 'b'])
16
+ end
17
+
18
+ it 'stringifies the target table name' do
19
+ fk = Convergence::ForeignKey.new('fk_name', :author_id, :authors, :id, {})
20
+ expect(fk.to_table).to eq('authors')
21
+ end
22
+
23
+ it 'defaults the :name option to the key name' do
24
+ fk = Convergence::ForeignKey.new('fk_name', :author_id, 'authors', :id, {})
25
+ expect(fk.options[:name]).to eq('fk_name')
26
+ end
27
+
28
+ it 'preserves any additional options passed in' do
29
+ fk = Convergence::ForeignKey.new('fk_name', :author_id, 'authors', :id, on_delete: :cascade)
30
+ expect(fk.options[:on_delete]).to eq(:cascade)
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,52 @@
1
+ require 'spec_helper'
2
+ require 'convergence/index'
3
+
4
+ describe Convergence::Index do
5
+ describe '#initialize' do
6
+ it 'defaults the :name option to the index name' do
7
+ index = Convergence::Index.new('idx_name', 'name', {})
8
+ expect(index.options[:name]).to eq('idx_name')
9
+ end
10
+
11
+ it 'wraps a single column into an array of strings' do
12
+ index = Convergence::Index.new('idx_name', :name, {})
13
+ expect(index.index_columns).to eq(['name'])
14
+ end
15
+
16
+ it 'wraps multiple columns into an array of strings' do
17
+ index = Convergence::Index.new('idx_name', [:first_name, :last_name], {})
18
+ expect(index.index_columns).to eq(['first_name', 'last_name'])
19
+ end
20
+
21
+ context 'when length is a single Integer' do
22
+ it 'applies it to every column' do
23
+ index = Convergence::Index.new('idx_name', [:first_name, :last_name], length: 10)
24
+ expect(index.options[:length]).to eq('first_name' => 10, 'last_name' => 10)
25
+ end
26
+ end
27
+
28
+ context 'when length is a Hash keyed by symbol' do
29
+ it 'normalizes the keys to strings' do
30
+ index = Convergence::Index.new('idx_name', [:first_name, :last_name], length: { first_name: 10, last_name: 20 })
31
+ expect(index.options[:length]).to eq('first_name' => 10, 'last_name' => 20)
32
+ end
33
+ end
34
+ end
35
+
36
+ describe '#quoted_columns' do
37
+ it 'quotes each column name with backticks' do
38
+ index = Convergence::Index.new('idx_name', [:first_name, :last_name], {})
39
+ expect(index.quoted_columns).to eq(['`first_name`', '`last_name`'])
40
+ end
41
+
42
+ it 'appends the prefix length in parentheses when configured' do
43
+ index = Convergence::Index.new('idx_name', [:first_name, :last_name], length: { first_name: 10 })
44
+ expect(index.quoted_columns).to eq(['`first_name`(10)', '`last_name`'])
45
+ end
46
+
47
+ it 'escapes a backtick embedded in a column name' do
48
+ index = Convergence::Index.new('idx_name', 'weird`name', {})
49
+ expect(index.quoted_columns).to eq(['`weird``name`'])
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,85 @@
1
+ require 'spec_helper'
2
+ require 'convergence/pretty_diff'
3
+ require 'convergence/table'
4
+
5
+ describe Convergence::PrettyDiff do
6
+ describe '#output' do
7
+ context 'when a table is added' do
8
+ let(:from_tables) { {} }
9
+ let(:to_tables) do
10
+ { 'users' => Convergence::Table.new('users').tap { |t| t.int('id', primary_key: true) } }
11
+ end
12
+
13
+ it 'should show the added table with a + prefix on every line' do
14
+ output = Convergence::PrettyDiff.new(from_tables, to_tables).output
15
+ expect(output).to be_include('+ create_table :users do |t|')
16
+ expect(output).to be_include('+ t.int :id, primary_key: true')
17
+ expect(output).to be_include('+ end')
18
+ end
19
+ end
20
+
21
+ context 'when a table is removed' do
22
+ let(:from_tables) do
23
+ { 'users' => Convergence::Table.new('users').tap { |t| t.int('id', primary_key: true) } }
24
+ end
25
+ let(:to_tables) { {} }
26
+
27
+ it 'should show the removed table with a - prefix on every line' do
28
+ output = Convergence::PrettyDiff.new(from_tables, to_tables).output
29
+ expect(output).to be_include('- create_table :users do |t|')
30
+ expect(output).to be_include('- t.int :id, primary_key: true')
31
+ expect(output).to be_include('- end')
32
+ end
33
+ end
34
+
35
+ context 'when a table column is changed' do
36
+ let(:from_tables) do
37
+ { 'users' => Convergence::Table.new('users').tap { |t| t.varchar('name', limit: 100) } }
38
+ end
39
+ let(:to_tables) do
40
+ { 'users' => Convergence::Table.new('users').tap { |t| t.varchar('name', limit: 200) } }
41
+ end
42
+
43
+ it 'should show a unified diff of only the changed column' do
44
+ output = Convergence::PrettyDiff.new(from_tables, to_tables).output
45
+ expect(output).to be_include('- t.varchar :name, limit: 100')
46
+ expect(output).to be_include('+ t.varchar :name, limit: 200')
47
+ expect(output).to be_include(' create_table :users do |t|')
48
+ end
49
+ end
50
+
51
+ context 'when nothing changed' do
52
+ let(:tables) do
53
+ { 'users' => Convergence::Table.new('users').tap { |t| t.int('id', primary_key: true) } }
54
+ end
55
+
56
+ it 'should return an empty string' do
57
+ output = Convergence::PrettyDiff.new(tables, tables).output
58
+ expect(output).to eq('')
59
+ end
60
+ end
61
+
62
+ context 'when tables are added, removed, and changed at the same time' do
63
+ let(:from_tables) do
64
+ {
65
+ 'authors' => Convergence::Table.new('authors').tap { |t| t.int('id', primary_key: true) },
66
+ 'papers' => Convergence::Table.new('papers').tap { |t| t.varchar('title', limit: 100) }
67
+ }
68
+ end
69
+ let(:to_tables) do
70
+ {
71
+ 'papers' => Convergence::Table.new('papers').tap { |t| t.varchar('title', limit: 200) },
72
+ 'comments' => Convergence::Table.new('comments').tap { |t| t.int('id', primary_key: true) }
73
+ }
74
+ end
75
+
76
+ it 'should show every add/remove/change table diff' do
77
+ output = Convergence::PrettyDiff.new(from_tables, to_tables).output
78
+ expect(output).to be_include('+ create_table :comments do |t|')
79
+ expect(output).to be_include('- create_table :authors do |t|')
80
+ expect(output).to be_include('- t.varchar :title, limit: 100')
81
+ expect(output).to be_include('+ t.varchar :title, limit: 200')
82
+ end
83
+ end
84
+ end
85
+ end
@@ -26,6 +26,52 @@ describe Convergence::Table do
26
26
  table.decimal(dummy_column, default: 1)
27
27
  expect(table.columns[dummy_column].options[:default]).to eq(1.0)
28
28
  end
29
+
30
+ it 'should extract renamed_from into its own accessor' do
31
+ table.int(dummy_column, renamed_from: 'old_column')
32
+ expect(table.columns[dummy_column].renamed_from).to eq('old_column')
33
+ expect(table.columns[dummy_column].options).not_to have_key(:renamed_from)
34
+ end
35
+
36
+ it 'should have a nil renamed_from when not specified' do
37
+ table.int(dummy_column)
38
+ expect(table.columns[dummy_column].renamed_from).to be_nil
39
+ end
40
+ end
41
+
42
+ describe 'renamed_from' do
43
+ it 'should extract renamed_from into its own accessor' do
44
+ renamed_table = Convergence::Table.new('new_table', renamed_from: 'old_table')
45
+ expect(renamed_table.renamed_from).to eq('old_table')
46
+ expect(renamed_table.table_options).not_to have_key(:renamed_from)
47
+ end
48
+
49
+ it 'should have a nil renamed_from when not specified' do
50
+ expect(table.renamed_from).to be_nil
51
+ end
52
+ end
53
+
54
+ describe '#boolean' do
55
+ it 'should be stored as a tinyint(1) column' do
56
+ table.boolean(dummy_column)
57
+ expect(table.columns[dummy_column].type).to eq(:tinyint)
58
+ expect(table.columns[dummy_column].options[:limit]).to eq(1)
59
+ end
60
+
61
+ it 'should convert a true default to 1' do
62
+ table.boolean(dummy_column, default: true)
63
+ expect(table.columns[dummy_column].options[:default]).to eq(1)
64
+ end
65
+
66
+ it 'should convert a false default to 0' do
67
+ table.boolean(dummy_column, default: false)
68
+ expect(table.columns[dummy_column].options[:default]).to eq(0)
69
+ end
70
+
71
+ it 'should preserve other options' do
72
+ table.boolean(dummy_column, null: false)
73
+ expect(table.columns[dummy_column].options[:null]).to eq(false)
74
+ end
29
75
  end
30
76
 
31
77
  describe '#index' do
@@ -0,0 +1,5 @@
1
+ create_table 'enum_set_dummies' do |t|
2
+ t.int 'id', primary_key: true, extra: 'auto_increment'
3
+ t.enum 'status', values: %w(active inactive pending), default: 'active'
4
+ t.set 'flags', values: %w(a b c)
5
+ end
@@ -14,6 +14,8 @@ create_table "papers", collate: "utf8_general_ci", comment: "Paper" do |t|
14
14
  t.varchar "title1", limit: 300, comment: "Title 1"
15
15
  t.varchar "title2", limit: 300, comment: "Title 2"
16
16
  t.text "description", null: true, comment: "Description"
17
+ t.int "edition_number", default: 0
18
+ t.datetime "published_at", default: -> { "CURRENT_TIMESTAMP" }
17
19
  end
18
20
 
19
21
  create_table "paper_authors", collate: "utf8_general_ci", comment: "Paper Author Relation" do |t|
@@ -0,0 +1,28 @@
1
+ create_table "authors", collate: "utf8_general_ci", comment: "" do |t|
2
+ t.int "id", primary_key: true, extra: "auto_increment"
3
+ t.varchar "name", limit: 110
4
+ t.int "age", unsigned: true
5
+ t.datetime "created_at", null: true
6
+ t.datetime "updated_at", null: true
7
+
8
+ t.index "created_at", name: "index_authors_on_created_at"
9
+ end
10
+
11
+ create_table "papers", collate: "utf8_general_ci", comment: "Paper" do |t|
12
+ t.int "id", primary_key: true, extra: "auto_increment"
13
+ t.varchar "slug", comment: "Slug"
14
+ t.varchar "title1", limit: 300, comment: "Title 1"
15
+ t.varchar "title2", limit: 300, comment: "Title 2"
16
+ t.text "description", null: true, comment: "Description"
17
+ end
18
+
19
+ create_table "paper_authors", collate: "utf8_general_ci", comment: "Paper Author Relation" do |t|
20
+ t.int "id", primary_key: true, extra: "auto_increment"
21
+ t.int "paper_id", comment: "Paper id"
22
+ t.int "author_id", comment: "Paper author id"
23
+
24
+ t.foreign_key "author_id", reference: "authors", reference_column: "id", name: "paper_authors_author_id_fk"
25
+ t.foreign_key "paper_id", reference: "papers", reference_column: "id", name: "paper_authors_paper_id_fk"
26
+ end
27
+
28
+ execute "UPDATE authors SET age = 0 WHERE age IS NULL"
@@ -0,0 +1,29 @@
1
+ create_table "authors" do |t|
2
+ t.int "id", primary_key: true, extra: "auto_increment"
3
+ t.varchar "name", limit: 110
4
+ t.int "age"
5
+ t.datetime "created_at", null: true
6
+ t.datetime "updated_at", null: true
7
+
8
+ t.index "created_at", name: "index_authors_on_created_at"
9
+ end
10
+
11
+ create_table "papers", comment: "Paper" do |t|
12
+ t.int "id", primary_key: true, extra: "auto_increment"
13
+ t.varchar "slug", comment: "Slug"
14
+ t.varchar "title1", limit: 300, comment: "Title 1"
15
+ t.varchar "title2", limit: 300, comment: "Title 2"
16
+ t.text "description", null: true, comment: "Description"
17
+ t.varchar "subtitle", null: true, comment: "Subtitle"
18
+
19
+ t.index "slug", name: "index_papers_on_slug", unique: true
20
+ end
21
+
22
+ create_table "paper_authors", comment: "Paper Author Relation" do |t|
23
+ t.int "id", primary_key: true, extra: "auto_increment"
24
+ t.int "paper_id", comment: "Paper id"
25
+ t.int "author_id", comment: "Paper author id"
26
+
27
+ t.foreign_key "author_id", reference: "authors", reference_column: "id", name: "paper_authors_author_id_fk"
28
+ t.foreign_key "paper_id", reference: "papers", reference_column: "id", name: "paper_authors_paper_id_fk"
29
+ end
@@ -0,0 +1,32 @@
1
+ create_table "authors" do |t|
2
+ t.int "id", primary_key: true, extra: "auto_increment"
3
+ t.varchar "name", limit: 110
4
+ t.int "age"
5
+ t.datetime "created_at", null: true
6
+ t.datetime "updated_at", null: true
7
+
8
+ t.index "created_at", name: "index_authors_on_created_at"
9
+ end
10
+
11
+ create_table "papers", comment: "Paper" do |t|
12
+ t.int "id", primary_key: true, extra: "auto_increment"
13
+ t.varchar "slug", comment: "Slug"
14
+ t.varchar "title1", limit: 300, comment: "Title 1"
15
+ t.varchar "title2", limit: 300, comment: "Title 2"
16
+ t.text "description", null: true, comment: "Description"
17
+
18
+ t.index "slug", name: "index_papers_on_slug", unique: true
19
+ end
20
+
21
+ create_table "paper_authors", comment: "Paper Author Relation" do |t|
22
+ t.int "id", primary_key: true, extra: "auto_increment"
23
+ t.int "paper_id", comment: "Paper id"
24
+ t.int "author_id", comment: "Paper author id"
25
+
26
+ t.foreign_key "author_id", reference: "authors", reference_column: "id", name: "paper_authors_author_id_fk"
27
+ t.foreign_key "paper_id", reference: "papers", reference_column: "id", name: "paper_authors_paper_id_fk"
28
+ end
29
+
30
+ create_table "dummies", comment: "Dummy Table" do |t|
31
+ t.int "id", primary_key: true, extra: "auto_increment", comment: "Hello Convergence"
32
+ end
@@ -0,0 +1,28 @@
1
+ create_table "authors" do |t|
2
+ t.int "id", primary_key: true, extra: "auto_increment"
3
+ t.varchar "name", limit: 110
4
+ t.int "age"
5
+ t.datetime "created_at", null: true, comment: "Created At"
6
+ t.datetime "updated_at", null: true
7
+
8
+ t.index "created_at", name: "index_authors_on_created_at"
9
+ end
10
+
11
+ create_table "papers", comment: "Paper" do |t|
12
+ t.int "id", primary_key: true, extra: "auto_increment"
13
+ t.varchar "slug", comment: "Slug"
14
+ t.varchar "title1", limit: 300, comment: "Title 1"
15
+ t.varchar "title2", limit: 300, comment: "Title 2"
16
+ t.text "description", null: true, comment: "Description"
17
+
18
+ t.index "slug", name: "index_papers_on_slug", unique: true
19
+ end
20
+
21
+ create_table "paper_authors", comment: "Paper Author Relation" do |t|
22
+ t.int "id", primary_key: true, extra: "auto_increment"
23
+ t.int "paper_id", comment: "Paper id"
24
+ t.int "author_id", comment: "Paper author id"
25
+
26
+ t.foreign_key "author_id", reference: "authors", reference_column: "id", name: "paper_authors_author_id_fk"
27
+ t.foreign_key "paper_id", reference: "papers", reference_column: "id", name: "paper_authors_paper_id_fk"
28
+ end
@@ -0,0 +1,28 @@
1
+ create_table "authors", comment: "Author Table" do |t|
2
+ t.int "id", primary_key: true, extra: "auto_increment"
3
+ t.varchar "name", limit: 110
4
+ t.int "age"
5
+ t.datetime "created_at", null: true
6
+ t.datetime "updated_at", null: true
7
+
8
+ t.index "created_at", name: "index_authors_on_created_at"
9
+ end
10
+
11
+ create_table "papers", comment: "Paper" do |t|
12
+ t.int "id", primary_key: true, extra: "auto_increment"
13
+ t.varchar "slug", comment: "Slug"
14
+ t.varchar "title1", limit: 300, comment: "Title 1"
15
+ t.varchar "title2", limit: 300, comment: "Title 2"
16
+ t.text "description", null: true, comment: "Description"
17
+
18
+ t.index "slug", name: "index_papers_on_slug", unique: true
19
+ end
20
+
21
+ create_table "paper_authors", comment: "Paper Author Relation" do |t|
22
+ t.int "id", primary_key: true, extra: "auto_increment"
23
+ t.int "paper_id", comment: "Paper id"
24
+ t.int "author_id", comment: "Paper author id"
25
+
26
+ t.foreign_key "author_id", reference: "authors", reference_column: "id", name: "paper_authors_author_id_fk"
27
+ t.foreign_key "paper_id", reference: "papers", reference_column: "id", name: "paper_authors_paper_id_fk"
28
+ end
@@ -0,0 +1,25 @@
1
+ create_table "authors" do |t|
2
+ t.int "id", primary_key: true, extra: "auto_increment"
3
+ t.varchar "name", limit: 110
4
+ t.int "age"
5
+ t.datetime "created_at", null: true
6
+ t.datetime "updated_at", null: true
7
+
8
+ t.index "created_at", name: "index_authors_on_created_at"
9
+ end
10
+
11
+ create_table "papers", comment: "Paper" do |t|
12
+ t.int "id", primary_key: true, extra: "auto_increment"
13
+ t.varchar "slug", comment: "Slug"
14
+ t.varchar "title1", limit: 300, comment: "Title 1"
15
+ t.varchar "title2", limit: 300, comment: "Title 2"
16
+ t.text "description", null: true, comment: "Description"
17
+
18
+ t.index "slug", name: "index_papers_on_slug", unique: true
19
+ end
20
+
21
+ create_table "paper_authors", comment: "Paper Author Relation" do |t|
22
+ t.int "id", primary_key: true, extra: "auto_increment"
23
+ t.int "paper_id", comment: "Paper id"
24
+ t.int "author_id", comment: "Paper author id"
25
+ end