fury_dumper 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
 - data/.github/workflows/build.yaml +43 -0
 - data/.gitignore +16 -0
 - data/.rspec +3 -0
 - data/.rubocop.yml +67 -0
 - data/.ruby-version +1 -0
 - data/.travis.yml +6 -0
 - data/Breadth-first.png +0 -0
 - data/CODE_OF_CONDUCT.md +74 -0
 - data/Depth-first.png +0 -0
 - data/Gemfile +10 -0
 - data/Gemfile.lock +202 -0
 - data/README.md +383 -0
 - data/README.ru.md +382 -0
 - data/Rakefile +8 -0
 - data/app/controllers/fury_dumper/dump_process_controller.rb +25 -0
 - data/config/routes.rb +6 -0
 - data/fury_dumper.gemspec +37 -0
 - data/lib/fury_dumper/api.rb +82 -0
 - data/lib/fury_dumper/config.rb +113 -0
 - data/lib/fury_dumper/dumper.rb +632 -0
 - data/lib/fury_dumper/dumpers/dump_state.rb +61 -0
 - data/lib/fury_dumper/dumpers/model.rb +131 -0
 - data/lib/fury_dumper/dumpers/model_queue.rb +34 -0
 - data/lib/fury_dumper/dumpers/relation_items.rb +79 -0
 - data/lib/fury_dumper/encrypter.rb +17 -0
 - data/lib/fury_dumper/engine.rb +7 -0
 - data/lib/fury_dumper/version.rb +5 -0
 - data/lib/fury_dumper.rb +102 -0
 - data/lib/generators/fury_dumper/config_generator.rb +21 -0
 - data/rails_generators/fury_dumper_config/fury_dumper_config_generator.rb +10 -0
 - data/rails_generators/fury_dumper_config/templates/fury_dumper.rb +1 -0
 - data/rails_generators/fury_dumper_config/templates/fury_dumper.yml +44 -0
 - metadata +181 -0
 
| 
         @@ -0,0 +1,131 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # frozen_string_literal: true
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            module FuryDumper
         
     | 
| 
      
 4 
     | 
    
         
            +
              module Dumpers
         
     | 
| 
      
 5 
     | 
    
         
            +
                class Model
         
     | 
| 
      
 6 
     | 
    
         
            +
                  attr_reader :source_model, :iteration, :warnings
         
     | 
| 
      
 7 
     | 
    
         
            +
                  attr_accessor :relation_items, :root_model
         
     | 
| 
      
 8 
     | 
    
         
            +
             
     | 
| 
      
 9 
     | 
    
         
            +
                  def initialize(source_model:, relation_items:, iteration: 0, root_model: nil)
         
     | 
| 
      
 10 
     | 
    
         
            +
                    raise ArgumentError unless source_model.is_a?(String)
         
     | 
| 
      
 11 
     | 
    
         
            +
                    raise ArgumentError unless relation_items.is_a?(RelationItems)
         
     | 
| 
      
 12 
     | 
    
         
            +
                    raise ArgumentError unless iteration.is_a?(Numeric)
         
     | 
| 
      
 13 
     | 
    
         
            +
                    raise ArgumentError unless root_model.is_a?(Model) || root_model.nil?
         
     | 
| 
      
 14 
     | 
    
         
            +
             
     | 
| 
      
 15 
     | 
    
         
            +
                    @source_model   = source_model
         
     | 
| 
      
 16 
     | 
    
         
            +
                    @relation_items = relation_items
         
     | 
| 
      
 17 
     | 
    
         
            +
                    @iteration      = iteration
         
     | 
| 
      
 18 
     | 
    
         
            +
                    @root_model     = root_model
         
     | 
| 
      
 19 
     | 
    
         
            +
                    @warnings       = []
         
     | 
| 
      
 20 
     | 
    
         
            +
                  end
         
     | 
| 
      
 21 
     | 
    
         
            +
             
     | 
| 
      
 22 
     | 
    
         
            +
                  def copy
         
     | 
| 
      
 23 
     | 
    
         
            +
                    self.class.new(source_model: source_model,
         
     | 
| 
      
 24 
     | 
    
         
            +
                                   relation_items: relation_items.copy,
         
     | 
| 
      
 25 
     | 
    
         
            +
                                   iteration: iteration,
         
     | 
| 
      
 26 
     | 
    
         
            +
                                   root_model: root_model)
         
     | 
| 
      
 27 
     | 
    
         
            +
                  end
         
     | 
| 
      
 28 
     | 
    
         
            +
             
     | 
| 
      
 29 
     | 
    
         
            +
                  delegate :table_name, to: :active_record_model
         
     | 
| 
      
 30 
     | 
    
         
            +
             
     | 
| 
      
 31 
     | 
    
         
            +
                  def column_names
         
     | 
| 
      
 32 
     | 
    
         
            +
                    active_record_model.columns.map(&:name)
         
     | 
| 
      
 33 
     | 
    
         
            +
                  end
         
     | 
| 
      
 34 
     | 
    
         
            +
             
     | 
| 
      
 35 
     | 
    
         
            +
                  def ==(other)
         
     | 
| 
      
 36 
     | 
    
         
            +
                    raise ArgumentError unless other.is_a?(Model)
         
     | 
| 
      
 37 
     | 
    
         
            +
             
     | 
| 
      
 38 
     | 
    
         
            +
                    @source_model == other.source_model &&
         
     | 
| 
      
 39 
     | 
    
         
            +
                      @relation_items.eql?(other.relation_items) &&
         
     | 
| 
      
 40 
     | 
    
         
            +
                      sub_path?(other)
         
     | 
| 
      
 41 
     | 
    
         
            +
                  end
         
     | 
| 
      
 42 
     | 
    
         
            +
             
     | 
| 
      
 43 
     | 
    
         
            +
                  def sub_path?(other_model)
         
     | 
| 
      
 44 
     | 
    
         
            +
                    raise ArgumentError unless other_model.is_a?(Model)
         
     | 
| 
      
 45 
     | 
    
         
            +
             
     | 
| 
      
 46 
     | 
    
         
            +
                    min_length = [root_path.length, other_model.root_path.length].min - 1
         
     | 
| 
      
 47 
     | 
    
         
            +
                    root_path[0..min_length] == other_model.root_path[0..min_length]
         
     | 
| 
      
 48 
     | 
    
         
            +
                  end
         
     | 
| 
      
 49 
     | 
    
         
            +
             
     | 
| 
      
 50 
     | 
    
         
            +
                  def root_path
         
     | 
| 
      
 51 
     | 
    
         
            +
                    return [nil] if @root_model.nil?
         
     | 
| 
      
 52 
     | 
    
         
            +
             
     | 
| 
      
 53 
     | 
    
         
            +
                    @root_model.root_path + [@root_model.source_model]
         
     | 
| 
      
 54 
     | 
    
         
            +
                  end
         
     | 
| 
      
 55 
     | 
    
         
            +
             
     | 
| 
      
 56 
     | 
    
         
            +
                  def to_full_str
         
     | 
| 
      
 57 
     | 
    
         
            +
                    buffer = "MODEL #{@source_model} by #{root_model&.source_model.presence || '-'} WHERE "
         
     | 
| 
      
 58 
     | 
    
         
            +
             
     | 
