lib/tasks/apartment.rake
require 'apartment/migrator'
require 'parallel'
apartment_namespace = namespace :apartment do
desc "Create all tenants"
task :create do
tenants.each do |tenant|
begin
puts("Creating #{tenant} tenant")
Apartment::Tenant.create(tenant)
rescue Apartment::TenantExists => e
puts e.message
end
end
end
desc "Drop all tenants"
task :drop do
tenants.each do |tenant|
begin
puts("Dropping #{tenant} tenant")
Apartment::Tenant.drop(tenant)
rescue Apartment::TenantNotFound => e
puts e.message
end
end
end
desc "Migrate all tenants"
task :migrate do
warn_if_tenants_empty
each_tenant do |tenant|
begin
puts("Migrating #{tenant} tenant")
Apartment::Migrator.migrate tenant
rescue Apartment::TenantNotFound => e
puts e.message
end
end
end
desc "Seed all tenants"
task :seed do
warn_if_tenants_empty
each_tenant do |tenant|
begin
puts("Seeding #{tenant} tenant")
Apartment::Tenant.switch(tenant) do
Apartment::Tenant.seed
end
rescue Apartment::TenantNotFound => e
puts e.message
end
end
end
desc "Rolls the migration back to the previous version (specify steps w/ STEP=n) across all tenants."
task :rollback do
warn_if_tenants_empty
step = ENV['STEP'] ? ENV['STEP'].to_i : 1
each_tenant do |tenant|
begin
puts("Rolling back #{tenant} tenant")
Apartment::Migrator.rollback tenant, step
rescue Apartment::TenantNotFound => e
puts e.message
end
end
end
namespace :migrate do
desc 'Runs the "up" for a given migration VERSION across all tenants.'
task :up do
warn_if_tenants_empty
version = ENV['VERSION'] ? ENV['VERSION'].to_i : nil
raise 'VERSION is required' unless version
each_tenant do |tenant|
begin
puts("Migrating #{tenant} tenant up")
Apartment::Migrator.run :up, tenant, version
rescue Apartment::TenantNotFound => e
puts e.message
end
end
end
desc 'Runs the "down" for a given migration VERSION across all tenants.'
task :down do
warn_if_tenants_empty
version = ENV['VERSION'] ? ENV['VERSION'].to_i : nil
raise 'VERSION is required' unless version
each_tenant do |tenant|
begin
puts("Migrating #{tenant} tenant down")
Apartment::Migrator.run :down, tenant, version
rescue Apartment::TenantNotFound => e
puts e.message
end
end
end
desc 'Rolls back the tenant one migration and re migrate up (options: STEP=x, VERSION=x).'
task :redo do
if ENV['VERSION']
apartment_namespace['migrate:down'].invoke
apartment_namespace['migrate:up'].invoke
else
apartment_namespace['rollback'].invoke
apartment_namespace['migrate'].invoke
end
end
end
def each_tenant(&block)
Parallel.each(tenants, in_threads: Apartment.parallel_migration_threads) do |tenant|
block.call(tenant)
end
end
def tenants
ENV['DB'] ? ENV['DB'].split(',').map { |s| s.strip } : Apartment.tenant_names || []
end
def warn_if_tenants_empty
if tenants.empty? && ENV['IGNORE_EMPTY_TENANTS'] != "true"
puts <<-WARNING
[WARNING] - The list of tenants to migrate appears to be empty. This could mean a few things:
1. You may not have created any, in which case you can ignore this message
2. You've run `apartment:migrate` directly without loading the Rails environment
* `apartment:migrate` is now deprecated. Tenants will automatically be migrated with `db:migrate`
Note that your tenants currently haven't been migrated. You'll need to run `db:migrate` to rectify this.
WARNING
end
end
end