defmodule AshPostgres.BulkCreateTest do use AshPostgres.RepoCase, async: false alias AshPostgres.Test.{Api, Post} describe "bulk creates" do test "bulk creates insert each input" do Api.bulk_create!([%{title: "fred"}, %{title: "george"}], Post, :create) assert [%{title: "fred"}, %{title: "george"}] = Post |> Ash.Query.sort(:title) |> Api.read!() end test "bulk creates can be streamed" do assert [{:ok, %{title: "fred"}}, {:ok, %{title: "george"}}] = Api.bulk_create!([%{title: "fred"}, %{title: "george"}], Post, :create, 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}} ] = Api.bulk_create!( [ %{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}} ] = Api.bulk_create!( [ %{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 end describe "validation errors" do test "skips invalid by default" do assert %{records: [_], errors: [_]} = Api.bulk_create!([%{title: "fred"}, %{title: "not allowed"}], Post, :create, return_records?: true, return_errors?: true ) end test "returns errors in the stream" do assert [{:ok, _}, {:error, _}] = Api.bulk_create!([%{title: "fred"}, %{title: "not allowed"}], Post, :create, 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 # assert %{records: [_], errors: [_]} = Api.bulk_create( [%{title: "fred"}, %{title: "george", organization_id: Ash.UUID.generate()}], Post, :create, return_records?: true ) assert [] = Post |> Ash.Query.sort(:title) |> Api.read!() end test "database errors don't affect other batches" do Api.bulk_create( [%{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) |> Api.read!() end end end