declare_schema 0.14.2 → 1.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/CODEOWNERS +1 -0
- data/.github/workflows/declare_schema_build.yml +22 -23
- data/.ruby-version +1 -1
- data/Appraisals +8 -0
- data/CHANGELOG.md +22 -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 +2 -2
- 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 +2 -2
- 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/field_spec_spec.rb +2 -2
- 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/lib/declare_schema/schema_change/column_add_spec.rb +1 -1
- data/spec/lib/declare_schema/schema_change/column_remove_spec.rb +1 -1
- data/spec/spec_helper.rb +1 -1
- metadata +7 -6
@@ -10,7 +10,7 @@ module DeclareSchema
|
|
10
10
|
attr_reader :constraint_name, :model, :foreign_key, :foreign_key_name, :parent_table_name, :child_table_name, :options, :on_delete_cascade
|
11
11
|
|
12
12
|
|
13
|
-
def initialize(model, foreign_key, options
|
13
|
+
def initialize(model, foreign_key, **options)
|
14
14
|
@model = model
|
15
15
|
@foreign_key = foreign_key.to_s.presence
|
16
16
|
@options = options
|
@@ -38,7 +38,7 @@ module DeclareSchema
|
|
38
38
|
}
|
39
39
|
options[:dependent] = :delete if fkc['ON DELETE CASCADE']
|
40
40
|
|
41
|
-
new(model, foreign_key, options)
|
41
|
+
new(model, foreign_key, **options)
|
42
42
|
end
|
43
43
|
end
|
44
44
|
end
|
@@ -14,7 +14,7 @@ module DeclareSchema
|
|
14
14
|
PRIMARY_KEY_NAME = "PRIMARY"
|
15
15
|
MYSQL_INDEX_NAME_MAX_LENGTH = 64
|
16
16
|
|
17
|
-
def initialize(model, fields, options
|
17
|
+
def initialize(model, fields, **options)
|
18
18
|
@model = model
|
19
19
|
@table = options.delete(:table_name) || model.table_name
|
20
20
|
@fields = Array.wrap(fields).map(&:to_s)
|
@@ -37,7 +37,7 @@ module DeclareSchema
|
|
37
37
|
def for_model(model, old_table_name = nil)
|
38
38
|
t = old_table_name || model.table_name
|
39
39
|
|
40
|
-
primary_key_columns = Array(model.connection.primary_key(t)).presence
|
40
|
+
primary_key_columns = Array(model.connection.primary_key(t)).presence or
|
41
41
|
raise "could not find primary key for table #{t} in #{model.connection.columns(t).inspect}"
|
42
42
|
|
43
43
|
primary_key_found = false
|
@@ -19,7 +19,7 @@ module DeclareSchema
|
|
19
19
|
{}
|
20
20
|
end
|
21
21
|
|
22
|
-
new(table_name, table_options)
|
22
|
+
new(table_name, **table_options)
|
23
23
|
end
|
24
24
|
|
25
25
|
private
|
@@ -48,7 +48,7 @@ module DeclareSchema
|
|
48
48
|
|
49
49
|
attr_reader :table_name, :table_options
|
50
50
|
|
51
|
-
def initialize(table_name, table_options
|
51
|
+
def initialize(table_name, **table_options)
|
52
52
|
@table_name = table_name
|
53
53
|
@table_options = table_options
|
54
54
|
end
|
data/lib/declare_schema/model.rb
CHANGED
@@ -49,11 +49,11 @@ module DeclareSchema
|
|
49
49
|
end
|
50
50
|
|
51
51
|
module ClassMethods
|
52
|
-
def index(fields, options
|
52
|
+
def index(fields, **options)
|
53
53
|
# make index idempotent
|
54
54
|
index_fields_s = Array.wrap(fields).map(&:to_s)
|
55
55
|
unless index_definitions.any? { |index_spec| index_spec.fields == index_fields_s }
|
56
|
-
index_definitions << ::DeclareSchema::Model::IndexDefinition.new(self, fields, options)
|
56
|
+
index_definitions << ::DeclareSchema::Model::IndexDefinition.new(self, fields, **options)
|
57
57
|
end
|
58
58
|
end
|
59
59
|
|
@@ -61,10 +61,10 @@ module DeclareSchema
|
|
61
61
|
index(fields.flatten, unique: true, name: ::DeclareSchema::Model::IndexDefinition::PRIMARY_KEY_NAME)
|
62
62
|
end
|
63
63
|
|
64
|
-
def constraint(fkey, options
|
64
|
+
def constraint(fkey, **options)
|
65
65
|
fkey_s = fkey.to_s
|
66
66
|
unless constraint_specs.any? { |constraint_spec| constraint_spec.foreign_key == fkey_s }
|
67
|
-
constraint_specs << DeclareSchema::Model::ForeignKeyDefinition.new(self, fkey, options)
|
67
|
+
constraint_specs << DeclareSchema::Model::ForeignKeyDefinition.new(self, fkey, **options)
|
68
68
|
end
|
69
69
|
end
|
70
70
|
|
@@ -157,10 +157,10 @@ module DeclareSchema
|
|
157
157
|
if refl.options[:polymorphic]
|
158
158
|
foreign_type = options[:foreign_type] || "#{name}_type"
|
159
159
|
_declare_polymorphic_type_field(foreign_type, column_options)
|
160
|
-
index([foreign_type, fkey], index_options) if index_options[:name] != false
|
160
|
+
index([foreign_type, fkey], **index_options) if index_options[:name] != false
|
161
161
|
else
|
162
|
-
index(fkey, index_options) if index_options[:name] != false
|
163
|
-
constraint(fkey, fk_options) if fk_options[:constraint_name] != false
|
162
|
+
index(fkey, **index_options) if index_options[:name] != false
|
163
|
+
constraint(fkey, **fk_options) if fk_options[:constraint_name] != false
|
164
164
|
end
|
165
165
|
end
|
166
166
|
|
@@ -258,7 +258,7 @@ module DeclareSchema
|
|
258
258
|
ActiveRecord::Coders::JSON
|
259
259
|
elsif [:load, :dump].all? { |x| class_name_or_coder.respond_to?(x) }
|
260
260
|
class_name_or_coder
|
261
|
-
else
|
261
|
+
else
|
262
262
|
ActiveRecord::Coders::YAMLColumn.new(attr_name, class_name_or_coder)
|
263
263
|
end
|
264
264
|
|
@@ -287,7 +287,7 @@ module DeclareSchema
|
|
287
287
|
}
|
288
288
|
# support index: true declaration
|
289
289
|
index_opts[:name] = to_name unless to_name == true
|
290
|
-
index(name, index_opts)
|
290
|
+
index(name, **index_opts)
|
291
291
|
end
|
292
292
|
end
|
293
293
|
|
@@ -24,7 +24,7 @@ module Generators
|
|
24
24
|
@active_record_class
|
25
25
|
end
|
26
26
|
|
27
|
-
def run(renames
|
27
|
+
def run(**renames)
|
28
28
|
Migrator.new(renames: renames).generate
|
29
29
|
end
|
30
30
|
|
@@ -235,7 +235,7 @@ module Generators
|
|
235
235
|
[f.type, f.name, f.sql_options]
|
236
236
|
end
|
237
237
|
|
238
|
-
table_options_definition = ::DeclareSchema::Model::TableOptionsDefinition.new(model.table_name, table_options_for_model(model))
|
238
|
+
table_options_definition = ::DeclareSchema::Model::TableOptionsDefinition.new(model.table_name, **table_options_for_model(model))
|
239
239
|
table_options = create_table_options(model, disable_auto_increment)
|
240
240
|
|
241
241
|
table_add = ::DeclareSchema::SchemaChange::TableAdd.new(t,
|
@@ -374,12 +374,12 @@ module Generators
|
|
374
374
|
else
|
375
375
|
[:integer, {}]
|
376
376
|
end
|
377
|
-
::DeclareSchema::SchemaChange::ColumnAdd.new(new_table_name, c, type, options)
|
377
|
+
::DeclareSchema::SchemaChange::ColumnAdd.new(new_table_name, c, type, **options)
|
378
378
|
end
|
379
379
|
|
380
380
|
removes = to_remove.map do |c|
|
381
381
|
old_type, old_options = add_column_back(model, current_table_name, c)
|
382
|
-
::DeclareSchema::SchemaChange::ColumnRemove.new(new_table_name, c, old_type, old_options)
|
382
|
+
::DeclareSchema::SchemaChange::ColumnRemove.new(new_table_name, c, old_type, **old_options)
|
383
383
|
end
|
384
384
|
|
385
385
|
old_names = to_rename.invert
|
@@ -502,7 +502,7 @@ module Generators
|
|
502
502
|
|
503
503
|
def change_table_options(model, current_table_name)
|
504
504
|
old_options_definition = ::DeclareSchema::Model::TableOptionsDefinition.for_model(model, current_table_name)
|
505
|
-
new_options_definition = ::DeclareSchema::Model::TableOptionsDefinition.new(model.table_name, table_options_for_model(model))
|
505
|
+
new_options_definition = ::DeclareSchema::Model::TableOptionsDefinition.new(model.table_name, **table_options_for_model(model))
|
506
506
|
|
507
507
|
if old_options_definition.equivalent?(new_options_definition)
|
508
508
|
[]
|
@@ -552,7 +552,7 @@ module Generators
|
|
552
552
|
end
|
553
553
|
|
554
554
|
SchemaDumper = ActiveRecord::ConnectionAdapters::SchemaDumper
|
555
|
-
|
555
|
+
|
556
556
|
|
557
557
|
def add_table_back(table)
|
558
558
|
dumped_schema_stream = StringIO.new
|
@@ -6,30 +6,6 @@ RSpec.describe DeclareSchema::FieldDeclarationDsl do
|
|
6
6
|
let(:model) { TestModel.new }
|
7
7
|
subject { declared_class.new(model) }
|
8
8
|
|
9
|
-
context 'Using fields' do
|
10
|
-
before do
|
11
|
-
load File.expand_path('prepare_testapp.rb', __dir__)
|
12
|
-
|
13
|
-
class TestModel < ActiveRecord::Base
|
14
|
-
fields do
|
15
|
-
name :string, limit: 127
|
16
|
-
|
17
|
-
timestamps
|
18
|
-
end
|
19
|
-
end
|
20
|
-
end
|
21
|
-
|
22
|
-
it 'has fields' do
|
23
|
-
expect(TestModel.field_specs).to be_kind_of(Hash)
|
24
|
-
expect(TestModel.field_specs.keys).to eq(['name', 'created_at', 'updated_at'])
|
25
|
-
expect(TestModel.field_specs.values.map(&:type)).to eq([:string, :datetime, :datetime])
|
26
|
-
end
|
27
|
-
|
28
|
-
it 'stores limits' do
|
29
|
-
expect(TestModel.field_specs['name'].limit).to eq(127), TestModel.field_specs['name'].inspect
|
30
|
-
end
|
31
|
-
end
|
32
|
-
|
33
9
|
context 'Using declare_schema' do
|
34
10
|
before do
|
35
11
|
load File.expand_path('prepare_testapp.rb', __dir__)
|
@@ -185,12 +185,12 @@ RSpec.describe DeclareSchema::Model::FieldSpec do
|
|
185
185
|
|
186
186
|
it 'does not allow precision:' do
|
187
187
|
expect_any_instance_of(described_class).to receive(:warn).with(/precision: only allowed for :decimal type/)
|
188
|
-
described_class.new(model, :quantity, t, { precision: 8, null: true, position: 3 }.merge(extra))
|
188
|
+
described_class.new(model, :quantity, t, **{ precision: 8, null: true, position: 3 }.merge(extra))
|
189
189
|
end unless t == :datetime
|
190
190
|
|
191
191
|
it 'does not allow scale:' do
|
192
192
|
expect_any_instance_of(described_class).to receive(:warn).with(/scale: only allowed for :decimal type/)
|
193
|
-
described_class.new(model, :quantity, t, { scale: 10, null: true, position: 3 }.merge(extra))
|
193
|
+
described_class.new(model, :quantity, t, **{ scale: 10, null: true, position: 3 }.merge(extra))
|
194
194
|
end
|
195
195
|
end
|
196
196
|
end
|
@@ -10,73 +10,6 @@ RSpec.describe 'DeclareSchema Migration Generator interactive primary key' do
|
|
10
10
|
load File.expand_path('prepare_testapp.rb', __dir__)
|
11
11
|
end
|
12
12
|
|
13
|
-
context 'Using fields' do
|
14
|
-
it "allows alternate primary keys" do
|
15
|
-
class Foo < ActiveRecord::Base
|
16
|
-
fields do
|
17
|
-
end
|
18
|
-
self.primary_key = "foo_id"
|
19
|
-
end
|
20
|
-
|
21
|
-
generate_migrations '-n', '-m'
|
22
|
-
expect(Foo._declared_primary_key).to eq('foo_id')
|
23
|
-
|
24
|
-
### migrate from
|
25
|
-
# rename from custom primary_key
|
26
|
-
class Foo < ActiveRecord::Base
|
27
|
-
fields do
|
28
|
-
end
|
29
|
-
self.primary_key = "id"
|
30
|
-
end
|
31
|
-
|
32
|
-
allow_any_instance_of(DeclareSchema::Support::ThorShell).to receive(:ask).with(/one of the rename choices or press enter to keep/) { 'id' }
|
33
|
-
generate_migrations '-n', '-m'
|
34
|
-
expect(Foo._declared_primary_key).to eq('id')
|
35
|
-
|
36
|
-
nuke_model_class(Foo)
|
37
|
-
|
38
|
-
# The ActiveRecord sqlite3 driver has a bug where rename_column recreates the entire table, but forgets to set the primary key:
|
39
|
-
#
|
40
|
-
# [7] pry(#<RSpec::ExampleGroups::DeclareSchemaMigrationGeneratorInteractivePrimaryKey>)> u = 'rename_column :foos, :foo_id, :id'
|
41
|
-
# => "rename_column :foos, :foo_id, :id"
|
42
|
-
# [8] pry(#<RSpec::ExampleGroups::DeclareSchemaMigrationGeneratorInteractivePrimaryKey>)> ActiveRecord::Migration.class_eval(u)
|
43
|
-
# (0.0ms) begin transaction
|
44
|
-
# (pry):17
|
45
|
-
# (0.2ms) CREATE TEMPORARY TABLE "afoos" ("id" integer NOT NULL)
|
46
|
-
# (pry):17
|
47
|
-
# (0.1ms) INSERT INTO "afoos" ("id")
|
48
|
-
#
|
49
|
-
# (pry):17
|
50
|
-
# (0.4ms) DROP TABLE "foos"
|
51
|
-
# (pry):17
|
52
|
-
# (0.1ms) CREATE TABLE "foos" ("id" integer NOT NULL)
|
53
|
-
# (pry):17
|
54
|
-
# (0.1ms) INSERT INTO "foos" ("id")
|
55
|
-
#
|
56
|
-
# (pry):17
|
57
|
-
# (0.1ms) DROP TABLE "afoos"
|
58
|
-
# (pry):17
|
59
|
-
# (0.9ms) commit transaction
|
60
|
-
if defined?(SQLite3)
|
61
|
-
ActiveRecord::Base.connection.execute("drop table foos")
|
62
|
-
ActiveRecord::Base.connection.execute("CREATE TABLE foos (id integer PRIMARY KEY AUTOINCREMENT NOT NULL)")
|
63
|
-
end
|
64
|
-
|
65
|
-
if !defined?(Mysql2) # TODO TECH-4814 Put this test back for Mysql2
|
66
|
-
# replace custom primary_key
|
67
|
-
class Foo < ActiveRecord::Base
|
68
|
-
fields do
|
69
|
-
end
|
70
|
-
self.primary_key = "foo_id"
|
71
|
-
end
|
72
|
-
|
73
|
-
allow_any_instance_of(DeclareSchema::Support::ThorShell).to receive(:ask).with(/one of the rename choices or press enter to keep/) { 'drop id' }
|
74
|
-
generate_migrations '-n', '-m'
|
75
|
-
expect(Foo._declared_primary_key).to eq('foo_id')
|
76
|
-
end
|
77
|
-
end
|
78
|
-
end
|
79
|
-
|
80
13
|
context 'Using declare_schema' do
|
81
14
|
it "allows alternate primary keys" do
|
82
15
|
class Foo < ActiveRecord::Base
|