Skip to content

Commit

Permalink
backup
Browse files Browse the repository at this point in the history
  • Loading branch information
IvanIvanoff committed Nov 15, 2023
1 parent d170685 commit 0b4d8f4
Show file tree
Hide file tree
Showing 6 changed files with 124 additions and 108 deletions.
19 changes: 13 additions & 6 deletions lib/sanbase/queries/menu/menu.ex
Original file line number Diff line number Diff line change
Expand Up @@ -28,25 +28,32 @@ defmodule Sanbase.Queries.Menu do
:parent_id,
:root_parent_id
])
|> validate_required([:name])
end

def create(attrs \\ %{}) do
%Menu{}
|> changeset(attrs)
|> validate_required([:name])
|> validate_length(:name, min: 1, max: 256)
end

def update(menu, attrs) do
menu
|> changeset(attrs)
|> Repo.update()
end

def delete(menu) do
Repo.delete(menu)
def get(id) do
base_query()
|> where([m], m.id == ^id)
end

def get_root_parent_id(id) do
base_query()
|> where([m], m.id == ^id)
|> select([m], m.root_parent_id)
end

def get(id) do
from(m in Menu, where: m.id == ^id)
defp base_query() do
__MODULE__
end
end
38 changes: 25 additions & 13 deletions lib/sanbase/queries/menu/menu_item.ex
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,11 @@ defmodule Sanbase.Queries.Menu.MenuItem do
alias Sanbase.Queries.Dashboard

schema "menu_items" do
belongs_to(:menu, Menu, foreign_key: :menu_id)
belongs_to(:root_menu, Menu, foreign_key: :root_menu_id)
belongs_to(:parent, Menu, foreign_key: :parent_id)

belongs_to(:query, Query, foreign_key: :query_id)
belongs_to(:dashboard, Dashboard, foreign_key: :dashboard_id)
belongs_to(:menu, Menu, foreign_key: :menu_id)

field(:position, :integer)

Expand All @@ -30,27 +30,39 @@ defmodule Sanbase.Queries.Menu.MenuItem do
])
end

@doc ~s"""
Get the next position for a menu item inside a specific menu
(it can be either sub-menu or a root menu)
"""
def get_next_position(menu_id) do
base_query()
|> where([m], m.menu_id == ^menu_id)
|> select([m], coalesce(max(m.position), 0) + 1)
end

@doc ~s"""
Get the next position for a menu item inside a specific menu
(it can be either sub-menu or a root menu)
"""
def inc_all_positions_after(menu_id, position) do
base_query()
|> where([m], m.menu_id == ^menu_id and m.position >= ^position)
|> update([m], inc: [position: +1])
end

def create(attrs \\ %{}) do
%__MODULE__{}
|> changeset(attrs)
|> Repo.insert()
end

def update(menu, attrs) do
menu
|> changeset(attrs)
|> Repo.update()
end

def delete(menu) do
Repo.delete(menu)
end

def get(id) do
Repo.get(Menu, id)
end
# Private functions

def list do
Repo.all(Menu)
defp base_query() do
from(m in __MODULE__)
end
end
89 changes: 77 additions & 12 deletions lib/sanbase/queries/menus.ex
Original file line number Diff line number Diff line change
Expand Up @@ -2,24 +2,89 @@ defmodule Sanbase.Menus do
alias Sanbase.Queries.Menu
alias Sanbase.Queries.Menu.MenuItem

def create_menu(args) do
Menu.create(args)
|> Sanbase.Repo.insert()
import Sanbase.Utils.ErrorHandling, only: [changeset_errors_string: 1]

@doc ~s"""
TODO
"""
def create_menu(params) do
Ecto.Multi.new()
|> Ecto.Multi.run(:get_root_parent_id, fn _repo, _changes ->
case Map.get(params, :parent_id) do
# If there is no parent_id then there is no root_parent_id as well
nil ->
{:ok, nil}

# The root_parent_id of the sub-menu is the same as the root_parent_id
# of the parent menu. Root menus don't have a root_parent_id pointing to themselves
# so in such case we put the parent_id as a root_parent_id (i.e. this new menu
# is a first-level child)
parent_id when is_integer(parent_id) ->
{:ok, root_parent_id} = get_root_parent_id(parent_id)

{:ok, root_parent_id || parent_id}
end
end)
|> Ecto.Multi.run(:create_menu, fn _repo, %{get_root_parent_id: root_parent_id} ->
params = Map.merge(params, %{root_parent_id: root_parent_id})
query = Menu.create(params)
Sanbase.Repo.insert(query)
end)
|> Sanbase.Repo.transaction()
|> process_transaction_result(:create_menu)
end

