mirror of
https://github.com/ash-project/ash_postgres.git
synced 2024-09-19 21:13:19 +12:00
improvement: add like and ilike
This commit is contained in:
parent
5a9abdc69c
commit
09b19c8bfd
5 changed files with 94 additions and 2 deletions
|
@ -625,7 +625,11 @@ defmodule AshPostgres.DataLayer do
|
|||
def functions(resource) do
|
||||
config = AshPostgres.DataLayer.Info.repo(resource).config()
|
||||
|
||||
functions = [AshPostgres.Functions.Fragment]
|
||||
functions = [
|
||||
AshPostgres.Functions.Fragment,
|
||||
AshPostgres.Functions.Like,
|
||||
AshPostgres.Functions.ILike
|
||||
]
|
||||
|
||||
if "pg_trgm" in (config[:installed_extensions] || []) do
|
||||
functions ++
|
||||
|
|
30
lib/expr.ex
30
lib/expr.ex
|
@ -5,7 +5,7 @@ defmodule AshPostgres.Expr do
|
|||
alias Ash.Query.{BooleanExpression, Exists, Not, Ref}
|
||||
alias Ash.Query.Operator.IsNil
|
||||
alias Ash.Query.Function.{Ago, Contains, GetPath, If, Length, Now, Type}
|
||||
alias AshPostgres.Functions.{Fragment, TrigramSimilarity}
|
||||
alias AshPostgres.Functions.{Fragment, ILike, Like, TrigramSimilarity}
|
||||
|
||||
require Ecto.Query
|
||||
|
||||
|
@ -51,6 +51,34 @@ defmodule AshPostgres.Expr do
|
|||
|> maybe_type(type, query)
|
||||
end
|
||||
|
||||
defp do_dynamic_expr(
|
||||
query,
|
||||
%Like{arguments: [arg1, arg2], embedded?: pred_embedded?},
|
||||
bindings,
|
||||
embedded?,
|
||||
type
|
||||
) do
|
||||
arg1 = do_dynamic_expr(query, arg1, bindings, pred_embedded? || embedded?)
|
||||
arg2 = do_dynamic_expr(query, arg2, bindings, pred_embedded? || embedded?)
|
||||
|
||||
Ecto.Query.dynamic(like(^arg1, ^arg2))
|
||||
|> maybe_type(type, query)
|
||||
end
|
||||
|
||||
defp do_dynamic_expr(
|
||||
query,
|
||||
%ILike{arguments: [arg1, arg2], embedded?: pred_embedded?},
|
||||
bindings,
|
||||
embedded?,
|
||||
type
|
||||
) do
|
||||
arg1 = do_dynamic_expr(query, arg1, bindings, pred_embedded? || embedded?)
|
||||
arg2 = do_dynamic_expr(query, arg2, bindings, pred_embedded? || embedded?)
|
||||
|
||||
Ecto.Query.dynamic(ilike(^arg1, ^arg2))
|
||||
|> maybe_type(type, query)
|
||||
end
|
||||
|
||||
defp do_dynamic_expr(
|
||||
query,
|
||||
%IsNil{left: left, right: right, embedded?: pred_embedded?},
|
||||
|
|
9
lib/functions/ilike.ex
Normal file
9
lib/functions/ilike.ex
Normal file
|
@ -0,0 +1,9 @@
|
|||
defmodule AshPostgres.Functions.ILike do
|
||||
@moduledoc """
|
||||
Maps to the builtin postgres function `ilike`.
|
||||
"""
|
||||
|
||||
use Ash.Query.Function, name: :ilike
|
||||
|
||||
def args, do: [[:string, :string]]
|
||||
end
|
9
lib/functions/like.ex
Normal file
9
lib/functions/like.ex
Normal file
|
@ -0,0 +1,9 @@
|
|||
defmodule AshPostgres.Functions.Like do
|
||||
@moduledoc """
|
||||
Maps to the builtin postgres function `like`.
|
||||
"""
|
||||
|
||||
use Ash.Query.Function, name: :like
|
||||
|
||||
def args, do: [[:string, :string]]
|
||||
end
|
|
@ -773,6 +773,48 @@ defmodule AshPostgres.FilterTest do
|
|||
end
|
||||
end
|
||||
|
||||
describe "like and ilike" do
|
||||
test "like builds and matches" do
|
||||
Post
|
||||
|> Ash.Changeset.new(%{title: "MaTcH"})
|
||||
|> Api.create!()
|
||||
|
||||
results =
|
||||
Post
|
||||
|> Ash.Query.filter(like(title, "%aTc%"))
|
||||
|> Api.read!()
|
||||
|
||||
assert [%Post{title: "MaTcH"}] = results
|
||||
|
||||
results =
|
||||
Post
|
||||
|> Ash.Query.filter(like(title, "%atc%"))
|
||||
|> Api.read!()
|
||||
|
||||
assert [] = results
|
||||
end
|
||||
|
||||
test "ilike builds and matches" do
|
||||
Post
|
||||
|> Ash.Changeset.new(%{title: "MaTcH"})
|
||||
|> Api.create!()
|
||||
|
||||
results =
|
||||
Post
|
||||
|> Ash.Query.filter(ilike(title, "%aTc%"))
|
||||
|> Api.read!()
|
||||
|
||||
assert [%Post{title: "MaTcH"}] = results
|
||||
|
||||
results =
|
||||
Post
|
||||
|> Ash.Query.filter(ilike(title, "%atc%"))
|
||||
|> Api.read!()
|
||||
|
||||
assert [%Post{title: "MaTcH"}] = results
|
||||
end
|
||||
end
|
||||
|
||||
describe "trigram_similarity" do
|
||||
test "it works on matches" do
|
||||
Post
|
||||
|
|
Loading…
Reference in a new issue