class Miguel::Command
Miguel
command line interface.
Attributes
env[R]
force[R]
format[R]
loggers[R]
quiet[R]
trace[R]
Public Instance Methods
init()
click to toggle source
Initialize the command options.
# File lib/miguel/command.rb, line 14 def init @env = nil @format = nil @loggers = [] @force = nil @quiet = nil @trace = nil end
run( args )
click to toggle source
Run the command.
# File lib/miguel/command.rb, line 24 def run( args ) args = args.dup init OptionParser.new( &method( :set_opts ) ).parse!( args ) execute( args ) exit 0 rescue Exception => e raise if trace or e.is_a?( SystemExit ) $stderr.print "#{e.class}: " unless e.is_a?( RuntimeError ) $stderr.puts e.message exit 1 end
Private Instance Methods
apply_schema( db, schema )
click to toggle source
Apply given schema to given database.
# File lib/miguel/command.rb, line 213 def apply_schema( db, schema ) from = import_schema( db ) changes = Migrator.new.changes( from, schema ).to_s if changes.empty? puts "No changes are necessary." unless quiet return end unless quiet puts "These changes will be applied to the database:" print changes end unless force fail "OK, aborting." unless confirm? end db.instance_eval( changes ) puts "OK, those changes were applied." unless quiet end
check_args( args, count )
click to toggle source
Make sure the argument count is as expected.
# File lib/miguel/command.rb, line 150 def check_args( args, count ) fail "Not enough arguments present, use -h to see usage." if args.count < count fail "Extra arguments present, use -h to see usage." if args.count > count end
confirm?()
click to toggle source
Ask the user for a confirmation.
# File lib/miguel/command.rb, line 237 def confirm? loop do print "Confirm (yes or no)? " unless line = $stdin.gets puts puts "I take EOF as 'no'. Use --force if you want to skip the confirmation instead." return end case line.chomp.downcase when 'yes' return true when 'no' return false else puts "Please answer 'yes' or 'no'." end end end
execute( args )
click to toggle source
Execute the command itself.
# File lib/miguel/command.rb, line 103 def execute( args ) command = args.shift or fail "Missing command, use -h to see usage." method = "execute_#{command}" fail "Invalid command, use -h to see usage." unless respond_to?( method, true ) check_args( args, method( method ).arity ) send( method, *args ) end
execute_apply( db_name, name )
click to toggle source
Execute the apply command.
# File lib/miguel/command.rb, line 137 def execute_apply( db_name, name ) db = get_db( db_name ) schema = get_schema( name ) apply_schema( db, schema ) end
execute_clear( db_name )
click to toggle source
Execute the clear command.
# File lib/miguel/command.rb, line 144 def execute_clear( db_name ) db = get_db( db_name ) apply_schema( db, Schema.new ) end
execute_diff( old_name, new_name )
click to toggle source
Execute the diff command.
# File lib/miguel/command.rb, line 130 def execute_diff( old_name, new_name ) old_schema = get_schema( old_name ) new_schema = get_schema( new_name ) show_changes( old_schema, new_schema ) end
execute_down( name )
click to toggle source
Execute the down command.
# File lib/miguel/command.rb, line 124 def execute_down( name ) schema = get_schema( name ) show_changes( schema, Schema.new ) end
execute_dump( name )
click to toggle source
Execute the dump command.
# File lib/miguel/command.rb, line 118 def execute_dump( name ) schema = get_schema( name ) show_changes( Schema.new, schema ) end
execute_show( name )
click to toggle source
Execute the show command.
# File lib/miguel/command.rb, line 112 def execute_show( name ) schema = get_schema( name ) print schema.dump end
get_db( name )
click to toggle source
Connect to given database.
# File lib/miguel/command.rb, line 174 def get_db( name ) db = if name.nil? or name.empty? fail "Missing database name." elsif File.exist?( name ) config = load_db_config( name ) Sequel.connect( config ) elsif name =~ /:/ Sequel.connect( name ) else fail "Database config #{name} not found." end db.loggers = loggers db end
get_schema( name )
click to toggle source
Get schema from given schema file or database.
# File lib/miguel/command.rb, line 161 def get_schema( name ) schema = if name.nil? or name.empty? fail "Missing database or schema name." elsif File.exist?( name ) and name =~ /\.rb\b/ Schema.load( name ) or fail "No schema loaded from file '#{name}'." else db = get_db( name ) import_schema( db ) end schema end
import_schema( db )
click to toggle source
Import schema from given database.
# File lib/miguel/command.rb, line 156 def import_schema( db ) Importer.new( db ).schema end
load_db_config( name )
click to toggle source
Load database config from given file.
# File lib/miguel/command.rb, line 190 def load_db_config( name ) require 'yaml' config = YAML.load_file( name ) env = self.env || "development" config = config[ env ] || config[ env.to_sym ] || config config.keys.each{ |k| config[ k.to_sym ] = config.delete( k ) } config end
set_opts( opts )
click to toggle source
Set the command options.
# File lib/miguel/command.rb, line 40 def set_opts( opts ) opts.banner = "Miguel: The Database Migrator and Migration Generator for Sequel" opts.define_head "Usage: miguel [options] <command> <db|schema> [db|schema]" opts.separator "" opts.separator "Examples:" opts.separator " miguel show mysql://localhost/main" opts.separator " miguel dump schema.rb" opts.separator " miguel diff db.yml test.yml" opts.separator " miguel apply db.yml schema.rb" opts.separator "" opts.separator "Commands:" opts.separator " show <db|schema> Show schema of given database or schema file" opts.separator " dump <db|schema> Dump migration which creates given schema" opts.separator " down <db|schema> Dump migration which reverses given schema" opts.separator " diff <db|schema> <db|schema> Dump migration needed to migrate to the second schema" opts.separator " apply <db> <db|schema> Apply given schema to the database" opts.separator " clear <db> Drop all tables in given database" opts.separator "" opts.separator "Options:" opts.on_tail( '-h', '-?', '--help', 'Show this message' ) do puts opts exit end opts.on( '-e', '--env <env>', 'Use given environment config for database(s)' ) do |v| @env = v end opts.on( '-E', '--echo', 'Echo SQL statements' ) do require 'logger' @loggers << Logger.new( $stdout ) end opts.on( '-f', '--force', 'Force changes to be applied without confirmation' ) do @force = true end opts.on( '-l', '--log <file>', 'Log SQL statements to given file' ) do |v| require 'logger' @loggers << Logger.new( v ) end formats = [ :bare, :change, :full ] opts.on( '-m', '--migration <format>', formats, "Select format for dumped migrations (#{formats.join(', ')})" ) do |v| @format = v end opts.on( '-q', '--quiet', "Don't display the changes to be applied" ) do @quiet = true end opts.on( '-t', '--trace', 'Show full backtrace if an exception is raised' ) do @trace = true end opts.on_tail( '-v', '--version', 'Print version' ) do puts "miguel #{Miguel::VERSION}" exit end end
show_changes( from, to )
click to toggle source
Show changes between the two schemas.
# File lib/miguel/command.rb, line 200 def show_changes( from, to ) m = Migrator.new case format when nil, :bare print m.changes( from, to ) when :change print m.change_migration( from, to ) when :full print m.full_migration( from, to ) end end