Class: JustOneDB::Command::Base

Inherits:
Object
  • Object
show all
Defined in:
lib/justonedb/command/base.rb

Direct Known Subclasses

Heroku

Defined Under Namespace

Classes: MigrationFailed

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.commandsObject



26
27
28
# File 'lib/justonedb/command/base.rb', line 26

def commands
	@@commands ||= {}
end

.loadObject



9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# File 'lib/justonedb/command/base.rb', line 9

def load
	# Now ask each sub-class to load it's commands
	@@commands = {}
	@@platforms = []
	sub_classes.each do |curr_class|
		if curr_class.respond_to?("get_commands")
			commands = curr_class.get_commands

			commands.each do |command|
				@@commands[command[:platform]] = {} unless @@commands[command[:platform]]
				@@commands[command[:platform]][command[:command]] = command
				@@platforms.push command[:platform] unless @@platforms.include?(command[:platform])
			end
		end
	end
end

.platformsObject



30
31
32
# File 'lib/justonedb/command/base.rb', line 30

def platforms
	@@platforms ||= []
end

Instance Method Details

#migrate(from, to, tmpdir) ⇒ Object



46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
# File 'lib/justonedb/command/base.rb', line 46

def migrate(from, to, tmpdir)
	# Extract details from URI
	dbi = URI.parse(from)
	username, password = dbi.userinfo.split(':')
	path = dbi.path.sub('/', '')

	tmpfile = File.join(tmpdir, "pg_dump_#{$$}.dmp")
	
	# Construct pg_dump command
	pg_dump = "pg_dump -Fp --no-privileges --no-owner --no-tablespaces " +
				"-h #{dbi.host}  -p #{dbi.port} -U #{username} #{path} 2>&1 > #{tmpfile}"

	puts "Extracting data from JUSTONEDB_DBI_URL using pg_dump"
	dumpin, dumpout, wait_thr = Open3.popen2({ "PGPASSWORD" => password }, pg_dump)
	dumpin.close
	dump_stdout = dumpout.read
	dumpout.close

	begin
		if wait_thr.value.exitstatus > 0
			puts dump_stdout
			raise MigrationFailed, "Database dump failed"
		end

		# Get a psql process read to read from us (pipe it's input, so that we can remove anything that we don't like
		new_dbi = URI.parse(to)
		username, password = new_dbi.userinfo.split(':')
		path = new_dbi.path.sub('/', '')
		psqlcmd = "psql --set=ON_ERROR_STOP=on -h #{new_dbi.host} -p #{new_dbi.port} -U #{username} -d #{path}"
		psqlin, psqlout, psqlerr, wait_thr = Open3.popen3({ "PGPASSWORD" => password }, psqlcmd)

		infd = open(tmpfile, "r")

		# Ignore creation of plpgsql language, as the user will not have permission to replace the one there
		puts "Importing data into JUSTONEDB_NEW_DBI_URL using psql"

		# Send everything to psql
		infd.each { |line| psqlin.write line unless line.match(/^create( or replace)? procedural language plpgsql;$/i) }

		infd.close
		psqlin.close

		psqlerr.each { |line| puts line }

		psqlout.close
		psqlerr.close

		if wait_thr.value.exitstatus > 0
			raise MigrationFailed, "Database restore failed"
		end

		puts "Data imported successfully, please fully check your application before running 'justonedb heroku promote'"

		rescue
			File.unlink(tmpfile) if File.exists?(tmpfile)
			raise
	end
end