declare_schema 0.9.0 → 0.11.1

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 (63) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/declare_schema_build.yml +1 -1
  3. data/CHANGELOG.md +32 -0
  4. data/Gemfile.lock +1 -1
  5. data/README.md +12 -2
  6. data/lib/declare_schema.rb +12 -1
  7. data/lib/declare_schema/dsl.rb +39 -0
  8. data/lib/declare_schema/extensions/active_record/fields_declaration.rb +22 -3
  9. data/lib/declare_schema/model.rb +4 -6
  10. data/lib/declare_schema/model/column.rb +1 -1
  11. data/lib/declare_schema/model/foreign_key_definition.rb +6 -11
  12. data/lib/declare_schema/model/index_definition.rb +1 -20
  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 +175 -177
  32. data/lib/generators/declare_schema/migration/templates/migration.rb.erb +3 -3
  33. data/lib/generators/declare_schema/support/model.rb +4 -4
  34. data/spec/lib/declare_schema/api_spec.rb +8 -8
  35. data/spec/lib/declare_schema/field_declaration_dsl_spec.rb +41 -15
  36. data/spec/lib/declare_schema/field_spec_spec.rb +2 -2
  37. data/spec/lib/declare_schema/generator_spec.rb +5 -5
  38. data/spec/lib/declare_schema/interactive_primary_key_spec.rb +117 -28
  39. data/spec/lib/declare_schema/migration_generator_spec.rb +1990 -843
  40. data/spec/lib/declare_schema/model/column_spec.rb +49 -23
  41. data/spec/lib/declare_schema/model/foreign_key_definition_spec.rb +158 -57
  42. data/spec/lib/declare_schema/model/habtm_model_shim_spec.rb +0 -2
  43. data/spec/lib/declare_schema/model/index_definition_spec.rb +189 -78
  44. data/spec/lib/declare_schema/model/table_options_definition_spec.rb +75 -11
  45. data/spec/lib/declare_schema/schema_change/base_spec.rb +75 -0
  46. data/spec/lib/declare_schema/schema_change/column_add_spec.rb +30 -0
  47. data/spec/lib/declare_schema/schema_change/column_change_spec.rb +33 -0
  48. data/spec/lib/declare_schema/schema_change/column_remove_spec.rb +30 -0
  49. data/spec/lib/declare_schema/schema_change/column_rename_spec.rb +28 -0
  50. data/spec/lib/declare_schema/schema_change/foreign_key_add_spec.rb +29 -0
  51. data/spec/lib/declare_schema/schema_change/foreign_key_remove_spec.rb +29 -0
  52. data/spec/lib/declare_schema/schema_change/index_add_spec.rb +56 -0
  53. data/spec/lib/declare_schema/schema_change/index_remove_spec.rb +29 -0
  54. data/spec/lib/declare_schema/schema_change/primary_key_change_spec.rb +69 -0
  55. data/spec/lib/declare_schema/schema_change/table_add_spec.rb +50 -0
  56. data/spec/lib/declare_schema/schema_change/table_change_spec.rb +30 -0
  57. data/spec/lib/declare_schema/schema_change/table_remove_spec.rb +27 -0
  58. data/spec/lib/declare_schema/schema_change/table_rename_spec.rb +27 -0
  59. data/spec/lib/generators/declare_schema/migration/migrator_spec.rb +59 -11
  60. data/spec/spec_helper.rb +1 -1
  61. data/spec/support/acceptance_spec_helpers.rb +2 -2
  62. metadata +35 -6
  63. data/test_responses.txt +0 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 531940d48f1fe38830944576136ff76e2b29dc69a323a2a8e3f60f431731f104
4
- data.tar.gz: 3afe0ce91fa631f4fa07d10ef1039f788589d440e87245c859db9bbe0179972d
3
+ metadata.gz: 389da0d9f9e0753e62297aeca33c3c73305d95082a3f50baf6288362011e6f52
4
+ data.tar.gz: 7d20d8ef4a085e37ec13273c020b8c3883e96359e9e4c7d173c3beccf5c73dab
5
5
  SHA512:
