mysql-slaver 0.1.13 → 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.
checksums.yaml CHANGED
@@ -1,7 +1,15 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 4e9d24a3c9ff946cc64f58907bde35066b175e77
4
- data.tar.gz: 8d4d3066bef6770d7a3d7f4b58a5230bbb2d7c88
2
+ !binary "U0hBMQ==":
3
+ metadata.gz: !binary |-
4
+ YzdhZjFhOTkyMGFhMjk3NGNjMWRkZDRlOWZjNmZhZmQzNTA4MTVkMQ==
5
+ data.tar.gz: !binary |-
6
+ N2IzYTBhODAwYzU2MjBmZGYwZDUxY2MwODg3YWVjNTk4MGYwM2E5Nw==
5
7
  SHA512:
6
- metadata.gz: a08b60d264c9b12ea14586fc5df10b45058a536f5b8e5ca7802ae790cea4e92face82a4d6022a467b86862dcca69dbc3dabc0ac43d16d74cb09e8792e81d585f
7
- data.tar.gz: 6e713f19740a10ab24d237b234a8e89f6d49b719c109d9d90512a517991e74eaece1895ecb1f9b49b7b8bffbc10f175e41394d2015c22b39269292763fb4179e
8
+ metadata.gz: !binary |-
9
+ OWY0MjgyODk1ODk5YTc1ZmE4OTUxNTAwN2MwNGEwNDFiNjY4NTQ5NDhhZDY5
10
+ OGRkNGRhMGM4OGQ1NjIzODc0YzMwMjI1NmIyNWEwZDM3MmMxNjJiMTI2NjNk
11
+ MDdiNTI1NmQwODA2MzkyODM5ZWY3NjU5NzcyMTc3NDRlZDdhZmU=
12
+ data.tar.gz: !binary |-
13
+ MzQ3OWZmOWVmMTdjMmM5NzhhZTM4NDA3MWFjZmRjOWYzYTJlN2Y0YmJmNWMx
14
+ ODZlYTQ0MTFkMGY4ZTI1MjFiNDI3NDBhZjg2MDEzYWIwODlkODUyODAyMDQx
15
+ NDQ3NDMyMDhiMzM0ZWFmYzgxMDU1ZTJlYTFlZGQxODY3YmY0OTk=
data/Gemfile CHANGED
@@ -9,5 +9,5 @@ group :development, :test do
9
9
  gem "gem-this"
10
10
  gem "gemcutter"
11
11
  gem "rspec"
12
- # gem "ruby-debug"
12
+ gem "debugger"
13
13
  end
data/Gemfile.lock CHANGED
@@ -1,34 +1,42 @@
1
1
  GEM
2
2
  remote: https://rubygems.org/
3
3
  specs:
4
+ columnize (0.9.0)
5
+ debugger (1.6.8)
6
+ columnize (>= 0.3.1)
7
+ debugger-linecache (~> 1.2.0)
8
+ debugger-ruby_core_source (~> 1.3.5)
9
+ debugger-linecache (1.2.0)
10
+ debugger-ruby_core_source (1.3.8)
4
11
  diff-lcs (1.2.5)
5
12
  gem-this (0.3.7)
6
13
  gemcutter (0.7.1)
7
- json (1.8.1)
14
+ json (1.8.3)
8
15
  rake (10.4.2)
9
16
  rdoc (4.2.0)
10
17
  json (~> 1.4)
11
18
  rdoc-data (4.0.1)
12
19
  rdoc (~> 4.0)
13
- rspec (3.2.0)
14
- rspec-core (~> 3.2.0)
15
- rspec-expectations (~> 3.2.0)
16
- rspec-mocks (~> 3.2.0)
17
- rspec-core (3.2.0)
18
- rspec-support (~> 3.2.0)
19
- rspec-expectations (3.2.0)
20
+ rspec (3.3.0)
21
+ rspec-core (~> 3.3.0)
22
+ rspec-expectations (~> 3.3.0)
23
+ rspec-mocks (~> 3.3.0)
24
+ rspec-core (3.3.2)
25
+ rspec-support (~> 3.3.0)
26
+ rspec-expectations (3.3.1)
20
27
  diff-lcs (>= 1.2.0, < 2.0)
