68 lines
2.1 KiB
Ruby
68 lines
2.1 KiB
Ruby
# app/models/schema_manager.rb
|
|
class SchemaManager
|
|
class << self
|
|
def create_schema(organization_id)
|
|
schema_name = schema_name_for(organization_id)
|
|
|
|
ActiveRecord::Base.connection.execute("CREATE SCHEMA IF NOT EXISTS #{schema_name}")
|
|
|
|
with_schema(organization_id) do
|
|
# Run all existing migrations in this schema
|
|
migration_context = ActiveRecord::MigrationContext.new(Rails.application.paths["db/migrate"].first)
|
|
migration_context.migrate
|
|
end
|
|
end
|
|
|
|
def drop_schema(organization_id)
|
|
schema_name = schema_name_for(organization_id)
|
|
ActiveRecord::Base.connection.execute("DROP SCHEMA IF EXISTS #{schema_name} CASCADE")
|
|
end
|
|
|
|
def with_schema(organization_id)
|
|
schema_name = schema_name_for(organization_id)
|
|
original_schema = ActiveRecord::Base.connection.schema_search_path
|
|
|
|
begin
|
|
ActiveRecord::Base.connection.schema_search_path = schema_name
|
|
yield
|
|
ensure
|
|
ActiveRecord::Base.connection.schema_search_path = original_schema
|
|
end
|
|
end
|
|
|
|
def schema_name_for(organization_id)
|
|
"org_#{organization_id.to_s.gsub('-', '_')}"
|
|
end
|
|
|
|
# Migrate all existing organization schemas
|
|
def migrate_all_schemas
|
|
migration_context = ActiveRecord::MigrationContext.new(Rails.application.paths["db/migrate"].first)
|
|
|
|
Organization.find_each do |org|
|
|
puts "Migrating schema for #{org.name}..."
|
|
org.with_schema do
|
|
migration_context.migrate
|
|
end
|
|
end
|
|
end
|
|
|
|
# List all organization schemas
|
|
def list_schemas
|
|
result = ActiveRecord::Base.connection.execute(
|
|
"SELECT schema_name FROM information_schema.schemata
|
|
WHERE schema_name LIKE 'org_%'"
|
|
)
|
|
result.map { |row| row['schema_name'] }
|
|
end
|
|
|
|
# Check if schema exists
|
|
def schema_exists?(organization_id)
|
|
schema_name = schema_name_for(organization_id)
|
|
result = ActiveRecord::Base.connection.execute(
|
|
"SELECT EXISTS(SELECT 1 FROM information_schema.schemata WHERE schema_name = '#{schema_name}')"
|
|
)
|
|
result.first['exists']
|
|
end
|
|
end
|
|
end
|