git_friendly_dumper 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/History.txt ADDED
@@ -0,0 +1,10 @@
1
+ == 0.0.1
2
+
3
+ * gem release
4
+ * Updated for latest rspec, cucumber, and ActiveRecord (3.x)
5
+
6
+ == Prior to gem release
7
+
8
+ * Improvements made while using for http://www.distinctivedoors.co.uk, (Ian White & Nick Rutherford)
9
+
10
+ * Initial release
data/MIT-LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2008-2012 Ian White - ian.w.white@gmail.com
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.rdoc ADDED
@@ -0,0 +1,48 @@
1
+ = git friendly dumper
2
+
3
+ Use fixtures to create a db independent and git friendly db dump.
4
+
5
+ It's git friendly because each record is in its own file (git doesn't do
6
+ very well with large files that are committed all at once).
7
+
8
+ If using the schema option (ie. db:dump & db:load), then each table's schema
9
+ definition is included as is the schema_migrations table.
10
+
11
+ == Example usage:
12
+
13
+ # drop-in replacement for mysqldump
14
+
15
+ rake db:dump DUMP_PATH=some/path
16
+ # just like mysqldump -u <user> -p<pass> <app>_development > some/path.sql
17
+
18
+ rake db:load DUMP_PATH=some/path
19
+ # just like script/dbconsole -p < some/path.sql
20
+
21
+ # without schema information, just the data
22
+
23
+ rake db:data:dump DUMP_PATH=some/path # dump the data without touching the structure
24
+ rake db:data:load DUMP_PATH=some/path # load the data without touching the structure
25
+
26
+ # just load particular table data
27
+ rake db:data:load DUMP_PATH=some/path TABLES=users,things
28
+
29
+ See `lib/tasks/git_friendly_dumper_tasks.rake` and the features for more info
30
+
31
+ == Notes
32
+
33
+ It's probably a bad idea to check your dump into the same repo as your app.
34
+
35
+ I created this so that we could have incremental scheduled backups of the db. With a database of 120M
36
+ containing many binary columns, this resulted in a massive saving in bandwidth.
37
+
38
+ Basically, we have the db backup inside the app, but ignored by the main app, the db/dump
39
+ has it's own git repo.
40
+
41
+ == Run the specs and features
42
+
43
+ Grab the last known good set of deps and run the specs and features
44
+
45
+ cp Gemfile.lock.development Gemfile.lock
46
+ bundle
47
+ rake
48
+
data/Rakefile ADDED
@@ -0,0 +1,43 @@
1
+ #!/usr/bin/env rake
2
+ begin
3
+ require 'bundler/setup'
4
+ rescue LoadError
5
+ puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
6
+ end
7
+ begin
8
+ require 'rdoc/task'
9
+ rescue LoadError
10
+ require 'rdoc/rdoc'
11
+ require 'rake/rdoctask'
12
+ RDoc::Task = Rake::RDocTask
13
+ end
14
+
15
+ RDoc::Task.new(:rdoc) do |rdoc|
16
+ rdoc.rdoc_dir = 'rdoc'
17
+ rdoc.title = 'GitFriendlyDumper'
18
+ rdoc.options << '--line-numbers'
19
+ rdoc.rdoc_files.include('README.rdoc')
20
+ rdoc.rdoc_files.include('lib/**/*.rb')
21
+ end
22
+
23
+ Bundler::GemHelper.install_tasks
24
+
25
+ require 'rspec/core/rake_task'
26
+ require "cucumber/rake/task"
27
+
28
+ task :default => [:spec, :features]
29
+
30
+ desc "Set up tmp stuff for running specs etc"
31
+ file "tmp/db" do
32
+ mkdir_p 'tmp/db'
33
+ end
34
+
35
+ desc "Run the specs"
36
+ RSpec::Core::RakeTask.new(:spec => ['tmp/db']) do |t|
37
+ t.pattern = "./spec/**/*_spec.rb"
38
+ end
39
+
40
+ desc "Run the features"
41
+ Cucumber::Rake::Task.new(:features) do |task|
42
+ task.cucumber_opts = ["features"]
43
+ end
@@ -0,0 +1,26 @@
1
+ Feature: Change dump path
2
+ In order to dump somewhere else than db/dump
3
+ I want the rake task to use the DUMP_PATH env variable to override the data path used
4
+
5
+ Background:
6
+ Given I am in an empty app
7
+ Given a Rakefile exists which has an environment task and loads git_friendly_dumper tasks
8
+ And an empty database
9
+ And the database has a "users" table (with timestamps):
10
+ | name (string) | surname (string) |
11
+ | Fred | Bloggs |
12
+ | Ethel | Smith |
13
+ | Jane | Heidie |
14
+ And the database has a "schema_migrations" table:
15
+ | version (string) |
16
+ | 01001010123 |
17
+
18
+
19
+
20
+ Scenario: change dump path
21
+ When I successfully run `rake db:dump FORCE=1 DUMP_PATH=db/override`
22
+ Then the output should contain "Dumping data and structure from database to db/override"
23
+ And the following directories should exist:
24
+ | db/override/users |
25
+ And the following files should exist:
26
+ | db/override/users/schema.rb |
@@ -0,0 +1,27 @@
1
+ Feature: Data dump
2
+ In order to …
3
+ I want to dump the data fixtures but not the schema or migrations table
4
+
5
+ Background:
6
+ Given I am in an empty app
7
+ Given a Rakefile exists which has an environment task and loads git_friendly_dumper tasks
8
+ And an empty database
9
+ And the database has a "users" table (with timestamps):
10
+ | name (string) | surname (string) |
11
+ | Fred | Bloggs |
12
+ | Ethel | Smith |
13
+ | Jane | Heidie |
14
+ And the database has a "schema_migrations" table:
15
+ | version (string) |
16
+ | 01001010123 |
17
+
18
+
19
+ Scenario: rake db:data:dump dumps all tables' contents but does not dump the schema or migrations table
20
+ When I successfully run `rake db:data:dump FORCE=1`
21
+ Then the output should contain "Dumping data from database to db/dump"
22
+ And the following directories should exist:
23
+ | db/dump/users |
24
+ But the following directories should not exist:
25
+ | db/dump/schema_migrations |
26
+ And the following files should not exist:
27
+ | db/dump/users/schema.rb |
@@ -0,0 +1,39 @@
1
+ Feature: Default dump
2
+ In order to produce incremental backups of my database using git
3
+ I want to backup my database in a form git can play nicely with
4
+
5
+ Background:
6
+ Given I am in an empty app
7
+ Given a Rakefile exists which has an environment task and loads git_friendly_dumper tasks
8
+ And an empty database
9
+ And the database has a "users" table (with timestamps):
10
+ | name (string) | surname (string) |
11
+ | Fred | Bloggs |
12
+ | Ethel | Smith |
13
+ | Jane | Heidie |
14
+ And the database has a "schema_migrations" table:
15
+ | version (string) |
16
+ | 01001010123 |
17
+
18
+
19
+
20
+ Scenario: rake db:dump dumps all tables' contents and the schema
21
+ When I successfully run `rake db:dump FORCE=1`
22
+ Then the output should contain "Dumping data and structure from database to db/dump"
23
+ And the following directories should exist:
24
+ | db/dump/users |
25
+ | db/dump/schema_migrations |
26
+ And the following files should exist:
27
+ | db/dump/users/schema.rb |
28
+
29
+ And the data in the dumped "users" yaml files should match the database contents
30
+
31
+ Given an empty database
32
+ When I execute the schema "db/dump/users/schema.rb"
33
+ Then a "users" table should exist with structure:
34
+ | name | type |
35
+ | id | INTEGER |
36
+ | created_at | datetime |
37
+ | updated_at | datetime |
38
+ | name | varchar(255) |
39
+ | surname | varchar(255) |
@@ -0,0 +1,58 @@
1
+ Feature: Toggle halting dump when runtime errors occur
2
+
3
+ Background:
4
+ Given I am in an empty app
5
+ Given a Rakefile exists which has an environment task and loads git_friendly_dumper tasks
6
+ And an empty database
7
+ And the database has a "users" table (with timestamps):
8
+ | name (string) | surname (string) |
9
+ | Fred | Bloggs |
10
+ | Ethel | Smith |
11
+ | Jane | Heidie |
12
+ And the database has a "schema_migrations" table:
13
+ | version (string) |
14
+ | 01001010123 |
15
+
16
+
17
+
18
+ Scenario: by default runtime errors are raised
19
+ When I run `rake db:dump FORCE=1 TABLES=doesntexist`
20
+ Then the exit status should be 1
21
+ And the output should contain "dumping doesntexist failed: SQLite3::SQLException: no such table: doesntexist: SELECT COUNT(*) FROM doesntexist"
22
+
23
+
24
+
25
+ Scenario Outline: RAISE_ERROR= toggles silence or raise runtime errors
26
+ When I run `rake db:dump FORCE=1 TABLES=doesntexist RAISE_ERROR=<RAISE_ERROR>`
27
+ Then the exit status should be <EXIT_STATUS>
28
+ But the output should contain "dumping doesntexist failed: SQLite3::SQLException: no such table: doesntexist: SELECT COUNT(*) FROM doesntexist"
29
+
30
+ Scenarios: don't raise
31
+ | RAISE_ERROR | EXIT_STATUS |
32
+ | false | 0 |
33
+ | 0 | 0 |
34
+
35
+ Scenarios: raise
36
+ | RAISE_ERROR | EXIT_STATUS |
37
+ | true | 1 |
38
+ | 1 | 1 |
39
+
40
+
41
+
42
+ Scenario: dirty directory warning on failed dump
43
+ When I run `rake db:dump FORCE=1 TABLES=doesntexist`
44
+ Then the exit status should be 1
45
+ And the following directories should exist:
46
+ | db/dump/doesntexist |
47
+ And the output should contain "Partial dump files have been left behind and you should clean up before continuing (e.g. git status, git checkout, git clean)."
48
+
49
+
50
+
51
+ Scenario: invalid FIXTURES argument raises an error
52
+ When I run `rake db:dump FORCE=1 FIXTURES=a_fixture.yml`
53
+ Then the exit status should be 1
54
+ And the output should contain "GitFriendlyDumper if :fixtures option given, neither :include_schema nor :clobber_fixtures can be given"
55
+
56
+ When I run `rake db:data:dump FORCE=1 FIXTURES=a_fixture.yml`
57
+ Then the exit status should be 1
58
+ And the output should contain "Cannot dump when :fixtures option is given"
@@ -0,0 +1,98 @@
1
+ Feature: What happens to fixtures belonging to deleted records when I perform a new dump
2
+ When dumping a table, any existing fixtures for that table are first removed
3
+ Any tables not being dumped, however, are ignored, and the old fixtures will remain in place
4
+
5
+ In order to have fixtures for what's in my database and nothing else
6
+ That is, no leftovers (deleted records, dropped tables, etc) from previous dumps
7
+ I want to CLOBBER them all before dumping
8
+
9
+ Background:
10
+ Given I am in an empty app
11
+ Given a Rakefile exists which has an environment task and loads git_friendly_dumper tasks
12
+ And an empty database
13
+ And the database has a "users" table (with timestamps):
14
+ | name (string) | surname (string) |
15
+ | Fred | Bloggs |
16
+ | Ethel | Smith |
17
+ | Jane | Heidie |
18
+ And the database has a "schema_migrations" table:
19
+ | version (string) |
20
+ | 01001010123 |
21
+
22
+
23
+
24
+ Scenario: fixtures belonging to deleted records are deleted and not recreated
25
+ When I run `rake db:dump FORCE=1`
26
+ Then the following files should exist:
27
+ | db/dump/users/0000/0001.yml |
28
+ | db/dump/users/0000/0002.yml |
29
+ | db/dump/users/0000/0003.yml |
30
+
31
+ When I destroy record 1 from the "users" table
32
+ And I run `rake db:dump FORCE=1`
33
+ Then the following files should exist:
34
+ | db/dump/users/0000/0002.yml |
35
+ | db/dump/users/0000/0003.yml |
36
+ But the following files should not exist:
37
+ | db/dump/users/0000/0001.yml |
38
+
39
+
40
+
41
+ Scenario: when dumping specific TABLES= any other tables' fixtures are left as they were (even if stale or deleted)
42
+ Given the database has a "debts" table (with timestamps):
43
+ | name (string) | surname (string) |
44
+ | Fred | Bloggs |
45
+ | Ethel | Smith |
46
+
47
+ When I run `rake db:dump FORCE=1`
48
+ Then the following files should exist:
49
+ | db/dump/users/0000/0001.yml |
50
+ | db/dump/users/0000/0002.yml |
51
+ | db/dump/users/0000/0003.yml |
52
+ | db/dump/debts/0000/0001.yml |
53
+ | db/dump/debts/0000/0002.yml |
54
+
55
+ When I destroy record 1 from the "debts" table
56
+ And I run `rake db:dump FORCE=1 TABLES=users`
57
+ Then the following files should exist:
58
+ | db/dump/users/0000/0001.yml |
59
+ | db/dump/users/0000/0002.yml |
60
+ | db/dump/users/0000/0003.yml |
61
+ | db/dump/debts/0000/0001.yml |
62
+ | db/dump/debts/0000/0002.yml |
63
+
64
+
65
+
66
+ Scenario Outline: CLOBBER= removes all existing fixtures before dumping new ones, combining with TABLES= means only those tables' fixtures will exist
67
+ Given the database has a "debts" table (with timestamps):
68
+ | name (string) | surname (string) |
69
+ | Fred | Bloggs |
70
+ | Ethel | Smith |
71
+ When I run `rake db:dump FORCE=1`
72
+ Then the following files should exist:
73
+ | db/dump/users/0000/0001.yml |
74
+ | db/dump/users/0000/0002.yml |
75
+ | db/dump/users/0000/0003.yml |
76
+ | db/dump/debts/0000/0001.yml |
77
+ | db/dump/debts/0000/0002.yml |
78
+
79
+ When I destroy record 1 from the "users" table
80
+ And I run `rake db:dump FORCE=1 TABLES=users CLOBBER=<CLOBBER>`
81
+ Then the following files should exist:
82
+ | db/dump/users/0000/0002.yml |
83
+ | db/dump/users/0000/0003.yml |
84
+ But the following files should not exist:
85
+ | db/dump/users/0000/0001.yml |
86
+ And the following files <EXISTENCE>:
87
+ | db/dump/debts/0000/0001.yml |
88
+ | db/dump/debts/0000/0002.yml |
89
+
90
+ Scenarios: deleting existing dump fixtures with CLOBBER=true|1
91
+ | CLOBBER | EXISTENCE |
92
+ | true | should not exist |
93
+ | 1 | should not exist |
94
+
95
+ Scenarios: not deleting existing dump fixtures with CLOBBER=false|0
96
+ | CLOBBER | EXISTENCE |
97
+ | false | should exist |
98
+ | 0 | should exist |
@@ -0,0 +1,39 @@
1
+ Feature: Dump specific tables
2
+ In order to only backup certain tables
3
+ I want TABLES to list the tables the rake task will dump
4
+
5
+ Background:
6
+ Given I am in an empty app
7
+ Given a Rakefile exists which has an environment task and loads git_friendly_dumper tasks
8
+ And an empty database
9
+ And the database has a "users" table (with timestamps):
10
+ | name (string) | surname (string) |
11
+ | Fred | Bloggs |
12
+ | Ethel | Smith |
13
+ | Jane | Heidie |
14
+ And the database has a "schema_migrations" table:
15
+ | version (string) |
16
+ | 01001010123 |
17
+
18
+
19
+
20
+ Scenario: dump specific tables
21
+ Given the database has a "seen" table (with timestamps):
22
+ | bird (string) | seen (integer) |
23
+ | Parrot | 1 |
24
+ | Robin | 3 |
25
+ | Goldfinch | 6 |
26
+ Given the database has a "notes" table:
27
+ | content (text) |
28
+ | Fred spotted a parrot?? |
29
+
30
+ When I successfully run `rake db:dump FORCE=1 TABLES=seen,users`
31
+ Then the output should contain "Dumping data and structure from database to db/dump"
32
+ And the following directories should exist:
33
+ | db/dump/users |
34
+ | db/dump/seen |
35
+ And the following files should exist:
36
+ | db/dump/users/schema.rb |
37
+ | db/dump/seen/schema.rb |
38
+ But the following directories should not exist:
39
+ | db/dump/notes |
@@ -0,0 +1,49 @@
1
+ Feature: CLOBBER is ignored when loading
2
+ CLOBBER=false|0 clobber fixtures on dump (default true)
3
+ Is ignored by db:load
4
+
5
+ Scenario: setting CLOBBER on load does nothing (fixtures are not deleted afterwards)
6
+ Given I am in an empty app
7
+ And a Rakefile exists which has an environment task and loads git_friendly_dumper tasks
8
+ And an empty database
9
+ And a file named "db/dump/users/schema.rb" with:
10
+ """
11
+ create_table "users", :force => true do |t|
12
+ t.datetime "created_at"
13
+ t.datetime "updated_at"
14
+ t.string "name"
15
+ t.string "surname"
16
+ end
17
+
18
+ """
19
+ And a file named "db/dump/users/0000/0001.yml" with:
20
+ """
21
+ ---
22
+ name: Jane
23
+ created_at: 2003-07-26 12:38:10
24
+ updated_at: 2007-07-26 12:48:10
25
+ id: 1
26
+ surname: Heidie
27
+
28
+ """
29
+ And a file named "db/dump/users/0000/0002.yml" with:
30
+ """
31
+ ---
32
+ name: Ethel
33
+ created_at: 2003-07-26 10:38:10
34
+ updated_at: 2007-07-26 10:48:10
35
+ id: 2
36
+ surname: Smith
37
+ """
38
+
39
+ When I successfully run `rake db:load FORCE=1 CLOBBER=true`
40
+ And I refresh the database tables cache
41
+ And the "users" table should match exactly:
42
+ | id | name | surname | created_at | updated_at |
43
+ | 1 | Jane | Heidie | 2003-07-26 12:38:10 | 2007-07-26 12:48:10 |
44
+ | 2 | Ethel | Smith | 2003-07-26 10:38:10 | 2007-07-26 10:48:10 |
45
+
46
+ But the following files should exist:
47
+ | db/dump/users/schema.rb |
48
+ | db/dump/users/0000/0001.yml |
49
+ | db/dump/users/0000/0002.yml |