departure 1.0.1 → 2.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +1 -1
- data/CHANGELOG.md +25 -20
- data/README.md +59 -1
- data/RELEASING.md +17 -0
- data/bin/rspec +17 -0
- data/config.yml +1 -1
- data/departure.gemspec +5 -4
- data/lib/active_record/connection_adapters/percona_adapter.rb +15 -9
- data/lib/departure.rb +20 -4
- data/lib/departure/cli_generator.rb +38 -87
- data/lib/departure/command.rb +96 -0
- data/lib/departure/configuration.rb +2 -1
- data/lib/departure/connection_details.rb +70 -0
- data/lib/departure/dsn.rb +26 -0
- data/lib/departure/errors.rb +4 -0
- data/lib/departure/log_sanitizers/password_sanitizer.rb +21 -0
- data/lib/departure/logger.rb +14 -2
- data/lib/departure/logger_factory.rb +2 -2
- data/lib/departure/option.rb +63 -0
- data/lib/departure/runner.rb +7 -73
- data/lib/departure/user_options.rb +44 -0
- data/lib/departure/version.rb +1 -1
- data/test_database.rb +1 -1
- metadata +31 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ef3cc8883b3b4dc294f1b94b7d93744e98812849
|
4
|
+
data.tar.gz: 242eac0339dd6f9aedf020d321cd9e6cc0bc24fe
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 515ab293664312a15f3482f1b0cc0156c325b59df452fa82a9a700adbff81197d1cfffcb4b1296a1afdad47f828a6aeffe0e5b831b61ff37dd89fab0127abdd4
|
7
|
+
data.tar.gz: 35b2746785ba419acddf8e2629e564f9382e7107fd4e57dcd75750e7440f347b3d1e4ce4c96a22a330096bec2bb383ef039070244a522dfd27df87018f850dd1
|
data/.gitignore
CHANGED
data/CHANGELOG.md
CHANGED
@@ -11,45 +11,50 @@ Please follow the format in [Keep a Changelog](http://keepachangelog.com/)
|
|
11
11
|
### Removed
|
12
12
|
### Fixed
|
13
13
|
|
14
|
-
## [
|
14
|
+
## [2.0.0 - 2017-04-20]
|
15
15
|
|
16
16
|
### Added
|
17
17
|
### Changed
|
18
|
+
|
19
|
+
- Rename the gem from percona_migrator to departure
|
20
|
+
|
18
21
|
### Removed
|
19
22
|
|
20
23
|
- Percona_migrator's deprecation warnings when installing and running the gem.
|
21
24
|
|
22
25
|
### Fixed
|
23
26
|
|
24
|
-
## [1.
|
27
|
+
## [1.1.0] - 2017-04-07
|
25
28
|
|
26
29
|
### Added
|
27
|
-
### Changed
|
28
30
|
|
29
|
-
-
|
31
|
+
- Allow passing any `pt-online-schema-change`'s arguments through the
|
32
|
+
`PERCONA_ARGS` env var when executing a migration with `rake db:migrate:up`
|
33
|
+
or `db:migrate:down`.
|
34
|
+
- Allow setting global percona arguments via gem configuration
|
35
|
+
- Filter MySQL's password from logs
|
30
36
|
|
31
|
-
###
|
32
|
-
|
37
|
+
### Changed
|
38
|
+
|
39
|
+
- Enable default pt-online-schema-change replicas discovering mechanism.
|
40
|
+
So far, this was purposely set to `none`. To keep this same behaviour
|
41
|
+
provide the `PERCONA_ARGS=--recursion-method=none` env var when running the
|
42
|
+
migration.
|
33
43
|
|
34
|
-
## [0.
|
44
|
+
## [1.0.0] - 2016-11-30
|
35
45
|
|
36
46
|
### Added
|
37
47
|
|
48
|
+
- Show pt-online-schema-change's stdout while the migration is running instead
|
49
|
+
of at then and all at once.
|
38
50
|
- Store pt-online-schema-change's stderr to percona_migrator_error.log in the
|
39
51
|
default Rails tmp folder.
|
40
|
-
- Allow configuring the tmp directory where the error log gets written into
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
- No longer a hard dependency on mysql2 0.3.20. Will accept 0.3.20 or any
|
47
|
-
higher patch revisions.
|
48
|
-
|
49
|
-
### Fixed
|
50
|
-
|
51
|
-
- Output pt-online-schema-change's stdout while the migration is running instead
|
52
|
-
of all of it at the end.
|
52
|
+
- Allow configuring the tmp directory where the error log gets written into,
|
53
|
+
with the `tmp_path` configuration setting.
|
54
|
+
- Support for ActiveRecord 4.0. Adds the following migration methods:
|
55
|
+
- #rename_index, #change_column_null, #add_reference, #remove_reference,
|
56
|
+
#set_field_encoding, #add_timestamps, #remove_timestamps, #rename_table,
|
57
|
+
#rename_column
|
53
58
|
|
54
59
|
## [0.1.0.rc.7] - 2016-09-15
|
55
60
|
|
data/README.md
CHANGED
@@ -26,6 +26,21 @@ Toolkit](https://www.percona.com/doc/percona-toolkit/2.0/pt-online-schema-change
|
|
26
26
|
|
27
27
|
`brew install percona-toolkit`
|
28
28
|
|
29
|
+
If when running a migration you see an error like:
|
30
|
+
|
31
|
+
```
|
32
|
+
PerconaMigrator::Error: Cannot connect to MySQL: Cannot connect to MySQL because
|
33
|
+
the Perl DBI module is not installed or not found.
|
34
|
+
```
|
35
|
+
|
36
|
+
You also need to install the DBI and DBD::MySQL modules from `cpan`.
|
37
|
+
|
38
|
+
```
|
39
|
+
$ sudo cpan
|
40
|
+
cpan> install DBI
|
41
|
+
cpan> install DBD::mysql
|
42
|
+
```
|
43
|
+
|
29
44
|
### Linux
|
30
45
|
|
31
46
|
#### Ubuntu/Debian based
|
@@ -67,6 +82,48 @@ All the `ALTER TABLE` statements will be executed with
|
|
67
82
|
`pt-online-schema-change`, which will provide additional output to the
|
68
83
|
migration.
|
69
84
|
|
85
|
+
### pt-online-schema-change arguments
|
86
|
+
|
87
|
+
#### with environment variable
|
88
|
+
|
89
|
+
You can specify any `pt-online-schema-change` arguments when running the
|
90
|
+
migration. All what you pass in the PERCONA_ARGS env var, will be bypassed to the
|
91
|
+
binary, overwriting any default values. Note the format is the same as in
|
92
|
+
`pt-online-schema-change`. Check the full list in [Percona Toolkit
|
93
|
+
documentation](https://www.percona.com/doc/percona-toolkit/2.2/pt-online-schema-change.html#options)
|
94
|
+
|
95
|
+
```ruby
|
96
|
+
$ PERCONA_ARGS='--chunk-time=1' bundle exec rake db:migrate:up VERSION=xxx
|
97
|
+
```
|
98
|
+
|
99
|
+
or even mulitple arguments
|
100
|
+
|
101
|
+
```ruby
|
102
|
+
$ PERCONA_ARGS='--chunk-time=1 --critical-load=55' bundle exec rake db:migrate:up VERSION=xxx
|
103
|
+
```
|
104
|
+
|
105
|
+
This however, only works for `db:migrate:up` or `db:migrate:down` rake tasks and
|
106
|
+
not with `db:migrate`. The settings you provide can't be generalized as these
|
107
|
+
vary depending on the database table and the kind of changes you apply.
|
108
|
+
|
109
|
+
#### with global configuration
|
110
|
+
|
111
|
+
You can specify any `pt-online-schema-change` arguments in global gem configuration
|
112
|
+
using `global_percona_args` option.
|
113
|
+
|
114
|
+
```ruby
|
115
|
+
PerconaMigrator.configure do |config|
|
116
|
+
config.global_percona_args = '--chunk-time=1 --critical-load=55'
|
117
|
+
end
|
118
|
+
```
|
119
|
+
|
120
|
+
Unlike using `PERCONA_ARGS`, options provided with global configuration will be applied
|
121
|
+
every time sql command is executed via `pt-online-schema-change`.
|
122
|
+
|
123
|
+
Arguments provided in global configuration can be overwritten with `PERCONA_ARGS` env variable.
|
124
|
+
|
125
|
+
We recommend using this option with caution and only when you understand the consequences.
|
126
|
+
|
70
127
|
### LHM support
|
71
128
|
|
72
129
|
If you moved to Soundcloud's [Lhm](https://github.com/soundcloud/lhm) already,
|
@@ -129,7 +186,8 @@ git commits and tags, and push the `.gem` file to
|
|
129
186
|
## Contributing
|
130
187
|
|
131
188
|
Bug reports and pull requests are welcome on GitHub at
|
132
|
-
https://github.com/redbooth/percona_migrator.
|
189
|
+
https://github.com/redbooth/percona_migrator. They need to be opened against
|
190
|
+
`master` or `v3.2` only if the changes fix a bug in Rails 3.2 apps.
|
133
191
|
|
134
192
|
Please note that this project is released with a Contributor Code of Conduct. By
|
135
193
|
participating in this project you agree to abide by its terms.
|
data/RELEASING.md
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
# Releasing Percona Migrator
|
2
|
+
|
3
|
+
All releases come from the master branch. All other branches won't be maintained
|
4
|
+
and will receive bug fix releases only.
|
5
|
+
|
6
|
+
In order to give support to a new major Rails version, we'll branch off of
|
7
|
+
master, name it following the Rails repo convention, such as `v4.2`, and
|
8
|
+
we'll keep it open for bug fixes.
|
9
|
+
|
10
|
+
1. Update `lib/percona_migrator/version.rb` accordingly
|
11
|
+
2. Review the `CHANGELOG.md` and add a new section following the format
|
12
|
+
`[version] - YYYY-MM-DD`. We conform to the guidelines of
|
13
|
+
http://keepachangelog.com/
|
14
|
+
3. Commit the changes with the message `Prepare release VERSION`
|
15
|
+
4. Execute the release rake task as `bundle exec rake release`. It creates the
|
16
|
+
tag, builds and pushes the gem to Rubygems.
|
17
|
+
5. Announce it! :tada:
|
data/bin/rspec
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
3
|
+
#
|
4
|
+
# This file was generated by Bundler.
|
5
|
+
#
|
6
|
+
# The application 'rspec' is installed as part of a gem, and
|
7
|
+
# this file is here to facilitate running it.
|
8
|
+
#
|
9
|
+
|
10
|
+
require "pathname"
|
11
|
+
ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile",
|
12
|
+
Pathname.new(__FILE__).realpath)
|
13
|
+
|
14
|
+
require "rubygems"
|
15
|
+
require "bundler/setup"
|
16
|
+
|
17
|
+
load Gem.bin_path("rspec-core", "rspec")
|
data/config.yml
CHANGED
data/departure.gemspec
CHANGED
@@ -7,8 +7,8 @@ require 'departure/version'
|
|
7
7
|
Gem::Specification.new do |spec|
|
8
8
|
spec.name = 'departure'
|
9
9
|
spec.version = Departure::VERSION
|
10
|
-
spec.authors = ['Ilya Zayats', 'Pau Pérez', 'Fran Casas', 'Jorge Morante']
|
11
|
-
spec.email = ['ilya.zayats@redbooth.com', 'pau.perez@redbooth.com', 'fran.casas@redbooth.com', 'jorge.morante@redbooth.com']
|
10
|
+
spec.authors = ['Ilya Zayats', 'Pau Pérez', 'Fran Casas', 'Jorge Morante', 'Adrian Serafin']
|
11
|
+
spec.email = ['ilya.zayats@redbooth.com', 'pau.perez@redbooth.com', 'fran.casas@redbooth.com', 'jorge.morante@redbooth.com', 'adrian@softmad.pl']
|
12
12
|
|
13
13
|
spec.summary = %q{pt-online-schema-change runner for ActiveRecord migrations}
|
14
14
|
spec.description = %q{Execute your ActiveRecord migrations with Percona's pt-online-schema-change. Formerly known as Percona Migrator.}
|
@@ -18,12 +18,13 @@ Gem::Specification.new do |spec|
|
|
18
18
|
spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
19
19
|
spec.require_paths = ['lib']
|
20
20
|
|
21
|
-
spec.add_runtime_dependency 'rails', '~>
|
22
|
-
spec.add_runtime_dependency 'mysql2', '
|
21
|
+
spec.add_runtime_dependency 'rails', '~> 4.0.0'
|
22
|
+
spec.add_runtime_dependency 'mysql2', '0.3.20'
|
23
23
|
|
24
24
|
spec.add_development_dependency 'bundler', '~> 1.10'
|
25
25
|
spec.add_development_dependency 'rake', '~> 10.0'
|
26
26
|
spec.add_development_dependency 'rspec', '~> 3.4', '>= 3.4.0'
|
27
27
|
spec.add_development_dependency 'rspec-its', '~> 1.2'
|
28
28
|
spec.add_development_dependency 'byebug', '~> 8.2', '>= 8.2.1'
|
29
|
+
spec.add_development_dependency 'climate_control', '~> 0.0.3'
|
29
30
|
end
|
@@ -5,15 +5,21 @@ require 'departure'
|
|
5
5
|
require 'forwardable'
|
6
6
|
|
7
7
|
module ActiveRecord
|
8
|
-
|
8
|
+
module ConnectionHandling
|
9
9
|
# Establishes a connection to the database that's used by all Active
|
10
10
|
# Record objects.
|
11
|
-
def
|
11
|
+
def percona_connection(config)
|
12
12
|
mysql2_connection = mysql2_connection(config)
|
13
13
|
|
14
|
+
config[:username] = 'root' if config[:username].nil?
|
15
|
+
|
16
|
+
connection_details = Departure::ConnectionDetails.new(config)
|
14
17
|
verbose = ActiveRecord::Migration.verbose
|
15
|
-
|
16
|
-
|
18
|
+
sanitizers = [
|
19
|
+
Departure::LogSanitizers::PasswordSanitizer.new(connection_details)
|
20
|
+
]
|
21
|
+
percona_logger = Departure::LoggerFactory.build(sanitizers: sanitizers, verbose: verbose)
|
22
|
+
cli_generator = Departure::CliGenerator.new(connection_details)
|
17
23
|
|
18
24
|
runner = Departure::Runner.new(
|
19
25
|
percona_logger,
|
@@ -45,7 +51,7 @@ module ActiveRecord
|
|
45
51
|
|
46
52
|
ADAPTER_NAME = 'Percona'.freeze
|
47
53
|
|
48
|
-
def_delegators :mysql_adapter, :last_inserted_id, :each_hash
|
54
|
+
def_delegators :mysql_adapter, :last_inserted_id, :each_hash, :set_field_encoding
|
49
55
|
|
50
56
|
def initialize(connection, _logger, connection_options, _config)
|
51
57
|
super
|
@@ -59,7 +65,7 @@ module ActiveRecord
|
|
59
65
|
end
|
60
66
|
alias :exec_update :exec_delete
|
61
67
|
|
62
|
-
def exec_insert(sql, name, binds)
|
68
|
+
def exec_insert(sql, name, binds, pk = nil, sequence_name = nil)
|
63
69
|
execute(to_sql(sql, binds), name)
|
64
70
|
end
|
65
71
|
|
@@ -77,7 +83,7 @@ module ActiveRecord
|
|
77
83
|
# Executes a SELECT query and returns an array of record hashes with the
|
78
84
|
# column names as keys and column values as values.
|
79
85
|
def select(sql, name = nil, binds = [])
|
80
|
-
exec_query(sql, name, binds)
|
86
|
+
exec_query(sql, name, binds)
|
81
87
|
end
|
82
88
|
|
83
89
|
# Returns true, as this adapter supports migrations
|
@@ -85,8 +91,8 @@ module ActiveRecord
|
|
85
91
|
true
|
86
92
|
end
|
87
93
|
|
88
|
-
def new_column(field, default, type, null, collation)
|
89
|
-
Column.new(field, default, type, null, collation)
|
94
|
+
def new_column(field, default, type, null, collation, extra = "")
|
95
|
+
Column.new(field, default, type, null, collation, extra)
|
90
96
|
end
|
91
97
|
|
92
98
|
# Adds a new index to the table
|
data/lib/departure.rb
CHANGED
@@ -2,6 +2,7 @@ require 'active_record'
|
|
2
2
|
require 'active_support/all'
|
3
3
|
|
4
4
|
require 'departure/version'
|
5
|
+
require 'departure/log_sanitizers/password_sanitizer'
|
5
6
|
require 'departure/runner'
|
6
7
|
require 'departure/cli_generator'
|
7
8
|
require 'departure/logger'
|
@@ -9,6 +10,7 @@ require 'departure/null_logger'
|
|
9
10
|
require 'departure/logger_factory'
|
10
11
|
require 'departure/configuration'
|
11
12
|
require 'departure/errors'
|
13
|
+
require 'departure/command'
|
12
14
|
|
13
15
|
require 'departure/railtie' if defined?(Rails)
|
14
16
|
|
@@ -28,6 +30,21 @@ module Departure
|
|
28
30
|
# Hooks Percona Migrator into Rails migrations by replacing the configured
|
29
31
|
# database adapter
|
30
32
|
def self.load
|
33
|
+
ActiveRecord::Migrator.instance_eval do
|
34
|
+
class << self
|
35
|
+
alias_method(:original_migrate, :migrate)
|
36
|
+
end
|
37
|
+
|
38
|
+
# Checks whether arguments are being passed through PERCONA_ARGS when running
|
39
|
+
# the db:migrate rake task
|
40
|
+
#
|
41
|
+
# @raise [ArgumentsNotSupported] if PERCONA_ARGS has any value
|
42
|
+
def migrate(migrations_paths, target_version = nil, &block)
|
43
|
+
raise ArgumentsNotSupported if ENV['PERCONA_ARGS'].present?
|
44
|
+
original_migrate(migrations_paths, target_version, &block)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
31
48
|
ActiveRecord::Migration.class_eval do
|
32
49
|
alias_method :original_migrate, :migrate
|
33
50
|
|
@@ -55,10 +72,9 @@ module Departure
|
|
55
72
|
# Make all connections in the connection pool to use PerconaAdapter
|
56
73
|
# instead of the current adapter.
|
57
74
|
def reconnect_with_percona
|
58
|
-
connection_config = ActiveRecord::Base
|
59
|
-
|
60
|
-
|
61
|
-
)
|
75
|
+
connection_config = ActiveRecord::Base
|
76
|
+
.connection_config.merge(adapter: 'percona')
|
77
|
+
ActiveRecord::Base.establish_connection(connection_config)
|
62
78
|
end
|
63
79
|
end
|
64
80
|
end
|
@@ -1,49 +1,36 @@
|
|
1
|
+
require 'departure/dsn'
|
2
|
+
require 'departure/option'
|
1
3
|
require 'departure/alter_argument'
|
4
|
+
require 'departure/connection_details'
|
5
|
+
require 'departure/user_options'
|
2
6
|
|
3
7
|
module Departure
|
4
8
|
|
5
|
-
# Represents the 'DSN' argument of Percona's pt-online-schema-change
|
6
|
-
# See https://www.percona.com/doc/percona-toolkit/2.0/pt-online-schema-change.html#dsn-options
|
7
|
-
class DSN
|
8
|
-
|
9
|
-
# Constructor
|
10
|
-
#
|
11
|
-
# @param database [String, Symbol]
|
12
|
-
# @param table_name [String, Symbol]
|
13
|
-
def initialize(database, table_name)
|
14
|
-
@database = database
|
15
|
-
@table_name = table_name
|
16
|
-
end
|
17
|
-
|
18
|
-
# Returns the pt-online-schema-change DSN string. See
|
19
|
-
# https://www.percona.com/doc/percona-toolkit/2.0/pt-online-schema-change.html#dsn-options
|
20
|
-
def to_s
|
21
|
-
"D=#{database},t=#{table_name}"
|
22
|
-
end
|
23
|
-
|
24
|
-
private
|
25
|
-
|
26
|
-
attr_reader :table_name, :database
|
27
|
-
end
|
28
|
-
|
29
9
|
# Generates the equivalent Percona's pt-online-schema-change command to the
|
30
10
|
# given SQL statement
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
11
|
+
#
|
12
|
+
# --no-check-alter is used to allow running CHANGE COLUMN statements. For
|
13
|
+
# more details, check: www.percona.com/doc/percona-toolkit/2.2/pt-online-schema-change.html#cmdoption-pt-online-schema-change--[no]check-alter
|
14
|
+
#
|
15
|
+
class CliGenerator
|
16
|
+
COMMAND_NAME = 'pt-online-schema-change'.freeze
|
17
|
+
DEFAULT_OPTIONS = Set.new(
|
18
|
+
[
|
19
|
+
Option.new('execute'),
|
20
|
+
Option.new('statistics'),
|
21
|
+
Option.new('alter-foreign-keys-method', 'auto'),
|
22
|
+
Option.new('no-check-alter')
|
23
|
+
]
|
24
|
+
).freeze
|
25
|
+
|
26
|
+
# TODO: Better doc.
|
27
|
+
#
|
28
|
+
# Constructor. Specify any arguments to pass to pt-online-schema-change
|
29
|
+
# passing the PERCONA_ARGS env var when executing the migration
|
41
30
|
#
|
42
31
|
# @param connection_data [Hash]
|
43
|
-
def initialize(
|
44
|
-
@
|
45
|
-
init_base_command
|
46
|
-
add_connection_details
|
32
|
+
def initialize(connection_details)
|
33
|
+
@connection_details = connection_details
|
47
34
|
end
|
48
35
|
|
49
36
|
# Generates the percona command. Fills all the connection credentials from
|
@@ -57,9 +44,9 @@ module Departure
|
|
57
44
|
# @return [String]
|
58
45
|
def generate(table_name, statement)
|
59
46
|
alter_argument = AlterArgument.new(statement)
|
60
|
-
dsn = DSN.new(database, table_name)
|
47
|
+
dsn = DSN.new(connection_details.database, table_name)
|
61
48
|
|
62
|
-
"#{
|
49
|
+
"#{command} #{all_options} #{dsn} #{alter_argument}"
|
63
50
|
end
|
64
51
|
|
65
52
|
# Generates the percona command for a raw MySQL statement. Fills all the
|
@@ -72,63 +59,27 @@ module Departure
|
|
72
59
|
# @return [String]
|
73
60
|
def parse_statement(statement)
|
74
61
|
alter_argument = AlterArgument.new(statement)
|
75
|
-
dsn = DSN.new(database, alter_argument.table_name)
|
62
|
+
dsn = DSN.new(connection_details.database, alter_argument.table_name)
|
76
63
|
|
77
|
-
"#{
|
64
|
+
"#{command} #{all_options} #{dsn} #{alter_argument}"
|
78
65
|
end
|
79
66
|
|
80
67
|
private
|
81
68
|
|
82
|
-
attr_reader :
|
83
|
-
|
84
|
-
# Sets up the command with its options
|
85
|
-
def init_base_command
|
86
|
-
@command = [BASE_COMMAND, BASE_OPTIONS.join(' ')]
|
87
|
-
end
|
88
|
-
|
89
|
-
# Adds the host, user and password, if present, to the command
|
90
|
-
def add_connection_details
|
91
|
-
@command.push("-h #{host}")
|
92
|
-
@command.push("-u #{user}")
|
93
|
-
@command.push("-p #{password}") if password.present?
|
94
|
-
end
|
95
|
-
|
96
|
-
# Returns the command as a string that can be executed in a shell
|
97
|
-
#
|
98
|
-
# @return [String]
|
99
|
-
def to_s
|
100
|
-
@command.join(' ')
|
101
|
-
end
|
102
|
-
|
103
|
-
# Returns the database host name, defaulting to localhost. If PERCONA_DB_HOST
|
104
|
-
# is passed its value will be used instead
|
105
|
-
#
|
106
|
-
# @return [String]
|
107
|
-
def host
|
108
|
-
ENV['PERCONA_DB_HOST'] || connection_data[:host] || 'localhost'
|
109
|
-
end
|
69
|
+
attr_reader :connection_details
|
110
70
|
|
111
|
-
|
112
|
-
|
113
|
-
#
|
114
|
-
# @return [String]
|
115
|
-
def user
|
116
|
-
ENV['PERCONA_DB_USER'] || connection_data[:username]
|
71
|
+
def command
|
72
|
+
"#{COMMAND_NAME} #{connection_details}"
|
117
73
|
end
|
118
74
|
|
119
|
-
# Returns the
|
120
|
-
# value will be used instead
|
75
|
+
# Returns all the arguments to execute pt-online-schema-change with
|
121
76
|
#
|
122
77
|
# @return [String]
|
123
|
-
def
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
# Returns the database name. If PERCONA_DB_NAME is passed its value will be
|
129
|
-
# used instead
|
130
|
-
def database
|
131
|
-
ENV['PERCONA_DB_NAME'] || connection_data[:database]
|
78
|
+
def all_options
|
79
|
+
env_variable_options = UserOptions.new
|
80
|
+
global_configuration_options = UserOptions.new(Departure.configuration.global_percona_args)
|
81
|
+
options = env_variable_options.merge(global_configuration_options).merge(DEFAULT_OPTIONS)
|
82
|
+
options.to_a.join(' ')
|
132
83
|
end
|
133
84
|
end
|
134
85
|
end
|
@@ -0,0 +1,96 @@
|
|
1
|
+
module Departure
|
2
|
+
# Executes the given command returning it's status and errors
|
3
|
+
class Command
|
4
|
+
COMMAND_NOT_FOUND = 127
|
5
|
+
|
6
|
+
# Constructor
|
7
|
+
#
|
8
|
+
# @param command_line [String]
|
9
|
+
# @param error_log_path [String]
|
10
|
+
# @param logger [#write_no_newline]
|
11
|
+
def initialize(command_line, error_log_path, logger)
|
12
|
+
@command_line = command_line
|
13
|
+
@error_log_path = error_log_path
|
14
|
+
@logger = logger
|
15
|
+
end
|
16
|
+
|
17
|
+
# Executes the command returning its status. It also prints its stdout to
|
18
|
+
# the logger and its stderr to the file specified in error_log_path.
|
19
|
+
#
|
20
|
+
# @raise [NoStatusError] if the spawned process' status can't be retrieved
|
21
|
+
# @raise [SignalError] if the spawned process received a signal
|
22
|
+
# @raise [CommandNotFoundError] if pt-online-schema-change can't be found
|
23
|
+
#
|
24
|
+
# @return [Process::Status]
|
25
|
+
def run
|
26
|
+
log_started
|
27
|
+
|
28
|
+
run_in_process
|
29
|
+
|
30
|
+
log_finished
|
31
|
+
|
32
|
+
validate_status!
|
33
|
+
status
|
34
|
+
end
|
35
|
+
|
36
|
+
private
|
37
|
+
|
38
|
+
attr_reader :command_line, :error_log_path, :logger, :status
|
39
|
+
|
40
|
+
# Runs the command in a separate process, capturing its stdout and
|
41
|
+
# execution status
|
42
|
+
def run_in_process
|
43
|
+
Open3.popen3(full_command) do |_stdin, stdout, _stderr, waith_thr|
|
44
|
+
begin
|
45
|
+
loop do
|
46
|
+
IO.select([stdout])
|
47
|
+
data = stdout.read_nonblock(8)
|
48
|
+
logger.write_no_newline(data)
|
49
|
+
end
|
50
|
+
rescue EOFError
|
51
|
+
# noop
|
52
|
+
ensure
|
53
|
+
@status = waith_thr.value
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
# Builds the actual command including stderr redirection to the specified
|
59
|
+
# log file
|
60
|
+
#
|
61
|
+
# @return [String]
|
62
|
+
def full_command
|
63
|
+
"#{command_line} 2> #{error_log_path}"
|
64
|
+
end
|
65
|
+
|
66
|
+
# Validates the status of the execution
|
67
|
+
#
|
68
|
+
# @raise [NoStatusError] if the spawned process' status can't be retrieved
|
69
|
+
# @raise [SignalError] if the spawned process received a signal
|
70
|
+
# @raise [CommandNotFoundError] if pt-online-schema-change can't be found
|
71
|
+
def validate_status!
|
72
|
+
raise SignalError.new(status) if status.signaled?
|
73
|
+
raise CommandNotFoundError if status.exitstatus == COMMAND_NOT_FOUND
|
74
|
+
raise Error, error_message unless status.success?
|
75
|
+
end
|
76
|
+
|
77
|
+
# Returns the error message that appeared in the process' stderr
|
78
|
+
#
|
79
|
+
# @return [String]
|
80
|
+
def error_message
|
81
|
+
File.read(error_log_path)
|
82
|
+
end
|
83
|
+
|
84
|
+
# Logs when the execution started
|
85
|
+
def log_started
|
86
|
+
logger.write("\n")
|
87
|
+
logger.say("Running #{command_line}\n\n", true)
|
88
|
+
end
|
89
|
+
|
90
|
+
# Prints a line break to keep the logs separate from the execution time
|
91
|
+
# print by the migration
|
92
|
+
def log_finished
|
93
|
+
logger.write("\n")
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
@@ -1,10 +1,11 @@
|
|
1
1
|
module Departure
|
2
2
|
class Configuration
|
3
|
-
attr_accessor :tmp_path
|
3
|
+
attr_accessor :tmp_path, :global_percona_args
|
4
4
|
|
5
5
|
def initialize
|
6
6
|
@tmp_path = '.'.freeze
|
7
7
|
@error_log_filename = 'departure_error.log'.freeze
|
8
|
+
@global_percona_args = nil
|
8
9
|
end
|
9
10
|
|
10
11
|
def error_log_path
|
@@ -0,0 +1,70 @@
|
|
1
|
+
module Departure
|
2
|
+
# Holds the parameters of the DB connection and formats them to string
|
3
|
+
class ConnectionDetails
|
4
|
+
|
5
|
+
# Constructor
|
6
|
+
#
|
7
|
+
# @param [Hash] connection parametes as used in #establish_conneciton
|
8
|
+
def initialize(connection_data)
|
9
|
+
@connection_data = connection_data
|
10
|
+
end
|
11
|
+
|
12
|
+
# Returns the details formatted as an string to be used with
|
13
|
+
# pt-online-schema-change. It follows the mysql client's format.
|
14
|
+
#
|
15
|
+
# @return [String]
|
16
|
+
def to_s
|
17
|
+
@to_s ||= "-h #{host} -u #{user} #{password_argument}"
|
18
|
+
end
|
19
|
+
|
20
|
+
# TODO: Doesn't the abstract adapter already handle this somehow?
|
21
|
+
# Returns the database name. If PERCONA_DB_NAME is passed its value will be
|
22
|
+
# used instead
|
23
|
+
#
|
24
|
+
# Returns the database name
|
25
|
+
#
|
26
|
+
# @return [String]
|
27
|
+
def database
|
28
|
+
ENV.fetch('PERCONA_DB_NAME', connection_data[:database])
|
29
|
+
end
|
30
|
+
|
31
|
+
# Returns the password fragment of the details string if a password is passed
|
32
|
+
#
|
33
|
+
# @return [String]
|
34
|
+
def password_argument
|
35
|
+
if password.present?
|
36
|
+
"-p #{password}"
|
37
|
+
else
|
38
|
+
''
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
private
|
43
|
+
|
44
|
+
attr_reader :connection_data
|
45
|
+
|
46
|
+
# Returns the database host name, defaulting to localhost. If PERCONA_DB_HOST
|
47
|
+
# is passed its value will be used instead
|
48
|
+
#
|
49
|
+
# @return [String]
|
50
|
+
def host
|
51
|
+
ENV.fetch('PERCONA_DB_HOST', connection_data[:host]) || 'localhost'
|
52
|
+
end
|
53
|
+
|
54
|
+
# Returns the database user. If PERCONA_DB_USER is passed its value will be
|
55
|
+
# used instead
|
56
|
+
#
|
57
|
+
# @return [String]
|
58
|
+
def user
|
59
|
+
ENV.fetch('PERCONA_DB_USER', connection_data[:username])
|
60
|
+
end
|
61
|
+
|
62
|
+
# Returns the database user's password. If PERCONA_DB_PASSWORD is passed its
|
63
|
+
# value will be used instead
|
64
|
+
#
|
65
|
+
# @return [String]
|
66
|
+
def password
|
67
|
+
ENV.fetch('PERCONA_DB_PASSWORD', connection_data[:password])
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module Departure
|
2
|
+
|
3
|
+
# Represents the 'DSN' argument of Percona's pt-online-schema-change
|
4
|
+
# See https://www.percona.com/doc/percona-toolkit/2.0/pt-online-schema-change.html#dsn-options
|
5
|
+
class DSN
|
6
|
+
|
7
|
+
# Constructor
|
8
|
+
#
|
9
|
+
# @param database [String, Symbol]
|
10
|
+
# @param table_name [String, Symbol]
|
11
|
+
def initialize(database, table_name)
|
12
|
+
@database = database
|
13
|
+
@table_name = table_name
|
14
|
+
end
|
15
|
+
|
16
|
+
# Returns the pt-online-schema-change DSN string. See
|
17
|
+
# https://www.percona.com/doc/percona-toolkit/2.0/pt-online-schema-change.html#dsn-options
|
18
|
+
def to_s
|
19
|
+
"D=#{database},t=#{table_name}"
|
20
|
+
end
|
21
|
+
|
22
|
+
private
|
23
|
+
|
24
|
+
attr_reader :table_name, :database
|
25
|
+
end
|
26
|
+
end
|
data/lib/departure/errors.rb
CHANGED
@@ -32,4 +32,8 @@ module Departure
|
|
32
32
|
'Please install pt-online-schema-change. Check: https://www.percona.com/doc/percona-toolkit for further details'
|
33
33
|
end
|
34
34
|
end
|
35
|
+
|
36
|
+
# Used to prevent running the db:migrate rake task when providing arguments
|
37
|
+
# through PERCONA_ARGS env var
|
38
|
+
class ArgumentsNotSupported < Error; end
|
35
39
|
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module Departure
|
2
|
+
module LogSanitizers
|
3
|
+
class PasswordSanitizer
|
4
|
+
PASSWORD_REPLACEMENT = '[filtered_password]'
|
5
|
+
|
6
|
+
delegate :password_argument, to: :connection_details
|
7
|
+
|
8
|
+
def initialize(connection_details)
|
9
|
+
@connection_details = connection_details
|
10
|
+
end
|
11
|
+
|
12
|
+
def execute(log_statement)
|
13
|
+
return log_statement if password_argument.blank?
|
14
|
+
log_statement.gsub(password_argument, PASSWORD_REPLACEMENT)
|
15
|
+
end
|
16
|
+
|
17
|
+
private
|
18
|
+
attr_accessor :connection_details
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
data/lib/departure/logger.rb
CHANGED
@@ -5,6 +5,10 @@ module Departure
|
|
5
5
|
# seen from the connection adapter.
|
6
6
|
class Logger
|
7
7
|
|
8
|
+
def initialize(sanitizers)
|
9
|
+
@sanitizers = sanitizers
|
10
|
+
end
|
11
|
+
|
8
12
|
# Outputs the message through the stdout, following the
|
9
13
|
# ActiveRecord::Migration log format
|
10
14
|
#
|
@@ -18,14 +22,22 @@ module Departure
|
|
18
22
|
#
|
19
23
|
# @param text [String]
|
20
24
|
def write(text = '')
|
21
|
-
puts(text)
|
25
|
+
puts(sanitize(text))
|
22
26
|
end
|
23
27
|
|
24
28
|
# Outputs the text through the stdout without adding a new line at the end
|
25
29
|
#
|
26
30
|
# @param text [String]
|
27
31
|
def write_no_newline(text)
|
28
|
-
print(text)
|
32
|
+
print(sanitize(text))
|
33
|
+
end
|
34
|
+
|
35
|
+
private
|
36
|
+
|
37
|
+
attr_accessor :sanitizers
|
38
|
+
|
39
|
+
def sanitize(text)
|
40
|
+
sanitizers.inject(text) { |memo, sanitizer| sanitizer.execute(memo) }
|
29
41
|
end
|
30
42
|
end
|
31
43
|
end
|
@@ -6,9 +6,9 @@ module Departure
|
|
6
6
|
#
|
7
7
|
# @param verbose [Boolean]
|
8
8
|
# @return [#say, #write]
|
9
|
-
def self.build(verbose: true)
|
9
|
+
def self.build(sanitizers: [], verbose: true)
|
10
10
|
if verbose
|
11
|
-
Departure::Logger.new
|
11
|
+
Departure::Logger.new(sanitizers)
|
12
12
|
else
|
13
13
|
Departure::NullLogger.new
|
14
14
|
end
|
@@ -0,0 +1,63 @@
|
|
1
|
+
module Departure
|
2
|
+
class Option
|
3
|
+
attr_reader :name, :value
|
4
|
+
|
5
|
+
# Builds an instance by parsing its name and value out of the given string.
|
6
|
+
# Note the string must conform to "--<arg>=<value>" format.
|
7
|
+
#
|
8
|
+
# @param string [String]
|
9
|
+
# @return [Option]
|
10
|
+
def self.from_string(string)
|
11
|
+
pair = string.split('=')
|
12
|
+
name = pair[0][2..-1]
|
13
|
+
value = pair[1]
|
14
|
+
|
15
|
+
new(name, value)
|
16
|
+
end
|
17
|
+
|
18
|
+
# Constructor
|
19
|
+
#
|
20
|
+
# @param name [String]
|
21
|
+
# @param optional value [String]
|
22
|
+
def initialize(name, value = nil)
|
23
|
+
@name = name
|
24
|
+
@value = value
|
25
|
+
end
|
26
|
+
|
27
|
+
# Compares two options
|
28
|
+
#
|
29
|
+
# @param [Option]
|
30
|
+
# @return [Boolean]
|
31
|
+
def ==(another_option)
|
32
|
+
name == another_option.name
|
33
|
+
end
|
34
|
+
alias :eql? :==
|
35
|
+
|
36
|
+
# Returns the option's hash
|
37
|
+
#
|
38
|
+
# @return [Fixnum]
|
39
|
+
def hash
|
40
|
+
name.hash
|
41
|
+
end
|
42
|
+
|
43
|
+
# Returns the option as string following the "--<name>=<value>" format
|
44
|
+
#
|
45
|
+
# @return [String]
|
46
|
+
def to_s
|
47
|
+
"--#{name}#{value_as_string}"
|
48
|
+
end
|
49
|
+
|
50
|
+
private
|
51
|
+
|
52
|
+
# Returns the value fragment of the option string if any value is specified
|
53
|
+
#
|
54
|
+
# @return [String]
|
55
|
+
def value_as_string
|
56
|
+
if value.nil?
|
57
|
+
''
|
58
|
+
else
|
59
|
+
"=#{value}"
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
data/lib/departure/runner.rb
CHANGED
@@ -5,7 +5,6 @@ module Departure
|
|
5
5
|
# It executes pt-online-schema-change commands in a new process and gets its
|
6
6
|
# output and status
|
7
7
|
class Runner
|
8
|
-
COMMAND_NOT_FOUND = 127
|
9
8
|
|
10
9
|
# Constructor
|
11
10
|
#
|
@@ -17,8 +16,7 @@ module Departure
|
|
17
16
|
@logger = logger
|
18
17
|
@cli_generator = cli_generator
|
19
18
|
@mysql_adapter = mysql_adapter
|
20
|
-
@
|
21
|
-
@config = config
|
19
|
+
@error_log_path = config.error_log_path
|
22
20
|
end
|
23
21
|
|
24
22
|
# Executes the passed sql statement using pt-online-schema-change for ALTER
|
@@ -27,8 +25,8 @@ module Departure
|
|
27
25
|
# @param sql [String]
|
28
26
|
def query(sql)
|
29
27
|
if alter_statement?(sql)
|
30
|
-
|
31
|
-
execute(
|
28
|
+
command_line = cli_generator.parse_statement(sql)
|
29
|
+
execute(command_line)
|
32
30
|
else
|
33
31
|
mysql_adapter.execute(sql)
|
34
32
|
end
|
@@ -45,18 +43,15 @@ module Departure
|
|
45
43
|
# TODO: rename it so we don't confuse it with AR's #execute
|
46
44
|
# Runs and logs the given command
|
47
45
|
#
|
48
|
-
# @param
|
46
|
+
# @param command_line [String]
|
49
47
|
# @return [Boolean]
|
50
|
-
def execute(
|
51
|
-
|
52
|
-
logging { run_command }
|
53
|
-
validate_status
|
54
|
-
status
|
48
|
+
def execute(command_line)
|
49
|
+
Command.new(command_line, error_log_path, logger).run
|
55
50
|
end
|
56
51
|
|
57
52
|
private
|
58
53
|
|
59
|
-
attr_reader :
|
54
|
+
attr_reader :logger, :cli_generator, :mysql_adapter, :error_log_path
|
60
55
|
|
61
56
|
# Checks whether the sql statement is an ALTER TABLE
|
62
57
|
#
|
@@ -65,66 +60,5 @@ module Departure
|
|
65
60
|
def alter_statement?(sql)
|
66
61
|
sql =~ /\Aalter table/i
|
67
62
|
end
|
68
|
-
|
69
|
-
# Logs the start and end of the execution
|
70
|
-
#
|
71
|
-
# @yield
|
72
|
-
def logging
|
73
|
-
log_started
|
74
|
-
yield
|
75
|
-
log_finished
|
76
|
-
end
|
77
|
-
|
78
|
-
# Logs when the execution started
|
79
|
-
def log_started
|
80
|
-
logger.write("\n")
|
81
|
-
logger.say("Running #{command}\n\n", true)
|
82
|
-
end
|
83
|
-
|
84
|
-
# Executes the command and prints its output to the stdout
|
85
|
-
def run_command
|
86
|
-
Open3.popen3("#{command} 2> #{error_log_path}") do |_stdin, stdout, _stderr, waith_thr|
|
87
|
-
begin
|
88
|
-
loop do
|
89
|
-
IO.select([stdout])
|
90
|
-
data = stdout.read_nonblock(8)
|
91
|
-
logger.write_no_newline(data)
|
92
|
-
end
|
93
|
-
rescue EOFError
|
94
|
-
# noop
|
95
|
-
ensure
|
96
|
-
@status = waith_thr.value
|
97
|
-
end
|
98
|
-
end
|
99
|
-
end
|
100
|
-
|
101
|
-
# Validates the status of the execution
|
102
|
-
#
|
103
|
-
# @raise [NoStatusError] if the spawned process' status can't be retrieved
|
104
|
-
# @raise [SignalError] if the spawned process received a signal
|
105
|
-
# @raise [CommandNotFoundError] if pt-online-schema-change can't be found
|
106
|
-
def validate_status
|
107
|
-
raise SignalError.new(status) if status.signaled?
|
108
|
-
raise CommandNotFoundError if status.exitstatus == COMMAND_NOT_FOUND
|
109
|
-
raise Error, error_message unless status.success?
|
110
|
-
end
|
111
|
-
|
112
|
-
# Prints a line break to keep the logs separate from the execution time
|
113
|
-
# print by the migration
|
114
|
-
def log_finished
|
115
|
-
logger.write("\n")
|
116
|
-
end
|
117
|
-
|
118
|
-
# The path where the percona toolkit stderr will be written
|
119
|
-
#
|
120
|
-
# @return [String]
|
121
|
-
def error_log_path
|
122
|
-
config.error_log_path
|
123
|
-
end
|
124
|
-
|
125
|
-
# @return [String]
|
126
|
-
def error_message
|
127
|
-
File.read(error_log_path)
|
128
|
-
end
|
129
63
|
end
|
130
64
|
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
module Departure
|
2
|
+
# Encapsulates the pt-online-schema-change options defined by the user
|
3
|
+
class UserOptions
|
4
|
+
delegate :each, :merge, to: :to_set
|
5
|
+
|
6
|
+
# Constructor
|
7
|
+
#
|
8
|
+
# @param arguments [String]
|
9
|
+
def initialize(arguments = ENV['PERCONA_ARGS'])
|
10
|
+
@arguments = arguments
|
11
|
+
end
|
12
|
+
|
13
|
+
private
|
14
|
+
|
15
|
+
attr_reader :arguments
|
16
|
+
|
17
|
+
# Returns the arguments the user defined but without duplicates
|
18
|
+
#
|
19
|
+
# @return [Set]
|
20
|
+
def to_set
|
21
|
+
Set.new(user_options)
|
22
|
+
end
|
23
|
+
|
24
|
+
# Returns Option instances from the arguments the user specified, if any
|
25
|
+
#
|
26
|
+
# @return [Array]
|
27
|
+
def user_options
|
28
|
+
if arguments
|
29
|
+
build_options
|
30
|
+
else
|
31
|
+
[]
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
# Builds Option instances from the user arguments
|
36
|
+
#
|
37
|
+
# @return [Array<Option>]
|
38
|
+
def build_options
|
39
|
+
arguments.split(' ').map do |argument|
|
40
|
+
Option.from_string(argument)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
data/lib/departure/version.rb
CHANGED
data/test_database.rb
CHANGED
@@ -19,7 +19,7 @@ class TestDatabase
|
|
19
19
|
drop_and_create_schema_migrations_table
|
20
20
|
end
|
21
21
|
|
22
|
-
# Creates the
|
22
|
+
# Creates the #{database} database and the comments table in it.
|
23
23
|
# Before, it drops both if they already exist
|
24
24
|
def setup_test_database
|
25
25
|
drop_and_create_test_database
|
metadata
CHANGED
@@ -1,17 +1,18 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: departure
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 2.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ilya Zayats
|
8
8
|
- Pau Pérez
|
9
9
|
- Fran Casas
|
10
10
|
- Jorge Morante
|
11
|
+
- Adrian Serafin
|
11
12
|
autorequire:
|
12
13
|
bindir: bin
|
13
14
|
cert_chain: []
|
14
|
-
date: 2017-04-
|
15
|
+
date: 2017-04-20 00:00:00.000000000 Z
|
15
16
|
dependencies:
|
16
17
|
- !ruby/object:Gem::Dependency
|
17
18
|
name: rails
|
@@ -19,26 +20,26 @@ dependencies:
|
|
19
20
|
requirements:
|
20
21
|
- - "~>"
|
21
22
|
- !ruby/object:Gem::Version
|
22
|
-
version:
|
23
|
+
version: 4.0.0
|
23
24
|
type: :runtime
|
24
25
|
prerelease: false
|
25
26
|
version_requirements: !ruby/object:Gem::Requirement
|
26
27
|
requirements:
|
27
28
|
- - "~>"
|
28
29
|
- !ruby/object:Gem::Version
|
29
|
-
version:
|
30
|
+
version: 4.0.0
|
30
31
|
- !ruby/object:Gem::Dependency
|
31
32
|
name: mysql2
|
32
33
|
requirement: !ruby/object:Gem::Requirement
|
33
34
|
requirements:
|
34
|
-
- -
|
35
|
+
- - '='
|
35
36
|
- !ruby/object:Gem::Version
|
36
37
|
version: 0.3.20
|
37
38
|
type: :runtime
|
38
39
|
prerelease: false
|
39
40
|
version_requirements: !ruby/object:Gem::Requirement
|
40
41
|
requirements:
|
41
|
-
- -
|
42
|
+
- - '='
|
42
43
|
- !ruby/object:Gem::Version
|
43
44
|
version: 0.3.20
|
44
45
|
- !ruby/object:Gem::Dependency
|
@@ -123,6 +124,20 @@ dependencies:
|
|
123
124
|
- - ">="
|
124
125
|
- !ruby/object:Gem::Version
|
125
126
|
version: 8.2.1
|
127
|
+
- !ruby/object:Gem::Dependency
|
128
|
+
name: climate_control
|
129
|
+
requirement: !ruby/object:Gem::Requirement
|
130
|
+
requirements:
|
131
|
+
- - "~>"
|
132
|
+
- !ruby/object:Gem::Version
|
133
|
+
version: 0.0.3
|
134
|
+
type: :development
|
135
|
+
prerelease: false
|
136
|
+
version_requirements: !ruby/object:Gem::Requirement
|
137
|
+
requirements:
|
138
|
+
- - "~>"
|
139
|
+
- !ruby/object:Gem::Version
|
140
|
+
version: 0.0.3
|
126
141
|
description: Execute your ActiveRecord migrations with Percona's pt-online-schema-change.
|
127
142
|
Formerly known as Percona Migrator.
|
128
143
|
email:
|
@@ -130,6 +145,7 @@ email:
|
|
130
145
|
- pau.perez@redbooth.com
|
131
146
|
- fran.casas@redbooth.com
|
132
147
|
- jorge.morante@redbooth.com
|
148
|
+
- adrian@softmad.pl
|
133
149
|
executables: []
|
134
150
|
extensions: []
|
135
151
|
extra_rdoc_files: []
|
@@ -142,23 +158,32 @@ files:
|
|
142
158
|
- Gemfile
|
143
159
|
- LICENSE.txt
|
144
160
|
- README.md
|
161
|
+
- RELEASING.md
|
145
162
|
- Rakefile
|
146
163
|
- bin/console
|
164
|
+
- bin/rspec
|
147
165
|
- bin/setup
|
148
166
|
- config.yml
|
149
167
|
- configuration.rb
|
150
168
|
- departure.gemspec
|
169
|
+
- departure_error.log
|
151
170
|
- lib/active_record/connection_adapters/percona_adapter.rb
|
152
171
|
- lib/departure.rb
|
153
172
|
- lib/departure/alter_argument.rb
|
154
173
|
- lib/departure/cli_generator.rb
|
174
|
+
- lib/departure/command.rb
|
155
175
|
- lib/departure/configuration.rb
|
176
|
+
- lib/departure/connection_details.rb
|
177
|
+
- lib/departure/dsn.rb
|
156
178
|
- lib/departure/errors.rb
|
179
|
+
- lib/departure/log_sanitizers/password_sanitizer.rb
|
157
180
|
- lib/departure/logger.rb
|
158
181
|
- lib/departure/logger_factory.rb
|
159
182
|
- lib/departure/null_logger.rb
|
183
|
+
- lib/departure/option.rb
|
160
184
|
- lib/departure/railtie.rb
|
161
185
|
- lib/departure/runner.rb
|
186
|
+
- lib/departure/user_options.rb
|
162
187
|
- lib/departure/version.rb
|
163
188
|
- lib/lhm.rb
|
164
189
|
- lib/lhm/adapter.rb
|