21
- rspec-support (~> 3.2.0)
22
- rspec-mocks (3.2.0)
28
+ rspec-support (~> 3.3.0)
29
+ rspec-mocks (3.3.2)
23
30
  diff-lcs (>= 1.2.0, < 2.0)
24
- rspec-support (~> 3.2.0)
25
- rspec-support (3.2.1)
31
+ rspec-support (~> 3.3.0)
32
+ rspec-support (3.3.0)
26
33
  thor (0.19.1)
27
34
 
28
35
  PLATFORMS
29
36
  ruby
30
37
 
31
38
  DEPENDENCIES
39
+ debugger
32
40
  gem-this
33
41
  gemcutter
34
42
  rake
@@ -36,3 +44,6 @@ DEPENDENCIES
36
44
  rdoc-data
37
45
  rspec
38
46
  thor
47
+
48
+ BUNDLED WITH
49
+ 1.10.6
data/README.md CHANGED
@@ -16,6 +16,7 @@ BLOGPOST
16
16
 
17
17
  ASSUMPTIONS/PRE-REQUISITES
18
18
 
19
+ * ruby 1.9.3 or greater
19
20
  * localhost is configured as a mysql replication slave
20
21
  * the current localhost user can ssh to the db master
21
22
  * any ssh config settings, other than a port number, required to access the master from localhost are set in a ~/.ssh/config file
data/Rakefile CHANGED
@@ -9,7 +9,7 @@ RSpec::Core::RakeTask.new do |t|
9
9
  end
10
10
 
11
11
 
12
- task :default => ["spec"]
12
+ task default: ["spec"]
13
13
 
14
14
  # This builds the actual gem. For details of what all these options
15
15
  # mean, and other ones you can add, check the documentation here:
@@ -20,7 +20,7 @@ spec = Gem::Specification.new do |s|
20
20
 
21
21
  # Change these as appropriate
22
22
  s.name = "mysql-slaver"
23
- s.version = "0.1.13"
23
+ s.version = "0.2.0"
24
24
  s.summary = "Setup mysql replication"
25
25
  s.author = "David Salgado"
26
26
  s.email = "david@digitalronin.com"
@@ -67,7 +67,7 @@ end
67
67
  # - using bundler with a git source
68
68
  # - building the gem without rake (i.e. gem build blah.gemspec)
69
69
  # - maybe others?
70
- task :package => :gemspec
70
+ task package: :gemspec
71
71
 
72
72
  # Generate documentation
73
73
  RDoc::Task.new do |rd|
@@ -77,6 +77,6 @@ RDoc::Task.new do |rd|
77
77
  end
78
78
 
79
79
  desc 'Clear out RDoc and generated packages'
80
- task :clean => [:clobber_rdoc, :clobber_package] do
80
+ task clean: [:clobber_rdoc, :clobber_package] do
81
81
  rm "#{spec.name}.gemspec"
82
82
  end
@@ -0,0 +1,6 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'bundler/setup'
4
+ require './lib/mysql_slaver'
5
+
6
+ MysqlSlaver::CLI.start(ARGV)
@@ -2,27 +2,31 @@ module MysqlSlaver
2
2
  class CLI < ::Thor
3
3
  desc "enslave", "Start MySQL replication to this host from a master"
4
4
 
5
- option :master_host, :required => true, :desc => "The server which will be the replication master, for this slave"
6
- option :database, :required => true, :desc => "The database to copy from the master"
7
- option :replication_user, :required => true, :desc => "DB user (on the master host), with replication permissions"
8
- option :replication_password, :required => true, :desc => "DB password for the replication user"
9
- option :root_password, :desc => "Password for the mysql root user (on both master and slave)"
10
- option :port, :default => 3306, :desc => "Mysql port"
11
- option :ssh_port, :default => 22, :desc => "SSH port"
12
- option :sock, :desc => "Mysql socket file (if any)"
13
- option :no_copy, :type => :boolean, :desc => "Do not copy data - just change master status"
5
+ option :master_host, required: true, desc: "The server which will be the replication master, for this slave"
6
+ option :database, required: true, desc: "The database to copy from the master"
7
+ option :replication_user, required: true, desc: "DB user (on the master host), with replication permissions"
8
+ option :replication_password, required: true, desc: "DB password for the replication user"
9
+ option :root_password, desc: "Password for the mysql root user (on both master and slave)"
10
+ option :port, default: 3306, desc: "Mysql port"
11
+ option :ssh_port, default: 22, desc: "SSH port"
12
+ option :sock, desc: "Mysql socket file (if any)"
13
+ option :no_copy, type: :boolean, desc: "Do not copy data - just change master status"
14
+ option :tables, desc: "Space-separated list of tables to copy (defaults to entire database)"
15
+ option :dry_run, type: :boolean, desc: "Display commands without executing"
14
16
 
