declare_schema 0.14.1 → 1.0.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 (35) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/declare_schema_build.yml +22 -23
  3. data/.ruby-version +1 -1
  4. data/Appraisals +8 -0
  5. data/CHANGELOG.md +22 -4
  6. data/Gemfile +3 -2
  7. data/Gemfile.lock +107 -77
  8. data/README.md +18 -8
  9. data/Rakefile +1 -1
  10. data/gemfiles/rails_5_mysql.gemfile +0 -1
  11. data/gemfiles/rails_5_sqlite.gemfile +0 -1
  12. data/gemfiles/rails_6_mysql.gemfile +2 -1
  13. data/gemfiles/rails_6_sqlite.gemfile +2 -1
  14. data/lib/declare_schema/command.rb +1 -1
  15. data/lib/declare_schema/dsl.rb +3 -3
  16. data/lib/declare_schema/extensions/active_record/fields_declaration.rb +0 -18
  17. data/lib/declare_schema/field_declaration_dsl.rb +4 -4
  18. data/lib/declare_schema/model/foreign_key_definition.rb +2 -2
  19. data/lib/declare_schema/model/index_definition.rb +1 -1
  20. data/lib/declare_schema/model/table_options_definition.rb +2 -2
  21. data/lib/declare_schema/model.rb +9 -9
  22. data/lib/declare_schema/version.rb +1 -1
  23. data/lib/generators/declare_schema/migration/migrator.rb +6 -6
  24. data/spec/lib/declare_schema/field_declaration_dsl_spec.rb +0 -24
  25. data/spec/lib/declare_schema/field_spec_spec.rb +2 -2
  26. data/spec/lib/declare_schema/interactive_primary_key_spec.rb +0 -67
  27. data/spec/lib/declare_schema/migration_generator_spec.rb +11 -1176
  28. data/spec/lib/declare_schema/model/column_spec.rb +1 -28
  29. data/spec/lib/declare_schema/model/foreign_key_definition_spec.rb +1 -94
  30. data/spec/lib/declare_schema/model/index_definition_spec.rb +0 -109
  31. data/spec/lib/declare_schema/model/table_options_definition_spec.rb +2 -65
  32. data/spec/lib/declare_schema/schema_change/column_add_spec.rb +1 -1
  33. data/spec/lib/declare_schema/schema_change/column_remove_spec.rb +1 -1
  34. data/spec/spec_helper.rb +1 -1
  35. metadata +6 -6
@@ -15,7 +15,7 @@ RSpec.describe DeclareSchema::Model::Column do
15
15
  describe 'class methods' do
16
16
  describe '.native_type?' do
17
17
  let(:native_types) { [:string, :text, :integer, :float, :decimal, :datetime, :time, :date, :binary, :boolean, :json] }
18
-
18
+
19
19
 
20
20
  it 'is falsey for :primary_key' do
21
21
  expect(described_class.native_type?(:primary_key)).to be_falsey
@@ -91,33 +91,6 @@ RSpec.describe DeclareSchema::Model::Column do
91
91
  sql_type_metadata: {}) }
92
92
  subject { described_class.new(model, current_table_name, column) }
93
93
 
94
- context 'Using fields' do
95
- before do
96
- class ColumnTestModel < ActiveRecord::Base
97
- fields do
98
- title :string, limit: 127, null: false
99
- count :integer, null: false
100
- end
101
- end
102
- end
103
-
104
- describe '#type' do
105
- it 'returns type' do
106
- expect(subject.type).to eq(type)
107
- end
108
- end
109
-
110
- describe '#schema_attributes' do
111
- it 'returns a hash with relevant key/values' do
112
- if defined?(Mysql2)
113
- expect(subject.schema_attributes).to eq(type: :integer, null: false, limit: 4)
114
- else
115
- expect(subject.schema_attributes).to eq(type: :integer, null: false)
116
- end
117
- end
118
- end
119
- end
120
-
121
94
  context 'Using declare_schema' do
