ardb 0.28.1 → 0.29.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 +7 -7
  2. data/.l.yml +8 -0
  3. data/.rubocop.yml +3 -0
  4. data/.t.yml +6 -0
  5. data/Gemfile +21 -8
  6. data/README.md +252 -3
  7. data/ardb.gemspec +14 -10
  8. data/bin/ardb +3 -1
  9. data/lib/ardb.rb +110 -80
  10. data/lib/ardb/adapter/base.rb +73 -47
  11. data/lib/ardb/adapter/mysql.rb +4 -17
  12. data/lib/ardb/adapter/postgresql.rb +51 -46
  13. data/lib/ardb/adapter/sqlite.rb +11 -15
  14. data/lib/ardb/adapter_spy.rb +18 -30
  15. data/lib/ardb/cli.rb +29 -24
  16. data/lib/ardb/cli/clirb.rb +19 -17
  17. data/lib/ardb/cli/commands.rb +308 -129
  18. data/lib/ardb/db_tests.rb +4 -4
  19. data/lib/ardb/default_order_by.rb +13 -21
  20. data/lib/ardb/migration.rb +15 -16
  21. data/lib/ardb/record_spy.rb +46 -61
  22. data/lib/ardb/relation_spy.rb +27 -31
  23. data/lib/ardb/require_autoloaded_active_record_files.rb +174 -58
  24. data/lib/ardb/test_helpers.rb +13 -14
  25. data/lib/ardb/use_db_default.rb +10 -19
  26. data/lib/ardb/version.rb +3 -1
  27. data/script/determine_autoloaded_active_record_files.rb +31 -24
  28. data/test/helper.rb +6 -13
  29. data/test/support/factory.rb +4 -3
  30. data/test/support/fake_schema.rb +3 -1
  31. data/test/support/postgresql/migrations/{.gitkeep → .keep} +0 -0
  32. data/test/support/postgresql/schema.rb +2 -1
  33. data/test/support/postgresql/setup_test_db.rb +17 -15
  34. data/test/support/relative_require_test_db_file.rb +1 -0
  35. data/test/support/require_test_db_file.rb +1 -0
  36. data/test/system/.keep +0 -0
  37. data/test/unit/adapter/base_tests.rb +83 -55
  38. data/test/unit/adapter/mysql_tests.rb +4 -19
  39. data/test/unit/adapter/postgresql_tests.rb +21 -30
  40. data/test/unit/adapter/sqlite_tests.rb +5 -11
  41. data/test/unit/adapter_spy_tests.rb +6 -17
  42. data/test/unit/ardb_tests.rb +81 -53
  43. data/test/unit/cli_tests.rb +232 -157
  44. data/test/unit/db_tests_tests.rb +7 -7
  45. data/test/unit/default_order_by_tests.rb +21 -20
  46. data/test/unit/migration_tests.rb +17 -18
  47. data/test/unit/record_spy_tests.rb +36 -34
  48. data/test/unit/relation_spy_tests.rb +40 -63
  49. data/test/unit/test_helpers_tests.rb +7 -15
  50. data/test/unit/use_db_default_tests.rb +22 -17
  51. metadata +117 -84
  52. data/lib/ardb/has_slug.rb +0 -107
  53. data/lib/ardb/migration_helpers.rb +0 -77
  54. data/lib/ardb/pg_json.rb +0 -90
  55. data/test/support/postgresql/pg_json_migrations/20160519133432_create_pg_json_migrate_test.rb +0 -13
  56. data/test/system/pg_json_tests.rb +0 -85
  57. data/test/unit/has_slug_tests.rb +0 -341
  58. data/test/unit/migration_helpers_tests.rb +0 -65
  59. data/test/unit/pg_json_tests.rb +0 -39
@@ -1,21 +1,28 @@
1
- require 'ardb/cli/clirb'
2
- require 'ardb/cli/commands'
3
- require 'ardb/version'
1
+ # frozen_string_literal: true
4
2
 
5
- module Ardb
3
+ require "ardb/cli/clirb"
4
+ require "ardb/cli/commands"
5
+ require "ardb/version"
6
6
 
7
+ module Ardb
7
8
  class CLI