| 
      
 59 
     | 
    
         
            +
                    buffer += @relation_items.items.map do |item|
         
     | 
| 
      
 60 
     | 
    
         
            +
                      if item.complex
         
     | 
| 
      
 61 
     | 
    
         
            +
                        item.key
         
     | 
| 
      
 62 
     | 
    
         
            +
                      elsif item.values_for_key.count > 10
         
     | 
| 
      
 63 
     | 
    
         
            +
                        "#{item.key} = #{item.values_for_key[0..10]} and #{item.values_for_key.count - 10} elements"
         
     | 
| 
      
 64 
     | 
    
         
            +
                      else
         
     | 
| 
      
 65 
     | 
    
         
            +
                        "#{item.key} = #{item.values_for_key}"
         
     | 
| 
      
 66 
     | 
    
         
            +
                      end
         
     | 
| 
      
 67 
     | 
    
         
            +
                    end.join(' AND ')
         
     | 
| 
      
 68 
     | 
    
         
            +
             
     | 
| 
      
 69 
     | 
    
         
            +
                    buffer
         
     | 
| 
      
 70 
     | 
    
         
            +
                  end
         
     | 
| 
      
 71 
     | 
    
         
            +
             
     | 
| 
      
 72 
     | 
    
         
            +
                  def active_record_model
         
     | 
| 
      
 73 
     | 
    
         
            +
                    @source_model.constantize
         
     | 
| 
      
 74 
     | 
    
         
            +
                  end
         
     | 
| 
      
 75 
     | 
    
         
            +
             
     | 
| 
      
 76 
     | 
    
         
            +
                  delegate :primary_key, to: :active_record_model
         
     | 
| 
      
 77 
     | 
    
         
            +
             
     | 
| 
      
 78 
     | 
    
         
            +
                  def to_short_str
         
     | 
| 
      
 79 
     | 
    
         
            +
                    "#{@source_model}.#{@relation_items.keys.join(' & ')}"
         
     | 
| 
      
 80 
     | 
    
         
            +
                  end
         
     | 
| 
      
 81 
     | 
    
         
            +
             
     | 
| 
      
 82 
     | 
    
         
            +
                  def fetch_complex_items
         
     | 
| 
      
 83 
     | 
    
         
            +
                    @relation_items.complex_items.map(&:key).join(' AND ')
         
     | 
| 
      
 84 
     | 
    
         
            +
                  end
         
     | 
| 
      
 85 
     | 
    
         
            +
             
     | 
| 
      
 86 
     | 
    
         
            +
                  def fetch_equality_items_hash
         
     | 
| 
      
 87 
     | 
    
         
            +
                    values = {}
         
     | 
| 
      
 88 
     | 
    
         
            +
                    @relation_items.equality_items.each do |item|
         
     | 
| 
      
 89 
     | 
    
         
            +
                      if active_record_model.column_names.include?(item.key)
         
     | 
| 
      
 90 
     | 
    
         
            +
                        values[item.key] = item.values_for_key
         
     | 
| 
      
 91 
     | 
    
         
            +
                      else
         
     | 
| 
      
 92 
     | 
    
         
            +
                        @warnings << "Shit relation: #{@source_model}.#{item.key} does not exist"
         
     | 
| 
      
 93 
     | 
    
         
            +
                        next
         
     | 
| 
      
 94 
     | 
    
         
            +
                      end
         
     | 
| 
      
 95 
     | 
    
         
            +
                    end
         
     | 
| 
      
 96 
     | 
    
         
            +
             
     | 
| 
      
 97 
     | 
    
         
            +
                    values
         
     | 
| 
      
 98 
     | 
    
         
            +
                  end
         
     | 
| 
      
 99 
     | 
    
         
            +
             
     | 
| 
      
 100 
     | 
    
         
            +
                  def all_non_scoped_models
         
     | 
| 
      
 101 
     | 
    
         
            +
                    active_record_model.reflect_on_all_associations.select { |rr| rr.scope.nil? }.map do |rr|
         
     | 
| 
      
 102 
     | 
    
         
            +
                      rr.klass.to_s
         
     | 
| 
      
 103 
     | 
    
         
            +
                    rescue NameError, LoadError => e
         
     | 
| 
      
 104 
     | 
    
         
            +
                      @warnings << e
         
     | 
| 
      
 105 
     | 
    
         
            +
                      next
         
     | 
| 
      
 106 
     | 
    
         
            +
                    end.compact.uniq
         
     | 
| 
      
 107 
     | 
    
         
            +
                  end
         
     | 
| 
      
 108 
     | 
    
         
            +
             
     | 
| 
      
 109 
     | 
    
         
            +
                  def to_active_record_relation
         
     | 
| 
      
 110 
     | 
    
         
            +
                    return @active_record_relation if @active_record_relation
         
     | 
| 
      
 111 
     | 
    
         
            +
             
     | 
| 
      
 112 
     | 
    
         
            +
                    complex_values          = fetch_complex_items
         
     | 
| 
      
 113 
     | 
    
         
            +
                    equality_values         = fetch_equality_items_hash
         
     | 
| 
      
 114 
     | 
    
         
            +
                    @active_record_relation = active_record_model.where(equality_values)
         
     | 
| 
      
 115 
     | 
    
         
            +
                                                                 .where(complex_values)
         
     | 
| 
      
 116 
     | 
    
         
            +
                                                                 .limit(FuryDumper::Config.limit)
         
     | 
| 
      
 117 
     | 
    
         
            +
             
     | 
| 
      
 118 
     | 
    
         
            +
                    unless FuryDumper::Config.fast?
         
     | 
| 
      
 119 
     | 
    
         
            +
                      order_value = { primary_key => :desc }
         
     | 
| 
      
 120 
     | 
    
         
            +
                      @active_record_relation = @active_record_relation.order(order_value)
         
     | 
| 
      
 121 
     | 
    
         
            +
                    end
         
     | 
| 
      
 122 
     | 
    
         
            +
             
     | 
| 
      
 123 
     | 
    
         
            +
                    @active_record_relation
         
     | 
| 
      
 124 
     | 
    
         
            +
                  end
         
     | 
| 
      
 125 
     | 
    
         
            +
             
     | 
| 
      
 126 
     | 
    
         
            +
                  def next_iteration
         
     | 
| 
      
 127 
     | 
    
         
            +
                    @iteration + 1
         
     | 
| 
      
 128 
     | 
    
         
            +
                  end
         
     | 
| 
      
 129 
     | 
    
         
            +
                end
         
     | 
| 
      
 130 
     | 
    
         
            +
              end
         
     | 
| 
      
 131 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,34 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # frozen_string_literal: true
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            module FuryDumper
         
     | 
| 
      
 4 
     | 
    
         
            +
              module Dumpers
         
     | 
| 
      
 5 
     | 
    
         
            +
                class ModelQueue
         
     | 
| 
      
 6 
     | 
    
         
            +
                  def initialize
         
     | 
| 
      
 7 
     | 
    
         
            +
                    @queue = []
         
     | 
| 
      
 8 
     | 
    
         
            +
                  end
         
     | 
| 
      
 9 
     | 
    
         
            +
             
     | 
| 
      
 10 
     | 
    
         
            +
                  def add_element(model:, dump_state:)
         
     | 
