diff --git a/libs/application_runner/lib/environment/query_dyn_sup.ex b/libs/application_runner/lib/environment/query_dyn_sup.ex index 9486dee7..176588f3 100644 --- a/libs/application_runner/lib/environment/query_dyn_sup.ex +++ b/libs/application_runner/lib/environment/query_dyn_sup.ex @@ -29,14 +29,14 @@ defmodule ApplicationRunner.Environment.QueryDynSup do DynamicSupervisor.init(strategy: :one_for_one) end - @spec ensure_child_started(term(), String.t() | nil, map() | nil, map() | nil, map()) :: + @spec ensure_child_started(term(), String.t() | nil, map() | nil, map() | nil, map(), map()) :: {:ok, pid()} | {:error, term()} - def ensure_child_started(env_id, coll, query_parsed, query_transformed, projection) do + def ensure_child_started(env_id, coll, query_parsed, query_transformed, projection, options \\ %{}) do Logger.debug( "#{__MODULE__} ensure query server started for #{inspect([env_id, coll, query_parsed, query_transformed])}" ) - case start_child(env_id, coll, query_parsed, query_transformed, projection) do + case start_child(env_id, coll, query_parsed, query_transformed, projection, options) do {:ok, pid} -> Logger.info("ApplicationRunner.Environment.QueryServer started") {:ok, pid} @@ -50,13 +50,14 @@ defmodule ApplicationRunner.Environment.QueryDynSup do end end - defp start_child(env_id, coll, query_parsed, query_transformed, projection) do + defp start_child(env_id, coll, query_parsed, query_transformed, projection, options) do init_value = [ query_parsed: query_parsed, query_transformed: query_transformed, coll: coll, env_id: env_id, - projection: projection + projection: projection, + options: options ] DynamicSupervisor.start_child(get_full_name(env_id), {QueryServer, init_value}) diff --git a/libs/application_runner/lib/environment/query_server.ex b/libs/application_runner/lib/environment/query_server.ex index 35d7891b..9d97187c 100644 --- a/libs/application_runner/lib/environment/query_server.ex +++ b/libs/application_runner/lib/environment/query_server.ex @@ -46,7 +46,7 @@ defmodule ApplicationRunner.Environment.QueryServer do Swarm.join(group, pid) end - def get_data(env_id, coll, query_parsed, projection) do + def get_data(env_id, coll, query_parsed, projection, options) do GenServer.call(get_full_name({env_id, coll, query_parsed}), {:get_data, projection}) end @@ -64,8 +64,9 @@ defmodule ApplicationRunner.Environment.QueryServer do {:ok, coll} <- Keyword.fetch(opts, :coll), {:ok, query_transformed} <- Keyword.fetch(opts, :query_transformed), {:ok, query_parsed} <- Keyword.fetch(opts, :query_parsed), - {:ok, data} <- fetch_initial_data(env_id, coll, query_transformed), - {:ok, projection} <- Keyword.fetch(opts, :projection) do + {:ok, projection} <- Keyword.fetch(opts, :projection), + {:ok, options} <- Keyword.fetch(opts, :options), + {:ok, data} <- fetch_initial_data(env_id, coll, query_transformed, projection, options) do projection_data = if projection != %{} do %{projection => projection_data(data, projection)} @@ -83,7 +84,8 @@ defmodule ApplicationRunner.Environment.QueryServer do latest_timestamp: Mongo.timestamp(DateTime.utc_now()), done_ids: MapSet.new(), w_pids: MapSet.new(), - projection_data: projection_data + projection_data: projection_data, + options: options }} else :error -> @@ -119,20 +121,27 @@ defmodule ApplicationRunner.Environment.QueryServer do Map.values(map_data) end - defp fetch_initial_data(_env_id, coll, query_transformed) + defp fetch_initial_data(_env_id, coll, query_transformed, projection, options) when is_nil(coll) or is_nil(query_transformed) do Logger.debug("#{__MODULE__} fetch_initial_data with nil query") {:ok, []} end - defp fetch_initial_data(env_id, coll, query_transformed) do + defp fetch_initial_data(env_id, coll, query_transformed, projection, options) do Logger.debug("#{__MODULE__} fetch_initial_data with data: #{inspect([env_id, coll, query_transformed])}") + mongo_opts = + Keyword.merge( + [projection: projection], + Enum.map(options, fn {k, v} -> {String.to_atom(k), v} end) + ) + MongoInstance.run_mongo_task(env_id, MongoStorage, :filter_docs, [ env_id, coll, - query_transformed + query_transformed, + mongo_opts ]) end @@ -418,14 +427,14 @@ defmodule ApplicationRunner.Environment.QueryServer do if projection_change?(projection_data, new_data, k) do {k, v} else - group = ViewServer.group_name(env_id, coll, query_parsed, k) + group = ViewServer.group_name(env_id, coll, query_parsed, k, %{}) Swarm.publish(group, {:data_changed, projection_data(new_data, k)}) {k, projection_data(new_data, k)} end end) # Notify ViewServer with no projection. - group = ViewServer.group_name(env_id, coll, query_parsed, %{}) + group = ViewServer.group_name(env_id, coll, query_parsed, %{}, %{}) Swarm.publish(group, {:data_changed, new_data}) new_projection_data @@ -441,11 +450,11 @@ defmodule ApplicationRunner.Environment.QueryServer do } ) do Enum.each(Map.keys(projection_data), fn projection_key -> - group = ViewServer.group_name(env_id, old_coll, query_parsed, projection_key) + group = ViewServer.group_name(env_id, old_coll, query_parsed, projection_key, %{}) Swarm.publish(group, {:coll_changed, new_coll}) end) - group = ViewServer.group_name(env_id, old_coll, query_parsed, %{}) + group = ViewServer.group_name(env_id, old_coll, query_parsed, %{}, %{}) Swarm.publish(group, {:coll_changed, new_coll}) end diff --git a/libs/application_runner/lib/environment/view_dyn_sup.ex b/libs/application_runner/lib/environment/view_dyn_sup.ex index 01991f0d..8a97bae9 100644 --- a/libs/application_runner/lib/environment/view_dyn_sup.ex +++ b/libs/application_runner/lib/environment/view_dyn_sup.ex @@ -29,6 +29,7 @@ defmodule ApplicationRunner.Environment.ViewDynSup do query_parsed = view_uid.query_parsed query_transformed = view_uid.query_transformed projection = view_uid.projection + options = view_uid.options Logger.debug("#{__MODULE__} ensure_child_started for #{inspect(%{env_id: env_id, session_id: session_id})}") @@ -38,14 +39,15 @@ defmodule ApplicationRunner.Environment.ViewDynSup do coll, query_parsed, query_transformed, - projection + projection, + options ) do case start_child(env_id, function_name, view_uid) do {:ok, pid} -> Logger.info("ApplicationRunner.Environment.ViewServer") QueryServer.join_group(qs_pid, session_id) - ViewServer.join_group(pid, env_id, coll, query_parsed, projection) + ViewServer.join_group(pid, env_id, coll, query_parsed, projection, options) QueryServer.monitor(qs_pid, pid) {:ok, pid} diff --git a/libs/application_runner/lib/environment/view_server.ex b/libs/application_runner/lib/environment/view_server.ex index 9d683971..d43b0900 100644 --- a/libs/application_runner/lib/environment/view_server.ex +++ b/libs/application_runner/lib/environment/view_server.ex @@ -10,12 +10,12 @@ defmodule ApplicationRunner.Environment.ViewServer do require Logger - def group_name(env_id, coll, query, projection) do - {__MODULE__, env_id, coll, query, projection} + def group_name(env_id, coll, query, projection, options \\ %{}) do + {__MODULE__, env_id, coll, query, projection, options} end - def join_group(pid, env_id, coll, query, projection) do - group = group_name(env_id, coll, query, projection) + def join_group(pid, env_id, coll, query, projection, options \\ %{}) do + group = group_name(env_id, coll, query, projection, options) Swarm.join(group, pid) end @@ -46,7 +46,7 @@ defmodule ApplicationRunner.Environment.ViewServer do %ViewUid{} = view_uid = Keyword.fetch!(opts, :view_uid) with data <- - QueryServer.get_data(env_id, view_uid.coll, view_uid.query_parsed, view_uid.projection), + QueryServer.get_data(env_id, view_uid.coll, view_uid.query_parsed, view_uid.projection, view_uid.options), {:ok, view} <- ApplicationServices.fetch_view( function_name, diff --git a/libs/application_runner/lib/environment/view_uid.ex b/libs/application_runner/lib/environment/view_uid.ex index 86d0e9ea..2041df1a 100644 --- a/libs/application_runner/lib/environment/view_uid.ex +++ b/libs/application_runner/lib/environment/view_uid.ex @@ -2,7 +2,7 @@ defmodule ApplicationRunner.Environment.ViewUid do @moduledoc """ This identify a unique widget for a given environment. """ - @enforce_keys [:name, :coll, :query_parsed, :query_transformed, :props, :context, :projection] + @enforce_keys [:name, :coll, :query_parsed, :query_transformed, :props, :context, :projection, :options] defstruct [ :name, :props, @@ -11,6 +11,7 @@ defmodule ApplicationRunner.Environment.ViewUid do :context, :coll, :projection, + :options, prefix_path: "" ] @@ -22,6 +23,7 @@ defmodule ApplicationRunner.Environment.ViewUid do coll: String.t() | nil, context: map() | nil, prefix_path: String.t(), - projection: map() + projection: map(), + options: map() } end diff --git a/libs/application_runner/lib/session/route_server.ex b/libs/application_runner/lib/session/route_server.ex index 9ddf10ca..279481c5 100644 --- a/libs/application_runner/lib/session/route_server.ex +++ b/libs/application_runner/lib/session/route_server.ex @@ -98,12 +98,12 @@ defmodule ApplicationRunner.Session.RouteServer do props <- Map.get(base_view, "props", %{}), find <- Map.get(base_view, "find", %{}), context_projection <- Map.get(base_view, "context"), - {coll, query, projection} <- extract_find(base_view, find), + {coll, query, projection, options} <- extract_find(base_view, find), {:ok, view_uid} <- create_view_uid( session_metadata, name, - %{coll: coll, query: query, projection: projection}, + %{coll: coll, query: query, projection: projection, options: options}, %{"route" => route_params}, props, session_metadata.context, @@ -128,15 +128,16 @@ defmodule ApplicationRunner.Session.RouteServer do coll = Map.get(find, "coll") query = Map.get(find, "query", %{}) projection = Map.get(find, "projection", %{}) + options = Map.get(find, "options", %{}) if find == %{} && coll_deprecated != nil do Logger.warning( "Definition of view #{name} is deprecated since applicationRunner beta 106 check https://docs.lenra.io/components-api/components/view.html." ) - {coll_deprecated, query_deprecated, %{}} + {coll_deprecated, query_deprecated, %{}, %{}} else - {coll, query, projection} + {coll, query, projection, options} end end @@ -195,6 +196,7 @@ defmodule ApplicationRunner.Session.RouteServer do coll = Map.get(find, :coll) query = Map.get(find, :query) projection = Map.get(find, :projection) + options = Map.get(find, :options) mongo_user_id = case session_metadata.user_id do @@ -236,7 +238,8 @@ defmodule ApplicationRunner.Session.RouteServer do query_transformed: query_transformed, coll: coll, context: context, - projection: projection + projection: projection, + options: options }} end end diff --git a/libs/application_runner/lib/session/ui_builders/lenra_builder.ex b/libs/application_runner/lib/session/ui_builders/lenra_builder.ex index 689b074e..9549489e 100644 --- a/libs/application_runner/lib/session/ui_builders/lenra_builder.ex +++ b/libs/application_runner/lib/session/ui_builders/lenra_builder.ex @@ -126,13 +126,13 @@ defmodule ApplicationRunner.Session.UiBuilders.LenraBuilder do find = Map.get(component, "find", %{}) context_projection = Map.get(component, "context") - {coll, query, projection} = RouteServer.extract_find(component, find) + {coll, query, projection, options} = RouteServer.extract_find(component, find) with {:ok, new_view_uid} <- RouteServer.create_view_uid( session_metadata, name, - %{coll: coll, query: query, projection: projection}, + %{coll: coll, query: query, projection: projection, options: options}, %{}, props, view_uid.context, diff --git a/libs/application_runner/priv/components-api b/libs/application_runner/priv/components-api index 87c0e492..cbe257da 160000 --- a/libs/application_runner/priv/components-api +++ b/libs/application_runner/priv/components-api @@ -1 +1 @@ -Subproject commit 87c0e492eda38e38ce900d4dc6cd21c270f6a9d6 +Subproject commit cbe257da5f729ec29556680cbb40e91685443677 diff --git a/libs/application_runner/test/environment/view_dyn_sup_test.exs b/libs/application_runner/test/environment/view_dyn_sup_test.exs index c12804d0..9bc43bee 100644 --- a/libs/application_runner/test/environment/view_dyn_sup_test.exs +++ b/libs/application_runner/test/environment/view_dyn_sup_test.exs @@ -76,7 +76,8 @@ defmodule ApplicationRunner.Environment.ViewDynSupTest do query_transformed: %{}, props: %{}, context: %{}, - projection: %{} + projection: %{}, + options: %{} } assert :undefined != Swarm.whereis_name(Environment.ViewDynSup.get_name(env_id))