122
95
  before do
123
96
  class ColumnTestModel < ActiveRecord::Base
@@ -5,99 +5,6 @@ require_relative '../../../../lib/declare_schema/model/foreign_key_definition'
5
5
  RSpec.describe DeclareSchema::Model::ForeignKeyDefinition do
6
6
  let(:model_class) { Network }
7
7
 
8
- context 'Using fields' do
9
- before do
10
- load File.expand_path('../prepare_testapp.rb', __dir__)
11
-
12
- class Network < ActiveRecord::Base
13
- fields do
14
- name :string, limit: 127, index: true
15
-
16
- timestamps
17
- end
18
- end
19
- end
20
-
21
- describe 'instance methods' do
22
- let(:connection) { instance_double(ActiveRecord::Base.connection.class) }
23
- let(:model) { instance_double('Model', table_name: 'models', connection: connection) }
24
- let(:foreign_key) { :network_id }
25
- let(:options) { {} }
26
- subject { described_class.new(model, foreign_key, options)}
27
-
28
- before do
29
- allow(model.connection).to receive(:index_name).with(any_args) { 'index_on_network_id' }
30
- end
31
-
32
- describe '#initialize' do
33
- it 'normalizes symbols to strings' do
34
- expect(subject.foreign_key).to eq('network_id')
35
- expect(subject.parent_table_name).to eq('networks')
36
- end
37
-
38
- context 'when most options passed' do
39
- let(:options) { { parent_table: :networks, foreign_key: :the_network_id } }
40
-
41
- it 'normalizes symbols to strings' do
42
- expect(subject.foreign_key).to eq('network_id')
43
- expect(subject.foreign_key_name).to eq('the_network_id')
44
- expect(subject.parent_table_name).to eq('networks')
45
- expect(subject.foreign_key).to eq('network_id')
46
- expect(subject.constraint_name).to eq('index_on_network_id')
47
- expect(subject.on_delete_cascade).to be_falsey
48
- end
49
- end
50
-
51
- context 'when all options passed' do
52
- let(:foreign_key) { nil }
53
- let(:options) { { parent_table: :networks, foreign_key: :the_network_id, constraint_name: :constraint_1, dependent: :delete } }
54
-
55
- it 'normalizes symbols to strings' do
56
- expect(subject.foreign_key).to be_nil
57
- expect(subject.foreign_key_name).to eq('the_network_id')
58
- expect(subject.parent_table_name).to eq('networks')
59
- expect(subject.constraint_name).to eq('constraint_1')
60
- expect(subject.on_delete_cascade).to be_truthy
61
- end
62
- end
63
-
64
- context 'when constraint name passed as empty string' do
65
- let(:options) { { constraint_name: "" } }
66
- it 'defaults to rails constraint name' do
67
- expect(subject.constraint_name).to eq("index_on_network_id")
68
- end
69
- end
70
-
71
- context 'when no constraint name passed' do
72
- it 'defaults to rails constraint name' do
73
- expect(subject.constraint_name).to eq("index_on_network_id")
74
- end
75
- end
76
- end
77
- end
78
-
79
- describe 'class << self' do
80
- let(:connection) { instance_double(ActiveRecord::Base.connection.class) }
81
- let(:model) { instance_double('Model', table_name: 'models', connection: connection) }
82
- let(:old_table_name) { 'networks' }
83
- before do
84
- allow(connection).to receive(:quote_table_name).with('networks') { 'networks' }
85
- allow(connection).to receive(:select_rows) { [['CONSTRAINT `constraint` FOREIGN KEY (`network_id`) REFERENCES `networks` (`id`)']] }
86
- allow(connection).to receive(:index_name).with('models', column: 'network_id') { }
87
- end
88
-
89
- describe '.for_model' do
90
- subject { described_class.for_model(model, old_table_name) }
91
-
92
- it 'returns new object' do
93
- expect(subject.size).to eq(1), subject.inspect
94
- expect(subject.first).to be_kind_of(described_class)
95
- expect(subject.first.foreign_key).to eq('network_id')
96
- end
97
- end
98
- end
99
- end
100
-
101
8
  context 'Using declare_schema' do
