# frozen_string_literal: true 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