Created
April 10, 2016 21:26
-
-
Save rpanachi/f16447f8b03fa5edcf935863fcdffb95 to your computer and use it in GitHub Desktop.
Rakefile for Sequel database operations
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
namespace :db do | |
require 'sequel' | |
Sequel.extension(:migration) | |
MIGRATIONS_PATH = 'db/migrations' | |
def db_conn_env | |
ENV["BOOKSHELF_DATABASE_URL"] | |
end | |
def db_conn_url | |
db = split_db_url(db_conn_env) | |
db_conn = "postgres://#{db[:user]}:#{db[:pass]}@#{db[:host]}" | |
end | |
def split_db_url(url) | |
user, pass, host, database = url.scan(/postgres:\/\/(.+?):(.+?)@(.+?)\/(.+?)$/).first | |
data = { | |
user: user, | |
pass: pass, | |
host: host, | |
database: database | |
} | |
end | |
def db_migrate(version = db_migrations.last) | |
puts "Migrating database to version #{version}" | |
Sequel::Migrator.run(DB, MIGRATIONS_PATH, target: version.to_i) | |
end | |
def db_migrated?(version, schema = :sequel) | |
db_versions(schema).include?(version.to_s) | |
end | |
def db_versions(schema = :sequel) | |
if schema == :sequel | |
DB[:schema_migrations].order(:filename).select_map(:filename) | |
elsif schema == :rails | |
DB[:schema_migrations].order(:version).select_map(:version) | |
else | |
[] | |
end | |
end | |
def db_migrations | |
Dir[MIGRATIONS_PATH + "/*.rb"] | |
.map { |f| File.basename(f) } | |
.sort | |
end | |
def db_schema(object) | |
Hash[DB.schema(object)] | |
rescue Sequel::DatabaseError | |
nil | |
end | |
desc 'Seed the database with application required data' | |
task seed: :environment do | |
load 'db/seeds.rb' | |
end | |
desc "Prints current schema version" | |
task :version => :environment do | |
puts "Current Schema Version: #{db_versions(:sequel).last}" | |
end | |
desc "Perform migration up to latest migration available" | |
task :migrate, [:version] => :environment do |t, args| | |
db_migrate(args[:version] || db_migrations.last) | |
Rake::Task['db:version'].execute | |
end | |
desc "Perform rollback to specified target or previous version as default" | |
task :rollback, [:version] => :environment do |t, args| | |
version = args[:version] || db_versions(:sequel)[-2] | |
db_migrate(version) | |
Rake::Task['db:version'].execute | |
end | |
desc "Perform migration reset (full rollback and migration) only on local environment" | |
task :reset => :environment do | |
if (ENV["HANAMI_ENV"] || ENV["RACK_ENV"]) == "production" | |
abort "You can't run this rake on production environment" | |
end | |
db_migrate(0) | |
db_migrate(db_migrations.last) | |
Rake::Task['db:version'].execute | |
end | |
desc "Creates database" | |
task :create => :"settings:load" do | |
db = split_db_url(db_conn_env) | |
exec "psql", | |
"#{db_conn_url}", | |
"-c", "CREATE DATABASE #{db[:database]}" | |
end | |
desc "Drops database" | |
task :drop => :"settings:load" do | |
if (ENV["HANAMI_ENV"] || ENV["RACK_ENV"]) == "production" | |
abort "You can't run this rake on production environment" | |
end | |
db = split_db_url(db_conn_env) | |
exec "psql", | |
"#{db_conn_url}", | |
"-c", "DROP DATABASE IF EXISTS #{db[:database]}" | |
end | |
desc "Start a database console on environment" | |
task :console => :'settings:load' do | |
exec "psql", db_conn_env | |
end | |
namespace :structure do | |
require 'hanami/model' | |
require 'hanami/model/migrator' | |
task :check_schema_migrations do | |
raise "Schema_migrations not prepared! Run 'rake db:migrate'" unless db_schema(:schema_migrations) | |
end | |
task :check_structure_sequel do | |
raise "Sequel schema_migrations not prepared! Run 'rake db:structure:to_sequel'" unless db_schema(:schema_migrations)[:filename] | |
end | |
task :prepare_structure_sequel do | |
schema_migrations = db_schema(:schema_migrations) | |
DB.run "alter table schema_migrations alter column version drop not null;" if schema_migrations[:version] | |
DB.run "alter table schema_migrations add filename varchar;" unless schema_migrations[:filename] | |
puts "Structure: DONE" | |
end | |
task :migrate_structure_sequel do | |
db_migrations.each do |filename| | |
version = filename.to_i | |
if db_migrated?(version, :rails) | |
DB.run "update schema_migrations set filename = '#{filename}' where version = '#{version}';" | |
else | |
DB.run "insert into schema_migrations (version, filename) values ('#{version}', '#{filename}');" | |
end | |
puts "> #{filename} DONE" | |
end | |
puts "Migration: DONE" | |
end | |
task :check_structure_rails do | |
raise "Rails schema_migrations not prepared! Run 'rake db:structure:to_rails'" unless db_schema(:schema_migrations)[:version] | |
end | |
task :prepare_structure_rails do | |
schema_migrations = db_schema(:schema_migrations) | |
DB.run "alter table schema_migrations drop constraint schema_migrations_pkey;" if db_schema(:schema_migrations_pkey) | |
DB.run "alter table schema_migrations alter column filename drop not null;" if schema_migrations[:filename] | |
DB.run "alter table schema_migrations add version varchar;" unless schema_migrations[:version] | |
puts "Structure: DONE" | |
end | |
task :migrate_structure_rails do | |
db_migrations.each do |filename| | |
version = filename.to_i | |
if db_migrated?(filename, :sequel) | |
DB.run "update schema_migrations set version = '#{version}' where filename = '#{filename}';" | |
else | |
DB.run "insert into schema_migrations (version, filename) values ('#{version}', '#{filename}');" | |
end | |
puts "> #{filename} DONE" | |
end | |
puts "Migration: DONE" | |
end | |
desc "Setup database structure from Sequel to Rails Migrations" | |
task :to_rails => [ | |
:environment, | |
:check_schema_migrations, | |
:check_structure_sequel, | |
:prepare_structure_rails, | |
:migrate_structure_rails | |
] | |
desc "Setup database structure from Rails to Sequel Migrations" | |
task :to_sequel => [ | |
:environment, | |
:check_schema_migrations, | |
:check_structure_rails, | |
:prepare_structure_sequel, | |
:migrate_structure_sequel | |
] | |
# Configure Hanami::Model for structure dump/load | |
task :configure do | |
Hanami::Model.configure do | |
adapter type: :sql, uri: db_conn_env | |
migrations 'db/migrations' | |
schema 'db/schema.sql' | |
mapping {} | |
end.load! | |
end | |
desc "Dump database structure to db/schema.sql" | |
task dump: [:environment, :configure] do | |
adapter = Hanami::Model::Migrator::Adapter.for(DB) | |
adapter.dump | |
end | |
desc "Load db/schema.sql database structure" | |
task load: :environment do | |
adapter = Hanami::Model::Migrator::Adapter.for(DB) | |
adapter.load | |
end | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment