Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix db commands acting on same databases multiple times #237

Merged
merged 1 commit into from
Sep 24, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 16 additions & 11 deletions lib/hanami/cli/commands/app/db/command.rb
Original file line number Diff line number Diff line change
Expand Up @@ -80,26 +80,31 @@ def database_for_slice(slice, gateway: nil)
def all_databases # rubocop:disable Metrics/AbcSize, Metrics/PerceivedComplexity
slices = [app] + app.slices.with_nested

slices_by_database_url = slices.each_with_object({}) { |slice, hsh|
slice_gateways_by_database_url = slices.each_with_object({}) { |slice, hsh|
db_provider_source = slice.container.providers[:db]&.source
next unless db_provider_source

db_provider_source.database_urls.values.each do |url|
db_provider_source.database_urls.each do |gateway, url|
hsh[url] ||= []
hsh[url] << slice
hsh[url] << {slice: slice, gateway: gateway}
end
}

slices_by_database_url.each_with_object([]) { |(_url, slices_for_url), arr|
slices_with_config = slices_for_url.select { _1.root.join("config", "db").directory? }
slice_gateways_by_database_url.each_with_object([]) { |(url, slice_gateways), arr|
slice_gateways_with_config = slice_gateways.select {
_1[:slice].root.join("config", "db").directory?
}

databases = build_databases(slices_with_config.first || slices_for_url.first).values
db_slice_gateway = slice_gateways_with_config.first || slice_gateways.first
database = Utils::Database.database_class(url).new(
slice: db_slice_gateway.fetch(:slice),
gateway_name: db_slice_gateway.fetch(:gateway),
system_call: system_call
)

databases.each do |database|
warn_on_misconfigured_database database, slices_with_config
end
warn_on_misconfigured_database database, slice_gateways.map { _1.fetch(:slice) }

arr.concat databases
arr << database
}
end

Expand All @@ -124,7 +129,7 @@ def warn_on_misconfigured_database(database, slices) # rubocop:disable Metrics/A
Migrating database using #{database.slice.slice_name.to_s.inspect} slice only.

STR
elsif slices.length < 1
elsif !database.db_config_dir?
relative_path = database.slice.root
.relative_path_from(database.slice.app.root)
.join("config", "db").to_s
Expand Down
26 changes: 16 additions & 10 deletions lib/hanami/cli/commands/app/db/utils/database.rb
Original file line number Diff line number Diff line change
Expand Up @@ -32,15 +32,17 @@ class Database
}
).freeze

def self.database_class(database_url)
database_scheme = URI(database_url).scheme
DATABASE_CLASS_RESOLVER[database_scheme].call
end

def self.from_slice(slice:, system_call:)
provider = slice.container.providers[:db]
raise "No :db provider for #{slice}" unless provider

provider.source.database_urls.map { |(gateway_name, database_url)|
database_scheme = URI(database_url).scheme
database_class = DATABASE_CLASS_RESOLVER[database_scheme].call

database = database_class.new(
database = database_class(database_url).new(
slice: slice,
gateway_name: gateway_name,
system_call: system_call
Expand Down Expand Up @@ -135,16 +137,20 @@ def applied_migrations
sequel_migrator.applied_migrations
end

def migrations_path
path = slice.root.join("config", "db")
def db_config_path
slice.root.join("config", "db")
end

def db_config_dir?
db_config_path.directory?
end

def migrations_path
if gateway_name == :default
path = path.join("migrate")
db_config_path.join("migrate")
else
path = path.join("#{gateway_name}_migrate")
db_config_path.join("#{gateway_name}_migrate")
end

path
end

def migrations_dir?
Expand Down
32 changes: 32 additions & 0 deletions spec/unit/hanami/cli/commands/app/db/drop_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,38 @@ def before_prepare
expect(command).to have_received(:exit).with(1).once
end

context "app and slice with gateways" do
def before_prepare
write "config/db/.keep", ""
write "slices/main/config/db/.keep", ""

ENV["DATABASE_URL__EXTRA"] = "sqlite://db/app_extra.sqlite3"
ENV["MAIN__DATABASE_URL__EXTRA"] = "sqlite://db/main_extra.sqlite3"
end

before do
command.run_command(Hanami::CLI::Commands::App::DB::Create)
out.truncate(0)
end

it "drops the databases for all gateways" do
expect { command.call }
.to change { File.exist?(@dir.join("db", "app.sqlite3")) }.to(false)
.and change { File.exist?(@dir.join("db", "app_extra.sqlite3")) }.to(false)
.and change { File.exist?(@dir.join("db", "main.sqlite3")) }.to(false)
.and change { File.exist?(@dir.join("db", "main_extra.sqlite3")) }.to(false)

expect(output.strip).to eq(<<~TEXT.strip)
=> database db/app.sqlite3 dropped
=> database db/app_extra.sqlite3 dropped
=> database db/main.sqlite3 dropped
=> database db/main_extra.sqlite3 dropped
TEXT

expect(command).not_to have_received(:exit)
end
end

context "app with gateways" do
def before_prepare
write "config/db/.keep", ""
Expand Down