6
- metadata.gz: 67270e128e00f45b8ed8393b85ffe65ab4bc7ae197296adacf22c37629bdf5e768d6e204987b67e2d63b3ac0cc79aadb0b02c2c4f60e7e4b85e01f4d24ef55e2
7
- data.tar.gz: c9763a6eacd9d1d1deef9e829072e974ea53a5575f0938a8b4202e4210aa704186022a12e8704c08edde24bc73c2da7f95b467b77f3c81e422df54eddaf2352a
6
+ metadata.gz: 0e4eb02bc1d989d648095b952e1feff00af9cbbc4ea3dbb7962f15fdbcafce2fac4bc93c467417d29396e6753993874c3c2faf882a620db0d54f3ea905195cf9
7
+ data.tar.gz: d504a96bb5f60d7c64b03fd975c9e7c78fe9614f06a0aa73fffe0c0987786a554e3f603a79198f962b13b0b869690b839fb1cd0215196353064360ef81e46e51
@@ -57,4 +57,4 @@ jobs:
57
57
  git config --global user.email "dummy@example.com"
58
58
  git config --global user.name "dummy"
59
59
  MYSQL_PORT=3306 bundle exec rake test:prepare_testapp[force]
60
- bundle exec rake test:all < test_responses.txt
60
+ bundle exec rake test:all
data/CHANGELOG.md CHANGED
@@ -4,6 +4,34 @@ Inspired by [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
4
4
 
5
5
  Note: this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
6
6
 
7
+ ## [0.11.1] - 2021-03-26
8
+ ### Fixed
9
+ - Fixed a bug where up and down in generated migration would be empty in Rails 4.
10
+
11
+ ## [0.11.0] - 2021-03-22
12
+ ### Removed
13
+ - Removed `g|m|c` prompt entirely, since it was confusing. Instead, the migration is
14
+ always generated; the user may press ^C at the filename prompt to cancel.
15
+ The migration will be run if `--migrate` is passed; otherwise, the migrate command will be displayed to be run later.
16
+ ### Added
17
+ - Added the new configuration option `DeclareSchema.@db_migrate_command =`.
18
+ ### Fixed
19
+ - Fixed bug where foreign key constraint names are not globally unique
20
+
21
+ ## [0.10.1] - 2021-03-18
22
+ ### Fixed
23
+ - Migration steps are now generated in a defined dependency order, so that--for example--indexes that depend
24
+ on columns are deleted first, before the columns themselves are deleted (since the latter implicitly does the former, which would break the migration when run).
25
+ - Related to the above, down migration steps are now always generated in exactly the reverse order of the up migration steps.
26
+
27
+ ## [0.10.0] - 2021-03-17
28
+ ### Deprecated
29
+ - Deprecated the `fields` DSL method in favor of `declare_schema`.
30
+
31
+ ### Added
32
+ - Added the `declare_schema` method to replace `fields`. We now expect a column's type to come before the name
33
+ i.e. `declare schema { string :title }`. Otherwise, there is no difference between `fields` and `declare_schema`.
34
+
7
35
  ## [0.9.0] - 2021-03-01
8
36
  ### Added
9
37
  - Added configurable default settings for `default_text_limit`, `default_string_limit`, `default_null`,
@@ -140,6 +168,10 @@ using the appropriate Rails configuration attributes.
140
168
  ### Added
141
169
  - Initial version from https://github.com/Invoca/hobo_fields v4.1.0.
142
170
 
171
+ [0.11.1]: https://github.com/Invoca/declare_schema/compare/v0.11.0...v0.11.1
172
+ [0.11.0]: https://github.com/Invoca/declare_schema/compare/v0.10.1...v0.11.0
173
+ [0.10.1]: https://github.com/Invoca/declare_schema/compare/v0.10.0...v0.10.1
174
+ [0.10.0]: https://github.com/Invoca/declare_schema/compare/v0.9.0...v0.10.0
143
175
  [0.9.0]: https://github.com/Invoca/declare_schema/compare/v0.8.0...v0.9.0
144
176
  [0.8.0]: https://github.com/Invoca/declare_schema/compare/v0.7.1...v0.8.0
145
177
  [0.7.1]: https://github.com/Invoca/declare_schema/compare/v0.7.0...v0.7.1
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- declare_schema (0.9.0)
4
+ declare_schema (0.11.1)
5
5
  rails (>= 4.2)
6
6
 
7
7
  GEM
data/README.md CHANGED
@@ -57,7 +57,7 @@ during the initialization of your Rails application.
57
57
 
58
58
  ### before_generating_migration callback
59
59
 
60
- During the initializtion process for generating migrations, `DeclareSchema` will
60
+ During the initialization process for generating migrations, `DeclareSchema` will
61
61
  trigger the `eager_load!` on the `Rails` application and all `Rails::Engine`s loaded
62
62
  into scope. If you need to generate migrations for models that aren't automatically loaded by `eager_load!`,
63
63
  load them in the `before_generating_migration` block.
@@ -163,6 +163,16 @@ turn all tables into `utf8mb4` supporting tables:
163
163
  DeclareSchema.default_charset = "utf8mb4"
164
164
  DeclareSchema.default_collation = "utf8mb4_bin"
165
165
  ```
166
+ #### db:migrate Command
167
+ `declare_schema` can run the migration once it is generated, if the `--migrate` option is passed.
168
+ If not, it will display the command to run later. By default this command is
169
+ ```
170
+ bundle exec rails db:migrate
171
+ ```
172
+ If your repo has a different command to run for migrations, you can configure it like this:
173
+ ```ruby
174
+ `DeclareSchema.db_migrate_command = "bundle exec rails db:migrate_immediate"`
175
+ ```
166
176
 
167
177
  ## Declaring Character Set and Collation
168
178
  _Note: This feature currently only works for MySQL database configurations._
@@ -228,5 +238,5 @@ or add it to your `bundler` Gemfile:
228
238
  To run tests:
229
239
  ```
230
240
  rake test:prepare_testapp[force]
231
- rake test:all < test_responses.txt
241
+ rake test:all
232
242
  ```
@@ -28,10 +28,16 @@ module DeclareSchema
28
28
  @default_null = false
29
29
  @default_generate_foreign_keys = true
30
30
  @default_generate_indexing = true
31
+ @db_migrate_command =
32
+ if ActiveSupport::VERSION::MAJOR < 5
33
+ "bundle exec rake db:migrate"
34
+ else
35
+ "bundle exec rails db:migrate"
36
+ end
31
37
 
32
38
  class << self
33
39
  attr_reader :default_charset, :default_collation, :default_text_limit, :default_string_limit, :default_null,
34
- :default_generate_foreign_keys, :default_generate_indexing
40
+ :default_generate_foreign_keys, :default_generate_indexing, :db_migrate_command
35
41
 
36
42
  def to_class(type)
37
43
  case type
@@ -78,6 +84,11 @@ module DeclareSchema
78
84
  generate_indexing.in?([true, false]) or raise ArgumentError, "generate_indexing must be either true or false (got #{generate_indexing.inspect})"
79
85
  @default_generate_indexing = generate_indexing
80
86
  end
87
+
88
+ def db_migrate_command=(db_migrate_command)
89
+ db_migrate_command.is_a?(String) or raise ArgumentError, "db_migrate_command must be a string (got #{db_migrate_command.inspect})"
90
+ @db_migrate_command = db_migrate_command
91
+ end
81
92
  end
82
93
  end
83
94
 
@@ -0,0 +1,39 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'active_support/proxy_object'
4
+
5
+ module DeclareSchema
6
+ class Dsl < BasicObject # avoid Object because that gets extended by lots of gems
7
+ include ::Kernel # but we need the basic class methods
8
+
9
+ instance_methods.each do |m|
10
+ unless m.to_s.starts_with?('__') || m.in?([:object_id, :instance_eval])
11
+ undef_method(m)
12
+ end
13
+ end
14
+
15
+ def initialize(model, options = {})
16
+ @model = model
17
+ @options = options
18
+ end
19
+
20
+ attr_reader :model
21
+
22
+ def timestamps
23
+ field(:created_at, :datetime, null: true)
24
+ field(:updated_at, :datetime, null: true)
25
+ end
26
+
27
+ def optimistic_lock
28
+ field(:lock_version, :integer, default: 1, null: false)
29
+ end
30
+
31
+ def field(name, type, *args, **options)
32
+ @model.declare_field(name, type, *(args + [@options.merge(options)]))
33
+ end
34
+
35
+ def method_missing(type, name, *args)
36
+ field(name, type, *args)
37
+ end
38
+ end
39
+ end
@@ -1,16 +1,16 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'active_record'
4
+ require 'declare_schema/dsl'
4
5
  require 'declare_schema/model'
5
6
  require 'declare_schema/field_declaration_dsl'
6
7
 
7
8
  module DeclareSchema
8
- module FieldsDsl
9
+ module Macros
9
10
  def fields(table_options = {}, &block)
10
11
  # Any model that calls 'fields' gets DeclareSchema::Model behavior
11
12
  DeclareSchema::Model.mix_in(self)
12
13
 
13
- # @include_in_migration = false #||= options.fetch(:include_in_migration, true); options.delete(:include_in_migration)
14
14
  @include_in_migration = true
15
15
  @table_options = table_options
16
16
 
@@ -23,7 +23,26 @@ module DeclareSchema
23
23
  end
24
24
  end
25
25
  end
26
+ deprecate :fields, deprecator: ActiveSupport::Deprecation.new('1.0', 'DeclareSchema')
27
+
28
+ def declare_schema(table_options = {}, &block)
29
+ # Any model that calls 'fields' gets DeclareSchema::Model behavior
30
+ DeclareSchema::Model.mix_in(self)
31
+
32
+ # @include_in_migration = false #||= options.fetch(:include_in_migration, true); options.delete(:include_in_migration)
33
+ @include_in_migration = true # TODO: Add back or delete the include_in_migration feature
34
+ @table_options = table_options
35
+
36
+ if block
37
+ dsl = DeclareSchema::Dsl.new(self, null: false)
38
+ if block.arity == 1
39
+ yield dsl
40
+ else
41
+ dsl.instance_eval(&block)
42
+ end
43
+ end
44
+ end
26
45
  end
27
46
  end
28
47
 
29
- ActiveRecord::Base.singleton_class.prepend DeclareSchema::FieldsDsl
48
+ ActiveRecord::Base.singleton_class.prepend DeclareSchema::Macros
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'rails'
4
-
5
3
  require 'declare_schema/extensions/module'
6
4
 
7
5
  module DeclareSchema
@@ -41,7 +39,7 @@ module DeclareSchema
41
39
  eval <<~EOS
42
40
  def self.inherited(klass)
43
41
  unless klass.field_specs.has_key?(inheritance_column)
44
- fields do |f|
42
+ declare_schema do |f|
45
43
  f.field(inheritance_column, :string, limit: 255, null: true)
46
44
  end
47
45
  index(inheritance_column)
@@ -130,7 +128,7 @@ module DeclareSchema
130
128
 
131
129
  fk_options[:dependent] = options.delete(:far_end_dependent) if options.has_key?(:far_end_dependent)
132
130
 
133
- if Rails::VERSION::MAJOR >= 5
131
+ if ActiveSupport::VERSION::MAJOR >= 5
134
132
  super
135
133
  else
136
134
  super(name, scope, options.except(:optional))
@@ -149,7 +147,7 @@ module DeclareSchema
149
147
  end
150
148
  end
151
149
 
152
- if ::Rails::VERSION::MAJOR < 5
150
+ if ::ActiveSupport::VERSION::MAJOR < 5
153
151
  def primary_key
154
152
  super || 'id'
155
153
  end
@@ -227,7 +225,7 @@ module DeclareSchema
227
225
  ActiveRecord::Coders::JSON
228
226
  elsif [:load, :dump].all? { |x| class_name_or_coder.respond_to?(x) }
229
227
  class_name_or_coder
230
- elsif Rails::VERSION::MAJOR >= 5
228
+ elsif ActiveSupport::VERSION::MAJOR >= 5
231
229
  ActiveRecord::Coders::YAMLColumn.new(attr_name, class_name_or_coder)
232
230
  else
233
231
  ActiveRecord::Coders::YAMLColumn.new(class_name_or_coder)
@@ -53,7 +53,7 @@ module DeclareSchema
53
53
  def deserialize_default_value(column, type, default_value)
54
54
  type or raise ArgumentError, "must pass type; got #{type.inspect}"
55
55
 
56
- case Rails::VERSION::MAJOR
56
+ case ActiveSupport::VERSION::MAJOR
57
57
  when 4
58
58
  # TODO: Delete this Rails 4 support ASAP! This could be wrong, since it's using the type of the old column...which
59
59
  # might be getting migrated to a new type. We should be using just type as below. -Colin
@@ -7,20 +7,20 @@ module DeclareSchema
7
7
  class ForeignKeyDefinition
8
8
  include Comparable
9
9
 
10
- attr_reader :constraint_name, :model, :foreign_key, :foreign_key_name, :options, :on_delete_cascade
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
14
  @model = model
14
15
  @foreign_key = foreign_key.to_s.presence
15
16
  @options = options
16
17
 
17
- @child_table = model.table_name # unless a table rename, which would happen when a class is renamed??
18
+ @child_table_name = model.table_name # unless a table rename, which would happen when a class is renamed??
18
19
  @parent_table_name = options[:parent_table]&.to_s
19
20
  @foreign_key_name = options[:foreign_key]&.to_s || @foreign_key
20
21
 
21
- @constraint_name = options[:constraint_name]&.to_s ||
22
- options[:index_name]&.to_s ||
23
- IndexDefinition.index_name(@foreign_key_name)
22
+ @constraint_name = options[:constraint_name]&.to_s.presence ||
23
+ model.connection.index_name(model.table_name, column: @foreign_key_name)
24
24
  @on_delete_cascade = options[:dependent] == :delete
25
25
  end
26
26
 
@@ -61,11 +61,6 @@ module DeclareSchema
61
61
  foreign_key.sub(/_id\z/, '').camelize.constantize.table_name
62
62
  end
63
63
 
64
- def to_add_statement
65
- "add_foreign_key(#{@child_table.inspect}, #{parent_table_name.inspect}, " +
66
- "column: #{@foreign_key_name.inspect}, name: #{@constraint_name.inspect})"
67
- end
68
-
69
64
  def <=>(rhs)
70
65
  key <=> rhs.send(:key)
71
66
  end
@@ -75,7 +70,7 @@ module DeclareSchema
75
70
  private
76
71
 
77
72
  def key
78
- @key ||= [@child_table, parent_table_name, @foreign_key_name, @on_delete_cascade].map(&:to_s)
73
+ @key ||= [@child_table_name, parent_table_name, @foreign_key_name, @on_delete_cascade].map(&:to_s)
79
74
  end
80
75
 
81
76
  def hash
@@ -68,7 +68,7 @@ module DeclareSchema
68
68
 
69
69
  # This is the old approach which is still needed for MySQL in Rails 4 and SQLite
70
70
  def sqlite_compound_primary_key(model, table)
71
- ActiveRecord::Base.connection.class.name.match?(/SQLite3Adapter/) || Rails::VERSION::MAJOR < 5 or return nil
71
+ ActiveRecord::Base.connection.class.name.match?(/SQLite3Adapter/) || ActiveSupport::VERSION::MAJOR < 5 or return nil
72
72
 
73
73
  connection = model.connection.dup
74
74
 
@@ -93,25 +93,6 @@ module DeclareSchema
93
93
  name == PRIMARY_KEY_NAME
94
94
  end
95
95
 
96
- def to_add_statement(new_table_name, existing_primary_key = nil)
97
- if primary_key? && !ActiveRecord::Base.connection.class.name.match?(/SQLite3Adapter/)
98
- to_add_primary_key_statement(new_table_name, existing_primary_key)
99
- else
100
- # Note: + below keeps that interpolated string from being frozen, so we can << into it.
101
- r = +"add_index #{new_table_name.to_sym.inspect}, #{fields.map(&:to_sym).inspect}"
102
- r << ", unique: true" if unique
103
- r << ", where: '#{where}'" if where.present?
104
- r << ", name: '#{name}'"
105
- r
106
- end
107
- end
108
-
109
- def to_add_primary_key_statement(new_table_name, existing_primary_key)
110
- drop = "DROP PRIMARY KEY, " if existing_primary_key
111
- statement = "ALTER TABLE #{new_table_name} #{drop}ADD PRIMARY KEY (#{fields.join(', ')})"
112
- "execute #{statement.inspect}"
113
- end
114
-
115
96
  def to_key
116
97
  @key ||= [table, fields, name, unique, where].map(&:to_s)
117
98
  end
@@ -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
10
+ @column_name = column_name
11
+ @column_type = 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