dbmanager 0.1.7 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.rvmrc +1 -0
- data/.travis.yml +8 -0
- data/CHANGELOG.md +5 -0
- data/README.md +16 -2
- data/dbmanager.gemspec +3 -3
- data/features/readme.md +16 -2
- data/features/support/dummy_app_initialization.rb +1 -0
- data/lib/dbmanager.rb +4 -7
- data/lib/dbmanager/adapters/mysql.rb +28 -15
- data/lib/dbmanager/dumper.rb +31 -0
- data/lib/dbmanager/importer.rb +31 -0
- data/lib/dbmanager/loader.rb +31 -0
- data/lib/dbmanager/runner.rb +27 -22
- data/lib/dbmanager/version.rb +1 -1
- data/lib/tasks/dbmanager.rake +9 -3
- data/spec/dummy/config/database.yml +2 -2
- data/spec/dummy/rerun.txt +1 -0
- data/spec/lib/adapters/mysql_spec.rb +52 -18
- data/spec/lib/dbmanager_spec.rb +1 -1
- data/spec/lib/dumper_spec.rb +28 -0
- data/spec/lib/{importable_spec.rb → importer_spec.rb} +31 -38
- data/spec/lib/loader_spec.rb +29 -0
- data/spec/lib/runner_spec.rb +46 -14
- data/spec/lib/yml_parser_spec.rb +0 -1
- data/spec/spec_helper.rb +19 -4
- metadata +36 -15
- data/lib/dbmanager/dumpable.rb +0 -41
- data/lib/dbmanager/importable.rb +0 -41
- data/spec/lib/dumpable_spec.rb +0 -38
- data/spec/support/std_stub.rb +0 -6
data/.rvmrc
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
rvm ruby-1.9.3
|
data/.travis.yml
ADDED
data/CHANGELOG.md
CHANGED
data/README.md
CHANGED
@@ -53,9 +53,19 @@ string 'production' in their name are protected by default, which means you cann
|
|
53
53
|
overwrite them unless you explicitly override this setting in the override file
|
54
54
|
(see next section for more info).
|
55
55
|
|
56
|
-
#### BEWARE
|
57
56
|
|
58
|
-
|
57
|
+
#### Database Loads
|
58
|
+
|
59
|
+
```ruby
|
60
|
+
rake db:load
|
61
|
+
```
|
62
|
+
|
63
|
+
This rake task will load the db data from a dump file.
|
64
|
+
|
65
|
+
You will be prompted to choose the source file (defaults to *tmp/{db_name}.sql* in the rails
|
66
|
+
root) and the target environment.
|
67
|
+
|
68
|
+
**Import and load processes are destructive** so be careful on which environment you
|
59
69
|
choose to overwite. I take no responsibility for misuse or bugs in the code ;-)
|
60
70
|
|
61
71
|
|
@@ -115,6 +125,10 @@ run rspec tests: ```rake```
|
|
115
125
|
|
116
126
|
run cucumber tests: ```cucumber```
|
117
127
|
|
128
|
+
Cucumber tests require mysql server running. Update spec/dummy/config/database.yml
|
129
|
+
with your mysql configuration, if necessary.
|
130
|
+
|
131
|
+
|
118
132
|
|
119
133
|
### TODO
|
120
134
|
|
data/dbmanager.gemspec
CHANGED
@@ -19,10 +19,10 @@ Gem::Specification.new do |s|
|
|
19
19
|
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
20
20
|
s.require_paths = ["lib"]
|
21
21
|
|
22
|
-
s.add_dependency '
|
23
|
-
|
24
|
-
s.add_development_dependency 'rspec'
|
22
|
+
s.add_dependency 'rails'
|
23
|
+
s.add_development_dependency 'rspec', '~> 2.12'
|
25
24
|
s.add_development_dependency 'rake'
|
25
|
+
s.add_development_dependency 'mysql2'
|
26
26
|
s.add_development_dependency 'cucumber'
|
27
27
|
s.add_development_dependency 'guard-rspec'
|
28
28
|
s.add_development_dependency 'guard-cucumber'
|
data/features/readme.md
CHANGED
@@ -53,9 +53,19 @@ string 'production' in their name are protected by default, which means you cann
|
|
53
53
|
overwrite them unless you explicitly override this setting in the override file
|
54
54
|
(see next section for more info).
|
55
55
|
|
56
|
-
#### BEWARE
|
57
56
|
|
58
|
-
|
57
|
+
#### Database Loads
|
58
|
+
|
59
|
+
```ruby
|
60
|
+
rake db:load
|
61
|
+
```
|
62
|
+
|
63
|
+
This rake task will load the db data from a dump file.
|
64
|
+
|
65
|
+
You will be prompted to choose the source file (defaults to *tmp/{db_name}.sql* in the rails
|
66
|
+
root) and the target environment.
|
67
|
+
|
68
|
+
**Import and load processes are destructive** so be careful on which environment you
|
59
69
|
choose to overwite. I take no responsibility for misuse or bugs in the code ;-)
|
60
70
|
|
61
71
|
|
@@ -115,6 +125,10 @@ run rspec tests: ```rake```
|
|
115
125
|
|
116
126
|
run cucumber tests: ```cucumber```
|
117
127
|
|
128
|
+
Cucumber tests require mysql server running. Update spec/dummy/config/database.yml
|
129
|
+
with your mysql configuration, if necessary.
|
130
|
+
|
131
|
+
|
118
132
|
|
119
133
|
### TODO
|
120
134
|
|
data/lib/dbmanager.rb
CHANGED
@@ -1,15 +1,12 @@
|
|
1
|
-
require 'active_support/
|
2
|
-
require 'active_support/core_ext/module'
|
3
|
-
require 'active_support/ordered_hash'
|
4
|
-
require 'active_support/core_ext/enumerable'
|
5
|
-
require 'active_support/core_ext/object/blank'
|
1
|
+
require 'active_support/all'
|
6
2
|
|
7
3
|
module Dbmanager
|
8
4
|
autoload :Environment, 'dbmanager/environment'
|
9
5
|
autoload :YmlParser, 'dbmanager/yml_parser'
|
10
6
|
autoload :Runner, 'dbmanager/runner'
|
11
|
-
autoload :
|
12
|
-
autoload :
|
7
|
+
autoload :Importer, 'dbmanager/importer'
|
8
|
+
autoload :Dumper, 'dbmanager/dumper'
|
9
|
+
autoload :Loader, 'dbmanager/loader'
|
13
10
|
autoload :Adapters, 'dbmanager/adapters'
|
14
11
|
|
15
12
|
class EnvironmentProtectedError < StandardError
|
@@ -40,39 +40,52 @@ module Dbmanager
|
|
40
40
|
end
|
41
41
|
end
|
42
42
|
|
43
|
-
class
|
43
|
+
class Loader
|
44
44
|
include Connectable
|
45
|
-
attr_reader :
|
45
|
+
attr_reader :target, :tmp_file
|
46
46
|
|
47
|
-
def initialize(
|
48
|
-
@source = source
|
47
|
+
def initialize(target, tmp_file)
|
49
48
|
@target = target
|
50
49
|
@tmp_file = tmp_file
|
51
50
|
end
|
52
51
|
|
53
52
|
def run
|
54
|
-
Dumper.new(source, tmp_file).run
|
55
53
|
Dbmanager.execute! create_db_if_missing_command
|
56
|
-
Dbmanager.execute!
|
57
|
-
ensure
|
58
|
-
remove_tmp_file
|
54
|
+
Dbmanager.execute! load_command
|
59
55
|
end
|
60
56
|
|
61
|
-
def
|
57
|
+
def load_command
|
62
58
|
"mysql #{params(target)} < '#{tmp_file}'"
|
63
59
|
end
|
64
60
|
|
65
|
-
def remove_tmp_file
|
66
|
-
Dbmanager.execute "rm '#{tmp_file}'"
|
67
|
-
end
|
68
|
-
|
69
61
|
def create_db_if_missing_command
|
70
|
-
# it is safe to hardcode bundle exec here?
|
71
62
|
"#{bundle} rake db:create RAILS_ENV=#{target.name}"
|
72
63
|
end
|
73
64
|
|
74
65
|
def bundle
|
75
|
-
Dbmanager.execute('which bundle') ? 'bundle exec' : nil
|
66
|
+
Dbmanager.execute('which bundle > /dev/null') ? 'bundle exec' : nil
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
class Importer
|
71
|
+
include Connectable
|
72
|
+
attr_reader :source, :target, :tmp_file
|
73
|
+
|
74
|
+
def initialize(source, target, tmp_file)
|
75
|
+
@source = source
|
76
|
+
@target = target
|
77
|
+
@tmp_file = tmp_file
|
78
|
+
end
|
79
|
+
|
80
|
+
def run
|
81
|
+
Dumper.new(source, tmp_file).run
|
82
|
+
Loader.new(target, tmp_file).run
|
83
|
+
ensure
|
84
|
+
remove_tmp_file
|
85
|
+
end
|
86
|
+
|
87
|
+
def remove_tmp_file
|
88
|
+
Dbmanager.execute "rm '#{tmp_file}'"
|
76
89
|
end
|
77
90
|
end
|
78
91
|
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module Dbmanager
|
2
|
+
class Dumper < Runner
|
3
|
+
|
4
|
+
attr_accessor :filename, :source
|
5
|
+
|
6
|
+
def run
|
7
|
+
get_data
|
8
|
+
dumper.run
|
9
|
+
output.puts "Database successfully dumped in #{filename} file."
|
10
|
+
end
|
11
|
+
|
12
|
+
private
|
13
|
+
|
14
|
+
def get_data
|
15
|
+
self.source = get_env('source')
|
16
|
+
self.filename = get_filename('target', default_filename)
|
17
|
+
end
|
18
|
+
|
19
|
+
def dumper
|
20
|
+
adapter::Dumper.new(source, filename)
|
21
|
+
end
|
22
|
+
|
23
|
+
def adapter
|
24
|
+
Dbmanager::Adapters.const_get source.adapter.capitalize
|
25
|
+
end
|
26
|
+
|
27
|
+
def default_filename
|
28
|
+
Dbmanager.rails_root.join "tmp/#{source.database}.sql"
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module Dbmanager
|
2
|
+
class Importer < Runner
|
3
|
+
|
4
|
+
attr_accessor :target, :source
|
5
|
+
|
6
|
+
def run
|
7
|
+
get_data
|
8
|
+
raise EnvironmentProtectedError if target.protected?
|
9
|
+
execute_import
|
10
|
+
output.puts 'Database Import completed.'
|
11
|
+
end
|
12
|
+
|
13
|
+
def get_data
|
14
|
+
self.source = get_env('source')
|
15
|
+
self.target = get_env('target')
|
16
|
+
end
|
17
|
+
|
18
|
+
def execute_import
|
19
|
+
adapter::Importer.new(source, target, tmp_file).run
|
20
|
+
end
|
21
|
+
|
22
|
+
def adapter
|
23
|
+
raise MixedAdapterError if source.adapter != target.adapter
|
24
|
+
Dbmanager::Adapters.const_get source.adapter.capitalize
|
25
|
+
end
|
26
|
+
|
27
|
+
def tmp_file
|
28
|
+
@tmp_file ||= File.join Dbmanager.rails_root, 'tmp', Time.now.strftime('%y%m%d%H%M%S')
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module Dbmanager
|
2
|
+
class Loader < Runner
|
3
|
+
|
4
|
+
attr_accessor :filename, :target
|
5
|
+
|
6
|
+
def run
|
7
|
+
get_data
|
8
|
+
loader.run
|
9
|
+
output.puts "Database successfully loaded from #{filename}."
|
10
|
+
end
|
11
|
+
|
12
|
+
private
|
13
|
+
|
14
|
+
def get_data
|
15
|
+
self.target = get_env('target')
|
16
|
+
self.filename = get_filename('source', default_filename)
|
17
|
+
end
|
18
|
+
|
19
|
+
def loader
|
20
|
+
adapter::Loader.new(target, filename)
|
21
|
+
end
|
22
|
+
|
23
|
+
def adapter
|
24
|
+
Dbmanager::Adapters.const_get target.adapter.capitalize
|
25
|
+
end
|
26
|
+
|
27
|
+
def default_filename
|
28
|
+
Dbmanager.rails_root.join "tmp/#{target.database}.sql"
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
data/lib/dbmanager/runner.rb
CHANGED
@@ -1,47 +1,52 @@
|
|
1
|
-
# The runner main responsibility is to interact with the user in order to gather
|
2
|
-
# the information to accomplish the task.
|
3
|
-
#
|
4
|
-
# The runner object cannot do much when freshly instantiated, so for each kind
|
5
|
-
# of available task there is a corresponding module that can extend the runner
|
6
|
-
# so that it can accomplish its goal.
|
7
|
-
#
|
8
|
-
# Extension modules must define the #run method which contains the specific
|
9
|
-
# behaviour they provide.
|
10
|
-
|
11
1
|
module Dbmanager
|
12
2
|
class Runner
|
13
|
-
attr_reader :input, :output, :environments
|
14
|
-
|
15
|
-
def self.run(module_name)
|
16
|
-
runner = new
|
17
|
-
runner.extend Dbmanager.const_get(module_name.capitalize)
|
18
|
-
runner.run
|
19
|
-
end
|
3
|
+
attr_reader :input, :output, :environments
|
20
4
|
|
21
5
|
def initialize(input=STDIN, output=STDOUT)
|
22
6
|
@input = input
|
23
7
|
@output = output
|
24
8
|
@environments = YmlParser.environments
|
25
|
-
@source = get_env
|
26
9
|
end
|
27
10
|
|
28
|
-
def get_env(type
|
11
|
+
def get_env(type)
|
29
12
|
output.puts "\nPlease choose #{type} db:\n\n"
|
30
|
-
|
13
|
+
choose_environment
|
14
|
+
end
|
15
|
+
|
16
|
+
def get_filename(type, default_filename)
|
17
|
+
output.print "\nPlease choose #{type} file (defaults to #{default_filename}): "
|
18
|
+
filename = get_input
|
19
|
+
if filename.blank?
|
20
|
+
default_filename
|
21
|
+
else
|
22
|
+
absolute_path(filename)
|
23
|
+
end
|
31
24
|
end
|
32
25
|
|
33
26
|
private
|
34
27
|
|
35
|
-
def
|
28
|
+
def absolute_path(filename)
|
29
|
+
if filename.first == '/'
|
30
|
+
filename
|
31
|
+
else
|
32
|
+
Dbmanager.rails_root.join(filename)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def choose_environment
|
36
37
|
environments.keys.each_with_index do |name, i|
|
37
38
|
output.puts "#{i+1}) #{name}"
|
38
39
|
end
|
39
40
|
output.puts
|
40
41
|
pos = ''
|
41
42
|
until (1..environments.size).include? pos
|
42
|
-
pos =
|
43
|
+
pos = get_input.to_i
|
43
44
|
end
|
44
45
|
environments.values[pos-1]
|
45
46
|
end
|
47
|
+
|
48
|
+
def get_input
|
49
|
+
input.gets.to_s.strip
|
50
|
+
end
|
46
51
|
end
|
47
52
|
end
|
data/lib/dbmanager/version.rb
CHANGED
data/lib/tasks/dbmanager.rake
CHANGED
@@ -2,12 +2,18 @@ namespace :db do
|
|
2
2
|
desc 'import specific environment db data into another environment db'
|
3
3
|
task :import do
|
4
4
|
require 'dbmanager'
|
5
|
-
Dbmanager::
|
5
|
+
Dbmanager::Importer.new.run
|
6
6
|
end
|
7
7
|
|
8
|
-
desc 'dump specific environment db data
|
8
|
+
desc 'dump specific environment db data to a file'
|
9
9
|
task :dump do
|
10
10
|
require 'dbmanager'
|
11
|
-
Dbmanager::
|
11
|
+
Dbmanager::Dumper.new.run
|
12
|
+
end
|
13
|
+
|
14
|
+
desc 'load specific environment db data from a file'
|
15
|
+
task :load do
|
16
|
+
require 'dbmanager'
|
17
|
+
Dbmanager::Loader.new.run
|
12
18
|
end
|
13
19
|
end
|
@@ -0,0 +1 @@
|
|
1
|
+
features/dump.feature:12
|
@@ -4,6 +4,8 @@ module Dbmanager
|
|
4
4
|
module Adapters
|
5
5
|
module Mysql
|
6
6
|
describe Dumper do
|
7
|
+
before { Dbmanager.stub :output => STDStub.new }
|
8
|
+
|
7
9
|
let :source do
|
8
10
|
Environment.new(
|
9
11
|
:username => 'root',
|
@@ -45,21 +47,23 @@ module Dbmanager
|
|
45
47
|
end
|
46
48
|
end
|
47
49
|
|
48
|
-
describe
|
50
|
+
describe Loader do
|
51
|
+
before { Dbmanager.stub :output => STDStub.new }
|
52
|
+
|
49
53
|
describe 'an importer instance' do
|
50
54
|
before { Time.stub! :now => Time.parse('2012/03/23 12:30:32') }
|
51
55
|
let(:source) { Environment.new :protected => false, :name => 'development', :username => 'root' }
|
52
56
|
let(:target) { Environment.new :protected => false, :name => 'beta', :username => 'beta_user' }
|
53
57
|
let(:tmp_file) { '/some/arbitrary/path' }
|
54
|
-
subject {
|
58
|
+
subject { Loader.new target, tmp_file }
|
55
59
|
|
56
|
-
it 'has target
|
57
|
-
%w[
|
60
|
+
it 'has target and tmp_file attribute methods' do
|
61
|
+
%w[target tmp_file].each { |m| subject.should respond_to m }
|
58
62
|
end
|
59
63
|
|
60
|
-
describe '#
|
64
|
+
describe '#load_command' do
|
61
65
|
it 'returns expected command' do
|
62
|
-
subject.
|
66
|
+
subject.load_command.should == 'mysql -ubeta_user < \'/some/arbitrary/path\''
|
63
67
|
end
|
64
68
|
end
|
65
69
|
|
@@ -69,13 +73,6 @@ module Dbmanager
|
|
69
73
|
end
|
70
74
|
end
|
71
75
|
|
72
|
-
describe '#remove_tmp_file' do
|
73
|
-
it 'tries to remove the temporary file' do
|
74
|
-
Dbmanager.should_receive(:execute).with('rm \'/some/arbitrary/path\'')
|
75
|
-
subject.remove_tmp_file
|
76
|
-
end
|
77
|
-
end
|
78
|
-
|
79
76
|
describe '#bundle' do
|
80
77
|
it 'returns "bundle exec" when bundler is present' do
|
81
78
|
Dbmanager.should_receive(:execute).and_return true
|
@@ -88,6 +85,45 @@ module Dbmanager
|
|
88
85
|
end
|
89
86
|
end
|
90
87
|
|
88
|
+
describe '#run' do
|
89
|
+
it 'creates the db if missing and then imports the db' do
|
90
|
+
subject.stub!(:remove_tmp_file => true)
|
91
|
+
Dbmanager.should_receive(:execute!).with(subject.create_db_if_missing_command)
|
92
|
+
Dbmanager.should_receive(:execute!).with(subject.load_command)
|
93
|
+
subject.run
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
describe Importer do
|
100
|
+
def environment(opts={})
|
101
|
+
opts = {:protected => false}.merge(opts)
|
102
|
+
Environment.new opts
|
103
|
+
end
|
104
|
+
|
105
|
+
before { Dbmanager.stub :output => STDStub.new }
|
106
|
+
|
107
|
+
describe 'an importer instance' do
|
108
|
+
before { Time.stub! :now => Time.parse('2012/03/23 12:30:32') }
|
109
|
+
|
110
|
+
subject { Importer.new source, target, tmp_file }
|
111
|
+
|
112
|
+
let(:source) { environment(:name => 'development', :username => 'root') }
|
113
|
+
let(:target) { environment(:name => 'beta', :username => 'beta_user') }
|
114
|
+
let(:tmp_file) { '/some/arbitrary/path' }
|
115
|
+
|
116
|
+
it 'has target, source and tmp_file attribute methods' do
|
117
|
+
%w[source target tmp_file].each { |m| subject.should respond_to m }
|
118
|
+
end
|
119
|
+
|
120
|
+
describe '#remove_tmp_file' do
|
121
|
+
it 'tries to remove the temporary file' do
|
122
|
+
Dbmanager.should_receive(:execute).with('rm \'/some/arbitrary/path\'')
|
123
|
+
subject.remove_tmp_file
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
91
127
|
describe '#run' do
|
92
128
|
it 'create ad Dumper that will dump the db' do
|
93
129
|
Dbmanager.stub!(:execute! => nil)
|
@@ -95,11 +131,9 @@ module Dbmanager
|
|
95
131
|
subject.run
|
96
132
|
end
|
97
133
|
|
98
|
-
it '
|
99
|
-
|
100
|
-
|
101
|
-
Dbmanager.should_receive(:execute!).with(subject.create_db_if_missing_command)
|
102
|
-
Dbmanager.should_receive(:execute!).with(subject.import_command)
|
134
|
+
it 'create ad Loader that will dump the db' do
|
135
|
+
Dbmanager.stub!(:execute! => nil)
|
136
|
+
Loader.should_receive(:new).and_return(mock.as_null_object)
|
103
137
|
subject.run
|
104
138
|
end
|
105
139
|
end
|
data/spec/lib/dbmanager_spec.rb
CHANGED
@@ -0,0 +1,28 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module Dbmanager
|
4
|
+
describe Dumper do
|
5
|
+
subject { described_class.new(STDStub.new, STDStub.new) }
|
6
|
+
|
7
|
+
describe '#run' do
|
8
|
+
before do
|
9
|
+
subject.stub(
|
10
|
+
:dumper => mock.as_null_object,
|
11
|
+
:get_env => mock(:database => 'beta'),
|
12
|
+
:get_filename => 'filename'
|
13
|
+
)
|
14
|
+
end
|
15
|
+
|
16
|
+
it 'sends expected output when successful' do
|
17
|
+
subject.run
|
18
|
+
subject.output.content.should include('Database successfully dumped in filename file.')
|
19
|
+
end
|
20
|
+
|
21
|
+
it 'delegates the actual dumping to the dumper' do
|
22
|
+
dumper = subject.send(:dumper)
|
23
|
+
dumper.should_receive(:run)
|
24
|
+
subject.run
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -1,19 +1,40 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
module Dbmanager
|
4
|
-
describe
|
5
|
-
subject
|
6
|
-
|
7
|
-
|
4
|
+
describe Importer do
|
5
|
+
subject { described_class.new(STDStub.new, STDStub.new) }
|
6
|
+
|
7
|
+
before { subject.stub :get_env => mock(:database => 'beta') }
|
8
|
+
|
9
|
+
it { should respond_to :source }
|
10
|
+
it { should respond_to :target }
|
11
|
+
|
12
|
+
describe '#run' do
|
13
|
+
context 'when target is protected' do
|
14
|
+
before { subject.stub :target => mock(:protected? => true) }
|
8
15
|
|
9
|
-
|
10
|
-
|
11
|
-
|
16
|
+
it 'raises EnvironmentProtectedError' do
|
17
|
+
expect { subject.run }.to raise_error(EnvironmentProtectedError)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
context 'when target is not protected' do
|
22
|
+
before { subject.stub :target => mock(:protected? => false) }
|
23
|
+
|
24
|
+
it 'successfully complete import' do
|
25
|
+
subject.stub(:execute_import => nil)
|
26
|
+
subject.run
|
27
|
+
message = 'Database Import completed.'
|
28
|
+
subject.output.content.should include(message)
|
29
|
+
end
|
30
|
+
end
|
12
31
|
end
|
13
32
|
|
14
|
-
|
15
|
-
|
16
|
-
|
33
|
+
describe '#tmp_file' do
|
34
|
+
it 'includes expected path' do
|
35
|
+
Time.stub :now => Time.parse('1974/09/20 14:12:33')
|
36
|
+
subject.tmp_file.should =~ Regexp.new('dbmanager/spec/fixtures/rails/tmp/740920141233')
|
37
|
+
end
|
17
38
|
end
|
18
39
|
|
19
40
|
context 'when source and target have same adapter' do
|
@@ -47,33 +68,5 @@ module Dbmanager
|
|
47
68
|
expect {subject.adapter}.to raise_error(MixedAdapterError)
|
48
69
|
end
|
49
70
|
end
|
50
|
-
|
51
|
-
describe '#run' do
|
52
|
-
context 'when target is protected' do
|
53
|
-
before { subject.stub :target => mock(:protected? => true) }
|
54
|
-
|
55
|
-
it 'raises EnvironmentProtectedError' do
|
56
|
-
expect { subject.run }.to raise_error(EnvironmentProtectedError)
|
57
|
-
end
|
58
|
-
end
|
59
|
-
|
60
|
-
context 'when target is not protected' do
|
61
|
-
before { subject.stub :target => mock(:protected? => false) }
|
62
|
-
|
63
|
-
it 'outputs expected messages' do
|
64
|
-
subject.stub(:execute_import => nil)
|
65
|
-
subject.run
|
66
|
-
message = 'Database Import completed.'
|
67
|
-
subject.output.content.should include(message)
|
68
|
-
end
|
69
|
-
end
|
70
|
-
end
|
71
|
-
|
72
|
-
describe '#tmp_file' do
|
73
|
-
it 'includes expected path' do
|
74
|
-
Time.stub :now => Time.parse('1974/09/20 14:12:33')
|
75
|
-
subject.tmp_file.should =~ Regexp.new('dbmanager/spec/fixtures/rails/tmp/740920141233')
|
76
|
-
end
|
77
|
-
end
|
78
71
|
end
|
79
72
|
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module Dbmanager
|
4
|
+
describe Loader do
|
5
|
+
|
6
|
+
subject { described_class.new(STDStub.new, STDStub.new) }
|
7
|
+
|
8
|
+
describe '#run' do
|
9
|
+
before do
|
10
|
+
subject.stub(
|
11
|
+
:loader => mock.as_null_object,
|
12
|
+
:get_env => mock(:database => 'beta'),
|
13
|
+
:get_filename => 'filename'
|
14
|
+
)
|
15
|
+
end
|
16
|
+
|
17
|
+
it 'sends expected output' do
|
18
|
+
subject.run
|
19
|
+
subject.output.content.should include('Database successfully loaded from filename.')
|
20
|
+
end
|
21
|
+
|
22
|
+
it 'delegates the actual loading to the loader' do
|
23
|
+
loader = subject.send(:loader)
|
24
|
+
loader.should_receive(:run)
|
25
|
+
subject.run
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
data/spec/lib/runner_spec.rb
CHANGED
@@ -7,37 +7,69 @@ module Dbmanager
|
|
7
7
|
let(:input) { STDStub.new }
|
8
8
|
let(:output) { STDStub.new }
|
9
9
|
|
10
|
+
subject { Runner.new(input, output) }
|
11
|
+
|
10
12
|
before do
|
11
13
|
YmlParser.stub!(:environments => envs)
|
12
|
-
|
14
|
+
subject.stub(:choose_environment => envs.first)
|
13
15
|
end
|
14
16
|
|
15
|
-
|
16
|
-
|
17
|
+
it { should respond_to :input }
|
18
|
+
it { should respond_to :output }
|
19
|
+
it { should respond_to :environments }
|
17
20
|
|
21
|
+
describe '#initialize' do
|
18
22
|
it 'sets expected attributes' do
|
19
|
-
subject.input.should
|
20
|
-
subject.output.should
|
23
|
+
subject.input.should == input
|
24
|
+
subject.output.should == output
|
21
25
|
subject.environments.should == envs
|
22
|
-
subject.source.should == envs.first
|
23
26
|
end
|
24
27
|
end
|
25
28
|
|
26
29
|
describe '#get_env' do
|
27
|
-
subject { Runner.new(input, output) }
|
28
|
-
|
29
|
-
it 'outputs default message' do
|
30
|
-
subject.get_env
|
31
|
-
output.content.should include('Please choose source db:')
|
32
|
-
end
|
33
|
-
|
34
30
|
it 'outputs expected message' do
|
35
31
|
subject.get_env('target')
|
36
32
|
output.content.should include('Please choose target db:')
|
37
33
|
end
|
38
34
|
|
39
35
|
it 'returns the chosen environment' do
|
40
|
-
subject.get_env.should == envs.first
|
36
|
+
subject.get_env('target').should == envs.first
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
describe '#get_filename' do
|
41
|
+
it 'outputs expected message' do
|
42
|
+
subject.get_filename('target', 'defaultname')
|
43
|
+
output.content.should include('Please choose target file (defaults to defaultname):')
|
44
|
+
end
|
45
|
+
|
46
|
+
context 'when user inputs no filename' do
|
47
|
+
before { subject.stub(:get_input => '') }
|
48
|
+
|
49
|
+
it 'returns the default filename' do
|
50
|
+
subject.get_filename('source', '/default.sql').should == '/default.sql'
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
context 'when user inputs an absolute path' do
|
55
|
+
before { subject.stub(:get_input => '/some/path.sql') }
|
56
|
+
|
57
|
+
it 'returns the absolute path' do
|
58
|
+
subject.get_filename('source', 'default').should == '/some/path.sql'
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
context 'when user inputs a relative path' do
|
63
|
+
before { subject.stub(:get_input => 'filename.sql') }
|
64
|
+
|
65
|
+
it 'returns a pathname object' do
|
66
|
+
subject.get_filename('source', 'default').should be_a(Pathname)
|
67
|
+
end
|
68
|
+
|
69
|
+
it 'appends the rails root to the path' do
|
70
|
+
expected = Pathname.new("#{fixture_path}/rails/filename.sql")
|
71
|
+
subject.get_filename('source', 'default').should == expected
|
72
|
+
end
|
41
73
|
end
|
42
74
|
end
|
43
75
|
end
|
data/spec/lib/yml_parser_spec.rb
CHANGED
data/spec/spec_helper.rb
CHANGED
@@ -1,9 +1,24 @@
|
|
1
|
-
|
2
|
-
require '
|
1
|
+
$LOAD_PATH.unshift File.expand_path('../../lib', __FILE__)
|
2
|
+
require 'dbmanager'
|
3
3
|
|
4
4
|
RSpec.configure do |config|
|
5
|
+
config.order = :random
|
5
6
|
config.color_enabled = true
|
6
|
-
config.formatter
|
7
|
+
config.formatter = 'documentation'
|
8
|
+
config.treat_symbols_as_metadata_keys_with_true_values = true
|
9
|
+
config.run_all_when_everything_filtered = true
|
10
|
+
config.filter_run :focus
|
11
|
+
config.before(:each) do
|
12
|
+
stub_rails_root unless example.metadata[:skip_stub_rails_root]
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
|
17
|
+
class STDStub < StringIO
|
18
|
+
def content
|
19
|
+
rewind
|
20
|
+
read
|
21
|
+
end
|
7
22
|
end
|
8
23
|
|
9
24
|
def fixture_path
|
@@ -11,5 +26,5 @@ def fixture_path
|
|
11
26
|
end
|
12
27
|
|
13
28
|
def stub_rails_root
|
14
|
-
Dbmanager.stub
|
29
|
+
Dbmanager.stub :rails_root => Pathname.new("#{fixture_path}/rails")
|
15
30
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: dbmanager
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,10 +9,10 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2013-03-31 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
|
-
name:
|
15
|
+
name: rails
|
16
16
|
requirement: !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
@@ -29,6 +29,22 @@ dependencies:
|
|
29
29
|
version: '0'
|
30
30
|
- !ruby/object:Gem::Dependency
|
31
31
|
name: rspec
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
34
|
+
requirements:
|
35
|
+
- - ~>
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: '2.12'
|
38
|
+
type: :development
|
39
|
+
prerelease: false
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ~>
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: '2.12'
|
46
|
+
- !ruby/object:Gem::Dependency
|
47
|
+
name: rake
|
32
48
|
requirement: !ruby/object:Gem::Requirement
|
33
49
|
none: false
|
34
50
|
requirements:
|
@@ -44,7 +60,7 @@ dependencies:
|
|
44
60
|
- !ruby/object:Gem::Version
|
45
61
|
version: '0'
|
46
62
|
- !ruby/object:Gem::Dependency
|
47
|
-
name:
|
63
|
+
name: mysql2
|
48
64
|
requirement: !ruby/object:Gem::Requirement
|
49
65
|
none: false
|
50
66
|
requirements:
|
@@ -115,6 +131,8 @@ extensions: []
|
|
115
131
|
extra_rdoc_files: []
|
116
132
|
files:
|
117
133
|
- .gitignore
|
134
|
+
- .rvmrc
|
135
|
+
- .travis.yml
|
118
136
|
- CHANGELOG.md
|
119
137
|
- Gemfile
|
120
138
|
- Guardfile
|
@@ -133,9 +151,10 @@ files:
|
|
133
151
|
- lib/dbmanager/adapters.rb
|
134
152
|
- lib/dbmanager/adapters/mysql.rb
|
135
153
|
- lib/dbmanager/adapters/mysql2.rb
|
136
|
-
- lib/dbmanager/
|
154
|
+
- lib/dbmanager/dumper.rb
|
137
155
|
- lib/dbmanager/environment.rb
|
138
|
-
- lib/dbmanager/
|
156
|
+
- lib/dbmanager/importer.rb
|
157
|
+
- lib/dbmanager/loader.rb
|
139
158
|
- lib/dbmanager/runner.rb
|
140
159
|
- lib/dbmanager/version.rb
|
141
160
|
- lib/dbmanager/yml_parser.rb
|
@@ -182,6 +201,7 @@ files:
|
|
182
201
|
- spec/dummy/public/favicon.ico
|
183
202
|
- spec/dummy/public/index.html
|
184
203
|
- spec/dummy/public/robots.txt
|
204
|
+
- spec/dummy/rerun.txt
|
185
205
|
- spec/dummy/script/rails
|
186
206
|
- spec/dummy/test/fixtures/.gitkeep
|
187
207
|
- spec/dummy/test/functional/.gitkeep
|
@@ -197,13 +217,13 @@ files:
|
|
197
217
|
- spec/fixtures/rails/config/dbmanager_override.yml
|
198
218
|
- spec/lib/adapters/mysql_spec.rb
|
199
219
|
- spec/lib/dbmanager_spec.rb
|
200
|
-
- spec/lib/
|
220
|
+
- spec/lib/dumper_spec.rb
|
201
221
|
- spec/lib/environment_spec.rb
|
202
|
-
- spec/lib/
|
222
|
+
- spec/lib/importer_spec.rb
|
223
|
+
- spec/lib/loader_spec.rb
|
203
224
|
- spec/lib/runner_spec.rb
|
204
225
|
- spec/lib/yml_parser_spec.rb
|
205
226
|
- spec/spec_helper.rb
|
206
|
-
- spec/support/std_stub.rb
|
207
227
|
homepage: https://github.com/spaghetticode/dbmanager
|
208
228
|
licenses: []
|
209
229
|
post_install_message:
|
@@ -218,7 +238,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
218
238
|
version: '0'
|
219
239
|
segments:
|
220
240
|
- 0
|
221
|
-
hash:
|
241
|
+
hash: 3782929993512571637
|
222
242
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
223
243
|
none: false
|
224
244
|
requirements:
|
@@ -227,10 +247,10 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
227
247
|
version: '0'
|
228
248
|
segments:
|
229
249
|
- 0
|
230
|
-
hash:
|
250
|
+
hash: 3782929993512571637
|
231
251
|
requirements: []
|
232
252
|
rubyforge_project: dbmanager
|
233
|
-
rubygems_version: 1.8.
|
253
|
+
rubygems_version: 1.8.25
|
234
254
|
signing_key:
|
235
255
|
specification_version: 3
|
236
256
|
summary: database manager
|
@@ -282,6 +302,7 @@ test_files:
|
|
282
302
|
- spec/dummy/public/favicon.ico
|
283
303
|
- spec/dummy/public/index.html
|
284
304
|
- spec/dummy/public/robots.txt
|
305
|
+
- spec/dummy/rerun.txt
|
285
306
|
- spec/dummy/script/rails
|
286
307
|
- spec/dummy/test/fixtures/.gitkeep
|
287
308
|
- spec/dummy/test/functional/.gitkeep
|
@@ -297,10 +318,10 @@ test_files:
|
|
297
318
|
- spec/fixtures/rails/config/dbmanager_override.yml
|
298
319
|
- spec/lib/adapters/mysql_spec.rb
|
299
320
|
- spec/lib/dbmanager_spec.rb
|
300
|
-
- spec/lib/
|
321
|
+
- spec/lib/dumper_spec.rb
|
301
322
|
- spec/lib/environment_spec.rb
|
302
|
-
- spec/lib/
|
323
|
+
- spec/lib/importer_spec.rb
|
324
|
+
- spec/lib/loader_spec.rb
|
303
325
|
- spec/lib/runner_spec.rb
|
304
326
|
- spec/lib/yml_parser_spec.rb
|
305
327
|
- spec/spec_helper.rb
|
306
|
-
- spec/support/std_stub.rb
|
data/lib/dbmanager/dumpable.rb
DELETED
@@ -1,41 +0,0 @@
|
|
1
|
-
# Extends the runner with database dumping capabilities.
|
2
|
-
#
|
3
|
-
# The user will be prompted to enter the target filename path, pressing enter
|
4
|
-
# will set it to the default which is the value returned by #default_filename.
|
5
|
-
#
|
6
|
-
# The dump process happens in the #run method, and is eventually delegated to
|
7
|
-
# the specific database adapter which must implement the #run method.
|
8
|
-
|
9
|
-
module Dbmanager
|
10
|
-
module Dumpable
|
11
|
-
def self.extended(base)
|
12
|
-
class << base; attr_accessor :filename; end
|
13
|
-
end
|
14
|
-
|
15
|
-
def run
|
16
|
-
output.print "\nPlease choose target file (defaults to #{default_filename}): "
|
17
|
-
@filename = get_filename
|
18
|
-
dumper.run
|
19
|
-
output.puts "Database successfully dumped in #{filename} file."
|
20
|
-
end
|
21
|
-
|
22
|
-
private
|
23
|
-
|
24
|
-
def dumper
|
25
|
-
adapter::Dumper.new(source, filename)
|
26
|
-
end
|
27
|
-
|
28
|
-
def adapter
|
29
|
-
Dbmanager::Adapters.const_get source.adapter.capitalize
|
30
|
-
end
|
31
|
-
|
32
|
-
def default_filename
|
33
|
-
Dbmanager.rails_root.join "tmp/#{source.database}.sql"
|
34
|
-
end
|
35
|
-
|
36
|
-
def get_filename
|
37
|
-
filename = input.gets.chomp
|
38
|
-
filename.blank? ? default_filename : Dbmanager.rails_root.join(filename)
|
39
|
-
end
|
40
|
-
end
|
41
|
-
end
|
data/lib/dbmanager/importable.rb
DELETED
@@ -1,41 +0,0 @@
|
|
1
|
-
# Extends the runner with database importing capabilities.
|
2
|
-
#
|
3
|
-
# The import process happens in the #run method, and is eventually delegated to
|
4
|
-
# the specific database adapter which must implement the #run method. This
|
5
|
-
# adapter will receive the source and target environment plus the path for the
|
6
|
-
# sql dump file.
|
7
|
-
#
|
8
|
-
# The source and target environment must use the same adapter, ie you cannot
|
9
|
-
# import a mysql database on a sqlite3 database. For that purpose you can use
|
10
|
-
# the taps gem.
|
11
|
-
|
12
|
-
module Dbmanager
|
13
|
-
module Importable
|
14
|
-
def self.extended(base)
|
15
|
-
class << base; attr_reader :target; end
|
16
|
-
end
|
17
|
-
|
18
|
-
def run
|
19
|
-
@target = get_env('target')
|
20
|
-
if target.protected?
|
21
|
-
raise EnvironmentProtectedError
|
22
|
-
else
|
23
|
-
execute_import
|
24
|
-
output.puts 'Database Import completed.'
|
25
|
-
end
|
26
|
-
end
|
27
|
-
|
28
|
-
def execute_import
|
29
|
-
adapter::Importer.new(source, target, tmp_file).run
|
30
|
-
end
|
31
|
-
|
32
|
-
def adapter
|
33
|
-
raise MixedAdapterError if source.adapter != target.adapter
|
34
|
-
Dbmanager::Adapters.const_get source.adapter.capitalize
|
35
|
-
end
|
36
|
-
|
37
|
-
def tmp_file
|
38
|
-
@tmp_file ||= File.join Dbmanager.rails_root, 'tmp', Time.now.strftime('%y%m%d%H%M%S')
|
39
|
-
end
|
40
|
-
end
|
41
|
-
end
|
data/spec/lib/dumpable_spec.rb
DELETED
@@ -1,38 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
module Dbmanager
|
4
|
-
describe Dumpable do
|
5
|
-
subject do
|
6
|
-
Object.new.tap {|o| o.extend Dumpable}
|
7
|
-
end
|
8
|
-
|
9
|
-
before do
|
10
|
-
subject.stub :output => STDStub.new, :input => STDStub.new
|
11
|
-
end
|
12
|
-
|
13
|
-
describe '#run' do
|
14
|
-
before do
|
15
|
-
subject.stub(
|
16
|
-
:get_filename => 'filename',
|
17
|
-
:default_filename => 'defaultname',
|
18
|
-
:dumper => mock.as_null_object
|
19
|
-
)
|
20
|
-
end
|
21
|
-
|
22
|
-
it 'sends expected output' do
|
23
|
-
subject.run
|
24
|
-
[
|
25
|
-
'Please choose target file (defaults to defaultname):',
|
26
|
-
'Database successfully dumped in filename file.'
|
27
|
-
].each do |message|
|
28
|
-
subject.output.content.should include(message)
|
29
|
-
end
|
30
|
-
end
|
31
|
-
|
32
|
-
it 'delegates the actual dumping to the dumper' do
|
33
|
-
subject.send(:dumper).should_receive(:run)
|
34
|
-
subject.run
|
35
|
-
end
|
36
|
-
end
|
37
|
-
end
|
38
|
-
end
|