diff --git a/lib/philomena/comments/query.ex b/lib/philomena/comments/query.ex index 9e9c8986..49ec6d68 100644 --- a/lib/philomena/comments/query.ex +++ b/lib/philomena/comments/query.ex @@ -92,8 +92,8 @@ defmodule Philomena.Comments.Query do |> Parser.parse(query_string, context) end - def compile(user, query_string) do - query_string = query_string || "" + def compile(query_string, opts \\ []) do + user = Keyword.get(opts, :user) case user do nil -> diff --git a/lib/philomena/filters/query.ex b/lib/philomena/filters/query.ex index 3b6bb3ef..3460a459 100644 --- a/lib/philomena/filters/query.ex +++ b/lib/philomena/filters/query.ex @@ -33,8 +33,8 @@ defmodule Philomena.Filters.Query do |> Parser.parse(query_string, context) end - def compile(user, query_string) do - query_string = query_string || "" + def compile(query_string, opts \\ []) do + user = Keyword.get(opts, :user) case user do nil -> diff --git a/lib/philomena/galleries/query.ex b/lib/philomena/galleries/query.ex index e04ceecc..ddfa1e8b 100644 --- a/lib/philomena/galleries/query.ex +++ b/lib/philomena/galleries/query.ex @@ -15,8 +15,6 @@ defmodule Philomena.Galleries.Query do end def compile(query_string) do - query_string = query_string || "" - fields() |> Parser.new() |> Parser.parse(query_string) diff --git a/lib/philomena/images/query.ex b/lib/philomena/images/query.ex index 9eedcd74..74d1b835 100644 --- a/lib/philomena/images/query.ex +++ b/lib/philomena/images/query.ex @@ -144,8 +144,9 @@ defmodule Philomena.Images.Query do |> Parser.parse(query_string, context) end - def compile(user, query_string, watch \\ false) do - query_string = query_string || "" + def compile(query_string, opts \\ []) do + user = Keyword.get(opts, :user) + watch = Keyword.get(opts, :watch, false) case user do nil -> diff --git a/lib/philomena/posts/query.ex b/lib/philomena/posts/query.ex index 331655c7..58d94d6c 100644 --- a/lib/philomena/posts/query.ex +++ b/lib/philomena/posts/query.ex @@ -90,8 +90,8 @@ defmodule Philomena.Posts.Query do |> Parser.parse(query_string, context) end - def compile(user, query_string) do - query_string = query_string || "" + def compile(query_string, opts \\ []) do + user = Keyword.get(opts, :user) case user do nil -> diff --git a/lib/philomena/reports/query.ex b/lib/philomena/reports/query.ex index c9d9be44..e88e2172 100644 --- a/lib/philomena/reports/query.ex +++ b/lib/philomena/reports/query.ex @@ -17,6 +17,6 @@ defmodule Philomena.Reports.Query do def compile(query_string) do fields() |> Parser.new() - |> Parser.parse(query_string || "", %{}) + |> Parser.parse(query_string, %{}) end end diff --git a/lib/philomena/schema/search.ex b/lib/philomena/schema/search.ex index 9b4e7e08..819823f2 100644 --- a/lib/philomena/schema/search.ex +++ b/lib/philomena/schema/search.ex @@ -5,7 +5,7 @@ defmodule Philomena.Schema.Search do def validate_search(changeset, field, user, watched \\ false) do query = changeset |> get_field(field) |> String.normalize() - output = Query.compile(user, query, watched) + output = Query.compile(query, user: user, watch: watched) case output do {:ok, _} -> diff --git a/lib/philomena/tags/query.ex b/lib/philomena/tags/query.ex index da148da4..6af25454 100644 --- a/lib/philomena/tags/query.ex +++ b/lib/philomena/tags/query.ex @@ -20,6 +20,6 @@ defmodule Philomena.Tags.Query do def compile(query_string) do fields() |> Parser.new() - |> Parser.parse(query_string || "") + |> Parser.parse(query_string) end end diff --git a/lib/philomena_query/parse/parser.ex b/lib/philomena_query/parse/parser.ex index a89434d2..e615653f 100644 --- a/lib/philomena_query/parse/parser.ex +++ b/lib/philomena_query/parse/parser.ex @@ -184,18 +184,18 @@ defmodule PhilomenaQuery.Parse.Parser do @spec parse(t(), String.t(), context()) :: {:ok, query()} | {:error, String.t()} def parse(parser, input, context \\ nil) - # Empty search should emit a match_none. - def parse(_parser, "", _context) do - {:ok, %{match_none: %{}}} - end - def parse(%Parser{} = parser, input, context) do parser = %{parser | __data__: context} - with {:ok, tokens, _1, _2, _3, _4} <- Lexer.lex(input), + with {:ok, input} <- coerce_string(input), + {:ok, tokens, _1, _2, _3, _4} <- Lexer.lex(input), + {:ok, tokens} <- convert_empty_token_list(tokens), {:ok, {tree, []}} <- search_top(parser, tokens) do {:ok, tree} else + {:error, :empty_query} -> + {:ok, %{match_none: %{}}} + {:ok, {_tree, tokens}} -> {:error, "junk at end of expression: " <> debug_tokens(tokens)} @@ -211,6 +211,13 @@ defmodule PhilomenaQuery.Parse.Parser do end end + defp coerce_string(term) when is_binary(term), do: {:ok, term} + defp coerce_string(nil), do: {:ok, ""} + defp coerce_string(_), do: {:error, "search query is not a string"} + + defp convert_empty_token_list([]), do: {:error, :empty_query} + defp convert_empty_token_list(tokens), do: {:ok, tokens} + defp debug_tokens(tokens) do Enum.map_join(tokens, fn {_k, v} -> v end) end diff --git a/lib/philomena_web/controllers/api/json/search/comment_controller.ex b/lib/philomena_web/controllers/api/json/search/comment_controller.ex index 5dbe5e4c..6942a4ff 100644 --- a/lib/philomena_web/controllers/api/json/search/comment_controller.ex +++ b/lib/philomena_web/controllers/api/json/search/comment_controller.ex @@ -10,7 +10,7 @@ defmodule PhilomenaWeb.Api.Json.Search.CommentController do user = conn.assigns.current_user filter = conn.assigns.current_filter - case Query.compile(user, params["q"] || "") do + case Query.compile(params["q"], user: user) do {:ok, query} -> comments = Comment diff --git a/lib/philomena_web/controllers/api/json/search/filter_controller.ex b/lib/philomena_web/controllers/api/json/search/filter_controller.ex index 7b402065..7c4f81b5 100644 --- a/lib/philomena_web/controllers/api/json/search/filter_controller.ex +++ b/lib/philomena_web/controllers/api/json/search/filter_controller.ex @@ -9,7 +9,7 @@ defmodule PhilomenaWeb.Api.Json.Search.FilterController do def index(conn, params) do user = conn.assigns.current_user - case Query.compile(user, params["q"] || "") do + case Query.compile(params["q"], user: user) do {:ok, query} -> filters = Filter diff --git a/lib/philomena_web/controllers/api/json/search/gallery_controller.ex b/lib/philomena_web/controllers/api/json/search/gallery_controller.ex index 8b2f247b..e1b999bb 100644 --- a/lib/philomena_web/controllers/api/json/search/gallery_controller.ex +++ b/lib/philomena_web/controllers/api/json/search/gallery_controller.ex @@ -7,7 +7,7 @@ defmodule PhilomenaWeb.Api.Json.Search.GalleryController do import Ecto.Query def index(conn, params) do - case Query.compile(params["q"] || "") do + case Query.compile(params["q"]) do {:ok, query} -> galleries = Gallery diff --git a/lib/philomena_web/controllers/api/json/search/post_controller.ex b/lib/philomena_web/controllers/api/json/search/post_controller.ex index 919a5b13..c305de12 100644 --- a/lib/philomena_web/controllers/api/json/search/post_controller.ex +++ b/lib/philomena_web/controllers/api/json/search/post_controller.ex @@ -9,7 +9,7 @@ defmodule PhilomenaWeb.Api.Json.Search.PostController do def index(conn, params) do user = conn.assigns.current_user - case Query.compile(user, params["q"] || "") do + case Query.compile(params["q"], user: user) do {:ok, query} -> posts = Post diff --git a/lib/philomena_web/controllers/api/json/search/tag_controller.ex b/lib/philomena_web/controllers/api/json/search/tag_controller.ex index 8cdaf7f4..b860cf46 100644 --- a/lib/philomena_web/controllers/api/json/search/tag_controller.ex +++ b/lib/philomena_web/controllers/api/json/search/tag_controller.ex @@ -7,7 +7,7 @@ defmodule PhilomenaWeb.Api.Json.Search.TagController do import Ecto.Query def index(conn, params) do - case Query.compile(params["q"] || "") do + case Query.compile(params["q"]) do {:ok, query} -> tags = Tag diff --git a/lib/philomena_web/controllers/comment_controller.ex b/lib/philomena_web/controllers/comment_controller.ex index 99b14f25..d64f3e16 100644 --- a/lib/philomena_web/controllers/comment_controller.ex +++ b/lib/philomena_web/controllers/comment_controller.ex @@ -13,8 +13,8 @@ defmodule PhilomenaWeb.CommentController do conn = Map.put(conn, :params, params) user = conn.assigns.current_user - user - |> Query.compile(cq) + cq + |> Query.compile(user: user) |> render_index(conn, user) end diff --git a/lib/philomena_web/controllers/filter_controller.ex b/lib/philomena_web/controllers/filter_controller.ex index 61469ffd..cbe001da 100644 --- a/lib/philomena_web/controllers/filter_controller.ex +++ b/lib/philomena_web/controllers/filter_controller.ex @@ -13,8 +13,8 @@ defmodule PhilomenaWeb.FilterController do def index(conn, %{"fq" => fq}) do user = conn.assigns.current_user - user - |> Query.compile(fq) + fq + |> Query.compile(user: user) |> render_index(conn, user) end diff --git a/lib/philomena_web/controllers/image/navigate_controller.ex b/lib/philomena_web/controllers/image/navigate_controller.ex index 9cb61d48..13facfae 100644 --- a/lib/philomena_web/controllers/image/navigate_controller.ex +++ b/lib/philomena_web/controllers/image/navigate_controller.ex @@ -54,7 +54,10 @@ defmodule PhilomenaWeb.Image.NavigateController do defp compile_query(conn) do user = conn.assigns.current_user - {:ok, query} = Query.compile(user, match_all_if_blank(conn.params["q"])) + {:ok, query} = + conn.params["q"] + |> match_all_if_blank() + |> Query.compile(user: user) query end diff --git a/lib/philomena_web/controllers/post_controller.ex b/lib/philomena_web/controllers/post_controller.ex index 17b8fcd5..6f00ff7c 100644 --- a/lib/philomena_web/controllers/post_controller.ex +++ b/lib/philomena_web/controllers/post_controller.ex @@ -13,8 +13,8 @@ defmodule PhilomenaWeb.PostController do conn = Map.put(conn, :params, params) user = conn.assigns.current_user - user - |> Query.compile(pq) + pq + |> Query.compile(user: user) |> render_index(conn, user) end diff --git a/lib/philomena_web/controllers/tag_controller.ex b/lib/philomena_web/controllers/tag_controller.ex index 82ea790a..4900ddd3 100644 --- a/lib/philomena_web/controllers/tag_controller.ex +++ b/lib/philomena_web/controllers/tag_controller.ex @@ -121,7 +121,7 @@ defmodule PhilomenaWeb.TagController do |> String.trim() |> String.downcase() - case Images.Query.compile(nil, name) do + case Images.Query.compile(name) do {:ok, %{term: %{"namespaced_tags.name" => ^name}}} -> name diff --git a/lib/philomena_web/image_loader.ex b/lib/philomena_web/image_loader.ex index d2bc80ea..81271e05 100644 --- a/lib/philomena_web/image_loader.ex +++ b/lib/philomena_web/image_loader.ex @@ -11,7 +11,7 @@ defmodule PhilomenaWeb.ImageLoader do def search_string(conn, search_string, options \\ []) do user = conn.assigns.current_user - with {:ok, tree} <- Query.compile(user, search_string) do + with {:ok, tree} <- Query.compile(search_string, user: user) do {:ok, query(conn, tree, options)} else error -> diff --git a/lib/philomena_web/plugs/filter_forced_users_plug.ex b/lib/philomena_web/plugs/filter_forced_users_plug.ex index e28de969..d9881f96 100644 --- a/lib/philomena_web/plugs/filter_forced_users_plug.ex +++ b/lib/philomena_web/plugs/filter_forced_users_plug.ex @@ -6,7 +6,7 @@ defmodule PhilomenaWeb.FilterForcedUsersPlug do import Phoenix.Controller import Plug.Conn - alias PhilomenaQuery.Parse.String, as: SearchString + alias PhilomenaQuery.Parse.String alias PhilomenaQuery.Parse.Evaluator alias Philomena.Images.Query alias PhilomenaWeb.ImageView @@ -53,7 +53,10 @@ defmodule PhilomenaWeb.FilterForcedUsersPlug do end defp compile_filter(user, search_string) do - case Query.compile(user, SearchString.normalize(search_string)) do + search_string + |> String.normalize() + |> Query.compile(user: user) + |> case do {:ok, query} -> query _error -> %{match_all: %{}} end diff --git a/lib/philomena_web/plugs/image_filter_plug.ex b/lib/philomena_web/plugs/image_filter_plug.ex index c8138d68..a6d46187 100644 --- a/lib/philomena_web/plugs/image_filter_plug.ex +++ b/lib/philomena_web/plugs/image_filter_plug.ex @@ -1,7 +1,6 @@ defmodule PhilomenaWeb.ImageFilterPlug do import Plug.Conn - import PhilomenaQuery.Parse.String - + alias PhilomenaQuery.Parse.String alias Philomena.Images.Query # No options @@ -50,7 +49,10 @@ defmodule PhilomenaWeb.ImageFilterPlug do end defp invalid_filter_guard(user, search_string) do - case Query.compile(user, normalize(search_string)) do + search_string + |> String.normalize() + |> Query.compile(user: user) + |> case do {:ok, query} -> query _error -> %{match_all: %{}} end