| 
      
 11 
     | 
    
         
            +
                    raise ArgumentError, "Expected model as Dumpers::Model, got: #{model.class}" unless model.is_a?(Model)
         
     | 
| 
      
 12 
     | 
    
         
            +
             
     | 
| 
      
 13 
     | 
    
         
            +
                    unless dump_state.is_a?(DumpState)
         
     | 
| 
      
 14 
     | 
    
         
            +
                      raise ArgumentError,
         
     | 
| 
      
 15 
     | 
    
         
            +
                            "Expected dump_state as Dumpers::DumpState, got: #{dump_state.class}"
         
     | 
| 
      
 16 
     | 
    
         
            +
                    end
         
     | 
| 
      
 17 
     | 
    
         
            +
             
     | 
| 
      
 18 
     | 
    
         
            +
                    @queue << [model, dump_state]
         
     | 
| 
      
 19 
     | 
    
         
            +
                  end
         
     | 
| 
      
 20 
     | 
    
         
            +
             
     | 
| 
      
 21 
     | 
    
         
            +
                  def empty?
         
     | 
| 
      
 22 
     | 
    
         
            +
                    @queue.empty?
         
     | 
| 
      
 23 
     | 
    
         
            +
                  end
         
     | 
| 
      
 24 
     | 
    
         
            +
             
     | 
| 
      
 25 
     | 
    
         
            +
                  def fetch_element
         
     | 
| 
      
 26 
     | 
    
         
            +
                    @queue.delete_at(0)
         
     | 
| 
      
 27 
     | 
    
         
            +
                  end
         
     | 
| 
      
 28 
     | 
    
         
            +
             
     | 
| 
      
 29 
     | 
    
         
            +
                  def count
         
     | 
| 
      
 30 
     | 
    
         
            +
                    @queue.count
         
     | 
| 
      
 31 
     | 
    
         
            +
                  end
         
     | 
| 
      
 32 
     | 
    
         
            +
                end
         
     | 
| 
      
 33 
     | 
    
         
            +
              end
         
     | 
| 
      
 34 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,79 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # frozen_string_literal: true
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            module FuryDumper
         
     | 
| 
      
 4 
     | 
    
         
            +
              module Dumpers
         
     | 
| 
      
 5 
     | 
    
         
            +
                RelationItem = Struct.new(:key, :values_for_key, :complex, :additional) do
         
     | 
| 
      
 6 
     | 
    
         
            +
                  def initialize(key:, values_for_key:, complex: false, additional: false)
         
     | 
| 
      
 7 
     | 
    
         
            +
                    super(key, values_for_key, complex, additional)
         
     | 
| 
      
 8 
     | 
    
         
            +
                  end
         
     | 
| 
      
 9 
     | 
    
         
            +
             
     | 
| 
      
 10 
     | 
    
         
            +
                  def eql?(other)
         
     | 
| 
      
 11 
     | 
    
         
            +
                    key == other.key
         
     | 
| 
      
 12 
     | 
    
         
            +
                  end
         
     | 
| 
      
 13 
     | 
    
         
            +
             
     | 
| 
      
 14 
     | 
    
         
            +
                  def copy
         
     | 
| 
      
 15 
     | 
    
         
            +
                    self.class.new(key: key, values_for_key: values_for_key.dup, complex: complex, additional: additional)
         
     | 
| 
      
 16 
     | 
    
         
            +
                  end
         
     | 
| 
      
 17 
     | 
    
         
            +
                end
         
     | 
| 
      
 18 
     | 
    
         
            +
             
     | 
| 
      
 19 
     | 
    
         
            +
                class RelationItems
         
     | 
| 
      
 20 
     | 
    
         
            +
                  attr_accessor :items
         
     | 
| 
      
 21 
     | 
    
         
            +
             
     | 
| 
      
 22 
     | 
    
         
            +
                  def initialize(items: [])
         
     | 
| 
      
 23 
     | 
    
         
            +
                    raise ArgumentError unless items.is_a?(Array)
         
     | 
| 
      
 24 
     | 
    
         
            +
                    raise ArgumentError unless items.all? { |item| item.is_a?(RelationItem) }
         
     | 
| 
      
 25 
     | 
    
         
            +
             
     | 
| 
      
 26 
     | 
    
         
            +
                    @items = items
         
     | 
| 
      
 27 
     | 
    
         
            +
                  end
         
     | 
| 
      
 28 
     | 
    
         
            +
             
     | 
| 
      
 29 
     | 
    
         
            +
                  def self.new_with_key_value(item_key: 'id', item_values: [])
         
     | 
| 
      
 30 
     | 
    
         
            +
                    new(items: [RelationItem.new(key: item_key, values_for_key: item_values.compact)])
         
     | 
| 
      
 31 
     | 
    
         
            +
                  end
         
     | 
| 
      
 32 
     | 
    
         
            +
             
     | 
| 
      
 33 
     | 
    
         
            +
                  def self.new_with_items(items: [])
         
     | 
| 
      
 34 
     | 
    
         
            +
                    new(items: items)
         
     | 
| 
      
 35 
     | 
    
         
            +
                  end
         
     | 
| 
      
 36 
     | 
    
         
            +
             
     | 
| 
      
 37 
     | 
    
         
            +
                  def eql?(other)
         
     | 
| 
      
 38 
     | 
    
         
            +
                    raise ArgumentError unless other.is_a?(RelationItems)
         
     | 
| 
      
 39 
     | 
    
         
            +
             
     | 
| 
      
 40 
     | 
    
         
            +
                    other.items.reject(&:additional).all? do |other_item|
         
     | 
| 
      
 41 
     | 
    
         
            +
                      items.reject(&:additional).any? { |item| item.eql?(other_item) }
         
     | 
| 
      
 42 
     | 
    
         
            +
                    end
         
     | 
| 
      
 43 
     | 
    
         
            +
                  end
         
     | 
| 
      
 44 
     | 
    
         
            +
             
     | 
| 
      
 45 
     | 
    
         
            +
                  def equality_items
         
     | 
| 
      
 46 
     | 
    
         
            +
                    items.reject(&:complex)
         
     | 
| 
      
 47 
     | 
    
         
            +
                  end
         
     | 
| 
      
 48 
     | 
    
         
            +
             
     | 
| 
      
 49 
     | 
    
         
            +
                  def complex_items
         
     | 
| 
      
 50 
     | 
    
         
            +
                    items.select(&:complex)
         
     | 
| 
      
 51 
     | 
    
         
            +
                  end
         
     | 
| 
      
 52 
     | 
    
         
            +
             
     | 
| 
      
 53 
     | 
    
         
            +
                  def keys
         
     | 
| 
      
 54 
     | 
    
         
            +
                    items.map(&:key).sort
         
     | 
| 
      
 55 
     | 
    
         
            +
                  end
         
     | 
| 
      
 56 
     | 
    
         
            +
             
     | 
| 
      
 57 
     | 
    
         
            +
                  def values(key)
         
     | 
| 
      
 58 
     | 
    
         
            +
                    items.select { |item| item.key == key }.values_for_key
         
     | 
| 
      
 59 
     | 
    
         
            +
                  end
         
     | 
| 
      
 60 
     | 
    
         
            +
             
     | 
| 
      
 61 
     | 
    
         
            +
                  def copy
         
     | 
