Add pagination to search
[akkoma] / lib / pleroma / user.ex
index 37f8da8922f800cd014eafd58b14c770407d620d..230155c3375f24b9f054b8b397ac9f77ea04a5c8 100644 (file)
@@ -547,11 +547,8 @@ defmodule Pleroma.User do
   end
 
   def get_followers_query(user, page) do
-    from(
-      u in get_followers_query(user, nil),
-      limit: 20,
-      offset: ^((page - 1) * 20)
-    )
+    from(u in get_followers_query(user, nil))
+    |> paginate(page, 20)
   end
 
   def get_followers_query(user), do: get_followers_query(user, nil)
@@ -577,11 +574,8 @@ defmodule Pleroma.User do
   end
 
   def get_friends_query(user, page) do
-    from(
-      u in get_friends_query(user, nil),
-      limit: 20,
-      offset: ^((page - 1) * 20)
-    )
+    from(u in get_friends_query(user, nil))
+    |> paginate(page, 20)
   end
 
   def get_friends_query(user), do: get_friends_query(user, nil)
@@ -755,51 +749,64 @@ defmodule Pleroma.User do
     Repo.all(query)
   end
 
-  def search(term, options \\ %{}) do
-    # Strip the beginning @ off if there is a query
+  @spec search_for_admin(binary(), %{
+          admin: Pleroma.User.t(),
+          local: boolean(),
+          page: number(),
+          page_size: number()
+        }) :: {:ok, [Pleroma.User.t()], number()}
+  def search_for_admin(term, %{admin: admin, local: local, page: page, page_size: page_size}) do
     term = String.trim_leading(term, "@")
-    query = options[:query] || User
 
-    if options[:resolve], do: get_or_fetch(term)
+    local_paginated_query =
+      User
+      |> maybe_local_user_query(local)
+      |> paginate(page, page_size)
 
-    fts_results =
-      do_search(fts_search_subquery(term, query), options[:for_user], %{
-        limit: options[:limit]
-      })
+    search_query = fts_search_subquery(term, local_paginated_query)
 
-    {:ok, trigram_results} =
-      Repo.transaction(fn ->
-        Ecto.Adapters.SQL.query(Repo, "select set_limit(0.25)", [])
-
-        do_search(trigram_search_subquery(term, query), options[:for_user], %{
-          limit: options[:limit]
-        })
-      end)
+    count =
+      term
+      |> fts_search_subquery()
+      |> maybe_local_user_query(local)
+      |> Repo.aggregate(:count, :id)
 
-    Enum.uniq_by(fts_results ++ trigram_results, & &1.id)
+    {:ok, do_search(search_query, admin), count}
   end
 
-  def all(page, page_size) do
-    from(
-      u in User,
-      limit: ^page_size,
-      offset: ^((page - 1) * page_size),
-      order_by: u.id
-    )
-    |> Repo.all()
+  @spec all_for_admin(number(), number()) :: {:ok, [Pleroma.User.t()], number()}
+  def all_for_admin(page, page_size) do
+    query = from(u in User, order_by: u.id)
+
+    paginated_query =
+      query
+      |> paginate(page, page_size)
+
+    count =
+      query
+      |> Repo.aggregate(:count, :id)
+
+    {:ok, Repo.all(paginated_query), count}
   end
 
-  def count_all_except_one(user) do
-    query =
-      from(
-        u in User,
-        where: u.id != ^user.id
-      )
+  def search(query, resolve \\ false, for_user \\ nil) do
+    # Strip the beginning @ off if there is a query
+    query = String.trim_leading(query, "@")
 
-    Repo.aggregate(query, :count, :id)
+    if resolve, do: get_or_fetch(query)
+
+    fts_results = do_search(fts_search_subquery(query), for_user)
+
+    {:ok, trigram_results} =
+      Repo.transaction(fn ->
+        Ecto.Adapters.SQL.query(Repo, "select set_limit(0.25)", [])
+        do_search(trigram_search_subquery(query), for_user)
+      end)
+
+    Enum.uniq_by(fts_results ++ trigram_results, & &1.id)
   end
 
-  defp do_search(subquery, for_user, options) do
+  defp do_search(subquery, for_user, options \\ []) do
     q =
       from(
         s in subquery(subquery),
@@ -815,7 +822,7 @@ defmodule Pleroma.User do
     boost_search_results(results, for_user)
   end
 
-  defp fts_search_subquery(term, query) do
+  defp fts_search_subquery(term, query \\ User) do
     processed_query =
       term
       |> String.replace(~r/\W+/, " ")
@@ -855,9 +862,9 @@ defmodule Pleroma.User do
     )
   end
 
-  defp trigram_search_subquery(term, query) do
+  defp trigram_search_subquery(term) do
     from(
-      u in query,
+      u in User,
       select_merge: %{
         search_rank:
           fragment(
@@ -1024,17 +1031,13 @@ defmodule Pleroma.User do
     update_and_set_cache(cng)
   end
 
-  def maybe_local_user_query(local) when local == true do
-    local_user_query()
-  end
-
-  def maybe_local_user_query(local) when local == false do
-    User
+  def maybe_local_user_query(query, local) do
+    if local, do: local_user_query(query), else: query
   end
 
-  def local_user_query do
+  def local_user_query(query \\ User) do
     from(
-      u in User,
+      u in query,
       where: u.local == true,
       where: not is_nil(u.nickname)
     )
@@ -1326,4 +1329,11 @@ defmodule Pleroma.User do
     )
     |> Repo.all()
   end
+
+  defp paginate(query, page, page_size) do
+    from(u in query,
+      limit: ^page_size,
+      offset: ^((page - 1) * page_size)
+    )
+  end
 end