dbmanager 0.1.7 → 0.2.0
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/.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
|