Created
July 29, 2012 08:14
-
-
Save deepfryed/3196621 to your computer and use it in GitHub Desktop.
migrations & hstore support
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env ruby | |
require 'swift' | |
require 'swift/adapter/postgres' | |
require 'swift/schema_migration' | |
require 'fileutils' | |
require 'optparse' | |
options = {} | |
OptionParser.new do |opt| | |
opt.on('-d', '--db name', String) {|value| options[:db] = value} | |
opt.on('-h', '--host name', String) {|value| options[:host] = value} | |
opt.on('-p', '--port port', Integer) {|value| options[:port] = value} | |
opt.on('-u', '--user name', String) {|value| options[:user] = value} | |
opt.on('-P', '--password secret', String) {|value| options[:password] = value} | |
end.parse! | |
path = options.delete(:path) || File.join(Dir.pwd, 'db/migrations') | |
db = Swift.setup :default, Swift::Adapter::Postgres, options | |
case ARGV.shift | |
when 'run', 'up' | |
Swift::SchemaMigration.new(db, path: path).up | |
when 'down' | |
Swift::SchemaMigration.new(db, path: path).down | |
when 'reset' | |
Swift::SchemaMigration.new(db, path: path).reset | |
when 'new' | |
name = ARGV.shift | |
file = File.join path, "#{Time.now.utc.strftime('%Y%m%d%H%M%S')}-#{name}" | |
raise "missing name" unless name | |
raise "missing or invalid extension (only .rb allowed)" unless %r{^.rb$}.match(File.extname(name)) | |
IO.write file, DATA.read | |
$stderr.puts "created:" | |
$stdout.puts " #{file.sub(File.join(path, '/'), '')}" | |
# Open migration in EDITOR | |
if editor = ENV['EDITOR'] | |
Kernel.exec "#{editor} #{file}" | |
end | |
else | |
puts "Invalid arguments: #{$0} [up|down|new] [name]" | |
end | |
exit 0 | |
__END__ | |
def up | |
end | |
def down | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require 'logger' | |
require 'swift/migrations' | |
module Swift | |
class SchemaMigration | |
attr_reader :db, :path | |
def initialize db, options = {} | |
@db = db | |
@path = options.fetch(:path) | |
end | |
def setup! | |
begin | |
db.execute('select * from schema_migrations limit 1') | |
rescue => e | |
db.execute 'create table schema_migrations(id serial primary key, name text, created_at timestamp)' | |
end | |
end | |
def existing_migrations | |
Swift.db.execute('select name from schema_migrations order by name desc').map {|r| r[:name]} | |
end | |
# runs the scope within the scope of current transaction | |
def migrate_up file | |
klassify(file).new.up | |
end | |
def migrate_down file | |
klassify(file).new.down | |
end | |
def klassify file | |
klass = Class.new | |
klass.class_eval <<-RUBY, __FILE__, __LINE__ + 1 | |
#{File.read(file)} | |
def execute *args | |
Swift.db.execute(*args) | |
end | |
RUBY | |
klass | |
end | |
def up | |
setup! | |
logger = Logger.new($stdout, 0) | |
migrated = existing_migrations | |
db.transaction do |db| | |
Dir[File.join(path, '*.{rb}')].sort.each do |file| | |
name = File.basename(file) | |
next if migrated.include?(name) | |
logger.info "migrating #{name}" | |
migrate_up(file) | |
db.execute('insert into schema_migrations(name, created_at) values(?, ?)', name, Time.now) | |
end | |
end | |
logger.info "done" | |
end | |
def down | |
setup! | |
logger = Logger.new($stdout, 0) | |
name = existing_migrations.first | |
file = File.join(path, "#{name}") | |
logger.info "migrating down #{name} using #{file}" | |
migrate_down(file) | |
db.execute('delete from schema_migrations where name = ?', name) | |
logger.info "done" | |
end | |
def reset | |
setup! | |
logger = Logger.new($stdout, 0) | |
existing_migrations.each do |name| | |
file = File.join(path, "#{name}") | |
logger.info "migrating down #{name} using #{file}" | |
migrate_down(file) | |
db.execute('delete from schema_migrations where name = ?', name) | |
end | |
logger.info "done" | |
end | |
end # SchemaMigration | |
end # Swift |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require 'hstore' | |
module Swift | |
module Type | |
class HStore < Attribute | |
def define_record_methods record | |
record.class_eval <<-RUBY, __FILE__, __LINE__ + 1 | |
def #{name}; ::HStore.parse(tuple.fetch(:#{field}, {})) end | |
def #{name}= value; tuple.store(:#{field}, ::HStore.dump(value)) end | |
RUBY | |
end | |
end | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment