#9 Active Storage - migration

This commit is contained in:
Karel Pičman 2025-10-15 16:31:53 +02:00
parent 6cf65bf3dd
commit bf17ddc7da

View File

@ -19,10 +19,13 @@
# Migrate documents to/from Active Storage # Migrate documents to/from Active Storage
class ActiveStorageMigration < ActiveRecord::Migration[7.0] class ActiveStorageMigration < ActiveRecord::Migration[7.0]
# File system -> Active Storage # File system -> Active Storage
def up def up
$stdout.puts "It could be a very long process. Be patient...\n" $stdout.puts 'It could be a very long process. Be patient...'
# Remove the Xapian database as it will be rebuilt from scratch during the migration
if xapian_database_removed?
$stdout.puts 'The Xapian database has been removed as it will be rebuilt from scratch during the migration'
end
Dir.glob(DmsfFile.storage_path.join('**/*')).each do |path| Dir.glob(DmsfFile.storage_path.join('**/*')).each do |path|
# Print out the currently processed directory # Print out the currently processed directory
unless File.file?(path) unless File.file?(path)
@ -32,11 +35,9 @@ class ActiveStorageMigration < ActiveRecord::Migration[7.0]
# Process a file # Process a file
disk_filename = File.basename(path) disk_filename = File.basename(path)
DmsfFileRevision.where(disk_filename: disk_filename) DmsfFileRevision.where(disk_filename: disk_filename)
.order(source_dmsf_file_revision_id: :asc) .order(source_dmsf_file_revision_id: :asc)
.find_each .find_each
.with_index do |r, i| .with_index do |r, i|
next if r.dmsf_file.project.id != 3886 # Dry run
if i.zero? if i.zero?
r.shared_file.attach( r.shared_file.attach(
io: File.open(path), io: File.open(path),
@ -50,9 +51,7 @@ class ActiveStorageMigration < ActiveRecord::Migration[7.0]
$stdout.puts "#{path} => #{File.join(key[0..1], key[2..3], key)} (#{r.shared_file.blob.filename})" $stdout.puts "#{path} => #{File.join(key[0..1], key[2..3], key)} (#{r.shared_file.blob.filename})"
else else
# The other revisions should have set the source revision # The other revisions should have set the source revision
unless r.source_dmsf_file_revision_id warn("r#{r.id}.source_dmsf_file_revision_id is null") unless r.source_dmsf_file_revision_id
warn "r#{r.id}.source_dmsf_file_revision_id is null"
end
end end
end end
end end
@ -61,22 +60,36 @@ class ActiveStorageMigration < ActiveRecord::Migration[7.0]
# Active Storage -> File system # Active Storage -> File system
def down def down
n = DmsfFileRevision.all.size $stdout.puts 'It could be a very long process. Be patient...'
$stdout.puts "#{n} revisions found. It could be a very long process. Be patient...\n" ActiveStorage::Attachment.find_each do |a|
DmsfFileRevision.find_each.with_index do |r, i| r = a.record
$stdout.print "\r#{i * 100 / n}%"
next unless r.shared_file.attached?
next if r.dmsf_file.project.id != 3886 # Dry run
new_path = r.disk_file(search_if_not_exists: false) new_path = r.disk_file(search_if_not_exists: false)
unless File.exist?(new_path) unless File.exist?(new_path)
r.shared_file.open do |f| a.blob.open do |f|
FileUtils.mv f.path, new_path FileUtils.mv f.path, new_path
end end
key = a.blob.key
$stdout.puts "#{File.join(key[0..1], key[2..3], key)} (#{a.blob.filename}) => #{new_path}"
end end
# Remove the original file # Remove the original file
r.shared_file.purge a.blob.purge
end
# Remove the Xapian database as it is useless now and has to be rebuilt with xapian_indexer.rb
if xapian_database_removed?
$stdout.puts 'Xapian database have been removed as it is useless now and has to be rebuilt with xapian_indexer.rb'
end end
$stdout.puts 'Done' $stdout.puts 'Done'
end end
private
# Delete Xapian database
def xapian_database_removed?
if RedmineDmsf::Plugin.lib_available?('xapian')
FileUtils.rm_rf File.join(RedmineDmsf.dmsf_index_database, RedmineDmsf.dmsf_stemming_lang)
true
else
false
end
end
end end