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 0b4d8f4 commit 0a2bbbf
Show file tree
Hide file tree
Showing 9 changed files with 105 additions and 38 deletions.
2 changes: 1 addition & 1 deletion lib/sanbase/dashboard/dashboard_query.ex
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ defmodule Sanbase.Dashboard.Query do
compressed_rows
|> Base.decode64!()
|> :zlib.gunzip()
|> :erlang.binary_to_term()
|> Plug.Crypto.non_executable_binary_to_term([:safe])
end

def valid_sql?(args) do
Expand Down
51 changes: 38 additions & 13 deletions lib/sanbase/queries/menus.ex → lib/sanbase/menu/menus.ex
Original file line number Diff line number Diff line change
@@ -1,13 +1,32 @@
defmodule Sanbase.Menus do
alias Sanbase.Queries.Menu
alias Sanbase.Queries.Menu.MenuItem
alias Sanbase.Menus.Menu
alias Sanbase.Menus.MenuItem
alias Sanbase.Repo

import Sanbase.Utils.ErrorHandling, only: [changeset_errors_string: 1]

@type user_id :: Sanbase.Accounts.User.user_id()

def get_menu(menu_id, querying_user_id) do
query = Menu.by_id(menu_id)

case Repo.one(query) do
nil ->
{:error, "Menu with id #{menu_id} not found"}

menu ->
{:ok, menu}
end
end

@doc ~s"""
TODO
Create a new menu.
A menu has a name and a description. It holds a list of MenuItems that have a given
order.
"""
def create_menu(params) do
@spec create_menu(map, user_id) :: {:ok, Menu.t()} | {:error, String.t()}
def create_menu(params, user_id) do
Ecto.Multi.new()
|> Ecto.Multi.run(:get_root_parent_id, fn _repo, _changes ->
case Map.get(params, :parent_id) do
Expand All @@ -28,16 +47,20 @@ defmodule Sanbase.Menus do
|> 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)
Repo.insert(query)
end)
|> Ecto.Multi.run(:create)
|> Ecto.Multi.run(:get_menu_with_preloads, fn _repo, %{create_menu: menu} ->
get_menu(menu.id, user_id)
end)
|> Sanbase.Repo.transaction()
|> Repo.transaction()
|> process_transaction_result(:create_menu)
end

@doc ~s"""
TODO
"""
def add_menu_item(menu_id, item_args) do
def create_menu_item(menu_id, item_args) do
Ecto.Multi.new()
|> Ecto.Multi.run(:get_root_parent_id, fn _repo, _changes ->
get_root_parent_id(menu_id)
Expand All @@ -50,33 +73,35 @@ defmodule Sanbase.Menus do

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, {_, 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)
params = item_args |> Map.merge(map) |> Map.put(:parent_id, menu_id)
query = MenuItem.create(params)
Sanbase.Repo.insert(query)
Repo.insert(query)
end
)
|> Repo.transaction()
|> process_transaction_result(:create_menu_item)
end

defp get_next_position(menu_id) do
query = MenuItem.get_next_position(menu_id)
{:ok, Sanbase.Repo.one(query)}
{:ok, Repo.one(query)}
end

defp inc_all_positions_after(menu_id, position) do
query = MenuItem.inc_all_positions_after(menu_id, position)
{:ok, Sanbase.Repo.update_all(query)}
{:ok, 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)}
{:ok, Repo.one(query)}
end

defp process_transaction_result({:ok, map}, ok_field),
Expand Down
Original file line number Diff line number Diff line change
@@ -1,21 +1,23 @@
defmodule Sanbase.Queries.Menu do
defmodule Sanbase.Menus.Menu do
use Ecto.Schema

import Ecto.Query
import Ecto.Changeset

alias __MODULE__.MenuItem
alias Sanbase.Menus.MenuItem
alias Sanbase.Accounts.User
alias __MODULE__, as: Menu

schema "menus" do
field(:name, :string)
field(:description, :string)

has_many(:menu_items, MenuItem)
has_many(:menu_items, MenuItem, foreign_key: :parent_id)

# Build a hierarchy of menus.
belongs_to(:parent, Menu, foreign_key: :parent_id)
belongs_to(:root_parent, Menu, foreign_key: :root_parent_id)
# belongs_to(:parent, Menu)
# belongs_to(:root_parent, Menu)
belongs_to(:user, User)

timestamps()
end
Expand All @@ -42,9 +44,19 @@ defmodule Sanbase.Queries.Menu do
|> changeset(attrs)
end

def get(id) do
@doc ~s"""
Get a menu by its id.
"""
def by_id(id) do
base_query()
|> where([m], m.id == ^id)
|> preload([
# The items of the root-menu
:menu_items,
# The items of the sub-menus one level deep
menu_items: [:menu, :query, :dashboard],
menu_items: [menu: :menu_items, menu: [menu_items: [:menu, :query, :dashboard]]]
])
end

def get_root_parent_id(id) do
Expand Down
Original file line number Diff line number Diff line change
@@ -1,19 +1,19 @@
defmodule Sanbase.Queries.Menu.MenuItem do
defmodule Sanbase.Menus.MenuItem do
use Ecto.Schema

