db2fog 0.4.2 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/HISTORY +4 -0
- data/README.rdoc +0 -1
- data/lib/db2fog/tasks.rb +0 -8
- data/lib/db2fog.rb +96 -40
- metadata +4 -4
data/HISTORY
CHANGED
data/README.rdoc
CHANGED
@@ -59,7 +59,6 @@ providers they should work with just a config change to Db2Fog.
|
|
59
59
|
rake db2fog:backup:full
|
60
60
|
|
61
61
|
# Handy tasks
|
62
|
-
rake db2fog:statistics # Shows you the size of your DB
|
63
62
|
rake db2fog:backup:restore # You should be testing this regularly
|
64
63
|
rake db2fog:backup:clean # Clean up old backups - cron this
|
65
64
|
|
data/lib/db2fog/tasks.rb
CHANGED
@@ -17,12 +17,4 @@ namespace :db2fog do
|
|
17
17
|
DB2Fog.new.clean
|
18
18
|
end
|
19
19
|
end
|
20
|
-
|
21
|
-
desc "Show table sizes for your database"
|
22
|
-
task :statistics => :environment do
|
23
|
-
rows = DB2Fog.new.statistics
|
24
|
-
rows.sort_by {|x| -x[3].to_i }
|
25
|
-
header = [["Type", "Data MB", "Index", "Rows", "Name"], []]
|
26
|
-
puts (header + rows).collect {|x| x.join("\t") }
|
27
|
-
end
|
28
20
|
end
|
data/lib/db2fog.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
|
1
3
|
require 'active_support'
|
2
4
|
require 'active_support/core_ext/class/attribute_accessors'
|
3
5
|
require 'active_support/core_ext/hash/except'
|
@@ -10,17 +12,16 @@ class DB2Fog
|
|
10
12
|
|
11
13
|
def full_backup
|
12
14
|
file_name = "dump-#{db_credentials[:database]}-#{Time.now.utc.strftime("%Y%m%d%H%M")}.sql.gz"
|
13
|
-
store.store(file_name, open(
|
15
|
+
store.store(file_name, open(database.dump))
|
14
16
|
store.store(most_recent_dump_file_name, file_name)
|
15
17
|
end
|
16
18
|
|
17
19
|
def restore
|
18
20
|
dump_file_name = store.fetch(most_recent_dump_file_name).read
|
19
21
|
file = store.fetch(dump_file_name)
|
20
|
-
|
22
|
+
database.restore(file.path)
|
21
23
|
end
|
22
24
|
|
23
|
-
# TODO: This method really needs specs
|
24
25
|
def clean
|
25
26
|
to_keep = []
|
26
27
|
filelist = store.list
|
@@ -52,44 +53,8 @@ class DB2Fog
|
|
52
53
|
end
|
53
54
|
end
|
54
55
|
|
55
|
-
def statistics
|
56
|
-
# From http://mysqlpreacher.com/wordpress/tag/table-size/
|
57
|
-
results = ActiveRecord::Base.connection.execute(<<-EOS)
|
58
|
-
SELECT
|
59
|
-
engine,
|
60
|
-
ROUND(data_length/1024/1024,2) total_size_mb,
|
61
|
-
ROUND(index_length/1024/1024,2) total_index_size_mb,
|
62
|
-
table_rows,
|
63
|
-
table_name article_attachment
|
64
|
-
FROM information_schema.tables
|
65
|
-
WHERE table_schema = '#{db_credentials[:database]}'
|
66
|
-
ORDER BY total_size_mb + total_index_size_mb desc;
|
67
|
-
EOS
|
68
|
-
rows = []
|
69
|
-
results.each {|x| rows << x.to_a }
|
70
|
-
rows
|
71
|
-
end
|
72
|
-
|
73
56
|
private
|
74
57
|
|
75
|
-
def dump_db
|
76
|
-
dump_file = Tempfile.new("dump")
|
77
|
-
|
78
|
-
cmd = "mysqldump --quick --single-transaction --create-options #{mysql_options}"
|
79
|
-
cmd += " | gzip > #{dump_file.path}"
|
80
|
-
run(cmd)
|
81
|
-
|
82
|
-
dump_file
|
83
|
-
end
|
84
|
-
|
85
|
-
def mysql_options
|
86
|
-
cmd = ''
|
87
|
-
cmd += " -u #{db_credentials[:username]} " unless db_credentials[:username].nil?
|
88
|
-
cmd += " -p'#{db_credentials[:password]}'" unless db_credentials[:password].nil?
|
89
|
-
cmd += " -h '#{db_credentials[:host]}'" unless db_credentials[:host].nil?
|
90
|
-
cmd += " #{db_credentials[:database]}"
|
91
|
-
end
|
92
|
-
|
93
58
|
def store
|
94
59
|
@store ||= FogStore.new
|
95
60
|
end
|
@@ -107,6 +72,97 @@ class DB2Fog
|
|
107
72
|
ActiveRecord::Base.connection.instance_eval { @config } # Dodgy!
|
108
73
|
end
|
109
74
|
|
75
|
+
def database
|
76
|
+
@database ||= case db_credentials[:adapter]
|
77
|
+
when /mysql/ then MysqlAdaptor.new(db_credentials)
|
78
|
+
when /postgres/ then PsqlAdaptor.new(db_credentials)
|
79
|
+
else
|
80
|
+
raise "database adaptor '#{db_credentials[:adapter]}' not supported"
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
class MysqlAdaptor
|
85
|
+
|
86
|
+
def initialize(credentials)
|
87
|
+
@credentials = credentials
|
88
|
+
end
|
89
|
+
|
90
|
+
def dump
|
91
|
+
dump_file = Tempfile.new("dump")
|
92
|
+
|
93
|
+
cmd = "mysqldump --quick --single-transaction --create-options #{mysql_options}"
|
94
|
+
cmd += " | gzip -9 > #{dump_file.path}"
|
95
|
+
run(cmd)
|
96
|
+
|
97
|
+
dump_file.path
|
98
|
+
end
|
99
|
+
|
100
|
+
def restore(path)
|
101
|
+
run "gunzip -c #{path} | mysql #{mysql_options}"
|
102
|
+
end
|
103
|
+
|
104
|
+
private
|
105
|
+
|
106
|
+
def mysql_options
|
107
|
+
cmd = ''
|
108
|
+
cmd += " -u #{@credentials[:username]} " unless @credentials[:username].nil?
|
109
|
+
cmd += " -p'#{@credentials[:password]}'" unless @credentials[:password].nil?
|
110
|
+
cmd += " -h '#{@credentials[:host]}'" unless @credentials[:host].nil?
|
111
|
+
cmd += " #{@credentials[:database]}"
|
112
|
+
end
|
113
|
+
|
114
|
+
def run(command)
|
115
|
+
result = system(command)
|
116
|
+
raise("error, process exited with status #{$?.exitstatus}") unless result
|
117
|
+
end
|
118
|
+
|
119
|
+
end
|
120
|
+
|
121
|
+
class PsqlAdaptor
|
122
|
+
|
123
|
+
def initialize(credentials)
|
124
|
+
@credentials = credentials
|
125
|
+
end
|
126
|
+
|
127
|
+
def dump
|
128
|
+
dump_file = Tempfile.new("dump")
|
129
|
+
|
130
|
+
cmd = "pg_dump --clean --format=p #{pg_dump_options}"
|
131
|
+
cmd += " | gzip -9 > #{dump_file.path}"
|
132
|
+
run(cmd)
|
133
|
+
|
134
|
+
dump_file.path
|
135
|
+
end
|
136
|
+
|
137
|
+
def restore
|
138
|
+
run "gunzip -c #{path} | psql #{psql_options}"
|
139
|
+
end
|
140
|
+
|
141
|
+
private
|
142
|
+
|
143
|
+
def pg_dump_options
|
144
|
+
cmd = ''
|
145
|
+
cmd += " -U #{@credentials[:username]} " unless @credentials[:username].nil?
|
146
|
+
cmd += " -w"
|
147
|
+
cmd += " -h '#{@credentials[:host]}'" unless @credentials[:host].nil?
|
148
|
+
cmd += " #{@credentials[:database]}"
|
149
|
+
end
|
150
|
+
|
151
|
+
def psql_options
|
152
|
+
cmd = ''
|
153
|
+
cmd += " -U #{@credentials[:username]} " unless @credentials[:username].nil?
|
154
|
+
cmd += " -w"
|
155
|
+
cmd += " -h '#{@credentials[:host]}'" unless @credentials[:host].nil?
|
156
|
+
cmd += " -d #{@credentials[:database]}"
|
157
|
+
end
|
158
|
+
|
159
|
+
def run(command)
|
160
|
+
result = system(command)
|
161
|
+
raise("error, process exited with status #{$?.exitstatus}") unless result
|
162
|
+
end
|
163
|
+
|
164
|
+
end
|
165
|
+
|
110
166
|
class FogStore
|
111
167
|
|
112
168
|
def store(remote_filename, io)
|
@@ -117,7 +173,7 @@ class DB2Fog
|
|
117
173
|
remote_file = directory.files.get(remote_filename)
|
118
174
|
|
119
175
|
file = Tempfile.new("dump")
|
120
|
-
open(file.path, '
|
176
|
+
open(file.path, 'wb') { |f| f.write(remote_file.body) }
|
121
177
|
file
|
122
178
|
end
|
123
179
|
|
metadata
CHANGED
@@ -4,9 +4,9 @@ version: !ruby/object:Gem::Version
|
|
4
4
|
prerelease: false
|
5
5
|
segments:
|
6
6
|
- 0
|
7
|
-
-
|
8
|
-
-
|
9
|
-
version: 0.
|
7
|
+
- 5
|
8
|
+
- 0
|
9
|
+
version: 0.5.0
|
10
10
|
platform: ruby
|
11
11
|
authors:
|
12
12
|
- James Healy
|
@@ -14,7 +14,7 @@ autorequire:
|
|
14
14
|
bindir: bin
|
15
15
|
cert_chain: []
|
16
16
|
|
17
|
-
date: 2011-07
|
17
|
+
date: 2011-08-07 00:00:00 +10:00
|
18
18
|
default_executable:
|
19
19
|
dependencies:
|
20
20
|
- !ruby/object:Gem::Dependency
|