From 5f8831ee843117ac87272be0bf5b1049b077b6b9 Mon Sep 17 00:00:00 2001 From: Michal Gibowski Date: Wed, 3 Apr 2024 20:31:40 +0100 Subject: [PATCH] WIP --- lib/ecto/adapters/postgres/connection.ex | 4 +++- lib/ecto/adapters/sql.ex | 3 +++ lib/ecto/migration.ex | 15 +++++++++++++-- lib/ecto/migration/runner.ex | 18 ++++++++++++++---- test/ecto/migration_test.exs | 19 +++++++++++++++++++ 5 files changed, 52 insertions(+), 7 deletions(-) diff --git a/lib/ecto/adapters/postgres/connection.ex b/lib/ecto/adapters/postgres/connection.ex index 9b59e7f5..5e1660fd 100644 --- a/lib/ecto/adapters/postgres/connection.ex +++ b/lib/ecto/adapters/postgres/connection.ex @@ -1239,7 +1239,9 @@ if Code.ensure_loaded?(Postgrex) do table_name = quote_name(table.prefix, table.name) query = [ - "CREATE TABLE ", + "CREATE ", + if_do(table.unlogged, "UNLOGGED "), + "TABLE ", if_do(command == :create_if_not_exists, "IF NOT EXISTS "), table_name, ?\s, diff --git a/lib/ecto/adapters/sql.ex b/lib/ecto/adapters/sql.ex index ba98643e..3c9c8557 100644 --- a/lib/ecto/adapters/sql.ex +++ b/lib/ecto/adapters/sql.ex @@ -871,6 +871,9 @@ defmodule Ecto.Adapters.SQL do IO.warn(message) end + # TODO: warn if :create_unlogged_tables and not in tests + # TODO: warn if :create_unlogged_tables and adapter other than Postgrex + config |> Keyword.delete(:name) |> Keyword.update(:pool, DBConnection.ConnectionPool, &normalize_pool/1) diff --git a/lib/ecto/migration.ex b/lib/ecto/migration.ex index 7b70dcde..44255320 100644 --- a/lib/ecto/migration.ex +++ b/lib/ecto/migration.ex @@ -416,7 +416,13 @@ defmodule Ecto.Migration do To define a table in a migration, see `Ecto.Migration.table/2`. """ - defstruct name: nil, prefix: nil, comment: nil, primary_key: true, engine: nil, options: nil + defstruct name: nil, + prefix: nil, + comment: nil, + primary_key: true, + engine: nil, + options: nil, + unlogged: false @type t :: %__MODULE__{ name: String.t(), @@ -424,7 +430,8 @@ defmodule Ecto.Migration do comment: String.t() | nil, primary_key: boolean | keyword(), engine: atom, - options: String.t() + options: String.t(), + unlogged: boolean } end @@ -560,6 +567,8 @@ defmodule Ecto.Migration do defp expand_create(object, command, block) do quote do table = %Table{} = unquote(object) + unlogged = Runner.repo_config(:create_unlogged_tables, false) + table = %Table{table | unlogged: unlogged} Runner.start_command({unquote(command), Ecto.Migration.__prefix__(table)}) if primary_key = Ecto.Migration.__primary_key__(table) do @@ -623,6 +632,8 @@ defmodule Ecto.Migration do end def create(%Table{} = table) do + unlogged = Runner.repo_config(:create_unlogged_tables, table.unlogged) + table = %Table{table | unlogged: unlogged} do_create(table, :create) table end diff --git a/lib/ecto/migration/runner.ex b/lib/ecto/migration/runner.ex index 38170b52..414b5928 100644 --- a/lib/ecto/migration/runner.ex +++ b/lib/ecto/migration/runner.ex @@ -432,11 +432,21 @@ defmodule Ecto.Migration.Runner do defp command(ddl) when is_binary(ddl) or is_list(ddl), do: "execute #{inspect(ddl)}" - defp command({:create, %Table{} = table, _}), - do: "create table #{quote_name(table.prefix, table.name)}" + defp command({:create, %Table{} = table, _}) do + if repo_config(:create_unlogged_tables, false) do + "create unlogged table #{quote_name(table.prefix, table.name)}" + else + "create table #{quote_name(table.prefix, table.name)}" + end + end - defp command({:create_if_not_exists, %Table{} = table, _}), - do: "create table if not exists #{quote_name(table.prefix, table.name)}" + defp command({:create_if_not_exists, %Table{} = table, _}) do + if repo_config(:create_unlogged_tables, false) do + "create unlogged table if not exists #{quote_name(table.prefix, table.name)}" + else + "create table if not exists #{quote_name(table.prefix, table.name)}" + end + end defp command({:alter, %Table{} = table, _}), do: "alter table #{quote_name(table.prefix, table.name)}" diff --git a/test/ecto/migration_test.exs b/test/ecto/migration_test.exs index 1c865185..3f18a99b 100644 --- a/test/ecto/migration_test.exs +++ b/test/ecto/migration_test.exs @@ -461,6 +461,16 @@ defmodule Ecto.MigrationTest do {:create, table, [{:add, :id, :bigserial, [primary_key: true]}]} end + @tag repo_config: [create_unlogged_tables: true] + test "create unlogged table" do + create table = table(:posts) + flush() + + assert last_command() == + {:create, %Table{table | unlogged: true}, + [{:add, :id, :bigserial, [primary_key: true]}]} + end + test "alters a table" do alter table(:posts) do add :summary, :text @@ -721,6 +731,15 @@ defmodule Ecto.MigrationTest do end end + @tag repo_config: [create_unlogged_tables: true] + test "creates unlogged table" do + create(table(:posts)) + flush() + + {_, table, _} = last_command() + assert table.unlogged == true + end + test "drops a table with prefix from migration" do drop(table(:posts, prefix: "foo")) flush()