lib/backup/splitter.rb
module Backup
class Splitter
include Utilities::Helpers
attr_reader :package, :chunk_size, :suffix_length
def initialize(model, chunk_size, suffix_length)
@package = model.package
@chunk_size = chunk_size
@suffix_length = suffix_length
end
##
# This is called as part of the procedure used to build the final
# backup package file(s). It yields it's portion of the command line
# for this procedure, which will split the data being piped into it
# into multiple files, based on the @chunk_size, using a suffix length as
# specified by @suffix_length.
# Once the packaging procedure is complete, it will return and
# @package.chunk_suffixes will be set based on the resulting files.
def split_with
Logger.info "Splitter configured with a chunk size of #{chunk_size}MB " \
"and suffix length of #{suffix_length}."
yield split_command
after_packaging
end
private
##
# The `split` command reads from $stdin and will store it's output in
# multiple files, based on @chunk_size and @suffix_length, using the full
# path to the final @package.basename, plus a '-' separator as the `prefix`.
def split_command
"#{utility(:split)} -a #{suffix_length} -b #{chunk_size}m - " \
"'#{File.join(Config.tmp_path, package.basename + "-")}'"
end
##
# Finds the resulting files from the packaging procedure
# and stores an Array of suffixes used in @package.chunk_suffixes.
# If the @chunk_size was never reached and only one file
# was written, that file will be suffixed with '-aa' (or -a; -aaa; etc
# depending upon suffix_length). In which case, it will simply
# remove the suffix from the filename.
def after_packaging
suffixes = chunk_suffixes
first_suffix = "a" * suffix_length
if suffixes == [first_suffix]
FileUtils.mv(
File.join(Config.tmp_path, "#{package.basename}-#{first_suffix}"),
File.join(Config.tmp_path, package.basename)
)
else
package.chunk_suffixes = suffixes
end
end
##
# Returns an array of suffixes for each chunk, in alphabetical order.
# For example: [aa, ab, ac, ad, ae] or [aaa, aab, aac aad]
def chunk_suffixes
chunks.map { |chunk| File.extname(chunk).split("-").last }.sort
end
##
# Returns an array of full paths to the backup chunks.
# Chunks are sorted in alphabetical order.
def chunks
Dir[File.join(Config.tmp_path, package.basename + "-*")].sort
end
end
end