dump 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (89) hide show
  1. data/.autotest +13 -0
  2. data/.gitignore +12 -0
  3. data/LICENSE.txt +20 -0
  4. data/README.markdown +250 -0
  5. data/dump.gemspec +22 -0
  6. data/lib/dump.rb +3 -0
  7. data/lib/dump/capistrano.rb +1 -0
  8. data/lib/dump/railtie.rb +8 -0
  9. data/lib/dump_rake.rb +85 -0
  10. data/lib/dump_rake/archive_tar_minitar_fix.rb +8 -0
  11. data/lib/dump_rake/assets.rb +22 -0
  12. data/lib/dump_rake/continious_timeout.rb +38 -0
  13. data/lib/dump_rake/dump.rb +175 -0
  14. data/lib/dump_rake/dump_reader.rb +289 -0
  15. data/lib/dump_rake/dump_writer.rb +119 -0
  16. data/lib/dump_rake/env.rb +139 -0
  17. data/lib/dump_rake/env/filter.rb +26 -0
  18. data/lib/dump_rake/rails_root.rb +12 -0
  19. data/lib/dump_rake/table_manipulation.rb +131 -0
  20. data/lib/generators/assets_config/assets_config_generator.rb +16 -0
  21. data/lib/generators/assets_config/templates/assets +8 -0
  22. data/lib/tasks/assets.rake +17 -0
  23. data/lib/tasks/dump.rake +27 -0
  24. data/recipes/dump.rb +343 -0
  25. data/script/update_readme +21 -0
  26. data/spec/.gitignore +1 -0
  27. data/spec/.tmignore +1 -0
  28. data/spec/cycle_spec.rb +229 -0
  29. data/spec/db/database.example.yml +19 -0
  30. data/spec/db/schema.rb +7 -0
  31. data/spec/dummy-3.1.3/.gitignore +15 -0
  32. data/spec/dummy-3.1.3/.rspec +1 -0
  33. data/spec/dummy-3.1.3/Gemfile +23 -0
  34. data/spec/dummy-3.1.3/Gemfile.lock +159 -0
  35. data/spec/dummy-3.1.3/README +261 -0
  36. data/spec/dummy-3.1.3/Rakefile +7 -0
  37. data/spec/dummy-3.1.3/app/assets/images/rails.png +0 -0
  38. data/spec/dummy-3.1.3/app/assets/javascripts/application.js +9 -0
  39. data/spec/dummy-3.1.3/app/assets/stylesheets/application.css +7 -0
  40. data/spec/dummy-3.1.3/app/controllers/application_controller.rb +3 -0
  41. data/spec/dummy-3.1.3/app/helpers/application_helper.rb +2 -0
  42. data/spec/dummy-3.1.3/app/mailers/.gitkeep +0 -0
  43. data/spec/dummy-3.1.3/app/models/.gitkeep +0 -0
  44. data/spec/dummy-3.1.3/app/views/layouts/application.html.erb +14 -0
  45. data/spec/dummy-3.1.3/config.ru +4 -0
  46. data/spec/dummy-3.1.3/config/application.rb +54 -0
  47. data/spec/dummy-3.1.3/config/boot.rb +6 -0
  48. data/spec/dummy-3.1.3/config/database.yml +25 -0
  49. data/spec/dummy-3.1.3/config/environment.rb +5 -0
  50. data/spec/dummy-3.1.3/config/environments/development.rb +30 -0
  51. data/spec/dummy-3.1.3/config/environments/production.rb +60 -0
  52. data/spec/dummy-3.1.3/config/environments/test.rb +39 -0
  53. data/spec/dummy-3.1.3/config/initializers/backtrace_silencers.rb +7 -0
  54. data/spec/dummy-3.1.3/config/initializers/inflections.rb +10 -0
  55. data/spec/dummy-3.1.3/config/initializers/mime_types.rb +5 -0
  56. data/spec/dummy-3.1.3/config/initializers/secret_token.rb +7 -0
  57. data/spec/dummy-3.1.3/config/initializers/session_store.rb +8 -0
  58. data/spec/dummy-3.1.3/config/initializers/wrap_parameters.rb +14 -0
  59. data/spec/dummy-3.1.3/config/locales/en.yml +5 -0
  60. data/spec/dummy-3.1.3/config/routes.rb +58 -0
  61. data/spec/dummy-3.1.3/db/seeds.rb +7 -0
  62. data/spec/dummy-3.1.3/doc/README_FOR_APP +2 -0
  63. data/spec/dummy-3.1.3/lib/assets/.gitkeep +0 -0
  64. data/spec/dummy-3.1.3/lib/tasks/.gitkeep +0 -0
  65. data/spec/dummy-3.1.3/log/.gitkeep +0 -0
  66. data/spec/dummy-3.1.3/public/404.html +26 -0
  67. data/spec/dummy-3.1.3/public/422.html +26 -0
  68. data/spec/dummy-3.1.3/public/500.html +26 -0
  69. data/spec/dummy-3.1.3/public/favicon.ico +0 -0
  70. data/spec/dummy-3.1.3/public/index.html +241 -0
  71. data/spec/dummy-3.1.3/public/robots.txt +5 -0
  72. data/spec/dummy-3.1.3/script/rails +6 -0
  73. data/spec/dummy-3.1.3/spec/spec_helper.rb +32 -0
  74. data/spec/dummy-3.1.3/vendor/assets/stylesheets/.gitkeep +0 -0
  75. data/spec/dummy-3.1.3/vendor/plugins/.gitkeep +0 -0
  76. data/spec/lib/dump_rake/dump_reader_spec.rb +638 -0
  77. data/spec/lib/dump_rake/dump_spec.rb +291 -0
  78. data/spec/lib/dump_rake/dump_writer_spec.rb +328 -0
  79. data/spec/lib/dump_rake/env/filter_spec.rb +56 -0
  80. data/spec/lib/dump_rake/env_spec.rb +139 -0
  81. data/spec/lib/dump_rake/rails_root_spec.rb +45 -0
  82. data/spec/lib/dump_rake/table_manipulation_spec.rb +256 -0
  83. data/spec/lib/dump_rake_spec.rb +326 -0
  84. data/spec/recipes/dump_spec.rb +553 -0
  85. data/spec/spec.opts +4 -0
  86. data/spec/spec_helper.rb +34 -0
  87. data/spec/tasks/assets_spec.rb +92 -0
  88. data/spec/tasks/dump_spec.rb +107 -0
  89. metadata +272 -0