8
-
9
- COMMANDS = CommandSet.new{ |unknown| InvalidCommand.new(unknown) }.tap do |c|
10
- c.add(ConnectCommand, 'connect')
11
- c.add(CreateCommand, 'create')
12
- c.add(DropCommand, 'drop')
13
- c.add(MigrateCommand, 'migrate')
14
- c.add(GenerateMigrationCommand, 'generate-migration')
15
- end
9
+ COMMANDS =
10
+ CommandSet.new{ |unknown|
11
+ InvalidCommand.new(unknown)
12
+ }.tap do |c|
13
+ c.add(ConnectCommand)
14
+ c.add(CreateCommand)
15
+ c.add(DropCommand)
16
+ c.add(GenerateMigrationCommand)
17
+ c.add(MigrateCommand)
18
+ c.add(MigrateUpCommand)
19
+ c.add(MigrateDownCommand)
20
+ c.add(MigrateForwardCommand)
21
+ c.add(MigrateBackwardCommand)
22
+ end
16
23
 
17
24
  def self.run(args)
18
- self.new.run(args)
25
+ new.run(args)
19
26
  end
20
27
 
21
28
  def initialize(kernel = nil, stdout = nil, stderr = nil)
@@ -32,19 +39,19 @@ module Ardb
32
39
  cmd = COMMANDS[cmd_name]
33
40
  cmd.run(args)
34
41
  rescue CLIRB::HelpExit
35
- @stdout.puts cmd.help
42
+ @stdout.puts cmd.command_help
36
43
  rescue CLIRB::VersionExit
37
44
  @stdout.puts Ardb::VERSION
38
- rescue CLIRB::Error, ArgumentError, InvalidCommandError => exception
39
- display_debug(exception)
40
- @stderr.puts "#{exception.message}\n\n"
41
- @stdout.puts cmd.help
45
+ rescue CLIRB::Error, ArgumentError, InvalidCommandError => ex
46
+ display_debug(ex)
47
+ @stderr.puts "#{ex.message}\n\n"
48
+ @stdout.puts cmd.command_help
42
49
  @kernel.exit 1
43
50
  rescue CommandExitError
44
51
  @kernel.exit 1
45
- rescue StandardError => exception
46
- @stderr.puts "#{exception.class}: #{exception.message}"
47
- @stderr.puts exception.backtrace.join("\n")
52
+ rescue => ex
53
+ @stderr.puts "#{ex.class}: #{ex.message}"
54
+ @stderr.puts ex.backtrace.join("\n")
48
55
  @kernel.exit 1
49
56
  end
50
57
  @kernel.exit 0
@@ -53,12 +60,10 @@ module Ardb
53
60
  private
54
61
 
55
62
  def display_debug(exception)
56
- if ENV['DEBUG']
63
+ if ENV["DEBUG"]
57
64
  @stderr.puts "#{exception.class}: #{exception.message}"
58
65
  @stderr.puts exception.backtrace.join("\n")
59
66
  end
60
67
  end
61
-
62
68
  end
63
-
64
69
  end
@@ -1,59 +1,61 @@
1
1
  module Ardb; end
2
- class Ardb::CLI
3
2
 
4
- class CLIRB # Version 1.0.0, https://github.com/redding/cli.rb
3
+ class Ardb::CLI
4
+ class CLIRB # Version 1.1.0, https://github.com/redding/cli.rb
5
5
  Error = Class.new(RuntimeError);
6
6
  HelpExit = Class.new(RuntimeError); VersionExit = Class.new(RuntimeError)
7
7
  attr_reader :argv, :args, :opts, :data
8
8
 
9
9
  def initialize(&block)
10
10
  @options = []; instance_eval(&block) if block
11
- require 'optparse'
11
+ require "optparse"
12
12
  @data, @args, @opts = [], [], {}; @parser = OptionParser.new do |p|
13
- p.banner = ''; @options.each do |o|
13
+ p.banner = ""; @options.each do |o|
14
14
  @opts[o.name] = o.value; p.on(*o.parser_args){ |v| @opts[o.name] = v }
15
15
  end
16
- p.on_tail('--version', ''){ |v| raise VersionExit, v.to_s }
17
- p.on_tail('--help', ''){ |v| raise HelpExit, v.to_s }
16
+ p.on_tail("--version", ""){ |v| raise VersionExit, v.to_s }
17
+ p.on_tail("--help", ""){ |v| raise HelpExit, v.to_s }
18
18
  end
