active_record_mysql_repl 0.1.3 → 0.1.5
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 +4 -4
- data/README.md +729 -13
- data/lib/active_record_mysql_repl/cli/erd.rb +1 -1
- data/lib/active_record_mysql_repl/cli/main.rb +19 -14
- data/lib/active_record_mysql_repl/cli/zsh_completion.rb +23 -23
- data/lib/active_record_mysql_repl/cli.rb +4 -4
- data/lib/active_record_mysql_repl/config.rb +7 -7
- data/lib/active_record_mysql_repl/database/association.rb +10 -10
- data/lib/active_record_mysql_repl/database/configs.rb +2 -2
- data/lib/active_record_mysql_repl/database/connection.rb +11 -13
- data/lib/active_record_mysql_repl/database/loader.rb +10 -5
- data/lib/active_record_mysql_repl/database.rb +4 -4
- data/lib/active_record_mysql_repl/extensions/active_record.rb +8 -8
- data/lib/active_record_mysql_repl/extensions/global.rb +0 -1
- data/lib/active_record_mysql_repl/extensions/hash.rb +8 -5
- data/lib/active_record_mysql_repl/extensions/object.rb +53 -54
- data/lib/active_record_mysql_repl/extensions/tabler.rb +2 -3
- data/lib/active_record_mysql_repl/extensions.rb +5 -6
- data/lib/active_record_mysql_repl/ssh_tunnel.rb +5 -3
- data/lib/active_record_mysql_repl/version.rb +1 -1
- data/lib/active_record_mysql_repl.rb +4 -5
- data/sample_config/{.pryrc.sample → .army.sample/.pryrc.sample} +2 -0
- data/sample_config/{associations.sample.yml → .army.sample/associations.sample.yml} +1 -1
- data/sample_config/{databases.sample.yml → .army.sample/databases.sample.yml} +2 -2
- data/sample_config/.army.sample/extensions/hello.rb +9 -0
- data/sample_config/.army.sample.yml +4 -4
- metadata +20 -5
@@ -1,43 +1,48 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
|
3
|
-
require
|
4
|
-
require
|
5
|
-
require
|
6
|
-
require
|
7
|
-
require
|
3
|
+
require "pry"
|
4
|
+
require "colorize"
|
5
|
+
require "active_support"
|
6
|
+
require "active_support/core_ext"
|
7
|
+
require "fileutils"
|
8
8
|
|
9
9
|
module ActiveRecordMysqlRepl
|
10
10
|
module CLI
|
11
11
|
module Main
|
12
12
|
def self.run(args)
|
13
|
-
if args
|
13
|
+
if args.empty?
|
14
|
+
puts "ActiveRecordMysqlRepl Version: #{VERSION}"
|
15
|
+
return
|
16
|
+
end
|
17
|
+
|
18
|
+
if args[0] == "--zsh-completion"
|
14
19
|
puts ZshCompletion.generate
|
15
20
|
return
|
16
21
|
end
|
17
22
|
|
18
23
|
opts = CLI::Options.parse(args)
|
19
|
-
army_config = Config.load(opts[:c] || File.join(Dir.home,
|
24
|
+
army_config = Config.load(opts[:c] || File.join(Dir.home, ".army.yml"))
|
20
25
|
|
21
26
|
db_configs = Database::Configs.load(army_config.database_config)
|
22
27
|
db_config_key = opts[:d]
|
23
28
|
db_config = db_configs[db_config_key]
|
24
29
|
return puts db_configs.keys unless db_config
|
25
30
|
|
26
|
-
generate_erf = opts[:e] ==
|
31
|
+
generate_erf = opts[:e] == "erd"
|
27
32
|
|
28
33
|
SSHTunnel.tunnel(db_config) do |port|
|
29
34
|
Database::Connection.connect(db_config, port) do
|
30
35
|
Database::Loader.load_tables(db_config_key, army_config, port)
|
31
36
|
|
32
37
|
if generate_erf
|
33
|
-
require
|
38
|
+
require "rails_erd/diagram/graphviz"
|
34
39
|
puts "Generating ERD for #{db_config_key}_erd.pdf".gray
|
35
40
|
RailsERD::Diagram::Graphviz.create
|
36
|
-
FileUtils.mv(
|
37
|
-
|
41
|
+
FileUtils.mv("erd.pdf", "#{db_config_key}_erd.pdf")
|
42
|
+
next
|
38
43
|
end
|
39
44
|
|
40
|
-
require
|
45
|
+
require "active_record_mysql_repl/extensions"
|
41
46
|
if army_config.extensions_dir.present?
|
42
47
|
puts "Loading custom extensions from #{army_config.extensions_dir}".gray
|
43
48
|
Extensions.load_external(army_config.extensions_dir)
|
@@ -52,8 +57,8 @@ module ActiveRecordMysqlRepl
|
|
52
57
|
end
|
53
58
|
|
54
59
|
def self.clear_screen
|
55
|
-
system(
|
56
|
-
system(
|
60
|
+
system("clear")
|
61
|
+
system("cls")
|
57
62
|
end
|
58
63
|
end
|
59
64
|
end
|
@@ -1,29 +1,29 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
COMPLETION = <<~COMPLETION
|
4
|
-
#!/usr/bin/env bash
|
5
|
-
|
6
|
-
function _army() {
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
}
|
21
|
-
|
22
|
-
function _database {
|
23
|
-
|
24
|
-
}
|
25
|
-
|
26
|
-
compdef _army army
|
4
|
+
#!/usr/bin/env bash
|
5
|
+
|
6
|
+
function _army() {
|
7
|
+
_arguments \
|
8
|
+
'-c[path to .armyrc file]:.armyrc:_files' \
|
9
|
+
'-d[Database name]:database:->database' \
|
10
|
+
'-e[output erd]:output erd:->erd'
|
11
|
+
|
12
|
+
case "$state" in
|
13
|
+
database)
|
14
|
+
slice=("${words[@]:1}")
|
15
|
+
_values 'Database name' $(_database ${slice})
|
16
|
+
;;
|
17
|
+
erd)
|
18
|
+
_values 'Generate ERD' erd ''
|
19
|
+
esac
|
20
|
+
}
|
21
|
+
|
22
|
+
function _database {
|
23
|
+
army ${@}
|
24
|
+
}
|
25
|
+
|
26
|
+
compdef _army army
|
27
27
|
COMPLETION
|
28
28
|
|
29
29
|
module ActiveRecordMysqlRepl
|
@@ -1,9 +1,9 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require_relative
|
4
|
-
require_relative
|
5
|
-
require_relative
|
6
|
-
require_relative
|
3
|
+
require_relative "cli/options"
|
4
|
+
require_relative "cli/main"
|
5
|
+
require_relative "cli/zsh_completion"
|
6
|
+
require_relative "cli/erd"
|
7
7
|
|
8
8
|
module ActiveRecordMysqlRepl
|
9
9
|
module CLI; end
|
@@ -1,6 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
3
|
+
require "yaml"
|
4
4
|
|
5
5
|
module ActiveRecordMysqlRepl
|
6
6
|
class Config
|
@@ -9,12 +9,12 @@ module ActiveRecordMysqlRepl
|
|
9
9
|
end
|
10
10
|
|
11
11
|
def database_config
|
12
|
-
raise
|
12
|
+
raise "database_config is not defined" unless @database_config
|
13
13
|
File.join(@army_config_dir, @database_config)
|
14
14
|
end
|
15
15
|
|
16
16
|
def associations
|
17
|
-
File.join(@army_config_dir, @associations)
|
17
|
+
File.join(@army_config_dir, @associations) if @associations.present?
|
18
18
|
end
|
19
19
|
|
20
20
|
def extensions_dir
|
@@ -29,10 +29,10 @@ module ActiveRecordMysqlRepl
|
|
29
29
|
|
30
30
|
def initialize(path, config)
|
31
31
|
@army_config_dir = File.dirname(File.absolute_path(path))
|
32
|
-
@database_config = config[
|
33
|
-
@associations = config[
|
34
|
-
@extensions_dir = config[
|
35
|
-
@pryrc = config[
|
32
|
+
@database_config = config["database_config"]
|
33
|
+
@associations = config["associations"]
|
34
|
+
@extensions_dir = config["extensions_dir"]
|
35
|
+
@pryrc = config["pryrc"]
|
36
36
|
end
|
37
37
|
end
|
38
38
|
end
|
@@ -27,7 +27,7 @@ module ActiveRecordMysqlRepl
|
|
27
27
|
|
28
28
|
# Analyze the relationship between tables based on the information of *_id columns
|
29
29
|
# For example, if users.company_id exists, users belongs_to companies and companies has_many users
|
30
|
-
def self.analyze(tables, association_settings)
|
30
|
+
def self.analyze(tables, association_settings = {})
|
31
31
|
analyzed_tables = tables.map { |table| [table, AnalyzedTable.new(table)] }.to_h
|
32
32
|
|
33
33
|
analyzed_tables.each do |table_name, table|
|
@@ -36,18 +36,18 @@ module ActiveRecordMysqlRepl
|
|
36
36
|
columns.each do |column|
|
37
37
|
next if association_setting.present? && association_settings.ignore_columns(table_name).include?(column.name)
|
38
38
|
|
39
|
-
associatable = column.name.gsub(/_id$/,
|
40
|
-
next if associatable.blank? || associatable ==
|
39
|
+
associatable = column.name.gsub(/_id$/, "") if column.name.end_with?("_id")
|
40
|
+
next if associatable.blank? || associatable == "class" # reserved word
|
41
41
|
|
42
|
-
if analyzed_tables.
|
42
|
+
if analyzed_tables.key?(associatable.pluralize)
|
43
43
|
table.belongs_to << associatable.singularize if associatable
|
44
44
|
analyzed_tables[associatable.pluralize].has_many << table_name.pluralize
|
45
45
|
else
|
46
|
-
associatable_table_name = associatable.split(
|
47
|
-
if analyzed_tables.
|
48
|
-
|
46
|
+
associatable_table_name = associatable.split("_").last
|
47
|
+
table.belongs_to << if analyzed_tables.key?(associatable_table_name.pluralize)
|
48
|
+
{name: associatable, class_name: associatable_table_name.classify, foreign_key: :id}
|
49
49
|
else
|
50
|
-
|
50
|
+
{name: associatable, class_name: table_name.singularize.classify, foreign_key: :id}
|
51
51
|
end
|
52
52
|
end
|
53
53
|
end
|
@@ -71,12 +71,12 @@ module ActiveRecordMysqlRepl
|
|
71
71
|
end
|
72
72
|
|
73
73
|
def [](table)
|
74
|
-
table = (@association.keys - [
|
74
|
+
table = (@association.keys - ["ignore_columns"]) & [table]
|
75
75
|
@association[table.first] if table.present?
|
76
76
|
end
|
77
77
|
|
78
78
|
def ignore_columns(table)
|
79
|
-
@association.fetch(
|
79
|
+
@association.fetch("ignore_columns", {}).fetch(table, [])
|
80
80
|
end
|
81
81
|
end
|
82
82
|
end
|
@@ -27,7 +27,7 @@ module ActiveRecordMysqlRepl
|
|
27
27
|
private
|
28
28
|
|
29
29
|
class Config
|
30
|
-
attr_reader
|
30
|
+
attr_reader(*%i[
|
31
31
|
bastion
|
32
32
|
ssh_user
|
33
33
|
remote_host
|
@@ -36,7 +36,7 @@ module ActiveRecordMysqlRepl
|
|
36
36
|
user
|
37
37
|
password
|
38
38
|
prompt_color
|
39
|
-
]
|
39
|
+
])
|
40
40
|
|
41
41
|
def initialize(config)
|
42
42
|
@bastion = config["bastion"]
|
@@ -7,28 +7,26 @@ module ActiveRecordMysqlRepl
|
|
7
7
|
|
8
8
|
def self.connect(db_config, port)
|
9
9
|
conn = {
|
10
|
-
adapter:
|
11
|
-
host:
|
10
|
+
adapter: "mysql2",
|
11
|
+
host: "127.0.0.1",
|
12
12
|
port: port,
|
13
13
|
username: db_config.user,
|
14
14
|
password: db_config.password,
|
15
|
-
database: db_config.database
|
15
|
+
database: db_config.database
|
16
16
|
}
|
17
17
|
|
18
|
-
ActiveRecord::Base.logger = Logger.new(
|
19
|
-
|
18
|
+
ActiveRecord::Base.logger = Logger.new($stdout)
|
19
|
+
ActiveRecord::Base.establish_connection(conn)
|
20
20
|
|
21
21
|
puts "Ensureing connection to #{db_config.database} on port 127.0.0.1:#{port}".gray
|
22
22
|
|
23
23
|
tables = nil
|
24
|
-
(1..MAX_RETRY-1).to_a.each do |time|
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
next
|
31
|
-
end
|
24
|
+
(1..MAX_RETRY - 1).to_a.each do |time|
|
25
|
+
tables = ActiveRecord::Base.connection.tables
|
26
|
+
rescue => e
|
27
|
+
puts "#{e}, Retry #{time}/#{MAX_RETRY}".red
|
28
|
+
sleep time * time
|
29
|
+
next
|
32
30
|
end
|
33
31
|
|
34
32
|
if tables.blank?
|
@@ -1,8 +1,8 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
4
|
-
require
|
5
|
-
require
|
3
|
+
require "json"
|
4
|
+
require "active_record"
|
5
|
+
require "active_support/all"
|
6
6
|
|
7
7
|
module ActiveRecordMysqlRepl
|
8
8
|
module Database
|
@@ -11,9 +11,14 @@ module ActiveRecordMysqlRepl
|
|
11
11
|
puts "Loading tables".gray
|
12
12
|
|
13
13
|
tables = ActiveRecord::Base.connection.tables
|
14
|
-
association_settings = Associations.load(army_config.associations)
|
14
|
+
association_settings = army_config.associations.present? ? Associations.load(army_config.associations) : {}
|
15
|
+
association_setting = association_settings[db_config_key]
|
16
|
+
analyzed_tables = if association_setting.present?
|
17
|
+
Associations.analyze(tables, association_setting)
|
18
|
+
else
|
19
|
+
Associations.analyze(tables)
|
20
|
+
end
|
15
21
|
|
16
|
-
analyzed_tables = Associations.analyze(tables, association_settings[db_config_key])
|
17
22
|
skipped = []
|
18
23
|
analyzed_tables.each do |analyzed_table|
|
19
24
|
# defer model definition for tables with `has_many: :xxx, through: xxx` associations
|
@@ -1,9 +1,9 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require_relative
|
4
|
-
require_relative
|
5
|
-
require_relative
|
6
|
-
require_relative
|
3
|
+
require_relative "database/configs"
|
4
|
+
require_relative "database/association"
|
5
|
+
require_relative "database/connection"
|
6
|
+
require_relative "database/loader"
|
7
7
|
|
8
8
|
module ActiveRecordMysqlRepl
|
9
9
|
module Database; end
|
@@ -5,28 +5,28 @@ module ActiverecordMysqlRepl
|
|
5
5
|
module ActiveRecord
|
6
6
|
module Base
|
7
7
|
def as(name = nil)
|
8
|
-
|
8
|
+
reflect_on_all_associations(name).map(&:name)
|
9
9
|
end
|
10
10
|
|
11
11
|
def describe
|
12
12
|
[
|
13
|
-
|
14
|
-
exec_sql("
|
13
|
+
"# #{table_name}",
|
14
|
+
exec_sql("DESCRIBE #{table_name}").tab(:h),
|
15
|
+
exec_sql("SHOW INDEX FROM #{table_name}").tab(:h)
|
15
16
|
].join("\n")
|
16
17
|
end
|
17
18
|
|
18
|
-
|
19
|
-
|
19
|
+
alias_method :desc, :describe
|
20
|
+
alias_method :d, :describe
|
20
21
|
|
21
22
|
def show_ddl
|
22
|
-
exec_sql("SHOW CREATE TABLE #{
|
23
|
+
exec_sql("SHOW CREATE TABLE #{table_name}")[0]["Create Table"]
|
23
24
|
end
|
24
25
|
|
25
|
-
|
26
|
+
alias_method :ddl, :show_ddl
|
26
27
|
end
|
27
28
|
|
28
29
|
::ActiveRecord::Base.extend(Base)
|
29
30
|
end
|
30
31
|
end
|
31
32
|
end
|
32
|
-
|
@@ -4,17 +4,20 @@ module ActiverecordMysqlRepl
|
|
4
4
|
module Extensions
|
5
5
|
module Hash
|
6
6
|
def method_missing(name, *args)
|
7
|
-
if (
|
7
|
+
if (keys & [name, name.to_s]).present?
|
8
8
|
self[name] || self[name.to_s]
|
9
|
-
elsif name.to_s.end_with?(
|
9
|
+
elsif name.to_s.end_with?("=") && keys.include?(name.to_s[0..-2])
|
10
10
|
name = name[0..-2]
|
11
|
-
self[name] = args.first if
|
12
|
-
self[name.to_sym] = args.first if
|
11
|
+
self[name] = args.first if key?(name)
|
12
|
+
self[name.to_sym] = args.first if key?(name.to_sym)
|
13
13
|
end
|
14
14
|
end
|
15
15
|
|
16
|
+
def respond_to_missing?
|
17
|
+
true
|
18
|
+
end
|
19
|
+
|
16
20
|
::Hash.include(Hash)
|
17
21
|
end
|
18
22
|
end
|
19
23
|
end
|
20
|
-
|
@@ -1,28 +1,28 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
4
|
-
require
|
5
|
-
require
|
6
|
-
require
|
3
|
+
require "terminal-table"
|
4
|
+
require "csv"
|
5
|
+
require "clipboard"
|
6
|
+
require "json"
|
7
7
|
|
8
8
|
module ActiverecordMysqlRepl
|
9
9
|
module Extensions
|
10
10
|
module Object
|
11
11
|
def tabulate(orientation = nil)
|
12
|
-
arr = if
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
12
|
+
arr = if is_a?(Array)
|
13
|
+
self
|
14
|
+
elsif is_a?(::ActiveRecord::Relation)
|
15
|
+
to_a
|
16
|
+
else
|
17
|
+
[self]
|
18
|
+
end
|
19
19
|
|
20
20
|
arr = arr.map do |e|
|
21
21
|
if e.is_a?(::ActiveRecord::Base)
|
22
|
-
values =
|
22
|
+
values = e.attributes.transform_values do |v|
|
23
23
|
next JSON.pretty_generate(v) if v.is_a?(Enumerable) && v.size > 0
|
24
|
-
next
|
25
|
-
next '""' if v ==
|
24
|
+
next "NULL" if v.nil?
|
25
|
+
next '""' if v == ""
|
26
26
|
v.to_s
|
27
27
|
end
|
28
28
|
next values
|
@@ -34,17 +34,17 @@ module ActiverecordMysqlRepl
|
|
34
34
|
raise "#{arr} contains Hashes with different keys".red unless arr.map(&:keys).uniq.size == 1
|
35
35
|
|
36
36
|
orientation = case orientation
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
37
|
+
when :vertical, :v
|
38
|
+
:vertical
|
39
|
+
when :horizontal, :h
|
40
|
+
:horizontal
|
41
|
+
else
|
42
|
+
if arr.first.keys.size > 5
|
43
|
+
:vertical
|
44
|
+
else
|
45
|
+
:horizontal
|
46
|
+
end
|
47
|
+
end
|
48
48
|
|
49
49
|
t = Terminal::Table.new
|
50
50
|
|
@@ -54,7 +54,7 @@ module ActiverecordMysqlRepl
|
|
54
54
|
t.rows = arr.map(&:values)
|
55
55
|
|
56
56
|
when :vertical
|
57
|
-
t.headings = [
|
57
|
+
t.headings = ["Name", "Value"]
|
58
58
|
arr.each.with_index do |row, i|
|
59
59
|
row.each { |col, val| t.add_row [col, val] }
|
60
60
|
t.add_separator if i < arr.size - 1
|
@@ -64,25 +64,25 @@ module ActiverecordMysqlRepl
|
|
64
64
|
t.to_s
|
65
65
|
end
|
66
66
|
|
67
|
-
|
68
|
-
|
69
|
-
|
67
|
+
alias_method :tab, :tabulate
|
68
|
+
alias_method :table, :tabulate
|
69
|
+
alias_method :to_table, :tabulate
|
70
70
|
|
71
71
|
def csv(orientation = nil)
|
72
|
-
arr = if
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
72
|
+
arr = if is_a?(Array)
|
73
|
+
self
|
74
|
+
elsif is_a?(::ActiveRecord::Relation)
|
75
|
+
to_a
|
76
|
+
else
|
77
|
+
[self]
|
78
|
+
end
|
79
79
|
|
80
80
|
arr = arr.map do |e|
|
81
81
|
if e.is_a?(::ActiveRecord::Base)
|
82
|
-
values =
|
82
|
+
values = e.attributes.transform_values do |v|
|
83
83
|
next JSON.pretty_generate(v) if v.is_a?(Enumerable) && v.size > 0
|
84
|
-
next
|
85
|
-
next '""' if v ==
|
84
|
+
next "NULL" if v.nil?
|
85
|
+
next '""' if v == ""
|
86
86
|
v.to_s
|
87
87
|
end
|
88
88
|
next values
|
@@ -94,17 +94,17 @@ module ActiverecordMysqlRepl
|
|
94
94
|
raise "#{arr} contains Hashes with different keys".red unless arr.map(&:keys).uniq.size == 1
|
95
95
|
|
96
96
|
orientation = case orientation
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
97
|
+
when :vertical, :v
|
98
|
+
:vertical
|
99
|
+
when :horizontal, :h
|
100
|
+
:horizontal
|
101
|
+
else
|
102
|
+
if arr.first.keys.size > 5
|
103
|
+
:vertical
|
104
|
+
else
|
105
|
+
:horizontal
|
106
|
+
end
|
107
|
+
end
|
108
108
|
|
109
109
|
CSV.generate do |csv|
|
110
110
|
case orientation
|
@@ -121,11 +121,11 @@ module ActiverecordMysqlRepl
|
|
121
121
|
end
|
122
122
|
|
123
123
|
def copy
|
124
|
-
Clipboard.copy(
|
124
|
+
Clipboard.copy(to_s)
|
125
125
|
end
|
126
|
-
|
126
|
+
alias_method :cp, :copy
|
127
127
|
|
128
|
-
|
128
|
+
alias_method :j, :to_json
|
129
129
|
|
130
130
|
def jp
|
131
131
|
JSON.pretty_generate(JSON.parse(to_json))
|
@@ -135,4 +135,3 @@ module ActiverecordMysqlRepl
|
|
135
135
|
|
136
136
|
::Object.include(Extensions::Object)
|
137
137
|
end
|
138
|
-
|
@@ -13,11 +13,11 @@ module ActiverecordMysqlRepl
|
|
13
13
|
end
|
14
14
|
|
15
15
|
model.column_names.each do |column|
|
16
|
-
define_method("#{model.table_name.singularize}_by_#{column}") do
|
16
|
+
define_method(:"#{model.table_name.singularize}_by_#{column}") do
|
17
17
|
model.where(column => self)
|
18
18
|
end
|
19
19
|
|
20
|
-
define_method("#{model.table_name.singularize}_#{column}_like") do
|
20
|
+
define_method(:"#{model.table_name.singularize}_#{column}_like") do
|
21
21
|
model.where("#{column} like ?", "%#{self}%")
|
22
22
|
end
|
23
23
|
end
|
@@ -29,4 +29,3 @@ module ActiverecordMysqlRepl
|
|
29
29
|
Enumerable.include Tabler
|
30
30
|
end
|
31
31
|
end
|
32
|
-
|
@@ -1,10 +1,10 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require_relative
|
4
|
-
require_relative
|
5
|
-
require_relative
|
6
|
-
require_relative
|
7
|
-
require_relative
|
3
|
+
require_relative "extensions/object"
|
4
|
+
require_relative "extensions/global"
|
5
|
+
require_relative "extensions/active_record"
|
6
|
+
require_relative "extensions/hash"
|
7
|
+
require_relative "extensions/tabler"
|
8
8
|
|
9
9
|
module ActiveRecordMysqlRepl
|
10
10
|
module Extensions
|
@@ -15,4 +15,3 @@ module ActiveRecordMysqlRepl
|
|
15
15
|
end
|
16
16
|
end
|
17
17
|
end
|
18
|
-
|
@@ -1,14 +1,16 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
4
|
-
require
|
3
|
+
require "net/ssh"
|
4
|
+
require "net/ssh/gateway"
|
5
5
|
|
6
6
|
module ActiveRecordMysqlRepl
|
7
7
|
module SSHTunnel
|
8
8
|
EPHEMERAL_PORT = 0
|
9
9
|
|
10
10
|
def self.tunnel(db_config)
|
11
|
-
|
11
|
+
unless db_config.bastion
|
12
|
+
return yield(db_config.port) if block_given?
|
13
|
+
end
|
12
14
|
|
13
15
|
puts "Establishing ssh tunnel to #{db_config.remote_host}:#{db_config.port} via #{db_config.ssh_user}#{db_config.bastion}".gray
|
14
16
|
|