dump 1.0.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 (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