db2fog 0.4.2 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (5) hide show
  1. data/HISTORY +4 -0
  2. data/README.rdoc +0 -1
  3. data/lib/db2fog/tasks.rb +0 -8
  4. data/lib/db2fog.rb +96 -40
  5. metadata +4 -4
data/HISTORY CHANGED
@@ -1,3 +1,7 @@
1
+ v0.5.0 (6th August 2011)
2
+ - initial postgresql support
3
+ - removed the statistics rake task
4
+ - fix an encoding issue under 1.9
1
5
  v0.4.2 (24th July 2011)
2
6
  - fixed recording of most recent backup
3
7
  - remove runtime dependency on mysql2
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(dump_db.path))
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
- run "gunzip -c #{file.path} | mysql #{mysql_options}"
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, 'w') { |f| f.write(remote_file.body) }
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
- - 4
8
- - 2
9
- version: 0.4.2
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-24 00:00:00 +10:00
17
+ date: 2011-08-07 00:00:00 +10:00
18
18
  default_executable:
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency