dk-dumpdb 0.0.1 → 0.1.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.
@@ -0,0 +1,69 @@
1
+ module Dk; end
2
+ module Dk::Dumpdb
3
+
4
+ class Db
5
+
6
+ DEFAULT_VALUE = ''.freeze
7
+
8
+ def initialize(dump_file_name = nil, values = nil)
9
+ dump_file_name = dump_file_name || 'dump.output'
10
+ @values = dk_dumpdb_symbolize_keys(values)
11
+
12
+ [:host, :port, :user, :pw, :db, :output_root].each do |key|
13
+ @values[key] ||= DEFAULT_VALUE
14
+ end
15
+
16
+ @values[:output_dir] = dk_dumpdb_build_output_dir(
17
+ self.output_root,
18
+ self.host,
19
+ self.db
20
+ )
21
+ @values[:dump_file] = File.join(self.output_dir, dump_file_name)
22
+ end
23
+
24
+ def to_hash; @values; end
25
+
26
+ def method_missing(meth, *args, &block)
27
+ if @values.has_key?(meth.to_sym)
28
+ @values[meth.to_sym]
29
+ else
30
+ super
31
+ end
32
+ end
33
+
34
+ def respond_to?(meth)
35
+ @values.has_key?(meth.to_sym) || super
36
+ end
37
+
38
+ def ==(other_db)
39
+ if other_db.kind_of?(Db)
40
+ self.to_hash == other_db.to_hash
41
+ else
42
+ super
43
+ end
44
+ end
45
+
46
+ private
47
+
48
+ def dk_dumpdb_build_output_dir(output_root, host, database)
49
+ dir_name = dk_dumpdb_build_output_dir_name(host, database)
50
+ if output_root && !output_root.to_s.empty?
51
+ File.join(output_root, dir_name)
52
+ else
53
+ dir_name
54
+ end
55
+ end
56
+
57
+ def dk_dumpdb_build_output_dir_name(host, database)
58
+ [host, database, Time.now.to_f].map(&:to_s).reject(&:empty?).join("__")
59
+ end
60
+
61
+ def dk_dumpdb_symbolize_keys(values)
62
+ (values || {}).inject({}) do |h, (k, v)|
63
+ h.merge(k.to_sym => v)
64
+ end
65
+ end
66
+
67
+ end
68
+
69
+ end
@@ -0,0 +1,83 @@
1
+ require 'much-plugin'
2
+ require 'dk-dumpdb/config'
3
+ require 'dk-dumpdb/task'
4
+
5
+ module Dk::Dumpdb
6
+
7
+ module Script
8
+ include MuchPlugin
9
+
10
+ plugin_included do
11
+ include InstanceMethods
12
+ extend ClassMethods
13
+
14
+ class self::Task
15
+ include Dk::Dumpdb::Task
16
+ end
17
+ self::Task.script_class self
18
+
19
+ end
20
+
21
+ module InstanceMethods
22
+
23
+ attr_reader :params
24
+
25
+ def initialize(task_params = nil)
26
+ @params = task_params || {}
27
+ end
28
+
29
+ def config
30
+ @config ||= Config.new.tap do |config|
31
+ self.class.config_blocks.each do |config_block|
32
+ config.instance_eval(&config_block)
33
+ end
34
+ end
35
+ end
36
+
37
+ def ssh; @ssh ||= config.ssh.value(self); end
38
+ def dump_file; @dump_file ||= config.dump_file.value(self); end
39
+ def source; @source ||= config.source.value(self); end
40
+ def target; @target ||= config.target.value(self); end
41
+
42
+ def copy_dump_cmd_args
43
+ @copy_dump_cmd_args ||= config.copy_dump_cmd_args.value(self)
44
+ end
45
+
46
+ def dump_cmds; @dump_cmds ||= config.dump_cmds.value(self); end
47
+ def restore_cmds; @restore_cmds ||= config.restore_cmds.value(self); end
48
+
49
+ def source_dump_file; self.source.dump_file; end
50
+ def target_dump_file; self.target.dump_file; end
51
+
52
+ def source_hash; self.source.to_hash; end
53
+ def target_hash; self.target.to_hash; end
54
+
55
+ def ssh?
56
+ self.ssh && !self.ssh.empty?
57
+ end
58
+
59
+ def dump_cmd(&block); config.dump_cmd(self, &block); end
60
+ def restore_cmd(&block) config.restore_cmd(self, &block); end
61
+
62
+ end
63
+
64
+ module ClassMethods
65
+
66
+ def config_blocks
67
+ @config_blocks ||= []
68
+ end
69
+
70
+ def config(&block)
71
+ self.config_blocks << block if !block.nil?
72
+ end
73
+
74
+ def task_description(value = nil)
75
+ self::Task.description(value)
76
+ end
77
+ alias_method :task_desc, :task_description
78
+
79
+ end
80
+
81
+ end
82
+
83
+ end
@@ -0,0 +1,58 @@
1
+ require 'dk/task'
2
+ require 'much-plugin'
3
+ require 'dk-dumpdb/task/copy_dump'
4
+ require 'dk-dumpdb/task/dump'
5
+ require 'dk-dumpdb/task/restore'
6
+ require 'dk-dumpdb/task/setup'
7
+ require 'dk-dumpdb/task/teardown'
8
+
9
+ module Dk::Dumpdb
10
+
11
+ module Task
12
+ include MuchPlugin
13
+
14
+ plugin_included do
15
+ include Dk::Task
16
+ include InstanceMethods
17
+ extend ClassMethods
18
+
19
+ end
20
+
21
+ module InstanceMethods
22
+
23
+ def run!
24
+ script = self.class.script_class.new(params)
25
+
26
+ run_task Setup, 'script' => script
27
+ begin
28
+ run_task Dump, 'script' => script
29
+ run_task CopyDump, 'script' => script
30
+ run_task Restore, 'script' => script
31
+ ensure
32
+ run_task Teardown, 'script' => script
33
+ end
34
+ end
35
+
36
+ end
37
+
38
+ module ClassMethods
39
+
40
+ def script_class(value = nil)
41
+ @script_class = value if !value.nil?
42
+ @script_class
43
+ end
44
+
45
+ end
46
+
47
+ module TestHelpers
48
+ include MuchPlugin
49
+
50
+ plugin_included do
51
+ include Dk::Task::TestHelpers
52
+ end
53
+
54
+ end
55
+
56
+ end
57
+
58
+ end
@@ -0,0 +1,16 @@
1
+ require 'dk-dumpdb/task/internal_task'
2
+
3
+ module Dk::Dumpdb::Task
4
+
5
+ class CopyDump
6
+ include Dk::Dumpdb::Task::InternalTask
7
+
8
+ desc "(dk-dumpdb) copy the given script's dump file from source to target"
9
+
10
+ def run!
11
+ copy_cmd! params['script'].copy_dump_cmd_args
12
+ end
13
+
14
+ end
15
+
16
+ end
@@ -0,0 +1,16 @@
1
+ require 'dk-dumpdb/task/internal_task'
2
+
3
+ module Dk::Dumpdb::Task
4
+
5
+ class Dump
6
+ include Dk::Dumpdb::Task::InternalTask
7
+
8
+ desc "(dk-dumpdb) run the given script's dump cmds"
9
+
10
+ def run!
11
+ params['script'].dump_cmds.each{ |cmd_str| source_cmd!(cmd_str) }
12
+ end
13
+
14
+ end
15
+
16
+ end
@@ -0,0 +1,44 @@
1
+ require 'dk/task'
2
+ require 'much-plugin'
3
+ require 'dk-dumpdb'
4
+
5
+ module Dk::Dumpdb::Task
6
+
7
+ module InternalTask
8
+ include MuchPlugin
9
+
10
+ plugin_included do
11
+ include Dk::Task
12
+ include InstanceMethods
13
+
14
+ end
15
+
16
+ module InstanceMethods
17
+
18
+ private
19
+
20
+ def source_cmd!(cmd_str)
21
+ if params['script'].ssh?
22
+ ssh!(cmd_str, :hosts => params['script'].ssh)
23
+ else
24
+ cmd!(cmd_str)
25
+ end
26
+ end
27
+
28
+ def copy_cmd!(args)
29
+ if (s = params['script']).ssh?
30
+ cmd! "scp #{try_param(Dk::Dumpdb::SCP_ARGS_PARAM_NAME)} #{s.ssh}:#{args}"
31
+ else
32
+ cmd! "cp #{args}"
33
+ end
34
+ end
35
+
36
+ def target_cmd!(cmd_str)
37
+ cmd!(cmd_str)
38
+ end
39
+
40
+ end
41
+
42
+ end
43
+
44
+ end
@@ -0,0 +1,16 @@
1
+ require 'dk-dumpdb/task/internal_task'
2
+
3
+ module Dk::Dumpdb::Task
4
+
5
+ class Restore
6
+ include Dk::Dumpdb::Task::InternalTask
7
+
8
+ desc "(dk-dumpdb) run the given script's restore cmds"
9
+
10
+ def run!
11
+ params['script'].restore_cmds.each{ |cmd_str| target_cmd!(cmd_str) }
12
+ end
13
+
14
+ end
15
+
16
+ end
@@ -0,0 +1,17 @@
1
+ require 'dk-dumpdb/task/internal_task'
2
+
3
+ module Dk::Dumpdb::Task
4
+
5
+ class Setup
6
+ include Dk::Dumpdb::Task::InternalTask
7
+
8
+ desc "(dk-dumpdb) setup a script run"
9
+
10
+ def run!
11
+ source_cmd!(params['script'].dump_cmd{ "mkdir -p #{source.output_dir}" })
12
+ target_cmd!(params['script'].restore_cmd{ "mkdir -p #{target.output_dir}" })
13
+ end
14
+
15
+ end
16
+
17
+ end
@@ -0,0 +1,17 @@
1
+ require 'dk-dumpdb/task/internal_task'
2
+
3
+ module Dk::Dumpdb::Task
4
+
5
+ class Teardown
6
+ include Dk::Dumpdb::Task::InternalTask
7
+
8
+ desc "(dk-dumpdb) teardown a script run"
9
+
10
+ def run!
11
+ source_cmd!(params['script'].dump_cmd{ "rm -rf #{source.output_dir}" })
12
+ target_cmd!(params['script'].restore_cmd{ "rm -rf #{target.output_dir}" })
13
+ end
14
+
15
+ end
16
+
17
+ end
@@ -1,4 +1,4 @@
1
1
  module Dk; end
