git_friendly_dumper 0.0.1

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.
@@ -0,0 +1,3 @@
1
+ class GitFriendlyDumper
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,51 @@
1
+ # All of these tasks can be modified with these environment vars:
2
+ #
3
+ # DUMP_PATH=some/path where the dump is (default db/dump)
4
+ # TABLES=comma,sep,list tables to dump/load (default all)
5
+ # FORCE=true|1 answer 'yes' (default false)
6
+ # PROGRESS=false|0 show progress (default true)
7
+ # CLOBBER=false|0 clobber fixtures on dump (default true)
8
+ # RAISE_ERROR=false|0 silence runtime errors (default true)
9
+ # FIXTURES=comma,sep,list specific fixture files to load, invalid argument for dump tasks, should be relative filenames e.g. users/0000/0001.yml
10
+ # FIXTURES_FILE=filename of newline separated list of fixtures to load (use instead of FIXTURES option)
11
+
12
+ require 'git_friendly_dumper'
13
+
14
+ namespace :db do
15
+ desc "dump structure and data to db/dump (DUMP_PATH)"
16
+ task :dump => :environment do
17
+ GitFriendlyDumper.dump gfd_options.merge(:include_schema => true)
18
+ end
19
+
20
+ desc "replace database with data and stucture in db/dump (DUMP_PATH)"
21
+ task :load => :environment do
22
+ GitFriendlyDumper.load gfd_options.merge(:include_schema => true)
23
+ end
24
+
25
+ namespace :data do
26
+ desc "dump table data to db/dump (DUMP_PATH)"
27
+ task :dump => :environment do
28
+ GitFriendlyDumper.dump gfd_options.merge(:include_schema => false)
29
+ end
30
+
31
+ desc "load table data from db/dump (DUMP_PATH)"
32
+ task :load => :environment do
33
+ GitFriendlyDumper.load gfd_options.merge(:include_schema => false)
34
+ end
35
+ end
36
+
37
+ def gfd_options
38
+ {
39
+ :tables => ENV['TABLES'].present? && ENV['TABLES'].split(',').map(&:squish),
40
+ :path => ENV['DUMP_PATH'] || 'db/dump',
41
+ :force => ['1', 'true'].include?(ENV['FORCE']) ? true : false,
42
+ :include_schema => ['1', 'true'].include?(ENV['SCHEMA']) ? true : false,
43
+ :show_progress => ['0', 'false'].include?(ENV['PROGRESS']) ? false : true,
44
+ :clobber_fixtures => ['1', 'true'].include?(ENV['CLOBBER']) ? true : false,
45
+ :limit => ENV['LIMIT'] || 2500,
46
+ :raise_error => ['0', 'false'].include?(ENV['RAISE_ERROR']) ? false : true,
47
+ :fixtures => ENV['FIXTURES'] && ENV['FIXTURES'].split(','),
48
+ :fixtures_file => ENV['FIXTURES_FILE']
49
+ }
50
+ end
51
+ end
@@ -0,0 +1,319 @@
1
+ require 'spec_helper'
2
+
3
+ module GitFriendlyDumperSpec
4
+ include FileUtils
5
+
6
+ # sample app
7
+ class First < ActiveRecord::Base
8
+ end
9
+
10
+ class Second < ActiveRecord::Base
11
+ end
12
+
13
+ # spec helper methods
14
+ def reset_db
15
+ ActiveRecord::Base.connection.tables.each do |table|
16
+ ActiveRecord::Base.connection.drop_table table
17
+ end
18
+ end
19
+
20
+ def migrate_up(version)
21
+ ActiveRecord::Migration.suppress_messages do
22
+ ActiveRecord::Migrator.migrate ['spec/resources/migrate'], version
23
+ end
24
+ end
25
+
26
+ def remove_dump(path = @path)
27
+ rm_rf @path
28
+ end
29
+
30
+ def dump_files_set(path = @path)
31
+ Dir["#{path}/**/*"].map{|f| f.sub("#{path}/", '')}.to_set
32
+ end
33
+
34
+ def next_string
35
+ @next ||= 0
36
+ @next += 1
37
+ ['Foo', 'Bar', 'Baz'][rand(3)] + ("%04d" % @next)
38
+ end
39
+
40
+ def connection
41
+ ActiveRecord::Base.connection
42
+ end
43
+
44
+ describe 'GitFriendlyDumper' do
45
+ include GitFriendlyDumperSpec
46
+
47
+ before do
48
+ reset_db
49
+ @path = File.join(File.dirname(__FILE__), '../../tmp/dump')
50
+ remove_dump
51
+ end
52
+
53
+ describe "when progressbar not installed" do
54
+ before do
55
+ if defined?(ProgressBar)
56
+ @progress_bar_class = ProgressBar
57
+ Object.send :remove_const, 'ProgressBar'
58
+ end
59
+ end
60
+
61
+ after do
62
+ if @progress_bar_class
63
+ ProgressBar = @progress_bar_class
64
+ end
65
+ end
66
+
67
+ it ":show_progress => true should raise error" do
68
+ lambda { GitFriendlyDumper.new :show_progress => true }.should raise_error(RuntimeError)
69
+ end
70
+ end
71
+
72
+ describe "when db data exists" do
73
+ before do
74
+ migrate_up(20070101010000)
75
+ First.create!(:name => next_string)
76
+ First.create!(:name => next_string)
77
+ Second.create!(:name => next_string)
78
+ Second.create!(:name => next_string)
79
+ end
80
+
81
+ it "connection should have tables == ['firsts', 'seconds', 'schema_migrations']" do
82
+ ActiveRecord::Base.connection.tables.to_set.should == ['firsts', 'seconds', 'schema_migrations'].to_set
83
+ end
84
+
85
+ shared_examples_for "when dump files do not exist" do
86
+ it "should not require confirmation on dump" do
87
+ $stdin.should_not_receive(:gets)
88
+ @dumper.dump
89
+ end
90
+ end
91
+
92
+ shared_examples_for "when dump files exist" do
93
+ it "should require confirmation, and not proceed if not 'yes'" do
94
+ $stdin.should_receive(:gets).and_return("\n")
95
+ @dumper.should_not_receive(:dump_table)
96
+ @dumper.dump
97
+ end
98
+
99
+ it "should require confirmation, and proceed if 'yes'" do
100
+ $stdin.should_receive(:gets).and_return("yes\n")
101
+ @dumper.should_receive(:dump_table).at_least(1)
102
+ @dumper.dump
103
+ end
104
+
105
+ describe ", but :force => true" do
106
+ before do
107
+ @dumper.force = true
108
+ end
109
+
110
+ it "should not ask for confirmation" do
111
+ $stdin.should_not_receive(:gets)
112
+ @dumper.dump
113
+ end
114
+ end
115
+ end
116
+
117
+ describe "dump :include_schema => false" do
118
+ before do
119
+ @dumper = GitFriendlyDumper.new :include_schema => false, :path => @path
120
+ end
121
+
122
+ it_should_behave_like "when dump files do not exist"
123
+
124
+ describe "when dump files exist" do
125
+ before { mkdir_p "#{@path}/firsts" }
126
+ it_should_behave_like "when dump files exist"
127
+ end
128
+
129
+ describe "(after dump)" do
130
+ before do
131
+ @dumper.dump
132
+ end
133
+
134
+ it "should create only dump/firsts and dump/seconds with record fixtures" do
135
+ dump_files_set.should == [
136
+ 'firsts', 'firsts/0000', 'firsts/0000/0001.yml', 'firsts/0000/0002.yml',
137
+ 'seconds', 'seconds/0000', 'seconds/0000/0001.yml', 'seconds/0000/0002.yml'
138
+ ].to_set
139
+ end
140
+
141
+ it "should create fixtures for firsts" do
142
+ File.read("#{@path}/firsts/0000/0001.yml").should == connection.select_one("SELECT * FROM firsts WHERE id=1").to_yaml
143
+ File.read("#{@path}/firsts/0000/0002.yml").should == connection.select_one("SELECT * FROM firsts WHERE id=2").to_yaml
144
+ end
145
+
146
+ it "should create fixtures for seconds" do
147
+ File.read("#{@path}/seconds/0000/0001.yml").should == connection.select_one("SELECT * FROM seconds WHERE id=1").to_yaml
148
+ File.read("#{@path}/seconds/0000/0002.yml").should == connection.select_one("SELECT * FROM seconds WHERE id=2").to_yaml
149
+ end
150
+ end
151
+ end
152
+
153
+ describe "dump :include_schema => true" do
154
+ before do
155
+ @dumper = GitFriendlyDumper.new :include_schema => true, :path => @path
156
+ end
157
+
158
+ it_should_behave_like "when dump files do not exist"
159
+
160
+ describe "when dump files exist" do
161
+ before { mkdir_p "#{@path}/firsts" }
162
+ it_should_behave_like "when dump files exist"
163
+ end
164
+
165
+ describe "(after dump)" do
166
+ before do
167
+ @dumper.dump
168
+ end
169
+
170
+ it "should create dump/firsts, dump/seconds dump/schema_migrations, with record fixtures, and table schemas" do
171
+ dump_files_set.should == [
172
+ 'firsts', 'firsts/0000', 'firsts/0000/0001.yml', 'firsts/0000/0002.yml', 'firsts/schema.rb',
173
+ 'seconds', 'seconds/0000', 'seconds/0000/0001.yml', 'seconds/0000/0002.yml', 'seconds/schema.rb',
174
+ 'schema_migrations', 'schema_migrations/0000', 'schema_migrations/0000/0001.yml', 'schema_migrations/0000/0002.yml', 'schema_migrations/schema.rb'
175
+ ].to_set
176
+ end
177
+
178
+ it "should create fixtures for firsts" do
179
+ File.read("#{@path}/firsts/0000/0001.yml").should == connection.select_one("SELECT * FROM firsts WHERE id=1").to_yaml
180
+ File.read("#{@path}/firsts/0000/0002.yml").should == connection.select_one("SELECT * FROM firsts WHERE id=2").to_yaml
181
+ end
182
+
183
+ it "should create fixtures for seconds" do
184
+ File.read("#{@path}/seconds/0000/0001.yml").should == connection.select_one("SELECT * FROM seconds WHERE id=1").to_yaml
185
+ File.read("#{@path}/seconds/0000/0002.yml").should == connection.select_one("SELECT * FROM seconds WHERE id=2").to_yaml
186
+ end
187
+
188
+ it "should create fixtures for schema_migrations" do
189
+ YAML.load(File.read("#{@path}/schema_migrations/0000/0001.yml")).should == {"version" => "20070101000000"}
190
+ YAML.load(File.read("#{@path}/schema_migrations/0000/0002.yml")).should == {"version" => "20070101010000"}
191
+ end
192
+
193
+ it "should contain create schema for firsts" do
194
+ File.read("#{@path}/firsts/schema.rb").should =~ /create_table "firsts".*string "name"/m
195
+ end
196
+
197
+ it "should contain create schema for seconds" do
198
+ File.read("#{@path}/seconds/schema.rb").should =~ /create_table "seconds".*string "name"/m
199
+ end
200
+
201
+ it "should contain create schema for schema_migrations" do
202
+ File.read("#{@path}/schema_migrations/schema.rb").should =~ /create_table "schema_migrations".*:id => false.*string "version"/m
203
+ end
204
+ end
205
+ end
206
+
207
+
208
+ describe "dumping when RAISE_ERROR=false" do
209
+ let(:dumper) {GitFriendlyDumper.new(:include_schema => true, :raise_error => false, :path => @path)}
210
+ subject{ dumper }
211
+
212
+ describe "when #dump_records raises a runtime error" do
213
+ before(:each) do
214
+ dumper.should_receive(:dump_records).and_raise(RuntimeError)
215
+ end
216
+
217
+ it "#dump should raise a runtime error" do
218
+ lambda { dumper.dump }.should raise_error(RuntimeError)
219
+ end
220
+ end
221
+
222
+ describe "when #dump_records raises an ActiveRecord::Error" do
223
+ before(:each) do
224
+ dumper.should_receive(:dump_records).at_least(1).times.and_raise(ActiveRecord::ActiveRecordError)
225
+ end
226
+
227
+ it "#dump should not raise a runtime error" do
228
+ lambda { dumper.dump }.should_not raise_error
229
+ end
230
+ end
231
+ end
232
+ end
233
+
234
+ describe "when fixtures exist" do
235
+ before do
236
+ migrate_up(20070101010000)
237
+ First.create!(:name => next_string)
238
+ First.create!(:name => next_string)
239
+ Second.create!(:name => next_string)
240
+ Second.create!(:name => next_string)
241
+ GitFriendlyDumper.dump :include_schema => true, :force => true, :path => @path
242
+ reset_db
243
+ end
244
+
245
+ shared_examples_for "when db data does not exist" do
246
+ it "should not require confirmation on load" do
247
+ $stdin.should_not_receive(:gets)
248
+ @dumper.load
249
+ end
250
+ end
251
+
252
+ shared_examples_for "when db data exists" do
253
+ it "should require confirmation, and not proceed if not 'yes'" do
254
+ $stdin.should_receive(:gets).and_return("\n")
255
+ @dumper.should_not_receive(:load_table)
256
+ @dumper.load
257
+ end
258
+
259
+ it "should require confirmation, and proceed if 'yes'" do
260
+ $stdin.should_receive(:gets).and_return("yes\n")
261
+ @dumper.should_receive(:load_table).at_least(1)
262
+ @dumper.load
263
+ end
264
+
265
+ describe ", but :force => true" do
266
+ before do
267
+ @dumper.force = true
268
+ end
269
+
270
+ it "should not ask for confirmation" do
271
+ $stdin.should_not_receive(:gets)
272
+ @dumper.load
273
+ end
274
+ end
275
+ end
276
+
277
+ describe "load :include_schema => true" do
278
+ before do
279
+ @dumper = GitFriendlyDumper.new :include_schema => true, :path => @path
280
+ end
281
+
282
+ it_should_behave_like "when db data does not exist"
283
+
284
+ describe "when db data exists" do
285
+ before do
286
+ migrate_up(20070101010000)
287
+ end
288
+
289
+ it_should_behave_like "when db data exists"
290
+ end
291
+ end
292
+
293
+ describe "loading when RAISE_ERROR=false" do
294
+ let(:dumper) {GitFriendlyDumper.new(:include_schema => true, :raise_error => false, :path => @path)}
295
+ subject{ dumper }
296
+
297
+ describe "when connection raises a runtime error" do
298
+ before(:each) do
299
+ dumper.connection.should_receive(:insert_fixture).and_raise(RuntimeError)
300
+ end
301
+
302
+ it "#load should raise a runtime error" do
303
+ lambda { dumper.load }.should raise_error(RuntimeError)
304
+ end
305
+ end
306
+
307
+ describe "when connection raises an ActiveRecord::Error" do
308
+ before(:each) do
309
+ dumper.connection.should_receive(:insert_fixture).at_least(1).times.and_raise(ActiveRecord::ActiveRecordError)
310
+ end
311
+
312
+ it "#load should not raise a runtime error" do
313
+ lambda { dumper.load }.should_not raise_error
314
+ end
315
+ end
316
+ end
317
+ end
318
+ end
319
+ end
@@ -0,0 +1,11 @@
1
+ class CreateFirsts < ActiveRecord::Migration
2
+ def self.up
3
+ create_table :firsts do |t|
4
+ t.string :name
5
+ end
6
+ end
7
+
8
+ def self.down
9
+ drop_table :firsts
10
+ end
11
+ end
@@ -0,0 +1,11 @@
1
+ class CreateSeconds < ActiveRecord::Migration
2
+ def self.up
3
+ create_table :seconds do |t|
4
+ t.string :name
5
+ end
6
+ end
7
+
8
+ def self.down
9
+ drop_table :seconds
10
+ end
11
+ end
@@ -0,0 +1,8 @@
1
+ require 'rubygems'
2
+ require 'rspec'
3
+
4
+ # Requires supporting files with custom matchers and macros, etc,
5
+ # in ./support/ and its subdirectories.
6
+ Dir[File.expand_path(File.join(File.dirname(__FILE__),'support','**','*.rb'))].each {|f| require f}
7
+
8
+ require 'git_friendly_dumper'
@@ -0,0 +1,6 @@
1
+ require 'active_record'
2
+
3
+ ActiveRecord::Base.establish_connection(
4
+ :adapter => "sqlite3",
5
+ :database => "tmp/db/test.sqlite3"
6
+ )
@@ -0,0 +1,7 @@
1
+ require 'logger'
2
+ require 'active_record'
3
+
4
+ log_filename = File.join(File.dirname(__FILE__), '..', '..', 'tmp', 'test.log')
5
+ `mkdir -p #{File.dirname(log_filename)}`
6
+ log_file = File.open(log_filename, 'w')
7
+ ActiveRecord::Base.logger = Logger.new(log_file)
metadata ADDED
@@ -0,0 +1,196 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: git_friendly_dumper
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Ian White
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-03-05 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: activerecord
16
+ requirement: &70093535094440 !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: *70093535094440
25
+ - !ruby/object:Gem::Dependency
26
+ name: mysql2
27
+ requirement: &70093535108500 !ruby/object:Gem::Requirement
28
+ none: false
29
+ requirements:
30
+ - - ! '>='
31
+ - !ruby/object:Gem::Version
32
+ version: '0'
33
+ type: :development
34
+ prerelease: false
35
+ version_requirements: *70093535108500
36
+ - !ruby/object:Gem::Dependency
37
+ name: sqlite3
38
+ requirement: &70093535105680 !ruby/object:Gem::Requirement
39
+ none: false
40
+ requirements:
41
+ - - ! '>='
42
+ - !ruby/object:Gem::Version
43
+ version: '0'
44
+ type: :development
45
+ prerelease: false
46
+ version_requirements: *70093535105680
47
+ - !ruby/object:Gem::Dependency
48
+ name: rake
49
+ requirement: &70093535104660 !ruby/object:Gem::Requirement
50
+ none: false
51
+ requirements:
52
+ - - ! '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ type: :development
56
+ prerelease: false
57
+ version_requirements: *70093535104660
58
+ - !ruby/object:Gem::Dependency
59
+ name: rspec
60
+ requirement: &70093535103600 !ruby/object:Gem::Requirement
61
+ none: false
62
+ requirements:
63
+ - - ! '>='
64
+ - !ruby/object:Gem::Version
65
+ version: '0'
66
+ type: :development
67
+ prerelease: false
68
+ version_requirements: *70093535103600
69
+ - !ruby/object:Gem::Dependency
70
+ name: cucumber
71
+ requirement: &70093535102400 !ruby/object:Gem::Requirement
72
+ none: false
73
+ requirements:
74
+ - - ! '>='
75
+ - !ruby/object:Gem::Version
76
+ version: '0'
77
+ type: :development
78
+ prerelease: false
79
+ version_requirements: *70093535102400
80
+ - !ruby/object:Gem::Dependency
81
+ name: aruba
82
+ requirement: &70093535117660 !ruby/object:Gem::Requirement
83
+ none: false
84
+ requirements:
85
+ - - ! '>='
86
+ - !ruby/object:Gem::Version
87
+ version: '0'
88
+ type: :development
89
+ prerelease: false
90
+ version_requirements: *70093535117660
91
+ - !ruby/object:Gem::Dependency
92
+ name: progressbar
93
+ requirement: &70093535116980 !ruby/object:Gem::Requirement
94
+ none: false
95
+ requirements:
96
+ - - ! '>='
97
+ - !ruby/object:Gem::Version
98
+ version: '0'
99
+ type: :development
100
+ prerelease: false
101
+ version_requirements: *70093535116980
102
+ description: Use fixtures to create a db independent and git friendly db dump. It's
103
+ git friendly because each record is in its own file (git doesn't do very well with
104
+ large files that are committed all at once).
105
+ email:
106
+ - ian.w.white@gmail.com
107
+ executables: []
108
+ extensions: []
109
+ extra_rdoc_files: []
110
+ files:
111
+ - lib/git_friendly_dumper/version.rb
112
+ - lib/git_friendly_dumper.rb
113
+ - lib/tasks/git_friendly_dumper_tasks.rake
114
+ - MIT-LICENSE
115
+ - Rakefile
116
+ - History.txt
117
+ - README.rdoc
118
+ - spec/git_friendly_dumper_spec.rb
119
+ - spec/resources/migrate/20070101000000_create_firsts.rb
120
+ - spec/resources/migrate/20070101010000_create_seconds.rb
121
+ - spec/spec_helper.rb
122
+ - spec/support/connect.rb
123
+ - spec/support/logger.rb
124
+ - features/dump/change_dump_path.feature
125
+ - features/dump/data_dump.feature
126
+ - features/dump/default_dump.feature
127
+ - features/dump/dump_and_raise_error.feature
128
+ - features/dump/dump_deleted_records_and_clobber.feature
129
+ - features/dump/dump_specific_tables.feature
130
+ - features/load/clobber_load.feature
131
+ - features/load/db_dump_path_load.feature
132
+ - features/load/default_load.feature
133
+ - features/load/load_and_raise_error.feature
134
+ - features/load/load_fixtures.feature
135
+ - features/load/load_git_changes.feature
136
+ - features/load/load_specific_tables.feature
137
+ - features/step_definitions/app_steps.rb
138
+ - features/step_definitions/database_steps.rb
139
+ - features/support/announce.rb
140
+ - features/support/env.rb
141
+ - features/support/logger.rb
142
+ homepage: http://github.com/ianwhite/git_friendly_dumper
143
+ licenses: []
144
+ post_install_message:
145
+ rdoc_options: []
146
+ require_paths:
147
+ - lib
148
+ required_ruby_version: !ruby/object:Gem::Requirement
149
+ none: false
150
+ requirements:
151
+ - - ! '>='
152
+ - !ruby/object:Gem::Version
153
+ version: '0'
154
+ segments:
155
+ - 0
156
+ hash: 402944153813948199
157
+ required_rubygems_version: !ruby/object:Gem::Requirement
158
+ none: false
159
+ requirements:
160
+ - - ! '>='
161
+ - !ruby/object:Gem::Version
162
+ version: '0'
163
+ segments:
164
+ - 0
165
+ hash: 402944153813948199
166
+ requirements: []
167
+ rubyforge_project:
168
+ rubygems_version: 1.8.10
169
+ signing_key:
170
+ specification_version: 3
171
+ summary: Use fixtures to create a db independent and git friendly db dump.
172
+ test_files:
173
+ - spec/git_friendly_dumper_spec.rb
174
+ - spec/resources/migrate/20070101000000_create_firsts.rb
175
+ - spec/resources/migrate/20070101010000_create_seconds.rb
176
+ - spec/spec_helper.rb
177
+ - spec/support/connect.rb
178
+ - spec/support/logger.rb
179
+ - features/dump/change_dump_path.feature
180
+ - features/dump/data_dump.feature
181
+ - features/dump/default_dump.feature
182
+ - features/dump/dump_and_raise_error.feature
183
+ - features/dump/dump_deleted_records_and_clobber.feature
184
+ - features/dump/dump_specific_tables.feature
185
+ - features/load/clobber_load.feature
186
+ - features/load/db_dump_path_load.feature
187
+ - features/load/default_load.feature
188
+ - features/load/load_and_raise_error.feature
189
+ - features/load/load_fixtures.feature
190
+ - features/load/load_git_changes.feature
191
+ - features/load/load_specific_tables.feature
192
+ - features/step_definitions/app_steps.rb
193
+ - features/step_definitions/database_steps.rb
194
+ - features/support/announce.rb
195
+ - features/support/env.rb
196
+ - features/support/logger.rb