Class: RailsArchiver::Archiver
- Inherits:
-
Object
- Object
- RailsArchiver::Archiver
- Defined in:
- lib/rails-archiver/archiver.rb
Defined Under Namespace
Classes: IDHash
Instance Attribute Summary collapse
-
#archive_location ⇒ Object
Returns the value of attribute archive_location.
-
#transport ⇒ Object
Returns the value of attribute transport.
Instance Method Summary collapse
-
#archive ⇒ Hash
Archive a model.
-
#delete_from_table(table, ids) ⇒ Object
Delete rows from a table.
-
#initialize(model, options = {}) ⇒ Archiver
constructor
Create a new Archiver with the given model.
-
#save_additional_data ⇒ Object
Use this method to add more data into the archive hash which isn’t directly accessible from the parent model.
- #unarchiver ⇒ RailsArchiver::Unarchiver
-
#visit(node) ⇒ Hash
Returns a single object in the database represented as a hash.
-
#visit_nodes(node) ⇒ Object
Used to visit an association, and recursively calls down to all child objects through all other allowed associations.
Constructor Details
#initialize(model, options = {}) ⇒ Archiver
Create a new Archiver with the given model.
27 28 29 30 31 32 33 34 35 |
# File 'lib/rails-archiver/archiver.rb', line 27 def initialize(model, ={}) @model = model @logger = .delete(:logger) || ::Logger.new(STDOUT) @hash = {} self.transport = _get_transport(.delete(:transport) || :in_memory) @options = # hash of table name -> IDs to delete in that table @ids_to_delete = {} end |
Instance Attribute Details
#archive_location ⇒ Object
Returns the value of attribute archive_location.
18 19 20 |
# File 'lib/rails-archiver/archiver.rb', line 18 def archive_location @archive_location end |
#transport ⇒ Object
Returns the value of attribute transport.
18 19 20 |
# File 'lib/rails-archiver/archiver.rb', line 18 def transport @transport end |
Instance Method Details
#archive ⇒ Hash
Archive a model.
39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 |
# File 'lib/rails-archiver/archiver.rb', line 39 def archive @logger.info("Starting archive of #{@model.class.name} #{@model.id}") @hash = {} visit_nodes(@model) save_additional_data @logger.info('Completed loading data') @archive_location = @transport.store_archive(@hash) if @model.attribute_names.include?('archived') @model.update_attribute(:archived, true) end if @options[:delete_records] @logger.info('Deleting rows') _delete_records @logger.info('All records deleted') end @hash end |
#delete_from_table(table, ids) ⇒ Object
Delete rows from a table. Can be used in #delete_records.
116 117 118 119 120 121 122 123 124 125 126 127 128 129 |
# File 'lib/rails-archiver/archiver.rb', line 116 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 = <<-SQL DELETE FROM `#{table}` WHERE `id` IN (#{group.compact.join(',')}) SQL ActiveRecord::Base.connection.delete(delete_query) end @logger.info("Finished deleting from #{table}") end |
#save_additional_data ⇒ Object
Use this method to add more data into the archive hash which isn’t directly accessible from the parent model. Call ‘visit_nodes` on each set of data you want to add. To be overridden by subclasses.
60 61 |
# File 'lib/rails-archiver/archiver.rb', line 60 def save_additional_data end |
#unarchiver ⇒ RailsArchiver::Unarchiver
132 133 134 135 136 |
# File 'lib/rails-archiver/archiver.rb', line 132 def unarchiver unarchiver = RailsArchiver::Unarchiver.new(@model, :logger => @logger) unarchiver.transport = self.transport unarchiver end |
#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.
96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 |
# File 'lib/rails-archiver/archiver.rb', line 96 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 |
#visit_nodes(node) ⇒ Object
Used to visit an association, and recursively calls down to all child objects through all other allowed associations.
67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 |
# File 'lib/rails-archiver/archiver.rb', line 67 def visit_nodes(node) return if node.blank? if node.respond_to?(:each) # e.g. a list of nodes from a has_many association node.each { |n| visit_nodes(n) } else class_name = node.class.name @hash[class_name] ||= Set.new @hash[class_name] << visit(node) get_associations(node).each do |assoc| @logger.debug("Visiting #{assoc.name}") new_nodes = node.send(assoc.name) next if new_nodes.blank? if new_nodes.respond_to?(:find_each) new_nodes.find_each { |n| visit_nodes(n) } else visit_nodes(new_nodes) end end end end |