diff --git a/CHANGELOG.md b/CHANGELOG.md index 2698850c..63521021 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,10 @@ and this project adheres to [Break Versioning](https://www.taoensso.com/break-ve ### Added +* Allow an app or slice to specify a custom database table name for the +migrations. If no custom table name is specified, the table will be +named `schema_migrations` as before. + ### Changed ### Deprecated diff --git a/lib/hanami/cli/commands/app/db/utils/database.rb b/lib/hanami/cli/commands/app/db/utils/database.rb index 32b80299..250c3e3f 100644 --- a/lib/hanami/cli/commands/app/db/utils/database.rb +++ b/lib/hanami/cli/commands/app/db/utils/database.rb @@ -118,7 +118,7 @@ def exec_load_command def run_migrations(**options) require "rom/sql" ROM::SQL.with_gateway(gateway) do - migrator.run(options) + migrator.run(options.merge(migrator_options)) end end @@ -127,7 +127,7 @@ def migrator slice.prepare :db require "rom/sql" - ROM::SQL::Migration::Migrator.new(connection, path: migrations_path) + ROM::SQL::Migration::Migrator.new(connection, path: migrations_path, **migrator_options) end end @@ -140,7 +140,7 @@ def sequel_migrator require "rom/sql" ROM::SQL.with_gateway(gateway) do - Sequel::TimestampMigrator.new(migrator.connection, migrations_path, {}) + Sequel::TimestampMigrator.new(migrator.connection, migrations_path, migrator_options) end end end @@ -197,6 +197,18 @@ def schema_migrations_sql_dump def post_process_dump(sql) sql end + + def migrator_options + {table: custom_migrations_table}.compact + end + + def custom_migrations_table + slice.config.db.migrations_table + rescue NoMethodError + # Backwards-compatibility, so that we don't cause an error in + # versions of the hanami gem that don't yet have the migrations_table setting + nil + end end end end diff --git a/spec/unit/hanami/cli/commands/app/db/migrate_spec.rb b/spec/unit/hanami/cli/commands/app/db/migrate_spec.rb index 793d357c..2f94fc68 100644 --- a/spec/unit/hanami/cli/commands/app/db/migrate_spec.rb +++ b/spec/unit/hanami/cli/commands/app/db/migrate_spec.rb @@ -600,4 +600,59 @@ def before_prepare expect(test_env_executor).not_to have_received(:call) end end + describe "migrations table" do + def before_prepare + write "config/db/migrate/20240602201330_create_posts.rb", <<~RUBY + ROM::SQL.migration do + change do + create_table :posts do + primary_key :id + column :title, :text, null: false + end + end + end + RUBY + + write "slices/main/config/db/migrate/20240602201330_create_users.rb", <<~RUBY + ROM::SQL.migration do + change do + create_table :comments do + primary_key :id + column :body, :text, null: false + end + end + end + RUBY + end + before do + ENV["DATABASE_URL"] = "sqlite://db/app.sqlite3" + ENV["MAIN__DATABASE_URL"] = "sqlite://db/main.sqlite3" + db_create + end + + it "defaults to schema_migrations" do + command.call + expect(Hanami.app["db.gateway"].connection[:schema_migrations].to_a).to eq [{filename: "20240602201330_create_posts.rb"}] + expect(Main::Slice["db.gateway"].connection[:schema_migrations].to_a).to eq [{filename: "20240602201330_create_users.rb"}] + end + + context "when a different table is configured" do + before do + MockDbConfig = Struct.new(:migrations_table, :import_from_parent, :log_level) + {Hanami.app => :amazing_table, Main::Slice => :lovely_table}.each do |slice, table_name| + mockable_config = slice.config.dup + allow(mockable_config).to receive(:db).and_return(MockDbConfig.new(table_name, false)) + allow(slice).to receive(:config).and_return(mockable_config) + end + end + it "uses the configured table" do + command.call + + expect(Hanami.app["db.gateway"].connection[:amazing_table].to_a).to eq [{filename: "20240602201330_create_posts.rb"}] + expect(Main::Slice["db.gateway"].connection[:lovely_table].to_a).to eq [{filename: "20240602201330_create_users.rb"}] + expect(Hanami.app["db.gateway"].connection.tables).not_to include :schema_migrations + expect(Main::Slice["db.gateway"].connection.tables).not_to include :schema_migrations + end + end + end end