dumpdb 1.1.0 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
File without changes
data/README.md CHANGED
@@ -10,10 +10,23 @@ require 'dumpdb'
10
10
  class MysqlFullRestore
11
11
  include Dumpdb
12
12
 
13
- databases { '/path/to/database.yml'}
14
13
  dump_file { "dump.bz2" }
15
- source { db('production', :output_root => '/some/source/dir') }
16
- target { db('development', :output_root => '/some/target/dir') }
14
+ source do
15
+ { :host => 'production.example.com',
16
+ :port => 1234,
17
+ :user => 'admin',
18
+ :pw => 'secret',
19
+ :db => 'myapp_db',
20
+ :output_root => '/some/source/dir'
21
+ }
22
+ end
23
+ target do
24
+ { :host => 'localhost',
25
+ :user => 'admin',
26
+ :db => 'myapp_db',
27
+ :output_root => '/some/target/dir'
28
+ }
29
+ end
17
30
 
18
31
  dump { "mysqldump -u :user -p\":pw\" :db | bzip2 > :dump_file" }
19
32
  restore { "mysqladmin -u :user -p\":pw\" -f -b DROP :db; true" }
@@ -152,17 +165,17 @@ class MysqlFullRestore
152
165
  include Dumpdb
153
166
 
154
167
  source do
