departure 4.0.1 → 5.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.codeclimate.yml +8 -0
- data/.rubocop.yml +60 -0
- data/CHANGELOG.md +7 -1
- data/Dockerfile +32 -0
- data/Gemfile +2 -1
- data/README.md +9 -3
- data/bin/console +3 -3
- data/bin/rspec +6 -7
- data/config.yml.erb +4 -0
- data/configuration.rb +3 -2
- data/departure.gemspec +6 -6
- data/docker-compose.yml +23 -0
- data/lib/active_record/connection_adapters/percona_adapter.rb +13 -11
- data/lib/departure.rb +1 -1
- data/lib/departure/alter_argument.rb +1 -1
- data/lib/departure/cli_generator.rb +2 -3
- data/lib/departure/command.rb +2 -2
- data/lib/departure/connection_details.rb +11 -3
- data/lib/departure/dsn.rb +0 -2
- data/lib/departure/log_sanitizers/password_sanitizer.rb +2 -1
- data/lib/departure/logger.rb +1 -2
- data/lib/departure/logger_factory.rb +0 -1
- data/lib/departure/option.rb +4 -4
- data/lib/departure/runner.rb +0 -2
- data/lib/departure/version.rb +1 -1
- data/lib/lhm.rb +1 -3
- data/lib/lhm/adapter.rb +1 -3
- data/lib/lhm/column_with_sql.rb +7 -3
- data/lib/lhm/column_with_type.rb +0 -2
- data/test_database.rb +38 -8
- metadata +11 -19
- data/config.yml +0 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 188abb75d64bc512bba775dfe589294bdf3bd075
|
4
|
+
data.tar.gz: 7c06bd461fe3c1a8756a6be3ebf38cc6aad7a9e6
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: fcdc8acbd5a3e40643a745b29423eda2dab89e7b919d6248eb3b73d64c9371bf50874d089790f05012b09845ffe4040ebaee9b9bdc1c01a0043d1ee6d26fa96c
|
7
|
+
data.tar.gz: 1a7933c409ab19e804849a60dd0507d9c6861c9deeadb141fcf03a3022a134dd0c124d56d4911033e2d096aed1b6eb249669f97dbaf8d1eda903d09d0455c744
|
data/.codeclimate.yml
ADDED
data/.rubocop.yml
ADDED
@@ -0,0 +1,60 @@
|
|
1
|
+
---
|
2
|
+
Metrics/AbcSize:
|
3
|
+
Enabled: false
|
4
|
+
|
5
|
+
Metrics/BlockLength:
|
6
|
+
Max: 20
|
7
|
+
Exclude:
|
8
|
+
- 'spec/*'
|
9
|
+
- 'spec/**/*'
|
10
|
+
|
11
|
+
Metrics/BlockNesting:
|
12
|
+
Max: 4
|
13
|
+
|
14
|
+
Metrics/ClassLength:
|
15
|
+
Max: 250
|
16
|
+
|
17
|
+
Metrics/LineLength:
|
18
|
+
Max: 120
|
19
|
+
Exclude:
|
20
|
+
- 'departure.gemspec'
|
21
|
+
- 'test_database.rb'
|
22
|
+
|
23
|
+
Metrics/MethodLength:
|
24
|
+
Max: 30
|
25
|
+
|
26
|
+
Metrics/ModuleLength:
|
27
|
+
Max: 250
|
28
|
+
|
29
|
+
Metrics/ParameterLists:
|
30
|
+
Max: 5
|
31
|
+
|
32
|
+
Performance/Casecmp:
|
33
|
+
Enabled: false
|
34
|
+
|
35
|
+
Style/BracesAroundHashParameters:
|
36
|
+
Exclude:
|
37
|
+
- 'spec/fixtures/migrate/**.rb'
|
38
|
+
- 'spec/integration/**.rb'
|
39
|
+
|
40
|
+
Style/CommandLiteral:
|
41
|
+
Exclude:
|
42
|
+
- 'test_database.rb'
|
43
|
+
|
44
|
+
Style/Documentation:
|
45
|
+
Enabled: false
|
46
|
+
|
47
|
+
Style/MultilineBlockChain:
|
48
|
+
Exclude:
|
49
|
+
- 'spec/integration_spec.rb'
|
50
|
+
|
51
|
+
Style/MultilineMethodCallIndentation:
|
52
|
+
Enabled: false
|
53
|
+
|
54
|
+
Style/SymbolArray:
|
55
|
+
Enabled: false
|
56
|
+
|
57
|
+
Style/UnneededPercentQ:
|
58
|
+
Exclude:
|
59
|
+
- 'departure.gemspec'
|
60
|
+
|
data/CHANGELOG.md
CHANGED
@@ -4,14 +4,20 @@ This project adheres to [Semantic Versioning](http://semver.org/).
|
|
4
4
|
|
5
5
|
Please follow the format in [Keep a Changelog](http://keepachangelog.com/)
|
6
6
|
|
7
|
-
## [
|
7
|
+
## [5.0.0] - 2017-09-19
|
8
8
|
|
9
9
|
### Added
|
10
|
+
|
11
|
+
- Support for ActiveRecord 5.0
|
12
|
+
- Docker setup to run the spec suite
|
13
|
+
|
10
14
|
### Changed
|
11
15
|
### Deprecated
|
12
16
|
### Removed
|
13
17
|
### Fixed
|
14
18
|
|
19
|
+
- Allow using bash special characters in passwords
|
20
|
+
|
15
21
|
## [4.0.1] - 2017-08-01
|
16
22
|
|
17
23
|
### Added
|
data/Dockerfile
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
FROM ruby:2.3.4
|
2
|
+
MAINTAINER muffinista@gmail.com
|
3
|
+
|
4
|
+
# Install apt based dependencies required to run Rails as
|
5
|
+
# well as RubyGems. As the Ruby image itself is based on a
|
6
|
+
# Debian image, we use apt-get to install those.
|
7
|
+
RUN apt-get update && apt-get install -y \
|
8
|
+
build-essential \
|
9
|
+
percona-toolkit
|
10
|
+
|
11
|
+
# Configure the main working directory. This is the base
|
12
|
+
# directory used in any further RUN, COPY, and ENTRYPOINT
|
13
|
+
# commands.
|
14
|
+
RUN mkdir -p /app /app/lib/departure
|
15
|
+
WORKDIR /app
|
16
|
+
|
17
|
+
# Copy the Gemfile as well as the Gemfile.lock and install
|
18
|
+
# the RubyGems. This is a separate step so the dependencies
|
19
|
+
# will be cached unless changes to one of those two files
|
20
|
+
# are made.
|
21
|
+
COPY departure.gemspec Gemfile ./
|
22
|
+
COPY lib/departure/version.rb ./lib/departure/
|
23
|
+
|
24
|
+
RUN gem install bundler && bundle install --jobs 20 --retry 5
|
25
|
+
|
26
|
+
# Copy the main application.
|
27
|
+
COPY . ./
|
28
|
+
|
29
|
+
# The main command to run when the container starts. Also
|
30
|
+
# tell the Rails dev server to bind to all interfaces by
|
31
|
+
# default.
|
32
|
+
#CMD ["bundle", "exec", "rails", "server", "-b", "0.0.0.0"]
|
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -117,10 +117,10 @@ Departure.configure do |config|
|
|
117
117
|
end
|
118
118
|
```
|
119
119
|
|
120
|
-
Unlike using `PERCONA_ARGS`, options provided with global configuration will be applied
|
120
|
+
Unlike using `PERCONA_ARGS`, options provided with global configuration will be applied
|
121
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.
|
122
|
+
|
123
|
+
Arguments provided in global configuration can be overwritten with `PERCONA_ARGS` env variable.
|
124
124
|
|
125
125
|
We recommend using this option with caution and only when you understand the consequences.
|
126
126
|
|
@@ -171,6 +171,12 @@ When an any error occurs, an `ActiveRecord::StatementInvalid` exception is
|
|
171
171
|
raised and the migration is aborted, as all other ActiveRecord connection
|
172
172
|
adapters.
|
173
173
|
|
174
|
+
## Trouleshooting
|
175
|
+
|
176
|
+
### Error creating new table: DBD::mysql::db do failed: Can't write; duplicate key in table (TABLE_NAME)
|
177
|
+
There is a [known bug](https://bugs.launchpad.net/percona-toolkit/+bug/1498128) in percona-toolkit version 2.2.15
|
178
|
+
that prevents schema changes when a table has constraints. You should upgrade to a version later than 2.2.17 to fix the issue.
|
179
|
+
|
174
180
|
## Development
|
175
181
|
|
176
182
|
After checking out the repo, run `bin/setup` to install dependencies. Then, run
|
data/bin/console
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
|
3
|
-
require
|
4
|
-
require
|
3
|
+
require 'bundler/setup'
|
4
|
+
require 'percona_migrator'
|
5
5
|
|
6
6
|
# You can add fixtures and/or initialization code here to make experimenting
|
7
7
|
# with your gem easier. You can also use a different console, if you like.
|
@@ -10,5 +10,5 @@ require "percona_migrator"
|
|
10
10
|
# require "pry"
|
11
11
|
# Pry.start
|
12
12
|
|
13
|
-
require
|
13
|
+
require 'irb'
|
14
14
|
IRB.start
|
data/bin/rspec
CHANGED
@@ -1,17 +1,16 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
# frozen_string_literal: true
|
3
|
-
|
3
|
+
|
4
4
|
# This file was generated by Bundler.
|
5
5
|
#
|
6
6
|
# The application 'rspec' is installed as part of a gem, and
|
7
7
|
# this file is here to facilitate running it.
|
8
8
|
#
|
9
9
|
|
10
|
-
require
|
11
|
-
ENV[
|
12
|
-
Pathname.new(__FILE__).realpath)
|
10
|
+
require 'pathname'
|
11
|
+
ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', Pathname.new(__FILE__).realpath)
|
13
12
|
|
14
|
-
require
|
15
|
-
require
|
13
|
+
require 'rubygems'
|
14
|
+
require 'bundler/setup'
|
16
15
|
|
17
|
-
load Gem.bin_path(
|
16
|
+
load Gem.bin_path('rspec-core', 'rspec')
|
data/config.yml.erb
ADDED
data/configuration.rb
CHANGED
@@ -1,12 +1,13 @@
|
|
1
1
|
require 'yaml'
|
2
|
+
require 'erb'
|
2
3
|
|
3
4
|
class Configuration
|
4
|
-
CONFIG_PATH = 'config.yml'
|
5
|
+
CONFIG_PATH = 'config.yml.erb'.freeze
|
5
6
|
|
6
7
|
attr_reader :config
|
7
8
|
|
8
9
|
def initialize
|
9
|
-
@config = YAML.
|
10
|
+
@config = YAML.load(ERB.new(File.read(CONFIG_PATH)).result).freeze
|
10
11
|
end
|
11
12
|
|
12
13
|
def [](key)
|
data/departure.gemspec
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
# coding: utf-8
|
2
|
+
|
2
3
|
lib = File.expand_path('../lib', __FILE__)
|
3
4
|
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
5
|
|
@@ -7,21 +8,20 @@ require 'departure/version'
|
|
7
8
|
Gem::Specification.new do |spec|
|
8
9
|
spec.name = 'departure'
|
9
10
|
spec.version = Departure::VERSION
|
10
|
-
spec.authors = ['Ilya Zayats', 'Pau Pérez', 'Fran Casas', 'Jorge Morante', 'Enrico Stano', 'Adrian Serafin']
|
11
|
-
spec.email = ['ilya.zayats@redbooth.com', 'pau.perez@redbooth.com', 'fran.casas@redbooth.com', 'jorge.morante@redbooth.com', 'adrian@softmad.pl']
|
11
|
+
spec.authors = ['Ilya Zayats', 'Pau Pérez', 'Fran Casas', 'Jorge Morante', 'Enrico Stano', 'Adrian Serafin', 'Kirk Haines']
|
12
|
+
spec.email = ['ilya.zayats@redbooth.com', 'pau.perez@redbooth.com', 'fran.casas@redbooth.com', 'jorge.morante@redbooth.com', 'adrian@softmad.pl', 'wyhaines@gmail.com']
|
12
13
|
|
13
|
-
spec.summary = %q
|
14
|
-
spec.description = %q
|
14
|
+
spec.summary = %q(pt-online-schema-change runner for ActiveRecord migrations)
|
15
|
+
spec.description = %q(Execute your ActiveRecord migrations with Percona's pt-online-schema-change. Formerly known as Percona Migrator.)
|
15
16
|
spec.homepage = 'http://github.com/redbooth/departure'
|
16
17
|
spec.license = 'MIT'
|
17
18
|
|
18
19
|
spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
19
20
|
spec.require_paths = ['lib']
|
20
21
|
|
21
|
-
spec.add_runtime_dependency 'rails', '~>
|
22
|
+
spec.add_runtime_dependency 'rails', '~> 5.0.0'
|
22
23
|
spec.add_runtime_dependency 'mysql2', '~> 0.4.0'
|
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'
|
data/docker-compose.yml
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
version: '2'
|
2
|
+
services:
|
3
|
+
db:
|
4
|
+
image: mysql/mysql-server
|
5
|
+
ports:
|
6
|
+
- "3306:3306"
|
7
|
+
environment:
|
8
|
+
MYSQL_DATABASE: departure_test
|
9
|
+
MYSQL_ALLOW_EMPTY_PASSWORD: 'yes'
|
10
|
+
MYSQL_ROOT_HOST: '%'
|
11
|
+
rails:
|
12
|
+
build: .
|
13
|
+
links:
|
14
|
+
- db
|
15
|
+
depends_on:
|
16
|
+
- db
|
17
|
+
tty: true
|
18
|
+
stdin_open: true
|
19
|
+
environment:
|
20
|
+
PERCONA_DB_USER: root
|
21
|
+
PERCONA_DB_HOST: db
|
22
|
+
PERCONA_DB_PASSWORD:
|
23
|
+
PERCONA_DB_NAME: departure_test
|
@@ -41,7 +41,7 @@ module ActiveRecord
|
|
41
41
|
module ConnectionAdapters
|
42
42
|
class DepartureAdapter < AbstractMysqlAdapter
|
43
43
|
|
44
|
-
class Column <
|
44
|
+
class Column < ActiveRecord::ConnectionAdapters::MySQL::Column
|
45
45
|
def adapter
|
46
46
|
DepartureAdapter
|
47
47
|
end
|
@@ -54,18 +54,18 @@ module ActiveRecord
|
|
54
54
|
def_delegators :mysql_adapter, :last_inserted_id, :each_hash, :set_field_encoding
|
55
55
|
|
56
56
|
def initialize(connection, _logger, connection_options, _config)
|
57
|
+
@mysql_adapter = connection_options[:mysql_adapter]
|
57
58
|
super
|
58
59
|
@prepared_statements = false
|
59
|
-
@mysql_adapter = connection_options[:mysql_adapter]
|
60
60
|
end
|
61
61
|
|
62
62
|
def exec_delete(sql, name, binds)
|
63
63
|
execute(to_sql(sql, binds), name)
|
64
64
|
@connection.affected_rows
|
65
65
|
end
|
66
|
-
alias
|
66
|
+
alias exec_update exec_delete
|
67
67
|
|
68
|
-
def exec_insert(sql, name, binds, pk = nil, sequence_name = nil)
|
68
|
+
def exec_insert(sql, name, binds, pk = nil, sequence_name = nil) # rubocop:disable Lint/UnusedMethodArgument, Metrics/LineLength
|
69
69
|
execute(to_sql(sql, binds), name)
|
70
70
|
end
|
71
71
|
|
@@ -76,8 +76,9 @@ module ActiveRecord
|
|
76
76
|
|
77
77
|
# Executes a SELECT query and returns an array of rows. Each row is an
|
78
78
|
# array of field values.
|
79
|
-
|
80
|
-
|
79
|
+
|
80
|
+
def select_rows(arel, name = nil, binds = [])
|
81
|
+
select_all(arel, name, binds).rows
|
81
82
|
end
|
82
83
|
|
83
84
|
# Executes a SELECT query and returns an array of record hashes with the
|
@@ -91,9 +92,11 @@ module ActiveRecord
|
|
91
92
|
true
|
92
93
|
end
|
93
94
|
|
94
|
-
|
95
|
-
|
95
|
+
# rubocop:disable Metrics/ParameterLists
|
96
|
+
def new_column(field, default, type_metadata, null, table_name, default_function, collation, comment)
|
97
|
+
Column.new(field, default, type_metadata, null, table_name, default_function, collation, comment)
|
96
98
|
end
|
99
|
+
# rubocop:enable Metrics/ParameterLists
|
97
100
|
|
98
101
|
# Adds a new index to the table
|
99
102
|
#
|
@@ -102,7 +105,7 @@ module ActiveRecord
|
|
102
105
|
# @param options [Hash] optional
|
103
106
|
def add_index(table_name, column_name, options = {})
|
104
107
|
index_name, index_type, index_columns, index_options = add_index_options(table_name, column_name, options)
|
105
|
-
execute "ALTER TABLE #{quote_table_name(table_name)} ADD #{index_type} INDEX #{quote_column_name(index_name)} (#{index_columns})#{index_options}"
|
108
|
+
execute "ALTER TABLE #{quote_table_name(table_name)} ADD #{index_type} INDEX #{quote_column_name(index_name)} (#{index_columns})#{index_options}" # rubocop:disable Metrics/LineLength
|
106
109
|
end
|
107
110
|
|
108
111
|
# Remove the given index from the table.
|
@@ -116,8 +119,7 @@ module ActiveRecord
|
|
116
119
|
|
117
120
|
# Returns the MySQL error number from the exception. The
|
118
121
|
# AbstractMysqlAdapter requires it to be implemented
|
119
|
-
def error_number(_exception)
|
120
|
-
end
|
122
|
+
def error_number(_exception); end
|
121
123
|
|
122
124
|
def full_version
|
123
125
|
mysql_adapter.raw_connection.server_info[:version]
|
data/lib/departure.rb
CHANGED
@@ -32,7 +32,7 @@ module Departure
|
|
32
32
|
def self.load
|
33
33
|
ActiveRecord::Migrator.instance_eval do
|
34
34
|
class << self
|
35
|
-
|
35
|
+
alias original_migrate migrate
|
36
36
|
end
|
37
37
|
|
38
38
|
# Checks whether arguments are being passed through PERCONA_ARGS when running
|
@@ -5,12 +5,11 @@ require 'departure/connection_details'
|
|
5
5
|
require 'departure/user_options'
|
6
6
|
|
7
7
|
module Departure
|
8
|
-
|
9
8
|
# Generates the equivalent Percona's pt-online-schema-change command to the
|
10
9
|
# given SQL statement
|
11
10
|
#
|
12
|
-
# --no-check-alter is used to allow running CHANGE COLUMN statements. For
|
13
|
-
#
|
11
|
+
# --no-check-alter is used to allow running CHANGE COLUMN statements. For more details, check:
|
12
|
+
# www.percona.com/doc/percona-toolkit/2.2/pt-online-schema-change.html#cmdoption-pt-online-schema-change--[no]check-alter # rubocop:disable Metrics/LineLength
|
14
13
|
#
|
15
14
|
class CliGenerator
|
16
15
|
COMMAND_NAME = 'pt-online-schema-change'.freeze
|
data/lib/departure/command.rb
CHANGED
@@ -47,7 +47,7 @@ module Departure
|
|
47
47
|
data = stdout.read_nonblock(8)
|
48
48
|
logger.write_no_newline(data)
|
49
49
|
end
|
50
|
-
rescue EOFError
|
50
|
+
rescue EOFError # rubocop:disable Lint/HandleExceptions
|
51
51
|
# noop
|
52
52
|
ensure
|
53
53
|
@status = waith_thr.value
|
@@ -69,7 +69,7 @@ module Departure
|
|
69
69
|
# @raise [SignalError] if the spawned process received a signal
|
70
70
|
# @raise [CommandNotFoundError] if pt-online-schema-change can't be found
|
71
71
|
def validate_status!
|
72
|
-
raise SignalError.new(status) if status.signaled?
|
72
|
+
raise SignalError.new(status) if status.signaled? # rubocop:disable Style/RaiseArgs
|
73
73
|
raise CommandNotFoundError if status.exitstatus == COMMAND_NOT_FOUND
|
74
74
|
raise Error, error_message unless status.success?
|
75
75
|
end
|
@@ -1,7 +1,8 @@
|
|
1
|
+
require 'shellwords'
|
1
2
|
module Departure
|
2
3
|
# Holds the parameters of the DB connection and formats them to string
|
3
4
|
class ConnectionDetails
|
4
|
-
|
5
|
+
DEFAULT_PORT = 3306
|
5
6
|
# Constructor
|
6
7
|
#
|
7
8
|
# @param [Hash] connection parametes as used in #establish_conneciton
|
@@ -14,7 +15,7 @@ module Departure
|
|
14
15
|
#
|
15
16
|
# @return [String]
|
16
17
|
def to_s
|
17
|
-
@to_s ||= "-h #{host} -u #{user} #{password_argument}"
|
18
|
+
@to_s ||= "-h #{host} -P #{port} -u #{user} #{password_argument}"
|
18
19
|
end
|
19
20
|
|
20
21
|
# TODO: Doesn't the abstract adapter already handle this somehow?
|
@@ -33,7 +34,7 @@ module Departure
|
|
33
34
|
# @return [String]
|
34
35
|
def password_argument
|
35
36
|
if password.present?
|
36
|
-
|
37
|
+
%(--password #{Shellwords.escape(password)} )
|
37
38
|
else
|
38
39
|
''
|
39
40
|
end
|
@@ -66,5 +67,12 @@ module Departure
|
|
66
67
|
def password
|
67
68
|
ENV.fetch('PERCONA_DB_PASSWORD', connection_data[:password])
|
68
69
|
end
|
70
|
+
|
71
|
+
# Returns the database's port.
|
72
|
+
#
|
73
|
+
# @return [String]
|
74
|
+
def port
|
75
|
+
connection_data.fetch(:port, DEFAULT_PORT)
|
76
|
+
end
|
69
77
|
end
|
70
78
|
end
|
data/lib/departure/dsn.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
module Departure
|
2
2
|
module LogSanitizers
|
3
3
|
class PasswordSanitizer
|
4
|
-
PASSWORD_REPLACEMENT = '[filtered_password]'
|
4
|
+
PASSWORD_REPLACEMENT = '[filtered_password]'.freeze
|
5
5
|
|
6
6
|
delegate :password_argument, to: :connection_details
|
7
7
|
|
@@ -15,6 +15,7 @@ module Departure
|
|
15
15
|
end
|
16
16
|
|
17
17
|
private
|
18
|
+
|
18
19
|
attr_accessor :connection_details
|
19
20
|
end
|
20
21
|
end
|
data/lib/departure/logger.rb
CHANGED
@@ -4,7 +4,6 @@ module Departure
|
|
4
4
|
# the from ActiveRecord::Migration because the migration's instance can't be
|
5
5
|
# seen from the connection adapter.
|
6
6
|
class Logger
|
7
|
-
|
8
7
|
def initialize(sanitizers)
|
9
8
|
@sanitizers = sanitizers
|
10
9
|
end
|
@@ -15,7 +14,7 @@ module Departure
|
|
15
14
|
# @param message [String]
|
16
15
|
# @param subitem [Boolean] whether to show message as a nested log item
|
17
16
|
def say(message, subitem = false)
|
18
|
-
write "#{subitem ?
|
17
|
+
write "#{subitem ? ' ->' : '--'} #{message}"
|
19
18
|
end
|
20
19
|
|
21
20
|
# Outputs the text through the stdout adding a new line at the end
|
data/lib/departure/option.rb
CHANGED
@@ -24,10 +24,10 @@ module Departure
|
|
24
24
|
#
|
25
25
|
# @param [Option]
|
26
26
|
# @return [Boolean]
|
27
|
-
def ==(
|
28
|
-
name ==
|
27
|
+
def ==(other)
|
28
|
+
name == other.name
|
29
29
|
end
|
30
|
-
alias
|
30
|
+
alias eql? ==
|
31
31
|
|
32
32
|
# Returns the option's hash
|
33
33
|
#
|
@@ -65,7 +65,7 @@ module Departure
|
|
65
65
|
def value_as_string
|
66
66
|
if value.nil?
|
67
67
|
''
|
68
|
-
elsif value.include?(
|
68
|
+
elsif value.include?('=')
|
69
69
|
" #{value}"
|
70
70
|
else
|
71
71
|
"=#{value}"
|
data/lib/departure/runner.rb
CHANGED
data/lib/departure/version.rb
CHANGED
data/lib/lhm.rb
CHANGED
@@ -4,14 +4,13 @@ require 'lhm/adapter'
|
|
4
4
|
# while providing a different behaviour. We delegate all LHM's methods to
|
5
5
|
# ActiveRecord so that you don't need to modify your old LHM migrations
|
6
6
|
module Lhm
|
7
|
-
|
8
7
|
# Yields an adapter instance so that Lhm migration Dsl methods get
|
9
8
|
# delegated to ActiveRecord::Migration ones instead
|
10
9
|
#
|
11
10
|
# @param table_name [String]
|
12
11
|
# @param _options [Hash]
|
13
12
|
# @param block [Block]
|
14
|
-
def self.change_table(table_name, _options = {}, &block)
|
13
|
+
def self.change_table(table_name, _options = {}, &block) # rubocop:disable Lint/UnusedMethodArgument
|
15
14
|
yield Adapter.new(@migration, table_name)
|
16
15
|
end
|
17
16
|
|
@@ -22,4 +21,3 @@ module Lhm
|
|
22
21
|
@migration = migration
|
23
22
|
end
|
24
23
|
end
|
25
|
-
|
data/lib/lhm/adapter.rb
CHANGED
@@ -2,12 +2,10 @@ require 'lhm/column_with_sql'
|
|
2
2
|
require 'lhm/column_with_type'
|
3
3
|
|
4
4
|
module Lhm
|
5
|
-
|
6
5
|
# Translates Lhm DSL to ActiveRecord's one, so Lhm migrations will now go
|
7
6
|
# through Percona as well, without any modification on the migration's
|
8
7
|
# code
|
9
8
|
class Adapter
|
10
|
-
|
11
9
|
# Constructor
|
12
10
|
#
|
13
11
|
# @param migration [ActiveRecord::Migtration]
|
@@ -79,7 +77,7 @@ module Lhm
|
|
79
77
|
# @param index_name [String]
|
80
78
|
def add_unique_index(columns, index_name = nil)
|
81
79
|
options = { unique: true }
|
82
|
-
options.merge!(name: index_name) if index_name
|
80
|
+
options.merge!(name: index_name) if index_name # rubocop:disable Performance/RedundantMerge
|
83
81
|
|
84
82
|
migration.add_index(table_name, columns, options)
|
85
83
|
end
|
data/lib/lhm/column_with_sql.rb
CHANGED
@@ -1,7 +1,6 @@
|
|
1
1
|
require 'forwardable'
|
2
2
|
|
3
3
|
module Lhm
|
4
|
-
|
5
4
|
# Abstracts the details of a table column definition when specified with a MySQL
|
6
5
|
# column definition string
|
7
6
|
class ColumnWithSql
|
@@ -54,11 +53,16 @@ module Lhm
|
|
54
53
|
# @return [column_factory]
|
55
54
|
def column
|
56
55
|
cast_type = ActiveRecord::Base.connection.lookup_cast_type(definition)
|
56
|
+
metadata = ActiveRecord::ConnectionAdapters::SqlTypeMetadata.new(
|
57
|
+
type: cast_type.type,
|
58
|
+
sql_type: definition,
|
59
|
+
limit: cast_type.limit
|
60
|
+
)
|
61
|
+
mysql_metadata = ActiveRecord::ConnectionAdapters::MySQL::TypeMetadata.new(metadata)
|
57
62
|
@column ||= self.class.column_factory.new(
|
58
63
|
name,
|
59
64
|
default_value,
|
60
|
-
|
61
|
-
definition,
|
65
|
+
mysql_metadata,
|
62
66
|
null_value
|
63
67
|
)
|
64
68
|
end
|
data/lib/lhm/column_with_type.rb
CHANGED
@@ -1,12 +1,10 @@
|
|
1
1
|
module Lhm
|
2
|
-
|
3
2
|
# Abstracts the details of a table column definition when specified with a type
|
4
3
|
# as a symbol. This is the regular ActiveRecord's #add_column syntax:
|
5
4
|
#
|
6
5
|
# add_column :tablenames, :field, :string
|
7
6
|
#
|
8
7
|
class ColumnWithType
|
9
|
-
|
10
8
|
# Constructor
|
11
9
|
#
|
12
10
|
# @param name [String, Symbol]
|
data/test_database.rb
CHANGED
@@ -1,9 +1,12 @@
|
|
1
|
+
require 'active_record'
|
2
|
+
|
1
3
|
# Setups the test database with the schema_migrations table that ActiveRecord
|
2
4
|
# requires for the migrations, plus a table for the Comment model used throught
|
3
5
|
# the tests.
|
4
6
|
#
|
5
7
|
class TestDatabase
|
6
8
|
|
9
|
+
|
7
10
|
# Constructor
|
8
11
|
#
|
9
12
|
# @param config [Hash]
|
@@ -19,7 +22,7 @@ class TestDatabase
|
|
19
22
|
drop_and_create_schema_migrations_table
|
20
23
|
end
|
21
24
|
|
22
|
-
# Creates the #{database} database and the comments table in it.
|
25
|
+
# Creates the #{@database} database and the comments table in it.
|
23
26
|
# Before, it drops both if they already exist
|
24
27
|
def setup_test_database
|
25
28
|
drop_and_create_test_database
|
@@ -29,7 +32,13 @@ class TestDatabase
|
|
29
32
|
# Creates the ActiveRecord's schema_migrations table required for
|
30
33
|
# migrations to work. Before, it drops the table if it already exists
|
31
34
|
def drop_and_create_schema_migrations_table
|
32
|
-
|
35
|
+
sql = [
|
36
|
+
"USE #{@database}",
|
37
|
+
"DROP TABLE IF EXISTS schema_migrations",
|
38
|
+
"CREATE TABLE schema_migrations ( version varchar(255) COLLATE utf8_unicode_ci NOT NULL, UNIQUE KEY unique_schema_migrations (version)) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci"
|
39
|
+
]
|
40
|
+
|
41
|
+
run_commands(sql)
|
33
42
|
end
|
34
43
|
|
35
44
|
private
|
@@ -37,16 +46,37 @@ class TestDatabase
|
|
37
46
|
attr_reader :config, :database
|
38
47
|
|
39
48
|
def drop_and_create_test_database
|
40
|
-
|
49
|
+
sql = [
|
50
|
+
"DROP DATABASE IF EXISTS #{@database}",
|
51
|
+
"CREATE DATABASE #{@database} DEFAULT CHARACTER SET utf8 DEFAULT COLLATE utf8_unicode_ci"
|
52
|
+
]
|
53
|
+
|
54
|
+
run_commands(sql)
|
41
55
|
end
|
42
56
|
|
43
57
|
def drop_and_create_comments_table
|
44
|
-
|
58
|
+
sql = [
|
59
|
+
"USE #{@database}",
|
60
|
+
"DROP TABLE IF EXISTS comments",
|
61
|
+
"CREATE TABLE comments ( id int(12) NOT NULL AUTO_INCREMENT, PRIMARY KEY (id)) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci"
|
62
|
+
]
|
63
|
+
|
64
|
+
run_commands(sql)
|
65
|
+
end
|
66
|
+
|
67
|
+
def run_commands(sql)
|
68
|
+
conn.execute("START TRANSACTION")
|
69
|
+
sql.each { |str|
|
70
|
+
conn.execute(str)
|
71
|
+
}
|
72
|
+
conn.execute("COMMIT")
|
45
73
|
end
|
46
74
|
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
75
|
+
def conn
|
76
|
+
@conn ||= ActiveRecord::Base.mysql2_connection(
|
77
|
+
host: @config['hostname'],
|
78
|
+
username: @config['username'],
|
79
|
+
password: @config['password'],
|
80
|
+
reconnect: true)
|
51
81
|
end
|
52
82
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: departure
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 5.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ilya Zayats
|
@@ -10,10 +10,11 @@ authors:
|
|
10
10
|
- Jorge Morante
|
11
11
|
- Enrico Stano
|
12
12
|
- Adrian Serafin
|
13
|
+
- Kirk Haines
|
13
14
|
autorequire:
|
14
15
|
bindir: bin
|
15
16
|
cert_chain: []
|
16
|
-
date: 2017-
|
17
|
+
date: 2017-09-19 00:00:00.000000000 Z
|
17
18
|
dependencies:
|
18
19
|
- !ruby/object:Gem::Dependency
|
19
20
|
name: rails
|
@@ -21,14 +22,14 @@ dependencies:
|
|
21
22
|
requirements:
|
22
23
|
- - "~>"
|
23
24
|
- !ruby/object:Gem::Version
|
24
|
-
version:
|
25
|
+
version: 5.0.0
|
25
26
|
type: :runtime
|
26
27
|
prerelease: false
|
27
28
|
version_requirements: !ruby/object:Gem::Requirement
|
28
29
|
requirements:
|
29
30
|
- - "~>"
|
30
31
|
- !ruby/object:Gem::Version
|
31
|
-
version:
|
32
|
+
version: 5.0.0
|
32
33
|
- !ruby/object:Gem::Dependency
|
33
34
|
name: mysql2
|
34
35
|
requirement: !ruby/object:Gem::Requirement
|
@@ -43,20 +44,6 @@ dependencies:
|
|
43
44
|
- - "~>"
|
44
45
|
- !ruby/object:Gem::Version
|
45
46
|
version: 0.4.0
|
46
|
-
- !ruby/object:Gem::Dependency
|
47
|
-
name: bundler
|
48
|
-
requirement: !ruby/object:Gem::Requirement
|
49
|
-
requirements:
|
50
|
-
- - "~>"
|
51
|
-
- !ruby/object:Gem::Version
|
52
|
-
version: '1.10'
|
53
|
-
type: :development
|
54
|
-
prerelease: false
|
55
|
-
version_requirements: !ruby/object:Gem::Requirement
|
56
|
-
requirements:
|
57
|
-
- - "~>"
|
58
|
-
- !ruby/object:Gem::Version
|
59
|
-
version: '1.10'
|
60
47
|
- !ruby/object:Gem::Dependency
|
61
48
|
name: rake
|
62
49
|
requirement: !ruby/object:Gem::Requirement
|
@@ -147,15 +134,19 @@ email:
|
|
147
134
|
- fran.casas@redbooth.com
|
148
135
|
- jorge.morante@redbooth.com
|
149
136
|
- adrian@softmad.pl
|
137
|
+
- wyhaines@gmail.com
|
150
138
|
executables: []
|
151
139
|
extensions: []
|
152
140
|
extra_rdoc_files: []
|
153
141
|
files:
|
142
|
+
- ".codeclimate.yml"
|
154
143
|
- ".gitignore"
|
155
144
|
- ".rspec"
|
145
|
+
- ".rubocop.yml"
|
156
146
|
- ".travis.yml"
|
157
147
|
- CHANGELOG.md
|
158
148
|
- CODE_OF_CONDUCT.md
|
149
|
+
- Dockerfile
|
159
150
|
- Gemfile
|
160
151
|
- LICENSE.txt
|
161
152
|
- README.md
|
@@ -164,10 +155,11 @@ files:
|
|
164
155
|
- bin/console
|
165
156
|
- bin/rspec
|
166
157
|
- bin/setup
|
167
|
-
- config.yml
|
158
|
+
- config.yml.erb
|
168
159
|
- configuration.rb
|
169
160
|
- departure.gemspec
|
170
161
|
- departure_error.log
|
162
|
+
- docker-compose.yml
|
171
163
|
- lib/active_record/connection_adapters/percona_adapter.rb
|
172
164
|
- lib/departure.rb
|
173
165
|
- lib/departure/alter_argument.rb
|
data/config.yml
DELETED