| 
      
 62 
     | 
    
         
            +
                    self.class.new(items: copy_items)
         
     | 
| 
      
 63 
     | 
    
         
            +
                  end
         
     | 
| 
      
 64 
     | 
    
         
            +
             
     | 
| 
      
 65 
     | 
    
         
            +
                  def copy_items
         
     | 
| 
      
 66 
     | 
    
         
            +
                    items.map(&:copy)
         
     | 
| 
      
 67 
     | 
    
         
            +
                  end
         
     | 
| 
      
 68 
     | 
    
         
            +
             
     | 
| 
      
 69 
     | 
    
         
            +
                  def copy_with_new_values(key, new_values)
         
     | 
| 
      
 70 
     | 
    
         
            +
                    new_items = copy_items
         
     | 
| 
      
 71 
     | 
    
         
            +
                    new_items.each do |item|
         
     | 
| 
      
 72 
     | 
    
         
            +
                      item.values_for_key = new_values.compact.dup if item.key == key
         
     | 
| 
      
 73 
     | 
    
         
            +
                    end
         
     | 
| 
      
 74 
     | 
    
         
            +
             
     | 
| 
      
 75 
     | 
    
         
            +
                    self.class.new_with_items(items: new_items)
         
     | 
| 
      
 76 
     | 
    
         
            +
                  end
         
     | 
| 
      
 77 
     | 
    
         
            +
                end
         
     | 
| 
      
 78 
     | 
    
         
            +
              end
         
     | 
| 
      
 79 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,17 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # frozen_string_literal: true
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            module FuryDumper
         
     | 
| 
      
 4 
     | 
    
         
            +
              class Encrypter
         
     | 
| 
      
 5 
     | 
    
         
            +
                KEY = "\xBE\nXx\xE2\xDB\x85\xBD\xE1j}qz?}\xB0j6\xA95\xBAy80\x95\xE6\xC1\x9D\x9F\x89\xA2t"
         
     | 
| 
      
 6 
     | 
    
         
            +
             
     | 
| 
      
 7 
     | 
    
         
            +
                def self.encrypt(msg)
         
     | 
| 
      
 8 
     | 
    
         
            +
                  crypt = ActiveSupport::MessageEncryptor.new(KEY)
         
     | 
| 
      
 9 
     | 
    
         
            +
                  crypt.encrypt_and_sign(msg)
         
     | 
| 
      
 10 
     | 
    
         
            +
                end
         
     | 
| 
      
 11 
     | 
    
         
            +
             
     | 
| 
      
 12 
     | 
    
         
            +
                def self.decrypt(encrypted_data)
         
     | 
| 
      
 13 
     | 
    
         
            +
                  crypt = ActiveSupport::MessageEncryptor.new(KEY)
         
     | 
| 
      
 14 
     | 
    
         
            +
                  crypt.decrypt_and_verify(encrypted_data)
         
     | 
| 
      
 15 
     | 
    
         
            +
                end
         
     | 
| 
      
 16 
     | 
    
         
            +
              end
         
     | 
| 
      
 17 
     | 
    
         
            +
            end
         
     | 
    
        data/lib/fury_dumper.rb
    ADDED
    
    | 
         @@ -0,0 +1,102 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # frozen_string_literal: true
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            require 'rails'
         
     | 
| 
      
 4 
     | 
    
         
            +
            require 'fury_dumper/version'
         
     | 
| 
      
 5 
     | 
    
         
            +
            require 'fury_dumper/config'
         
     | 
| 
      
 6 
     | 
    
         
            +
            require 'fury_dumper/engine'
         
     | 
| 
      
 7 
     | 
    
         
            +
            require 'fury_dumper/dumper'
         
     | 
| 
      
 8 
     | 
    
         
            +
            require 'fury_dumper/api'
         
     | 
| 
      
 9 
     | 
    
         
            +
            require 'fury_dumper/dumpers/relation_items'
         
     | 
| 
      
 10 
     | 
    
         
            +
            require 'fury_dumper/dumpers/dump_state'
         
     | 
| 
      
 11 
     | 
    
         
            +
            require 'fury_dumper/dumpers/model_queue'
         
     | 
| 
      
 12 
     | 
    
         
            +
            require 'fury_dumper/dumpers/model'
         
     | 
| 
      
 13 
     | 
    
         
            +
            require 'fury_dumper/encrypter'
         
     | 
| 
      
 14 
     | 
    
         
            +
            require 'httpclient'
         
     | 
| 
      
 15 
     | 
    
         
            +
            require 'highline/import'
         
     | 
| 
      
 16 
     | 
    
         
            +
             
     | 
| 
      
 17 
     | 
    
         
            +
            module FuryDumper
         
     | 
| 
      
 18 
     | 
    
         
            +
              class Error < StandardError
         
     | 
| 
      
 19 
     | 
    
         
            +
              end
         
     | 
| 
      
 20 
     | 
    
         
            +
             
     | 
| 
      
 21 
     | 
    
         
            +
              def self.configuration
         
     | 
| 
      
 22 
     | 
    
         
            +
                @configuration ||= Config.config
         
     | 
| 
      
 23 
     | 
    
         
            +
              end
         
     | 
| 
      
 24 
     | 
    
         
            +
             
     | 
| 
      
 25 
     | 
    
         
            +
              # Start dumping
         
     | 
| 
      
 26 
     | 
    
         
            +
              #
         
     | 
| 
      
 27 
     | 
    
         
            +
              # @param password[String]           - password for remote DB
         
     | 
| 
      
 28 
     | 
    
         
            +
              # @param host[String]               - host for remote DB
         
     | 
| 
      
 29 
     | 
    
         
            +
              # @param port[String]               - port for remote DB
         
     | 
| 
      
 30 
     | 
    
         
            +
              # @param user[String]               - username for remote DB
         
     | 
| 
      
 31 
     | 
    
         
            +
              # @param model_name[String]         - name of model for dump
         
     | 
| 
      
 32 
     | 
    
         
            +
              # @param field_name[String]         - field name for model
         
     | 
| 
      
 33 
     | 
    
         
            +
              # @param field_values[Array|Range]  - values of field_name
         
     | 
| 
      
 34 
     | 
    
         
            +
              # @param database[String]           - DB remote name
         
     | 
| 
      
 35 
     | 
    
         
            +
              # @param debug_mode[Symbol]         - debug mode (full - all msgs, short - part of msgs, none -  nothing)
         
     | 
| 
      
 36 
     | 
    
         
            +
              # @param ask[Boolean]               - ask user for confirm different schema of target & remote DB
         
     | 
| 
      
 37 
     | 
    
         
            +
              #
         
     | 
| 
      
 38 
     | 
    
         
            +
              # @example FuryDumper.dump( password:     '12345',
         
     | 
| 
      
 39 
     | 
    
         
            +
              #                             host:         'localhost',
         
     | 
| 
      
 40 
     | 
    
         
            +
              #                             port:         '5432',
         
     | 
| 
      
 41 
     | 
    
         
            +
              #                             user:         'username',
         
     | 
| 
      
 42 
     | 
    
         
            +
              #                             model_name:   'User',
         
     | 
| 
      
 43 
     | 
    
         
            +
              #                             field_name:   'admin_token',
         
     | 
| 
      
 44 
     | 
    
         
            +
              #                             field_values: ['99999999-8888-4444-1212-111111111111'],
         
     | 
