Class: RailsArchiver::Archiver

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

Defined Under Namespace

Classes: IDHash

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

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

Create a new Archiver with the given model.

Parameters:

  • model (ActiveRecord::Base)

    the model to archive or unarchive.

  • options (Hash) (defaults to: {})
    • logger [Logger]

    • transport [Sybmol] :in_memory or :s3 right now

    • delete_records [Boolean] whether or not we should delete existing records



27
28
29
30
31
32
33
34
35
# File 'lib/rails-archiver/archiver.rb', line 27

def initialize(model, options={})
  @model = model
  @logger = options.delete(:logger) || ::Logger.new(STDOUT)
  @hash = {}
  self.transport = _get_transport(options.delete(:transport) || :in_memory)
  @options = options
  # hash of table name -> IDs to delete in that table
  @ids_to_delete = {}
end

Instance Attribute Details

#transportObject

Returns the value of attribute transport.



18
19
20
# File 'lib/rails-archiver/archiver.rb', line 18

def transport
  @transport
end

Instance Method Details

#archiveHash

Archive a model.

Returns:

  • (Hash)

    the hash that was archived.



39
40
41
42
43
44
45
46
47
48
49
50
51
52
# File 'lib/rails-archiver/archiver.rb', line 39

def archive
  @logger.info("Starting archive of #{@model.class.name} #{@model.id}")
  @hash = {}
  _visit_association(@model)
  @logger.info('Completed loading data')
  @transport.store_archive(@hash)
  if @model.attribute_names.include?('archived')
    @model.update_attribute(:archived, true)
  end
  @logger.info('Deleting rows')
  _delete_records if @options[:delete_records]
  @logger.info('All records deleted')
  @hash
end

#delete_from_table(table, ids) ⇒ Object

Delete rows from a table. Can be used in #delete_records.

Parameters:

  • table (String)

    the table name.

  • ids (Array<Integer>)

    the IDs to delete.



80
81
82
83
84
85
86
87
88
89
90
91
92
93
# File 'lib/rails-archiver/archiver.rb', line 80

def delete_from_table(table, ids)
  return if ids.blank?
  @logger.info("Deleting #{ids.size} records from #{table}")
  groups = ids.to_a.in_groups_of(10000)
  groups.each_with_index do |group, i|
    sleep(0.5) if i > 0 # throttle so we don't kill the DB
    delete_query = "      DELETE FROM `\#{table}` WHERE `id` IN (\#{group.compact.join(',')})\n    SQL\n    ActiveRecord::Base.connection.delete(delete_query)\n  end\n\n  @logger.info(\"Finished deleting from \#{table}\")\nend\n"

#visit(node) ⇒ Hash

Returns a single object in the database represented as a hash. Does not account for any associations, only prints out the columns associated with the object as they relate to the current schema. Can be extended but should not be overridden or called explicitly.

Parameters:

  • node (ActiveRecord::Base)

    an object that inherits from AR::Base

Returns:

  • (Hash)


60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
# File 'lib/rails-archiver/archiver.rb', line 60

def visit(node)
  return {} unless node.class.respond_to?(:column_names)
   if @options[:delete_records] && node != @model
    @ids_to_delete[node.class.table_name] ||= Set.new
    @ids_to_delete[node.class.table_name] << node.id
  end
  IDHash[
    node.class.column_names.select do |cn|
      next unless node.respond_to?(cn)
      # Only export columns that we actually have data for
      !node[cn].nil?
    end.map do |cn|
      [cn.to_sym, node[cn]]
    end
  ]
end