declare_schema 0.10.0 → 0.12.0.pre.2

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 (59) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +31 -1
  3. data/Gemfile.lock +1 -1
  4. data/README.md +16 -6
  5. data/lib/declare_schema.rb +12 -1
  6. data/lib/declare_schema/extensions/active_record/fields_declaration.rb +4 -2
  7. data/lib/declare_schema/model.rb +59 -15
  8. data/lib/declare_schema/model/column.rb +2 -2
  9. data/lib/declare_schema/model/field_spec.rb +4 -4
  10. data/lib/declare_schema/model/foreign_key_definition.rb +6 -11
  11. data/lib/declare_schema/model/habtm_model_shim.rb +2 -2
  12. data/lib/declare_schema/model/index_definition.rb +8 -25
  13. data/lib/declare_schema/schema_change/all.rb +22 -0
  14. data/lib/declare_schema/schema_change/base.rb +45 -0
  15. data/lib/declare_schema/schema_change/column_add.rb +27 -0
  16. data/lib/declare_schema/schema_change/column_change.rb +32 -0
  17. data/lib/declare_schema/schema_change/column_remove.rb +20 -0
  18. data/lib/declare_schema/schema_change/column_rename.rb +23 -0
  19. data/lib/declare_schema/schema_change/foreign_key_add.rb +25 -0
  20. data/lib/declare_schema/schema_change/foreign_key_remove.rb +20 -0
  21. data/lib/declare_schema/schema_change/index_add.rb +33 -0
  22. data/lib/declare_schema/schema_change/index_remove.rb +20 -0
  23. data/lib/declare_schema/schema_change/primary_key_change.rb +33 -0
  24. data/lib/declare_schema/schema_change/table_add.rb +37 -0
  25. data/lib/declare_schema/schema_change/table_change.rb +36 -0
  26. data/lib/declare_schema/schema_change/table_remove.rb +22 -0
  27. data/lib/declare_schema/schema_change/table_rename.rb +22 -0
  28. data/lib/declare_schema/version.rb +1 -1
  29. data/lib/generators/declare_schema/migration/USAGE +14 -24
  30. data/lib/generators/declare_schema/migration/migration_generator.rb +40 -38
  31. data/lib/generators/declare_schema/migration/migrator.rb +190 -187
  32. data/lib/generators/declare_schema/migration/templates/migration.rb.erb +3 -3
  33. data/spec/lib/declare_schema/api_spec.rb +3 -1
  34. data/spec/lib/declare_schema/field_spec_spec.rb +3 -3
  35. data/spec/lib/declare_schema/generator_spec.rb +2 -2
  36. data/spec/lib/declare_schema/interactive_primary_key_spec.rb +60 -25
  37. data/spec/lib/declare_schema/migration_generator_spec.rb +471 -377
  38. data/spec/lib/declare_schema/model/column_spec.rb +2 -6
  39. data/spec/lib/declare_schema/model/foreign_key_definition_spec.rb +28 -16
  40. data/spec/lib/declare_schema/model/habtm_model_shim_spec.rb +4 -6
  41. data/spec/lib/declare_schema/model/index_definition_spec.rb +4 -4
  42. data/spec/lib/declare_schema/schema_change/base_spec.rb +75 -0
  43. data/spec/lib/declare_schema/schema_change/column_add_spec.rb +30 -0
  44. data/spec/lib/declare_schema/schema_change/column_change_spec.rb +33 -0
  45. data/spec/lib/declare_schema/schema_change/column_remove_spec.rb +30 -0
  46. data/spec/lib/declare_schema/schema_change/column_rename_spec.rb +28 -0
  47. data/spec/lib/declare_schema/schema_change/foreign_key_add_spec.rb +29 -0
  48. data/spec/lib/declare_schema/schema_change/foreign_key_remove_spec.rb +29 -0
  49. data/spec/lib/declare_schema/schema_change/index_add_spec.rb +56 -0
  50. data/spec/lib/declare_schema/schema_change/index_remove_spec.rb +29 -0
  51. data/spec/lib/declare_schema/schema_change/primary_key_change_spec.rb +69 -0
  52. data/spec/lib/declare_schema/schema_change/table_add_spec.rb +50 -0
  53. data/spec/lib/declare_schema/schema_change/table_change_spec.rb +30 -0
  54. data/spec/lib/declare_schema/schema_change/table_remove_spec.rb +27 -0
  55. data/spec/lib/declare_schema/schema_change/table_rename_spec.rb +27 -0
  56. data/spec/lib/generators/declare_schema/migration/migrator_spec.rb +59 -11
  57. data/spec/spec_helper.rb +1 -1
  58. data/spec/support/acceptance_spec_helpers.rb +2 -2
  59. 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
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module DeclareSchema
4
- VERSION = "0.10.0"
4
+ VERSION = "0.12.0.pre.2"
5
5
  end