| 
      
 45 
     | 
    
         
            +
              #                             database:     'staging',
         
     | 
| 
      
 46 
     | 
    
         
            +
              #                             debug_mode:   :short)
         
     | 
| 
      
 47 
     | 
    
         
            +
              def self.dump(password:,
         
     | 
| 
      
 48 
     | 
    
         
            +
                            host:,
         
     | 
| 
      
 49 
     | 
    
         
            +
                            port:,
         
     | 
| 
      
 50 
     | 
    
         
            +
                            user:,
         
     | 
| 
      
 51 
     | 
    
         
            +
                            field_values:, database:, model_name: 'Lead',
         
     | 
| 
      
 52 
     | 
    
         
            +
                            field_name: 'id',
         
     | 
| 
      
 53 
     | 
    
         
            +
                            debug_mode: :none,
         
     | 
| 
      
 54 
     | 
    
         
            +
                            ask: true)
         
     | 
| 
      
 55 
     | 
    
         
            +
             
     | 
| 
      
 56 
     | 
    
         
            +
                check_type(model_name, String, 'model name')
         
     | 
| 
      
 57 
     | 
    
         
            +
                check_type(field_name, String, 'field name')
         
     | 
| 
      
 58 
     | 
    
         
            +
                check_type(field_values, [Array, Range], 'field values')
         
     | 
| 
      
 59 
     | 
    
         
            +
             
     | 
| 
      
 60 
     | 
    
         
            +
                states = []
         
     | 
| 
      
 61 
     | 
    
         
            +
                field_values.to_a.in_groups_of(FuryDumper::Config.batch_size) do |batch|
         
     | 
| 
      
 62 
     | 
    
         
            +
                  relation_items = FuryDumper::Dumpers::RelationItems.new_with_key_value(item_key: field_name, item_values: batch)
         
     | 
| 
      
 63 
     | 
    
         
            +
             
     | 
| 
      
 64 
     | 
    
         
            +
                  sync = Dumper.new \
         
     | 
| 
      
 65 
     | 
    
         
            +
                    password: password,
         
     | 
| 
      
 66 
     | 
    
         
            +
                    host: host,
         
     | 
| 
      
 67 
     | 
    
         
            +
                    port: port,
         
     | 
| 
      
 68 
     | 
    
         
            +
                    user: user,
         
     | 
| 
      
 69 
     | 
    
         
            +
                    database: database,
         
     | 
| 
      
 70 
     | 
    
         
            +
                    model: FuryDumper::Dumpers::Model.new(source_model: model_name, relation_items: relation_items),
         
     | 
| 
      
 71 
     | 
    
         
            +
                    debug_mode: debug_mode
         
     | 
| 
      
 72 
     | 
    
         
            +
             
     | 
| 
      
 73 
     | 
    
         
            +
                  if ask && !sync.equal_schemas?
         
     | 
| 
      
 74 
     | 
    
         
            +
                    confirm = ask('Are you sure to continue? [Y/N] ') { |yn| yn.limit = 1, yn.validate = /[yn]/i }
         
     | 
| 
      
 75 
     | 
    
         
            +
                    ask     = false
         
     | 
| 
      
 76 
     | 
    
         
            +
                    return unless confirm.downcase == 'y' # rubocop:disable Lint/NonLocalExitFromIterator
         
     | 
| 
      
 77 
     | 
    
         
            +
                  end
         
     | 
| 
      
 78 
     | 
    
         
            +
             
     | 
| 
      
 79 
     | 
    
         
            +
                  sync.sync_models
         
     | 
| 
      
 80 
     | 
    
         
            +
                  states << sync.dump_state
         
     | 
| 
      
 81 
     | 
    
         
            +
                end
         
     | 
| 
      
 82 
     | 
    
         
            +
             
     | 
| 
      
 83 
     | 
    
         
            +
                states.each_with_index do |state, index|
         
     | 
| 
      
 84 
     | 
    
         
            +
                  p "Batch ##{index}:"
         
     | 
| 
      
 85 
     | 
    
         
            +
                  state.print_statistic
         
     | 
| 
      
 86 
     | 
    
         
            +
                end
         
     | 
| 
      
 87 
     | 
    
         
            +
                true
         
     | 
| 
      
 88 
     | 
    
         
            +
              end
         
     | 
| 
      
 89 
     | 
    
         
            +
             
     | 
| 
      
 90 
     | 
    
         
            +
              def self.check_type(field, expected_type, field_name)
         
     | 
| 
      
 91 
     | 
    
         
            +
                is_ok     = if expected_type.is_a?(Array)
         
     | 
| 
      
 92 
     | 
    
         
            +
                              expected_type.any? do |type|
         
     | 
| 
      
 93 
     | 
    
         
            +
                                field.is_a?(type)
         
     | 
| 
      
 94 
     | 
    
         
            +
                              end
         
     | 
| 
      
 95 
     | 
    
         
            +
                            else
         
     | 
| 
      
 96 
     | 
    
         
            +
                              field.is_a?(expected_type)
         
     | 
| 
      
 97 
     | 
    
         
            +
                            end
         
     | 
| 
      
 98 
     | 
    
         
            +
                types_str = expected_type.is_a?(Array) ? expected_type.join(' or ') : expected_type
         
     | 
| 
      
 99 
     | 
    
         
            +
             
     | 
| 
      
 100 
     | 
    
         
            +
                raise ArgumentError, "Expected #{field_name} as #{types_str}, got: #{field.class}" unless is_ok
         
     | 
| 
      
 101 
     | 
    
         
            +
              end
         
     | 
| 
      
 102 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,21 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # frozen_string_literal: true
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            module FuryDumper
         
     | 
| 
      
 4 
     | 
    
         
            +
              module Generators
         
     | 
| 
      
 5 
     | 
    
         
            +
                class ConfigGenerator < Rails::Generators::Base
         
     | 
| 
      
 6 
     | 
    
         
            +
                  def self.gem_root
         
     | 
| 
      
 7 
     | 
    
         
            +
                    File.expand_path('../../..', __dir__)
         
     | 
| 
      
 8 
     | 
    
         
            +
                  end
         
     | 
| 
      
 9 
     | 
    
         
            +
             
     | 
| 
      
 10 
     | 
    
         
            +
                  def self.source_root
         
     | 
| 
      
 11 
     | 
    
         
            +
                    # Use the templates from the 2.3.x generator
         
     | 
| 
      
 12 
     | 
    
         
            +
                    File.join(gem_root, 'rails_generators', 'fury_dumper_config', 'templates')
         
     | 
| 
      
 13 
     | 
    
         
            +
                  end
         
     | 
| 
      
 14 
     | 
    
         
            +
             
     | 
| 
      
 15 
     | 
    
         
            +
                  def generate
         
     | 
| 
      
 16 
     | 
    
         
            +
                    template 'fury_dumper.rb', File.join('config', 'initializers', 'fury_dumper.rb')
         
     | 
| 
      
 17 
     | 
    
         
            +
                    template 'fury_dumper.yml', File.join('config', 'fury_dumper.yml')
         
     | 
| 
      
 18 
     | 
    
         
            +
                  end
         
     | 
| 
      
 19 
     | 
    
         
            +
                end
         
     | 
