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 ADDED
@@ -0,0 +1 @@
1
+ rvm ruby-1.9.3
@@ -0,0 +1,8 @@
1
+ language: ruby
2
+ rvm:
3
+ - 1.9.3
4
+ - 1.8.7
5
+ branches:
6
+ only:
7
+ - master
8
+ - elia/loadable
@@ -1,3 +1,8 @@
1
+ ## v0.2.0
2
+
3
+ * merge pull request from Elia (add loader task)
4
+ * refactoring of the main structure and specs
5
+
1
6
  ## v0.1.7
2
7
 
3
8
  * merge pull request from Racko (add quotes to file names)
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
- **the import process is destructive** so be careful on which environment you
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
 
@@ -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 'activesupport'
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'
@@ -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
- **the import process is destructive** so be careful on which environment you
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
 
@@ -8,6 +8,7 @@
8
8
  STDIN_STUB = 'STDIN_stub'
9
9
  DUMMY_PATH = '../../../spec/dummy'
10
10
  Dir.chdir File.expand_path(DUMMY_PATH, __FILE__) do
11
+ system 'mkdir tmp'
11
12
  system 'bundle install'
12
13
  system 'rm -f tmp/*sql'
13
14
  %w[
@@ -1,15 +1,12 @@
1
- require 'active_support/deprecation'
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 :Importable, 'dbmanager/importable'
12
- autoload :Dumpable, 'dbmanager/dumpable'
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 Importer
43
+ class Loader
44
44
  include Connectable
45
- attr_reader :source, :target, :tmp_file
45
+ attr_reader :target, :tmp_file
46
46
 
47
- def initialize(source, target, tmp_file)
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! import_command
57
- ensure
58
- remove_tmp_file
54
+ Dbmanager.execute! load_command
59
55
  end
60
56
 
61
- def import_command
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
@@ -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, :source
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='source')
11
+ def get_env(type)
29
12
  output.puts "\nPlease choose #{type} db:\n\n"
30
- get_environment
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 get_environment
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 = input.gets.chomp.to_i
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
@@ -1,3 +1,3 @@
1
1
  module Dbmanager
2
- VERSION = '0.1.7'
2
+ VERSION = '0.2.0'
3
3
  end
@@ -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::Runner.run('importable')
5
+ Dbmanager::Importer.new.run
6
6
  end
7
7
 
8
- desc 'dump specific environment db data in tmp directory'
8
+ desc 'dump specific environment db data to a file'
9
9
  task :dump do
10
10
  require 'dbmanager'
11
- Dbmanager::Runner.run('dumpable')
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
@@ -2,10 +2,10 @@ development:
2
2
  adapter: mysql2
3
3
  database: dbmanager_dummy_dev
4
4
  username: root
5
- password: root
5
+ password:
6
6
 
7
7
  test:
8
8
  adapter: mysql2
9
9
  database: dbmanager_dummy_test
10
10
  username: root
11
- password: root
11
+ password:
@@ -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 Importer do
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 { Importer.new source, target, tmp_file }
58
+ subject { Loader.new target, tmp_file }
55
59
 
56
- it 'has target, source and tmp_file attribute methods' do
57
- %w[source target tmp_file].each { |m| subject.should respond_to m }
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 '#import_command' do
64
+ describe '#load_command' do
61
65
  it 'returns expected command' do
62
- subject.import_command.should == 'mysql -ubeta_user < \'/some/arbitrary/path\''
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 'creates the db if missing and then imports the db' do
99
- Dumper.stub!(:new => mock.as_null_object)
100
- subject.stub!(:remove_tmp_file => true)
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
@@ -1,7 +1,7 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe Dbmanager do
4
- describe '#rails_root' do
4
+ describe '#rails_root', :skip_stub_rails_root => true do
5
5
  it 'wraps Rails.root' do
6
6
  Rails = mock unless defined? Rails
7
7
  Rails.should_receive :root
@@ -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 Importable do
5
- subject do
6
- Object.new.tap {|o| o.extend Importable}
7
- end
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
- before do
10
- stub_rails_root
11
- subject.stub :output => STDStub.new, :input => STDStub.new, :get_env => nil
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
- it 'has target attribute reader' do
15
- subject.instance_eval { @target = 'something'}
16
- subject.target.should == 'something'
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
@@ -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
- Runner.any_instance.stub(:get_environment => envs.first)
14
+ subject.stub(:choose_environment => envs.first)
13
15
  end
14
16
 
15
- describe '#initialize' do
16
- subject { Runner.new(input, output) }
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 == input
20
- subject.output.should == output
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
@@ -3,7 +3,6 @@ require 'spec_helper'
3
3
  module Dbmanager
4
4
  describe YmlParser do
5
5
  before do
6
- stub_rails_root
7
6
  YmlParser.instance_eval { @config = nil }
8
7
  end
9
8
 
@@ -1,9 +1,24 @@
1
- require File.expand_path('../../lib/dbmanager', __FILE__)
2
- require 'support/std_stub'
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 = 'documentation'
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! :rails_root => "#{fixture_path}/rails"
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.1.7
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: 2012-10-30 00:00:00.000000000 Z
12
+ date: 2013-03-31 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
- name: activesupport
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: rake
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/dumpable.rb
154
+ - lib/dbmanager/dumper.rb
137
155
  - lib/dbmanager/environment.rb
138
- - lib/dbmanager/importable.rb
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/dumpable_spec.rb
220
+ - spec/lib/dumper_spec.rb
201
221
  - spec/lib/environment_spec.rb
202
- - spec/lib/importable_spec.rb
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: 1798185120944994185
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: 1798185120944994185
250
+ hash: 3782929993512571637
231
251
  requirements: []
232
252
  rubyforge_project: dbmanager
233
- rubygems_version: 1.8.24
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/dumpable_spec.rb
321
+ - spec/lib/dumper_spec.rb
301
322
  - spec/lib/environment_spec.rb
302
- - spec/lib/importable_spec.rb
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
@@ -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
@@ -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
@@ -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
@@ -1,6 +0,0 @@
1
- class STDStub < StringIO
2
- def content
3
- rewind
4
- read
5
- end
6
- end