102
9
  before do
103
10
  load File.expand_path('../prepare_testapp.rb', __dir__)
@@ -116,7 +23,7 @@ RSpec.describe DeclareSchema::Model::ForeignKeyDefinition do
116
23
  let(:model) { instance_double('Model', table_name: 'models', connection: connection) }
117
24
  let(:foreign_key) { :network_id }
118
25
  let(:options) { {} }
119
- subject { described_class.new(model, foreign_key, options)}
26
+ subject { described_class.new(model, foreign_key, **options)}
120
27
 
121
28
  before do
122
29
  allow(model.connection).to receive(:index_name).with(any_args) { 'index_on_network_id' }
@@ -12,115 +12,6 @@ require_relative '../../../../lib/declare_schema/model/index_definition'
12
12
  RSpec.describe DeclareSchema::Model::IndexDefinition do
13
13
  let(:model_class) { IndexDefinitionTestModel }
14
14
 
15
- context 'Using fields' do
16
- before do
17
- load File.expand_path('../prepare_testapp.rb', __dir__)
18
-
19
- class IndexDefinitionTestModel < ActiveRecord::Base
20
- fields do
21
- name :string, limit: 127, index: true
22
-
23
- timestamps
24
- end
25
- end
26
-
27
- class IndexDefinitionCompoundIndexModel < ActiveRecord::Base
28
- fields do
29
- fk1_id :integer
30
- fk2_id :integer
31
-
32
- timestamps
33
- end
34
- end
35
- end
36
-
37
- describe 'instance methods' do
38
- let(:model) { model_class.new }
39
- subject { declared_class.new(model_class) }
40
-
41
- it 'has index_definitions' do
42
- expect(model_class.index_definitions).to be_kind_of(Array)
43
- expect(model_class.index_definitions.map(&:name)).to eq(['on_name'])
44
- expect([:name, :fields, :unique].map { |attr| model_class.index_definitions[0].send(attr)}).to eq(
45
- ['on_name', ['name'], false]
46
- )
47
- end
48
-
49
- it 'has index_definitions_with_primary_key' do
50
- expect(model_class.index_definitions_with_primary_key).to be_kind_of(Array)
51
- result = model_class.index_definitions_with_primary_key.sort_by(&:name)
52
- expect(result.map(&:name)).to eq(['PRIMARY', 'on_name'])
53
- expect([:name, :fields, :unique].map { |attr| result[0].send(attr)}).to eq(
54
- ['PRIMARY', ['id'], true]
55
- )
56
- expect([:name, :fields, :unique].map { |attr| result[1].send(attr)}).to eq(
57
- ['on_name', ['name'], false]
58
- )
59
- end
60
- end
61
-
62
- describe 'class methods' do
63
- describe 'index_name' do
64
- it 'works with a single column' do
65
- expect(described_class.index_name('parent_id')).to eq('on_parent_id')
66
- end
67
-
68
- it 'works with many columns' do
69
- expect(described_class.index_name(['a', 'b', 'c'])).to eq('on_a_and_b_and_c')
70
- end
71
- end
72
-
73
- context 'with a migrated database' do
74
- before do
75
- ActiveRecord::Base.connection.execute <<~EOS
76
- CREATE TABLE index_definition_test_models (
77
- id INTEGER NOT NULL PRIMARY KEY,
78
- name #{if defined?(SQLite3) then 'TEXT' else 'VARCHAR(255)' end} NOT NULL
79
- )
80
- EOS
81
- ActiveRecord::Base.connection.execute <<~EOS
82
- CREATE UNIQUE INDEX index_definition_test_models_on_name ON index_definition_test_models(name)
83
- EOS
84
- ActiveRecord::Base.connection.execute <<~EOS
85
- CREATE TABLE index_definition_compound_index_models (
86
- fk1_id INTEGER NOT NULL,
87
- fk2_id INTEGER NOT NULL,
88
- PRIMARY KEY (fk1_id, fk2_id)
89
- )
90
- EOS
91
- ActiveRecord::Base.connection.schema_cache.clear!
92
- end
93
-
94
- describe 'for_model' do
95
- subject { described_class.for_model(model_class) }
96
-
97
- context 'with single-column PK' do
98
- it 'returns the indexes for the model' do
99
- expect(subject.size).to eq(2), subject.inspect
100
- expect([:name, :columns, :unique].map { |attr| subject[0].send(attr) }).to eq(
101
- ['index_definition_test_models_on_name', ['name'], true]
102
- )
103
- expect([:name, :columns, :unique].map { |attr| subject[1].send(attr) }).to eq(
104
- ['PRIMARY', ['id'], true]
105
- )
106
- end
107
- end
108
-
109
- context 'with compound-column PK' do
110
- let(:model_class) { IndexDefinitionCompoundIndexModel }
111
-
112
- it 'returns the indexes for the model' do
113
- expect(subject.size).to eq(1), subject.inspect
114
- expect([:name, :columns, :unique].map { |attr| subject[0].send(attr) }).to eq(
115
- ['PRIMARY', ['fk1_id', 'fk2_id'], true]
116
- )
117
- end
118
- end
119
- end
120
- end
121
- end
122
- end
123
-
124
15
  context 'Using declare_schema' do
