class Duck_Duck_Duck
Constants
- DB
- SCHEMA_TABLE
Attributes
Public Class Methods
create(*args)
click to toggle source
# File lib/duck_duck_duck.rb, line 19 def create *args new(*args).create end
dev_only()
click to toggle source
# File lib/duck_duck_duck.rb, line 15 def dev_only fail "Not allowed on a dev machine." if ENV['IS_DEV'] end
migrate_schema()
click to toggle source
# File lib/duck_duck_duck.rb, line 23 def migrate_schema DB << <<-EOF CREATE TABLE IF NOT EXISTS #{SCHEMA_TABLE} ( name varchar(255) NOT NULL PRIMARY KEY, version smallint NOT NULL DEFAULT 0 ) EOF end
new(*args)
click to toggle source
# File lib/duck_duck_duck.rb, line 78 def initialize *args @name, @action, @sub_action = args if !@name fail ArgumentError, "Name required." end @__files = `find . -iregex ".+/#{name}/migrates/__.+\.sql"` .strip .split("\n") .sort @files = ( `find . -iregex ".+/#{name}/migrates/.+\.sql"` .strip .split("\n") .grep(/\/\d+\-/) .sort ) end
read_file(f)
click to toggle source
# File lib/duck_duck_duck.rb, line 32 def read_file f raw = File.read(f).split(/\s*--\s+(UP|BOTH|DOWN):?\s*/). inject([:UP, {:UP=>[], :DOWN=>[]}]) do |memo, val| dir = memo.first meta = memo.last case val when 'UP', :UP, :DOWN, 'DOWN', 'BOTH', :BOTH dir = val.to_sym when '' # do nothing else case dir when :BOTH meta[:UP] << val meta[:DOWN] << val else meta[dir] << val end end [dir, meta] end meta = raw.last {:UP=>meta[:UP].join("\n"), :DOWN=>meta[:DOWN].join("\n")} end
stdout(*args)
click to toggle source
# File lib/duck_duck_duck.rb, line 11 def stdout *args args.each { |a| print "#{a}\n" } end
Public Instance Methods
create()
click to toggle source
# File lib/duck_duck_duck.rb, line 207 def create `mkdir -p #{name}/migrates` size = 3 next_ver = begin (@files.last || '')[/\/(\d+)[^\/]+\z/] v = if $1 size = $1.size $1 else '0' end "%0#{size}d" % (v.to_i + 1) end new_file = "#{name}/migrates/#{next_ver}-#{[action, sub_action].compact.join('-')}.sql" File.open(new_file, 'a') do |f| f.print "\n\n\n\n-- DOWN\n\n\n\n" end stdout new_file end
down()
click to toggle source
# File lib/duck_duck_duck.rb, line 166 def down rec = init_model_in_schema if rec[:version] < 0 stdout "#{name} is at invalid version: #{rec[:version]}\n" exit 1 end files = if rec[:version] == 0 [] else @files.sort.reverse.map { |f| ver = file_to_ver(f) next unless ver <= rec[:version] [ ver, Duck_Duck_Duck.read_file(f)[:DOWN] ] }.compact end if @__files.empty? && files.empty? stdout "#{name} is already the latest: #{rec[:version]}\n" exit 0 end new_ver = nil files.each_with_index { |pair, i| prev_pair = files[i+1] || [0, nil] ver = prev_pair.first.to_i sql = pair[1] DB << sql DB[" UPDATE #{SCHEMA_TABLE} SET version = ? WHERE name = upper( ? )", ver, name].update stdout "#{name} schema is now : #{ver}" } @__files.reverse.each { |f| DB << Duck_Duck_Duck.read_file(f)[:DOWN] stdout "down: #{f}" } end
file_to_ver(str)
click to toggle source
# File lib/duck_duck_duck.rb, line 102 def file_to_ver str File.basename(str)[/\A\d{1,}/].to_i end
init_model_in_schema()
click to toggle source
# File lib/duck_duck_duck.rb, line 111 def init_model_in_schema rec = DB.fetch( "SELECT version FROM #{SCHEMA_TABLE} WHERE name = upper( :name )", :name=>name ).all.first if !rec dir_name = "#{name}/migrates" dir = `find . -iregex ".+/#{dir_name}"`.strip.split("\n") if dir.empty? fail "Directory #{dir_name} does not exist." end rec = DB.fetch( "INSERT INTO #{SCHEMA_TABLE} (name, version) VALUES (upper(:name), :version) RETURNING *", :name=>name, :version=>0 ).all.first end {:version=>rec[:version]} end
reset()
click to toggle source
# File lib/duck_duck_duck.rb, line 106 def reset down up end
stdout(*args)
click to toggle source
# File lib/duck_duck_duck.rb, line 98 def stdout *args Duck_Duck_Duck.stdout *args end
up()
click to toggle source
# File lib/duck_duck_duck.rb, line 132 def up rec = init_model_in_schema if rec[:version] < 0 stdout "#{name} has an invalid version: #{rec[:version]}\n" exit 1 end files = @files.sort.map { |f| ver = file_to_ver(f) if ver > rec[:version] [ ver, Duck_Duck_Duck.read_file(f)[:UP] ] end }.compact if @__files.empty? && files.empty? stdout "#{name} is already the latest: #{rec[:version]}" end @__files.each { |f| DB << Duck_Duck_Duck.read_file(f)[:UP] stdout "ran file: #{f}" } files.each { |pair| ver = pair.first sql = pair[1] DB << sql DB[" UPDATE #{SCHEMA_TABLE.inspect} SET version = ? WHERE name = upper( ? ); ", ver, name].update stdout "#{name} schema is now : #{ver}" } end