diff --git a/lib/sanbase/clickhouse/project/project.ex b/lib/sanbase/clickhouse/project/project.ex new file mode 100644 index 0000000000..d1539280cf --- /dev/null +++ b/lib/sanbase/clickhouse/project/project.ex @@ -0,0 +1,28 @@ +defmodule Sanbase.Clickhouse.Project do + def projects_info(slugs) do + query = projects_info_query(slugs) + + Sanbase.ClickhouseRepo.query_reduce(query, %{}, fn [slug, full, summary], acc -> + Map.put(acc, slug, %{full: full, summary: summary}) + end) + end + + defp projects_info_query(slugs) do + sql = """ + SELECT + slug, + info, + info_summary + FROM projects_info + WHERE + version = ( SELECT max(version) FROM projects_info) AND + slug IN {{slugs}} + """ + + params = %{ + slugs: slugs + } + + Sanbase.Clickhouse.Query.new(sql, params) + end +end diff --git a/lib/sanbase/clickhouse/top_holders/project/project.ex b/lib/sanbase/clickhouse/top_holders/project/project.ex new file mode 100644 index 0000000000..e69de29bb2 diff --git a/lib/sanbase_web/graphql/dataloader/clickhouse_dataloader.ex b/lib/sanbase_web/graphql/dataloader/clickhouse_dataloader.ex index 32c82a7400..600632e760 100644 --- a/lib/sanbase_web/graphql/dataloader/clickhouse_dataloader.ex +++ b/lib/sanbase_web/graphql/dataloader/clickhouse_dataloader.ex @@ -5,6 +5,16 @@ defmodule SanbaseWeb.Graphql.ClickhouseDataloader do def data(), do: Dataloader.KV.new(&query/2) + def query(:project_info, args) do + args + |> Enum.to_list() + |> Clickhouse.Project.projects_info() + |> case do + {:ok, map} -> map + {:error, _} = error -> error + end + end + def query(:aggregated_metric, args) do args_list = args |> Enum.to_list() diff --git a/lib/sanbase_web/graphql/dataloader/sanbase_dataloader.ex b/lib/sanbase_web/graphql/dataloader/sanbase_dataloader.ex index 470ffb5208..71ead81a1b 100644 --- a/lib/sanbase_web/graphql/dataloader/sanbase_dataloader.ex +++ b/lib/sanbase_web/graphql/dataloader/sanbase_dataloader.ex @@ -21,7 +21,8 @@ defmodule SanbaseWeb.Graphql.SanbaseDataloader do :average_daily_active_addresses, :average_dev_activity, :eth_spent, - :aggregated_metric + :aggregated_metric, + :project_info ] @balance_dataloader [ diff --git a/lib/sanbase_web/graphql/resolvers/project/project_resolver.ex b/lib/sanbase_web/graphql/resolvers/project/project_resolver.ex index 3e757ba6e4..b7eb88928d 100644 --- a/lib/sanbase_web/graphql/resolvers/project/project_resolver.ex +++ b/lib/sanbase_web/graphql/resolvers/project/project_resolver.ex @@ -93,6 +93,16 @@ defmodule SanbaseWeb.Graphql.Resolvers.ProjectResolver do end) end + def project_info(%Project{slug: slug}, _args, %{context: %{loader: loader}}) do + loader + |> Dataloader.load(SanbaseDataloader, :project_info, slug) + |> on_load(fn loader -> + description = Dataloader.get(loader, SanbaseDataloader, :project_info, slug) + + {:ok, description} + end) + end + def roi_usd(%Project{} = project, _args, _resolution) do roi = Project.roi_usd(project) diff --git a/lib/sanbase_web/graphql/schema/types/project_types.ex b/lib/sanbase_web/graphql/schema/types/project_types.ex index 46d37b3e51..bc6d8f9eb8 100644 --- a/lib/sanbase_web/graphql/schema/types/project_types.ex +++ b/lib/sanbase_web/graphql/schema/types/project_types.ex @@ -360,6 +360,10 @@ defmodule SanbaseWeb.Graphql.ProjectTypes do field(:long_description, :string) field(:token_decimals, :integer) + field :info, :project_info do + cache_resolve(&ProjectResolver.project_info/3) + end + @desc ~s""" Shows if a project is marked as hidden. @@ -788,6 +792,11 @@ defmodule SanbaseWeb.Graphql.ProjectTypes do end end + object :project_info do + field(:full, :string) + field(:summary, :string) + end + object :ico_with_eth_contract_info do field(:id, non_null(:id)) field(:start_date, :date) diff --git a/test/sanbase/project/project_info_test.exs b/test/sanbase/project/project_info_test.exs new file mode 100644 index 0000000000..24624f556b --- /dev/null +++ b/test/sanbase/project/project_info_test.exs @@ -0,0 +1,50 @@ +defmodule Sanbase.Project.InfoTest do + use SanbaseWeb.ConnCase, async: false + + import Sanbase.Factory + import SanbaseWeb.Graphql.TestHelpers + + test "get project's available metrics", context do + insert(:project, slug: "bitcoin") + insert(:project, slug: "ethereum") + + rows = [ + ["bitcoin", "bitcoin full info", "short btc info"], + ["ethereum", "ethereum full info", "short eth info"] + ] + + Sanbase.Mock.prepare_mock2(&Sanbase.ClickhouseRepo.query/2, {:ok, %{rows: rows}}) + |> Sanbase.Mock.run_with_mocks(fn -> + result = get_projects_info(context.conn) |> get_in(["data", "allProjects"]) + assert length(result) == 2 + + assert %{ + "info" => %{"full" => "bitcoin full info", "summary" => "short btc info"}, + "slug" => "bitcoin" + } in result + + assert %{ + "info" => %{"full" => "ethereum full info", "summary" => "short eth info"}, + "slug" => "ethereum" + } in result + end) + end + + defp get_projects_info(conn) do + query = """ + { + allProjects{ + slug + info { + full + summary + } + } + } + """ + + conn + |> post("/graphql", query_skeleton(query)) + |> json_response(200) + end +end