dbgeni 0.10.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (46) hide show
  1. checksums.yaml +7 -0
  2. data/Rakefile +29 -0
  3. data/bin/dbgeni +2 -0
  4. data/lib/dbgeni/base.rb +146 -0
  5. data/lib/dbgeni/base_code.rb +143 -0
  6. data/lib/dbgeni/blank_slate.rb +24 -0
  7. data/lib/dbgeni/cli.rb +96 -0
  8. data/lib/dbgeni/code.rb +235 -0
  9. data/lib/dbgeni/code_list.rb +60 -0
  10. data/lib/dbgeni/commands/code.rb +151 -0
  11. data/lib/dbgeni/commands/commands.rb +41 -0
  12. data/lib/dbgeni/commands/config.rb +36 -0
  13. data/lib/dbgeni/commands/dmls.rb +244 -0
  14. data/lib/dbgeni/commands/generate.rb +257 -0
  15. data/lib/dbgeni/commands/initialize.rb +41 -0
  16. data/lib/dbgeni/commands/migrations.rb +243 -0
  17. data/lib/dbgeni/commands/milestones.rb +52 -0
  18. data/lib/dbgeni/commands/new.rb +178 -0
  19. data/lib/dbgeni/config.rb +325 -0
  20. data/lib/dbgeni/connectors/connector.rb +59 -0
  21. data/lib/dbgeni/connectors/mysql.rb +146 -0
  22. data/lib/dbgeni/connectors/oracle.rb +149 -0
  23. data/lib/dbgeni/connectors/sqlite.rb +166 -0
  24. data/lib/dbgeni/connectors/sybase.rb +97 -0
  25. data/lib/dbgeni/dml_cli.rb +35 -0
  26. data/lib/dbgeni/environment.rb +161 -0
  27. data/lib/dbgeni/exceptions/exception.rb +69 -0
  28. data/lib/dbgeni/file_converter.rb +44 -0
  29. data/lib/dbgeni/initializers/initializer.rb +44 -0
  30. data/lib/dbgeni/initializers/mysql.rb +36 -0
  31. data/lib/dbgeni/initializers/oracle.rb +38 -0
  32. data/lib/dbgeni/initializers/sqlite.rb +33 -0
  33. data/lib/dbgeni/initializers/sybase.rb +34 -0
  34. data/lib/dbgeni/logger.rb +60 -0
  35. data/lib/dbgeni/migration.rb +302 -0
  36. data/lib/dbgeni/migration_cli.rb +204 -0
  37. data/lib/dbgeni/migration_list.rb +91 -0
  38. data/lib/dbgeni/migrators/migrator.rb +40 -0
  39. data/lib/dbgeni/migrators/migrator_interface.rb +51 -0
  40. data/lib/dbgeni/migrators/mysql.rb +82 -0
  41. data/lib/dbgeni/migrators/oracle.rb +211 -0
  42. data/lib/dbgeni/migrators/sqlite.rb +90 -0
  43. data/lib/dbgeni/migrators/sybase.rb +118 -0
  44. data/lib/dbgeni/plugin.rb +92 -0
  45. data/lib/dbgeni.rb +52 -0
  46. metadata +87 -0
