alterity 1.2.0 → 1.4.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 6283968b3d028f736da1517832ee5ebf8410aa4281aea4a2fa7af9e868a7ef89
4
- data.tar.gz: c4e6ae366bea0f1065aa303824c0f64f7dc684f7566e600ede7ece16c4e58b60
3
+ metadata.gz: 20a0079693908430f136c8f85839cdfa2a39872a4ec021a9014b5fd8bf27c493
4
+ data.tar.gz: 388fcc530f490f858e344eaf2a24e1287b275cae3b33739ced28b7a1a8a42d9f
5
5
  SHA512:
6
- metadata.gz: 1bf501f5c7f2ce204f995341c7ee2bf73a0c3d8fc16ed9b32ea710ff4b77251e464891df9866a6847b7740ae9472f1c639cae7b7ac31bb82381616b84d5ea66b
7
- data.tar.gz: 58fb3f6708f0b610d4129c960f1765e5073d74e0170f46456d549cf3f65ecf8e34da7b139efee3afbb5575d0f0c01d5630170590d51ffba2b6de9ef8d52e4a1c
6
+ metadata.gz: '095a935c8a09050ddfe41c0b149c167a9264d9f343260c06501717fe54fabd31cdb134634db009db13468efbe7f88ccff120889095e854edf2295f9523d15bc1'
7
+ data.tar.gz: 701b4b23a3478f4b8c3302371b41f5b70acbea0410e2dc5b5430ad88dd97f80926d211ea11f821cb43f4f33d6e66a14163e14fe7e94d85a3f9825d294b9b1fc1
data/lib/alterity.rb CHANGED
@@ -8,12 +8,14 @@ require "alterity/railtie"
8
8
  class Alterity
9
9
  class << self
10
10
  def process_sql_query(sql, &block)
11
+ return block.call if state.disabled
12
+
11
13
  case sql.tr("\n", " ").strip
12
14
  when /^alter\s+table\s+(?<table>.+?)\s+(?<updates>.+)/i
13
15
  table = $~[:table]
14
16
  updates = $~[:updates]
15
- if updates.split(",").all? { |s| s =~ /^\s*drop\s+foreign\s+key\s+\w+\s*$/i } ||
16
- updates.split(",").all? { |s| s =~ /^\s*add\s+constraint\s+`?\w+`?\s+foreign\s+key\s+\(`?\w+`?\)\s+references\s+`?\w+`?\s+\(`?\w+`?\)\s*$/i }
17
+ if updates.split(",").all? { |s| s =~ /^\s*drop\s+foreign\s+key/i } ||
18
+ updates.split(",").all? { |s| s =~ /^\s*add\s+constraint/i }
17
19
  block.call
18
20
  elsif updates =~ /drop\s+foreign\s+key/i || updates =~ /add\s+constraint/i
19
21
  # ADD CONSTRAINT / DROP FOREIGN KEY have to go to the original table,
@@ -35,6 +37,7 @@ class Alterity
35
37
 
36
38
  # hooks
37
39
  def before_running_migrations
40
+ require "open3"
38
41
  state.migrating = true
39
42
  set_database_config
40
43
  prepare_replicas_dsns_table
@@ -51,7 +54,21 @@ class Alterity
51
54
  alter_argument = %("#{updates.gsub('"', '\\"').gsub('`', '\\\`')}")
52
55
  prepared_command = config.command.call(altered_table, alter_argument).to_s.gsub(/\n/, "\\\n")
53
56
  puts "[Alterity] Will execute: #{prepared_command}"
54
- system(prepared_command) || raise("[Alterity] Command failed")
57
+ config.before_command&.call(prepared_command)
58
+
59
+ result_str = +""
60
+ exit_status = nil
61
+ Open3.popen2e(prepared_command) do |_stdin, stdout_and_stderr, wait_thr|
62
+ stdout_and_stderr.each do |line|
63
+ puts line
64
+ result_str << line
65
+ config.on_command_output&.call(line)
66
+ end
67
+ exit_status = wait_thr.value
68
+ config.after_command&.call(wait_thr.value.to_i)
69
+ end
70
+
71
+ raise("[Alterity] Command failed. Full output: #{result_str}") unless exit_status.success?
55
72
  end
56
73
 
57
74
  def set_database_config
@@ -4,7 +4,10 @@ class Alterity
4
4
  Configuration = Struct.new(
5
5
  :command,
6
6
  :host, :port, :database, :username, :password,
7
- :replicas_dsns_database, :replicas_dsns_table, :replicas_dsns
7
+ :replicas_dsns_database, :replicas_dsns_table, :replicas_dsns,
8
+ :before_command,
9
+ :on_command_output,
10
+ :after_command
8
11
  )
9
12
  CurrentState = Struct.new(:migrating, :disabled)
10
13
  cattr_accessor :state
@@ -36,10 +39,6 @@ class Alterity
36
39
  yield config
37
40
  end
38
41
 
39
- def command=(new_command)
40
- config.command = new_command
41
- end
42
-
43
42
  def disable
44
43
  state.disabled = true
45
44
  yield
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  class Alterity
4
- VERSION = "1.2.0"
4
+ VERSION = "1.4.1"
5
5
  end
@@ -10,7 +10,7 @@ RSpec.describe Alterity do
10
10
  ["CREATE UNIQUE INDEX `idx_users_on_col` ON `users` (col)", "`users`", "ADD UNIQUE INDEX `idx_users_on_col` (col)"],
11
11
  ["DROP INDEX `idx_users_on_col` ON `users`", "`users`", "DROP INDEX `idx_users_on_col`"],
12
12
  ["alter table users drop col", "users", "drop col"],