125
16
  before do
126
17
  load File.expand_path('../prepare_testapp.rb', __dir__)
@@ -10,69 +10,6 @@ require_relative '../../../../lib/declare_schema/model/table_options_definition'
10
10
  RSpec.describe DeclareSchema::Model::TableOptionsDefinition do
11
11
  let(:model_class) { TableOptionsDefinitionTestModel }
12
12
 
13
- context 'Using fields' do
14
- before do
15
- load File.expand_path('../prepare_testapp.rb', __dir__)
16
-
17
- class TableOptionsDefinitionTestModel < ActiveRecord::Base
18
- fields do
19
- name :string, limit: 127, index: true
20
- end
21
- end
22
- end
23
-
24
- context 'instance methods' do
25
- let(:table_options) { { charset: "utf8", collation: "utf8_general"} }
26
- let(:model) { described_class.new('table_options_definition_test_models', table_options) }
27
-
28
- describe '#to_key' do
29
- subject { model.to_key }
30
- it { should eq(['table_options_definition_test_models', '{:charset=>"utf8", :collation=>"utf8_general"}']) }
31
- end
32
-
33
- describe '#settings' do
34
- subject { model.settings }
35
- it { should eq("CHARACTER SET utf8 COLLATE utf8_general") }
36
- end
37
-
38
- describe '#hash' do
39
- subject { model.hash }
40
- it { should eq(['table_options_definition_test_models', '{:charset=>"utf8", :collation=>"utf8_general"}'].hash) }
41
- end
42
-
43
- describe '#to_s' do
44
- subject { model.to_s }
45
- it { should eq("CHARACTER SET utf8 COLLATE utf8_general") }
46
- end
47
-
48
- describe '#alter_table_statement' do
49
- subject { model.alter_table_statement }
50
- it { should match(/execute "ALTER TABLE .*table_options_definition_test_models.* CHARACTER SET utf8 COLLATE utf8_general"/) }
51
- end
52
- end
53
-
54
- context 'class << self' do
55
- describe '#for_model' do
56
- context 'when database migrated' do
57
- let(:options) do
58
- if defined?(Mysql2)
59
- { charset: "utf8mb4", collation: "utf8mb4_bin" }
60
- else
61
- { }
62
- end
63
- end
64
- subject { described_class.for_model(model_class) }
65
-
66
- before do
67
- generate_migrations '-n', '-m'
68
- end
69
-
70
- it { should eq(described_class.new(model_class.table_name, options)) }
71
- end
72
- end
73
- end
74
- end
75
-
76
13
  context 'Using declare_schema' do
77
14
  before do
78
15
  load File.expand_path('../prepare_testapp.rb', __dir__)
@@ -86,7 +23,7 @@ RSpec.describe DeclareSchema::Model::TableOptionsDefinition do
86
23
 
87
24
  context 'instance methods' do
88
25
  let(:table_options) { { charset: "utf8", collation: "utf8_general"} }
89
- let(:model) { described_class.new('table_options_definition_test_models', table_options) }
26
+ let(:model) { described_class.new('table_options_definition_test_models', **table_options) }
90
27
 
91
28
  describe '#to_key' do
92
29
  subject { model.to_key }
@@ -130,7 +67,7 @@ RSpec.describe DeclareSchema::Model::TableOptionsDefinition do
130
67
  generate_migrations '-n', '-m'
131
68
  end
132
69
 
133
- it { should eq(described_class.new(model_class.table_name, options)) }
70
+ it { should eq(described_class.new(model_class.table_name, **options)) }
134
71
  end
135
72
  end
136
73
  end
@@ -12,7 +12,7 @@ RSpec.describe DeclareSchema::SchemaChange::ColumnAdd do
12
12
  let(:column_type) { :integer }
13
13
  let(:column_options) { { limit: 8 } }
14
14
  let(:column_options_string) { "limit: 8" }
15
- subject { described_class.new(table_name, column_name, column_type, column_options) }
15
+ subject { described_class.new(table_name, column_name, column_type, **column_options) }
16
16
 
17
17
  describe '#up/down' do
18
18
  describe '#up' do
@@ -12,7 +12,7 @@ RSpec.describe DeclareSchema::SchemaChange::ColumnRemove do
12
12
  let(:column_type) { :integer }
13
13
  let(:column_options) { { limit: 8 } }
14
14
  let(:column_options_string) { "limit: 8" }
15
- subject { described_class.new(table_name, column_name, column_type, column_options) }
15
+ subject { described_class.new(table_name, column_name, column_type, **column_options) }
16
16
 
17
17
  describe '#up/down' do
18
18
  describe '#up' do
data/spec/spec_helper.rb CHANGED
@@ -31,7 +31,7 @@ RSpec.configure do |config|
31
31
  end
32
32
 
33
33
  def migrate(renames = {})
34
- up, down = Generators::DeclareSchema::Migration::Migrator.run(renames)
34
+ up, down = Generators::DeclareSchema::Migration::Migrator.run(**renames)
35
35
  ActiveRecord::Migration.class_eval(up)
36
36
  ActiveRecord::Base.send(:descendants).each { |model| model.reset_column_information }
37
37
  [up, down]
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: declare_schema
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.14.1
4
+ version: 1.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Invoca Development adapted from hobo_fields by Tom Locke
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-09-01 00:00:00.000000000 Z
11
+ date: 2022-03-28 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -126,7 +126,7 @@ homepage: https://github.com/Invoca/declare_schema
126
126
  licenses: []
127
127
  metadata:
128
128
  allowed_push_host: https://rubygems.org
129
- post_install_message:
129
+ post_install_message:
130
130
  rdoc_options: []
131
131
  require_paths:
132
132
  - lib
@@ -141,8 +141,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
141
141
  - !ruby/object:Gem::Version
142
142
  version: 1.3.6
143
143
  requirements: []
144
- rubygems_version: 3.1.2
145
- signing_key:
144
+ rubygems_version: 3.1.6
145
+ signing_key:
146
146
  specification_version: 4
147
147
  summary: Database schema declaration and migration generator for Rails
148
148
  test_files: []