| 
      
 20 
     | 
    
         
            +
              end
         
     | 
| 
      
 21 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            FuryDumper::Config.load("#{Rails.root}/config/fury_dumper.yml")
         
     | 
| 
         @@ -0,0 +1,44 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            exclude_relations: <class_name>.<relation_name>, <class_name>.<relation_name>
         
     | 
| 
      
 2 
     | 
    
         
            +
            batch_size: 100
         
     | 
| 
      
 3 
     | 
    
         
            +
            ratio_records_batches: 10
         
     | 
| 
      
 4 
     | 
    
         
            +
            fast: true
         
     | 
| 
      
 5 
     | 
    
         
            +
            mode: wide
         
     | 
| 
      
 6 
     | 
    
         
            +
            relative_services:
         
     | 
| 
      
 7 
     | 
    
         
            +
              <service_name>:
         
     | 
| 
      
 8 
     | 
    
         
            +
                database: <database_name>
         
     | 
| 
      
 9 
     | 
    
         
            +
                host: <host>
         
     | 
| 
      
 10 
     | 
    
         
            +
                port: <port>
         
     | 
| 
      
 11 
     | 
    
         
            +
                user: <user>
         
     | 
| 
      
 12 
     | 
    
         
            +
                password: <password>
         
     | 
| 
      
 13 
     | 
    
         
            +
                tables:
         
     | 
| 
      
 14 
     | 
    
         
            +
                  <self_table_name>:
         
     | 
| 
      
 15 
     | 
    
         
            +
                    <remote_table_name>:
         
     | 
| 
      
 16 
     | 
    
         
            +
                      self_field_name: <self_field_name>
         
     | 
| 
      
 17 
     | 
    
         
            +
                      ms_model_name: <ms_model_name>
         
     | 
| 
      
 18 
     | 
    
         
            +
                      ms_field_name: <ms_field_name>
         
     | 
| 
      
 19 
     | 
    
         
            +
                    <other_remote_table_name>:
         
     | 
| 
      
 20 
     | 
    
         
            +
                      self_field_name: <self_field_name>
         
     | 
| 
      
 21 
     | 
    
         
            +
                      ms_model_name: <ms_model_name>
         
     | 
| 
      
 22 
     | 
    
         
            +
                      ms_field_name: <ms_field_name>
         
     | 
| 
      
 23 
     | 
    
         
            +
                  <other_self_table_name>:
         
     | 
| 
      
 24 
     | 
    
         
            +
                    <remote_table_name>:
         
     | 
| 
      
 25 
     | 
    
         
            +
                      self_field_name: <self_field_name>
         
     | 
| 
      
 26 
     | 
    
         
            +
                      ms_model_name: <ms_model_name>
         
     | 
| 
      
 27 
     | 
    
         
            +
                      ms_field_name: <ms_field_name>
         
     | 
| 
      
 28 
     | 
    
         
            +
                    <other_remote_table_name>:
         
     | 
| 
      
 29 
     | 
    
         
            +
                      self_field_name: <self_field_name>
         
     | 
| 
      
 30 
     | 
    
         
            +
                      ms_model_name: <ms_model_name>
         
     | 
| 
      
 31 
     | 
    
         
            +
                      ms_field_name: <ms_field_name>
         
     | 
| 
      
 32 
     | 
    
         
            +
              <other_service_name>:
         
     | 
| 
      
 33 
     | 
    
         
            +
                database: <database_name>
         
     | 
| 
      
 34 
     | 
    
         
            +
                host: <host>
         
     | 
| 
      
 35 
     | 
    
         
            +
                port: <port>
         
     | 
| 
      
 36 
     | 
    
         
            +
                user: <user>
         
     | 
| 
      
 37 
     | 
    
         
            +
                password: <password>
         
     | 
| 
      
 38 
     | 
    
         
            +
                tables:
         
     | 
| 
      
 39 
     | 
    
         
            +
                  <self_table_name>:
         
     | 
| 
      
 40 
     | 
    
         
            +
                    <remote_table_name>:
         
     | 
| 
      
 41 
     | 
    
         
            +
                      self_field_name: <self_field_name>
         
     | 
| 
      
 42 
     | 
    
         
            +
                      ms_model_name: <ms_model_name>
         
     | 
| 
      
 43 
     | 
    
         
            +
                      ms_field_name: <ms_field_name>
         
     | 
| 
      
 44 
     | 
    
         
            +
             
     | 
    
        metadata
    ADDED
    
    | 
         @@ -0,0 +1,181 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            --- !ruby/object:Gem::Specification
         
     | 
| 
      
 2 
     | 
    
         
            +
            name: fury_dumper
         
     | 
| 
      
 3 
     | 
    
         
            +
            version: !ruby/object:Gem::Version
         
     | 
| 
      
 4 
     | 
    
         
            +
              version: 0.1.0
         
     | 
| 
      
 5 
     | 
    
         
            +
            platform: ruby
         
     | 
| 
      
 6 
     | 
    
         
            +
            authors:
         
     | 
| 
      
 7 
     | 
    
         
            +
            - Nastya Patutina
         
     | 
| 
      
 8 
     | 
    
         
            +
            autorequire:
         
     | 
| 
      
 9 
     | 
    
         
            +
            bindir: exe
         
     | 
| 
      
 10 
     | 
    
         
            +
            cert_chain: []
         
     | 
| 
      
 11 
     | 
    
         
            +
            date: 2023-03-19 00:00:00.000000000 Z
         
     | 
| 
      
 12 
     | 
    
         
            +
            dependencies:
         
     | 
| 
      
 13 
     | 
    
         
            +
            - !ruby/object:Gem::Dependency
         
     | 
| 
      
 14 
     | 
    
         
            +
              name: bundler
         
     | 
| 
      
 15 
     | 
    
         
            +
              requirement: !ruby/object:Gem::Requirement
         
     | 
| 
      
 16 
     | 
    
         
            +
                requirements:
         
     | 
| 
      
 17 
     | 
    
         
            +
                - - "~>"
         
     | 
| 
      
 18 
     | 
    
         
            +
                  - !ruby/object:Gem::Version
         
     | 
| 
      
 19 
     | 
    
         
            +
                    version: '2.0'
         
     | 
| 
      
 20 
     | 
    
         
            +
              type: :development
         
     | 
| 
      
 21 
     | 
    
         
            +
              prerelease: false
         
     | 
| 
      
 22 
     | 
    
         
            +
              version_requirements: !ruby/object:Gem::Requirement
         
     | 
| 
      
 23 
     | 
    
         
            +
                requirements:
         
     | 
| 
      
 24 
     | 
    
         
            +
                - - "~>"
         
     | 
| 
      
 25 
     | 
    
         
            +
                  - !ruby/object:Gem::Version
         
     | 
| 
      
 26 
     | 
    
         
            +
                    version: '2.0'
         
     | 
| 
      
 27 
     | 
    
         
            +
            - !ruby/object:Gem::Dependency
         
     | 
| 
      
 28 
     | 
    
         
            +
              name: rake
         
     | 
| 
      
 29 
     | 
    
         
            +
              requirement: !ruby/object:Gem::Requirement
         
     | 
| 
      
 30 
     | 
    
         
            +
                requirements:
         
     | 
| 
      
 31 
     | 
    
         
            +
                - - "~>"
         
     | 