19
19
  end
20
20
 
21
21
  def option(*args); @options << Option.new(*args); end
22
+
22
23
  def parse!(argv)
23
24
  @args = (argv || []).dup.tap do |args_list|
24
25
  begin; @parser.parse!(args_list)
25
26
  rescue OptionParser::ParseError => err; raise Error, err.message; end
26
27
  end; @data = @args + [@opts]
27
28
  end
29
+
28
30
  def to_s; @parser.to_s; end
31
+
29
32
  def inspect
30
- "#<#{self.class}:#{'0x0%x' % (object_id << 1)} @data=#{@data.inspect}>"
33
+ "#<#{self.class}:#{"0x0%x" % (object_id << 1)} @data=#{@data.inspect}>"
31
34
  end
32
35
 
33
36
  class Option
34
37
  attr_reader :name, :opt_name, :desc, :abbrev, :value, :klass, :parser_args
35
38
 
36
- def initialize(name, *args)
37
- settings, @desc = args.last.kind_of?(::Hash) ? args.pop : {}, args.pop || ''
38
- @name, @opt_name, @abbrev = parse_name_values(name, settings[:abbrev])
39
- @value, @klass = gvalinfo(settings[:value])
39
+ def initialize(name, desc = nil, abbrev: nil, value: nil)
40
+ @name, @desc = name, desc || ""
41
+ @opt_name, @abbrev = parse_name_values(name, abbrev)
42
+ @value, @klass = gvalinfo(value)
40
43
  @parser_args = if [TrueClass, FalseClass, NilClass].include?(@klass)
41
44
  ["-#{@abbrev}", "--[no-]#{@opt_name}", @desc]
42
45
  else
43
- ["-#{@abbrev}", "--#{@opt_name} #{@opt_name.upcase}", @klass, @desc]
46
+ ["-#{@abbrev}", "--#{@opt_name} VALUE", @klass, @desc]
44
47
  end
45
48
  end
46
49
 
47
50
  private
48
51
 
49
52
  def parse_name_values(name, custom_abbrev)