@doc ~s"""
TODO
"""
def add_menu_item(menu_id, item_args) do
with {:ok, root_parent_id} <- get_root_parent_id(menu_id),
{:ok, position} <- MenuItem.get_next_position(root_parent_id) do
MenuItem.create(%{menu_id: menu_id, root_menu_id: root_parent_id} ++ item_args)
|> Sanbase.Repo.insert()
end
Ecto.Multi.new()
|> Ecto.Multi.run(:get_root_parent_id, fn _repo, _changes ->
get_root_parent_id(menu_id)
end)
|> Ecto.Multi.run(:get_and_adjust_position, fn _repo, %{get_root_parent_id: root_parent_id} ->
case Map.get(item_args, :position) do
nil ->
# If `position` is not specified, add it at the end by getting the last position + 1
{:ok, get_next_position(menu_id)}

MenuItem.create(%{menu_id: menu_id} ++ item_args)
position when is_integer(position) ->
# If `position` is specified, bump all the positions bigger than it by 1
{:ok, {nil, _}} = inc_all_positions_after(menu_id, position)
{:ok, position}
end
end)
|> Ecto.Multi.run(
:create_menu_item,
fn _repo, %{get_root_parent_id: _, get_and_adjust_position: _} = map ->
params = Map.merge(item_args, map)
query = MenuItem.create(params)
Sanbase.Repo.insert(query)
end
)
end

defp get_root_parent_id(menu_id) do
query = Menu.get(menu_id) |> select(:root_parent_id)
defp get_next_position(menu_id) do
query = MenuItem.get_next_position(menu_id)
{:ok, Sanbase.Repo.one(query)}
end

{:ok, root_parent_id} = Sanbase.Repo.one(query)
defp inc_all_positions_after(menu_id, position) do
query = MenuItem.inc_all_positions_after(menu_id, position)
{:ok, Sanbase.Repo.update_all(query)}
end

defp get_root_parent_id(menu_id) when is_integer(menu_id) do
query = Menu.get_root_parent_id(menu_id)
{:ok, Sanbase.Repo.one(query)}
end

defp process_transaction_result({:ok, map}, ok_field),
do: {:ok, map[ok_field]}

defp process_transaction_result({:error, _, %Ecto.Changeset{} = changeset, _}, _ok_field),
do: {:error, changeset_errors_string(changeset)}

defp process_transaction_result({:error, _, error, _}, _ok_field),
do: {:error, error}
end
54 changes: 0 additions & 54 deletions lib/sanbase_web/graphql/schema/queries/menu_queries.ex
Original file line number Diff line number Diff line change
Expand Up @@ -52,59 +52,5 @@ defmodule SanbaseWeb.Graphql.Schema.MenuQueriesQueries do

resolve(&MenuResolver.add_menu_item/3)
end

field :create_menu_question, :string do
arg(:menu_uuid, non_null(:string))

arg(:params, :menu_question_params_input_object)

middleware(JWTAuth)

resolve(&MenuResolver.create_question/3)
end

field :update_menu_question, :menu do
arg(:question_uuid, non_null(:string))
arg(:params, :menu_question_params_input_object)

middleware(JWTAuth)

resolve(&MenuResolver.update_question/3)
end

field :delete_menu_question, :menu do
arg(:question_uuid, non_null(:string))

middleware(JWTAuth)

resolve(&MenuResolver.delete_question/3)
end

field :create_menu_answer, :menu_answer do
arg(:question_uuid, non_null(:string))
arg(:params, :menu_answer_params_input_object)

middleware(JWTAuth)

resolve(&MenuResolver.create_answer/3)
end

field :update_menu_answer, :menu_answer do
arg(:answer_uuid, non_null(:string))
arg(:params, :menu_answer_params_input_object)

middleware(JWTAuth)

resolve(&MenuResolver.update_answer/3)
end

field :delete_menu_answer, :menu_answer do
arg(:answer_uuid, non_null(:string))
arg(:params, :menu_answer_params_input_object)

middleware(JWTAuth)

