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 ADDED
@@ -0,0 +1,19 @@
1
+ *.gem
2
+ *.rbc
3
+ *~
4
+ .bundle
5
+ .config
6
+ .yardoc
7
+ Gemfile.lock
8
+ InstalledFiles
9
+ _yardoc
10
+ coverage
11
+ doc/
12
+ lib/bundler/man
13
+ pkg
14
+ rdoc
15
+ spec/reports
16
+ test/tmp
17
+ test/version_tmp
18
+ tmp
19
+ .DS_Store
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in db_backup_tool.gemspec
4
+ gemspec
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
@@ -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,3 @@
1
+ module DbBackupTool
2
+ VERSION = "0.0.1"
3
+ 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
@@ -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
@@ -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
@@ -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