| 
      
 32 
     | 
    
         
            +
                  - !ruby/object:Gem::Version
         
     | 
| 
      
 33 
     | 
    
         
            +
                    version: '10.0'
         
     | 
| 
      
 34 
     | 
    
         
            +
              type: :development
         
     | 
| 
      
 35 
     | 
    
         
            +
              prerelease: false
         
     | 
| 
      
 36 
     | 
    
         
            +
              version_requirements: !ruby/object:Gem::Requirement
         
     | 
| 
      
 37 
     | 
    
         
            +
                requirements:
         
     | 
| 
      
 38 
     | 
    
         
            +
                - - "~>"
         
     | 
| 
      
 39 
     | 
    
         
            +
                  - !ruby/object:Gem::Version
         
     | 
| 
      
 40 
     | 
    
         
            +
                    version: '10.0'
         
     | 
| 
      
 41 
     | 
    
         
            +
            - !ruby/object:Gem::Dependency
         
     | 
| 
      
 42 
     | 
    
         
            +
              name: rspec
         
     | 
| 
      
 43 
     | 
    
         
            +
              requirement: !ruby/object:Gem::Requirement
         
     | 
| 
      
 44 
     | 
    
         
            +
                requirements:
         
     | 
| 
      
 45 
     | 
    
         
            +
                - - "~>"
         
     | 
| 
      
 46 
     | 
    
         
            +
                  - !ruby/object:Gem::Version
         
     | 
| 
      
 47 
     | 
    
         
            +
                    version: '3.0'
         
     | 
| 
      
 48 
     | 
    
         
            +
              type: :development
         
     | 
| 
      
 49 
     | 
    
         
            +
              prerelease: false
         
     | 
| 
      
 50 
     | 
    
         
            +
              version_requirements: !ruby/object:Gem::Requirement
         
     | 
| 
      
 51 
     | 
    
         
            +
                requirements:
         
     | 
| 
      
 52 
     | 
    
         
            +
                - - "~>"
         
     | 
| 
      
 53 
     | 
    
         
            +
                  - !ruby/object:Gem::Version
         
     | 
| 
      
 54 
     | 
    
         
            +
                    version: '3.0'
         
     | 
| 
      
 55 
     | 
    
         
            +
            - !ruby/object:Gem::Dependency
         
     | 
| 
      
 56 
     | 
    
         
            +
              name: highline
         
     | 
| 
      
 57 
     | 
    
         
            +
              requirement: !ruby/object:Gem::Requirement
         
     | 
| 
      
 58 
     | 
    
         
            +
                requirements:
         
     | 
| 
      
 59 
     | 
    
         
            +
                - - "~>"
         
     | 
| 
      
 60 
     | 
    
         
            +
                  - !ruby/object:Gem::Version
         
     | 
| 
      
 61 
     | 
    
         
            +
                    version: '1.6'
         
     | 
| 
      
 62 
     | 
    
         
            +
              type: :runtime
         
     | 
| 
      
 63 
     | 
    
         
            +
              prerelease: false
         
     | 
| 
      
 64 
     | 
    
         
            +
              version_requirements: !ruby/object:Gem::Requirement
         
     | 
| 
      
 65 
     | 
    
         
            +
                requirements:
         
     | 
| 
      
 66 
     | 
    
         
            +
                - - "~>"
         
     | 
| 
      
 67 
     | 
    
         
            +
                  - !ruby/object:Gem::Version
         
     | 
| 
      
 68 
     | 
    
         
            +
                    version: '1.6'
         
     | 
| 
      
 69 
     | 
    
         
            +
            - !ruby/object:Gem::Dependency
         
     | 
| 
      
 70 
     | 
    
         
            +
              name: httpclient
         
     | 
| 
      
 71 
     | 
    
         
            +
              requirement: !ruby/object:Gem::Requirement
         
     | 
| 
      
 72 
     | 
    
         
            +
                requirements:
         
     | 
| 
      
 73 
     | 
    
         
            +
                - - "~>"
         
     | 
| 
      
 74 
     | 
    
         
            +
                  - !ruby/object:Gem::Version
         
     | 
| 
      
 75 
     | 
    
         
            +
                    version: '2.8'
         
     | 
| 
      
 76 
     | 
    
         
            +
              type: :runtime
         
     | 
| 
      
 77 
     | 
    
         
            +
              prerelease: false
         
     | 
| 
      
 78 
     | 
    
         
            +
              version_requirements: !ruby/object:Gem::Requirement
         
     | 
| 
      
 79 
     | 
    
         
            +
                requirements:
         
     | 
| 
      
 80 
     | 
    
         
            +
                - - "~>"
         
     | 
| 
      
 81 
     | 
    
         
            +
                  - !ruby/object:Gem::Version
         
     | 
| 
      
 82 
     | 
    
         
            +
                    version: '2.8'
         
     | 
| 
      
 83 
     | 
    
         
            +
            - !ruby/object:Gem::Dependency
         
     | 
| 
      
 84 
     | 
    
         
            +
              name: pg
         
     | 
| 
      
 85 
     | 
    
         
            +
              requirement: !ruby/object:Gem::Requirement
         
     | 
| 
      
 86 
     | 
    
         
            +
                requirements:
         
     | 
| 
      
 87 
     | 
    
         
            +
                - - "~>"
         
     | 
| 
      
 88 
     | 
    
         
            +
                  - !ruby/object:Gem::Version
         
     | 
| 
      
 89 
     | 
    
         
            +
                    version: '1.4'
         
     | 
| 
      
 90 
     | 
    
         
            +
              type: :runtime
         
     | 
| 
      
 91 
     | 
    
         
            +
              prerelease: false
         
     | 
| 
      
 92 
     | 
    
         
            +
              version_requirements: !ruby/object:Gem::Requirement
         
     | 
| 
      
 93 
     | 
    
         
            +
                requirements:
         
     | 
| 
      
 94 
     | 
    
         
            +
                - - "~>"
         
     | 
| 
      
 95 
     | 
    
         
            +
                  - !ruby/object:Gem::Version
         
     | 
| 
      
 96 
     | 
    
         
            +
                    version: '1.4'
         
     | 
| 
      
 97 
     | 
    
         
            +
            - !ruby/object:Gem::Dependency
         
     | 
| 
      
 98 
     | 
    
         
            +
              name: rails
         
     | 
| 
      
 99 
     | 
    
         
            +
              requirement: !ruby/object:Gem::Requirement
         
     | 
| 
      
 100 
     | 
    
         
            +
                requirements:
         
     | 
| 
      
 101 
     | 
    
         
            +
                - - "~>"
         
     | 
| 
      
 102 
     | 
    
         
            +
                  - !ruby/object:Gem::Version
         
     | 
| 
      
 103 
     | 
    
         
            +
                    version: '5.0'
         
     | 
| 
      
 104 
     | 
    
         
            +
                - - ">="
         
     | 
| 
      
 105 
     | 
    
         
            +
                  - !ruby/object:Gem::Version
         
     | 
| 
      
 106 
     | 
    
         
            +
                    version: 4.0.13
         
     | 
| 
      
 107 
     | 
    
         
            +
              type: :runtime
         
     | 
| 
      
 108 
     | 
    
         
            +
              prerelease: false
         
     | 