13
- [" ALTER TABLE\n users\n DROP col", "users", "DROP col"]
13
+ [" ALTER TABLE\n users\n DROP col", "users", "DROP col"],
14
14
  ].each do |(query, expected_table, expected_updates)|
15
15
  puts query.inspect
16
16
  expected_block = proc {}
@@ -32,7 +32,8 @@ RSpec.describe Alterity do
32
32
  "SHOW FULL FIELDS FROM `users`",
33
33
  "ALTER TABLE `installment_events` DROP FOREIGN KEY _fk_rails_0123456789",
34
34
  "ALTER TABLE `installment_events` DROP FOREIGN KEY _fk_rails_0123456789, DROP FOREIGN KEY _fk_rails_9876543210",
35
- "ALTER TABLE `installment_events` ADD CONSTRAINT `fk_rails_0cb5590091` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`)"
35
+ "ALTER TABLE `installment_events` ADD CONSTRAINT `fk_rails_0cb5590091` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`)",
36
+ "ALTER TABLE `installment_events` ADD CONSTRAINT `fk_rails_0cb5590091` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE CASCADE",
36
37
  ].each do |query|
37
38
  expected_block = proc {}
38
39
  expect(expected_block).to receive(:call)
@@ -8,6 +8,7 @@ Alterity.configure do |config|
8
8
  system("echo '#{string}' > /tmp/custom_command_result.txt")
9
9
  system("echo '#{altered_table}' >> /tmp/custom_command_result.txt")
10
10
  system("echo '#{alter_argument}' >> /tmp/custom_command_result.txt")
11
+ "ls /"
11
12
  }
12
13
 
13
14
  config.replicas(
@@ -23,4 +24,16 @@ Alterity.configure do |config|
23
24
  "h=#{ENV['MYSQL_HOST']}"
24
25
  ]
25
26
  )
27
+
28
+ config.before_command = lambda do |command|
29
+ File.new("/tmp/before_command.txt", "w").syswrite(command)
30
+ end
31
+
32
+ config.on_command_output = lambda do |output|
33
+ File.new("/tmp/on_command_output.txt", "w+").syswrite(output)
34
+ end
35
+
36
+ config.after_command = lambda do |exit_status|
37
+ File.new("/tmp/after_command.txt", "w").syswrite(exit_status)
38
+ end
26
39
  end
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ class AddYetAnotherColorToShirts < ActiveRecord::Migration[6.1]
4
+ def up
5
+ Alterity.disable do
6
+ add_column :shirts, :color3, :string
7
+ end
8
+ end
9
+ end
@@ -69,3 +69,9 @@ ruby ../spec/bin/test_custom_config_result.rb
69
69
 
70
70
  # Also testing what's in replicas_dsns, also checking that master was detected and removed.
71
71
  bundle e rails runner 'res=ActiveRecord::Base.connection.execute("select dsn from percona.replicas_dsns").to_a.flatten;p(res); res == ["h=host1,P=3306", "h=host2,P=3306"] || exit(1)'
72
+
73
+ rm /tmp/custom_command_result.txt
74
+ cp ../spec/bin/disabled_migration.rb db/migrate/20210728182628_add_yet_another_color_to_shirts.rb
75
+ bundle e rails db:migrate --trace
76
+ bundle e rails runner 'Shirt.columns.map(&:name).include?("color3") || exit(1)'
77
+ ruby ../spec/bin/test_disabled_state.rb
@@ -15,6 +15,25 @@ puts result
15
15
  p result.chars.map(&:hex)
16
16
 
17
17
  if result != expected_result
18
- puts "=> mismatch"
18
+ puts "=> mismatched result"
19
+ exit(1)
20
+ end
21
+
22
+
23
+ result = File.read("/tmp/before_command.txt")
24
+ if result != "ls /"
25
+ puts "=> mismatched before_command"
26
+ exit(1)
27
+ end
28
+
29
+ result = File.read("/tmp/on_command_output.txt")
30
+ if !result.include?("var")
31
+ puts "=> mismatched on_command_output"
32
+ exit(1)
33
+ end
34
+
35
+ result = File.read("/tmp/after_command.txt")
36
+ if result.strip != "0"
37
+ puts "=> mismatched after_command"
19
38
  exit(1)
20
39
  end
@@ -0,0 +1,6 @@
1
+ # frozen_string_literal: true
2
+
3
+ if File.exist?("/tmp/custom_command_result.txt")
4
+ puts "=> disabled state does not work"
5
+ exit(1)
6
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: alterity
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2.0
4
+ version: 1.4.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Chris Maximin
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-05-05 00:00:00.000000000 Z
11
+ date: 2021-07-28 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: mysql2
@@ -53,8 +53,10 @@ files:
53
53
  - lib/alterity/version.rb
54
54
  - spec/alterity_spec.rb
55
55
  - spec/bin/custom_config.rb
56
+ - spec/bin/disabled_migration.rb
56
57
  - spec/bin/rails_app_migration_test.sh
57
58
  - spec/bin/test_custom_config_result.rb
59
+ - spec/bin/test_disabled_state.rb
58
60
  - spec/spec_helper.rb
59
61
  homepage: https://github.com/gumroad/alterity
60
62
  licenses:
@@ -85,6 +87,8 @@ summary: Execute your ActiveRecord migrations with Percona's pt-online-schema-ch
85
87
  test_files:
86
88
  - spec/alterity_spec.rb
87
89
  - spec/bin/custom_config.rb
90
+ - spec/bin/disabled_migration.rb
88
91
  - spec/bin/rails_app_migration_test.sh
89
92
  - spec/bin/test_custom_config_result.rb
93
+ - spec/bin/test_disabled_state.rb
90
94
  - spec/spec_helper.rb