Class: RailsArchiver::Unarchiver

Inherits:
Object
  • Object
show all
Defined in:
lib/rails-archiver/unarchiver.rb

Defined Under Namespace

Classes: ImportError

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(model, options = {}) ⇒ Unarchiver



20
21
22
23
24
25
26
27
# File 'lib/rails-archiver/unarchiver.rb', line 20

def initialize(model, options={})
  @model = model
  @logger = options.delete(:logger) || Logger.new(STDOUT)
  @options = options
  # Transport for downloading
  self.transport = _get_transport(options.delete(:transport) || :in_memory)
  self.errors = []
end

Instance Attribute Details

#errorsObject

Returns the value of attribute errors.



11
12
13
# File 'lib/rails-archiver/unarchiver.rb', line 11

def errors
  @errors
end

#transportObject

Returns the value of attribute transport.



11
12
13
# File 'lib/rails-archiver/unarchiver.rb', line 11

def transport
  @transport
end

Instance Method Details

#import_objects(klass, models) ⇒ Object

Import saved objects.



66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
# File 'lib/rails-archiver/unarchiver.rb', line 66

def import_objects(klass, models)
  cols_to_update = klass.column_names - [klass.primary_key]
  # check other unique indexes
  indexes = ActiveRecord::Base.connection.indexes(klass.table_name).
    select(&:unique)
  indexes.each { |index| cols_to_update -= index.columns }
  options = { :validate => false, :timestamps => false,
              :on_duplicate_key_update => cols_to_update }

  @logger.info("Importing #{models.length} for #{klass.name}")
  models.in_groups_of(1000).each do |group|
    klass.import(group.compact, options)
  end
rescue => e
  self.errors << "Error importing class #{klass.name}: #{e.message}"
end

#init_model(klass, hash) ⇒ Object



83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
# File 'lib/rails-archiver/unarchiver.rb', line 83

def init_model(klass, hash)
  attrs = hash.select do |x|
    klass.column_names.include?(x) && x != klass.primary_key
  end

  # fix time zone issues
  klass.columns.each do |col|
    if col.type == :datetime && attrs[col.name]
      attrs[col.name] = Time.zone.parse(attrs[col.name])
    end
  end

  model = klass.where(klass.primary_key => hash[klass.primary_key]).first
  if model.nil?
    model = klass.new
    model.send(:attributes=, attrs, false)
    # can't set this in the attribute hash, it'll be overridden. Need
    # to set it manually.
    model[klass.primary_key] = hash[klass.primary_key]
  else
    model.send(:attributes=, attrs, false)
  end

  model
end

#load_classes(hash) ⇒ Object

Load a list of general classes that were saved as JSON.



45
46
47
48
49
50
51
52
53
# File 'lib/rails-archiver/unarchiver.rb', line 45

def load_classes(hash)
  full_hash = hash.with_indifferent_access
  full_hash.each do |key, vals|
    save_models(key.constantize, vals)
  end
  if @options[:crash_on_errors] && self.errors.any?
    raise ImportError.new("Errors occurred during load - please see 'errors' method for more details")
  end
end

#save_models(klass, hashes) ⇒ Object

Save all models into memory in the given hash on the given class.



58
59
60
61
# File 'lib/rails-archiver/unarchiver.rb', line 58

def save_models(klass, hashes)
  models = hashes.map { |hash| init_model(klass, hash) }
  import_objects(klass, models)
end

#unarchiveObject

Unarchive a model.



30
31
32
33
34
35
36
37
38
39
40
41
# File 'lib/rails-archiver/unarchiver.rb', line 30

def unarchive
  @errors = []
  @logger.info('Downloading JSON file')
  hash = @transport.retrieve_archive
  @logger.info("Loading #{@model.class.name}")
  load_classes(hash)
  @model.reload
  if @model.attribute_names.include?('archived')
    @model.update_attribute(:archived, false)
  end
  @logger.info("#{@model.class.name} load complete!")
end