15
17
  def enslave
16
18
  MysqlSlaver::Slaver.new(
17
- :master_host => options[:master_host],
18
- :port => options[:port],
19
- :ssh_port => options[:ssh_port],
20
- :socket_file => options[:sock],
21
- :no_copy => options[:no_copy],
22
- :mysql_root_password => options[:root_password],
23
- :database => options[:database],
24
- :replication_user => options[:replication_user],
25
- :replication_password => options[:replication_password]
19
+ master_host: options[:master_host],
20
+ port: options[:port],
21
+ ssh_port: options[:ssh_port],
22
+ socket_file: options[:sock],
23
+ no_copy: options[:no_copy],
24
+ mysql_root_password: options[:root_password],
25
+ database: options[:database],
26
+ replication_user: options[:replication_user],
27
+ replication_password: options[:replication_password],
28
+ tables: options[:tables],
29
+ dry_run: options[:dry_run]
26
30
  ).enslave!
27
31
  end
28
32
  end
@@ -2,7 +2,7 @@ module MysqlSlaver
2
2
  class DbCopier
3
3
  include MysqlCommand
4
4
 
5
- attr_accessor :master_host, :mysql_root_password, :database, :executor, :port, :socket_file
5
+ attr_accessor :master_host, :mysql_root_password, :database, :executor, :port, :socket_file, :tables
6
6
 
7
7
  def initialize(params)
8
8
  @master_host = params.fetch(:master_host)
@@ -10,7 +10,8 @@ module MysqlSlaver
10
10
  @database = params.fetch(:database)
11
11
  @port = params.fetch(:port, nil)
12
12
  @socket_file = params.fetch(:socket_file, nil)
13
- @executor = params.fetch(:executor) { Executor.new(:ssh_port => params[:ssh_port]) }
13
+ @executor = params.fetch(:executor) { Executor.new(ssh_port: params[:ssh_port]) }
14
+ @tables = params.fetch(:tables, nil)
14
15
  end
15
16
 
16
17
  def copy!
@@ -26,8 +27,8 @@ module MysqlSlaver
26
27
 
27
28
  def mysql_params
28
29
  {
29
- :root_password => mysql_root_password,
30
- :socket_file => socket_file
30
+ root_password: mysql_root_password,
31
+ socket_file: socket_file
31
32
  }
32
33
  end
33
34
 
@@ -36,6 +37,7 @@ module MysqlSlaver
36
37
  rtn = %[mysqldump]
37
38
  rtn << %[ -P #{port}] if port
38
39
  rtn << %[ #{creds} -h #{master_host} --master-data --single-transaction --quick --skip-add-locks --skip-lock-tables --default-character-set=utf8 --compress #{database}]
40
+ rtn << %[ #{tables}] unless tables.to_s.empty?
39
41
  rtn
40
42
  end
41
43
  end
@@ -1,11 +1,12 @@
1
1
  module MysqlSlaver
2
2
  class Executor
3
- attr_reader :ssh_port
3
+ attr_reader :ssh_port, :dry_run
4
4
 
5
5
  include Logger
6
6
 
7
7
  def initialize(params = {})
8
8
  @ssh_port = params[:ssh_port]
9
+ @dry_run = params.fetch(:dry_run, false)
9
10
  end
10
11
 
11
12
  def ssh_command(cmd, host)
@@ -19,8 +20,18 @@ module MysqlSlaver
19
20
  def execute(cmd)
20
21
  string = cmd.is_a?(Array) ? cmd.join('; ') : cmd
21
22
  log "CMD: #{string}"
22
- result = `#{string}`
23
- $?.success? ? result : nil
23
+ if dry_run
24
+ "[DUMMY RESULT]"
25
+ else
26
+ result = `#{string}`
27
+ success? ? result : nil
28
+ end
29
+ end
30
+
31
+ private
32
+
33
+ def success?
34
+ $?.success?
24
35
  end
25
36
  end
26
37
  end
@@ -28,8 +28,8 @@ module MysqlSlaver
28
28
 
29
29
  def mysql_params
30
30
  {
31
- :root_password => mysql_root_password,
32
- :socket_file => socket_file
31
+ root_password: mysql_root_password,
32
+ socket_file: socket_file
33
33
  }
34
34
  end
35
35
 
@@ -8,43 +8,51 @@ module MysqlSlaver
8
8
  class Slaver
9
9
  include Logger
10
10
 
11
- attr_reader :status_fetcher, :data_copier, :master_changer, :no_copy
11
+ attr_reader :status_fetcher, :data_copier, :master_changer, :no_copy, :tables
12
12
 
13
13
  def initialize(params)
14
14
  mysql_root_password = params.fetch(:mysql_root_password, '')
15
15
  port = params.fetch(:port, 3306)
16
16
  ssh_port = params.fetch(:ssh_port, 22)
17
17
  socket_file = params.fetch(:socket_file, nil)
18
+ tables = params.fetch(:tables, nil)
18
19
  @no_copy = params.fetch(:no_copy, false)
19
20
 
21
+ dry_run = params.fetch(:dry_run, false)
22
+ executor = Executor.new(ssh_port: params[:ssh_port], dry_run: dry_run)
23
+
20
24
  @status_fetcher = params.fetch(:status_fetcher) {
21
25
  StatusFetcher.new(
22
- :master_host => params.fetch(:master_host),
23
- :mysql_root_password => mysql_root_password,
24
- :socket_file => socket_file,
25
- :ssh_port => ssh_port
26
+ master_host: params.fetch(:master_host),
27
+ mysql_root_password: mysql_root_password,
28
+ socket_file: socket_file,
29
+ ssh_port: ssh_port,
30
+ executor: executor
26
31
  )
27
32
  }
28
33
 
29
34
  @data_copier = params.fetch(:data_copier) {
30
35
  DbCopier.new(
31
- :master_host => params.fetch(:master_host),
32
- :mysql_root_password => mysql_root_password,
33
- :database => params.fetch(:database),
34
- :port => port,
35
- :socket_file => socket_file,
36
- :ssh_port => ssh_port
36
+ master_host: params.fetch(:master_host),
37
+ mysql_root_password: mysql_root_password,
38
+ database: params.fetch(:database),
39
+ port: port,
40
+ socket_file: socket_file,
41
+ tables: tables,
42
+ ssh_port: ssh_port,
43
+ executor: executor
37
44
  )
38
45
  }
39
46
 
40
47
  @master_changer = params.fetch(:master_changer) {
41
48
  MasterChanger.new(
42
- :master_host => params.fetch(:master_host),
43
- :mysql_root_password => mysql_root_password,
44
- :replication_user => params.fetch(:replication_user),
45
- :replication_password => params.fetch(:replication_password),
46
- :port => port,
47
- :socket_file => socket_file
49
+ master_host: params.fetch(:master_host),
50
+ mysql_root_password: mysql_root_password,
51
+ replication_user: params.fetch(:replication_user),
52
+ replication_password: params.fetch(:replication_password),
53
+ port: port,
54
+ socket_file: socket_file,
55
+ executor: executor
48
56
  )
49
57
  }
50
58
  end
@@ -9,11 +9,11 @@ module MysqlSlaver
9
9
  @master_host = params.fetch(:master_host)
10
10
  @socket_file = params.fetch(:socket_file, nil)
11
11
  @mysql_root_password = params.fetch(:mysql_root_password, '')
12
- @executor = params.fetch(:executor) { Executor.new(:ssh_port => params[:ssh_port]) }
12
+ @executor = params.fetch(:executor) { Executor.new(ssh_port: params[:ssh_port]) }
13
13
  end
14
14
 
15
15
  def status
16
- params = {:root_password => mysql_root_password, :socket_file => socket_file}
16
+ params = {root_password: mysql_root_password, socket_file: socket_file}
17
17
  cmd = mysql_command("show master status\\G", params)
18
18
  if data = executor.execute(executor.ssh_command(cmd, master_host))
19
19
  rtn = parse data
@@ -37,7 +37,7 @@ module MysqlSlaver
37
37
  position = $1
38
38
  end
39
39
  end
40
- {:file => file, :position => position}
40
+ {file: file, position: position}
41
41
  end
42
42
 
43
43
  end
@@ -1,15 +1,15 @@
1
- require 'spec/spec_helper'
1
+ require './spec/spec_helper'
2
2
 
3
3
  module MysqlSlaver
4
4
  describe DbCopier do
5
- let(:executor) { double(Executor, :execute => true, :ssh_command => "dummy-ssh-command") }
5
+ let(:executor) { double(Executor, execute: true, ssh_command: "dummy-ssh-command") }
6
6
 
7
7
  let(:params) {
8
8
  {
9
- :master_host => 'my.db.host',
10
- :mysql_root_password => 'supersekrit',
11
- :database => 'myappdb',
12
- :executor => executor
9
+ master_host: 'my.db.host',
10
+ mysql_root_password: 'supersekrit',
11
+ database: 'myappdb',
12
+ executor: executor
13
13
  }
14
14
  }
15
15
  subject(:copier) { described_class.new(params) }
@@ -37,7 +37,7 @@ module MysqlSlaver
37
37
  end
38
38
 
39
39
  context "with a non-standard mysql port" do
40
- let(:params) { super().merge(:port => 3307) }
40
+ let(:params) { super().merge(port: 3307) }
41
41
 
42
42
  it "issues mysqldump over ssh" do
43
43
  dump = "mysqldump -P 3307 -u root -p supersekrit -h my.db.host --master-data --single-transaction --quick --skip-add-locks --skip-lock-tables --default-character-set=utf8 --compress myappdb"
@@ -47,7 +47,7 @@ module MysqlSlaver
47
47
  end
48
48
 
49
49
  context "with a socket file" do
50
- let(:params) { super().merge(:socket_file => "/tmp/mysql.sock") }
50
+ let(:params) { super().merge(socket_file: "/tmp/mysql.sock") }
51
51
 
52
52
  it "issues mysqldump over ssh" do
53
53
  dump = "mysqldump -S /tmp/mysql.sock -u root -p supersekrit -h my.db.host --master-data --single-transaction --quick --skip-add-locks --skip-lock-tables --default-character-set=utf8 --compress myappdb"
@@ -62,5 +62,15 @@ module MysqlSlaver
62
62
  end
63
63
 
64
64
  end
65
+
66
+ context "with a list of tables" do
67
+ let(:params) { super().merge(tables: 'foo bar baz') }
68
+
69
+ it "lists tables in mysqldump command" do
70
+ dump = "mysqldump -u root -p supersekrit -h my.db.host --master-data --single-transaction --quick --skip-add-locks --skip-lock-tables --default-character-set=utf8 --compress myappdb foo bar baz"
71
+ expect(executor).to receive(:ssh_command).with(dump, 'my.db.host')
72
+ copier.copy!
73
+ end
74
+ end
65
75
  end
66
76
  end
@@ -1,12 +1,16 @@
1
- require 'spec/spec_helper'
1
+ require './spec/spec_helper'
2
2
 
3
3
  module MysqlSlaver
4
4
  describe Executor do
5
5
  let(:ssh_port) { nil }
6
- let(:params) { {:ssh_port => ssh_port} }
6
+ let(:params) { {ssh_port: ssh_port} }
7
7
 
8
8
  subject(:executor) { described_class.new(params) }
9
9
 
10
+ before do
11
+ allow(executor).to receive(:log)
12
+ end
13
+
10
14
  describe "#ssh_command" do
11
15
  it "formats command" do
12
16
  expect(executor.ssh_command("foo", "myhost")).to eq("ssh myhost 'foo'")
@@ -20,5 +24,57 @@ module MysqlSlaver
20
24
  end
21
25
  end
22
26
  end
27
+
28
+ describe "#execute" do
29
+ let(:succeeded) { true }
30
+
31
+ before do
32
+ allow(executor).to receive(:success?).and_return(succeeded)
33
+ end
34
+
35
+ context "when command succeeds" do
36
+ let(:succeeded) { true }
37
+
38
+ it "runs command in backticks" do
39
+ expect(executor).to receive(:`).with('ls')
40
+ executor.execute('ls')
41
+ end
42
+
43
+ it "returns the command output" do
44
+ expect(executor).to receive(:`).with('ls').and_return("foo\nbar\nbaz")
45
+ expect(executor.execute('ls')).to eq("foo\nbar\nbaz")
46
+ end
47
+ end
48
+
49
+ context "when command fails" do
50
+ let(:succeeded) { false }
51
+
52
+ before do
53
+ allow(executor).to receive(:`)
54
+ end
55
+
56
+ it "runs command in backticks" do
57
+ expect(executor).to receive(:`).with('ls')
58
+ executor.execute('ls')
59
+ end
60
+
61
+ it "returns nil" do
62
+ expect(executor.execute('ls')).to be_nil
63
+ end
64
+ end
65
+
66
+ context "dry-run" do
67
+ let(:params) { super().merge(dry_run: true) }
68
+
69
+ it "doesn't run the command" do
70
+ expect(executor).to_not receive(:`)
71
+ executor.execute('ls')
72
+ end
73
+
74
+ it "returns dummy result" do
75
+ expect(executor.execute('ls')).to eq("[DUMMY RESULT]")
76
+ end
77
+ end
78
+ end
23
79
  end
24
80
  end
@@ -1,18 +1,18 @@
1
- require 'spec/spec_helper'
1
+ require './spec/spec_helper'
2
2
 
3
3
  module MysqlSlaver
4
4
  describe MasterChanger do
5
- let(:executor) { double(Executor, :execute => true) }
5
+ let(:executor) { double(Executor, execute: true) }
6
6
 
7
- let(:status) { {:file => 'mysql-bin.001555', :position => 18426246} }
7
+ let(:status) { {file: 'mysql-bin.001555', position: 18426246} }
8
8
  let(:params) {
9
9
  {
10
- :master_host => 'my.db.host',
11
- :port => 3306,
12
- :mysql_root_password => 'supersekrit',
13
- :replication_user => 'repluser',
14
- :replication_password => 'replpassword',
15
- :executor => executor
10
+ master_host: 'my.db.host',
11
+ port: 3306,
12
+ mysql_root_password: 'supersekrit',
13
+ replication_user: 'repluser',
14
+ replication_password: 'replpassword',
15
+ executor: executor
16
16
  }
17
17
  }
18
18
  subject(:changer) { described_class.new(params) }
@@ -26,7 +26,7 @@ module MysqlSlaver
26
26
  end
27
27
 
28
28
  context "with a non-standard mysql port" do
29
- let(:params) { super().merge(:port => 3307) }
29
+ let(:params) { super().merge(port: 3307) }
30
30
 
31
31
  it "executes multi-part mysql command" do
32
32
  change_cmd = %[mysql -u root -p supersekrit -e "stop slave; CHANGE MASTER TO MASTER_LOG_FILE='mysql-bin.001555', MASTER_LOG_POS=18426246, MASTER_HOST='my.db.host', MASTER_PORT=3307, MASTER_USER='repluser', MASTER_PASSWORD='replpassword'; start slave"]
@@ -36,7 +36,7 @@ module MysqlSlaver
36
36
  end
37
37
 
38
38
  context "with a mysql socket file" do
39
- let(:params) { super().merge(:socket_file => "/tmp/mysql.sock") }
39
+ let(:params) { super().merge(socket_file: "/tmp/mysql.sock") }
40
40
 
41
41
  it "executes multi-part mysql command" do
42
42
  change_cmd = %[mysql -S /tmp/mysql.sock -u root -p supersekrit -e "stop slave; CHANGE MASTER TO MASTER_LOG_FILE='mysql-bin.001555', MASTER_LOG_POS=18426246, MASTER_HOST='my.db.host', MASTER_PORT=3306, MASTER_USER='repluser', MASTER_PASSWORD='replpassword'; start slave"]
@@ -1,19 +1,19 @@
1
- require 'spec/spec_helper'
1
+ require './spec/spec_helper'
2
2
 
3
3
  module MysqlSlaver
4
4
  describe Slaver do
5
5
  subject(:slaver) { described_class.new(params) }
6
6
 
7
7
  describe "#enslave!" do
8
- let(:status_fetcher) { double(StatusFetcher, :status => ()) }
9
- let(:data_copier) { double(DbCopier, :copy! => true) }
10
- let(:master_changer) { double(MasterChanger, :change! => true) }
8
+ let(:status_fetcher) { double(StatusFetcher, status: ()) }
9
+ let(:data_copier) { double(DbCopier, copy!: true) }
10
+ let(:master_changer) { double(MasterChanger, change!: true) }
11
11
 
12
12
  let(:params) {
13
13
  {
14
- :status_fetcher => status_fetcher,
15
- :data_copier => data_copier,
16
- :master_changer => master_changer
14
+ status_fetcher: status_fetcher,
15
+ data_copier: data_copier,
16
+ master_changer: master_changer
17
17
  }
18
18
  }
19
19
 
@@ -53,7 +53,7 @@ module MysqlSlaver
53
53
  end
54
54
 
55
55
  context "no-copy" do
56
- let(:params) { super().merge(:no_copy => true) }
56
+ let(:params) { super().merge(no_copy: true) }
57
57
 
58
58
  it "fetches master status" do
59
59
  slaver.enslave!
@@ -75,11 +75,11 @@ module MysqlSlaver
75
75
  context "instantiating collaborators" do
76
76
  let(:params) {
77
77
  {
78
- :master_host => 'my.db.host',
79
- :mysql_root_password => 'supersekrit',
80
- :database => 'myappdb',
81
- :replication_user => 'repluser',
82
- :replication_password => 'replpassword'
78
+ master_host: 'my.db.host',
79
+ mysql_root_password: 'supersekrit',
80
+ database: 'myappdb',
81
+ replication_user: 'repluser',
82
+ replication_password: 'replpassword'
83
83
  }
84
84
  }
85
85
 
@@ -106,7 +106,7 @@ module MysqlSlaver
106
106
  end
107
107
 
108
108
  context "with non-standard mysql port" do
109
- let(:params) { super().merge(:port => 3307) }
109
+ let(:params) { super().merge(port: 3307) }
110
110
 
111
111
  it "instantiates a master changer" do
112
112
  changer = slaver.master_changer
@@ -115,7 +115,7 @@ module MysqlSlaver
115
115
  end
116
116
 
117
117
  context "with non-standard ssh port" do
118
- let(:params) { super().merge(:ssh_port => 64389) }
118
+ let(:params) { super().merge(ssh_port: 64389) }
119
119
 
120
120
  it "instantiates a status fetcher" do
121
121
  fetcher = slaver.status_fetcher
@@ -129,7 +129,7 @@ module MysqlSlaver
129
129
  end
130
130
 
131
131
  context "with mysql socket" do
132
- let(:params) { super().merge(:socket_file => "/tmp/mysql.sock") }
132
+ let(:params) { super().merge(socket_file: "/tmp/mysql.sock") }
133
133
 
134
134
  it "instantiates a status fetcher" do
135
135
  fetcher = slaver.status_fetcher
@@ -146,6 +146,34 @@ module MysqlSlaver
146
146
  expect(copier.socket_file).to eq("/tmp/mysql.sock")
147
147
  end
148
148
  end
149
+
150
+ context "with a list of tables" do
151
+ let(:params) { super().merge(tables: 'foo bar baz') }
152
+
153
+ it "instantiates a data copier" do
154
+ copier = slaver.data_copier
155
+ expect(copier.tables).to eq('foo bar baz')
156
+ end
157
+ end
158
+
159
+ context "dry-run" do
160
+ let(:params) { super().merge(dry_run: true) }
161
+
162
+ it "instantiates a status fetcher" do
163
+ fetcher = slaver.status_fetcher
164
+ expect(fetcher.executor.dry_run).to be_truthy
165
+ end
166
+
167
+ it "instantiates a master changer" do
168
+ changer = slaver.master_changer
169
+ expect(changer.executor.dry_run).to be_truthy
170
+ end
171
+
172
+ it "instantiates a data copier" do
173
+ copier = slaver.data_copier
174
+ expect(copier.executor.dry_run).to be_truthy
175
+ end
176
+ end
149
177
  end
150
178
  end
151
179
  end
@@ -1,14 +1,14 @@
1
- require 'spec/spec_helper'
1
+ require './spec/spec_helper'
2
2
 
3
3
  module MysqlSlaver
4
4
  describe StatusFetcher do
5
- let(:executor) { double(Executor, :execute => "", :ssh_command => "dummy-ssh-command") }
5
+ let(:executor) { double(Executor, execute: "", ssh_command: "dummy-ssh-command") }
6
6
 
7
7
  let(:params) {
8
8
  {
9
- :master_host => 'my.db.host',
10
- :mysql_root_password => 'supersekrit',
11
- :executor => executor
9
+ master_host: 'my.db.host',
10
+ mysql_root_password: 'supersekrit',
11
+ executor: executor
12
12
  }
13
13
  }
14
14
  subject(:fetcher) { described_class.new(params) }
@@ -52,13 +52,13 @@ EOF
52
52
  end
53
53
 
54
54
  it "parses show master output" do
55
- expect(fetcher.status).to eq({:file => 'mysql-bin.003219', :position => '37065270'})
55
+ expect(fetcher.status).to eq({file: 'mysql-bin.003219', position: '37065270'})
56
56
  end
57
57
  end
58
58
  end
59
59
 
60
60
  context "using a socket filename" do
61
- let(:params) { super().merge(:socket_file => "/var/run/mysqld/mysqld.master.sock") }
61
+ let(:params) { super().merge(socket_file: "/var/run/mysqld/mysqld.master.sock") }
62
62
 
63
63
  it "executes show master command over ssh" do
64
64
  show_master = %[mysql -S /var/run/mysqld/mysqld.master.sock -u root -p supersekrit -e "show master status\\G"]
data/spec/spec_helper.rb CHANGED
@@ -1,4 +1,4 @@
1
- require 'ruby-debug'
1
+ require 'debugger'
2
2
  Debugger.start
3
3
 
4
- require 'lib/mysql_slaver'
4
+ require './lib/mysql_slaver'
metadata CHANGED
@@ -1,33 +1,34 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mysql-slaver
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.13
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - David Salgado
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-02-09 00:00:00.000000000 Z
11
+ date: 2015-08-15 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rspec
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - ">="
17
+ - - ! '>='
18
18
  - !ruby/object:Gem::Version
19
19
  version: '0'
20
20
  type: :development
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - ">="
24
+ - - ! '>='
25
25
  - !ruby/object:Gem::Version
26
26
  version: '0'
27
27
  description: Make a mysql server into a slave of another, optionally copying data
28
28
  email: david@digitalronin.com
29
29
  executables:
30
30
  - mysql_slaver
31
+ - mysql_slaver-dev
31
32
  extensions: []
32
33
  extra_rdoc_files:
33
34
  - README.md
@@ -37,6 +38,7 @@ files:
37
38
  - README.md
38
39
  - Rakefile
39
40
  - bin/mysql_slaver
41
+ - bin/mysql_slaver-dev
40
42
  - lib/mysql_slaver.rb
41
43
  - lib/mysql_slaver/cli.rb
42
44
  - lib/mysql_slaver/db_copier.rb
@@ -55,27 +57,27 @@ files:
55
57
  - spec/spec_helper.rb
56
58
  homepage: https://digitalronin.github.io/2014/04/16/mysql-slaver-gem-setup-mysql-replication/
57
59
  licenses:
58
- - "[MIT]"
60
+ - ! '[MIT]'
59
61
  metadata: {}
60
62
  post_install_message:
61
63
  rdoc_options:
62
- - "--main"
64
+ - --main
63
65
  - README.md
64
66
  require_paths:
65
67
  - lib
66
68
  required_ruby_version: !ruby/object:Gem::Requirement
67
69
  requirements:
68
- - - ">="
70
+ - - ! '>='
69
71
  - !ruby/object:Gem::Version
70
72
  version: '0'
71
73
  required_rubygems_version: !ruby/object:Gem::Requirement
72
74
  requirements:
73
- - - ">="
75
+ - - ! '>='
74
76
  - !ruby/object:Gem::Version
75
77
  version: '0'
76
78
  requirements: []
77
79
  rubyforge_project:
78
- rubygems_version: 2.4.5
80
+ rubygems_version: 2.4.6
79
81
  signing_key:
80
82
  specification_version: 4
81
83
  summary: Setup mysql replication