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.
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