declare_schema 0.14.3 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/workflows/declare_schema_build.yml +22 -23
- data/.ruby-version +1 -1
- data/Appraisals +8 -0
- data/CHANGELOG.md +12 -4
- data/Gemfile +3 -2
- data/Gemfile.lock +107 -77
- data/README.md +18 -8
- data/Rakefile +1 -1
- data/gemfiles/rails_5_mysql.gemfile +0 -1
- data/gemfiles/rails_5_sqlite.gemfile +0 -1
- data/gemfiles/rails_6_mysql.gemfile +2 -1
- data/gemfiles/rails_6_sqlite.gemfile +2 -1
- data/lib/declare_schema/command.rb +1 -1
- data/lib/declare_schema/dsl.rb +1 -1
- data/lib/declare_schema/extensions/active_record/fields_declaration.rb +0 -18
- data/lib/declare_schema/field_declaration_dsl.rb +4 -4
- data/lib/declare_schema/model/foreign_key_definition.rb +2 -2
- data/lib/declare_schema/model/index_definition.rb +1 -1
- data/lib/declare_schema/model/table_options_definition.rb +2 -2
- data/lib/declare_schema/model.rb +9 -9
- data/lib/declare_schema/version.rb +1 -1
- data/lib/generators/declare_schema/migration/migrator.rb +6 -6
- data/spec/lib/declare_schema/field_declaration_dsl_spec.rb +0 -24
- data/spec/lib/declare_schema/interactive_primary_key_spec.rb +0 -67
- data/spec/lib/declare_schema/migration_generator_spec.rb +11 -1176
- data/spec/lib/declare_schema/model/column_spec.rb +1 -28
- data/spec/lib/declare_schema/model/foreign_key_definition_spec.rb +1 -94
- data/spec/lib/declare_schema/model/index_definition_spec.rb +0 -109
- data/spec/lib/declare_schema/model/table_options_definition_spec.rb +2 -65
- data/spec/spec_helper.rb +1 -1
- 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
|
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.
|
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:
|
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.
|
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: []
|