namespace :db do
namespace :snapshot do desc "Create a snapshot of the current database and store it in S3" task create: :load do abort "Meant for production only!" unless Rails.env.production? ActiveRecord::Snapshot::List.download ActiveRecord::Snapshot::Version.download ActiveRecord::Snapshot::Create.call end desc "Take a snapshot of the current database and store it in S3" task create_named: :load do abort "Do not run in production!" if Rails.env.production? puts <<~TEXT Please enter a unique name for this snapshot. You will need to remember this to access it later: TEXT snapshot_name = STDIN.gets.strip abort "Please don't use spaces in your snapshot name." if snapshot_name =~ /\s/ abort "Please ensure your name is a string, integers are used for daily snapshots" if snapshot_name.to_i.to_s == snapshot_name ActiveRecord::Snapshot::Create.call(name: snapshot_name) end desc "Import production database snapshot." task :import, [:version] => [:load] do |_t, args| abort "Do not run in production mode!" if Rails.env.production? version = args.fetch(:version, "").strip ActiveRecord::Snapshot::Import.call(version: version) end namespace :import do desc "Import only specific tables from the most recent snapshot" task :only, [:tables] => :load do |_t, args| abort "Do not run in production mode!" if Rails.env.production? if args[:tables].blank? abort "Usage: bundle exec rake db:snapshot:import:only['table1 table2']" end tables = args[:tables].split(/[, ;'"]+/).reject(&:blank?) ActiveRecord::Snapshot::Import.call(tables: tables) end end desc "Reload current snapshot version" task reload: :load do version = ActiveRecord::Snapshot::Version.current abort "No current version found" unless version Rake::Task["db:snapshot:import"].invoke(version.to_s) end desc "Show available snapshot versions" task :list, [:count] => [:load] do |_t, args| version = ActiveRecord::Snapshot::Version.current puts "Current snapshot version is #{version}" if version path = ActiveRecord::Snapshot::List.path File.file?(path) || ActiveRecord::Snapshot::List.download lines = File.readlines(path) count = args.fetch(:count, 11).to_i - 1 puts lines[0..count] end task load: :environment do FileUtils.mkdir_p(ActiveRecord::Snapshot.config.store.values) end end
end