50
- [ (processed_name = name.to_s.strip.downcase), processed_name.gsub('_', '-'),
51
- custom_abbrev || processed_name.gsub(/[^a-z]/, '').chars.first || 'a'
53
+ [ (processed_name = name.to_s.strip.downcase).gsub("_", "-"),
54
+ custom_abbrev || processed_name.gsub(/[^a-z]/, "").chars.first || "a"
52
55
  ]
53
56
  end
54
- def gvalinfo(v); v.kind_of?(Class) ? [nil,gklass(v)] : [v,gklass(v.class)]; end
55
- def gklass(k); k == Fixnum ? Integer : k; end
57
+
58
+ def gvalinfo(v); v.kind_of?(Class) ? [nil,v] : [v,v.class]; end
56
59
  end
57
60
  end
58
-
59
61
  end
@@ -1,15 +1,16 @@
1
- require 'ardb'
2
- require 'ardb/cli/clirb'
3
- require 'much-plugin'
1
+ # frozen_string_literal: true
2
+
3
+ require "ardb"
4
+ require "ardb/cli/clirb"
5
+ require "much-mixin"
4
6
 
5
7
  module Ardb; end
6
- class Ardb::CLI
7
8
 
9
+ class Ardb::CLI
8
10
  InvalidCommandError = Class.new(ArgumentError)
9
11
  CommandExitError = Class.new(RuntimeError)
10
12
 
11
13
  class InvalidCommand
12
-
13
14
  attr_reader :name, :clirb
14
15
 
15
16
  def initialize(name)
@@ -17,37 +18,45 @@ class Ardb::CLI
17
18
  @clirb = CLIRB.new
18
19
  end
19
20
 
20
- def new; self; end
21
+ def new
22
+ self
23
+ end
21
24
 
22
25
  def run(argv)
23
26
  @clirb.parse!([@name, argv].flatten.compact)
24
27
  raise CLIRB::HelpExit if @name.to_s.empty?
25
- raise InvalidCommandError, "'#{self.name}' is not a command."
28
+ raise InvalidCommandError, "\"#{name}\" is not a command."
26
29
  end
27
30
 
28
- def help
31
+ def command_help
29
32
  "Usage: ardb [COMMAND] [options]\n\n" \
30
33
  "Options: #{@clirb}\n" \
31
34
  "Commands:\n" \
32
35
  "#{COMMANDS.to_s.split("\n").map{ |l| " #{l}" }.join("\n")}\n"
33
36
  end
34
-
35
37
  end
36
38
 
37
39
  module ValidCommand
38
- include MuchPlugin
40
+ include MuchMixin
39
41
 
40
- plugin_included do
41
- include InstanceMethods
42
- end
42
+ mixin_class_methods do
43
+ def command_name
44
+ raise NotImplementedError
45
+ end
43
46
 
44
- module InstanceMethods
47
+ def command_summary
48
+ ""
49
+ end
50
+ end
45
51
 
52
+ mixin_instance_methods do
46
53
  def initialize(&clirb_build)
47
54
  @clirb = CLIRB.new(&clirb_build)
48
55
  end
49
56
 
50
- def clirb; @clirb; end
57
+ def clirb
58
+ @clirb
59
+ end
51
60
 
52
61
  def run(argv, stdout = nil, stderr = nil)
53
62
  @clirb.parse!(argv)
@@ -55,206 +64,379 @@ class Ardb::CLI
55
64
  @stderr = stderr || $stderr
56
65
  end
57
66
 
58
- def summary
59
- ''
67
+ def command_name
68
+ self.class.command_name
60
69
  end
61
70
 
62
- end
71
+ def command_summary
72
+ self.class.command_summary
73
+ end
63
74
 
75
+ def command_help
76
+ "Usage: ardb #{command_name} [options]\n\n" \
77
+ "Options: #{clirb}\n" \
78
+ "Description:\n" \
79
+ " #{command_summary}"
80
+ end
81
+ end
64
82
  end
65
83
 
66
84
  class ConnectCommand
67
85
  include ValidCommand
68
86
 
87
+ def self.command_name
88
+ "connect"
89
+ end
90
+
91
+ def self.command_summary
92
+ "Connect to the configured DB"
93
+ end
94
+
69
95
  def run(argv, *args)
70
96
  super
71
97
 
72
- Ardb.init(false)
73
98
  begin
99
+ Ardb.init(false)
74
100
  Ardb.adapter.connect_db
75
- @stdout.puts "connected to #{Ardb.config.adapter} db `#{Ardb.config.database}`"
76
- rescue StandardError => e
77
- @stderr.puts e
78
- @stderr.puts e.backtrace.join("\n")
79
- @stderr.puts "error connecting to #{Ardb.config.database.inspect} database " \
80
- "with #{Ardb.config.activerecord_connect_hash.inspect}"
101
+ @stdout.puts(
102
+ "connected to #{Ardb.config.adapter} "\
103
+ "db #{Ardb.config.database.inspect}",
104
+ )
105
+ rescue ActiveRecord::NoDatabaseError
106
+ @stderr.puts(
107
+ "error: database #{Ardb.config.database.inspect} does not exist",
108
+ )
109
+ rescue => ex
110
+ @stderr.puts ex
111
+ @stderr.puts ex.backtrace.join("\n")
112
+ @stderr.puts(
113
+ "error connecting to #{Ardb.config.database.inspect} database " \
114
+ "with #{Ardb.config.activerecord_connect_hash.inspect}",
115
+ )
81
116
  raise CommandExitError
82
117
  end
83
118
  end
84
-
85
- def summary
86
- "Connect to the configured DB"
87
- end
88
-
89
- def help
90
- "Usage: ardb connect [options]\n\n" \
91
- "Options: #{@clirb}\n" \
92
- "Description:\n" \
93
- " #{self.summary}"
94
- end
95
-
96
119
  end
97
120
 
98
121
  class CreateCommand
99
122
  include ValidCommand
100
123
 
124
+ def self.command_name
125
+ "create"
126
+ end
127
+
128
+ def self.command_summary
129
+ "Create the configured DB"
130
+ end
131
+
101
132
  def run(argv, *args)
102
133
  super
103
134
 
104
- Ardb.init(false)
105
135
  begin
136
+ Ardb.init(false)
106
137
  Ardb.adapter.create_db
107
- @stdout.puts "created #{Ardb.config.adapter} db `#{Ardb.config.database}`"
108
- rescue StandardError => e
109
- @stderr.puts e
138
+ @stdout.puts(
139
+ "created #{Ardb.config.adapter} db #{Ardb.config.database.inspect}",
140
+ )
141
+ rescue ActiveRecord::StatementInvalid
142
+ @stderr.puts(
143
+ "error: database #{Ardb.config.database.inspect} already exists",
144
+ )
145
+ rescue => ex
146
+ @stderr.puts ex
110
147
  @stderr.puts "error creating #{Ardb.config.database.inspect} database"
111
148
  raise CommandExitError
112
149
  end
113
150
  end
151
+ end
114
152
 
115
- def summary
116
- "Create the configured DB"
153
+ class DropCommand
154
+ include ValidCommand
155
+
156
+ def self.command_name
157
+ "drop"
117
158
  end
118
159
 
119
- def help
120
- "Usage: ardb create [options]\n\n" \
121
- "Options: #{@clirb}\n" \
122
- "Description:\n" \
123
- " #{self.summary}"
160
+ def self.command_summary
161
+ "Drop the configured DB"
124
162
  end
125
163
 
164
+ def run(argv, *args)
165
+ super
166
+
167
+ begin
168
+ Ardb.init(true)
169
+ Ardb.adapter.drop_db
170
+ @stdout.puts(
171
+ "dropped #{Ardb.config.adapter} db #{Ardb.config.database.inspect}",
172
+ )
173
+ rescue ActiveRecord::NoDatabaseError
174
+ @stderr.puts(
175
+ "error: database #{Ardb.config.database.inspect} does not exist",
176
+ )
177
+ rescue => ex
178
+ @stderr.puts ex
179
+ @stderr.puts "error dropping #{Ardb.config.database.inspect} database"
180
+ raise CommandExitError
181
+ end
182
+ end
126
183
  end
127
184
 
128
- class DropCommand
185
+ class GenerateMigrationCommand
129
186
  include ValidCommand
130
187
 
188
+ def self.command_name
189
+ "generate-migration"
190
+ end
191
+
192
+ def self.command_summary
193
+ "Generate a MIGRATION-NAME migration file"
194
+ end
195
+
131
196
  def run(argv, *args)
132
197
  super
133
198
 
134
- Ardb.init(true)
135
199
  begin
136
- Ardb.adapter.drop_db
137
- @stdout.puts "dropped #{Ardb.config.adapter} db `#{Ardb.config.database}`"
138
- rescue StandardError => e
139
- @stderr.puts e
140
- @stderr.puts "error dropping #{Ardb.config.database.inspect} database"
200
+ Ardb.init(false)
201
+
202
+ require "ardb/migration"
203
+ migration = Ardb::Migration.new(Ardb.config, @clirb.args.first)
204
+ migration.save!
205
+ @stdout.puts "generated #{migration.file_path}"
206
+ rescue Ardb::Migration::NoIdentifierError => ex
207
+ error = ArgumentError.new("MIGRATION-NAME must be provided")
208
+ error.set_backtrace(ex.backtrace)
209
+ raise error
210
+ rescue => ex
211
+ @stderr.puts ex
212
+ @stderr.puts ex.backtrace.join("\n")
213
+ @stderr.puts "error generating migration"
141
214
  raise CommandExitError
142
215
  end
143
216
  end
144
217
 
145
- def summary
146
- "Drop the configured DB"
218
+ def command_help
219
+ "Usage: ardb #{command_name} MIGRATION-NAME [options]\n\n" \
220
+ "Options: #{clirb}\n" \
221
+ "Description:\n" \
222
+ " #{command_summary}"
147
223
  end
224
+ end
148
225
 
149
- def help
150
- "Usage: ardb drop [options]\n\n" \
151
- "Options: #{@clirb}\n" \
152
- "Description:\n" \
153
- " #{self.summary}"
226
+ module MigrateCommandBehaviors
227
+ include MuchMixin
228
+
229
+ mixin_included do
230
+ include ValidCommand
154
231
  end
155
232
 
233
+ mixin_instance_methods do
234
+ def migrate
235
+ raise NotImplementedError
236
+ end
237
+
238
+ def run(argv, *args)
239
+ super
240
+
241
+ begin
242
+ Ardb.init(true)
243
+ migrate
244
+ Ardb.adapter.dump_schema unless ENV["ARDB_MIGRATE_NO_SCHEMA"]
245
+ rescue ActiveRecord::NoDatabaseError
246
+ @stderr.puts(
247
+ "error: database #{Ardb.config.database.inspect} does not exist",
248
+ )
249
+ rescue => ex
250
+ @stderr.puts ex
251
+ @stderr.puts ex.backtrace.join("\n")
252
+ @stderr.puts(
253
+ "error migrating #{Ardb.config.database.inspect} database",
254
+ )
255
+ raise CommandExitError
256
+ end
257
+ end
258
+ end
156
259
  end
157
260
 
158
261
  class MigrateCommand
159
- include ValidCommand
262
+ include MigrateCommandBehaviors
160
263
 
161
- def run(argv, *args)
162
- super
264
+ def self.command_name
265
+ "migrate"
266
+ end
163
267
 
164
- Ardb.init(true)
165
- begin
166
- Ardb.adapter.migrate_db
167
- Ardb.adapter.dump_schema unless ENV['ARDB_MIGRATE_NO_SCHEMA']
168
- rescue StandardError => e
169
- @stderr.puts e
170
- @stderr.puts e.backtrace.join("\n")
171
- @stderr.puts "error migrating #{Ardb.config.database.inspect} database"
172
- raise CommandExitError
268
+ def self.command_summary
269
+ "Migrate the configured DB"
270
+ end
271
+
272
+ def migrate
273
+ Ardb.adapter.migrate_db
274
+ end
275
+ end
276
+
277
+ module MigrateStyleBehaviors
278
+ include MuchMixin
279
+
280
+ mixin_included do
281
+ include MigrateCommandBehaviors
282
+ end
283
+
284
+ mixin_class_methods do
285
+ def command_style
286
+ raise NotImplementedError
287
+ end
288
+
289
+ def command_name
290
+ "migrate-#{command_style}"
291
+ end
292
+
293
+ def command_summary
294
+ "Migrate the configured DB #{command_style}"
173
295
  end
174
296
  end
175
297
 
176
- def summary
177
- "Migrate the configured DB"
298
+ mixin_instance_methods do
299
+ def migrate
300
+ Ardb.adapter.send(
301
+ "migrate_db_#{self.class.command_style}",
302
+ *migrate_args,
303
+ )
304
+ end
305
+
306
+ private
307
+
308
+ def migrate_args
309
+ raise NotImplementedError
310
+ end
178
311
  end
312
+ end
179
313
 
180
- def help
181
- "Usage: ardb migrate [options]\n\n" \
182
- "Options: #{@clirb}\n" \
183
- "Description:\n" \
184
- " #{self.summary}"
314
+ module MigrateDirectionBehaviors
315
+ include MuchMixin
316
+
317
+ mixin_included do
318
+ include MigrateStyleBehaviors
185
319
  end
186
320
 
321
+ mixin_class_methods do
322
+ def command_style
323
+ command_direction
324
+ end
325
+
326
+ def command_direction
327
+ raise NotImplementedError
328
+ end
329
+ end
330
+
331
+ mixin_instance_methods do
332
+ def initialize
333
+ super do
334
+ option(:target_version, "version to migrate to", value: String)
335
+ end
336
+ end
337
+
338
+ private
339
+
340
+ def migrate_args
341
+ [@clirb.opts[:target_version]]
342
+ end
343
+ end
187
344
  end
188
345
 
189
- class GenerateMigrationCommand
190
- include ValidCommand
346
+ module MigrateStepDirectionBehaviors
347
+ include MuchMixin
191
348
 
192
- def run(argv, *args)
193
- super
349
+ mixin_included do
350
+ include MigrateStyleBehaviors
351
+ end
194
352
 
195
- Ardb.init(false)
196
- begin
197
- require 'ardb/migration'
198
- migration = Ardb::Migration.new(Ardb.config, @clirb.args.first)
199
- migration.save!
200
- @stdout.puts "generated #{migration.file_path}"
201
- rescue Ardb::Migration::NoIdentifierError => exception
202
- error = ArgumentError.new("MIGRATION-NAME must be provided")
203
- error.set_backtrace(exception.backtrace)
204
- raise error
205
- rescue StandardError => e
206
- @stderr.puts e
207
- @stderr.puts e.backtrace.join("\n")
208
- @stderr.puts "error generating migration"
209
- raise CommandExitError
353
+ mixin_class_methods do
354
+ def command_style
355
+ command_direction
356
+ end
357
+
358
+ def command_direction
359
+ raise NotImplementedError
210
360
  end
211
361
  end
212
362
 
213
- def summary
214
- "Generate a migration file given a MIGRATION-NAME"
363
+ mixin_instance_methods do
364
+ def initialize
365
+ super do
366
+ option(:steps, "number of migrations to migrate", value: 1)
367
+ end
368
+ end
369
+
370
+ private
371
+
372
+ def migrate_args
373
+ [@clirb.opts[:steps]]
374
+ end
215
375
  end
376
+ end
216
377
 
217
- def help
218
- "Usage: ardb generate-migration [options] MIGRATION-NAME\n\n" \
219
- "Options: #{@clirb}\n" \
220
- "Description:\n" \
221
- " #{self.summary}"
378
+ class MigrateUpCommand
379
+ include MigrateDirectionBehaviors
380
+
381
+ def self.command_direction
382
+ "up"
222
383
  end
384
+ end
223
385
 
386
+ class MigrateDownCommand
387
+ include MigrateDirectionBehaviors
388
+
389
+ def self.command_direction
390
+ "down"
391
+ end
224
392
  end
225
393
 
226
- class CommandSet
394
+ class MigrateForwardCommand
395
+ include MigrateStepDirectionBehaviors
396
+
397
+ def self.command_direction
398
+ "forward"
399
+ end
400
+ end
401
+
402
+ class MigrateBackwardCommand
403
+ include MigrateStepDirectionBehaviors
227
404
 
405
+ def self.command_direction
406
+ "backward"
407
+ end
408
+ end
409
+
410
+ class CommandSet
228
411
  def initialize(&unknown_cmd_block)
229
- @lookup = Hash.new{ |h,k| unknown_cmd_block.call(k) }
412
+ @lookup = Hash.new{ |_h, k| unknown_cmd_block.call(k) }
230
413
  @names = []
231
414
  @aliases = {}
232
415
  @summaries = {}
233
416
  end
234
417
 
235
- def add(klass, name, *aliases)
418
+ def add(klass)
236
419
  begin
237
420
  cmd = klass.new
238
- rescue StandardError => err
239
- # don't add any commands you can't init
421
+ rescue
422
+ # don"t add any commands you can"t initialize
240
423
  else
241
- ([name] + aliases).each{ |n| @lookup[n] = cmd }
424
+ @lookup[cmd.command_name] = cmd
242
425
  @to_s = nil
243
- @names << name
244
- @aliases[name] = aliases.empty? ? '' : "(#{aliases.join(', ')})"
245
- @summaries[name] = cmd.summary.to_s.empty? ? '' : "# #{cmd.summary}"
426
+ @names << cmd.command_name
427
+ @summaries[cmd.command_name] = cmd.command_summary.to_s
246
428
  end
247
429
  end
248
430
 
249
- def remove(name)
250
- @lookup.delete(name)
251
- @names.delete(name)
252
- @aliases.delete(name)
431
+ def remove(klass)
432
+ @lookup.delete(klass.command_name)
433
+ @names.delete(klass.command_name)
434
+ @summaries.delete(klass.command_name)
253
435
  @to_s = nil
254
436
  end
255
437
 
256
- def [](name)
257
- @lookup[name]
438
+ def [](cmd_name)
439
+ @lookup[cmd_name]
258
440
  end
259
441
 
260
442
  def size
@@ -262,14 +444,11 @@ class Ardb::CLI
262
444
  end
263
445
 
264
446
  def to_s
265
- max_name_size = @names.map{ |n| n.size }.max || 0
266
- max_alias_size = @aliases.values.map{ |v| v.size }.max || 0
447
+ max_name_size = @names.map(&:size).max || 0
267
448
 
268
- @to_s ||= @names.map do |n|
269
- "#{n.ljust(max_name_size)} #{@aliases[n].ljust(max_alias_size)} #{@summaries[n]}"
270
- end.join("\n")
449
+ @to_s ||= @names.map{ |n|
450
+ "#{n.ljust(max_name_size)} #{@summaries[n]}"
451
+ }.join("\n")
271
452
  end
272
-
273
453
  end
274
-
275
454
  end