@@ -0,0 +1,257 @@
1
+ def usage
2
+ puts <<-EOF
3
+ Usage:
4
+
5
+ The generate command is a helper to create appropriately named db migration
6
+ and code files.
7
+
8
+ Use --config-file to specify the config file to use. If none is specified
9
+ then a file called .dbgeni will be used if it is present in the current directory,
10
+ otherwise an error will be raised.
11
+
12
+ Usage:
13
+ dbgeni generate command parameters
14
+
15
+ The allowed commands are:
16
+
17
+ migration Generates a set of files for a new database migration. The only parameter
18
+ is a name for the migration:
19
+ dbgeni generate migration name_for_this_migration
20
+
21
+ dml_migration Generates a set of files for a new dml database migration. The only parameter
22
+ is a name for the migration:
23
+ dbgeni generate dml_migration name_for_this_migration
24
+
25
+
26
+ milestone Generates a milestone, which is like a tag on a particular migration indicating
27
+ that a migration completes a release of the application
28
+ dbgenu generate milestone name_for_milestone existing_migration_for_milestone
29
+
30
+ package Generates a pair of files for a plsql package with the given package name
31
+ dbgeni generate package my_package_name
32
+
33
+ procedure Generates a file for a stored procedure with the given procedure name
34
+ dbgeni generate procedure my_procedure_name
35
+
36
+ function Generates a file for a stored function with the given function name
37
+ dbgeni generate function my_procedure_name
38
+
39
+ trigger Generates a file for a trigger with the given trigger name
40
+ dbgeni generate trigger my_trigger_name
41
+
42
+ type Generates a file for a type definition with the given type name
43
+ dbgeni generate type my_type_name
44
+
45
+ EOF
46
+ end
47
+
48
+ if %w(-h --help).include? ARGV[0]
49
+ usage
50
+ exit(0)
51
+ end
52
+
53
+ command = ARGV.shift
54
+ name = ARGV.shift
55
+
56
+ unless name
57
+ puts "error: You must specify a name for the #{command}"
58
+ exit(1)
59
+ end
60
+
61
+ require 'fileutils'
62
+
63
+ config = DBGeni::Config.load_from_file($config_file)
64
+
65
+ case command
66
+ when 'migration', 'mig'
67
+ datestamp = Time.now.strftime('%Y%m%d%H%M')
68
+ %w(up down).each do |f|
69
+ filename = File.join(config.migration_directory, "#{datestamp}_#{f}_#{name}.sql")
70
+ puts "creating: #{filename}"
71
+ FileUtils.touch(filename)
72
+ end
73
+ when 'dml_migration', 'dml'
74
+ datestamp = Time.now.strftime('%Y%m%d%H%M')
75
+ %w(up down).each do |f|
76
+ filename = File.join(config.dml_directory, "#{datestamp}_#{f}_#{name}.sql")
77
+ puts "creating: #{filename}"
78
+ FileUtils.touch(filename)
79
+ end
80
+ when 'package', 'pkg'
81
+ filename = File.join(config.code_dir, "#{name}.pks")
82
+ if File.exists?(filename)
83
+ puts "exists: #{filename}"
84
+ else
85
+ puts "creating: #{filename}"
86
+ File.open(filename, 'w') do |f|
87
+ f.puts "create or replace package #{name}"
88
+ f.puts "as"
89
+ f.puts "begin"
90
+ f.puts ""
91
+ f.puts "end #{name};"
92
+ f.puts "/"
93
+ end
94
+ end
95
+ filename = File.join(config.code_dir, "#{name}.pkb")
96
+ if File.exists?(filename)
97
+ puts "exists: #{filename}"
98
+ else
99
+ puts "creating: #{filename}"
100
+ File.open(filename, 'w') do |f|
101
+ f.puts "create or replace package body #{name}"
102
+ f.puts "as"
103
+ f.puts "begin"
104
+ f.puts ""
105
+ f.puts "end #{name};"
106
+ f.puts "/"
107
+ end
108
+ end
109
+ when 'procedure', 'prc', 'proc'
110
+ filename = File.join(config.code_dir, "#{name}.prc")
111
+ if File.exists?(filename)
112
+ puts "exists: #{filename}"
113
+ else
114
+ puts "creating: #{filename}"
115
+ File.open(filename, 'w') do |f|
116
+ if config.db_type == 'oracle'
117
+ f.puts "create or replace procedure #{name}"
118
+ f.puts "as"
119
+ f.puts "begin"
120
+ f.puts " null;"
121
+ f.puts "end #{name};"
122
+ f.puts "/"
123
+ elsif config.db_type == 'mysql'
124
+ f.puts "delimiter $$"
125
+ f.puts "drop procedure if exists #{name}$$"
126
+ f.puts "create procedure #{name}()"
127
+ f.puts "begin"
128
+ f.puts "end$$"
129
+ elsif config.db_type == 'sybase'
130
+ f.puts "if exists (select 1 from sysobjects"
131
+ f.puts " where name = '#{name}'"
132
+ f.puts " and type in ('P', 'TR'))"
133
+ f.puts " drop proc #{name}"
134
+ f.puts "go"
135
+ f.puts ""
136
+ f.puts "create proc #{name}"
137
+ f.puts "as"
138
+ f.puts "return(0)"
139
+ f.puts "go"
140
+ end
141
+ end
142
+ end
143
+ when 'function', 'fnc', 'func'
144
+ filename = File.join(config.code_dir, "#{name}.fnc")
145
+ if File.exists?(filename)
146
+ puts "exists: #{filename}"
147
+ else
148
+ puts "creating: #{filename}"
149
+ File.open(filename, 'w') do |f|
150
+ if config.db_type == 'oracle'
151
+ f.puts "create or replace function #{name}"
152
+ f.puts " return varchar2"
153
+ f.puts "as"
154
+ f.puts "begin"
155
+ f.puts " null;"
156
+ f.puts "end #{name};"
157
+ f.puts "/"
158
+ elsif config.db_type == 'mysql'
159
+ f.puts "delimiter $$"
160
+ f.puts "drop function if exists #{name}$$"
161
+ f.puts "create function #{name}()"
162
+ f.puts " returns varchar(10)"
163
+ f.puts "begin"
164
+ f.puts " return 'abcd';"
165
+ f.puts "end$$"
166
+ elsif config.db_type == 'sybase'
167
+ f.puts "if exists (select 1 from sysobjects"
168
+ f.puts " where name = '#{name}'"
169
+ f.puts " and type in ('P', 'TR'))"
170
+ f.puts " drop func #{name}"
171
+ f.puts "go"
172
+ f.puts ""
173
+ f.puts "create func #{name}"
174
+ f.puts " returns int"
175
+ f.puts "as"
176
+ f.puts " return(0)"
177
+ f.puts "go"
178
+ end
179
+ end
180
+ end
181
+ when 'trigger', 'trg'
182
+ filename = File.join(config.code_dir, "#{name}.trg")
183
+ if File.exists?(filename)
184
+ puts "exists: #{filename}"
185
+ else
186
+ puts "creating: #{filename}"
187
+ File.open(filename, 'w') do |f|
188
+ if config.db_type == 'oracle'
189
+ f.puts "create or replace trigger #{name} before insert on TABLE"
190
+ f.puts "for each row"
191
+ f.puts "begin"
192
+ f.puts " null;"
193
+ f.puts "end;"
194
+ f.puts "/"
195
+ elsif config.db_type == 'mysql'
196
+ f.puts "delimiter $$"
197
+ f.puts "drop trigger if exists #{name}$$"
198
+ f.puts "CREATE TRIGGER #{name} BEFORE INSERT ON TABLE"
199
+ f.puts "FOR EACH ROW"
200
+ f.puts "BEGIN"
201
+ f.puts "END$$"
202
+ elsif config.db_type == 'sybase'
203
+ f.puts "if exists (select 1 from sysobjects"
204
+ f.puts " where name = '#{name}'"
205
+ f.puts " and type in ('P', 'TR'))"
206
+ f.puts " drop trigger #{name}"
207
+ f.puts "go"
208
+ f.puts ""
209
+ f.puts "create trigger #{name}"
210
+ f.puts "on MYTABLE"
211
+ f.puts "for insert, update"
212
+ f.puts ""
213
+ f.puts "go"
214
+ end
215
+ end
216
+ end
217
+ when 'type', 'typ'
218
+ filename = File.join(config.code_dir, "#{name}.typ")
219
+ if File.exists?(filename)
220
+ puts "exists: #{filename}"
221
+ else
222
+ puts "creating: #{filename}"
223
+ File.open(filename, 'w') do |f|
224
+ f.puts "create or replace type #{name}"
225
+ f.puts "as"
226
+ f.puts "/"
227
+ end
228
+ end
229
+ when 'milestone'
230
+ filename = File.join(config.migration_directory, "#{name}.milestone")
231
+ if File.exists?(filename)
232
+ puts "milestone already exists"
233
+ exit(1)
234
+ end
235
+ # The migration can be either the migration filename, or the internal :: name
236
+ migration = ARGV.shift
237
+ unless migration
238
+ puts "You must specify a migration for the milestone"
239
+ exit(1)
240
+ end
241
+ if migration =~ /::/ # internal name
242
+ migration = DBGeni::Migration.filename_from_internal_name(migration)
243
+ end
244
+ unless File.exists?(File.join(config.migration_directory, migration))
245
+ puts "The migration #{migration} does not exist"
246
+ exit(1)
247
+ end
248
+ File.open(filename, 'w') do |f|
249
+ f.puts migration
250
+ end
251
+ puts "creating: #{filename}"
252
+ else
253
+ puts "Error: #{command} is not a invalid generator"
254
+ exit(1)
255
+ end
256
+
257
+ exit(0)
@@ -0,0 +1,41 @@
1
+ if %w(-h --help).include? ARGV[0]
2
+ puts <<-EOF
3
+ Usage: dbgeni initialize <--environment-name env_name> <--config-file path/to/config> <--username user> <--password password>
4
+
5
+ If config-file is not specified, then a file called .dbgeni in the current directory will be
6
+ used if it exists, otherwise an error will occurr
7
+
8
+ If there is more than one environment defined in the config file, then environment-name must
9
+ be specified.
10
+
11
+ -e can be used as an abbreviation for --environment-name
12
+ -c can be used as an abbreviation for --config-file
13
+ -u can be used as an abbreviation for --username
14
+ -p can be used as an abbreviation for --password
15
+
16
+
17
+ EOF
18
+ exit(0)
19
+ end
20
+
21
+ installer = $build_installer.call
22
+
23
+ begin
24
+ logger = DBGeni::Logger.instance
25
+ installer.initialize_database
26
+ logger.info "Database initialized successfully"
27
+ rescue DBGeni::DatabaseAlreadyInitialized
28
+ logger.error "The Database has already been initialized"
29
+ exit(1)
30
+ rescue DBGeni::NoInitializerForDBType
31
+ logger.error "There is no initializer for the db_type setting"
32
+ exit(1)
33
+ rescue DBGeni::NoConnectorForDBType
34
+ logger.error "There is no connector defined for the db_type setting"
35
+ exit(1)
36
+ end
37
+
38
+ exit(0)
39
+
40
+
41
+
@@ -0,0 +1,243 @@
1
+ if %w(-h --help).include? ARGV[0]
2
+ puts <<-EOF
3
+ Usage: dbgeni migrations command <--environment-name env_name> <--config-file path/to/config> <--force> <--username user> <--password password>
4
+
5
+ If config-file is not specified, then a file called .dbgeni in the current directory will be
6
+ used if it exists, otherwise an error will occurr
7
+
8
+ If there is more than one environment defined in the config file, then environment-name must
9
+ be specified.
10
+
11
+ If --force is specified, the migration will run to completion and be marked as Completed even
12
+ if errors occur.
13
+
14
+ -e can be used as an abbreviation for --environment-name
15
+ -c can be used as an abbreviation for --config-file
16
+ -f can be used as an abbreviation for --force
17
+ -u can be used as an abbreviation for --username
18
+ -p can be used as an abbreviation for --password
19
+
20
+
21
+ Avaliable commands are:
22
+
23
+ Readonly
24
+ --------
25
+
26
+ list Prints out all available migrations
27
+ dbgeni migrations list --config-file /home/myapp/.dbgeni
28
+
29
+ applied Prints all migrations which have been applied to an environment
30
+ dbgeni migrations applied --environment-name test --config-file /home/myapp/.dbgeni
31
+
32
+ outstanding Prints all migrations which have not been applied to an environment
33
+ dbgeni migrations outstanding --environment-name test --config-file /home/myapp/.dbgeni
34
+
35
+
36
+ Destructive
37
+ -----------
38
+
39
+ apply Apply migrations to the given environment. Can specify:
40
+
41
+ all Apply all outstanding migrations
42
+ next Apply only the next migration and stop
43
+ until Apply upto and including the specified migration
44
+ specific migrations to apply
45
+ milestone Apply upto a specified milestone
46
+
47
+ dbgeni migrations apply all --environment-name test --config-file /home/myapp/.dbgeni <--force>
48
+ dbgeni migrations apply next --environment-name test --config-file /home/myapp/.dbgeni <--force>
49
+ dbgeni migrations apply until YYYYMMDDHHMM::Name1 --environment-name test --config-file /home/myapp/.dbgeni <--force>
50
+ dbgeni migrations apply YYYYMMDDHHMM::Name1 YYYYMMDDHHMM::Name2 YYYYMMDDHHMM::Name3 --environment-name test --config-file /home/myapp/.dbgeni <--force>
51
+ dbgeni migrations apply milestone release_1.0 --environment-name test --config-file /home/myapp/.dbgeni <--force>
52
+
53
+ rollback Run the rollback script for a given migration. Can specify:
54
+
55
+ all Rollback everything that has even been applied
56
+ last Rollback the last migration applied
57
+ until Rollback from the last applied migration until and including the specified migration
58
+ specific migrations to rollback
59
+
60
+ dbgeni migrations rollback all --environment-name test --config-file /home/myapp/.dbgeni <--force>
61
+ dbgeni migrations rollback last --environment-name test --config-file /home/myapp/.dbgeni <--force>
62
+ dbgeni migrations rollback until YYYYMMDDHHMM::Name1 --environment-name test --config-file /home/myapp/.dbgeni <--force>
63
+ dbgeni migrations rollback YYYYMMDDHHMM::Name1 YYYYMMDDHHMM::Name2 YYYYMMDDHHMM::Name3 --environment-name test --config-file /home/myapp/.dbgeni <--force>
64
+ dbgeni migrations rollback milestone release_1.0 --environment-name test --config-file /home/myapp/.dbgeni <--force>
65
+
66
+ EOF
67
+ exit
68
+ end
69
+
70
+ command = ARGV.shift
71
+
72
+ installer = nil
73
+ installer = $build_installer.call
74
+
75
+ logger = DBGeni::Logger.instance
76
+
77
+ begin
78
+ case command
79
+ when 'list'
80
+ migrations = installer.migrations
81
+ if migrations.length == 0
82
+ logger.info "There are no migrations in #{installer.config.migration_directory}"
83
+ end
84
+ migrations.each do |m|
85
+ puts m.to_s
86
+ end
87
+ when 'applied'
88
+ applied = installer.applied_migrations
89
+ if applied.length == 0
90
+ logger.info "There are no applied migrations in #{installer.config.migration_directory}"
91
+ end
92
+ applied.each do |m|
93
+ puts m.to_s
94
+ end
95
+ when 'outstanding'
96
+ outstanding = installer.outstanding_migrations
97
+ if outstanding.length == 0
98
+ logger.info "There are no outstanding migrations in #{installer.config.migration_directory}"
99
+ end
100
+ outstanding.each do |m|
101
+ puts m.to_s
102
+ end
103
+
104
+ when 'apply'
105
+ sub_command = ARGV.shift
106
+ case sub_command
107
+ when 'all'
108
+ installer.apply_all_migrations($force)
109
+ when 'next'
110
+ installer.apply_next_migration($force)
111
+ when 'until', 'milestone'
112
+ migration_name = nil
113
+ if sub_command == 'milestone'
114
+ unless ARGV[0]
115
+ logger.error "A milestone must be specified"
116
+ exit(1)
117
+ end
118
+ unless File.exists? File.join(installer.config.migration_directory, "#{ARGV[0]}.milestone")
119
+ logger.error "The milestone #{ARGV[0]} does not exist"
120
+ exit(1)
121
+ end
122
+ migration_name = DBGeni::Migration.internal_name_from_filename(
123
+ DBGeni::Migration.get_milestone_migration(
124
+ installer.config.migration_directory, "#{ARGV[0]}.milestone"))
125
+ else
126
+ # a migration name needs to be the next parameter
127
+ migration_name = ARGV[0]
128
+ end
129
+
130
+ unless migration_name
131
+ logger.error "A migration name must be specified"
132
+ exit(1)
133
+ end
134
+ # and the migration needs to be in the correct format
135
+ unless migration_name =~ /^(\d{12})::/
136
+ logger.error "#{migration_name} is not a valid migration name"
137
+ exit(1)
138
+ end
139
+ installer.apply_until_migration(migration_name, $force)
140
+ when /^(\d{12})::/
141
+ # The param list are specific migration files, but in the internal format. One is
142
+ # stored in sub_command and the rest are in ARGV. Grab all params that match the
143
+ # parameter name format
144
+ files = ARGV.select{ |f| f =~ /^(\d{12})::/ }
145
+ files.unshift sub_command
146
+ installer.apply_list_of_migrations(files, $force)
147
+ else
148
+ logger.error "#{sub_command} is not a valid command"
149
+ end
150
+
151
+ when 'rollback'
152
+ sub_command = ARGV.shift
153
+ case sub_command
154
+ when 'all'
155
+ installer.rollback_all_migrations($force)
156
+ when 'last'
157
+ installer.rollback_last_migration($force)
158
+ when 'until', 'milestone'
159
+ migration_name = nil
160
+ if sub_command == 'milestone'
161
+ unless ARGV[0]
162
+ logger.error "You must specify a milestone"
163
+ exit(1)
164
+ end
165
+ unless File.exists? File.join(installer.config.migration_directory, "#{ARGV[0]}.milestone")
166
+ logger.error "The milestone #{ARGV[0]} does not exist"
167
+ exit(1)
168
+ end
169
+ migration_name = DBGeni::Migration.internal_name_from_filename(
170
+ DBGeni::Migration.get_milestone_migration(
171
+ installer.config.migration_directory, "#{ARGV[0]}.milestone"))
172
+ else
173
+ # a migration name needs to be the next parameter
174
+ migration_name = ARGV[0]
175
+ end
176
+
177
+ unless migration_name
178
+ logger.error "A migration name must be specified"
179
+ exit(1)
180
+ end
181
+ # and the migration needs to be in the correct format
182
+ unless migration_name =~ /^(\d{12})::/
183
+ logger.error "#{migration_name} is not a valid migration name"
184
+ exit(1)
185
+ end
186
+ installer.rollback_until_migration(migration_name, $force)
187
+ when /^(\d{12})::/
188
+ # The param list are specific migration files, but in the internal format. One is
189
+ # stored in sub_command and the rest are in ARGV. Grab all params that match the
190
+ # parameter name format
191
+ files = ARGV.select{ |f| f =~ /^(\d{12})::/ }
192
+ files.unshift sub_command
193
+ installer.rollback_list_of_migrations(files, $force)
194
+ # migrations = files.map {|f| DBGeni::Migration.initialize_from_internal_name(installer.config.migration_directory, f)}
195
+ # # Now attempt to run each migration ... backwards for rollback
196
+ # migrations.sort{|x,y| y.migration_file <=> x.migration_file}.each do |m|
197
+ # installer.rollback_migration(m, $force)
198
+ # end
199
+ else
200
+ logger.error "#{sub_command} is not a valid command"
201
+ end
202
+ else
203
+ logger.error "#{command} is not a valid command"
204
+ end
205
+ rescue DBGeni::NoOutstandingMigrations => e
206
+ logger.info "There are no outstanding migrations to apply"
207
+ exit(0)
208
+ rescue DBGeni::MigrationApplyFailed => e
209
+ logger.error "There was a problem #{command == 'rollback' ? 'rolling back' : 'applying' } #{e.to_s}"
210
+ exit(1)
211
+ rescue DBGeni::MigrationAlreadyApplied => e
212
+ logger.error "The migration is already applied #{e.to_s}"
213
+ exit(1)
214
+ rescue DBGeni::MigrationFileNotExist => e
215
+ logger.error "The migration file #{e.to_s} does not exist"
216
+ exit(1)
217
+ rescue DBGeni:: DatabaseNotInitialized => e
218
+ logger.error "The database needs to be initialized with the command dbgeni initialize"
219
+ exit(1)
220
+ rescue DBGeni::NoAppliedMigrations => e
221
+ logger.error "There are no applied migrations to rollback"
222
+ exit(1)
223
+ rescue DBGeni::MigrationNotApplied => e
224
+ logger.error "#{e.to_s} has not been applied so cannot be rolledback"
225
+ exit(1)
226
+ rescue DBGeni::MigrationNotOutstanding => e
227
+ logger.error "#{e.to_s} does not exist or is not outstanding"
228
+ exit(1)
229
+ rescue DBGeni::DBCLINotOnPath => e
230
+ logger.error "The command line interface for the database is not on the path (sqlite3, sqlplus)"
231
+ exit(1)
232
+ rescue DBGeni::MilestoneHasNoMigration => e
233
+ logger.error "The milestone does not contain a valid migration"
234
+ exit(1)
235
+ rescue DBGeni::PluginDirectoryNotAccessible => e
236
+ logger.error "The plugin directory specified in config is not accessable: #{e.to_s}"
237
+ exit(1)
238
+ rescue DBGeni::PluginDoesNotRespondToRun
239
+ logger.error "A pluggin was loaded that does not have a run method: #{e.to_s}"
240
+ exit(1)
241
+ end
242
+
243
+ exit(0)
@@ -0,0 +1,52 @@
1
+ if %w(-h --help).include? ARGV[0]
2
+ puts <<-EOF
3
+
4
+ The milestone command can be used to list milestones.
5
+
6
+ Usage: dbgeni milestones command <--environment-name env_name> <--config-file path/to/config> <--force>
7
+
8
+ If config-file is not specified, then a file called .dbgeni in the current directory will be
9
+ used if it exists, otherwise an error will occurr
10
+
11
+ If there is more than one environment defined in the config file, then environment-name must
12
+ be specified.
13
+
14
+ If --force is specified, the migration will run to completion and be marked as Completed even
15
+ if errors occur.
16
+
17
+ -e can be used as an abbreviation for --environment-name
18
+ -c can be used as an abbreviation for --config-file
19
+ -f can be used as an abbreviation for --force
20
+
21
+
22
+ Avaliable commands are:
23
+
24
+ list Prints out all available milestones
25
+ dbgeni milestones list
26
+
27
+ EOF
28
+ exit(0)
29
+ end
30
+
31
+ command = ARGV.shift
32
+
33
+ installer = nil
34
+ installer = $build_installer.call
35
+
36
+ begin
37
+ case command
38
+ when 'list'
39
+ milestones = Dir.entries(installer.config.migration_directory).grep(/milestone$/)
40
+ if milestones.length == 0
41
+ puts "There are no milestones in the migrations_directory"
42
+ exit(1)
43
+ end
44
+ milestones.each do |m|
45
+ puts m.gsub(/\.milestone/, '')
46
+ end
47
+ else
48
+ puts "#{command} is an invalid command"
49
+ exit(1)
50
+ end
51
+ end
52
+