@@ -0,0 +1,8 @@
1
+ # Lines starting with # are comments
2
+ # Put paths of dirs you want to dump here
3
+ # Example
4
+ # public/audios
5
+ # public/flash
6
+ # public/images/upload
7
+ # public/videos
8
+ public/system
@@ -0,0 +1,17 @@
1
+ $: << File.join(File.dirname(__FILE__), '../../lib')
2
+ require 'dump_rake'
3
+
4
+ task :assets do
5
+ ENV['ASSETS'] ||= DumpRake::Assets.assets
6
+ end
7
+
8
+ namespace :assets do
9
+ desc "Delete assets" << DumpRake::Env.explain_variables_for_command(:assets)
10
+ task :delete => :assets do
11
+ ENV['ASSETS'].split(':').each do |asset|
12
+ DumpRake::Assets.glob_asset_children(asset, '*').each do |child|
13
+ FileUtils.remove_entry(child)
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,27 @@
1
+ $: << File.join(File.dirname(__FILE__), '../../lib')
2
+ require 'dump_rake'
3
+
4
+ desc "Short for dump:create" << DumpRake::Env.explain_variables_for_command(:create)
5
+ task :dump => 'dump:create'
6
+
7
+ namespace :dump do
8
+ desc "Show avaliable versions" << DumpRake::Env.explain_variables_for_command(:versions)
9
+ task :versions => :environment do
10
+ DumpRake.versions(DumpRake::Env.for_command(:versions))
11
+ end
12
+
13
+ desc "Create dump" << DumpRake::Env.explain_variables_for_command(:create)
14
+ task :create => :environment do
15
+ DumpRake.create(DumpRake::Env.for_command(:create))
16
+ end
17
+
18
+ desc "Restore dump" << DumpRake::Env.explain_variables_for_command(:restore)
19
+ task :restore => :environment do
20
+ DumpRake.restore(DumpRake::Env.for_command(:restore))
21
+ end
22
+
23
+ desc "Cleanup dumps" << DumpRake::Env.explain_variables_for_command(:cleanup)
24
+ task :cleanup => :environment do
25
+ DumpRake.cleanup(DumpRake::Env.for_command(:cleanup))
26
+ end
27
+ end
@@ -0,0 +1,343 @@
1
+ # encoding: UTF-8
2
+
3
+ Capistrano::Configuration.instance(:i_need_this!).load do
4
+ $: << File.join(File.dirname(__FILE__), '../lib')
5
+ require 'fileutils'
6
+ require 'shellwords'
7
+
8
+ require 'dump_rake/continious_timeout'
9
+ require 'dump_rake/env'
10
+
11
+ begin
12
+ nil.blank?
13
+ rescue
14
+ Object.class_eval do
15
+ def blank?
16
+ respond_to?(:empty?) ? empty? : !self
17
+ end
18
+ def present?
19
+ !blank?
20
+ end
21
+ end
22
+ end
23
+
24
+ namespace :dump do
25
+ def dump_command(command, env = {})
26
+ rake = env.delete(:rake) || 'rake'
27
+
28
+ # stringify_keys! from activesupport
29
+ DumpRake::Env.stringify!(env)
30
+
31
+ env.update(DumpRake::Env.for_command(command, true))
32
+
33
+ cmd = %W[#{rake} -s dump:#{command}]
34
+ cmd += env.sort.map{ |key, value| "#{key}=#{value}" }
35
+ cmd.shelljoin
36
+ end
37
+
38
+ def fetch_rails_env
39
+ fetch(:rails_env, "production")
40
+ end
41
+
42
+ def got_rsync?
43
+ `which rsync`
44
+ $?.success?
45
+ end
46
+
47
+ def do_transfer_via(via, direction, from, to)
48
+ case via
49
+ when :rsync
50
+ if run_local('which rsync').present? && $?.success?
51
+ execute_on_servers do |servers|
52
+ commands = servers.map do |server|
53
+ target = sessions[server]
54
+ user = target.options[:user] || fetch(:user, nil)
55
+ host = target.host
56
+ port = target.options[:port]
57
+ full_host = "#{"#{user}@" if user.present?}#{host}"
58
+
59
+ ssh = port.present? ? "ssh -p #{port}" : 'ssh'
60
+ cmd = %W[rsync -P -e #{ssh} --timeout=15]
61
+ case direction
62
+ when :up
63
+ cmd << from << "#{full_host}:#{to}"
64
+ when :down
65
+ cmd << "#{full_host}:#{from}" << to
66
+ else
67
+ raise "Don't know how to transfer in direction #{direction}"
68
+ end
69
+ cmd.shelljoin
70
+ end
71
+ commands.each do |cmd|
72
+ logger.info cmd if logger
73
+
74
+ 3.times do
75
+ break if system(cmd)
76
+ break unless [10, 11, 12, 23, 30, 35].include?($?.exitstatus)
77
+ end
78
+ raise "rsync returned #{$?.exitstatus}" unless $?.success?
79
+ end
80
+ end
81
+ end
82
+ when :sftp, :scp
83
+ ContiniousTimeout.timeout 15 do |thread|
84
+ transfer(direction, from, to, :via => via) do |channel, path, transfered, total|
85
+ thread.defer
86
+ progress = if transfered < total
87
+ "\e[1m%5.1f%%\e[0m" % (transfered * 100.0 / total)
88
+ else
89
+ "100%"
90
+ end
91
+ $stderr << "\rTransfering: #{progress}"
92
+ end
93
+ end
94
+ else
95
+ raise "Unknown transfer method #{via}"
96
+ end
97
+ end
98
+
99
+ def do_transfer(direction, from, to)
100
+ if via = DumpRake::Env[:transfer_via]
101
+ case via.downcase
102
+ when 'rsync'
103
+ do_transfer_via(:rsync, direction, from, to)
104
+ when 'sftp'
105
+ do_transfer_via(:sftp, direction, from, to)
106
+ when 'scp'
107
+ do_transfer_via(:scp, direction, from, to)
108
+ else
109
+ raise "Unknown transfer method #{via}"
110
+ end
111
+ else
112
+ if got_rsync?
113
+ do_transfer_via(:rsync, direction, from, to)
114
+ else
115
+ $stderr.puts "To transfer using rsync — make rsync binary accessible and verify that remote host can work with rsync through ssh"
116
+ begin
117
+ do_transfer_via(:sftp, direction, from, to)
118
+ rescue => e
119
+ $stderr.puts e
120
+ do_transfer_via(:scp, direction, from, to)
121
+ end
122
+ end
123
+ end
124
+ end
125
+
126
+ def with_additional_tags(*tags)
127
+ tags = [tags, DumpRake::Env[:tags]].flatten.select(&:present?).join(',')
128
+ DumpRake::Env.with_env(:tags => tags) do
129
+ yield
130
+ end
131
+ end
132
+
133
+ def print_and_return_or_fail
134
+ out = yield
135
+ raise 'Failed creating dump' if out.blank?
136
+ print out
137
+ out.strip
138
+ end
139
+
140
+ def run_local(cmd)
141
+ `#{cmd}`
142
+ end
143
+
144
+ def run_remote(cmd)
145
+ output = ''
146
+ run(cmd) do |channel, io, data|
147
+ case io
148
+ when :out
149
+ output << data
150
+ when :err
151
+ $stderr << data
152
+ end
153
+ end
154
+ output
155
+ end
156
+
157
+ def last_part_of_last_line(out)
158
+ if line = out.strip.split(/\s*[\n\r]\s*/).last
159
+ line.split("\t").last
160
+ end
161
+ end
162
+
163
+ def fetch_rake
164
+ fetch(:rake, nil)
165
+ end
166
+
167
+ def auto_backup?
168
+ !DumpRake::Env.no?(:backup)
169
+ end
170
+
171
+ namespace :local do
172
+ desc "Shorthand for dump:local:create" << DumpRake::Env.explain_variables_for_command(:create)
173
+ task :default, :roles => :db, :only => {:primary => true} do
174
+ create
175
+ end
176
+
177
+ desc "Create local dump" << DumpRake::Env.explain_variables_for_command(:create)
178
+ task :create, :roles => :db, :only => {:primary => true} do
179
+ print_and_return_or_fail do
180
+ with_additional_tags('local') do
181
+ run_local(dump_command(:create))
182
+ end
183
+ end
184
+ end
185
+
186
+ desc "Restore local dump" << DumpRake::Env.explain_variables_for_command(:restore)
187
+ task :restore, :roles => :db, :only => {:primary => true} do
188
+ run_local(dump_command(:restore))
189
+ end
190
+
191
+ desc "Versions of local dumps" << DumpRake::Env.explain_variables_for_command(:versions)
192
+ task :versions, :roles => :db, :only => {:primary => true} do
193
+ print run_local(dump_command(:versions, :show_size => true))
194
+ end
195
+
196
+ desc "Cleanup local dumps" << DumpRake::Env.explain_variables_for_command(:cleanup)
197
+ task :cleanup, :roles => :db, :only => {:primary => true} do
198
+ print run_local(dump_command(:cleanup))
199
+ end
200
+
201
+ desc "Upload dump" << DumpRake::Env.explain_variables_for_command(:transfer)
202
+ task :upload, :roles => :db, :only => {:primary => true} do
203
+ file = DumpRake::Env.with_env(:summary => nil) do
204
+ last_part_of_last_line(run_local(dump_command(:versions)))
205
+ end
206
+ if file
207
+ do_transfer :up, "dump/#{file}", "#{current_path}/dump/#{file}"
208
+ end
209
+ end
210
+ end
211
+
212
+ namespace :remote do
213
+ desc "Shorthand for dump:remote:create" << DumpRake::Env.explain_variables_for_command(:create)
214
+ task :default, :roles => :db, :only => {:primary => true} do
215
+ remote.create
216
+ end
217
+
218
+ desc "Create remote dump" << DumpRake::Env.explain_variables_for_command(:create)
219
+ task :create, :roles => :db, :only => {:primary => true} do
220
+ print_and_return_or_fail do
221
+ with_additional_tags('remote') do
222
+ run_remote("cd #{current_path}; #{dump_command(:create, :rake => fetch_rake, :RAILS_ENV => fetch_rails_env, :PROGRESS_TTY => '+')}")
223
+ end
224
+ end
225
+ end
226
+
227
+ desc "Restore remote dump" << DumpRake::Env.explain_variables_for_command(:restore)
228
+ task :restore, :roles => :db, :only => {:primary => true} do
229
+ run_remote("cd #{current_path}; #{dump_command(:restore, :rake => fetch_rake, :RAILS_ENV => fetch_rails_env, :PROGRESS_TTY => '+')}")
230
+ end
231
+
232
+ desc "Versions of remote dumps" << DumpRake::Env.explain_variables_for_command(:versions)
233
+ task :versions, :roles => :db, :only => {:primary => true} do
234
+ print run_remote("cd #{current_path}; #{dump_command(:versions, :rake => fetch_rake, :RAILS_ENV => fetch_rails_env, :PROGRESS_TTY => '+', :show_size => true)}")
235
+ end
236
+
237
+ desc "Cleanup of remote dumps" << DumpRake::Env.explain_variables_for_command(:cleanup)
238
+ task :cleanup, :roles => :db, :only => {:primary => true} do
239
+ print run_remote("cd #{current_path}; #{dump_command(:cleanup, :rake => fetch_rake, :RAILS_ENV => fetch_rails_env, :PROGRESS_TTY => '+')}")
240
+ end
241
+
242
+ desc "Download dump" << DumpRake::Env.explain_variables_for_command(:transfer)
243
+ task :download, :roles => :db, :only => {:primary => true} do
244
+ file = DumpRake::Env.with_env(:summary => nil) do
245
+ last_part_of_last_line(run_remote("cd #{current_path}; #{dump_command(:versions, :rake => fetch_rake, :RAILS_ENV => fetch_rails_env, :PROGRESS_TTY => '+')}"))
246
+ end
247
+ if file
248
+ FileUtils.mkpath('dump')
249
+ do_transfer :down, "#{current_path}/dump/#{file}", "dump/#{file}"
250
+ end
251
+ end
252
+ end
253
+
254
+ desc "Shorthand for dump:local:upload" << DumpRake::Env.explain_variables_for_command(:transfer)
255
+ task :upload, :roles => :db, :only => {:primary => true} do
256
+ local.upload
257
+ end
258
+
259
+ desc "Shorthand for dump:remote:download" << DumpRake::Env.explain_variables_for_command(:transfer)
260
+ task :download, :roles => :db, :only => {:primary => true} do
261
+ remote:download
262
+ end
263
+
264
+ namespace :mirror do
265
+ desc "Creates local dump, uploads and restores on remote" << DumpRake::Env.explain_variables_for_command(:mirror)
266
+ task :up, :roles => :db, :only => {:primary => true} do
267
+ auto_backup = if auto_backup?
268
+ with_additional_tags('auto-backup') do
269
+ remote.create
270
+ end
271
+ end
272
+ if !auto_backup? || auto_backup.present?
273
+ file = with_additional_tags('mirror') do
274
+ local.create
275
+ end
276
+ if file.present?
277
+ DumpRake::Env.with_clean_env(:like => file) do
278
+ local.upload
279
+ remote.restore
280
+ end
281
+ end
282
+ end
283
+ end
284
+
285
+ desc "Creates remote dump, downloads and restores on local" << DumpRake::Env.explain_variables_for_command(:mirror)
286
+ task :down, :roles => :db, :only => {:primary => true} do
287
+ auto_backup = if auto_backup?
288
+ with_additional_tags('auto-backup') do
289
+ local.create
290
+ end
291
+ end
292
+ if !auto_backup? || auto_backup.present?
293
+ file = with_additional_tags('mirror') do
294
+ remote.create
295
+ end
296
+ if file.present?
297
+ DumpRake::Env.with_clean_env(:like => file) do
298
+ remote.download
299
+ local.restore
300
+ end
301
+ end
302
+ end
303
+ end
304
+ end
305
+
306
+ namespace :backup do
307
+ desc "Shorthand for dump:backup:create" << DumpRake::Env.explain_variables_for_command(:backup)
308
+ task :default, :roles => :db, :only => {:primary => true} do
309
+ create
310
+ end
311
+
312
+ desc "Creates remote dump and downloads to local (desc defaults to 'backup')" << DumpRake::Env.explain_variables_for_command(:backup)
313
+ task :create, :roles => :db, :only => {:primary => true} do
314
+ file = with_additional_tags('backup') do
315
+ remote.create
316
+ end
317
+ if file.present?
318
+ DumpRake::Env.with_clean_env(:like => file) do
319
+ remote.download
320
+ end
321
+ end
322
+ end
323
+
324
+ desc "Uploads dump with backup tag and restores it on remote" << DumpRake::Env.explain_variables_for_command(:backup_restore)
325
+ task :restore, :roles => :db, :only => {:primary => true} do
326
+ file = with_additional_tags('backup') do
327
+ last_part_of_last_line(run_local(dump_command(:versions)))
328
+ end
329
+ if file.present?
330
+ DumpRake::Env.with_clean_env(:like => file) do
331
+ local.upload
332
+ remote.restore
333
+ end
334
+ end
335
+ end
336
+ end
337
+ end
338
+
339
+ after 'deploy:update_code' do
340
+ from, to = %W[#{shared_path}/dump #{release_path}/dump]
341
+ run "mkdir -p #{from}; rm -rf #{to}; ln -s #{from} #{to}"
342
+ end
343
+ end
@@ -0,0 +1,21 @@
1
+ #!/usr/bin/env ruby -rrubygems
2
+
3
+ $: << File.join(File.dirname(__FILE__), '../lib')
4
+ require 'pathname'
5
+ require 'dump_rake/env'
6
+
7
+ readme = Pathname('README.markdown')
8
+ lines = readme.readlines.map(&:rstrip)
9
+ readme.open('w') do |f|
10
+ lines.each do |line|
11
+ line.sub!(/^`(.+?)`.*—.*$/) do
12
+ key, names = DumpRake::Env::DICTIONARY.find{ |key, values| values.include?($1) }
13
+ if key
14
+ names = names.map{ |name| "`#{name}`" }.join(', ')
15
+ explanation = DumpRake::Env::EXPLANATIONS[key]
16
+ "#{names} — #{explanation}"
17
+ end
18
+ end
19
+ f.puts line
20
+ end
21
+ end
@@ -0,0 +1 @@
1
+ /db/database.yml
@@ -0,0 +1 @@
1
+ /dummy-*
@@ -0,0 +1,229 @@
1
+ require File.dirname(__FILE__) + '/spec_helper'
2
+
3
+ require File.dirname(__FILE__) + '/../lib/dump_rake'
4
+
5
+ def database_configs
6
+ YAML::load(IO.read(PLUGIN_SPEC_DIR + "/db/database.yml"))
7
+ end
8
+
9
+ def adapters
10
+ database_configs.keys
11
+ end
12
+
13
+ def use_adapter(adapter)
14
+ config = database_configs[adapter]
15
+ begin
16
+ case config['adapter']
17
+ when /^mysql/
18
+ ActiveRecord::Base.establish_connection(config.merge('database' => nil))
19
+ ActiveRecord::Base.connection.create_database(config['database'])
20
+ ActiveRecord::Base.establish_connection(config)
21
+ when /^postgresql/
22
+ ActiveRecord::Base.establish_connection(config.merge('database' => 'postgres', 'schema_search_path' => 'public'))
23
+ ActiveRecord::Base.connection.create_database(config['database'])
24
+ ActiveRecord::Base.establish_connection(config)
25
+ else
26
+ ActiveRecord::Base.establish_connection(config)
27
+ end
28
+ load_schema
29
+ yield
30
+ ensure
31
+ case config['adapter']
32
+ when /^mysql/
33
+ ActiveRecord::Base.establish_connection(config)
34
+ ActiveRecord::Base.connection.drop_database config['database']
35
+ when /^postgresql/
36
+ ActiveRecord::Base.establish_connection(config.merge('database' => 'postgres', 'schema_search_path' => 'public'))
37
+ ActiveRecord::Base.connection.drop_database config['database']
38
+ end
39
+ end
40
+ ensure
41
+ ActiveRecord::Base.establish_connection(:adapter => 'sqlite3', :database => ':memory:')
42
+ end
43
+
44
+ def load_schema
45
+ grab_output{
46
+ load(DUMMY_SCHEMA_PATH)
47
+ }
48
+ end
49
+
50
+ def in_temp_rails_app
51
+ old_rails_root = DumpRake::RailsRoot.dup
52
+ DumpRake::RailsRoot.replace(File.join(PLUGIN_SPEC_DIR, 'temp_rails_app'))
53
+ FileUtils.remove_entry(DumpRake::RailsRoot) if File.exist?(DumpRake::RailsRoot)
54
+ FileUtils.mkpath(DumpRake::RailsRoot)
55
+ Progress.stub!(:io).and_return(StringIO.new)
56
+ yield
57
+ ensure
58
+ FileUtils.remove_entry(DumpRake::RailsRoot) if File.exist?(DumpRake::RailsRoot)
59
+ DumpRake::RailsRoot.replace(old_rails_root)
60
+ end
61
+
62
+ def create_chickens!(options = {})
63
+ time = Time.local(2000,"jan",1,20,15,1)
64
+ data = {
65
+ :string => ['', 'lala'],
66
+ :text => ['', 'lala', 'lala' * 100],
67
+ :integer => [-1000, 0, 1000],
68
+ :float => [-1000.0, 0.0, 1000.0],
69
+ :decimal => [-1000.0, 0.0, 1000.0],
70
+ :datetime => [time, time - 5.years],
71
+ :timestamp => [time, time - 5.years],
72
+ :time => [time, time - 5.years],
73
+ :date => [time, time - 5.years],
74
+ :boolean => [true, false],
75
+ }
76
+ Chicken.create!
77
+ data.each do |type, values|
78
+ values.each do |value|
79
+ Chicken.create!("#{type}_col" => value)
80
+ end
81
+ end
82
+ if options[:random]
83
+ options[:random].to_i.times do
84
+ attributes = {}
85
+ data.each do |type, values|
86
+ attributes["#{type}_col"] = values[rand(values.length)] if rand > 0.5
87
+ end
88
+ Chicken.create!(attributes)
89
+ end
90
+ end
91
+ end
92
+
93
+ def reset_rake!
94
+ @rake = Rake::Application.new
95
+ Rake.application = @rake
96
+ load File.dirname(__FILE__) + '/../lib/tasks/assets.rake'
97
+ load File.dirname(__FILE__) + '/../lib/tasks/dump.rake'
98
+ Rake::Task.define_task('environment')
99
+ Rake::Task.define_task('db:schema:dump') do
100
+ File.open(DUMMY_SCHEMA_PATH, 'r') do |r|
101
+ if ENV['SCHEMA']
102
+ File.open(ENV['SCHEMA'], 'w') do |w|
103
+ w.write(r.read)
104
+ end
105
+ end
106
+ end
107
+ end
108
+ Rake::Task.define_task('db:schema:load') do
109
+ load(ENV['SCHEMA'])
110
+ end
111
+ end
112
+
113
+ def call_rake
114
+ reset_rake!
115
+ grab_output{
116
+ yield
117
+ }
118
+ end
119
+
120
+ def call_rake_create(*args)
121
+ call_rake{
122
+ DumpRake.create(*args)
123
+ }
124
+ end
125
+
126
+ def call_rake_restore(*args)
127
+ call_rake{
128
+ DumpRake.restore(*args)
129
+ }
130
+ end
131
+
132
+ describe 'full cycle' do
133
+ begin
134
+ database_configs
135
+
136
+ adapters.each do |adapter|
137
+ it "should dump and restore using #{adapter}" do
138
+ in_temp_rails_app do
139
+ use_adapter(adapter) do
140
+ #add chickens store their attributes and create dump
141
+ create_chickens!(:random => 100)
142
+ chicken_attributes = Chicken.all.map(&:attributes)
143
+ call_rake_create(:description => 'chickens')
144
+
145
+ #clear database
146
+ load_schema
147
+ Chicken.all.should == []
148
+
149
+ #restore dump and verify equality
150
+ call_rake_restore(:version => 'chickens')
151
+ Chicken.all.map(&:attributes).should == chicken_attributes
152
+
153
+ # go throught create/restore cycle and verify equality
154
+ call_rake_create
155
+ load_schema
156
+ Chicken.all.should be_empty
157
+ call_rake_restore
158
+ Chicken.all.map(&:attributes).should == chicken_attributes
159
+ end
160
+ end
161
+ end
162
+ end
163
+
164
+ adapters.each do |adapter|
165
+ it "should not break id incrementing using #{adapter}" do
166
+ in_temp_rails_app do
167
+ use_adapter(adapter) do
168
+ create_chickens!(:random => 100)
169
+ call_rake_create(:description => 'chickens')
170
+ load_schema
171
+ call_rake_restore(:version => 'chickens')
172
+ create_chickens!
173
+ end
174
+ end
175
+ end
176
+ end
177
+
178
+ adapters.combination(2) do |adapter_src, adapter_dst|
179
+ it "should dump using #{adapter_src} and restore using #{adapter_dst}" do
180
+ in_temp_rails_app do
181
+ chicken_attributes = nil
182
+ use_adapter(adapter_src) do
183
+ Chicken.all.should be_empty
184
+
185
+ create_chickens!(:random => 100)
186
+ chicken_attributes = Chicken.all.map(&:attributes)
187
+ call_rake_create
188
+ end
189
+
190
+ use_adapter(adapter_dst) do
191
+ Chicken.all.should be_empty
192
+
193
+ call_rake_restore
194
+ chicken_attributes.should == Chicken.all.map(&:attributes)
195
+ end
196
+ end
197
+ end
198
+ end
199
+
200
+ it "should create same dump for all adapters" do
201
+ in_temp_rails_app do
202
+ dumps = []
203
+ adapters.each do |adapter|
204
+ use_adapter(adapter) do
205
+ dump_name = call_rake_create(:desc => adapter)[:stdout].strip
206
+ dump_path = File.join(DumpRake::RailsRoot, 'dump', dump_name)
207
+
208
+ data = []
209
+ Zlib::GzipReader.open(dump_path) do |gzip|
210
+ Archive::Tar::Minitar.open(gzip, 'r') do |stream|
211
+ stream.each do |entry|
212
+ data << [entry.full_name, entry.read]
213
+ end
214
+ end
215
+ end
216
+ dumps << {:path => dump_path, :data => data.sort}
217
+ end
218
+ end
219
+
220
+ dumps.combination(2) do |dump_a, dump_b|
221
+ dump_a[:path].should_not == dump_b[:path]
222
+ dump_a[:data].should == dump_b[:data]
223
+ end
224
+ end
225
+ end
226
+ rescue Errno::ENOENT => e
227
+ $stderr.puts e
228
+ end
229
+ end