| 
      
 109 
     | 
    
         
            +
              version_requirements: !ruby/object:Gem::Requirement
         
     | 
| 
      
 110 
     | 
    
         
            +
                requirements:
         
     | 
| 
      
 111 
     | 
    
         
            +
                - - "~>"
         
     | 
| 
      
 112 
     | 
    
         
            +
                  - !ruby/object:Gem::Version
         
     | 
| 
      
 113 
     | 
    
         
            +
                    version: '5.0'
         
     | 
| 
      
 114 
     | 
    
         
            +
                - - ">="
         
     | 
| 
      
 115 
     | 
    
         
            +
                  - !ruby/object:Gem::Version
         
     | 
| 
      
 116 
     | 
    
         
            +
                    version: 4.0.13
         
     | 
| 
      
 117 
     | 
    
         
            +
            description: Dump from remote DB by lead_ids interval
         
     | 
| 
      
 118 
     | 
    
         
            +
            email:
         
     | 
| 
      
 119 
     | 
    
         
            +
            - npatutina@gmail.con
         
     | 
| 
      
 120 
     | 
    
         
            +
            executables: []
         
     | 
| 
      
 121 
     | 
    
         
            +
            extensions: []
         
     | 
| 
      
 122 
     | 
    
         
            +
            extra_rdoc_files: []
         
     | 
| 
      
 123 
     | 
    
         
            +
            files:
         
     | 
| 
      
 124 
     | 
    
         
            +
            - ".github/workflows/build.yaml"
         
     | 
| 
      
 125 
     | 
    
         
            +
            - ".gitignore"
         
     | 
| 
      
 126 
     | 
    
         
            +
            - ".rspec"
         
     | 
| 
      
 127 
     | 
    
         
            +
            - ".rubocop.yml"
         
     | 
| 
      
 128 
     | 
    
         
            +
            - ".ruby-version"
         
     | 
| 
      
 129 
     | 
    
         
            +
            - ".travis.yml"
         
     | 
| 
      
 130 
     | 
    
         
            +
            - Breadth-first.png
         
     | 
| 
      
 131 
     | 
    
         
            +
            - CODE_OF_CONDUCT.md
         
     | 
| 
      
 132 
     | 
    
         
            +
            - Depth-first.png
         
     | 
| 
      
 133 
     | 
    
         
            +
            - Gemfile
         
     | 
| 
      
 134 
     | 
    
         
            +
            - Gemfile.lock
         
     | 
| 
      
 135 
     | 
    
         
            +
            - README.md
         
     | 
| 
      
 136 
     | 
    
         
            +
            - README.ru.md
         
     | 
| 
      
 137 
     | 
    
         
            +
            - Rakefile
         
     | 
| 
      
 138 
     | 
    
         
            +
            - app/controllers/fury_dumper/dump_process_controller.rb
         
     | 
| 
      
 139 
     | 
    
         
            +
            - config/routes.rb
         
     | 
| 
      
 140 
     | 
    
         
            +
            - fury_dumper.gemspec
         
     | 
| 
      
 141 
     | 
    
         
            +
            - lib/fury_dumper.rb
         
     | 
| 
      
 142 
     | 
    
         
            +
            - lib/fury_dumper/api.rb
         
     | 
| 
      
 143 
     | 
    
         
            +
            - lib/fury_dumper/config.rb
         
     | 
| 
      
 144 
     | 
    
         
            +
            - lib/fury_dumper/dumper.rb
         
     | 
| 
      
 145 
     | 
    
         
            +
            - lib/fury_dumper/dumpers/dump_state.rb
         
     | 
| 
      
 146 
     | 
    
         
            +
            - lib/fury_dumper/dumpers/model.rb
         
     | 
| 
      
 147 
     | 
    
         
            +
            - lib/fury_dumper/dumpers/model_queue.rb
         
     | 
| 
      
 148 
     | 
    
         
            +
            - lib/fury_dumper/dumpers/relation_items.rb
         
     | 
| 
      
 149 
     | 
    
         
            +
            - lib/fury_dumper/encrypter.rb
         
     | 
| 
      
 150 
     | 
    
         
            +
            - lib/fury_dumper/engine.rb
         
     | 
| 
      
 151 
     | 
    
         
            +
            - lib/fury_dumper/version.rb
         
     | 
| 
      
 152 
     | 
    
         
            +
            - lib/generators/fury_dumper/config_generator.rb
         
     | 
| 
      
 153 
     | 
    
         
            +
            - rails_generators/fury_dumper_config/fury_dumper_config_generator.rb
         
     | 
| 
      
 154 
     | 
    
         
            +
            - rails_generators/fury_dumper_config/templates/fury_dumper.rb
         
     | 
| 
      
 155 
     | 
    
         
            +
            - rails_generators/fury_dumper_config/templates/fury_dumper.yml
         
     | 
| 
      
 156 
     | 
    
         
            +
            homepage: https://github.com/NastyaPatutina/fury_dumper
         
     | 
| 
      
 157 
     | 
    
         
            +
            licenses: []
         
     | 
| 
      
 158 
     | 
    
         
            +
            metadata:
         
     | 
| 
      
 159 
     | 
    
         
            +
              homepage_uri: https://github.com/NastyaPatutina/fury_dumper
         
     | 
| 
      
 160 
     | 
    
         
            +
              source_code_uri: https://github.com/NastyaPatutina/fury_dumper
         
     | 
| 
      
 161 
     | 
    
         
            +
              rubygems_mfa_required: 'true'
         
     | 
| 
      
 162 
     | 
    
         
            +
            post_install_message:
         
     | 
| 
      
 163 
     | 
    
         
            +
            rdoc_options: []
         
     | 
| 
      
 164 
     | 
    
         
            +
            require_paths:
         
     | 
| 
      
 165 
     | 
    
         
            +
            - lib
         
     | 
| 
      
 166 
     | 
    
         
            +
            required_ruby_version: !ruby/object:Gem::Requirement
         
     | 
| 
      
 167 
     | 
    
         
            +
              requirements:
         
     | 
| 
      
 168 
     | 
    
         
            +
              - - ">="
         
     | 
| 
      
 169 
     | 
    
         
            +
                - !ruby/object:Gem::Version
         
     | 
| 
      
 170 
     | 
    
         
            +
                  version: 2.3.0
         
     | 
| 
      
 171 
     | 
    
         
            +
            required_rubygems_version: !ruby/object:Gem::Requirement
         
     | 
| 
      
 172 
     | 
    
         
            +
              requirements:
         
     | 
| 
      
 173 
     | 
    
         
            +
              - - ">="
         
     | 
| 
      
 174 
     | 
    
         
            +
                - !ruby/object:Gem::Version
         
     | 
| 
      
 175 
     | 
    
         
            +
                  version: '0'
         
     | 
| 
      
 176 
     | 
    
         
            +
            requirements: []
         
     | 
| 
      
 177 
     | 
    
         
            +
            rubygems_version: 3.1.2
         
     | 
| 
      
 178 
     | 
    
         
            +
            signing_key:
         
     | 
| 
      
 179 
     | 
    
         
            +
            specification_version: 4
         
     | 
| 
      
 180 
     | 
    
         
            +
            summary: Simple dump for main service and other microservices
         
     | 
| 
      
 181 
     | 
    
         
            +
            test_files: []
         
     |