Skip to content

Commit

Permalink
Implement support for upgrades from older backups.
Browse files Browse the repository at this point in the history
This is done by using a zip file as backup. This includes both the YAML
data and a schema.rb. When restoring, we create an empty database using
the schema.rb, import the data, and then run all the pending migrations.

Conflicts:
	app/models/backup.rb
  • Loading branch information
huerlisi committed May 20, 2014
1 parent a53a216 commit 256c5a3
Show file tree
Hide file tree
Showing 3 changed files with 55 additions and 10 deletions.
2 changes: 2 additions & 0 deletions app/controllers/backups_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,13 @@ class BackupsController < AttachmentsController

def create
@backup = current_tenant.export
redirect_to current_tenant
end

def restore
# TODO: access validation
@backup = Backup.find(params[:id])
@backup.import
redirect_to current_tenant
end
end
60 changes: 53 additions & 7 deletions app/models/backup.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,24 +12,70 @@ class Backup < Attachment
#
# Use this method for backup or migrations.
def export
temp = Tempfile.open('export')
temp.binmode
dir = Dir.mktmpdir 'bookyt.backup'

data = Tempfile.new('data.yml', dir)
data.binmode

old_level = ActiveRecord::Base.logger.level
ActiveRecord::Base.logger.level = 2 # don't log debug or info
YamlDb::Helper.dumper.dump(temp)
YamlDb::Helper.dumper.dump(data)
ActiveRecord::Base.logger.level = old_level

temp.close
title = "Backup %s.yaml" % DateTime.now.to_s(:db)
data.close

schema = Tempfile.new('schema.rb', dir)
schema.binmode

ActiveRecord::SchemaDumper.dump(ActiveRecord::Base.connection, schema)
schema.close

zip = Pathname.new(dir).join('backup-v1.zip')
Zip::File.open(zip, Zip::File::CREATE) do |zipfile|
zipfile.add('schema.rb', schema.path)
zipfile.add('data.yml', data.path)
end

self.file = temp
data.unlink
schema.unlink

title = "Backup %s" % DateTime.now.to_s(:db)

zip_file = File.new(zip, 'r')
# TODO: test if we can remove the directory before finishing reading
# a file it contains on Windows.
FileUtils.rmdir(dir)

self.file = zip_file
self.title = title
end

# Import Data from YAML
#
# This method loas a YAML file out of all the records in the database.
# This method restores a backup from a Backup record
# This record is normaly attached to a Tenant record.
#
# Use this method to restore.
def import
dir = Dir.mktmpdir 'bookyt.backup'
dirname = Pathname.new(dir)

Zip::File.open(file.current_path) do |zipfile|
schema = zipfile.glob('schema.rb').first
schema.extract(dirname.join('schema.rb'))
data = zipfile.glob('data.yml').first
data.extract(dirname.join('data.yml'))
end

load(dirname.join('schema.rb'))
ActiveRecord::Migrator.migrate(ActiveRecord::Migrator.migrations_paths, nil)

self.class.import_file(dirname.join('data.yml'))
end

# Import Data from a file
#
# This method loads a backup YAML file and creates records in the database.
# This file is normaly attached to a Tenant record.
#
# Use this method for restore or migrations.
Expand Down
3 changes: 0 additions & 3 deletions app/models/tenant.rb
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,4 @@ def export

backup
end

def import
end
end

0 comments on commit 256c5a3

Please sign in to comment.