resolve(&MenuResolver.delete_answer/3)
end
end
end
12 changes: 3 additions & 9 deletions priv/repo/migrations/20231110093800_create_menus_table.exs
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,6 @@ defmodule Sanbase.Repo.Migrations.CreatesMenusTable do
add(:parent_id, references(:menus, on_delete: :delete_all))
add(:root_parent_id, references(:menus, on_delete: :delete_all))

add(:position, :integer)

add(:user_id, references(:users, on_delete: :delete_all))

add(:is_admin_controlled, :boolean, default: false)
Expand All @@ -25,22 +23,18 @@ defmodule Sanbase.Repo.Migrations.CreatesMenusTable do
create(index(:menus, [:user_id]))

create table(:menu_items) do
add(:menu_id, references(:menus, on_delete: :delete_all))
add(:root_menu_id, references(:menus, on_delete: :delete_all))
add(:parent_id, references(:menus, on_delete: :delete_all))
# add(:root_parent_id, references(:menus, on_delete: :delete_all))

add(:query_id, references(:queries, on_delete: :delete_all))
add(:dashboard_id, references(:dashboards, on_delete: :delete_all))
add(:menu_id, references(:menus, on_delete: :delete_all))

add(:position, :integer)

timestamps()
end

# When searching for all menu items of a menu, the `where` clause will
# find these items by the root_menu_id, hence the index. The
# menu_id is used only to build the hierarchy after that.
create(index(:menu_items, [:root_menu_id]))

fk_check = """
(CASE WHEN query_id IS NULL THEN 0 ELSE 1 END) +
(CASE WHEN dashboard_id IS NULL THEN 0 ELSE 1 END) = 1
Expand Down
20 changes: 6 additions & 14 deletions priv/repo/structure.sql
Original file line number Diff line number Diff line change
Expand Up @@ -2011,10 +2011,10 @@ ALTER SEQUENCE public.market_segments_id_seq OWNED BY public.market_segments.id;

CREATE TABLE public.menu_items (
id bigint NOT NULL,
menu_id bigint,
root_menu_id bigint,
parent_id bigint,
query_id bigint,
dashboard_id bigint,
menu_id bigint,
"position" integer,
inserted_at timestamp without time zone NOT NULL,
updated_at timestamp without time zone NOT NULL,
Expand Down Expand Up @@ -2059,7 +2059,6 @@ CREATE TABLE public.menus (
description character varying(255),
parent_id bigint,
root_parent_id bigint,
"position" integer,
user_id bigint,
is_admin_controlled boolean DEFAULT false,
inserted_at timestamp without time zone NOT NULL,
Expand Down Expand Up @@ -6732,13 +6731,6 @@ CREATE UNIQUE INDEX list_items_user_list_id_project_id_index ON public.list_item
CREATE UNIQUE INDEX market_segments_name_index ON public.market_segments USING btree (name);


--
-- Name: menu_items_root_menu_id_index; Type: INDEX; Schema: public; Owner: -
--

CREATE INDEX menu_items_root_menu_id_index ON public.menu_items USING btree (root_menu_id);


--
-- Name: menus_root_parent_id_index; Type: INDEX; Schema: public; Owner: -
--
Expand Down Expand Up @@ -7906,19 +7898,19 @@ ALTER TABLE ONLY public.menu_items


--
-- Name: menu_items menu_items_query_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: -
-- Name: menu_items menu_items_parent_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: -
--

ALTER TABLE ONLY public.menu_items
ADD CONSTRAINT menu_items_query_id_fkey FOREIGN KEY (query_id) REFERENCES public.queries(id) ON DELETE CASCADE;
ADD CONSTRAINT menu_items_parent_id_fkey FOREIGN KEY (parent_id) REFERENCES public.menus(id) ON DELETE CASCADE;


--
-- Name: menu_items menu_items_root_menu_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: -
-- Name: menu_items menu_items_query_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: -
--

ALTER TABLE ONLY public.menu_items
ADD CONSTRAINT menu_items_root_menu_id_fkey FOREIGN KEY (root_menu_id) REFERENCES public.menus(id) ON DELETE CASCADE;
ADD CONSTRAINT menu_items_query_id_fkey FOREIGN KEY (query_id) REFERENCES public.queries(id) ON DELETE CASCADE;


--
Expand Down

0 comments on commit 0b4d8f4

Please sign in to comment.