2
2
  module Dk::Dumpdb
3
- VERSION = "0.0.1"
3
+ VERSION = "0.1.0"
4
4
  end
@@ -1,6 +1,18 @@
1
1
  require 'assert/factory'
2
+ require 'dk-dumpdb/script'
2
3
 
3
4
  module Factory
4
5
  extend Assert::Factory
5
6
 
7
+ def self.script_class(&config_proc)
8
+ Class.new do
9
+ include Dk::Dumpdb::Script
10
+ config &config_proc
11
+ end
12
+ end
13
+
14
+ def self.script(script_class = nil, &config_proc)
15
+ (script_class || self.script_class(&config_proc)).new
16
+ end
17
+
6
18
  end
@@ -0,0 +1,27 @@
1
+ require 'dk/task'
2
+ require 'much-plugin'
3
+ require 'dk-dumpdb/task/internal_task'
4
+
5
+ module Dk::Dumpdb::Task::InternalTask
6
+
7
+ module TestHelpers
8
+ include MuchPlugin
9
+
10
+ plugin_included do
11
+ include Dk::Task::TestHelpers
12
+ include InstanceMethods
13
+
14
+ end
15
+
16
+ module InstanceMethods
17
+
18
+ def set_dk_dumpdb_script_param(*args, &block)
19
+ @params ||= {}
20
+ @params['script'] = Factory.script(*args, &block)
21
+ end
22
+
23
+ end
24
+
25
+ end
26
+
27
+ end
@@ -0,0 +1,259 @@
1
+ require 'assert'
2
+ require 'dk-dumpdb/config'
3
+
4
+ require 'dk-dumpdb/db'
5
+ # require 'test/support/test_scripts'
6
+
7
+ class Dk::Dumpdb::Config
8
+
9
+ class UnitTests < Assert::Context
10
+ desc "Dk::Dumpdb::Config"
11
+ setup do
12
+ @script = FakeScript.new
13
+ @config_class = Dk::Dumpdb::Config
14
+ end
15
+
16
+ end
17
+
18
+ class InitTests < UnitTests
19
+ desc "when init"
20
+ setup do
21
+ now = Factory.time
22
+ Assert.stub(Time, :now){ now }
23
+
24
+ @config = @config_class.new
25
+ end
26
+ subject{ @config }
27
+
28
+ should have_readers :copy_dump_cmd_args, :dump_cmds, :restore_cmds
29
+ should have_imeths :ssh, :dump_file, :source, :target, :dump, :restore
30
+ should have_imeths :dump_cmd, :restore_cmd
31
+
32
+ should "default its values" do
33
+ assert_instance_of Ssh, subject.ssh
34
+ assert_equal '', subject.ssh.value(@script)
35
+
36
+ assert_instance_of DumpFile, subject.dump_file
37
+ assert_equal '', subject.dump_file.value(@script)
38
+
39
+ assert_instance_of SourceTargetDb, subject.source
40
+ val = subject.source.value(@script)
41
+ assert_instance_of Dk::Dumpdb::Db, val
42
+ exp = Dk::Dumpdb::Db.new(@script.dump_file, {})
43
+ assert_equal exp, val
44
+
45
+ assert_instance_of SourceTargetDb, subject.target
46
+ val = subject.target.value(@script)
47
+ assert_instance_of Dk::Dumpdb::Db, val
48
+ exp = Dk::Dumpdb::Db.new(@script.dump_file, {})
49
+ assert_equal exp, val
50
+
51
+ assert_instance_of CopyDumpCmdArgs, subject.copy_dump_cmd_args
52
+
53
+ assert_instance_of CmdList, subject.dump_cmds
54
+ assert_equal [], subject.dump_cmds.value(@script)
55
+
56
+ assert_instance_of CmdList, subject.restore_cmds
57
+ assert_equal [], subject.restore_cmds.value(@script)
58
+ end
59
+
60
+ should "allow setting new values" do
61
+ value = Factory.string
62
+ subject.ssh{ value }
63
+ assert_equal value, subject.ssh.value(@script)
64
+
65
+ subject.dump_file{ value }
66
+ assert_equal value, subject.dump_file.value(@script)
67
+
68
+ subject.source do
69
+ { 'pw' => value }
70
+ end
71
+ val = subject.source.value(@script)
72
+ exp = Dk::Dumpdb::Db.new(@script.dump_file, { 'pw' => value })
73
+ assert_equal exp, val
74
+
75
+ subject.target do
76
+ { 'pw' => value }
77
+ end
78
+ val = subject.target.value(@script)
79
+ exp = Dk::Dumpdb::Db.new(@script.dump_file, { 'pw' => value })
80
+ assert_equal exp, val
81
+ end
82
+
83
+ should "append dump/restore cmds" do
84
+ subject.dump{ Factory.string }
85
+ assert_equal 1, subject.dump_cmds.value(@script).size
86
+ assert_instance_of DumpCmd, subject.dump_cmds.first
87
+
88
+ subject.restore{ Factory.string }
89
+ assert_equal 1, subject.restore_cmds.value(@script).size
90
+ assert_instance_of RestoreCmd, subject.restore_cmds.first
91
+ end
92
+
93
+ should "build dump/restore cmd strs" do
94
+ cmd_str = "#{Factory.string}; pw: `:pw`"
95
+
96
+ exp = DumpCmd.new(proc{ cmd_str }).value(@script)
97
+ assert_equal exp, subject.dump_cmd(@script){ cmd_str }
98
+
99
+ exp = RestoreCmd.new(proc{ cmd_str }).value(@script)
100
+ assert_equal exp, subject.restore_cmd(@script){ cmd_str }
101
+ end
102
+
103
+ end
104
+
105
+ class ValueTests < UnitTests
106
+ desc "Value"
107
+ setup do
108
+ @setting = Value.new
109
+ end
110
+ subject{ @setting }
111
+
112
+ should have_readers :proc
113
+ should have_imeths :value
114
+
115
+ should "know its proc" do
116
+ assert_kind_of ::Proc, subject.proc
117
+ assert_nil subject.proc.call
118
+ end
119
+
120
+ should "instance eval its proc in the scope of a script to return a value" do
121
+ setting = Value.new(Proc.new{ "something: #{dump_file}" })
122
+ assert_equal "something: #{@script.dump_file}", setting.value(@script)
123
+ end
124
+
125
+ end
126
+
127
+ class SshTests < UnitTests
128
+ desc "Ssh"
129
+
130
+ should "be a Value" do
131
+ assert_true Ssh < Value
132
+ end
133
+
134
+ end
135
+
136
+ class DumpFileTests < UnitTests
137
+ desc "DumpFile"
138
+
139
+ should "be a Value" do
140
+ assert_true DumpFile < Value
141
+ end
142
+
143
+ end
144
+
145
+ class SourceTargetDbTests < UnitTests
146
+ desc "SourceTargetDb"
147
+
148
+ should "be a Value" do
149
+ assert_true SourceTargetDb < Value
150
+ end
151
+
152
+ should "have a Db value built from a hash" do
153
+ db_hash = { 'host' => Factory.string }
154
+ db = SourceTargetDb.new(db_hash).value(@script)
155
+ assert_instance_of Dk::Dumpdb::Db, db
156
+
157
+ assert_equal db_hash['host'], db.host
158
+ assert_includes @script.dump_file, db.to_hash[:dump_file]
159
+ end
160
+
161
+ end
162
+
163
+ class CopyDumpCmdArgsTests < UnitTests
164
+ desc "CopyDumpCmdArgs"
165
+
166
+ should "be a Value" do
167
+ assert_true CopyDumpCmdArgs < Value
168
+ end
169
+
170
+ should "know its value" do
171
+ exp = "#{@script.source_dump_file} #{@script.target_dump_file}"
172
+ assert_equal exp, CopyDumpCmdArgs.new.value(@script)
173
+ end
174
+
175
+ end
176
+
177
+ class CmdTests < UnitTests
178
+ desc "Cmd"
179
+
180
+ should "be a Value" do
181
+ assert_true Cmd < Value
182
+ end
183
+
184
+ should "eval and apply any placeholders to the cmd string" do
185
+ cmd_str = Proc.new{ "dump file: `#{dump_file}`; pw: `:pw`" }
186
+
187
+ exp = "dump file: `#{@script.dump_file}`; pw: `#{@script.source_hash['pw']}`"
188
+ assert_equal exp, Cmd.new(cmd_str).value(@script, @script.source_hash)
189
+ end
190
+
191
+ end
192
+
193
+ class DumpCmdTests < UnitTests
194
+ desc "DumpCmd"
195
+
196
+ should "be a Cmd" do
197
+ assert_true DumpCmd < Cmd
198
+ end
199
+
200
+ should "eval and apply any source placeholders to the cmd string" do
201
+ cmd_str = Proc.new{ "dump file: `#{dump_file}`; pw: `:pw`" }
202
+
203
+ exp = "dump file: `#{@script.dump_file}`; pw: `#{@script.source_hash['pw']}`"
204
+ assert_equal exp, DumpCmd.new(cmd_str).value(@script)
205
+ end
206
+
207
+ end
208
+
209
+ class RestoreCmdTests < UnitTests
210
+ desc "RestoreCmd"
211
+
212
+ should "be a Cmd" do
213
+ assert_true RestoreCmd < Cmd
214
+ end
215
+
216
+ should "eval and apply any target placeholders to the cmd string" do
217
+ cmd_str = Proc.new{ "dump file: `#{dump_file}`; pw: `:pw`" }
218
+
219
+ exp = "dump file: `#{@script.dump_file}`; pw: `#{@script.target_hash['pw']}`"
220
+ assert_equal exp, RestoreCmd.new(cmd_str).value(@script)
221
+ end
222
+
223
+ end
224
+
225
+ class CmdListTests < UnitTests
226
+ desc "CmdList"
227
+ setup do
228
+ other_cmd = Factory.string
229
+ @cmds = [
230
+ Cmd.new(Proc.new{ "dump file: `#{dump_file}`; pw: `:pw`" }),
231
+ Cmd.new(Proc.new{ other_cmd })
232
+ ]
233
+ end
234
+
235
+ should "be an Array" do
236
+ assert_kind_of ::Array, CmdList.new
237
+ end
238
+
239
+ should "return the commands, eval'd and placeholders applied" do
240
+ exp = @cmds.map{ |c| c.value(@script, @script.source_hash) }
241
+ assert_equal exp, CmdList.new(@cmds).value(@script, @script.source_hash)
242
+ end
243
+
244
+ end
245
+
246
+ class FakeScript
247
+ attr_reader :dump_file, :source_dump_file, :target_dump_file
248
+ attr_reader :source_hash, :target_hash
249
+
250
+ def initialize
251
+ @dump_file = Factory.string
252
+ @source_dump_file = File.join(Factory.path, @dump_file)
253
+ @target_dump_file = File.join(Factory.path, @dump_file)
254
+ @source_hash = { 'pw' => Factory.string }
255
+ @target_hash = { 'pw' => Factory.string }
256
+ end
257
+ end
258
+
259
+ end