2023-09-23 14:52:22 +12:00
|
|
|
defmodule AshSqlite.BulkCreateTest do
|
|
|
|
use AshSqlite.RepoCase, async: false
|
2024-04-02 05:18:42 +13:00
|
|
|
alias AshSqlite.Test.Post
|
2023-09-23 14:52:22 +12:00
|
|
|
|
|
|
|
describe "bulk creates" do
|
|
|
|
test "bulk creates insert each input" do
|
2024-04-02 05:18:42 +13:00
|
|
|
Ash.bulk_create!([%{title: "fred"}, %{title: "george"}], Post, :create)
|
2023-09-23 14:52:22 +12:00
|
|
|
|
|
|
|
assert [%{title: "fred"}, %{title: "george"}] =
|
|
|
|
Post
|
|
|
|
|> Ash.Query.sort(:title)
|
2024-04-02 05:18:42 +13:00
|
|
|
|> Ash.read!()
|
2023-09-23 14:52:22 +12:00
|
|
|
end
|
|
|
|
|
|
|
|
test "bulk creates can be streamed" do
|
|
|
|
assert [{:ok, %{title: "fred"}}, {:ok, %{title: "george"}}] =
|
2024-04-02 05:18:42 +13:00
|
|
|
Ash.bulk_create!([%{title: "fred"}, %{title: "george"}], Post, :create,
|
2023-09-23 14:52:22 +12:00
|
|
|
return_stream?: true,
|
|
|
|
return_records?: true
|
|
|
|
)
|
|
|
|
|> Enum.sort_by(fn {:ok, result} -> result.title end)
|
|
|
|
end
|
|
|
|
|
|
|
|
test "bulk creates can upsert" do
|
|
|
|
assert [
|
|
|
|
{:ok, %{title: "fred", uniq_one: "one", uniq_two: "two", price: 10}},
|
|
|
|
{:ok, %{title: "george", uniq_one: "three", uniq_two: "four", price: 20}}
|
|
|
|
] =
|
2024-04-02 05:18:42 +13:00
|
|
|
Ash.bulk_create!(
|
2023-09-23 14:52:22 +12:00
|
|
|
[
|
|
|
|
%{title: "fred", uniq_one: "one", uniq_two: "two", price: 10},
|
|
|
|
%{title: "george", uniq_one: "three", uniq_two: "four", price: 20}
|
|
|
|
],
|
|
|
|
Post,
|
|
|
|
:create,
|
|
|
|
return_stream?: true,
|
|
|
|
return_records?: true
|
|
|
|
)
|
|
|
|
|> Enum.sort_by(fn {:ok, result} -> result.title end)
|
|
|
|
|
|
|
|
assert [
|
|
|
|
{:ok, %{title: "fred", uniq_one: "one", uniq_two: "two", price: 1000}},
|
|
|
|
{:ok, %{title: "george", uniq_one: "three", uniq_two: "four", price: 20_000}}
|
|
|
|
] =
|
2024-04-02 05:18:42 +13:00
|
|
|
Ash.bulk_create!(
|
2023-09-23 14:52:22 +12:00
|
|
|
[
|
|
|
|
%{title: "something", uniq_one: "one", uniq_two: "two", price: 1000},
|
|
|
|
%{title: "else", uniq_one: "three", uniq_two: "four", price: 20_000}
|
|
|
|
],
|
|
|
|
Post,
|
|
|
|
:create,
|
|
|
|
upsert?: true,
|
|
|
|
upsert_identity: :uniq_one_and_two,
|
|
|
|
upsert_fields: [:price],
|
|
|
|
return_stream?: true,
|
|
|
|
return_records?: true
|
|
|
|
)
|
|
|
|
|> Enum.sort_by(fn
|
|
|
|
{:ok, result} ->
|
|
|
|
result.title
|
|
|
|
|
|
|
|
_ ->
|
|
|
|
nil
|
|
|
|
end)
|
|
|
|
end
|
|
|
|
|
|
|
|
test "bulk creates can create relationships" do
|
2024-04-02 05:18:42 +13:00
|
|
|
Ash.bulk_create!(
|
2023-09-23 14:52:22 +12:00
|
|
|
[%{title: "fred", rating: %{score: 5}}, %{title: "george", rating: %{score: 0}}],
|
|
|
|
Post,
|
|
|
|
:create
|
|
|
|
)
|
|
|
|
|
|
|
|
assert [
|
|
|
|
%{title: "fred", ratings: [%{score: 5}]},
|
|
|
|
%{title: "george", ratings: [%{score: 0}]}
|
|
|
|
] =
|
|
|
|
Post
|
|
|
|
|> Ash.Query.sort(:title)
|
|
|
|
|> Ash.Query.load(:ratings)
|
2024-04-02 05:18:42 +13:00
|
|
|
|> Ash.read!()
|
2023-09-23 14:52:22 +12:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
describe "validation errors" do
|
|
|
|
test "skips invalid by default" do
|
|
|
|
assert %{records: [_], errors: [_]} =
|
2024-04-02 05:18:42 +13:00
|
|
|
Ash.bulk_create!([%{title: "fred"}, %{title: "not allowed"}], Post, :create,
|
2023-09-23 14:52:22 +12:00
|
|
|
return_records?: true,
|
|
|
|
return_errors?: true
|
|
|
|
)
|
|
|
|
end
|
|
|
|
|
|
|
|
test "returns errors in the stream" do
|
|
|
|
assert [{:ok, _}, {:error, _}] =
|
2024-04-02 05:18:42 +13:00
|
|
|
Ash.bulk_create!([%{title: "fred"}, %{title: "not allowed"}], Post, :create,
|
2023-09-23 14:52:22 +12:00
|
|
|
return_records?: true,
|
|
|
|
return_stream?: true,
|
|
|
|
return_errors?: true
|
|
|
|
)
|
|
|
|
|> Enum.to_list()
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
describe "database errors" do
|
|
|
|
test "database errors affect the entire batch" do
|
2023-10-12 09:30:00 +13:00
|
|
|
org =
|
|
|
|
AshSqlite.Test.Organization
|
|
|
|
|> Ash.Changeset.for_create(:create, %{name: "foo"})
|
2024-04-02 05:18:42 +13:00
|
|
|
|> Ash.create!()
|
2023-10-12 09:30:00 +13:00
|
|
|
|
2024-04-02 05:18:42 +13:00
|
|
|
Ash.bulk_create(
|
2023-10-12 09:30:00 +13:00
|
|
|
[
|
|
|
|
%{title: "fred", organization_id: org.id},
|
|
|
|
%{title: "george", organization_id: Ash.UUID.generate()}
|
|
|
|
],
|
2023-09-23 14:52:22 +12:00
|
|
|
Post,
|
|
|
|
:create,
|
|
|
|
return_records?: true
|
|
|
|
)
|
|
|
|
|
|
|
|
assert [] =
|
|
|
|
Post
|
|
|
|
|> Ash.Query.sort(:title)
|
2024-04-02 05:18:42 +13:00
|
|
|
|> Ash.read!()
|
2023-09-23 14:52:22 +12:00
|
|
|
end
|
|
|
|
|
|
|
|
test "database errors don't affect other batches" do
|
2024-04-02 05:18:42 +13:00
|
|
|
Ash.bulk_create(
|
2023-09-23 14:52:22 +12:00
|
|
|
[%{title: "george", organization_id: Ash.UUID.generate()}, %{title: "fred"}],
|
|
|
|
Post,
|
|
|
|
:create,
|
|
|
|
return_records?: true,
|
|
|
|
batch_size: 1
|
|
|
|
)
|
|
|
|
|
|
|
|
assert [%{title: "fred"}] =
|
|
|
|
Post
|
|
|
|
|> Ash.Query.sort(:title)
|
2024-04-02 05:18:42 +13:00
|
|
|
|> Ash.read!()
|
2023-09-23 14:52:22 +12:00
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|