Created
June 5, 2015 13:47
-
-
Save leschenko/5a9130000fd0df879d1b to your computer and use it in GitHub Desktop.
Deep record dump
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Deep record dump | |
# | |
# Usage: | |
# dump = DeepRecordDump.new(order) | |
# | |
# 1) build sql dump file | |
# dump.write('/var/www/your_app/tmp/order_nnn.sql') | |
# 2) build shell commands to restore assets | |
# puts dump.shell_dump | |
# 3) restore `mysql db_name -e 'source /var/www/your_app/tmp/order_nnn.sql'` !!! NOT mysql db_name < dump.sql !!! | |
# 4) run shell commands | |
# | |
class DeepRecordDump | |
attr_accessor :dump_records | |
def initialize(record, dump_records={}, options={}) | |
@options = options | |
@options.reverse_merge!(dependent: false) | |
@record = record | |
@dump_records = dump_records | |
end | |
def dump | |
@dump ||= build_dump_records.values | |
end | |
def build_dump_records | |
dump_records[key_for(@record)] ||= dump_for(@record) | |
dump_associations.each do |assoc| | |
Array(@record.send(assoc.name)).each do |record| | |
dump_records[key_for(record)] or DeepRecordDump.new(record, dump_records, @options).build_dump_records | |
end | |
end | |
dump_records | |
end | |
def dump_associations | |
@record.class.reflect_on_all_associations.reject { |assoc| !@options[:dependent] && !assoc.options[:dependent] } | |
end | |
def dump_for(record) | |
data = {sql: insert_for(record)} | |
data[:shell] = shell_for(record) if record.class.table_name == 'assets' | |
data | |
end | |
def insert_for(record) | |
arel = record.class.arel_table.create_insert | |
arel.insert(record.send(:arel_attributes_with_values_for_create, record.attribute_names)) | |
arel.to_sql | |
end | |
def shell_for(record) | |
store_relative_dir = record.data.store_dir | |
target_dir = "/var/www/your_app/public/#{store_relative_dir}" | |
backup_dir = "/var/backups/content/#{store_relative_dir}/" | |
"mkdir -p #{target_dir} && rsync -a backup:#{backup_dir} #{target_dir}" | |
end | |
def key_for(record) | |
"#{record.class.table_name}##{record.id}" | |
end | |
def sql_dump | |
dump.map { |d| d[:sql] }.join(";\n") | |
end | |
def shell_dump | |
dump.map { |d| d[:shell] }.compact.join("\n") | |
end | |
def write(path) | |
File.write(path, sql_dump) | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment