lhm 2.1.0 → 2.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 +5 -13
- data/.rubocop.yml +256 -0
- data/.travis.yml +2 -3
- data/CHANGELOG.md +21 -0
- data/README.md +30 -3
- data/Rakefile +2 -2
- data/bin/lhm-config.sh +7 -0
- data/bin/lhm-kill-queue +13 -15
- data/bin/lhm-spec-clobber.sh +1 -1
- data/bin/lhm-spec-grants.sh +2 -2
- data/bin/lhm-spec-setup-cluster.sh +1 -1
- data/gemfiles/ar-2.3_mysql.gemfile +1 -0
- data/lhm.gemspec +6 -6
- data/lib/lhm.rb +20 -8
- data/lib/lhm/atomic_switcher.rb +2 -1
- data/lib/lhm/chunker.rb +19 -19
- data/lib/lhm/command.rb +1 -1
- data/lib/lhm/connection.rb +12 -0
- data/lib/lhm/entangler.rb +5 -5
- data/lib/lhm/intersection.rb +29 -16
- data/lib/lhm/invoker.rb +3 -3
- data/lib/lhm/locked_switcher.rb +6 -6
- data/lib/lhm/migration.rb +5 -4
- data/lib/lhm/migrator.rb +39 -10
- data/lib/lhm/printer.rb +4 -6
- data/lib/lhm/sql_helper.rb +4 -4
- data/lib/lhm/table.rb +12 -12
- data/lib/lhm/version.rb +1 -1
- data/spec/fixtures/users.ddl +1 -1
- data/spec/integration/atomic_switcher_spec.rb +7 -7
- data/spec/integration/chunker_spec.rb +2 -2
- data/spec/integration/cleanup_spec.rb +34 -10
- data/spec/integration/entangler_spec.rb +11 -11
- data/spec/integration/integration_helper.rb +10 -3
- data/spec/integration/lhm_spec.rb +96 -46
- data/spec/integration/locked_switcher_spec.rb +7 -7
- data/spec/integration/table_spec.rb +15 -15
- data/spec/test_helper.rb +4 -4
- data/spec/unit/atomic_switcher_spec.rb +6 -6
- data/spec/unit/chunker_spec.rb +22 -9
- data/spec/unit/entangler_spec.rb +19 -19
- data/spec/unit/intersection_spec.rb +27 -15
- data/spec/unit/lhm_spec.rb +6 -6
- data/spec/unit/locked_switcher_spec.rb +14 -14
- data/spec/unit/migration_spec.rb +6 -6
- data/spec/unit/migrator_spec.rb +53 -41
- data/spec/unit/printer_spec.rb +7 -7
- data/spec/unit/sql_helper_spec.rb +10 -10
- data/spec/unit/table_spec.rb +11 -11
- data/spec/unit/throttler_spec.rb +12 -12
- metadata +12 -10
data/spec/unit/migrator_spec.rb
CHANGED
@@ -10,125 +10,137 @@ describe Lhm::Migrator do
|
|
10
10
|
include UnitHelper
|
11
11
|
|
12
12
|
before(:each) do
|
13
|
-
@table = Lhm::Table.new(
|
13
|
+
@table = Lhm::Table.new('alt')
|
14
14
|
@creator = Lhm::Migrator.new(@table)
|
15
15
|
end
|
16
16
|
|
17
|
-
describe
|
18
|
-
it
|
17
|
+
describe 'index changes' do
|
18
|
+
it 'should add an index' do
|
19
19
|
@creator.add_index(:a)
|
20
20
|
|
21
21
|
@creator.statements.must_equal([
|
22
|
-
|
22
|
+
'create index `index_alt_on_a` on `lhmn_alt` (`a`)'
|
23
23
|
])
|
24
24
|
end
|
25
25
|
|
26
|
-
it
|
26
|
+
it 'should add a composite index' do
|
27
27
|
@creator.add_index([:a, :b])
|
28
28
|
|
29
29
|
@creator.statements.must_equal([
|
30
|
-
|
30
|
+
'create index `index_alt_on_a_and_b` on `lhmn_alt` (`a`, `b`)'
|
31
31
|
])
|
32
32
|
end
|
33
33
|
|
34
|
-
it
|
35
|
-
@creator.add_index([
|
34
|
+
it 'should add an index with prefix length' do
|
35
|
+
@creator.add_index(['a(10)', 'b'])
|
36
36
|
|
37
37
|
@creator.statements.must_equal([
|
38
|
-
|
38
|
+
'create index `index_alt_on_a_and_b` on `lhmn_alt` (`a`(10), `b`)'
|
39
39
|
])
|
40
40
|
end
|
41
41
|
|
42
|
-
it
|
42
|
+
it 'should add an index with a custom name' do
|
43
43
|
@creator.add_index([:a, :b], :custom_index_name)
|
44
44
|
|
45
45
|
@creator.statements.must_equal([
|
46
|
-
|
46
|
+
'create index `custom_index_name` on `lhmn_alt` (`a`, `b`)'
|
47
47
|
])
|
48
48
|
end
|
49
49
|
|
50
|
-
it
|
51
|
-
|
50
|
+
it 'should raise an error when the index name is not a string or symbol' do
|
51
|
+
assert_raises ArgumentError do
|
52
|
+
@creator.add_index([:a, :b], :name => :custom_index_name)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
it 'should add a unique index' do
|
57
|
+
@creator.add_unique_index(['a(5)', :b])
|
52
58
|
|
53
59
|
@creator.statements.must_equal([
|
54
|
-
|
60
|
+
'create unique index `index_alt_on_a_and_b` on `lhmn_alt` (`a`(5), `b`)'
|
55
61
|
])
|
56
62
|
end
|
57
63
|
|
58
|
-
it
|
64
|
+
it 'should add a unique index with a custom name' do
|
59
65
|
@creator.add_unique_index([:a, :b], :custom_index_name)
|
60
66
|
|
61
67
|
@creator.statements.must_equal([
|
62
|
-
|
68
|
+
'create unique index `custom_index_name` on `lhmn_alt` (`a`, `b`)'
|
63
69
|
])
|
64
70
|
end
|
65
71
|
|
66
|
-
it
|
67
|
-
|
72
|
+
it 'should raise an error when the unique index name is not a string or symbol' do
|
73
|
+
assert_raises ArgumentError do
|
74
|
+
@creator.add_unique_index([:a, :b], :name => :custom_index_name)
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
it 'should remove an index' do
|
79
|
+
@creator.remove_index(['b', 'a'])
|
68
80
|
|
69
81
|
@creator.statements.must_equal([
|
70
|
-
|
82
|
+
'drop index `index_alt_on_b_and_a` on `lhmn_alt`'
|
71
83
|
])
|
72
84
|
end
|
73
85
|
|
74
|
-
it
|
86
|
+
it 'should remove an index with a custom name' do
|
75
87
|
@creator.remove_index([:a, :b], :custom_index_name)
|
76
88
|
|
77
89
|
@creator.statements.must_equal([
|
78
|
-
|
90
|
+
'drop index `custom_index_name` on `lhmn_alt`'
|
79
91
|
])
|
80
92
|
end
|
81
93
|
end
|
82
94
|
|
83
|
-
describe
|
84
|
-
it
|
85
|
-
@creator.add_column(
|
95
|
+
describe 'column changes' do
|
96
|
+
it 'should add a column' do
|
97
|
+
@creator.add_column('logins', 'INT(12)')
|
86
98
|
|
87
99
|
@creator.statements.must_equal([
|
88
|
-
|
100
|
+
'alter table `lhmn_alt` add column `logins` INT(12)'
|
89
101
|
])
|
90
102
|
end
|
91
103
|
|
92
|
-
it
|
93
|
-
@creator.remove_column(
|
104
|
+
it 'should remove a column' do
|
105
|
+
@creator.remove_column('logins')
|
94
106
|
|
95
107
|
@creator.statements.must_equal([
|
96
|
-
|
108
|
+
'alter table `lhmn_alt` drop `logins`'
|
97
109
|
])
|
98
110
|
end
|
99
111
|
|
100
|
-
it
|
101
|
-
@creator.change_column(
|
112
|
+
it 'should change a column' do
|
113
|
+
@creator.change_column('logins', 'INT(11)')
|
102
114
|
|
103
115
|
@creator.statements.must_equal([
|
104
|
-
|
116
|
+
'alter table `lhmn_alt` modify column `logins` INT(11)'
|
105
117
|
])
|
106
118
|
end
|
107
119
|
end
|
108
120
|
|
109
|
-
describe
|
110
|
-
it
|
111
|
-
ddl = @creator.ddl(
|
121
|
+
describe 'direct changes' do
|
122
|
+
it 'should accept a ddl statement' do
|
123
|
+
ddl = @creator.ddl('alter table `%s` add column `f` tinyint(1)' % @creator.name)
|
112
124
|
|
113
125
|
@creator.statements.must_equal([
|
114
|
-
|
126
|
+
'alter table `lhmn_alt` add column `f` tinyint(1)'
|
115
127
|
])
|
116
128
|
end
|
117
129
|
end
|
118
130
|
|
119
|
-
describe
|
120
|
-
it
|
121
|
-
@creator.add_column(
|
122
|
-
@creator.add_column(
|
131
|
+
describe 'multiple changes' do
|
132
|
+
it 'should add two columns' do
|
133
|
+
@creator.add_column('first', 'VARCHAR(64)')
|
134
|
+
@creator.add_column('last', 'VARCHAR(64)')
|
123
135
|
@creator.statements.length.must_equal(2)
|
124
136
|
|
125
137
|
@creator.
|
126
138
|
statements[0].
|
127
|
-
must_equal(
|
139
|
+
must_equal('alter table `lhmn_alt` add column `first` VARCHAR(64)')
|
128
140
|
|
129
141
|
@creator.
|
130
142
|
statements[1].
|
131
|
-
must_equal(
|
143
|
+
must_equal('alter table `lhmn_alt` add column `last` VARCHAR(64)')
|
132
144
|
end
|
133
145
|
end
|
134
146
|
end
|
data/spec/unit/printer_spec.rb
CHANGED
@@ -5,13 +5,13 @@ require 'lhm/printer'
|
|
5
5
|
describe Lhm::Printer do
|
6
6
|
include UnitHelper
|
7
7
|
|
8
|
-
describe
|
8
|
+
describe 'percentage printer' do
|
9
9
|
|
10
10
|
before(:each) do
|
11
11
|
@printer = Lhm::Printer::Percentage.new
|
12
12
|
end
|
13
13
|
|
14
|
-
it
|
14
|
+
it 'prints the percentage' do
|
15
15
|
mock = MiniTest::Mock.new
|
16
16
|
10.times do |i|
|
17
17
|
mock.expect(:write, :return_value) do |message|
|
@@ -25,7 +25,7 @@ describe Lhm::Printer do
|
|
25
25
|
mock.verify
|
26
26
|
end
|
27
27
|
|
28
|
-
it
|
28
|
+
it 'always print a bigger message' do
|
29
29
|
@length = 0
|
30
30
|
mock = MiniTest::Mock.new
|
31
31
|
3.times do |i|
|
@@ -45,7 +45,7 @@ describe Lhm::Printer do
|
|
45
45
|
mock.verify
|
46
46
|
end
|
47
47
|
|
48
|
-
it
|
48
|
+
it 'prints the end message' do
|
49
49
|
mock = MiniTest::Mock.new
|
50
50
|
mock.expect(:write, :return_value, [String])
|
51
51
|
mock.expect(:write, :return_value, ["\n"])
|
@@ -57,16 +57,16 @@ describe Lhm::Printer do
|
|
57
57
|
end
|
58
58
|
end
|
59
59
|
|
60
|
-
describe
|
60
|
+
describe 'dot printer' do
|
61
61
|
|
62
62
|
before(:each) do
|
63
63
|
@printer = Lhm::Printer::Dot.new
|
64
64
|
end
|
65
65
|
|
66
|
-
it
|
66
|
+
it 'prints the dots' do
|
67
67
|
mock = MiniTest::Mock.new
|
68
68
|
10.times do
|
69
|
-
mock.expect(:write, :return_value, [
|
69
|
+
mock.expect(:write, :return_value, ['.'])
|
70
70
|
end
|
71
71
|
|
72
72
|
@printer.instance_variable_set(:@output, mock)
|
@@ -6,27 +6,27 @@ require File.expand_path(File.dirname(__FILE__)) + '/unit_helper'
|
|
6
6
|
require 'lhm/sql_helper'
|
7
7
|
|
8
8
|
describe Lhm::SqlHelper do
|
9
|
-
it
|
9
|
+
it 'should name index with a single column' do
|
10
10
|
Lhm::SqlHelper.
|
11
11
|
idx_name(:users, :name).
|
12
|
-
must_equal(
|
12
|
+
must_equal('index_users_on_name')
|
13
13
|
end
|
14
14
|
|
15
|
-
it
|
15
|
+
it 'should name index with multiple columns' do
|
16
16
|
Lhm::SqlHelper.
|
17
17
|
idx_name(:users, [:name, :firstname]).
|
18
|
-
must_equal(
|
18
|
+
must_equal('index_users_on_name_and_firstname')
|
19
19
|
end
|
20
20
|
|
21
|
-
it
|
21
|
+
it 'should name index with prefixed column' do
|
22
22
|
Lhm::SqlHelper.
|
23
|
-
idx_name(:tracks, [
|
24
|
-
must_equal(
|
23
|
+
idx_name(:tracks, ['title(10)', 'album']).
|
24
|
+
must_equal('index_tracks_on_title_and_album')
|
25
25
|
end
|
26
26
|
|
27
|
-
it
|
27
|
+
it 'should quote column names in index specification' do
|
28
28
|
Lhm::SqlHelper.
|
29
|
-
idx_spec([
|
30
|
-
must_equal(
|
29
|
+
idx_spec(['title(10)', 'album']).
|
30
|
+
must_equal('`title`(10), `album`')
|
31
31
|
end
|
32
32
|
end
|
data/spec/unit/table_spec.rb
CHANGED
@@ -8,26 +8,26 @@ require 'lhm/table'
|
|
8
8
|
describe Lhm::Table do
|
9
9
|
include UnitHelper
|
10
10
|
|
11
|
-
describe
|
12
|
-
it
|
13
|
-
@table = Lhm::Table.new(
|
14
|
-
@table.destination_name.must_equal
|
11
|
+
describe 'names' do
|
12
|
+
it 'should name destination' do
|
13
|
+
@table = Lhm::Table.new('users')
|
14
|
+
@table.destination_name.must_equal 'lhmn_users'
|
15
15
|
end
|
16
16
|
end
|
17
17
|
|
18
|
-
describe
|
19
|
-
it
|
20
|
-
@table = Lhm::Table.new(
|
18
|
+
describe 'constraints' do
|
19
|
+
it 'should be satisfied with a single column primary key called id' do
|
20
|
+
@table = Lhm::Table.new('table', 'id')
|
21
21
|
@table.satisfies_primary_key?.must_equal true
|
22
22
|
end
|
23
23
|
|
24
|
-
it
|
25
|
-
@table = Lhm::Table.new(
|
24
|
+
it 'should not be satisfied with a primary key unless called id' do
|
25
|
+
@table = Lhm::Table.new('table', 'uuid')
|
26
26
|
@table.satisfies_primary_key?.must_equal false
|
27
27
|
end
|
28
28
|
|
29
|
-
it
|
30
|
-
@table = Lhm::Table.new(
|
29
|
+
it 'should not be satisfied with multicolumn primary key' do
|
30
|
+
@table = Lhm::Table.new('table', ['id', 'secondary'])
|
31
31
|
@table.satisfies_primary_key?.must_equal false
|
32
32
|
end
|
33
33
|
end
|
data/spec/unit/throttler_spec.rb
CHANGED
@@ -11,22 +11,22 @@ describe Lhm::Throttler do
|
|
11
11
|
end
|
12
12
|
end
|
13
13
|
|
14
|
-
describe
|
15
|
-
describe
|
14
|
+
describe '#setup_throttler' do
|
15
|
+
describe 'when passing a key' do
|
16
16
|
before do
|
17
17
|
@mock.setup_throttler(:time_throttler, :delay => 2)
|
18
18
|
end
|
19
19
|
|
20
|
-
it
|
20
|
+
it 'instantiates the time throttle' do
|
21
21
|
@mock.throttler.class.must_equal Lhm::Throttler::Time
|
22
22
|
end
|
23
23
|
|
24
|
-
it
|
24
|
+
it 'returns 2 seconds as time' do
|
25
25
|
@mock.throttler.timeout_seconds.must_equal 2
|
26
26
|
end
|
27
27
|
end
|
28
28
|
|
29
|
-
describe
|
29
|
+
describe 'when passing an instance' do
|
30
30
|
|
31
31
|
before do
|
32
32
|
@instance = Class.new(Lhm::Throttler::Time) do
|
@@ -38,35 +38,35 @@ describe Lhm::Throttler do
|
|
38
38
|
@mock.setup_throttler(@instance)
|
39
39
|
end
|
40
40
|
|
41
|
-
it
|
41
|
+
it 'returns the instace given' do
|
42
42
|
@mock.throttler.must_equal @instance
|
43
43
|
end
|
44
44
|
|
45
|
-
it
|
45
|
+
it 'returns 0 seconds as time' do
|
46
46
|
@mock.throttler.timeout_seconds.must_equal 0
|
47
47
|
end
|
48
48
|
end
|
49
49
|
|
50
|
-
describe
|
50
|
+
describe 'when passing a class' do
|
51
51
|
|
52
52
|
before do
|
53
53
|
@klass = Class.new(Lhm::Throttler::Time)
|
54
54
|
@mock.setup_throttler(@klass)
|
55
55
|
end
|
56
56
|
|
57
|
-
it
|
57
|
+
it 'has the same class as given' do
|
58
58
|
@mock.throttler.class.must_equal @klass
|
59
59
|
end
|
60
60
|
end
|
61
61
|
end
|
62
62
|
|
63
|
-
describe
|
63
|
+
describe '#throttler' do
|
64
64
|
|
65
|
-
it
|
65
|
+
it 'returns the default Time based' do
|
66
66
|
@mock.throttler.class.must_equal Lhm::Throttler::Time
|
67
67
|
end
|
68
68
|
|
69
|
-
it
|
69
|
+
it 'should default to 100 milliseconds' do
|
70
70
|
@mock.throttler.timeout_seconds.must_equal 0.1
|
71
71
|
end
|
72
72
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: lhm
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.
|
4
|
+
version: 2.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- SoundCloud
|
@@ -11,34 +11,34 @@ authors:
|
|
11
11
|
autorequire:
|
12
12
|
bindir: bin
|
13
13
|
cert_chain: []
|
14
|
-
date:
|
14
|
+
date: 2015-01-16 00:00:00.000000000 Z
|
15
15
|
dependencies:
|
16
16
|
- !ruby/object:Gem::Dependency
|
17
17
|
name: minitest
|
18
18
|
requirement: !ruby/object:Gem::Requirement
|
19
19
|
requirements:
|
20
|
-
- - ~>
|
20
|
+
- - "~>"
|
21
21
|
- !ruby/object:Gem::Version
|
22
22
|
version: 5.0.8
|
23
23
|
type: :development
|
24
24
|
prerelease: false
|
25
25
|
version_requirements: !ruby/object:Gem::Requirement
|
26
26
|
requirements:
|
27
|
-
- - ~>
|
27
|
+
- - "~>"
|
28
28
|
- !ruby/object:Gem::Version
|
29
29
|
version: 5.0.8
|
30
30
|
- !ruby/object:Gem::Dependency
|
31
31
|
name: rake
|
32
32
|
requirement: !ruby/object:Gem::Requirement
|
33
33
|
requirements:
|
34
|
-
- -
|
34
|
+
- - ">="
|
35
35
|
- !ruby/object:Gem::Version
|
36
36
|
version: '0'
|
37
37
|
type: :development
|
38
38
|
prerelease: false
|
39
39
|
version_requirements: !ruby/object:Gem::Requirement
|
40
40
|
requirements:
|
41
|
-
- -
|
41
|
+
- - ">="
|
42
42
|
- !ruby/object:Gem::Version
|
43
43
|
version: '0'
|
44
44
|
description: Migrate large tables without downtime by copying to a temporary table
|
@@ -50,12 +50,14 @@ executables:
|
|
50
50
|
extensions: []
|
51
51
|
extra_rdoc_files: []
|
52
52
|
files:
|
53
|
-
- .gitignore
|
54
|
-
- .
|
53
|
+
- ".gitignore"
|
54
|
+
- ".rubocop.yml"
|
55
|
+
- ".travis.yml"
|
55
56
|
- CHANGELOG.md
|
56
57
|
- LICENSE
|
57
58
|
- README.md
|
58
59
|
- Rakefile
|
60
|
+
- bin/lhm-config.sh
|
59
61
|
- bin/lhm-kill-queue
|
60
62
|
- bin/lhm-spec-clobber.sh
|
61
63
|
- bin/lhm-spec-grants.sh
|
@@ -126,12 +128,12 @@ require_paths:
|
|
126
128
|
- lib
|
127
129
|
required_ruby_version: !ruby/object:Gem::Requirement
|
128
130
|
requirements:
|
129
|
-
- -
|
131
|
+
- - ">="
|
130
132
|
- !ruby/object:Gem::Version
|
131
133
|
version: '0'
|
132
134
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
133
135
|
requirements:
|
134
|
-
- -
|
136
|
+
- - ">="
|
135
137
|
- !ruby/object:Gem::Version
|
136
138
|
version: '0'
|
137
139
|
requirements: []
|