diff --git a/lib/tasks/veksel_tasks.rake b/lib/tasks/veksel_tasks.rake index 8955ea4..802febd 100644 --- a/lib/tasks/veksel_tasks.rake +++ b/lib/tasks/veksel_tasks.rake @@ -8,41 +8,10 @@ namespace :veksel do desc "List forked databases" task list: 'db:load_config' do - require 'veksel/commands/clean' + require 'veksel/commands/list' db = ActiveRecord::Base.configurations.find_db_config('development') - command = Veksel::Commands::Clean.new(db) - databases = command.all_databases - active_branches = command.active_branches - - if databases.empty? - puts "No databases created by Veksel" - next - end - - hash = {} - databases.each do |database| - branch = database.sub(command.prefix, '') - hash[branch] = database - end - - longest_branch_name = hash.keys.max_by(&:length).length - longest_database_name = hash.values.max_by(&:length).length - puts "Databases created by Veksel:" - puts "" - puts "#{'Branch'.ljust(longest_branch_name)} #{'Database'.ljust(longest_database_name)} Active" - inactive_count = 0 - hash.each do |branch, database| - # Print a formatted string padded to fit the longest branch name - active = active_branches.include?(branch) ? 'Yes' : 'No' - inactive_count += 1 if active == 'No' - puts "#{branch.ljust(longest_branch_name)} #{database.ljust(longest_database_name)} #{active}" - end - - if inactive_count > 0 - puts "" - puts "Clean inactive databases with bin/rails veksel:clean" - end + Veksel::Commands::List.new(db).perform end desc "Delete forked databases" diff --git a/lib/veksel.rb b/lib/veksel.rb index 15b2950..734f8bc 100644 --- a/lib/veksel.rb +++ b/lib/veksel.rb @@ -14,6 +14,10 @@ def current_branch `git rev-parse --abbrev-ref HEAD`.strip end + def active_branches + `git for-each-ref 'refs/heads/' --format '%(refname)'`.split("\n").map { |ref| ref.sub('refs/heads/', '') } + end + def skip_fork? suffix.to_s.strip.empty? end diff --git a/lib/veksel/commands/clean.rb b/lib/veksel/commands/clean.rb index 4ff64da..e048c44 100644 --- a/lib/veksel/commands/clean.rb +++ b/lib/veksel/commands/clean.rb @@ -3,16 +3,15 @@ module Veksel module Commands class Clean - attr_reader :prefix - def initialize(db, dry_run: false) @pg_cluster = PgCluster.new(db.configuration_hash) - @prefix = Veksel.prefix(db.configuration_hash[:database]) @dry_run = dry_run end def perform - all_databases = @pg_cluster.list_databases(prefix: @prefix) + all_databases = @pg_cluster.forked_databases + active_branches = Veksel.active_branches + stale_databases = all_databases.filter do |database| active_branches.none? { |branch| database.end_with?("_#{branch}") } end @@ -20,14 +19,6 @@ def perform @pg_cluster.drop_database(database, dry_run: @dry_run) end end - - def active_branches - `git for-each-ref 'refs/heads/' --format '%(refname)'`.split("\n").map { |ref| ref.sub('refs/heads/', '') } - end - - def all_databases - @pg_cluster.list_databases(prefix: @prefix) - end end end end diff --git a/lib/veksel/commands/list.rb b/lib/veksel/commands/list.rb new file mode 100644 index 0000000..7fbf6eb --- /dev/null +++ b/lib/veksel/commands/list.rb @@ -0,0 +1,47 @@ +require_relative '../pg_cluster' + +module Veksel + module Commands + class List + attr_reader :adapter + + def initialize(db) + @adapter = PgCluster.new(db.configuration_hash) + end + + def perform + databases = adapter.forked_databases + active_branches = Veksel.active_branches + + if databases.empty? + puts "No databases created by Veksel" + return + end + + hash = {} + databases.each do |database| + branch = database.sub(adapter.forked_database_prefix, '') + hash[branch] = database + end + + longest_branch_name = hash.keys.max_by(&:length).length + longest_database_name = hash.values.max_by(&:length).length + puts "Databases created by Veksel:" + puts "" + puts "#{'Branch'.ljust(longest_branch_name)} #{'Database'.ljust(longest_database_name)} Active" + inactive_count = 0 + hash.each do |branch, database| + # Print a formatted string padded to fit the longest branch name + active = active_branches.include?(branch) ? 'Yes' : 'No' + inactive_count += 1 if active == 'No' + puts "#{branch.ljust(longest_branch_name)} #{database.ljust(longest_database_name)} #{active}" + end + + if inactive_count > 0 + puts "" + puts "Clean inactive databases with bin/rails veksel:clean" + end + end + end + end +end diff --git a/lib/veksel/pg_cluster.rb b/lib/veksel/pg_cluster.rb index 5cb05df..a08d2db 100644 --- a/lib/veksel/pg_cluster.rb +++ b/lib/veksel/pg_cluster.rb @@ -6,6 +6,18 @@ def initialize(configuration_hash) @configuration_hash = configuration_hash end + def main_database + configuration_hash[:veksel_main_database] || configuration_hash[:database] + end + + def forked_databases + list_databases(prefix: forked_database_prefix) + end + + def forked_database_prefix + "#{main_database}_" + end + def target_populated?(dbname) IO.pipe do |r, w| spawn(pg_env, %[psql -t #{pg_connection_args(dbname)} -c "SELECT 'ok' FROM ar_internal_metadata LIMIT 1;"], out: w, err: '/dev/null') diff --git a/lib/veksel/railtie.rb b/lib/veksel/railtie.rb index 6583245..d1d6393 100644 --- a/lib/veksel/railtie.rb +++ b/lib/veksel/railtie.rb @@ -14,7 +14,8 @@ class Railtie < ::Rails::Railtie if PgCluster.new(config).target_populated?("#{config[:database]}#{Veksel.suffix}") ActiveRecord::DatabaseConfigurations::HashConfig.new(env_name, name, config.merge({ - database: "#{config[:database]}#{Veksel.suffix}" + database: "#{config[:database]}#{Veksel.suffix}", + veksel_main_database: config[:database], })) else ActiveRecord::DatabaseConfigurations::HashConfig.new(env_name, name, config)