From 0bf761497477b021c46a584c514aa8da39c24ebf Mon Sep 17 00:00:00 2001 From: Andrei Kaleshka Date: Wed, 1 May 2024 17:36:09 +0200 Subject: [PATCH 1/7] multidb support --- Gemfile.lock | 3 + actual_db_schema.gemspec | 1 + lib/actual_db_schema/commands/base.rb | 4 - .../patches/migration_context.rb | 2 +- lib/actual_db_schema/store.rb | 2 +- test/dummy_app/db/migrate_secondary/.keep | 0 test/dummy_app/db/secondary_schema.rb | 14 +++ test/rake_task_secondary_test.rb | 88 +++++++++++++++++++ test/test_helper.rb | 29 ++++-- 9 files changed, 128 insertions(+), 15 deletions(-) create mode 100644 test/dummy_app/db/migrate_secondary/.keep create mode 100644 test/dummy_app/db/secondary_schema.rb create mode 100644 test/rake_task_secondary_test.rb diff --git a/Gemfile.lock b/Gemfile.lock index 9c4e186..8b388da 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -122,6 +122,8 @@ GEM marcel (1.0.2) mini_mime (1.1.5) minitest (5.20.0) + minitest-around (0.5.0) + minitest (~> 5.0) mutex_m (0.1.2) net-imap (0.4.4) date @@ -230,6 +232,7 @@ DEPENDENCIES appraisal debug minitest (~> 5.0) + minitest-around rails rake rubocop (~> 1.21) diff --git a/actual_db_schema.gemspec b/actual_db_schema.gemspec index 4a49412..957d9cd 100644 --- a/actual_db_schema.gemspec +++ b/actual_db_schema.gemspec @@ -41,6 +41,7 @@ Gem::Specification.new do |spec| spec.add_development_dependency "appraisal" spec.add_development_dependency "debug" + spec.add_development_dependency "minitest-around" spec.add_development_dependency "rails" spec.add_development_dependency "sqlite3" diff --git a/lib/actual_db_schema/commands/base.rb b/lib/actual_db_schema/commands/base.rb index 016d06e..bd43026 100644 --- a/lib/actual_db_schema/commands/base.rb +++ b/lib/actual_db_schema/commands/base.rb @@ -9,10 +9,6 @@ def call raise "ActualDbSchema is disabled. Set ActualDbSchema.config[:enabled] = true to enable it." end - if ActiveRecord::Migration.current_version >= 6 - ActiveRecord::Tasks::DatabaseTasks.raise_for_multi_db(command: "db:rollback_branches") - end - call_impl end diff --git a/lib/actual_db_schema/patches/migration_context.rb b/lib/actual_db_schema/patches/migration_context.rb index bdd2254..d5e0478 100644 --- a/lib/actual_db_schema/patches/migration_context.rb +++ b/lib/actual_db_schema/patches/migration_context.rb @@ -32,7 +32,7 @@ def down_migrator_for(migration) def migration_files paths = Array(migrations_paths) current_branch_files = Dir[*paths.flat_map { |path| "#{path}/**/[0-9]*_*.rb" }] - other_branches_files = Dir["#{ActualDbSchema.migrated_folder}/**/[0-9]*_*.rb"] + other_branches_files = Dir[*ActualDbSchema.migrated_folders.flat_map { |path| "#{path}/**/[0-9]*_*.rb" }] current_branch_file_names = current_branch_files.map { |f| ActualDbSchema.migration_filename(f) } other_branches_files.reject { |f| ActualDbSchema.migration_filename(f).in?(current_branch_file_names) } diff --git a/lib/actual_db_schema/store.rb b/lib/actual_db_schema/store.rb index c32602d..d412ceb 100644 --- a/lib/actual_db_schema/store.rb +++ b/lib/actual_db_schema/store.rb @@ -34,7 +34,7 @@ def record_metadata(filename) end def folder - ActualDbSchema.migrated_folder + ActualDbSchema.migrated_folders.first end def store_file diff --git a/test/dummy_app/db/migrate_secondary/.keep b/test/dummy_app/db/migrate_secondary/.keep new file mode 100644 index 0000000..e69de29 diff --git a/test/dummy_app/db/secondary_schema.rb b/test/dummy_app/db/secondary_schema.rb new file mode 100644 index 0000000..f23614c --- /dev/null +++ b/test/dummy_app/db/secondary_schema.rb @@ -0,0 +1,14 @@ +# This file is auto-generated from the current state of the database. Instead +# of editing this file, please use the migrations feature of Active Record to +# incrementally modify your database, and then regenerate this schema definition. +# +# This file is the source Rails uses to define your schema when running `bin/rails +# db:schema:load`. When creating a new database, `bin/rails db:schema:load` tends to +# be faster and is potentially less error prone than running all of your +# migrations from scratch. Old migrations may fail to apply correctly if those +# migrations use external dependencies or application code. +# +# It's strongly recommended that you check this file into your version control system. + +ActiveRecord::Schema[7.1].define(version: 2013_09_06_111513) do +end diff --git a/test/rake_task_secondary_test.rb b/test/rake_task_secondary_test.rb new file mode 100644 index 0000000..eed3210 --- /dev/null +++ b/test/rake_task_secondary_test.rb @@ -0,0 +1,88 @@ +# frozen_string_literal: true + +require "test_helper" + +describe "multiple databases support" do + let(:utils) do + TestUtils.new(migrations_path: "db/migrate_secondary", migrated_path: "tmp/migrated_migrate_secondary") + end + + around do |block| + original_db_config = ActiveRecord::Base.connection_db_config + ActiveRecord::Base.establish_connection(TestingState.db_config["secondary"]) + utils.cleanup + block.call + ensure + ActiveRecord::Base.establish_connection(original_db_config) + end + + describe "db:rollback_branches" do + it "creates the tmp/migrated_migrate_secondary folder" do + refute File.exist?(utils.app_file("tmp/migrated_migrate_secondary")) + utils.run_migrations + assert File.exist?(utils.app_file("tmp/migrated_migrate_secondary")) + end + + it "migrates the migrations" do + assert_empty utils.applied_migrations + utils.run_migrations + assert_equal %w[20130906111511 20130906111512], utils.applied_migrations + end + + it "keeps migrated migrations in tmp/migrated folder" do + utils.run_migrations + assert_equal %w[20130906111511_first.rb 20130906111512_second.rb], utils.migrated_files + end + + it "rolls back the migrations in the reversed order" do + utils.prepare_phantom_migrations + assert_empty TestingState.down + utils.run_migrations + assert_equal %i[second first], TestingState.down + end + + describe "with irreversible migration" do + before do + utils.define_migration_file("20130906111513_irreversible.rb", <<~RUBY) + class Irreversible < ActiveRecord::Migration[6.0] + def up + TestingState.up << :irreversible + end + + def down + raise ActiveRecord::IrreversibleMigration + end + end + RUBY + end + + it "keeps track of the irreversible migrations" do + utils.prepare_phantom_migrations + assert_equal %i[first second irreversible], TestingState.up + assert_empty ActualDbSchema.failed + utils.run_migrations + assert_equal(%w[20130906111513_irreversible.rb], ActualDbSchema.failed.map { |m| File.basename(m.filename) }) + end + end + end + + describe "db:phantom_migrations" do + it "shows the list of phantom migrations" do + ActualDbSchema::Git.stub(:current_branch, "fix-bug") do + utils.prepare_phantom_migrations + Rake::Task["db:phantom_migrations"].invoke + Rake::Task["db:phantom_migrations"].reenable + assert_match(/ Status Migration ID Branch Migration File/, TestingState.output) + assert_match(/---------------------------------------------------/, TestingState.output) + assert_match( + %r{ up 20130906111511 fix-bug tmp/migrated_migrate_secondary/20130906111511_first.rb}, + TestingState.output + ) + assert_match( + %r{ up 20130906111512 fix-bug tmp/migrated_migrate_secondary/20130906111512_second.rb}, + TestingState.output + ) + end + end + end +end diff --git a/test/test_helper.rb b/test/test_helper.rb index 1db5699..32e8b73 100644 --- a/test/test_helper.rb +++ b/test/test_helper.rb @@ -4,6 +4,7 @@ require "rails/all" require "actual_db_schema" require "minitest/autorun" +require "minitest/around/spec" require "debug" require "support/test_utils" @@ -18,20 +19,25 @@ def initialize Rails.application = FakeApplication.new -db_config = { - adapter: "sqlite3", - database: "tmp/test.sqlite3" -} -ActiveRecord::Tasks::DatabaseTasks.database_configuration = { test: db_config } -ActiveRecord::Base.establish_connection(**db_config) - -ActualDbSchema.config[:enabled] = true - class TestingState class << self attr_accessor :up, :down, :output end + def self.db_config + { + "primary" => { + adapter: "sqlite3", + database: "tmp/primary.sqlite3" + }, + "secondary" => { + adapter: "sqlite3", + database: "tmp/secondary.sqlite3", + migrations_paths: Rails.root.join("db", "migrate_secondary").to_s + } + } + end + def self.reset self.up = [] self.down = [] @@ -41,6 +47,11 @@ def self.reset reset end +ActiveRecord::Tasks::DatabaseTasks.database_configuration = { "test" => TestingState.db_config } +ActiveRecord::Base.establish_connection(TestingState.db_config["primary"]) + +ActualDbSchema.config[:enabled] = true + module Kernel alias original_puts puts From 52e5b0d8f812d7aa27b150e51866fdc7d50116d6 Mon Sep 17 00:00:00 2001 From: Andrei Kaleshka Date: Wed, 1 May 2024 17:39:06 +0200 Subject: [PATCH 2/7] revert change --- lib/actual_db_schema/patches/migration_context.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/actual_db_schema/patches/migration_context.rb b/lib/actual_db_schema/patches/migration_context.rb index d5e0478..bdd2254 100644 --- a/lib/actual_db_schema/patches/migration_context.rb +++ b/lib/actual_db_schema/patches/migration_context.rb @@ -32,7 +32,7 @@ def down_migrator_for(migration) def migration_files paths = Array(migrations_paths) current_branch_files = Dir[*paths.flat_map { |path| "#{path}/**/[0-9]*_*.rb" }] - other_branches_files = Dir[*ActualDbSchema.migrated_folders.flat_map { |path| "#{path}/**/[0-9]*_*.rb" }] + other_branches_files = Dir["#{ActualDbSchema.migrated_folder}/**/[0-9]*_*.rb"] current_branch_file_names = current_branch_files.map { |f| ActualDbSchema.migration_filename(f) } other_branches_files.reject { |f| ActualDbSchema.migration_filename(f).in?(current_branch_file_names) } From f86c1d52d9075fae2b9d7764e328622f2f10ce73 Mon Sep 17 00:00:00 2001 From: Andrei Kaleshka Date: Wed, 1 May 2024 17:41:23 +0200 Subject: [PATCH 3/7] revert --- lib/actual_db_schema/store.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/actual_db_schema/store.rb b/lib/actual_db_schema/store.rb index d412ceb..c32602d 100644 --- a/lib/actual_db_schema/store.rb +++ b/lib/actual_db_schema/store.rb @@ -34,7 +34,7 @@ def record_metadata(filename) end def folder - ActualDbSchema.migrated_folders.first + ActualDbSchema.migrated_folder end def store_file From 65d44c24d84f9b41389ecf25ca1040dd327c0878 Mon Sep 17 00:00:00 2001 From: Andrei Kaleshka Date: Wed, 1 May 2024 17:41:52 +0200 Subject: [PATCH 4/7] revert --- test/test_helper.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/test_helper.rb b/test/test_helper.rb index 32e8b73..bb1e6a2 100644 --- a/test/test_helper.rb +++ b/test/test_helper.rb @@ -47,7 +47,7 @@ def self.reset reset end -ActiveRecord::Tasks::DatabaseTasks.database_configuration = { "test" => TestingState.db_config } +ActiveRecord::Tasks::DatabaseTasks.database_configuration = { test: TestingState.db_config } ActiveRecord::Base.establish_connection(TestingState.db_config["primary"]) ActualDbSchema.config[:enabled] = true From a1cfbb130b157bd25c8e264f5b236ca7d97a038a Mon Sep 17 00:00:00 2001 From: Andrei Kaleshka Date: Wed, 1 May 2024 17:42:24 +0200 Subject: [PATCH 5/7] revert --- test/test_helper.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/test_helper.rb b/test/test_helper.rb index bb1e6a2..5aff263 100644 --- a/test/test_helper.rb +++ b/test/test_helper.rb @@ -48,7 +48,7 @@ def self.reset end ActiveRecord::Tasks::DatabaseTasks.database_configuration = { test: TestingState.db_config } -ActiveRecord::Base.establish_connection(TestingState.db_config["primary"]) +ActiveRecord::Base.establish_connection(**TestingState.db_config["primary"]) ActualDbSchema.config[:enabled] = true From 81f91c623b12ee1bdef40212708150543b92e7da Mon Sep 17 00:00:00 2001 From: Andrei Kaleshka Date: Wed, 1 May 2024 17:54:44 +0200 Subject: [PATCH 6/7] fix failed tests --- test/rake_task_secondary_test.rb | 2 +- test/test_helper.rb | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/test/rake_task_secondary_test.rb b/test/rake_task_secondary_test.rb index eed3210..ad05623 100644 --- a/test/rake_task_secondary_test.rb +++ b/test/rake_task_secondary_test.rb @@ -9,7 +9,7 @@ around do |block| original_db_config = ActiveRecord::Base.connection_db_config - ActiveRecord::Base.establish_connection(TestingState.db_config["secondary"]) + ActiveRecord::Base.establish_connection(TestingState.db_config.fetch(:secondary)) utils.cleanup block.call ensure diff --git a/test/test_helper.rb b/test/test_helper.rb index 5aff263..eb88f8f 100644 --- a/test/test_helper.rb +++ b/test/test_helper.rb @@ -26,11 +26,11 @@ class << self def self.db_config { - "primary" => { + primary: { adapter: "sqlite3", database: "tmp/primary.sqlite3" }, - "secondary" => { + secondary: { adapter: "sqlite3", database: "tmp/secondary.sqlite3", migrations_paths: Rails.root.join("db", "migrate_secondary").to_s @@ -47,8 +47,8 @@ def self.reset reset end -ActiveRecord::Tasks::DatabaseTasks.database_configuration = { test: TestingState.db_config } -ActiveRecord::Base.establish_connection(**TestingState.db_config["primary"]) +ActiveRecord::Tasks::DatabaseTasks.database_configuration = { test: TestingState.db_config.fetch(:primary) } +ActiveRecord::Base.establish_connection(**TestingState.db_config.fetch(:primary)) ActualDbSchema.config[:enabled] = true From d08bd31f6f0ac2f2bffb8e87719581912774d2d4 Mon Sep 17 00:00:00 2001 From: Andrei Kaleshka Date: Wed, 1 May 2024 17:58:49 +0200 Subject: [PATCH 7/7] fix --- .../db/migrate_secondary/20130906111511_first.rb | 9 +++++++++ .../db/migrate_secondary/20130906111512_second.rb | 9 +++++++++ test/rake_task_secondary_test.rb | 5 +++++ 3 files changed, 23 insertions(+) create mode 100644 test/dummy_app/db/migrate_secondary/20130906111511_first.rb create mode 100644 test/dummy_app/db/migrate_secondary/20130906111512_second.rb diff --git a/test/dummy_app/db/migrate_secondary/20130906111511_first.rb b/test/dummy_app/db/migrate_secondary/20130906111511_first.rb new file mode 100644 index 0000000..469540c --- /dev/null +++ b/test/dummy_app/db/migrate_secondary/20130906111511_first.rb @@ -0,0 +1,9 @@ +class First < ActiveRecord::Migration[6.0] + def up + TestingState.up << :first + end + + def down + TestingState.down << :first + end +end diff --git a/test/dummy_app/db/migrate_secondary/20130906111512_second.rb b/test/dummy_app/db/migrate_secondary/20130906111512_second.rb new file mode 100644 index 0000000..b3e1665 --- /dev/null +++ b/test/dummy_app/db/migrate_secondary/20130906111512_second.rb @@ -0,0 +1,9 @@ +class Second < ActiveRecord::Migration[6.0] + def up + TestingState.up << :second + end + + def down + TestingState.down << :second + end +end diff --git a/test/rake_task_secondary_test.rb b/test/rake_task_secondary_test.rb index ad05623..44fe761 100644 --- a/test/rake_task_secondary_test.rb +++ b/test/rake_task_secondary_test.rb @@ -9,11 +9,16 @@ around do |block| original_db_config = ActiveRecord::Base.connection_db_config + original = ActiveRecord::Tasks::DatabaseTasks.database_configuration + ActiveRecord::Tasks::DatabaseTasks.database_configuration = { + test: TestingState.db_config.fetch(:secondary) + } ActiveRecord::Base.establish_connection(TestingState.db_config.fetch(:secondary)) utils.cleanup block.call ensure ActiveRecord::Base.establish_connection(original_db_config) + ActiveRecord::Tasks::DatabaseTasks.database_configuration = original end describe "db:rollback_branches" do