import Ecto.Query
import Ecto.Changeset

alias Sanbase.Queries.Menu
alias Sanbase.Menus.Menu
alias Sanbase.Queries.Query
alias Sanbase.Queries.Dashboard

schema "menu_items" do
belongs_to(:parent, Menu, foreign_key: :parent_id)
belongs_to(:parent, Menu)

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

field(:position, :integer)

Expand All @@ -23,9 +23,14 @@ defmodule Sanbase.Queries.Menu.MenuItem do
def changeset(menu, attrs \\ %{}) do
menu
|> cast(attrs, [
# Who this item belongs to
:parent_id,
# What is the item. There's check constraint on the DB level that only one
# of these can be set
:menu_id,
:query_id,
:dashboard_id,
# The position of the item in the menu
:position
])
end
Expand Down
2 changes: 1 addition & 1 deletion lib/sanbase/queries/executor/result.ex
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,6 @@ defmodule Sanbase.Queries.Executor.Result do
compressed_rows
|> Base.decode64!()
|> :zlib.gunzip()
|> :erlang.binary_to_term()
|> Plug.Crypto.non_executable_binary_to_term([:safe])
end
end
31 changes: 29 additions & 2 deletions lib/sanbase/run_examples.ex
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ defmodule Sanbase.RunExamples do
"""
@queries [
:santiment_queries,
:menus,
:basic_metric_queries,
:available_metrics,
:trending_words,
Expand Down Expand Up @@ -697,9 +698,7 @@ defmodule Sanbase.RunExamples do
)

{:ok, dashboard} = Sanbase.Dashboards.create_dashboard(%{name: "MyName"}, user.id)

{:ok, mapping} = Sanbase.Dashboards.add_query_to_dashboard(dashboard.id, query.id, user.id)

{:ok, q} = Sanbase.Queries.get_dashboard_query(dashboard.id, mapping.id, user.id)

query_metadata = Sanbase.Queries.QueryMetadata.from_local_dev(user.id)
Expand All @@ -723,4 +722,32 @@ defmodule Sanbase.RunExamples do

{:ok, :success}
end

defp do_run(:menus) do
user = Sanbase.Factory.insert(:user)

{:ok, query} = Sanbase.Queries.create_query(%{name: "Query"}, user.id)
{:ok, dashboard} = Sanbase.Dashboards.create_dashboard(%{name: "MyName"}, user.id)

{:ok, menu} = Sanbase.Menus.create_menu(%{name: "MyMenu", description: "MyDescription"})

{:ok, menu_item1} =
Sanbase.Menus.create_menu_item(menu.id, %{query_id: query.id, position: 1})

{:ok, menu_item2} =
Sanbase.Menus.create_menu_item(menu.id, %{dashboard_id: dashboard.id, position: 2})

{:ok, sub_menu} =
Sanbase.Menus.create_menu(%{
name: "MySubMenu",
description: "MySubDescription",
parent_id: menu.id,
position: 1
})

for r <- [query, dashboard, sub_menu, menu],
do: Sanbase.Repo.delete(r)

{:ok, :success}
end
end
7 changes: 0 additions & 7 deletions lib/sanbase_web/graphql/schema/types/menu_types.ex
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,6 @@ defmodule SanbaseWeb.Graphql.MenuTypes do
input_object :menu_create_params_input_object do
field(:name, non_null(:string))
field(:description, :string)

@desc ~s"""
If the menu is a sub-menu, this field should be set to the parent menu's id.
If this field is not set or explicitly set to null, the menu will be created as
a top-level menu
"""
field(:parent_id, :integer, default_value: nil)
end

input_object :menu_update_params_input_object do
Expand Down
3 changes: 2 additions & 1 deletion priv/repo/migrations/20231110093800_create_menus_table.exs
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,8 @@ defmodule Sanbase.Repo.Migrations.CreatesMenusTable do

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
(CASE WHEN dashboard_id IS NULL THEN 0 ELSE 1 END) +
(CASE WHEN menu_id IS NULL THEN 0 ELSE 1 END) = 1
"""

create(constraint(:menu_items, :only_one_fk, check: fk_check))
Expand Down
6 changes: 5 additions & 1 deletion priv/repo/structure.sql
Original file line number Diff line number Diff line change
Expand Up @@ -2018,14 +2018,18 @@ CREATE TABLE public.menu_items (
"position" integer,
inserted_at timestamp without time zone NOT NULL,
updated_at timestamp without time zone NOT NULL,
CONSTRAINT only_one_fk CHECK (((
CONSTRAINT only_one_fk CHECK ((((
CASE
WHEN (query_id IS NULL) THEN 0
ELSE 1
END +
CASE
WHEN (dashboard_id IS NULL) THEN 0
ELSE 1
END) +
CASE
WHEN (menu_id IS NULL) THEN 0
ELSE 1
END) = 1))
);

Expand Down

0 comments on commit 0a2bbbf

Please sign in to comment.