155
- { 'user' => 'something',
156
- 'pw' => 'secret',
157
- 'db' => 'something_production',
158
- 'something' => 'else'
168
+ { :user => 'something',
169
+ :pw => 'secret',
170
+ :db => 'something_production',
171
+ :something => 'else'
159
172
  }
160
173
  end
161
174
 
162
175
  target do
163
- { 'user' => 'root',
164
- 'pw' => 'supersecret',
165
- 'db' => 'something_development'
176
+ { :user => 'root',
177
+ :pw => 'supersecret',
178
+ :db => 'something_development'
166
179
  }
167
180
  end
168
181
 
@@ -172,43 +185,6 @@ end
172
185
 
173
186
  Any settings keys can be used as command placeholders in dump and restore commands.
174
187
 
175
- **Note:** When reading source and target settings, Dumpdb takes common keys like 'hostname', 'username', 'password', and 'database' and exposes them with the more succinct 'host', 'user', 'pw', and 'db'.
176
-
177
- ### Lookup settings from YAML
178
-
179
- Since many ORMs allow you to configure db connections using yaml files, Dumpdb supports specifying your databases from a yaml file.
180
-
181
- ```ruby
182
- class MysqlFullRestore
183
- include Dumpdb
184
-
185
- databases { '/path/to/database.yml' }
186
-
187
- # ...
188
- end
189
- ```
190
-
191
- Now you can lookup your source and target settings using the `db` method.
192
-
193
- ```ruby
194
- databases { '/path/to/database.yml' }
195
- source { db('production') }
196
- target { db('development') }
197
- ```
198
-
199
- You can merge in additional settings by passing them to the `db` command:
200
-
201
- ```ruby
202
- class MysqlFullRestore
203
- include Dumpdb
204
-
205
- databases { '/path/to/database.yml' }
206
- source { db('produciton', :something => 'else') }
207
-
208
- # ...
209
- end
210
- ```
211
-
212
188
  ### Building Commands
213
189
 
214
190
  As you may have noticed, the script DSL settings methods all take a proc as their argument. This is because the procs are lazy-eval'd in the scope of the script instance. This allows you to use interpolation to help build commands with dynamic data.
@@ -231,7 +207,7 @@ class MysqlIgnoredTablesRestore
231
207
  end
232
208
 
233
209
  def ignored_tables
234
- @opts[:ignored_tables].collect {|t| "--ignore-table=#{source.db}.#{t}"}.join(' ')
210
+ @opts[:ignored_tables].map{ |t| "--ignore-table=#{source.db}.#{t}" }.join(' ')
235
211
  end
236
212
  end
237
213
  ```
data/lib/dumpdb/db.rb CHANGED
@@ -2,42 +2,57 @@ module Dumpdb
2
2
 
3
3
  class Db
4
4
 
5
- def initialize(dump_file_name, values=nil)
6
- @dump_file_name = dump_file_name || 'dump.output'
7
- @values = (values || {}).inject({}) do |vals, (k, v)|
8
- # stringify keys
9
- vals.merge(k.to_s => v)
10
- end
5
+ DEFAULT_VALUE = ''.freeze
6
+
7
+ def initialize(dump_file_name = nil, values = nil)
8
+ dump_file_name = dump_file_name || 'dump.output'
9
+ @values = dumpdb_symbolize_keys(values)
11
10
 
12
- @values['host'] ||= (@values['hostname'] || '')
13
- @values['user'] ||= (@values['username'] || '')
14
- @values['pw'] ||= (@values['password'] || '')
15
- @values['db'] ||= (@values['database'] || '')
16
- @values['output_root'] ||= ''
11
+ [:host, :port, :user, :pw, :db, :output_root].each do |key|
12
+ @values[key] ||= DEFAULT_VALUE
13
+ end
17
14
 
18
- @values['output_dir'] = output_dir(self.output_root, "#{self.host}__#{self.db}")
19
- @values['dump_file'] = File.join(self.output_dir, @dump_file_name)
15
+ @values[:output_dir] = dumpdb_build_output_dir(
16
+ self.output_root,
17
+ self.host,
18
+ self.db
19
+ )
20
+ @values[:dump_file] = File.join(self.output_dir, dump_file_name)
20
21
  end
21
22
 
22
23
  def to_hash; @values; end
23
24
 
24
25
  def method_missing(meth, *args, &block)
25
- if @values.has_key?(meth.to_s)
26
- @values[meth.to_s]
26
+ if @values.has_key?(meth.to_sym)
27
+ @values[meth.to_sym]
27
28
  else
28
29
  super
29
30
  end
30
31
  end
31
32
 
32
33
  def respond_to?(meth)
33
- @values.has_key?(meth.to_s) || super
34
+ @values.has_key?(meth.to_sym) || super
34
35
  end
35
36
 
36
37
  private
37
38
 
38
- def output_dir(root, name)
39
- name_time = "#{name}__#{Time.now.to_f}"
40
- root && !root.empty? ? File.join(root, name_time) : name_time
39
+ def dumpdb_build_output_dir(output_root, host, database)
40
+ dir_name = dumpdb_build_output_dir_name(host, database)
41
+ if output_root && !output_root.to_s.empty?
42
+ File.join(output_root, dir_name)
43
+ else
44
+ dir_name
45
+ end
46
+ end
47
+
48
+ def dumpdb_build_output_dir_name(host, database)
49
+ [host, database, Time.now.to_f].map(&:to_s).reject(&:empty?).join("__")
50
+ end
51
+
52
+ def dumpdb_symbolize_keys(values)
53
+ (values || {}).inject({}) do |h, (k, v)|
54
+ h.merge(k.to_sym => v)
55
+ end
41
56
  end
42
57
 
43
58
  end
@@ -1,4 +1,3 @@
1
- require 'yaml'
2
1
  require 'dumpdb/db'
3
2
 
4
3
  module Dumpdb::Settings
@@ -19,27 +18,13 @@ module Dumpdb::Settings
19
18
 
20
19
  class Ssh < Base; end
21
20
 
22
- class Databases < Base
23
-
24
- def value(script)
25
- val = super
26
- val.kind_of?(::String) ? load_yaml(val) : val
27
- end
28
-
29
- private
30
-
31
- def load_yaml(file_path)
32
- YAML.load(File.read(File.expand_path(file_path)))
33
- end
34
- end
35
-
36
21
  class DumpFile < Base; end
37
22
 
38
23
  class SourceTarget < Base
39
24
 
40
25
  def value(script)
41
- val = super
42
- val.kind_of?(Dumpdb::Db) ? val : Dumpdb::Db.new(script.dump_file, val)
26
+ hash = super
27
+ Dumpdb::Db.new(script.dump_file, hash)
43
28
  end
44
29
 
45
30
  end
@@ -53,7 +38,7 @@ module Dumpdb::Settings
53
38
  private
54
39
 
55
40
  def hsub(string, hash)
56
- hash.inject(string) {|new_str, (k, v)| new_str.gsub(":#{k}", v.to_s)}
41
+ hash.inject(string){ |new_str, (k, v)| new_str.gsub(":#{k}", v.to_s) }
57
42
  end
58
43
 
59
44
  end
@@ -94,7 +79,7 @@ module Dumpdb::Settings
94
79
  class CmdList < ::Array
95
80
 
96
81
  def value(script, placeholder_vals={})
97
- self.map{|cmd| cmd.value(script, placeholder_vals)}
82
+ self.map{ |cmd| cmd.value(script, placeholder_vals) }
98
83
  end
99
84
 
100
85
  end
@@ -1,3 +1,3 @@
1
1
  module Dumpdb
2
- VERSION = "1.1.0"
2
+ VERSION = "2.0.0"
3
3
  end
data/lib/dumpdb.rb CHANGED
@@ -13,7 +13,6 @@ module Dumpdb
13
13
  include NsOptions
14
14
  options :settings do
15
15
  option 'ssh', Settings::Ssh, :default => ''
16
- option 'databases', Settings::Databases, :default => {}
17
16
  option 'dump_file', Settings::DumpFile, :default => ''
18
17
  option 'source', Settings::SourceTarget, :default => {}
19
18
  option 'target', Settings::SourceTarget, :default => {}
@@ -34,7 +33,6 @@ module Dumpdb
34
33
  module SettingsDslMethods
35
34
 
36
35
  def ssh(&block); settings.ssh = Settings::Ssh.new(block); end
37
- def databases(&block); settings.databases = Settings::Databases.new(block); end
38
36
  def dump_file(&block); settings.dump_file = Settings::DumpFile.new(block); end
39
37
  def source(&block); settings.source = Settings::SourceTarget.new(block); end
40
38
  def target(&block); settings.target = Settings::SourceTarget.new(block); end
@@ -49,7 +47,6 @@ module Dumpdb
49
47
  def settings; self.class.settings; end
50
48
 
51
49
  def ssh; @ssh ||= settings.ssh.value(self); end
52
- def databases; @databases ||= settings.databases.value(self); end
53
50
  def dump_file; @dump_file ||= settings.dump_file.value(self); end
54
51
  def source; @source ||= settings.source.value(self); end
55
52
  def target; @target ||= settings.target.value(self); end
@@ -60,13 +57,6 @@ module Dumpdb
60
57
 
61
58
  end
62
59
 
63
- def db(database_name, other_vals=nil)
64
- if (db_vals = self.databases[database_name]).nil?
65
- raise BadDatabaseName, "no database named `#{database_name}'."
66
- end
67
- Db.new(self.dump_file, db_vals.merge(other_vals || {}))
68
- end
69
-
70
60
  def dump_cmd(&block); Settings::DumpCmd.new(block).value(self); end
71
61
  def restore_cmd(&block) Settings::RestoreCmd.new(block).value(self); end
72
62
 
data/test/helper.rb CHANGED
@@ -8,3 +8,5 @@ $LOAD_PATH.unshift(ROOT_PATH)
8
8
  # require pry for debugging (`binding.pry`)
9
9
  require 'pry'
10
10
 
11
+ require 'test/support/factory'
12
+
@@ -0,0 +1,6 @@
1
+ require 'assert/factory'
2
+
3
+ module Factory
4
+ extend Assert::Factory
5
+
6
+ end
@@ -3,10 +3,22 @@ require 'dumpdb'
3
3
  class LocalScript
4
4
  include Dumpdb
5
5
 
6
- databases { File.join(ROOT_PATH, 'test/support/database.yaml') }
7
6
  dump_file { "dump.#{type}" }
8
- source { db('development', :another => 'value') }
9
- target { db('test') }
7
+ source do
8
+ { :host => 'devhost',
9
+ :user => 'devuser',
10
+ :pw => 'devpw',
11
+ :db => 'devdb',
12
+ :another => 'value'
13
+ }
14
+ end
15
+ target do
16
+ { :host => 'testhost',
17
+ :user => 'testuser',
18
+ :pw => 'testpw',
19
+ :db => 'testdb'
20
+ }
21
+ end
10
22
 
11
23
  def type; "local"; end
12
24
  end
@@ -15,10 +27,21 @@ class RemoteScript
15
27
  include Dumpdb
16
28
 
17
29
  ssh { 'user@example.com' }
18
- databases { File.join(ROOT_PATH, 'test/support/database.yaml') }
19
30
  dump_file { "dump.#{type}" }
20
- source { db('development') }
21
- target { db('test') }
31
+ source do
32
+ { :host => 'devhost',
33
+ :user => 'devuser',
34
+ :pw => 'devpw',
35
+ :db => 'devdb',
36
+ }
37
+ end
38
+ target do
39
+ { :host => 'testhost',
40
+ :user => 'testuser',
41
+ :pw => 'testpw',
42
+ :db => 'testdb'
43
+ }
44
+ end
22
45
 
23
46
  def type; "remote"; end
24
47
  end
@@ -1,33 +1,84 @@
1
1
  require 'assert'
2
2
  require 'dumpdb/db'
3
3
 
4
- module Dumpdb
4
+ class Dumpdb::Db
5
5
 
6
- class DbTests < Assert::Context
7
- desc "the Db helper class"
6
+ class UnitTests < Assert::Context
7
+ desc "Dumpdb::Db"
8
8
  setup do
9
- @db = Db.new(nil)
9
+ @db_class = Dumpdb::Db
10
+ end
11
+ subject{ @db_class }
12
+
13
+ should "know its default value" do
14
+ assert_equal '', DEFAULT_VALUE
15
+ end
16
+
17
+ end
18
+
19
+ class InitTests < UnitTests
20
+ desc "when init"
21
+ setup do
22
+ @dump_file_name = Factory.file_name
23
+ @host = Factory.string
24
+ @port = Factory.integer
25
+ @user = Factory.string
26
+ @pw = Factory.string
27
+ @db_name = Factory.string
28
+ @output_root = Factory.dir_path
29
+ @custom_value = Factory.string
30
+
31
+ @current_time = Factory.time
32
+ Assert.stub(Time, :now){ @current_time }
33
+
34
+ @db = @db_class.new(@dump_file_name, {
35
+ :host => @host,
36
+ :port => @port,
37
+ :user => @user,
38
+ :pw => @pw,
39
+ :db => @db_name,
40
+ :output_root => @output_root,
41
+ :custom_value => @custom_value
42
+ })
10
43
  end
11
44
  subject { @db }
12
45
 
13
- should have_imeths :host, :user, :pw, :db, :output_root, :output_dir, :dump_file
46
+ should have_imeths :host, :port, :user, :pw, :db
47
+ should have_imeths :output_root, :output_dir, :dump_file
48
+ should have_imeths :to_hash
14
49
 
15
- should "default its values" do
16
- [:host, :user, :pw, :db, :output_root].each do |val|
17
- assert_equal '', subject.send(val)
18
- end
19
- assert_match '____', subject.output_dir
20
- assert_match 'dump.output', subject.dump_file
50
+ should "know its attributes" do
51
+ assert_equal @host, subject.host
52
+ assert_equal @port, subject.port
53
+ assert_equal @user, subject.user
54
+ assert_equal @pw, subject.pw
55
+ assert_equal @db_name, subject.db
56
+ assert_equal @output_root, subject.output_root
57
+ exp = File.join(@output_root, "#{@host}__#{@db_name}__#{@current_time.to_f}")
58
+ assert_equal exp, subject.output_dir
59
+ exp = File.join(subject.output_dir, @dump_file_name)
60
+ assert_equal exp, subject.dump_file
21
61
  end
22
62
 
23
- should "set values" do
24
- db = Db.new('dump.file', :host => 'h', :db => 'd', :something => 'else')
63
+ should "allow custom attributes" do
64
+ assert_true subject.respond_to?(:custom_value)
65
+ assert_equal @custom_value, subject.custom_value
66
+ end
67
+
68
+ should "default its attributes" do
69
+ db = @db_class.new
25
70
 
26
- assert_equal 'h', db.host
27
- assert_equal 'd', db.db
28
- assert_match 'h__d__', db.output_dir
29
- assert_match 'dump.file', db.dump_file
71
+ assert_equal DEFAULT_VALUE, db.host
72
+ assert_equal DEFAULT_VALUE, db.port
73
+ assert_equal DEFAULT_VALUE, db.user
74
+ assert_equal DEFAULT_VALUE, db.pw
75
+ assert_equal DEFAULT_VALUE, db.db
76
+ assert_equal DEFAULT_VALUE, db.output_root
77
+ assert_equal @current_time.to_f.to_s, db.output_dir
78
+ exp = File.join(db.output_dir, 'dump.output')
79
+ assert_equal exp, db.dump_file
30
80
  end
81
+
31
82
  end
32
83
 
33
84
  end
@@ -12,10 +12,11 @@ module Dumpdb
12
12
  subject { @script }
13
13
 
14
14
  should have_cmeths :settings
15
- should have_imeths :settings, :db, :dump_cmd, :restore_cmd, :ssh?, :ssh_opts, :run
15
+ should have_imeths :settings, :dump_cmd, :restore_cmd
16
+ should have_imeths :ssh?, :ssh_opts, :run
16
17
 
17
- should have_cmeths :ssh, :databases, :dump_file, :source, :target
18
- should have_imeths :ssh, :databases, :dump_file, :source, :target
18
+ should have_cmeths :ssh, :dump_file, :source, :target
19
+ should have_imeths :ssh, :dump_file, :source, :target
19
20
 
20
21
  should have_cmeths :dump, :restore
21
22
  should have_imeths :dump_cmds, :restore_cmds, :copy_dump_cmd
@@ -32,7 +33,6 @@ module Dumpdb
32
33
 
33
34
  should "store off the settings for the script" do
34
35
  assert_kind_of Settings::Ssh, subject.settings.ssh
35
- assert_kind_of Settings::Databases, subject.settings.databases
36
36
  assert_kind_of Settings::DumpFile, subject.settings.dump_file
37
37
  assert_kind_of Settings::SourceTarget, subject.settings.source
38
38
  assert_kind_of Settings::SourceTarget, subject.settings.target
@@ -42,31 +42,6 @@ module Dumpdb
42
42
 
43
43
  end
44
44
 
45
- class DbMethTests < ScriptTests
46
- desc "`db' method"
47
- setup do
48
- @script = LocalScript.new
49
- end
50
-
51
- should "build a Db based on the named database values" do
52
- assert_kind_of Db, subject.target
53
- assert_equal 'testhost', subject.target.host
54
- end
55
-
56
- should "build a Db based on the named database values plus additional values" do
57
- assert_kind_of Db, subject.source
58
- assert_equal 'devhost', subject.source.host
59
- assert_equal 'value', subject.source.another
60
- end
61
-
62
- should "complain if looking up a db not in the `databases` collection" do
63
- assert_raises BadDatabaseName do
64
- subject.db('does_not_exist')
65
- end
66
- end
67
-
68
- end
69
-
70
45
  class CmdMethsTests < ScriptTests
71
46
 
72
47
  should "build dump command strings" do
@@ -38,34 +38,6 @@ module Dumpdb
38
38
 
39
39
  end
40
40
 
41
- class DatabasesSettingTests < SettingsTests
42
- desc "`databases` setting"
43
- setup do
44
- @from_hash = {
45
- 'db1' => {'db' => 'one'},
46
- 'db2' => {'db' => 'two'},
47
- }
48
- end
49
-
50
- should "be available" do
51
- assert Settings::Databases
52
- end
53
-
54
- should "come from a hash" do
55
- databases = Settings::Databases.new(@from_hash)
56
- assert_equal @from_hash, databases.value(@script)
57
- end
58
-
59
- should "come from a yaml file" do
60
- databases = Settings::Databases.new(File.join(ROOT_PATH, 'test/support/test.yaml'))
61
- assert_equal({
62
- 'db-one' => {'db' => 1},
63
- 'db-two' => {'db' => 2},
64
- }, databases.value(@script))
65
- end
66
-
67
- end
68
-
69
41
  class DumpFileSettingTests < SettingsTests
70
42
  desc "`dump_file` setting"
71
43
 
@@ -92,13 +64,6 @@ module Dumpdb
92
64
  assert_equal 'from_hash', db.host
93
65
  end
94
66
 
95
- should "come from a Db obj" do
96
- db = Settings::Databases.new(Db.new('dump.file', {'host' => 'from_db'})).value(@script)
97
-
98
- assert_kind_of Db, db
99
- assert_equal 'from_db', db.host
100
- end
101
-
102
67
  end
103
68
 
104
69
  class CmdTests < SettingsTests
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dumpdb
3
3
  version: !ruby/object:Gem::Version
4
- hash: 19
4
+ hash: 15
5
5
  prerelease:
6
6
  segments:
7
- - 1
8
- - 1
7
+ - 2
9
8
  - 0
10
- version: 1.1.0
9
+ - 0
10
+ version: 2.0.0
11
11
  platform: ruby
12
12
  authors:
13
13
  - Kelly Redding
@@ -16,7 +16,7 @@ autorequire:
16
16
  bindir: bin
17
17
  cert_chain: []
18
18
 
19
- date: 2015-10-13 00:00:00 Z
19
+ date: 2015-12-09 00:00:00 Z
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency
22
22
  requirement: &id001 !ruby/object:Gem::Requirement
@@ -84,7 +84,7 @@ extra_rdoc_files: []
84
84
  files:
85
85
  - .gitignore
86
86
  - Gemfile
87
- - LICENSE.txt
87
+ - LICENSE
88
88
  - README.md
89
89
  - Rakefile
90
90
  - dumpdb.gemspec
@@ -95,9 +95,8 @@ files:
95
95
  - lib/dumpdb/version.rb
96
96
  - log/.gitkeep
97
97
  - test/helper.rb
98
- - test/support/database.yaml
98
+ - test/support/factory.rb
99
99
  - test/support/fake_cmd_runner.rb
100
- - test/support/test.yaml
101
100
  - test/support/test_scripts.rb
102
101
  - test/unit/db_tests.rb
103
102
  - test/unit/runner_tests.rb
@@ -139,9 +138,8 @@ specification_version: 3
139
138
  summary: Dump and restore your databases.
140
139
  test_files:
141
140
  - test/helper.rb
142
- - test/support/database.yaml
141
+ - test/support/factory.rb
143
142
  - test/support/fake_cmd_runner.rb
144
- - test/support/test.yaml
145
143
  - test/support/test_scripts.rb
146
144
  - test/unit/db_tests.rb
147
145
  - test/unit/runner_tests.rb
@@ -1,12 +0,0 @@
1
- ---
2
- test:
3
- hostname: testhost
4
- username: testuser
5
- password: testpw
6
- database: testdb
7
-
8
- development:
9
- hostname: devhost
10
- username: devuser
11
- password: devpw
12
- database: devdb
@@ -1,6 +0,0 @@
1
- ---
2
- "db-one":
3
- db: 1
4
-
5
- "db-two":
6
- db: 2