declare_schema 0.10.0 → 0.12.0.pre.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +31 -1
- data/Gemfile.lock +1 -1
- data/README.md +16 -6
- data/lib/declare_schema.rb +12 -1
- data/lib/declare_schema/extensions/active_record/fields_declaration.rb +4 -2
- data/lib/declare_schema/model.rb +59 -15
- data/lib/declare_schema/model/column.rb +2 -2
- data/lib/declare_schema/model/field_spec.rb +4 -4
- data/lib/declare_schema/model/foreign_key_definition.rb +6 -11
- data/lib/declare_schema/model/habtm_model_shim.rb +2 -2
- data/lib/declare_schema/model/index_definition.rb +8 -25
- data/lib/declare_schema/schema_change/all.rb +22 -0
- data/lib/declare_schema/schema_change/base.rb +45 -0
- data/lib/declare_schema/schema_change/column_add.rb +27 -0
- data/lib/declare_schema/schema_change/column_change.rb +32 -0
- data/lib/declare_schema/schema_change/column_remove.rb +20 -0
- data/lib/declare_schema/schema_change/column_rename.rb +23 -0
- data/lib/declare_schema/schema_change/foreign_key_add.rb +25 -0
- data/lib/declare_schema/schema_change/foreign_key_remove.rb +20 -0
- data/lib/declare_schema/schema_change/index_add.rb +33 -0
- data/lib/declare_schema/schema_change/index_remove.rb +20 -0
- data/lib/declare_schema/schema_change/primary_key_change.rb +33 -0
- data/lib/declare_schema/schema_change/table_add.rb +37 -0
- data/lib/declare_schema/schema_change/table_change.rb +36 -0
- data/lib/declare_schema/schema_change/table_remove.rb +22 -0
- data/lib/declare_schema/schema_change/table_rename.rb +22 -0
- data/lib/declare_schema/version.rb +1 -1
- data/lib/generators/declare_schema/migration/USAGE +14 -24
- data/lib/generators/declare_schema/migration/migration_generator.rb +40 -38
- data/lib/generators/declare_schema/migration/migrator.rb +190 -187
- data/lib/generators/declare_schema/migration/templates/migration.rb.erb +3 -3
- data/spec/lib/declare_schema/api_spec.rb +3 -1
- data/spec/lib/declare_schema/field_spec_spec.rb +3 -3
- data/spec/lib/declare_schema/generator_spec.rb +2 -2
- data/spec/lib/declare_schema/interactive_primary_key_spec.rb +60 -25
- data/spec/lib/declare_schema/migration_generator_spec.rb +471 -377
- data/spec/lib/declare_schema/model/column_spec.rb +2 -6
- data/spec/lib/declare_schema/model/foreign_key_definition_spec.rb +28 -16
- data/spec/lib/declare_schema/model/habtm_model_shim_spec.rb +4 -6
- data/spec/lib/declare_schema/model/index_definition_spec.rb +4 -4
- data/spec/lib/declare_schema/schema_change/base_spec.rb +75 -0
- data/spec/lib/declare_schema/schema_change/column_add_spec.rb +30 -0
- data/spec/lib/declare_schema/schema_change/column_change_spec.rb +33 -0
- data/spec/lib/declare_schema/schema_change/column_remove_spec.rb +30 -0
- data/spec/lib/declare_schema/schema_change/column_rename_spec.rb +28 -0
- data/spec/lib/declare_schema/schema_change/foreign_key_add_spec.rb +29 -0
- data/spec/lib/declare_schema/schema_change/foreign_key_remove_spec.rb +29 -0
- data/spec/lib/declare_schema/schema_change/index_add_spec.rb +56 -0
- data/spec/lib/declare_schema/schema_change/index_remove_spec.rb +29 -0
- data/spec/lib/declare_schema/schema_change/primary_key_change_spec.rb +69 -0
- data/spec/lib/declare_schema/schema_change/table_add_spec.rb +50 -0
- data/spec/lib/declare_schema/schema_change/table_change_spec.rb +30 -0
- data/spec/lib/declare_schema/schema_change/table_remove_spec.rb +27 -0
- data/spec/lib/declare_schema/schema_change/table_rename_spec.rb +27 -0
- data/spec/lib/generators/declare_schema/migration/migrator_spec.rb +59 -11
- data/spec/spec_helper.rb +1 -1
- data/spec/support/acceptance_spec_helpers.rb +2 -2
- metadata +34 -5
@@ -0,0 +1,22 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module DeclareSchema
|
4
|
+
module SchemaChange
|
5
|
+
module All
|
6
|
+
end
|
7
|
+
autoload :Base, 'declare_schema/schema_change/base'
|
8
|
+
autoload :ColumnAdd, 'declare_schema/schema_change/column_add'
|
9
|
+
autoload :ColumnChange, 'declare_schema/schema_change/column_change'
|
10
|
+
autoload :ColumnRename, 'declare_schema/schema_change/column_rename'
|
11
|
+
autoload :ForeignKeyAdd, 'declare_schema/schema_change/foreign_key_add'
|
12
|
+
autoload :ForeignKeyRemove, 'declare_schema/schema_change/foreign_key_remove'
|
13
|
+
autoload :IndexAdd, 'declare_schema/schema_change/index_add'
|
14
|
+
autoload :IndexRemove, 'declare_schema/schema_change/index_remove'
|
15
|
+
autoload :PrimaryKeyChange, 'declare_schema/schema_change/primary_key_change'
|
16
|
+
autoload :TableAdd, 'declare_schema/schema_change/table_add'
|
17
|
+
autoload :TableChange, 'declare_schema/schema_change/table_change'
|
18
|
+
autoload :TableRemove, 'declare_schema/schema_change/table_remove'
|
19
|
+
autoload :TableRename, 'declare_schema/schema_change/table_rename'
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
@@ -0,0 +1,45 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'base'
|
4
|
+
|
5
|
+
module DeclareSchema
|
6
|
+
module SchemaChange
|
7
|
+
class Base
|
8
|
+
class << self
|
9
|
+
def format_options(options)
|
10
|
+
options.map do |k, v|
|
11
|
+
value =
|
12
|
+
if v.is_a?(Hash)
|
13
|
+
"{ #{format_options(v).join(', ')} }"
|
14
|
+
else
|
15
|
+
v.inspect
|
16
|
+
end
|
17
|
+
if k.is_a?(Symbol)
|
18
|
+
"#{k}: #{value}"
|
19
|
+
else
|
20
|
+
"#{k.inspect} => #{value}"
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def up
|
27
|
+
up_command + spacing(up_command)
|
28
|
+
end
|
29
|
+
|
30
|
+
def down
|
31
|
+
down_command + spacing(down_command)
|
32
|
+
end
|
33
|
+
|
34
|
+
private
|
35
|
+
|
36
|
+
def spacing(command)
|
37
|
+
if command["\n"]
|
38
|
+
"\n\n"
|
39
|
+
else
|
40
|
+
"\n"
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'base'
|
4
|
+
|
5
|
+
module DeclareSchema
|
6
|
+
module SchemaChange
|
7
|
+
class ColumnAdd < Base
|
8
|
+
def initialize(table_name, column_name, column_type, **column_options)
|
9
|
+
@table_name = table_name or raise ArgumentError, "must provide table_name"
|
10
|
+
@column_name = column_name or raise ArgumentError, "must provide column_name"
|
11
|
+
@column_type = column_type or raise ArgumentError, "must provide column_type"
|
12
|
+
@column_options = column_options
|
13
|
+
end
|
14
|
+
|
15
|
+
def up_command
|
16
|
+
"add_column #{[@table_name.to_sym.inspect,
|
17
|
+
@column_name.to_sym.inspect,
|
18
|
+
@column_type.to_sym.inspect,
|
19
|
+
*self.class.format_options(@column_options)].join(", ")}"
|
20
|
+
end
|
21
|
+
|
22
|
+
def down_command
|
23
|
+
"remove_column #{@table_name.to_sym.inspect}, #{@column_name.to_sym.inspect}"
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'base'
|
4
|
+
|
5
|
+
module DeclareSchema
|
6
|
+
module SchemaChange
|
7
|
+
class ColumnChange < Base
|
8
|
+
def initialize(table_name, column_name, old_type:, old_options:, new_type:, new_options:)
|
9
|
+
@table_name = table_name
|
10
|
+
@column_name = column_name
|
11
|
+
@old_type = old_type
|
12
|
+
@old_options = old_options
|
13
|
+
@new_type = new_type
|
14
|
+
@new_options = new_options
|
15
|
+
end
|
16
|
+
|
17
|
+
def up_command
|
18
|
+
"change_column #{[@table_name.to_sym.inspect,
|
19
|
+
@column_name.to_sym.inspect,
|
20
|
+
@new_type.to_sym.inspect,
|
21
|
+
*self.class.format_options(@new_options)].join(", ")}"
|
22
|
+
end
|
23
|
+
|
24
|
+
def down_command
|
25
|
+
"change_column #{[@table_name.to_sym.inspect,
|
26
|
+
@column_name.to_sym.inspect,
|
27
|
+
@old_type.to_sym.inspect,
|
28
|
+
*self.class.format_options(@old_options)].join(", ")}"
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'column_add'
|
4
|
+
|
5
|
+
module DeclareSchema
|
6
|
+
module SchemaChange
|
7
|
+
class ColumnRemove < ColumnAdd
|
8
|
+
alias column_add_up_command up_command
|
9
|
+
alias column_add_down_command down_command
|
10
|
+
|
11
|
+
def up_command
|
12
|
+
column_add_down_command
|
13
|
+
end
|
14
|
+
|
15
|
+
def down_command
|
16
|
+
column_add_up_command
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'base'
|
4
|
+
|
5
|
+
module DeclareSchema
|
6
|
+
module SchemaChange
|
7
|
+
class ColumnRename < Base
|
8
|
+
def initialize(table_name, old_name, new_name)
|
9
|
+
@table_name = table_name
|
10
|
+
@old_name = old_name
|
11
|
+
@new_name = new_name
|
12
|
+
end
|
13
|
+
|
14
|
+
def up_command
|
15
|
+
"rename_column #{@table_name.to_sym.inspect}, #{@old_name.to_sym.inspect}, #{@new_name.to_sym.inspect}"
|
16
|
+
end
|
17
|
+
|
18
|
+
def down_command
|
19
|
+
"rename_column #{@table_name.to_sym.inspect}, #{@new_name.to_sym.inspect}, #{@old_name.to_sym.inspect}"
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'base'
|
4
|
+
|
5
|
+
module DeclareSchema
|
6
|
+
module SchemaChange
|
7
|
+
class ForeignKeyAdd < Base
|
8
|
+
def initialize(table_name, parent_table_name, column_name:, name:)
|
9
|
+
@table_name = table_name
|
10
|
+
@parent_table_name = parent_table_name
|
11
|
+
@column_name = column_name
|
12
|
+
@name = name
|
13
|
+
end
|
14
|
+
|
15
|
+
def up_command
|
16
|
+
"add_foreign_key #{@table_name.to_sym.inspect}, #{@parent_table_name.to_sym.inspect}, " +
|
17
|
+
"column: #{@column_name.to_sym.inspect}, name: #{@name.to_sym.inspect}"
|
18
|
+
end
|
19
|
+
|
20
|
+
def down_command
|
21
|
+
"remove_foreign_key #{@table_name.to_sym.inspect}, name: #{@name.to_sym.inspect}"
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'foreign_key_add'
|
4
|
+
|
5
|
+
module DeclareSchema
|
6
|
+
module SchemaChange
|
7
|
+
class ForeignKeyRemove < ForeignKeyAdd
|
8
|
+
alias index_add_up_command up_command
|
9
|
+
alias index_add_down_command down_command
|
10
|
+
|
11
|
+
def up_command
|
12
|
+
index_add_down_command
|
13
|
+
end
|
14
|
+
|
15
|
+
def down_command
|
16
|
+
index_add_up_command
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'base'
|
4
|
+
|
5
|
+
module DeclareSchema
|
6
|
+
module SchemaChange
|
7
|
+
class IndexAdd < Base
|
8
|
+
def initialize(table_name, column_names, name:, unique:, where: nil)
|
9
|
+
@table_name = table_name
|
10
|
+
@column_names = column_names
|
11
|
+
@name = name
|
12
|
+
@unique = unique
|
13
|
+
@where = where.presence
|
14
|
+
end
|
15
|
+
|
16
|
+
def up_command
|
17
|
+
options = {
|
18
|
+
name: @name.to_sym,
|
19
|
+
}
|
20
|
+
options[:unique] = true if @unique
|
21
|
+
options[:where] = @where if @where
|
22
|
+
|
23
|
+
"add_index #{[@table_name.to_sym.inspect,
|
24
|
+
@column_names.map(&:to_sym).inspect,
|
25
|
+
*self.class.format_options(options)].join(', ')}"
|
26
|
+
end
|
27
|
+
|
28
|
+
def down_command
|
29
|
+
"remove_index #{@table_name.to_sym.inspect}, name: #{@name.to_sym.inspect}"
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'index_add'
|
4
|
+
|
5
|
+
module DeclareSchema
|
6
|
+
module SchemaChange
|
7
|
+
class IndexRemove < IndexAdd
|
8
|
+
alias index_add_up_command up_command
|
9
|
+
alias index_add_down_command down_command
|
10
|
+
|
11
|
+
def up_command
|
12
|
+
index_add_down_command
|
13
|
+
end
|
14
|
+
|
15
|
+
def down_command
|
16
|
+
index_add_up_command
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'base'
|
4
|
+
|
5
|
+
module DeclareSchema
|
6
|
+
module SchemaChange
|
7
|
+
class PrimaryKeyChange < Base
|
8
|
+
def initialize(table_name, old_column_names, new_column_names)
|
9
|
+
@table_name = table_name
|
10
|
+
@old_column_names = old_column_names.presence
|
11
|
+
@new_column_names = new_column_names.presence
|
12
|
+
end
|
13
|
+
|
14
|
+
def up_command
|
15
|
+
alter_primary_key(@old_column_names, @new_column_names)
|
16
|
+
end
|
17
|
+
|
18
|
+
def down_command
|
19
|
+
alter_primary_key(@new_column_names, @old_column_names)
|
20
|
+
end
|
21
|
+
|
22
|
+
private
|
23
|
+
|
24
|
+
def alter_primary_key(old_col_names, new_col_names)
|
25
|
+
drop_command = "DROP PRIMARY KEY" if old_col_names
|
26
|
+
add_command = "ADD PRIMARY KEY (#{new_col_names.join(', ')})" if new_col_names
|
27
|
+
commands = [drop_command, add_command].compact.join(', ')
|
28
|
+
statement = "ALTER TABLE #{ActiveRecord::Base.connection.quote_table_name(@table_name)} #{commands}"
|
29
|
+
"execute #{statement.inspect}"
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'base'
|
4
|
+
|
5
|
+
module DeclareSchema
|
6
|
+
module SchemaChange
|
7
|
+
class TableAdd < Base
|
8
|
+
def initialize(table_name, fields, create_table_options, sql_options: nil)
|
9
|
+
@table_name = table_name
|
10
|
+
fields.all? do |type, name, options|
|
11
|
+
type.is_a?(Symbol) && name.is_a?(Symbol) && options.is_a?(Hash)
|
12
|
+
end or raise ArgumentError, "fields must be Array(Array(Symbol, Symbol, Hash)); got #{fields.inspect}"
|
13
|
+
@fields = fields
|
14
|
+
@create_table_options = create_table_options
|
15
|
+
@create_table_options = @create_table_options.merge(options: sql_options) if sql_options.present?
|
16
|
+
end
|
17
|
+
|
18
|
+
def up_command
|
19
|
+
longest_field_type_length = @fields.map { |type, _name, _option| type.to_s.length }.max
|
20
|
+
|
21
|
+
<<~EOS.strip
|
22
|
+
create_table #{[@table_name.to_sym.inspect, *self.class.format_options(@create_table_options)].join(', ')} do |t|
|
23
|
+
#{@fields.map do |type, name, options|
|
24
|
+
padded_type = format("%-*s", longest_field_type_length, type)
|
25
|
+
args = [name.inspect, *self.class.format_options(options)].join(', ')
|
26
|
+
" t.#{padded_type} #{args}"
|
27
|
+
end.join("\n")}
|
28
|
+
end
|
29
|
+
EOS
|
30
|
+
end
|
31
|
+
|
32
|
+
def down_command
|
33
|
+
"drop_table #{@table_name.to_sym.inspect}"
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'base'
|
4
|
+
|
5
|
+
module DeclareSchema
|
6
|
+
module SchemaChange
|
7
|
+
class TableChange < Base
|
8
|
+
def initialize(table_name, old_options, new_options)
|
9
|
+
@table_name = table_name
|
10
|
+
@old_options = old_options
|
11
|
+
@new_options = new_options
|
12
|
+
end
|
13
|
+
|
14
|
+
def up_command
|
15
|
+
alter_table(@table_name, @new_options)
|
16
|
+
end
|
17
|
+
|
18
|
+
def down_command
|
19
|
+
alter_table(@table_name, @old_options)
|
20
|
+
end
|
21
|
+
|
22
|
+
private
|
23
|
+
|
24
|
+
TABLE_OPTIONS_TO_SQL_MAPPINGS = {
|
25
|
+
charset: 'CHARACTER SET',
|
26
|
+
collation: 'COLLATE'
|
27
|
+
}.freeze
|
28
|
+
|
29
|
+
def alter_table(table_name, options)
|
30
|
+
sql_options = options.map { |key, value| [TABLE_OPTIONS_TO_SQL_MAPPINGS[key], value] }
|
31
|
+
statement = "ALTER TABLE #{ActiveRecord::Base.connection.quote_table_name(table_name)} #{sql_options.join(' ')}"
|
32
|
+
"execute #{statement.inspect}"
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'base'
|
4
|
+
|
5
|
+
module DeclareSchema
|
6
|
+
module SchemaChange
|
7
|
+
class TableRemove < Base
|
8
|
+
def initialize(table_name, add_table_back)
|
9
|
+
@table_name = table_name
|
10
|
+
@add_table_back = add_table_back
|
11
|
+
end
|
12
|
+
|
13
|
+
def up_command
|
14
|
+
"drop_table #{@table_name.to_sym.inspect}"
|
15
|
+
end
|
16
|
+
|
17
|
+
def down_command
|
18
|
+
@add_table_back
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'base'
|
4
|
+
|
5
|
+
module DeclareSchema
|
6
|
+
module SchemaChange
|
7
|
+
class TableRename < Base
|
8
|
+
def initialize(old_name, new_name)
|
9
|
+
@old_name = old_name
|
10
|
+
@new_name = new_name
|
11
|
+
end
|
12
|
+
|
13
|
+
def up_command
|
14
|
+
"rename_table #{@old_name.to_sym.inspect}, #{@new_name.to_sym.inspect}"
|
15
|
+
end
|
16
|
+
|
17
|
+
def down_command
|
18
|
+
"rename_table #{@new_name.to_sym.inspect}, #{@old_name.to_sym.inspect}"
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|