mirror of
https://github.com/ash-project/ash_sqlite.git
synced 2024-09-19 12:52:50 +12:00
improvement: clean ups, remove operators that don't make sense for sqlite
This commit is contained in:
parent
ea9c3faccd
commit
9caf99844b
8 changed files with 234 additions and 385 deletions
|
@ -322,7 +322,7 @@ defmodule AshSqlite.DataLayer do
|
|||
Mix.Task.run("ash_sqlite.drop", args)
|
||||
end
|
||||
|
||||
import Ecto.Query, only: [from: 2, subquery: 1]
|
||||
import Ecto.Query, only: [from: 2]
|
||||
|
||||
@impl true
|
||||
def can?(_, :async_engine), do: false
|
||||
|
|
220
lib/expr.ex
220
lib/expr.ex
|
@ -7,17 +7,13 @@ defmodule AshSqlite.Expr do
|
|||
|
||||
alias Ash.Query.Function.{
|
||||
Ago,
|
||||
At,
|
||||
Contains,
|
||||
DateAdd,
|
||||
DateTimeAdd,
|
||||
FromNow,
|
||||
GetPath,
|
||||
If,
|
||||
Length,
|
||||
Now,
|
||||
StringJoin,
|
||||
StringSplit,
|
||||
Today,
|
||||
Type
|
||||
}
|
||||
|
@ -232,29 +228,6 @@ defmodule AshSqlite.Expr do
|
|||
)
|
||||
end
|
||||
|
||||
defp do_dynamic_expr(
|
||||
query,
|
||||
%Length{arguments: [list], embedded?: pred_embedded?},
|
||||
bindings,
|
||||
embedded?,
|
||||
type
|
||||
) do
|
||||
do_dynamic_expr(
|
||||
query,
|
||||
%Fragment{
|
||||
embedded?: pred_embedded?,
|
||||
arguments: [
|
||||
raw: "array_length((",
|
||||
expr: list,
|
||||
raw: "), 1)"
|
||||
]
|
||||
},
|
||||
bindings,
|
||||
embedded?,
|
||||
type
|
||||
)
|
||||
end
|
||||
|
||||
defp do_dynamic_expr(
|
||||
query,
|
||||
%If{arguments: [condition, when_true, when_false], embedded?: pred_embedded?},
|
||||
|
@ -319,82 +292,101 @@ defmodule AshSqlite.Expr do
|
|||
)
|
||||
end
|
||||
|
||||
defp do_dynamic_expr(
|
||||
query,
|
||||
%StringJoin{arguments: [values, joiner], embedded?: pred_embedded?},
|
||||
bindings,
|
||||
embedded?,
|
||||
type
|
||||
) do
|
||||
do_dynamic_expr(
|
||||
query,
|
||||
%Fragment{
|
||||
embedded?: pred_embedded?,
|
||||
arguments:
|
||||
Enum.reduce(values, [raw: "(concat_ws(", expr: joiner], fn value, acc ->
|
||||
acc ++ [raw: ", ", expr: value]
|
||||
end) ++ [raw: "))"]
|
||||
},
|
||||
bindings,
|
||||
embedded?,
|
||||
type
|
||||
)
|
||||
end
|
||||
# Wow, even this doesn't work, because of course it doesn't.
|
||||
# Doing string joining properly requires a recursive "if not empty" check
|
||||
# that honestly I don't have the energy to do right now.
|
||||
# There are commented out tests for this in the calculation tests, make sure those pass, whoever feels like fixing this.
|
||||
# defp do_dynamic_expr(
|
||||
# _query,
|
||||
# %StringJoin{arguments: [values | _], embedded?: _pred_embedded?} = string_join,
|
||||
# _bindings,
|
||||
# _embedded?,
|
||||
# _type
|
||||
# )
|
||||
# when not is_list(values) do
|
||||
# raise "SQLite can only join literal lists, not dynamic values. i.e `string_join([foo, bar])`, but not `string_join(something)`. Got #{inspect(string_join)}"
|
||||
# end
|
||||
|
||||
defp do_dynamic_expr(
|
||||
query,
|
||||
%StringSplit{arguments: [string, delimiter, options], embedded?: pred_embedded?},
|
||||
bindings,
|
||||
embedded?,
|
||||
type
|
||||
) do
|
||||
if options[:trim?] do
|
||||
raise "trim?: true not supported by AshSqlite"
|
||||
else
|
||||
do_dynamic_expr(
|
||||
query,
|
||||
%Fragment{
|
||||
embedded?: pred_embedded?,
|
||||
arguments: [
|
||||
raw: "string_to_array(",
|
||||
expr: string,
|
||||
raw: ", NULLIF(",
|
||||
expr: delimiter,
|
||||
raw: ", ''))"
|
||||
]
|
||||
},
|
||||
bindings,
|
||||
embedded?,
|
||||
type
|
||||
)
|
||||
end
|
||||
end
|
||||
# defp do_dynamic_expr(
|
||||
# query,
|
||||
# %StringJoin{arguments: [values, joiner], embedded?: pred_embedded?},
|
||||
# bindings,
|
||||
# embedded?,
|
||||
# type
|
||||
# ) do
|
||||
# # Not optimal, but it works
|
||||
# last_value = :lists.last(values)
|
||||
|
||||
defp do_dynamic_expr(
|
||||
query,
|
||||
%StringJoin{arguments: [values], embedded?: pred_embedded?},
|
||||
bindings,
|
||||
embedded?,
|
||||
type
|
||||
) do
|
||||
do_dynamic_expr(
|
||||
query,
|
||||
%Fragment{
|
||||
embedded?: pred_embedded?,
|
||||
arguments:
|
||||
[raw: "(concat("] ++
|
||||
(values
|
||||
|> Enum.reduce([], fn value, acc ->
|
||||
acc ++ [expr: value]
|
||||
end)
|
||||
|> Enum.intersperse({:raw, ", "})) ++
|
||||
[raw: "))"]
|
||||
},
|
||||
bindings,
|
||||
embedded?,
|
||||
type
|
||||
)
|
||||
end
|
||||
# values =
|
||||
# values
|
||||
# |> :lists.droplast()
|
||||
# |> Enum.map(&{:not_last, &1})
|
||||
# |> Enum.concat([{:last, last_value}])
|
||||
|
||||
# do_dynamic_expr(
|
||||
# query,
|
||||
# %Fragment{
|
||||
# embedded?: pred_embedded?,
|
||||
# arguments:
|
||||
# Enum.reduce(values, [raw: "("], fn
|
||||
# {:last, value}, acc ->
|
||||
# acc ++
|
||||
# [
|
||||
# raw: "COALESCE(",
|
||||
# expr: value,
|
||||
# raw: ", '')"
|
||||
# ]
|
||||
|
||||
# {:not_last, value}, acc ->
|
||||
# acc ++
|
||||
# [
|
||||
# raw: "(CASE ",
|
||||
# expr: value,
|
||||
# raw: " WHEN NULL THEN '' ELSE ",
|
||||
# expr: value,
|
||||
# raw: " || ",
|
||||
# expr: joiner,
|
||||
# raw: " END) || "
|
||||
# ]
|
||||
# end)
|
||||
# |> Enum.concat(raw: ")")
|
||||
# },
|
||||
# bindings,
|
||||
# embedded?,
|
||||
# type
|
||||
# )
|
||||
# end
|
||||
|
||||
# defp do_dynamic_expr(
|
||||
# query,
|
||||
# %StringJoin{arguments: [values], embedded?: pred_embedded?},
|
||||
# bindings,
|
||||
# embedded?,
|
||||
# type
|
||||
# ) do
|
||||
# do_dynamic_expr(
|
||||
# query,
|
||||
# %Fragment{
|
||||
# embedded?: pred_embedded?,
|
||||
# arguments:
|
||||
# Enum.reduce(values, {[raw: "("], true}, fn value, {acc, first?} ->
|
||||
# add =
|
||||
# if first? do
|
||||
# [expr: value]
|
||||
# else
|
||||
# [raw: " || COALESCE(", expr: value, raw: ", '')"]
|
||||
# end
|
||||
|
||||
# {acc ++ add, false}
|
||||
# end)
|
||||
# |> elem(0)
|
||||
# |> Enum.concat(raw: ")")
|
||||
# },
|
||||
# bindings,
|
||||
# embedded?,
|
||||
# type
|
||||
# )
|
||||
# end
|
||||
|
||||
# Sorry :(
|
||||
# This is bad to do, but is the only reasonable way I could find.
|
||||
|
@ -642,23 +634,21 @@ defmodule AshSqlite.Expr do
|
|||
|
||||
defp do_dynamic_expr(
|
||||
query,
|
||||
%Ash.CiString{string: string} = expression,
|
||||
%Ash.CiString{string: string},
|
||||
bindings,
|
||||
embedded?,
|
||||
type
|
||||
) do
|
||||
string = do_dynamic_expr(query, string, bindings, embedded?)
|
||||
|
||||
require_extension!(query, "citext", expression)
|
||||
|
||||
do_dynamic_expr(
|
||||
query,
|
||||
%Fragment{
|
||||
embedded?: embedded?,
|
||||
arguments: [
|
||||
raw: "",
|
||||
raw: "(",
|
||||
casted_expr: string,
|
||||
raw: "::citext"
|
||||
raw: "collate nocase)"
|
||||
]
|
||||
},
|
||||
bindings,
|
||||
|
@ -842,6 +832,10 @@ defmodule AshSqlite.Expr do
|
|||
embedded?,
|
||||
type
|
||||
) do
|
||||
if !bindings[:parent_bindings] do
|
||||
raise "Used `parent/1` without parent context. AshSqlite is not capable of supporting `parent/1` in relationship where clauses yet."
|
||||
end
|
||||
|
||||
parent? = Map.get(bindings.parent_bindings, :parent_is_parent_as?, true)
|
||||
|
||||
do_dynamic_expr(
|
||||
|
@ -1071,7 +1065,6 @@ defmodule AshSqlite.Expr do
|
|||
if is_list(other) do
|
||||
list_expr(query, other, bindings, true, type)
|
||||
else
|
||||
IO.inspect(other, structs: false)
|
||||
raise "Unsupported expression in AshSqlite query: #{inspect(other)}"
|
||||
end
|
||||
else
|
||||
|
@ -1223,7 +1216,7 @@ defmodule AshSqlite.Expr do
|
|||
embedded?: pred_embedded?,
|
||||
arguments:
|
||||
[
|
||||
raw: "jsonb_extract_path(",
|
||||
raw: "json_extract(",
|
||||
expr: left,
|
||||
raw: ","
|
||||
] ++ path_frags
|
||||
|
@ -1241,17 +1234,6 @@ defmodule AshSqlite.Expr do
|
|||
end
|
||||
end
|
||||
|
||||
defp require_extension!(query, extension, context) do
|
||||
repo = AshSqlite.DataLayer.Info.repo(query.__ash_bindings__.resource)
|
||||
|
||||
unless extension in repo.installed_extensions() do
|
||||
raise Ash.Error.Query.InvalidExpression,
|
||||
expression: context,
|
||||
message:
|
||||
"The #{extension} extension needs to be installed before #{inspect(context)} can be used. Please add \"#{extension}\" to the list of installed_extensions in #{inspect(repo)}."
|
||||
end
|
||||
end
|
||||
|
||||
defp determine_type_at_path(type, path) do
|
||||
path
|
||||
|> Enum.reject(&is_integer/1)
|
||||
|
|
|
@ -425,7 +425,6 @@ defmodule AshSqlite.Join do
|
|||
# Ash.Resource.Info.primary_key(joined_query.__ash_bindings__.resource)
|
||||
# )
|
||||
# )
|
||||
# |> IO.inspect()
|
||||
# else
|
||||
joined_query
|
||||
# end
|
||||
|
|
|
@ -3,7 +3,6 @@ defmodule AshSqlite.CalculationTest do
|
|||
alias AshSqlite.Test.{Account, Api, Author, Comment, Post, User}
|
||||
|
||||
require Ash.Query
|
||||
import Ash.Expr
|
||||
|
||||
test "calculations can refer to embedded attributes" do
|
||||
author =
|
||||
|
@ -185,105 +184,50 @@ defmodule AshSqlite.CalculationTest do
|
|||
assert account.active
|
||||
end
|
||||
|
||||
describe "string join expression" do
|
||||
test "no nil values" do
|
||||
author =
|
||||
Author
|
||||
|> Ash.Changeset.for_create(:create, %{
|
||||
first_name: "Bill",
|
||||
last_name: "Jones",
|
||||
bio: %{title: "Mr.", bio: "Bones"}
|
||||
})
|
||||
|> Api.create!()
|
||||
# describe "string join expression" do
|
||||
# test "no nil values" do
|
||||
# author =
|
||||
# Author
|
||||
# |> Ash.Changeset.for_create(:create, %{
|
||||
# first_name: "Bill",
|
||||
# last_name: "Jones",
|
||||
# bio: %{title: "Mr.", bio: "Bones"}
|
||||
# })
|
||||
# |> Api.create!()
|
||||
|
||||
assert %{
|
||||
full_name_with_nils: "Bill Jones",
|
||||
full_name_with_nils_no_joiner: "BillJones"
|
||||
} =
|
||||
Author
|
||||
|> Ash.Query.filter(id == ^author.id)
|
||||
|> Ash.Query.load(:full_name_with_nils)
|
||||
|> Ash.Query.load(:full_name_with_nils_no_joiner)
|
||||
|> Api.read_one!()
|
||||
end
|
||||
# assert %{
|
||||
# full_name_with_nils: "Bill Jones",
|
||||
# full_name_with_nils_no_joiner: "BillJones"
|
||||
# } =
|
||||
# Author
|
||||
# |> Ash.Query.filter(id == ^author.id)
|
||||
# |> Ash.Query.load(:full_name_with_nils)
|
||||
# |> Ash.Query.load(:full_name_with_nils_no_joiner)
|
||||
# |> Api.read_one!()
|
||||
# end
|
||||
|
||||
test "with nil value" do
|
||||
author =
|
||||
Author
|
||||
|> Ash.Changeset.for_create(:create, %{
|
||||
first_name: "Bill",
|
||||
bio: %{title: "Mr.", bio: "Bones"}
|
||||
})
|
||||
|> Api.create!()
|
||||
# test "with nil value" do
|
||||
# author =
|
||||
# Author
|
||||
# |> Ash.Changeset.for_create(:create, %{
|
||||
# first_name: "Bill",
|
||||
# bio: %{title: "Mr.", bio: "Bones"}
|
||||
# })
|
||||
# |> Api.create!()
|
||||
|
||||
assert %{
|
||||
full_name_with_nils: "Bill",
|
||||
full_name_with_nils_no_joiner: "Bill"
|
||||
} =
|
||||
Author
|
||||
|> Ash.Query.filter(id == ^author.id)
|
||||
|> Ash.Query.load(:full_name_with_nils)
|
||||
|> Ash.Query.load(:full_name_with_nils_no_joiner)
|
||||
|> Api.read_one!()
|
||||
end
|
||||
end
|
||||
# Logger.configure(level: :debug)
|
||||
|
||||
test "arguments with cast_in_query?: false are not cast" do
|
||||
Post
|
||||
|> Ash.Changeset.new(%{title: "match", score: 42})
|
||||
|> Api.create!()
|
||||
|
||||
Post
|
||||
|> Ash.Changeset.new(%{title: "not", score: 42})
|
||||
|> Api.create!()
|
||||
|
||||
assert [post] =
|
||||
Post
|
||||
|> Ash.Query.filter(similarity(search: expr(query(search: "match"))))
|
||||
|> Api.read!()
|
||||
|
||||
assert post.title == "match"
|
||||
end
|
||||
|
||||
describe "string split expression" do
|
||||
test "with the default delimiter" do
|
||||
author =
|
||||
Author
|
||||
|> Ash.Changeset.for_create(:create, %{
|
||||
first_name: "Bill",
|
||||
last_name: "Jones",
|
||||
bio: %{title: "Mr.", bio: "Bones"}
|
||||
})
|
||||
|> Api.create!()
|
||||
|
||||
assert %{
|
||||
split_full_name: ["Bill", "Jones"]
|
||||
} =
|
||||
Author
|
||||
|> Ash.Query.filter(id == ^author.id)
|
||||
|> Ash.Query.load(:split_full_name)
|
||||
|> Api.read_one!()
|
||||
end
|
||||
|
||||
test "trimming whitespace" do
|
||||
author =
|
||||
Author
|
||||
|> Ash.Changeset.for_create(:create, %{
|
||||
first_name: "Bill ",
|
||||
last_name: "Jones ",
|
||||
bio: %{title: "Mr.", bio: "Bones"}
|
||||
})
|
||||
|> Api.create!()
|
||||
|
||||
assert %{
|
||||
split_full_name: ["Bill", "Jones"]
|
||||
} =
|
||||
Author
|
||||
|> Ash.Query.filter(id == ^author.id)
|
||||
|> Ash.Query.load([:split_full_name])
|
||||
|> Api.read_one!()
|
||||
end
|
||||
end
|
||||
# assert %{
|
||||
# full_name_with_nils: "Bill",
|
||||
# full_name_with_nils_no_joiner: "Bill"
|
||||
# } =
|
||||
# Author
|
||||
# |> Ash.Query.filter(id == ^author.id)
|
||||
# |> Ash.Query.load(:full_name_with_nils)
|
||||
# |> Ash.Query.load(:full_name_with_nils_no_joiner)
|
||||
# |> Api.read_one!()
|
||||
# end
|
||||
# end
|
||||
|
||||
describe "-/1" do
|
||||
test "makes numbers negative" do
|
||||
|
|
|
@ -474,79 +474,6 @@ defmodule AshSqlite.FilterTest do
|
|||
end
|
||||
end
|
||||
|
||||
describe "length/1" do
|
||||
test "it works with a list attribute" do
|
||||
author1 =
|
||||
Author
|
||||
|> Ash.Changeset.new(%{badges: [:author_of_the_year]})
|
||||
|> Api.create!()
|
||||
|
||||
_author2 =
|
||||
Author
|
||||
|> Ash.Changeset.new(%{badges: []})
|
||||
|> Api.create!()
|
||||
|
||||
author1_id = author1.id
|
||||
|
||||
assert [%{id: ^author1_id}] =
|
||||
Author
|
||||
|> Ash.Query.filter(length(badges) > 0)
|
||||
|> Api.read!()
|
||||
end
|
||||
|
||||
test "it works with nil" do
|
||||
author1 =
|
||||
Author
|
||||
|> Ash.Changeset.new(%{badges: [:author_of_the_year]})
|
||||
|> Api.create!()
|
||||
|
||||
_author2 =
|
||||
Author
|
||||
|> Ash.Changeset.new()
|
||||
|> Api.create!()
|
||||
|
||||
author1_id = author1.id
|
||||
|
||||
assert [%{id: ^author1_id}] =
|
||||
Author
|
||||
|> Ash.Query.filter(length(badges || []) > 0)
|
||||
|> Api.read!()
|
||||
end
|
||||
|
||||
test "it works with a list" do
|
||||
author1 =
|
||||
Author
|
||||
|> Ash.Changeset.new()
|
||||
|> Api.create!()
|
||||
|
||||
author1_id = author1.id
|
||||
|
||||
explicit_list = [:foo]
|
||||
|
||||
assert [%{id: ^author1_id}] =
|
||||
Author
|
||||
|> Ash.Query.filter(length(^explicit_list) > 0)
|
||||
|> Api.read!()
|
||||
|
||||
assert [] =
|
||||
Author
|
||||
|> Ash.Query.filter(length(^explicit_list) > 1)
|
||||
|> Api.read!()
|
||||
end
|
||||
|
||||
test "it raises with bad values" do
|
||||
Author
|
||||
|> Ash.Changeset.new()
|
||||
|> Api.create!()
|
||||
|
||||
assert_raise(Ash.Error.Unknown, fn ->
|
||||
Author
|
||||
|> Ash.Query.filter(length(first_name) > 0)
|
||||
|> Api.read!()
|
||||
end)
|
||||
end
|
||||
end
|
||||
|
||||
describe "exists/2" do
|
||||
test "it works with single relationships" do
|
||||
post =
|
||||
|
|
|
@ -106,115 +106,117 @@ defmodule AshSqlite.Test.LoadTest do
|
|||
end
|
||||
|
||||
describe "lateral join loads" do
|
||||
test "parent references are resolved" do
|
||||
post1 =
|
||||
Post
|
||||
|> Ash.Changeset.new(%{title: "title"})
|
||||
|> Api.create!()
|
||||
# uncomment when lateral join is supported
|
||||
# it does not necessarily have to be implemented *exactly* as lateral join
|
||||
# test "parent references are resolved" do
|
||||
# post1 =
|
||||
# Post
|
||||
# |> Ash.Changeset.new(%{title: "title"})
|
||||
# |> Api.create!()
|
||||
|
||||
post2 =
|
||||
Post
|
||||
|> Ash.Changeset.new(%{title: "title"})
|
||||
|> Api.create!()
|
||||
# post2 =
|
||||
# Post
|
||||
# |> Ash.Changeset.new(%{title: "title"})
|
||||
# |> Api.create!()
|
||||
|
||||
post2_id = post2.id
|
||||
# post2_id = post2.id
|
||||
|
||||
post3 =
|
||||
Post
|
||||
|> Ash.Changeset.new(%{title: "no match"})
|
||||
|> Api.create!()
|
||||
# post3 =
|
||||
# Post
|
||||
# |> Ash.Changeset.new(%{title: "no match"})
|
||||
# |> Api.create!()
|
||||
|
||||
assert [%{posts_with_matching_title: [%{id: ^post2_id}]}] =
|
||||
Post
|
||||
|> Ash.Query.load(:posts_with_matching_title)
|
||||
|> Ash.Query.filter(id == ^post1.id)
|
||||
|> Api.read!()
|
||||
# assert [%{posts_with_matching_title: [%{id: ^post2_id}]}] =
|
||||
# Post
|
||||
# |> Ash.Query.load(:posts_with_matching_title)
|
||||
# |> Ash.Query.filter(id == ^post1.id)
|
||||
# |> Api.read!()
|
||||
|
||||
assert [%{posts_with_matching_title: []}] =
|
||||
Post
|
||||
|> Ash.Query.load(:posts_with_matching_title)
|
||||
|> Ash.Query.filter(id == ^post3.id)
|
||||
|> Api.read!()
|
||||
end
|
||||
# assert [%{posts_with_matching_title: []}] =
|
||||
# Post
|
||||
# |> Ash.Query.load(:posts_with_matching_title)
|
||||
# |> Ash.Query.filter(id == ^post3.id)
|
||||
# |> Api.read!()
|
||||
# end
|
||||
|
||||
test "parent references work when joining for filters" do
|
||||
%{id: post1_id} =
|
||||
Post
|
||||
|> Ash.Changeset.new(%{title: "title"})
|
||||
|> Api.create!()
|
||||
# test "parent references work when joining for filters" do
|
||||
# %{id: post1_id} =
|
||||
# Post
|
||||
# |> Ash.Changeset.new(%{title: "title"})
|
||||
# |> Api.create!()
|
||||
|
||||
post2 =
|
||||
Post
|
||||
|> Ash.Changeset.new(%{title: "title"})
|
||||
|> Api.create!()
|
||||
# post2 =
|
||||
# Post
|
||||
# |> Ash.Changeset.new(%{title: "title"})
|
||||
# |> Api.create!()
|
||||
|
||||
Post
|
||||
|> Ash.Changeset.new(%{title: "no match"})
|
||||
|> Api.create!()
|
||||
# Post
|
||||
# |> Ash.Changeset.new(%{title: "no match"})
|
||||
# |> Api.create!()
|
||||
|
||||
Post
|
||||
|> Ash.Changeset.new(%{title: "no match"})
|
||||
|> Api.create!()
|
||||
# Post
|
||||
# |> Ash.Changeset.new(%{title: "no match"})
|
||||
# |> Api.create!()
|
||||
|
||||
assert [%{id: ^post1_id}] =
|
||||
Post
|
||||
|> Ash.Query.filter(posts_with_matching_title.id == ^post2.id)
|
||||
|> Api.read!()
|
||||
end
|
||||
# assert [%{id: ^post1_id}] =
|
||||
# Post
|
||||
# |> Ash.Query.filter(posts_with_matching_title.id == ^post2.id)
|
||||
# |> Api.read!()
|
||||
# end
|
||||
|
||||
test "lateral join loads (loads with limits or offsets) are supported" do
|
||||
assert %Post{comments: %Ash.NotLoaded{type: :relationship}} =
|
||||
post =
|
||||
Post
|
||||
|> Ash.Changeset.new(%{title: "title"})
|
||||
|> Api.create!()
|
||||
# test "lateral join loads (loads with limits or offsets) are supported" do
|
||||
# assert %Post{comments: %Ash.NotLoaded{type: :relationship}} =
|
||||
# post =
|
||||
# Post
|
||||
# |> Ash.Changeset.new(%{title: "title"})
|
||||
# |> Api.create!()
|
||||
|
||||
Comment
|
||||
|> Ash.Changeset.new(%{title: "abc"})
|
||||
|> Ash.Changeset.manage_relationship(:post, post, type: :append_and_remove)
|
||||
|> Api.create!()
|
||||
# Comment
|
||||
# |> Ash.Changeset.new(%{title: "abc"})
|
||||
# |> Ash.Changeset.manage_relationship(:post, post, type: :append_and_remove)
|
||||
# |> Api.create!()
|
||||
|
||||
Comment
|
||||
|> Ash.Changeset.new(%{title: "def"})
|
||||
|> Ash.Changeset.manage_relationship(:post, post, type: :append_and_remove)
|
||||
|> Api.create!()
|
||||
# Comment
|
||||
# |> Ash.Changeset.new(%{title: "def"})
|
||||
# |> Ash.Changeset.manage_relationship(:post, post, type: :append_and_remove)
|
||||
# |> Api.create!()
|
||||
|
||||
comments_query =
|
||||
Comment
|
||||
|> Ash.Query.limit(1)
|
||||
|> Ash.Query.sort(:title)
|
||||
# comments_query =
|
||||
# Comment
|
||||
# |> Ash.Query.limit(1)
|
||||
# |> Ash.Query.sort(:title)
|
||||
|
||||
results =
|
||||
Post
|
||||
|> Ash.Query.load(comments: comments_query)
|
||||
|> Api.read!()
|
||||
# results =
|
||||
# Post
|
||||
# |> Ash.Query.load(comments: comments_query)
|
||||
# |> Api.read!()
|
||||
|
||||
assert [%Post{comments: [%{title: "abc"}]}] = results
|
||||
# assert [%Post{comments: [%{title: "abc"}]}] = results
|
||||
|
||||
comments_query =
|
||||
Comment
|
||||
|> Ash.Query.limit(1)
|
||||
|> Ash.Query.sort(title: :desc)
|
||||
# comments_query =
|
||||
# Comment
|
||||
# |> Ash.Query.limit(1)
|
||||
# |> Ash.Query.sort(title: :desc)
|
||||
|
||||
results =
|
||||
Post
|
||||
|> Ash.Query.load(comments: comments_query)
|
||||
|> Api.read!()
|
||||
# results =
|
||||
# Post
|
||||
# |> Ash.Query.load(comments: comments_query)
|
||||
# |> Api.read!()
|
||||
|
||||
assert [%Post{comments: [%{title: "def"}]}] = results
|
||||
# assert [%Post{comments: [%{title: "def"}]}] = results
|
||||
|
||||
comments_query =
|
||||
Comment
|
||||
|> Ash.Query.limit(2)
|
||||
|> Ash.Query.sort(title: :desc)
|
||||
# comments_query =
|
||||
# Comment
|
||||
# |> Ash.Query.limit(2)
|
||||
# |> Ash.Query.sort(title: :desc)
|
||||
|
||||
results =
|
||||
Post
|
||||
|> Ash.Query.load(comments: comments_query)
|
||||
|> Api.read!()
|
||||
# results =
|
||||
# Post
|
||||
# |> Ash.Query.load(comments: comments_query)
|
||||
# |> Api.read!()
|
||||
|
||||
assert [%Post{comments: [%{title: "def"}, %{title: "abc"}]}] = results
|
||||
end
|
||||
# assert [%Post{comments: [%{title: "def"}, %{title: "abc"}]}] = results
|
||||
# end
|
||||
|
||||
test "loading many to many relationships on records works without loading its join relationship when using code interface" do
|
||||
source_post =
|
||||
|
|
|
@ -28,9 +28,9 @@ defmodule AshSqlite.Test.Author do
|
|||
calculations do
|
||||
calculate(:title, :string, expr(bio[:title]))
|
||||
calculate(:full_name, :string, expr(first_name <> " " <> last_name))
|
||||
calculate(:full_name_with_nils, :string, expr(string_join([first_name, last_name], " ")))
|
||||
calculate(:full_name_with_nils_no_joiner, :string, expr(string_join([first_name, last_name])))
|
||||
calculate(:split_full_name, {:array, :string}, expr(string_split(full_name)))
|
||||
# calculate(:full_name_with_nils, :string, expr(string_join([first_name, last_name], " ")))
|
||||
# calculate(:full_name_with_nils_no_joiner, :string, expr(string_join([first_name, last_name])))
|
||||
# calculate(:split_full_name, {:array, :string}, expr(string_split(full_name)))
|
||||
|
||||
calculate(:first_name_or_bob, :string, expr(first_name || "bob"))
|
||||
calculate(:first_name_and_bob, :string, expr(first_name && "bob"))
|
||||
|
|
|
@ -98,11 +98,6 @@ defmodule AshSqlite.Test.Post do
|
|||
|
||||
belongs_to(:author, AshSqlite.Test.Author)
|
||||
|
||||
has_many :posts_with_matching_title, __MODULE__ do
|
||||
no_attributes?(true)
|
||||
filter(expr(parent(title) == title and parent(id) != id))
|
||||
end
|
||||
|
||||
has_many(:comments, AshSqlite.Test.Comment, destination_attribute: :post_id)
|
||||
|
||||
has_many :comments_matching_post_title, AshSqlite.Test.Comment do
|
||||
|
|
Loading…
Reference in a new issue