db_backup_tool 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.
- data/.gitignore +19 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +39 -0
- data/Rakefile +12 -0
- data/bin/db_backup_tool +62 -0
- data/db_backup_tool.gemspec +34 -0
- data/lib/db_backup_tool/archiver.rb +42 -0
- data/lib/db_backup_tool/dumper.rb +20 -0
- data/lib/db_backup_tool/loader.rb +21 -0
- data/lib/db_backup_tool/mappers/active_record_mapper.rb +98 -0
- data/lib/db_backup_tool/mappers.rb +16 -0
- data/lib/db_backup_tool/version.rb +3 -0
- data/lib/db_backup_tool.rb +11 -0
- data/spec/active_record_mapper_spec.rb +52 -0
- data/spec/dumper_spec.rb +38 -0
- data/spec/factories/mappers.rb +26 -0
- data/spec/loader_spec.rb +31 -0
- data/spec/mappers_spec.rb +14 -0
- data/spec/spec_helper.rb +17 -0
- metadata +232 -0
data/.gitignore
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2012 David Lin
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,39 @@
|
|
1
|
+
# DbBackupTool
|
2
|
+
|
3
|
+
A very simple backup tool for Rails Database
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
Add this line to your application's Gemfile:
|
8
|
+
|
9
|
+
gem 'db_backup_tool'
|
10
|
+
|
11
|
+
And then execute:
|
12
|
+
|
13
|
+
$ bundle
|
14
|
+
|
15
|
+
Or install it yourself as:
|
16
|
+
|
17
|
+
$ gem install db_backup_tool
|
18
|
+
|
19
|
+
## Usage
|
20
|
+
|
21
|
+
Please set DATABASE_URL as an env variable
|
22
|
+
|
23
|
+
$ export DATABASE_URL=postgres://....
|
24
|
+
|
25
|
+
Dump and export to a zip file
|
26
|
+
|
27
|
+
$ db_backup_tool dump
|
28
|
+
|
29
|
+
Load from a zip file
|
30
|
+
|
31
|
+
$ db_backup_tool -i ZIP_FILE load
|
32
|
+
|
33
|
+
## Contributing
|
34
|
+
|
35
|
+
1. Fork it
|
36
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
37
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
38
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
39
|
+
5. Create new Pull Request
|
data/Rakefile
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
2
|
+
require "rake/testtask"
|
3
|
+
|
4
|
+
Rake::TestTask.new :spec do |t|
|
5
|
+
t.libs << "spec"
|
6
|
+
t.pattern = "spec/**/*_spec.rb"
|
7
|
+
end
|
8
|
+
|
9
|
+
desc "Open an irb session preloaded with this library"
|
10
|
+
task :console do
|
11
|
+
sh "irb -rubygems -I lib -r db_backup_tool"
|
12
|
+
end
|
data/bin/db_backup_tool
ADDED
@@ -0,0 +1,62 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'optparse'
|
4
|
+
require_relative '../lib/db_backup_tool'
|
5
|
+
require 'fileutils'
|
6
|
+
|
7
|
+
# convert DATABASE_URL to config hash
|
8
|
+
def config_from_url(db_url)
|
9
|
+
uri = URI.parse db_url
|
10
|
+
{
|
11
|
+
adapter: (uri.scheme == 'postgres' ? 'postgresql' : uri.scheme ),
|
12
|
+
database: (uri.path || "").split("/")[1],
|
13
|
+
username: uri.user,
|
14
|
+
password: uri.password,
|
15
|
+
host: uri.host,
|
16
|
+
port: uri.port
|
17
|
+
}
|
18
|
+
end
|
19
|
+
|
20
|
+
# parse options
|
21
|
+
argv = ARGV.dup
|
22
|
+
options = {}
|
23
|
+
OptionParser.new do |opts|
|
24
|
+
opts.banner = "Usage: #{opts.program_name} [options] ACTION"
|
25
|
+
opts.separator "Actions:"
|
26
|
+
opts.separator " dump: Dump all or selected tables in the database"
|
27
|
+
opts.separator " load: Load tables from the archive"
|
28
|
+
opts.separator "Options:"
|
29
|
+
|
30
|
+
opts.on("-d", "--database URL"){ |p|
|
31
|
+
options[:config] = config_from_url(p)
|
32
|
+
}
|
33
|
+
|
34
|
+
opts.on("-i", "--import ARCHIVE"){ |p|
|
35
|
+
options[:import] = p
|
36
|
+
}
|
37
|
+
|
38
|
+
end.parse! argv
|
39
|
+
|
40
|
+
# ensure configuration
|
41
|
+
if ENV['DATABASE_URL']
|
42
|
+
options[:config] ||= config_from_url(ENV['DATABASE_URL'])
|
43
|
+
else
|
44
|
+
raise RuntimeError, "You must have configured database correctly"
|
45
|
+
end
|
46
|
+
|
47
|
+
# mapper
|
48
|
+
mapper = DbBackupTool::Mappers.build options[:config]
|
49
|
+
ActiveRecord::Base.logger = Logger.new($stdout)
|
50
|
+
|
51
|
+
# perform action
|
52
|
+
case action = argv.shift
|
53
|
+
when 'dump'
|
54
|
+
begin
|
55
|
+
DbBackupTool::Archiver.new(mapper).export(FileUtils.pwd)
|
56
|
+
end
|
57
|
+
when 'load'
|
58
|
+
begin
|
59
|
+
DbBackupTool::Archiver.new(mapper).import(options[:import])
|
60
|
+
end
|
61
|
+
else raise RuntimeError, "Unknown Action"
|
62
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'db_backup_tool/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |gem|
|
7
|
+
gem.name = "db_backup_tool"
|
8
|
+
gem.version = DbBackupTool::VERSION
|
9
|
+
gem.authors = ["David Lin"]
|
10
|
+
gem.email = ["davll.xc@gmail.com"]
|
11
|
+
gem.description = %q{A simple DB backup tool}
|
12
|
+
gem.summary = %q{A simple DB backup tool}
|
13
|
+
gem.homepage = "https://github.com/davll/db_backup_tool"
|
14
|
+
|
15
|
+
gem.files = `git ls-files`.split($/)
|
16
|
+
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
17
|
+
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
18
|
+
gem.require_paths = ["lib"]
|
19
|
+
|
20
|
+
gem.required_ruby_version = "~> 1.9.0"
|
21
|
+
|
22
|
+
gem.add_dependency "activesupport", "~> 3.2.8"
|
23
|
+
gem.add_dependency "activerecord", "~> 3.2.8"
|
24
|
+
gem.add_dependency "backports", "~> 2.6.4"
|
25
|
+
gem.add_dependency "taps", "~> 0.3.24"
|
26
|
+
gem.add_dependency "rubyzip", "~> 0.9.9"
|
27
|
+
|
28
|
+
gem.add_development_dependency "rake", "~> 0.9.2.2"
|
29
|
+
gem.add_development_dependency "minitest", "~> 4.1.0"
|
30
|
+
gem.add_development_dependency "mocha", "~> 0.12.7"
|
31
|
+
gem.add_development_dependency "factory_girl", "~> 4.1.0"
|
32
|
+
gem.add_development_dependency "sqlite3", "~> 1.3.6"
|
33
|
+
|
34
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
require 'zip/zip'
|
2
|
+
require 'yaml'
|
3
|
+
|
4
|
+
module DbBackupTool
|
5
|
+
class Archiver
|
6
|
+
|
7
|
+
def initialize(mapper)
|
8
|
+
@mapper = mapper
|
9
|
+
end
|
10
|
+
|
11
|
+
def tables; @mapper.tables; end
|
12
|
+
|
13
|
+
def export(output_directory)
|
14
|
+
# Create an archive file
|
15
|
+
path = File.join output_directory, "#{Time.now.to_i}.zip"
|
16
|
+
puts "output path: #{path}"
|
17
|
+
Zip::ZipFile.open(path, Zip::ZipFile::CREATE) do |zipfile|
|
18
|
+
zipfile.get_output_stream('tables.yml') { |f|
|
19
|
+
f.puts Hash[tables.each_with_index.map{|t,i|[i,t.first]}].to_yaml
|
20
|
+
}
|
21
|
+
tables.each_with_index do |t,i|
|
22
|
+
zipfile.get_output_stream("#{i}.csv") { |f|
|
23
|
+
DbBackupTool::Dumper.new(t.last).dump(f)
|
24
|
+
}
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def import(path)
|
30
|
+
tables = self.tables
|
31
|
+
Zip::ZipFile.open(path) do |zipfile|
|
32
|
+
table_map = YAML::load zipfile.read('tables.yml')
|
33
|
+
table_map.each do |i,tn|
|
34
|
+
zipfile.get_input_stream("#{i}.csv"){ |f|
|
35
|
+
DbBackupTool::Loader.new(tables[tn]).load(f)
|
36
|
+
} if tables.has_key?(tn)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require 'csv'
|
2
|
+
class DbBackupTool::Dumper
|
3
|
+
|
4
|
+
def initialize(table, options = {})
|
5
|
+
@table, @options = table, options.dup
|
6
|
+
end
|
7
|
+
|
8
|
+
def dump(io)
|
9
|
+
csv = CSV.new(io, headers: true, write_headers: true)
|
10
|
+
csv << @table.column_names
|
11
|
+
@table.each_record(batch_size) do |record|
|
12
|
+
csv << record.values_at(*(@table.column_names))
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def batch_size
|
17
|
+
@options[:batch_size] || 1000
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'csv'
|
2
|
+
class DbBackupTool::Loader
|
3
|
+
|
4
|
+
def initialize(table, options = {})
|
5
|
+
@table, @options = table, options.dup
|
6
|
+
end
|
7
|
+
|
8
|
+
def load(io)
|
9
|
+
csv = CSV.new(io, headers: true)
|
10
|
+
|
11
|
+
@table.truncate
|
12
|
+
csv.each_slice(batch_size) do |rows|
|
13
|
+
@table.update rows.map(&:to_hash)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def batch_size
|
18
|
+
@options[:batch_size] || 1000
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
@@ -0,0 +1,98 @@
|
|
1
|
+
require 'active_record'
|
2
|
+
|
3
|
+
class DbBackupTool::Mappers::ActiveRecordMapper
|
4
|
+
|
5
|
+
# Constructor
|
6
|
+
def initialize(config)
|
7
|
+
@orm = Class.new(ActiveRecord::Base) {
|
8
|
+
self.abstract_class = true
|
9
|
+
establish_connection(config)
|
10
|
+
}
|
11
|
+
end
|
12
|
+
|
13
|
+
# :internal
|
14
|
+
def connection
|
15
|
+
@orm.connection
|
16
|
+
end
|
17
|
+
|
18
|
+
# Return tables (proxy) in the database
|
19
|
+
def tables
|
20
|
+
table_names = @orm.connection.tables.dup
|
21
|
+
table_names.reject! {|t| %w(schema_info schema_migrations).include? t }
|
22
|
+
Hash[ table_names.map {|t| [t, Table.new(@orm, t)] } ].freeze
|
23
|
+
end
|
24
|
+
|
25
|
+
# Table Proxy
|
26
|
+
class Table
|
27
|
+
|
28
|
+
# Constructor
|
29
|
+
def initialize(orm_class, table_name)
|
30
|
+
@model = Class.new(orm_class) {
|
31
|
+
self.table_name = table_name
|
32
|
+
}
|
33
|
+
end
|
34
|
+
|
35
|
+
# Table name
|
36
|
+
def name
|
37
|
+
@model.table_name
|
38
|
+
end
|
39
|
+
|
40
|
+
# Names of columns
|
41
|
+
def column_names
|
42
|
+
@model.columns.map(&:name)
|
43
|
+
end
|
44
|
+
|
45
|
+
# Clear the table
|
46
|
+
def truncate
|
47
|
+
begin
|
48
|
+
@model.connection.execute "TRUNCATE #{@model.quoted_table_name}"
|
49
|
+
rescue ActiveRecord::ActiveRecordError
|
50
|
+
begin
|
51
|
+
@model.connection.execute "DELETE FROM #{@model.quoted_table_name}"
|
52
|
+
rescue ActiveRecord::ActiveRecordError
|
53
|
+
@model.connection.execute "DELETE * FROM #{@model.quoted_table_name}"
|
54
|
+
end
|
55
|
+
end
|
56
|
+
if @model.connection.respond_to? :reset_pk_sequence!
|
57
|
+
@model.connection.reset_pk_sequence! (@model.table_name)
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
# Enumerate records in the table
|
62
|
+
def each_record(batch_size = 1000)
|
63
|
+
if block_given?
|
64
|
+
@model.find_each(batch_size: batch_size) do |r|
|
65
|
+
yield record_hash(r)
|
66
|
+
end
|
67
|
+
else
|
68
|
+
Enumerator.new self, :each_record
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
# Update or create records
|
73
|
+
def update(records)
|
74
|
+
raise ArgumentError unless records.is_a?(Enumerable)
|
75
|
+
@model.transaction do
|
76
|
+
records.each {|attributes|
|
77
|
+
id = attributes['id']
|
78
|
+
r = @model.find_or_initialize_by_id(id)
|
79
|
+
r.id ||= id
|
80
|
+
r.assign_attributes attributes.except('id')
|
81
|
+
r.save!
|
82
|
+
}
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
private
|
87
|
+
|
88
|
+
# Wrap the record object into hash to prevent from hacking
|
89
|
+
def record_hash(record)
|
90
|
+
hash = Hash[ column_names.map{|c| [c, record[c]] } ]
|
91
|
+
def hash.method_missing(symbol, *args)
|
92
|
+
(has_key?(symbol.to_s) ? self[symbol.to_s] : super(symbol, *args) )
|
93
|
+
end
|
94
|
+
hash
|
95
|
+
end
|
96
|
+
|
97
|
+
end
|
98
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module DbBackupTool::Mappers
|
2
|
+
|
3
|
+
def self.build(config)
|
4
|
+
config = config.dup
|
5
|
+
orm = ( config.has_key?(:orm) ? config.delete(:orm) : :active_record )
|
6
|
+
self.send :"build_#{orm}", config
|
7
|
+
end
|
8
|
+
|
9
|
+
private
|
10
|
+
|
11
|
+
def self.build_active_record(config)
|
12
|
+
require_relative "mappers/active_record_mapper"
|
13
|
+
ActiveRecordMapper.new(config)
|
14
|
+
end
|
15
|
+
|
16
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
require "active_support/core_ext"
|
2
|
+
require "backports"
|
3
|
+
|
4
|
+
require_relative "db_backup_tool/version"
|
5
|
+
require_relative 'db_backup_tool/mappers'
|
6
|
+
require_relative 'db_backup_tool/dumper'
|
7
|
+
require_relative 'db_backup_tool/loader'
|
8
|
+
require_relative 'db_backup_tool/archiver'
|
9
|
+
|
10
|
+
module DbBackupTool
|
11
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'db_backup_tool/mappers/active_record_mapper'
|
3
|
+
|
4
|
+
module DbBackupTool
|
5
|
+
describe Mappers::ActiveRecordMapper do
|
6
|
+
include TestHelper::MapperHelpers
|
7
|
+
before do
|
8
|
+
@mapper = active_record_mapper_with_schema
|
9
|
+
end
|
10
|
+
|
11
|
+
it "should list tables" do
|
12
|
+
@mapper.tables.keys.must_equal ['members']
|
13
|
+
end
|
14
|
+
|
15
|
+
it "can read columns" do
|
16
|
+
table = @mapper.tables['members']
|
17
|
+
table.name.must_equal 'members'
|
18
|
+
table.must_be_kind_of Mappers::ActiveRecordMapper::Table
|
19
|
+
table.column_names.must_equal %w(id name gender_id)
|
20
|
+
end
|
21
|
+
|
22
|
+
describe "with records" do
|
23
|
+
before do
|
24
|
+
@table = @mapper.tables['members']
|
25
|
+
|
26
|
+
@data = [
|
27
|
+
{ name: 'Adam Jensen', gender_id: 1 },
|
28
|
+
{ name: 'Nathan Drake', gender_id: 1 },
|
29
|
+
{ name: 'Lara Croft', gender_id: 2 }
|
30
|
+
]
|
31
|
+
|
32
|
+
# create records via #update
|
33
|
+
@table.update(@data)
|
34
|
+
end
|
35
|
+
|
36
|
+
it "can read records" do
|
37
|
+
@table.each_record.map(&:name).must_equal @data.map{|e|e[:name]}
|
38
|
+
end
|
39
|
+
|
40
|
+
it "can read records in specific batch sizes" do
|
41
|
+
@table.each_record(1).map(&:name).must_equal @data.map{|e|e[:name]}
|
42
|
+
@table.each_record(2).map(&:name).must_equal @data.map{|e|e[:name]}
|
43
|
+
@table.each_record(3).map(&:name).must_equal @data.map{|e|e[:name]}
|
44
|
+
end
|
45
|
+
|
46
|
+
it "can truncate the whole table" do
|
47
|
+
@table.truncate
|
48
|
+
@table.each_record.count.must_equal 0
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
data/spec/dumper_spec.rb
ADDED
@@ -0,0 +1,38 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module DbBackupTool
|
4
|
+
describe Dumper do
|
5
|
+
include TestHelper::MapperHelpers
|
6
|
+
before do
|
7
|
+
@mapper = active_record_mapper_with_schema
|
8
|
+
table = @mapper.tables['members']
|
9
|
+
|
10
|
+
record_data = [
|
11
|
+
{ name: 'Adam Jensen', gender_id: 1 },
|
12
|
+
{ name: 'Nathan Drake', gender_id: 1 },
|
13
|
+
{ name: 'Lara Croft', gender_id: 2 }
|
14
|
+
]
|
15
|
+
table.update(record_data)
|
16
|
+
|
17
|
+
@expected_data =<<-CSV
|
18
|
+
id,name,gender_id
|
19
|
+
1,Adam Jensen,1
|
20
|
+
2,Nathan Drake,1
|
21
|
+
3,Lara Croft,2
|
22
|
+
CSV
|
23
|
+
|
24
|
+
@dumper = Dumper.new(table)
|
25
|
+
end
|
26
|
+
|
27
|
+
it "should be a dumper, and can dump" do
|
28
|
+
@dumper.must_be_kind_of Dumper
|
29
|
+
|
30
|
+
io = StringIO.new
|
31
|
+
@dumper.dump(io)
|
32
|
+
io.close
|
33
|
+
|
34
|
+
io.string.must_equal @expected_data
|
35
|
+
end
|
36
|
+
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module DbBackupTool
|
2
|
+
module TestHelper
|
3
|
+
module MapperHelpers
|
4
|
+
|
5
|
+
def active_record_mapper
|
6
|
+
config = { adapter: 'sqlite3', database: ':memory:' }
|
7
|
+
Mappers::ActiveRecordMapper.new(config)
|
8
|
+
end
|
9
|
+
|
10
|
+
def active_record_mapper_with_schema
|
11
|
+
mapper = active_record_mapper
|
12
|
+
|
13
|
+
ActiveRecord::Schema.define do
|
14
|
+
@connection = mapper.connection
|
15
|
+
create_table :members do |t|
|
16
|
+
t.string :name
|
17
|
+
t.integer :gender_id
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
mapper
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
data/spec/loader_spec.rb
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module DbBackupTool
|
4
|
+
describe Loader do
|
5
|
+
include TestHelper::MapperHelpers
|
6
|
+
before do
|
7
|
+
@mapper = active_record_mapper_with_schema
|
8
|
+
@table = @mapper.tables['members']
|
9
|
+
|
10
|
+
@dumped_data =<<-CSV
|
11
|
+
id,name,gender_id
|
12
|
+
1,Adam Jensen,1
|
13
|
+
2,Nathan Drake,1
|
14
|
+
3,Lara Croft,2
|
15
|
+
CSV
|
16
|
+
|
17
|
+
@loader = Loader.new(@table)
|
18
|
+
end
|
19
|
+
|
20
|
+
it "should be a loader, and can load" do
|
21
|
+
@loader.must_be_kind_of Loader
|
22
|
+
@loader.load(StringIO.new @dumped_data)
|
23
|
+
|
24
|
+
@table.each_record.map(&:name).must_equal [
|
25
|
+
'Adam Jensen', 'Nathan Drake', 'Lara Croft'
|
26
|
+
]
|
27
|
+
@table.each_record.map(&:id).must_equal (1..3).to_a
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module DbBackupTool
|
4
|
+
describe Mappers do
|
5
|
+
before { @config = { adapter: 'sqlite3', database: ':memory:' } }
|
6
|
+
|
7
|
+
it "should build a ActiveRecordMapper by default" do
|
8
|
+
@config.wont_include :orm
|
9
|
+
mapper = Mappers.build(@config)
|
10
|
+
mapper.must_be_kind_of Mappers::ActiveRecordMapper
|
11
|
+
end
|
12
|
+
|
13
|
+
end
|
14
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
# Bundler
|
2
|
+
require "rubygems"
|
3
|
+
require "bundler/setup"
|
4
|
+
|
5
|
+
# Test Framework
|
6
|
+
require "minitest/autorun"
|
7
|
+
require "mocha"
|
8
|
+
require "factory_girl"
|
9
|
+
|
10
|
+
#
|
11
|
+
require 'db_backup_tool'
|
12
|
+
|
13
|
+
#
|
14
|
+
SPEC_ROOT = File.expand_path("..", __FILE__)
|
15
|
+
|
16
|
+
# load factories
|
17
|
+
Dir[File.join(SPEC_ROOT, "factories/**/*.rb")].each {|f| require f }
|
metadata
ADDED
@@ -0,0 +1,232 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: db_backup_tool
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- David Lin
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2012-11-07 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: activesupport
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ~>
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: 3.2.8
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ~>
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: 3.2.8
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: activerecord
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
34
|
+
requirements:
|
35
|
+
- - ~>
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: 3.2.8
|
38
|
+
type: :runtime
|
39
|
+
prerelease: false
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ~>
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: 3.2.8
|
46
|
+
- !ruby/object:Gem::Dependency
|
47
|
+
name: backports
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
49
|
+
none: false
|
50
|
+
requirements:
|
51
|
+
- - ~>
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: 2.6.4
|
54
|
+
type: :runtime
|
55
|
+
prerelease: false
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
58
|
+
requirements:
|
59
|
+
- - ~>
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: 2.6.4
|
62
|
+
- !ruby/object:Gem::Dependency
|
63
|
+
name: taps
|
64
|
+
requirement: !ruby/object:Gem::Requirement
|
65
|
+
none: false
|
66
|
+
requirements:
|
67
|
+
- - ~>
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: 0.3.24
|
70
|
+
type: :runtime
|
71
|
+
prerelease: false
|
72
|
+
version_requirements: !ruby/object:Gem::Requirement
|
73
|
+
none: false
|
74
|
+
requirements:
|
75
|
+
- - ~>
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
version: 0.3.24
|
78
|
+
- !ruby/object:Gem::Dependency
|
79
|
+
name: rubyzip
|
80
|
+
requirement: !ruby/object:Gem::Requirement
|
81
|
+
none: false
|
82
|
+
requirements:
|
83
|
+
- - ~>
|
84
|
+
- !ruby/object:Gem::Version
|
85
|
+
version: 0.9.9
|
86
|
+
type: :runtime
|
87
|
+
prerelease: false
|
88
|
+
version_requirements: !ruby/object:Gem::Requirement
|
89
|
+
none: false
|
90
|
+
requirements:
|
91
|
+
- - ~>
|
92
|
+
- !ruby/object:Gem::Version
|
93
|
+
version: 0.9.9
|
94
|
+
- !ruby/object:Gem::Dependency
|
95
|
+
name: rake
|
96
|
+
requirement: !ruby/object:Gem::Requirement
|
97
|
+
none: false
|
98
|
+
requirements:
|
99
|
+
- - ~>
|
100
|
+
- !ruby/object:Gem::Version
|
101
|
+
version: 0.9.2.2
|
102
|
+
type: :development
|
103
|
+
prerelease: false
|
104
|
+
version_requirements: !ruby/object:Gem::Requirement
|
105
|
+
none: false
|
106
|
+
requirements:
|
107
|
+
- - ~>
|
108
|
+
- !ruby/object:Gem::Version
|
109
|
+
version: 0.9.2.2
|
110
|
+
- !ruby/object:Gem::Dependency
|
111
|
+
name: minitest
|
112
|
+
requirement: !ruby/object:Gem::Requirement
|
113
|
+
none: false
|
114
|
+
requirements:
|
115
|
+
- - ~>
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: 4.1.0
|
118
|
+
type: :development
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
none: false
|
122
|
+
requirements:
|
123
|
+
- - ~>
|
124
|
+
- !ruby/object:Gem::Version
|
125
|
+
version: 4.1.0
|
126
|
+
- !ruby/object:Gem::Dependency
|
127
|
+
name: mocha
|
128
|
+
requirement: !ruby/object:Gem::Requirement
|
129
|
+
none: false
|
130
|
+
requirements:
|
131
|
+
- - ~>
|
132
|
+
- !ruby/object:Gem::Version
|
133
|
+
version: 0.12.7
|
134
|
+
type: :development
|
135
|
+
prerelease: false
|
136
|
+
version_requirements: !ruby/object:Gem::Requirement
|
137
|
+
none: false
|
138
|
+
requirements:
|
139
|
+
- - ~>
|
140
|
+
- !ruby/object:Gem::Version
|
141
|
+
version: 0.12.7
|
142
|
+
- !ruby/object:Gem::Dependency
|
143
|
+
name: factory_girl
|
144
|
+
requirement: !ruby/object:Gem::Requirement
|
145
|
+
none: false
|
146
|
+
requirements:
|
147
|
+
- - ~>
|
148
|
+
- !ruby/object:Gem::Version
|
149
|
+
version: 4.1.0
|
150
|
+
type: :development
|
151
|
+
prerelease: false
|
152
|
+
version_requirements: !ruby/object:Gem::Requirement
|
153
|
+
none: false
|
154
|
+
requirements:
|
155
|
+
- - ~>
|
156
|
+
- !ruby/object:Gem::Version
|
157
|
+
version: 4.1.0
|
158
|
+
- !ruby/object:Gem::Dependency
|
159
|
+
name: sqlite3
|
160
|
+
requirement: !ruby/object:Gem::Requirement
|
161
|
+
none: false
|
162
|
+
requirements:
|
163
|
+
- - ~>
|
164
|
+
- !ruby/object:Gem::Version
|
165
|
+
version: 1.3.6
|
166
|
+
type: :development
|
167
|
+
prerelease: false
|
168
|
+
version_requirements: !ruby/object:Gem::Requirement
|
169
|
+
none: false
|
170
|
+
requirements:
|
171
|
+
- - ~>
|
172
|
+
- !ruby/object:Gem::Version
|
173
|
+
version: 1.3.6
|
174
|
+
description: A simple DB backup tool
|
175
|
+
email:
|
176
|
+
- davll.xc@gmail.com
|
177
|
+
executables:
|
178
|
+
- db_backup_tool
|
179
|
+
extensions: []
|
180
|
+
extra_rdoc_files: []
|
181
|
+
files:
|
182
|
+
- .gitignore
|
183
|
+
- Gemfile
|
184
|
+
- LICENSE.txt
|
185
|
+
- README.md
|
186
|
+
- Rakefile
|
187
|
+
- bin/db_backup_tool
|
188
|
+
- db_backup_tool.gemspec
|
189
|
+
- lib/db_backup_tool.rb
|
190
|
+
- lib/db_backup_tool/archiver.rb
|
191
|
+
- lib/db_backup_tool/dumper.rb
|
192
|
+
- lib/db_backup_tool/loader.rb
|
193
|
+
- lib/db_backup_tool/mappers.rb
|
194
|
+
- lib/db_backup_tool/mappers/active_record_mapper.rb
|
195
|
+
- lib/db_backup_tool/version.rb
|
196
|
+
- spec/active_record_mapper_spec.rb
|
197
|
+
- spec/dumper_spec.rb
|
198
|
+
- spec/factories/mappers.rb
|
199
|
+
- spec/loader_spec.rb
|
200
|
+
- spec/mappers_spec.rb
|
201
|
+
- spec/spec_helper.rb
|
202
|
+
homepage: https://github.com/davll/db_backup_tool
|
203
|
+
licenses: []
|
204
|
+
post_install_message:
|
205
|
+
rdoc_options: []
|
206
|
+
require_paths:
|
207
|
+
- lib
|
208
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
209
|
+
none: false
|
210
|
+
requirements:
|
211
|
+
- - ~>
|
212
|
+
- !ruby/object:Gem::Version
|
213
|
+
version: 1.9.0
|
214
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
215
|
+
none: false
|
216
|
+
requirements:
|
217
|
+
- - ! '>='
|
218
|
+
- !ruby/object:Gem::Version
|
219
|
+
version: '0'
|
220
|
+
requirements: []
|
221
|
+
rubyforge_project:
|
222
|
+
rubygems_version: 1.8.24
|
223
|
+
signing_key:
|
224
|
+
specification_version: 3
|
225
|
+
summary: A simple DB backup tool
|
226
|
+
test_files:
|
227
|
+
- spec/active_record_mapper_spec.rb
|
228
|
+
- spec/dumper_spec.rb
|
229
|
+
- spec/factories/mappers.rb
|
230
|
+
- spec/loader_spec.rb
|
231
|
+
- spec/mappers_spec.rb
|
232
|
+
- spec/spec_helper.rb
|