From 6d693ed4e40e22963545ef36b468ae98ffef3a1d Mon Sep 17 00:00:00 2001 From: Victor Date: Wed, 21 May 2025 15:50:24 -0700 Subject: [PATCH 001/174] fix: Convert sensitive patterns from module constant to function for OTP/28 (#552) compatibility --- lib/resource_generator/sensitive_data.ex | 113 ++++++++++++----------- 1 file changed, 58 insertions(+), 55 deletions(-) diff --git a/lib/resource_generator/sensitive_data.ex b/lib/resource_generator/sensitive_data.ex index 77b0e45b..7b720aef 100644 --- a/lib/resource_generator/sensitive_data.ex +++ b/lib/resource_generator/sensitive_data.ex @@ -2,72 +2,75 @@ defmodule AshPostgres.ResourceGenerator.SensitiveData do @moduledoc false # I got this from ChatGPT, but this is a best effort transformation # anyway. - @sensitive_patterns [ - # Password-related - ~r/password/i, - ~r/passwd/i, - ~r/pass/i, - ~r/pwd/i, - ~r/hash(ed)?(_password)?/i, - # Authentication-related - ~r/auth(_key)?/i, - ~r/token/i, - ~r/secret(_key)?/i, - ~r/api_key/i, + def sensitive_patterns do + [ + # Password-related + ~r/password/i, + ~r/passwd/i, + ~r/pass/i, + ~r/pwd/i, + ~r/hash(ed)?(_password)?/i, - # Personal Information - ~r/ssn/i, - ~r/social(_security)?(_number)?/i, - ~r/(credit_?card|cc)(_number)?/i, - ~r/passport(_number)?/i, - ~r/driver_?licen(s|c)e(_number)?/i, - ~r/national_id/i, + # Authentication-related + ~r/auth(_key)?/i, + ~r/token/i, + ~r/secret(_key)?/i, + ~r/api_key/i, - # Financial Information - ~r/account(_number)?/i, - ~r/routing(_number)?/i, - ~r/iban/i, - ~r/swift(_code)?/i, - ~r/tax_id/i, + # Personal Information + ~r/ssn/i, + ~r/social(_security)?(_number)?/i, + ~r/(credit_?card|cc)(_number)?/i, + ~r/passport(_number)?/i, + ~r/driver_?licen(s|c)e(_number)?/i, + ~r/national_id/i, - # Contact Information - ~r/phone(_number)?/i, - ~r/email(_address)?/i, - ~r/address/i, + # Financial Information + ~r/account(_number)?/i, + ~r/routing(_number)?/i, + ~r/iban/i, + ~r/swift(_code)?/i, + ~r/tax_id/i, - # Health Information - ~r/medical(_record)?/i, - ~r/health(_data)?/i, - ~r/diagnosis/i, - ~r/treatment/i, + # Contact Information + ~r/phone(_number)?/i, + ~r/email(_address)?/i, + ~r/address/i, - # Biometric Data - ~r/fingerprint/i, - ~r/retina_scan/i, - ~r/face_id/i, - ~r/dna/i, + # Health Information + ~r/medical(_record)?/i, + ~r/health(_data)?/i, + ~r/diagnosis/i, + ~r/treatment/i, - # Encrypted or Encoded Data - ~r/encrypt(ed)?/i, - ~r/encoded/i, - ~r/cipher/i, + # Biometric Data + ~r/fingerprint/i, + ~r/retina_scan/i, + ~r/face_id/i, + ~r/dna/i, - # Other Potentially Sensitive Data - ~r/private(_key)?/i, - ~r/confidential/i, - ~r/restricted/i, - ~r/sensitive/i, + # Encrypted or Encoded Data + ~r/encrypt(ed)?/i, + ~r/encoded/i, + ~r/cipher/i, - # General patterns - ~r/.*_salt/i, - ~r/.*_secret/i, - ~r/.*_key/i, - ~r/.*_token/i - ] + # Other Potentially Sensitive Data + ~r/private(_key)?/i, + ~r/confidential/i, + ~r/restricted/i, + ~r/sensitive/i, + + # General patterns + ~r/.*_salt/i, + ~r/.*_secret/i, + ~r/.*_key/i, + ~r/.*_token/i + ] + end def sensitive?(column_name) do - Enum.any?(@sensitive_patterns, fn pattern -> + Enum.any?(sensitive_patterns(), fn pattern -> Regex.match?(pattern, column_name) end) end From 0325b028f93a31ad775caf0f26ad379975667d05 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kenneth=20Kostre=C5=A1evi=C4=87?= Date: Thu, 22 May 2025 12:44:28 +0200 Subject: [PATCH 002/174] Expand aggregate test covering rem expression (#541) --- test/aggregate_test.exs | 10 ++++++++++ test/support/resources/post.ex | 4 ++++ 2 files changed, 14 insertions(+) diff --git a/test/aggregate_test.exs b/test/aggregate_test.exs index bd34f579..e3ad5fa1 100644 --- a/test/aggregate_test.exs +++ b/test/aggregate_test.exs @@ -957,6 +957,16 @@ defmodule AshSql.AggregateTest do assert %{sum_of_popular_comment_rating_scores_2: 80} = values + + values = + post + |> Ash.load!([ + :sum_of_odd_comment_rating_scores + ]) + |> Map.take([:sum_of_odd_comment_rating_scores]) + + assert %{sum_of_popular_comment_rating_scores_2: 120} = + values end test "can't define multidimensional array aggregate types" do diff --git a/test/support/resources/post.ex b/test/support/resources/post.ex index f996c324..c66c8680 100644 --- a/test/support/resources/post.ex +++ b/test/support/resources/post.ex @@ -1061,6 +1061,10 @@ defmodule AshPostgres.Test.Post do filter(expr(score > 5)) end + sum :sum_of_odd_comment_rating_scores, [:comments, :ratings], :score do + filter(expr(rem(score, 2) == 1)) + end + sum(:sum_of_popular_comment_rating_scores_2, [:comments, :popular_ratings], :score) sum :sum_of_comment_likes_called_match, :comments, :likes do From 593fa84cee9f7a36c070b364493d4fd3d4118790 Mon Sep 17 00:00:00 2001 From: Zach Daniel Date: Thu, 22 May 2025 06:58:29 -0400 Subject: [PATCH 003/174] chore: format --- test/support/domain.ex | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/test/support/domain.ex b/test/support/domain.ex index 805a1dce..25616374 100644 --- a/test/support/domain.ex +++ b/test/support/domain.ex @@ -4,9 +4,11 @@ defmodule AshPostgres.Test.Domain do resources do resource(AshPostgres.Test.CoAuthorPost) + resource(AshPostgres.Test.Post) do - define :review, action: :review + define(:review, action: :review) end + resource(AshPostgres.Test.Comedian) resource(AshPostgres.Test.Comment) resource(AshPostgres.Test.CommentLink) From 6b7336921731a8e0075a030f2c31a764bf3dc8bb Mon Sep 17 00:00:00 2001 From: Zach Daniel Date: Thu, 22 May 2025 08:37:16 -0400 Subject: [PATCH 004/174] chore: release version v2.5.22 --- CHANGELOG.md | 9 +++++++++ mix.exs | 2 +- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 498a0f43..63141775 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,15 @@ See [Conventional Commits](https://www.conventionalcommits.org) for commit guide +## [v2.5.22](https://github.com/ash-project/ash_postgres/compare/v2.5.21...v2.5.22) (2025-05-22) + + + + +### Bug Fixes: + +* Convert sensitive patterns from module constant to function for OTP/28 (#552) + ## [v2.5.21](https://github.com/ash-project/ash_postgres/compare/v2.5.20...v2.5.21) (2025-05-21) diff --git a/mix.exs b/mix.exs index 4d9fc3a6..31424e80 100644 --- a/mix.exs +++ b/mix.exs @@ -5,7 +5,7 @@ defmodule AshPostgres.MixProject do The PostgreSQL data layer for Ash Framework """ - @version "2.5.21" + @version "2.5.22" def project do [ From f573c42889ce9e190dd816b8020ccd282b513f3d Mon Sep 17 00:00:00 2001 From: Zach Daniel Date: Thu, 22 May 2025 23:24:31 -0400 Subject: [PATCH 005/174] chore: fix aggregate test --- test/aggregate_test.exs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/aggregate_test.exs b/test/aggregate_test.exs index e3ad5fa1..167a00c9 100644 --- a/test/aggregate_test.exs +++ b/test/aggregate_test.exs @@ -965,7 +965,7 @@ defmodule AshSql.AggregateTest do ]) |> Map.take([:sum_of_odd_comment_rating_scores]) - assert %{sum_of_popular_comment_rating_scores_2: 120} = + assert %{sum_of_odd_comment_rating_scores: 120} = values end From 38691cb67cd29da4e359142236de56fd4e7b2bc2 Mon Sep 17 00:00:00 2001 From: Zach Daniel Date: Thu, 22 May 2025 23:27:08 -0400 Subject: [PATCH 006/174] chore: update deps --- mix.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/mix.lock b/mix.lock index d5fc1b67..648043ae 100644 --- a/mix.lock +++ b/mix.lock @@ -1,6 +1,6 @@ %{ - "ash": {:hex, :ash, "3.5.11", "6d20782aeeb99773bd6f4902883c4ff2ad18404b7ad84bfc464ee772133c7368", [:mix], [{:decimal, "~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:ecto, "~> 3.7", [hex: :ecto, repo: "hexpm", optional: false]}, {:ets, "~> 0.8", [hex: :ets, repo: "hexpm", optional: false]}, {:igniter, ">= 0.5.24 and < 1.0.0-0", [hex: :igniter, repo: "hexpm", optional: true]}, {:jason, ">= 1.0.0", [hex: :jason, repo: "hexpm", optional: false]}, {:owl, "~> 0.11", [hex: :owl, repo: "hexpm", optional: false]}, {:picosat_elixir, "~> 0.2", [hex: :picosat_elixir, repo: "hexpm", optional: true]}, {:plug, ">= 0.0.0", [hex: :plug, repo: "hexpm", optional: true]}, {:reactor, "~> 0.11", [hex: :reactor, repo: "hexpm", optional: false]}, {:simple_sat, ">= 0.1.1 and < 1.0.0-0", [hex: :simple_sat, repo: "hexpm", optional: true]}, {:spark, ">= 2.2.29 and < 3.0.0-0", [hex: :spark, repo: "hexpm", optional: false]}, {:splode, ">= 0.2.6 and < 1.0.0-0", [hex: :splode, repo: "hexpm", optional: false]}, {:stream_data, "~> 1.0", [hex: :stream_data, repo: "hexpm", optional: false]}, {:telemetry, "~> 1.1", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "f37122fe27f67a81624ba09de0fde56e84a3395ff41d457c075822427d741887"}, - "ash_sql": {:hex, :ash_sql, "0.2.75", "94252b460db2e14b778fa542684811c48fa08b4b2a2916db6a05a33e4272c361", [:mix], [{:ash, "~> 3.5", [hex: :ash, repo: "hexpm", optional: false]}, {:ecto, "~> 3.9", [hex: :ecto, repo: "hexpm", optional: false]}, {:ecto_sql, "~> 3.9", [hex: :ecto_sql, repo: "hexpm", optional: false]}], "hexpm", "966226cd5b368258d05359c9a3f37cf86b412f5822a59c85ac27f047ca9e95cb"}, + "ash": {:hex, :ash, "3.5.12", "435a6916d47e4ed6eabce886de2443d17af9dd9ca9765a29c73d9e02507b86b3", [:mix], [{:decimal, "~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:ecto, "~> 3.7", [hex: :ecto, repo: "hexpm", optional: false]}, {:ets, "~> 0.8", [hex: :ets, repo: "hexpm", optional: false]}, {:igniter, "~> 0.6", [hex: :igniter, repo: "hexpm", optional: true]}, {:jason, ">= 1.0.0", [hex: :jason, repo: "hexpm", optional: false]}, {:owl, "~> 0.11", [hex: :owl, repo: "hexpm", optional: false]}, {:picosat_elixir, "~> 0.2", [hex: :picosat_elixir, repo: "hexpm", optional: true]}, {:plug, ">= 0.0.0", [hex: :plug, repo: "hexpm", optional: true]}, {:reactor, "~> 0.11", [hex: :reactor, repo: "hexpm", optional: false]}, {:simple_sat, ">= 0.1.1 and < 1.0.0-0", [hex: :simple_sat, repo: "hexpm", optional: true]}, {:spark, ">= 2.2.60 and < 3.0.0-0", [hex: :spark, repo: "hexpm", optional: false]}, {:splode, ">= 0.2.6 and < 1.0.0-0", [hex: :splode, repo: "hexpm", optional: false]}, {:stream_data, "~> 1.0", [hex: :stream_data, repo: "hexpm", optional: false]}, {:telemetry, "~> 1.1", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "503492989c56e33c300d731b3717d1df9eeebba2b9018e5dd9f330db727edb57"}, + "ash_sql": {:hex, :ash_sql, "0.2.76", "4afac3284194f3d7820b7edc1263ac1eb232a25734406ad7b2284683b9384205", [:mix], [{:ash, "~> 3.5", [hex: :ash, repo: "hexpm", optional: false]}, {:ecto, "~> 3.9", [hex: :ecto, repo: "hexpm", optional: false]}, {:ecto_sql, "~> 3.9", [hex: :ecto_sql, repo: "hexpm", optional: false]}], "hexpm", "f6bc02d8c4cba3f8f9a532e6ff73eaf8a4f7685257646a58fe7a320cfaf10c39"}, "benchee": {:hex, :benchee, "1.4.0", "9f1f96a30ac80bab94faad644b39a9031d5632e517416a8ab0a6b0ac4df124ce", [:mix], [{:deep_merge, "~> 1.0", [hex: :deep_merge, repo: "hexpm", optional: false]}, {:statistex, "~> 1.0", [hex: :statistex, repo: "hexpm", optional: false]}, {:table, "~> 0.1.0", [hex: :table, repo: "hexpm", optional: true]}], "hexpm", "299cd10dd8ce51c9ea3ddb74bb150f93d25e968f93e4c1fa31698a8e4fa5d715"}, "bunt": {:hex, :bunt, "1.0.0", "081c2c665f086849e6d57900292b3a161727ab40431219529f13c4ddcf3e7a44", [:mix], [], "hexpm", "dc5f86aa08a5f6fa6b8096f0735c4e76d54ae5c9fa2c143e5a1fc7c1cd9bb6b5"}, "credo": {:hex, :credo, "1.7.12", "9e3c20463de4b5f3f23721527fcaf16722ec815e70ff6c60b86412c695d426c1", [:mix], [{:bunt, "~> 0.2.1 or ~> 1.0", [hex: :bunt, repo: "hexpm", optional: false]}, {:file_system, "~> 0.2 or ~> 1.0", [hex: :file_system, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "8493d45c656c5427d9c729235b99d498bd133421f3e0a683e5c1b561471291e5"}, @@ -20,10 +20,10 @@ "file_system": {:hex, :file_system, "1.1.0", "08d232062284546c6c34426997dd7ef6ec9f8bbd090eb91780283c9016840e8f", [:mix], [], "hexpm", "bfcf81244f416871f2a2e15c1b515287faa5db9c6bcf290222206d120b3d43f6"}, "finch": {:hex, :finch, "0.19.0", "c644641491ea854fc5c1bbaef36bfc764e3f08e7185e1f084e35e0672241b76d", [:mix], [{:mime, "~> 1.0 or ~> 2.0", [hex: :mime, repo: "hexpm", optional: false]}, {:mint, "~> 1.6.2 or ~> 1.7", [hex: :mint, repo: "hexpm", optional: false]}, {:nimble_options, "~> 0.4 or ~> 1.0", [hex: :nimble_options, repo: "hexpm", optional: false]}, {:nimble_pool, "~> 1.1", [hex: :nimble_pool, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "fc5324ce209125d1e2fa0fcd2634601c52a787aff1cd33ee833664a5af4ea2b6"}, "git_cli": {:hex, :git_cli, "0.3.0", "a5422f9b95c99483385b976f5d43f7e8233283a47cda13533d7c16131cb14df5", [:mix], [], "hexpm", "78cb952f4c86a41f4d3511f1d3ecb28edb268e3a7df278de2faa1bd4672eaf9b"}, - "git_ops": {:hex, :git_ops, "2.7.2", "2d3c164a8bcaf13f129ab339e8e9f0a99c80ffa8f85dd0b344d7515275236dbc", [:mix], [{:git_cli, "~> 0.2", [hex: :git_cli, repo: "hexpm", optional: false]}, {:igniter, ">= 0.5.27 and < 1.0.0-0", [hex: :igniter, repo: "hexpm", optional: true]}, {:nimble_parsec, "~> 1.0", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "1dcd68b3f5bcd0999d69274cd21e74e652a90452e683b54d490fa5b26152945f"}, + "git_ops": {:hex, :git_ops, "2.7.3", "c993aedb11005752e321d482de6f2a46d0b5d5f09ce69961f31a856e76bf4f12", [:mix], [{:git_cli, "~> 0.2", [hex: :git_cli, repo: "hexpm", optional: false]}, {:igniter, ">= 0.5.27 and < 1.0.0-0", [hex: :igniter, repo: "hexpm", optional: true]}, {:nimble_parsec, "~> 1.0", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "c54ee65e12778be1f4dd6a0921e57ab2bddd35bd6130cbe274dcb1f0a21ca59d"}, "glob_ex": {:hex, :glob_ex, "0.1.11", "cb50d3f1ef53f6ca04d6252c7fde09fd7a1cf63387714fe96f340a1349e62c93", [:mix], [], "hexpm", "342729363056e3145e61766b416769984c329e4378f1d558b63e341020525de4"}, "hpax": {:hex, :hpax, "1.0.3", "ed67ef51ad4df91e75cc6a1494f851850c0bd98ebc0be6e81b026e765ee535aa", [:mix], [], "hexpm", "8eab6e1cfa8d5918c2ce4ba43588e894af35dbd8e91e6e55c817bca5847df34a"}, - "igniter": {:hex, :igniter, "0.6.0", "ad1e794286519bd52a0bc645419cdab1b8bf0352903199f534ea369ea5623dc4", [:mix], [{:glob_ex, "~> 0.1.7", [hex: :glob_ex, repo: "hexpm", optional: false]}, {:jason, "~> 1.4", [hex: :jason, repo: "hexpm", optional: false]}, {:owl, "~> 0.11", [hex: :owl, repo: "hexpm", optional: false]}, {:phx_new, "~> 1.7", [hex: :phx_new, repo: "hexpm", optional: true]}, {:req, "~> 0.5", [hex: :req, repo: "hexpm", optional: false]}, {:rewrite, ">= 1.1.1 and < 2.0.0-0", [hex: :rewrite, repo: "hexpm", optional: false]}, {:sourceror, "~> 1.4", [hex: :sourceror, repo: "hexpm", optional: false]}, {:spitfire, ">= 0.1.3 and < 1.0.0-0", [hex: :spitfire, repo: "hexpm", optional: false]}], "hexpm", "424df02a8acaeaec9cd01412916f60148d3ec710cd7317787c6656067f168f8b"}, + "igniter": {:hex, :igniter, "0.6.1", "e683495de01cb3cb30943670fd93fc9f603093c380225a4a6dd1f468a393f891", [:mix], [{:glob_ex, "~> 0.1.7", [hex: :glob_ex, repo: "hexpm", optional: false]}, {:jason, "~> 1.4", [hex: :jason, repo: "hexpm", optional: false]}, {:owl, "~> 0.11", [hex: :owl, repo: "hexpm", optional: false]}, {:phx_new, "~> 1.7", [hex: :phx_new, repo: "hexpm", optional: true]}, {:req, "~> 0.5", [hex: :req, repo: "hexpm", optional: false]}, {:rewrite, ">= 1.1.1 and < 2.0.0-0", [hex: :rewrite, repo: "hexpm", optional: false]}, {:sourceror, "~> 1.4", [hex: :sourceror, repo: "hexpm", optional: false]}, {:spitfire, ">= 0.1.3 and < 1.0.0-0", [hex: :spitfire, repo: "hexpm", optional: false]}], "hexpm", "81467df9d6e7210b262c41ccbbdb08c48491bd6fd3f2aee529a8ed730c6f84ba"}, "iterex": {:hex, :iterex, "0.1.2", "58f9b9b9a22a55cbfc7b5234a9c9c63eaac26d276b3db80936c0e1c60355a5a6", [:mix], [], "hexpm", "2e103b8bcc81757a9af121f6dc0df312c9a17220f302b1193ef720460d03029d"}, "jason": {:hex, :jason, "1.4.4", "b9226785a9aa77b6857ca22832cffa5d5011a667207eb2a0ad56adb5db443b8a", [:mix], [{:decimal, "~> 1.0 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm", "c5eb0cab91f094599f94d55bc63409236a8ec69a21a67814529e8d5f6cc90b3b"}, "libgraph": {:hex, :libgraph, "0.16.0", "3936f3eca6ef826e08880230f806bfea13193e49bf153f93edcf0239d4fd1d07", [:mix], [], "hexpm", "41ca92240e8a4138c30a7e06466acc709b0cbb795c643e9e17174a178982d6bf"}, From c9f88460faf9341bf05fffa6f5d60006d46190ec Mon Sep 17 00:00:00 2001 From: Zach Daniel Date: Fri, 23 May 2025 17:26:48 -0400 Subject: [PATCH 007/174] improvement: support scale & precision in decimal types --- .../migration_generator.ex | 80 ++++- lib/migration_generator/operation.ex | 46 ++- lib/multitenancy.ex | 9 +- test/migration_generator_test.exs | 326 ++++++++++++++++++ 4 files changed, 446 insertions(+), 15 deletions(-) diff --git a/lib/migration_generator/migration_generator.ex b/lib/migration_generator/migration_generator.ex index a0c04a02..231697ac 100644 --- a/lib/migration_generator/migration_generator.ex +++ b/lib/migration_generator/migration_generator.ex @@ -694,6 +694,8 @@ defmodule AshPostgres.MigrationGenerator do generated?: Enum.any?(attributes, & &1.generated?), references: merge_references(Enum.map(attributes, & &1.references), source, table), primary_key?: false, + scale: attributes |> Enum.map(& &1[:scale]) |> Enum.max(), + precision: attributes |> Enum.map(& &1[:precision]) |> Enum.max(), order: attributes |> Enum.map(& &1.order) |> Enum.min() } end) @@ -3012,19 +3014,25 @@ defmodule AshPostgres.MigrationGenerator do type end - {type, size} = + {type, size, precision, scale} = case type do {:varchar, size} -> - {:varchar, size} + {:varchar, size, nil, nil} {:binary, size} -> - {:binary, size} + {:binary, size, nil, nil} + + {:decimal, precision, scale} -> + {:decimal, nil, precision, scale} + + {:decimal, precision} -> + {:decimal, nil, precision, nil} {other, size} when is_atom(other) and is_integer(size) -> - {other, size} + {other, size, nil, nil} other -> - {other, nil} + {other, nil, nil, nil} end attribute @@ -3033,6 +3041,20 @@ defmodule AshPostgres.MigrationGenerator do |> Map.put(:type, type) |> Map.put(:source, attribute.source || attribute.name) |> Map.drop([:name, :constraints]) + |> then(fn map -> + if precision do + Map.put(map, :precision, precision) + else + map + end + end) + |> then(fn map -> + if scale do + Map.put(map, :scale, scale) + else + map + end + end) end) |> Enum.map(fn attribute -> references = find_reference(resource, table, attribute) @@ -3145,6 +3167,28 @@ defmodule AshPostgres.MigrationGenerator do end end + defp migration_type(Ash.Type.Decimal, constraints) do + precision = + case constraints[:precision] do + :arbitrary -> nil + nil -> nil + precision -> precision + end + + scale = + case constraints[:scale] do + :arbitrary -> nil + nil -> nil + scale -> scale + end + + cond do + precision && scale -> {:decimal, precision, scale} + precision -> {:decimal, precision} + true -> :decimal + end + end + defp migration_type(other, constraints) do type = Ash.Type.get_type(other) @@ -3451,19 +3495,25 @@ defmodule AshPostgres.MigrationGenerator do defp load_attribute(attribute, table) do type = load_type(attribute.type) - {type, size} = + {type, size, scale, precision} = case type do {:varchar, size} -> - {:varchar, size} + {:varchar, size, nil, nil} {:binary, size} -> - {:binary, size} + {:binary, size, nil, nil} {other, size} when is_atom(other) and is_integer(size) -> - {other, size} + {other, size, nil, nil} + + {:decimal, scale} -> + {:decimal, scale, nil, nil} + + {:decimal, scale, precision} -> + {:decimal, scale, precision, nil} other -> - {other, nil} + {other, nil, nil, nil} end attribute = @@ -3476,6 +3526,8 @@ defmodule AshPostgres.MigrationGenerator do attribute |> Map.put(:type, type) |> Map.put(:size, size) + |> Map.put(:precision, precision) + |> Map.put(:scale, scale) |> Map.put_new(:default, "nil") |> Map.update!(:default, &(&1 || "nil")) |> Map.update!(:references, fn @@ -3562,6 +3614,14 @@ defmodule AshPostgres.MigrationGenerator do {:binary, size} end + defp load_type(["decimal", scale]) do + {:decimal, scale} + end + + defp load_type(["decimal", scale, precision]) do + {:decimal, scale, precision} + end + defp load_type([string, size]) when is_binary(string) and is_integer(size) do {String.to_existing_atom(string), size} end diff --git a/lib/migration_generator/operation.ex b/lib/migration_generator/operation.ex index 62b3b3a6..242a5db1 100644 --- a/lib/migration_generator/operation.ex +++ b/lib/migration_generator/operation.ex @@ -135,6 +135,12 @@ defmodule AshPostgres.MigrationGenerator.Operation do keys end end + + def maybe_add_precision(nil), do: nil + def maybe_add_precision(precision), do: "precision: #{precision}" + + def maybe_add_scale(nil), do: nil + def maybe_add_scale(scale), do: "scale: #{scale}" end defmodule CreateTable do @@ -179,7 +185,9 @@ defmodule AshPostgres.MigrationGenerator.Operation do option("prefix", destination_schema), on_delete(reference), on_update(reference), - size + size, + maybe_add_precision(attribute[:precision]), + maybe_add_scale(attribute[:scale]) ], ")", maybe_add_default(attribute.default), @@ -219,6 +227,8 @@ defmodule AshPostgres.MigrationGenerator.Operation do "name: #{inspect(reference.name)}", "type: #{inspect(reference_type(attribute, reference))}", size, + maybe_add_precision(attribute[:precision]), + maybe_add_scale(attribute[:scale]), on_delete(reference), on_update(reference) ], @@ -250,6 +260,8 @@ defmodule AshPostgres.MigrationGenerator.Operation do maybe_add_default(attribute.default), maybe_add_primary_key(attribute.primary_key?), size, + maybe_add_precision(attribute[:precision]), + maybe_add_scale(attribute[:scale]), maybe_add_null(attribute.allow_nil?) ] |> join() @@ -275,6 +287,8 @@ defmodule AshPostgres.MigrationGenerator.Operation do maybe_add_default(attribute.default), maybe_add_primary_key(attribute.primary_key?), size, + maybe_add_precision(attribute[:precision]), + maybe_add_scale(attribute[:scale]), maybe_add_null(attribute.allow_nil?) ] |> join() @@ -309,6 +323,8 @@ defmodule AshPostgres.MigrationGenerator.Operation do "type: #{inspect(reference_type(attribute, reference))}", "prefix: prefix()", size, + maybe_add_precision(attribute[:precision]), + maybe_add_scale(attribute[:scale]), on_delete(reference), on_update(reference) ], @@ -355,6 +371,8 @@ defmodule AshPostgres.MigrationGenerator.Operation do "type: #{inspect(reference_type(attribute, reference))}", option("prefix", destination_schema), size, + maybe_add_precision(attribute[:precision]), + maybe_add_scale(attribute[:scale]), on_delete(reference), on_update(reference) ], @@ -394,6 +412,8 @@ defmodule AshPostgres.MigrationGenerator.Operation do "type: #{inspect(reference_type(attribute, reference))}", option("prefix", destination_schema), size, + maybe_add_precision(attribute[:precision]), + maybe_add_scale(attribute[:scale]), on_delete(reference), on_update(reference) ], @@ -437,6 +457,8 @@ defmodule AshPostgres.MigrationGenerator.Operation do maybe_add_null(attribute.allow_nil?), maybe_add_default(attribute.default), size, + maybe_add_precision(attribute[:precision]), + maybe_add_scale(attribute[:scale]), maybe_add_primary_key(attribute.primary_key?) ] |> join() @@ -538,7 +560,21 @@ defmodule AshPostgres.MigrationGenerator.Operation do ", null: #{attribute.allow_nil?}" end - "#{null}#{default}#{primary_key}" + precision = + if Map.get(attribute, :precision) != Map.get(old_attribute, :precision) do + if attribute.precision do + ", precision: #{attribute.precision}" + end + end + + scale = + if Map.get(attribute, :scale) != Map.get(old_attribute, :scale) do + if attribute.scale do + ", scale: #{attribute.scale}" + end + end + + "#{null}#{default}#{precision}#{scale}#{primary_key}" end def up(%{ @@ -587,6 +623,8 @@ defmodule AshPostgres.MigrationGenerator.Operation do "name: #{inspect(reference.name)}", "type: #{inspect(reference_type(attribute, reference))}", size, + maybe_add_precision(attribute[:precision]), + maybe_add_scale(attribute[:scale]), "prefix: prefix()", on_delete(reference), on_update(reference), @@ -625,6 +663,8 @@ defmodule AshPostgres.MigrationGenerator.Operation do "name: #{inspect(reference.name)}", "type: #{inspect(reference_type(attribute, reference))}", size, + maybe_add_precision(attribute[:precision]), + maybe_add_scale(attribute[:scale]), option("prefix", destination_schema), on_delete(reference), on_update(reference), @@ -699,6 +739,8 @@ defmodule AshPostgres.MigrationGenerator.Operation do "name: #{inspect(reference.name)}", "type: #{inspect(reference_type(attribute, reference))}", size, + maybe_add_precision(attribute[:precision]), + maybe_add_scale(attribute[:scale]), option("prefix", destination_schema), on_delete(reference), on_update(reference), diff --git a/lib/multitenancy.ex b/lib/multitenancy.ex index 6927a960..96cddafc 100644 --- a/lib/multitenancy.ex +++ b/lib/multitenancy.ex @@ -3,7 +3,6 @@ defmodule AshPostgres.MultiTenancy do @dialyzer {:nowarn_function, load_migration!: 1} - @tenant_name_regex ~r/^[a-zA-Z0-9_-]+$/ def create_tenant!(tenant_name, repo) do validate_tenant_name!(tenant_name) Ecto.Adapters.SQL.query!(repo, "CREATE SCHEMA IF NOT EXISTS \"#{tenant_name}\"", []) @@ -87,8 +86,8 @@ defmodule AshPostgres.MultiTenancy do end defp validate_tenant_name!(tenant_name) do - if !Regex.match?(@tenant_name_regex, tenant_name) do - raise "Tenant name must match #{inspect(@tenant_name_regex)}, got: #{tenant_name}" + if !Regex.match?(tenant_name_regex(), tenant_name) do + raise "Tenant name must match #{inspect(tenant_name_regex())}, got: #{tenant_name}" end end @@ -100,4 +99,8 @@ defmodule AshPostgres.MultiTenancy do |> Path.join(repo_name) |> Path.join("tenant_migrations") end + + defp tenant_name_regex do + ~r/^[a-zA-Z0-9_-]+$/ + end end diff --git a/test/migration_generator_test.exs b/test/migration_generator_test.exs index 1ef76978..5b564b5f 100644 --- a/test/migration_generator_test.exs +++ b/test/migration_generator_test.exs @@ -2634,4 +2634,330 @@ defmodule AshPostgres.MigrationGeneratorTest do ~S[modify :post_id, references(:posts, column: :id, name: "comments_post_id_fkey", type: :uuid, prefix: "public")] end end + + describe "decimal precision and scale" do + setup do + on_exit(fn -> + File.rm_rf!("test_snapshots_path") + File.rm_rf!("test_migration_path") + end) + end + + test "creates decimal columns with precision and scale" do + defresource Product do + postgres do + table "products" + repo(AshPostgres.TestRepo) + end + + actions do + defaults([:create, :read, :update, :destroy]) + end + + attributes do + uuid_primary_key(:id) + + attribute(:price, :decimal, + constraints: [precision: 10, scale: 2], + public?: true, + allow_nil?: false + ) + + attribute(:weight, :decimal, + constraints: [precision: 8], + public?: true, + allow_nil?: false + ) + + attribute(:rating, :decimal, public?: true, allow_nil?: false) + end + end + + defdomain([Product]) + + AshPostgres.MigrationGenerator.generate(Domain, + snapshot_path: "test_snapshots_path", + migration_path: "test_migration_path", + quiet: true, + format: false + ) + + assert [file] = + Enum.sort(Path.wildcard("test_migration_path/**/*_migrate_resources*.exs")) + |> Enum.reject(&String.contains?(&1, "extensions")) + + file_content = File.read!(file) + + # Check that precision and scale are included for the price field + assert file_content =~ ~S[add :price, :decimal, null: false, precision: 10, scale: 2] + + # Check that only precision is included for the weight field + assert file_content =~ ~S[add :weight, :decimal, null: false, precision: 8] + + # Check that no precision or scale is included for the rating field + assert file_content =~ ~S[add :rating, :decimal, null: false] + end + + test "alters decimal columns with precision and scale changes" do + defresource Product do + postgres do + table "products" + repo(AshPostgres.TestRepo) + end + + actions do + defaults([:create, :read, :update, :destroy]) + end + + attributes do + uuid_primary_key(:id) + attribute(:price, :decimal, constraints: [precision: 8, scale: 2], public?: true) + end + end + + defdomain([Product]) + + # Generate initial migration + AshPostgres.MigrationGenerator.generate(Domain, + snapshot_path: "test_snapshots_path", + migration_path: "test_migration_path", + quiet: true, + format: false + ) + + # Now update the precision and scale + defresource Product do + postgres do + table "products" + repo(AshPostgres.TestRepo) + end + + actions do + defaults([:create, :read, :update, :destroy]) + end + + attributes do + uuid_primary_key(:id) + attribute(:price, :decimal, constraints: [precision: 12, scale: 4], public?: true) + end + end + + # Generate follow-up migration + AshPostgres.MigrationGenerator.generate(Domain, + snapshot_path: "test_snapshots_path", + migration_path: "test_migration_path", + quiet: true, + format: false + ) + + migration_files = + Enum.sort(Path.wildcard("test_migration_path/**/*_migrate_resources*.exs")) + |> Enum.reject(&String.contains?(&1, "extensions")) + + assert length(migration_files) == 2 + + # Check the second migration file + second_migration = File.read!(Enum.at(migration_files, 1)) + + # Should contain the alter statement with new precision and scale + assert second_migration =~ ~S[modify :price, :decimal, precision: 12, scale: 4] + end + + test "handles arbitrary precision and scale constraints" do + defresource Product do + postgres do + table "products" + repo(AshPostgres.TestRepo) + end + + actions do + defaults([:create, :read, :update, :destroy]) + end + + attributes do + uuid_primary_key(:id) + + attribute(:price, :decimal, + constraints: [precision: :arbitrary, scale: :arbitrary], + public?: true, + allow_nil?: false + ) + end + end + + defdomain([Product]) + + AshPostgres.MigrationGenerator.generate(Domain, + snapshot_path: "test_snapshots_path", + migration_path: "test_migration_path", + quiet: true, + format: false + ) + + assert [file] = + Enum.sort(Path.wildcard("test_migration_path/**/*_migrate_resources*.exs")) + |> Enum.reject(&String.contains?(&1, "extensions")) + + file_content = File.read!(file) + + # Check that no precision or scale is included when they are :arbitrary + assert file_content =~ ~S[add :price, :decimal, null: false] + refute file_content =~ ~S[precision:] + refute file_content =~ ~S[scale:] + end + + test "removes precision and scale when changing to arbitrary" do + defresource Product do + postgres do + table "products" + repo(AshPostgres.TestRepo) + end + + actions do + defaults([:create, :read, :update, :destroy]) + end + + attributes do + uuid_primary_key(:id) + + attribute(:price, :decimal, + constraints: [precision: 10, scale: 2], + public?: true, + allow_nil?: false + ) + end + end + + defdomain([Product]) + + # Generate initial migration + AshPostgres.MigrationGenerator.generate(Domain, + snapshot_path: "test_snapshots_path", + migration_path: "test_migration_path", + quiet: true, + format: false + ) + + # Now change to arbitrary precision and scale + defresource Product do + postgres do + table "products" + repo(AshPostgres.TestRepo) + end + + actions do + defaults([:create, :read, :update, :destroy]) + end + + attributes do + uuid_primary_key(:id) + + attribute(:price, :decimal, + constraints: [precision: :arbitrary, scale: :arbitrary], + public?: true, + allow_nil?: false + ) + end + end + + # Generate follow-up migration + AshPostgres.MigrationGenerator.generate(Domain, + snapshot_path: "test_snapshots_path", + migration_path: "test_migration_path", + quiet: true, + format: false + ) + + migration_files = + Enum.sort(Path.wildcard("test_migration_path/**/*_migrate_resources*.exs")) + |> Enum.reject(&String.contains?(&1, "extensions")) + + assert length(migration_files) == 2 + + # Check the second migration file + second_migration = File.read!(Enum.at(migration_files, 1)) + + # Should contain the alter statement removing precision and scale + assert second_migration =~ ~S[modify :price, :decimal] + refute second_migration =~ ~S[precision:] + refute second_migration =~ ~S[scale:] + end + + test "works with decimal references that have precision and scale" do + defresource Category do + postgres do + table "categories" + repo(AshPostgres.TestRepo) + end + + actions do + defaults([:create, :read, :update, :destroy]) + end + + attributes do + attribute(:id, :decimal, + constraints: [precision: 10, scale: 0], + primary_key?: true, + allow_nil?: false, + public?: true + ) + + attribute(:name, :string, public?: true) + end + end + + defresource Product do + postgres do + table "products" + repo(AshPostgres.TestRepo) + end + + actions do + defaults([:create, :read, :update, :destroy]) + end + + attributes do + uuid_primary_key(:id) + + attribute(:category_id, :decimal, + constraints: [precision: 10, scale: 0], + allow_nil?: false, + public?: true + ) + end + + relationships do + belongs_to(:category, Category) do + source_attribute(:category_id) + destination_attribute(:id) + public?(true) + end + end + end + + defdomain([Category, Product]) + + AshPostgres.MigrationGenerator.generate(Domain, + snapshot_path: "test_snapshots_path", + migration_path: "test_migration_path", + quiet: true, + format: false + ) + + assert [file] = + Enum.sort(Path.wildcard("test_migration_path/**/*_migrate_resources*.exs")) + |> Enum.reject(&String.contains?(&1, "extensions")) + + file_content = File.read!(file) + + # Check that both tables are created with proper decimal precision + assert file_content =~ + ~S[add :id, :decimal, null: false, precision: 10, scale: 0, primary_key: true] + + assert file_content =~ ~S[add :category_id, :decimal, null: false, precision: 10, scale: 0] + + assert file_content =~ + ~S[modify :category_id, references(:categories, column: :id, name: "products_category_id_fkey", type: :decimal, precision: 10, scale: 0] + end + end end From f0203458dd768cc2f7005f452e5a1ed03ea9bb20 Mon Sep 17 00:00:00 2001 From: Zach Daniel Date: Sun, 25 May 2025 23:19:23 -0400 Subject: [PATCH 008/174] chore: update deps --- mix.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/mix.lock b/mix.lock index 648043ae..10820741 100644 --- a/mix.lock +++ b/mix.lock @@ -23,7 +23,7 @@ "git_ops": {:hex, :git_ops, "2.7.3", "c993aedb11005752e321d482de6f2a46d0b5d5f09ce69961f31a856e76bf4f12", [:mix], [{:git_cli, "~> 0.2", [hex: :git_cli, repo: "hexpm", optional: false]}, {:igniter, ">= 0.5.27 and < 1.0.0-0", [hex: :igniter, repo: "hexpm", optional: true]}, {:nimble_parsec, "~> 1.0", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "c54ee65e12778be1f4dd6a0921e57ab2bddd35bd6130cbe274dcb1f0a21ca59d"}, "glob_ex": {:hex, :glob_ex, "0.1.11", "cb50d3f1ef53f6ca04d6252c7fde09fd7a1cf63387714fe96f340a1349e62c93", [:mix], [], "hexpm", "342729363056e3145e61766b416769984c329e4378f1d558b63e341020525de4"}, "hpax": {:hex, :hpax, "1.0.3", "ed67ef51ad4df91e75cc6a1494f851850c0bd98ebc0be6e81b026e765ee535aa", [:mix], [], "hexpm", "8eab6e1cfa8d5918c2ce4ba43588e894af35dbd8e91e6e55c817bca5847df34a"}, - "igniter": {:hex, :igniter, "0.6.1", "e683495de01cb3cb30943670fd93fc9f603093c380225a4a6dd1f468a393f891", [:mix], [{:glob_ex, "~> 0.1.7", [hex: :glob_ex, repo: "hexpm", optional: false]}, {:jason, "~> 1.4", [hex: :jason, repo: "hexpm", optional: false]}, {:owl, "~> 0.11", [hex: :owl, repo: "hexpm", optional: false]}, {:phx_new, "~> 1.7", [hex: :phx_new, repo: "hexpm", optional: true]}, {:req, "~> 0.5", [hex: :req, repo: "hexpm", optional: false]}, {:rewrite, ">= 1.1.1 and < 2.0.0-0", [hex: :rewrite, repo: "hexpm", optional: false]}, {:sourceror, "~> 1.4", [hex: :sourceror, repo: "hexpm", optional: false]}, {:spitfire, ">= 0.1.3 and < 1.0.0-0", [hex: :spitfire, repo: "hexpm", optional: false]}], "hexpm", "81467df9d6e7210b262c41ccbbdb08c48491bd6fd3f2aee529a8ed730c6f84ba"}, + "igniter": {:hex, :igniter, "0.6.2", "6263fa3d2b7698f8d9afc506e4e1bccef69f1b8a3288760fe749dc70a9f6b408", [:mix], [{:glob_ex, "~> 0.1.7", [hex: :glob_ex, repo: "hexpm", optional: false]}, {:jason, "~> 1.4", [hex: :jason, repo: "hexpm", optional: false]}, {:owl, "~> 0.11", [hex: :owl, repo: "hexpm", optional: false]}, {:phx_new, "~> 1.7", [hex: :phx_new, repo: "hexpm", optional: true]}, {:req, "~> 0.5", [hex: :req, repo: "hexpm", optional: false]}, {:rewrite, ">= 1.1.1 and < 2.0.0-0", [hex: :rewrite, repo: "hexpm", optional: false]}, {:sourceror, "~> 1.4", [hex: :sourceror, repo: "hexpm", optional: false]}, {:spitfire, ">= 0.1.3 and < 1.0.0-0", [hex: :spitfire, repo: "hexpm", optional: false]}], "hexpm", "480c679066444459eecd371a41639cee365449e20cfb611457081394fd146b05"}, "iterex": {:hex, :iterex, "0.1.2", "58f9b9b9a22a55cbfc7b5234a9c9c63eaac26d276b3db80936c0e1c60355a5a6", [:mix], [], "hexpm", "2e103b8bcc81757a9af121f6dc0df312c9a17220f302b1193ef720460d03029d"}, "jason": {:hex, :jason, "1.4.4", "b9226785a9aa77b6857ca22832cffa5d5011a667207eb2a0ad56adb5db443b8a", [:mix], [{:decimal, "~> 1.0 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm", "c5eb0cab91f094599f94d55bc63409236a8ec69a21a67814529e8d5f6cc90b3b"}, "libgraph": {:hex, :libgraph, "0.16.0", "3936f3eca6ef826e08880230f806bfea13193e49bf153f93edcf0239d4fd1d07", [:mix], [], "hexpm", "41ca92240e8a4138c30a7e06466acc709b0cbb795c643e9e17174a178982d6bf"}, @@ -38,13 +38,13 @@ "nimble_pool": {:hex, :nimble_pool, "1.1.0", "bf9c29fbdcba3564a8b800d1eeb5a3c58f36e1e11d7b7fb2e084a643f645f06b", [:mix], [], "hexpm", "af2e4e6b34197db81f7aad230c1118eac993acc0dae6bc83bac0126d4ae0813a"}, "owl": {:hex, :owl, "0.12.2", "65906b525e5c3ef51bab6cba7687152be017aebe1da077bb719a5ee9f7e60762", [:mix], [{:ucwidth, "~> 0.2", [hex: :ucwidth, repo: "hexpm", optional: true]}], "hexpm", "6398efa9e1fea70a04d24231e10dcd66c1ac1aa2da418d20ef5357ec61de2880"}, "postgrex": {:hex, :postgrex, "0.20.0", "363ed03ab4757f6bc47942eff7720640795eb557e1935951c1626f0d303a3aed", [:mix], [{:db_connection, "~> 2.1", [hex: :db_connection, repo: "hexpm", optional: false]}, {:decimal, "~> 1.5 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:table, "~> 0.1.0", [hex: :table, repo: "hexpm", optional: true]}], "hexpm", "d36ef8b36f323d29505314f704e21a1a038e2dc387c6409ee0cd24144e187c0f"}, - "reactor": {:hex, :reactor, "0.15.2", "8c1b3fe0527b7a92b0b22c3f33f2e66858dd069bf1dd51d1031f63cd8cbd1fd5", [:mix], [{:igniter, "~> 0.4", [hex: :igniter, repo: "hexpm", optional: true]}, {:iterex, "~> 0.1", [hex: :iterex, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}, {:libgraph, "~> 0.16", [hex: :libgraph, repo: "hexpm", optional: false]}, {:spark, "~> 2.0", [hex: :spark, repo: "hexpm", optional: false]}, {:splode, "~> 0.2", [hex: :splode, repo: "hexpm", optional: false]}, {:telemetry, "~> 1.2", [hex: :telemetry, repo: "hexpm", optional: false]}, {:yaml_elixir, "~> 2.11", [hex: :yaml_elixir, repo: "hexpm", optional: false]}, {:ymlr, "~> 5.0", [hex: :ymlr, repo: "hexpm", optional: false]}], "hexpm", "091435a1fa0cab9bc2ed3934b203a0fd190f62e8b6aca63741f9242b8c7631ac"}, + "reactor": {:hex, :reactor, "0.15.3", "f1f05d5b0f229ad1a164b7a5543beee58c9975e7e146afc71821e5afc5c69a79", [:mix], [{:igniter, "~> 0.4", [hex: :igniter, repo: "hexpm", optional: true]}, {:iterex, "~> 0.1", [hex: :iterex, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}, {:libgraph, "~> 0.16", [hex: :libgraph, repo: "hexpm", optional: false]}, {:spark, "~> 2.0", [hex: :spark, repo: "hexpm", optional: false]}, {:splode, "~> 0.2", [hex: :splode, repo: "hexpm", optional: false]}, {:telemetry, "~> 1.2", [hex: :telemetry, repo: "hexpm", optional: false]}, {:yaml_elixir, "~> 2.11", [hex: :yaml_elixir, repo: "hexpm", optional: false]}, {:ymlr, "~> 5.0", [hex: :ymlr, repo: "hexpm", optional: false]}], "hexpm", "8a16a46163fcdeb1d1be06749f54bd71282126be27c9dc80010cf3b97fe7193c"}, "req": {:hex, :req, "0.5.10", "a3a063eab8b7510785a467f03d30a8d95f66f5c3d9495be3474b61459c54376c", [:mix], [{:brotli, "~> 0.3.1", [hex: :brotli, repo: "hexpm", optional: true]}, {:ezstd, "~> 1.0", [hex: :ezstd, repo: "hexpm", optional: true]}, {:finch, "~> 0.17", [hex: :finch, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}, {:mime, "~> 2.0.6 or ~> 2.1", [hex: :mime, repo: "hexpm", optional: false]}, {:nimble_csv, "~> 1.0", [hex: :nimble_csv, repo: "hexpm", optional: true]}, {:plug, "~> 1.0", [hex: :plug, repo: "hexpm", optional: true]}], "hexpm", "8a604815743f8a2d3b5de0659fa3137fa4b1cffd636ecb69b30b2b9b2c2559be"}, "rewrite": {:hex, :rewrite, "1.1.2", "f5a5d10f5fed1491a6ff48e078d4585882695962ccc9e6c779bae025d1f92eda", [:mix], [{:glob_ex, "~> 0.1", [hex: :glob_ex, repo: "hexpm", optional: false]}, {:sourceror, "~> 1.0", [hex: :sourceror, repo: "hexpm", optional: false]}, {:text_diff, "~> 0.1", [hex: :text_diff, repo: "hexpm", optional: false]}], "hexpm", "7f8b94b1e3528d0a47b3e8b7bfeca559d2948a65fa7418a9ad7d7712703d39d4"}, "simple_sat": {:hex, :simple_sat, "0.1.3", "f650fc3c184a5fe741868b5ac56dc77fdbb428468f6dbf1978e14d0334497578", [:mix], [], "hexpm", "a54305066a356b7194dc81db2a89232bacdc0b3edaef68ed9aba28dcbc34887b"}, "sobelow": {:hex, :sobelow, "0.14.0", "dd82aae8f72503f924fe9dd97ffe4ca694d2f17ec463dcfd365987c9752af6ee", [:mix], [{:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "7ecf91e298acfd9b24f5d761f19e8f6e6ac585b9387fb6301023f1f2cd5eed5f"}, "sourceror": {:hex, :sourceror, "1.10.0", "38397dedbbc286966ec48c7af13e228b171332be1ad731974438c77791945ce9", [:mix], [], "hexpm", "29dbdfc92e04569c9d8e6efdc422fc1d815f4bd0055dc7c51b8800fb75c4b3f1"}, - "spark": {:hex, :spark, "2.2.60", "1183d97cfd417d00902e3fafcaa154604f26e1d0ca558be0022006b7827a0ec8", [:mix], [{:igniter, ">= 0.3.64 and < 1.0.0-0", [hex: :igniter, repo: "hexpm", optional: true]}, {:jason, "~> 1.4", [hex: :jason, repo: "hexpm", optional: true]}, {:sourceror, "~> 1.2", [hex: :sourceror, repo: "hexpm", optional: true]}], "hexpm", "130c68bbe7d45dfb0c3e357d9778c487def0d15339b0b09b40e683c4f18aa2a5"}, + "spark": {:hex, :spark, "2.2.61", "64745581832caf136cbd654c1ecef98d291f3d1b347a14411b7d0dc726e3822b", [:mix], [{:igniter, ">= 0.3.64 and < 1.0.0-0", [hex: :igniter, repo: "hexpm", optional: true]}, {:jason, "~> 1.4", [hex: :jason, repo: "hexpm", optional: true]}, {:sourceror, "~> 1.2", [hex: :sourceror, repo: "hexpm", optional: true]}], "hexpm", "cb10300e17f74b41848954d61630fb627f4e0d5acf9aacd7d9f312d5b119d50f"}, "spitfire": {:hex, :spitfire, "0.2.0", "0de1f519a23f65bde40d316adad53c07a9563f25cc68915d639d8a509a0aad8a", [:mix], [], "hexpm", "743daaee2d81a0d8095431729f478ce49b47ea8943c7d770de86704975cb7775"}, "splode": {:hex, :splode, "0.2.9", "3a2776e187c82f42f5226b33b1220ccbff74f4bcc523dd4039c804caaa3ffdc7", [:mix], [], "hexpm", "8002b00c6e24f8bd1bcced3fbaa5c33346048047bb7e13d2f3ad428babbd95c3"}, "statistex": {:hex, :statistex, "1.0.0", "f3dc93f3c0c6c92e5f291704cf62b99b553253d7969e9a5fa713e5481cd858a5", [:mix], [], "hexpm", "ff9d8bee7035028ab4742ff52fc80a2aa35cece833cf5319009b52f1b5a86c27"}, From d18f6c60b27face846a9b75c603ec7e716515a31 Mon Sep 17 00:00:00 2001 From: Zach Daniel Date: Mon, 26 May 2025 00:38:40 -0400 Subject: [PATCH 009/174] fix: properly encode decimal scale & preicison into snapshots --- .../migration_generator.ex | 22 ++++++++++++------- test/migration_generator_test.exs | 8 ++++--- 2 files changed, 19 insertions(+), 11 deletions(-) diff --git a/lib/migration_generator/migration_generator.ex b/lib/migration_generator/migration_generator.ex index 231697ac..ea395da9 100644 --- a/lib/migration_generator/migration_generator.ex +++ b/lib/migration_generator/migration_generator.ex @@ -3384,29 +3384,35 @@ defmodule AshPostgres.MigrationGenerator do references |> Map.update!(:on_delete, &(&1 && references_on_delete_to_binary(&1))) end) - |> Map.update!(:type, fn type -> sanitize_type(type, attribute[:size]) end) + |> Map.update!(:type, fn type -> + sanitize_type(type, attribute[:size], attribute[:precision], attribute[:scale]) + end) end defp references_on_delete_to_binary(value) when is_atom(value), do: value defp references_on_delete_to_binary({:nilify, columns}), do: [:nilify, columns] - defp sanitize_type({:array, type}, size) do - ["array", sanitize_type(type, size)] + defp sanitize_type({:array, type}, size, scale, precision) do + ["array", sanitize_type(type, size, scale, precision)] end - defp sanitize_type(:varchar, size) when not is_nil(size) do + defp sanitize_type(:varchar, size, _scale, _precision) when not is_nil(size) do ["varchar", size] end - defp sanitize_type(:binary, size) when not is_nil(size) do + defp sanitize_type(:binary, size, _scale, _precision) when not is_nil(size) do ["binary", size] end - defp sanitize_type(type, size) when is_atom(type) and is_integer(size) do - [sanitize_type(type, nil), size] + defp sanitize_type(:decimal, _size, scale, precision) do + ["decimal", scale, precision] |> Enum.reject(&is_nil/1) + end + + defp sanitize_type(type, size, precision, decimal) when is_atom(type) and is_integer(size) do + [sanitize_type(type, nil, precision, decimal), size] end - defp sanitize_type(type, _) do + defp sanitize_type(type, _, _, _) do type end diff --git a/test/migration_generator_test.exs b/test/migration_generator_test.exs index 5b564b5f..a1168ccb 100644 --- a/test/migration_generator_test.exs +++ b/test/migration_generator_test.exs @@ -2877,10 +2877,12 @@ defmodule AshPostgres.MigrationGeneratorTest do # Check the second migration file second_migration = File.read!(Enum.at(migration_files, 1)) + [up, _down] = String.split(second_migration, "def down") + # Should contain the alter statement removing precision and scale - assert second_migration =~ ~S[modify :price, :decimal] - refute second_migration =~ ~S[precision:] - refute second_migration =~ ~S[scale:] + assert up =~ ~S[modify :price, :decimal] + refute up =~ ~S[precision:] + refute up =~ ~S[scale:] end test "works with decimal references that have precision and scale" do From dac674b53b5ed7f195c3ffb07cff14b478697859 Mon Sep 17 00:00:00 2001 From: Zach Daniel Date: Mon, 26 May 2025 21:42:51 -0400 Subject: [PATCH 010/174] feat: --dev flag for codegen (#555) --------- Co-authored-by: ken-kost --- config/config.exs | 10 +- .../development/migrations-and-tasks.md | 9 +- .../migration_generator.ex | 289 ++++++++++++++---- .../tasks/ash_postgres.generate_migrations.ex | 14 +- lib/mix/tasks/ash_postgres.migrate.ex | 11 +- lib/mix/tasks/ash_postgres.rollback.ex | 25 +- lib/multitenancy.ex | 14 +- mix.exs | 2 +- ...6214825_migrate_resources_extensions_1.exs | 172 +++++++++++ .../20250526214827_migrate_resources1.exs | 29 ++ .../dev_test_repo/extensions.json | 11 + .../multitenant_orgs/20250526214827.json | 70 +++++ test/dev_migrations_test.exs | 234 ++++++++++++++ test/migration_generator_test.exs | 189 ++++++++---- test/mix_squash_snapshots_test.exs | 9 +- test/support/dev_test_repo.ex | 39 +++ test/support/multitenancy/domain.ex | 1 + .../resources/dev_migrations_org.ex | 91 ++++++ test/test_helper.exs | 2 + usage-rules.md | 19 +- 20 files changed, 1091 insertions(+), 149 deletions(-) create mode 100644 priv/dev_test_repo/migrations/20250526214825_migrate_resources_extensions_1.exs create mode 100644 priv/dev_test_repo/migrations/20250526214827_migrate_resources1.exs create mode 100644 priv/resource_snapshots/dev_test_repo/extensions.json create mode 100644 priv/resource_snapshots/dev_test_repo/multitenant_orgs/20250526214827.json create mode 100644 test/dev_migrations_test.exs create mode 100644 test/support/dev_test_repo.ex create mode 100644 test/support/multitenancy/resources/dev_migrations_org.ex diff --git a/config/config.exs b/config/config.exs index ee88e028..0041c0ac 100644 --- a/config/config.exs +++ b/config/config.exs @@ -37,6 +37,14 @@ if Mix.env() == :test do hostname: "localhost", pool: Ecto.Adapters.SQL.Sandbox + config :ash_postgres, AshPostgres.DevTestRepo, + username: "postgres", + password: "postgres", + database: "ash_postgres_dev_test", + hostname: "localhost", + migration_primary_key: [name: :id, type: :binary_id], + pool: Ecto.Adapters.SQL.Sandbox + # sobelow_skip ["Config.Secrets"] config :ash_postgres, AshPostgres.TestRepo, password: "postgres" @@ -54,7 +62,7 @@ if Mix.env() == :test do migration_primary_key: [name: :id, type: :binary_id] config :ash_postgres, - ecto_repos: [AshPostgres.TestRepo, AshPostgres.TestNoSandboxRepo], + ecto_repos: [AshPostgres.TestRepo, AshPostgres.DevTestRepo, AshPostgres.TestNoSandboxRepo], ash_domains: [ AshPostgres.Test.Domain, AshPostgres.MultitenancyTest.Domain, diff --git a/documentation/topics/development/migrations-and-tasks.md b/documentation/topics/development/migrations-and-tasks.md index a9d6b951..04fefc93 100644 --- a/documentation/topics/development/migrations-and-tasks.md +++ b/documentation/topics/development/migrations-and-tasks.md @@ -7,9 +7,16 @@ Ash comes with its own tasks, and AshPostgres exposes lower level tasks that you ## Basic Workflow - Make resource changes -- Run `mix ash.codegen --name add_a_combobulator` to generate migrations and resource snapshots +- Run `mix ash.codegen --dev` to generate a migration tagged as a `dev` migration, which will later be squashed and does not require a name. +- Run `mix ash.migrate` to run the migrations. +- Make some more resource changes. +- Once you're all done, run `mix ash.codegen add_a_combobulator`, using a good name for your changes to generate migrations and resource snapshots. This will **rollback** the dev migrations, and squash them into a the new named migration (or sometimes migrations). - Run `mix ash.migrate` to run those migrations +The `--dev` workflow enables you to avoid having to think of a name for migrations while developing, and also enables some +upcoming workflows that will detect when code generation needs to be run on page load and will show you a button to generate +dev migrations and run them. + For more information on generating migrations, run `mix help ash_postgres.generate_migrations` (the underlying task that is called by `mix ash.migrate`) > ### list_tenants/0 {: .info} diff --git a/lib/migration_generator/migration_generator.ex b/lib/migration_generator/migration_generator.ex index ea395da9..2479d067 100644 --- a/lib/migration_generator/migration_generator.ex +++ b/lib/migration_generator/migration_generator.ex @@ -19,7 +19,9 @@ defmodule AshPostgres.MigrationGenerator do format: true, dry_run: false, check: false, + dev: false, snapshots_only: false, + auto_name: false, dont_drop_columns: false def generate(domains, opts \\ []) do @@ -226,11 +228,13 @@ defmodule AshPostgres.MigrationGenerator do Mix.shell().info("No extensions to install") :ok else + dev = if opts.dev, do: "_dev" + {module, migration_name} = case to_install do [{ext_name, version, _up_fn, _down_fn}] -> {"install_#{ext_name}_v#{version}_#{timestamp(true)}", - "#{timestamp(true)}_install_#{ext_name}_v#{version}_extension"} + "#{timestamp(true)}_install_#{ext_name}_v#{version}_extension#{dev}"} ["ash_functions"] -> {"install_ash_functions_extension_#{AshPostgres.MigrationGenerator.AshFunctions.latest_version()}_#{timestamp(true)}", @@ -239,6 +243,8 @@ defmodule AshPostgres.MigrationGenerator do _multiple -> migration_path = migration_path(opts, repo, false) + require_name!(opts) + if opts.name do count = migration_path @@ -262,7 +268,7 @@ defmodule AshPostgres.MigrationGenerator do |> Kernel.+(1) {"#{opts.name}_extensions_#{count}", - "#{timestamp(true)}_#{opts.name}_extensions_#{count}"} + "#{timestamp(true)}_#{opts.name}_extensions_#{count}#{dev}"} else count = migration_path @@ -286,7 +292,7 @@ defmodule AshPostgres.MigrationGenerator do |> Kernel.+(1) {"migrate_resources_extensions_#{count}", - "#{timestamp(true)}_migrate_resources_extensions_#{count}"} + "#{timestamp(true)}_migrate_resources_extensions_#{count}#{dev}"} end end @@ -452,6 +458,23 @@ defmodule AshPostgres.MigrationGenerator do :ok operations -> + dev_migrations = get_dev_migrations(opts, tenant?, repo) + + if !opts.dev and dev_migrations != [] do + if opts.check do + Mix.shell().error(""" + Generated migrations are from dev mode. + + Generate migrations without `--dev` flag. + """) + + exit({:shutdown, 1}) + else + remove_dev_migrations(dev_migrations, tenant?, repo, opts) + remove_dev_snapshots(snapshots, opts) + end + end + if opts.check do Mix.shell().error(""" Migrations would have been generated, but the --check flag was provided. @@ -491,6 +514,159 @@ defmodule AshPostgres.MigrationGenerator do end) end + defp get_dev_migrations(opts, tenant?, repo) do + opts + |> migration_path(repo, tenant?) + |> File.ls() + |> case do + {:error, _error} -> [] + {:ok, migrations} -> Enum.filter(migrations, &String.contains?(&1, "_dev.exs")) + end + end + + if Mix.env() == :test do + defp with_repo_not_in_test(repo, fun) do + fun.(repo) + end + else + defp with_repo_not_in_test(repo, fun) do + Ecto.Migrator.with_repo(repo, fun) + end + end + + defp require_name!(opts) do + if !opts.name && !opts.dry_run && !opts.check && !opts.snapshots_only && !opts.dev && + !opts.auto_name do + raise """ + Name must be provided when generating migrations, unless `--dry-run` or `--check` or `--dev` is also provided. + + Please provide a name. for example: + + mix ash_postgres.generate_migrations ...args + """ + end + + :ok + end + + defp remove_dev_migrations(dev_migrations, tenant?, repo, opts) do + dev_migrations = + Enum.map(dev_migrations, fn migration -> + opts + |> migration_path(repo, tenant?) + |> Path.join(migration) + end) + + if tenant? do + with_repo_not_in_test(repo, fn repo -> + for prefix <- repo.all_tenants() do + {repo, query, opts} = Ecto.Migration.SchemaMigration.versions(repo, [], prefix) + + versions = repo.all(query, opts) + + dev_migrations + |> Enum.map(&extract_migration_info/1) + |> Enum.filter(& &1) + |> Enum.map(&load_migration!/1) + |> Enum.filter(fn {version, _} -> + version in versions + end) + |> Enum.each(fn {version, mod} -> + Ecto.Migration.Runner.run( + repo, + [], + version, + mod, + :forward, + :down, + :down, + all: true, + prefix: prefix + ) + + Ecto.Migration.SchemaMigration.down(repo, repo.config(), version, prefix: prefix) + end) + end + end) + else + with_repo_not_in_test(repo, fn repo -> + {repo, query, opts} = Ecto.Migration.SchemaMigration.versions(repo, [], nil) + + versions = repo.all(query, opts) + + dev_migrations + |> Enum.map(&extract_migration_info/1) + |> Enum.filter(& &1) + |> Enum.map(&load_migration!/1) + |> Enum.sort() + |> Enum.filter(fn {version, _} -> + version in versions + end) + |> Enum.each(fn {version, mod} -> + Ecto.Migration.Runner.run( + repo, + [], + version, + mod, + :forward, + :down, + :down, + all: true + ) + + Ecto.Migration.SchemaMigration.down(repo, repo.config(), version, []) + end) + end) + end + + Enum.each(dev_migrations, &File.rm!/1) + end + + defp extract_migration_info(file) do + base = Path.basename(file) + + case Integer.parse(Path.rootname(base)) do + {integer, "_" <> name} -> {integer, name, file} + _ -> nil + end + end + + defp load_migration!({version, _, file}) when is_binary(file) do + loaded_modules = file |> compile_file() |> Enum.map(&elem(&1, 0)) + + if mod = Enum.find(loaded_modules, &migration?/1) do + {version, mod} + else + raise Ecto.MigrationError, + "file #{Path.relative_to_cwd(file)} does not define an Ecto.Migration" + end + end + + defp compile_file(file) do + AshPostgres.MigrationCompileCache.start_link() + AshPostgres.MigrationCompileCache.compile_file(file) + end + + defp migration?(mod) do + function_exported?(mod, :__migration__, 0) + end + + def remove_dev_snapshots(snapshots, opts) do + Enum.each(snapshots, fn snapshot -> + folder = get_snapshot_folder(snapshot, opts) + snapshot_path = get_snapshot_path(snapshot, folder) + + snapshot_path + |> File.ls!() + |> Enum.filter(&String.contains?(&1, "_dev.json")) + |> Enum.each(fn snapshot_name -> + snapshot_path + |> Path.join(snapshot_name) + |> File.rm!() + end) + end) + end + defp split_into_migrations(operations) do operations |> Enum.split_with(fn @@ -932,6 +1108,8 @@ defmodule AshPostgres.MigrationGenerator do defp write_migration!({up, down}, repo, opts, tenant?, run_without_transaction?) do migration_path = migration_path(opts, repo, tenant?) + require_name!(opts) + {migration_name, last_part} = if opts.name do {"#{timestamp(true)}_#{opts.name}", "#{opts.name}"} @@ -962,7 +1140,7 @@ defmodule AshPostgres.MigrationGenerator do migration_file = migration_path - |> Path.join(migration_name <> ".exs") + |> Path.join(migration_name <> "#{if opts.dev, do: "_dev"}.exs") module_name = if tenant? do @@ -1056,20 +1234,25 @@ defmodule AshPostgres.MigrationGenerator do |> Path.join(repo_name) end + dev = if opts.dev, do: "_dev" + snapshot_file = if snapshot.schema do - Path.join(snapshot_folder, "#{snapshot.schema}.#{snapshot.table}/#{timestamp()}.json") + Path.join( + snapshot_folder, + "#{snapshot.schema}.#{snapshot.table}/#{timestamp()}#{dev}.json" + ) else - Path.join(snapshot_folder, "#{snapshot.table}/#{timestamp()}.json") + Path.join(snapshot_folder, "#{snapshot.table}/#{timestamp()}#{dev}.json") end File.mkdir_p(Path.dirname(snapshot_file)) create_file(snapshot_file, snapshot_binary, force: true) - old_snapshot_folder = Path.join(snapshot_folder, "#{snapshot.table}.json") + old_snapshot_folder = Path.join(snapshot_folder, "#{snapshot.table}#{dev}.json") if File.exists?(old_snapshot_folder) do - new_snapshot_folder = Path.join(snapshot_folder, "#{snapshot.table}/initial.json") + new_snapshot_folder = Path.join(snapshot_folder, "#{snapshot.table}/initial#{dev}.json") File.rename(old_snapshot_folder, new_snapshot_folder) end end) @@ -2653,43 +2836,22 @@ defmodule AshPostgres.MigrationGenerator do end def get_existing_snapshot(snapshot, opts) do - repo_name = snapshot.repo |> Module.split() |> List.last() |> Macro.underscore() - - folder = - if snapshot.multitenancy.strategy == :context do - opts - |> snapshot_path(snapshot.repo) - |> Path.join(repo_name) - |> Path.join("tenants") - else - opts - |> snapshot_path(snapshot.repo) - |> Path.join(repo_name) - end - - snapshot_folder = - if snapshot.schema do - schema_dir = Path.join(folder, "#{snapshot.schema}.#{snapshot.table}") + folder = get_snapshot_folder(snapshot, opts) + snapshot_path = get_snapshot_path(snapshot, folder) - if File.dir?(schema_dir) do - schema_dir - else - Path.join(folder, snapshot.table) - end - else - Path.join(folder, snapshot.table) - end - - if File.exists?(snapshot_folder) do - snapshot_folder + if File.exists?(snapshot_path) do + snapshot_path |> File.ls!() - |> Enum.filter(&String.match?(&1, ~r/^\d{14}\.json$/)) + |> Enum.filter( + &(String.match?(&1, ~r/^\d{14}\.json$/) or + (opts.dev and String.match?(&1, ~r/^\d{14}\_dev.json$/))) + ) |> case do [] -> get_old_snapshot(folder, snapshot) snapshot_files -> - snapshot_folder + snapshot_path |> Path.join(Enum.max(snapshot_files)) |> File.read!() |> load_snapshot() @@ -2699,6 +2861,33 @@ defmodule AshPostgres.MigrationGenerator do end end + defp get_snapshot_folder(snapshot, opts) do + if snapshot.multitenancy.strategy == :context do + opts + |> snapshot_path(snapshot.repo) + |> Path.join(repo_name(snapshot.repo)) + |> Path.join("tenants") + else + opts + |> snapshot_path(snapshot.repo) + |> Path.join(repo_name(snapshot.repo)) + end + end + + defp get_snapshot_path(snapshot, folder) do + if snapshot.schema do + schema_dir = Path.join(folder, "#{snapshot.schema}.#{snapshot.table}") + + if File.dir?(schema_dir) do + schema_dir + else + Path.join(folder, snapshot.table) + end + else + Path.join(folder, snapshot.table) + end + end + defp get_old_snapshot(folder, snapshot) do schema_file = if snapshot.schema do @@ -3182,11 +3371,7 @@ defmodule AshPostgres.MigrationGenerator do scale -> scale end - cond do - precision && scale -> {:decimal, precision, scale} - precision -> {:decimal, precision} - true -> :decimal - end + {:decimal, precision, scale} end defp migration_type(other, constraints) do @@ -3405,7 +3590,7 @@ defmodule AshPostgres.MigrationGenerator do end defp sanitize_type(:decimal, _size, scale, precision) do - ["decimal", scale, precision] |> Enum.reject(&is_nil/1) + ["decimal", precision, scale] end defp sanitize_type(type, size, precision, decimal) when is_atom(type) and is_integer(size) do @@ -3512,11 +3697,11 @@ defmodule AshPostgres.MigrationGenerator do {other, size} when is_atom(other) and is_integer(size) -> {other, size, nil, nil} - {:decimal, scale} -> - {:decimal, scale, nil, nil} + {:decimal, precision} -> + {:decimal, nil, nil, precision} - {:decimal, scale, precision} -> - {:decimal, scale, precision, nil} + {:decimal, precision, scale} -> + {:decimal, nil, precision, scale} other -> {other, nil, nil, nil} @@ -3620,12 +3805,12 @@ defmodule AshPostgres.MigrationGenerator do {:binary, size} end - defp load_type(["decimal", scale]) do - {:decimal, scale} + defp load_type(["decimal", precision]) do + {:decimal, precision} end - defp load_type(["decimal", scale, precision]) do - {:decimal, scale, precision} + defp load_type(["decimal", precision, scale]) do + {:decimal, precision, scale} end defp load_type([string, size]) when is_binary(string) and is_integer(size) do diff --git a/lib/mix/tasks/ash_postgres.generate_migrations.ex b/lib/mix/tasks/ash_postgres.generate_migrations.ex index 065942c8..8431572c 100644 --- a/lib/mix/tasks/ash_postgres.generate_migrations.ex +++ b/lib/mix/tasks/ash_postgres.generate_migrations.ex @@ -21,6 +21,7 @@ defmodule Mix.Tasks.AshPostgres.GenerateMigrations do * `no-format` - files that are created will not be formatted with the code formatter * `dry-run` - no files are created, instead the new migration is printed * `check` - no files are created, returns an exit(1) code if the current snapshots and resources don't fit + * `dev` - dev files are created * `snapshots-only` - no migrations are generated, only snapshots are stored * `concurrent-indexes` - new identities will be run concurrently and in a separate migration (like concurrent custom indexes) @@ -93,10 +94,12 @@ defmodule Mix.Tasks.AshPostgres.GenerateMigrations do tenant_migration_path: :string, quiet: :boolean, snapshots_only: :boolean, + auto_name: :boolean, name: :string, no_format: :boolean, dry_run: :boolean, check: :boolean, + dev: :boolean, dont_drop_columns: :boolean, concurrent_indexes: :boolean ] @@ -110,17 +113,6 @@ defmodule Mix.Tasks.AshPostgres.GenerateMigrations do |> Keyword.delete(:no_format) |> Keyword.put_new(:name, name) - if !opts[:name] && !opts[:dry_run] && !opts[:check] && !opts[:snapshots_only] do - IO.warn(""" - Name must be provided when generating migrations, unless `--dry-run` or `--check` is also provided. - Using an autogenerated name will be deprecated in a future release. - - Please provide a name. for example: - - mix ash_postgres.generate_migrations #{Enum.join(args, " ")} - """) - end - AshPostgres.MigrationGenerator.generate(domains, opts) end end diff --git a/lib/mix/tasks/ash_postgres.migrate.ex b/lib/mix/tasks/ash_postgres.migrate.ex index 36b9187d..3299fc5b 100644 --- a/lib/mix/tasks/ash_postgres.migrate.ex +++ b/lib/mix/tasks/ash_postgres.migrate.ex @@ -119,6 +119,8 @@ defmodule Mix.Tasks.AshPostgres.Migrate do |> AshPostgres.Mix.Helpers.delete_flag("--tenants") |> AshPostgres.Mix.Helpers.delete_arg("--only-tenants") |> AshPostgres.Mix.Helpers.delete_arg("--except-tenants") + |> AshPostgres.Mix.Helpers.delete_arg("--repo") + |> AshPostgres.Mix.Helpers.delete_arg("-r") Mix.Task.reenable("ecto.migrate") @@ -128,9 +130,16 @@ defmodule Mix.Tasks.AshPostgres.Migrate do for tenant <- tenants(repo, opts) do rest_opts = AshPostgres.Mix.Helpers.delete_arg(rest_opts, "--prefix") + repo = + if is_atom(repo) do + inspect(repo) + else + repo + end + Mix.Task.run( "ecto.migrate", - ["-r", to_string(repo)] ++ + ["-r", repo] ++ rest_opts ++ ["--prefix", tenant, "--migrations-path", tenant_migrations_path(opts, repo)] ) diff --git a/lib/mix/tasks/ash_postgres.rollback.ex b/lib/mix/tasks/ash_postgres.rollback.ex index b9a8354a..add81d59 100644 --- a/lib/mix/tasks/ash_postgres.rollback.ex +++ b/lib/mix/tasks/ash_postgres.rollback.ex @@ -61,6 +61,7 @@ defmodule Mix.Tasks.AshPostgres.Rollback do log_migrator_sql: :boolean, only_tenants: :string, except_tenants: :string, + already_started: :boolean, repo: :string ], aliases: [n: :step, v: :to, r: :repo] @@ -76,25 +77,23 @@ defmodule Mix.Tasks.AshPostgres.Rollback do |> AshPostgres.Mix.Helpers.delete_flag("--only-tenants") |> AshPostgres.Mix.Helpers.delete_flag("--except-tenants") |> AshPostgres.Mix.Helpers.delete_arg("-r") + |> AshPostgres.Mix.Helpers.delete_arg("--already-started") Mix.Task.reenable("ecto.rollback") if opts[:tenants] do for repo <- repos do - Ecto.Migrator.with_repo(repo, fn repo -> - for tenant <- tenants(repo, opts) do - rest_opts = AshPostgres.Mix.Helpers.delete_arg(rest_opts, "--prefix") + for tenant <- tenants(repo, opts) do + Mix.Task.reenable("ecto.rollback") + rest_opts = AshPostgres.Mix.Helpers.delete_arg(rest_opts, "--prefix") - Mix.Task.run( - "ecto.rollback", - ["-r", to_string(repo)] ++ - rest_opts ++ - ["--prefix", tenant, "--migrations-path", tenant_migrations_path(opts, repo)] - ) - - Mix.Task.reenable("ecto.rollback") - end - end) + Mix.Task.run( + "ecto.rollback", + ["-r", to_string(repo)] ++ + rest_opts ++ + ["--prefix", tenant, "--migrations-path", tenant_migrations_path(opts, repo)] + ) + end end else for repo <- repos do diff --git a/lib/multitenancy.ex b/lib/multitenancy.ex index 96cddafc..eac6d15a 100644 --- a/lib/multitenancy.ex +++ b/lib/multitenancy.ex @@ -3,6 +3,7 @@ defmodule AshPostgres.MultiTenancy do @dialyzer {:nowarn_function, load_migration!: 1} + # sobelow_skip ["SQL.Query"] def create_tenant!(tenant_name, repo) do validate_tenant_name!(tenant_name) Ecto.Adapters.SQL.query!(repo, "CREATE SCHEMA IF NOT EXISTS \"#{tenant_name}\"", []) @@ -10,7 +11,7 @@ defmodule AshPostgres.MultiTenancy do migrate_tenant(tenant_name, repo) end - def migrate_tenant(tenant_name, repo, migrations_path \\ nil) do + def migrate_tenant(tenant_name, repo, migrations_path \\ nil, after_file \\ nil) do tenant_migrations_path = migrations_path || repo.config()[:tenant_migrations_path] || default_tenant_migration_path(repo) @@ -24,6 +25,17 @@ defmodule AshPostgres.MultiTenancy do [tenant_migrations_path, "**", "*.exs"] |> Path.join() |> Path.wildcard() + |> then(fn files -> + if after_file do + files + |> Enum.drop_while(fn file -> + file != after_file + end) + |> Enum.drop(1) + else + files + end + end) |> Enum.map(&extract_migration_info/1) |> Enum.filter(& &1) |> Enum.map(&load_migration!/1) diff --git a/mix.exs b/mix.exs index 31424e80..fb84295b 100644 --- a/mix.exs +++ b/mix.exs @@ -240,7 +240,7 @@ defmodule AshPostgres.MixProject do format: "format --migrate", "spark.formatter": "spark.formatter --extensions AshPostgres.DataLayer", "spark.cheat_sheets": "spark.cheat_sheets --extensions AshPostgres.DataLayer", - "test.generate_migrations": "ash_postgres.generate_migrations", + "test.generate_migrations": "ash_postgres.generate_migrations --auto-name", "test.check_migrations": "ash_postgres.generate_migrations --check", "test.migrate_tenants": "ash_postgres.migrate --tenants", "test.migrate": "ash_postgres.migrate", diff --git a/priv/dev_test_repo/migrations/20250526214825_migrate_resources_extensions_1.exs b/priv/dev_test_repo/migrations/20250526214825_migrate_resources_extensions_1.exs new file mode 100644 index 00000000..389b0b27 --- /dev/null +++ b/priv/dev_test_repo/migrations/20250526214825_migrate_resources_extensions_1.exs @@ -0,0 +1,172 @@ +defmodule AshPostgres.DevTestRepo.Migrations.MigrateResourcesExtensions1 do + @moduledoc """ + Installs any extensions that are mentioned in the repo's `installed_extensions/0` callback + + This file was autogenerated with `mix ash_postgres.generate_migrations` + """ + + use Ecto.Migration + + def up do + execute(""" + CREATE OR REPLACE FUNCTION ash_elixir_or(left BOOLEAN, in right ANYCOMPATIBLE, out f1 ANYCOMPATIBLE) + AS $$ SELECT COALESCE(NULLIF($1, FALSE), $2) $$ + LANGUAGE SQL + SET search_path = '' + IMMUTABLE; + """) + + execute(""" + CREATE OR REPLACE FUNCTION ash_elixir_or(left ANYCOMPATIBLE, in right ANYCOMPATIBLE, out f1 ANYCOMPATIBLE) + AS $$ SELECT COALESCE($1, $2) $$ + LANGUAGE SQL + SET search_path = '' + IMMUTABLE; + """) + + execute(""" + CREATE OR REPLACE FUNCTION ash_elixir_and(left BOOLEAN, in right ANYCOMPATIBLE, out f1 ANYCOMPATIBLE) AS $$ + SELECT CASE + WHEN $1 IS TRUE THEN $2 + ELSE $1 + END $$ + LANGUAGE SQL + SET search_path = '' + IMMUTABLE; + """) + + execute(""" + CREATE OR REPLACE FUNCTION ash_elixir_and(left ANYCOMPATIBLE, in right ANYCOMPATIBLE, out f1 ANYCOMPATIBLE) AS $$ + SELECT CASE + WHEN $1 IS NOT NULL THEN $2 + ELSE $1 + END $$ + LANGUAGE SQL + SET search_path = '' + IMMUTABLE; + """) + + execute(""" + CREATE OR REPLACE FUNCTION ash_trim_whitespace(arr text[]) + RETURNS text[] AS $$ + DECLARE + start_index INT = 1; + end_index INT = array_length(arr, 1); + BEGIN + WHILE start_index <= end_index AND arr[start_index] = '' LOOP + start_index := start_index + 1; + END LOOP; + + WHILE end_index >= start_index AND arr[end_index] = '' LOOP + end_index := end_index - 1; + END LOOP; + + IF start_index > end_index THEN + RETURN ARRAY[]::text[]; + ELSE + RETURN arr[start_index : end_index]; + END IF; + END; $$ + LANGUAGE plpgsql + SET search_path = '' + IMMUTABLE; + """) + + execute(""" + CREATE OR REPLACE FUNCTION ash_raise_error(json_data jsonb) + RETURNS BOOLEAN AS $$ + BEGIN + -- Raise an error with the provided JSON data. + -- The JSON object is converted to text for inclusion in the error message. + RAISE EXCEPTION 'ash_error: %', json_data::text; + RETURN NULL; + END; + $$ LANGUAGE plpgsql + STABLE + SET search_path = ''; + """) + + execute(""" + CREATE OR REPLACE FUNCTION ash_raise_error(json_data jsonb, type_signal ANYCOMPATIBLE) + RETURNS ANYCOMPATIBLE AS $$ + BEGIN + -- Raise an error with the provided JSON data. + -- The JSON object is converted to text for inclusion in the error message. + RAISE EXCEPTION 'ash_error: %', json_data::text; + RETURN NULL; + END; + $$ LANGUAGE plpgsql + STABLE + SET search_path = ''; + """) + + execute(""" + CREATE OR REPLACE FUNCTION uuid_generate_v7() + RETURNS UUID + AS $$ + DECLARE + timestamp TIMESTAMPTZ; + microseconds INT; + BEGIN + timestamp = clock_timestamp(); + microseconds = (cast(extract(microseconds FROM timestamp)::INT - (floor(extract(milliseconds FROM timestamp))::INT * 1000) AS DOUBLE PRECISION) * 4.096)::INT; + + RETURN encode( + set_byte( + set_byte( + overlay(uuid_send(gen_random_uuid()) placing substring(int8send(floor(extract(epoch FROM timestamp) * 1000)::BIGINT) FROM 3) FROM 1 FOR 6 + ), + 6, (b'0111' || (microseconds >> 8)::bit(4))::bit(8)::int + ), + 7, microseconds::bit(8)::int + ), + 'hex')::UUID; + END + $$ + LANGUAGE PLPGSQL + SET search_path = '' + VOLATILE; + """) + + execute(""" + CREATE OR REPLACE FUNCTION timestamp_from_uuid_v7(_uuid uuid) + RETURNS TIMESTAMP WITHOUT TIME ZONE + AS $$ + SELECT to_timestamp(('x0000' || substr(_uuid::TEXT, 1, 8) || substr(_uuid::TEXT, 10, 4))::BIT(64)::BIGINT::NUMERIC / 1000); + $$ + LANGUAGE SQL + SET search_path = '' + IMMUTABLE PARALLEL SAFE STRICT; + """) + + execute("CREATE EXTENSION IF NOT EXISTS \"uuid-ossp\"") + execute("CREATE EXTENSION IF NOT EXISTS \"pg_trgm\"") + execute("CREATE EXTENSION IF NOT EXISTS \"citext\"") + + execute(""" + CREATE OR REPLACE FUNCTION ash_demo_functions() + RETURNS boolean AS $$ SELECT TRUE $$ + LANGUAGE SQL + IMMUTABLE; + """) + + execute("CREATE EXTENSION IF NOT EXISTS \"ltree\"") + end + + def down do + # Uncomment this if you actually want to uninstall the extensions + # when this migration is rolled back: + execute( + "DROP FUNCTION IF EXISTS uuid_generate_v7(), timestamp_from_uuid_v7(uuid), ash_raise_error(jsonb), ash_raise_error(jsonb, ANYCOMPATIBLE), ash_elixir_and(BOOLEAN, ANYCOMPATIBLE), ash_elixir_and(ANYCOMPATIBLE, ANYCOMPATIBLE), ash_elixir_or(ANYCOMPATIBLE, ANYCOMPATIBLE), ash_elixir_or(BOOLEAN, ANYCOMPATIBLE), ash_trim_whitespace(text[])" + ) + + # execute("DROP EXTENSION IF EXISTS \"uuid-ossp\"") + # execute("DROP EXTENSION IF EXISTS \"pg_trgm\"") + # execute("DROP EXTENSION IF EXISTS \"citext\"") + execute(""" + DROP FUNCTION IF EXISTS ash_demo_functions() + """) + + # execute("DROP EXTENSION IF EXISTS \"ltree\"") + end +end diff --git a/priv/dev_test_repo/migrations/20250526214827_migrate_resources1.exs b/priv/dev_test_repo/migrations/20250526214827_migrate_resources1.exs new file mode 100644 index 00000000..3a56462c --- /dev/null +++ b/priv/dev_test_repo/migrations/20250526214827_migrate_resources1.exs @@ -0,0 +1,29 @@ +defmodule AshPostgres.DevTestRepo.Migrations.MigrateResources1 do + @moduledoc """ + Updates resources based on their most recent snapshots. + + This file was autogenerated with `mix ash_postgres.generate_migrations` + """ + + use Ecto.Migration + + def up do + create table(:multitenant_orgs, primary_key: false) do + add(:id, :uuid, null: false, default: fragment("gen_random_uuid()"), primary_key: true) + add(:name, :text) + add(:owner_id, :uuid) + end + + create( + unique_index(:multitenant_orgs, [:id, :name], name: "multitenant_orgs_unique_by_name_index") + ) + end + + def down do + drop_if_exists( + unique_index(:multitenant_orgs, [:id, :name], name: "multitenant_orgs_unique_by_name_index") + ) + + drop(table(:multitenant_orgs)) + end +end diff --git a/priv/resource_snapshots/dev_test_repo/extensions.json b/priv/resource_snapshots/dev_test_repo/extensions.json new file mode 100644 index 00000000..d1c5a122 --- /dev/null +++ b/priv/resource_snapshots/dev_test_repo/extensions.json @@ -0,0 +1,11 @@ +{ + "ash_functions_version": 5, + "installed": [ + "ash-functions", + "uuid-ossp", + "pg_trgm", + "citext", + "demo-functions_v1", + "ltree" + ] +} \ No newline at end of file diff --git a/priv/resource_snapshots/dev_test_repo/multitenant_orgs/20250526214827.json b/priv/resource_snapshots/dev_test_repo/multitenant_orgs/20250526214827.json new file mode 100644 index 00000000..072cfe57 --- /dev/null +++ b/priv/resource_snapshots/dev_test_repo/multitenant_orgs/20250526214827.json @@ -0,0 +1,70 @@ +{ + "attributes": [ + { + "allow_nil?": false, + "default": "fragment(\"gen_random_uuid()\")", + "generated?": false, + "precision": null, + "primary_key?": true, + "references": null, + "scale": null, + "size": null, + "source": "id", + "type": "uuid" + }, + { + "allow_nil?": true, + "default": "nil", + "generated?": false, + "precision": null, + "primary_key?": false, + "references": null, + "scale": null, + "size": null, + "source": "name", + "type": "text" + }, + { + "allow_nil?": true, + "default": "nil", + "generated?": false, + "precision": null, + "primary_key?": false, + "references": null, + "scale": null, + "size": null, + "source": "owner_id", + "type": "uuid" + } + ], + "base_filter": null, + "check_constraints": [], + "custom_indexes": [], + "custom_statements": [], + "has_create_action": true, + "hash": "979D7BEB5939EAD2706978B7914C561B5F6854EBBCFD1F2748AB4C98668304EB", + "identities": [ + { + "all_tenants?": false, + "base_filter": null, + "index_name": "multitenant_orgs_unique_by_name_index", + "keys": [ + { + "type": "atom", + "value": "name" + } + ], + "name": "unique_by_name", + "nils_distinct?": true, + "where": null + } + ], + "multitenancy": { + "attribute": "id", + "global": true, + "strategy": "attribute" + }, + "repo": "Elixir.AshPostgres.DevTestRepo", + "schema": null, + "table": "multitenant_orgs" +} \ No newline at end of file diff --git a/test/dev_migrations_test.exs b/test/dev_migrations_test.exs new file mode 100644 index 00000000..475aa909 --- /dev/null +++ b/test/dev_migrations_test.exs @@ -0,0 +1,234 @@ +defmodule AshPostgres.DevMigrationsTest do + use AshPostgres.RepoCase, async: false + @moduletag :migration + + import ExUnit.CaptureLog + require Logger + + alias Ecto.Adapters.SQL.Sandbox + + setup do + current_shell = Mix.shell() + + :ok = Mix.shell(Mix.Shell.Process) + + on_exit(fn -> + Mix.shell(current_shell) + end) + + Sandbox.checkout(AshPostgres.DevTestRepo) + end + + defmacrop defresource(mod, do: body) do + quote do + Code.compiler_options(ignore_module_conflict: true) + + defmodule unquote(mod) do + use Ash.Resource, + domain: nil, + data_layer: AshPostgres.DataLayer + + unquote(body) + end + + Code.compiler_options(ignore_module_conflict: false) + end + end + + defmacrop defposts(do: body) do + quote do + defresource Post do + postgres do + table "posts" + repo(AshPostgres.DevTestRepo) + + custom_indexes do + # need one without any opts + index(["id"]) + index(["id"], unique: true, name: "test_unique_index") + end + end + + actions do + defaults([:create, :read, :update, :destroy]) + end + + unquote(body) + end + end + end + + defmacrop defdomain(resources) do + quote do + Code.compiler_options(ignore_module_conflict: true) + + defmodule Domain do + use Ash.Domain + + resources do + for resource <- unquote(resources) do + resource(resource) + end + end + end + + Code.compiler_options(ignore_module_conflict: false) + end + end + + setup do + resource_dev_path = "priv/resource_snapshots/dev_test_repo" + + initial_resource_files = + if File.exists?(resource_dev_path), do: File.ls!(resource_dev_path), else: [] + + migrations_dev_path = "priv/dev_test_repo/migrations" + + initial_migration_files = + if File.exists?(migrations_dev_path), do: File.ls!(migrations_dev_path), else: [] + + tenant_migrations_dev_path = "priv/dev_test_repo/tenant_migrations" + + initial_tenant_migration_files = + if File.exists?(tenant_migrations_dev_path), + do: File.ls!(tenant_migrations_dev_path), + else: [] + + on_exit(fn -> + if File.exists?(resource_dev_path) do + current_resource_files = File.ls!(resource_dev_path) + new_resource_files = current_resource_files -- initial_resource_files + Enum.each(new_resource_files, &File.rm_rf!(Path.join(resource_dev_path, &1))) + end + + if File.exists?(migrations_dev_path) do + current_migration_files = File.ls!(migrations_dev_path) + new_migration_files = current_migration_files -- initial_migration_files + Enum.each(new_migration_files, &File.rm!(Path.join(migrations_dev_path, &1))) + end + + if File.exists?(tenant_migrations_dev_path) do + current_tenant_migration_files = File.ls!(tenant_migrations_dev_path) + + new_tenant_migration_files = + current_tenant_migration_files -- initial_tenant_migration_files + + Enum.each( + new_tenant_migration_files, + &File.rm!(Path.join(tenant_migrations_dev_path, &1)) + ) + end + + AshPostgres.DevTestRepo.query!("DROP TABLE IF EXISTS posts") + end) + end + + describe "--dev option" do + test "rolls back dev migrations before deleting" do + defposts do + attributes do + uuid_primary_key(:id) + attribute(:title, :string, public?: true) + end + end + + defdomain([Post]) + + AshPostgres.MigrationGenerator.generate(Domain, + snapshot_path: "priv/resource_snapshots", + migration_path: "priv/dev_test_repo/migrations", + dev: true, + auto_name: true + ) + + assert [_extensions, migration, _migration] = + Path.wildcard("priv/dev_test_repo/migrations/**/*_migrate_resources*.exs") + + assert capture_log(fn -> migrate(migration) end) =~ "create table posts" + + AshPostgres.MigrationGenerator.generate(Domain, + snapshot_path: "priv/resource_snapshots", + migration_path: "priv/dev_test_repo/migrations", + auto_name: true + ) + + assert capture_log(fn -> migrate(migration) end) =~ "create table posts" + end + end + + describe "--dev option tenant" do + test "rolls back dev migrations before deleting" do + defposts do + attributes do + uuid_primary_key(:id) + attribute(:title, :string, public?: true, primary_key?: true, allow_nil?: false) + end + + multitenancy do + strategy(:context) + end + end + + defdomain([Post]) + + AshPostgres.MigrationGenerator.generate(Domain, + snapshot_path: "priv/resource_snapshots", + migration_path: "priv/dev_test_repo/migrations", + tenant_migration_path: "priv/dev_test_repo/tenant_migrations", + dev: true, + auto_name: true + ) + + org = + AshPostgres.MultitenancyTest.DevMigrationsOrg + |> Ash.Changeset.for_create(:create, %{name: "test1"}, authorize?: false) + |> Ash.create!() + + assert [_] = + Enum.sort( + Path.wildcard("priv/dev_test_repo/migrations/**/*_migrate_resources*.exs") + ) + |> Enum.reject(&String.contains?(&1, "extensions")) + + assert [_tenant_migration] = + Enum.sort( + Path.wildcard("priv/dev_test_repo/tenant_migrations/**/*_migrate_resources*.exs") + ) + |> Enum.reject(&String.contains?(&1, "extensions")) + + AshPostgres.MigrationGenerator.generate(Domain, + snapshot_path: "priv/resource_snapshots", + migration_path: "priv/dev_test_repo/migrations", + tenant_migration_path: "priv/dev_test_repo/tenant_migrations", + auto_name: true + ) + + assert [_tenant_migration] = + Enum.sort( + Path.wildcard("priv/dev_test_repo/tenant_migrations/**/*_migrate_resources*.exs") + ) + |> Enum.reject(&String.contains?(&1, "extensions")) + + assert capture_log(fn -> tenant_migrate() end) =~ "create table org_#{org.id}.posts" + end + end + + defp migrate(after_file) do + AshPostgres.MultiTenancy.migrate_tenant( + nil, + AshPostgres.DevTestRepo, + "priv/dev_test_repo/migrations", + after_file + ) + end + + defp tenant_migrate do + for tenant <- AshPostgres.DevTestRepo.all_tenants() do + AshPostgres.MultiTenancy.migrate_tenant( + tenant, + AshPostgres.DevTestRepo, + "priv/dev_test_repo/tenant_migrations" + ) + end + end +end diff --git a/test/migration_generator_test.exs b/test/migration_generator_test.exs index a1168ccb..6a4d0ef5 100644 --- a/test/migration_generator_test.exs +++ b/test/migration_generator_test.exs @@ -147,7 +147,8 @@ defmodule AshPostgres.MigrationGeneratorTest do snapshot_path: "test_snapshots_path", migration_path: "test_migration_path", quiet: true, - format: false + format: false, + auto_name: true ) :ok @@ -247,7 +248,8 @@ defmodule AshPostgres.MigrationGeneratorTest do snapshot_path: "test_snapshots_path", migration_path: "test_migration_path", quiet: true, - format: false + format: false, + auto_name: true ) :ok @@ -326,7 +328,8 @@ defmodule AshPostgres.MigrationGeneratorTest do snapshot_path: "test_snapshots_path", migration_path: "test_migration_path", quiet: true, - format: false + format: false, + auto_name: true ) end @@ -371,7 +374,8 @@ defmodule AshPostgres.MigrationGeneratorTest do snapshot_path: "test_snapshots_path", migration_path: "test_migration_path", quiet: true, - format: false + format: false, + auto_name: true ) end @@ -414,7 +418,8 @@ defmodule AshPostgres.MigrationGeneratorTest do snapshot_path: "test_snapshots_path", migration_path: "test_migration_path", quiet: true, - format: false + format: false, + auto_name: true ) end @@ -440,7 +445,8 @@ defmodule AshPostgres.MigrationGeneratorTest do snapshot_path: "test_snapshots_path", migration_path: "test_migration_path", quiet: true, - format: false + format: false, + auto_name: true ) assert [_file1, file2] = @@ -493,7 +499,8 @@ defmodule AshPostgres.MigrationGeneratorTest do snapshot_path: "test_snapshots_path", migration_path: "test_migration_path", quiet: true, - format: false + format: false, + auto_name: true ) :ok @@ -518,7 +525,8 @@ defmodule AshPostgres.MigrationGeneratorTest do snapshot_path: "test_snapshots_path", migration_path: "test_migration_path", quiet: true, - format: false + format: false, + auto_name: true ) assert [_file1, file2] = @@ -552,7 +560,8 @@ defmodule AshPostgres.MigrationGeneratorTest do snapshot_path: "test_snapshots_path", migration_path: "test_migration_path", quiet: true, - format: false + format: false, + auto_name: true ) assert [_file1, _file2, file3] = @@ -605,7 +614,8 @@ defmodule AshPostgres.MigrationGeneratorTest do migration_path: "test_migration_path", tenant_migration_path: "test_tenant_migration_path", quiet: false, - format: false + format: false, + auto_name: true ) defposts do @@ -632,7 +642,8 @@ defmodule AshPostgres.MigrationGeneratorTest do migration_path: "test_migration_path", tenant_migration_path: "test_tenant_migration_path", quiet: false, - format: false + format: false, + auto_name: true ) assert [_file1, file2] = @@ -675,7 +686,8 @@ defmodule AshPostgres.MigrationGeneratorTest do snapshot_path: "test_snapshots_path", migration_path: "test_migration_path", quiet: true, - format: false + format: false, + auto_name: true ) :ok @@ -701,7 +713,8 @@ defmodule AshPostgres.MigrationGeneratorTest do snapshot_path: "test_snapshots_path", migration_path: "test_migration_path", quiet: true, - format: false + format: false, + auto_name: true ) assert [_file1, file2] = @@ -731,7 +744,8 @@ defmodule AshPostgres.MigrationGeneratorTest do snapshot_path: "test_snapshots_path", migration_path: "test_migration_path", quiet: true, - format: false + format: false, + auto_name: true ) assert [_file1, file2] = @@ -774,7 +788,8 @@ defmodule AshPostgres.MigrationGeneratorTest do snapshot_path: "test_snapshots_path", migration_path: "test_migration_path", quiet: true, - format: false + format: false, + auto_name: true ) :ok @@ -805,7 +820,8 @@ defmodule AshPostgres.MigrationGeneratorTest do snapshot_path: "test_snapshots_path", migration_path: "test_migration_path", quiet: true, - format: false + format: false, + auto_name: true ) assert [_file1] = @@ -838,7 +854,8 @@ defmodule AshPostgres.MigrationGeneratorTest do snapshot_path: "test_snapshots_path", migration_path: "test_migration_path", quiet: true, - format: false + format: false, + auto_name: true ) :ok @@ -864,7 +881,8 @@ defmodule AshPostgres.MigrationGeneratorTest do snapshot_path: "test_snapshots_path", migration_path: "test_migration_path", quiet: true, - format: false + format: false, + auto_name: true ) assert [_file1, file2] = @@ -897,7 +915,8 @@ defmodule AshPostgres.MigrationGeneratorTest do snapshot_path: "test_snapshots_path", migration_path: "test_migration_path", quiet: true, - format: false + format: false, + auto_name: true ) assert [_file1, file2] = @@ -930,7 +949,8 @@ defmodule AshPostgres.MigrationGeneratorTest do snapshot_path: "test_snapshots_path", migration_path: "test_migration_path", quiet: true, - format: false + format: false, + auto_name: true ) assert [_file1, file2] = @@ -966,7 +986,8 @@ defmodule AshPostgres.MigrationGeneratorTest do snapshot_path: "test_snapshots_path", migration_path: "test_migration_path", quiet: true, - format: false + format: false, + auto_name: true ) assert [_file1, file2] = @@ -993,7 +1014,8 @@ defmodule AshPostgres.MigrationGeneratorTest do snapshot_path: "test_snapshots_path", migration_path: "test_migration_path", quiet: true, - format: false + format: false, + auto_name: true ) assert [_file1, file2] = @@ -1019,7 +1041,8 @@ defmodule AshPostgres.MigrationGeneratorTest do snapshot_path: "test_snapshots_path", migration_path: "test_migration_path", quiet: true, - format: false + format: false, + auto_name: true ) assert [_file1, file2] = @@ -1048,7 +1071,8 @@ defmodule AshPostgres.MigrationGeneratorTest do snapshot_path: "test_snapshots_path", migration_path: "test_migration_path", quiet: true, - format: false + format: false, + auto_name: true ) assert [_file1, file2] = @@ -1083,7 +1107,8 @@ defmodule AshPostgres.MigrationGeneratorTest do snapshot_path: "test_snapshots_path", migration_path: "test_migration_path", quiet: true, - format: false + format: false, + auto_name: true ) assert [_file1, file2] = @@ -1156,7 +1181,8 @@ defmodule AshPostgres.MigrationGeneratorTest do snapshot_path: "test_snapshots_path", migration_path: "test_migration_path", quiet: true, - format: false + format: false, + auto_name: true ) assert [_file1, file2] = @@ -1189,7 +1215,8 @@ defmodule AshPostgres.MigrationGeneratorTest do snapshot_path: "test_snapshots_path", migration_path: "test_migration_path", quiet: true, - format: false + format: false, + auto_name: true ) assert [_file1, file2] = @@ -1232,7 +1259,8 @@ defmodule AshPostgres.MigrationGeneratorTest do snapshot_path: "test_snapshots_path", migration_path: "test_migration_path", quiet: true, - format: false + format: false, + auto_name: true ) assert [file1, file2] = @@ -1277,7 +1305,8 @@ defmodule AshPostgres.MigrationGeneratorTest do migration_path: "test_migration_path", quiet: true, concurrent_indexes: true, - format: false + format: false, + auto_name: true ) assert [_file1, _file2, file3] = @@ -1316,7 +1345,8 @@ defmodule AshPostgres.MigrationGeneratorTest do snapshot_path: "test_snapshots_path", migration_path: "test_migration_path", quiet: true, - format: false + format: false, + auto_name: true ) assert [_file1, file2] = @@ -1356,7 +1386,8 @@ defmodule AshPostgres.MigrationGeneratorTest do snapshot_path: "test_snapshots_path", migration_path: "test_migration_path", quiet: true, - format: false + format: false, + auto_name: true ) :ok @@ -1394,7 +1425,8 @@ defmodule AshPostgres.MigrationGeneratorTest do AshPostgres.MigrationGenerator.generate(domain, snapshot_path: "test_snapshots_path", migration_path: "test_migration_path", - check: true + check: true, + auto_name: true ) ) == {:shutdown, 1} @@ -1437,7 +1469,8 @@ defmodule AshPostgres.MigrationGeneratorTest do snapshot_path: "test_snapshots_path", migration_path: "test_migration_path", quiet: true, - format: false + format: false, + auto_name: true ) assert [file] = @@ -1474,7 +1507,8 @@ defmodule AshPostgres.MigrationGeneratorTest do snapshot_path: "test_snapshots_path", migration_path: "test_migration_path", quiet: true, - format: false + format: false, + auto_name: true ) assert [file] = @@ -1520,7 +1554,8 @@ defmodule AshPostgres.MigrationGeneratorTest do snapshot_path: "test_snapshots_path", migration_path: "test_migration_path", quiet: true, - format: false + format: false, + auto_name: true ) assert [file] = @@ -1566,7 +1601,8 @@ defmodule AshPostgres.MigrationGeneratorTest do snapshot_path: "test_snapshots_path", migration_path: "test_migration_path", quiet: true, - format: false + format: false, + auto_name: true ) assert [file] = @@ -1617,7 +1653,8 @@ defmodule AshPostgres.MigrationGeneratorTest do snapshot_path: "test_snapshots_path", migration_path: "test_migration_path", quiet: true, - format: false + format: false, + auto_name: true ) defposts Post2 do @@ -1646,7 +1683,8 @@ defmodule AshPostgres.MigrationGeneratorTest do snapshot_path: "test_snapshots_path", migration_path: "test_migration_path", quiet: true, - format: false + format: false, + auto_name: true ) assert file = @@ -1727,7 +1765,8 @@ defmodule AshPostgres.MigrationGeneratorTest do snapshot_path: "test_snapshots_path", migration_path: "test_migration_path", quiet: true, - format: false + format: false, + auto_name: true ) assert [file] = @@ -1781,7 +1820,8 @@ defmodule AshPostgres.MigrationGeneratorTest do snapshot_path: "test_snapshots_path", migration_path: "test_migration_path", quiet: true, - format: false + format: false, + auto_name: true ) assert file = @@ -1863,7 +1903,8 @@ defmodule AshPostgres.MigrationGeneratorTest do snapshot_path: "test_snapshots_path", migration_path: "test_migration_path", quiet: true, - format: false + format: false, + auto_name: true ) assert [file] = @@ -1918,7 +1959,8 @@ defmodule AshPostgres.MigrationGeneratorTest do snapshot_path: "test_snapshots_path", migration_path: "test_migration_path", quiet: true, - format: false + format: false, + auto_name: true ) assert [file] = @@ -1957,7 +1999,8 @@ defmodule AshPostgres.MigrationGeneratorTest do snapshot_path: "test_snapshots_path", migration_path: "test_migration_path", quiet: true, - format: false + format: false, + auto_name: true ) defposts Post2 do @@ -1983,7 +2026,8 @@ defmodule AshPostgres.MigrationGeneratorTest do snapshot_path: "test_snapshots_path", migration_path: "test_migration_path", quiet: true, - format: false + format: false, + auto_name: true ) assert file = @@ -2089,7 +2133,8 @@ defmodule AshPostgres.MigrationGeneratorTest do snapshot_path: "test_snapshots_path", migration_path: "test_migration_path", quiet: true, - format: false + format: false, + auto_name: true ) assert [file] = @@ -2169,7 +2214,8 @@ defmodule AshPostgres.MigrationGeneratorTest do snapshot_path: "test_snapshots_path", migration_path: "test_migration_path", quiet: true, - format: false + format: false, + auto_name: true ) assert [file] = @@ -2209,7 +2255,8 @@ defmodule AshPostgres.MigrationGeneratorTest do snapshot_path: "test_snapshots_path", migration_path: "test_migration_path", quiet: true, - format: false + format: false, + auto_name: true ) assert file = @@ -2242,7 +2289,8 @@ defmodule AshPostgres.MigrationGeneratorTest do snapshot_path: "test_snapshots_path", migration_path: "test_migration_path", quiet: true, - format: false + format: false, + auto_name: true ) assert file = @@ -2288,7 +2336,8 @@ defmodule AshPostgres.MigrationGeneratorTest do snapshot_path: "test_snapshots_path", migration_path: "test_migration_path", quiet: true, - format: false + format: false, + auto_name: true ) assert file = @@ -2323,7 +2372,8 @@ defmodule AshPostgres.MigrationGeneratorTest do snapshot_path: "test_snapshots_path", migration_path: "test_migration_path", quiet: true, - format: false + format: false, + auto_name: true ) defposts do @@ -2337,7 +2387,8 @@ defmodule AshPostgres.MigrationGeneratorTest do snapshot_path: "test_snapshots_path", migration_path: "test_migration_path", quiet: true, - format: false + format: false, + auto_name: true ) assert file = @@ -2414,7 +2465,8 @@ defmodule AshPostgres.MigrationGeneratorTest do snapshot_path: "test_snapshots_path", migration_path: "test_migration_path", quiet: true, - format: false + format: false, + auto_name: true ) [domain: Domain] @@ -2471,7 +2523,8 @@ defmodule AshPostgres.MigrationGeneratorTest do snapshot_path: "test_snapshots_path", migration_path: "test_migration_path", quiet: true, - format: false + format: false, + auto_name: true ) assert [file1] = @@ -2527,7 +2580,8 @@ defmodule AshPostgres.MigrationGeneratorTest do snapshot_path: "test_snapshots_path", migration_path: "test_migration_path", quiet: true, - format: false + format: false, + auto_name: true ) end) @@ -2576,7 +2630,8 @@ defmodule AshPostgres.MigrationGeneratorTest do snapshot_path: "test_snapshots_path", migration_path: "test_migration_path", quiet: true, - format: false + format: false, + auto_name: true ) :ok @@ -2614,7 +2669,8 @@ defmodule AshPostgres.MigrationGeneratorTest do snapshot_path: "test_snapshots_path", migration_path: "test_migration_path", quiet: true, - format: false + format: false, + auto_name: true ) assert [_file1, file2] = @@ -2679,7 +2735,8 @@ defmodule AshPostgres.MigrationGeneratorTest do snapshot_path: "test_snapshots_path", migration_path: "test_migration_path", quiet: true, - format: false + format: false, + auto_name: true ) assert [file] = @@ -2722,7 +2779,8 @@ defmodule AshPostgres.MigrationGeneratorTest do snapshot_path: "test_snapshots_path", migration_path: "test_migration_path", quiet: true, - format: false + format: false, + auto_name: true ) # Now update the precision and scale @@ -2747,7 +2805,8 @@ defmodule AshPostgres.MigrationGeneratorTest do snapshot_path: "test_snapshots_path", migration_path: "test_migration_path", quiet: true, - format: false + format: false, + auto_name: true ) migration_files = @@ -2791,7 +2850,8 @@ defmodule AshPostgres.MigrationGeneratorTest do snapshot_path: "test_snapshots_path", migration_path: "test_migration_path", quiet: true, - format: false + format: false, + auto_name: true ) assert [file] = @@ -2835,7 +2895,8 @@ defmodule AshPostgres.MigrationGeneratorTest do snapshot_path: "test_snapshots_path", migration_path: "test_migration_path", quiet: true, - format: false + format: false, + auto_name: true ) # Now change to arbitrary precision and scale @@ -2865,7 +2926,8 @@ defmodule AshPostgres.MigrationGeneratorTest do snapshot_path: "test_snapshots_path", migration_path: "test_migration_path", quiet: true, - format: false + format: false, + auto_name: true ) migration_files = @@ -2943,7 +3005,8 @@ defmodule AshPostgres.MigrationGeneratorTest do snapshot_path: "test_snapshots_path", migration_path: "test_migration_path", quiet: true, - format: false + format: false, + auto_name: true ) assert [file] = diff --git a/test/mix_squash_snapshots_test.exs b/test/mix_squash_snapshots_test.exs index f2827228..dcdce819 100644 --- a/test/mix_squash_snapshots_test.exs +++ b/test/mix_squash_snapshots_test.exs @@ -94,7 +94,8 @@ defmodule AshPostgres.MixSquashSnapshotsTest do snapshot_path: "test_snapshots_path", migration_path: "test_migration_path", quiet: true, - format: false + format: false, + auto_name: true ) defposts do @@ -113,7 +114,8 @@ defmodule AshPostgres.MixSquashSnapshotsTest do snapshot_path: "test_snapshots_path", migration_path: "test_migration_path", quiet: true, - format: false + format: false, + auto_name: true ) :ok @@ -179,7 +181,8 @@ defmodule AshPostgres.MixSquashSnapshotsTest do snapshot_path: "test_snapshots_path", migration_path: "test_migration_path", quiet: true, - format: false + format: false, + auto_name: true ) :ok diff --git a/test/support/dev_test_repo.ex b/test/support/dev_test_repo.ex new file mode 100644 index 00000000..2b1fe929 --- /dev/null +++ b/test/support/dev_test_repo.ex @@ -0,0 +1,39 @@ +defmodule AshPostgres.DevTestRepo do + @moduledoc false + use AshPostgres.Repo, + otp_app: :ash_postgres + + def on_transaction_begin(data) do + send(self(), data) + end + + def prefer_transaction?, do: false + + def prefer_transaction_for_atomic_updates?, do: false + + def installed_extensions do + ["ash-functions", "uuid-ossp", "pg_trgm", "citext", AshPostgres.TestCustomExtension, "ltree"] -- + Application.get_env(:ash_postgres, :no_extensions, []) + end + + def min_pg_version do + case System.get_env("PG_VERSION") do + nil -> + %Version{major: 16, minor: 0, patch: 0} + + version -> + case Integer.parse(version) do + {major, ""} -> %Version{major: major, minor: 0, patch: 0} + _ -> Version.parse!(version) + end + end + end + + def all_tenants do + Code.ensure_compiled(AshPostgres.MultitenancyTest.Org) + + AshPostgres.MultitenancyTest.DevMigrationsOrg + |> Ash.read!() + |> Enum.map(&"org_#{&1.id}") + end +end diff --git a/test/support/multitenancy/domain.ex b/test/support/multitenancy/domain.ex index 9ad6f881..52ffbc63 100644 --- a/test/support/multitenancy/domain.ex +++ b/test/support/multitenancy/domain.ex @@ -4,6 +4,7 @@ defmodule AshPostgres.MultitenancyTest.Domain do resources do resource(AshPostgres.MultitenancyTest.Org) + resource(AshPostgres.MultitenancyTest.DevMigrationsOrg) resource(AshPostgres.MultitenancyTest.NamedOrg) resource(AshPostgres.MultitenancyTest.User) resource(AshPostgres.MultitenancyTest.Post) diff --git a/test/support/multitenancy/resources/dev_migrations_org.ex b/test/support/multitenancy/resources/dev_migrations_org.ex new file mode 100644 index 00000000..6ebd3394 --- /dev/null +++ b/test/support/multitenancy/resources/dev_migrations_org.ex @@ -0,0 +1,91 @@ +defmodule AshPostgres.MultitenancyTest.DevMigrationsOrg do + @moduledoc false + use Ash.Resource, + domain: AshPostgres.MultitenancyTest.Domain, + data_layer: AshPostgres.DataLayer, + authorizers: [Ash.Policy.Authorizer] + + defimpl Ash.ToTenant do + def to_tenant(%{id: id}, resource) do + if Ash.Resource.Info.data_layer(resource) == AshPostgres.DataLayer && + Ash.Resource.Info.multitenancy_strategy(resource) == :context do + "org_#{id}" + else + id + end + end + end + + policies do + policy action(:has_policies) do + authorize_if(relates_to_actor_via(:owner)) + end + + # policy always() do + # authorize_if(always()) + # end + end + + identities do + identity(:unique_by_name, [:name]) + end + + attributes do + uuid_primary_key(:id, writable?: true) + attribute(:name, :string, public?: true) + end + + actions do + default_accept(:*) + + defaults([:create, :read, :update, :destroy]) + + read(:has_policies) + end + + postgres do + table "multitenant_orgs" + repo(AshPostgres.DevTestRepo) + + manage_tenant do + template(["org_", :id]) + end + end + + multitenancy do + strategy(:attribute) + attribute(:id) + global?(true) + parse_attribute({__MODULE__, :tenant, []}) + end + + aggregates do + count(:total_users_posts, [:users, :posts]) + count(:total_posts, :posts) + end + + relationships do + belongs_to :owner, AshPostgres.MultitenancyTest.User do + attribute_public?(false) + public?(false) + end + + has_many(:posts, AshPostgres.MultitenancyTest.Post, + destination_attribute: :org_id, + public?: true + ) + + has_many(:users, AshPostgres.MultitenancyTest.User, + destination_attribute: :org_id, + public?: true + ) + end + + def tenant("org_" <> tenant) do + tenant + end + + def tenant(tenant) do + tenant + end +end diff --git a/test/test_helper.exs b/test/test_helper.exs index 056ebefd..6745f6eb 100644 --- a/test/test_helper.exs +++ b/test/test_helper.exs @@ -20,6 +20,7 @@ exclude_tags = ExUnit.configure(stacktrace_depth: 100, exclude: exclude_tags) AshPostgres.TestRepo.start_link() +AshPostgres.DevTestRepo.start_link() AshPostgres.TestNoSandboxRepo.start_link() format_sql_query = @@ -49,4 +50,5 @@ format_sql_query = end Ecto.DevLogger.install(AshPostgres.TestRepo, before_inline_callback: format_sql_query) +Ecto.DevLogger.install(AshPostgres.DevTestRepo, before_inline_callback: format_sql_query) Ecto.DevLogger.install(AshPostgres.TestNoSandboxRepo, before_inline_callback: format_sql_query) diff --git a/usage-rules.md b/usage-rules.md index 5c8ee524..632fc52d 100644 --- a/usage-rules.md +++ b/usage-rules.md @@ -149,14 +149,29 @@ end ## Migrations and Codegen -### Generating Migrations +### Development Migration Workflow (Recommended) -After creating or modifying Ash resources: +For development iterations, use the dev workflow to avoid naming migrations prematurely: + +1. Make resource changes +2. Run `mix ash.codegen --dev` to generate and run dev migrations +3. Review the migrations and run `mix ash.migrate` to run them +4. Continue making changes and running `mix ash.codegen --dev` as needed +5. When your feature is complete, run `mix ash.codegen add_feature_name` to generate final named migrations (this will rollback dev migrations and squash them) +3. Review the migrations and run `mix ash.migrate` to run them + +### Traditional Migration Generation + +For single-step changes or when you know the final feature name: 1. Run `mix ash.codegen add_feature_name` to generate migrations 2. Review the generated migrations in `priv/repo/migrations` 3. Run `mix ash.migrate` to apply the migrations +> **Tip**: The dev workflow (`--dev` flag) is preferred during development as it allows you to iterate without thinking of migration names and provides better development ergonomics. + +> **Warning**: Always review migrations before applying them to ensure they are correct and safe. + ## Multitenancy AshPostgres supports schema-based multitenancy: From 831940d3368e2db536a43928fad142c54b0da761 Mon Sep 17 00:00:00 2001 From: Zach Daniel Date: Mon, 26 May 2025 22:09:49 -0400 Subject: [PATCH 011/174] chore: temporarily override ash dep --- mix.exs | 3 ++- mix.lock | 4 ++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/mix.exs b/mix.exs index fb84295b..a0399b50 100644 --- a/mix.exs +++ b/mix.exs @@ -166,7 +166,8 @@ defmodule AshPostgres.MixProject do # Run "mix help deps" to learn about dependencies. defp deps do [ - {:ash, ash_version("~> 3.4 and >= 3.4.69")}, + # {:ash, ash_version("~> 3.4 and >= 3.4.69")}, + {:ash, github: "ash-project/ash", override: true}, {:ash_sql, ash_sql_version("~> 0.2 and >= 0.2.72")}, {:igniter, "~> 0.6", optional: true}, {:ecto_sql, "~> 3.12"}, diff --git a/mix.lock b/mix.lock index 10820741..624ec23b 100644 --- a/mix.lock +++ b/mix.lock @@ -1,5 +1,5 @@ %{ - "ash": {:hex, :ash, "3.5.12", "435a6916d47e4ed6eabce886de2443d17af9dd9ca9765a29c73d9e02507b86b3", [:mix], [{:decimal, "~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:ecto, "~> 3.7", [hex: :ecto, repo: "hexpm", optional: false]}, {:ets, "~> 0.8", [hex: :ets, repo: "hexpm", optional: false]}, {:igniter, "~> 0.6", [hex: :igniter, repo: "hexpm", optional: true]}, {:jason, ">= 1.0.0", [hex: :jason, repo: "hexpm", optional: false]}, {:owl, "~> 0.11", [hex: :owl, repo: "hexpm", optional: false]}, {:picosat_elixir, "~> 0.2", [hex: :picosat_elixir, repo: "hexpm", optional: true]}, {:plug, ">= 0.0.0", [hex: :plug, repo: "hexpm", optional: true]}, {:reactor, "~> 0.11", [hex: :reactor, repo: "hexpm", optional: false]}, {:simple_sat, ">= 0.1.1 and < 1.0.0-0", [hex: :simple_sat, repo: "hexpm", optional: true]}, {:spark, ">= 2.2.60 and < 3.0.0-0", [hex: :spark, repo: "hexpm", optional: false]}, {:splode, ">= 0.2.6 and < 1.0.0-0", [hex: :splode, repo: "hexpm", optional: false]}, {:stream_data, "~> 1.0", [hex: :stream_data, repo: "hexpm", optional: false]}, {:telemetry, "~> 1.1", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "503492989c56e33c300d731b3717d1df9eeebba2b9018e5dd9f330db727edb57"}, + "ash": {:git, "https://github.com/ash-project/ash.git", "3eee4fa4fd836e8dad7bc8fb09df602221867565", []}, "ash_sql": {:hex, :ash_sql, "0.2.76", "4afac3284194f3d7820b7edc1263ac1eb232a25734406ad7b2284683b9384205", [:mix], [{:ash, "~> 3.5", [hex: :ash, repo: "hexpm", optional: false]}, {:ecto, "~> 3.9", [hex: :ecto, repo: "hexpm", optional: false]}, {:ecto_sql, "~> 3.9", [hex: :ecto_sql, repo: "hexpm", optional: false]}], "hexpm", "f6bc02d8c4cba3f8f9a532e6ff73eaf8a4f7685257646a58fe7a320cfaf10c39"}, "benchee": {:hex, :benchee, "1.4.0", "9f1f96a30ac80bab94faad644b39a9031d5632e517416a8ab0a6b0ac4df124ce", [:mix], [{:deep_merge, "~> 1.0", [hex: :deep_merge, repo: "hexpm", optional: false]}, {:statistex, "~> 1.0", [hex: :statistex, repo: "hexpm", optional: false]}, {:table, "~> 0.1.0", [hex: :table, repo: "hexpm", optional: true]}], "hexpm", "299cd10dd8ce51c9ea3ddb74bb150f93d25e968f93e4c1fa31698a8e4fa5d715"}, "bunt": {:hex, :bunt, "1.0.0", "081c2c665f086849e6d57900292b3a161727ab40431219529f13c4ddcf3e7a44", [:mix], [], "hexpm", "dc5f86aa08a5f6fa6b8096f0735c4e76d54ae5c9fa2c143e5a1fc7c1cd9bb6b5"}, @@ -44,7 +44,7 @@ "simple_sat": {:hex, :simple_sat, "0.1.3", "f650fc3c184a5fe741868b5ac56dc77fdbb428468f6dbf1978e14d0334497578", [:mix], [], "hexpm", "a54305066a356b7194dc81db2a89232bacdc0b3edaef68ed9aba28dcbc34887b"}, "sobelow": {:hex, :sobelow, "0.14.0", "dd82aae8f72503f924fe9dd97ffe4ca694d2f17ec463dcfd365987c9752af6ee", [:mix], [{:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "7ecf91e298acfd9b24f5d761f19e8f6e6ac585b9387fb6301023f1f2cd5eed5f"}, "sourceror": {:hex, :sourceror, "1.10.0", "38397dedbbc286966ec48c7af13e228b171332be1ad731974438c77791945ce9", [:mix], [], "hexpm", "29dbdfc92e04569c9d8e6efdc422fc1d815f4bd0055dc7c51b8800fb75c4b3f1"}, - "spark": {:hex, :spark, "2.2.61", "64745581832caf136cbd654c1ecef98d291f3d1b347a14411b7d0dc726e3822b", [:mix], [{:igniter, ">= 0.3.64 and < 1.0.0-0", [hex: :igniter, repo: "hexpm", optional: true]}, {:jason, "~> 1.4", [hex: :jason, repo: "hexpm", optional: true]}, {:sourceror, "~> 1.2", [hex: :sourceror, repo: "hexpm", optional: true]}], "hexpm", "cb10300e17f74b41848954d61630fb627f4e0d5acf9aacd7d9f312d5b119d50f"}, + "spark": {:hex, :spark, "2.2.62", "610502559834465edce437de712bf7e6d59713ad48050789dbef69a798e71a3c", [:mix], [{:igniter, ">= 0.3.64 and < 1.0.0-0", [hex: :igniter, repo: "hexpm", optional: true]}, {:jason, "~> 1.4", [hex: :jason, repo: "hexpm", optional: true]}, {:sourceror, "~> 1.2", [hex: :sourceror, repo: "hexpm", optional: true]}], "hexpm", "726df72e1b9c17401584b4657e75e08a27a1cf6a6effa2486bf1c074da6176a7"}, "spitfire": {:hex, :spitfire, "0.2.0", "0de1f519a23f65bde40d316adad53c07a9563f25cc68915d639d8a509a0aad8a", [:mix], [], "hexpm", "743daaee2d81a0d8095431729f478ce49b47ea8943c7d770de86704975cb7775"}, "splode": {:hex, :splode, "0.2.9", "3a2776e187c82f42f5226b33b1220ccbff74f4bcc523dd4039c804caaa3ffdc7", [:mix], [], "hexpm", "8002b00c6e24f8bd1bcced3fbaa5c33346048047bb7e13d2f3ad428babbd95c3"}, "statistex": {:hex, :statistex, "1.0.0", "f3dc93f3c0c6c92e5f291704cf62b99b553253d7969e9a5fa713e5481cd858a5", [:mix], [], "hexpm", "ff9d8bee7035028ab4742ff52fc80a2aa35cece833cf5319009b52f1b5a86c27"}, From d226fcd79d09d6aec926019ebc227d7d5eb9322f Mon Sep 17 00:00:00 2001 From: Zach Daniel Date: Mon, 26 May 2025 22:25:16 -0400 Subject: [PATCH 012/174] ci: temporarily only have one postgres-version --- .github/workflows/elixir.yml | 2 +- mix.exs | 3 +-- mix.lock | 2 +- 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/.github/workflows/elixir.yml b/.github/workflows/elixir.yml index 084df209..cb875c93 100644 --- a/.github/workflows/elixir.yml +++ b/.github/workflows/elixir.yml @@ -11,7 +11,7 @@ jobs: strategy: fail-fast: false matrix: - postgres-version: ["14", "15", "16"] + postgres-version: ["16"] uses: ash-project/ash/.github/workflows/ash-ci.yml@main with: postgres: true diff --git a/mix.exs b/mix.exs index a0399b50..fb84295b 100644 --- a/mix.exs +++ b/mix.exs @@ -166,8 +166,7 @@ defmodule AshPostgres.MixProject do # Run "mix help deps" to learn about dependencies. defp deps do [ - # {:ash, ash_version("~> 3.4 and >= 3.4.69")}, - {:ash, github: "ash-project/ash", override: true}, + {:ash, ash_version("~> 3.4 and >= 3.4.69")}, {:ash_sql, ash_sql_version("~> 0.2 and >= 0.2.72")}, {:igniter, "~> 0.6", optional: true}, {:ecto_sql, "~> 3.12"}, diff --git a/mix.lock b/mix.lock index 624ec23b..1f94b151 100644 --- a/mix.lock +++ b/mix.lock @@ -1,5 +1,5 @@ %{ - "ash": {:git, "https://github.com/ash-project/ash.git", "3eee4fa4fd836e8dad7bc8fb09df602221867565", []}, + "ash": {:hex, :ash, "3.5.12", "435a6916d47e4ed6eabce886de2443d17af9dd9ca9765a29c73d9e02507b86b3", [:mix], [{:decimal, "~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:ecto, "~> 3.7", [hex: :ecto, repo: "hexpm", optional: false]}, {:ets, "~> 0.8", [hex: :ets, repo: "hexpm", optional: false]}, {:igniter, "~> 0.6", [hex: :igniter, repo: "hexpm", optional: true]}, {:jason, ">= 1.0.0", [hex: :jason, repo: "hexpm", optional: false]}, {:owl, "~> 0.11", [hex: :owl, repo: "hexpm", optional: false]}, {:picosat_elixir, "~> 0.2", [hex: :picosat_elixir, repo: "hexpm", optional: true]}, {:plug, ">= 0.0.0", [hex: :plug, repo: "hexpm", optional: true]}, {:reactor, "~> 0.11", [hex: :reactor, repo: "hexpm", optional: false]}, {:simple_sat, ">= 0.1.1 and < 1.0.0-0", [hex: :simple_sat, repo: "hexpm", optional: true]}, {:spark, ">= 2.2.60 and < 3.0.0-0", [hex: :spark, repo: "hexpm", optional: false]}, {:splode, ">= 0.2.6 and < 1.0.0-0", [hex: :splode, repo: "hexpm", optional: false]}, {:stream_data, "~> 1.0", [hex: :stream_data, repo: "hexpm", optional: false]}, {:telemetry, "~> 1.1", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "503492989c56e33c300d731b3717d1df9eeebba2b9018e5dd9f330db727edb57"}, "ash_sql": {:hex, :ash_sql, "0.2.76", "4afac3284194f3d7820b7edc1263ac1eb232a25734406ad7b2284683b9384205", [:mix], [{:ash, "~> 3.5", [hex: :ash, repo: "hexpm", optional: false]}, {:ecto, "~> 3.9", [hex: :ecto, repo: "hexpm", optional: false]}, {:ecto_sql, "~> 3.9", [hex: :ecto_sql, repo: "hexpm", optional: false]}], "hexpm", "f6bc02d8c4cba3f8f9a532e6ff73eaf8a4f7685257646a58fe7a320cfaf10c39"}, "benchee": {:hex, :benchee, "1.4.0", "9f1f96a30ac80bab94faad644b39a9031d5632e517416a8ab0a6b0ac4df124ce", [:mix], [{:deep_merge, "~> 1.0", [hex: :deep_merge, repo: "hexpm", optional: false]}, {:statistex, "~> 1.0", [hex: :statistex, repo: "hexpm", optional: false]}, {:table, "~> 0.1.0", [hex: :table, repo: "hexpm", optional: true]}], "hexpm", "299cd10dd8ce51c9ea3ddb74bb150f93d25e968f93e4c1fa31698a8e4fa5d715"}, "bunt": {:hex, :bunt, "1.0.0", "081c2c665f086849e6d57900292b3a161727ab40431219529f13c4ddcf3e7a44", [:mix], [], "hexpm", "dc5f86aa08a5f6fa6b8096f0735c4e76d54ae5c9fa2c143e5a1fc7c1cd9bb6b5"}, From cb7a216e3d59df03430cd5699b737965cc29a687 Mon Sep 17 00:00:00 2001 From: Zach Daniel Date: Tue, 27 May 2025 22:05:47 -0400 Subject: [PATCH 013/174] chore: try to migrate in transaction to see if that helps --- .../migration_generator.ex | 68 ++++++++++--------- 1 file changed, 36 insertions(+), 32 deletions(-) diff --git a/lib/migration_generator/migration_generator.ex b/lib/migration_generator/migration_generator.ex index 2479d067..7516aa96 100644 --- a/lib/migration_generator/migration_generator.ex +++ b/lib/migration_generator/migration_generator.ex @@ -562,12 +562,46 @@ defmodule AshPostgres.MigrationGenerator do for prefix <- repo.all_tenants() do {repo, query, opts} = Ecto.Migration.SchemaMigration.versions(repo, [], prefix) + repo.transaction(fn -> + versions = repo.all(query, Keyword.put(opts, :timeout, :infinity)) + + dev_migrations + |> Enum.map(&extract_migration_info/1) + |> Enum.filter(& &1) + |> Enum.map(&load_migration!/1) + |> Enum.filter(fn {version, _} -> + version in versions + end) + |> Enum.each(fn {version, mod} -> + Ecto.Migration.Runner.run( + repo, + [], + version, + mod, + :forward, + :down, + :down, + all: true, + prefix: prefix + ) + + Ecto.Migration.SchemaMigration.down(repo, repo.config(), version, prefix: prefix) + end) + end) + end + end) + else + with_repo_not_in_test(repo, fn repo -> + {repo, query, opts} = Ecto.Migration.SchemaMigration.versions(repo, [], nil) + + repo.transaction(fn -> versions = repo.all(query, opts) dev_migrations |> Enum.map(&extract_migration_info/1) |> Enum.filter(& &1) |> Enum.map(&load_migration!/1) + |> Enum.sort() |> Enum.filter(fn {version, _} -> version in versions end) @@ -580,41 +614,11 @@ defmodule AshPostgres.MigrationGenerator do :forward, :down, :down, - all: true, - prefix: prefix + all: true ) - Ecto.Migration.SchemaMigration.down(repo, repo.config(), version, prefix: prefix) + Ecto.Migration.SchemaMigration.down(repo, repo.config(), version, []) end) - end - end) - else - with_repo_not_in_test(repo, fn repo -> - {repo, query, opts} = Ecto.Migration.SchemaMigration.versions(repo, [], nil) - - versions = repo.all(query, opts) - - dev_migrations - |> Enum.map(&extract_migration_info/1) - |> Enum.filter(& &1) - |> Enum.map(&load_migration!/1) - |> Enum.sort() - |> Enum.filter(fn {version, _} -> - version in versions - end) - |> Enum.each(fn {version, mod} -> - Ecto.Migration.Runner.run( - repo, - [], - version, - mod, - :forward, - :down, - :down, - all: true - ) - - Ecto.Migration.SchemaMigration.down(repo, repo.config(), version, []) end) end) end From c52ec455889dbd9a8fb2223274306677eb852a11 Mon Sep 17 00:00:00 2001 From: Zach Daniel Date: Tue, 27 May 2025 22:10:55 -0400 Subject: [PATCH 014/174] CI: add back in older pg versions --- .github/workflows/elixir.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/elixir.yml b/.github/workflows/elixir.yml index cb875c93..084df209 100644 --- a/.github/workflows/elixir.yml +++ b/.github/workflows/elixir.yml @@ -11,7 +11,7 @@ jobs: strategy: fail-fast: false matrix: - postgres-version: ["16"] + postgres-version: ["14", "15", "16"] uses: ash-project/ash/.github/workflows/ash-ci.yml@main with: postgres: true From 69b06eeba6754773b3a32eadc0cf526d5bea6142 Mon Sep 17 00:00:00 2001 From: Zach Daniel Date: Tue, 27 May 2025 22:20:45 -0400 Subject: [PATCH 015/174] CI: add temporary logging for CI strangeness --- lib/multitenancy.ex | 4 ++++ test/dev_migrations_test.exs | 2 ++ 2 files changed, 6 insertions(+) diff --git a/lib/multitenancy.ex b/lib/multitenancy.ex index eac6d15a..3469b0f4 100644 --- a/lib/multitenancy.ex +++ b/lib/multitenancy.ex @@ -21,6 +21,7 @@ defmodule AshPostgres.MultiTenancy do repo.config(), prefix: tenant_name ) + |> tap(fn v -> Logger.warning(inspect(v, label: "ensure migraitons result")) end) [tenant_migrations_path, "**", "*.exs"] |> Path.join() @@ -39,6 +40,7 @@ defmodule AshPostgres.MultiTenancy do |> Enum.map(&extract_migration_info/1) |> Enum.filter(& &1) |> Enum.map(&load_migration!/1) + |> tap(fn v -> Logger.warning(inspect(v, label: "migrations")) end) |> Enum.each(fn {version, mod} -> Ecto.Migration.Runner.run( repo, @@ -51,8 +53,10 @@ defmodule AshPostgres.MultiTenancy do all: true, prefix: tenant_name ) + |> tap(fn v -> Logger.warning(inspect(v, label: "run result")) end) Ecto.Migration.SchemaMigration.up(repo, repo.config(), version, prefix: tenant_name) + |> tap(fn v -> Logger.warning(inspect(v, label: "schema run result")) end) end) end diff --git a/test/dev_migrations_test.exs b/test/dev_migrations_test.exs index 475aa909..0f7b93c0 100644 --- a/test/dev_migrations_test.exs +++ b/test/dev_migrations_test.exs @@ -220,6 +220,7 @@ defmodule AshPostgres.DevMigrationsTest do "priv/dev_test_repo/migrations", after_file ) + |> tap(fn v -> Logger.warning(inspect(v, label: "result")) end) end defp tenant_migrate do @@ -229,6 +230,7 @@ defmodule AshPostgres.DevMigrationsTest do AshPostgres.DevTestRepo, "priv/dev_test_repo/tenant_migrations" ) + |> tap(fn v -> Logger.warning(inspect(v, label: "result")) end) end end end From bb9024f5616e47f44a48ffbbfd6c19064565bb24 Mon Sep 17 00:00:00 2001 From: Zach Daniel Date: Tue, 27 May 2025 22:21:46 -0400 Subject: [PATCH 016/174] chore: add require logger --- lib/multitenancy.ex | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/multitenancy.ex b/lib/multitenancy.ex index 3469b0f4..a8601209 100644 --- a/lib/multitenancy.ex +++ b/lib/multitenancy.ex @@ -2,6 +2,7 @@ defmodule AshPostgres.MultiTenancy do @moduledoc false @dialyzer {:nowarn_function, load_migration!: 1} + require Logger # sobelow_skip ["SQL.Query"] def create_tenant!(tenant_name, repo) do From 08b2e44391fe8b42fa063d0b49824daae21c1c0e Mon Sep 17 00:00:00 2001 From: Zach Daniel Date: Tue, 27 May 2025 22:39:22 -0400 Subject: [PATCH 017/174] chore: try sorting migration files --- lib/multitenancy.ex | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/multitenancy.ex b/lib/multitenancy.ex index a8601209..30abecbd 100644 --- a/lib/multitenancy.ex +++ b/lib/multitenancy.ex @@ -27,6 +27,7 @@ defmodule AshPostgres.MultiTenancy do [tenant_migrations_path, "**", "*.exs"] |> Path.join() |> Path.wildcard() + |> Enum.sort() |> then(fn files -> if after_file do files From 1ce6568271cae5ede04c1448e2ebed489ec108ab Mon Sep 17 00:00:00 2001 From: Zach Daniel Date: Tue, 27 May 2025 23:07:46 -0400 Subject: [PATCH 018/174] chore: add missing sort --- lib/migration_generator/migration_generator.ex | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/migration_generator/migration_generator.ex b/lib/migration_generator/migration_generator.ex index 7516aa96..57e0787e 100644 --- a/lib/migration_generator/migration_generator.ex +++ b/lib/migration_generator/migration_generator.ex @@ -569,6 +569,7 @@ defmodule AshPostgres.MigrationGenerator do |> Enum.map(&extract_migration_info/1) |> Enum.filter(& &1) |> Enum.map(&load_migration!/1) + |> Enum.sort() |> Enum.filter(fn {version, _} -> version in versions end) From bdd71d742772544c6250b0fea6e0e5e5f04541f1 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 29 May 2025 10:29:24 -0400 Subject: [PATCH 019/174] chore(deps): bump igniter in the production-dependencies group (#556) Bumps the production-dependencies group with 1 update: [igniter](https://github.com/ash-project/igniter). Updates `igniter` from 0.6.2 to 0.6.3 - [Changelog](https://github.com/ash-project/igniter/blob/main/CHANGELOG.md) - [Commits](https://github.com/ash-project/igniter/compare/v0.6.2...v0.6.3) --- updated-dependencies: - dependency-name: igniter dependency-version: 0.6.3 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: production-dependencies ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- mix.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mix.lock b/mix.lock index 1f94b151..3f532193 100644 --- a/mix.lock +++ b/mix.lock @@ -23,7 +23,7 @@ "git_ops": {:hex, :git_ops, "2.7.3", "c993aedb11005752e321d482de6f2a46d0b5d5f09ce69961f31a856e76bf4f12", [:mix], [{:git_cli, "~> 0.2", [hex: :git_cli, repo: "hexpm", optional: false]}, {:igniter, ">= 0.5.27 and < 1.0.0-0", [hex: :igniter, repo: "hexpm", optional: true]}, {:nimble_parsec, "~> 1.0", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "c54ee65e12778be1f4dd6a0921e57ab2bddd35bd6130cbe274dcb1f0a21ca59d"}, "glob_ex": {:hex, :glob_ex, "0.1.11", "cb50d3f1ef53f6ca04d6252c7fde09fd7a1cf63387714fe96f340a1349e62c93", [:mix], [], "hexpm", "342729363056e3145e61766b416769984c329e4378f1d558b63e341020525de4"}, "hpax": {:hex, :hpax, "1.0.3", "ed67ef51ad4df91e75cc6a1494f851850c0bd98ebc0be6e81b026e765ee535aa", [:mix], [], "hexpm", "8eab6e1cfa8d5918c2ce4ba43588e894af35dbd8e91e6e55c817bca5847df34a"}, - "igniter": {:hex, :igniter, "0.6.2", "6263fa3d2b7698f8d9afc506e4e1bccef69f1b8a3288760fe749dc70a9f6b408", [:mix], [{:glob_ex, "~> 0.1.7", [hex: :glob_ex, repo: "hexpm", optional: false]}, {:jason, "~> 1.4", [hex: :jason, repo: "hexpm", optional: false]}, {:owl, "~> 0.11", [hex: :owl, repo: "hexpm", optional: false]}, {:phx_new, "~> 1.7", [hex: :phx_new, repo: "hexpm", optional: true]}, {:req, "~> 0.5", [hex: :req, repo: "hexpm", optional: false]}, {:rewrite, ">= 1.1.1 and < 2.0.0-0", [hex: :rewrite, repo: "hexpm", optional: false]}, {:sourceror, "~> 1.4", [hex: :sourceror, repo: "hexpm", optional: false]}, {:spitfire, ">= 0.1.3 and < 1.0.0-0", [hex: :spitfire, repo: "hexpm", optional: false]}], "hexpm", "480c679066444459eecd371a41639cee365449e20cfb611457081394fd146b05"}, + "igniter": {:hex, :igniter, "0.6.3", "8bfaf5955ce83301da0f0a53455f73a0bc4dc5aacd6c311363089850a5dc2dd7", [:mix], [{:glob_ex, "~> 0.1.7", [hex: :glob_ex, repo: "hexpm", optional: false]}, {:jason, "~> 1.4", [hex: :jason, repo: "hexpm", optional: false]}, {:owl, "~> 0.11", [hex: :owl, repo: "hexpm", optional: false]}, {:phx_new, "~> 1.7", [hex: :phx_new, repo: "hexpm", optional: true]}, {:req, "~> 0.5", [hex: :req, repo: "hexpm", optional: false]}, {:rewrite, ">= 1.1.1 and < 2.0.0-0", [hex: :rewrite, repo: "hexpm", optional: false]}, {:sourceror, "~> 1.4", [hex: :sourceror, repo: "hexpm", optional: false]}, {:spitfire, ">= 0.1.3 and < 1.0.0-0", [hex: :spitfire, repo: "hexpm", optional: false]}], "hexpm", "95d34d8280dea992e05dcbf9865414d69e421a76d743661eaf1d1337ea54fa80"}, "iterex": {:hex, :iterex, "0.1.2", "58f9b9b9a22a55cbfc7b5234a9c9c63eaac26d276b3db80936c0e1c60355a5a6", [:mix], [], "hexpm", "2e103b8bcc81757a9af121f6dc0df312c9a17220f302b1193ef720460d03029d"}, "jason": {:hex, :jason, "1.4.4", "b9226785a9aa77b6857ca22832cffa5d5011a667207eb2a0ad56adb5db443b8a", [:mix], [{:decimal, "~> 1.0 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm", "c5eb0cab91f094599f94d55bc63409236a8ec69a21a67814529e8d5f6cc90b3b"}, "libgraph": {:hex, :libgraph, "0.16.0", "3936f3eca6ef826e08880230f806bfea13193e49bf153f93edcf0239d4fd1d07", [:mix], [], "hexpm", "41ca92240e8a4138c30a7e06466acc709b0cbb795c643e9e17174a178982d6bf"}, From e415d9e2fc5557dab9d4ffd1042b984d7b9a5922 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 29 May 2025 10:29:35 -0400 Subject: [PATCH 020/174] chore(deps-dev): bump ex_doc in the dev-dependencies group (#557) Bumps the dev-dependencies group with 1 update: [ex_doc](https://github.com/elixir-lang/ex_doc). Updates `ex_doc` from 0.38.1 to 0.38.2 - [Release notes](https://github.com/elixir-lang/ex_doc/releases) - [Changelog](https://github.com/elixir-lang/ex_doc/blob/main/CHANGELOG.md) - [Commits](https://github.com/elixir-lang/ex_doc/compare/v0.38.1...v0.38.2) --- updated-dependencies: - dependency-name: ex_doc dependency-version: 0.38.2 dependency-type: direct:development update-type: version-update:semver-patch dependency-group: dev-dependencies ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- mix.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mix.lock b/mix.lock index 3f532193..4076ca19 100644 --- a/mix.lock +++ b/mix.lock @@ -16,7 +16,7 @@ "erlex": {:hex, :erlex, "0.2.7", "810e8725f96ab74d17aac676e748627a07bc87eb950d2b83acd29dc047a30595", [:mix], [], "hexpm", "3ed95f79d1a844c3f6bf0cea61e0d5612a42ce56da9c03f01df538685365efb0"}, "ets": {:hex, :ets, "0.9.0", "79c6a6c205436780486f72d84230c6cba2f8a9920456750ddd1e47389107d5fd", [:mix], [], "hexpm", "2861fdfb04bcaeff370f1a5904eec864f0a56dcfebe5921ea9aadf2a481c822b"}, "ex_check": {:hex, :ex_check, "0.16.0", "07615bef493c5b8d12d5119de3914274277299c6483989e52b0f6b8358a26b5f", [:mix], [], "hexpm", "4d809b72a18d405514dda4809257d8e665ae7cf37a7aee3be6b74a34dec310f5"}, - "ex_doc": {:hex, :ex_doc, "0.38.1", "bae0a0bd5b5925b1caef4987e3470902d072d03347114ffe03a55dbe206dd4c2", [:mix], [{:earmark_parser, "~> 1.4.44", [hex: :earmark_parser, repo: "hexpm", optional: false]}, {:makeup_c, ">= 0.1.0", [hex: :makeup_c, repo: "hexpm", optional: true]}, {:makeup_elixir, "~> 0.14 or ~> 1.0", [hex: :makeup_elixir, repo: "hexpm", optional: false]}, {:makeup_erlang, "~> 0.1 or ~> 1.0", [hex: :makeup_erlang, repo: "hexpm", optional: false]}, {:makeup_html, ">= 0.1.0", [hex: :makeup_html, repo: "hexpm", optional: true]}], "hexpm", "754636236d191b895e1e4de2ebb504c057fe1995fdfdd92e9d75c4b05633008b"}, + "ex_doc": {:hex, :ex_doc, "0.38.2", "504d25eef296b4dec3b8e33e810bc8b5344d565998cd83914ffe1b8503737c02", [:mix], [{:earmark_parser, "~> 1.4.44", [hex: :earmark_parser, repo: "hexpm", optional: false]}, {:makeup_c, ">= 0.1.0", [hex: :makeup_c, repo: "hexpm", optional: true]}, {:makeup_elixir, "~> 0.14 or ~> 1.0", [hex: :makeup_elixir, repo: "hexpm", optional: false]}, {:makeup_erlang, "~> 0.1 or ~> 1.0", [hex: :makeup_erlang, repo: "hexpm", optional: false]}, {:makeup_html, ">= 0.1.0", [hex: :makeup_html, repo: "hexpm", optional: true]}], "hexpm", "732f2d972e42c116a70802f9898c51b54916e542cc50968ac6980512ec90f42b"}, "file_system": {:hex, :file_system, "1.1.0", "08d232062284546c6c34426997dd7ef6ec9f8bbd090eb91780283c9016840e8f", [:mix], [], "hexpm", "bfcf81244f416871f2a2e15c1b515287faa5db9c6bcf290222206d120b3d43f6"}, "finch": {:hex, :finch, "0.19.0", "c644641491ea854fc5c1bbaef36bfc764e3f08e7185e1f084e35e0672241b76d", [:mix], [{:mime, "~> 1.0 or ~> 2.0", [hex: :mime, repo: "hexpm", optional: false]}, {:mint, "~> 1.6.2 or ~> 1.7", [hex: :mint, repo: "hexpm", optional: false]}, {:nimble_options, "~> 0.4 or ~> 1.0", [hex: :nimble_options, repo: "hexpm", optional: false]}, {:nimble_pool, "~> 1.1", [hex: :nimble_pool, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "fc5324ce209125d1e2fa0fcd2634601c52a787aff1cd33ee833664a5af4ea2b6"}, "git_cli": {:hex, :git_cli, "0.3.0", "a5422f9b95c99483385b976f5d43f7e8233283a47cda13533d7c16131cb14df5", [:mix], [], "hexpm", "78cb952f4c86a41f4d3511f1d3ecb28edb268e3a7df278de2faa1bd4672eaf9b"}, From 3f837d14e80ece91aca6fd8ec7fc7c7be713d39f Mon Sep 17 00:00:00 2001 From: Zach Daniel Date: Thu, 29 May 2025 22:15:50 -0400 Subject: [PATCH 021/174] improvement: assume not renaming when generating dev migrations --- lib/migration_generator/migration_generator.ex | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/lib/migration_generator/migration_generator.ex b/lib/migration_generator/migration_generator.ex index 57e0787e..2d5dfca1 100644 --- a/lib/migration_generator/migration_generator.ex +++ b/lib/migration_generator/migration_generator.ex @@ -2960,10 +2960,14 @@ defmodule AshPostgres.MigrationGenerator do end defp renaming?(table, removing, opts) do - if opts.no_shell? do - raise "Unimplemented: cannot determine: Are you renaming #{table}.#{removing.source}? without shell input" + if opts.dev do + if opts.no_shell? do + raise "Unimplemented: cannot determine: Are you renaming #{table}.#{removing.source}? without shell input" + else + yes?(opts, "Are you renaming #{table}.#{removing.source}?") + end else - yes?(opts, "Are you renaming #{table}.#{removing.source}?") + false end end From 755c5564abd94f0b017e854cd0aaa2bb29e14c15 Mon Sep 17 00:00:00 2001 From: Zach Daniel Date: Fri, 30 May 2025 00:25:24 -0400 Subject: [PATCH 022/174] improvement: use new `PendingCodegen` error --- .tool-versions | 2 +- lib/data_layer.ex | 1 + .../migration_generator.ex | 204 ++++++++---------- mix.exs | 31 +-- mix.lock | 2 +- test/migration_generator_test.exs | 18 +- 6 files changed, 118 insertions(+), 140 deletions(-) diff --git a/.tool-versions b/.tool-versions index cab727e0..005db769 100644 --- a/.tool-versions +++ b/.tool-versions @@ -1,2 +1,2 @@ erlang 27.0.1 -elixir 1.18.0-otp-27 +elixir 1.18.4-otp-27 diff --git a/lib/data_layer.ex b/lib/data_layer.ex index ae642468..40227e7f 100644 --- a/lib/data_layer.ex +++ b/lib/data_layer.ex @@ -568,6 +568,7 @@ defmodule AshPostgres.DataLayer do end def codegen(args) do + Mix.Task.reenable("ash_postgres.generate_migrations") Mix.Task.run("ash_postgres.generate_migrations", args) end diff --git a/lib/migration_generator/migration_generator.ex b/lib/migration_generator/migration_generator.ex index 2d5dfca1..de411a97 100644 --- a/lib/migration_generator/migration_generator.ex +++ b/lib/migration_generator/migration_generator.ex @@ -3,8 +3,6 @@ defmodule AshPostgres.MigrationGenerator do require Logger - import Mix.Generator - alias AshPostgres.MigrationGenerator.{Operation, Phase} defstruct snapshot_path: nil, @@ -52,12 +50,46 @@ defmodule AshPostgres.MigrationGenerator do |> Enum.concat(find_repos()) |> Enum.uniq() - Mix.shell().info("\nExtension Migrations: ") - create_extension_migrations(repos, opts) - Mix.shell().info("\nGenerating Tenant Migrations: ") - create_migrations(tenant_snapshots, opts, true, snapshots) - Mix.shell().info("\nGenerating Migrations:") - create_migrations(snapshots, opts, false) + extension_migration_files = + create_extension_migrations(repos, opts) + + tenant_migration_files = + create_migrations(tenant_snapshots, opts, true, snapshots) + + migration_files = + create_migrations(snapshots, opts, false) + + case extension_migration_files ++ tenant_migration_files ++ migration_files do + [] -> + if !opts.check || opts.dry_run do + Mix.shell().info( + "No changes detected, so no migrations or snapshots have been created." + ) + end + + :ok + + files -> + cond do + opts.check -> + raise Ash.Error.Framework.PendingCodegen, + diff: files + + opts.dry_run -> + Mix.shell().info( + files + |> Enum.sort_by(&elem(&1, 0)) + |> Enum.map_join("\n\n", fn {file, contents} -> + "#{file}\n#{contents}" + end) + ) + + true -> + Enum.each(files, fn {file, contents} -> + Mix.Generator.create_file(file, contents, force?: true) + end) + end + end end defp find_repos do @@ -225,8 +257,7 @@ defmodule AshPostgres.MigrationGenerator do |> Enum.map(fn {_name, extension} -> extension end) if Enum.empty?(to_install) do - Mix.shell().info("No extensions to install") - :ok + [] else dev = if opts.dev, do: "_dev" @@ -378,40 +409,13 @@ defmodule AshPostgres.MigrationGenerator do contents = format(migration_file, contents, opts) - if opts.dry_run do - Mix.shell().info(snapshot_contents) - Mix.shell().info(contents) - - if opts.check do - Mix.shell().error(""" - Migrations would have been generated, but the --check flag was provided. - - To see what migration would have been generated, run with the `--dry-run` - option instead. To generate those migrations, run without either flag. - """) - - exit({:shutdown, 1}) - end - else - if opts.check do - Mix.shell().error(""" - Migrations would have been generated, but the --check flag was provided. - - To see what migration would have been generated, run with the `--dry-run` - option instead. To generate those migrations, run without either flag. - """) - - exit({:shutdown, 1}) - end - - create_file(snapshot_file, snapshot_contents, force: true) - - if !opts.snapshots_only do - create_file(migration_file, contents) - end - end + [ + {snapshot_file, snapshot_contents}, + {migration_file, contents} + ] end end + |> List.flatten() end defp set_ash_functions(snapshot, installed_extensions) do @@ -429,7 +433,7 @@ defmodule AshPostgres.MigrationGenerator do defp create_migrations(snapshots, opts, tenant?, non_tenant_snapshots \\ []) do snapshots |> Enum.group_by(& &1.repo) - |> Enum.each(fn {repo, snapshots} -> + |> Enum.flat_map(fn {repo, snapshots} -> deduped = deduplicate_snapshots(snapshots, opts, non_tenant_snapshots) snapshots_with_operations = @@ -444,18 +448,7 @@ defmodule AshPostgres.MigrationGenerator do |> Enum.uniq() |> case do [] -> - tenant_str = - if tenant? do - "tenant " - else - "" - end - - Mix.shell().info( - "No #{tenant_str}changes detected, so no migrations or snapshots have been created." - ) - - :ok + [] operations -> dev_migrations = get_dev_migrations(opts, tenant?, repo) @@ -475,21 +468,12 @@ defmodule AshPostgres.MigrationGenerator do end end - if opts.check do - Mix.shell().error(""" - Migrations would have been generated, but the --check flag was provided. - - To see what migration would have been generated, run with the `--dry-run` - option instead. To generate those migrations, run without either flag. - """) - - exit({:shutdown, 1}) - end - - if !opts.snapshots_only do + if opts.snapshots_only do + [] + else operations |> split_into_migrations() - |> Enum.each(fn operations -> + |> Enum.map(fn operations -> run_without_transaction? = Enum.any?(operations, fn %Operation.AddCustomIndex{index: %{concurrently: true}} -> @@ -505,11 +489,10 @@ defmodule AshPostgres.MigrationGenerator do operations |> organize_operations |> build_up_and_down() - |> write_migration!(repo, opts, tenant?, run_without_transaction?) + |> migration(repo, opts, tenant?, run_without_transaction?) end) end - - create_new_snapshot(snapshots, repo_name(repo), opts, tenant?) + |> Enum.concat(create_new_snapshot(snapshots, repo_name(repo), opts, tenant?)) end end) end @@ -1110,7 +1093,7 @@ defmodule AshPostgres.MigrationGenerator do repo |> Module.split() |> List.last() |> Macro.underscore() end - defp write_migration!({up, down}, repo, opts, tenant?, run_without_transaction?) do + defp migration({up, down}, repo, opts, tenant?, run_without_transaction?) do migration_path = migration_path(opts, repo, tenant?) require_name!(opts) @@ -1185,13 +1168,7 @@ defmodule AshPostgres.MigrationGenerator do """ try do - contents = format(migration_file, contents, opts) - - if opts.dry_run do - Mix.shell().info(contents) - else - create_file(migration_file, contents) - end + {migration_file, format(migration_file, contents, opts)} rescue exception -> reraise( @@ -1223,45 +1200,44 @@ defmodule AshPostgres.MigrationGenerator do end defp create_new_snapshot(snapshots, repo_name, opts, tenant?) do - if !opts.dry_run do - Enum.each(snapshots, fn snapshot -> - snapshot_binary = snapshot_to_binary(snapshot) + Enum.map(snapshots, fn snapshot -> + snapshot_binary = snapshot_to_binary(snapshot) - snapshot_folder = - if tenant? do - opts - |> snapshot_path(snapshot.repo) - |> Path.join(repo_name) - |> Path.join("tenants") - else - opts - |> snapshot_path(snapshot.repo) - |> Path.join(repo_name) - end + snapshot_folder = + if tenant? do + opts + |> snapshot_path(snapshot.repo) + |> Path.join(repo_name) + |> Path.join("tenants") + else + opts + |> snapshot_path(snapshot.repo) + |> Path.join(repo_name) + end - dev = if opts.dev, do: "_dev" + dev = if opts.dev, do: "_dev" - snapshot_file = - if snapshot.schema do - Path.join( - snapshot_folder, - "#{snapshot.schema}.#{snapshot.table}/#{timestamp()}#{dev}.json" - ) - else - Path.join(snapshot_folder, "#{snapshot.table}/#{timestamp()}#{dev}.json") - end + snapshot_file = + if snapshot.schema do + Path.join( + snapshot_folder, + "#{snapshot.schema}.#{snapshot.table}/#{timestamp()}#{dev}.json" + ) + else + Path.join(snapshot_folder, "#{snapshot.table}/#{timestamp()}#{dev}.json") + end - File.mkdir_p(Path.dirname(snapshot_file)) - create_file(snapshot_file, snapshot_binary, force: true) + File.mkdir_p(Path.dirname(snapshot_file)) - old_snapshot_folder = Path.join(snapshot_folder, "#{snapshot.table}#{dev}.json") + old_snapshot_folder = Path.join(snapshot_folder, "#{snapshot.table}#{dev}.json") - if File.exists?(old_snapshot_folder) do - new_snapshot_folder = Path.join(snapshot_folder, "#{snapshot.table}/initial#{dev}.json") - File.rename(old_snapshot_folder, new_snapshot_folder) - end - end) - end + if File.exists?(old_snapshot_folder) do + new_snapshot_folder = Path.join(snapshot_folder, "#{snapshot.table}/initial#{dev}.json") + File.rename(old_snapshot_folder, new_snapshot_folder) + end + + {snapshot_file, snapshot_binary} + end) end @doc false @@ -2961,13 +2937,13 @@ defmodule AshPostgres.MigrationGenerator do defp renaming?(table, removing, opts) do if opts.dev do + false + else if opts.no_shell? do raise "Unimplemented: cannot determine: Are you renaming #{table}.#{removing.source}? without shell input" else yes?(opts, "Are you renaming #{table}.#{removing.source}?") end - else - false end end diff --git a/mix.exs b/mix.exs index fb84295b..6cb94ca9 100644 --- a/mix.exs +++ b/mix.exs @@ -166,7 +166,8 @@ defmodule AshPostgres.MixProject do # Run "mix help deps" to learn about dependencies. defp deps do [ - {:ash, ash_version("~> 3.4 and >= 3.4.69")}, + # {:ash, ash_version("~> 3.4 and >= 3.4.69")}, + {:ash, github: "ash-project/ash", override: true}, {:ash_sql, ash_sql_version("~> 0.2 and >= 0.2.72")}, {:igniter, "~> 0.6", optional: true}, {:ecto_sql, "~> 3.12"}, @@ -189,24 +190,24 @@ defmodule AshPostgres.MixProject do ] end - defp ash_version(default_version) do - case System.get_env("ASH_VERSION") do - nil -> - default_version + # defp ash_version(default_version) do + # case System.get_env("ASH_VERSION") do + # nil -> + # default_version - "local" -> - [path: "../ash", override: true] + # "local" -> + # [path: "../ash", override: true] - "main" -> - [git: "https://github.com/ash-project/ash.git", override: true] + # "main" -> + # [git: "https://github.com/ash-project/ash.git", override: true] - version when is_binary(version) -> - "~> #{version}" + # version when is_binary(version) -> + # "~> #{version}" - version -> - version - end - end + # version -> + # version + # end + # end defp ash_sql_version(default_version) do case System.get_env("ASH_SQL_VERSION") do diff --git a/mix.lock b/mix.lock index 4076ca19..89d5b5af 100644 --- a/mix.lock +++ b/mix.lock @@ -1,5 +1,5 @@ %{ - "ash": {:hex, :ash, "3.5.12", "435a6916d47e4ed6eabce886de2443d17af9dd9ca9765a29c73d9e02507b86b3", [:mix], [{:decimal, "~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:ecto, "~> 3.7", [hex: :ecto, repo: "hexpm", optional: false]}, {:ets, "~> 0.8", [hex: :ets, repo: "hexpm", optional: false]}, {:igniter, "~> 0.6", [hex: :igniter, repo: "hexpm", optional: true]}, {:jason, ">= 1.0.0", [hex: :jason, repo: "hexpm", optional: false]}, {:owl, "~> 0.11", [hex: :owl, repo: "hexpm", optional: false]}, {:picosat_elixir, "~> 0.2", [hex: :picosat_elixir, repo: "hexpm", optional: true]}, {:plug, ">= 0.0.0", [hex: :plug, repo: "hexpm", optional: true]}, {:reactor, "~> 0.11", [hex: :reactor, repo: "hexpm", optional: false]}, {:simple_sat, ">= 0.1.1 and < 1.0.0-0", [hex: :simple_sat, repo: "hexpm", optional: true]}, {:spark, ">= 2.2.60 and < 3.0.0-0", [hex: :spark, repo: "hexpm", optional: false]}, {:splode, ">= 0.2.6 and < 1.0.0-0", [hex: :splode, repo: "hexpm", optional: false]}, {:stream_data, "~> 1.0", [hex: :stream_data, repo: "hexpm", optional: false]}, {:telemetry, "~> 1.1", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "503492989c56e33c300d731b3717d1df9eeebba2b9018e5dd9f330db727edb57"}, + "ash": {:git, "https://github.com/ash-project/ash.git", "e7b1a738644e1092ed350115ebebf5da8ac2aec1", []}, "ash_sql": {:hex, :ash_sql, "0.2.76", "4afac3284194f3d7820b7edc1263ac1eb232a25734406ad7b2284683b9384205", [:mix], [{:ash, "~> 3.5", [hex: :ash, repo: "hexpm", optional: false]}, {:ecto, "~> 3.9", [hex: :ecto, repo: "hexpm", optional: false]}, {:ecto_sql, "~> 3.9", [hex: :ecto_sql, repo: "hexpm", optional: false]}], "hexpm", "f6bc02d8c4cba3f8f9a532e6ff73eaf8a4f7685257646a58fe7a320cfaf10c39"}, "benchee": {:hex, :benchee, "1.4.0", "9f1f96a30ac80bab94faad644b39a9031d5632e517416a8ab0a6b0ac4df124ce", [:mix], [{:deep_merge, "~> 1.0", [hex: :deep_merge, repo: "hexpm", optional: false]}, {:statistex, "~> 1.0", [hex: :statistex, repo: "hexpm", optional: false]}, {:table, "~> 0.1.0", [hex: :table, repo: "hexpm", optional: true]}], "hexpm", "299cd10dd8ce51c9ea3ddb74bb150f93d25e968f93e4c1fa31698a8e4fa5d715"}, "bunt": {:hex, :bunt, "1.0.0", "081c2c665f086849e6d57900292b3a161727ab40431219529f13c4ddcf3e7a44", [:mix], [], "hexpm", "dc5f86aa08a5f6fa6b8096f0735c4e76d54ae5c9fa2c143e5a1fc7c1cd9bb6b5"}, diff --git a/test/migration_generator_test.exs b/test/migration_generator_test.exs index 6a4d0ef5..afbd4ed8 100644 --- a/test/migration_generator_test.exs +++ b/test/migration_generator_test.exs @@ -1420,15 +1420,15 @@ defmodule AshPostgres.MigrationGeneratorTest do [domain: Domain] end - test "returns code(1) if snapshots and resources don't fit", %{domain: domain} do - assert catch_exit( - AshPostgres.MigrationGenerator.generate(domain, - snapshot_path: "test_snapshots_path", - migration_path: "test_migration_path", - check: true, - auto_name: true - ) - ) == {:shutdown, 1} + test "raises an error on pending codegen", %{domain: domain} do + assert_raise Ash.Error.Framework.PendingCodegen, fn -> + AshPostgres.MigrationGenerator.generate(domain, + snapshot_path: "test_snapshots_path", + migration_path: "test_migration_path", + check: true, + auto_name: true + ) + end refute File.exists?(Path.wildcard("test_migration_path2/**/*_migrate_resources*.exs")) refute File.exists?(Path.wildcard("test_snapshots_path2/test_repo/posts/*.json")) From 0f21c885f7072daf317108112ed83f31d3e5f93a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kenneth=20Kostre=C5=A1evi=C4=87?= Date: Fri, 30 May 2025 18:33:51 +0200 Subject: [PATCH 023/174] chore: Bump erlang elixir version in tool versions (#559) --- .tool-versions | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.tool-versions b/.tool-versions index 005db769..32823875 100644 --- a/.tool-versions +++ b/.tool-versions @@ -1,2 +1,2 @@ -erlang 27.0.1 -elixir 1.18.4-otp-27 +erlang 27.1.2 +elixir 1.18.4 \ No newline at end of file From de093d8f5683d5b9d848be0fb00244a4e06e6939 Mon Sep 17 00:00:00 2001 From: Zach Daniel Date: Fri, 30 May 2025 01:33:29 -0400 Subject: [PATCH 024/174] chore: better dev mode check --- lib/migration_generator/migration_generator.ex | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/lib/migration_generator/migration_generator.ex b/lib/migration_generator/migration_generator.ex index de411a97..58a0ad71 100644 --- a/lib/migration_generator/migration_generator.ex +++ b/lib/migration_generator/migration_generator.ex @@ -456,9 +456,12 @@ defmodule AshPostgres.MigrationGenerator do if !opts.dev and dev_migrations != [] do if opts.check do Mix.shell().error(""" - Generated migrations are from dev mode. + Codegen check failed. - Generate migrations without `--dev` flag. + You have migrations remaining that were generated with the --dev flag. + + Run `mix ash.codegen ` to remove the dev migraitons and replace them + with production ready migrations. """) exit({:shutdown, 1}) From a6c2f2e18bd78dec40aa45acf8dcf7dead4b23e7 Mon Sep 17 00:00:00 2001 From: Zach Daniel Date: Fri, 30 May 2025 16:08:16 -0400 Subject: [PATCH 025/174] chore: update deps --- mix.exs | 31 +++++++++++++++---------------- mix.lock | 6 +++--- 2 files changed, 18 insertions(+), 19 deletions(-) diff --git a/mix.exs b/mix.exs index 6cb94ca9..91eb50a7 100644 --- a/mix.exs +++ b/mix.exs @@ -166,8 +166,7 @@ defmodule AshPostgres.MixProject do # Run "mix help deps" to learn about dependencies. defp deps do [ - # {:ash, ash_version("~> 3.4 and >= 3.4.69")}, - {:ash, github: "ash-project/ash", override: true}, + {:ash, ash_version("~> 3.5 and >= 3.5.13")}, {:ash_sql, ash_sql_version("~> 0.2 and >= 0.2.72")}, {:igniter, "~> 0.6", optional: true}, {:ecto_sql, "~> 3.12"}, @@ -190,24 +189,24 @@ defmodule AshPostgres.MixProject do ] end - # defp ash_version(default_version) do - # case System.get_env("ASH_VERSION") do - # nil -> - # default_version + defp ash_version(default_version) do + case System.get_env("ASH_VERSION") do + nil -> + default_version - # "local" -> - # [path: "../ash", override: true] + "local" -> + [path: "../ash", override: true] - # "main" -> - # [git: "https://github.com/ash-project/ash.git", override: true] + "main" -> + [git: "https://github.com/ash-project/ash.git", override: true] - # version when is_binary(version) -> - # "~> #{version}" + version when is_binary(version) -> + "~> #{version}" - # version -> - # version - # end - # end + version -> + version + end + end defp ash_sql_version(default_version) do case System.get_env("ASH_SQL_VERSION") do diff --git a/mix.lock b/mix.lock index 89d5b5af..1f3910ec 100644 --- a/mix.lock +++ b/mix.lock @@ -1,5 +1,5 @@ %{ - "ash": {:git, "https://github.com/ash-project/ash.git", "e7b1a738644e1092ed350115ebebf5da8ac2aec1", []}, + "ash": {:hex, :ash, "3.5.13", "1e2d15188dcf01a00f7c91180f6a0fb990c427828fdf9f014b8a6dde951f46a0", [:mix], [{:decimal, "~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:ecto, "~> 3.7", [hex: :ecto, repo: "hexpm", optional: false]}, {:ets, "~> 0.8", [hex: :ets, repo: "hexpm", optional: false]}, {:igniter, "~> 0.6", [hex: :igniter, repo: "hexpm", optional: true]}, {:jason, ">= 1.0.0", [hex: :jason, repo: "hexpm", optional: false]}, {:owl, "~> 0.11", [hex: :owl, repo: "hexpm", optional: false]}, {:picosat_elixir, "~> 0.2", [hex: :picosat_elixir, repo: "hexpm", optional: true]}, {:plug, ">= 0.0.0", [hex: :plug, repo: "hexpm", optional: true]}, {:reactor, "~> 0.11", [hex: :reactor, repo: "hexpm", optional: false]}, {:simple_sat, ">= 0.1.1 and < 1.0.0-0", [hex: :simple_sat, repo: "hexpm", optional: true]}, {:spark, ">= 2.2.61 and < 3.0.0-0", [hex: :spark, repo: "hexpm", optional: false]}, {:splode, ">= 0.2.6 and < 1.0.0-0", [hex: :splode, repo: "hexpm", optional: false]}, {:stream_data, "~> 1.0", [hex: :stream_data, repo: "hexpm", optional: false]}, {:telemetry, "~> 1.1", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "bdd52d10f95af357f37b61b74636226bf7c1082c4b815df94443d2aa2607c961"}, "ash_sql": {:hex, :ash_sql, "0.2.76", "4afac3284194f3d7820b7edc1263ac1eb232a25734406ad7b2284683b9384205", [:mix], [{:ash, "~> 3.5", [hex: :ash, repo: "hexpm", optional: false]}, {:ecto, "~> 3.9", [hex: :ecto, repo: "hexpm", optional: false]}, {:ecto_sql, "~> 3.9", [hex: :ecto_sql, repo: "hexpm", optional: false]}], "hexpm", "f6bc02d8c4cba3f8f9a532e6ff73eaf8a4f7685257646a58fe7a320cfaf10c39"}, "benchee": {:hex, :benchee, "1.4.0", "9f1f96a30ac80bab94faad644b39a9031d5632e517416a8ab0a6b0ac4df124ce", [:mix], [{:deep_merge, "~> 1.0", [hex: :deep_merge, repo: "hexpm", optional: false]}, {:statistex, "~> 1.0", [hex: :statistex, repo: "hexpm", optional: false]}, {:table, "~> 0.1.0", [hex: :table, repo: "hexpm", optional: true]}], "hexpm", "299cd10dd8ce51c9ea3ddb74bb150f93d25e968f93e4c1fa31698a8e4fa5d715"}, "bunt": {:hex, :bunt, "1.0.0", "081c2c665f086849e6d57900292b3a161727ab40431219529f13c4ddcf3e7a44", [:mix], [], "hexpm", "dc5f86aa08a5f6fa6b8096f0735c4e76d54ae5c9fa2c143e5a1fc7c1cd9bb6b5"}, @@ -23,7 +23,7 @@ "git_ops": {:hex, :git_ops, "2.7.3", "c993aedb11005752e321d482de6f2a46d0b5d5f09ce69961f31a856e76bf4f12", [:mix], [{:git_cli, "~> 0.2", [hex: :git_cli, repo: "hexpm", optional: false]}, {:igniter, ">= 0.5.27 and < 1.0.0-0", [hex: :igniter, repo: "hexpm", optional: true]}, {:nimble_parsec, "~> 1.0", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "c54ee65e12778be1f4dd6a0921e57ab2bddd35bd6130cbe274dcb1f0a21ca59d"}, "glob_ex": {:hex, :glob_ex, "0.1.11", "cb50d3f1ef53f6ca04d6252c7fde09fd7a1cf63387714fe96f340a1349e62c93", [:mix], [], "hexpm", "342729363056e3145e61766b416769984c329e4378f1d558b63e341020525de4"}, "hpax": {:hex, :hpax, "1.0.3", "ed67ef51ad4df91e75cc6a1494f851850c0bd98ebc0be6e81b026e765ee535aa", [:mix], [], "hexpm", "8eab6e1cfa8d5918c2ce4ba43588e894af35dbd8e91e6e55c817bca5847df34a"}, - "igniter": {:hex, :igniter, "0.6.3", "8bfaf5955ce83301da0f0a53455f73a0bc4dc5aacd6c311363089850a5dc2dd7", [:mix], [{:glob_ex, "~> 0.1.7", [hex: :glob_ex, repo: "hexpm", optional: false]}, {:jason, "~> 1.4", [hex: :jason, repo: "hexpm", optional: false]}, {:owl, "~> 0.11", [hex: :owl, repo: "hexpm", optional: false]}, {:phx_new, "~> 1.7", [hex: :phx_new, repo: "hexpm", optional: true]}, {:req, "~> 0.5", [hex: :req, repo: "hexpm", optional: false]}, {:rewrite, ">= 1.1.1 and < 2.0.0-0", [hex: :rewrite, repo: "hexpm", optional: false]}, {:sourceror, "~> 1.4", [hex: :sourceror, repo: "hexpm", optional: false]}, {:spitfire, ">= 0.1.3 and < 1.0.0-0", [hex: :spitfire, repo: "hexpm", optional: false]}], "hexpm", "95d34d8280dea992e05dcbf9865414d69e421a76d743661eaf1d1337ea54fa80"}, + "igniter": {:hex, :igniter, "0.6.4", "81b7442be9ae0b9107b715144f3633f72788644d13ffded612cb508861b2c726", [:mix], [{:glob_ex, "~> 0.1.7", [hex: :glob_ex, repo: "hexpm", optional: false]}, {:jason, "~> 1.4", [hex: :jason, repo: "hexpm", optional: false]}, {:owl, "~> 0.11", [hex: :owl, repo: "hexpm", optional: false]}, {:phx_new, "~> 1.7", [hex: :phx_new, repo: "hexpm", optional: true]}, {:req, "~> 0.5", [hex: :req, repo: "hexpm", optional: false]}, {:rewrite, ">= 1.1.1 and < 2.0.0-0", [hex: :rewrite, repo: "hexpm", optional: false]}, {:sourceror, "~> 1.4", [hex: :sourceror, repo: "hexpm", optional: false]}, {:spitfire, ">= 0.1.3 and < 1.0.0-0", [hex: :spitfire, repo: "hexpm", optional: false]}], "hexpm", "e999fc4b883e5eacc07ca2823273880ab30108c7e6a0d1542a3c8e00605aef46"}, "iterex": {:hex, :iterex, "0.1.2", "58f9b9b9a22a55cbfc7b5234a9c9c63eaac26d276b3db80936c0e1c60355a5a6", [:mix], [], "hexpm", "2e103b8bcc81757a9af121f6dc0df312c9a17220f302b1193ef720460d03029d"}, "jason": {:hex, :jason, "1.4.4", "b9226785a9aa77b6857ca22832cffa5d5011a667207eb2a0ad56adb5db443b8a", [:mix], [{:decimal, "~> 1.0 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm", "c5eb0cab91f094599f94d55bc63409236a8ec69a21a67814529e8d5f6cc90b3b"}, "libgraph": {:hex, :libgraph, "0.16.0", "3936f3eca6ef826e08880230f806bfea13193e49bf153f93edcf0239d4fd1d07", [:mix], [], "hexpm", "41ca92240e8a4138c30a7e06466acc709b0cbb795c643e9e17174a178982d6bf"}, @@ -38,7 +38,7 @@ "nimble_pool": {:hex, :nimble_pool, "1.1.0", "bf9c29fbdcba3564a8b800d1eeb5a3c58f36e1e11d7b7fb2e084a643f645f06b", [:mix], [], "hexpm", "af2e4e6b34197db81f7aad230c1118eac993acc0dae6bc83bac0126d4ae0813a"}, "owl": {:hex, :owl, "0.12.2", "65906b525e5c3ef51bab6cba7687152be017aebe1da077bb719a5ee9f7e60762", [:mix], [{:ucwidth, "~> 0.2", [hex: :ucwidth, repo: "hexpm", optional: true]}], "hexpm", "6398efa9e1fea70a04d24231e10dcd66c1ac1aa2da418d20ef5357ec61de2880"}, "postgrex": {:hex, :postgrex, "0.20.0", "363ed03ab4757f6bc47942eff7720640795eb557e1935951c1626f0d303a3aed", [:mix], [{:db_connection, "~> 2.1", [hex: :db_connection, repo: "hexpm", optional: false]}, {:decimal, "~> 1.5 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:table, "~> 0.1.0", [hex: :table, repo: "hexpm", optional: true]}], "hexpm", "d36ef8b36f323d29505314f704e21a1a038e2dc387c6409ee0cd24144e187c0f"}, - "reactor": {:hex, :reactor, "0.15.3", "f1f05d5b0f229ad1a164b7a5543beee58c9975e7e146afc71821e5afc5c69a79", [:mix], [{:igniter, "~> 0.4", [hex: :igniter, repo: "hexpm", optional: true]}, {:iterex, "~> 0.1", [hex: :iterex, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}, {:libgraph, "~> 0.16", [hex: :libgraph, repo: "hexpm", optional: false]}, {:spark, "~> 2.0", [hex: :spark, repo: "hexpm", optional: false]}, {:splode, "~> 0.2", [hex: :splode, repo: "hexpm", optional: false]}, {:telemetry, "~> 1.2", [hex: :telemetry, repo: "hexpm", optional: false]}, {:yaml_elixir, "~> 2.11", [hex: :yaml_elixir, repo: "hexpm", optional: false]}, {:ymlr, "~> 5.0", [hex: :ymlr, repo: "hexpm", optional: false]}], "hexpm", "8a16a46163fcdeb1d1be06749f54bd71282126be27c9dc80010cf3b97fe7193c"}, + "reactor": {:hex, :reactor, "0.15.4", "ef0c56a901c132529a14ab59fed0ccb4fcecb24308fb189a94c908255d4fdafc", [:mix], [{:igniter, "~> 0.4", [hex: :igniter, repo: "hexpm", optional: true]}, {:iterex, "~> 0.1", [hex: :iterex, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}, {:libgraph, "~> 0.16", [hex: :libgraph, repo: "hexpm", optional: false]}, {:spark, "~> 2.0", [hex: :spark, repo: "hexpm", optional: false]}, {:splode, "~> 0.2", [hex: :splode, repo: "hexpm", optional: false]}, {:telemetry, "~> 1.2", [hex: :telemetry, repo: "hexpm", optional: false]}, {:yaml_elixir, "~> 2.11", [hex: :yaml_elixir, repo: "hexpm", optional: false]}, {:ymlr, "~> 5.0", [hex: :ymlr, repo: "hexpm", optional: false]}], "hexpm", "783bf62fd0c72ded033afabdb8b6190b7048769771a2a97256e6f0bf4fb0a891"}, "req": {:hex, :req, "0.5.10", "a3a063eab8b7510785a467f03d30a8d95f66f5c3d9495be3474b61459c54376c", [:mix], [{:brotli, "~> 0.3.1", [hex: :brotli, repo: "hexpm", optional: true]}, {:ezstd, "~> 1.0", [hex: :ezstd, repo: "hexpm", optional: true]}, {:finch, "~> 0.17", [hex: :finch, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}, {:mime, "~> 2.0.6 or ~> 2.1", [hex: :mime, repo: "hexpm", optional: false]}, {:nimble_csv, "~> 1.0", [hex: :nimble_csv, repo: "hexpm", optional: true]}, {:plug, "~> 1.0", [hex: :plug, repo: "hexpm", optional: true]}], "hexpm", "8a604815743f8a2d3b5de0659fa3137fa4b1cffd636ecb69b30b2b9b2c2559be"}, "rewrite": {:hex, :rewrite, "1.1.2", "f5a5d10f5fed1491a6ff48e078d4585882695962ccc9e6c779bae025d1f92eda", [:mix], [{:glob_ex, "~> 0.1", [hex: :glob_ex, repo: "hexpm", optional: false]}, {:sourceror, "~> 1.0", [hex: :sourceror, repo: "hexpm", optional: false]}, {:text_diff, "~> 0.1", [hex: :text_diff, repo: "hexpm", optional: false]}], "hexpm", "7f8b94b1e3528d0a47b3e8b7bfeca559d2948a65fa7418a9ad7d7712703d39d4"}, "simple_sat": {:hex, :simple_sat, "0.1.3", "f650fc3c184a5fe741868b5ac56dc77fdbb428468f6dbf1978e14d0334497578", [:mix], [], "hexpm", "a54305066a356b7194dc81db2a89232bacdc0b3edaef68ed9aba28dcbc34887b"}, From ea9d09c8e675deac12b91f01ea110a58fe43b365 Mon Sep 17 00:00:00 2001 From: Zach Daniel Date: Fri, 30 May 2025 16:08:24 -0400 Subject: [PATCH 026/174] chore: release version v2.6.0 --- CHANGELOG.md | 21 +++++++++++++++++++++ mix.exs | 2 +- 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 63141775..b739ea7e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,27 @@ See [Conventional Commits](https://www.conventionalcommits.org) for commit guide +## [v2.6.0](https://github.com/ash-project/ash_postgres/compare/v2.5.22...v2.6.0) (2025-05-30) + + + + +### Features: + +* --dev flag for codegen (#555) + +### Bug Fixes: + +* properly encode decimal scale & preicison into snapshots + +### Improvements: + +* use new `PendingCodegen` error + +* assume not renaming when generating dev migrations + +* support scale & precision in decimal types + ## [v2.5.22](https://github.com/ash-project/ash_postgres/compare/v2.5.21...v2.5.22) (2025-05-22) diff --git a/mix.exs b/mix.exs index 91eb50a7..306c04c6 100644 --- a/mix.exs +++ b/mix.exs @@ -5,7 +5,7 @@ defmodule AshPostgres.MixProject do The PostgreSQL data layer for Ash Framework """ - @version "2.5.22" + @version "2.6.0" def project do [ From be48da96af1d08614d725053b9ea8c088aee79b8 Mon Sep 17 00:00:00 2001 From: Frank Dugan III Date: Fri, 30 May 2025 17:03:44 -0500 Subject: [PATCH 027/174] fix: retain repo as atom in migrator task (#560) --- lib/mix/tasks/ash_postgres.migrate.ex | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/lib/mix/tasks/ash_postgres.migrate.ex b/lib/mix/tasks/ash_postgres.migrate.ex index 3299fc5b..f8ab1d20 100644 --- a/lib/mix/tasks/ash_postgres.migrate.ex +++ b/lib/mix/tasks/ash_postgres.migrate.ex @@ -130,16 +130,9 @@ defmodule Mix.Tasks.AshPostgres.Migrate do for tenant <- tenants(repo, opts) do rest_opts = AshPostgres.Mix.Helpers.delete_arg(rest_opts, "--prefix") - repo = - if is_atom(repo) do - inspect(repo) - else - repo - end - Mix.Task.run( "ecto.migrate", - ["-r", repo] ++ + ["-r", to_string(repo)] ++ rest_opts ++ ["--prefix", tenant, "--migrations-path", tenant_migrations_path(opts, repo)] ) From 7f91cc87e8f0106c593dce6d9f8745fe9b71e733 Mon Sep 17 00:00:00 2001 From: Zach Daniel Date: Fri, 30 May 2025 18:04:09 -0400 Subject: [PATCH 028/174] chore: release version v2.6.1 --- CHANGELOG.md | 9 +++++++++ mix.exs | 2 +- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b739ea7e..f627e950 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,15 @@ See [Conventional Commits](https://www.conventionalcommits.org) for commit guide +## [v2.6.1](https://github.com/ash-project/ash_postgres/compare/v2.6.0...v2.6.1) (2025-05-30) + + + + +### Bug Fixes: + +* retain repo as atom in migrator task (#560) + ## [v2.6.0](https://github.com/ash-project/ash_postgres/compare/v2.5.22...v2.6.0) (2025-05-30) diff --git a/mix.exs b/mix.exs index 306c04c6..036bf575 100644 --- a/mix.exs +++ b/mix.exs @@ -5,7 +5,7 @@ defmodule AshPostgres.MixProject do The PostgreSQL data layer for Ash Framework """ - @version "2.6.0" + @version "2.6.1" def project do [ From 57dbdb4bf52d4d27ec87b831a09ee7190c291a24 Mon Sep 17 00:00:00 2001 From: Zach Daniel Date: Mon, 2 Jun 2025 17:24:44 -0400 Subject: [PATCH 029/174] test: add tests corresponding to #561 unable to reproduce --- test/atomics_test.exs | 21 +++++++++++++++++++++ test/support/resources/post.ex | 10 ++++++++++ 2 files changed, 31 insertions(+) diff --git a/test/atomics_test.exs b/test/atomics_test.exs index 301cf8e3..2439ab9d 100644 --- a/test/atomics_test.exs +++ b/test/atomics_test.exs @@ -40,6 +40,27 @@ defmodule AshPostgres.AtomicsTest do |> Ash.update!() end + test "an atomic update on decimals works" do + post = + Post + |> Ash.Changeset.for_create(:create, %{title: "foo", decimal: Decimal.new("1")}) + |> Ash.create!() + + assert %{decimal: result} = + post + |> Ash.Changeset.for_update(:subtract_integer_from_decimal, %{amount: 2}) + |> Ash.update!() + + assert Decimal.eq?(result, Decimal.new("-1")) + + assert %{decimal: result} = + post + |> Ash.Changeset.for_update(:subtract_from_decimal, %{amount: Decimal.new("2")}) + |> Ash.update!() + + assert Decimal.eq?(result, Decimal.new("-3")) + end + test "an atomic works on a constrained integer" do post = Post diff --git a/test/support/resources/post.ex b/test/support/resources/post.ex index c66c8680..4b893048 100644 --- a/test/support/resources/post.ex +++ b/test/support/resources/post.ex @@ -184,6 +184,16 @@ defmodule AshPostgres.Test.Post do end) end + update :subtract_integer_from_decimal do + argument(:amount, :integer, allow_nil?: false) + change(atomic_update(:decimal, expr(decimal + -(^arg(:amount))))) + end + + update :subtract_from_decimal do + argument(:amount, :decimal, allow_nil?: false) + change(atomic_update(:decimal, expr(decimal + -(^arg(:amount))))) + end + update :add_to_limited_score do argument(:amount, :integer, allow_nil?: false) change(atomic_update(:limited_score, expr((limited_score || 0) + ^arg(:amount)))) From b7d69500ec8fb7fa6cd7a1900b88a0ac41a9e841 Mon Sep 17 00:00:00 2001 From: Zach Daniel Date: Tue, 3 Jun 2025 22:32:55 -0400 Subject: [PATCH 030/174] chore: remove ash added content when running query --- lib/data_layer.ex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/data_layer.ex b/lib/data_layer.ex index 40227e7f..8196cbe7 100644 --- a/lib/data_layer.ex +++ b/lib/data_layer.ex @@ -1532,7 +1532,7 @@ defmodule AshPostgres.DataLayer do {_, results} = with_savepoint(repo, query, fn -> repo.update_all( - query, + Map.delete(query, :__ash_bindings__), [], repo_opts ) From afa872b660fcac55dcb50900c19ca21cface7d8f Mon Sep 17 00:00:00 2001 From: Zach Daniel Date: Tue, 3 Jun 2025 22:49:31 -0400 Subject: [PATCH 031/174] chore: cleanup community files --- .github/CODE_OF_CONDUCT.md | 76 ----------------------- .github/CONTRIBUTING.md | 2 - .github/ISSUE_TEMPLATE/bug_report.md | 27 -------- .github/ISSUE_TEMPLATE/feature_request.md | 35 ----------- .github/PULL_REQUEST_TEMPLATE.md | 4 -- 5 files changed, 144 deletions(-) delete mode 100644 .github/CODE_OF_CONDUCT.md delete mode 100644 .github/CONTRIBUTING.md delete mode 100644 .github/ISSUE_TEMPLATE/bug_report.md delete mode 100644 .github/ISSUE_TEMPLATE/feature_request.md delete mode 100644 .github/PULL_REQUEST_TEMPLATE.md diff --git a/.github/CODE_OF_CONDUCT.md b/.github/CODE_OF_CONDUCT.md deleted file mode 100644 index 7aa6f743..00000000 --- a/.github/CODE_OF_CONDUCT.md +++ /dev/null @@ -1,76 +0,0 @@ -# Contributor Covenant Code of Conduct - -## Our Pledge - -In the interest of fostering an open and welcoming environment, we as -contributors and maintainers pledge to making participation in our project and -our community a harassment-free experience for everyone, regardless of age, body -size, disability, ethnicity, sex characteristics, gender identity and expression, -level of experience, education, socio-economic status, nationality, personal -appearance, race, religion, or sexual identity and orientation. - -## Our Standards - -Examples of behavior that contributes to creating a positive environment -include: - -* Using welcoming and inclusive language -* Being respectful of differing viewpoints and experiences -* Gracefully accepting constructive criticism -* Focusing on what is best for the community -* Showing empathy towards other community members - -Examples of unacceptable behavior by participants include: - -* The use of sexualized language or imagery and unwelcome sexual attention or - advances -* Trolling, insulting/derogatory comments, and personal or political attacks -* Public or private harassment -* Publishing others' private information, such as a physical or electronic - address, without explicit permission -* Other conduct which could reasonably be considered inappropriate in a - professional setting - -## Our Responsibilities - -Project maintainers are responsible for clarifying the standards of acceptable -behavior and are expected to take appropriate and fair corrective action in -response to any instances of unacceptable behavior. - -Project maintainers have the right and responsibility to remove, edit, or -reject comments, commits, code, wiki edits, issues, and other contributions -that are not aligned to this Code of Conduct, or to ban temporarily or -permanently any contributor for other behaviors that they deem inappropriate, -threatening, offensive, or harmful. - -## Scope - -This Code of Conduct applies both within project spaces and in public spaces -when an individual is representing the project or its community. Examples of -representing a project or community include using an official project e-mail -address, posting via an official social media account, or acting as an appointed -representative at an online or offline event. Representation of a project may be -further defined and clarified by project maintainers. - -## Enforcement - -Instances of abusive, harassing, or otherwise unacceptable behavior may be -reported by contacting the project team at zach@zachdaniel.dev. All -complaints will be reviewed and investigated and will result in a response that -is deemed necessary and appropriate to the circumstances. The project team is -obligated to maintain confidentiality with regard to the reporter of an incident. -Further details of specific enforcement policies may be posted separately. - -Project maintainers who do not follow or enforce the Code of Conduct in good -faith may face temporary or permanent repercussions as determined by other -members of the project's leadership. - -## Attribution - -This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, -available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html - -[homepage]: https://www.contributor-covenant.org - -For answers to common questions about this code of conduct, see -https://www.contributor-covenant.org/faq diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md deleted file mode 100644 index f537454f..00000000 --- a/.github/CONTRIBUTING.md +++ /dev/null @@ -1,2 +0,0 @@ -# Contributing Guidelines -Contributing guidelines can be found in the core project, [ash](https://github.com/ash-project/ash/blob/main/.github/CONTRIBUTING.md) diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md deleted file mode 100644 index 1f47341d..00000000 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ /dev/null @@ -1,27 +0,0 @@ ---- -name: Bug report -about: Create a report to help us improve -title: '' -labels: bug, needs review -assignees: '' - ---- - -**Describe the bug** -A clear and concise description of what the bug is. If you are not sure if the bug is related to `ash` or an extension, log it with [ash](https://github.com/ash-project/ash/issues/new) and we will move it. - -**To Reproduce** -A minimal set of resource definitions and calls that can reproduce the bug. - -**Expected behavior** -A clear and concise description of what you expected to happen. - -** Runtime - - Elixir version - - Erlang version - - OS - - Ash version - - any related extension versions - -**Additional context** -Add any other context about the problem here. diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md deleted file mode 100644 index a6442e0d..00000000 --- a/.github/ISSUE_TEMPLATE/feature_request.md +++ /dev/null @@ -1,35 +0,0 @@ ---- -name: Proposal -about: Suggest an idea for this project -title: "" -labels: enhancement, needs review -assignees: "" ---- - -**Is your feature request related to a problem? Please describe.** -A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] - -**Describe the solution you'd like** -A clear and concise description of what you want to happen. - -**Describe alternatives you've considered** -A clear and concise description of any alternative solutions or features you've considered. - -**Express the feature either with a change to resource syntax, or with a change to the resource interface** - -For example - -```elixir - attributes do - attribute :foo, :integer, bar: 10 # <- Adding `bar` here would cause - end -``` - -Or - -```elixir - Ash.read(Resource, bar: 10) # <- Adding `bar` here would cause -``` - -**Additional context** -Add any other context or screenshots about the feature request here. diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md deleted file mode 100644 index 8c13744f..00000000 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ /dev/null @@ -1,4 +0,0 @@ -### Contributor checklist - -- [ ] Bug fixes include regression tests -- [ ] Features include unit/acceptance tests From 3e24e7c8970547b710020fec62918bd3bbfedb5e Mon Sep 17 00:00:00 2001 From: Zach Daniel Date: Wed, 4 Jun 2025 09:49:24 -0400 Subject: [PATCH 032/174] fix: don't use `:"timestamptz(6)"` in ecto storage type --- lib/migration_generator/migration_generator.ex | 7 ++++++- lib/type.ex | 5 ++++- lib/types/timestamptz.ex | 4 ---- lib/types/timestamptz_usec.ex | 6 ++++-- 4 files changed, 14 insertions(+), 8 deletions(-) diff --git a/lib/migration_generator/migration_generator.ex b/lib/migration_generator/migration_generator.ex index 58a0ad71..1699141d 100644 --- a/lib/migration_generator/migration_generator.ex +++ b/lib/migration_generator/migration_generator.ex @@ -3364,8 +3364,13 @@ defmodule AshPostgres.MigrationGenerator do defp migration_type(other, constraints) do type = Ash.Type.get_type(other) + Code.ensure_loaded(type) - migration_type_from_storage_type(Ash.Type.storage_type(type, constraints)) + if function_exported?(type, :migration_type, 1) do + type.migration_type(constraints) + else + migration_type_from_storage_type(Ash.Type.storage_type(type, constraints)) + end end defp migration_type_from_storage_type(:string), do: :text diff --git a/lib/type.ex b/lib/type.ex index a437057e..22a3ec07 100644 --- a/lib/type.ex +++ b/lib/type.ex @@ -11,8 +11,11 @@ defmodule AshPostgres.Type do @callback postgres_reference_expr(Ash.Type.t(), Ash.Type.constraints(), term) :: {:ok, term} | :error + @callback migration_type(Ash.Type.constraints()) :: term() + @optional_callbacks value_to_postgres_default: 3, - postgres_reference_expr: 3 + postgres_reference_expr: 3, + migration_type: 1 defmacro __using__(_) do quote do diff --git a/lib/types/timestamptz.ex b/lib/types/timestamptz.ex index dfac2d4f..11b007a3 100644 --- a/lib/types/timestamptz.ex +++ b/lib/types/timestamptz.ex @@ -28,10 +28,6 @@ defmodule AshPostgres.Timestamptz do attribute :timestamp, :timestamptz timestamps type: :timestamptz ``` - - - - """ use Ash.Type.NewType, subtype_of: :datetime, constraints: [precision: :second] diff --git a/lib/types/timestamptz_usec.ex b/lib/types/timestamptz_usec.ex index 513d455d..d723a2dd 100644 --- a/lib/types/timestamptz_usec.ex +++ b/lib/types/timestamptz_usec.ex @@ -21,14 +21,16 @@ defmodule AshPostgres.TimestamptzUsec do timestamps type: :timestamptz_usec ``` - - Please see `AshPostgres.Timestamptz` for details about the usecase for this type. """ use Ash.Type.NewType, subtype_of: :datetime, constraints: [precision: :microsecond] @impl true def storage_type(_constraints) do + :timestamptz + end + + def migration_type(_constraints) do :"timestamptz(6)" end end From 9c6e40426eab9f93a4688fc0b9af4f2d3336e990 Mon Sep 17 00:00:00 2001 From: Zach Daniel Date: Wed, 4 Jun 2025 11:05:13 -0400 Subject: [PATCH 033/174] chore: release version v2.6.2 --- CHANGELOG.md | 9 +++++++++ mix.exs | 2 +- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f627e950..7280df90 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,15 @@ See [Conventional Commits](https://www.conventionalcommits.org) for commit guide +## [v2.6.2](https://github.com/ash-project/ash_postgres/compare/v2.6.1...v2.6.2) (2025-06-04) + + + + +### Bug Fixes: + +* don't use `:"timestamptz(6)"` in ecto storage type + ## [v2.6.1](https://github.com/ash-project/ash_postgres/compare/v2.6.0...v2.6.1) (2025-05-30) diff --git a/mix.exs b/mix.exs index 036bf575..e260f2fd 100644 --- a/mix.exs +++ b/mix.exs @@ -5,7 +5,7 @@ defmodule AshPostgres.MixProject do The PostgreSQL data layer for Ash Framework """ - @version "2.6.1" + @version "2.6.2" def project do [ From 3995ba30cf8eda1faf748785280f4d12dd194cd9 Mon Sep 17 00:00:00 2001 From: Zach Daniel Date: Wed, 4 Jun 2025 13:16:57 -0400 Subject: [PATCH 034/174] fix: undo change for timestamptz usec, retaining precision --- lib/types/timestamptz_usec.ex | 4 ---- 1 file changed, 4 deletions(-) diff --git a/lib/types/timestamptz_usec.ex b/lib/types/timestamptz_usec.ex index d723a2dd..f1dae8fd 100644 --- a/lib/types/timestamptz_usec.ex +++ b/lib/types/timestamptz_usec.ex @@ -27,10 +27,6 @@ defmodule AshPostgres.TimestamptzUsec do @impl true def storage_type(_constraints) do - :timestamptz - end - - def migration_type(_constraints) do :"timestamptz(6)" end end From 1492fc5596b0e6aaf019294f835db72141633dad Mon Sep 17 00:00:00 2001 From: Zach Daniel Date: Wed, 4 Jun 2025 13:39:41 -0400 Subject: [PATCH 035/174] chore: stabilize migration tests --- test/dev_migrations_test.exs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/test/dev_migrations_test.exs b/test/dev_migrations_test.exs index 0f7b93c0..400bca14 100644 --- a/test/dev_migrations_test.exs +++ b/test/dev_migrations_test.exs @@ -94,7 +94,7 @@ defmodule AshPostgres.DevMigrationsTest do do: File.ls!(tenant_migrations_dev_path), else: [] - on_exit(fn -> + clean = fn -> if File.exists?(resource_dev_path) do current_resource_files = File.ls!(resource_dev_path) new_resource_files = current_resource_files -- initial_resource_files @@ -120,7 +120,11 @@ defmodule AshPostgres.DevMigrationsTest do end AshPostgres.DevTestRepo.query!("DROP TABLE IF EXISTS posts") - end) + end + + clean.() + + on_exit(clean) end describe "--dev option" do From 6238948e5cfbe54bdc47b13959c10d7a30765eb7 Mon Sep 17 00:00:00 2001 From: Zach Daniel Date: Wed, 4 Jun 2025 13:40:16 -0400 Subject: [PATCH 036/174] chore: release version v2.6.3 --- CHANGELOG.md | 9 +++++++++ mix.exs | 2 +- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7280df90..b5f5faed 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,15 @@ See [Conventional Commits](https://www.conventionalcommits.org) for commit guide +## [v2.6.3](https://github.com/ash-project/ash_postgres/compare/v2.6.2...v2.6.3) (2025-06-04) + + + + +### Bug Fixes: + +* undo change for timestamptz usec, retaining precision + ## [v2.6.2](https://github.com/ash-project/ash_postgres/compare/v2.6.1...v2.6.2) (2025-06-04) diff --git a/mix.exs b/mix.exs index e260f2fd..e13172bb 100644 --- a/mix.exs +++ b/mix.exs @@ -5,7 +5,7 @@ defmodule AshPostgres.MixProject do The PostgreSQL data layer for Ash Framework """ - @version "2.6.2" + @version "2.6.3" def project do [ From 2b5011369595a5a64d85bd99d7de7209fd0aa0fe Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 5 Jun 2025 08:01:53 -0400 Subject: [PATCH 037/174] chore(deps): bump the production-dependencies group with 3 updates (#562) Bumps the production-dependencies group with 3 updates: [ash](https://github.com/ash-project/ash), [ash_sql](https://github.com/ash-project/ash_sql) and [igniter](https://github.com/ash-project/igniter). Updates `ash` from 3.5.13 to 3.5.15 - [Changelog](https://github.com/ash-project/ash/blob/main/CHANGELOG.md) - [Commits](https://github.com/ash-project/ash/compare/v3.5.13...v3.5.15) Updates `ash_sql` from 0.2.76 to 0.2.77 - [Changelog](https://github.com/ash-project/ash_sql/blob/main/CHANGELOG.md) - [Commits](https://github.com/ash-project/ash_sql/compare/v0.2.76...v0.2.77) Updates `igniter` from 0.6.4 to 0.6.5 - [Changelog](https://github.com/ash-project/igniter/blob/main/CHANGELOG.md) - [Commits](https://github.com/ash-project/igniter/compare/v0.6.4...v0.6.5) --- updated-dependencies: - dependency-name: ash dependency-version: 3.5.15 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: production-dependencies - dependency-name: ash_sql dependency-version: 0.2.77 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: production-dependencies - dependency-name: igniter dependency-version: 0.6.5 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: production-dependencies ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- mix.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/mix.lock b/mix.lock index 1f3910ec..751ea5f0 100644 --- a/mix.lock +++ b/mix.lock @@ -1,6 +1,6 @@ %{ - "ash": {:hex, :ash, "3.5.13", "1e2d15188dcf01a00f7c91180f6a0fb990c427828fdf9f014b8a6dde951f46a0", [:mix], [{:decimal, "~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:ecto, "~> 3.7", [hex: :ecto, repo: "hexpm", optional: false]}, {:ets, "~> 0.8", [hex: :ets, repo: "hexpm", optional: false]}, {:igniter, "~> 0.6", [hex: :igniter, repo: "hexpm", optional: true]}, {:jason, ">= 1.0.0", [hex: :jason, repo: "hexpm", optional: false]}, {:owl, "~> 0.11", [hex: :owl, repo: "hexpm", optional: false]}, {:picosat_elixir, "~> 0.2", [hex: :picosat_elixir, repo: "hexpm", optional: true]}, {:plug, ">= 0.0.0", [hex: :plug, repo: "hexpm", optional: true]}, {:reactor, "~> 0.11", [hex: :reactor, repo: "hexpm", optional: false]}, {:simple_sat, ">= 0.1.1 and < 1.0.0-0", [hex: :simple_sat, repo: "hexpm", optional: true]}, {:spark, ">= 2.2.61 and < 3.0.0-0", [hex: :spark, repo: "hexpm", optional: false]}, {:splode, ">= 0.2.6 and < 1.0.0-0", [hex: :splode, repo: "hexpm", optional: false]}, {:stream_data, "~> 1.0", [hex: :stream_data, repo: "hexpm", optional: false]}, {:telemetry, "~> 1.1", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "bdd52d10f95af357f37b61b74636226bf7c1082c4b815df94443d2aa2607c961"}, - "ash_sql": {:hex, :ash_sql, "0.2.76", "4afac3284194f3d7820b7edc1263ac1eb232a25734406ad7b2284683b9384205", [:mix], [{:ash, "~> 3.5", [hex: :ash, repo: "hexpm", optional: false]}, {:ecto, "~> 3.9", [hex: :ecto, repo: "hexpm", optional: false]}, {:ecto_sql, "~> 3.9", [hex: :ecto_sql, repo: "hexpm", optional: false]}], "hexpm", "f6bc02d8c4cba3f8f9a532e6ff73eaf8a4f7685257646a58fe7a320cfaf10c39"}, + "ash": {:hex, :ash, "3.5.15", "418055e74c4d85d1f397577407aa71c29d44ef0b729be144e23e64630ad2eedc", [:mix], [{:decimal, "~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:ecto, "~> 3.7", [hex: :ecto, repo: "hexpm", optional: false]}, {:ets, "~> 0.8", [hex: :ets, repo: "hexpm", optional: false]}, {:igniter, ">= 0.6.4 and < 1.0.0-0", [hex: :igniter, repo: "hexpm", optional: true]}, {:jason, ">= 1.0.0", [hex: :jason, repo: "hexpm", optional: false]}, {:picosat_elixir, "~> 0.2", [hex: :picosat_elixir, repo: "hexpm", optional: true]}, {:plug, ">= 0.0.0", [hex: :plug, repo: "hexpm", optional: true]}, {:reactor, "~> 0.11", [hex: :reactor, repo: "hexpm", optional: false]}, {:simple_sat, ">= 0.1.1 and < 1.0.0-0", [hex: :simple_sat, repo: "hexpm", optional: true]}, {:spark, ">= 2.2.61 and < 3.0.0-0", [hex: :spark, repo: "hexpm", optional: false]}, {:splode, ">= 0.2.6 and < 1.0.0-0", [hex: :splode, repo: "hexpm", optional: false]}, {:stream_data, "~> 1.0", [hex: :stream_data, repo: "hexpm", optional: false]}, {:telemetry, "~> 1.1", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "8ee885ccc6be65d1023cccbdfda6a534497cf5170d53b67c0b29db72c0c30b9b"}, + "ash_sql": {:hex, :ash_sql, "0.2.77", "731c87a624ffe2bed61de8fed4d11aacc5057ceedbe1df076979e9b6bc3fd499", [:mix], [{:ash, "~> 3.5", [hex: :ash, repo: "hexpm", optional: false]}, {:ecto, "~> 3.9", [hex: :ecto, repo: "hexpm", optional: false]}, {:ecto_sql, "~> 3.9", [hex: :ecto_sql, repo: "hexpm", optional: false]}], "hexpm", "a94f9be7e6583f193dbb1705192c3ddee6a49ff5a870ddeb6cd3a9a947add0db"}, "benchee": {:hex, :benchee, "1.4.0", "9f1f96a30ac80bab94faad644b39a9031d5632e517416a8ab0a6b0ac4df124ce", [:mix], [{:deep_merge, "~> 1.0", [hex: :deep_merge, repo: "hexpm", optional: false]}, {:statistex, "~> 1.0", [hex: :statistex, repo: "hexpm", optional: false]}, {:table, "~> 0.1.0", [hex: :table, repo: "hexpm", optional: true]}], "hexpm", "299cd10dd8ce51c9ea3ddb74bb150f93d25e968f93e4c1fa31698a8e4fa5d715"}, "bunt": {:hex, :bunt, "1.0.0", "081c2c665f086849e6d57900292b3a161727ab40431219529f13c4ddcf3e7a44", [:mix], [], "hexpm", "dc5f86aa08a5f6fa6b8096f0735c4e76d54ae5c9fa2c143e5a1fc7c1cd9bb6b5"}, "credo": {:hex, :credo, "1.7.12", "9e3c20463de4b5f3f23721527fcaf16722ec815e70ff6c60b86412c695d426c1", [:mix], [{:bunt, "~> 0.2.1 or ~> 1.0", [hex: :bunt, repo: "hexpm", optional: false]}, {:file_system, "~> 0.2 or ~> 1.0", [hex: :file_system, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "8493d45c656c5427d9c729235b99d498bd133421f3e0a683e5c1b561471291e5"}, @@ -23,7 +23,7 @@ "git_ops": {:hex, :git_ops, "2.7.3", "c993aedb11005752e321d482de6f2a46d0b5d5f09ce69961f31a856e76bf4f12", [:mix], [{:git_cli, "~> 0.2", [hex: :git_cli, repo: "hexpm", optional: false]}, {:igniter, ">= 0.5.27 and < 1.0.0-0", [hex: :igniter, repo: "hexpm", optional: true]}, {:nimble_parsec, "~> 1.0", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "c54ee65e12778be1f4dd6a0921e57ab2bddd35bd6130cbe274dcb1f0a21ca59d"}, "glob_ex": {:hex, :glob_ex, "0.1.11", "cb50d3f1ef53f6ca04d6252c7fde09fd7a1cf63387714fe96f340a1349e62c93", [:mix], [], "hexpm", "342729363056e3145e61766b416769984c329e4378f1d558b63e341020525de4"}, "hpax": {:hex, :hpax, "1.0.3", "ed67ef51ad4df91e75cc6a1494f851850c0bd98ebc0be6e81b026e765ee535aa", [:mix], [], "hexpm", "8eab6e1cfa8d5918c2ce4ba43588e894af35dbd8e91e6e55c817bca5847df34a"}, - "igniter": {:hex, :igniter, "0.6.4", "81b7442be9ae0b9107b715144f3633f72788644d13ffded612cb508861b2c726", [:mix], [{:glob_ex, "~> 0.1.7", [hex: :glob_ex, repo: "hexpm", optional: false]}, {:jason, "~> 1.4", [hex: :jason, repo: "hexpm", optional: false]}, {:owl, "~> 0.11", [hex: :owl, repo: "hexpm", optional: false]}, {:phx_new, "~> 1.7", [hex: :phx_new, repo: "hexpm", optional: true]}, {:req, "~> 0.5", [hex: :req, repo: "hexpm", optional: false]}, {:rewrite, ">= 1.1.1 and < 2.0.0-0", [hex: :rewrite, repo: "hexpm", optional: false]}, {:sourceror, "~> 1.4", [hex: :sourceror, repo: "hexpm", optional: false]}, {:spitfire, ">= 0.1.3 and < 1.0.0-0", [hex: :spitfire, repo: "hexpm", optional: false]}], "hexpm", "e999fc4b883e5eacc07ca2823273880ab30108c7e6a0d1542a3c8e00605aef46"}, + "igniter": {:hex, :igniter, "0.6.5", "0b16a37e1aaaefc39777c6250980a314df8ba02a8ae81063d786a7bddb40dbf0", [:mix], [{:glob_ex, "~> 0.1.7", [hex: :glob_ex, repo: "hexpm", optional: false]}, {:jason, "~> 1.4", [hex: :jason, repo: "hexpm", optional: false]}, {:owl, "~> 0.11", [hex: :owl, repo: "hexpm", optional: false]}, {:phx_new, "~> 1.7", [hex: :phx_new, repo: "hexpm", optional: true]}, {:req, "~> 0.5", [hex: :req, repo: "hexpm", optional: false]}, {:rewrite, ">= 1.1.1 and < 2.0.0-0", [hex: :rewrite, repo: "hexpm", optional: false]}, {:sourceror, "~> 1.4", [hex: :sourceror, repo: "hexpm", optional: false]}, {:spitfire, ">= 0.1.3 and < 1.0.0-0", [hex: :spitfire, repo: "hexpm", optional: false]}], "hexpm", "21dec3066f372f49f391d00a2067769eb20f7a2213513e022593e4b51bad93e2"}, "iterex": {:hex, :iterex, "0.1.2", "58f9b9b9a22a55cbfc7b5234a9c9c63eaac26d276b3db80936c0e1c60355a5a6", [:mix], [], "hexpm", "2e103b8bcc81757a9af121f6dc0df312c9a17220f302b1193ef720460d03029d"}, "jason": {:hex, :jason, "1.4.4", "b9226785a9aa77b6857ca22832cffa5d5011a667207eb2a0ad56adb5db443b8a", [:mix], [{:decimal, "~> 1.0 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm", "c5eb0cab91f094599f94d55bc63409236a8ec69a21a67814529e8d5f6cc90b3b"}, "libgraph": {:hex, :libgraph, "0.16.0", "3936f3eca6ef826e08880230f806bfea13193e49bf153f93edcf0239d4fd1d07", [:mix], [], "hexpm", "41ca92240e8a4138c30a7e06466acc709b0cbb795c643e9e17174a178982d6bf"}, @@ -45,7 +45,7 @@ "sobelow": {:hex, :sobelow, "0.14.0", "dd82aae8f72503f924fe9dd97ffe4ca694d2f17ec463dcfd365987c9752af6ee", [:mix], [{:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "7ecf91e298acfd9b24f5d761f19e8f6e6ac585b9387fb6301023f1f2cd5eed5f"}, "sourceror": {:hex, :sourceror, "1.10.0", "38397dedbbc286966ec48c7af13e228b171332be1ad731974438c77791945ce9", [:mix], [], "hexpm", "29dbdfc92e04569c9d8e6efdc422fc1d815f4bd0055dc7c51b8800fb75c4b3f1"}, "spark": {:hex, :spark, "2.2.62", "610502559834465edce437de712bf7e6d59713ad48050789dbef69a798e71a3c", [:mix], [{:igniter, ">= 0.3.64 and < 1.0.0-0", [hex: :igniter, repo: "hexpm", optional: true]}, {:jason, "~> 1.4", [hex: :jason, repo: "hexpm", optional: true]}, {:sourceror, "~> 1.2", [hex: :sourceror, repo: "hexpm", optional: true]}], "hexpm", "726df72e1b9c17401584b4657e75e08a27a1cf6a6effa2486bf1c074da6176a7"}, - "spitfire": {:hex, :spitfire, "0.2.0", "0de1f519a23f65bde40d316adad53c07a9563f25cc68915d639d8a509a0aad8a", [:mix], [], "hexpm", "743daaee2d81a0d8095431729f478ce49b47ea8943c7d770de86704975cb7775"}, + "spitfire": {:hex, :spitfire, "0.2.1", "29e154873f05444669c7453d3d931820822cbca5170e88f0f8faa1de74a79b47", [:mix], [], "hexpm", "6eeed75054a38341b2e1814d41bb0a250564092358de2669fdb57ff88141d91b"}, "splode": {:hex, :splode, "0.2.9", "3a2776e187c82f42f5226b33b1220ccbff74f4bcc523dd4039c804caaa3ffdc7", [:mix], [], "hexpm", "8002b00c6e24f8bd1bcced3fbaa5c33346048047bb7e13d2f3ad428babbd95c3"}, "statistex": {:hex, :statistex, "1.0.0", "f3dc93f3c0c6c92e5f291704cf62b99b553253d7969e9a5fa713e5481cd858a5", [:mix], [], "hexpm", "ff9d8bee7035028ab4742ff52fc80a2aa35cece833cf5319009b52f1b5a86c27"}, "stream_data": {:hex, :stream_data, "1.2.0", "58dd3f9e88afe27dc38bef26fce0c84a9e7a96772b2925c7b32cd2435697a52b", [:mix], [], "hexpm", "eb5c546ee3466920314643edf68943a5b14b32d1da9fe01698dc92b73f89a9ed"}, From 7c8b89a6eeb28ddd69535b553b91b0a143a6ed81 Mon Sep 17 00:00:00 2001 From: Zach Daniel Date: Thu, 5 Jun 2025 13:38:51 -0400 Subject: [PATCH 038/174] chore: add test --- test/calculation_test.exs | 16 +++++++++++++++- test/support/resources/record.ex | 14 +++++++++++--- 2 files changed, 26 insertions(+), 4 deletions(-) diff --git a/test/calculation_test.exs b/test/calculation_test.exs index 017ca25a..a8c1703f 100644 --- a/test/calculation_test.exs +++ b/test/calculation_test.exs @@ -1,6 +1,6 @@ defmodule AshPostgres.CalculationTest do use AshPostgres.RepoCase, async: false - alias AshPostgres.Test.{Account, Author, Comedian, Comment, Post, User} + alias AshPostgres.Test.{Account, Author, Comedian, Comment, Post, Record, TempEntity, User} require Ash.Query import Ash.Expr @@ -1016,4 +1016,18 @@ defmodule AshPostgres.CalculationTest do def fred do "fred" end + + test "calculation references use the appropriate schema" do + record = Record |> Ash.Changeset.for_create(:create, %{full_name: "name"}) |> Ash.create!() + + TempEntity |> Ash.Changeset.for_create(:create, %{full_name: "name"}) |> Ash.create!() + + full_name = + Record + |> Ash.Query.load(:temp_entity_full_name) + |> Ash.read_first!() + |> Map.get(:temp_entity_full_name) + + assert full_name == "name" + end end diff --git a/test/support/resources/record.ex b/test/support/resources/record.ex index b98ef59e..db820fca 100644 --- a/test/support/resources/record.ex +++ b/test/support/resources/record.ex @@ -14,9 +14,7 @@ defmodule AshPostgres.Test.Record do end relationships do - alias AshPostgres.Test.Entity - - has_one :entity, Entity do + has_one :entity, AshPostgres.Test.Entity do public?(true) no_attributes?(true) @@ -24,6 +22,12 @@ defmodule AshPostgres.Test.Record do filter(expr(full_name == parent(full_name))) end + + has_one :temp_entity, AshPostgres.Test.TempEntity do + public?(true) + source_attribute(:full_name) + destination_attribute(:full_name) + end end postgres do @@ -31,6 +35,10 @@ defmodule AshPostgres.Test.Record do repo AshPostgres.TestRepo end + calculations do + calculate(:temp_entity_full_name, :string, expr(temp_entity.full_name)) + end + actions do default_accept(:*) From 5e21f8946ed7fa01c4e541fedf52fc0dd6120720 Mon Sep 17 00:00:00 2001 From: Zach Daniel Date: Thu, 5 Jun 2025 14:51:58 -0400 Subject: [PATCH 039/174] test: add test for ash_sql datetime time zone issues --- test/calculation_test.exs | 2 +- test/complex_calculations_test.exs | 27 +++++++++++++++++++ .../resources/documentation.ex | 11 ++++++++ 3 files changed, 39 insertions(+), 1 deletion(-) diff --git a/test/calculation_test.exs b/test/calculation_test.exs index a8c1703f..4b6fff35 100644 --- a/test/calculation_test.exs +++ b/test/calculation_test.exs @@ -1018,7 +1018,7 @@ defmodule AshPostgres.CalculationTest do end test "calculation references use the appropriate schema" do - record = Record |> Ash.Changeset.for_create(:create, %{full_name: "name"}) |> Ash.create!() + Record |> Ash.Changeset.for_create(:create, %{full_name: "name"}) |> Ash.create!() TempEntity |> Ash.Changeset.for_create(:create, %{full_name: "name"}) |> Ash.create!() diff --git a/test/complex_calculations_test.exs b/test/complex_calculations_test.exs index 73fd689d..83cb39cf 100644 --- a/test/complex_calculations_test.exs +++ b/test/complex_calculations_test.exs @@ -346,4 +346,31 @@ defmodule AshPostgres.Test.ComplexCalculationsTest do |> Ash.Query.for_read(:failing_many_reference) |> Ash.read!(page: [count: true]) end + + test "lazy datetime with timezone is respected in calculations" do + documentation_before = + AshPostgres.Test.ComplexCalculations.Documentation + |> Ash.Changeset.for_create(:create, %{ + status: :demonstrated, + # 2 hours before Seoul time in UTC + inserted_at: ~U[2024-05-01 10:00:00Z] + }) + |> Ash.create!() + + documentation_after = + AshPostgres.Test.ComplexCalculations.Documentation + |> Ash.Changeset.for_create(:create, %{ + status: :demonstrated, + # 2 hours after Seoul time in UTC + inserted_at: ~U[2024-05-01 14:00:00Z] + }) + |> Ash.create!() + + [doc_before, doc_after] = + [documentation_before, documentation_after] + |> Ash.load!([:is_active_with_timezone]) + + assert doc_before.is_active_with_timezone == false + assert doc_after.is_active_with_timezone == true + end end diff --git a/test/support/complex_calculations/resources/documentation.ex b/test/support/complex_calculations/resources/documentation.ex index ad961895..df6c5415 100644 --- a/test/support/complex_calculations/resources/documentation.ex +++ b/test/support/complex_calculations/resources/documentation.ex @@ -42,6 +42,10 @@ defmodule AshPostgres.Test.ComplexCalculations.Documentation do end ) ) + + calculate :is_active_with_timezone, :boolean do + calculation(expr(inserted_at > lazy({AshPostgres.Test.TimezoneHelper, :seoul_time, []}))) + end end postgres do @@ -55,3 +59,10 @@ defmodule AshPostgres.Test.ComplexCalculations.Documentation do end end end + +defmodule AshPostgres.Test.TimezoneHelper do + def seoul_time do + # Fixed datetime for testing - equivalent to 2024-05-01 21:00:00 in Seoul (UTC+9) + ~U[2024-05-01 12:00:00Z] |> DateTime.shift_zone!("Asia/Seoul") + end +end From 5b8f46ffb52378a818dee7278d9ab9702dc12121 Mon Sep 17 00:00:00 2001 From: kernel-io Date: Fri, 6 Jun 2025 12:39:56 +1200 Subject: [PATCH 040/174] test: failing test for calculations in different schema (#563) * failing test for calculations in different schema Signed-off-by: kernel-io * fix test to not require grouping Signed-off-by: kernel-io --------- Signed-off-by: kernel-io --- .../records_temp_entities/20250605230457.json | 93 +++++++++++++++++++ ...0457_create_record_temp_entities_table.exs | 43 +++++++++ test/calculation_test.exs | 8 +- test/support/domain.ex | 1 + test/support/resources/record.ex | 12 ++- test/support/resources/record_temp_entity.ex | 25 +++++ 6 files changed, 179 insertions(+), 3 deletions(-) create mode 100644 priv/resource_snapshots/test_repo/records_temp_entities/20250605230457.json create mode 100644 priv/test_repo/migrations/20250605230457_create_record_temp_entities_table.exs create mode 100644 test/support/resources/record_temp_entity.ex diff --git a/priv/resource_snapshots/test_repo/records_temp_entities/20250605230457.json b/priv/resource_snapshots/test_repo/records_temp_entities/20250605230457.json new file mode 100644 index 00000000..af6e3c23 --- /dev/null +++ b/priv/resource_snapshots/test_repo/records_temp_entities/20250605230457.json @@ -0,0 +1,93 @@ +{ + "attributes": [ + { + "allow_nil?": false, + "default": "fragment(\"gen_random_uuid()\")", + "generated?": false, + "precision": null, + "primary_key?": true, + "references": null, + "scale": null, + "size": null, + "source": "id", + "type": "uuid" + }, + { + "allow_nil?": true, + "default": "nil", + "generated?": false, + "precision": null, + "primary_key?": false, + "references": { + "deferrable": false, + "destination_attribute": "id", + "destination_attribute_default": null, + "destination_attribute_generated": null, + "index?": false, + "match_type": null, + "match_with": null, + "multitenancy": { + "attribute": null, + "global": null, + "strategy": null + }, + "name": "records_temp_entities_record_id_fkey", + "on_delete": null, + "on_update": null, + "primary_key?": true, + "schema": "public", + "table": "records" + }, + "scale": null, + "size": null, + "source": "record_id", + "type": "uuid" + }, + { + "allow_nil?": true, + "default": "nil", + "generated?": false, + "precision": null, + "primary_key?": false, + "references": { + "deferrable": false, + "destination_attribute": "id", + "destination_attribute_default": null, + "destination_attribute_generated": null, + "index?": false, + "match_type": null, + "match_with": null, + "multitenancy": { + "attribute": null, + "global": null, + "strategy": null + }, + "name": "records_temp_entities_temp_entity_id_fkey", + "on_delete": null, + "on_update": null, + "primary_key?": true, + "schema": "temp", + "table": "temp_entities" + }, + "scale": null, + "size": null, + "source": "temp_entity_id", + "type": "uuid" + } + ], + "base_filter": null, + "check_constraints": [], + "custom_indexes": [], + "custom_statements": [], + "has_create_action": true, + "hash": "1F00231E86F4E276096E683FD2836B40F36C6AD617A777D947E908FD52D09FDB", + "identities": [], + "multitenancy": { + "attribute": null, + "global": null, + "strategy": null + }, + "repo": "Elixir.AshPostgres.TestRepo", + "schema": null, + "table": "records_temp_entities" +} \ No newline at end of file diff --git a/priv/test_repo/migrations/20250605230457_create_record_temp_entities_table.exs b/priv/test_repo/migrations/20250605230457_create_record_temp_entities_table.exs new file mode 100644 index 00000000..fe910c8c --- /dev/null +++ b/priv/test_repo/migrations/20250605230457_create_record_temp_entities_table.exs @@ -0,0 +1,43 @@ +defmodule AshPostgres.TestRepo.Migrations.CreateRecordTempEntitiesTable do + @moduledoc """ + Updates resources based on their most recent snapshots. + + This file was autogenerated with `mix ash_postgres.generate_migrations` + """ + + use Ecto.Migration + + def up do + create table(:records_temp_entities, primary_key: false) do + add(:id, :uuid, null: false, default: fragment("gen_random_uuid()"), primary_key: true) + + add( + :record_id, + references(:records, + column: :id, + name: "records_temp_entities_record_id_fkey", + type: :uuid, + prefix: "public" + ) + ) + + add( + :temp_entity_id, + references(:temp_entities, + column: :id, + name: "records_temp_entities_temp_entity_id_fkey", + type: :uuid, + prefix: "temp" + ) + ) + end + end + + def down do + drop(constraint(:records_temp_entities, "records_temp_entities_record_id_fkey")) + + drop(constraint(:records_temp_entities, "records_temp_entities_temp_entity_id_fkey")) + + drop(table(:records_temp_entities)) + end +end diff --git a/test/calculation_test.exs b/test/calculation_test.exs index 4b6fff35..6aa911fe 100644 --- a/test/calculation_test.exs +++ b/test/calculation_test.exs @@ -1,4 +1,5 @@ defmodule AshPostgres.CalculationTest do + alias AshPostgres.Test.RecordTempEntity use AshPostgres.RepoCase, async: false alias AshPostgres.Test.{Account, Author, Comedian, Comment, Post, Record, TempEntity, User} @@ -1018,9 +1019,12 @@ defmodule AshPostgres.CalculationTest do end test "calculation references use the appropriate schema" do - Record |> Ash.Changeset.for_create(:create, %{full_name: "name"}) |> Ash.create!() + record = Record |> Ash.Changeset.for_create(:create, %{full_name: "name"}) |> Ash.create!() - TempEntity |> Ash.Changeset.for_create(:create, %{full_name: "name"}) |> Ash.create!() + temp_entity = + TempEntity |> Ash.Changeset.for_create(:create, %{full_name: "name"}) |> Ash.create!() + + Ash.Seed.seed!(RecordTempEntity, %{record_id: record.id, temp_entity_id: temp_entity.id}) full_name = Record diff --git a/test/support/domain.ex b/test/support/domain.ex index 25616374..c8c596d5 100644 --- a/test/support/domain.ex +++ b/test/support/domain.ex @@ -31,6 +31,7 @@ defmodule AshPostgres.Test.Domain do resource(AshPostgres.Test.Entity) resource(AshPostgres.Test.ContentVisibilityGroup) resource(AshPostgres.Test.TempEntity) + resource(AshPostgres.Test.RecordTempEntity) resource(AshPostgres.Test.Permalink) resource(AshPostgres.Test.Record) resource(AshPostgres.Test.PostFollower) diff --git a/test/support/resources/record.ex b/test/support/resources/record.ex index db820fca..804c981a 100644 --- a/test/support/resources/record.ex +++ b/test/support/resources/record.ex @@ -28,6 +28,12 @@ defmodule AshPostgres.Test.Record do source_attribute(:full_name) destination_attribute(:full_name) end + + many_to_many :temp_entities, AshPostgres.Test.TempEntity do + public?(true) + + through(AshPostgres.Test.RecordTempEntity) + end end postgres do @@ -36,7 +42,11 @@ defmodule AshPostgres.Test.Record do end calculations do - calculate(:temp_entity_full_name, :string, expr(temp_entity.full_name)) + calculate( + :temp_entity_full_name, + :string, + expr(fragment("coalesce(?, '')", temp_entities.full_name)) + ) end actions do diff --git a/test/support/resources/record_temp_entity.ex b/test/support/resources/record_temp_entity.ex new file mode 100644 index 00000000..7750a1df --- /dev/null +++ b/test/support/resources/record_temp_entity.ex @@ -0,0 +1,25 @@ +defmodule AshPostgres.Test.RecordTempEntity do + @moduledoc false + + use Ash.Resource, + domain: AshPostgres.Test.Domain, + data_layer: AshPostgres.DataLayer + + postgres do + table "records_temp_entities" + repo AshPostgres.TestRepo + end + + attributes do + uuid_primary_key(:id) + end + + relationships do + belongs_to(:record, AshPostgres.Test.Record, public?: true) + belongs_to(:temp_entity, AshPostgres.Test.TempEntity, public?: true) + end + + actions do + defaults([:read, :destroy, create: :*, update: :*]) + end +end From db011c06900cd24f320dfe5b938a685730497eb0 Mon Sep 17 00:00:00 2001 From: Zach Daniel Date: Sat, 7 Jun 2025 15:05:26 -0400 Subject: [PATCH 041/174] fix: use better wrappers around string/ci_string --- lib/types/ci_string_wrapper.ex | 9 +-------- lib/types/string_wrapper.ex | 9 +-------- 2 files changed, 2 insertions(+), 16 deletions(-) diff --git a/lib/types/ci_string_wrapper.ex b/lib/types/ci_string_wrapper.ex index 20a9b12e..74e47347 100644 --- a/lib/types/ci_string_wrapper.ex +++ b/lib/types/ci_string_wrapper.ex @@ -1,14 +1,7 @@ defmodule AshPostgres.Type.CiStringWrapper do @moduledoc false - use Ash.Type + use Ash.Type.NewType, subtype_of: :ci_string, constraints: [allow_empty?: true, trim?: false] @impl true def storage_type(_), do: :citext - - @impl true - defdelegate cast_input(value, constraints), to: Ash.Type.CiString - @impl true - defdelegate cast_stored(value, constraints), to: Ash.Type.CiString - @impl true - defdelegate dump_to_native(value, constraints), to: Ash.Type.CiString end diff --git a/lib/types/string_wrapper.ex b/lib/types/string_wrapper.ex index e6101c52..84b5cd2c 100644 --- a/lib/types/string_wrapper.ex +++ b/lib/types/string_wrapper.ex @@ -1,14 +1,7 @@ defmodule AshPostgres.Type.StringWrapper do @moduledoc false - use Ash.Type + use Ash.Type.NewType, subtype_of: :string, constraints: [allow_empty?: true, trim?: false] @impl true def storage_type(_), do: :text - - @impl true - defdelegate cast_input(value, constraints), to: Ash.Type.String - @impl true - defdelegate cast_stored(value, constraints), to: Ash.Type.String - @impl true - defdelegate dump_to_native(value, constraints), to: Ash.Type.String end From 12579ad3e79418a996dbddf7462b4e3d4e67e158 Mon Sep 17 00:00:00 2001 From: Zach Daniel Date: Sun, 8 Jun 2025 01:02:44 -0400 Subject: [PATCH 042/174] chore: remove deprecated syntax --- lib/sql_implementation.ex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/sql_implementation.ex b/lib/sql_implementation.ex index 6648a7e4..a91b8786 100644 --- a/lib/sql_implementation.ex +++ b/lib/sql_implementation.ex @@ -188,7 +188,7 @@ defmodule AshPostgres.SqlImplementation do type ) do if function_exported?(attr_type, :postgres_reference_expr, 3) do - non_bare_ref = %Ash.Query.Ref{ref | bare?: nil} + non_bare_ref = %{ref | bare?: nil} {expr, acc} = AshSql.Expr.dynamic_expr(query, non_bare_ref, bindings, embedded?, type, acc) case attr_type.postgres_reference_expr(attr_type, constraints, expr) do From 5c15c7e70e15f34f8fa81816ba2711519cb335c2 Mon Sep 17 00:00:00 2001 From: "Stephan Hug (FlyingNoodle)" <88476449+StephanH90@users.noreply.github.com> Date: Sun, 8 Jun 2025 07:04:06 +0200 Subject: [PATCH 043/174] fix: casting integers to string in expressions works as intended (#564) This commit currently only adds a failing test. --- test/support/resources/post.ex | 6 ++++++ test/type_test.exs | 7 +++++++ 2 files changed, 13 insertions(+) diff --git a/test/support/resources/post.ex b/test/support/resources/post.ex index 4b893048..369283bc 100644 --- a/test/support/resources/post.ex +++ b/test/support/resources/post.ex @@ -154,6 +154,12 @@ defmodule AshPostgres.Test.Post do defaults([:read, :destroy]) + read :with_version_check do + argument(:version, :integer) + + filter(expr(type(^arg(:version), :string) in ["1", "2"])) + end + read :first_and_last_post do prepare(fn query, _ -> Ash.Query.combination_of(query, [ diff --git a/test/type_test.exs b/test/type_test.exs index 428fcab1..4c3731e7 100644 --- a/test/type_test.exs +++ b/test/type_test.exs @@ -100,4 +100,11 @@ defmodule AshPostgres.Test.TypeTest do assert %{x: 2.0, y: 3.0, z: 4.0} = p.db_string_point_id assert %{x: 2.0, y: 3.0, z: 4.0} = p.db_string_point.id end + + test "casting integer to string works" do + Post |> Ash.Changeset.for_create(:create) |> Ash.create!() + + post = Ash.Query.for_read(Post, :with_version_check, version: 1) |> Ash.read!() + refute is_nil(post) + end end From cf3da36618ca27c069386bb35b61d4337752a433 Mon Sep 17 00:00:00 2001 From: Zach Daniel Date: Sun, 8 Jun 2025 01:08:28 -0400 Subject: [PATCH 044/174] chore: update deps --- mix.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/mix.lock b/mix.lock index 751ea5f0..0fd35a2e 100644 --- a/mix.lock +++ b/mix.lock @@ -1,6 +1,6 @@ %{ "ash": {:hex, :ash, "3.5.15", "418055e74c4d85d1f397577407aa71c29d44ef0b729be144e23e64630ad2eedc", [:mix], [{:decimal, "~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:ecto, "~> 3.7", [hex: :ecto, repo: "hexpm", optional: false]}, {:ets, "~> 0.8", [hex: :ets, repo: "hexpm", optional: false]}, {:igniter, ">= 0.6.4 and < 1.0.0-0", [hex: :igniter, repo: "hexpm", optional: true]}, {:jason, ">= 1.0.0", [hex: :jason, repo: "hexpm", optional: false]}, {:picosat_elixir, "~> 0.2", [hex: :picosat_elixir, repo: "hexpm", optional: true]}, {:plug, ">= 0.0.0", [hex: :plug, repo: "hexpm", optional: true]}, {:reactor, "~> 0.11", [hex: :reactor, repo: "hexpm", optional: false]}, {:simple_sat, ">= 0.1.1 and < 1.0.0-0", [hex: :simple_sat, repo: "hexpm", optional: true]}, {:spark, ">= 2.2.61 and < 3.0.0-0", [hex: :spark, repo: "hexpm", optional: false]}, {:splode, ">= 0.2.6 and < 1.0.0-0", [hex: :splode, repo: "hexpm", optional: false]}, {:stream_data, "~> 1.0", [hex: :stream_data, repo: "hexpm", optional: false]}, {:telemetry, "~> 1.1", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "8ee885ccc6be65d1023cccbdfda6a534497cf5170d53b67c0b29db72c0c30b9b"}, - "ash_sql": {:hex, :ash_sql, "0.2.77", "731c87a624ffe2bed61de8fed4d11aacc5057ceedbe1df076979e9b6bc3fd499", [:mix], [{:ash, "~> 3.5", [hex: :ash, repo: "hexpm", optional: false]}, {:ecto, "~> 3.9", [hex: :ecto, repo: "hexpm", optional: false]}, {:ecto_sql, "~> 3.9", [hex: :ecto_sql, repo: "hexpm", optional: false]}], "hexpm", "a94f9be7e6583f193dbb1705192c3ddee6a49ff5a870ddeb6cd3a9a947add0db"}, + "ash_sql": {:hex, :ash_sql, "0.2.78", "130d54ca85b8fbd1e65f038beafb905ade1941d1f5e3aef1fec7f8bba7414fc2", [:mix], [{:ash, "~> 3.5", [hex: :ash, repo: "hexpm", optional: false]}, {:ecto, "~> 3.9", [hex: :ecto, repo: "hexpm", optional: false]}, {:ecto_sql, "~> 3.9", [hex: :ecto_sql, repo: "hexpm", optional: false]}], "hexpm", "a640ec0ef176f3a0e95f88d8639d9d23479ca8a5f5e7e177af351f18cddf4f30"}, "benchee": {:hex, :benchee, "1.4.0", "9f1f96a30ac80bab94faad644b39a9031d5632e517416a8ab0a6b0ac4df124ce", [:mix], [{:deep_merge, "~> 1.0", [hex: :deep_merge, repo: "hexpm", optional: false]}, {:statistex, "~> 1.0", [hex: :statistex, repo: "hexpm", optional: false]}, {:table, "~> 0.1.0", [hex: :table, repo: "hexpm", optional: true]}], "hexpm", "299cd10dd8ce51c9ea3ddb74bb150f93d25e968f93e4c1fa31698a8e4fa5d715"}, "bunt": {:hex, :bunt, "1.0.0", "081c2c665f086849e6d57900292b3a161727ab40431219529f13c4ddcf3e7a44", [:mix], [], "hexpm", "dc5f86aa08a5f6fa6b8096f0735c4e76d54ae5c9fa2c143e5a1fc7c1cd9bb6b5"}, "credo": {:hex, :credo, "1.7.12", "9e3c20463de4b5f3f23721527fcaf16722ec815e70ff6c60b86412c695d426c1", [:mix], [{:bunt, "~> 0.2.1 or ~> 1.0", [hex: :bunt, repo: "hexpm", optional: false]}, {:file_system, "~> 0.2 or ~> 1.0", [hex: :file_system, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "8493d45c656c5427d9c729235b99d498bd133421f3e0a683e5c1b561471291e5"}, @@ -23,7 +23,7 @@ "git_ops": {:hex, :git_ops, "2.7.3", "c993aedb11005752e321d482de6f2a46d0b5d5f09ce69961f31a856e76bf4f12", [:mix], [{:git_cli, "~> 0.2", [hex: :git_cli, repo: "hexpm", optional: false]}, {:igniter, ">= 0.5.27 and < 1.0.0-0", [hex: :igniter, repo: "hexpm", optional: true]}, {:nimble_parsec, "~> 1.0", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "c54ee65e12778be1f4dd6a0921e57ab2bddd35bd6130cbe274dcb1f0a21ca59d"}, "glob_ex": {:hex, :glob_ex, "0.1.11", "cb50d3f1ef53f6ca04d6252c7fde09fd7a1cf63387714fe96f340a1349e62c93", [:mix], [], "hexpm", "342729363056e3145e61766b416769984c329e4378f1d558b63e341020525de4"}, "hpax": {:hex, :hpax, "1.0.3", "ed67ef51ad4df91e75cc6a1494f851850c0bd98ebc0be6e81b026e765ee535aa", [:mix], [], "hexpm", "8eab6e1cfa8d5918c2ce4ba43588e894af35dbd8e91e6e55c817bca5847df34a"}, - "igniter": {:hex, :igniter, "0.6.5", "0b16a37e1aaaefc39777c6250980a314df8ba02a8ae81063d786a7bddb40dbf0", [:mix], [{:glob_ex, "~> 0.1.7", [hex: :glob_ex, repo: "hexpm", optional: false]}, {:jason, "~> 1.4", [hex: :jason, repo: "hexpm", optional: false]}, {:owl, "~> 0.11", [hex: :owl, repo: "hexpm", optional: false]}, {:phx_new, "~> 1.7", [hex: :phx_new, repo: "hexpm", optional: true]}, {:req, "~> 0.5", [hex: :req, repo: "hexpm", optional: false]}, {:rewrite, ">= 1.1.1 and < 2.0.0-0", [hex: :rewrite, repo: "hexpm", optional: false]}, {:sourceror, "~> 1.4", [hex: :sourceror, repo: "hexpm", optional: false]}, {:spitfire, ">= 0.1.3 and < 1.0.0-0", [hex: :spitfire, repo: "hexpm", optional: false]}], "hexpm", "21dec3066f372f49f391d00a2067769eb20f7a2213513e022593e4b51bad93e2"}, + "igniter": {:hex, :igniter, "0.6.6", "82d707a2419a95e6ea115949c68a9113dfc0b4802d3d8386aa351feb0ead71ee", [:mix], [{:glob_ex, "~> 0.1.7", [hex: :glob_ex, repo: "hexpm", optional: false]}, {:jason, "~> 1.4", [hex: :jason, repo: "hexpm", optional: false]}, {:owl, "~> 0.11", [hex: :owl, repo: "hexpm", optional: false]}, {:phx_new, "~> 1.7", [hex: :phx_new, repo: "hexpm", optional: true]}, {:req, "~> 0.5", [hex: :req, repo: "hexpm", optional: false]}, {:rewrite, ">= 1.1.1 and < 2.0.0-0", [hex: :rewrite, repo: "hexpm", optional: false]}, {:sourceror, "~> 1.4", [hex: :sourceror, repo: "hexpm", optional: false]}, {:spitfire, ">= 0.1.3 and < 1.0.0-0", [hex: :spitfire, repo: "hexpm", optional: false]}], "hexpm", "a85832987fc78f5fdc38f628a62acfd50b4e441166496fea15c7b05218fa84f5"}, "iterex": {:hex, :iterex, "0.1.2", "58f9b9b9a22a55cbfc7b5234a9c9c63eaac26d276b3db80936c0e1c60355a5a6", [:mix], [], "hexpm", "2e103b8bcc81757a9af121f6dc0df312c9a17220f302b1193ef720460d03029d"}, "jason": {:hex, :jason, "1.4.4", "b9226785a9aa77b6857ca22832cffa5d5011a667207eb2a0ad56adb5db443b8a", [:mix], [{:decimal, "~> 1.0 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm", "c5eb0cab91f094599f94d55bc63409236a8ec69a21a67814529e8d5f6cc90b3b"}, "libgraph": {:hex, :libgraph, "0.16.0", "3936f3eca6ef826e08880230f806bfea13193e49bf153f93edcf0239d4fd1d07", [:mix], [], "hexpm", "41ca92240e8a4138c30a7e06466acc709b0cbb795c643e9e17174a178982d6bf"}, @@ -44,7 +44,7 @@ "simple_sat": {:hex, :simple_sat, "0.1.3", "f650fc3c184a5fe741868b5ac56dc77fdbb428468f6dbf1978e14d0334497578", [:mix], [], "hexpm", "a54305066a356b7194dc81db2a89232bacdc0b3edaef68ed9aba28dcbc34887b"}, "sobelow": {:hex, :sobelow, "0.14.0", "dd82aae8f72503f924fe9dd97ffe4ca694d2f17ec463dcfd365987c9752af6ee", [:mix], [{:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "7ecf91e298acfd9b24f5d761f19e8f6e6ac585b9387fb6301023f1f2cd5eed5f"}, "sourceror": {:hex, :sourceror, "1.10.0", "38397dedbbc286966ec48c7af13e228b171332be1ad731974438c77791945ce9", [:mix], [], "hexpm", "29dbdfc92e04569c9d8e6efdc422fc1d815f4bd0055dc7c51b8800fb75c4b3f1"}, - "spark": {:hex, :spark, "2.2.62", "610502559834465edce437de712bf7e6d59713ad48050789dbef69a798e71a3c", [:mix], [{:igniter, ">= 0.3.64 and < 1.0.0-0", [hex: :igniter, repo: "hexpm", optional: true]}, {:jason, "~> 1.4", [hex: :jason, repo: "hexpm", optional: true]}, {:sourceror, "~> 1.2", [hex: :sourceror, repo: "hexpm", optional: true]}], "hexpm", "726df72e1b9c17401584b4657e75e08a27a1cf6a6effa2486bf1c074da6176a7"}, + "spark": {:hex, :spark, "2.2.63", "bc771c3c1028136559507e235e721e730118ca316e22e75da347ae1c195b94a1", [:mix], [{:igniter, ">= 0.3.64 and < 1.0.0-0", [hex: :igniter, repo: "hexpm", optional: true]}, {:jason, "~> 1.4", [hex: :jason, repo: "hexpm", optional: true]}, {:sourceror, "~> 1.2", [hex: :sourceror, repo: "hexpm", optional: true]}], "hexpm", "42708ab2884af6abc1aa33aa981a4f51f65146d7879651d1e6c11948a4d8fcfe"}, "spitfire": {:hex, :spitfire, "0.2.1", "29e154873f05444669c7453d3d931820822cbca5170e88f0f8faa1de74a79b47", [:mix], [], "hexpm", "6eeed75054a38341b2e1814d41bb0a250564092358de2669fdb57ff88141d91b"}, "splode": {:hex, :splode, "0.2.9", "3a2776e187c82f42f5226b33b1220ccbff74f4bcc523dd4039c804caaa3ffdc7", [:mix], [], "hexpm", "8002b00c6e24f8bd1bcced3fbaa5c33346048047bb7e13d2f3ad428babbd95c3"}, "statistex": {:hex, :statistex, "1.0.0", "f3dc93f3c0c6c92e5f291704cf62b99b553253d7969e9a5fa713e5481cd858a5", [:mix], [], "hexpm", "ff9d8bee7035028ab4742ff52fc80a2aa35cece833cf5319009b52f1b5a86c27"}, From 2c6466d7d0576815bfe01e5d2231b3a6c8440a22 Mon Sep 17 00:00:00 2001 From: Zach Daniel Date: Mon, 9 Jun 2025 10:59:29 -0400 Subject: [PATCH 045/174] improvement: add `c:AshPostgres.Repo.create_schemas_in_migrations?` callback --- lib/migration_generator/migration_generator.ex | 11 +++++++++-- lib/migration_generator/operation.ex | 2 +- lib/migration_generator/phase.ex | 12 +++++++++--- lib/repo.ex | 5 +++++ 4 files changed, 24 insertions(+), 6 deletions(-) diff --git a/lib/migration_generator/migration_generator.ex b/lib/migration_generator/migration_generator.ex index 1699141d..129a7ddd 100644 --- a/lib/migration_generator/migration_generator.ex +++ b/lib/migration_generator/migration_generator.ex @@ -1361,14 +1361,20 @@ defmodule AshPostgres.MigrationGenerator do defp group_into_phases( [ - %Operation.CreateTable{table: table, schema: schema, multitenancy: multitenancy} | rest + %Operation.CreateTable{ + table: table, + schema: schema, + multitenancy: multitenancy, + repo: repo + } + | rest ], nil, acc ) do group_into_phases( rest, - %Phase.Create{table: table, schema: schema, multitenancy: multitenancy}, + %Phase.Create{table: table, schema: schema, multitenancy: multitenancy, repo: repo}, acc ) end @@ -2010,6 +2016,7 @@ defmodule AshPostgres.MigrationGenerator do %Operation.CreateTable{ table: snapshot.table, schema: snapshot.schema, + repo: snapshot.repo, multitenancy: snapshot.multitenancy, old_multitenancy: empty_snapshot.multitenancy } diff --git a/lib/migration_generator/operation.ex b/lib/migration_generator/operation.ex index 242a5db1..5c8bfbc0 100644 --- a/lib/migration_generator/operation.ex +++ b/lib/migration_generator/operation.ex @@ -145,7 +145,7 @@ defmodule AshPostgres.MigrationGenerator.Operation do defmodule CreateTable do @moduledoc false - defstruct [:table, :schema, :multitenancy, :old_multitenancy] + defstruct [:table, :schema, :multitenancy, :old_multitenancy, :repo] end defmodule AddAttribute do diff --git a/lib/migration_generator/phase.ex b/lib/migration_generator/phase.ex index d743810d..6be7dd81 100644 --- a/lib/migration_generator/phase.ex +++ b/lib/migration_generator/phase.ex @@ -3,18 +3,24 @@ defmodule AshPostgres.MigrationGenerator.Phase do defmodule Create do @moduledoc false - defstruct [:table, :schema, :multitenancy, operations: [], commented?: false] + defstruct [:table, :schema, :multitenancy, :repo, operations: [], commented?: false] import AshPostgres.MigrationGenerator.Operation.Helper, only: [as_atom: 1] - def up(%{schema: schema, table: table, operations: operations, multitenancy: multitenancy}) do + def up(%{ + schema: schema, + table: table, + operations: operations, + multitenancy: multitenancy, + repo: repo + }) do if multitenancy.strategy == :context do "create table(:#{as_atom(table)}, primary_key: false, prefix: prefix()) do\n" <> Enum.map_join(operations, "\n", fn operation -> operation.__struct__.up(operation) end) <> "\nend" else {pre_create, opts} = - if schema do + if schema && repo.create_schemas_in_migrations?() do {"execute(\"CREATE SCHEMA IF NOT EXISTS #{schema}\")" <> "\n\n", ", prefix: \"#{schema}\""} else diff --git a/lib/repo.ex b/lib/repo.ex index eb1beebf..fb7cb7eb 100644 --- a/lib/repo.ex +++ b/lib/repo.ex @@ -78,6 +78,9 @@ defmodule AshPostgres.Repo do @doc "The default prefix(postgres schema) to use when building queries" @callback default_prefix() :: String.t() + @doc "Whether or not to create schemas for tables when generating migrations" + @callback create_schemas_in_migrations?() :: boolean() + @doc "Whether or not to explicitly start and close a transaction for each action, even if there are no transaction hooks. Defaults to `true`." @callback prefer_transaction?() :: boolean @@ -135,6 +138,7 @@ defmodule AshPostgres.Repo do def installed_extensions, do: [] def tenant_migrations_path, do: nil def migrations_path, do: nil + def create_schemas_in_migrations?, do: true def default_prefix, do: "public" def override_migration_type(type), do: type def create?, do: true @@ -304,6 +308,7 @@ defmodule AshPostgres.Repo do prefer_transaction?: 0, prefer_transaction_for_atomic_updates?: 0, tenant_migrations_path: 0, + create_schemas_in_migrations?: 0, migrations_path: 0, default_prefix: 0, override_migration_type: 1, From 1c29ac9e3484863e649cd475e6967a0b082f6289 Mon Sep 17 00:00:00 2001 From: Zach Daniel Date: Mon, 9 Jun 2025 12:17:17 -0400 Subject: [PATCH 046/174] fix: use `force: true`, not `force?: true` calling mix.generator --- lib/migration_generator/migration_generator.ex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/migration_generator/migration_generator.ex b/lib/migration_generator/migration_generator.ex index 129a7ddd..e00cd4f6 100644 --- a/lib/migration_generator/migration_generator.ex +++ b/lib/migration_generator/migration_generator.ex @@ -86,7 +86,7 @@ defmodule AshPostgres.MigrationGenerator do true -> Enum.each(files, fn {file, contents} -> - Mix.Generator.create_file(file, contents, force?: true) + Mix.Generator.create_file(file, contents, force: true) end) end end From f3465d2308d224f7d1b937c3298f12f43d576d0f Mon Sep 17 00:00:00 2001 From: Zach Daniel Date: Mon, 9 Jun 2025 12:27:15 -0400 Subject: [PATCH 047/174] fix: reenable migrate task --- lib/data_layer.ex | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/data_layer.ex b/lib/data_layer.ex index 8196cbe7..10d1a17b 100644 --- a/lib/data_layer.ex +++ b/lib/data_layer.ex @@ -419,6 +419,7 @@ defmodule AshPostgres.DataLayer do ] def migrate(args) do + Mix.Task.reenable("ash_postgres.migrate") Mix.Task.run("ash_postgres.migrate", args) end From dc81e68f5fc03fb99f90f0c95d952fdcf8272090 Mon Sep 17 00:00:00 2001 From: Zach Daniel Date: Mon, 9 Jun 2025 12:31:02 -0400 Subject: [PATCH 048/174] chore: release version v2.6.4 --- CHANGELOG.md | 19 +++++++++++++++++++ mix.exs | 2 +- 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b5f5faed..4b094699 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,25 @@ See [Conventional Commits](https://www.conventionalcommits.org) for commit guide +## [v2.6.4](https://github.com/ash-project/ash_postgres/compare/v2.6.3...v2.6.4) (2025-06-09) + + + + +### Bug Fixes: + +* reenable migrate task + +* use `force: true`, not `force?: true` calling mix.generator + +* casting integers to string in expressions works as intended (#564) + +* use better wrappers around string/ci_string + +### Improvements: + +* add `c:AshPostgres.Repo.create_schemas_in_migrations?` callback + ## [v2.6.3](https://github.com/ash-project/ash_postgres/compare/v2.6.2...v2.6.3) (2025-06-04) diff --git a/mix.exs b/mix.exs index e13172bb..ee671a1f 100644 --- a/mix.exs +++ b/mix.exs @@ -5,7 +5,7 @@ defmodule AshPostgres.MixProject do The PostgreSQL data layer for Ash Framework """ - @version "2.6.3" + @version "2.6.4" def project do [ From 2afe9640c289a78024a6948c0274a9d5fd95c2ec Mon Sep 17 00:00:00 2001 From: Zach Daniel Date: Tue, 10 Jun 2025 09:18:04 -0400 Subject: [PATCH 049/174] fix: properly detect nested array decimals --- lib/migration_generator/migration_generator.ex | 4 ++-- test/migration_generator_test.exs | 5 +++++ 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/lib/migration_generator/migration_generator.ex b/lib/migration_generator/migration_generator.ex index e00cd4f6..ba9990ca 100644 --- a/lib/migration_generator/migration_generator.ex +++ b/lib/migration_generator/migration_generator.ex @@ -3593,8 +3593,8 @@ defmodule AshPostgres.MigrationGenerator do ["decimal", precision, scale] end - defp sanitize_type(type, size, precision, decimal) when is_atom(type) and is_integer(size) do - [sanitize_type(type, nil, precision, decimal), size] + defp sanitize_type(type, size, precision, decimal) when is_tuple(type) do + sanitize_type(elem(type, 0), size, precision, decimal) end defp sanitize_type(type, _, _, _) do diff --git a/test/migration_generator_test.exs b/test/migration_generator_test.exs index afbd4ed8..bd8f2c92 100644 --- a/test/migration_generator_test.exs +++ b/test/migration_generator_test.exs @@ -2511,6 +2511,11 @@ defmodule AshPostgres.MigrationGeneratorTest do public?: true ) + attribute(:decimal_list, {:array, :decimal}, + default: [Decimal.new("123.4567890987654321987")], + public?: true + ) + attribute(:name, :string, default: "Fred", public?: true) attribute(:tag, :atom, default: :value, public?: true) attribute(:enabled, :boolean, default: false, public?: true) From e2c0621f2d06d4a63835935a9cedf35b7cfe424a Mon Sep 17 00:00:00 2001 From: Zach Daniel Date: Tue, 10 Jun 2025 11:20:28 -0400 Subject: [PATCH 050/174] fix: remove spurios debug logging --- lib/multitenancy.ex | 4 ---- test/dev_migrations_test.exs | 2 -- 2 files changed, 6 deletions(-) diff --git a/lib/multitenancy.ex b/lib/multitenancy.ex index 30abecbd..6d70aa49 100644 --- a/lib/multitenancy.ex +++ b/lib/multitenancy.ex @@ -22,7 +22,6 @@ defmodule AshPostgres.MultiTenancy do repo.config(), prefix: tenant_name ) - |> tap(fn v -> Logger.warning(inspect(v, label: "ensure migraitons result")) end) [tenant_migrations_path, "**", "*.exs"] |> Path.join() @@ -42,7 +41,6 @@ defmodule AshPostgres.MultiTenancy do |> Enum.map(&extract_migration_info/1) |> Enum.filter(& &1) |> Enum.map(&load_migration!/1) - |> tap(fn v -> Logger.warning(inspect(v, label: "migrations")) end) |> Enum.each(fn {version, mod} -> Ecto.Migration.Runner.run( repo, @@ -55,10 +53,8 @@ defmodule AshPostgres.MultiTenancy do all: true, prefix: tenant_name ) - |> tap(fn v -> Logger.warning(inspect(v, label: "run result")) end) Ecto.Migration.SchemaMigration.up(repo, repo.config(), version, prefix: tenant_name) - |> tap(fn v -> Logger.warning(inspect(v, label: "schema run result")) end) end) end diff --git a/test/dev_migrations_test.exs b/test/dev_migrations_test.exs index 400bca14..fdaeeff9 100644 --- a/test/dev_migrations_test.exs +++ b/test/dev_migrations_test.exs @@ -224,7 +224,6 @@ defmodule AshPostgres.DevMigrationsTest do "priv/dev_test_repo/migrations", after_file ) - |> tap(fn v -> Logger.warning(inspect(v, label: "result")) end) end defp tenant_migrate do @@ -234,7 +233,6 @@ defmodule AshPostgres.DevMigrationsTest do AshPostgres.DevTestRepo, "priv/dev_test_repo/tenant_migrations" ) - |> tap(fn v -> Logger.warning(inspect(v, label: "result")) end) end end end From 17c66b9402a14e588eddd6ed3a8a72d7ab33fb90 Mon Sep 17 00:00:00 2001 From: Zach Daniel Date: Tue, 10 Jun 2025 11:20:38 -0400 Subject: [PATCH 051/174] chore: release version v2.6.5 --- CHANGELOG.md | 11 +++++++++++ mix.exs | 2 +- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4b094699..1d810f81 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,17 @@ See [Conventional Commits](https://www.conventionalcommits.org) for commit guide +## [v2.6.5](https://github.com/ash-project/ash_postgres/compare/v2.6.4...v2.6.5) (2025-06-10) + + + + +### Bug Fixes: + +* remove spurios debug logging + +* properly detect nested array decimals + ## [v2.6.4](https://github.com/ash-project/ash_postgres/compare/v2.6.3...v2.6.4) (2025-06-09) diff --git a/mix.exs b/mix.exs index ee671a1f..d1548b95 100644 --- a/mix.exs +++ b/mix.exs @@ -5,7 +5,7 @@ defmodule AshPostgres.MixProject do The PostgreSQL data layer for Ash Framework """ - @version "2.6.4" + @version "2.6.5" def project do [ From 8d99e9aca932e4dd2cd6428f50d8a0063256ecab Mon Sep 17 00:00:00 2001 From: Zach Daniel Date: Tue, 10 Jun 2025 19:22:16 -0400 Subject: [PATCH 052/174] fix: simply storage of size/scale/precision information --- .../migration_generator.ex | 109 +++++------------- 1 file changed, 31 insertions(+), 78 deletions(-) diff --git a/lib/migration_generator/migration_generator.ex b/lib/migration_generator/migration_generator.ex index ba9990ca..a5984a67 100644 --- a/lib/migration_generator/migration_generator.ex +++ b/lib/migration_generator/migration_generator.ex @@ -3199,25 +3199,7 @@ defmodule AshPostgres.MigrationGenerator do end {type, size, precision, scale} = - case type do - {:varchar, size} -> - {:varchar, size, nil, nil} - - {:binary, size} -> - {:binary, size, nil, nil} - - {:decimal, precision, scale} -> - {:decimal, nil, precision, scale} - - {:decimal, precision} -> - {:decimal, nil, precision, nil} - - {other, size} when is_atom(other) and is_integer(size) -> - {other, size, nil, nil} - - other -> - {other, nil, nil, nil} - end + migration_type_to_type(type) attribute |> Map.put(:default, default) @@ -3247,6 +3229,32 @@ defmodule AshPostgres.MigrationGenerator do end) end + defp migration_type_to_type(type) do + case type do + {:varchar, size} -> + {:varchar, size, nil, nil} + + {:binary, size} -> + {:binary, size, nil, nil} + + {:decimal, precision, scale} -> + {:decimal, nil, precision, scale} + + {:decimal, precision} -> + {:decimal, nil, precision, nil} + + {other, size} when is_atom(other) and is_integer(size) -> + {other, size, nil, nil} + + {:array, other} -> + {nested, size, precision, scale} = migration_type_to_type(other) + {{:array, nested}, size, precision, scale} + + other -> + {other, nil, nil, nil} + end + end + defp find_reference(resource, table, attribute) do resource |> Ash.Resource.Info.relationships() @@ -3581,22 +3589,6 @@ defmodule AshPostgres.MigrationGenerator do ["array", sanitize_type(type, size, scale, precision)] end - defp sanitize_type(:varchar, size, _scale, _precision) when not is_nil(size) do - ["varchar", size] - end - - defp sanitize_type(:binary, size, _scale, _precision) when not is_nil(size) do - ["binary", size] - end - - defp sanitize_type(:decimal, _size, scale, precision) do - ["decimal", precision, scale] - end - - defp sanitize_type(type, size, precision, decimal) when is_tuple(type) do - sanitize_type(elem(type, 0), size, precision, decimal) - end - defp sanitize_type(type, _, _, _) do type end @@ -3686,27 +3678,6 @@ defmodule AshPostgres.MigrationGenerator do defp load_attribute(attribute, table) do type = load_type(attribute.type) - {type, size, scale, precision} = - case type do - {:varchar, size} -> - {:varchar, size, nil, nil} - - {:binary, size} -> - {:binary, size, nil, nil} - - {other, size} when is_atom(other) and is_integer(size) -> - {other, size, nil, nil} - - {:decimal, precision} -> - {:decimal, nil, nil, precision} - - {:decimal, precision, scale} -> - {:decimal, nil, precision, scale} - - other -> - {other, nil, nil, nil} - end - attribute = if Map.has_key?(attribute, :name) do Map.put(attribute, :source, maybe_to_atom(attribute.name)) @@ -3716,9 +3687,9 @@ defmodule AshPostgres.MigrationGenerator do attribute |> Map.put(:type, type) - |> Map.put(:size, size) - |> Map.put(:precision, precision) - |> Map.put(:scale, scale) + |> Map.put_new(:size, nil) + |> Map.put_new(:precision, nil) + |> Map.put_new(:scale, nil) |> Map.put_new(:default, "nil") |> Map.update!(:default, &(&1 || "nil")) |> Map.update!(:references, fn @@ -3797,25 +3768,7 @@ defmodule AshPostgres.MigrationGenerator do {:array, load_type(type)} end - defp load_type(["varchar", size]) do - {:varchar, size} - end - - defp load_type(["binary", size]) do - {:binary, size} - end - - defp load_type(["decimal", precision]) do - {:decimal, precision} - end - - defp load_type(["decimal", precision, scale]) do - {:decimal, precision, scale} - end - - defp load_type([string, size]) when is_binary(string) and is_integer(size) do - {String.to_existing_atom(string), size} - end + defp load_type([type | _]), do: String.to_existing_atom(type) defp load_type(type) do maybe_to_atom(type) From c653161950948a7a39be8e699f72efefc99fdea9 Mon Sep 17 00:00:00 2001 From: Zach Daniel Date: Tue, 10 Jun 2025 19:22:22 -0400 Subject: [PATCH 053/174] chore: release version v2.6.6 --- CHANGELOG.md | 9 +++++++++ mix.exs | 2 +- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1d810f81..cfda92aa 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,15 @@ See [Conventional Commits](https://www.conventionalcommits.org) for commit guide +## [v2.6.6](https://github.com/ash-project/ash_postgres/compare/v2.6.5...v2.6.6) (2025-06-10) + + + + +### Bug Fixes: + +* simply storage of size/scale/precision information + ## [v2.6.5](https://github.com/ash-project/ash_postgres/compare/v2.6.4...v2.6.5) (2025-06-10) diff --git a/mix.exs b/mix.exs index d1548b95..cf243ab3 100644 --- a/mix.exs +++ b/mix.exs @@ -5,7 +5,7 @@ defmodule AshPostgres.MixProject do The PostgreSQL data layer for Ash Framework """ - @version "2.6.5" + @version "2.6.6" def project do [ From a5b590b59d43be5cfc4394c9ad4349064792bbf6 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 12 Jun 2025 08:26:49 -0400 Subject: [PATCH 054/174] chore(deps): bump the production-dependencies group with 4 updates (#566) Bumps the production-dependencies group with 4 updates: [ash](https://github.com/ash-project/ash), [ash_sql](https://github.com/ash-project/ash_sql), [ecto](https://github.com/elixir-ecto/ecto) and [igniter](https://github.com/ash-project/igniter). Updates `ash` from 3.5.15 to 3.5.18 - [Changelog](https://github.com/ash-project/ash/blob/main/CHANGELOG.md) - [Commits](https://github.com/ash-project/ash/compare/v3.5.15...v3.5.18) Updates `ash_sql` from 0.2.78 to 0.2.79 - [Changelog](https://github.com/ash-project/ash_sql/blob/main/CHANGELOG.md) - [Commits](https://github.com/ash-project/ash_sql/compare/v0.2.78...v0.2.79) Updates `ecto` from 3.12.5 to 3.12.6 - [Release notes](https://github.com/elixir-ecto/ecto/releases) - [Changelog](https://github.com/elixir-ecto/ecto/blob/master/CHANGELOG.md) - [Commits](https://github.com/elixir-ecto/ecto/compare/v3.12.5...v3.12.6) Updates `igniter` from 0.6.6 to 0.6.7 - [Changelog](https://github.com/ash-project/igniter/blob/main/CHANGELOG.md) - [Commits](https://github.com/ash-project/igniter/compare/v0.6.6...v0.6.7) --- updated-dependencies: - dependency-name: ash dependency-version: 3.5.18 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: production-dependencies - dependency-name: ash_sql dependency-version: 0.2.79 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: production-dependencies - dependency-name: ecto dependency-version: 3.12.6 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: production-dependencies - dependency-name: igniter dependency-version: 0.6.7 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: production-dependencies ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- mix.lock | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/mix.lock b/mix.lock index 0fd35a2e..24d983d4 100644 --- a/mix.lock +++ b/mix.lock @@ -1,6 +1,6 @@ %{ - "ash": {:hex, :ash, "3.5.15", "418055e74c4d85d1f397577407aa71c29d44ef0b729be144e23e64630ad2eedc", [:mix], [{:decimal, "~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:ecto, "~> 3.7", [hex: :ecto, repo: "hexpm", optional: false]}, {:ets, "~> 0.8", [hex: :ets, repo: "hexpm", optional: false]}, {:igniter, ">= 0.6.4 and < 1.0.0-0", [hex: :igniter, repo: "hexpm", optional: true]}, {:jason, ">= 1.0.0", [hex: :jason, repo: "hexpm", optional: false]}, {:picosat_elixir, "~> 0.2", [hex: :picosat_elixir, repo: "hexpm", optional: true]}, {:plug, ">= 0.0.0", [hex: :plug, repo: "hexpm", optional: true]}, {:reactor, "~> 0.11", [hex: :reactor, repo: "hexpm", optional: false]}, {:simple_sat, ">= 0.1.1 and < 1.0.0-0", [hex: :simple_sat, repo: "hexpm", optional: true]}, {:spark, ">= 2.2.61 and < 3.0.0-0", [hex: :spark, repo: "hexpm", optional: false]}, {:splode, ">= 0.2.6 and < 1.0.0-0", [hex: :splode, repo: "hexpm", optional: false]}, {:stream_data, "~> 1.0", [hex: :stream_data, repo: "hexpm", optional: false]}, {:telemetry, "~> 1.1", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "8ee885ccc6be65d1023cccbdfda6a534497cf5170d53b67c0b29db72c0c30b9b"}, - "ash_sql": {:hex, :ash_sql, "0.2.78", "130d54ca85b8fbd1e65f038beafb905ade1941d1f5e3aef1fec7f8bba7414fc2", [:mix], [{:ash, "~> 3.5", [hex: :ash, repo: "hexpm", optional: false]}, {:ecto, "~> 3.9", [hex: :ecto, repo: "hexpm", optional: false]}, {:ecto_sql, "~> 3.9", [hex: :ecto_sql, repo: "hexpm", optional: false]}], "hexpm", "a640ec0ef176f3a0e95f88d8639d9d23479ca8a5f5e7e177af351f18cddf4f30"}, + "ash": {:hex, :ash, "3.5.18", "3fafe7b0c67fb863409ea06fd9ca0f1cb681b4e798973989aabedc42a82e8f2a", [:mix], [{:decimal, "~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:ecto, "~> 3.7", [hex: :ecto, repo: "hexpm", optional: false]}, {:ets, "~> 0.8", [hex: :ets, repo: "hexpm", optional: false]}, {:igniter, ">= 0.6.4 and < 1.0.0-0", [hex: :igniter, repo: "hexpm", optional: true]}, {:jason, ">= 1.0.0", [hex: :jason, repo: "hexpm", optional: false]}, {:picosat_elixir, "~> 0.2", [hex: :picosat_elixir, repo: "hexpm", optional: true]}, {:plug, ">= 0.0.0", [hex: :plug, repo: "hexpm", optional: true]}, {:reactor, "~> 0.11", [hex: :reactor, repo: "hexpm", optional: false]}, {:simple_sat, ">= 0.1.1 and < 1.0.0-0", [hex: :simple_sat, repo: "hexpm", optional: true]}, {:spark, ">= 2.2.65 and < 3.0.0-0", [hex: :spark, repo: "hexpm", optional: false]}, {:splode, ">= 0.2.6 and < 1.0.0-0", [hex: :splode, repo: "hexpm", optional: false]}, {:stream_data, "~> 1.0", [hex: :stream_data, repo: "hexpm", optional: false]}, {:telemetry, "~> 1.1", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "52e3156f832026aeef0ca4a705741d29d5a94a7a393ab280b694a2d3d43bcf12"}, + "ash_sql": {:hex, :ash_sql, "0.2.79", "1378bb33a7469f50e2854b7490add380ad2cbf73dda9d5b373194097ad03d3eb", [:mix], [{:ash, "~> 3.5", [hex: :ash, repo: "hexpm", optional: false]}, {:ecto, "~> 3.9", [hex: :ecto, repo: "hexpm", optional: false]}, {:ecto_sql, "~> 3.9", [hex: :ecto_sql, repo: "hexpm", optional: false]}], "hexpm", "7ef10d909f238912b4be7aeb587ae32cce7e42d136bf94da07bc7e54a475cdde"}, "benchee": {:hex, :benchee, "1.4.0", "9f1f96a30ac80bab94faad644b39a9031d5632e517416a8ab0a6b0ac4df124ce", [:mix], [{:deep_merge, "~> 1.0", [hex: :deep_merge, repo: "hexpm", optional: false]}, {:statistex, "~> 1.0", [hex: :statistex, repo: "hexpm", optional: false]}, {:table, "~> 0.1.0", [hex: :table, repo: "hexpm", optional: true]}], "hexpm", "299cd10dd8ce51c9ea3ddb74bb150f93d25e968f93e4c1fa31698a8e4fa5d715"}, "bunt": {:hex, :bunt, "1.0.0", "081c2c665f086849e6d57900292b3a161727ab40431219529f13c4ddcf3e7a44", [:mix], [], "hexpm", "dc5f86aa08a5f6fa6b8096f0735c4e76d54ae5c9fa2c143e5a1fc7c1cd9bb6b5"}, "credo": {:hex, :credo, "1.7.12", "9e3c20463de4b5f3f23721527fcaf16722ec815e70ff6c60b86412c695d426c1", [:mix], [{:bunt, "~> 0.2.1 or ~> 1.0", [hex: :bunt, repo: "hexpm", optional: false]}, {:file_system, "~> 0.2 or ~> 1.0", [hex: :file_system, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "8493d45c656c5427d9c729235b99d498bd133421f3e0a683e5c1b561471291e5"}, @@ -9,7 +9,7 @@ "deep_merge": {:hex, :deep_merge, "1.0.0", "b4aa1a0d1acac393bdf38b2291af38cb1d4a52806cf7a4906f718e1feb5ee961", [:mix], [], "hexpm", "ce708e5f094b9cd4e8f2be4f00d2f4250c4095be93f8cd6d018c753894885430"}, "dialyxir": {:hex, :dialyxir, "1.4.5", "ca1571ac18e0f88d4ab245f0b60fa31ff1b12cbae2b11bd25d207f865e8ae78a", [:mix], [{:erlex, ">= 0.2.7", [hex: :erlex, repo: "hexpm", optional: false]}], "hexpm", "b0fb08bb8107c750db5c0b324fa2df5ceaa0f9307690ee3c1f6ba5b9eb5d35c3"}, "earmark_parser": {:hex, :earmark_parser, "1.4.44", "f20830dd6b5c77afe2b063777ddbbff09f9759396500cdbe7523efd58d7a339c", [:mix], [], "hexpm", "4778ac752b4701a5599215f7030989c989ffdc4f6df457c5f36938cc2d2a2750"}, - "ecto": {:hex, :ecto, "3.12.5", "4a312960ce612e17337e7cefcf9be45b95a3be6b36b6f94dfb3d8c361d631866", [:mix], [{:decimal, "~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "6eb18e80bef8bb57e17f5a7f068a1719fbda384d40fc37acb8eb8aeca493b6ea"}, + "ecto": {:hex, :ecto, "3.12.6", "8bf762dc5b87d85b7aca7ad5fe31ef8142a84cea473a3381eb933bd925751300", [:mix], [{:decimal, "~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "4c0cba01795463eebbcd9e4b5ef53c1ee8e68b9c482baef2a80de5a61e7a57fe"}, "ecto_dev_logger": {:hex, :ecto_dev_logger, "0.14.1", "af385ce1af1c4210ad67a4c46b985c370713446a179144a1da2885138c9fb242", [:mix], [{:ecto, "~> 3.7", [hex: :ecto, repo: "hexpm", optional: false]}, {:geo, "~> 3.5 or ~> 4.0", [hex: :geo, repo: "hexpm", optional: true]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "14a64ebae728b3c45db6ba8bb185979c8e01fc1b0d3d1d9c01c7a2b798e8c698"}, "ecto_sql": {:hex, :ecto_sql, "3.12.1", "c0d0d60e85d9ff4631f12bafa454bc392ce8b9ec83531a412c12a0d415a3a4d0", [:mix], [{:db_connection, "~> 2.4.1 or ~> 2.5", [hex: :db_connection, repo: "hexpm", optional: false]}, {:ecto, "~> 3.12", [hex: :ecto, repo: "hexpm", optional: false]}, {:myxql, "~> 0.7", [hex: :myxql, repo: "hexpm", optional: true]}, {:postgrex, "~> 0.19 or ~> 1.0", [hex: :postgrex, repo: "hexpm", optional: true]}, {:tds, "~> 2.1.1 or ~> 2.2", [hex: :tds, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4.0 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "aff5b958a899762c5f09028c847569f7dfb9cc9d63bdb8133bff8a5546de6bf5"}, "eflame": {:hex, :eflame, "1.0.1", "0664d287e39eef3c413749254b3af5f4f8b00be71c1af67d325331c4890be0fc", [:mix], [], "hexpm", "e0b08854a66f9013129de0b008488f3411ae9b69b902187837f994d7a99cf04e"}, @@ -23,7 +23,7 @@ "git_ops": {:hex, :git_ops, "2.7.3", "c993aedb11005752e321d482de6f2a46d0b5d5f09ce69961f31a856e76bf4f12", [:mix], [{:git_cli, "~> 0.2", [hex: :git_cli, repo: "hexpm", optional: false]}, {:igniter, ">= 0.5.27 and < 1.0.0-0", [hex: :igniter, repo: "hexpm", optional: true]}, {:nimble_parsec, "~> 1.0", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "c54ee65e12778be1f4dd6a0921e57ab2bddd35bd6130cbe274dcb1f0a21ca59d"}, "glob_ex": {:hex, :glob_ex, "0.1.11", "cb50d3f1ef53f6ca04d6252c7fde09fd7a1cf63387714fe96f340a1349e62c93", [:mix], [], "hexpm", "342729363056e3145e61766b416769984c329e4378f1d558b63e341020525de4"}, "hpax": {:hex, :hpax, "1.0.3", "ed67ef51ad4df91e75cc6a1494f851850c0bd98ebc0be6e81b026e765ee535aa", [:mix], [], "hexpm", "8eab6e1cfa8d5918c2ce4ba43588e894af35dbd8e91e6e55c817bca5847df34a"}, - "igniter": {:hex, :igniter, "0.6.6", "82d707a2419a95e6ea115949c68a9113dfc0b4802d3d8386aa351feb0ead71ee", [:mix], [{:glob_ex, "~> 0.1.7", [hex: :glob_ex, repo: "hexpm", optional: false]}, {:jason, "~> 1.4", [hex: :jason, repo: "hexpm", optional: false]}, {:owl, "~> 0.11", [hex: :owl, repo: "hexpm", optional: false]}, {:phx_new, "~> 1.7", [hex: :phx_new, repo: "hexpm", optional: true]}, {:req, "~> 0.5", [hex: :req, repo: "hexpm", optional: false]}, {:rewrite, ">= 1.1.1 and < 2.0.0-0", [hex: :rewrite, repo: "hexpm", optional: false]}, {:sourceror, "~> 1.4", [hex: :sourceror, repo: "hexpm", optional: false]}, {:spitfire, ">= 0.1.3 and < 1.0.0-0", [hex: :spitfire, repo: "hexpm", optional: false]}], "hexpm", "a85832987fc78f5fdc38f628a62acfd50b4e441166496fea15c7b05218fa84f5"}, + "igniter": {:hex, :igniter, "0.6.7", "4e183afc59d89289e223c4282fd3e9bb39b82e28d0aa6d3369f70fbd3e21a243", [:mix], [{:glob_ex, "~> 0.1.7", [hex: :glob_ex, repo: "hexpm", optional: false]}, {:jason, "~> 1.4", [hex: :jason, repo: "hexpm", optional: false]}, {:owl, "~> 0.11", [hex: :owl, repo: "hexpm", optional: false]}, {:phx_new, "~> 1.7", [hex: :phx_new, repo: "hexpm", optional: true]}, {:req, "~> 0.5", [hex: :req, repo: "hexpm", optional: false]}, {:rewrite, ">= 1.1.1 and < 2.0.0-0", [hex: :rewrite, repo: "hexpm", optional: false]}, {:sourceror, "~> 1.4", [hex: :sourceror, repo: "hexpm", optional: false]}, {:spitfire, ">= 0.1.3 and < 1.0.0-0", [hex: :spitfire, repo: "hexpm", optional: false]}], "hexpm", "43b0a584dc84fd1320772c87047355b604ed2bcdd25392b17f7da8bdd09b61ac"}, "iterex": {:hex, :iterex, "0.1.2", "58f9b9b9a22a55cbfc7b5234a9c9c63eaac26d276b3db80936c0e1c60355a5a6", [:mix], [], "hexpm", "2e103b8bcc81757a9af121f6dc0df312c9a17220f302b1193ef720460d03029d"}, "jason": {:hex, :jason, "1.4.4", "b9226785a9aa77b6857ca22832cffa5d5011a667207eb2a0ad56adb5db443b8a", [:mix], [{:decimal, "~> 1.0 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm", "c5eb0cab91f094599f94d55bc63409236a8ec69a21a67814529e8d5f6cc90b3b"}, "libgraph": {:hex, :libgraph, "0.16.0", "3936f3eca6ef826e08880230f806bfea13193e49bf153f93edcf0239d4fd1d07", [:mix], [], "hexpm", "41ca92240e8a4138c30a7e06466acc709b0cbb795c643e9e17174a178982d6bf"}, @@ -44,7 +44,7 @@ "simple_sat": {:hex, :simple_sat, "0.1.3", "f650fc3c184a5fe741868b5ac56dc77fdbb428468f6dbf1978e14d0334497578", [:mix], [], "hexpm", "a54305066a356b7194dc81db2a89232bacdc0b3edaef68ed9aba28dcbc34887b"}, "sobelow": {:hex, :sobelow, "0.14.0", "dd82aae8f72503f924fe9dd97ffe4ca694d2f17ec463dcfd365987c9752af6ee", [:mix], [{:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "7ecf91e298acfd9b24f5d761f19e8f6e6ac585b9387fb6301023f1f2cd5eed5f"}, "sourceror": {:hex, :sourceror, "1.10.0", "38397dedbbc286966ec48c7af13e228b171332be1ad731974438c77791945ce9", [:mix], [], "hexpm", "29dbdfc92e04569c9d8e6efdc422fc1d815f4bd0055dc7c51b8800fb75c4b3f1"}, - "spark": {:hex, :spark, "2.2.63", "bc771c3c1028136559507e235e721e730118ca316e22e75da347ae1c195b94a1", [:mix], [{:igniter, ">= 0.3.64 and < 1.0.0-0", [hex: :igniter, repo: "hexpm", optional: true]}, {:jason, "~> 1.4", [hex: :jason, repo: "hexpm", optional: true]}, {:sourceror, "~> 1.2", [hex: :sourceror, repo: "hexpm", optional: true]}], "hexpm", "42708ab2884af6abc1aa33aa981a4f51f65146d7879651d1e6c11948a4d8fcfe"}, + "spark": {:hex, :spark, "2.2.65", "4c10d109c108417ce394158f330be09ef184878bde45de6462397fbda68cec29", [:mix], [{:igniter, ">= 0.3.64 and < 1.0.0-0", [hex: :igniter, repo: "hexpm", optional: true]}, {:jason, "~> 1.4", [hex: :jason, repo: "hexpm", optional: true]}, {:sourceror, "~> 1.2", [hex: :sourceror, repo: "hexpm", optional: true]}], "hexpm", "d66d5070a77f4c69cb4f007e941ac17d5d751ce71190fcd6e6e5fb42ba86f101"}, "spitfire": {:hex, :spitfire, "0.2.1", "29e154873f05444669c7453d3d931820822cbca5170e88f0f8faa1de74a79b47", [:mix], [], "hexpm", "6eeed75054a38341b2e1814d41bb0a250564092358de2669fdb57ff88141d91b"}, "splode": {:hex, :splode, "0.2.9", "3a2776e187c82f42f5226b33b1220ccbff74f4bcc523dd4039c804caaa3ffdc7", [:mix], [], "hexpm", "8002b00c6e24f8bd1bcced3fbaa5c33346048047bb7e13d2f3ad428babbd95c3"}, "statistex": {:hex, :statistex, "1.0.0", "f3dc93f3c0c6c92e5f291704cf62b99b553253d7969e9a5fa713e5481cd858a5", [:mix], [], "hexpm", "ff9d8bee7035028ab4742ff52fc80a2aa35cece833cf5319009b52f1b5a86c27"}, From 4a94b817ffc850421d485ff0e41b37b98e43abeb Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 12 Jun 2025 08:27:03 -0400 Subject: [PATCH 055/174] chore(deps-dev): bump the dev-dependencies group with 2 updates (#567) Bumps the dev-dependencies group with 2 updates: [git_ops](https://github.com/zachdaniel/git_ops) and [mix_audit](https://github.com/mirego/mix_audit). Updates `git_ops` from 2.7.3 to 2.8.0 - [Changelog](https://github.com/zachdaniel/git_ops/blob/master/CHANGELOG.md) - [Commits](https://github.com/zachdaniel/git_ops/compare/v2.7.3...v2.8.0) Updates `mix_audit` from 2.1.4 to 2.1.5 - [Changelog](https://github.com/mirego/mix_audit/blob/main/CHANGELOG.md) - [Commits](https://github.com/mirego/mix_audit/compare/v2.1.4...v2.1.5) --- updated-dependencies: - dependency-name: git_ops dependency-version: 2.8.0 dependency-type: direct:development update-type: version-update:semver-minor dependency-group: dev-dependencies - dependency-name: mix_audit dependency-version: 2.1.5 dependency-type: direct:development update-type: version-update:semver-patch dependency-group: dev-dependencies ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- mix.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mix.lock b/mix.lock index 24d983d4..d7a02173 100644 --- a/mix.lock +++ b/mix.lock @@ -20,7 +20,7 @@ "file_system": {:hex, :file_system, "1.1.0", "08d232062284546c6c34426997dd7ef6ec9f8bbd090eb91780283c9016840e8f", [:mix], [], "hexpm", "bfcf81244f416871f2a2e15c1b515287faa5db9c6bcf290222206d120b3d43f6"}, "finch": {:hex, :finch, "0.19.0", "c644641491ea854fc5c1bbaef36bfc764e3f08e7185e1f084e35e0672241b76d", [:mix], [{:mime, "~> 1.0 or ~> 2.0", [hex: :mime, repo: "hexpm", optional: false]}, {:mint, "~> 1.6.2 or ~> 1.7", [hex: :mint, repo: "hexpm", optional: false]}, {:nimble_options, "~> 0.4 or ~> 1.0", [hex: :nimble_options, repo: "hexpm", optional: false]}, {:nimble_pool, "~> 1.1", [hex: :nimble_pool, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "fc5324ce209125d1e2fa0fcd2634601c52a787aff1cd33ee833664a5af4ea2b6"}, "git_cli": {:hex, :git_cli, "0.3.0", "a5422f9b95c99483385b976f5d43f7e8233283a47cda13533d7c16131cb14df5", [:mix], [], "hexpm", "78cb952f4c86a41f4d3511f1d3ecb28edb268e3a7df278de2faa1bd4672eaf9b"}, - "git_ops": {:hex, :git_ops, "2.7.3", "c993aedb11005752e321d482de6f2a46d0b5d5f09ce69961f31a856e76bf4f12", [:mix], [{:git_cli, "~> 0.2", [hex: :git_cli, repo: "hexpm", optional: false]}, {:igniter, ">= 0.5.27 and < 1.0.0-0", [hex: :igniter, repo: "hexpm", optional: true]}, {:nimble_parsec, "~> 1.0", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "c54ee65e12778be1f4dd6a0921e57ab2bddd35bd6130cbe274dcb1f0a21ca59d"}, + "git_ops": {:hex, :git_ops, "2.8.0", "29ac9ab68bf9645973cb2752047b987e75cbd3d9761489c615e3ba80018fa885", [:mix], [{:git_cli, "~> 0.2", [hex: :git_cli, repo: "hexpm", optional: false]}, {:igniter, ">= 0.5.27 and < 1.0.0-0", [hex: :igniter, repo: "hexpm", optional: true]}, {:nimble_parsec, "~> 1.0", [hex: :nimble_parsec, repo: "hexpm", optional: false]}, {:req, "~> 0.5", [hex: :req, repo: "hexpm", optional: false]}], "hexpm", "b535e4ad6b5d13e14c455e76f65825659081b5530b0827eb0232d18719530eec"}, "glob_ex": {:hex, :glob_ex, "0.1.11", "cb50d3f1ef53f6ca04d6252c7fde09fd7a1cf63387714fe96f340a1349e62c93", [:mix], [], "hexpm", "342729363056e3145e61766b416769984c329e4378f1d558b63e341020525de4"}, "hpax": {:hex, :hpax, "1.0.3", "ed67ef51ad4df91e75cc6a1494f851850c0bd98ebc0be6e81b026e765ee535aa", [:mix], [], "hexpm", "8eab6e1cfa8d5918c2ce4ba43588e894af35dbd8e91e6e55c817bca5847df34a"}, "igniter": {:hex, :igniter, "0.6.7", "4e183afc59d89289e223c4282fd3e9bb39b82e28d0aa6d3369f70fbd3e21a243", [:mix], [{:glob_ex, "~> 0.1.7", [hex: :glob_ex, repo: "hexpm", optional: false]}, {:jason, "~> 1.4", [hex: :jason, repo: "hexpm", optional: false]}, {:owl, "~> 0.11", [hex: :owl, repo: "hexpm", optional: false]}, {:phx_new, "~> 1.7", [hex: :phx_new, repo: "hexpm", optional: true]}, {:req, "~> 0.5", [hex: :req, repo: "hexpm", optional: false]}, {:rewrite, ">= 1.1.1 and < 2.0.0-0", [hex: :rewrite, repo: "hexpm", optional: false]}, {:sourceror, "~> 1.4", [hex: :sourceror, repo: "hexpm", optional: false]}, {:spitfire, ">= 0.1.3 and < 1.0.0-0", [hex: :spitfire, repo: "hexpm", optional: false]}], "hexpm", "43b0a584dc84fd1320772c87047355b604ed2bcdd25392b17f7da8bdd09b61ac"}, @@ -32,7 +32,7 @@ "makeup_erlang": {:hex, :makeup_erlang, "1.0.2", "03e1804074b3aa64d5fad7aa64601ed0fb395337b982d9bcf04029d68d51b6a7", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}], "hexpm", "af33ff7ef368d5893e4a267933e7744e46ce3cf1f61e2dccf53a111ed3aa3727"}, "mime": {:hex, :mime, "2.0.7", "b8d739037be7cd402aee1ba0306edfdef982687ee7e9859bee6198c1e7e2f128", [:mix], [], "hexpm", "6171188e399ee16023ffc5b76ce445eb6d9672e2e241d2df6050f3c771e80ccd"}, "mint": {:hex, :mint, "1.7.1", "113fdb2b2f3b59e47c7955971854641c61f378549d73e829e1768de90fc1abf1", [:mix], [{:castore, "~> 0.1.0 or ~> 1.0", [hex: :castore, repo: "hexpm", optional: true]}, {:hpax, "~> 0.1.1 or ~> 0.2.0 or ~> 1.0", [hex: :hpax, repo: "hexpm", optional: false]}], "hexpm", "fceba0a4d0f24301ddee3024ae116df1c3f4bb7a563a731f45fdfeb9d39a231b"}, - "mix_audit": {:hex, :mix_audit, "2.1.4", "0a23d5b07350cdd69001c13882a4f5fb9f90fbd4cbf2ebc190a2ee0d187ea3e9", [:make, :mix], [{:jason, "~> 1.4", [hex: :jason, repo: "hexpm", optional: false]}, {:yaml_elixir, "~> 2.11", [hex: :yaml_elixir, repo: "hexpm", optional: false]}], "hexpm", "fd807653cc8c1cada2911129c7eb9e985e3cc76ebf26f4dd628bb25bbcaa7099"}, + "mix_audit": {:hex, :mix_audit, "2.1.5", "c0f77cee6b4ef9d97e37772359a187a166c7a1e0e08b50edf5bf6959dfe5a016", [:make, :mix], [{:jason, "~> 1.4", [hex: :jason, repo: "hexpm", optional: false]}, {:yaml_elixir, "~> 2.11", [hex: :yaml_elixir, repo: "hexpm", optional: false]}], "hexpm", "87f9298e21da32f697af535475860dc1d3617a010e0b418d2ec6142bc8b42d69"}, "nimble_options": {:hex, :nimble_options, "1.1.1", "e3a492d54d85fc3fd7c5baf411d9d2852922f66e69476317787a7b2bb000a61b", [:mix], [], "hexpm", "821b2470ca9442c4b6984882fe9bb0389371b8ddec4d45a9504f00a66f650b44"}, "nimble_parsec": {:hex, :nimble_parsec, "1.4.2", "8efba0122db06df95bfaa78f791344a89352ba04baedd3849593bfce4d0dc1c6", [:mix], [], "hexpm", "4b21398942dda052b403bbe1da991ccd03a053668d147d53fb8c4e0efe09c973"}, "nimble_pool": {:hex, :nimble_pool, "1.1.0", "bf9c29fbdcba3564a8b800d1eeb5a3c58f36e1e11d7b7fb2e084a643f645f06b", [:mix], [], "hexpm", "af2e4e6b34197db81f7aad230c1118eac993acc0dae6bc83bac0126d4ae0813a"}, From 61a075f46a96ddbf9d94137bbd20ffd5db7e6d11 Mon Sep 17 00:00:00 2001 From: Zach Daniel Date: Thu, 12 Jun 2025 08:47:43 -0400 Subject: [PATCH 056/174] test: update tests --- .../test_repo/posts/20250612113920.json | 678 ++++++++++++++++++ .../20250612113920_migrate_resources55.exs | 21 + test/filter_test.exs | 15 + test/support/resources/post.ex | 1 - 4 files changed, 714 insertions(+), 1 deletion(-) create mode 100644 priv/resource_snapshots/test_repo/posts/20250612113920.json create mode 100644 priv/test_repo/migrations/20250612113920_migrate_resources55.exs diff --git a/priv/resource_snapshots/test_repo/posts/20250612113920.json b/priv/resource_snapshots/test_repo/posts/20250612113920.json new file mode 100644 index 00000000..4d585717 --- /dev/null +++ b/priv/resource_snapshots/test_repo/posts/20250612113920.json @@ -0,0 +1,678 @@ +{ + "attributes": [ + { + "allow_nil?": false, + "default": "fragment(\"gen_random_uuid()\")", + "generated?": false, + "precision": null, + "primary_key?": true, + "references": null, + "scale": null, + "size": null, + "source": "id", + "type": "uuid" + }, + { + "allow_nil?": false, + "default": "1", + "generated?": false, + "precision": null, + "primary_key?": false, + "references": null, + "scale": null, + "size": null, + "source": "version", + "type": "bigint" + }, + { + "allow_nil?": true, + "default": "nil", + "generated?": false, + "precision": null, + "primary_key?": false, + "references": null, + "scale": null, + "size": null, + "source": "title_column", + "type": "text" + }, + { + "allow_nil?": true, + "default": "nil", + "generated?": false, + "precision": null, + "primary_key?": false, + "references": null, + "scale": null, + "size": null, + "source": "not_selected_by_default", + "type": "text" + }, + { + "allow_nil?": true, + "default": "nil", + "generated?": false, + "precision": null, + "primary_key?": false, + "references": null, + "scale": null, + "size": null, + "source": "datetime", + "type": "timestamptz(6)" + }, + { + "allow_nil?": true, + "default": "nil", + "generated?": false, + "precision": null, + "primary_key?": false, + "references": null, + "scale": null, + "size": null, + "source": "score", + "type": "bigint" + }, + { + "allow_nil?": true, + "default": "nil", + "generated?": false, + "precision": null, + "primary_key?": false, + "references": null, + "scale": null, + "size": null, + "source": "limited_score", + "type": "bigint" + }, + { + "allow_nil?": true, + "default": "nil", + "generated?": false, + "precision": null, + "primary_key?": false, + "references": null, + "scale": null, + "size": null, + "source": "public", + "type": "boolean" + }, + { + "allow_nil?": true, + "default": "nil", + "generated?": false, + "precision": null, + "primary_key?": false, + "references": null, + "scale": null, + "size": null, + "source": "category", + "type": "citext" + }, + { + "allow_nil?": true, + "default": "\"sponsored\"", + "generated?": false, + "precision": null, + "primary_key?": false, + "references": null, + "scale": null, + "size": null, + "source": "type", + "type": "text" + }, + { + "allow_nil?": true, + "default": "nil", + "generated?": false, + "precision": null, + "primary_key?": false, + "references": null, + "scale": null, + "size": null, + "source": "price", + "type": "bigint" + }, + { + "allow_nil?": true, + "default": "\"0\"", + "generated?": false, + "precision": null, + "primary_key?": false, + "references": null, + "scale": null, + "size": null, + "source": "decimal", + "type": "decimal" + }, + { + "allow_nil?": true, + "default": "nil", + "generated?": false, + "precision": null, + "primary_key?": false, + "references": null, + "scale": null, + "size": null, + "source": "status", + "type": "text" + }, + { + "allow_nil?": true, + "default": "nil", + "generated?": false, + "precision": null, + "primary_key?": false, + "references": null, + "scale": null, + "size": null, + "source": "status_enum", + "type": "status" + }, + { + "allow_nil?": true, + "default": "nil", + "generated?": false, + "precision": null, + "primary_key?": false, + "references": null, + "scale": null, + "size": null, + "source": "metadata", + "type": "map" + }, + { + "allow_nil?": false, + "default": "2", + "generated?": false, + "precision": null, + "primary_key?": false, + "references": null, + "scale": null, + "size": null, + "source": "constrained_int", + "type": "bigint" + }, + { + "allow_nil?": true, + "default": "nil", + "generated?": false, + "precision": null, + "primary_key?": false, + "references": null, + "scale": null, + "size": null, + "source": "point", + "type": [ + "array", + "float" + ] + }, + { + "allow_nil?": true, + "default": "nil", + "generated?": false, + "precision": null, + "primary_key?": false, + "references": null, + "scale": null, + "size": null, + "source": "composite_point", + "type": "custom_point" + }, + { + "allow_nil?": true, + "default": "nil", + "generated?": false, + "precision": null, + "primary_key?": false, + "references": null, + "scale": null, + "size": null, + "source": "string_point", + "type": "text" + }, + { + "allow_nil?": true, + "default": "nil", + "generated?": false, + "precision": null, + "primary_key?": false, + "references": null, + "scale": null, + "size": null, + "source": "person_detail", + "type": "map" + }, + { + "allow_nil?": true, + "default": "nil", + "generated?": false, + "precision": null, + "primary_key?": false, + "references": null, + "scale": null, + "size": null, + "source": "stuff", + "type": "map" + }, + { + "allow_nil?": true, + "default": "nil", + "generated?": false, + "precision": null, + "primary_key?": false, + "references": null, + "scale": null, + "size": null, + "source": "list_of_stuff", + "type": [ + "array", + "map" + ] + }, + { + "allow_nil?": true, + "default": "nil", + "generated?": false, + "precision": null, + "primary_key?": false, + "references": null, + "scale": null, + "size": null, + "source": "uniq_one", + "type": "text" + }, + { + "allow_nil?": true, + "default": "nil", + "generated?": false, + "precision": null, + "primary_key?": false, + "references": null, + "scale": null, + "size": null, + "source": "uniq_two", + "type": "text" + }, + { + "allow_nil?": true, + "default": "nil", + "generated?": false, + "precision": null, + "primary_key?": false, + "references": null, + "scale": null, + "size": null, + "source": "uniq_custom_one", + "type": "text" + }, + { + "allow_nil?": true, + "default": "nil", + "generated?": false, + "precision": null, + "primary_key?": false, + "references": null, + "scale": null, + "size": null, + "source": "uniq_custom_two", + "type": "text" + }, + { + "allow_nil?": true, + "default": "nil", + "generated?": false, + "precision": null, + "primary_key?": false, + "references": null, + "scale": null, + "size": null, + "source": "uniq_on_upper", + "type": "text" + }, + { + "allow_nil?": true, + "default": "nil", + "generated?": false, + "precision": null, + "primary_key?": false, + "references": null, + "scale": null, + "size": null, + "source": "uniq_if_contains_foo", + "type": "text" + }, + { + "allow_nil?": true, + "default": "nil", + "generated?": false, + "precision": null, + "primary_key?": false, + "references": null, + "scale": null, + "size": null, + "source": "model", + "type": "map" + }, + { + "allow_nil?": true, + "default": "nil", + "generated?": false, + "precision": null, + "primary_key?": false, + "references": null, + "scale": null, + "size": null, + "source": "list_containing_nils", + "type": [ + "array", + "text" + ] + }, + { + "allow_nil?": true, + "default": "nil", + "generated?": false, + "precision": null, + "primary_key?": false, + "references": null, + "scale": null, + "size": null, + "source": "ltree_unescaped", + "type": "ltree" + }, + { + "allow_nil?": true, + "default": "nil", + "generated?": false, + "precision": null, + "primary_key?": false, + "references": null, + "scale": null, + "size": null, + "source": "ltree_escaped", + "type": "ltree" + }, + { + "allow_nil?": false, + "default": "fragment(\"(now() AT TIME ZONE 'utc')\")", + "generated?": false, + "precision": null, + "primary_key?": false, + "references": null, + "scale": null, + "size": null, + "source": "created_at", + "type": "utc_datetime_usec" + }, + { + "allow_nil?": false, + "default": "fragment(\"(now() AT TIME ZONE 'utc')\")", + "generated?": false, + "precision": null, + "primary_key?": false, + "references": null, + "scale": null, + "size": null, + "source": "updated_at", + "type": "timestamptz(6)" + }, + { + "allow_nil?": true, + "default": "nil", + "generated?": false, + "precision": null, + "primary_key?": false, + "references": { + "deferrable": false, + "destination_attribute": "id", + "destination_attribute_default": null, + "destination_attribute_generated": null, + "index?": false, + "match_type": null, + "match_with": null, + "multitenancy": { + "attribute": null, + "global": null, + "strategy": null + }, + "name": "posts_organization_id_fkey", + "on_delete": null, + "on_update": null, + "primary_key?": true, + "schema": "public", + "table": "orgs" + }, + "scale": null, + "size": null, + "source": "organization_id", + "type": "uuid" + }, + { + "allow_nil?": true, + "default": "nil", + "generated?": false, + "precision": null, + "primary_key?": false, + "references": { + "deferrable": false, + "destination_attribute": "id", + "destination_attribute_default": null, + "destination_attribute_generated": null, + "index?": false, + "match_type": null, + "match_with": null, + "multitenancy": { + "attribute": null, + "global": null, + "strategy": null + }, + "name": "posts_parent_post_id_fkey", + "on_delete": null, + "on_update": null, + "primary_key?": true, + "schema": "public", + "table": "posts" + }, + "scale": null, + "size": null, + "source": "parent_post_id", + "type": "uuid" + }, + { + "allow_nil?": true, + "default": "nil", + "generated?": false, + "precision": null, + "primary_key?": false, + "references": { + "deferrable": false, + "destination_attribute": "id", + "destination_attribute_default": null, + "destination_attribute_generated": null, + "index?": false, + "match_type": null, + "match_with": null, + "multitenancy": { + "attribute": null, + "global": null, + "strategy": null + }, + "name": "posts_author_id_fkey", + "on_delete": null, + "on_update": null, + "primary_key?": true, + "schema": "public", + "table": "authors" + }, + "scale": null, + "size": null, + "source": "author_id", + "type": "uuid" + }, + { + "allow_nil?": true, + "default": "nil", + "generated?": false, + "precision": null, + "primary_key?": false, + "references": { + "deferrable": false, + "destination_attribute": "id", + "destination_attribute_default": null, + "destination_attribute_generated": null, + "index?": false, + "match_type": null, + "match_with": null, + "multitenancy": { + "attribute": null, + "global": null, + "strategy": null + }, + "name": "posts_db_point_id_fkey", + "on_delete": null, + "on_update": null, + "primary_key?": true, + "schema": "public", + "table": "points" + }, + "scale": null, + "size": null, + "source": "db_point_id", + "type": [ + "array", + "float" + ] + }, + { + "allow_nil?": true, + "default": "nil", + "generated?": false, + "precision": null, + "primary_key?": false, + "references": { + "deferrable": false, + "destination_attribute": "id", + "destination_attribute_default": null, + "destination_attribute_generated": null, + "index?": false, + "match_type": null, + "match_with": null, + "multitenancy": { + "attribute": null, + "global": null, + "strategy": null + }, + "name": "posts_db_string_point_id_fkey", + "on_delete": null, + "on_update": null, + "primary_key?": true, + "schema": "public", + "table": "string_points" + }, + "scale": null, + "size": null, + "source": "db_string_point_id", + "type": "text" + } + ], + "base_filter": "type = 'sponsored'", + "check_constraints": [ + { + "attribute": [ + "price" + ], + "base_filter": "type = 'sponsored'", + "check": "price > 0", + "name": "price_must_be_positive" + } + ], + "custom_indexes": [ + { + "all_tenants?": false, + "concurrently": true, + "error_fields": [ + "uniq_custom_one", + "uniq_custom_two" + ], + "fields": [ + { + "type": "atom", + "value": "uniq_custom_one" + }, + { + "type": "atom", + "value": "uniq_custom_two" + } + ], + "include": null, + "message": "dude what the heck", + "name": null, + "nulls_distinct": true, + "prefix": null, + "table": null, + "unique": true, + "using": null, + "where": null + } + ], + "custom_statements": [], + "has_create_action": true, + "hash": "90D4DD5BCCA4A66F2979715F980190DBC33A0A71C697943F2756B87302E0FE5A", + "identities": [ + { + "all_tenants?": false, + "base_filter": "type = 'sponsored'", + "index_name": "posts_uniq_if_contains_foo_index", + "keys": [ + { + "type": "atom", + "value": "uniq_if_contains_foo" + } + ], + "name": "uniq_if_contains_foo", + "nils_distinct?": true, + "where": "(uniq_if_contains_foo LIKE '%foo%')" + }, + { + "all_tenants?": false, + "base_filter": "type = 'sponsored'", + "index_name": "posts_uniq_on_upper_index", + "keys": [ + { + "type": "string", + "value": "(UPPER(uniq_on_upper))" + } + ], + "name": "uniq_on_upper", + "nils_distinct?": true, + "where": null + }, + { + "all_tenants?": false, + "base_filter": "type = 'sponsored'", + "index_name": "posts_uniq_one_and_two_index", + "keys": [ + { + "type": "atom", + "value": "uniq_one" + }, + { + "type": "atom", + "value": "uniq_two" + } + ], + "name": "uniq_one_and_two", + "nils_distinct?": true, + "where": null + } + ], + "multitenancy": { + "attribute": null, + "global": null, + "strategy": null + }, + "repo": "Elixir.AshPostgres.TestRepo", + "schema": null, + "table": "posts" +} \ No newline at end of file diff --git a/priv/test_repo/migrations/20250612113920_migrate_resources55.exs b/priv/test_repo/migrations/20250612113920_migrate_resources55.exs new file mode 100644 index 00000000..082dad95 --- /dev/null +++ b/priv/test_repo/migrations/20250612113920_migrate_resources55.exs @@ -0,0 +1,21 @@ +defmodule AshPostgres.TestRepo.Migrations.MigrateResources55 do + @moduledoc """ + Updates resources based on their most recent snapshots. + + This file was autogenerated with `mix ash_postgres.generate_migrations` + """ + + use Ecto.Migration + + def up do + alter table(:posts) do + modify(:model, :map, null: true) + end + end + + def down do + alter table(:posts) do + modify(:model, :map, null: false) + end + end +end diff --git a/test/filter_test.exs b/test/filter_test.exs index 83bcbba0..261dd0bf 100644 --- a/test/filter_test.exs +++ b/test/filter_test.exs @@ -21,6 +21,21 @@ defmodule AshPostgres.FilterTest do end end + describe "type casting" do + test "it does not do unnecessary type casting" do + {query, vars} = + Post + |> Ash.Query.filter(version == ^10) + |> Ash.data_layer_query!() + |> Map.get(:query) + |> then(&AshPostgres.TestRepo.to_sql(:all, &1)) + + assert vars == ["sponsored", 10] + + assert String.contains?(query, "(p0.\"version\"::bigint = $2::bigint)") + end + end + describe "ci_string argument casting" do test "it properly casts" do Post diff --git a/test/support/resources/post.ex b/test/support/resources/post.ex index 369283bc..a2c3ceea 100644 --- a/test/support/resources/post.ex +++ b/test/support/resources/post.ex @@ -551,7 +551,6 @@ defmodule AshPostgres.Test.Post do ] ) - allow_nil?(false) default(fn -> {3.0, 3.0, 1.0} end) end From fd2b80d3173e338662b3a2bfed91c3fb60a290ca Mon Sep 17 00:00:00 2001 From: Zach Daniel Date: Thu, 12 Jun 2025 08:47:54 -0400 Subject: [PATCH 057/174] chore: update bench --- benchmarks/bulk_create.exs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/benchmarks/bulk_create.exs b/benchmarks/bulk_create.exs index 5d9ee395..99f235a1 100644 --- a/benchmarks/bulk_create.exs +++ b/benchmarks/bulk_create.exs @@ -1,5 +1,7 @@ alias AshPostgres.Test.{Domain, Post} +AshPostgres.TestRepo.start_link() + ten_rows = 1..10 |> Enum.map(fn i -> From aff1c410f51a12a5ea6e50a7be0e33dbc3658e89 Mon Sep 17 00:00:00 2001 From: Christian Alexander Date: Thu, 12 Jun 2025 08:09:14 -0700 Subject: [PATCH 058/174] docs: Fix mix task documentation typos (#568) --- lib/mix/tasks/ash_postgres.drop.ex | 2 +- lib/mix/tasks/ash_postgres.gen.resources.ex | 4 ++-- lib/mix/tasks/ash_postgres.generate_migrations.ex | 2 +- lib/mix/tasks/ash_postgres.migrate.ex | 4 ++-- lib/mix/tasks/ash_postgres.rollback.ex | 2 +- lib/mix/tasks/ash_postgres.squash_snapshots.ex | 2 +- 6 files changed, 8 insertions(+), 8 deletions(-) diff --git a/lib/mix/tasks/ash_postgres.drop.ex b/lib/mix/tasks/ash_postgres.drop.ex index 43028c38..e54ffddb 100644 --- a/lib/mix/tasks/ash_postgres.drop.ex +++ b/lib/mix/tasks/ash_postgres.drop.ex @@ -39,7 +39,7 @@ defmodule Mix.Tasks.AshPostgres.Drop do * `--force-drop` - force the database to be dropped even if it has connections to it (requires PostgreSQL 13+) * `--no-compile` - do not compile before dropping - * `--no-deps-check` - do not compile before dropping + * `--no-deps-check` - do not check dependencies before dropping """ @doc false diff --git a/lib/mix/tasks/ash_postgres.gen.resources.ex b/lib/mix/tasks/ash_postgres.gen.resources.ex index 2196c2f0..a187f8d9 100644 --- a/lib/mix/tasks/ash_postgres.gen.resources.ex +++ b/lib/mix/tasks/ash_postgres.gen.resources.ex @@ -2,7 +2,7 @@ if Code.ensure_loaded?(Igniter) do defmodule Mix.Tasks.AshPostgres.Gen.Resources do use Igniter.Mix.Task - @example "mix ash_postgres.gen.resource MyApp.MyDomain" + @example "mix ash_postgres.gen.resources MyApp.MyDomain" @shortdoc "Generates resources based on a database schema" @@ -23,7 +23,7 @@ if Code.ensure_loaded?(Igniter) do - `repo`, `r` - The repo or repos to generate resources for, comma separated. Can be specified multiple times. Defaults to all repos. - `tables`, `t` - Defaults to `public.*`. The tables to generate resources for, comma separated. Can be specified multiple times. See the section on tables for more. - `skip-tables`, `s` - The tables to skip generating resources for, comma separated. Can be specified multiple times. See the section on tables for more. `schema_migrations` is always skipped. - - `snapshots-only` - Only generate snapshots for the generated resources, and not migraitons. + - `snapshots-only` - Only generate snapshots for the generated resources, and not migrations. - `extend`, `e` - Extension or extensions to apply to the generated resources. See `mix ash.patch.extend` for more. - `yes`, `y` - Answer yes (or skip) to all questions. - `default-actions` - Add default actions for each resource. Defaults to `true`. diff --git a/lib/mix/tasks/ash_postgres.generate_migrations.ex b/lib/mix/tasks/ash_postgres.generate_migrations.ex index 8431572c..028ac8bb 100644 --- a/lib/mix/tasks/ash_postgres.generate_migrations.ex +++ b/lib/mix/tasks/ash_postgres.generate_migrations.ex @@ -37,7 +37,7 @@ defmodule Mix.Tasks.AshPostgres.GenerateMigrations do Generally speaking, it is bad practice to drop columns when you deploy a change that would remove an attribute. The main reasons for this are backwards compatibility and rolling restarts. - If you deploy an attribute removal, and run migrations. Regardless of your deployment sstrategy, you + If you deploy an attribute removal, and run migrations. Regardless of your deployment strategy, you won't be able to roll back, because the data has been deleted. In a rolling restart situation, some of the machines/pods/whatever may still be running after the column has been deleted, causing errors. With this in mind, its best not to delete those columns until later, after the data has been confirmed unnecessary. diff --git a/lib/mix/tasks/ash_postgres.migrate.ex b/lib/mix/tasks/ash_postgres.migrate.ex index f8ab1d20..7da14a78 100644 --- a/lib/mix/tasks/ash_postgres.migrate.ex +++ b/lib/mix/tasks/ash_postgres.migrate.ex @@ -4,7 +4,7 @@ defmodule Mix.Tasks.AshPostgres.Migrate do import AshPostgres.Mix.Helpers, only: [migrations_path: 2, tenant_migrations_path: 2, tenants: 2] - @shortdoc "Runs the repository migrations for all repositories in the provided (or congigured) domains" + @shortdoc "Runs the repository migrations for all repositories in the provided (or configured) domains" @aliases [ n: :step, @@ -95,7 +95,7 @@ defmodule Mix.Tasks.AshPostgres.Migrate do * `--no-compile` - does not compile applications before migrating - * `--no-deps-check` - does not check depedendencies before migrating + * `--no-deps-check` - does not check dependencies before migrating * `--migrations-path` - the path to load the migrations from, defaults to `"priv/repo/migrations"`. This option may be given multiple times in which case the migrations diff --git a/lib/mix/tasks/ash_postgres.rollback.ex b/lib/mix/tasks/ash_postgres.rollback.ex index add81d59..d59fc1bf 100644 --- a/lib/mix/tasks/ash_postgres.rollback.ex +++ b/lib/mix/tasks/ash_postgres.rollback.ex @@ -30,7 +30,7 @@ defmodule Mix.Tasks.AshPostgres.Rollback do mix ash_postgres.rollback --to 20080906120000 ## Command line options - * `--domains` - the domains who's repos should be rolledback + * `--domains` - the domains whose repos should be rolled back * `--all` - revert all applied migrations * `--repo`, `-r` - the repo to rollback * `--step` / `-n` - revert n number of applied migrations diff --git a/lib/mix/tasks/ash_postgres.squash_snapshots.ex b/lib/mix/tasks/ash_postgres.squash_snapshots.ex index 1cf1fd68..84032c9b 100644 --- a/lib/mix/tasks/ash_postgres.squash_snapshots.ex +++ b/lib/mix/tasks/ash_postgres.squash_snapshots.ex @@ -28,7 +28,7 @@ defmodule Mix.Tasks.AshPostgres.SquashSnapshots do a remaining snapshot. `last` keeps the name of the last snapshot, `first` renames it to the previously first, `zero` sets name with fourteen zeros. * `--snapshot-path` - a custom path to stored snapshots. The default is "priv/resource_snapshots". - * `--quiet` - no messages will not be printed. + * `--quiet` - no messages will be printed. * `--dry-run` - no files are touched, instead prints folders that have snapshots to squash. * `--check` - no files are touched, instead returns an exit(1) code if there are snapshots to squash. """ From 25c924d43893c6a4ff78ed11dd281cc7054cb4b1 Mon Sep 17 00:00:00 2001 From: Barnabas Jovanovics Date: Fri, 13 Jun 2025 02:32:24 +0200 Subject: [PATCH 059/174] fix: double select error (#569) --- lib/data_layer.ex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/data_layer.ex b/lib/data_layer.ex index 10d1a17b..ffa72385 100644 --- a/lib/data_layer.ex +++ b/lib/data_layer.ex @@ -3423,7 +3423,7 @@ defmodule AshPostgres.DataLayer do ) query_with_select = - from(sub in query, + from(sub in Ecto.Query.exclude(query, :select), join: row in ^query.__ash_bindings__.resource, # why doesn't `.root_binding` work the way I expect it to here? on: ^dynamic, From c3304a13f42a072e3afc126ada37c03009409f2c Mon Sep 17 00:00:00 2001 From: Zach Daniel Date: Thu, 12 Jun 2025 20:33:06 -0400 Subject: [PATCH 060/174] chore: credo --- test/support/complex_calculations/resources/documentation.ex | 1 + 1 file changed, 1 insertion(+) diff --git a/test/support/complex_calculations/resources/documentation.ex b/test/support/complex_calculations/resources/documentation.ex index df6c5415..405c9dae 100644 --- a/test/support/complex_calculations/resources/documentation.ex +++ b/test/support/complex_calculations/resources/documentation.ex @@ -61,6 +61,7 @@ defmodule AshPostgres.Test.ComplexCalculations.Documentation do end defmodule AshPostgres.Test.TimezoneHelper do + @moduledoc false def seoul_time do # Fixed datetime for testing - equivalent to 2024-05-01 21:00:00 in Seoul (UTC+9) ~U[2024-05-01 12:00:00Z] |> DateTime.shift_zone!("Asia/Seoul") From d2f5d17db06091e04980def178a55c75f53c4893 Mon Sep 17 00:00:00 2001 From: Zach Daniel Date: Thu, 12 Jun 2025 20:34:02 -0400 Subject: [PATCH 061/174] chore: release version v2.6.7 --- CHANGELOG.md | 9 +++++++++ mix.exs | 2 +- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index cfda92aa..c9ac6016 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,15 @@ See [Conventional Commits](https://www.conventionalcommits.org) for commit guide +## [v2.6.7](https://github.com/ash-project/ash_postgres/compare/v2.6.6...v2.6.7) (2025-06-13) + + + + +### Bug Fixes: + +* double select error (#569) by Barnabas Jovanovics + ## [v2.6.6](https://github.com/ash-project/ash_postgres/compare/v2.6.5...v2.6.6) (2025-06-10) diff --git a/mix.exs b/mix.exs index cf243ab3..6f5a16cf 100644 --- a/mix.exs +++ b/mix.exs @@ -5,7 +5,7 @@ defmodule AshPostgres.MixProject do The PostgreSQL data layer for Ash Framework """ - @version "2.6.6" + @version "2.6.7" def project do [ From cb93a8f95be1bbf21b8fc23c5d44552b3521936f Mon Sep 17 00:00:00 2001 From: Rebecca Le <543859+sevenseacat@users.noreply.github.com> Date: Wed, 18 Jun 2025 01:06:45 +0800 Subject: [PATCH 062/174] docs: Add minimum supported PostgreSQL version to README (#570) --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 51f74e61..1bef9edc 100644 --- a/README.md +++ b/README.md @@ -10,6 +10,8 @@ Welcome! `AshPostgres` is the PostgreSQL data layer for [Ash Framework](https://hexdocs.pm/ash). +Minimum required PostgreSQL version: `13.0` + ## Tutorials - [Get Started](documentation/tutorials/get-started-with-ash-postgres.md) From f9d13294c29f786c95e7f55cfb627bad13deae3d Mon Sep 17 00:00:00 2001 From: Zach Daniel Date: Tue, 17 Jun 2025 14:51:49 -0400 Subject: [PATCH 063/174] fix: ensure prefix is set even with create_schemas_in_migrations? false --- lib/migration_generator/phase.ex | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/lib/migration_generator/phase.ex b/lib/migration_generator/phase.ex index 6be7dd81..a4e5861b 100644 --- a/lib/migration_generator/phase.ex +++ b/lib/migration_generator/phase.ex @@ -19,12 +19,18 @@ defmodule AshPostgres.MigrationGenerator.Phase do Enum.map_join(operations, "\n", fn operation -> operation.__struct__.up(operation) end) <> "\nend" else - {pre_create, opts} = + pre_create = if schema && repo.create_schemas_in_migrations?() do - {"execute(\"CREATE SCHEMA IF NOT EXISTS #{schema}\")" <> "\n\n", - ", prefix: \"#{schema}\""} + "execute(\"CREATE SCHEMA IF NOT EXISTS #{schema}\")" <> "\n\n" else - {"", ""} + "" + end + + opts = + if schema do + ", prefix: \"#{schema}\"" + else + "" end pre_create <> From 46f325e6e2902fcb3a7737f79d16568aaacba2e5 Mon Sep 17 00:00:00 2001 From: Zach Daniel Date: Tue, 17 Jun 2025 15:02:32 -0400 Subject: [PATCH 064/174] chore: update deps --- mix.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mix.lock b/mix.lock index d7a02173..69d19586 100644 --- a/mix.lock +++ b/mix.lock @@ -1,6 +1,6 @@ %{ - "ash": {:hex, :ash, "3.5.18", "3fafe7b0c67fb863409ea06fd9ca0f1cb681b4e798973989aabedc42a82e8f2a", [:mix], [{:decimal, "~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:ecto, "~> 3.7", [hex: :ecto, repo: "hexpm", optional: false]}, {:ets, "~> 0.8", [hex: :ets, repo: "hexpm", optional: false]}, {:igniter, ">= 0.6.4 and < 1.0.0-0", [hex: :igniter, repo: "hexpm", optional: true]}, {:jason, ">= 1.0.0", [hex: :jason, repo: "hexpm", optional: false]}, {:picosat_elixir, "~> 0.2", [hex: :picosat_elixir, repo: "hexpm", optional: true]}, {:plug, ">= 0.0.0", [hex: :plug, repo: "hexpm", optional: true]}, {:reactor, "~> 0.11", [hex: :reactor, repo: "hexpm", optional: false]}, {:simple_sat, ">= 0.1.1 and < 1.0.0-0", [hex: :simple_sat, repo: "hexpm", optional: true]}, {:spark, ">= 2.2.65 and < 3.0.0-0", [hex: :spark, repo: "hexpm", optional: false]}, {:splode, ">= 0.2.6 and < 1.0.0-0", [hex: :splode, repo: "hexpm", optional: false]}, {:stream_data, "~> 1.0", [hex: :stream_data, repo: "hexpm", optional: false]}, {:telemetry, "~> 1.1", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "52e3156f832026aeef0ca4a705741d29d5a94a7a393ab280b694a2d3d43bcf12"}, - "ash_sql": {:hex, :ash_sql, "0.2.79", "1378bb33a7469f50e2854b7490add380ad2cbf73dda9d5b373194097ad03d3eb", [:mix], [{:ash, "~> 3.5", [hex: :ash, repo: "hexpm", optional: false]}, {:ecto, "~> 3.9", [hex: :ecto, repo: "hexpm", optional: false]}, {:ecto_sql, "~> 3.9", [hex: :ecto_sql, repo: "hexpm", optional: false]}], "hexpm", "7ef10d909f238912b4be7aeb587ae32cce7e42d136bf94da07bc7e54a475cdde"}, + "ash": {:hex, :ash, "3.5.21", "389303c193962d67fd59da18a3557f5015fdfdaeddaa77150db539bc7203d1a1", [:mix], [{:decimal, "~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:ecto, "~> 3.7", [hex: :ecto, repo: "hexpm", optional: false]}, {:ets, "~> 0.8", [hex: :ets, repo: "hexpm", optional: false]}, {:igniter, ">= 0.6.4 and < 1.0.0-0", [hex: :igniter, repo: "hexpm", optional: true]}, {:jason, ">= 1.0.0", [hex: :jason, repo: "hexpm", optional: false]}, {:picosat_elixir, "~> 0.2", [hex: :picosat_elixir, repo: "hexpm", optional: true]}, {:plug, ">= 0.0.0", [hex: :plug, repo: "hexpm", optional: true]}, {:reactor, "~> 0.11", [hex: :reactor, repo: "hexpm", optional: false]}, {:simple_sat, ">= 0.1.1 and < 1.0.0-0", [hex: :simple_sat, repo: "hexpm", optional: true]}, {:spark, ">= 2.2.65 and < 3.0.0-0", [hex: :spark, repo: "hexpm", optional: false]}, {:splode, ">= 0.2.6 and < 1.0.0-0", [hex: :splode, repo: "hexpm", optional: false]}, {:stream_data, "~> 1.0", [hex: :stream_data, repo: "hexpm", optional: false]}, {:telemetry, "~> 1.1", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "cb90005d1972e22d0d2ae514394e43e0d67cce18c4485595aa3d3e4bbf25260f"}, + "ash_sql": {:hex, :ash_sql, "0.2.81", "cdc7767400425bb11928ba76e0cdc66a82ff9eabea59af21eb474a60732815ce", [:mix], [{:ash, "~> 3.5", [hex: :ash, repo: "hexpm", optional: false]}, {:ecto, "~> 3.9", [hex: :ecto, repo: "hexpm", optional: false]}, {:ecto_sql, "~> 3.9", [hex: :ecto_sql, repo: "hexpm", optional: false]}], "hexpm", "c2ccef696620852c93cc3fb3bc564200b910a3487266f54b51c444a7e5dfa3d0"}, "benchee": {:hex, :benchee, "1.4.0", "9f1f96a30ac80bab94faad644b39a9031d5632e517416a8ab0a6b0ac4df124ce", [:mix], [{:deep_merge, "~> 1.0", [hex: :deep_merge, repo: "hexpm", optional: false]}, {:statistex, "~> 1.0", [hex: :statistex, repo: "hexpm", optional: false]}, {:table, "~> 0.1.0", [hex: :table, repo: "hexpm", optional: true]}], "hexpm", "299cd10dd8ce51c9ea3ddb74bb150f93d25e968f93e4c1fa31698a8e4fa5d715"}, "bunt": {:hex, :bunt, "1.0.0", "081c2c665f086849e6d57900292b3a161727ab40431219529f13c4ddcf3e7a44", [:mix], [], "hexpm", "dc5f86aa08a5f6fa6b8096f0735c4e76d54ae5c9fa2c143e5a1fc7c1cd9bb6b5"}, "credo": {:hex, :credo, "1.7.12", "9e3c20463de4b5f3f23721527fcaf16722ec815e70ff6c60b86412c695d426c1", [:mix], [{:bunt, "~> 0.2.1 or ~> 1.0", [hex: :bunt, repo: "hexpm", optional: false]}, {:file_system, "~> 0.2 or ~> 1.0", [hex: :file_system, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "8493d45c656c5427d9c729235b99d498bd133421f3e0a683e5c1b561471291e5"}, From db2d60d8c2196545680724d5190d6ff587d7f68a Mon Sep 17 00:00:00 2001 From: Zach Daniel Date: Tue, 17 Jun 2025 21:34:41 -0400 Subject: [PATCH 065/174] test: add tests for new boolean expressions --- .../test_repo/posts/20250618011917.json | 690 ++++++++++++++++++ .../20250618011917_migrate_resources56.exs | 21 + test/filter_test.exs | 33 + test/support/resources/post.ex | 1 + 4 files changed, 745 insertions(+) create mode 100644 priv/resource_snapshots/test_repo/posts/20250618011917.json create mode 100644 priv/test_repo/migrations/20250618011917_migrate_resources56.exs diff --git a/priv/resource_snapshots/test_repo/posts/20250618011917.json b/priv/resource_snapshots/test_repo/posts/20250618011917.json new file mode 100644 index 00000000..5031b3cf --- /dev/null +++ b/priv/resource_snapshots/test_repo/posts/20250618011917.json @@ -0,0 +1,690 @@ +{ + "attributes": [ + { + "allow_nil?": false, + "default": "fragment(\"gen_random_uuid()\")", + "generated?": false, + "precision": null, + "primary_key?": true, + "references": null, + "scale": null, + "size": null, + "source": "id", + "type": "uuid" + }, + { + "allow_nil?": false, + "default": "1", + "generated?": false, + "precision": null, + "primary_key?": false, + "references": null, + "scale": null, + "size": null, + "source": "version", + "type": "bigint" + }, + { + "allow_nil?": true, + "default": "nil", + "generated?": false, + "precision": null, + "primary_key?": false, + "references": null, + "scale": null, + "size": null, + "source": "title_column", + "type": "text" + }, + { + "allow_nil?": true, + "default": "nil", + "generated?": false, + "precision": null, + "primary_key?": false, + "references": null, + "scale": null, + "size": null, + "source": "not_selected_by_default", + "type": "text" + }, + { + "allow_nil?": true, + "default": "nil", + "generated?": false, + "precision": null, + "primary_key?": false, + "references": null, + "scale": null, + "size": null, + "source": "datetime", + "type": "timestamptz(6)" + }, + { + "allow_nil?": true, + "default": "nil", + "generated?": false, + "precision": null, + "primary_key?": false, + "references": null, + "scale": null, + "size": null, + "source": "score", + "type": "bigint" + }, + { + "allow_nil?": true, + "default": "nil", + "generated?": false, + "precision": null, + "primary_key?": false, + "references": null, + "scale": null, + "size": null, + "source": "limited_score", + "type": "bigint" + }, + { + "allow_nil?": true, + "default": "nil", + "generated?": false, + "precision": null, + "primary_key?": false, + "references": null, + "scale": null, + "size": null, + "source": "public", + "type": "boolean" + }, + { + "allow_nil?": false, + "default": "true", + "generated?": false, + "precision": null, + "primary_key?": false, + "references": null, + "scale": null, + "size": null, + "source": "is_special", + "type": "boolean" + }, + { + "allow_nil?": true, + "default": "nil", + "generated?": false, + "precision": null, + "primary_key?": false, + "references": null, + "scale": null, + "size": null, + "source": "category", + "type": "citext" + }, + { + "allow_nil?": true, + "default": "\"sponsored\"", + "generated?": false, + "precision": null, + "primary_key?": false, + "references": null, + "scale": null, + "size": null, + "source": "type", + "type": "text" + }, + { + "allow_nil?": true, + "default": "nil", + "generated?": false, + "precision": null, + "primary_key?": false, + "references": null, + "scale": null, + "size": null, + "source": "price", + "type": "bigint" + }, + { + "allow_nil?": true, + "default": "\"0\"", + "generated?": false, + "precision": null, + "primary_key?": false, + "references": null, + "scale": null, + "size": null, + "source": "decimal", + "type": "decimal" + }, + { + "allow_nil?": true, + "default": "nil", + "generated?": false, + "precision": null, + "primary_key?": false, + "references": null, + "scale": null, + "size": null, + "source": "status", + "type": "text" + }, + { + "allow_nil?": true, + "default": "nil", + "generated?": false, + "precision": null, + "primary_key?": false, + "references": null, + "scale": null, + "size": null, + "source": "status_enum", + "type": "status" + }, + { + "allow_nil?": true, + "default": "nil", + "generated?": false, + "precision": null, + "primary_key?": false, + "references": null, + "scale": null, + "size": null, + "source": "metadata", + "type": "map" + }, + { + "allow_nil?": false, + "default": "2", + "generated?": false, + "precision": null, + "primary_key?": false, + "references": null, + "scale": null, + "size": null, + "source": "constrained_int", + "type": "bigint" + }, + { + "allow_nil?": true, + "default": "nil", + "generated?": false, + "precision": null, + "primary_key?": false, + "references": null, + "scale": null, + "size": null, + "source": "point", + "type": [ + "array", + "float" + ] + }, + { + "allow_nil?": true, + "default": "nil", + "generated?": false, + "precision": null, + "primary_key?": false, + "references": null, + "scale": null, + "size": null, + "source": "composite_point", + "type": "custom_point" + }, + { + "allow_nil?": true, + "default": "nil", + "generated?": false, + "precision": null, + "primary_key?": false, + "references": null, + "scale": null, + "size": null, + "source": "string_point", + "type": "text" + }, + { + "allow_nil?": true, + "default": "nil", + "generated?": false, + "precision": null, + "primary_key?": false, + "references": null, + "scale": null, + "size": null, + "source": "person_detail", + "type": "map" + }, + { + "allow_nil?": true, + "default": "nil", + "generated?": false, + "precision": null, + "primary_key?": false, + "references": null, + "scale": null, + "size": null, + "source": "stuff", + "type": "map" + }, + { + "allow_nil?": true, + "default": "nil", + "generated?": false, + "precision": null, + "primary_key?": false, + "references": null, + "scale": null, + "size": null, + "source": "list_of_stuff", + "type": [ + "array", + "map" + ] + }, + { + "allow_nil?": true, + "default": "nil", + "generated?": false, + "precision": null, + "primary_key?": false, + "references": null, + "scale": null, + "size": null, + "source": "uniq_one", + "type": "text" + }, + { + "allow_nil?": true, + "default": "nil", + "generated?": false, + "precision": null, + "primary_key?": false, + "references": null, + "scale": null, + "size": null, + "source": "uniq_two", + "type": "text" + }, + { + "allow_nil?": true, + "default": "nil", + "generated?": false, + "precision": null, + "primary_key?": false, + "references": null, + "scale": null, + "size": null, + "source": "uniq_custom_one", + "type": "text" + }, + { + "allow_nil?": true, + "default": "nil", + "generated?": false, + "precision": null, + "primary_key?": false, + "references": null, + "scale": null, + "size": null, + "source": "uniq_custom_two", + "type": "text" + }, + { + "allow_nil?": true, + "default": "nil", + "generated?": false, + "precision": null, + "primary_key?": false, + "references": null, + "scale": null, + "size": null, + "source": "uniq_on_upper", + "type": "text" + }, + { + "allow_nil?": true, + "default": "nil", + "generated?": false, + "precision": null, + "primary_key?": false, + "references": null, + "scale": null, + "size": null, + "source": "uniq_if_contains_foo", + "type": "text" + }, + { + "allow_nil?": true, + "default": "nil", + "generated?": false, + "precision": null, + "primary_key?": false, + "references": null, + "scale": null, + "size": null, + "source": "model", + "type": "map" + }, + { + "allow_nil?": true, + "default": "nil", + "generated?": false, + "precision": null, + "primary_key?": false, + "references": null, + "scale": null, + "size": null, + "source": "list_containing_nils", + "type": [ + "array", + "text" + ] + }, + { + "allow_nil?": true, + "default": "nil", + "generated?": false, + "precision": null, + "primary_key?": false, + "references": null, + "scale": null, + "size": null, + "source": "ltree_unescaped", + "type": "ltree" + }, + { + "allow_nil?": true, + "default": "nil", + "generated?": false, + "precision": null, + "primary_key?": false, + "references": null, + "scale": null, + "size": null, + "source": "ltree_escaped", + "type": "ltree" + }, + { + "allow_nil?": false, + "default": "fragment(\"(now() AT TIME ZONE 'utc')\")", + "generated?": false, + "precision": null, + "primary_key?": false, + "references": null, + "scale": null, + "size": null, + "source": "created_at", + "type": "utc_datetime_usec" + }, + { + "allow_nil?": false, + "default": "fragment(\"(now() AT TIME ZONE 'utc')\")", + "generated?": false, + "precision": null, + "primary_key?": false, + "references": null, + "scale": null, + "size": null, + "source": "updated_at", + "type": "timestamptz(6)" + }, + { + "allow_nil?": true, + "default": "nil", + "generated?": false, + "precision": null, + "primary_key?": false, + "references": { + "deferrable": false, + "destination_attribute": "id", + "destination_attribute_default": null, + "destination_attribute_generated": null, + "index?": false, + "match_type": null, + "match_with": null, + "multitenancy": { + "attribute": null, + "global": null, + "strategy": null + }, + "name": "posts_organization_id_fkey", + "on_delete": null, + "on_update": null, + "primary_key?": true, + "schema": "public", + "table": "orgs" + }, + "scale": null, + "size": null, + "source": "organization_id", + "type": "uuid" + }, + { + "allow_nil?": true, + "default": "nil", + "generated?": false, + "precision": null, + "primary_key?": false, + "references": { + "deferrable": false, + "destination_attribute": "id", + "destination_attribute_default": null, + "destination_attribute_generated": null, + "index?": false, + "match_type": null, + "match_with": null, + "multitenancy": { + "attribute": null, + "global": null, + "strategy": null + }, + "name": "posts_parent_post_id_fkey", + "on_delete": null, + "on_update": null, + "primary_key?": true, + "schema": "public", + "table": "posts" + }, + "scale": null, + "size": null, + "source": "parent_post_id", + "type": "uuid" + }, + { + "allow_nil?": true, + "default": "nil", + "generated?": false, + "precision": null, + "primary_key?": false, + "references": { + "deferrable": false, + "destination_attribute": "id", + "destination_attribute_default": null, + "destination_attribute_generated": null, + "index?": false, + "match_type": null, + "match_with": null, + "multitenancy": { + "attribute": null, + "global": null, + "strategy": null + }, + "name": "posts_author_id_fkey", + "on_delete": null, + "on_update": null, + "primary_key?": true, + "schema": "public", + "table": "authors" + }, + "scale": null, + "size": null, + "source": "author_id", + "type": "uuid" + }, + { + "allow_nil?": true, + "default": "nil", + "generated?": false, + "precision": null, + "primary_key?": false, + "references": { + "deferrable": false, + "destination_attribute": "id", + "destination_attribute_default": null, + "destination_attribute_generated": null, + "index?": false, + "match_type": null, + "match_with": null, + "multitenancy": { + "attribute": null, + "global": null, + "strategy": null + }, + "name": "posts_db_point_id_fkey", + "on_delete": null, + "on_update": null, + "primary_key?": true, + "schema": "public", + "table": "points" + }, + "scale": null, + "size": null, + "source": "db_point_id", + "type": [ + "array", + "float" + ] + }, + { + "allow_nil?": true, + "default": "nil", + "generated?": false, + "precision": null, + "primary_key?": false, + "references": { + "deferrable": false, + "destination_attribute": "id", + "destination_attribute_default": null, + "destination_attribute_generated": null, + "index?": false, + "match_type": null, + "match_with": null, + "multitenancy": { + "attribute": null, + "global": null, + "strategy": null + }, + "name": "posts_db_string_point_id_fkey", + "on_delete": null, + "on_update": null, + "primary_key?": true, + "schema": "public", + "table": "string_points" + }, + "scale": null, + "size": null, + "source": "db_string_point_id", + "type": "text" + } + ], + "base_filter": "type = 'sponsored'", + "check_constraints": [ + { + "attribute": [ + "price" + ], + "base_filter": "type = 'sponsored'", + "check": "price > 0", + "name": "price_must_be_positive" + } + ], + "custom_indexes": [ + { + "all_tenants?": false, + "concurrently": true, + "error_fields": [ + "uniq_custom_one", + "uniq_custom_two" + ], + "fields": [ + { + "type": "atom", + "value": "uniq_custom_one" + }, + { + "type": "atom", + "value": "uniq_custom_two" + } + ], + "include": null, + "message": "dude what the heck", + "name": null, + "nulls_distinct": true, + "prefix": null, + "table": null, + "unique": true, + "using": null, + "where": null + } + ], + "custom_statements": [], + "has_create_action": true, + "hash": "28B63D8AA18EE499B2A10DFF793995FF00B811F6CB45E01EBFEF15516D305DF8", + "identities": [ + { + "all_tenants?": false, + "base_filter": "type = 'sponsored'", + "index_name": "posts_uniq_if_contains_foo_index", + "keys": [ + { + "type": "atom", + "value": "uniq_if_contains_foo" + } + ], + "name": "uniq_if_contains_foo", + "nils_distinct?": true, + "where": "(uniq_if_contains_foo LIKE '%foo%')" + }, + { + "all_tenants?": false, + "base_filter": "type = 'sponsored'", + "index_name": "posts_uniq_on_upper_index", + "keys": [ + { + "type": "string", + "value": "(UPPER(uniq_on_upper))" + } + ], + "name": "uniq_on_upper", + "nils_distinct?": true, + "where": null + }, + { + "all_tenants?": false, + "base_filter": "type = 'sponsored'", + "index_name": "posts_uniq_one_and_two_index", + "keys": [ + { + "type": "atom", + "value": "uniq_one" + }, + { + "type": "atom", + "value": "uniq_two" + } + ], + "name": "uniq_one_and_two", + "nils_distinct?": true, + "where": null + } + ], + "multitenancy": { + "attribute": null, + "global": null, + "strategy": null + }, + "repo": "Elixir.AshPostgres.TestRepo", + "schema": null, + "table": "posts" +} \ No newline at end of file diff --git a/priv/test_repo/migrations/20250618011917_migrate_resources56.exs b/priv/test_repo/migrations/20250618011917_migrate_resources56.exs new file mode 100644 index 00000000..641aa008 --- /dev/null +++ b/priv/test_repo/migrations/20250618011917_migrate_resources56.exs @@ -0,0 +1,21 @@ +defmodule AshPostgres.TestRepo.Migrations.MigrateResources56 do + @moduledoc """ + Updates resources based on their most recent snapshots. + + This file was autogenerated with `mix ash_postgres.generate_migrations` + """ + + use Ecto.Migration + + def up do + alter table(:posts) do + add(:is_special, :boolean, null: false, default: true) + end + end + + def down do + alter table(:posts) do + remove(:is_special) + end + end +end diff --git a/test/filter_test.exs b/test/filter_test.exs index 261dd0bf..d0332301 100644 --- a/test/filter_test.exs +++ b/test/filter_test.exs @@ -34,6 +34,39 @@ defmodule AshPostgres.FilterTest do assert String.contains?(query, "(p0.\"version\"::bigint = $2::bigint)") end + + test "it uses coalesce to optimize the || operator for non-booleans" do + {query, _vars} = + Post + |> Ash.Query.filter((version || 10) == 20) + |> Ash.data_layer_query!() + |> Map.get(:query) + |> then(&AshPostgres.TestRepo.to_sql(:all, &1)) + + assert String.contains?(query, "(coalesce(p0.\"version\"::bigint, $2::bigint)") + end + + test "it uses OR to optimize the || operator for booleans" do + {query, _vars} = + Post + |> Ash.Query.filter(is_special || true) + |> Ash.data_layer_query!() + |> Map.get(:query) + |> then(&AshPostgres.TestRepo.to_sql(:all, &1)) + + assert String.contains?(query, "(p0.\"is_special\"::boolean OR $2::boolean)") + end + + test "it uses AND to optimize the && operator for booleans" do + {query, _vars} = + Post + |> Ash.Query.filter(is_special && public) + |> Ash.data_layer_query!() + |> Map.get(:query) + |> then(&AshPostgres.TestRepo.to_sql(:all, &1)) + + assert String.contains?(query, "(p0.\"is_special\"::boolean AND p0.\"public\"::boolean)") + end end describe "ci_string argument casting" do diff --git a/test/support/resources/post.ex b/test/support/resources/post.ex index a2c3ceea..f22d3fef 100644 --- a/test/support/resources/post.ex +++ b/test/support/resources/post.ex @@ -509,6 +509,7 @@ defmodule AshPostgres.Test.Post do attribute(:limited_score, :integer, public?: true, constraints: [min: 0, max: 100]) attribute(:public, :boolean, public?: true) + attribute(:is_special, :boolean, public?: true, allow_nil?: false, default: true) attribute(:category, CiCategory, public?: true) attribute(:type, :atom, default: :sponsored, writable?: false, public?: false) attribute(:price, :integer, public?: true) From 0994310ef1c608d9609509e9d36948ca801ddc56 Mon Sep 17 00:00:00 2001 From: Zach Daniel Date: Wed, 18 Jun 2025 14:32:29 -0400 Subject: [PATCH 066/174] chore: more literal -> identifier --- documentation/topics/advanced/manual-relationships.md | 2 +- lib/data_layer.ex | 6 +++--- lib/sql_implementation.ex | 2 +- mix.exs | 4 ++-- mix.lock | 4 ++-- 5 files changed, 9 insertions(+), 9 deletions(-) diff --git a/documentation/topics/advanced/manual-relationships.md b/documentation/topics/advanced/manual-relationships.md index 2da54328..a7adaac3 100644 --- a/documentation/topics/advanced/manual-relationships.md +++ b/documentation/topics/advanced/manual-relationships.md @@ -240,7 +240,7 @@ defmodule MyApp.Employee.ManagedEmployees do employee_keys = Employee.__schema__(:fields) cte_name_ref = - from(cte in fragment("?", literal(^cte_name)), select: map(cte, ^employee_keys)) + from(cte in fragment("?", identifier(^cte_name)), select: map(cte, ^employee_keys)) recursion_query = query diff --git a/lib/data_layer.ex b/lib/data_layer.ex index ffa72385..ddfdc060 100644 --- a/lib/data_layer.ex +++ b/lib/data_layer.ex @@ -2109,7 +2109,7 @@ defmodule AshPostgres.DataLayer do |> Enum.map(fn upsert_field -> # for safety, we check once more at the end that all values in # upsert_fields are names of attributes. This is because - # below we use `literal/1` to bring them into the query + # below we use `identifier/1` to bring them into the query if is_nil(resource.__schema__(:type, upsert_field)) do raise "Only attribute names can be used in upsert_fields" end @@ -2122,7 +2122,7 @@ defmodule AshPostgres.DataLayer do [], fragment( "COALESCE(EXCLUDED.?, ?)", - literal(^to_string(get_source_for_upsert_field(upsert_field, resource))), + identifier(^to_string(get_source_for_upsert_field(upsert_field, resource))), ^default ) )} @@ -2136,7 +2136,7 @@ defmodule AshPostgres.DataLayer do [], fragment( "EXCLUDED.?", - literal(^to_string(get_source_for_upsert_field(upsert_field, resource))) + identifier(^to_string(get_source_for_upsert_field(upsert_field, resource))) ) )} end diff --git a/lib/sql_implementation.ex b/lib/sql_implementation.ex index a91b8786..99d80f8f 100644 --- a/lib/sql_implementation.ex +++ b/lib/sql_implementation.ex @@ -56,7 +56,7 @@ defmodule AshPostgres.SqlImplementation do [], fragment( "EXCLUDED.?", - literal( + identifier( ^to_string( AshPostgres.DataLayer.get_source_for_upsert_field( attribute, diff --git a/mix.exs b/mix.exs index 6f5a16cf..a4db2bc6 100644 --- a/mix.exs +++ b/mix.exs @@ -169,8 +169,8 @@ defmodule AshPostgres.MixProject do {:ash, ash_version("~> 3.5 and >= 3.5.13")}, {:ash_sql, ash_sql_version("~> 0.2 and >= 0.2.72")}, {:igniter, "~> 0.6", optional: true}, - {:ecto_sql, "~> 3.12"}, - {:ecto, "~> 3.12 and >= 3.12.1"}, + {:ecto_sql, "~> 3.13"}, + {:ecto, "~> 3.13"}, {:jason, "~> 1.0"}, {:postgrex, ">= 0.0.0"}, # dev/test dependencies diff --git a/mix.lock b/mix.lock index 69d19586..693c305b 100644 --- a/mix.lock +++ b/mix.lock @@ -9,9 +9,9 @@ "deep_merge": {:hex, :deep_merge, "1.0.0", "b4aa1a0d1acac393bdf38b2291af38cb1d4a52806cf7a4906f718e1feb5ee961", [:mix], [], "hexpm", "ce708e5f094b9cd4e8f2be4f00d2f4250c4095be93f8cd6d018c753894885430"}, "dialyxir": {:hex, :dialyxir, "1.4.5", "ca1571ac18e0f88d4ab245f0b60fa31ff1b12cbae2b11bd25d207f865e8ae78a", [:mix], [{:erlex, ">= 0.2.7", [hex: :erlex, repo: "hexpm", optional: false]}], "hexpm", "b0fb08bb8107c750db5c0b324fa2df5ceaa0f9307690ee3c1f6ba5b9eb5d35c3"}, "earmark_parser": {:hex, :earmark_parser, "1.4.44", "f20830dd6b5c77afe2b063777ddbbff09f9759396500cdbe7523efd58d7a339c", [:mix], [], "hexpm", "4778ac752b4701a5599215f7030989c989ffdc4f6df457c5f36938cc2d2a2750"}, - "ecto": {:hex, :ecto, "3.12.6", "8bf762dc5b87d85b7aca7ad5fe31ef8142a84cea473a3381eb933bd925751300", [:mix], [{:decimal, "~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "4c0cba01795463eebbcd9e4b5ef53c1ee8e68b9c482baef2a80de5a61e7a57fe"}, + "ecto": {:hex, :ecto, "3.13.0", "7528ef4f3a4cdcfebeb7eb6545806c8109529b385a69f701fc3d77b5b8bde6e7", [:mix], [{:decimal, "~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "061f095f1cc097f71f743b500affc792d6869df22b1946a73ab5495eb9b4a280"}, "ecto_dev_logger": {:hex, :ecto_dev_logger, "0.14.1", "af385ce1af1c4210ad67a4c46b985c370713446a179144a1da2885138c9fb242", [:mix], [{:ecto, "~> 3.7", [hex: :ecto, repo: "hexpm", optional: false]}, {:geo, "~> 3.5 or ~> 4.0", [hex: :geo, repo: "hexpm", optional: true]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "14a64ebae728b3c45db6ba8bb185979c8e01fc1b0d3d1d9c01c7a2b798e8c698"}, - "ecto_sql": {:hex, :ecto_sql, "3.12.1", "c0d0d60e85d9ff4631f12bafa454bc392ce8b9ec83531a412c12a0d415a3a4d0", [:mix], [{:db_connection, "~> 2.4.1 or ~> 2.5", [hex: :db_connection, repo: "hexpm", optional: false]}, {:ecto, "~> 3.12", [hex: :ecto, repo: "hexpm", optional: false]}, {:myxql, "~> 0.7", [hex: :myxql, repo: "hexpm", optional: true]}, {:postgrex, "~> 0.19 or ~> 1.0", [hex: :postgrex, repo: "hexpm", optional: true]}, {:tds, "~> 2.1.1 or ~> 2.2", [hex: :tds, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4.0 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "aff5b958a899762c5f09028c847569f7dfb9cc9d63bdb8133bff8a5546de6bf5"}, + "ecto_sql": {:hex, :ecto_sql, "3.13.0", "a732428f38ce86612a2c34a1ea5d0a9642a5a71f044052007fd2f2e815707990", [:mix], [{:db_connection, "~> 2.4.1 or ~> 2.5", [hex: :db_connection, repo: "hexpm", optional: false]}, {:ecto, "~> 3.13.0", [hex: :ecto, repo: "hexpm", optional: false]}, {:myxql, "~> 0.7", [hex: :myxql, repo: "hexpm", optional: true]}, {:postgrex, "~> 0.19 or ~> 1.0", [hex: :postgrex, repo: "hexpm", optional: true]}, {:tds, "~> 2.1.1 or ~> 2.2", [hex: :tds, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4.0 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "5ce13085122a0871d93ea9ba1a886447d89c07f3b563e19e0b3dcdf201ed9fe9"}, "eflame": {:hex, :eflame, "1.0.1", "0664d287e39eef3c413749254b3af5f4f8b00be71c1af67d325331c4890be0fc", [:mix], [], "hexpm", "e0b08854a66f9013129de0b008488f3411ae9b69b902187837f994d7a99cf04e"}, "erlex": {:hex, :erlex, "0.2.7", "810e8725f96ab74d17aac676e748627a07bc87eb950d2b83acd29dc047a30595", [:mix], [], "hexpm", "3ed95f79d1a844c3f6bf0cea61e0d5612a42ce56da9c03f01df538685365efb0"}, "ets": {:hex, :ets, "0.9.0", "79c6a6c205436780486f72d84230c6cba2f8a9920456750ddd1e47389107d5fd", [:mix], [], "hexpm", "2861fdfb04bcaeff370f1a5904eec864f0a56dcfebe5921ea9aadf2a481c822b"}, From ebc3101400e764f1b83c0020c9615a0264de365c Mon Sep 17 00:00:00 2001 From: Zach Daniel Date: Wed, 18 Jun 2025 19:49:53 -0400 Subject: [PATCH 067/174] chore: update deps --- mix.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/mix.lock b/mix.lock index 693c305b..6b5900db 100644 --- a/mix.lock +++ b/mix.lock @@ -1,6 +1,6 @@ %{ "ash": {:hex, :ash, "3.5.21", "389303c193962d67fd59da18a3557f5015fdfdaeddaa77150db539bc7203d1a1", [:mix], [{:decimal, "~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:ecto, "~> 3.7", [hex: :ecto, repo: "hexpm", optional: false]}, {:ets, "~> 0.8", [hex: :ets, repo: "hexpm", optional: false]}, {:igniter, ">= 0.6.4 and < 1.0.0-0", [hex: :igniter, repo: "hexpm", optional: true]}, {:jason, ">= 1.0.0", [hex: :jason, repo: "hexpm", optional: false]}, {:picosat_elixir, "~> 0.2", [hex: :picosat_elixir, repo: "hexpm", optional: true]}, {:plug, ">= 0.0.0", [hex: :plug, repo: "hexpm", optional: true]}, {:reactor, "~> 0.11", [hex: :reactor, repo: "hexpm", optional: false]}, {:simple_sat, ">= 0.1.1 and < 1.0.0-0", [hex: :simple_sat, repo: "hexpm", optional: true]}, {:spark, ">= 2.2.65 and < 3.0.0-0", [hex: :spark, repo: "hexpm", optional: false]}, {:splode, ">= 0.2.6 and < 1.0.0-0", [hex: :splode, repo: "hexpm", optional: false]}, {:stream_data, "~> 1.0", [hex: :stream_data, repo: "hexpm", optional: false]}, {:telemetry, "~> 1.1", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "cb90005d1972e22d0d2ae514394e43e0d67cce18c4485595aa3d3e4bbf25260f"}, - "ash_sql": {:hex, :ash_sql, "0.2.81", "cdc7767400425bb11928ba76e0cdc66a82ff9eabea59af21eb474a60732815ce", [:mix], [{:ash, "~> 3.5", [hex: :ash, repo: "hexpm", optional: false]}, {:ecto, "~> 3.9", [hex: :ecto, repo: "hexpm", optional: false]}, {:ecto_sql, "~> 3.9", [hex: :ecto_sql, repo: "hexpm", optional: false]}], "hexpm", "c2ccef696620852c93cc3fb3bc564200b910a3487266f54b51c444a7e5dfa3d0"}, + "ash_sql": {:hex, :ash_sql, "0.2.82", "a4fe01ccd2c29ce43af50233e63cd1298735b68ee2c22a1cbb0baa5f31f78ab5", [:mix], [{:ash, "~> 3.5", [hex: :ash, repo: "hexpm", optional: false]}, {:ecto, "~> 3.9", [hex: :ecto, repo: "hexpm", optional: false]}, {:ecto_sql, "~> 3.9", [hex: :ecto_sql, repo: "hexpm", optional: false]}], "hexpm", "a31f1065b72387b7a19d4e357f06904910b4c4fc8986209975786015f40cf795"}, "benchee": {:hex, :benchee, "1.4.0", "9f1f96a30ac80bab94faad644b39a9031d5632e517416a8ab0a6b0ac4df124ce", [:mix], [{:deep_merge, "~> 1.0", [hex: :deep_merge, repo: "hexpm", optional: false]}, {:statistex, "~> 1.0", [hex: :statistex, repo: "hexpm", optional: false]}, {:table, "~> 0.1.0", [hex: :table, repo: "hexpm", optional: true]}], "hexpm", "299cd10dd8ce51c9ea3ddb74bb150f93d25e968f93e4c1fa31698a8e4fa5d715"}, "bunt": {:hex, :bunt, "1.0.0", "081c2c665f086849e6d57900292b3a161727ab40431219529f13c4ddcf3e7a44", [:mix], [], "hexpm", "dc5f86aa08a5f6fa6b8096f0735c4e76d54ae5c9fa2c143e5a1fc7c1cd9bb6b5"}, "credo": {:hex, :credo, "1.7.12", "9e3c20463de4b5f3f23721527fcaf16722ec815e70ff6c60b86412c695d426c1", [:mix], [{:bunt, "~> 0.2.1 or ~> 1.0", [hex: :bunt, repo: "hexpm", optional: false]}, {:file_system, "~> 0.2 or ~> 1.0", [hex: :file_system, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "8493d45c656c5427d9c729235b99d498bd133421f3e0a683e5c1b561471291e5"}, @@ -38,13 +38,13 @@ "nimble_pool": {:hex, :nimble_pool, "1.1.0", "bf9c29fbdcba3564a8b800d1eeb5a3c58f36e1e11d7b7fb2e084a643f645f06b", [:mix], [], "hexpm", "af2e4e6b34197db81f7aad230c1118eac993acc0dae6bc83bac0126d4ae0813a"}, "owl": {:hex, :owl, "0.12.2", "65906b525e5c3ef51bab6cba7687152be017aebe1da077bb719a5ee9f7e60762", [:mix], [{:ucwidth, "~> 0.2", [hex: :ucwidth, repo: "hexpm", optional: true]}], "hexpm", "6398efa9e1fea70a04d24231e10dcd66c1ac1aa2da418d20ef5357ec61de2880"}, "postgrex": {:hex, :postgrex, "0.20.0", "363ed03ab4757f6bc47942eff7720640795eb557e1935951c1626f0d303a3aed", [:mix], [{:db_connection, "~> 2.1", [hex: :db_connection, repo: "hexpm", optional: false]}, {:decimal, "~> 1.5 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:table, "~> 0.1.0", [hex: :table, repo: "hexpm", optional: true]}], "hexpm", "d36ef8b36f323d29505314f704e21a1a038e2dc387c6409ee0cd24144e187c0f"}, - "reactor": {:hex, :reactor, "0.15.4", "ef0c56a901c132529a14ab59fed0ccb4fcecb24308fb189a94c908255d4fdafc", [:mix], [{:igniter, "~> 0.4", [hex: :igniter, repo: "hexpm", optional: true]}, {:iterex, "~> 0.1", [hex: :iterex, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}, {:libgraph, "~> 0.16", [hex: :libgraph, repo: "hexpm", optional: false]}, {:spark, "~> 2.0", [hex: :spark, repo: "hexpm", optional: false]}, {:splode, "~> 0.2", [hex: :splode, repo: "hexpm", optional: false]}, {:telemetry, "~> 1.2", [hex: :telemetry, repo: "hexpm", optional: false]}, {:yaml_elixir, "~> 2.11", [hex: :yaml_elixir, repo: "hexpm", optional: false]}, {:ymlr, "~> 5.0", [hex: :ymlr, repo: "hexpm", optional: false]}], "hexpm", "783bf62fd0c72ded033afabdb8b6190b7048769771a2a97256e6f0bf4fb0a891"}, + "reactor": {:hex, :reactor, "0.15.5", "341d9ee664d6141df6639f227692ee6adc8a493d04232dee79e8a4a88e6cef8a", [:mix], [{:igniter, "~> 0.4", [hex: :igniter, repo: "hexpm", optional: true]}, {:iterex, "~> 0.1", [hex: :iterex, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}, {:libgraph, "~> 0.16", [hex: :libgraph, repo: "hexpm", optional: false]}, {:spark, "~> 2.0", [hex: :spark, repo: "hexpm", optional: false]}, {:splode, "~> 0.2", [hex: :splode, repo: "hexpm", optional: false]}, {:telemetry, "~> 1.2", [hex: :telemetry, repo: "hexpm", optional: false]}, {:yaml_elixir, "~> 2.11", [hex: :yaml_elixir, repo: "hexpm", optional: false]}, {:ymlr, "~> 5.0", [hex: :ymlr, repo: "hexpm", optional: false]}], "hexpm", "f9f440ecbdb0c41a832902a692608bd24be621fa7a602819d0dd12971d69f9aa"}, "req": {:hex, :req, "0.5.10", "a3a063eab8b7510785a467f03d30a8d95f66f5c3d9495be3474b61459c54376c", [:mix], [{:brotli, "~> 0.3.1", [hex: :brotli, repo: "hexpm", optional: true]}, {:ezstd, "~> 1.0", [hex: :ezstd, repo: "hexpm", optional: true]}, {:finch, "~> 0.17", [hex: :finch, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}, {:mime, "~> 2.0.6 or ~> 2.1", [hex: :mime, repo: "hexpm", optional: false]}, {:nimble_csv, "~> 1.0", [hex: :nimble_csv, repo: "hexpm", optional: true]}, {:plug, "~> 1.0", [hex: :plug, repo: "hexpm", optional: true]}], "hexpm", "8a604815743f8a2d3b5de0659fa3137fa4b1cffd636ecb69b30b2b9b2c2559be"}, "rewrite": {:hex, :rewrite, "1.1.2", "f5a5d10f5fed1491a6ff48e078d4585882695962ccc9e6c779bae025d1f92eda", [:mix], [{:glob_ex, "~> 0.1", [hex: :glob_ex, repo: "hexpm", optional: false]}, {:sourceror, "~> 1.0", [hex: :sourceror, repo: "hexpm", optional: false]}, {:text_diff, "~> 0.1", [hex: :text_diff, repo: "hexpm", optional: false]}], "hexpm", "7f8b94b1e3528d0a47b3e8b7bfeca559d2948a65fa7418a9ad7d7712703d39d4"}, "simple_sat": {:hex, :simple_sat, "0.1.3", "f650fc3c184a5fe741868b5ac56dc77fdbb428468f6dbf1978e14d0334497578", [:mix], [], "hexpm", "a54305066a356b7194dc81db2a89232bacdc0b3edaef68ed9aba28dcbc34887b"}, "sobelow": {:hex, :sobelow, "0.14.0", "dd82aae8f72503f924fe9dd97ffe4ca694d2f17ec463dcfd365987c9752af6ee", [:mix], [{:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "7ecf91e298acfd9b24f5d761f19e8f6e6ac585b9387fb6301023f1f2cd5eed5f"}, "sourceror": {:hex, :sourceror, "1.10.0", "38397dedbbc286966ec48c7af13e228b171332be1ad731974438c77791945ce9", [:mix], [], "hexpm", "29dbdfc92e04569c9d8e6efdc422fc1d815f4bd0055dc7c51b8800fb75c4b3f1"}, - "spark": {:hex, :spark, "2.2.65", "4c10d109c108417ce394158f330be09ef184878bde45de6462397fbda68cec29", [:mix], [{:igniter, ">= 0.3.64 and < 1.0.0-0", [hex: :igniter, repo: "hexpm", optional: true]}, {:jason, "~> 1.4", [hex: :jason, repo: "hexpm", optional: true]}, {:sourceror, "~> 1.2", [hex: :sourceror, repo: "hexpm", optional: true]}], "hexpm", "d66d5070a77f4c69cb4f007e941ac17d5d751ce71190fcd6e6e5fb42ba86f101"}, + "spark": {:hex, :spark, "2.2.66", "b7b47e76961c747f6128ad092c2109dbf742342dec533d3002c35207cb5f6b8e", [:mix], [{:igniter, ">= 0.3.64 and < 1.0.0-0", [hex: :igniter, repo: "hexpm", optional: true]}, {:jason, "~> 1.4", [hex: :jason, repo: "hexpm", optional: true]}, {:sourceror, "~> 1.2", [hex: :sourceror, repo: "hexpm", optional: true]}], "hexpm", "8f0b79839033ab816c2ae37aea29ded83e245a74240e2c931e2396531a9760d6"}, "spitfire": {:hex, :spitfire, "0.2.1", "29e154873f05444669c7453d3d931820822cbca5170e88f0f8faa1de74a79b47", [:mix], [], "hexpm", "6eeed75054a38341b2e1814d41bb0a250564092358de2669fdb57ff88141d91b"}, "splode": {:hex, :splode, "0.2.9", "3a2776e187c82f42f5226b33b1220ccbff74f4bcc523dd4039c804caaa3ffdc7", [:mix], [], "hexpm", "8002b00c6e24f8bd1bcced3fbaa5c33346048047bb7e13d2f3ad428babbd95c3"}, "statistex": {:hex, :statistex, "1.0.0", "f3dc93f3c0c6c92e5f291704cf62b99b553253d7969e9a5fa713e5481cd858a5", [:mix], [], "hexpm", "ff9d8bee7035028ab4742ff52fc80a2aa35cece833cf5319009b52f1b5a86c27"}, From abaa6e71ef364e7562e8460ca929d3618a7887ac Mon Sep 17 00:00:00 2001 From: Zach Daniel Date: Wed, 18 Jun 2025 19:50:31 -0400 Subject: [PATCH 068/174] chore: release version v2.6.8 --- CHANGELOG.md | 9 +++++++++ mix.exs | 2 +- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c9ac6016..4600e4e0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,15 @@ See [Conventional Commits](https://www.conventionalcommits.org) for commit guide +## [v2.6.8](https://github.com/ash-project/ash_postgres/compare/v2.6.7...v2.6.8) (2025-06-18) + + + + +### Bug Fixes: + +* ensure prefix is set even with create_schemas_in_migrations? false by Zach Daniel + ## [v2.6.7](https://github.com/ash-project/ash_postgres/compare/v2.6.6...v2.6.7) (2025-06-13) diff --git a/mix.exs b/mix.exs index a4db2bc6..af70fd8a 100644 --- a/mix.exs +++ b/mix.exs @@ -5,7 +5,7 @@ defmodule AshPostgres.MixProject do The PostgreSQL data layer for Ash Framework """ - @version "2.6.7" + @version "2.6.8" def project do [ From adf7a0420d7aef3fb60bc46dfe8955eec20d969a Mon Sep 17 00:00:00 2001 From: Oliver Severin Mulelid-Tynes Date: Thu, 19 Jun 2025 18:42:59 +0200 Subject: [PATCH 069/174] fix: Fix foreign key constraint on specially named references (#572) --- lib/data_layer.ex | 9 ++++++++- test/references_test.exs | 23 +++++++++++++++++++++++ 2 files changed, 31 insertions(+), 1 deletion(-) diff --git a/lib/data_layer.ex b/lib/data_layer.ex index ddfdc060..22efd25e 100644 --- a/lib/data_layer.ex +++ b/lib/data_layer.ex @@ -2682,8 +2682,15 @@ defmodule AshPostgres.DataLayer do resource |> Ash.Resource.Info.relationships() |> Enum.reduce(changeset, fn relationship, changeset -> + # Check if there's a custom reference name defined in the DSL name = - "#{AshPostgres.DataLayer.Info.table(resource)}_#{relationship.source_attribute}_fkey" + case AshPostgres.DataLayer.Info.reference(resource, relationship.name) do + %{name: custom_name} when not is_nil(custom_name) -> + custom_name + + _ -> + "#{AshPostgres.DataLayer.Info.table(resource)}_#{relationship.source_attribute}_fkey" + end case repo.default_constraint_match_type(:foreign, name) do {:regex, regex} -> diff --git a/test/references_test.exs b/test/references_test.exs index afb89acd..626a2d97 100644 --- a/test/references_test.exs +++ b/test/references_test.exs @@ -105,4 +105,27 @@ defmodule AshPostgres.ReferencesTest do end end end + + test "named reference results in properly applied foreign_key_constraint/3 on the underlying changeset" do + # Create a comment with an invalid post_id + assert {:error, %Ash.Error.Invalid{errors: errors}} = + AshPostgres.Test.Comment + |> Ash.Changeset.for_create(:create, %{ + title: "Test Comment", + # This post doesn't exist + post_id: Ash.UUID.generate() + }) + |> Ash.create() + + assert [ + %Ash.Error.Changes.InvalidAttribute{ + field: :post_id, + message: "does not exist", + private_vars: private_vars + } + ] = errors + + assert Keyword.get(private_vars, :constraint) == "special_name_fkey" + assert Keyword.get(private_vars, :constraint_type) == :foreign_key + end end From 919b9dfbbdfc0b89b776a527af986a9d604622cd Mon Sep 17 00:00:00 2001 From: Marc Planelles Date: Sat, 21 Jun 2025 23:42:24 +0200 Subject: [PATCH 070/174] fix: smallserial not mapping to proper type (#574) --- lib/resource_generator/spec.ex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/resource_generator/spec.ex b/lib/resource_generator/spec.ex index 38eebac5..ff942f16 100644 --- a/lib/resource_generator/spec.ex +++ b/lib/resource_generator/spec.ex @@ -958,7 +958,7 @@ defmodule AshPostgres.ResourceGenerator.Spec do defp type("numeric"), do: {:ok, :decimal} defp type("decimal"), do: {:ok, :decimal} defp type("smallint"), do: {:ok, :integer} - defp type("smallserial"), do: {:ok, :ineger} + defp type("smallserial"), do: {:ok, :integer} defp type("serial"), do: {:ok, :integer} defp type("text"), do: {:ok, :string} defp type("time"), do: {:ok, :time} From d6c35209fb124d4b5c605135262780acd7dd9eb6 Mon Sep 17 00:00:00 2001 From: Zach Daniel Date: Sun, 22 Jun 2025 16:44:38 -0400 Subject: [PATCH 071/174] test: add tests for calculation typing --- test/calculation_test.exs | 11 +++++++++++ test/support/resources/post.ex | 18 ++++++++++++++++++ 2 files changed, 29 insertions(+) diff --git a/test/calculation_test.exs b/test/calculation_test.exs index 6aa911fe..287ccf9a 100644 --- a/test/calculation_test.exs +++ b/test/calculation_test.exs @@ -1034,4 +1034,15 @@ defmodule AshPostgres.CalculationTest do assert full_name == "name" end + + test "calculation with fragment and cond returning integer doesn't cause Postgrex encoding error" do + Post + |> Ash.Changeset.for_create(:create, %{title: "hello ash lovers"}) + |> Ash.create!() + + assert [%Post{}] = + Post + |> Ash.Query.sort("posts_with_matching_title.relevance_score") + |> Ash.read!() + end end diff --git a/test/support/resources/post.ex b/test/support/resources/post.ex index f22d3fef..85cd60bb 100644 --- a/test/support/resources/post.ex +++ b/test/support/resources/post.ex @@ -788,6 +788,24 @@ defmodule AshPostgres.Test.Post do end calculations do + calculate :relevance_score, + :integer, + expr( + cond do + fragment( + "ts_rank_cd(to_tsvector(?), ?, 32)::float", + ^ref(:title), + fragment("to_tsquery(?)", ^arg(:query)) + ) > 0.6 -> + 1 + + true -> + 2 + end + ) do + argument(:query, :string) + end + calculate(:upper_thing, :string, expr(fragment("UPPER(?)", uniq_on_upper))) calculate(:upper_title, :string, expr(fragment("UPPER(?)", title))) From 2ff3cb2f44486b07a12ca28bbbe76a1542cc30d6 Mon Sep 17 00:00:00 2001 From: Zach Daniel Date: Tue, 24 Jun 2025 23:54:12 -0400 Subject: [PATCH 072/174] chore: credo --- mix.lock | 12 ++++++------ test/support/resources/post.ex | 18 ++++++++---------- 2 files changed, 14 insertions(+), 16 deletions(-) diff --git a/mix.lock b/mix.lock index 6b5900db..601ad73d 100644 --- a/mix.lock +++ b/mix.lock @@ -1,17 +1,17 @@ %{ - "ash": {:hex, :ash, "3.5.21", "389303c193962d67fd59da18a3557f5015fdfdaeddaa77150db539bc7203d1a1", [:mix], [{:decimal, "~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:ecto, "~> 3.7", [hex: :ecto, repo: "hexpm", optional: false]}, {:ets, "~> 0.8", [hex: :ets, repo: "hexpm", optional: false]}, {:igniter, ">= 0.6.4 and < 1.0.0-0", [hex: :igniter, repo: "hexpm", optional: true]}, {:jason, ">= 1.0.0", [hex: :jason, repo: "hexpm", optional: false]}, {:picosat_elixir, "~> 0.2", [hex: :picosat_elixir, repo: "hexpm", optional: true]}, {:plug, ">= 0.0.0", [hex: :plug, repo: "hexpm", optional: true]}, {:reactor, "~> 0.11", [hex: :reactor, repo: "hexpm", optional: false]}, {:simple_sat, ">= 0.1.1 and < 1.0.0-0", [hex: :simple_sat, repo: "hexpm", optional: true]}, {:spark, ">= 2.2.65 and < 3.0.0-0", [hex: :spark, repo: "hexpm", optional: false]}, {:splode, ">= 0.2.6 and < 1.0.0-0", [hex: :splode, repo: "hexpm", optional: false]}, {:stream_data, "~> 1.0", [hex: :stream_data, repo: "hexpm", optional: false]}, {:telemetry, "~> 1.1", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "cb90005d1972e22d0d2ae514394e43e0d67cce18c4485595aa3d3e4bbf25260f"}, + "ash": {:hex, :ash, "3.5.23", "e3c4e508569850fc276780f4ac94bee4c5f2d8e259ec2157c71e8e286db1c3ce", [:mix], [{:decimal, "~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:ecto, "~> 3.7", [hex: :ecto, repo: "hexpm", optional: false]}, {:ets, "~> 0.8", [hex: :ets, repo: "hexpm", optional: false]}, {:igniter, ">= 0.6.4 and < 1.0.0-0", [hex: :igniter, repo: "hexpm", optional: true]}, {:jason, ">= 1.0.0", [hex: :jason, repo: "hexpm", optional: false]}, {:picosat_elixir, "~> 0.2", [hex: :picosat_elixir, repo: "hexpm", optional: true]}, {:plug, ">= 0.0.0", [hex: :plug, repo: "hexpm", optional: true]}, {:reactor, "~> 0.11", [hex: :reactor, repo: "hexpm", optional: false]}, {:simple_sat, ">= 0.1.1 and < 1.0.0-0", [hex: :simple_sat, repo: "hexpm", optional: true]}, {:spark, ">= 2.2.65 and < 3.0.0-0", [hex: :spark, repo: "hexpm", optional: false]}, {:splode, ">= 0.2.6 and < 1.0.0-0", [hex: :splode, repo: "hexpm", optional: false]}, {:stream_data, "~> 1.0", [hex: :stream_data, repo: "hexpm", optional: false]}, {:telemetry, "~> 1.1", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "dd491cae52fa73b150e2c3b095ec3ae3aef681666503c300cee60c886d94ebfd"}, "ash_sql": {:hex, :ash_sql, "0.2.82", "a4fe01ccd2c29ce43af50233e63cd1298735b68ee2c22a1cbb0baa5f31f78ab5", [:mix], [{:ash, "~> 3.5", [hex: :ash, repo: "hexpm", optional: false]}, {:ecto, "~> 3.9", [hex: :ecto, repo: "hexpm", optional: false]}, {:ecto_sql, "~> 3.9", [hex: :ecto_sql, repo: "hexpm", optional: false]}], "hexpm", "a31f1065b72387b7a19d4e357f06904910b4c4fc8986209975786015f40cf795"}, "benchee": {:hex, :benchee, "1.4.0", "9f1f96a30ac80bab94faad644b39a9031d5632e517416a8ab0a6b0ac4df124ce", [:mix], [{:deep_merge, "~> 1.0", [hex: :deep_merge, repo: "hexpm", optional: false]}, {:statistex, "~> 1.0", [hex: :statistex, repo: "hexpm", optional: false]}, {:table, "~> 0.1.0", [hex: :table, repo: "hexpm", optional: true]}], "hexpm", "299cd10dd8ce51c9ea3ddb74bb150f93d25e968f93e4c1fa31698a8e4fa5d715"}, "bunt": {:hex, :bunt, "1.0.0", "081c2c665f086849e6d57900292b3a161727ab40431219529f13c4ddcf3e7a44", [:mix], [], "hexpm", "dc5f86aa08a5f6fa6b8096f0735c4e76d54ae5c9fa2c143e5a1fc7c1cd9bb6b5"}, "credo": {:hex, :credo, "1.7.12", "9e3c20463de4b5f3f23721527fcaf16722ec815e70ff6c60b86412c695d426c1", [:mix], [{:bunt, "~> 0.2.1 or ~> 1.0", [hex: :bunt, repo: "hexpm", optional: false]}, {:file_system, "~> 0.2 or ~> 1.0", [hex: :file_system, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "8493d45c656c5427d9c729235b99d498bd133421f3e0a683e5c1b561471291e5"}, - "db_connection": {:hex, :db_connection, "2.7.0", "b99faa9291bb09892c7da373bb82cba59aefa9b36300f6145c5f201c7adf48ec", [:mix], [{:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "dcf08f31b2701f857dfc787fbad78223d61a32204f217f15e881dd93e4bdd3ff"}, + "db_connection": {:hex, :db_connection, "2.8.0", "64fd82cfa6d8e25ec6660cea73e92a4cbc6a18b31343910427b702838c4b33b2", [:mix], [{:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "008399dae5eee1bf5caa6e86d204dcb44242c82b1ed5e22c881f2c34da201b15"}, "decimal": {:hex, :decimal, "2.3.0", "3ad6255aa77b4a3c4f818171b12d237500e63525c2fd056699967a3e7ea20f62", [:mix], [], "hexpm", "a4d66355cb29cb47c3cf30e71329e58361cfcb37c34235ef3bf1d7bf3773aeac"}, "deep_merge": {:hex, :deep_merge, "1.0.0", "b4aa1a0d1acac393bdf38b2291af38cb1d4a52806cf7a4906f718e1feb5ee961", [:mix], [], "hexpm", "ce708e5f094b9cd4e8f2be4f00d2f4250c4095be93f8cd6d018c753894885430"}, "dialyxir": {:hex, :dialyxir, "1.4.5", "ca1571ac18e0f88d4ab245f0b60fa31ff1b12cbae2b11bd25d207f865e8ae78a", [:mix], [{:erlex, ">= 0.2.7", [hex: :erlex, repo: "hexpm", optional: false]}], "hexpm", "b0fb08bb8107c750db5c0b324fa2df5ceaa0f9307690ee3c1f6ba5b9eb5d35c3"}, "earmark_parser": {:hex, :earmark_parser, "1.4.44", "f20830dd6b5c77afe2b063777ddbbff09f9759396500cdbe7523efd58d7a339c", [:mix], [], "hexpm", "4778ac752b4701a5599215f7030989c989ffdc4f6df457c5f36938cc2d2a2750"}, - "ecto": {:hex, :ecto, "3.13.0", "7528ef4f3a4cdcfebeb7eb6545806c8109529b385a69f701fc3d77b5b8bde6e7", [:mix], [{:decimal, "~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "061f095f1cc097f71f743b500affc792d6869df22b1946a73ab5495eb9b4a280"}, + "ecto": {:hex, :ecto, "3.13.2", "7d0c0863f3fc8d71d17fc3ad3b9424beae13f02712ad84191a826c7169484f01", [:mix], [{:decimal, "~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "669d9291370513ff56e7b7e7081b7af3283d02e046cf3d403053c557894a0b3e"}, "ecto_dev_logger": {:hex, :ecto_dev_logger, "0.14.1", "af385ce1af1c4210ad67a4c46b985c370713446a179144a1da2885138c9fb242", [:mix], [{:ecto, "~> 3.7", [hex: :ecto, repo: "hexpm", optional: false]}, {:geo, "~> 3.5 or ~> 4.0", [hex: :geo, repo: "hexpm", optional: true]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "14a64ebae728b3c45db6ba8bb185979c8e01fc1b0d3d1d9c01c7a2b798e8c698"}, - "ecto_sql": {:hex, :ecto_sql, "3.13.0", "a732428f38ce86612a2c34a1ea5d0a9642a5a71f044052007fd2f2e815707990", [:mix], [{:db_connection, "~> 2.4.1 or ~> 2.5", [hex: :db_connection, repo: "hexpm", optional: false]}, {:ecto, "~> 3.13.0", [hex: :ecto, repo: "hexpm", optional: false]}, {:myxql, "~> 0.7", [hex: :myxql, repo: "hexpm", optional: true]}, {:postgrex, "~> 0.19 or ~> 1.0", [hex: :postgrex, repo: "hexpm", optional: true]}, {:tds, "~> 2.1.1 or ~> 2.2", [hex: :tds, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4.0 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "5ce13085122a0871d93ea9ba1a886447d89c07f3b563e19e0b3dcdf201ed9fe9"}, + "ecto_sql": {:hex, :ecto_sql, "3.13.2", "a07d2461d84107b3d037097c822ffdd36ed69d1cf7c0f70e12a3d1decf04e2e1", [:mix], [{:db_connection, "~> 2.4.1 or ~> 2.5", [hex: :db_connection, repo: "hexpm", optional: false]}, {:ecto, "~> 3.13.0", [hex: :ecto, repo: "hexpm", optional: false]}, {:myxql, "~> 0.7", [hex: :myxql, repo: "hexpm", optional: true]}, {:postgrex, "~> 0.19 or ~> 1.0", [hex: :postgrex, repo: "hexpm", optional: true]}, {:tds, "~> 2.1.1 or ~> 2.2", [hex: :tds, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4.0 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "539274ab0ecf1a0078a6a72ef3465629e4d6018a3028095dc90f60a19c371717"}, "eflame": {:hex, :eflame, "1.0.1", "0664d287e39eef3c413749254b3af5f4f8b00be71c1af67d325331c4890be0fc", [:mix], [], "hexpm", "e0b08854a66f9013129de0b008488f3411ae9b69b902187837f994d7a99cf04e"}, "erlex": {:hex, :erlex, "0.2.7", "810e8725f96ab74d17aac676e748627a07bc87eb950d2b83acd29dc047a30595", [:mix], [], "hexpm", "3ed95f79d1a844c3f6bf0cea61e0d5612a42ce56da9c03f01df538685365efb0"}, "ets": {:hex, :ets, "0.9.0", "79c6a6c205436780486f72d84230c6cba2f8a9920456750ddd1e47389107d5fd", [:mix], [], "hexpm", "2861fdfb04bcaeff370f1a5904eec864f0a56dcfebe5921ea9aadf2a481c822b"}, @@ -23,7 +23,7 @@ "git_ops": {:hex, :git_ops, "2.8.0", "29ac9ab68bf9645973cb2752047b987e75cbd3d9761489c615e3ba80018fa885", [:mix], [{:git_cli, "~> 0.2", [hex: :git_cli, repo: "hexpm", optional: false]}, {:igniter, ">= 0.5.27 and < 1.0.0-0", [hex: :igniter, repo: "hexpm", optional: true]}, {:nimble_parsec, "~> 1.0", [hex: :nimble_parsec, repo: "hexpm", optional: false]}, {:req, "~> 0.5", [hex: :req, repo: "hexpm", optional: false]}], "hexpm", "b535e4ad6b5d13e14c455e76f65825659081b5530b0827eb0232d18719530eec"}, "glob_ex": {:hex, :glob_ex, "0.1.11", "cb50d3f1ef53f6ca04d6252c7fde09fd7a1cf63387714fe96f340a1349e62c93", [:mix], [], "hexpm", "342729363056e3145e61766b416769984c329e4378f1d558b63e341020525de4"}, "hpax": {:hex, :hpax, "1.0.3", "ed67ef51ad4df91e75cc6a1494f851850c0bd98ebc0be6e81b026e765ee535aa", [:mix], [], "hexpm", "8eab6e1cfa8d5918c2ce4ba43588e894af35dbd8e91e6e55c817bca5847df34a"}, - "igniter": {:hex, :igniter, "0.6.7", "4e183afc59d89289e223c4282fd3e9bb39b82e28d0aa6d3369f70fbd3e21a243", [:mix], [{:glob_ex, "~> 0.1.7", [hex: :glob_ex, repo: "hexpm", optional: false]}, {:jason, "~> 1.4", [hex: :jason, repo: "hexpm", optional: false]}, {:owl, "~> 0.11", [hex: :owl, repo: "hexpm", optional: false]}, {:phx_new, "~> 1.7", [hex: :phx_new, repo: "hexpm", optional: true]}, {:req, "~> 0.5", [hex: :req, repo: "hexpm", optional: false]}, {:rewrite, ">= 1.1.1 and < 2.0.0-0", [hex: :rewrite, repo: "hexpm", optional: false]}, {:sourceror, "~> 1.4", [hex: :sourceror, repo: "hexpm", optional: false]}, {:spitfire, ">= 0.1.3 and < 1.0.0-0", [hex: :spitfire, repo: "hexpm", optional: false]}], "hexpm", "43b0a584dc84fd1320772c87047355b604ed2bcdd25392b17f7da8bdd09b61ac"}, + "igniter": {:hex, :igniter, "0.6.8", "f058e7e5e3e69af9c795cc3022a92f802c8e2e1fd366579f6b60af328f69e2bb", [:mix], [{:glob_ex, "~> 0.1.7", [hex: :glob_ex, repo: "hexpm", optional: false]}, {:jason, "~> 1.4", [hex: :jason, repo: "hexpm", optional: false]}, {:owl, "~> 0.11", [hex: :owl, repo: "hexpm", optional: false]}, {:phx_new, "~> 1.7", [hex: :phx_new, repo: "hexpm", optional: true]}, {:req, "~> 0.5", [hex: :req, repo: "hexpm", optional: false]}, {:rewrite, ">= 1.1.1 and < 2.0.0-0", [hex: :rewrite, repo: "hexpm", optional: false]}, {:sourceror, "~> 1.4", [hex: :sourceror, repo: "hexpm", optional: false]}, {:spitfire, ">= 0.1.3 and < 1.0.0-0", [hex: :spitfire, repo: "hexpm", optional: false]}], "hexpm", "b0d9cf65a64ec984417c2eec1fcbbb059faba6eb64fcce3abdae00e0f6d36a33"}, "iterex": {:hex, :iterex, "0.1.2", "58f9b9b9a22a55cbfc7b5234a9c9c63eaac26d276b3db80936c0e1c60355a5a6", [:mix], [], "hexpm", "2e103b8bcc81757a9af121f6dc0df312c9a17220f302b1193ef720460d03029d"}, "jason": {:hex, :jason, "1.4.4", "b9226785a9aa77b6857ca22832cffa5d5011a667207eb2a0ad56adb5db443b8a", [:mix], [{:decimal, "~> 1.0 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm", "c5eb0cab91f094599f94d55bc63409236a8ec69a21a67814529e8d5f6cc90b3b"}, "libgraph": {:hex, :libgraph, "0.16.0", "3936f3eca6ef826e08880230f806bfea13193e49bf153f93edcf0239d4fd1d07", [:mix], [], "hexpm", "41ca92240e8a4138c30a7e06466acc709b0cbb795c643e9e17174a178982d6bf"}, @@ -39,7 +39,7 @@ "owl": {:hex, :owl, "0.12.2", "65906b525e5c3ef51bab6cba7687152be017aebe1da077bb719a5ee9f7e60762", [:mix], [{:ucwidth, "~> 0.2", [hex: :ucwidth, repo: "hexpm", optional: true]}], "hexpm", "6398efa9e1fea70a04d24231e10dcd66c1ac1aa2da418d20ef5357ec61de2880"}, "postgrex": {:hex, :postgrex, "0.20.0", "363ed03ab4757f6bc47942eff7720640795eb557e1935951c1626f0d303a3aed", [:mix], [{:db_connection, "~> 2.1", [hex: :db_connection, repo: "hexpm", optional: false]}, {:decimal, "~> 1.5 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:table, "~> 0.1.0", [hex: :table, repo: "hexpm", optional: true]}], "hexpm", "d36ef8b36f323d29505314f704e21a1a038e2dc387c6409ee0cd24144e187c0f"}, "reactor": {:hex, :reactor, "0.15.5", "341d9ee664d6141df6639f227692ee6adc8a493d04232dee79e8a4a88e6cef8a", [:mix], [{:igniter, "~> 0.4", [hex: :igniter, repo: "hexpm", optional: true]}, {:iterex, "~> 0.1", [hex: :iterex, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}, {:libgraph, "~> 0.16", [hex: :libgraph, repo: "hexpm", optional: false]}, {:spark, "~> 2.0", [hex: :spark, repo: "hexpm", optional: false]}, {:splode, "~> 0.2", [hex: :splode, repo: "hexpm", optional: false]}, {:telemetry, "~> 1.2", [hex: :telemetry, repo: "hexpm", optional: false]}, {:yaml_elixir, "~> 2.11", [hex: :yaml_elixir, repo: "hexpm", optional: false]}, {:ymlr, "~> 5.0", [hex: :ymlr, repo: "hexpm", optional: false]}], "hexpm", "f9f440ecbdb0c41a832902a692608bd24be621fa7a602819d0dd12971d69f9aa"}, - "req": {:hex, :req, "0.5.10", "a3a063eab8b7510785a467f03d30a8d95f66f5c3d9495be3474b61459c54376c", [:mix], [{:brotli, "~> 0.3.1", [hex: :brotli, repo: "hexpm", optional: true]}, {:ezstd, "~> 1.0", [hex: :ezstd, repo: "hexpm", optional: true]}, {:finch, "~> 0.17", [hex: :finch, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}, {:mime, "~> 2.0.6 or ~> 2.1", [hex: :mime, repo: "hexpm", optional: false]}, {:nimble_csv, "~> 1.0", [hex: :nimble_csv, repo: "hexpm", optional: true]}, {:plug, "~> 1.0", [hex: :plug, repo: "hexpm", optional: true]}], "hexpm", "8a604815743f8a2d3b5de0659fa3137fa4b1cffd636ecb69b30b2b9b2c2559be"}, + "req": {:hex, :req, "0.5.12", "7ce85835867a114c28b6cfc2d8a412f86660290907315ceb173a00e587b853d2", [:mix], [{:brotli, "~> 0.3.1", [hex: :brotli, repo: "hexpm", optional: true]}, {:ezstd, "~> 1.0", [hex: :ezstd, repo: "hexpm", optional: true]}, {:finch, "~> 0.17", [hex: :finch, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}, {:mime, "~> 2.0.6 or ~> 2.1", [hex: :mime, repo: "hexpm", optional: false]}, {:nimble_csv, "~> 1.0", [hex: :nimble_csv, repo: "hexpm", optional: true]}, {:plug, "~> 1.0", [hex: :plug, repo: "hexpm", optional: true]}], "hexpm", "d65f3d0e7032eb245706554cb5240dbe7a07493154e2dd34e7bb65001aa6ef32"}, "rewrite": {:hex, :rewrite, "1.1.2", "f5a5d10f5fed1491a6ff48e078d4585882695962ccc9e6c779bae025d1f92eda", [:mix], [{:glob_ex, "~> 0.1", [hex: :glob_ex, repo: "hexpm", optional: false]}, {:sourceror, "~> 1.0", [hex: :sourceror, repo: "hexpm", optional: false]}, {:text_diff, "~> 0.1", [hex: :text_diff, repo: "hexpm", optional: false]}], "hexpm", "7f8b94b1e3528d0a47b3e8b7bfeca559d2948a65fa7418a9ad7d7712703d39d4"}, "simple_sat": {:hex, :simple_sat, "0.1.3", "f650fc3c184a5fe741868b5ac56dc77fdbb428468f6dbf1978e14d0334497578", [:mix], [], "hexpm", "a54305066a356b7194dc81db2a89232bacdc0b3edaef68ed9aba28dcbc34887b"}, "sobelow": {:hex, :sobelow, "0.14.0", "dd82aae8f72503f924fe9dd97ffe4ca694d2f17ec463dcfd365987c9752af6ee", [:mix], [{:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "7ecf91e298acfd9b24f5d761f19e8f6e6ac585b9387fb6301023f1f2cd5eed5f"}, diff --git a/test/support/resources/post.ex b/test/support/resources/post.ex index 85cd60bb..5ff80458 100644 --- a/test/support/resources/post.ex +++ b/test/support/resources/post.ex @@ -791,16 +791,14 @@ defmodule AshPostgres.Test.Post do calculate :relevance_score, :integer, expr( - cond do - fragment( - "ts_rank_cd(to_tsvector(?), ?, 32)::float", - ^ref(:title), - fragment("to_tsquery(?)", ^arg(:query)) - ) > 0.6 -> - 1 - - true -> - 2 + if fragment( + "ts_rank_cd(to_tsvector(?), ?, 32)::float", + ^ref(:title), + fragment("to_tsquery(?)", ^arg(:query)) + ) > 0.6 do + 1 + else + 2 end ) do argument(:query, :string) From 50fc2ba3ed340f072364078f930358a99beca61a Mon Sep 17 00:00:00 2001 From: Zach Daniel Date: Tue, 24 Jun 2025 23:57:05 -0400 Subject: [PATCH 073/174] chore: update deps --- mix.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/mix.lock b/mix.lock index 601ad73d..b802109e 100644 --- a/mix.lock +++ b/mix.lock @@ -1,6 +1,6 @@ %{ - "ash": {:hex, :ash, "3.5.23", "e3c4e508569850fc276780f4ac94bee4c5f2d8e259ec2157c71e8e286db1c3ce", [:mix], [{:decimal, "~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:ecto, "~> 3.7", [hex: :ecto, repo: "hexpm", optional: false]}, {:ets, "~> 0.8", [hex: :ets, repo: "hexpm", optional: false]}, {:igniter, ">= 0.6.4 and < 1.0.0-0", [hex: :igniter, repo: "hexpm", optional: true]}, {:jason, ">= 1.0.0", [hex: :jason, repo: "hexpm", optional: false]}, {:picosat_elixir, "~> 0.2", [hex: :picosat_elixir, repo: "hexpm", optional: true]}, {:plug, ">= 0.0.0", [hex: :plug, repo: "hexpm", optional: true]}, {:reactor, "~> 0.11", [hex: :reactor, repo: "hexpm", optional: false]}, {:simple_sat, ">= 0.1.1 and < 1.0.0-0", [hex: :simple_sat, repo: "hexpm", optional: true]}, {:spark, ">= 2.2.65 and < 3.0.0-0", [hex: :spark, repo: "hexpm", optional: false]}, {:splode, ">= 0.2.6 and < 1.0.0-0", [hex: :splode, repo: "hexpm", optional: false]}, {:stream_data, "~> 1.0", [hex: :stream_data, repo: "hexpm", optional: false]}, {:telemetry, "~> 1.1", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "dd491cae52fa73b150e2c3b095ec3ae3aef681666503c300cee60c886d94ebfd"}, - "ash_sql": {:hex, :ash_sql, "0.2.82", "a4fe01ccd2c29ce43af50233e63cd1298735b68ee2c22a1cbb0baa5f31f78ab5", [:mix], [{:ash, "~> 3.5", [hex: :ash, repo: "hexpm", optional: false]}, {:ecto, "~> 3.9", [hex: :ecto, repo: "hexpm", optional: false]}, {:ecto_sql, "~> 3.9", [hex: :ecto_sql, repo: "hexpm", optional: false]}], "hexpm", "a31f1065b72387b7a19d4e357f06904910b4c4fc8986209975786015f40cf795"}, + "ash": {:hex, :ash, "3.5.24", "47bffb562c39482315d245ce22a381768b1bc16628ba974195630f3ca87d6218", [:mix], [{:decimal, "~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:ecto, "~> 3.7", [hex: :ecto, repo: "hexpm", optional: false]}, {:ets, "~> 0.8", [hex: :ets, repo: "hexpm", optional: false]}, {:igniter, ">= 0.6.4 and < 1.0.0-0", [hex: :igniter, repo: "hexpm", optional: true]}, {:jason, ">= 1.0.0", [hex: :jason, repo: "hexpm", optional: false]}, {:picosat_elixir, "~> 0.2", [hex: :picosat_elixir, repo: "hexpm", optional: true]}, {:plug, ">= 0.0.0", [hex: :plug, repo: "hexpm", optional: true]}, {:reactor, "~> 0.11", [hex: :reactor, repo: "hexpm", optional: false]}, {:simple_sat, ">= 0.1.1 and < 1.0.0-0", [hex: :simple_sat, repo: "hexpm", optional: true]}, {:spark, ">= 2.2.65 and < 3.0.0-0", [hex: :spark, repo: "hexpm", optional: false]}, {:splode, ">= 0.2.6 and < 1.0.0-0", [hex: :splode, repo: "hexpm", optional: false]}, {:stream_data, "~> 1.0", [hex: :stream_data, repo: "hexpm", optional: false]}, {:telemetry, "~> 1.1", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "881e0decc5e75a0109ca545472b5c6ecb3b28893fec9eaf1866b8c35ddf78c16"}, + "ash_sql": {:hex, :ash_sql, "0.2.83", "de8a9776186d1d1df54e265c1cf0c4e61c1d72be1297c9538f1a32eb9b84de55", [:mix], [{:ash, "~> 3.5", [hex: :ash, repo: "hexpm", optional: false]}, {:ecto, "~> 3.9", [hex: :ecto, repo: "hexpm", optional: false]}, {:ecto_sql, "~> 3.9", [hex: :ecto_sql, repo: "hexpm", optional: false]}], "hexpm", "5c99192814177d589d2ba518968b97d1ec7af12446631e3e5538f7a617d7d289"}, "benchee": {:hex, :benchee, "1.4.0", "9f1f96a30ac80bab94faad644b39a9031d5632e517416a8ab0a6b0ac4df124ce", [:mix], [{:deep_merge, "~> 1.0", [hex: :deep_merge, repo: "hexpm", optional: false]}, {:statistex, "~> 1.0", [hex: :statistex, repo: "hexpm", optional: false]}, {:table, "~> 0.1.0", [hex: :table, repo: "hexpm", optional: true]}], "hexpm", "299cd10dd8ce51c9ea3ddb74bb150f93d25e968f93e4c1fa31698a8e4fa5d715"}, "bunt": {:hex, :bunt, "1.0.0", "081c2c665f086849e6d57900292b3a161727ab40431219529f13c4ddcf3e7a44", [:mix], [], "hexpm", "dc5f86aa08a5f6fa6b8096f0735c4e76d54ae5c9fa2c143e5a1fc7c1cd9bb6b5"}, "credo": {:hex, :credo, "1.7.12", "9e3c20463de4b5f3f23721527fcaf16722ec815e70ff6c60b86412c695d426c1", [:mix], [{:bunt, "~> 0.2.1 or ~> 1.0", [hex: :bunt, repo: "hexpm", optional: false]}, {:file_system, "~> 0.2 or ~> 1.0", [hex: :file_system, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "8493d45c656c5427d9c729235b99d498bd133421f3e0a683e5c1b561471291e5"}, @@ -23,7 +23,7 @@ "git_ops": {:hex, :git_ops, "2.8.0", "29ac9ab68bf9645973cb2752047b987e75cbd3d9761489c615e3ba80018fa885", [:mix], [{:git_cli, "~> 0.2", [hex: :git_cli, repo: "hexpm", optional: false]}, {:igniter, ">= 0.5.27 and < 1.0.0-0", [hex: :igniter, repo: "hexpm", optional: true]}, {:nimble_parsec, "~> 1.0", [hex: :nimble_parsec, repo: "hexpm", optional: false]}, {:req, "~> 0.5", [hex: :req, repo: "hexpm", optional: false]}], "hexpm", "b535e4ad6b5d13e14c455e76f65825659081b5530b0827eb0232d18719530eec"}, "glob_ex": {:hex, :glob_ex, "0.1.11", "cb50d3f1ef53f6ca04d6252c7fde09fd7a1cf63387714fe96f340a1349e62c93", [:mix], [], "hexpm", "342729363056e3145e61766b416769984c329e4378f1d558b63e341020525de4"}, "hpax": {:hex, :hpax, "1.0.3", "ed67ef51ad4df91e75cc6a1494f851850c0bd98ebc0be6e81b026e765ee535aa", [:mix], [], "hexpm", "8eab6e1cfa8d5918c2ce4ba43588e894af35dbd8e91e6e55c817bca5847df34a"}, - "igniter": {:hex, :igniter, "0.6.8", "f058e7e5e3e69af9c795cc3022a92f802c8e2e1fd366579f6b60af328f69e2bb", [:mix], [{:glob_ex, "~> 0.1.7", [hex: :glob_ex, repo: "hexpm", optional: false]}, {:jason, "~> 1.4", [hex: :jason, repo: "hexpm", optional: false]}, {:owl, "~> 0.11", [hex: :owl, repo: "hexpm", optional: false]}, {:phx_new, "~> 1.7", [hex: :phx_new, repo: "hexpm", optional: true]}, {:req, "~> 0.5", [hex: :req, repo: "hexpm", optional: false]}, {:rewrite, ">= 1.1.1 and < 2.0.0-0", [hex: :rewrite, repo: "hexpm", optional: false]}, {:sourceror, "~> 1.4", [hex: :sourceror, repo: "hexpm", optional: false]}, {:spitfire, ">= 0.1.3 and < 1.0.0-0", [hex: :spitfire, repo: "hexpm", optional: false]}], "hexpm", "b0d9cf65a64ec984417c2eec1fcbbb059faba6eb64fcce3abdae00e0f6d36a33"}, + "igniter": {:hex, :igniter, "0.6.9", "99dd9ea7bcf2fe829617dac660069b3461183e4efbf303dd120fdef96923287d", [:mix], [{:glob_ex, "~> 0.1.7", [hex: :glob_ex, repo: "hexpm", optional: false]}, {:jason, "~> 1.4", [hex: :jason, repo: "hexpm", optional: false]}, {:owl, "~> 0.11", [hex: :owl, repo: "hexpm", optional: false]}, {:phx_new, "~> 1.7", [hex: :phx_new, repo: "hexpm", optional: true]}, {:req, "~> 0.5", [hex: :req, repo: "hexpm", optional: false]}, {:rewrite, ">= 1.1.1 and < 2.0.0-0", [hex: :rewrite, repo: "hexpm", optional: false]}, {:sourceror, "~> 1.4", [hex: :sourceror, repo: "hexpm", optional: false]}, {:spitfire, ">= 0.1.3 and < 1.0.0-0", [hex: :spitfire, repo: "hexpm", optional: false]}], "hexpm", "5fe407e10bc9416f7cd6af90d0409c8226ff2acacb9a7e7b9a097a66c8b5caef"}, "iterex": {:hex, :iterex, "0.1.2", "58f9b9b9a22a55cbfc7b5234a9c9c63eaac26d276b3db80936c0e1c60355a5a6", [:mix], [], "hexpm", "2e103b8bcc81757a9af121f6dc0df312c9a17220f302b1193ef720460d03029d"}, "jason": {:hex, :jason, "1.4.4", "b9226785a9aa77b6857ca22832cffa5d5011a667207eb2a0ad56adb5db443b8a", [:mix], [{:decimal, "~> 1.0 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm", "c5eb0cab91f094599f94d55bc63409236a8ec69a21a67814529e8d5f6cc90b3b"}, "libgraph": {:hex, :libgraph, "0.16.0", "3936f3eca6ef826e08880230f806bfea13193e49bf153f93edcf0239d4fd1d07", [:mix], [], "hexpm", "41ca92240e8a4138c30a7e06466acc709b0cbb795c643e9e17174a178982d6bf"}, @@ -44,7 +44,7 @@ "simple_sat": {:hex, :simple_sat, "0.1.3", "f650fc3c184a5fe741868b5ac56dc77fdbb428468f6dbf1978e14d0334497578", [:mix], [], "hexpm", "a54305066a356b7194dc81db2a89232bacdc0b3edaef68ed9aba28dcbc34887b"}, "sobelow": {:hex, :sobelow, "0.14.0", "dd82aae8f72503f924fe9dd97ffe4ca694d2f17ec463dcfd365987c9752af6ee", [:mix], [{:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "7ecf91e298acfd9b24f5d761f19e8f6e6ac585b9387fb6301023f1f2cd5eed5f"}, "sourceror": {:hex, :sourceror, "1.10.0", "38397dedbbc286966ec48c7af13e228b171332be1ad731974438c77791945ce9", [:mix], [], "hexpm", "29dbdfc92e04569c9d8e6efdc422fc1d815f4bd0055dc7c51b8800fb75c4b3f1"}, - "spark": {:hex, :spark, "2.2.66", "b7b47e76961c747f6128ad092c2109dbf742342dec533d3002c35207cb5f6b8e", [:mix], [{:igniter, ">= 0.3.64 and < 1.0.0-0", [hex: :igniter, repo: "hexpm", optional: true]}, {:jason, "~> 1.4", [hex: :jason, repo: "hexpm", optional: true]}, {:sourceror, "~> 1.2", [hex: :sourceror, repo: "hexpm", optional: true]}], "hexpm", "8f0b79839033ab816c2ae37aea29ded83e245a74240e2c931e2396531a9760d6"}, + "spark": {:hex, :spark, "2.2.67", "67626cb9f59ea4b1c5aa85d4afdd025e0740cbd49ed82665d0a40ff007d7fd4b", [:mix], [{:igniter, ">= 0.3.64 and < 1.0.0-0", [hex: :igniter, repo: "hexpm", optional: true]}, {:jason, "~> 1.4", [hex: :jason, repo: "hexpm", optional: true]}, {:sourceror, "~> 1.2", [hex: :sourceror, repo: "hexpm", optional: true]}], "hexpm", "c8575402e3afc66871362e821bece890536d16319cdb758c5fb2d1250182e46f"}, "spitfire": {:hex, :spitfire, "0.2.1", "29e154873f05444669c7453d3d931820822cbca5170e88f0f8faa1de74a79b47", [:mix], [], "hexpm", "6eeed75054a38341b2e1814d41bb0a250564092358de2669fdb57ff88141d91b"}, "splode": {:hex, :splode, "0.2.9", "3a2776e187c82f42f5226b33b1220ccbff74f4bcc523dd4039c804caaa3ffdc7", [:mix], [], "hexpm", "8002b00c6e24f8bd1bcced3fbaa5c33346048047bb7e13d2f3ad428babbd95c3"}, "statistex": {:hex, :statistex, "1.0.0", "f3dc93f3c0c6c92e5f291704cf62b99b553253d7969e9a5fa713e5481cd858a5", [:mix], [], "hexpm", "ff9d8bee7035028ab4742ff52fc80a2aa35cece833cf5319009b52f1b5a86c27"}, From 844f7ba6a40f9c3b52b93c8168b14eca95817559 Mon Sep 17 00:00:00 2001 From: Zach Daniel Date: Tue, 24 Jun 2025 23:58:07 -0400 Subject: [PATCH 074/174] chore: release version v2.6.9 --- CHANGELOG.md | 11 +++++++++++ mix.exs | 2 +- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4600e4e0..5cf99e8d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,17 @@ See [Conventional Commits](https://www.conventionalcommits.org) for commit guide +## [v2.6.9](https://github.com/ash-project/ash_postgres/compare/v2.6.8...v2.6.9) (2025-06-25) + + + + +### Bug Fixes: + +* smallserial not mapping to proper type (#574) by Marc Planelles + +* Fix foreign key constraint on specially named references (#572) by olivermt + ## [v2.6.8](https://github.com/ash-project/ash_postgres/compare/v2.6.7...v2.6.8) (2025-06-18) diff --git a/mix.exs b/mix.exs index af70fd8a..4c59bea1 100644 --- a/mix.exs +++ b/mix.exs @@ -5,7 +5,7 @@ defmodule AshPostgres.MixProject do The PostgreSQL data layer for Ash Framework """ - @version "2.6.8" + @version "2.6.9" def project do [ From 83abe4fcdabf451a36db09d6ca26820996075536 Mon Sep 17 00:00:00 2001 From: Frank Dugan III Date: Sun, 29 Jun 2025 14:33:06 -0500 Subject: [PATCH 075/174] refactor: use multiline string templates to preserve escapes in checks (#578) --- lib/migration_generator/operation.ex | 28 ++++++++++++++++++++---- test/migration_generator_test.exs | 32 ++++++++++++++++++++++++---- 2 files changed, 52 insertions(+), 8 deletions(-) diff --git a/lib/migration_generator/operation.ex b/lib/migration_generator/operation.ex index 5c8bfbc0..3b266494 100644 --- a/lib/migration_generator/operation.ex +++ b/lib/migration_generator/operation.ex @@ -1351,10 +1351,20 @@ defmodule AshPostgres.MigrationGenerator.Operation do }, table: table }) do + prefix = if schema, do: ", " <> option(:prefix, schema), else: "" + if base_filter do - "create constraint(:#{as_atom(table)}, :#{as_atom(name)}, #{join(["check: \"(#{check}) OR NOT (#{base_filter})\")", option(:prefix, schema)])}" + ~s''' + create constraint(:#{as_atom(table)}, :#{as_atom(name)}, check: """ + (#{check}) OR NOT (#{base_filter}) + """#{prefix}) + ''' else - "create constraint(:#{as_atom(table)}, :#{as_atom(name)}, #{join(["check: \"#{check}\")", option(:prefix, schema)])}" + ~s''' + create constraint(:#{as_atom(table)}, :#{as_atom(name)}, check: """ + #{check} + """#{prefix}) + ''' end end @@ -1386,10 +1396,20 @@ defmodule AshPostgres.MigrationGenerator.Operation do schema: schema, table: table }) do + prefix = if schema, do: ", " <> option(:prefix, schema), else: "" + if base_filter do - "create constraint(:#{as_atom(table)}, :#{as_atom(name)}, #{join(["check: \"#{base_filter} AND #{check}\")", option(:prefix, schema)])}" + ~s''' + create constraint(:#{as_atom(table)}, :#{as_atom(name)}, check: """ + #{base_filter} AND #{check} + """#{prefix}) + ''' else - "create constraint(:#{as_atom(table)}, :#{as_atom(name)}, #{join(["check: \"#{check}\")", option(:prefix, schema)])}" + ~s''' + create constraint(:#{as_atom(table)}, :#{as_atom(name)}, check: """ + #{check} + """#{prefix}) + ''' end end end diff --git a/test/migration_generator_test.exs b/test/migration_generator_test.exs index bd8f2c92..e284e847 100644 --- a/test/migration_generator_test.exs +++ b/test/migration_generator_test.exs @@ -2240,11 +2240,16 @@ defmodule AshPostgres.MigrationGeneratorTest do attributes do uuid_primary_key(:id) attribute(:price, :integer, public?: true) + attribute(:title, :string, public?: true) end postgres do check_constraints do - check_constraint(:price, "price_must_be_positive", check: "price > 0") + check_constraint(:price, "price_must_be_positive", check: ~S["price" > 0]) + + check_constraint(:title, "title_must_conform_to_format", + check: ~S[title ~= '("\"\\"\\\"\\\\"\\\\\")'] + ) end end end @@ -2268,7 +2273,18 @@ defmodule AshPostgres.MigrationGeneratorTest do |> File.read!() assert file =~ - ~S[create constraint(:posts, :price_must_be_positive, check: "price > 0")] + ~S''' + create constraint(:posts, :price_must_be_positive, check: """ + "price" > 0 + """) + ''' + + assert file =~ + ~S''' + create constraint(:posts, :title_must_conform_to_format, check: """ + title ~= '("\"\\"\\\"\\\\"\\\\\")' + """) + ''' defposts do attributes do @@ -2307,7 +2323,11 @@ defmodule AshPostgres.MigrationGeneratorTest do String.split(down, "drop_if_exists constraint(:posts, :price_must_be_positive)") assert remaining =~ - ~S[create constraint(:posts, :price_must_be_positive, check: "price > 0")] + ~S''' + create constraint(:posts, :price_must_be_positive, check: """ + "price" > 0 + """) + ''' end test "base filters are taken into account, negated" do @@ -2349,7 +2369,11 @@ defmodule AshPostgres.MigrationGeneratorTest do |> File.read!() assert file =~ - ~S[create constraint(:posts, :price_must_be_positive, check: "(price > 0) OR NOT (price > -10)")] + ~S''' + create constraint(:posts, :price_must_be_positive, check: """ + (price > 0) OR NOT (price > -10) + """) + ''' end test "when removed, the constraint is dropped before modification" do From 70189697ee962bb1e366a14a4c0bb665e4ae5f6f Mon Sep 17 00:00:00 2001 From: Zach Daniel Date: Wed, 2 Jul 2025 10:12:51 -0400 Subject: [PATCH 076/174] test: fix test case to be transactional --- test/references_test.exs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/references_test.exs b/test/references_test.exs index 626a2d97..a8be1d07 100644 --- a/test/references_test.exs +++ b/test/references_test.exs @@ -1,5 +1,5 @@ defmodule AshPostgres.ReferencesTest do - use ExUnit.Case + use AshPostgres.RepoCase test "can't use match_type != :full when referencing an non-primary key index" do Code.compiler_options(ignore_module_conflict: true) From b175eb4785ee65978a22afe72cbe10a623cd971b Mon Sep 17 00:00:00 2001 From: kernel-io Date: Thu, 3 Jul 2025 23:42:55 +1200 Subject: [PATCH 077/174] test: failing test for parent ref / policy thing (#580) * failing test Signed-off-by: kernel-io * cleaned up and added another failing test Signed-off-by: kernel-io * updated tests Signed-off-by: kernel-io --------- Signed-off-by: kernel-io --- mix.lock | 10 ++++---- test/parent_filter_test.exs | 47 ++++++++++++++++++++++++++++++++++ test/support/resources/post.ex | 15 +++++++++++ 3 files changed, 67 insertions(+), 5 deletions(-) create mode 100644 test/parent_filter_test.exs diff --git a/mix.lock b/mix.lock index b802109e..7f05569e 100644 --- a/mix.lock +++ b/mix.lock @@ -1,6 +1,6 @@ %{ - "ash": {:hex, :ash, "3.5.24", "47bffb562c39482315d245ce22a381768b1bc16628ba974195630f3ca87d6218", [:mix], [{:decimal, "~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:ecto, "~> 3.7", [hex: :ecto, repo: "hexpm", optional: false]}, {:ets, "~> 0.8", [hex: :ets, repo: "hexpm", optional: false]}, {:igniter, ">= 0.6.4 and < 1.0.0-0", [hex: :igniter, repo: "hexpm", optional: true]}, {:jason, ">= 1.0.0", [hex: :jason, repo: "hexpm", optional: false]}, {:picosat_elixir, "~> 0.2", [hex: :picosat_elixir, repo: "hexpm", optional: true]}, {:plug, ">= 0.0.0", [hex: :plug, repo: "hexpm", optional: true]}, {:reactor, "~> 0.11", [hex: :reactor, repo: "hexpm", optional: false]}, {:simple_sat, ">= 0.1.1 and < 1.0.0-0", [hex: :simple_sat, repo: "hexpm", optional: true]}, {:spark, ">= 2.2.65 and < 3.0.0-0", [hex: :spark, repo: "hexpm", optional: false]}, {:splode, ">= 0.2.6 and < 1.0.0-0", [hex: :splode, repo: "hexpm", optional: false]}, {:stream_data, "~> 1.0", [hex: :stream_data, repo: "hexpm", optional: false]}, {:telemetry, "~> 1.1", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "881e0decc5e75a0109ca545472b5c6ecb3b28893fec9eaf1866b8c35ddf78c16"}, - "ash_sql": {:hex, :ash_sql, "0.2.83", "de8a9776186d1d1df54e265c1cf0c4e61c1d72be1297c9538f1a32eb9b84de55", [:mix], [{:ash, "~> 3.5", [hex: :ash, repo: "hexpm", optional: false]}, {:ecto, "~> 3.9", [hex: :ecto, repo: "hexpm", optional: false]}, {:ecto_sql, "~> 3.9", [hex: :ecto_sql, repo: "hexpm", optional: false]}], "hexpm", "5c99192814177d589d2ba518968b97d1ec7af12446631e3e5538f7a617d7d289"}, + "ash": {:hex, :ash, "3.5.25", "99f7139e98b745a64312ae80e2420589205b2fec1799f00fc58da771d2c63373", [:mix], [{:decimal, "~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:ecto, "~> 3.7", [hex: :ecto, repo: "hexpm", optional: false]}, {:ets, "~> 0.8", [hex: :ets, repo: "hexpm", optional: false]}, {:igniter, ">= 0.6.4 and < 1.0.0-0", [hex: :igniter, repo: "hexpm", optional: true]}, {:jason, ">= 1.0.0", [hex: :jason, repo: "hexpm", optional: false]}, {:picosat_elixir, "~> 0.2", [hex: :picosat_elixir, repo: "hexpm", optional: true]}, {:plug, ">= 0.0.0", [hex: :plug, repo: "hexpm", optional: true]}, {:reactor, "~> 0.11", [hex: :reactor, repo: "hexpm", optional: false]}, {:simple_sat, ">= 0.1.1 and < 1.0.0-0", [hex: :simple_sat, repo: "hexpm", optional: true]}, {:spark, ">= 2.2.65 and < 3.0.0-0", [hex: :spark, repo: "hexpm", optional: false]}, {:splode, ">= 0.2.6 and < 1.0.0-0", [hex: :splode, repo: "hexpm", optional: false]}, {:stream_data, "~> 1.0", [hex: :stream_data, repo: "hexpm", optional: false]}, {:telemetry, "~> 1.1", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "d45844ea30062b796d4adcad75b8d91e21081ac0f1bb6627d1a2663ca5ecf258"}, + "ash_sql": {:hex, :ash_sql, "0.2.84", "1187555609f4773aacb5cccdca82a78c2b3f7390e78b400a8f03c91b2e7cd82f", [:mix], [{:ash, ">= 3.5.25 and < 4.0.0-0", [hex: :ash, repo: "hexpm", optional: false]}, {:ecto, "~> 3.9", [hex: :ecto, repo: "hexpm", optional: false]}, {:ecto_sql, "~> 3.9", [hex: :ecto_sql, repo: "hexpm", optional: false]}], "hexpm", "5e6a4d3070e60a0653c572527276a8c034b9458e37b1aca8868b17fcf0a1d1c0"}, "benchee": {:hex, :benchee, "1.4.0", "9f1f96a30ac80bab94faad644b39a9031d5632e517416a8ab0a6b0ac4df124ce", [:mix], [{:deep_merge, "~> 1.0", [hex: :deep_merge, repo: "hexpm", optional: false]}, {:statistex, "~> 1.0", [hex: :statistex, repo: "hexpm", optional: false]}, {:table, "~> 0.1.0", [hex: :table, repo: "hexpm", optional: true]}], "hexpm", "299cd10dd8ce51c9ea3ddb74bb150f93d25e968f93e4c1fa31698a8e4fa5d715"}, "bunt": {:hex, :bunt, "1.0.0", "081c2c665f086849e6d57900292b3a161727ab40431219529f13c4ddcf3e7a44", [:mix], [], "hexpm", "dc5f86aa08a5f6fa6b8096f0735c4e76d54ae5c9fa2c143e5a1fc7c1cd9bb6b5"}, "credo": {:hex, :credo, "1.7.12", "9e3c20463de4b5f3f23721527fcaf16722ec815e70ff6c60b86412c695d426c1", [:mix], [{:bunt, "~> 0.2.1 or ~> 1.0", [hex: :bunt, repo: "hexpm", optional: false]}, {:file_system, "~> 0.2 or ~> 1.0", [hex: :file_system, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "8493d45c656c5427d9c729235b99d498bd133421f3e0a683e5c1b561471291e5"}, @@ -23,7 +23,7 @@ "git_ops": {:hex, :git_ops, "2.8.0", "29ac9ab68bf9645973cb2752047b987e75cbd3d9761489c615e3ba80018fa885", [:mix], [{:git_cli, "~> 0.2", [hex: :git_cli, repo: "hexpm", optional: false]}, {:igniter, ">= 0.5.27 and < 1.0.0-0", [hex: :igniter, repo: "hexpm", optional: true]}, {:nimble_parsec, "~> 1.0", [hex: :nimble_parsec, repo: "hexpm", optional: false]}, {:req, "~> 0.5", [hex: :req, repo: "hexpm", optional: false]}], "hexpm", "b535e4ad6b5d13e14c455e76f65825659081b5530b0827eb0232d18719530eec"}, "glob_ex": {:hex, :glob_ex, "0.1.11", "cb50d3f1ef53f6ca04d6252c7fde09fd7a1cf63387714fe96f340a1349e62c93", [:mix], [], "hexpm", "342729363056e3145e61766b416769984c329e4378f1d558b63e341020525de4"}, "hpax": {:hex, :hpax, "1.0.3", "ed67ef51ad4df91e75cc6a1494f851850c0bd98ebc0be6e81b026e765ee535aa", [:mix], [], "hexpm", "8eab6e1cfa8d5918c2ce4ba43588e894af35dbd8e91e6e55c817bca5847df34a"}, - "igniter": {:hex, :igniter, "0.6.9", "99dd9ea7bcf2fe829617dac660069b3461183e4efbf303dd120fdef96923287d", [:mix], [{:glob_ex, "~> 0.1.7", [hex: :glob_ex, repo: "hexpm", optional: false]}, {:jason, "~> 1.4", [hex: :jason, repo: "hexpm", optional: false]}, {:owl, "~> 0.11", [hex: :owl, repo: "hexpm", optional: false]}, {:phx_new, "~> 1.7", [hex: :phx_new, repo: "hexpm", optional: true]}, {:req, "~> 0.5", [hex: :req, repo: "hexpm", optional: false]}, {:rewrite, ">= 1.1.1 and < 2.0.0-0", [hex: :rewrite, repo: "hexpm", optional: false]}, {:sourceror, "~> 1.4", [hex: :sourceror, repo: "hexpm", optional: false]}, {:spitfire, ">= 0.1.3 and < 1.0.0-0", [hex: :spitfire, repo: "hexpm", optional: false]}], "hexpm", "5fe407e10bc9416f7cd6af90d0409c8226ff2acacb9a7e7b9a097a66c8b5caef"}, + "igniter": {:hex, :igniter, "0.6.10", "896d75fc48ed493ff22accd111fe2e34747163d26c5f374267bad1ef4a6c5076", [:mix], [{:glob_ex, "~> 0.1.7", [hex: :glob_ex, repo: "hexpm", optional: false]}, {:jason, "~> 1.4", [hex: :jason, repo: "hexpm", optional: false]}, {:owl, "~> 0.11", [hex: :owl, repo: "hexpm", optional: false]}, {:phx_new, "~> 1.7", [hex: :phx_new, repo: "hexpm", optional: true]}, {:req, "~> 0.5", [hex: :req, repo: "hexpm", optional: false]}, {:rewrite, ">= 1.1.1 and < 2.0.0-0", [hex: :rewrite, repo: "hexpm", optional: false]}, {:sourceror, "~> 1.4", [hex: :sourceror, repo: "hexpm", optional: false]}, {:spitfire, ">= 0.1.3 and < 1.0.0-0", [hex: :spitfire, repo: "hexpm", optional: false]}], "hexpm", "9a3abc56e94f362730a3023dfe0ac2ced1186f95fa1ccf4cc30df0c8ce0fc276"}, "iterex": {:hex, :iterex, "0.1.2", "58f9b9b9a22a55cbfc7b5234a9c9c63eaac26d276b3db80936c0e1c60355a5a6", [:mix], [], "hexpm", "2e103b8bcc81757a9af121f6dc0df312c9a17220f302b1193ef720460d03029d"}, "jason": {:hex, :jason, "1.4.4", "b9226785a9aa77b6857ca22832cffa5d5011a667207eb2a0ad56adb5db443b8a", [:mix], [{:decimal, "~> 1.0 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm", "c5eb0cab91f094599f94d55bc63409236a8ec69a21a67814529e8d5f6cc90b3b"}, "libgraph": {:hex, :libgraph, "0.16.0", "3936f3eca6ef826e08880230f806bfea13193e49bf153f93edcf0239d4fd1d07", [:mix], [], "hexpm", "41ca92240e8a4138c30a7e06466acc709b0cbb795c643e9e17174a178982d6bf"}, @@ -38,8 +38,8 @@ "nimble_pool": {:hex, :nimble_pool, "1.1.0", "bf9c29fbdcba3564a8b800d1eeb5a3c58f36e1e11d7b7fb2e084a643f645f06b", [:mix], [], "hexpm", "af2e4e6b34197db81f7aad230c1118eac993acc0dae6bc83bac0126d4ae0813a"}, "owl": {:hex, :owl, "0.12.2", "65906b525e5c3ef51bab6cba7687152be017aebe1da077bb719a5ee9f7e60762", [:mix], [{:ucwidth, "~> 0.2", [hex: :ucwidth, repo: "hexpm", optional: true]}], "hexpm", "6398efa9e1fea70a04d24231e10dcd66c1ac1aa2da418d20ef5357ec61de2880"}, "postgrex": {:hex, :postgrex, "0.20.0", "363ed03ab4757f6bc47942eff7720640795eb557e1935951c1626f0d303a3aed", [:mix], [{:db_connection, "~> 2.1", [hex: :db_connection, repo: "hexpm", optional: false]}, {:decimal, "~> 1.5 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:table, "~> 0.1.0", [hex: :table, repo: "hexpm", optional: true]}], "hexpm", "d36ef8b36f323d29505314f704e21a1a038e2dc387c6409ee0cd24144e187c0f"}, - "reactor": {:hex, :reactor, "0.15.5", "341d9ee664d6141df6639f227692ee6adc8a493d04232dee79e8a4a88e6cef8a", [:mix], [{:igniter, "~> 0.4", [hex: :igniter, repo: "hexpm", optional: true]}, {:iterex, "~> 0.1", [hex: :iterex, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}, {:libgraph, "~> 0.16", [hex: :libgraph, repo: "hexpm", optional: false]}, {:spark, "~> 2.0", [hex: :spark, repo: "hexpm", optional: false]}, {:splode, "~> 0.2", [hex: :splode, repo: "hexpm", optional: false]}, {:telemetry, "~> 1.2", [hex: :telemetry, repo: "hexpm", optional: false]}, {:yaml_elixir, "~> 2.11", [hex: :yaml_elixir, repo: "hexpm", optional: false]}, {:ymlr, "~> 5.0", [hex: :ymlr, repo: "hexpm", optional: false]}], "hexpm", "f9f440ecbdb0c41a832902a692608bd24be621fa7a602819d0dd12971d69f9aa"}, - "req": {:hex, :req, "0.5.12", "7ce85835867a114c28b6cfc2d8a412f86660290907315ceb173a00e587b853d2", [:mix], [{:brotli, "~> 0.3.1", [hex: :brotli, repo: "hexpm", optional: true]}, {:ezstd, "~> 1.0", [hex: :ezstd, repo: "hexpm", optional: true]}, {:finch, "~> 0.17", [hex: :finch, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}, {:mime, "~> 2.0.6 or ~> 2.1", [hex: :mime, repo: "hexpm", optional: false]}, {:nimble_csv, "~> 1.0", [hex: :nimble_csv, repo: "hexpm", optional: true]}, {:plug, "~> 1.0", [hex: :plug, repo: "hexpm", optional: true]}], "hexpm", "d65f3d0e7032eb245706554cb5240dbe7a07493154e2dd34e7bb65001aa6ef32"}, + "reactor": {:hex, :reactor, "0.15.6", "d717f9add549b25a089a94c90197718d2d838e35d81dd776b1d81587d4cf2aaa", [:mix], [{:igniter, "~> 0.4", [hex: :igniter, repo: "hexpm", optional: true]}, {:iterex, "~> 0.1", [hex: :iterex, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}, {:libgraph, "~> 0.16", [hex: :libgraph, repo: "hexpm", optional: false]}, {:spark, "~> 2.0", [hex: :spark, repo: "hexpm", optional: false]}, {:splode, "~> 0.2", [hex: :splode, repo: "hexpm", optional: false]}, {:telemetry, "~> 1.2", [hex: :telemetry, repo: "hexpm", optional: false]}, {:yaml_elixir, "~> 2.11", [hex: :yaml_elixir, repo: "hexpm", optional: false]}, {:ymlr, "~> 5.0", [hex: :ymlr, repo: "hexpm", optional: false]}], "hexpm", "74db98165e3644d86e0f723672d91ceca4339eaa935bcad7e78bf146a46d77b9"}, + "req": {:hex, :req, "0.5.14", "521b449fa0bf275e6d034c05f29bec21789a0d6cd6f7a1c326c7bee642bf6e07", [:mix], [{:brotli, "~> 0.3.1", [hex: :brotli, repo: "hexpm", optional: true]}, {:ezstd, "~> 1.0", [hex: :ezstd, repo: "hexpm", optional: true]}, {:finch, "~> 0.17", [hex: :finch, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}, {:mime, "~> 2.0.6 or ~> 2.1", [hex: :mime, repo: "hexpm", optional: false]}, {:nimble_csv, "~> 1.0", [hex: :nimble_csv, repo: "hexpm", optional: true]}, {:plug, "~> 1.0", [hex: :plug, repo: "hexpm", optional: true]}], "hexpm", "b7b15692071d556c73432c7797aa7e96b51d1a2db76f746b976edef95c930021"}, "rewrite": {:hex, :rewrite, "1.1.2", "f5a5d10f5fed1491a6ff48e078d4585882695962ccc9e6c779bae025d1f92eda", [:mix], [{:glob_ex, "~> 0.1", [hex: :glob_ex, repo: "hexpm", optional: false]}, {:sourceror, "~> 1.0", [hex: :sourceror, repo: "hexpm", optional: false]}, {:text_diff, "~> 0.1", [hex: :text_diff, repo: "hexpm", optional: false]}], "hexpm", "7f8b94b1e3528d0a47b3e8b7bfeca559d2948a65fa7418a9ad7d7712703d39d4"}, "simple_sat": {:hex, :simple_sat, "0.1.3", "f650fc3c184a5fe741868b5ac56dc77fdbb428468f6dbf1978e14d0334497578", [:mix], [], "hexpm", "a54305066a356b7194dc81db2a89232bacdc0b3edaef68ed9aba28dcbc34887b"}, "sobelow": {:hex, :sobelow, "0.14.0", "dd82aae8f72503f924fe9dd97ffe4ca694d2f17ec463dcfd365987c9752af6ee", [:mix], [{:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "7ecf91e298acfd9b24f5d761f19e8f6e6ac585b9387fb6301023f1f2cd5eed5f"}, diff --git a/test/parent_filter_test.exs b/test/parent_filter_test.exs new file mode 100644 index 00000000..fefbde24 --- /dev/null +++ b/test/parent_filter_test.exs @@ -0,0 +1,47 @@ +defmodule AshPostgres.Test.ParentFilterTest do + use AshPostgres.RepoCase, async: false + + alias AshPostgres.Test.{Organization, Post, User} + + require Ash.Query + + test "when the first relationship in an `exists` path has parent references in its filter, we don't get error" do + organization = + Organization + |> Ash.Changeset.for_create(:create, %{name: "test_org"}) + |> Ash.create!() + + not_my_organization = + Organization + |> Ash.Changeset.for_create(:create, %{name: "test_org_2"}) + |> Ash.create!() + + user = + User + |> Ash.Changeset.for_create(:create, %{organization_id: organization.id, name: "foo bar"}) + |> Ash.create!() + + Post + |> Ash.Changeset.for_create(:create, %{organization_id: not_my_organization.id}) + |> Ash.create!() + + Post + |> Ash.Changeset.for_create(:create, %{organization_id: organization.id, title: "test_org"}) + |> Ash.create!() + + assert {:ok, [%Post{title: "test_org"}]} = + Post + |> Ash.Query.for_read(:read_with_policy_with_parent) + |> Ash.read( + authorize?: true, + actor: user + ) + + assert {:ok, _} = + Post + |> Ash.Query.filter( + organization.posts.posts_with_my_organization_name_as_a_title.title == "tuna" + ) + |> Ash.read(authorize?: false) + end +end diff --git a/test/support/resources/post.ex b/test/support/resources/post.ex index 5ff80458..5da68941 100644 --- a/test/support/resources/post.ex +++ b/test/support/resources/post.ex @@ -92,6 +92,12 @@ defmodule AshPostgres.Test.Post do authorize_if(relates_to_actor_via([:organization, :users])) end + policy action(:read_with_policy_with_parent) do + authorize_if( + relates_to_actor_via([:posts_with_my_organization_name_as_a_title, :organization, :users]) + ) + end + policy action(:allow_any) do authorize_if(always()) end @@ -360,6 +366,9 @@ defmodule AshPostgres.Test.Post do filter(expr(title == "foo")) end + read :read_with_policy_with_parent do + end + read :category_matches do argument(:category, CiCategory) filter(expr(category == ^arg(:category))) @@ -599,6 +608,12 @@ defmodule AshPostgres.Test.Post do filter(expr(^actor(:id) == id)) end + has_many(:posts_with_my_organization_name_as_a_title, __MODULE__) do + public?(true) + no_attributes?(true) + filter(expr(fragment("? = ?", title, parent(organization.name)))) + end + belongs_to :parent_post, __MODULE__ do public?(true) end From 5522c5cae178996285e826eaf3458e45d9d6441a Mon Sep 17 00:00:00 2001 From: Robert Ellen Date: Tue, 8 Jul 2025 11:06:08 +1000 Subject: [PATCH 078/174] test: Add tests for combination queries and loading calculations (#586) These tests show that loading calculations in queries that have combinations works. --- test/combination_nullable_calc_test.exs | 197 ++++++++++++++++++++++++ test/support/resources/author.ex | 2 + test/support/resources/post.ex | 2 + 3 files changed, 201 insertions(+) create mode 100644 test/combination_nullable_calc_test.exs diff --git a/test/combination_nullable_calc_test.exs b/test/combination_nullable_calc_test.exs new file mode 100644 index 00000000..1618f1c8 --- /dev/null +++ b/test/combination_nullable_calc_test.exs @@ -0,0 +1,197 @@ +defmodule AshPostgres.CombinationNullableCalcTest do + @moduledoc false + use AshPostgres.RepoCase, async: false + alias AshPostgres.Test.Author + alias AshPostgres.Test.Post + + require Ash.Query + import Ash.Expr + + describe "combination_of with nullable calculations" do + test "combination query with allow_nil? calculation loses ORDER BY" do + Post + |> Ash.Changeset.for_create(:create, %{title: "Zebra", score: 5}) + |> Ash.create!() + + Post + |> Ash.Changeset.for_create(:create, %{title: "Apple", score: 25}) + |> Ash.create!() + + Post + |> Ash.Changeset.for_create(:create, %{title: "Dog", score: 10}) + |> Ash.create!() + + Post + |> Ash.Changeset.for_create(:create, %{title: "Cat", score: 20}) + |> Ash.create!() + + query = + Post + |> Ash.Query.sort([{:title, :asc}]) + |> Ash.Query.load([:latest_comment_title]) + |> Ash.Query.combination_of([ + Ash.Query.Combination.base( + filter: expr(score < 15), + calculations: %{ + sort_order: calc(score * 20, type: :integer) + }, + sort: [{calc(score * 20, type: :integer), :desc}] + ), + Ash.Query.Combination.union( + filter: expr(score >= 15), + calculations: %{ + sort_order: calc(score * 5, type: :integer) + }, + sort: [{calc(score * 5, type: :integer), :desc}] + ) + ]) + |> Ash.Query.sort([{calc(^combinations(:sort_order)), :desc}], prepend?: true) + + result = Ash.read!(query) + titles = Enum.map(result, & &1.title) + # Expected order: sort_order DESC, then title ASC + # Dog(200), Apple(125), Cat(100), Zebra(100) + expected_title_order = ["Dog", "Apple", "Cat", "Zebra"] + assert titles == expected_title_order + end + + test "combination query without nullable calc works" do + Post + |> Ash.Changeset.for_create(:create, %{title: "Zebra", score: 5}) + |> Ash.create!() + + Post + |> Ash.Changeset.for_create(:create, %{title: "Apple", score: 25}) + |> Ash.create!() + + Post + |> Ash.Changeset.for_create(:create, %{title: "Dog", score: 10}) + |> Ash.create!() + + Post + |> Ash.Changeset.for_create(:create, %{title: "Cat", score: 20}) + |> Ash.create!() + + query = + Post + |> Ash.Query.sort([{:title, :asc}]) + |> Ash.Query.combination_of([ + Ash.Query.Combination.base( + filter: expr(score < 15), + calculations: %{ + sort_order: calc(score * 20, type: :integer) + }, + sort: [{calc(score * 20, type: :integer), :desc}] + ), + Ash.Query.Combination.union( + filter: expr(score >= 15), + calculations: %{ + sort_order: calc(score * 5, type: :integer) + }, + sort: [{calc(score * 5, type: :integer), :desc}] + ) + ]) + |> Ash.Query.sort([{calc(^combinations(:sort_order)), :desc}], prepend?: true) + + result = Ash.read!(query) + titles = Enum.map(result, & &1.title) + # Expected order: sort_order DESC, then title ASC + # Dog(200), Apple(125), Cat(100), Zebra(100) + expected_title_order = ["Dog", "Apple", "Cat", "Zebra"] + assert titles == expected_title_order + end + end + + describe "Author combination_of with nullable calculations" do + test "Author combination query with allow_nil? calculation loses ORDER BY" do + Author + |> Ash.Changeset.for_create(:create, %{first_name: "Zebra", last_name: "User"}) + |> Ash.create!() + + Author + |> Ash.Changeset.for_create(:create, %{first_name: "Apple", last_name: "User"}) + |> Ash.create!() + + Author + |> Ash.Changeset.for_create(:create, %{first_name: "Dog", last_name: "User"}) + |> Ash.create!() + + Author + |> Ash.Changeset.for_create(:create, %{first_name: "Cat", last_name: "User"}) + |> Ash.create!() + + query = + Author + |> Ash.Query.sort([{:first_name, :asc}]) + |> Ash.Query.load([:profile_description_calc]) + |> Ash.Query.combination_of([ + Ash.Query.Combination.base( + filter: expr(first_name in ["Zebra", "Dog"]), + calculations: %{ + sort_order: calc(1000, type: :integer) + }, + sort: [{calc(1000, type: :integer), :desc}] + ), + Ash.Query.Combination.union( + filter: expr(first_name in ["Apple", "Cat"]), + calculations: %{ + sort_order: calc(500, type: :integer) + }, + sort: [{calc(500, type: :integer), :desc}] + ) + ]) + |> Ash.Query.sort([{calc(^combinations(:sort_order)), :desc}], prepend?: true) + + result = Ash.read!(query) + first_names = Enum.map(result, & &1.first_name) + # Expected order: sort_order DESC, then first_name ASC + # [Dog, Zebra] (1000), [Apple, Cat] (500) → Dog, Zebra, Apple, Cat + expected_name_order = ["Dog", "Zebra", "Apple", "Cat"] + assert first_names == expected_name_order + end + + test "Author combination query without nullable calc works" do + Author + |> Ash.Changeset.for_create(:create, %{first_name: "Zebra", last_name: "User"}) + |> Ash.create!() + + Author + |> Ash.Changeset.for_create(:create, %{first_name: "Apple", last_name: "User"}) + |> Ash.create!() + + Author + |> Ash.Changeset.for_create(:create, %{first_name: "Dog", last_name: "User"}) + |> Ash.create!() + + Author + |> Ash.Changeset.for_create(:create, %{first_name: "Cat", last_name: "User"}) + |> Ash.create!() + + query = + Author + |> Ash.Query.sort([{:first_name, :asc}]) + |> Ash.Query.combination_of([ + Ash.Query.Combination.base( + filter: expr(first_name in ["Zebra", "Dog"]), + calculations: %{ + sort_order: calc(1000, type: :integer) + } + ), + Ash.Query.Combination.union( + filter: expr(first_name in ["Apple", "Cat"]), + calculations: %{ + sort_order: calc(500, type: :integer) + } + ) + ]) + |> Ash.Query.sort([{calc(^combinations(:sort_order)), :desc}], prepend?: true) + + result = Ash.read!(query) + first_names = Enum.map(result, & &1.first_name) + # Expected order: sort_order DESC, then first_name ASC + # [Dog, Zebra] (1000), [Apple, Cat] (500) → Dog, Zebra, Apple, Cat + expected_name_order = ["Dog", "Zebra", "Apple", "Cat"] + assert first_names == expected_name_order + end + end +end diff --git a/test/support/resources/author.ex b/test/support/resources/author.ex index acf9310a..54568518 100644 --- a/test/support/resources/author.ex +++ b/test/support/resources/author.ex @@ -175,6 +175,8 @@ defmodule AshPostgres.Test.Author do calculate(:has_posts, :boolean, expr(exists(posts, true == true))) calculate(:has_no_posts, :boolean, expr(has_posts == false)) + + calculate(:profile_description_calc, :string, expr(profile.description), allow_nil?: true) end aggregates do diff --git a/test/support/resources/post.ex b/test/support/resources/post.ex index 5da68941..94ab170e 100644 --- a/test/support/resources/post.ex +++ b/test/support/resources/post.ex @@ -1006,6 +1006,8 @@ defmodule AshPostgres.Test.Post do calculate(:author_first_name_ref_agg_calc, :string, expr(author_first_name)) calculate(:author_profile_description_from_agg, :string, expr(author_profile_description)) + + calculate(:latest_comment_title, :string, expr(latest_comment.title), allow_nil?: true) end aggregates do From 8f5097f779a36dcbde791ff91d9e67d470f2b962 Mon Sep 17 00:00:00 2001 From: Zach Daniel Date: Mon, 7 Jul 2025 21:11:40 -0400 Subject: [PATCH 079/174] fix: retain sort when upgrading to a subquery --- lib/data_layer.ex | 1 + test/combination_nullable_calc_test.exs | 197 ------------------------ test/combination_test.exs | 191 +++++++++++++++++++++++ 3 files changed, 192 insertions(+), 197 deletions(-) delete mode 100644 test/combination_nullable_calc_test.exs diff --git a/lib/data_layer.ex b/lib/data_layer.ex index 22efd25e..0a8b4644 100644 --- a/lib/data_layer.ex +++ b/lib/data_layer.ex @@ -3445,6 +3445,7 @@ defmodule AshPostgres.DataLayer do &Map.merge(&1, %{ already_selected: fieldset, subquery_upgrade?: true, + sort: query.__ash_bindings__[:sort], context: query.__ash_bindings__.context }) ) diff --git a/test/combination_nullable_calc_test.exs b/test/combination_nullable_calc_test.exs deleted file mode 100644 index 1618f1c8..00000000 --- a/test/combination_nullable_calc_test.exs +++ /dev/null @@ -1,197 +0,0 @@ -defmodule AshPostgres.CombinationNullableCalcTest do - @moduledoc false - use AshPostgres.RepoCase, async: false - alias AshPostgres.Test.Author - alias AshPostgres.Test.Post - - require Ash.Query - import Ash.Expr - - describe "combination_of with nullable calculations" do - test "combination query with allow_nil? calculation loses ORDER BY" do - Post - |> Ash.Changeset.for_create(:create, %{title: "Zebra", score: 5}) - |> Ash.create!() - - Post - |> Ash.Changeset.for_create(:create, %{title: "Apple", score: 25}) - |> Ash.create!() - - Post - |> Ash.Changeset.for_create(:create, %{title: "Dog", score: 10}) - |> Ash.create!() - - Post - |> Ash.Changeset.for_create(:create, %{title: "Cat", score: 20}) - |> Ash.create!() - - query = - Post - |> Ash.Query.sort([{:title, :asc}]) - |> Ash.Query.load([:latest_comment_title]) - |> Ash.Query.combination_of([ - Ash.Query.Combination.base( - filter: expr(score < 15), - calculations: %{ - sort_order: calc(score * 20, type: :integer) - }, - sort: [{calc(score * 20, type: :integer), :desc}] - ), - Ash.Query.Combination.union( - filter: expr(score >= 15), - calculations: %{ - sort_order: calc(score * 5, type: :integer) - }, - sort: [{calc(score * 5, type: :integer), :desc}] - ) - ]) - |> Ash.Query.sort([{calc(^combinations(:sort_order)), :desc}], prepend?: true) - - result = Ash.read!(query) - titles = Enum.map(result, & &1.title) - # Expected order: sort_order DESC, then title ASC - # Dog(200), Apple(125), Cat(100), Zebra(100) - expected_title_order = ["Dog", "Apple", "Cat", "Zebra"] - assert titles == expected_title_order - end - - test "combination query without nullable calc works" do - Post - |> Ash.Changeset.for_create(:create, %{title: "Zebra", score: 5}) - |> Ash.create!() - - Post - |> Ash.Changeset.for_create(:create, %{title: "Apple", score: 25}) - |> Ash.create!() - - Post - |> Ash.Changeset.for_create(:create, %{title: "Dog", score: 10}) - |> Ash.create!() - - Post - |> Ash.Changeset.for_create(:create, %{title: "Cat", score: 20}) - |> Ash.create!() - - query = - Post - |> Ash.Query.sort([{:title, :asc}]) - |> Ash.Query.combination_of([ - Ash.Query.Combination.base( - filter: expr(score < 15), - calculations: %{ - sort_order: calc(score * 20, type: :integer) - }, - sort: [{calc(score * 20, type: :integer), :desc}] - ), - Ash.Query.Combination.union( - filter: expr(score >= 15), - calculations: %{ - sort_order: calc(score * 5, type: :integer) - }, - sort: [{calc(score * 5, type: :integer), :desc}] - ) - ]) - |> Ash.Query.sort([{calc(^combinations(:sort_order)), :desc}], prepend?: true) - - result = Ash.read!(query) - titles = Enum.map(result, & &1.title) - # Expected order: sort_order DESC, then title ASC - # Dog(200), Apple(125), Cat(100), Zebra(100) - expected_title_order = ["Dog", "Apple", "Cat", "Zebra"] - assert titles == expected_title_order - end - end - - describe "Author combination_of with nullable calculations" do - test "Author combination query with allow_nil? calculation loses ORDER BY" do - Author - |> Ash.Changeset.for_create(:create, %{first_name: "Zebra", last_name: "User"}) - |> Ash.create!() - - Author - |> Ash.Changeset.for_create(:create, %{first_name: "Apple", last_name: "User"}) - |> Ash.create!() - - Author - |> Ash.Changeset.for_create(:create, %{first_name: "Dog", last_name: "User"}) - |> Ash.create!() - - Author - |> Ash.Changeset.for_create(:create, %{first_name: "Cat", last_name: "User"}) - |> Ash.create!() - - query = - Author - |> Ash.Query.sort([{:first_name, :asc}]) - |> Ash.Query.load([:profile_description_calc]) - |> Ash.Query.combination_of([ - Ash.Query.Combination.base( - filter: expr(first_name in ["Zebra", "Dog"]), - calculations: %{ - sort_order: calc(1000, type: :integer) - }, - sort: [{calc(1000, type: :integer), :desc}] - ), - Ash.Query.Combination.union( - filter: expr(first_name in ["Apple", "Cat"]), - calculations: %{ - sort_order: calc(500, type: :integer) - }, - sort: [{calc(500, type: :integer), :desc}] - ) - ]) - |> Ash.Query.sort([{calc(^combinations(:sort_order)), :desc}], prepend?: true) - - result = Ash.read!(query) - first_names = Enum.map(result, & &1.first_name) - # Expected order: sort_order DESC, then first_name ASC - # [Dog, Zebra] (1000), [Apple, Cat] (500) → Dog, Zebra, Apple, Cat - expected_name_order = ["Dog", "Zebra", "Apple", "Cat"] - assert first_names == expected_name_order - end - - test "Author combination query without nullable calc works" do - Author - |> Ash.Changeset.for_create(:create, %{first_name: "Zebra", last_name: "User"}) - |> Ash.create!() - - Author - |> Ash.Changeset.for_create(:create, %{first_name: "Apple", last_name: "User"}) - |> Ash.create!() - - Author - |> Ash.Changeset.for_create(:create, %{first_name: "Dog", last_name: "User"}) - |> Ash.create!() - - Author - |> Ash.Changeset.for_create(:create, %{first_name: "Cat", last_name: "User"}) - |> Ash.create!() - - query = - Author - |> Ash.Query.sort([{:first_name, :asc}]) - |> Ash.Query.combination_of([ - Ash.Query.Combination.base( - filter: expr(first_name in ["Zebra", "Dog"]), - calculations: %{ - sort_order: calc(1000, type: :integer) - } - ), - Ash.Query.Combination.union( - filter: expr(first_name in ["Apple", "Cat"]), - calculations: %{ - sort_order: calc(500, type: :integer) - } - ) - ]) - |> Ash.Query.sort([{calc(^combinations(:sort_order)), :desc}], prepend?: true) - - result = Ash.read!(query) - first_names = Enum.map(result, & &1.first_name) - # Expected order: sort_order DESC, then first_name ASC - # [Dog, Zebra] (1000), [Apple, Cat] (500) → Dog, Zebra, Apple, Cat - expected_name_order = ["Dog", "Zebra", "Apple", "Cat"] - assert first_names == expected_name_order - end - end -end diff --git a/test/combination_test.exs b/test/combination_test.exs index 086ae91d..5faaa020 100644 --- a/test/combination_test.exs +++ b/test/combination_test.exs @@ -5,6 +5,9 @@ defmodule AshPostgres.CombinationTest do require Ash.Query import Ash.Expr + alias AshPostgres.Test.Author + alias AshPostgres.Test.Post + describe "combinations in actions" do test "with no data" do Post @@ -427,4 +430,192 @@ defmodule AshPostgres.CombinationTest do |> Enum.map(&to_string(&1.category)) end end + + describe "combination_of with nullable calculations" do + test "combination query with allow_nil? calculation loses ORDER BY" do + Post + |> Ash.Changeset.for_create(:create, %{title: "Zebra", score: 5}) + |> Ash.create!() + + Post + |> Ash.Changeset.for_create(:create, %{title: "Apple", score: 25}) + |> Ash.create!() + + Post + |> Ash.Changeset.for_create(:create, %{title: "Dog", score: 10}) + |> Ash.create!() + + Post + |> Ash.Changeset.for_create(:create, %{title: "Cat", score: 20}) + |> Ash.create!() + + query = + Post + |> Ash.Query.sort([{:title, :asc}]) + |> Ash.Query.load([:latest_comment_title]) + |> Ash.Query.combination_of([ + Ash.Query.Combination.base( + filter: expr(score < 15), + calculations: %{ + sort_order: calc(score * 20, type: :integer) + }, + sort: [{calc(score * 20, type: :integer), :desc}] + ), + Ash.Query.Combination.union( + filter: expr(score >= 15), + calculations: %{ + sort_order: calc(score * 5, type: :integer) + }, + sort: [{calc(score * 5, type: :integer), :desc}] + ) + ]) + |> Ash.Query.sort([{calc(^combinations(:sort_order)), :desc}], prepend?: true) + + result = Ash.read!(query) + titles = Enum.map(result, & &1.title) + # Expected order: sort_order DESC, then title ASC + # Dog(200), Apple(125), Cat(100), Zebra(100) + expected_title_order = ["Dog", "Apple", "Cat", "Zebra"] + assert titles == expected_title_order + end + + test "combination query without nullable calc works" do + Post + |> Ash.Changeset.for_create(:create, %{title: "Zebra", score: 5}) + |> Ash.create!() + + Post + |> Ash.Changeset.for_create(:create, %{title: "Apple", score: 25}) + |> Ash.create!() + + Post + |> Ash.Changeset.for_create(:create, %{title: "Dog", score: 10}) + |> Ash.create!() + + Post + |> Ash.Changeset.for_create(:create, %{title: "Cat", score: 20}) + |> Ash.create!() + + query = + Post + |> Ash.Query.sort([{:title, :asc}]) + |> Ash.Query.combination_of([ + Ash.Query.Combination.base( + filter: expr(score < 15), + calculations: %{ + sort_order: calc(score * 20, type: :integer) + }, + sort: [{calc(score * 20, type: :integer), :desc}] + ), + Ash.Query.Combination.union( + filter: expr(score >= 15), + calculations: %{ + sort_order: calc(score * 5, type: :integer) + }, + sort: [{calc(score * 5, type: :integer), :desc}] + ) + ]) + |> Ash.Query.sort([{calc(^combinations(:sort_order)), :desc}], prepend?: true) + + result = Ash.read!(query) + titles = Enum.map(result, & &1.title) + # Expected order: sort_order DESC, then title ASC + # Dog(200), Apple(125), Cat(100), Zebra(100) + expected_title_order = ["Dog", "Apple", "Cat", "Zebra"] + assert titles == expected_title_order + end + end + + describe "Author combination_of with nullable calculations" do + test "Author combination query with allow_nil? calculation loses ORDER BY" do + Author + |> Ash.Changeset.for_create(:create, %{first_name: "Zebra", last_name: "User"}) + |> Ash.create!() + + Author + |> Ash.Changeset.for_create(:create, %{first_name: "Apple", last_name: "User"}) + |> Ash.create!() + + Author + |> Ash.Changeset.for_create(:create, %{first_name: "Dog", last_name: "User"}) + |> Ash.create!() + + Author + |> Ash.Changeset.for_create(:create, %{first_name: "Cat", last_name: "User"}) + |> Ash.create!() + + query = + Author + |> Ash.Query.sort([{:first_name, :asc}]) + |> Ash.Query.load([:profile_description_calc]) + |> Ash.Query.combination_of([ + Ash.Query.Combination.base( + filter: expr(first_name in ["Zebra", "Dog"]), + calculations: %{ + sort_order: calc(1000, type: :integer) + }, + sort: [{calc(1000, type: :integer), :desc}] + ), + Ash.Query.Combination.union( + filter: expr(first_name in ["Apple", "Cat"]), + calculations: %{ + sort_order: calc(500, type: :integer) + }, + sort: [{calc(500, type: :integer), :desc}] + ) + ]) + |> Ash.Query.sort([{calc(^combinations(:sort_order)), :desc}], prepend?: true) + + result = Ash.read!(query) + first_names = Enum.map(result, & &1.first_name) + # Expected order: sort_order DESC, then first_name ASC + # [Dog, Zebra] (1000), [Apple, Cat] (500) → Dog, Zebra, Apple, Cat + expected_name_order = ["Dog", "Zebra", "Apple", "Cat"] + assert first_names == expected_name_order + end + + test "Author combination query without nullable calc works" do + Author + |> Ash.Changeset.for_create(:create, %{first_name: "Zebra", last_name: "User"}) + |> Ash.create!() + + Author + |> Ash.Changeset.for_create(:create, %{first_name: "Apple", last_name: "User"}) + |> Ash.create!() + + Author + |> Ash.Changeset.for_create(:create, %{first_name: "Dog", last_name: "User"}) + |> Ash.create!() + + Author + |> Ash.Changeset.for_create(:create, %{first_name: "Cat", last_name: "User"}) + |> Ash.create!() + + query = + Author + |> Ash.Query.sort([{:first_name, :asc}]) + |> Ash.Query.combination_of([ + Ash.Query.Combination.base( + filter: expr(first_name in ["Zebra", "Dog"]), + calculations: %{ + sort_order: calc(1000, type: :integer) + } + ), + Ash.Query.Combination.union( + filter: expr(first_name in ["Apple", "Cat"]), + calculations: %{ + sort_order: calc(500, type: :integer) + } + ) + ]) + |> Ash.Query.sort([{calc(^combinations(:sort_order)), :desc}], prepend?: true) + + result = Ash.read!(query) + first_names = Enum.map(result, & &1.first_name) + # Expected order: sort_order DESC, then first_name ASC + # [Dog, Zebra] (1000), [Apple, Cat] (500) → Dog, Zebra, Apple, Cat + expected_name_order = ["Dog", "Zebra", "Apple", "Cat"] + assert first_names == expected_name_order + end + end end From 986c4c724ea098c4679be271869f1d598ad287e6 Mon Sep 17 00:00:00 2001 From: Zach Daniel Date: Mon, 7 Jul 2025 21:25:02 -0400 Subject: [PATCH 080/174] fix: properly return the type when configured closes #588 --- lib/resource_generator/spec.ex | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/lib/resource_generator/spec.ex b/lib/resource_generator/spec.ex index ff942f16..8b6d4ae6 100644 --- a/lib/resource_generator/spec.ex +++ b/lib/resource_generator/spec.ex @@ -908,7 +908,7 @@ defmodule AshPostgres.ResourceGenerator.Spec do - MyApp.Types.CustomType - {:array, :string} - Use `skip` to skip ignore this attribute. + Use `skip` to ignore this attribute. """) end @@ -921,13 +921,12 @@ defmodule AshPostgres.ResourceGenerator.Spec do ":" <> type -> new_type = String.to_atom(type) Process.put({:type_cache, attribute.type}, new_type) - {:ok, %{attribute | attr_type: new_type}} + {:ok, new_type} type -> try do - Code.eval_string(type) Process.put({:type_cache, attribute.type}, new_type) - {:ok, %{attribute | attr_type: new_type}} + {:ok, type} rescue _e -> get_type(attribute, opts) From 50d9d0f02c0f5747b30d74012f40a649c265ca76 Mon Sep 17 00:00:00 2001 From: Zach Daniel Date: Tue, 8 Jul 2025 23:10:22 -0400 Subject: [PATCH 081/174] chore: update deps --- mix.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/mix.lock b/mix.lock index 7f05569e..297b4075 100644 --- a/mix.lock +++ b/mix.lock @@ -18,12 +18,12 @@ "ex_check": {:hex, :ex_check, "0.16.0", "07615bef493c5b8d12d5119de3914274277299c6483989e52b0f6b8358a26b5f", [:mix], [], "hexpm", "4d809b72a18d405514dda4809257d8e665ae7cf37a7aee3be6b74a34dec310f5"}, "ex_doc": {:hex, :ex_doc, "0.38.2", "504d25eef296b4dec3b8e33e810bc8b5344d565998cd83914ffe1b8503737c02", [:mix], [{:earmark_parser, "~> 1.4.44", [hex: :earmark_parser, repo: "hexpm", optional: false]}, {:makeup_c, ">= 0.1.0", [hex: :makeup_c, repo: "hexpm", optional: true]}, {:makeup_elixir, "~> 0.14 or ~> 1.0", [hex: :makeup_elixir, repo: "hexpm", optional: false]}, {:makeup_erlang, "~> 0.1 or ~> 1.0", [hex: :makeup_erlang, repo: "hexpm", optional: false]}, {:makeup_html, ">= 0.1.0", [hex: :makeup_html, repo: "hexpm", optional: true]}], "hexpm", "732f2d972e42c116a70802f9898c51b54916e542cc50968ac6980512ec90f42b"}, "file_system": {:hex, :file_system, "1.1.0", "08d232062284546c6c34426997dd7ef6ec9f8bbd090eb91780283c9016840e8f", [:mix], [], "hexpm", "bfcf81244f416871f2a2e15c1b515287faa5db9c6bcf290222206d120b3d43f6"}, - "finch": {:hex, :finch, "0.19.0", "c644641491ea854fc5c1bbaef36bfc764e3f08e7185e1f084e35e0672241b76d", [:mix], [{:mime, "~> 1.0 or ~> 2.0", [hex: :mime, repo: "hexpm", optional: false]}, {:mint, "~> 1.6.2 or ~> 1.7", [hex: :mint, repo: "hexpm", optional: false]}, {:nimble_options, "~> 0.4 or ~> 1.0", [hex: :nimble_options, repo: "hexpm", optional: false]}, {:nimble_pool, "~> 1.1", [hex: :nimble_pool, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "fc5324ce209125d1e2fa0fcd2634601c52a787aff1cd33ee833664a5af4ea2b6"}, + "finch": {:hex, :finch, "0.20.0", "5330aefb6b010f424dcbbc4615d914e9e3deae40095e73ab0c1bb0968933cadf", [:mix], [{:mime, "~> 1.0 or ~> 2.0", [hex: :mime, repo: "hexpm", optional: false]}, {:mint, "~> 1.6.2 or ~> 1.7", [hex: :mint, repo: "hexpm", optional: false]}, {:nimble_options, "~> 0.4 or ~> 1.0", [hex: :nimble_options, repo: "hexpm", optional: false]}, {:nimble_pool, "~> 1.1", [hex: :nimble_pool, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "2658131a74d051aabfcba936093c903b8e89da9a1b63e430bee62045fa9b2ee2"}, "git_cli": {:hex, :git_cli, "0.3.0", "a5422f9b95c99483385b976f5d43f7e8233283a47cda13533d7c16131cb14df5", [:mix], [], "hexpm", "78cb952f4c86a41f4d3511f1d3ecb28edb268e3a7df278de2faa1bd4672eaf9b"}, "git_ops": {:hex, :git_ops, "2.8.0", "29ac9ab68bf9645973cb2752047b987e75cbd3d9761489c615e3ba80018fa885", [:mix], [{:git_cli, "~> 0.2", [hex: :git_cli, repo: "hexpm", optional: false]}, {:igniter, ">= 0.5.27 and < 1.0.0-0", [hex: :igniter, repo: "hexpm", optional: true]}, {:nimble_parsec, "~> 1.0", [hex: :nimble_parsec, repo: "hexpm", optional: false]}, {:req, "~> 0.5", [hex: :req, repo: "hexpm", optional: false]}], "hexpm", "b535e4ad6b5d13e14c455e76f65825659081b5530b0827eb0232d18719530eec"}, "glob_ex": {:hex, :glob_ex, "0.1.11", "cb50d3f1ef53f6ca04d6252c7fde09fd7a1cf63387714fe96f340a1349e62c93", [:mix], [], "hexpm", "342729363056e3145e61766b416769984c329e4378f1d558b63e341020525de4"}, "hpax": {:hex, :hpax, "1.0.3", "ed67ef51ad4df91e75cc6a1494f851850c0bd98ebc0be6e81b026e765ee535aa", [:mix], [], "hexpm", "8eab6e1cfa8d5918c2ce4ba43588e894af35dbd8e91e6e55c817bca5847df34a"}, - "igniter": {:hex, :igniter, "0.6.10", "896d75fc48ed493ff22accd111fe2e34747163d26c5f374267bad1ef4a6c5076", [:mix], [{:glob_ex, "~> 0.1.7", [hex: :glob_ex, repo: "hexpm", optional: false]}, {:jason, "~> 1.4", [hex: :jason, repo: "hexpm", optional: false]}, {:owl, "~> 0.11", [hex: :owl, repo: "hexpm", optional: false]}, {:phx_new, "~> 1.7", [hex: :phx_new, repo: "hexpm", optional: true]}, {:req, "~> 0.5", [hex: :req, repo: "hexpm", optional: false]}, {:rewrite, ">= 1.1.1 and < 2.0.0-0", [hex: :rewrite, repo: "hexpm", optional: false]}, {:sourceror, "~> 1.4", [hex: :sourceror, repo: "hexpm", optional: false]}, {:spitfire, ">= 0.1.3 and < 1.0.0-0", [hex: :spitfire, repo: "hexpm", optional: false]}], "hexpm", "9a3abc56e94f362730a3023dfe0ac2ced1186f95fa1ccf4cc30df0c8ce0fc276"}, + "igniter": {:hex, :igniter, "0.6.12", "a8e20a67c2729dd0e03ccb06799efb23017fbdbed939ac6a88d8ddcc1a005bf7", [:mix], [{:glob_ex, "~> 0.1.7", [hex: :glob_ex, repo: "hexpm", optional: false]}, {:jason, "~> 1.4", [hex: :jason, repo: "hexpm", optional: false]}, {:owl, "~> 0.11", [hex: :owl, repo: "hexpm", optional: false]}, {:phx_new, "~> 1.7", [hex: :phx_new, repo: "hexpm", optional: true]}, {:req, "~> 0.5", [hex: :req, repo: "hexpm", optional: false]}, {:rewrite, ">= 1.1.1 and < 2.0.0-0", [hex: :rewrite, repo: "hexpm", optional: false]}, {:sourceror, "~> 1.4", [hex: :sourceror, repo: "hexpm", optional: false]}, {:spitfire, ">= 0.1.3 and < 1.0.0-0", [hex: :spitfire, repo: "hexpm", optional: false]}], "hexpm", "4ba183c8fa299ac1207c078c3d055c635b418d6573006a2e92c131dfd1879a92"}, "iterex": {:hex, :iterex, "0.1.2", "58f9b9b9a22a55cbfc7b5234a9c9c63eaac26d276b3db80936c0e1c60355a5a6", [:mix], [], "hexpm", "2e103b8bcc81757a9af121f6dc0df312c9a17220f302b1193ef720460d03029d"}, "jason": {:hex, :jason, "1.4.4", "b9226785a9aa77b6857ca22832cffa5d5011a667207eb2a0ad56adb5db443b8a", [:mix], [{:decimal, "~> 1.0 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm", "c5eb0cab91f094599f94d55bc63409236a8ec69a21a67814529e8d5f6cc90b3b"}, "libgraph": {:hex, :libgraph, "0.16.0", "3936f3eca6ef826e08880230f806bfea13193e49bf153f93edcf0239d4fd1d07", [:mix], [], "hexpm", "41ca92240e8a4138c30a7e06466acc709b0cbb795c643e9e17174a178982d6bf"}, @@ -47,7 +47,7 @@ "spark": {:hex, :spark, "2.2.67", "67626cb9f59ea4b1c5aa85d4afdd025e0740cbd49ed82665d0a40ff007d7fd4b", [:mix], [{:igniter, ">= 0.3.64 and < 1.0.0-0", [hex: :igniter, repo: "hexpm", optional: true]}, {:jason, "~> 1.4", [hex: :jason, repo: "hexpm", optional: true]}, {:sourceror, "~> 1.2", [hex: :sourceror, repo: "hexpm", optional: true]}], "hexpm", "c8575402e3afc66871362e821bece890536d16319cdb758c5fb2d1250182e46f"}, "spitfire": {:hex, :spitfire, "0.2.1", "29e154873f05444669c7453d3d931820822cbca5170e88f0f8faa1de74a79b47", [:mix], [], "hexpm", "6eeed75054a38341b2e1814d41bb0a250564092358de2669fdb57ff88141d91b"}, "splode": {:hex, :splode, "0.2.9", "3a2776e187c82f42f5226b33b1220ccbff74f4bcc523dd4039c804caaa3ffdc7", [:mix], [], "hexpm", "8002b00c6e24f8bd1bcced3fbaa5c33346048047bb7e13d2f3ad428babbd95c3"}, - "statistex": {:hex, :statistex, "1.0.0", "f3dc93f3c0c6c92e5f291704cf62b99b553253d7969e9a5fa713e5481cd858a5", [:mix], [], "hexpm", "ff9d8bee7035028ab4742ff52fc80a2aa35cece833cf5319009b52f1b5a86c27"}, + "statistex": {:hex, :statistex, "1.1.0", "7fec1eb2f580a0d2c1a05ed27396a084ab064a40cfc84246dbfb0c72a5c761e5", [:mix], [], "hexpm", "f5950ea26ad43246ba2cce54324ac394a4e7408fdcf98b8e230f503a0cba9cf5"}, "stream_data": {:hex, :stream_data, "1.2.0", "58dd3f9e88afe27dc38bef26fce0c84a9e7a96772b2925c7b32cd2435697a52b", [:mix], [], "hexpm", "eb5c546ee3466920314643edf68943a5b14b32d1da9fe01698dc92b73f89a9ed"}, "telemetry": {:hex, :telemetry, "1.3.0", "fedebbae410d715cf8e7062c96a1ef32ec22e764197f70cda73d82778d61e7a2", [:rebar3], [], "hexpm", "7015fc8919dbe63764f4b4b87a95b7c0996bd539e0d499be6ec9d7f3875b79e6"}, "text_diff": {:hex, :text_diff, "0.1.0", "1caf3175e11a53a9a139bc9339bd607c47b9e376b073d4571c031913317fecaa", [:mix], [], "hexpm", "d1ffaaecab338e49357b6daa82e435f877e0649041ace7755583a0ea3362dbd7"}, From a0314239db57fff2046b80cc70e482fced54d99a Mon Sep 17 00:00:00 2001 From: Zach Daniel Date: Tue, 8 Jul 2025 23:11:22 -0400 Subject: [PATCH 082/174] chore: release version v2.6.10 --- CHANGELOG.md | 11 +++++++++++ mix.exs | 2 +- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5cf99e8d..b5d718f2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,17 @@ See [Conventional Commits](https://www.conventionalcommits.org) for commit guide +## [v2.6.10](https://github.com/ash-project/ash_postgres/compare/v2.6.9...v2.6.10) (2025-07-09) + + + + +### Bug Fixes: + +* properly return the type when configured by Zach Daniel + +* retain sort when upgrading to a subquery by Zach Daniel + ## [v2.6.9](https://github.com/ash-project/ash_postgres/compare/v2.6.8...v2.6.9) (2025-06-25) diff --git a/mix.exs b/mix.exs index 4c59bea1..c954d13a 100644 --- a/mix.exs +++ b/mix.exs @@ -5,7 +5,7 @@ defmodule AshPostgres.MixProject do The PostgreSQL data layer for Ash Framework """ - @version "2.6.9" + @version "2.6.10" def project do [ From 106a532e95ffe393f387ca518e84b5b38a6b5303 Mon Sep 17 00:00:00 2001 From: Zach Daniel Date: Tue, 8 Jul 2025 23:11:46 -0400 Subject: [PATCH 083/174] chore: update more deps --- mix.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mix.lock b/mix.lock index 297b4075..a09948cd 100644 --- a/mix.lock +++ b/mix.lock @@ -1,6 +1,6 @@ %{ - "ash": {:hex, :ash, "3.5.25", "99f7139e98b745a64312ae80e2420589205b2fec1799f00fc58da771d2c63373", [:mix], [{:decimal, "~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:ecto, "~> 3.7", [hex: :ecto, repo: "hexpm", optional: false]}, {:ets, "~> 0.8", [hex: :ets, repo: "hexpm", optional: false]}, {:igniter, ">= 0.6.4 and < 1.0.0-0", [hex: :igniter, repo: "hexpm", optional: true]}, {:jason, ">= 1.0.0", [hex: :jason, repo: "hexpm", optional: false]}, {:picosat_elixir, "~> 0.2", [hex: :picosat_elixir, repo: "hexpm", optional: true]}, {:plug, ">= 0.0.0", [hex: :plug, repo: "hexpm", optional: true]}, {:reactor, "~> 0.11", [hex: :reactor, repo: "hexpm", optional: false]}, {:simple_sat, ">= 0.1.1 and < 1.0.0-0", [hex: :simple_sat, repo: "hexpm", optional: true]}, {:spark, ">= 2.2.65 and < 3.0.0-0", [hex: :spark, repo: "hexpm", optional: false]}, {:splode, ">= 0.2.6 and < 1.0.0-0", [hex: :splode, repo: "hexpm", optional: false]}, {:stream_data, "~> 1.0", [hex: :stream_data, repo: "hexpm", optional: false]}, {:telemetry, "~> 1.1", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "d45844ea30062b796d4adcad75b8d91e21081ac0f1bb6627d1a2663ca5ecf258"}, - "ash_sql": {:hex, :ash_sql, "0.2.84", "1187555609f4773aacb5cccdca82a78c2b3f7390e78b400a8f03c91b2e7cd82f", [:mix], [{:ash, ">= 3.5.25 and < 4.0.0-0", [hex: :ash, repo: "hexpm", optional: false]}, {:ecto, "~> 3.9", [hex: :ecto, repo: "hexpm", optional: false]}, {:ecto_sql, "~> 3.9", [hex: :ecto_sql, repo: "hexpm", optional: false]}], "hexpm", "5e6a4d3070e60a0653c572527276a8c034b9458e37b1aca8868b17fcf0a1d1c0"}, + "ash": {:hex, :ash, "3.5.26", "f2e884623bfc39e0228a4fee0c41fbdb90195c6b1e1618a0a97f03f2dfbb1c4f", [:mix], [{:decimal, "~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:ecto, "~> 3.7", [hex: :ecto, repo: "hexpm", optional: false]}, {:ets, "~> 0.8", [hex: :ets, repo: "hexpm", optional: false]}, {:igniter, ">= 0.6.4 and < 1.0.0-0", [hex: :igniter, repo: "hexpm", optional: true]}, {:jason, ">= 1.0.0", [hex: :jason, repo: "hexpm", optional: false]}, {:picosat_elixir, "~> 0.2", [hex: :picosat_elixir, repo: "hexpm", optional: true]}, {:plug, ">= 0.0.0", [hex: :plug, repo: "hexpm", optional: true]}, {:reactor, "~> 0.11", [hex: :reactor, repo: "hexpm", optional: false]}, {:simple_sat, ">= 0.1.1 and < 1.0.0-0", [hex: :simple_sat, repo: "hexpm", optional: true]}, {:spark, ">= 2.2.65 and < 3.0.0-0", [hex: :spark, repo: "hexpm", optional: false]}, {:splode, ">= 0.2.6 and < 1.0.0-0", [hex: :splode, repo: "hexpm", optional: false]}, {:stream_data, "~> 1.0", [hex: :stream_data, repo: "hexpm", optional: false]}, {:telemetry, "~> 1.1", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "a9f5edbb7d838e2053e84f62c428650dadbff3ea4ec40ef68f167483eb7e9012"}, + "ash_sql": {:hex, :ash_sql, "0.2.85", "96a35d197f5ff846c17aca9225d4baafa0fda6c804f1e46a79345d237b5e5c5f", [:mix], [{:ash, ">= 3.5.25 and < 4.0.0-0", [hex: :ash, repo: "hexpm", optional: false]}, {:ecto, "~> 3.9", [hex: :ecto, repo: "hexpm", optional: false]}, {:ecto_sql, "~> 3.9", [hex: :ecto_sql, repo: "hexpm", optional: false]}], "hexpm", "62e7f8b79bcb04d82654ba519008b80bd21bd177ec646e9fffb87ec34285722b"}, "benchee": {:hex, :benchee, "1.4.0", "9f1f96a30ac80bab94faad644b39a9031d5632e517416a8ab0a6b0ac4df124ce", [:mix], [{:deep_merge, "~> 1.0", [hex: :deep_merge, repo: "hexpm", optional: false]}, {:statistex, "~> 1.0", [hex: :statistex, repo: "hexpm", optional: false]}, {:table, "~> 0.1.0", [hex: :table, repo: "hexpm", optional: true]}], "hexpm", "299cd10dd8ce51c9ea3ddb74bb150f93d25e968f93e4c1fa31698a8e4fa5d715"}, "bunt": {:hex, :bunt, "1.0.0", "081c2c665f086849e6d57900292b3a161727ab40431219529f13c4ddcf3e7a44", [:mix], [], "hexpm", "dc5f86aa08a5f6fa6b8096f0735c4e76d54ae5c9fa2c143e5a1fc7c1cd9bb6b5"}, "credo": {:hex, :credo, "1.7.12", "9e3c20463de4b5f3f23721527fcaf16722ec815e70ff6c60b86412c695d426c1", [:mix], [{:bunt, "~> 0.2.1 or ~> 1.0", [hex: :bunt, repo: "hexpm", optional: false]}, {:file_system, "~> 0.2 or ~> 1.0", [hex: :file_system, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "8493d45c656c5427d9c729235b99d498bd133421f3e0a683e5c1b561471291e5"}, From fdb077e7b52b1ecf50352ff18446a960480d14e4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kenneth=20Kostre=C5=A1evi=C4=87?= Date: Wed, 9 Jul 2025 22:02:33 +0200 Subject: [PATCH 084/174] fix: Reverse migrations order when reverting dev migrations (#590) --- lib/migration_generator/migration_generator.ex | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/migration_generator/migration_generator.ex b/lib/migration_generator/migration_generator.ex index a5984a67..84630f7d 100644 --- a/lib/migration_generator/migration_generator.ex +++ b/lib/migration_generator/migration_generator.ex @@ -556,6 +556,7 @@ defmodule AshPostgres.MigrationGenerator do |> Enum.filter(& &1) |> Enum.map(&load_migration!/1) |> Enum.sort() + |> Enum.reverse() |> Enum.filter(fn {version, _} -> version in versions end) @@ -589,6 +590,7 @@ defmodule AshPostgres.MigrationGenerator do |> Enum.filter(& &1) |> Enum.map(&load_migration!/1) |> Enum.sort() + |> Enum.reverse() |> Enum.filter(fn {version, _} -> version in versions end) From d174139867ace7027b6a97fcd557ff1d0a31592d Mon Sep 17 00:00:00 2001 From: Zach Daniel Date: Wed, 9 Jul 2025 17:34:56 -0400 Subject: [PATCH 085/174] chore: update installer for latest igniter changes --- lib/mix/tasks/ash_postgres.install.ex | 11 +++++++++-- mix.exs | 2 +- mix.lock | 2 +- 3 files changed, 11 insertions(+), 4 deletions(-) diff --git a/lib/mix/tasks/ash_postgres.install.ex b/lib/mix/tasks/ash_postgres.install.ex index 73f50db0..a984f2d8 100644 --- a/lib/mix/tasks/ash_postgres.install.ex +++ b/lib/mix/tasks/ash_postgres.install.ex @@ -200,12 +200,12 @@ if Code.ensure_loaded?(Igniter) do ) do {:ok, _zipper} -> zipper - |> Igniter.Project.Config.modify_configuration_code( + |> modify_configuration_code( [repo, :url], otp_app, {:database_url, [], nil} ) - |> Igniter.Project.Config.modify_configuration_code( + |> modify_configuration_code( [repo, :pool_size], otp_app, Sourceror.parse_string!(""" @@ -252,6 +252,13 @@ if Code.ensure_loaded?(Igniter) do end end + defp modify_configuration_code(zipper, path, otp_app, code) do + case Igniter.Project.Config.modify_config_code(zipper, path, otp_app, code) do + {:ok, zipper} -> zipper + _ -> zipper + end + end + defp configure_dev(igniter, otp_app, repo) do if Igniter.Project.Config.configures_key?(igniter, "dev.exs", otp_app, [repo]) do igniter diff --git a/mix.exs b/mix.exs index c954d13a..4aa37c8e 100644 --- a/mix.exs +++ b/mix.exs @@ -168,7 +168,7 @@ defmodule AshPostgres.MixProject do [ {:ash, ash_version("~> 3.5 and >= 3.5.13")}, {:ash_sql, ash_sql_version("~> 0.2 and >= 0.2.72")}, - {:igniter, "~> 0.6", optional: true}, + {:igniter, "~> 0.6 and >= 0.6.14", optional: true}, {:ecto_sql, "~> 3.13"}, {:ecto, "~> 3.13"}, {:jason, "~> 1.0"}, diff --git a/mix.lock b/mix.lock index a09948cd..e27a5efc 100644 --- a/mix.lock +++ b/mix.lock @@ -23,7 +23,7 @@ "git_ops": {:hex, :git_ops, "2.8.0", "29ac9ab68bf9645973cb2752047b987e75cbd3d9761489c615e3ba80018fa885", [:mix], [{:git_cli, "~> 0.2", [hex: :git_cli, repo: "hexpm", optional: false]}, {:igniter, ">= 0.5.27 and < 1.0.0-0", [hex: :igniter, repo: "hexpm", optional: true]}, {:nimble_parsec, "~> 1.0", [hex: :nimble_parsec, repo: "hexpm", optional: false]}, {:req, "~> 0.5", [hex: :req, repo: "hexpm", optional: false]}], "hexpm", "b535e4ad6b5d13e14c455e76f65825659081b5530b0827eb0232d18719530eec"}, "glob_ex": {:hex, :glob_ex, "0.1.11", "cb50d3f1ef53f6ca04d6252c7fde09fd7a1cf63387714fe96f340a1349e62c93", [:mix], [], "hexpm", "342729363056e3145e61766b416769984c329e4378f1d558b63e341020525de4"}, "hpax": {:hex, :hpax, "1.0.3", "ed67ef51ad4df91e75cc6a1494f851850c0bd98ebc0be6e81b026e765ee535aa", [:mix], [], "hexpm", "8eab6e1cfa8d5918c2ce4ba43588e894af35dbd8e91e6e55c817bca5847df34a"}, - "igniter": {:hex, :igniter, "0.6.12", "a8e20a67c2729dd0e03ccb06799efb23017fbdbed939ac6a88d8ddcc1a005bf7", [:mix], [{:glob_ex, "~> 0.1.7", [hex: :glob_ex, repo: "hexpm", optional: false]}, {:jason, "~> 1.4", [hex: :jason, repo: "hexpm", optional: false]}, {:owl, "~> 0.11", [hex: :owl, repo: "hexpm", optional: false]}, {:phx_new, "~> 1.7", [hex: :phx_new, repo: "hexpm", optional: true]}, {:req, "~> 0.5", [hex: :req, repo: "hexpm", optional: false]}, {:rewrite, ">= 1.1.1 and < 2.0.0-0", [hex: :rewrite, repo: "hexpm", optional: false]}, {:sourceror, "~> 1.4", [hex: :sourceror, repo: "hexpm", optional: false]}, {:spitfire, ">= 0.1.3 and < 1.0.0-0", [hex: :spitfire, repo: "hexpm", optional: false]}], "hexpm", "4ba183c8fa299ac1207c078c3d055c635b418d6573006a2e92c131dfd1879a92"}, + "igniter": {:hex, :igniter, "0.6.14", "c7d1aa437bd87389a724ab8971ed4f4b645d844f55cb9dfa2d3933a8350f5d68", [:mix], [{:glob_ex, "~> 0.1.7", [hex: :glob_ex, repo: "hexpm", optional: false]}, {:jason, "~> 1.4", [hex: :jason, repo: "hexpm", optional: false]}, {:owl, "~> 0.11", [hex: :owl, repo: "hexpm", optional: false]}, {:phx_new, "~> 1.7", [hex: :phx_new, repo: "hexpm", optional: true]}, {:req, "~> 0.5", [hex: :req, repo: "hexpm", optional: false]}, {:rewrite, ">= 1.1.1 and < 2.0.0-0", [hex: :rewrite, repo: "hexpm", optional: false]}, {:sourceror, "~> 1.4", [hex: :sourceror, repo: "hexpm", optional: false]}, {:spitfire, ">= 0.1.3 and < 1.0.0-0", [hex: :spitfire, repo: "hexpm", optional: false]}], "hexpm", "2d566654e3ee33351307053869235c51bed25fb2c0af491896fd91c3315ecb8c"}, "iterex": {:hex, :iterex, "0.1.2", "58f9b9b9a22a55cbfc7b5234a9c9c63eaac26d276b3db80936c0e1c60355a5a6", [:mix], [], "hexpm", "2e103b8bcc81757a9af121f6dc0df312c9a17220f302b1193ef720460d03029d"}, "jason": {:hex, :jason, "1.4.4", "b9226785a9aa77b6857ca22832cffa5d5011a667207eb2a0ad56adb5db443b8a", [:mix], [{:decimal, "~> 1.0 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm", "c5eb0cab91f094599f94d55bc63409236a8ec69a21a67814529e8d5f6cc90b3b"}, "libgraph": {:hex, :libgraph, "0.16.0", "3936f3eca6ef826e08880230f806bfea13193e49bf153f93edcf0239d4fd1d07", [:mix], [], "hexpm", "41ca92240e8a4138c30a7e06466acc709b0cbb795c643e9e17174a178982d6bf"}, From de90abdd71c10d26bdb7907856511d414b68e7ca Mon Sep 17 00:00:00 2001 From: Zach Daniel Date: Sun, 13 Jul 2025 22:01:25 -0400 Subject: [PATCH 086/174] improvement: make rollbacks safer by using `--to` instead of `-n` --- lib/data_layer.ex | 60 +++++++++++++++++++++++++++++++++++------------ 1 file changed, 45 insertions(+), 15 deletions(-) diff --git a/lib/data_layer.ex b/lib/data_layer.ex index 0a8b4644..b0000ee2 100644 --- a/lib/data_layer.ex +++ b/lib/data_layer.ex @@ -459,10 +459,14 @@ defmodule AshPostgres.DataLayer do end) |> Enum.take(20) |> Enum.map(&String.trim_leading(&1, migrations_path)) + |> Enum.map(&String.trim_leading(&1, "/")) + + indexed = + files |> Enum.with_index() |> Enum.map(fn {file, index} -> "#{index + 1}: #{file}" end) - n = + to = Mix.shell().prompt( """ How many migrations should be rolled back#{for_repo}? (default: 0) @@ -470,7 +474,7 @@ defmodule AshPostgres.DataLayer do Last 20 migration names, with the input you must provide to rollback up to *and including* that migration: - #{Enum.join(files, "\n")} + #{Enum.join(indexed, "\n")} Rollback to: """ |> String.trim_trailing() @@ -478,19 +482,32 @@ defmodule AshPostgres.DataLayer do |> String.trim() |> case do "" -> - 0 + nil + + "0" -> + nil n -> try do - String.to_integer(n) + files + |> Enum.at(String.to_integer(n) - 1) rescue _ -> reraise "Required an integer value, got: #{n}", __STACKTRACE__ end + |> String.split("_", parts: 2) + |> Enum.at(0) + |> String.to_integer() end - Mix.Task.run("ash_postgres.rollback", args ++ ["-r", inspect(repo), "-n", to_string(n)]) - Mix.Task.reenable("ash_postgres.rollback") + if to do + Mix.Task.run( + "ash_postgres.rollback", + args ++ ["-r", inspect(repo), "--to", to_string(to)] + ) + + Mix.Task.reenable("ash_postgres.rollback") + end tenant_files = tenant_migrations_path @@ -520,10 +537,14 @@ defmodule AshPostgres.DataLayer do end) |> Enum.take(20) |> Enum.map(&String.trim_leading(&1, tenant_migrations_path)) + |> Enum.map(&String.trim_leading(&1, "/")) + + indexed = + tenant_files |> Enum.with_index() |> Enum.map(fn {file, index} -> "#{index + 1}: #{file}" end) - n = + to = Mix.shell().prompt( """ @@ -536,7 +557,7 @@ defmodule AshPostgres.DataLayer do Last 20 migration names, with the input you must provide to rollback up to *and including* that migration: - #{Enum.join(tenant_files, "\n")} + #{Enum.join(indexed, "\n")} Rollback to: """ @@ -545,23 +566,32 @@ defmodule AshPostgres.DataLayer do |> String.trim() |> case do "" -> - 0 + nil + + "0" -> + nil n -> try do - String.to_integer(n) + tenant_files + |> Enum.at(String.to_integer(n) - 1) rescue _ -> reraise "Required an integer value, got: #{n}", __STACKTRACE__ end + |> String.split("_", parts: 2) + |> Enum.at(0) + |> String.to_integer() end - Mix.Task.run( - "ash_postgres.rollback", - args ++ ["--tenants", "-r", inspect(repo), "-n", to_string(n)] - ) + if to do + Mix.Task.run( + "ash_postgres.rollback", + args ++ ["--tenants", "-r", inspect(repo), "--to", to] + ) - Mix.Task.reenable("ash_postgres.rollback") + Mix.Task.reenable("ash_postgres.rollback") + end end end end) From 1f064f52b51e7661aee0fde95a9c719a0f1ad70e Mon Sep 17 00:00:00 2001 From: Zach Daniel Date: Mon, 14 Jul 2025 13:48:00 -0400 Subject: [PATCH 087/174] fix: clean args and properly scope rollback task closes #592 --- lib/data_layer.ex | 10 +++++++++- lib/mix/helpers.ex | 4 ++-- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/lib/data_layer.ex b/lib/data_layer.ex index b0000ee2..d527bce6 100644 --- a/lib/data_layer.ex +++ b/lib/data_layer.ex @@ -424,7 +424,15 @@ defmodule AshPostgres.DataLayer do end def rollback(args) do - repos = AshPostgres.Mix.Helpers.repos!([], args) + {opts, _, _} = + OptionParser.parse(args, + switches: [ + repo: :string + ], + aliases: [r: :repo] + ) + + repos = AshPostgres.Mix.Helpers.repos!(opts, args) show_for_repo? = Enum.count_until(repos, 2) == 2 diff --git a/lib/mix/helpers.ex b/lib/mix/helpers.ex index 2eb2d40b..316778fd 100644 --- a/lib/mix/helpers.ex +++ b/lib/mix/helpers.ex @@ -119,7 +119,7 @@ defmodule AshPostgres.Mix.Helpers do def delete_flag(args, arg) do case Enum.split_while(args, &(&1 != arg)) do {left, [_ | rest]} -> - left ++ rest + delete_flag(left ++ rest, arg) _ -> args @@ -129,7 +129,7 @@ defmodule AshPostgres.Mix.Helpers do def delete_arg(args, arg) do case Enum.split_while(args, &(&1 != arg)) do {left, [_, _ | rest]} -> - left ++ rest + delete_arg(left ++ rest, arg) _ -> args From 8787615f38e276c8b37d405f010b1c044d0ed834 Mon Sep 17 00:00:00 2001 From: Jesse Williams Date: Tue, 15 Jul 2025 16:26:43 -0700 Subject: [PATCH 088/174] test: reproduce a bug with a complex calculation (#593) * reproduce a bug with a complex calculation * no unused vars --- .../20250714225304.json | 86 +++++++++++++++++++ .../20250714225304.json | 55 ++++++++++++ ..._complex_calculations_folder_and_items.exs | 61 +++++++++++++ test/complex_calculations_test.exs | 30 +++++++ test/support/complex_calculations/domain.ex | 2 + .../complex_calculations/resources/folder.ex | 75 ++++++++++++++++ .../resources/folder_item.ex | 38 ++++++++ 7 files changed, 347 insertions(+) create mode 100644 priv/resource_snapshots/test_repo/complex_calculations_folder_items/20250714225304.json create mode 100644 priv/resource_snapshots/test_repo/complex_calculations_folders/20250714225304.json create mode 100644 priv/test_repo/migrations/20250714225304_add_complex_calculations_folder_and_items.exs create mode 100644 test/support/complex_calculations/resources/folder.ex create mode 100644 test/support/complex_calculations/resources/folder_item.ex diff --git a/priv/resource_snapshots/test_repo/complex_calculations_folder_items/20250714225304.json b/priv/resource_snapshots/test_repo/complex_calculations_folder_items/20250714225304.json new file mode 100644 index 00000000..f217c546 --- /dev/null +++ b/priv/resource_snapshots/test_repo/complex_calculations_folder_items/20250714225304.json @@ -0,0 +1,86 @@ +{ + "attributes": [ + { + "allow_nil?": false, + "default": "fragment(\"gen_random_uuid()\")", + "generated?": false, + "precision": null, + "primary_key?": true, + "references": null, + "scale": null, + "size": null, + "source": "id", + "type": "uuid" + }, + { + "allow_nil?": true, + "default": "nil", + "generated?": false, + "precision": null, + "primary_key?": false, + "references": null, + "scale": null, + "size": null, + "source": "name", + "type": "text" + }, + { + "allow_nil?": true, + "default": "nil", + "generated?": false, + "precision": null, + "primary_key?": false, + "references": null, + "scale": null, + "size": null, + "source": "level", + "type": "bigint" + }, + { + "allow_nil?": true, + "default": "nil", + "generated?": false, + "precision": null, + "primary_key?": false, + "references": { + "deferrable": false, + "destination_attribute": "id", + "destination_attribute_default": null, + "destination_attribute_generated": null, + "index?": false, + "match_type": null, + "match_with": null, + "multitenancy": { + "attribute": null, + "global": null, + "strategy": null + }, + "name": "complex_calculations_folder_items_folder_id_fkey", + "on_delete": null, + "on_update": null, + "primary_key?": true, + "schema": "public", + "table": "complex_calculations_folders" + }, + "scale": null, + "size": null, + "source": "folder_id", + "type": "uuid" + } + ], + "base_filter": null, + "check_constraints": [], + "custom_indexes": [], + "custom_statements": [], + "has_create_action": false, + "hash": "C7BC97676F202A744482B4095560986B265E6BCB74F6E69C1330034FBC4981E5", + "identities": [], + "multitenancy": { + "attribute": null, + "global": null, + "strategy": null + }, + "repo": "Elixir.AshPostgres.TestRepo", + "schema": null, + "table": "complex_calculations_folder_items" +} \ No newline at end of file diff --git a/priv/resource_snapshots/test_repo/complex_calculations_folders/20250714225304.json b/priv/resource_snapshots/test_repo/complex_calculations_folders/20250714225304.json new file mode 100644 index 00000000..8d499706 --- /dev/null +++ b/priv/resource_snapshots/test_repo/complex_calculations_folders/20250714225304.json @@ -0,0 +1,55 @@ +{ + "attributes": [ + { + "allow_nil?": false, + "default": "fragment(\"gen_random_uuid()\")", + "generated?": false, + "precision": null, + "primary_key?": true, + "references": null, + "scale": null, + "size": null, + "source": "id", + "type": "uuid" + }, + { + "allow_nil?": true, + "default": "nil", + "generated?": false, + "precision": null, + "primary_key?": false, + "references": null, + "scale": null, + "size": null, + "source": "some_integer_setting", + "type": "bigint" + }, + { + "allow_nil?": true, + "default": "nil", + "generated?": false, + "precision": null, + "primary_key?": false, + "references": null, + "scale": null, + "size": null, + "source": "level", + "type": "ltree" + } + ], + "base_filter": null, + "check_constraints": [], + "custom_indexes": [], + "custom_statements": [], + "has_create_action": false, + "hash": "1982E0DAF0B5B22502A5747ED8533C6F1D58E882E1132FAB0939EC13F2CFC5AF", + "identities": [], + "multitenancy": { + "attribute": null, + "global": null, + "strategy": null + }, + "repo": "Elixir.AshPostgres.TestRepo", + "schema": null, + "table": "complex_calculations_folders" +} \ No newline at end of file diff --git a/priv/test_repo/migrations/20250714225304_add_complex_calculations_folder_and_items.exs b/priv/test_repo/migrations/20250714225304_add_complex_calculations_folder_and_items.exs new file mode 100644 index 00000000..88d73d15 --- /dev/null +++ b/priv/test_repo/migrations/20250714225304_add_complex_calculations_folder_and_items.exs @@ -0,0 +1,61 @@ +defmodule AshPostgres.TestRepo.Migrations.AddComplexCalculationsFolderAndItems do + @moduledoc """ + Updates resources based on their most recent snapshots. + + This file was autogenerated with `mix ash_postgres.generate_migrations` + """ + + use Ecto.Migration + + def up do + create table(:complex_calculations_folder_items, primary_key: false) do + add(:id, :uuid, null: false, default: fragment("gen_random_uuid()"), primary_key: true) + add(:name, :text) + add(:level, :bigint) + add(:folder_id, :uuid) + end + + create table(:complex_calculations_folders, primary_key: false) do + add(:id, :uuid, null: false, default: fragment("gen_random_uuid()"), primary_key: true) + end + + alter table(:complex_calculations_folder_items) do + modify( + :folder_id, + references(:complex_calculations_folders, + column: :id, + name: "complex_calculations_folder_items_folder_id_fkey", + type: :uuid, + prefix: "public" + ) + ) + end + + alter table(:complex_calculations_folders) do + add(:some_integer_setting, :bigint) + add(:level, :ltree) + end + end + + def down do + alter table(:complex_calculations_folders) do + remove(:level) + remove(:some_integer_setting) + end + + drop( + constraint( + :complex_calculations_folder_items, + "complex_calculations_folder_items_folder_id_fkey" + ) + ) + + alter table(:complex_calculations_folder_items) do + modify(:folder_id, :uuid) + end + + drop(table(:complex_calculations_folders)) + + drop(table(:complex_calculations_folder_items)) + end +end diff --git a/test/complex_calculations_test.exs b/test/complex_calculations_test.exs index 83cb39cf..5617a6d1 100644 --- a/test/complex_calculations_test.exs +++ b/test/complex_calculations_test.exs @@ -373,4 +373,34 @@ defmodule AshPostgres.Test.ComplexCalculationsTest do assert doc_before.is_active_with_timezone == false assert doc_after.is_active_with_timezone == true end + + test "gnarly parent bug with some weird ltree setup" do + _folder_a = + Ash.Seed.seed!( + AshPostgres.Test.Support.ComplexCalculations.Folder, + %{some_integer_setting: 1, level: "a"} + ) + + _folder_b = + Ash.Seed.seed!( + AshPostgres.Test.Support.ComplexCalculations.Folder, + %{some_integer_setting: nil, level: "a.b"} + ) + + folder_c = + Ash.Seed.seed!( + AshPostgres.Test.Support.ComplexCalculations.Folder, + %{some_integer_setting: nil, level: "a.b.c"} + ) + + folder_c_item = + Ash.Seed.seed!( + AshPostgres.Test.Support.ComplexCalculations.FolderItem, + %{name: "Item in C", level: 1, folder_id: folder_c.id} + ) + + # reproduction: this raises Unknown Error + # * ** (Postgrex.Error) ERROR 42846 (cannot_coerce) cannot cast type bigint to ltree + assert Ash.calculate!(folder_c_item, :folder_setting) == 1 + end end diff --git a/test/support/complex_calculations/domain.ex b/test/support/complex_calculations/domain.ex index 76d066c2..15a306ef 100644 --- a/test/support/complex_calculations/domain.ex +++ b/test/support/complex_calculations/domain.ex @@ -9,6 +9,8 @@ defmodule AshPostgres.Test.ComplexCalculations.Domain do resource(AshPostgres.Test.ComplexCalculations.Channel) resource(AshPostgres.Test.ComplexCalculations.DMChannel) resource(AshPostgres.Test.ComplexCalculations.ChannelMember) + resource(AshPostgres.Test.Support.ComplexCalculations.Folder) + resource(AshPostgres.Test.Support.ComplexCalculations.FolderItem) end authorization do diff --git a/test/support/complex_calculations/resources/folder.ex b/test/support/complex_calculations/resources/folder.ex new file mode 100644 index 00000000..d4b31e38 --- /dev/null +++ b/test/support/complex_calculations/resources/folder.ex @@ -0,0 +1,75 @@ +defmodule AshPostgres.Test.Support.ComplexCalculations.Folder do + @moduledoc """ + A tree structure using the ltree type. + """ + + alias AshPostgres.Test.Support.ComplexCalculations.Folder + + use Ash.Resource, + domain: AshPostgres.Test.ComplexCalculations.Domain, + data_layer: AshPostgres.DataLayer + + @default_integer_setting 5 + + postgres do + table "complex_calculations_folders" + repo(AshPostgres.TestRepo) + end + + attributes do + uuid_primary_key(:id) + + attribute(:some_integer_setting, :integer, + public?: true, + description: "Some setting that can be inherited. No real semantic meaning, just for demo" + ) + + attribute(:level, AshPostgres.Ltree, public?: true) + end + + actions do + defaults([:read]) + end + + relationships do + has_many :ancestors, Folder do + public?(true) + no_attributes?(true) + + # use ltree @> operator to get all ancestors + filter(expr(fragment("? @> ? AND ? < ?", level, parent(level), nlevel, parent(nlevel)))) + end + + has_many :items, AshPostgres.Test.Support.ComplexCalculations.FolderItem do + public?(true) + end + end + + calculations do + calculate(:nlevel, :integer, expr(fragment("nlevel(?)", level))) + + calculate( + :effective_integer_setting, + :integer, + expr( + if is_nil(some_integer_setting) do + # closest ancestor with a non-nil setting, or the default + first( + ancestors, + query: [ + sort: [nlevel: :desc], + filter: expr(not is_nil(some_integer_setting)) + ], + field: :some_integer_setting + ) || @default_integer_setting + else + some_integer_setting + end + ), + description: """ + The effective integer setting, inheriting from ancestors if not explicitly set, + or defaulting to #{@default_integer_setting} if none are set. No real semantic meaning, just for demo + """ + ) + end +end diff --git a/test/support/complex_calculations/resources/folder_item.ex b/test/support/complex_calculations/resources/folder_item.ex new file mode 100644 index 00000000..ac115aef --- /dev/null +++ b/test/support/complex_calculations/resources/folder_item.ex @@ -0,0 +1,38 @@ +defmodule AshPostgres.Test.Support.ComplexCalculations.FolderItem do + @moduledoc false + use Ash.Resource, + domain: AshPostgres.Test.ComplexCalculations.Domain, + data_layer: AshPostgres.DataLayer + + postgres do + table "complex_calculations_folder_items" + repo(AshPostgres.TestRepo) + end + + attributes do + uuid_primary_key(:id) + attribute(:name, :string, public?: true) + + attribute(:level, :integer, + public?: true, + description: """ + No real semantic meaning here, just for demo, this *deliberately* is named the same as the ltree level column in Folder, + but is NOT related to it in any way + """ + ) + end + + actions do + defaults([:read]) + end + + calculations do + calculate(:folder_setting, :integer, expr(folder.effective_integer_setting)) + end + + relationships do + belongs_to(:folder, AshPostgres.Test.Support.ComplexCalculations.Folder) do + public?(true) + end + end +end From ce21b9239aeb85240082fe5f2657894e2a078031 Mon Sep 17 00:00:00 2001 From: Zach Daniel Date: Thu, 17 Jul 2025 10:48:53 -0400 Subject: [PATCH 089/174] chore: release version v2.6.11 --- CHANGELOG.md | 15 +++++++++++++++ mix.exs | 2 +- 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b5d718f2..996183c1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,21 @@ See [Conventional Commits](https://www.conventionalcommits.org) for commit guide +## [v2.6.11](https://github.com/ash-project/ash_postgres/compare/v2.6.10...v2.6.11) (2025-07-17) + + + + +### Bug Fixes: + +* clean args and properly scope rollback task by Zach Daniel + +* Reverse migrations order when reverting dev migrations (#590) by Kenneth Kostrešević + +### Improvements: + +* make rollbacks safer by using `--to` instead of `-n` by Zach Daniel + ## [v2.6.10](https://github.com/ash-project/ash_postgres/compare/v2.6.9...v2.6.10) (2025-07-09) diff --git a/mix.exs b/mix.exs index 4aa37c8e..68afd199 100644 --- a/mix.exs +++ b/mix.exs @@ -5,7 +5,7 @@ defmodule AshPostgres.MixProject do The PostgreSQL data layer for Ash Framework """ - @version "2.6.10" + @version "2.6.11" def project do [ From db24c4e4a55355c410173456b7be7eebc3187004 Mon Sep 17 00:00:00 2001 From: Zach Daniel Date: Thu, 17 Jul 2025 10:49:25 -0400 Subject: [PATCH 090/174] chore: update deps --- mix.lock | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/mix.lock b/mix.lock index e27a5efc..b0c5a864 100644 --- a/mix.lock +++ b/mix.lock @@ -1,6 +1,6 @@ %{ - "ash": {:hex, :ash, "3.5.26", "f2e884623bfc39e0228a4fee0c41fbdb90195c6b1e1618a0a97f03f2dfbb1c4f", [:mix], [{:decimal, "~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:ecto, "~> 3.7", [hex: :ecto, repo: "hexpm", optional: false]}, {:ets, "~> 0.8", [hex: :ets, repo: "hexpm", optional: false]}, {:igniter, ">= 0.6.4 and < 1.0.0-0", [hex: :igniter, repo: "hexpm", optional: true]}, {:jason, ">= 1.0.0", [hex: :jason, repo: "hexpm", optional: false]}, {:picosat_elixir, "~> 0.2", [hex: :picosat_elixir, repo: "hexpm", optional: true]}, {:plug, ">= 0.0.0", [hex: :plug, repo: "hexpm", optional: true]}, {:reactor, "~> 0.11", [hex: :reactor, repo: "hexpm", optional: false]}, {:simple_sat, ">= 0.1.1 and < 1.0.0-0", [hex: :simple_sat, repo: "hexpm", optional: true]}, {:spark, ">= 2.2.65 and < 3.0.0-0", [hex: :spark, repo: "hexpm", optional: false]}, {:splode, ">= 0.2.6 and < 1.0.0-0", [hex: :splode, repo: "hexpm", optional: false]}, {:stream_data, "~> 1.0", [hex: :stream_data, repo: "hexpm", optional: false]}, {:telemetry, "~> 1.1", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "a9f5edbb7d838e2053e84f62c428650dadbff3ea4ec40ef68f167483eb7e9012"}, - "ash_sql": {:hex, :ash_sql, "0.2.85", "96a35d197f5ff846c17aca9225d4baafa0fda6c804f1e46a79345d237b5e5c5f", [:mix], [{:ash, ">= 3.5.25 and < 4.0.0-0", [hex: :ash, repo: "hexpm", optional: false]}, {:ecto, "~> 3.9", [hex: :ecto, repo: "hexpm", optional: false]}, {:ecto_sql, "~> 3.9", [hex: :ecto_sql, repo: "hexpm", optional: false]}], "hexpm", "62e7f8b79bcb04d82654ba519008b80bd21bd177ec646e9fffb87ec34285722b"}, + "ash": {:hex, :ash, "3.5.27", "bfa227b75da2b447d1b98e16a19b2fa957fe32bef33dfe33aa93b861a532c641", [:mix], [{:decimal, "~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:ecto, "~> 3.7", [hex: :ecto, repo: "hexpm", optional: false]}, {:ets, "~> 0.8", [hex: :ets, repo: "hexpm", optional: false]}, {:igniter, ">= 0.6.4 and < 1.0.0-0", [hex: :igniter, repo: "hexpm", optional: true]}, {:jason, ">= 1.0.0", [hex: :jason, repo: "hexpm", optional: false]}, {:picosat_elixir, "~> 0.2", [hex: :picosat_elixir, repo: "hexpm", optional: true]}, {:plug, ">= 0.0.0", [hex: :plug, repo: "hexpm", optional: true]}, {:reactor, "~> 0.11", [hex: :reactor, repo: "hexpm", optional: false]}, {:simple_sat, ">= 0.1.1 and < 1.0.0-0", [hex: :simple_sat, repo: "hexpm", optional: true]}, {:spark, ">= 2.2.65 and < 3.0.0-0", [hex: :spark, repo: "hexpm", optional: false]}, {:splode, ">= 0.2.6 and < 1.0.0-0", [hex: :splode, repo: "hexpm", optional: false]}, {:stream_data, "~> 1.0", [hex: :stream_data, repo: "hexpm", optional: false]}, {:telemetry, "~> 1.1", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "f75694b0012e4e56293e1beef1d6c20a52f2f2c9baebfa5c8f2426d25d43608e"}, + "ash_sql": {:hex, :ash_sql, "0.2.86", "9b4013010981352e295eed22dc6b09998e23a724baca07f1ff617b6bec4ba8d4", [:mix], [{:ash, ">= 3.5.25 and < 4.0.0-0", [hex: :ash, repo: "hexpm", optional: false]}, {:ecto, "~> 3.9", [hex: :ecto, repo: "hexpm", optional: false]}, {:ecto_sql, "~> 3.9", [hex: :ecto_sql, repo: "hexpm", optional: false]}], "hexpm", "97fa13e87d55194f7746c5a9fa97a9693bc26cdf7825d1c6d7cdfe5f166285a4"}, "benchee": {:hex, :benchee, "1.4.0", "9f1f96a30ac80bab94faad644b39a9031d5632e517416a8ab0a6b0ac4df124ce", [:mix], [{:deep_merge, "~> 1.0", [hex: :deep_merge, repo: "hexpm", optional: false]}, {:statistex, "~> 1.0", [hex: :statistex, repo: "hexpm", optional: false]}, {:table, "~> 0.1.0", [hex: :table, repo: "hexpm", optional: true]}], "hexpm", "299cd10dd8ce51c9ea3ddb74bb150f93d25e968f93e4c1fa31698a8e4fa5d715"}, "bunt": {:hex, :bunt, "1.0.0", "081c2c665f086849e6d57900292b3a161727ab40431219529f13c4ddcf3e7a44", [:mix], [], "hexpm", "dc5f86aa08a5f6fa6b8096f0735c4e76d54ae5c9fa2c143e5a1fc7c1cd9bb6b5"}, "credo": {:hex, :credo, "1.7.12", "9e3c20463de4b5f3f23721527fcaf16722ec815e70ff6c60b86412c695d426c1", [:mix], [{:bunt, "~> 0.2.1 or ~> 1.0", [hex: :bunt, repo: "hexpm", optional: false]}, {:file_system, "~> 0.2 or ~> 1.0", [hex: :file_system, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "8493d45c656c5427d9c729235b99d498bd133421f3e0a683e5c1b561471291e5"}, @@ -23,7 +23,7 @@ "git_ops": {:hex, :git_ops, "2.8.0", "29ac9ab68bf9645973cb2752047b987e75cbd3d9761489c615e3ba80018fa885", [:mix], [{:git_cli, "~> 0.2", [hex: :git_cli, repo: "hexpm", optional: false]}, {:igniter, ">= 0.5.27 and < 1.0.0-0", [hex: :igniter, repo: "hexpm", optional: true]}, {:nimble_parsec, "~> 1.0", [hex: :nimble_parsec, repo: "hexpm", optional: false]}, {:req, "~> 0.5", [hex: :req, repo: "hexpm", optional: false]}], "hexpm", "b535e4ad6b5d13e14c455e76f65825659081b5530b0827eb0232d18719530eec"}, "glob_ex": {:hex, :glob_ex, "0.1.11", "cb50d3f1ef53f6ca04d6252c7fde09fd7a1cf63387714fe96f340a1349e62c93", [:mix], [], "hexpm", "342729363056e3145e61766b416769984c329e4378f1d558b63e341020525de4"}, "hpax": {:hex, :hpax, "1.0.3", "ed67ef51ad4df91e75cc6a1494f851850c0bd98ebc0be6e81b026e765ee535aa", [:mix], [], "hexpm", "8eab6e1cfa8d5918c2ce4ba43588e894af35dbd8e91e6e55c817bca5847df34a"}, - "igniter": {:hex, :igniter, "0.6.14", "c7d1aa437bd87389a724ab8971ed4f4b645d844f55cb9dfa2d3933a8350f5d68", [:mix], [{:glob_ex, "~> 0.1.7", [hex: :glob_ex, repo: "hexpm", optional: false]}, {:jason, "~> 1.4", [hex: :jason, repo: "hexpm", optional: false]}, {:owl, "~> 0.11", [hex: :owl, repo: "hexpm", optional: false]}, {:phx_new, "~> 1.7", [hex: :phx_new, repo: "hexpm", optional: true]}, {:req, "~> 0.5", [hex: :req, repo: "hexpm", optional: false]}, {:rewrite, ">= 1.1.1 and < 2.0.0-0", [hex: :rewrite, repo: "hexpm", optional: false]}, {:sourceror, "~> 1.4", [hex: :sourceror, repo: "hexpm", optional: false]}, {:spitfire, ">= 0.1.3 and < 1.0.0-0", [hex: :spitfire, repo: "hexpm", optional: false]}], "hexpm", "2d566654e3ee33351307053869235c51bed25fb2c0af491896fd91c3315ecb8c"}, + "igniter": {:hex, :igniter, "0.6.19", "d87703b36890bc4278341d966a7ed8e10604a18610a4331ac10c75d1af48fff4", [:mix], [{:glob_ex, "~> 0.1.7", [hex: :glob_ex, repo: "hexpm", optional: false]}, {:jason, "~> 1.4", [hex: :jason, repo: "hexpm", optional: false]}, {:owl, "~> 0.11", [hex: :owl, repo: "hexpm", optional: false]}, {:phx_new, "~> 1.7", [hex: :phx_new, repo: "hexpm", optional: true]}, {:req, "~> 0.5", [hex: :req, repo: "hexpm", optional: false]}, {:rewrite, ">= 1.1.1 and < 2.0.0-0", [hex: :rewrite, repo: "hexpm", optional: false]}, {:sourceror, "~> 1.4", [hex: :sourceror, repo: "hexpm", optional: false]}, {:spitfire, ">= 0.1.3 and < 1.0.0-0", [hex: :spitfire, repo: "hexpm", optional: false]}], "hexpm", "c2070b3fdbd238fc0a0bfbc1f125b5c0f79a1fe2f5b3c7b43cd33de696783663"}, "iterex": {:hex, :iterex, "0.1.2", "58f9b9b9a22a55cbfc7b5234a9c9c63eaac26d276b3db80936c0e1c60355a5a6", [:mix], [], "hexpm", "2e103b8bcc81757a9af121f6dc0df312c9a17220f302b1193ef720460d03029d"}, "jason": {:hex, :jason, "1.4.4", "b9226785a9aa77b6857ca22832cffa5d5011a667207eb2a0ad56adb5db443b8a", [:mix], [{:decimal, "~> 1.0 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm", "c5eb0cab91f094599f94d55bc63409236a8ec69a21a67814529e8d5f6cc90b3b"}, "libgraph": {:hex, :libgraph, "0.16.0", "3936f3eca6ef826e08880230f806bfea13193e49bf153f93edcf0239d4fd1d07", [:mix], [], "hexpm", "41ca92240e8a4138c30a7e06466acc709b0cbb795c643e9e17174a178982d6bf"}, @@ -39,7 +39,7 @@ "owl": {:hex, :owl, "0.12.2", "65906b525e5c3ef51bab6cba7687152be017aebe1da077bb719a5ee9f7e60762", [:mix], [{:ucwidth, "~> 0.2", [hex: :ucwidth, repo: "hexpm", optional: true]}], "hexpm", "6398efa9e1fea70a04d24231e10dcd66c1ac1aa2da418d20ef5357ec61de2880"}, "postgrex": {:hex, :postgrex, "0.20.0", "363ed03ab4757f6bc47942eff7720640795eb557e1935951c1626f0d303a3aed", [:mix], [{:db_connection, "~> 2.1", [hex: :db_connection, repo: "hexpm", optional: false]}, {:decimal, "~> 1.5 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:table, "~> 0.1.0", [hex: :table, repo: "hexpm", optional: true]}], "hexpm", "d36ef8b36f323d29505314f704e21a1a038e2dc387c6409ee0cd24144e187c0f"}, "reactor": {:hex, :reactor, "0.15.6", "d717f9add549b25a089a94c90197718d2d838e35d81dd776b1d81587d4cf2aaa", [:mix], [{:igniter, "~> 0.4", [hex: :igniter, repo: "hexpm", optional: true]}, {:iterex, "~> 0.1", [hex: :iterex, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}, {:libgraph, "~> 0.16", [hex: :libgraph, repo: "hexpm", optional: false]}, {:spark, "~> 2.0", [hex: :spark, repo: "hexpm", optional: false]}, {:splode, "~> 0.2", [hex: :splode, repo: "hexpm", optional: false]}, {:telemetry, "~> 1.2", [hex: :telemetry, repo: "hexpm", optional: false]}, {:yaml_elixir, "~> 2.11", [hex: :yaml_elixir, repo: "hexpm", optional: false]}, {:ymlr, "~> 5.0", [hex: :ymlr, repo: "hexpm", optional: false]}], "hexpm", "74db98165e3644d86e0f723672d91ceca4339eaa935bcad7e78bf146a46d77b9"}, - "req": {:hex, :req, "0.5.14", "521b449fa0bf275e6d034c05f29bec21789a0d6cd6f7a1c326c7bee642bf6e07", [:mix], [{:brotli, "~> 0.3.1", [hex: :brotli, repo: "hexpm", optional: true]}, {:ezstd, "~> 1.0", [hex: :ezstd, repo: "hexpm", optional: true]}, {:finch, "~> 0.17", [hex: :finch, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}, {:mime, "~> 2.0.6 or ~> 2.1", [hex: :mime, repo: "hexpm", optional: false]}, {:nimble_csv, "~> 1.0", [hex: :nimble_csv, repo: "hexpm", optional: true]}, {:plug, "~> 1.0", [hex: :plug, repo: "hexpm", optional: true]}], "hexpm", "b7b15692071d556c73432c7797aa7e96b51d1a2db76f746b976edef95c930021"}, + "req": {:hex, :req, "0.5.15", "662020efb6ea60b9f0e0fac9be88cd7558b53fe51155a2d9899de594f9906ba9", [:mix], [{:brotli, "~> 0.3.1", [hex: :brotli, repo: "hexpm", optional: true]}, {:ezstd, "~> 1.0", [hex: :ezstd, repo: "hexpm", optional: true]}, {:finch, "~> 0.17", [hex: :finch, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}, {:mime, "~> 2.0.6 or ~> 2.1", [hex: :mime, repo: "hexpm", optional: false]}, {:nimble_csv, "~> 1.0", [hex: :nimble_csv, repo: "hexpm", optional: true]}, {:plug, "~> 1.0", [hex: :plug, repo: "hexpm", optional: true]}], "hexpm", "a6513a35fad65467893ced9785457e91693352c70b58bbc045b47e5eb2ef0c53"}, "rewrite": {:hex, :rewrite, "1.1.2", "f5a5d10f5fed1491a6ff48e078d4585882695962ccc9e6c779bae025d1f92eda", [:mix], [{:glob_ex, "~> 0.1", [hex: :glob_ex, repo: "hexpm", optional: false]}, {:sourceror, "~> 1.0", [hex: :sourceror, repo: "hexpm", optional: false]}, {:text_diff, "~> 0.1", [hex: :text_diff, repo: "hexpm", optional: false]}], "hexpm", "7f8b94b1e3528d0a47b3e8b7bfeca559d2948a65fa7418a9ad7d7712703d39d4"}, "simple_sat": {:hex, :simple_sat, "0.1.3", "f650fc3c184a5fe741868b5ac56dc77fdbb428468f6dbf1978e14d0334497578", [:mix], [], "hexpm", "a54305066a356b7194dc81db2a89232bacdc0b3edaef68ed9aba28dcbc34887b"}, "sobelow": {:hex, :sobelow, "0.14.0", "dd82aae8f72503f924fe9dd97ffe4ca694d2f17ec463dcfd365987c9752af6ee", [:mix], [{:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "7ecf91e298acfd9b24f5d761f19e8f6e6ac585b9387fb6301023f1f2cd5eed5f"}, @@ -54,5 +54,5 @@ "tz": {:hex, :tz, "0.28.1", "717f5ffddfd1e475e2a233e221dc0b4b76c35c4b3650b060c8e3ba29dd6632e9", [:mix], [{:castore, "~> 0.1 or ~> 1.0", [hex: :castore, repo: "hexpm", optional: true]}, {:mint, "~> 1.6", [hex: :mint, repo: "hexpm", optional: true]}], "hexpm", "bfdca1aa1902643c6c43b77c1fb0cb3d744fd2f09a8a98405468afdee0848c8a"}, "yamerl": {:hex, :yamerl, "0.10.0", "4ff81fee2f1f6a46f1700c0d880b24d193ddb74bd14ef42cb0bcf46e81ef2f8e", [:rebar3], [], "hexpm", "346adb2963f1051dc837a2364e4acf6eb7d80097c0f53cbdc3046ec8ec4b4e6e"}, "yaml_elixir": {:hex, :yaml_elixir, "2.11.0", "9e9ccd134e861c66b84825a3542a1c22ba33f338d82c07282f4f1f52d847bd50", [:mix], [{:yamerl, "~> 0.10", [hex: :yamerl, repo: "hexpm", optional: false]}], "hexpm", "53cc28357ee7eb952344995787f4bb8cc3cecbf189652236e9b163e8ce1bc242"}, - "ymlr": {:hex, :ymlr, "5.1.3", "a8061add5a378e20272a31905be70209a5680fdbe0ad51f40cb1af4bdd0a010b", [:mix], [], "hexpm", "8663444fa85101a117887c170204d4c5a2182567e5f84767f0071cf15f2efb1e"}, + "ymlr": {:hex, :ymlr, "5.1.4", "b924d61e1fc1ec371cde6ab3ccd9311110b1e052fc5c2460fb322e8380e7712a", [:mix], [], "hexpm", "75f16cf0709fbd911b30311a0359a7aa4b5476346c01882addefd5f2b1cfaa51"}, } From 5428e89671872cf585e07d71ae6090bc9c2e111e Mon Sep 17 00:00:00 2001 From: Zach Daniel Date: Sun, 20 Jul 2025 23:14:40 -0400 Subject: [PATCH 091/174] chore: tests for aggregate error w/ modify_query --- test/aggregate_test.exs | 11 +++++++++++ test/support/resources/comment.ex | 15 +++++++++++++++ test/support/resources/post.ex | 4 ++++ 3 files changed, 30 insertions(+) diff --git a/test/aggregate_test.exs b/test/aggregate_test.exs index 167a00c9..d17b753b 100644 --- a/test/aggregate_test.exs +++ b/test/aggregate_test.exs @@ -1667,4 +1667,15 @@ defmodule AshSql.AggregateTest do Ash.Query.filter_input(AshPostgres.Test.StandupClub, filter) |> Ash.read!(load: [:punchline_count]) end + + @tag :regression + test "aggregates with modify_query raise an appropriate error" do + assert_raise Ash.Error.Unknown, ~r/does not currently support aggregates/, fn -> + Post + |> Ash.Query.load([ + :count_comments_with_modify_query + ]) + |> Ash.read_one!() + end + end end diff --git a/test/support/resources/comment.ex b/test/support/resources/comment.ex index fe4a818e..517c42af 100644 --- a/test/support/resources/comment.ex +++ b/test/support/resources/comment.ex @@ -33,6 +33,10 @@ defmodule AshPostgres.Test.Comment do change(manage_relationship(:rating, :ratings, on_missing: :ignore, on_match: :create)) end + + read :with_modify_query do + modify_query({AshPostgres.Test.Comment.ModifyQuery, :modify, []}) + end end attributes do @@ -104,3 +108,14 @@ defmodule AshPostgres.Test.Comment do ) end end + +defmodule AshPostgres.Test.Comment.ModifyQuery do + @moduledoc """ + Raises when modifying query so we can assert + this code path is called. + """ + + def modify(_ash_query, _ecto_query) do + raise "modifying query!" + end +end diff --git a/test/support/resources/post.ex b/test/support/resources/post.ex index 94ab170e..79eddd34 100644 --- a/test/support/resources/post.ex +++ b/test/support/resources/post.ex @@ -1164,6 +1164,10 @@ defmodule AshPostgres.Test.Post do end first(:author_profile_description, :author, :description) + + count :count_comments_with_modify_query, :comments do + read_action(:with_modify_query) + end end end From b24b845ae35b7654fc613d60d02c3a3aaf86ceef Mon Sep 17 00:00:00 2001 From: Zach Daniel Date: Tue, 22 Jul 2025 15:09:00 -0400 Subject: [PATCH 092/174] Update dependabot schedule to monthly --- .github/dependabot.yml | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/.github/dependabot.yml b/.github/dependabot.yml index a3168e45..597c8ec7 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -1,13 +1,14 @@ -version: 2 +--- updates: - - package-ecosystem: mix - directory: "/" - versioning-strategy: lockfile-only - schedule: - interval: weekly - day: thursday + - directory: / groups: - production-dependencies: - dependency-type: production dev-dependencies: dependency-type: development + production-dependencies: + dependency-type: production + package-ecosystem: mix + schedule: + day: thursday + interval: monthly + versioning-strategy: lockfile-only +version: 2 From 5bbc43fa64b69b4dfd18957f0be151fb6e37cceb Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 22 Jul 2025 15:20:32 -0400 Subject: [PATCH 093/174] chore(deps): bump the production-dependencies group with 3 updates (#598) Bumps the production-dependencies group with 3 updates: [ash](https://github.com/ash-project/ash), [ash_sql](https://github.com/ash-project/ash_sql) and [igniter](https://github.com/ash-project/igniter). Updates `ash` from 3.5.27 to 3.5.31 - [Release notes](https://github.com/ash-project/ash/releases) - [Changelog](https://github.com/ash-project/ash/blob/main/CHANGELOG.md) - [Commits](https://github.com/ash-project/ash/compare/v3.5.27...v3.5.31) Updates `ash_sql` from 0.2.86 to 0.2.87 - [Release notes](https://github.com/ash-project/ash_sql/releases) - [Changelog](https://github.com/ash-project/ash_sql/blob/main/CHANGELOG.md) - [Commits](https://github.com/ash-project/ash_sql/compare/v0.2.86...v0.2.87) Updates `igniter` from 0.6.19 to 0.6.22 - [Release notes](https://github.com/ash-project/igniter/releases) - [Changelog](https://github.com/ash-project/igniter/blob/main/CHANGELOG.md) - [Commits](https://github.com/ash-project/igniter/compare/v0.6.19...v0.6.22) --- updated-dependencies: - dependency-name: ash dependency-version: 3.5.31 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: production-dependencies - dependency-name: ash_sql dependency-version: 0.2.87 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: production-dependencies - dependency-name: igniter dependency-version: 0.6.22 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: production-dependencies ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- mix.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/mix.lock b/mix.lock index b0c5a864..7706f2a1 100644 --- a/mix.lock +++ b/mix.lock @@ -1,6 +1,6 @@ %{ - "ash": {:hex, :ash, "3.5.27", "bfa227b75da2b447d1b98e16a19b2fa957fe32bef33dfe33aa93b861a532c641", [:mix], [{:decimal, "~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:ecto, "~> 3.7", [hex: :ecto, repo: "hexpm", optional: false]}, {:ets, "~> 0.8", [hex: :ets, repo: "hexpm", optional: false]}, {:igniter, ">= 0.6.4 and < 1.0.0-0", [hex: :igniter, repo: "hexpm", optional: true]}, {:jason, ">= 1.0.0", [hex: :jason, repo: "hexpm", optional: false]}, {:picosat_elixir, "~> 0.2", [hex: :picosat_elixir, repo: "hexpm", optional: true]}, {:plug, ">= 0.0.0", [hex: :plug, repo: "hexpm", optional: true]}, {:reactor, "~> 0.11", [hex: :reactor, repo: "hexpm", optional: false]}, {:simple_sat, ">= 0.1.1 and < 1.0.0-0", [hex: :simple_sat, repo: "hexpm", optional: true]}, {:spark, ">= 2.2.65 and < 3.0.0-0", [hex: :spark, repo: "hexpm", optional: false]}, {:splode, ">= 0.2.6 and < 1.0.0-0", [hex: :splode, repo: "hexpm", optional: false]}, {:stream_data, "~> 1.0", [hex: :stream_data, repo: "hexpm", optional: false]}, {:telemetry, "~> 1.1", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "f75694b0012e4e56293e1beef1d6c20a52f2f2c9baebfa5c8f2426d25d43608e"}, - "ash_sql": {:hex, :ash_sql, "0.2.86", "9b4013010981352e295eed22dc6b09998e23a724baca07f1ff617b6bec4ba8d4", [:mix], [{:ash, ">= 3.5.25 and < 4.0.0-0", [hex: :ash, repo: "hexpm", optional: false]}, {:ecto, "~> 3.9", [hex: :ecto, repo: "hexpm", optional: false]}, {:ecto_sql, "~> 3.9", [hex: :ecto_sql, repo: "hexpm", optional: false]}], "hexpm", "97fa13e87d55194f7746c5a9fa97a9693bc26cdf7825d1c6d7cdfe5f166285a4"}, + "ash": {:hex, :ash, "3.5.31", "fea1abcbb58d00d1edf65ac5bccba5d679ca80754aaac6af7877cbf9056d4462", [:mix], [{:decimal, "~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:ecto, "~> 3.7", [hex: :ecto, repo: "hexpm", optional: false]}, {:ets, "~> 0.8", [hex: :ets, repo: "hexpm", optional: false]}, {:igniter, ">= 0.6.4 and < 1.0.0-0", [hex: :igniter, repo: "hexpm", optional: true]}, {:jason, ">= 1.0.0", [hex: :jason, repo: "hexpm", optional: false]}, {:picosat_elixir, "~> 0.2", [hex: :picosat_elixir, repo: "hexpm", optional: true]}, {:plug, ">= 0.0.0", [hex: :plug, repo: "hexpm", optional: true]}, {:reactor, "~> 0.11", [hex: :reactor, repo: "hexpm", optional: false]}, {:simple_sat, ">= 0.1.1 and < 1.0.0-0", [hex: :simple_sat, repo: "hexpm", optional: true]}, {:spark, ">= 2.2.65 and < 3.0.0-0", [hex: :spark, repo: "hexpm", optional: false]}, {:splode, ">= 0.2.6 and < 1.0.0-0", [hex: :splode, repo: "hexpm", optional: false]}, {:stream_data, "~> 1.0", [hex: :stream_data, repo: "hexpm", optional: false]}, {:telemetry, "~> 1.1", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "a7e07c8ae297dd764d92dd3c478e8bbb825fc0dd14a5cce83b85d19235510a74"}, + "ash_sql": {:hex, :ash_sql, "0.2.87", "17197c643918cdaee657946a1998860402dcf53a980f7665bb81d1fa53c224e7", [:mix], [{:ash, ">= 3.5.25 and < 4.0.0-0", [hex: :ash, repo: "hexpm", optional: false]}, {:ecto, "~> 3.9", [hex: :ecto, repo: "hexpm", optional: false]}, {:ecto_sql, "~> 3.9", [hex: :ecto_sql, repo: "hexpm", optional: false]}], "hexpm", "f82d6bf78f08bd9040af3adc28676965421598c88866074d8b1ccca65978d774"}, "benchee": {:hex, :benchee, "1.4.0", "9f1f96a30ac80bab94faad644b39a9031d5632e517416a8ab0a6b0ac4df124ce", [:mix], [{:deep_merge, "~> 1.0", [hex: :deep_merge, repo: "hexpm", optional: false]}, {:statistex, "~> 1.0", [hex: :statistex, repo: "hexpm", optional: false]}, {:table, "~> 0.1.0", [hex: :table, repo: "hexpm", optional: true]}], "hexpm", "299cd10dd8ce51c9ea3ddb74bb150f93d25e968f93e4c1fa31698a8e4fa5d715"}, "bunt": {:hex, :bunt, "1.0.0", "081c2c665f086849e6d57900292b3a161727ab40431219529f13c4ddcf3e7a44", [:mix], [], "hexpm", "dc5f86aa08a5f6fa6b8096f0735c4e76d54ae5c9fa2c143e5a1fc7c1cd9bb6b5"}, "credo": {:hex, :credo, "1.7.12", "9e3c20463de4b5f3f23721527fcaf16722ec815e70ff6c60b86412c695d426c1", [:mix], [{:bunt, "~> 0.2.1 or ~> 1.0", [hex: :bunt, repo: "hexpm", optional: false]}, {:file_system, "~> 0.2 or ~> 1.0", [hex: :file_system, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "8493d45c656c5427d9c729235b99d498bd133421f3e0a683e5c1b561471291e5"}, @@ -23,7 +23,7 @@ "git_ops": {:hex, :git_ops, "2.8.0", "29ac9ab68bf9645973cb2752047b987e75cbd3d9761489c615e3ba80018fa885", [:mix], [{:git_cli, "~> 0.2", [hex: :git_cli, repo: "hexpm", optional: false]}, {:igniter, ">= 0.5.27 and < 1.0.0-0", [hex: :igniter, repo: "hexpm", optional: true]}, {:nimble_parsec, "~> 1.0", [hex: :nimble_parsec, repo: "hexpm", optional: false]}, {:req, "~> 0.5", [hex: :req, repo: "hexpm", optional: false]}], "hexpm", "b535e4ad6b5d13e14c455e76f65825659081b5530b0827eb0232d18719530eec"}, "glob_ex": {:hex, :glob_ex, "0.1.11", "cb50d3f1ef53f6ca04d6252c7fde09fd7a1cf63387714fe96f340a1349e62c93", [:mix], [], "hexpm", "342729363056e3145e61766b416769984c329e4378f1d558b63e341020525de4"}, "hpax": {:hex, :hpax, "1.0.3", "ed67ef51ad4df91e75cc6a1494f851850c0bd98ebc0be6e81b026e765ee535aa", [:mix], [], "hexpm", "8eab6e1cfa8d5918c2ce4ba43588e894af35dbd8e91e6e55c817bca5847df34a"}, - "igniter": {:hex, :igniter, "0.6.19", "d87703b36890bc4278341d966a7ed8e10604a18610a4331ac10c75d1af48fff4", [:mix], [{:glob_ex, "~> 0.1.7", [hex: :glob_ex, repo: "hexpm", optional: false]}, {:jason, "~> 1.4", [hex: :jason, repo: "hexpm", optional: false]}, {:owl, "~> 0.11", [hex: :owl, repo: "hexpm", optional: false]}, {:phx_new, "~> 1.7", [hex: :phx_new, repo: "hexpm", optional: true]}, {:req, "~> 0.5", [hex: :req, repo: "hexpm", optional: false]}, {:rewrite, ">= 1.1.1 and < 2.0.0-0", [hex: :rewrite, repo: "hexpm", optional: false]}, {:sourceror, "~> 1.4", [hex: :sourceror, repo: "hexpm", optional: false]}, {:spitfire, ">= 0.1.3 and < 1.0.0-0", [hex: :spitfire, repo: "hexpm", optional: false]}], "hexpm", "c2070b3fdbd238fc0a0bfbc1f125b5c0f79a1fe2f5b3c7b43cd33de696783663"}, + "igniter": {:hex, :igniter, "0.6.22", "b170fc64ae0cae54a7713cf3f96e7c96183f81d75f31746de080b27518b0f96e", [:mix], [{:glob_ex, "~> 0.1.7", [hex: :glob_ex, repo: "hexpm", optional: false]}, {:jason, "~> 1.4", [hex: :jason, repo: "hexpm", optional: false]}, {:owl, "~> 0.11", [hex: :owl, repo: "hexpm", optional: false]}, {:phx_new, "~> 1.7", [hex: :phx_new, repo: "hexpm", optional: true]}, {:req, "~> 0.5", [hex: :req, repo: "hexpm", optional: false]}, {:rewrite, ">= 1.1.1 and < 2.0.0-0", [hex: :rewrite, repo: "hexpm", optional: false]}, {:sourceror, "~> 1.4", [hex: :sourceror, repo: "hexpm", optional: false]}, {:spitfire, ">= 0.1.3 and < 1.0.0-0", [hex: :spitfire, repo: "hexpm", optional: false]}], "hexpm", "d753129f693a214da32f39ba5b335f7ea6e1e87833e647b280f395b3c3742acf"}, "iterex": {:hex, :iterex, "0.1.2", "58f9b9b9a22a55cbfc7b5234a9c9c63eaac26d276b3db80936c0e1c60355a5a6", [:mix], [], "hexpm", "2e103b8bcc81757a9af121f6dc0df312c9a17220f302b1193ef720460d03029d"}, "jason": {:hex, :jason, "1.4.4", "b9226785a9aa77b6857ca22832cffa5d5011a667207eb2a0ad56adb5db443b8a", [:mix], [{:decimal, "~> 1.0 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm", "c5eb0cab91f094599f94d55bc63409236a8ec69a21a67814529e8d5f6cc90b3b"}, "libgraph": {:hex, :libgraph, "0.16.0", "3936f3eca6ef826e08880230f806bfea13193e49bf153f93edcf0239d4fd1d07", [:mix], [], "hexpm", "41ca92240e8a4138c30a7e06466acc709b0cbb795c643e9e17174a178982d6bf"}, From 7f441488f0205ba82deb21a91b083168a219c280 Mon Sep 17 00:00:00 2001 From: "Pois.Nada" <46747395+horberlan@users.noreply.github.com> Date: Fri, 25 Jul 2025 13:03:22 -0300 Subject: [PATCH 094/174] improvement: do not create snapshots for resources that have no attributes #571 (#599) --- .../migration_generator.ex | 68 ++++++++++------- test/migration_generator_test.exs | 73 +++++++++++++++++++ 2 files changed, 116 insertions(+), 25 deletions(-) diff --git a/lib/migration_generator/migration_generator.ex b/lib/migration_generator/migration_generator.ex index 84630f7d..7222c7f4 100644 --- a/lib/migration_generator/migration_generator.ex +++ b/lib/migration_generator/migration_generator.ex @@ -1983,6 +1983,17 @@ defmodule AshPostgres.MigrationGenerator do end) end + defp resource_has_meaningful_content?(snapshot) do + [ + snapshot.attributes, + snapshot.identities, + snapshot.custom_indexes, + snapshot.custom_statements, + snapshot.check_constraints + ] + |> Enum.any?(&Enum.any?/1) + end + defp do_fetch_operations(snapshot, existing_snapshot, opts, acc \\ []) defp do_fetch_operations( @@ -1996,34 +2007,41 @@ defmodule AshPostgres.MigrationGenerator do end defp do_fetch_operations(snapshot, nil, opts, acc) do - empty_snapshot = %{ - attributes: [], - identities: [], - schema: nil, - custom_indexes: [], - custom_statements: [], - check_constraints: [], - table: snapshot.table, - repo: snapshot.repo, - base_filter: nil, - empty?: true, - multitenancy: %{ - attribute: nil, - strategy: nil, - global: nil - } - } - - do_fetch_operations(snapshot, empty_snapshot, opts, [ - %Operation.CreateTable{ + if resource_has_meaningful_content?(snapshot) do + empty_snapshot = %{ + attributes: [], + identities: [], + schema: nil, + custom_indexes: [], + custom_statements: [], + check_constraints: [], table: snapshot.table, - schema: snapshot.schema, repo: snapshot.repo, - multitenancy: snapshot.multitenancy, - old_multitenancy: empty_snapshot.multitenancy + base_filter: nil, + empty?: true, + multitenancy: %{ + attribute: nil, + strategy: nil, + global: nil + } } - | acc - ]) + + do_fetch_operations(snapshot, empty_snapshot, opts, [ + %Operation.CreateTable{ + table: snapshot.table, + schema: snapshot.schema, + repo: snapshot.repo, + multitenancy: snapshot.multitenancy, + old_multitenancy: empty_snapshot.multitenancy + } + | acc + ]) + else + unless opts.quiet do + Logger.info("Skipping migration for empty resource: #{snapshot.table} (no attributes, identities, indexes, statements, or constraints)") + end + acc + end end defp do_fetch_operations(snapshot, old_snapshot, opts, acc) do diff --git a/test/migration_generator_test.exs b/test/migration_generator_test.exs index e284e847..18577e13 100644 --- a/test/migration_generator_test.exs +++ b/test/migration_generator_test.exs @@ -111,6 +111,79 @@ defmodule AshPostgres.MigrationGeneratorTest do end end + describe "empty resources" do + setup do + on_exit(fn -> + File.rm_rf!("test_snapshots_path") + File.rm_rf!("test_migration_path") + end) + end + + test "empty resource does not generate migration files" do + defresource EmptyPost, "empty_posts" do + resource do + require_primary_key?(false) + end + + actions do + defaults([:read, :create]) + end + end + + defdomain([EmptyPost]) + + AshPostgres.MigrationGenerator.generate(Domain, + snapshot_path: "test_snapshots_path", + migration_path: "test_migration_path", + quiet: false, + format: false, + auto_name: true + ) + + migration_files = + Path.wildcard("test_migration_path/**/*_migrate_resources*.exs") + |> Enum.reject(&String.contains?(&1, "extensions")) + + assert migration_files == [] + + snapshot_files = + Path.wildcard("test_snapshots_path/**/*.json") + |> Enum.reject(&String.contains?(&1, "extensions")) + + assert snapshot_files == [] + end + + test "resource with only primary key generates migration" do + defresource PostWithId, "posts_with_id" do + attributes do + uuid_primary_key(:id) + end + end + + defdomain([PostWithId]) + + AshPostgres.MigrationGenerator.generate(Domain, + snapshot_path: "test_snapshots_path", + migration_path: "test_migration_path", + quiet: false, + format: false, + auto_name: true + ) + + migration_files = + Path.wildcard("test_migration_path/**/*_migrate_resources*.exs") + |> Enum.reject(&String.contains?(&1, "extensions")) + + assert length(migration_files) == 1 + + snapshot_files = + Path.wildcard("test_snapshots_path/**/*.json") + |> Enum.reject(&String.contains?(&1, "extensions")) + + assert length(snapshot_files) == 1 + end + end + describe "creating initial snapshots" do setup do on_exit(fn -> From 60ab568d6747a98ad6db9ceae86c663397e54bac Mon Sep 17 00:00:00 2001 From: Zach Daniel Date: Fri, 25 Jul 2025 12:11:17 -0400 Subject: [PATCH 095/174] fix: ensure tenant is set on query for updates --- lib/data_layer.ex | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/lib/data_layer.ex b/lib/data_layer.ex index d527bce6..e407eaff 100644 --- a/lib/data_layer.ex +++ b/lib/data_layer.ex @@ -3139,6 +3139,14 @@ defmodule AshPostgres.DataLayer do changeset.context ) |> pkey_filter(changeset.data) + |> then(fn query -> + if changeset.tenant do + set_tenant(resource, query, changeset.tenant) + |> elem(1) + else + query + end + end) |> then(fn query -> Map.put( query, From 10b2162dfb5d20aea0375b370c22ddfb7761cfa1 Mon Sep 17 00:00:00 2001 From: Zach Daniel Date: Fri, 25 Jul 2025 12:12:42 -0400 Subject: [PATCH 096/174] chore: mix.lock --- mix.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mix.lock b/mix.lock index 7706f2a1..ba960c35 100644 --- a/mix.lock +++ b/mix.lock @@ -1,5 +1,5 @@ %{ - "ash": {:hex, :ash, "3.5.31", "fea1abcbb58d00d1edf65ac5bccba5d679ca80754aaac6af7877cbf9056d4462", [:mix], [{:decimal, "~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:ecto, "~> 3.7", [hex: :ecto, repo: "hexpm", optional: false]}, {:ets, "~> 0.8", [hex: :ets, repo: "hexpm", optional: false]}, {:igniter, ">= 0.6.4 and < 1.0.0-0", [hex: :igniter, repo: "hexpm", optional: true]}, {:jason, ">= 1.0.0", [hex: :jason, repo: "hexpm", optional: false]}, {:picosat_elixir, "~> 0.2", [hex: :picosat_elixir, repo: "hexpm", optional: true]}, {:plug, ">= 0.0.0", [hex: :plug, repo: "hexpm", optional: true]}, {:reactor, "~> 0.11", [hex: :reactor, repo: "hexpm", optional: false]}, {:simple_sat, ">= 0.1.1 and < 1.0.0-0", [hex: :simple_sat, repo: "hexpm", optional: true]}, {:spark, ">= 2.2.65 and < 3.0.0-0", [hex: :spark, repo: "hexpm", optional: false]}, {:splode, ">= 0.2.6 and < 1.0.0-0", [hex: :splode, repo: "hexpm", optional: false]}, {:stream_data, "~> 1.0", [hex: :stream_data, repo: "hexpm", optional: false]}, {:telemetry, "~> 1.1", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "a7e07c8ae297dd764d92dd3c478e8bbb825fc0dd14a5cce83b85d19235510a74"}, + "ash": {:hex, :ash, "3.5.32", "ee717c49744374be7abe8997011115a4997917535e02d36146937fb6f89c19fe", [:mix], [{:decimal, "~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:ecto, "~> 3.7", [hex: :ecto, repo: "hexpm", optional: false]}, {:ets, "~> 0.8", [hex: :ets, repo: "hexpm", optional: false]}, {:igniter, ">= 0.6.4 and < 1.0.0-0", [hex: :igniter, repo: "hexpm", optional: true]}, {:jason, ">= 1.0.0", [hex: :jason, repo: "hexpm", optional: false]}, {:picosat_elixir, "~> 0.2", [hex: :picosat_elixir, repo: "hexpm", optional: true]}, {:plug, ">= 0.0.0", [hex: :plug, repo: "hexpm", optional: true]}, {:reactor, "~> 0.11", [hex: :reactor, repo: "hexpm", optional: false]}, {:simple_sat, ">= 0.1.1 and < 1.0.0-0", [hex: :simple_sat, repo: "hexpm", optional: true]}, {:spark, ">= 2.2.65 and < 3.0.0-0", [hex: :spark, repo: "hexpm", optional: false]}, {:splode, ">= 0.2.6 and < 1.0.0-0", [hex: :splode, repo: "hexpm", optional: false]}, {:stream_data, "~> 1.0", [hex: :stream_data, repo: "hexpm", optional: false]}, {:telemetry, "~> 1.1", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "4704f536682538ee3ae0e8f99ff3cef6af53df09ef3e7e550e202da9d5ce685c"}, "ash_sql": {:hex, :ash_sql, "0.2.87", "17197c643918cdaee657946a1998860402dcf53a980f7665bb81d1fa53c224e7", [:mix], [{:ash, ">= 3.5.25 and < 4.0.0-0", [hex: :ash, repo: "hexpm", optional: false]}, {:ecto, "~> 3.9", [hex: :ecto, repo: "hexpm", optional: false]}, {:ecto_sql, "~> 3.9", [hex: :ecto_sql, repo: "hexpm", optional: false]}], "hexpm", "f82d6bf78f08bd9040af3adc28676965421598c88866074d8b1ccca65978d774"}, "benchee": {:hex, :benchee, "1.4.0", "9f1f96a30ac80bab94faad644b39a9031d5632e517416a8ab0a6b0ac4df124ce", [:mix], [{:deep_merge, "~> 1.0", [hex: :deep_merge, repo: "hexpm", optional: false]}, {:statistex, "~> 1.0", [hex: :statistex, repo: "hexpm", optional: false]}, {:table, "~> 0.1.0", [hex: :table, repo: "hexpm", optional: true]}], "hexpm", "299cd10dd8ce51c9ea3ddb74bb150f93d25e968f93e4c1fa31698a8e4fa5d715"}, "bunt": {:hex, :bunt, "1.0.0", "081c2c665f086849e6d57900292b3a161727ab40431219529f13c4ddcf3e7a44", [:mix], [], "hexpm", "dc5f86aa08a5f6fa6b8096f0735c4e76d54ae5c9fa2c143e5a1fc7c1cd9bb6b5"}, @@ -23,7 +23,7 @@ "git_ops": {:hex, :git_ops, "2.8.0", "29ac9ab68bf9645973cb2752047b987e75cbd3d9761489c615e3ba80018fa885", [:mix], [{:git_cli, "~> 0.2", [hex: :git_cli, repo: "hexpm", optional: false]}, {:igniter, ">= 0.5.27 and < 1.0.0-0", [hex: :igniter, repo: "hexpm", optional: true]}, {:nimble_parsec, "~> 1.0", [hex: :nimble_parsec, repo: "hexpm", optional: false]}, {:req, "~> 0.5", [hex: :req, repo: "hexpm", optional: false]}], "hexpm", "b535e4ad6b5d13e14c455e76f65825659081b5530b0827eb0232d18719530eec"}, "glob_ex": {:hex, :glob_ex, "0.1.11", "cb50d3f1ef53f6ca04d6252c7fde09fd7a1cf63387714fe96f340a1349e62c93", [:mix], [], "hexpm", "342729363056e3145e61766b416769984c329e4378f1d558b63e341020525de4"}, "hpax": {:hex, :hpax, "1.0.3", "ed67ef51ad4df91e75cc6a1494f851850c0bd98ebc0be6e81b026e765ee535aa", [:mix], [], "hexpm", "8eab6e1cfa8d5918c2ce4ba43588e894af35dbd8e91e6e55c817bca5847df34a"}, - "igniter": {:hex, :igniter, "0.6.22", "b170fc64ae0cae54a7713cf3f96e7c96183f81d75f31746de080b27518b0f96e", [:mix], [{:glob_ex, "~> 0.1.7", [hex: :glob_ex, repo: "hexpm", optional: false]}, {:jason, "~> 1.4", [hex: :jason, repo: "hexpm", optional: false]}, {:owl, "~> 0.11", [hex: :owl, repo: "hexpm", optional: false]}, {:phx_new, "~> 1.7", [hex: :phx_new, repo: "hexpm", optional: true]}, {:req, "~> 0.5", [hex: :req, repo: "hexpm", optional: false]}, {:rewrite, ">= 1.1.1 and < 2.0.0-0", [hex: :rewrite, repo: "hexpm", optional: false]}, {:sourceror, "~> 1.4", [hex: :sourceror, repo: "hexpm", optional: false]}, {:spitfire, ">= 0.1.3 and < 1.0.0-0", [hex: :spitfire, repo: "hexpm", optional: false]}], "hexpm", "d753129f693a214da32f39ba5b335f7ea6e1e87833e647b280f395b3c3742acf"}, + "igniter": {:hex, :igniter, "0.6.25", "e2774a4605c2bc9fc38f689232604aea0fc925c7966ae8e928fd9ea2fa9d300c", [:mix], [{:glob_ex, "~> 0.1.7", [hex: :glob_ex, repo: "hexpm", optional: false]}, {:jason, "~> 1.4", [hex: :jason, repo: "hexpm", optional: false]}, {:owl, "~> 0.11", [hex: :owl, repo: "hexpm", optional: false]}, {:phx_new, "~> 1.7", [hex: :phx_new, repo: "hexpm", optional: true]}, {:req, "~> 0.5", [hex: :req, repo: "hexpm", optional: false]}, {:rewrite, ">= 1.1.1 and < 2.0.0-0", [hex: :rewrite, repo: "hexpm", optional: false]}, {:sourceror, "~> 1.4", [hex: :sourceror, repo: "hexpm", optional: false]}, {:spitfire, ">= 0.1.3 and < 1.0.0-0", [hex: :spitfire, repo: "hexpm", optional: false]}], "hexpm", "b1916e1e45796d5c371c7671305e81277231617eb58b1c120915aba237fbce6a"}, "iterex": {:hex, :iterex, "0.1.2", "58f9b9b9a22a55cbfc7b5234a9c9c63eaac26d276b3db80936c0e1c60355a5a6", [:mix], [], "hexpm", "2e103b8bcc81757a9af121f6dc0df312c9a17220f302b1193ef720460d03029d"}, "jason": {:hex, :jason, "1.4.4", "b9226785a9aa77b6857ca22832cffa5d5011a667207eb2a0ad56adb5db443b8a", [:mix], [{:decimal, "~> 1.0 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm", "c5eb0cab91f094599f94d55bc63409236a8ec69a21a67814529e8d5f6cc90b3b"}, "libgraph": {:hex, :libgraph, "0.16.0", "3936f3eca6ef826e08880230f806bfea13193e49bf153f93edcf0239d4fd1d07", [:mix], [], "hexpm", "41ca92240e8a4138c30a7e06466acc709b0cbb795c643e9e17174a178982d6bf"}, From 7b6bf1d595e31b29ad75cfcccc9e365146f5bb45 Mon Sep 17 00:00:00 2001 From: Zach Daniel Date: Fri, 25 Jul 2025 12:13:17 -0400 Subject: [PATCH 097/174] chore: release version v2.6.12 --- CHANGELOG.md | 13 +++++++++++++ mix.exs | 2 +- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 996183c1..8b1f381a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,19 @@ See [Conventional Commits](https://www.conventionalcommits.org) for commit guide +## [v2.6.12](https://github.com/ash-project/ash_postgres/compare/v2.6.11...v2.6.12) (2025-07-25) + + + + +### Bug Fixes: + +* ensure tenant is set on query for updates by Zach Daniel + +### Improvements: + +* do not create snapshots for resources that have no attributes #571 (#599) by horberlan + ## [v2.6.11](https://github.com/ash-project/ash_postgres/compare/v2.6.10...v2.6.11) (2025-07-17) diff --git a/mix.exs b/mix.exs index 68afd199..da422e01 100644 --- a/mix.exs +++ b/mix.exs @@ -5,7 +5,7 @@ defmodule AshPostgres.MixProject do The PostgreSQL data layer for Ash Framework """ - @version "2.6.11" + @version "2.6.12" def project do [ From 2655ddcf6edf947ac77fb9b7b206271e386a5345 Mon Sep 17 00:00:00 2001 From: Emad Shaaban Date: Sun, 27 Jul 2025 08:26:58 +0300 Subject: [PATCH 098/174] fix: ensure tenant prefix is set only for resources with context multitenancy (#600) This fixes attribute multitenancy which is currently broken by this commit https://github.com/ash-project/ash_postgres/commit/60ab568d6747a98ad6db9ceae86c663397e54bac I thought updating set_tenant is the proper way to do it since it currently just adds the prefix to the query which only makes sense in context multitenancy Maybe attribute multitenancy can be handled there too? .. by adding a filter or something, but it currently seems to be handled somewhere else (not sure where) but I see the multitennacy attribute filter is added to my update queries. * chore: format --- lib/data_layer.ex | 8 ++++++-- lib/migration_generator/migration_generator.ex | 7 +++++-- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/lib/data_layer.ex b/lib/data_layer.ex index e407eaff..506e0baf 100644 --- a/lib/data_layer.ex +++ b/lib/data_layer.ex @@ -893,8 +893,12 @@ defmodule AshPostgres.DataLayer do end @impl true - def set_tenant(_resource, query, tenant) do - {:ok, Map.put(Ecto.Query.put_query_prefix(query, to_string(tenant)), :__tenant__, tenant)} + def set_tenant(resource, query, tenant) do + if Ash.Resource.Info.multitenancy_strategy(resource) == :context do + {:ok, Map.put(Ecto.Query.put_query_prefix(query, to_string(tenant)), :__tenant__, tenant)} + else + {:ok, query} + end end @impl true diff --git a/lib/migration_generator/migration_generator.ex b/lib/migration_generator/migration_generator.ex index 7222c7f4..74e0611d 100644 --- a/lib/migration_generator/migration_generator.ex +++ b/lib/migration_generator/migration_generator.ex @@ -2037,9 +2037,12 @@ defmodule AshPostgres.MigrationGenerator do | acc ]) else - unless opts.quiet do - Logger.info("Skipping migration for empty resource: #{snapshot.table} (no attributes, identities, indexes, statements, or constraints)") + if !opts.quiet do + Logger.info( + "Skipping migration for empty resource: #{snapshot.table} (no attributes, identities, indexes, statements, or constraints)" + ) end + acc end end From 424c536aa5371f6db668f885d3e5ae6a01a0f2ce Mon Sep 17 00:00:00 2001 From: Zach Daniel Date: Sun, 27 Jul 2025 01:27:09 -0400 Subject: [PATCH 099/174] chore: release version v2.6.13 --- CHANGELOG.md | 9 +++++++++ mix.exs | 2 +- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8b1f381a..b214923a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,15 @@ See [Conventional Commits](https://www.conventionalcommits.org) for commit guide +## [v2.6.13](https://github.com/ash-project/ash_postgres/compare/v2.6.12...v2.6.13) (2025-07-27) + + + + +### Bug Fixes: + +* ensure tenant prefix is set only for resources with context multitenancy (#600) by Emad Shaaban + ## [v2.6.12](https://github.com/ash-project/ash_postgres/compare/v2.6.11...v2.6.12) (2025-07-25) diff --git a/mix.exs b/mix.exs index da422e01..8f83ed84 100644 --- a/mix.exs +++ b/mix.exs @@ -5,7 +5,7 @@ defmodule AshPostgres.MixProject do The PostgreSQL data layer for Ash Framework """ - @version "2.6.12" + @version "2.6.13" def project do [ From 1e271ca54ddb7968d3f889486bfd1e8be9e5efd3 Mon Sep 17 00:00:00 2001 From: Zach Daniel Date: Mon, 28 Jul 2025 11:28:48 -0400 Subject: [PATCH 100/174] fix: deduplicate identity keys fixes #602 --- lib/migration_generator/operation.ex | 2 +- mix.lock | 2 +- test/migration_generator_test.exs | 62 ++++++++++++++++++++++++++++ 3 files changed, 64 insertions(+), 2 deletions(-) diff --git a/lib/migration_generator/operation.ex b/lib/migration_generator/operation.ex index 3b266494..13127d2a 100644 --- a/lib/migration_generator/operation.ex +++ b/lib/migration_generator/operation.ex @@ -130,7 +130,7 @@ defmodule AshPostgres.MigrationGenerator.Operation do def index_keys(keys, all_tenants?, multitenancy) do if multitenancy.strategy == :attribute and not all_tenants? do - [multitenancy.attribute | keys] + Enum.uniq([multitenancy.attribute | keys]) else keys end diff --git a/mix.lock b/mix.lock index ba960c35..bc1b7e3e 100644 --- a/mix.lock +++ b/mix.lock @@ -1,6 +1,6 @@ %{ "ash": {:hex, :ash, "3.5.32", "ee717c49744374be7abe8997011115a4997917535e02d36146937fb6f89c19fe", [:mix], [{:decimal, "~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:ecto, "~> 3.7", [hex: :ecto, repo: "hexpm", optional: false]}, {:ets, "~> 0.8", [hex: :ets, repo: "hexpm", optional: false]}, {:igniter, ">= 0.6.4 and < 1.0.0-0", [hex: :igniter, repo: "hexpm", optional: true]}, {:jason, ">= 1.0.0", [hex: :jason, repo: "hexpm", optional: false]}, {:picosat_elixir, "~> 0.2", [hex: :picosat_elixir, repo: "hexpm", optional: true]}, {:plug, ">= 0.0.0", [hex: :plug, repo: "hexpm", optional: true]}, {:reactor, "~> 0.11", [hex: :reactor, repo: "hexpm", optional: false]}, {:simple_sat, ">= 0.1.1 and < 1.0.0-0", [hex: :simple_sat, repo: "hexpm", optional: true]}, {:spark, ">= 2.2.65 and < 3.0.0-0", [hex: :spark, repo: "hexpm", optional: false]}, {:splode, ">= 0.2.6 and < 1.0.0-0", [hex: :splode, repo: "hexpm", optional: false]}, {:stream_data, "~> 1.0", [hex: :stream_data, repo: "hexpm", optional: false]}, {:telemetry, "~> 1.1", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "4704f536682538ee3ae0e8f99ff3cef6af53df09ef3e7e550e202da9d5ce685c"}, - "ash_sql": {:hex, :ash_sql, "0.2.87", "17197c643918cdaee657946a1998860402dcf53a980f7665bb81d1fa53c224e7", [:mix], [{:ash, ">= 3.5.25 and < 4.0.0-0", [hex: :ash, repo: "hexpm", optional: false]}, {:ecto, "~> 3.9", [hex: :ecto, repo: "hexpm", optional: false]}, {:ecto_sql, "~> 3.9", [hex: :ecto_sql, repo: "hexpm", optional: false]}], "hexpm", "f82d6bf78f08bd9040af3adc28676965421598c88866074d8b1ccca65978d774"}, + "ash_sql": {:hex, :ash_sql, "0.2.89", "ad4ad497263b586a7f3949ceea5d44620a36cb99a1ef0ff5f58f13a77d9b99ef", [:mix], [{:ash, ">= 3.5.25 and < 4.0.0-0", [hex: :ash, repo: "hexpm", optional: false]}, {:ecto, "~> 3.9", [hex: :ecto, repo: "hexpm", optional: false]}, {:ecto_sql, "~> 3.9", [hex: :ecto_sql, repo: "hexpm", optional: false]}], "hexpm", "bd957aee95bbdf6326fc7a9212f9a2ab87329b99ee3646c373a87bb3c9968566"}, "benchee": {:hex, :benchee, "1.4.0", "9f1f96a30ac80bab94faad644b39a9031d5632e517416a8ab0a6b0ac4df124ce", [:mix], [{:deep_merge, "~> 1.0", [hex: :deep_merge, repo: "hexpm", optional: false]}, {:statistex, "~> 1.0", [hex: :statistex, repo: "hexpm", optional: false]}, {:table, "~> 0.1.0", [hex: :table, repo: "hexpm", optional: true]}], "hexpm", "299cd10dd8ce51c9ea3ddb74bb150f93d25e968f93e4c1fa31698a8e4fa5d715"}, "bunt": {:hex, :bunt, "1.0.0", "081c2c665f086849e6d57900292b3a161727ab40431219529f13c4ddcf3e7a44", [:mix], [], "hexpm", "dc5f86aa08a5f6fa6b8096f0735c4e76d54ae5c9fa2c143e5a1fc7c1cd9bb6b5"}, "credo": {:hex, :credo, "1.7.12", "9e3c20463de4b5f3f23721527fcaf16722ec815e70ff6c60b86412c695d426c1", [:mix], [{:bunt, "~> 0.2.1 or ~> 1.0", [hex: :bunt, repo: "hexpm", optional: false]}, {:file_system, "~> 0.2 or ~> 1.0", [hex: :file_system, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "8493d45c656c5427d9c729235b99d498bd133421f3e0a683e5c1b561471291e5"}, diff --git a/test/migration_generator_test.exs b/test/migration_generator_test.exs index 18577e13..1e666f72 100644 --- a/test/migration_generator_test.exs +++ b/test/migration_generator_test.exs @@ -2793,6 +2793,68 @@ defmodule AshPostgres.MigrationGeneratorTest do end end + describe "multitenancy identity with tenant attribute" do + setup do + on_exit(fn -> + File.rm_rf!("test_snapshots_path") + File.rm_rf!("test_migration_path") + end) + end + + test "identity including tenant attribute does not duplicate columns in index" do + defresource Channel, "channels" do + postgres do + table "channels" + repo(AshPostgres.TestRepo) + end + + actions do + defaults([:create, :read, :update, :destroy]) + end + + multitenancy do + strategy(:attribute) + attribute(:project_id) + end + + identities do + identity(:unique_type_per_project, [:project_id, :type]) + end + + attributes do + uuid_primary_key(:id) + attribute(:project_id, :uuid, allow_nil?: false, public?: true) + attribute(:type, :string, allow_nil?: false, public?: true) + attribute(:name, :string, public?: true) + end + end + + defdomain([Channel]) + + AshPostgres.MigrationGenerator.generate(Domain, + snapshot_path: "test_snapshots_path", + migration_path: "test_migration_path", + quiet: true, + format: false, + auto_name: true + ) + + assert [file] = + Path.wildcard("test_migration_path/**/*_migrate_resources*.exs") + |> Enum.reject(&String.contains?(&1, "extensions")) + + file_content = File.read!(file) + + # The index should only have project_id and type, not project_id twice + assert file_content =~ + ~S{create unique_index(:channels, [:project_id, :type], name: "channels_unique_type_per_project_index")} + + # Make sure it doesn't have duplicate columns + refute file_content =~ + ~S{create unique_index(:channels, [:project_id, :project_id, :type]} + end + end + describe "decimal precision and scale" do setup do on_exit(fn -> From 1b20a9bc9939d2a39067377027e32e855785ec64 Mon Sep 17 00:00:00 2001 From: Zach Daniel Date: Tue, 29 Jul 2025 17:23:58 -0400 Subject: [PATCH 101/174] chore: release version v2.6.14 --- CHANGELOG.md | 9 +++++++++ mix.exs | 2 +- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b214923a..a51285bc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,15 @@ See [Conventional Commits](https://www.conventionalcommits.org) for commit guide +## [v2.6.14](https://github.com/ash-project/ash_postgres/compare/v2.6.13...v2.6.14) (2025-07-29) + + + + +### Bug Fixes: + +* deduplicate identity keys by Zach Daniel + ## [v2.6.13](https://github.com/ash-project/ash_postgres/compare/v2.6.12...v2.6.13) (2025-07-27) diff --git a/mix.exs b/mix.exs index 8f83ed84..143f43ce 100644 --- a/mix.exs +++ b/mix.exs @@ -5,7 +5,7 @@ defmodule AshPostgres.MixProject do The PostgreSQL data layer for Ash Framework """ - @version "2.6.13" + @version "2.6.14" def project do [ From 996327077edefb5b67db96f8765168acc90bb2d6 Mon Sep 17 00:00:00 2001 From: Zach Daniel Date: Wed, 30 Jul 2025 10:44:12 -0400 Subject: [PATCH 102/174] fix: always set disable_async, and remove log level config --- lib/mix/tasks/ash_postgres.install.ex | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/lib/mix/tasks/ash_postgres.install.ex b/lib/mix/tasks/ash_postgres.install.ex index a984f2d8..5bfa39f4 100644 --- a/lib/mix/tasks/ash_postgres.install.ex +++ b/lib/mix/tasks/ash_postgres.install.ex @@ -341,9 +341,8 @@ if Code.ensure_loaded?(Igniter) do Ecto.Adapters.SQL.Sandbox ) |> Igniter.Project.Config.configure_new("test.exs", otp_app, [repo, :pool_size], 10) - |> Igniter.Project.Config.configure_new("test.exs", :ash, [:disable_async?], true) - |> Igniter.Project.Config.configure_new("test.exs", :logger, [:level], :warning) end + |> Igniter.Project.Config.configure_new("test.exs", :ash, [:disable_async?], true) end defp setup_data_case(igniter) do From baf4e3247e28346dc61d682756fd55948e4e4b61 Mon Sep 17 00:00:00 2001 From: Anatolij Werle Date: Sun, 3 Aug 2025 19:17:22 +0200 Subject: [PATCH 103/174] fix: Use new attribute source in down migration (#604) closes: #582 When an attribute is renamed, alongside other changes to it (like changing default or not null constraint), the generated up migration first renames the column, then modifies it. For the generated down migration, the order of operations is reversed, so we need to use the new column name when modifying the column, before renaming it back. --- lib/migration_generator/operation.ex | 2 +- test/migration_generator_test.exs | 37 ++++++++++++++++++++++++++-- 2 files changed, 36 insertions(+), 3 deletions(-) diff --git a/lib/migration_generator/operation.ex b/lib/migration_generator/operation.ex index 13127d2a..88525c11 100644 --- a/lib/migration_generator/operation.ex +++ b/lib/migration_generator/operation.ex @@ -752,7 +752,7 @@ defmodule AshPostgres.MigrationGenerator.Operation do up(%{ op | old_attribute: op.new_attribute, - new_attribute: op.old_attribute, + new_attribute: Map.put(op.old_attribute, :source, op.new_attribute.source), old_multitenancy: op.multitenancy, multitenancy: op.old_multitenancy }) diff --git a/test/migration_generator_test.exs b/test/migration_generator_test.exs index 1e666f72..a12a09a0 100644 --- a/test/migration_generator_test.exs +++ b/test/migration_generator_test.exs @@ -825,8 +825,41 @@ defmodule AshPostgres.MigrationGeneratorTest do Enum.sort(Path.wildcard("test_migration_path/**/*_migrate_resources*.exs")) |> Enum.reject(&String.contains?(&1, "extensions")) - assert File.read!(file2) =~ ~S[rename table(:posts, prefix: "example"), :title, to: :name] - assert File.read!(file2) =~ ~S[modify :title, :text, null: true, default: nil] + contents = File.read!(file2) + + [up_side, down_side] = String.split(contents, "def down", parts: 2) + + up_side_parts = + String.split(up_side, "\n", trim: true) + |> Enum.map(&String.trim/1) + + up_rename_index = + Enum.find_index(up_side_parts, fn x -> + x == ~S[rename table(:posts, prefix: "example"), :title, to: :name] + end) + + up_modify_index = + Enum.find_index(up_side_parts, fn x -> + x == ~S[modify :name, :text, null: false, default: "fred"] + end) + + assert up_rename_index < up_modify_index + + down_side_parts = + String.split(down_side, "\n", trim: true) + |> Enum.map(&String.trim/1) + + down_modify_index = + Enum.find_index(down_side_parts, fn x -> + x == ~S[modify :name, :text, null: true, default: nil] + end) + + down_rename_index = + Enum.find_index(down_side_parts, fn x -> + x == ~S[rename table(:posts, prefix: "example"), :name, to: :title] + end) + + assert down_modify_index < down_rename_index end end From e19918967b7ea33f31d5a07a8a78f87c0ca5a772 Mon Sep 17 00:00:00 2001 From: Zach Daniel Date: Wed, 6 Aug 2025 22:23:30 -0400 Subject: [PATCH 104/174] chore: release version v2.6.15 --- CHANGELOG.md | 11 +++++++++++ mix.exs | 2 +- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a51285bc..a9610b52 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,17 @@ See [Conventional Commits](https://www.conventionalcommits.org) for commit guide +## [v2.6.15](https://github.com/ash-project/ash_postgres/compare/v2.6.14...v2.6.15) (2025-08-07) + + + + +### Bug Fixes: + +* Use new attribute source in down migration (#604) by Anatolij Werle + +* always set disable_async, and remove log level config by Zach Daniel + ## [v2.6.14](https://github.com/ash-project/ash_postgres/compare/v2.6.13...v2.6.14) (2025-07-29) diff --git a/mix.exs b/mix.exs index 143f43ce..549fbcd9 100644 --- a/mix.exs +++ b/mix.exs @@ -5,7 +5,7 @@ defmodule AshPostgres.MixProject do The PostgreSQL data layer for Ash Framework """ - @version "2.6.14" + @version "2.6.15" def project do [ From 7cd3019b543b528aa75a07d718cdd36f668f0bdd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kenneth=20Kostre=C5=A1evi=C4=87?= Date: Mon, 11 Aug 2025 15:53:36 +0200 Subject: [PATCH 105/174] test: Add distinct sort tests (#605) * Add support for sorting with filtered relationship tests * Add filter relationship tests --- .../test_repo/post_tags/20250810102512.json | 100 ++++++++++++++++++ .../test_repo/tags/20250810102512.json | 43 ++++++++ .../20250810102512_migrate_resources57.exs | 58 ++++++++++ test/calculation_test.exs | 33 +++++- test/sort_test.exs | 24 ++++- test/support/domain.ex | 2 + test/support/resources/post.ex | 6 ++ test/support/resources/post_tag.ex | 37 +++++++ test/support/resources/tag.ex | 47 ++++++++ 9 files changed, 348 insertions(+), 2 deletions(-) create mode 100644 priv/resource_snapshots/test_repo/post_tags/20250810102512.json create mode 100644 priv/resource_snapshots/test_repo/tags/20250810102512.json create mode 100644 priv/test_repo/migrations/20250810102512_migrate_resources57.exs create mode 100644 test/support/resources/post_tag.ex create mode 100644 test/support/resources/tag.ex diff --git a/priv/resource_snapshots/test_repo/post_tags/20250810102512.json b/priv/resource_snapshots/test_repo/post_tags/20250810102512.json new file mode 100644 index 00000000..31adb69f --- /dev/null +++ b/priv/resource_snapshots/test_repo/post_tags/20250810102512.json @@ -0,0 +1,100 @@ +{ + "attributes": [ + { + "allow_nil?": false, + "default": "nil", + "generated?": false, + "precision": null, + "primary_key?": true, + "references": { + "deferrable": false, + "destination_attribute": "id", + "destination_attribute_default": null, + "destination_attribute_generated": null, + "index?": false, + "match_type": null, + "match_with": null, + "multitenancy": { + "attribute": null, + "global": null, + "strategy": null + }, + "name": "post_tags_post_id_fkey", + "on_delete": null, + "on_update": null, + "primary_key?": true, + "schema": "public", + "table": "posts" + }, + "scale": null, + "size": null, + "source": "post_id", + "type": "uuid" + }, + { + "allow_nil?": false, + "default": "nil", + "generated?": false, + "precision": null, + "primary_key?": true, + "references": { + "deferrable": false, + "destination_attribute": "id", + "destination_attribute_default": null, + "destination_attribute_generated": null, + "index?": false, + "match_type": null, + "match_with": null, + "multitenancy": { + "attribute": null, + "global": null, + "strategy": null + }, + "name": "post_tags_tag_id_fkey", + "on_delete": null, + "on_update": null, + "primary_key?": true, + "schema": "public", + "table": "tags" + }, + "scale": null, + "size": null, + "source": "tag_id", + "type": "uuid" + } + ], + "base_filter": null, + "check_constraints": [], + "custom_indexes": [], + "custom_statements": [], + "has_create_action": true, + "hash": "BC5024D4E17EDD4ABDD0EF3D81EE5932FB63DF036E1BA81989D21A12496FE4A9", + "identities": [ + { + "all_tenants?": false, + "base_filter": null, + "index_name": "post_tags_unique_post_tag_index", + "keys": [ + { + "type": "atom", + "value": "post_id" + }, + { + "type": "atom", + "value": "tag_id" + } + ], + "name": "unique_post_tag", + "nils_distinct?": true, + "where": null + } + ], + "multitenancy": { + "attribute": null, + "global": null, + "strategy": null + }, + "repo": "Elixir.AshPostgres.TestRepo", + "schema": null, + "table": "post_tags" +} \ No newline at end of file diff --git a/priv/resource_snapshots/test_repo/tags/20250810102512.json b/priv/resource_snapshots/test_repo/tags/20250810102512.json new file mode 100644 index 00000000..4ca1e30a --- /dev/null +++ b/priv/resource_snapshots/test_repo/tags/20250810102512.json @@ -0,0 +1,43 @@ +{ + "attributes": [ + { + "allow_nil?": false, + "default": "fragment(\"gen_random_uuid()\")", + "generated?": false, + "precision": null, + "primary_key?": true, + "references": null, + "scale": null, + "size": null, + "source": "id", + "type": "uuid" + }, + { + "allow_nil?": false, + "default": "0", + "generated?": false, + "precision": null, + "primary_key?": false, + "references": null, + "scale": null, + "size": null, + "source": "importance", + "type": "bigint" + } + ], + "base_filter": null, + "check_constraints": [], + "custom_indexes": [], + "custom_statements": [], + "has_create_action": true, + "hash": "9770C678D127B7ECA9FEAF174305101CC111417744E5D5712CD7F0A865D9877A", + "identities": [], + "multitenancy": { + "attribute": null, + "global": null, + "strategy": null + }, + "repo": "Elixir.AshPostgres.TestRepo", + "schema": null, + "table": "tags" +} \ No newline at end of file diff --git a/priv/test_repo/migrations/20250810102512_migrate_resources57.exs b/priv/test_repo/migrations/20250810102512_migrate_resources57.exs new file mode 100644 index 00000000..1eb6911a --- /dev/null +++ b/priv/test_repo/migrations/20250810102512_migrate_resources57.exs @@ -0,0 +1,58 @@ +defmodule AshPostgres.TestRepo.Migrations.MigrateResources57 do + @moduledoc """ + Updates resources based on their most recent snapshots. + + This file was autogenerated with `mix ash_postgres.generate_migrations` + """ + + use Ecto.Migration + + def up do + create table(:tags, primary_key: false) do + add(:id, :uuid, null: false, default: fragment("gen_random_uuid()"), primary_key: true) + add(:importance, :bigint, null: false, default: 0) + end + + create table(:post_tags, primary_key: false) do + add( + :post_id, + references(:posts, + column: :id, + name: "post_tags_post_id_fkey", + type: :uuid, + prefix: "public" + ), + primary_key: true, + null: false + ) + + add( + :tag_id, + references(:tags, + column: :id, + name: "post_tags_tag_id_fkey", + type: :uuid, + prefix: "public" + ), + primary_key: true, + null: false + ) + end + + create(unique_index(:post_tags, [:post_id, :tag_id], name: "post_tags_unique_post_tag_index")) + end + + def down do + drop_if_exists( + unique_index(:post_tags, [:post_id, :tag_id], name: "post_tags_unique_post_tag_index") + ) + + drop(constraint(:post_tags, "post_tags_post_id_fkey")) + + drop(constraint(:post_tags, "post_tags_tag_id_fkey")) + + drop(table(:post_tags)) + + drop(table(:tags)) + end +end diff --git a/test/calculation_test.exs b/test/calculation_test.exs index 287ccf9a..68c975d9 100644 --- a/test/calculation_test.exs +++ b/test/calculation_test.exs @@ -1,7 +1,19 @@ defmodule AshPostgres.CalculationTest do alias AshPostgres.Test.RecordTempEntity use AshPostgres.RepoCase, async: false - alias AshPostgres.Test.{Account, Author, Comedian, Comment, Post, Record, TempEntity, User} + + alias AshPostgres.Test.{ + Account, + Author, + Comedian, + Comment, + Post, + PostTag, + Record, + Tag, + TempEntity, + User + } require Ash.Query import Ash.Expr @@ -1045,4 +1057,23 @@ defmodule AshPostgres.CalculationTest do |> Ash.Query.sort("posts_with_matching_title.relevance_score") |> Ash.read!() end + + test "sorting with filtered relationship by calculated field" do + tag = Ash.Changeset.for_create(Tag, :create) |> Ash.create!() + scores = [0, 3, 111, 22, 9, 4, 2, 33, 10] + + scores + |> Enum.each(fn score -> + post = + Ash.Changeset.for_create(Post, :create, %{score: score}) + |> Ash.create!() + + Ash.Changeset.for_create(PostTag, :create, post_id: post.id, tag_id: tag.id) + |> Ash.create!() + end) + + post_with_highest_score = Ash.load!(tag, :post_with_highest_score).post_with_highest_score + highest_score = hd(Enum.sort(scores, :desc)) + assert post_with_highest_score.score == highest_score + end end diff --git a/test/sort_test.exs b/test/sort_test.exs index 5ca9c922..cd5deddb 100644 --- a/test/sort_test.exs +++ b/test/sort_test.exs @@ -1,7 +1,7 @@ defmodule AshPostgres.SortTest do @moduledoc false use AshPostgres.RepoCase, async: false - alias AshPostgres.Test.{Comment, Post, PostLink, PostView} + alias AshPostgres.Test.{Comment, Post, PostLink, PostTag, PostView, Tag} require Ash.Query require Ash.Sort @@ -267,4 +267,26 @@ defmodule AshPostgres.SortTest do |> Ash.Query.sort({Ash.Sort.expr_sort(views.time, :datetime), :desc}, title: :asc) ) end + + test "sorting with filtered relationship" do + tag = Ash.Changeset.for_create(Tag, :create) |> Ash.create!() + dates = [~D[2025-01-03], ~D[2025-01-05], ~D[2025-01-01], ~D[2025-01-10], ~D[2025-01-02]] + + dates + |> Enum.each(fn date -> + {:ok, datetime} = DateTime.new(date, ~T[00:00:00]) + + post = + Ash.Changeset.for_create(Post, :create, %{created_at: datetime}) + |> Ash.create!() + + Ash.Changeset.for_create(PostTag, :create, post_id: post.id, tag_id: tag.id) + |> Ash.create!() + end) + + latest_post = Ash.load!(tag, :latest_post).latest_post + expected_date = hd(Enum.sort(dates, :desc)) + + assert DateTime.to_date(latest_post.created_at) == expected_date + end end diff --git a/test/support/domain.ex b/test/support/domain.ex index c8c596d5..58074271 100644 --- a/test/support/domain.ex +++ b/test/support/domain.ex @@ -42,6 +42,8 @@ defmodule AshPostgres.Test.Domain do resource(AshPostgres.Test.CSV) resource(AshPostgres.Test.StandupClub) resource(AshPostgres.Test.Punchline) + resource(AshPostgres.Test.Tag) + resource(AshPostgres.Test.PostTag) end authorization do diff --git a/test/support/resources/post.ex b/test/support/resources/post.ex index 79eddd34..1f90535c 100644 --- a/test/support/resources/post.ex +++ b/test/support/resources/post.ex @@ -777,6 +777,12 @@ defmodule AshPostgres.Test.Post do sort: [Ash.Sort.expr_sort(parent(post_followers.order), :integer)] ) + many_to_many :tags, AshPostgres.Test.Tag do + public?(true) + through(AshPostgres.Test.PostTag) + sort(importance: :desc) + end + has_many(:views, AshPostgres.Test.PostView) do public?(true) end diff --git a/test/support/resources/post_tag.ex b/test/support/resources/post_tag.ex new file mode 100644 index 00000000..c1cb13e8 --- /dev/null +++ b/test/support/resources/post_tag.ex @@ -0,0 +1,37 @@ +defmodule AshPostgres.Test.PostTag do + @moduledoc false + use Ash.Resource, + domain: AshPostgres.Test.Domain, + data_layer: AshPostgres.DataLayer + + require Ash.Sort + + postgres do + table "post_tags" + repo AshPostgres.TestRepo + end + + actions do + default_accept(:*) + + defaults([:create, :read, :update, :destroy]) + end + + identities do + identity(:unique_post_tag, [:post_id, :tag_id]) + end + + relationships do + belongs_to :post, AshPostgres.Test.Post do + primary_key?(true) + public?(true) + allow_nil?(false) + end + + belongs_to :tag, AshPostgres.Test.Tag do + primary_key?(true) + public?(true) + allow_nil?(false) + end + end +end diff --git a/test/support/resources/tag.ex b/test/support/resources/tag.ex new file mode 100644 index 00000000..20d8d5a8 --- /dev/null +++ b/test/support/resources/tag.ex @@ -0,0 +1,47 @@ +defmodule AshPostgres.Test.Tag do + @moduledoc false + use Ash.Resource, + domain: AshPostgres.Test.Domain, + data_layer: AshPostgres.DataLayer + + require Ash.Sort + + postgres do + table "tags" + repo AshPostgres.TestRepo + end + + actions do + defaults([:read]) + + create :create do + accept(:*) + end + end + + attributes do + uuid_primary_key(:id) + attribute(:importance, :integer, allow_nil?: false, default: 0, public?: true) + end + + relationships do + many_to_many :posts, AshPostgres.Test.Post do + through(AshPostgres.Test.PostTag) + public?(true) + end + + has_one :latest_post, AshPostgres.Test.Post do + public?(true) + no_attributes?(true) + filter(expr(tags.id == parent(id))) + sort(created_at: :desc) + end + + has_one :post_with_highest_score, AshPostgres.Test.Post do + public?(true) + no_attributes?(true) + filter(expr(tags.id == parent(id))) + sort(score_after_winning: :desc) + end + end +end From d1236799194d4d2d4f1f5f655cc173f2c5a21d27 Mon Sep 17 00:00:00 2001 From: Zach Daniel Date: Mon, 11 Aug 2025 17:39:35 -0400 Subject: [PATCH 106/174] improvement: Unrelated aggregates (#606) --- lib/data_layer.ex | 1 + mix.exs | 4 +- mix.lock | 8 +- .../unrelated_profiles/20250731124648.json | 91 ++++ .../unrelated_reports/20250731124648.json | 79 +++ .../20250731124648.json | 91 ++++ .../unrelated_users/20250731124648.json | 79 +++ .../20250731124648_migrate_resources57.exs | 59 ++ test/support/domain.ex | 4 + test/support/unrelated_aggregates/profile.ex | 36 ++ test/support/unrelated_aggregates/report.ex | 33 ++ .../unrelated_aggregates/secure_profile.ex | 38 ++ test/support/unrelated_aggregates/user.ex | 154 ++++++ test/unrelated_aggregates_test.exs | 507 ++++++++++++++++++ 14 files changed, 1178 insertions(+), 6 deletions(-) create mode 100644 priv/resource_snapshots/test_repo/unrelated_profiles/20250731124648.json create mode 100644 priv/resource_snapshots/test_repo/unrelated_reports/20250731124648.json create mode 100644 priv/resource_snapshots/test_repo/unrelated_secure_profiles/20250731124648.json create mode 100644 priv/resource_snapshots/test_repo/unrelated_users/20250731124648.json create mode 100644 priv/test_repo/migrations/20250731124648_migrate_resources57.exs create mode 100644 test/support/unrelated_aggregates/profile.ex create mode 100644 test/support/unrelated_aggregates/report.ex create mode 100644 test/support/unrelated_aggregates/secure_profile.ex create mode 100644 test/support/unrelated_aggregates/user.ex create mode 100644 test/unrelated_aggregates_test.exs diff --git a/lib/data_layer.ex b/lib/data_layer.ex index 506e0baf..3fa1aa30 100644 --- a/lib/data_layer.ex +++ b/lib/data_layer.ex @@ -721,6 +721,7 @@ defmodule AshPostgres.DataLayer do when type in [:count, :sum, :first, :list, :avg, :max, :min, :exists, :custom], do: true + def can?(_, {:aggregate, :unrelated}), do: true def can?(_, :aggregate_filter), do: true def can?(_, :aggregate_sort), do: true def can?(_, :calculate), do: true diff --git a/mix.exs b/mix.exs index 549fbcd9..0ff8df8e 100644 --- a/mix.exs +++ b/mix.exs @@ -166,8 +166,8 @@ defmodule AshPostgres.MixProject do # Run "mix help deps" to learn about dependencies. defp deps do [ - {:ash, ash_version("~> 3.5 and >= 3.5.13")}, - {:ash_sql, ash_sql_version("~> 0.2 and >= 0.2.72")}, + {:ash, ash_version(github: "ash-project/ash", branch: "main")}, + {:ash_sql, ash_sql_version(github: "ash-project/ash_sql", branch: "main")}, {:igniter, "~> 0.6 and >= 0.6.14", optional: true}, {:ecto_sql, "~> 3.13"}, {:ecto, "~> 3.13"}, diff --git a/mix.lock b/mix.lock index bc1b7e3e..3c6f7826 100644 --- a/mix.lock +++ b/mix.lock @@ -1,6 +1,6 @@ %{ - "ash": {:hex, :ash, "3.5.32", "ee717c49744374be7abe8997011115a4997917535e02d36146937fb6f89c19fe", [:mix], [{:decimal, "~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:ecto, "~> 3.7", [hex: :ecto, repo: "hexpm", optional: false]}, {:ets, "~> 0.8", [hex: :ets, repo: "hexpm", optional: false]}, {:igniter, ">= 0.6.4 and < 1.0.0-0", [hex: :igniter, repo: "hexpm", optional: true]}, {:jason, ">= 1.0.0", [hex: :jason, repo: "hexpm", optional: false]}, {:picosat_elixir, "~> 0.2", [hex: :picosat_elixir, repo: "hexpm", optional: true]}, {:plug, ">= 0.0.0", [hex: :plug, repo: "hexpm", optional: true]}, {:reactor, "~> 0.11", [hex: :reactor, repo: "hexpm", optional: false]}, {:simple_sat, ">= 0.1.1 and < 1.0.0-0", [hex: :simple_sat, repo: "hexpm", optional: true]}, {:spark, ">= 2.2.65 and < 3.0.0-0", [hex: :spark, repo: "hexpm", optional: false]}, {:splode, ">= 0.2.6 and < 1.0.0-0", [hex: :splode, repo: "hexpm", optional: false]}, {:stream_data, "~> 1.0", [hex: :stream_data, repo: "hexpm", optional: false]}, {:telemetry, "~> 1.1", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "4704f536682538ee3ae0e8f99ff3cef6af53df09ef3e7e550e202da9d5ce685c"}, - "ash_sql": {:hex, :ash_sql, "0.2.89", "ad4ad497263b586a7f3949ceea5d44620a36cb99a1ef0ff5f58f13a77d9b99ef", [:mix], [{:ash, ">= 3.5.25 and < 4.0.0-0", [hex: :ash, repo: "hexpm", optional: false]}, {:ecto, "~> 3.9", [hex: :ecto, repo: "hexpm", optional: false]}, {:ecto_sql, "~> 3.9", [hex: :ecto_sql, repo: "hexpm", optional: false]}], "hexpm", "bd957aee95bbdf6326fc7a9212f9a2ab87329b99ee3646c373a87bb3c9968566"}, + "ash": {:git, "https://github.com/ash-project/ash.git", "471274d2f75a4bda6405c5630b72f9323d572260", [branch: "main"]}, + "ash_sql": {:git, "https://github.com/ash-project/ash_sql.git", "40c9bcb905603dbcee2bc064f37c6f5ce30da7c7", [branch: "main"]}, "benchee": {:hex, :benchee, "1.4.0", "9f1f96a30ac80bab94faad644b39a9031d5632e517416a8ab0a6b0ac4df124ce", [:mix], [{:deep_merge, "~> 1.0", [hex: :deep_merge, repo: "hexpm", optional: false]}, {:statistex, "~> 1.0", [hex: :statistex, repo: "hexpm", optional: false]}, {:table, "~> 0.1.0", [hex: :table, repo: "hexpm", optional: true]}], "hexpm", "299cd10dd8ce51c9ea3ddb74bb150f93d25e968f93e4c1fa31698a8e4fa5d715"}, "bunt": {:hex, :bunt, "1.0.0", "081c2c665f086849e6d57900292b3a161727ab40431219529f13c4ddcf3e7a44", [:mix], [], "hexpm", "dc5f86aa08a5f6fa6b8096f0735c4e76d54ae5c9fa2c143e5a1fc7c1cd9bb6b5"}, "credo": {:hex, :credo, "1.7.12", "9e3c20463de4b5f3f23721527fcaf16722ec815e70ff6c60b86412c695d426c1", [:mix], [{:bunt, "~> 0.2.1 or ~> 1.0", [hex: :bunt, repo: "hexpm", optional: false]}, {:file_system, "~> 0.2 or ~> 1.0", [hex: :file_system, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "8493d45c656c5427d9c729235b99d498bd133421f3e0a683e5c1b561471291e5"}, @@ -23,7 +23,7 @@ "git_ops": {:hex, :git_ops, "2.8.0", "29ac9ab68bf9645973cb2752047b987e75cbd3d9761489c615e3ba80018fa885", [:mix], [{:git_cli, "~> 0.2", [hex: :git_cli, repo: "hexpm", optional: false]}, {:igniter, ">= 0.5.27 and < 1.0.0-0", [hex: :igniter, repo: "hexpm", optional: true]}, {:nimble_parsec, "~> 1.0", [hex: :nimble_parsec, repo: "hexpm", optional: false]}, {:req, "~> 0.5", [hex: :req, repo: "hexpm", optional: false]}], "hexpm", "b535e4ad6b5d13e14c455e76f65825659081b5530b0827eb0232d18719530eec"}, "glob_ex": {:hex, :glob_ex, "0.1.11", "cb50d3f1ef53f6ca04d6252c7fde09fd7a1cf63387714fe96f340a1349e62c93", [:mix], [], "hexpm", "342729363056e3145e61766b416769984c329e4378f1d558b63e341020525de4"}, "hpax": {:hex, :hpax, "1.0.3", "ed67ef51ad4df91e75cc6a1494f851850c0bd98ebc0be6e81b026e765ee535aa", [:mix], [], "hexpm", "8eab6e1cfa8d5918c2ce4ba43588e894af35dbd8e91e6e55c817bca5847df34a"}, - "igniter": {:hex, :igniter, "0.6.25", "e2774a4605c2bc9fc38f689232604aea0fc925c7966ae8e928fd9ea2fa9d300c", [:mix], [{:glob_ex, "~> 0.1.7", [hex: :glob_ex, repo: "hexpm", optional: false]}, {:jason, "~> 1.4", [hex: :jason, repo: "hexpm", optional: false]}, {:owl, "~> 0.11", [hex: :owl, repo: "hexpm", optional: false]}, {:phx_new, "~> 1.7", [hex: :phx_new, repo: "hexpm", optional: true]}, {:req, "~> 0.5", [hex: :req, repo: "hexpm", optional: false]}, {:rewrite, ">= 1.1.1 and < 2.0.0-0", [hex: :rewrite, repo: "hexpm", optional: false]}, {:sourceror, "~> 1.4", [hex: :sourceror, repo: "hexpm", optional: false]}, {:spitfire, ">= 0.1.3 and < 1.0.0-0", [hex: :spitfire, repo: "hexpm", optional: false]}], "hexpm", "b1916e1e45796d5c371c7671305e81277231617eb58b1c120915aba237fbce6a"}, + "igniter": {:hex, :igniter, "0.6.26", "a6b4f6680a7e158bd13cd3b2be047102e42c046b3b240578d68d89d1a39a83fa", [:mix], [{:glob_ex, "~> 0.1.7", [hex: :glob_ex, repo: "hexpm", optional: false]}, {:jason, "~> 1.4", [hex: :jason, repo: "hexpm", optional: false]}, {:owl, "~> 0.11", [hex: :owl, repo: "hexpm", optional: false]}, {:phx_new, "~> 1.7", [hex: :phx_new, repo: "hexpm", optional: true]}, {:req, "~> 0.5", [hex: :req, repo: "hexpm", optional: false]}, {:rewrite, ">= 1.1.1 and < 2.0.0-0", [hex: :rewrite, repo: "hexpm", optional: false]}, {:sourceror, "~> 1.4", [hex: :sourceror, repo: "hexpm", optional: false]}, {:spitfire, ">= 0.1.3 and < 1.0.0-0", [hex: :spitfire, repo: "hexpm", optional: false]}], "hexpm", "a4f8c404fc4cbc05a1b536c8125ae64909e3a02d5f972ffe6a3a2ebd75530f3c"}, "iterex": {:hex, :iterex, "0.1.2", "58f9b9b9a22a55cbfc7b5234a9c9c63eaac26d276b3db80936c0e1c60355a5a6", [:mix], [], "hexpm", "2e103b8bcc81757a9af121f6dc0df312c9a17220f302b1193ef720460d03029d"}, "jason": {:hex, :jason, "1.4.4", "b9226785a9aa77b6857ca22832cffa5d5011a667207eb2a0ad56adb5db443b8a", [:mix], [{:decimal, "~> 1.0 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm", "c5eb0cab91f094599f94d55bc63409236a8ec69a21a67814529e8d5f6cc90b3b"}, "libgraph": {:hex, :libgraph, "0.16.0", "3936f3eca6ef826e08880230f806bfea13193e49bf153f93edcf0239d4fd1d07", [:mix], [], "hexpm", "41ca92240e8a4138c30a7e06466acc709b0cbb795c643e9e17174a178982d6bf"}, @@ -37,7 +37,7 @@ "nimble_parsec": {:hex, :nimble_parsec, "1.4.2", "8efba0122db06df95bfaa78f791344a89352ba04baedd3849593bfce4d0dc1c6", [:mix], [], "hexpm", "4b21398942dda052b403bbe1da991ccd03a053668d147d53fb8c4e0efe09c973"}, "nimble_pool": {:hex, :nimble_pool, "1.1.0", "bf9c29fbdcba3564a8b800d1eeb5a3c58f36e1e11d7b7fb2e084a643f645f06b", [:mix], [], "hexpm", "af2e4e6b34197db81f7aad230c1118eac993acc0dae6bc83bac0126d4ae0813a"}, "owl": {:hex, :owl, "0.12.2", "65906b525e5c3ef51bab6cba7687152be017aebe1da077bb719a5ee9f7e60762", [:mix], [{:ucwidth, "~> 0.2", [hex: :ucwidth, repo: "hexpm", optional: true]}], "hexpm", "6398efa9e1fea70a04d24231e10dcd66c1ac1aa2da418d20ef5357ec61de2880"}, - "postgrex": {:hex, :postgrex, "0.20.0", "363ed03ab4757f6bc47942eff7720640795eb557e1935951c1626f0d303a3aed", [:mix], [{:db_connection, "~> 2.1", [hex: :db_connection, repo: "hexpm", optional: false]}, {:decimal, "~> 1.5 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:table, "~> 0.1.0", [hex: :table, repo: "hexpm", optional: true]}], "hexpm", "d36ef8b36f323d29505314f704e21a1a038e2dc387c6409ee0cd24144e187c0f"}, + "postgrex": {:hex, :postgrex, "0.21.1", "2c5cc830ec11e7a0067dd4d623c049b3ef807e9507a424985b8dcf921224cd88", [:mix], [{:db_connection, "~> 2.1", [hex: :db_connection, repo: "hexpm", optional: false]}, {:decimal, "~> 1.5 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:table, "~> 0.1.0", [hex: :table, repo: "hexpm", optional: true]}], "hexpm", "27d8d21c103c3cc68851b533ff99eef353e6a0ff98dc444ea751de43eb48bdac"}, "reactor": {:hex, :reactor, "0.15.6", "d717f9add549b25a089a94c90197718d2d838e35d81dd776b1d81587d4cf2aaa", [:mix], [{:igniter, "~> 0.4", [hex: :igniter, repo: "hexpm", optional: true]}, {:iterex, "~> 0.1", [hex: :iterex, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}, {:libgraph, "~> 0.16", [hex: :libgraph, repo: "hexpm", optional: false]}, {:spark, "~> 2.0", [hex: :spark, repo: "hexpm", optional: false]}, {:splode, "~> 0.2", [hex: :splode, repo: "hexpm", optional: false]}, {:telemetry, "~> 1.2", [hex: :telemetry, repo: "hexpm", optional: false]}, {:yaml_elixir, "~> 2.11", [hex: :yaml_elixir, repo: "hexpm", optional: false]}, {:ymlr, "~> 5.0", [hex: :ymlr, repo: "hexpm", optional: false]}], "hexpm", "74db98165e3644d86e0f723672d91ceca4339eaa935bcad7e78bf146a46d77b9"}, "req": {:hex, :req, "0.5.15", "662020efb6ea60b9f0e0fac9be88cd7558b53fe51155a2d9899de594f9906ba9", [:mix], [{:brotli, "~> 0.3.1", [hex: :brotli, repo: "hexpm", optional: true]}, {:ezstd, "~> 1.0", [hex: :ezstd, repo: "hexpm", optional: true]}, {:finch, "~> 0.17", [hex: :finch, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}, {:mime, "~> 2.0.6 or ~> 2.1", [hex: :mime, repo: "hexpm", optional: false]}, {:nimble_csv, "~> 1.0", [hex: :nimble_csv, repo: "hexpm", optional: true]}, {:plug, "~> 1.0", [hex: :plug, repo: "hexpm", optional: true]}], "hexpm", "a6513a35fad65467893ced9785457e91693352c70b58bbc045b47e5eb2ef0c53"}, "rewrite": {:hex, :rewrite, "1.1.2", "f5a5d10f5fed1491a6ff48e078d4585882695962ccc9e6c779bae025d1f92eda", [:mix], [{:glob_ex, "~> 0.1", [hex: :glob_ex, repo: "hexpm", optional: false]}, {:sourceror, "~> 1.0", [hex: :sourceror, repo: "hexpm", optional: false]}, {:text_diff, "~> 0.1", [hex: :text_diff, repo: "hexpm", optional: false]}], "hexpm", "7f8b94b1e3528d0a47b3e8b7bfeca559d2948a65fa7418a9ad7d7712703d39d4"}, diff --git a/priv/resource_snapshots/test_repo/unrelated_profiles/20250731124648.json b/priv/resource_snapshots/test_repo/unrelated_profiles/20250731124648.json new file mode 100644 index 00000000..a3c884ee --- /dev/null +++ b/priv/resource_snapshots/test_repo/unrelated_profiles/20250731124648.json @@ -0,0 +1,91 @@ +{ + "attributes": [ + { + "allow_nil?": false, + "default": "fragment(\"gen_random_uuid()\")", + "generated?": false, + "precision": null, + "primary_key?": true, + "references": null, + "scale": null, + "size": null, + "source": "id", + "type": "uuid" + }, + { + "allow_nil?": true, + "default": "nil", + "generated?": false, + "precision": null, + "primary_key?": false, + "references": null, + "scale": null, + "size": null, + "source": "name", + "type": "text" + }, + { + "allow_nil?": true, + "default": "nil", + "generated?": false, + "precision": null, + "primary_key?": false, + "references": null, + "scale": null, + "size": null, + "source": "age", + "type": "bigint" + }, + { + "allow_nil?": true, + "default": "nil", + "generated?": false, + "precision": null, + "primary_key?": false, + "references": null, + "scale": null, + "size": null, + "source": "bio", + "type": "text" + }, + { + "allow_nil?": true, + "default": "true", + "generated?": false, + "precision": null, + "primary_key?": false, + "references": null, + "scale": null, + "size": null, + "source": "active", + "type": "boolean" + }, + { + "allow_nil?": true, + "default": "nil", + "generated?": false, + "precision": null, + "primary_key?": false, + "references": null, + "scale": null, + "size": null, + "source": "owner_id", + "type": "uuid" + } + ], + "base_filter": null, + "check_constraints": [], + "custom_indexes": [], + "custom_statements": [], + "has_create_action": true, + "hash": "B32650B5196D79814F5D5EF0481C757CDE5F7545E787EA911A13B9B9CBD38E7E", + "identities": [], + "multitenancy": { + "attribute": null, + "global": null, + "strategy": null + }, + "repo": "Elixir.AshPostgres.TestRepo", + "schema": null, + "table": "unrelated_profiles" +} \ No newline at end of file diff --git a/priv/resource_snapshots/test_repo/unrelated_reports/20250731124648.json b/priv/resource_snapshots/test_repo/unrelated_reports/20250731124648.json new file mode 100644 index 00000000..327cce49 --- /dev/null +++ b/priv/resource_snapshots/test_repo/unrelated_reports/20250731124648.json @@ -0,0 +1,79 @@ +{ + "attributes": [ + { + "allow_nil?": false, + "default": "fragment(\"gen_random_uuid()\")", + "generated?": false, + "precision": null, + "primary_key?": true, + "references": null, + "scale": null, + "size": null, + "source": "id", + "type": "uuid" + }, + { + "allow_nil?": true, + "default": "nil", + "generated?": false, + "precision": null, + "primary_key?": false, + "references": null, + "scale": null, + "size": null, + "source": "title", + "type": "text" + }, + { + "allow_nil?": true, + "default": "nil", + "generated?": false, + "precision": null, + "primary_key?": false, + "references": null, + "scale": null, + "size": null, + "source": "author_name", + "type": "text" + }, + { + "allow_nil?": true, + "default": "nil", + "generated?": false, + "precision": null, + "primary_key?": false, + "references": null, + "scale": null, + "size": null, + "source": "score", + "type": "bigint" + }, + { + "allow_nil?": false, + "default": "fragment(\"(now() AT TIME ZONE 'utc')\")", + "generated?": false, + "precision": null, + "primary_key?": false, + "references": null, + "scale": null, + "size": null, + "source": "inserted_at", + "type": "utc_datetime" + } + ], + "base_filter": null, + "check_constraints": [], + "custom_indexes": [], + "custom_statements": [], + "has_create_action": true, + "hash": "728B41F3FC4BC58102261057925992766C0A3D9ED3AD7D16B887CCF8EF6B6E19", + "identities": [], + "multitenancy": { + "attribute": null, + "global": null, + "strategy": null + }, + "repo": "Elixir.AshPostgres.TestRepo", + "schema": null, + "table": "unrelated_reports" +} \ No newline at end of file diff --git a/priv/resource_snapshots/test_repo/unrelated_secure_profiles/20250731124648.json b/priv/resource_snapshots/test_repo/unrelated_secure_profiles/20250731124648.json new file mode 100644 index 00000000..9df541b0 --- /dev/null +++ b/priv/resource_snapshots/test_repo/unrelated_secure_profiles/20250731124648.json @@ -0,0 +1,91 @@ +{ + "attributes": [ + { + "allow_nil?": false, + "default": "fragment(\"gen_random_uuid()\")", + "generated?": false, + "precision": null, + "primary_key?": true, + "references": null, + "scale": null, + "size": null, + "source": "id", + "type": "uuid" + }, + { + "allow_nil?": true, + "default": "nil", + "generated?": false, + "precision": null, + "primary_key?": false, + "references": null, + "scale": null, + "size": null, + "source": "name", + "type": "text" + }, + { + "allow_nil?": true, + "default": "nil", + "generated?": false, + "precision": null, + "primary_key?": false, + "references": null, + "scale": null, + "size": null, + "source": "age", + "type": "bigint" + }, + { + "allow_nil?": true, + "default": "true", + "generated?": false, + "precision": null, + "primary_key?": false, + "references": null, + "scale": null, + "size": null, + "source": "active", + "type": "boolean" + }, + { + "allow_nil?": true, + "default": "nil", + "generated?": false, + "precision": null, + "primary_key?": false, + "references": null, + "scale": null, + "size": null, + "source": "owner_id", + "type": "uuid" + }, + { + "allow_nil?": true, + "default": "nil", + "generated?": false, + "precision": null, + "primary_key?": false, + "references": null, + "scale": null, + "size": null, + "source": "department", + "type": "text" + } + ], + "base_filter": null, + "check_constraints": [], + "custom_indexes": [], + "custom_statements": [], + "has_create_action": true, + "hash": "56BB9374A010E8E23144743DEDD10B6557BCD002338D1B06A35431AB0320F88B", + "identities": [], + "multitenancy": { + "attribute": null, + "global": null, + "strategy": null + }, + "repo": "Elixir.AshPostgres.TestRepo", + "schema": null, + "table": "unrelated_secure_profiles" +} \ No newline at end of file diff --git a/priv/resource_snapshots/test_repo/unrelated_users/20250731124648.json b/priv/resource_snapshots/test_repo/unrelated_users/20250731124648.json new file mode 100644 index 00000000..4d83b926 --- /dev/null +++ b/priv/resource_snapshots/test_repo/unrelated_users/20250731124648.json @@ -0,0 +1,79 @@ +{ + "attributes": [ + { + "allow_nil?": false, + "default": "fragment(\"gen_random_uuid()\")", + "generated?": false, + "precision": null, + "primary_key?": true, + "references": null, + "scale": null, + "size": null, + "source": "id", + "type": "uuid" + }, + { + "allow_nil?": true, + "default": "nil", + "generated?": false, + "precision": null, + "primary_key?": false, + "references": null, + "scale": null, + "size": null, + "source": "name", + "type": "text" + }, + { + "allow_nil?": true, + "default": "nil", + "generated?": false, + "precision": null, + "primary_key?": false, + "references": null, + "scale": null, + "size": null, + "source": "age", + "type": "bigint" + }, + { + "allow_nil?": true, + "default": "nil", + "generated?": false, + "precision": null, + "primary_key?": false, + "references": null, + "scale": null, + "size": null, + "source": "email", + "type": "text" + }, + { + "allow_nil?": true, + "default": "\"user\"", + "generated?": false, + "precision": null, + "primary_key?": false, + "references": null, + "scale": null, + "size": null, + "source": "role", + "type": "text" + } + ], + "base_filter": null, + "check_constraints": [], + "custom_indexes": [], + "custom_statements": [], + "has_create_action": true, + "hash": "E56D245A9DA955A309FDF1BD11C215F3056FF9BA7A4D4D3A3D5E285F0D183AC2", + "identities": [], + "multitenancy": { + "attribute": null, + "global": null, + "strategy": null + }, + "repo": "Elixir.AshPostgres.TestRepo", + "schema": null, + "table": "unrelated_users" +} \ No newline at end of file diff --git a/priv/test_repo/migrations/20250731124648_migrate_resources57.exs b/priv/test_repo/migrations/20250731124648_migrate_resources57.exs new file mode 100644 index 00000000..3493fd6b --- /dev/null +++ b/priv/test_repo/migrations/20250731124648_migrate_resources57.exs @@ -0,0 +1,59 @@ +defmodule AshPostgres.TestRepo.Migrations.MigrateResources57 do + @moduledoc """ + Updates resources based on their most recent snapshots. + + This file was autogenerated with `mix ash_postgres.generate_migrations` + """ + + use Ecto.Migration + + def up do + create table(:unrelated_reports, primary_key: false) do + add(:id, :uuid, null: false, default: fragment("gen_random_uuid()"), primary_key: true) + add(:title, :text) + add(:author_name, :text) + add(:score, :bigint) + + add(:inserted_at, :utc_datetime, + null: false, + default: fragment("(now() AT TIME ZONE 'utc')") + ) + end + + create table(:unrelated_users, primary_key: false) do + add(:id, :uuid, null: false, default: fragment("gen_random_uuid()"), primary_key: true) + add(:name, :text) + add(:age, :bigint) + add(:email, :text) + add(:role, :text, default: "user") + end + + create table(:unrelated_profiles, primary_key: false) do + add(:id, :uuid, null: false, default: fragment("gen_random_uuid()"), primary_key: true) + add(:name, :text) + add(:age, :bigint) + add(:bio, :text) + add(:active, :boolean, default: true) + add(:owner_id, :uuid) + end + + create table(:unrelated_secure_profiles, primary_key: false) do + add(:id, :uuid, null: false, default: fragment("gen_random_uuid()"), primary_key: true) + add(:name, :text) + add(:age, :bigint) + add(:active, :boolean, default: true) + add(:owner_id, :uuid) + add(:department, :text) + end + end + + def down do + drop(table(:unrelated_secure_profiles)) + + drop(table(:unrelated_profiles)) + + drop(table(:unrelated_users)) + + drop(table(:unrelated_reports)) + end +end diff --git a/test/support/domain.ex b/test/support/domain.ex index 58074271..58802a18 100644 --- a/test/support/domain.ex +++ b/test/support/domain.ex @@ -44,6 +44,10 @@ defmodule AshPostgres.Test.Domain do resource(AshPostgres.Test.Punchline) resource(AshPostgres.Test.Tag) resource(AshPostgres.Test.PostTag) + resource(AshPostgres.Test.UnrelatedAggregatesTest.Profile) + resource(AshPostgres.Test.UnrelatedAggregatesTest.SecureProfile) + resource(AshPostgres.Test.UnrelatedAggregatesTest.Report) + resource(AshPostgres.Test.UnrelatedAggregatesTest.User) end authorization do diff --git a/test/support/unrelated_aggregates/profile.ex b/test/support/unrelated_aggregates/profile.ex new file mode 100644 index 00000000..87a9fa9f --- /dev/null +++ b/test/support/unrelated_aggregates/profile.ex @@ -0,0 +1,36 @@ +defmodule AshPostgres.Test.UnrelatedAggregatesTest.Profile do + @moduledoc false + use Ash.Resource, + domain: AshPostgres.Test.Domain, + data_layer: AshPostgres.DataLayer, + authorizers: [Ash.Policy.Authorizer] + + postgres do + table("unrelated_profiles") + repo(AshPostgres.TestRepo) + end + + attributes do + uuid_primary_key(:id) + attribute(:name, :string, public?: true) + attribute(:age, :integer, public?: true) + attribute(:bio, :string, public?: true) + attribute(:active, :boolean, default: true, public?: true) + attribute(:owner_id, :uuid, public?: true) + end + + actions do + defaults([:read, :destroy, create: :*, update: :*]) + end + + policies do + # Allow unrestricted access for most tests, but we'll create a SecureProfile for auth tests + policy action_type([:create, :update, :destroy]) do + authorize_if(always()) + end + + policy action_type(:read) do + authorize_if(always()) + end + end +end diff --git a/test/support/unrelated_aggregates/report.ex b/test/support/unrelated_aggregates/report.ex new file mode 100644 index 00000000..652df03c --- /dev/null +++ b/test/support/unrelated_aggregates/report.ex @@ -0,0 +1,33 @@ +defmodule AshPostgres.Test.UnrelatedAggregatesTest.Report do + @moduledoc false + use Ash.Resource, + domain: AshPostgres.Test.Domain, + data_layer: AshPostgres.DataLayer + + postgres do + table("unrelated_reports") + repo(AshPostgres.TestRepo) + end + + attributes do + uuid_primary_key(:id) + attribute(:title, :string, public?: true) + attribute(:author_name, :string, public?: true) + attribute(:score, :integer, public?: true) + + attribute(:inserted_at, :utc_datetime, + public?: true, + default: &DateTime.utc_now/0, + allow_nil?: false + ) + end + + actions do + defaults([:read, :destroy, update: :*]) + + create :create do + primary?(true) + accept([:title, :author_name, :score, :inserted_at]) + end + end +end diff --git a/test/support/unrelated_aggregates/secure_profile.ex b/test/support/unrelated_aggregates/secure_profile.ex new file mode 100644 index 00000000..3f50bf73 --- /dev/null +++ b/test/support/unrelated_aggregates/secure_profile.ex @@ -0,0 +1,38 @@ +defmodule AshPostgres.Test.UnrelatedAggregatesTest.SecureProfile do + @moduledoc false + use Ash.Resource, + domain: AshPostgres.Test.Domain, + data_layer: AshPostgres.DataLayer, + authorizers: [Ash.Policy.Authorizer] + + postgres do + table("unrelated_secure_profiles") + repo(AshPostgres.TestRepo) + end + + attributes do + uuid_primary_key(:id) + attribute(:name, :string, public?: true) + attribute(:age, :integer, public?: true) + attribute(:active, :boolean, default: true, public?: true) + attribute(:owner_id, :uuid, public?: true) + attribute(:department, :string, public?: true) + end + + actions do + defaults([:read, :destroy, create: :*, update: :*]) + end + + policies do + # Allow creation/updates for testing setup + policy action_type([:create, :update, :destroy]) do + authorize_if(always()) + end + + # Only allow users to see their own profiles, or admins to see all + policy action_type(:read) do + authorize_if(actor_attribute_equals(:role, :admin)) + authorize_if(expr(owner_id == ^actor(:id))) + end + end +end diff --git a/test/support/unrelated_aggregates/user.ex b/test/support/unrelated_aggregates/user.ex new file mode 100644 index 00000000..ce143489 --- /dev/null +++ b/test/support/unrelated_aggregates/user.ex @@ -0,0 +1,154 @@ +defmodule AshPostgres.Test.UnrelatedAggregatesTest.User do + @moduledoc false + use Ash.Resource, + domain: AshPostgres.Test.Domain, + data_layer: AshPostgres.DataLayer + + alias AshPostgres.Test.UnrelatedAggregatesTest.{Profile, Report, SecureProfile} + + postgres do + table("unrelated_users") + repo(AshPostgres.TestRepo) + end + + attributes do + uuid_primary_key(:id) + attribute(:name, :string, public?: true) + attribute(:age, :integer, public?: true) + attribute(:email, :string, public?: true) + attribute(:role, :atom, public?: true, default: :user) + end + + # Test basic unrelated aggregates + aggregates do + # Count of profiles with matching name + count :matching_name_profiles_count, Profile do + filter(expr(name == parent(name))) + public?(true) + end + + # Count of all active profiles (no parent filter) + count :total_active_profiles, Profile do + filter(expr(active == true)) + public?(true) + end + + # First report with matching author name + first :latest_authored_report, Report, :title do + filter(expr(author_name == parent(name))) + sort(inserted_at: :desc) + public?(true) + end + + # Sum of report scores for matching author + sum :total_report_score, Report, :score do + filter(expr(author_name == parent(name))) + public?(true) + end + + # Exists check for profiles with same name + exists :has_matching_name_profile, Profile do + filter(expr(name == parent(name))) + public?(true) + end + + # List of all profile names with same name (should be just one usually) + list :matching_profile_names, Profile, :name do + filter(expr(name == parent(name))) + public?(true) + end + + # Max age of profiles with same name + max :max_age_same_name, Profile, :age do + filter(expr(name == parent(name))) + public?(true) + end + + # Min age of profiles with same name + min :min_age_same_name, Profile, :age do + filter(expr(name == parent(name))) + public?(true) + end + + # Average age of profiles with same name + avg :avg_age_same_name, Profile, :age do + filter(expr(name == parent(name))) + public?(true) + end + + # Secure aggregate - should respect authorization policies + count :secure_profile_count, SecureProfile do + filter(expr(name == parent(name))) + public?(true) + end + end + + # Test unrelated aggregates in calculations + calculations do + calculate :matching_profiles_summary, + :string, + expr("Found " <> type(matching_name_profiles_count, :string) <> " profiles") do + public?(true) + end + + calculate :inline_profile_count, + :integer, + expr(count(Profile, filter: expr(name == parent(name)))) do + public?(true) + end + + calculate :inline_latest_report_title, + :string, + expr( + first(Report, + field: :title, + query: [ + filter: expr(author_name == parent(name)), + sort: [inserted_at: :desc] + ] + ) + ) do + public?(true) + end + + calculate :inline_total_score, + :integer, + expr( + sum(Report, + field: :score, + query: [ + filter: expr(author_name == parent(name)) + ] + ) + ) do + public?(true) + end + + calculate :complex_calculation, + :map, + expr(%{ + profile_count: count(Profile, filter: expr(name == parent(name))), + latest_report: + first(Report, + field: :title, + query: [ + filter: expr(author_name == parent(name)), + sort: [inserted_at: :desc] + ] + ), + total_score: + sum(Report, + field: :score, + query: [ + filter: expr(author_name == parent(name)) + ] + ) + }) do + public?(true) + end + end + + actions do + defaults([:read, :destroy, create: :*, update: :*]) + end +end diff --git a/test/unrelated_aggregates_test.exs b/test/unrelated_aggregates_test.exs new file mode 100644 index 00000000..09a15740 --- /dev/null +++ b/test/unrelated_aggregates_test.exs @@ -0,0 +1,507 @@ +defmodule AshPostgres.Test.UnrelatedAggregatesTest do + @moduledoc false + use AshPostgres.RepoCase, async: false + + require Ash.Query + import Ash.Expr + + alias AshPostgres.Test.UnrelatedAggregatesTest.{Profile, Report, SecureProfile, User} + + describe "basic unrelated aggregate definitions" do + test "aggregates are properly defined with related?: false" do + aggregates = Ash.Resource.Info.aggregates(User) + + count_agg = Enum.find(aggregates, &(&1.name == :matching_name_profiles_count)) + assert count_agg + assert count_agg.related? == false + assert count_agg.resource == Profile + assert count_agg.kind == :count + assert count_agg.relationship_path == [] + + first_agg = Enum.find(aggregates, &(&1.name == :latest_authored_report)) + assert first_agg + assert first_agg.related? == false + assert first_agg.resource == Report + assert first_agg.kind == :first + assert first_agg.field == :title + + sum_agg = Enum.find(aggregates, &(&1.name == :total_report_score)) + assert sum_agg + assert sum_agg.related? == false + assert sum_agg.resource == Report + assert sum_agg.kind == :sum + assert sum_agg.field == :score + end + + test "unrelated aggregates support all aggregate kinds" do + aggregates = Ash.Resource.Info.aggregates(User) + aggregate_names = Enum.map(aggregates, & &1.name) + + # Verify all kinds are supported + # count + assert :matching_name_profiles_count in aggregate_names + # first + assert :latest_authored_report in aggregate_names + # sum + assert :total_report_score in aggregate_names + # exists + assert :has_matching_name_profile in aggregate_names + # list + assert :matching_profile_names in aggregate_names + # max + assert :max_age_same_name in aggregate_names + # min + assert :min_age_same_name in aggregate_names + # avg + assert :avg_age_same_name in aggregate_names + end + + test "can define aggregates without parent filters" do + aggregates = Ash.Resource.Info.aggregates(User) + total_active_agg = Enum.find(aggregates, &(&1.name == :total_active_profiles)) + + assert total_active_agg + assert total_active_agg.related? == false + assert total_active_agg.resource == Profile + # Should have filter but no parent() reference + end + end + + describe "loading unrelated aggregates" do + setup do + # Create test data + {:ok, user1} = Ash.create(User, %{name: "John", email: "john@example.com"}) + {:ok, user2} = Ash.create(User, %{name: "Jane", email: "jane@example.com"}) + + {:ok, _profile1} = Ash.create(Profile, %{name: "John", age: 25, active: true}) + {:ok, _profile2} = Ash.create(Profile, %{name: "John", age: 30, active: true}) + {:ok, _profile3} = Ash.create(Profile, %{name: "Jane", age: 28, active: true}) + {:ok, _profile4} = Ash.create(Profile, %{name: "Bob", age: 35, active: false}) + + base_time = ~U[2024-01-01 12:00:00Z] + + {:ok, _report1} = + Ash.create(Report, %{ + title: "John's First Report", + author_name: "John", + score: 85, + inserted_at: base_time + }) + + {:ok, _report2} = + Ash.create(Report, %{ + title: "John's Latest Report", + author_name: "John", + score: 92, + inserted_at: DateTime.add(base_time, 3600, :second) + }) + + {:ok, _report3} = + Ash.create(Report, %{ + title: "Jane's Report", + author_name: "Jane", + score: 78 + }) + + %{user1: user1, user2: user2} + end + + test "can load count unrelated aggregates", %{user1: user1, user2: user2} do + # Load users with aggregates + users = + User + |> Ash.Query.load([:matching_name_profiles_count, :total_active_profiles]) + |> Ash.read!() + + john = Enum.find(users, &(&1.id == user1.id)) + jane = Enum.find(users, &(&1.id == user2.id)) + + # John should have 2 matching profiles + assert john.matching_name_profiles_count == 2 + # Both should see 3 total active profiles (John x2, Jane x1) + assert john.total_active_profiles == 3 + + # Jane should have 1 matching profile + assert jane.matching_name_profiles_count == 1 + assert jane.total_active_profiles == 3 + end + + test "can load first unrelated aggregates", %{user1: user1} do + user = + User + |> Ash.Query.filter(id == ^user1.id) + |> Ash.Query.load(:latest_authored_report) + |> Ash.read_one!() + + # Should get the latest report title + assert user.latest_authored_report == "John's Latest Report" + end + + test "can load sum unrelated aggregates", %{user1: user1, user2: user2} do + users = + User + |> Ash.Query.load(:total_report_score) + |> Ash.read!() + + john = Enum.find(users, &(&1.id == user1.id)) + jane = Enum.find(users, &(&1.id == user2.id)) + + # John's total score: 85 + 92 = 177 + assert john.total_report_score == 177 + # Jane's total score: 78 + assert jane.total_report_score == 78 + end + + test "can load exists unrelated aggregates", %{user1: user1} do + user = + User + |> Ash.Query.filter(id == ^user1.id) + |> Ash.Query.load(:has_matching_name_profile) + |> Ash.read_one!() + + assert user.has_matching_name_profile == true + end + + test "can load list unrelated aggregates", %{user1: user1} do + user = + User + |> Ash.Query.filter(id == ^user1.id) + |> Ash.Query.load(:matching_profile_names) + |> Ash.read_one!() + + # Should have two "John" entries + assert length(user.matching_profile_names) == 2 + assert Enum.all?(user.matching_profile_names, &(&1 == "John")) + end + + test "can load min/max/avg unrelated aggregates", %{user1: user1} do + user = + User + |> Ash.Query.filter(id == ^user1.id) + |> Ash.Query.load([:min_age_same_name, :max_age_same_name, :avg_age_same_name]) + |> Ash.read_one!() + + # John profiles have ages 25 and 30 + assert user.min_age_same_name == 25 + assert user.max_age_same_name == 30 + assert user.avg_age_same_name == 27.5 + end + end + + describe "unrelated aggregates in calculations" do + setup do + {:ok, user} = Ash.create(User, %{name: "Alice", email: "alice@example.com"}) + {:ok, _profile} = Ash.create(Profile, %{name: "Alice", age: 25, active: true}) + + {:ok, _report} = + Ash.create(Report, %{ + title: "Alice's Research", + author_name: "Alice", + score: 95, + inserted_at: ~U[2024-01-01 12:00:00Z] + }) + + %{user: user} + end + + test "calculations using named unrelated aggregates work", %{user: user} do + user = + User + |> Ash.Query.filter(id == ^user.id) + |> Ash.Query.load(:matching_profiles_summary) + |> Ash.read_one!() + + assert user.matching_profiles_summary == "Found 1 profiles" + end + + test "inline unrelated aggregates in calculations work", %{user: user} do + user = + User + |> Ash.Query.filter(id == ^user.id) + |> Ash.Query.load([ + :inline_profile_count, + :inline_latest_report_title, + :inline_total_score + ]) + |> Ash.read_one!() + + assert user.inline_profile_count == 1 + assert user.inline_latest_report_title == "Alice's Research" + assert user.inline_total_score == 95 + end + + test "complex calculations with multiple inline unrelated aggregates work", %{user: user} do + user = + User + |> Ash.Query.filter(id == ^user.id) + |> Ash.Query.load(:complex_calculation) + |> Ash.read_one!() + + assert user.complex_calculation == %{ + profile_count: 1, + latest_report: "Alice's Research", + total_score: 95 + } + end + end + + describe "data layer capability checking" do + test "Postgres data layer should support unrelated aggregates" do + # This will fail until we implement the capability + assert AshPostgres.DataLayer.can?(nil, {:aggregate, :unrelated}) == true + end + + test "error when data layer doesn't support unrelated aggregates" do + # Test with a mock data layer that doesn't support unrelated aggregates + # This will be relevant when we add the capability checking + end + end + + describe "authorization with unrelated aggregates" do + # These tests verify that authorization works properly for unrelated aggregates + # The main concern is that unrelated aggregates don't have relationship paths, + # so the authorization logic must handle this correctly + + test "unrelated aggregates work without relationship path authorization errors" do + # This test verifies that unrelated aggregates don't trigger the + # :lists.droplast([]) error that was happening before the fix + {:ok, user} = Ash.create(User, %{name: "AuthTest", email: "auth@example.com"}) + {:ok, _profile} = Ash.create(Profile, %{name: "AuthTest", age: 25, active: true}) + + # This should not raise authorization errors + user = + User + |> Ash.Query.filter(id == ^user.id) + |> Ash.Query.load(:matching_name_profiles_count) + |> Ash.read_one!() + + assert user.matching_name_profiles_count == 1 + end + + test "unrelated aggregates in calculations don't cause authorization errors" do + # Test that the authorization logic correctly handles unrelated aggregates + # when they're referenced in calculations + {:ok, user} = Ash.create(User, %{name: "CalcAuth", email: "calcauth@example.com"}) + {:ok, _profile} = Ash.create(Profile, %{name: "CalcAuth", age: 30, active: true}) + + # This should not raise authorization errors + user = + User + |> Ash.Query.filter(id == ^user.id) + |> Ash.Query.load(:matching_profiles_summary) + |> Ash.read_one!() + + assert user.matching_profiles_summary == "Found 1 profiles" + end + + test "multiple unrelated aggregates can be loaded together without authorization issues" do + # Test loading multiple unrelated aggregates simultaneously + {:ok, user} = Ash.create(User, %{name: "MultiAuth", email: "multi@example.com"}) + {:ok, _profile} = Ash.create(Profile, %{name: "MultiAuth", age: 28, active: true}) + + {:ok, _report} = + Ash.create(Report, %{ + title: "MultiAuth Report", + author_name: "MultiAuth", + score: 88, + inserted_at: ~U[2024-01-01 15:00:00Z] + }) + + # Loading multiple unrelated aggregates should work + user = + User + |> Ash.Query.filter(id == ^user.id) + |> Ash.Query.load([ + :matching_name_profiles_count, + :total_active_profiles, + :latest_authored_report, + :total_report_score + ]) + |> Ash.read_one!() + + assert user.matching_name_profiles_count == 1 + # Could include profiles from other tests + assert user.total_active_profiles >= 1 + assert user.latest_authored_report == "MultiAuth Report" + assert user.total_report_score == 88 + end + + test "unrelated aggregates respect target resource authorization policies" do + admin_user = Ash.create!(User, %{name: "Admin", email: "admin@test.com", role: :admin}) + regular_user1 = Ash.create!(User, %{name: "User1", email: "user1@test.com", role: :user}) + regular_user2 = Ash.create!(User, %{name: "User1", email: "user2@test.com", role: :user}) + + Ash.create!(SecureProfile, %{ + name: "User1", + age: 25, + active: true, + owner_id: regular_user1.id, + department: "Engineering" + }) + + Ash.create!(SecureProfile, %{ + name: "User1", + age: 30, + active: true, + owner_id: regular_user2.id, + department: "Marketing" + }) + + Ash.create!(SecureProfile, %{ + name: "Admin", + age: 35, + active: true, + owner_id: admin_user.id, + department: "Management" + }) + + user1_result = + User + |> Ash.Query.filter(id == ^regular_user1.id) + |> Ash.Query.load(:secure_profile_count) + |> Ash.read_one!(actor: regular_user1, authorize?: true) + + assert user1_result.secure_profile_count == 1 + + user2_result = + User + |> Ash.Query.filter(id == ^regular_user2.id) + |> Ash.Query.load(:secure_profile_count) + |> Ash.read_one!(actor: regular_user2, authorize?: true) + + assert user2_result.secure_profile_count == 1 + + admin_as_user1 = + User + |> Ash.Query.filter(id == ^regular_user1.id) + |> Ash.Query.load(:secure_profile_count) + |> Ash.read_one!(actor: admin_user, authorize?: true) + + assert admin_as_user1.secure_profile_count == 2 + + admin_result = + User + |> Ash.Query.filter(id == ^admin_user.id) + |> Ash.Query.load(:secure_profile_count) + |> Ash.read_one!(actor: admin_user, authorize?: true) + + assert admin_result.secure_profile_count == 1 + end + end + + describe "edge cases" do + test "unrelated aggregates work with empty result sets" do + users = + User + |> Ash.Query.filter(name == "NonExistent") + |> Ash.Query.load(:matching_name_profiles_count) + |> Ash.read!() + + # Should be empty, but aggregate should still work + assert users == [] + end + + test "unrelated aggregates work with filters that return no results" do + {:ok, user} = Ash.create(User, %{name: "Unique", email: "unique@example.com"}) + + # No profiles with name "Unique" exist + loaded_user = + User + |> Ash.Query.filter(id == ^user.id) + |> Ash.Query.load(:matching_name_profiles_count) + |> Ash.read_one!() + + assert loaded_user.matching_name_profiles_count == 0 + end + + test "unrelated aggregates work with complex filter expressions" do + {:ok, user} = + Ash.create(User, %{name: "ComplexTest", age: 25, email: "complex@example.com"}) + + # Create profiles with various attributes + {:ok, _profile1} = + Ash.create(Profile, %{name: "ComplexTest", age: 25, bio: "Bio contains ComplexTest"}) + + {:ok, _profile2} = + Ash.create(Profile, %{name: "ComplexTest", age: 30, bio: "Different bio"}) + + {:ok, _profile3} = + Ash.create(Profile, %{name: "Other", age: 25, bio: "ComplexTest mentioned"}) + + # Test parent() with boolean AND + loaded_user = + User + |> Ash.Query.filter(id == ^user.id) + |> Ash.Query.aggregate(:same_name_and_age, :count, Profile, + query: [filter: expr(name == parent(name) and age == parent(age))] + ) + |> Ash.read_one!() + + assert loaded_user.aggregates.same_name_and_age == 1 + + # Test parent() with OR conditions + loaded_user = + User + |> Ash.Query.filter(id == ^user.id) + |> Ash.Query.aggregate(:name_or_bio_match, :count, Profile, + query: [filter: expr(name == parent(name) or contains(bio, parent(name)))] + ) + |> Ash.read_one!() + + assert loaded_user.aggregates.name_or_bio_match == 3 + + # Test parent() with comparison operators + loaded_user = + User + |> Ash.Query.filter(id == ^user.id) + |> Ash.Query.aggregate(:older_profiles, :count, Profile, + query: [filter: expr(name == parent(name) and age > parent(age))] + ) + |> Ash.read_one!() + + assert loaded_user.aggregates.older_profiles == 1 + end + + test "parent() works with nested conditional expressions" do + {:ok, user} = Ash.create(User, %{name: "NestedTest", age: 30, email: "nested@example.com"}) + + {:ok, _profile1} = Ash.create(Profile, %{name: "NestedTest", age: 25, bio: "Young"}) + {:ok, _profile2} = Ash.create(Profile, %{name: "NestedTest", age: 35, bio: "Old"}) + {:ok, _profile3} = Ash.create(Profile, %{name: "Other", age: 30, bio: "Same age"}) + + # Test nested parentheses with parent() + loaded_user = + User + |> Ash.Query.filter(id == ^user.id) + |> Ash.Query.aggregate(:complex_condition, :count, Profile, + query: [filter: expr(name == parent(name) and (age < parent(age) or age > parent(age)))] + ) + |> Ash.read_one!() + + assert loaded_user.aggregates.complex_condition == 2 + end + + test "parent() works with string functions" do + {:ok, user} = Ash.create(User, %{name: "StringTest", email: "string@example.com"}) + + {:ok, _profile1} = + Ash.create(Profile, %{name: "StringTest", bio: "StringTest is mentioned here"}) + + {:ok, _profile2} = + Ash.create(Profile, %{name: "DifferentName", bio: "StringTest appears in bio"}) + + {:ok, _profile3} = Ash.create(Profile, %{name: "StringTest", bio: "No mention"}) + + # Test parent() with string contains function + loaded_user = + User + |> Ash.Query.filter(id == ^user.id) + |> Ash.Query.aggregate(:bio_mentions_name, :count, Profile, + query: [filter: expr(contains(bio, parent(name)))] + ) + |> Ash.read_one!() + + assert loaded_user.aggregates.bio_mentions_name == 2 + end + end +end From d83157df2ee0a27e5d7fe4450ca44a43a0d9454b Mon Sep 17 00:00:00 2001 From: Zach Daniel Date: Thu, 21 Aug 2025 18:33:40 -0400 Subject: [PATCH 107/174] chore: update ash/ash_sql --- mix.exs | 4 ++-- mix.lock | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/mix.exs b/mix.exs index 0ff8df8e..e9bd0ed8 100644 --- a/mix.exs +++ b/mix.exs @@ -166,8 +166,8 @@ defmodule AshPostgres.MixProject do # Run "mix help deps" to learn about dependencies. defp deps do [ - {:ash, ash_version(github: "ash-project/ash", branch: "main")}, - {:ash_sql, ash_sql_version(github: "ash-project/ash_sql", branch: "main")}, + {:ash, ash_version("~> 3.5 and >= 3.5.35")}, + {:ash_sql, ash_sql_version("~> 0.2 and >= 0.2.90")}, {:igniter, "~> 0.6 and >= 0.6.14", optional: true}, {:ecto_sql, "~> 3.13"}, {:ecto, "~> 3.13"}, diff --git a/mix.lock b/mix.lock index 3c6f7826..a6ba65e8 100644 --- a/mix.lock +++ b/mix.lock @@ -1,6 +1,6 @@ %{ - "ash": {:git, "https://github.com/ash-project/ash.git", "471274d2f75a4bda6405c5630b72f9323d572260", [branch: "main"]}, - "ash_sql": {:git, "https://github.com/ash-project/ash_sql.git", "40c9bcb905603dbcee2bc064f37c6f5ce30da7c7", [branch: "main"]}, + "ash": {:hex, :ash, "3.5.35", "ff63b9d3670a05ad036ecc8732c0143770aff4e23f07662931a9ebd1f4aba3c4", [:mix], [{:decimal, "~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:ecto, "~> 3.7", [hex: :ecto, repo: "hexpm", optional: false]}, {:ets, "~> 0.8", [hex: :ets, repo: "hexpm", optional: false]}, {:igniter, ">= 0.6.4 and < 1.0.0-0", [hex: :igniter, repo: "hexpm", optional: true]}, {:jason, ">= 1.0.0", [hex: :jason, repo: "hexpm", optional: false]}, {:picosat_elixir, "~> 0.2", [hex: :picosat_elixir, repo: "hexpm", optional: true]}, {:plug, ">= 0.0.0", [hex: :plug, repo: "hexpm", optional: true]}, {:reactor, "~> 0.11", [hex: :reactor, repo: "hexpm", optional: false]}, {:simple_sat, ">= 0.1.1 and < 1.0.0-0", [hex: :simple_sat, repo: "hexpm", optional: true]}, {:spark, ">= 2.2.68 and < 3.0.0-0", [hex: :spark, repo: "hexpm", optional: false]}, {:splode, ">= 0.2.6 and < 1.0.0-0", [hex: :splode, repo: "hexpm", optional: false]}, {:stream_data, "~> 1.0", [hex: :stream_data, repo: "hexpm", optional: false]}, {:telemetry, "~> 1.1", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "b6ff48f80efabcc1867af9847c8656fa376d9b800e8988b82ec0a42bee4f6b58"}, + "ash_sql": {:hex, :ash_sql, "0.2.90", "6b533e963e4b7c0855654597d8eb7bb87c30db0be7328628cb9bb63e2e547a54", [:mix], [{:ash, ">= 3.5.35 and < 4.0.0-0", [hex: :ash, repo: "hexpm", optional: false]}, {:ecto, "~> 3.9", [hex: :ecto, repo: "hexpm", optional: false]}, {:ecto_sql, "~> 3.9", [hex: :ecto_sql, repo: "hexpm", optional: false]}], "hexpm", "57a7235f22f01381b1a2d63364c353fe6fa31278f3bbd402aacab6dba78a7e6b"}, "benchee": {:hex, :benchee, "1.4.0", "9f1f96a30ac80bab94faad644b39a9031d5632e517416a8ab0a6b0ac4df124ce", [:mix], [{:deep_merge, "~> 1.0", [hex: :deep_merge, repo: "hexpm", optional: false]}, {:statistex, "~> 1.0", [hex: :statistex, repo: "hexpm", optional: false]}, {:table, "~> 0.1.0", [hex: :table, repo: "hexpm", optional: true]}], "hexpm", "299cd10dd8ce51c9ea3ddb74bb150f93d25e968f93e4c1fa31698a8e4fa5d715"}, "bunt": {:hex, :bunt, "1.0.0", "081c2c665f086849e6d57900292b3a161727ab40431219529f13c4ddcf3e7a44", [:mix], [], "hexpm", "dc5f86aa08a5f6fa6b8096f0735c4e76d54ae5c9fa2c143e5a1fc7c1cd9bb6b5"}, "credo": {:hex, :credo, "1.7.12", "9e3c20463de4b5f3f23721527fcaf16722ec815e70ff6c60b86412c695d426c1", [:mix], [{:bunt, "~> 0.2.1 or ~> 1.0", [hex: :bunt, repo: "hexpm", optional: false]}, {:file_system, "~> 0.2 or ~> 1.0", [hex: :file_system, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "8493d45c656c5427d9c729235b99d498bd133421f3e0a683e5c1b561471291e5"}, @@ -23,7 +23,7 @@ "git_ops": {:hex, :git_ops, "2.8.0", "29ac9ab68bf9645973cb2752047b987e75cbd3d9761489c615e3ba80018fa885", [:mix], [{:git_cli, "~> 0.2", [hex: :git_cli, repo: "hexpm", optional: false]}, {:igniter, ">= 0.5.27 and < 1.0.0-0", [hex: :igniter, repo: "hexpm", optional: true]}, {:nimble_parsec, "~> 1.0", [hex: :nimble_parsec, repo: "hexpm", optional: false]}, {:req, "~> 0.5", [hex: :req, repo: "hexpm", optional: false]}], "hexpm", "b535e4ad6b5d13e14c455e76f65825659081b5530b0827eb0232d18719530eec"}, "glob_ex": {:hex, :glob_ex, "0.1.11", "cb50d3f1ef53f6ca04d6252c7fde09fd7a1cf63387714fe96f340a1349e62c93", [:mix], [], "hexpm", "342729363056e3145e61766b416769984c329e4378f1d558b63e341020525de4"}, "hpax": {:hex, :hpax, "1.0.3", "ed67ef51ad4df91e75cc6a1494f851850c0bd98ebc0be6e81b026e765ee535aa", [:mix], [], "hexpm", "8eab6e1cfa8d5918c2ce4ba43588e894af35dbd8e91e6e55c817bca5847df34a"}, - "igniter": {:hex, :igniter, "0.6.26", "a6b4f6680a7e158bd13cd3b2be047102e42c046b3b240578d68d89d1a39a83fa", [:mix], [{:glob_ex, "~> 0.1.7", [hex: :glob_ex, repo: "hexpm", optional: false]}, {:jason, "~> 1.4", [hex: :jason, repo: "hexpm", optional: false]}, {:owl, "~> 0.11", [hex: :owl, repo: "hexpm", optional: false]}, {:phx_new, "~> 1.7", [hex: :phx_new, repo: "hexpm", optional: true]}, {:req, "~> 0.5", [hex: :req, repo: "hexpm", optional: false]}, {:rewrite, ">= 1.1.1 and < 2.0.0-0", [hex: :rewrite, repo: "hexpm", optional: false]}, {:sourceror, "~> 1.4", [hex: :sourceror, repo: "hexpm", optional: false]}, {:spitfire, ">= 0.1.3 and < 1.0.0-0", [hex: :spitfire, repo: "hexpm", optional: false]}], "hexpm", "a4f8c404fc4cbc05a1b536c8125ae64909e3a02d5f972ffe6a3a2ebd75530f3c"}, + "igniter": {:hex, :igniter, "0.6.28", "9db10192f19f10b924f14c805f5b2ad992617fccaff9cf9582b7f065d562d4d8", [:mix], [{:glob_ex, "~> 0.1.7", [hex: :glob_ex, repo: "hexpm", optional: false]}, {:jason, "~> 1.4", [hex: :jason, repo: "hexpm", optional: false]}, {:owl, "~> 0.11", [hex: :owl, repo: "hexpm", optional: false]}, {:phx_new, "~> 1.7", [hex: :phx_new, repo: "hexpm", optional: true]}, {:req, "~> 0.5", [hex: :req, repo: "hexpm", optional: false]}, {:rewrite, ">= 1.1.1 and < 2.0.0-0", [hex: :rewrite, repo: "hexpm", optional: false]}, {:sourceror, "~> 1.4", [hex: :sourceror, repo: "hexpm", optional: false]}, {:spitfire, ">= 0.1.3 and < 1.0.0-0", [hex: :spitfire, repo: "hexpm", optional: false]}], "hexpm", "ad9369d626aeca21079ef17661a2672fb32598610c5e5bccae2537efd36b27d4"}, "iterex": {:hex, :iterex, "0.1.2", "58f9b9b9a22a55cbfc7b5234a9c9c63eaac26d276b3db80936c0e1c60355a5a6", [:mix], [], "hexpm", "2e103b8bcc81757a9af121f6dc0df312c9a17220f302b1193ef720460d03029d"}, "jason": {:hex, :jason, "1.4.4", "b9226785a9aa77b6857ca22832cffa5d5011a667207eb2a0ad56adb5db443b8a", [:mix], [{:decimal, "~> 1.0 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm", "c5eb0cab91f094599f94d55bc63409236a8ec69a21a67814529e8d5f6cc90b3b"}, "libgraph": {:hex, :libgraph, "0.16.0", "3936f3eca6ef826e08880230f806bfea13193e49bf153f93edcf0239d4fd1d07", [:mix], [], "hexpm", "41ca92240e8a4138c30a7e06466acc709b0cbb795c643e9e17174a178982d6bf"}, @@ -44,7 +44,7 @@ "simple_sat": {:hex, :simple_sat, "0.1.3", "f650fc3c184a5fe741868b5ac56dc77fdbb428468f6dbf1978e14d0334497578", [:mix], [], "hexpm", "a54305066a356b7194dc81db2a89232bacdc0b3edaef68ed9aba28dcbc34887b"}, "sobelow": {:hex, :sobelow, "0.14.0", "dd82aae8f72503f924fe9dd97ffe4ca694d2f17ec463dcfd365987c9752af6ee", [:mix], [{:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "7ecf91e298acfd9b24f5d761f19e8f6e6ac585b9387fb6301023f1f2cd5eed5f"}, "sourceror": {:hex, :sourceror, "1.10.0", "38397dedbbc286966ec48c7af13e228b171332be1ad731974438c77791945ce9", [:mix], [], "hexpm", "29dbdfc92e04569c9d8e6efdc422fc1d815f4bd0055dc7c51b8800fb75c4b3f1"}, - "spark": {:hex, :spark, "2.2.67", "67626cb9f59ea4b1c5aa85d4afdd025e0740cbd49ed82665d0a40ff007d7fd4b", [:mix], [{:igniter, ">= 0.3.64 and < 1.0.0-0", [hex: :igniter, repo: "hexpm", optional: true]}, {:jason, "~> 1.4", [hex: :jason, repo: "hexpm", optional: true]}, {:sourceror, "~> 1.2", [hex: :sourceror, repo: "hexpm", optional: true]}], "hexpm", "c8575402e3afc66871362e821bece890536d16319cdb758c5fb2d1250182e46f"}, + "spark": {:hex, :spark, "2.2.68", "4c4547c88d73311e3157bc402ab27f3a7bbd5e55a2ee92bcf7cd3a0a475d201e", [:mix], [{:igniter, ">= 0.3.64 and < 1.0.0-0", [hex: :igniter, repo: "hexpm", optional: true]}, {:jason, "~> 1.4", [hex: :jason, repo: "hexpm", optional: true]}, {:sourceror, "~> 1.2", [hex: :sourceror, repo: "hexpm", optional: true]}], "hexpm", "2fa4dd89801415a098a421589633f0e3df7ed9ff4046e80a65d35a413bc0d194"}, "spitfire": {:hex, :spitfire, "0.2.1", "29e154873f05444669c7453d3d931820822cbca5170e88f0f8faa1de74a79b47", [:mix], [], "hexpm", "6eeed75054a38341b2e1814d41bb0a250564092358de2669fdb57ff88141d91b"}, "splode": {:hex, :splode, "0.2.9", "3a2776e187c82f42f5226b33b1220ccbff74f4bcc523dd4039c804caaa3ffdc7", [:mix], [], "hexpm", "8002b00c6e24f8bd1bcced3fbaa5c33346048047bb7e13d2f3ad428babbd95c3"}, "statistex": {:hex, :statistex, "1.1.0", "7fec1eb2f580a0d2c1a05ed27396a084ab064a40cfc84246dbfb0c72a5c761e5", [:mix], [], "hexpm", "f5950ea26ad43246ba2cce54324ac394a4e7408fdcf98b8e230f503a0cba9cf5"}, From 3d1fe5e744c3815b5f644cece4d68c087c8346e6 Mon Sep 17 00:00:00 2001 From: Zach Daniel Date: Thu, 21 Aug 2025 18:49:18 -0400 Subject: [PATCH 108/174] chore: release version v2.6.16 --- CHANGELOG.md | 9 +++++++++ mix.exs | 2 +- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a9610b52..7df2c49a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,15 @@ See [Conventional Commits](https://www.conventionalcommits.org) for commit guide +## [v2.6.16](https://github.com/ash-project/ash_postgres/compare/v2.6.15...v2.6.16) (2025-08-21) + + + + +### Improvements: + +* Unrelated aggregates (#606) by Zach Daniel + ## [v2.6.15](https://github.com/ash-project/ash_postgres/compare/v2.6.14...v2.6.15) (2025-08-07) diff --git a/mix.exs b/mix.exs index e9bd0ed8..2d3f04b1 100644 --- a/mix.exs +++ b/mix.exs @@ -5,7 +5,7 @@ defmodule AshPostgres.MixProject do The PostgreSQL data layer for Ash Framework """ - @version "2.6.15" + @version "2.6.16" def project do [ From ed22f3e699e30069a3048f5f2566d1bd45055805 Mon Sep 17 00:00:00 2001 From: Zach Daniel Date: Sat, 23 Aug 2025 10:37:21 -0400 Subject: [PATCH 109/174] chore: rename migration file --- ...e_resources57.exs => 20250810102512_migrate_resources58.exs} | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename priv/test_repo/migrations/{20250810102512_migrate_resources57.exs => 20250810102512_migrate_resources58.exs} (95%) diff --git a/priv/test_repo/migrations/20250810102512_migrate_resources57.exs b/priv/test_repo/migrations/20250810102512_migrate_resources58.exs similarity index 95% rename from priv/test_repo/migrations/20250810102512_migrate_resources57.exs rename to priv/test_repo/migrations/20250810102512_migrate_resources58.exs index 1eb6911a..484e4dc0 100644 --- a/priv/test_repo/migrations/20250810102512_migrate_resources57.exs +++ b/priv/test_repo/migrations/20250810102512_migrate_resources58.exs @@ -1,4 +1,4 @@ -defmodule AshPostgres.TestRepo.Migrations.MigrateResources57 do +defmodule AshPostgres.TestRepo.Migrations.MigrateResources58 do @moduledoc """ Updates resources based on their most recent snapshots. From ad0fd663a9e3de091ef1622907c9ae1e7c557014 Mon Sep 17 00:00:00 2001 From: Sheharyar Naseer Date: Mon, 25 Aug 2025 07:06:05 -0600 Subject: [PATCH 110/174] fix: resolve a typo in pending dev migration error message (#608) --- lib/migration_generator/migration_generator.ex | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/migration_generator/migration_generator.ex b/lib/migration_generator/migration_generator.ex index 74e0611d..86920ed4 100644 --- a/lib/migration_generator/migration_generator.ex +++ b/lib/migration_generator/migration_generator.ex @@ -460,8 +460,8 @@ defmodule AshPostgres.MigrationGenerator do You have migrations remaining that were generated with the --dev flag. - Run `mix ash.codegen ` to remove the dev migraitons and replace them - with production ready migrations. + Run `mix ash.codegen ` to remove the dev migrations and replace them + with production-ready migrations. """) exit({:shutdown, 1}) From 22ab05e0b2d56600dbe72dda12a2f1402d48b9a4 Mon Sep 17 00:00:00 2001 From: Zach Daniel Date: Sun, 31 Aug 2025 11:48:45 -0400 Subject: [PATCH 111/174] chore: release version v2.6.17 --- CHANGELOG.md | 9 +++++++++ mix.exs | 2 +- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7df2c49a..08169773 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,15 @@ See [Conventional Commits](https://www.conventionalcommits.org) for commit guide +## [v2.6.17](https://github.com/ash-project/ash_postgres/compare/v2.6.16...v2.6.17) (2025-08-31) + + + + +### Bug Fixes: + +* resolve a typo in pending dev migration error message (#608) by Sheharyar Naseer + ## [v2.6.16](https://github.com/ash-project/ash_postgres/compare/v2.6.15...v2.6.16) (2025-08-21) diff --git a/mix.exs b/mix.exs index 2d3f04b1..3e8719c1 100644 --- a/mix.exs +++ b/mix.exs @@ -5,7 +5,7 @@ defmodule AshPostgres.MixProject do The PostgreSQL data layer for Ash Framework """ - @version "2.6.16" + @version "2.6.17" def project do [ From ff3402e759faae5364e37ad855a0f06a1778c304 Mon Sep 17 00:00:00 2001 From: Rodolfo Torres Date: Sun, 31 Aug 2025 16:46:44 -0400 Subject: [PATCH 112/174] test: test for default sort referencing parent field in many_to_many relationship with no_attributes? true (#607) --- test/parent_sort_test.ex | 32 ++++++++++++++++++++++++++++++++ test/support/resources/post.ex | 6 ++++++ 2 files changed, 38 insertions(+) create mode 100644 test/parent_sort_test.ex diff --git a/test/parent_sort_test.ex b/test/parent_sort_test.ex new file mode 100644 index 00000000..e4647672 --- /dev/null +++ b/test/parent_sort_test.ex @@ -0,0 +1,32 @@ +defmodule AshPostgres.Test.ParentSortTest do + use AshPostgres.RepoCase, async: false + + alias AshPostgres.Test.{Organization, Post, User} + + require Ash.Query + + test "can reference parent field when declaring default sort in has_many no_attributes? relationship" do + organization = + Organization + |> Ash.Changeset.for_create(:create, %{name: "test_org"}) + |> Ash.create!() + + user = + User + |> Ash.Changeset.for_create(:create, %{organization_id: organization.id, name: "foo bar"}) + |> Ash.create!() + + Post + |> Ash.Changeset.for_create(:create, %{organization_id: organization.id}) + |> Ash.create!() + + Post + |> Ash.Changeset.for_create(:create, %{organization_id: organization.id, title: "test_org"}) + |> Ash.create!() + + assert {:ok, _} = + Post + |> Ash.Query.load(:recommendations) + |> Ash.read(authorize?: false) + end +end diff --git a/test/support/resources/post.ex b/test/support/resources/post.ex index 1f90535c..0441dda9 100644 --- a/test/support/resources/post.ex +++ b/test/support/resources/post.ex @@ -614,6 +614,12 @@ defmodule AshPostgres.Test.Post do filter(expr(fragment("? = ?", title, parent(organization.name)))) end + has_many(:recommendations, __MODULE__) do + public?(true) + no_attributes?(true) + sort([calc(fragment("abs(extract epoch from ?))", parent(datetime) - datetime))]) + end + belongs_to :parent_post, __MODULE__ do public?(true) end From 7d53f476b9af782bd88cedf76b74cc7cb5d50ca9 Mon Sep 17 00:00:00 2001 From: Rodolfo Torres Date: Mon, 1 Sep 2025 08:07:07 -0400 Subject: [PATCH 113/174] rename test file so it matches pattern (#609) --- test/{parent_sort_test.ex => parent_sort_test.exs} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename test/{parent_sort_test.ex => parent_sort_test.exs} (100%) diff --git a/test/parent_sort_test.ex b/test/parent_sort_test.exs similarity index 100% rename from test/parent_sort_test.ex rename to test/parent_sort_test.exs From 1948f80b2a982f19981c599a953d311d8a483e4d Mon Sep 17 00:00:00 2001 From: Zach Daniel Date: Thu, 4 Sep 2025 21:46:51 -0400 Subject: [PATCH 114/174] fix: annotate unrelated exists expressions as supported --- lib/data_layer.ex | 1 + test/unrelated_aggregates_test.exs | 17 +++++++++++++++++ 2 files changed, 18 insertions(+) diff --git a/lib/data_layer.ex b/lib/data_layer.ex index 3fa1aa30..27b88dd1 100644 --- a/lib/data_layer.ex +++ b/lib/data_layer.ex @@ -722,6 +722,7 @@ defmodule AshPostgres.DataLayer do do: true def can?(_, {:aggregate, :unrelated}), do: true + def can?(_, {:exists, :unrelated}), do: true def can?(_, :aggregate_filter), do: true def can?(_, :aggregate_sort), do: true def can?(_, :calculate), do: true diff --git a/test/unrelated_aggregates_test.exs b/test/unrelated_aggregates_test.exs index 09a15740..0ec55535 100644 --- a/test/unrelated_aggregates_test.exs +++ b/test/unrelated_aggregates_test.exs @@ -503,5 +503,22 @@ defmodule AshPostgres.Test.UnrelatedAggregatesTest do assert loaded_user.aggregates.bio_mentions_name == 2 end + + test "unrelated exists expressions work with parent() reference" do + {:ok, user1} = Ash.create(User, %{name: "ExistsTest", email: "exists@example.com"}) + {:ok, user2} = Ash.create(User, %{name: "NoMatch", email: "nomatch@example.com"}) + + {:ok, _profile} = Ash.create(Profile, %{name: "ExistsTest", age: 25, active: true}) + + # Check if any profile exists with the same name using unrelated exists + users_with_matching_profiles = + User + |> Ash.Query.filter(exists(Profile, name == parent(name))) + |> Ash.read!() + + user_ids = Enum.map(users_with_matching_profiles, & &1.id) + assert user1.id in user_ids + refute user2.id in user_ids + end end end From 36213e4e00631a5911b9bfcd6acfd558d0fc5cbf Mon Sep 17 00:00:00 2001 From: Zach Daniel Date: Sun, 7 Sep 2025 01:15:27 +0200 Subject: [PATCH 115/174] fix: properly handle sorts w/ parent refs on lateral joins --- lib/data_layer.ex | 11 +++++++---- test/parent_sort_test.exs | 15 +++++++-------- test/support/resources/post.ex | 2 +- 3 files changed, 15 insertions(+), 13 deletions(-) diff --git a/lib/data_layer.ex b/lib/data_layer.ex index 27b88dd1..e4cde133 100644 --- a/lib/data_layer.ex +++ b/lib/data_layer.ex @@ -1185,7 +1185,7 @@ defmodule AshPostgres.DataLayer do if query.__ash_bindings__[:__order__?] do {:ok, from(source in data_layer_query, - inner_lateral_join: destination in ^subquery, + inner_lateral_join: destination in subquery(get_subquery(subquery)), on: true, order_by: destination.__order__, select: merge(destination, %{__lateral_join_source__: map(source, ^source_pkey)}), @@ -1194,7 +1194,7 @@ defmodule AshPostgres.DataLayer do else {:ok, from(source in data_layer_query, - inner_lateral_join: destination in ^subquery, + inner_lateral_join: destination in subquery(get_subquery(subquery)), on: true, select: merge(destination, %{__lateral_join_source__: map(source, ^source_pkey)}), distinct: true @@ -1286,7 +1286,7 @@ defmodule AshPostgres.DataLayer do {:ok, from(source in data_layer_query, where: field(source, ^source_attribute) in ^source_values, - inner_lateral_join: destination in ^subquery, + inner_lateral_join: destination in subquery(get_subquery(subquery)), on: true, select: destination, select_merge: %{__lateral_join_source__: map(source, ^source_pkey)}, @@ -1321,7 +1321,7 @@ defmodule AshPostgres.DataLayer do {:ok, from(source in data_layer_query, where: field(source, ^source_attribute) in ^source_values, - inner_lateral_join: destination in ^subquery, + inner_lateral_join: destination in subquery(get_subquery(subquery)), on: true, select: destination, select_merge: %{__lateral_join_source__: map(source, ^source_pkey)}, @@ -1434,6 +1434,9 @@ defmodule AshPostgres.DataLayer do Ash.Query.do_filter(query, expr) end + defp get_subquery(%Ecto.Query{} = query), do: query + defp get_subquery(%Ecto.SubQuery{query: query}), do: query + @doc false def set_subquery_prefix(data_layer_query, source_query, resource) do repo = AshPostgres.DataLayer.Info.repo(resource, :mutate) diff --git a/test/parent_sort_test.exs b/test/parent_sort_test.exs index e4647672..423d6634 100644 --- a/test/parent_sort_test.exs +++ b/test/parent_sort_test.exs @@ -11,10 +11,9 @@ defmodule AshPostgres.Test.ParentSortTest do |> Ash.Changeset.for_create(:create, %{name: "test_org"}) |> Ash.create!() - user = - User - |> Ash.Changeset.for_create(:create, %{organization_id: organization.id, name: "foo bar"}) - |> Ash.create!() + User + |> Ash.Changeset.for_create(:create, %{organization_id: organization.id, name: "foo bar"}) + |> Ash.create!() Post |> Ash.Changeset.for_create(:create, %{organization_id: organization.id}) @@ -24,9 +23,9 @@ defmodule AshPostgres.Test.ParentSortTest do |> Ash.Changeset.for_create(:create, %{organization_id: organization.id, title: "test_org"}) |> Ash.create!() - assert {:ok, _} = - Post - |> Ash.Query.load(:recommendations) - |> Ash.read(authorize?: false) + # just asserting it doesn't errror + Post + |> Ash.Query.load(:recommendations) + |> Ash.read!(authorize?: false) end end diff --git a/test/support/resources/post.ex b/test/support/resources/post.ex index 0441dda9..dfba5a06 100644 --- a/test/support/resources/post.ex +++ b/test/support/resources/post.ex @@ -617,7 +617,7 @@ defmodule AshPostgres.Test.Post do has_many(:recommendations, __MODULE__) do public?(true) no_attributes?(true) - sort([calc(fragment("abs(extract epoch from ?))", parent(datetime) - datetime))]) + sort([calc(parent(datetime) > now())]) end belongs_to :parent_post, __MODULE__ do From 6f97884ec6930c79441f05afb4fa3a18959402d7 Mon Sep 17 00:00:00 2001 From: kernel-io Date: Mon, 8 Sep 2025 21:42:13 +1200 Subject: [PATCH 116/174] test: add failing tests for loads not getting added automatically in certain situations (#612) --- test/parent_filter_test.exs | 29 ++++++++++++++++++++++++++++- test/support/resources/post.ex | 10 ++++++++++ 2 files changed, 38 insertions(+), 1 deletion(-) diff --git a/test/parent_filter_test.exs b/test/parent_filter_test.exs index fefbde24..78d295fe 100644 --- a/test/parent_filter_test.exs +++ b/test/parent_filter_test.exs @@ -1,7 +1,7 @@ defmodule AshPostgres.Test.ParentFilterTest do use AshPostgres.RepoCase, async: false - alias AshPostgres.Test.{Organization, Post, User} + alias AshPostgres.Test.{Organization, Post, User, Comment} require Ash.Query @@ -44,4 +44,31 @@ defmodule AshPostgres.Test.ParentFilterTest do ) |> Ash.read(authorize?: false) end + + test "something else" do + organization = + Organization + |> Ash.Changeset.for_create(:create, %{name: "test_org"}) + |> Ash.create!() + + post_in_my_org = + Post + |> Ash.Changeset.for_create(:create, %{organization_id: organization.id, title: "test_org"}) + |> Ash.create!() + + Comment + |> Ash.Changeset.for_create(:create, %{title: "test_org"}) + |> Ash.Changeset.manage_relationship(:post, post_in_my_org, type: :append_and_remove) + |> Ash.create!() + + assert {:ok, _} = + Post + |> Ash.Query.for_read(:read) + |> Ash.Query.filter( + organizations_with_posts_that_have_the_post_title_somewhere_in_their_comments.name in [ + ^organization.name + ] + ) + |> Ash.read(authorize?: false) + end end diff --git a/test/support/resources/post.ex b/test/support/resources/post.ex index dfba5a06..e6009d57 100644 --- a/test/support/resources/post.ex +++ b/test/support/resources/post.ex @@ -614,6 +614,14 @@ defmodule AshPostgres.Test.Post do filter(expr(fragment("? = ?", title, parent(organization.name)))) end + has_many( + :organizations_with_posts_that_have_the_post_title_somewhere_in_their_comments, + AshPostgres.Test.Organization + ) do + no_attributes?(true) + filter(expr(fragment("POSITION(? IN ?) > 0", posts.title, parent(concated_comment_titles)))) + end + has_many(:recommendations, __MODULE__) do public?(true) no_attributes?(true) @@ -1020,6 +1028,8 @@ defmodule AshPostgres.Test.Post do calculate(:author_profile_description_from_agg, :string, expr(author_profile_description)) calculate(:latest_comment_title, :string, expr(latest_comment.title), allow_nil?: true) + + calculate(:concated_comment_titles, :string, expr(fragment("concat(?)", comment_titles))) end aggregates do From 89622eb6fef805278eb76724531fceea0dbe90e3 Mon Sep 17 00:00:00 2001 From: Zach Daniel Date: Mon, 8 Sep 2025 11:43:37 +0200 Subject: [PATCH 117/174] test: add tests of distinct/sort issues --- .../test_repo/chats/20250908093505.json | 43 ++++++++ .../test_repo/customers/20250908073737.json | 43 ++++++++ .../test_repo/messages/20250908093505.json | 98 +++++++++++++++++++ .../test_repo/orders/20250908073737.json | 93 ++++++++++++++++++ .../test_repo/products/20250908073737.json | 43 ++++++++ .../20250908073737_migrate_resources59.exs | 73 ++++++++++++++ .../20250908093505_migrate_resources60.exs | 55 +++++++++++ test/distinct_test.exs | 28 +++++- test/sort_test.exs | 54 +++++++++- test/support/domain.ex | 5 + test/support/resources/chat.ex | 40 ++++++++ test/support/resources/customer.ex | 35 +++++++ test/support/resources/message.ex | 30 ++++++ test/support/resources/order.ex | 32 ++++++ test/support/resources/product.ex | 33 +++++++ 15 files changed, 703 insertions(+), 2 deletions(-) create mode 100644 priv/resource_snapshots/test_repo/chats/20250908093505.json create mode 100644 priv/resource_snapshots/test_repo/customers/20250908073737.json create mode 100644 priv/resource_snapshots/test_repo/messages/20250908093505.json create mode 100644 priv/resource_snapshots/test_repo/orders/20250908073737.json create mode 100644 priv/resource_snapshots/test_repo/products/20250908073737.json create mode 100644 priv/test_repo/migrations/20250908073737_migrate_resources59.exs create mode 100644 priv/test_repo/migrations/20250908093505_migrate_resources60.exs create mode 100644 test/support/resources/chat.ex create mode 100644 test/support/resources/customer.ex create mode 100644 test/support/resources/message.ex create mode 100644 test/support/resources/order.ex create mode 100644 test/support/resources/product.ex diff --git a/priv/resource_snapshots/test_repo/chats/20250908093505.json b/priv/resource_snapshots/test_repo/chats/20250908093505.json new file mode 100644 index 00000000..aa5ea757 --- /dev/null +++ b/priv/resource_snapshots/test_repo/chats/20250908093505.json @@ -0,0 +1,43 @@ +{ + "attributes": [ + { + "allow_nil?": false, + "default": "fragment(\"gen_random_uuid()\")", + "generated?": false, + "precision": null, + "primary_key?": true, + "references": null, + "scale": null, + "size": null, + "source": "id", + "type": "uuid" + }, + { + "allow_nil?": true, + "default": "nil", + "generated?": false, + "precision": null, + "primary_key?": false, + "references": null, + "scale": null, + "size": null, + "source": "name", + "type": "text" + } + ], + "base_filter": null, + "check_constraints": [], + "custom_indexes": [], + "custom_statements": [], + "has_create_action": true, + "hash": "E200EA8628A3CC9B29EF3921CA5E72F3819E7E4CBA4B64E2E0684A2F45F9E873", + "identities": [], + "multitenancy": { + "attribute": null, + "global": null, + "strategy": null + }, + "repo": "Elixir.AshPostgres.TestRepo", + "schema": null, + "table": "chats" +} \ No newline at end of file diff --git a/priv/resource_snapshots/test_repo/customers/20250908073737.json b/priv/resource_snapshots/test_repo/customers/20250908073737.json new file mode 100644 index 00000000..28f93ea2 --- /dev/null +++ b/priv/resource_snapshots/test_repo/customers/20250908073737.json @@ -0,0 +1,43 @@ +{ + "attributes": [ + { + "allow_nil?": false, + "default": "fragment(\"gen_random_uuid()\")", + "generated?": false, + "precision": null, + "primary_key?": true, + "references": null, + "scale": null, + "size": null, + "source": "id", + "type": "uuid" + }, + { + "allow_nil?": true, + "default": "nil", + "generated?": false, + "precision": null, + "primary_key?": false, + "references": null, + "scale": null, + "size": null, + "source": "name", + "type": "text" + } + ], + "base_filter": null, + "check_constraints": [], + "custom_indexes": [], + "custom_statements": [], + "has_create_action": true, + "hash": "93AF0132FAB23B3B438FD526411F0C9E504C80F803322B5ABCDFFA8B3103B762", + "identities": [], + "multitenancy": { + "attribute": null, + "global": null, + "strategy": null + }, + "repo": "Elixir.AshPostgres.TestRepo", + "schema": null, + "table": "customers" +} \ No newline at end of file diff --git a/priv/resource_snapshots/test_repo/messages/20250908093505.json b/priv/resource_snapshots/test_repo/messages/20250908093505.json new file mode 100644 index 00000000..abe62ca8 --- /dev/null +++ b/priv/resource_snapshots/test_repo/messages/20250908093505.json @@ -0,0 +1,98 @@ +{ + "attributes": [ + { + "allow_nil?": false, + "default": "fragment(\"gen_random_uuid()\")", + "generated?": false, + "precision": null, + "primary_key?": true, + "references": null, + "scale": null, + "size": null, + "source": "id", + "type": "uuid" + }, + { + "allow_nil?": true, + "default": "nil", + "generated?": false, + "precision": null, + "primary_key?": false, + "references": null, + "scale": null, + "size": null, + "source": "content", + "type": "text" + }, + { + "allow_nil?": true, + "default": "fragment(\"(now() AT TIME ZONE 'utc')\")", + "generated?": false, + "precision": null, + "primary_key?": false, + "references": null, + "scale": null, + "size": null, + "source": "sent_at", + "type": "utc_datetime" + }, + { + "allow_nil?": true, + "default": "nil", + "generated?": false, + "precision": null, + "primary_key?": false, + "references": null, + "scale": null, + "size": null, + "source": "read_at", + "type": "utc_datetime" + }, + { + "allow_nil?": false, + "default": "nil", + "generated?": false, + "precision": null, + "primary_key?": false, + "references": { + "deferrable": false, + "destination_attribute": "id", + "destination_attribute_default": null, + "destination_attribute_generated": null, + "index?": false, + "match_type": null, + "match_with": null, + "multitenancy": { + "attribute": null, + "global": null, + "strategy": null + }, + "name": "messages_chat_id_fkey", + "on_delete": null, + "on_update": null, + "primary_key?": true, + "schema": "public", + "table": "chats" + }, + "scale": null, + "size": null, + "source": "chat_id", + "type": "uuid" + } + ], + "base_filter": null, + "check_constraints": [], + "custom_indexes": [], + "custom_statements": [], + "has_create_action": true, + "hash": "97C85779868973EAB5363B16FCE9562DBAD347062547341855A08557B127FD7E", + "identities": [], + "multitenancy": { + "attribute": null, + "global": null, + "strategy": null + }, + "repo": "Elixir.AshPostgres.TestRepo", + "schema": null, + "table": "messages" +} \ No newline at end of file diff --git a/priv/resource_snapshots/test_repo/orders/20250908073737.json b/priv/resource_snapshots/test_repo/orders/20250908073737.json new file mode 100644 index 00000000..104128a4 --- /dev/null +++ b/priv/resource_snapshots/test_repo/orders/20250908073737.json @@ -0,0 +1,93 @@ +{ + "attributes": [ + { + "allow_nil?": false, + "default": "fragment(\"gen_random_uuid()\")", + "generated?": false, + "precision": null, + "primary_key?": true, + "references": null, + "scale": null, + "size": null, + "source": "id", + "type": "uuid" + }, + { + "allow_nil?": false, + "default": "nil", + "generated?": false, + "precision": null, + "primary_key?": false, + "references": { + "deferrable": false, + "destination_attribute": "id", + "destination_attribute_default": null, + "destination_attribute_generated": null, + "index?": false, + "match_type": null, + "match_with": null, + "multitenancy": { + "attribute": null, + "global": null, + "strategy": null + }, + "name": "orders_customer_id_fkey", + "on_delete": null, + "on_update": null, + "primary_key?": true, + "schema": "public", + "table": "customers" + }, + "scale": null, + "size": null, + "source": "customer_id", + "type": "uuid" + }, + { + "allow_nil?": false, + "default": "nil", + "generated?": false, + "precision": null, + "primary_key?": false, + "references": { + "deferrable": false, + "destination_attribute": "id", + "destination_attribute_default": null, + "destination_attribute_generated": null, + "index?": false, + "match_type": null, + "match_with": null, + "multitenancy": { + "attribute": null, + "global": null, + "strategy": null + }, + "name": "orders_product_id_fkey", + "on_delete": null, + "on_update": null, + "primary_key?": true, + "schema": "public", + "table": "products" + }, + "scale": null, + "size": null, + "source": "product_id", + "type": "uuid" + } + ], + "base_filter": null, + "check_constraints": [], + "custom_indexes": [], + "custom_statements": [], + "has_create_action": true, + "hash": "BDB105B45D28F7BB79E6AC102805F748C15EB6B19B7FFC6D166E71CD40F60B15", + "identities": [], + "multitenancy": { + "attribute": null, + "global": null, + "strategy": null + }, + "repo": "Elixir.AshPostgres.TestRepo", + "schema": null, + "table": "orders" +} \ No newline at end of file diff --git a/priv/resource_snapshots/test_repo/products/20250908073737.json b/priv/resource_snapshots/test_repo/products/20250908073737.json new file mode 100644 index 00000000..1b787e4f --- /dev/null +++ b/priv/resource_snapshots/test_repo/products/20250908073737.json @@ -0,0 +1,43 @@ +{ + "attributes": [ + { + "allow_nil?": false, + "default": "fragment(\"gen_random_uuid()\")", + "generated?": false, + "precision": null, + "primary_key?": true, + "references": null, + "scale": null, + "size": null, + "source": "id", + "type": "uuid" + }, + { + "allow_nil?": true, + "default": "nil", + "generated?": false, + "precision": null, + "primary_key?": false, + "references": null, + "scale": null, + "size": null, + "source": "name", + "type": "text" + } + ], + "base_filter": null, + "check_constraints": [], + "custom_indexes": [], + "custom_statements": [], + "has_create_action": true, + "hash": "F8C4228D8DCC1DADD126675744C0BEE52107FADA5135A2E603A26F5F115709DC", + "identities": [], + "multitenancy": { + "attribute": null, + "global": null, + "strategy": null + }, + "repo": "Elixir.AshPostgres.TestRepo", + "schema": null, + "table": "products" +} \ No newline at end of file diff --git a/priv/test_repo/migrations/20250908073737_migrate_resources59.exs b/priv/test_repo/migrations/20250908073737_migrate_resources59.exs new file mode 100644 index 00000000..a4acd79a --- /dev/null +++ b/priv/test_repo/migrations/20250908073737_migrate_resources59.exs @@ -0,0 +1,73 @@ +defmodule AshPostgres.TestRepo.Migrations.MigrateResources59 do + @moduledoc """ + Updates resources based on their most recent snapshots. + + This file was autogenerated with `mix ash_postgres.generate_migrations` + """ + + use Ecto.Migration + + def up do + create table(:products, primary_key: false) do + add(:id, :uuid, null: false, default: fragment("gen_random_uuid()"), primary_key: true) + add(:name, :text) + end + + create table(:orders, primary_key: false) do + add(:id, :uuid, null: false, default: fragment("gen_random_uuid()"), primary_key: true) + add(:customer_id, :uuid, null: false) + add(:product_id, :uuid, null: false) + end + + create table(:customers, primary_key: false) do + add(:id, :uuid, null: false, default: fragment("gen_random_uuid()"), primary_key: true) + end + + alter table(:orders) do + modify( + :customer_id, + references(:customers, + column: :id, + name: "orders_customer_id_fkey", + type: :uuid, + prefix: "public" + ) + ) + + modify( + :product_id, + references(:products, + column: :id, + name: "orders_product_id_fkey", + type: :uuid, + prefix: "public" + ) + ) + end + + alter table(:customers) do + add(:name, :text) + end + end + + def down do + alter table(:customers) do + remove(:name) + end + + drop(constraint(:orders, "orders_customer_id_fkey")) + + drop(constraint(:orders, "orders_product_id_fkey")) + + alter table(:orders) do + modify(:product_id, :uuid) + modify(:customer_id, :uuid) + end + + drop(table(:customers)) + + drop(table(:orders)) + + drop(table(:products)) + end +end diff --git a/priv/test_repo/migrations/20250908093505_migrate_resources60.exs b/priv/test_repo/migrations/20250908093505_migrate_resources60.exs new file mode 100644 index 00000000..404906e5 --- /dev/null +++ b/priv/test_repo/migrations/20250908093505_migrate_resources60.exs @@ -0,0 +1,55 @@ +defmodule AshPostgres.TestRepo.Migrations.MigrateResources60 do + @moduledoc """ + Updates resources based on their most recent snapshots. + + This file was autogenerated with `mix ash_postgres.generate_migrations` + """ + + use Ecto.Migration + + def up do + create table(:messages, primary_key: false) do + add(:id, :uuid, null: false, default: fragment("gen_random_uuid()"), primary_key: true) + add(:content, :text) + add(:sent_at, :utc_datetime, default: fragment("(now() AT TIME ZONE 'utc')")) + add(:read_at, :utc_datetime) + add(:chat_id, :uuid, null: false) + end + + create table(:chats, primary_key: false) do + add(:id, :uuid, null: false, default: fragment("gen_random_uuid()"), primary_key: true) + end + + alter table(:messages) do + modify( + :chat_id, + references(:chats, + column: :id, + name: "messages_chat_id_fkey", + type: :uuid, + prefix: "public" + ) + ) + end + + alter table(:chats) do + add(:name, :text) + end + end + + def down do + alter table(:chats) do + remove(:name) + end + + drop(constraint(:messages, "messages_chat_id_fkey")) + + alter table(:messages) do + modify(:chat_id, :uuid) + end + + drop(table(:chats)) + + drop(table(:messages)) + end +end diff --git a/test/distinct_test.exs b/test/distinct_test.exs index bbc9a1c6..452f0068 100644 --- a/test/distinct_test.exs +++ b/test/distinct_test.exs @@ -1,7 +1,7 @@ defmodule AshPostgres.DistinctTest do @moduledoc false use AshPostgres.RepoCase, async: false - alias AshPostgres.Test.Post + alias AshPostgres.Test.{Customer, Post, Product, Order} require Ash.Query @@ -177,4 +177,30 @@ defmodule AshPostgres.DistinctTest do assert [_, _] = results end + + test "distinct breaks with prepare build(sort: [:id]) - original issue reproduction" do + + customer = + Customer + |> Ash.Changeset.for_create(:create, %{name: "Test Customer"}) + |> Ash.create!() + + product = + Product + |> Ash.Changeset.for_create(:create, %{name: "Test Product"}) + |> Ash.create!() + + Order + |> Ash.Changeset.for_create(:create, %{customer_id: customer.id, product_id: product.id}) + |> Ash.create!() + + Order + |> Ash.Changeset.for_create(:create, %{customer_id: customer.id, product_id: product.id}) + |> Ash.create!() + + customer_with_products = Ash.load!(customer, :purchased_products) + purchased_products = customer_with_products.purchased_products + + assert length(purchased_products) == 1, "Expected 1 unique product, got #{length(purchased_products)} products. This indicates the distinct + sort preparation bug." + end end diff --git a/test/sort_test.exs b/test/sort_test.exs index cd5deddb..6be3113d 100644 --- a/test/sort_test.exs +++ b/test/sort_test.exs @@ -1,10 +1,11 @@ defmodule AshPostgres.SortTest do @moduledoc false use AshPostgres.RepoCase, async: false - alias AshPostgres.Test.{Comment, Post, PostLink, PostTag, PostView, Tag} + alias AshPostgres.Test.{Chat, Comment, Message, Post, PostLink, PostTag, PostView, Tag} require Ash.Query require Ash.Sort + import Ash.Expr test "multi-column sorts work" do Post @@ -289,4 +290,55 @@ defmodule AshPostgres.SortTest do assert DateTime.to_date(latest_post.created_at) == expected_date end + + describe "sorting by multiple has_one relationships" do + test "sorting by single calculated field through has_one relationship works" do + chat = Ash.create!(Chat, %{name: "Test Chat"}) + + # Create some messages + Ash.create!(Message, %{chat_id: chat.id, content: "First", sent_at: ~U[2025-01-01 10:00:00Z]}) + Ash.create!(Message, %{chat_id: chat.id, content: "Second", sent_at: ~U[2025-01-02 10:00:00Z], read_at: ~U[2025-01-02 11:00:00Z]}) + Ash.create!(Message, %{chat_id: chat.id, content: "Third", sent_at: ~U[2025-01-03 10:00:00Z]}) + + # This should work - sorting by single has_one relationship calculation + result = + Chat + |> Ash.Query.sort([{Ash.Sort.expr_sort(expr(last_unread_message.sent_at)), :desc}]) + |> Ash.read!() + + assert [%Chat{}] = result + end + + test "sorting by different single calculated field through has_one relationship works" do + chat = Ash.create!(Chat, %{name: "Test Chat"}) + + # Create some messages + Ash.create!(Message, %{chat_id: chat.id, content: "First", sent_at: ~U[2025-01-01 10:00:00Z]}) + Ash.create!(Message, %{chat_id: chat.id, content: "Second", sent_at: ~U[2025-01-02 10:00:00Z], read_at: ~U[2025-01-02 11:00:00Z]}) + + # This should work - sorting by different single has_one relationship calculation + result = + Chat + |> Ash.Query.sort([{Ash.Sort.expr_sort(expr(last_message.read_at)), :desc}]) + |> Ash.read!() + + assert [%Chat{}] = result + end + + test "sorting by multiple calculated fields through different has_one relationships fails" do + chat = Ash.create!(Chat, %{name: "Test Chat"}) + + # Create some messages + Ash.create!(Message, %{chat_id: chat.id, content: "First", sent_at: ~U[2025-01-01 10:00:00Z]}) + Ash.create!(Message, %{chat_id: chat.id, content: "Second", sent_at: ~U[2025-01-02 10:00:00Z], read_at: ~U[2025-01-02 11:00:00Z]}) + Ash.create!(Message, %{chat_id: chat.id, content: "Third", sent_at: ~U[2025-01-03 10:00:00Z]}) + + Chat + |> Ash.Query.sort([ + {Ash.Sort.expr_sort(expr(last_unread_message.sent_at)), :desc}, + {Ash.Sort.expr_sort(expr(last_message.read_at)), :desc} + ]) + |> Ash.read!() + end + end end diff --git a/test/support/domain.ex b/test/support/domain.ex index 58802a18..2bf55a0b 100644 --- a/test/support/domain.ex +++ b/test/support/domain.ex @@ -48,6 +48,11 @@ defmodule AshPostgres.Test.Domain do resource(AshPostgres.Test.UnrelatedAggregatesTest.SecureProfile) resource(AshPostgres.Test.UnrelatedAggregatesTest.Report) resource(AshPostgres.Test.UnrelatedAggregatesTest.User) + resource(AshPostgres.Test.Customer) + resource(AshPostgres.Test.Product) + resource(AshPostgres.Test.Order) + resource(AshPostgres.Test.Chat) + resource(AshPostgres.Test.Message) end authorization do diff --git a/test/support/resources/chat.ex b/test/support/resources/chat.ex new file mode 100644 index 00000000..853c3c17 --- /dev/null +++ b/test/support/resources/chat.ex @@ -0,0 +1,40 @@ +defmodule AshPostgres.Test.Chat do + @moduledoc false + use Ash.Resource, + domain: AshPostgres.Test.Domain, + data_layer: AshPostgres.DataLayer + + postgres do + table("chats") + repo(AshPostgres.TestRepo) + end + + actions do + default_accept(:*) + defaults([:create, :read, :destroy, :update]) + end + + attributes do + uuid_primary_key(:id, writable?: true) + attribute(:name, :string, public?: true) + end + + relationships do + has_many :messages, AshPostgres.Test.Message do + public?(true) + end + + has_one :last_message, AshPostgres.Test.Message do + public?(true) + from_many?(true) + sort(sent_at: :desc) + end + + has_one :last_unread_message, AshPostgres.Test.Message do + public?(true) + from_many?(true) + filter(expr(is_nil(read_at))) + sort(sent_at: :desc) + end + end +end \ No newline at end of file diff --git a/test/support/resources/customer.ex b/test/support/resources/customer.ex new file mode 100644 index 00000000..2bd94105 --- /dev/null +++ b/test/support/resources/customer.ex @@ -0,0 +1,35 @@ +defmodule AshPostgres.Test.Customer do + @moduledoc false + use Ash.Resource, + domain: AshPostgres.Test.Domain, + data_layer: AshPostgres.DataLayer + + postgres do + table("customers") + repo(AshPostgres.TestRepo) + end + + actions do + default_accept(:*) + defaults([:create, :read, :destroy, :update]) + end + + attributes do + uuid_primary_key(:id, writable?: true) + attribute(:name, :string, public?: true) + end + + relationships do + has_many :orders, AshPostgres.Test.Order do + public?(true) + end + + # This relationship reproduces the bug described in: + # https://github.com/ash-project/ash_sql/issues/172#issuecomment-3264660128 + has_many :purchased_products, AshPostgres.Test.Product do + public?(true) + no_attributes?(true) + filter(expr(orders.customer_id == parent(id))) + end + end +end \ No newline at end of file diff --git a/test/support/resources/message.ex b/test/support/resources/message.ex new file mode 100644 index 00000000..6e0a2ded --- /dev/null +++ b/test/support/resources/message.ex @@ -0,0 +1,30 @@ +defmodule AshPostgres.Test.Message do + @moduledoc false + use Ash.Resource, + domain: AshPostgres.Test.Domain, + data_layer: AshPostgres.DataLayer + + postgres do + table("messages") + repo(AshPostgres.TestRepo) + end + + actions do + default_accept(:*) + defaults([:create, :read, :destroy, :update]) + end + + attributes do + uuid_primary_key(:id, writable?: true) + attribute(:content, :string, public?: true) + attribute(:sent_at, :utc_datetime, default: &DateTime.utc_now/0, public?: true) + attribute(:read_at, :utc_datetime, public?: true) + end + + relationships do + belongs_to :chat, AshPostgres.Test.Chat do + public?(true) + allow_nil?(false) + end + end +end \ No newline at end of file diff --git a/test/support/resources/order.ex b/test/support/resources/order.ex new file mode 100644 index 00000000..83c6751a --- /dev/null +++ b/test/support/resources/order.ex @@ -0,0 +1,32 @@ +defmodule AshPostgres.Test.Order do + @moduledoc false + use Ash.Resource, + domain: AshPostgres.Test.Domain, + data_layer: AshPostgres.DataLayer + + postgres do + table("orders") + repo(AshPostgres.TestRepo) + end + + actions do + default_accept(:*) + defaults([:create, :read, :destroy, :update]) + end + + attributes do + uuid_primary_key(:id, writable?: true) + end + + relationships do + belongs_to :customer, AshPostgres.Test.Customer do + public?(true) + allow_nil?(false) + end + + belongs_to :product, AshPostgres.Test.Product do + public?(true) + allow_nil?(false) + end + end +end \ No newline at end of file diff --git a/test/support/resources/product.ex b/test/support/resources/product.ex new file mode 100644 index 00000000..0ddb9169 --- /dev/null +++ b/test/support/resources/product.ex @@ -0,0 +1,33 @@ +defmodule AshPostgres.Test.Product do + @moduledoc false + use Ash.Resource, + domain: AshPostgres.Test.Domain, + data_layer: AshPostgres.DataLayer + + postgres do + table("products") + repo(AshPostgres.TestRepo) + end + + actions do + default_accept(:*) + defaults([:create, :read, :destroy, :update]) + end + + # This preparation reproduces the bug described in: + # https://github.com/ash-project/ash_sql/issues/172#issuecomment-3264660128 + preparations do + prepare build(sort: [:id]) + end + + attributes do + uuid_primary_key(:id, writable?: true) + attribute(:name, :string, public?: true) + end + + relationships do + has_many :orders, AshPostgres.Test.Order do + public?(true) + end + end +end \ No newline at end of file From 108dd845a49297b00dfd39c3260554ab565aafe5 Mon Sep 17 00:00:00 2001 From: Zach Daniel Date: Mon, 8 Sep 2025 11:44:52 +0200 Subject: [PATCH 118/174] chore: format/credo --- test/distinct_test.exs | 6 ++-- test/parent_filter_test.exs | 2 +- test/sort_test.exs | 56 +++++++++++++++++++++++++----- test/support/resources/chat.ex | 2 +- test/support/resources/customer.ex | 2 +- test/support/resources/message.ex | 2 +- test/support/resources/order.ex | 2 +- test/support/resources/product.ex | 4 +-- 8 files changed, 58 insertions(+), 18 deletions(-) diff --git a/test/distinct_test.exs b/test/distinct_test.exs index 452f0068..284ed5b5 100644 --- a/test/distinct_test.exs +++ b/test/distinct_test.exs @@ -1,7 +1,7 @@ defmodule AshPostgres.DistinctTest do @moduledoc false use AshPostgres.RepoCase, async: false - alias AshPostgres.Test.{Customer, Post, Product, Order} + alias AshPostgres.Test.{Customer, Order, Post, Product} require Ash.Query @@ -179,7 +179,6 @@ defmodule AshPostgres.DistinctTest do end test "distinct breaks with prepare build(sort: [:id]) - original issue reproduction" do - customer = Customer |> Ash.Changeset.for_create(:create, %{name: "Test Customer"}) @@ -201,6 +200,7 @@ defmodule AshPostgres.DistinctTest do customer_with_products = Ash.load!(customer, :purchased_products) purchased_products = customer_with_products.purchased_products - assert length(purchased_products) == 1, "Expected 1 unique product, got #{length(purchased_products)} products. This indicates the distinct + sort preparation bug." + assert length(purchased_products) == 1, + "Expected 1 unique product, got #{length(purchased_products)} products. This indicates the distinct + sort preparation bug." end end diff --git a/test/parent_filter_test.exs b/test/parent_filter_test.exs index 78d295fe..aa2e7af3 100644 --- a/test/parent_filter_test.exs +++ b/test/parent_filter_test.exs @@ -1,7 +1,7 @@ defmodule AshPostgres.Test.ParentFilterTest do use AshPostgres.RepoCase, async: false - alias AshPostgres.Test.{Organization, Post, User, Comment} + alias AshPostgres.Test.{Comment, Organization, Post, User} require Ash.Query diff --git a/test/sort_test.exs b/test/sort_test.exs index 6be3113d..e7d949da 100644 --- a/test/sort_test.exs +++ b/test/sort_test.exs @@ -296,9 +296,24 @@ defmodule AshPostgres.SortTest do chat = Ash.create!(Chat, %{name: "Test Chat"}) # Create some messages - Ash.create!(Message, %{chat_id: chat.id, content: "First", sent_at: ~U[2025-01-01 10:00:00Z]}) - Ash.create!(Message, %{chat_id: chat.id, content: "Second", sent_at: ~U[2025-01-02 10:00:00Z], read_at: ~U[2025-01-02 11:00:00Z]}) - Ash.create!(Message, %{chat_id: chat.id, content: "Third", sent_at: ~U[2025-01-03 10:00:00Z]}) + Ash.create!(Message, %{ + chat_id: chat.id, + content: "First", + sent_at: ~U[2025-01-01 10:00:00Z] + }) + + Ash.create!(Message, %{ + chat_id: chat.id, + content: "Second", + sent_at: ~U[2025-01-02 10:00:00Z], + read_at: ~U[2025-01-02 11:00:00Z] + }) + + Ash.create!(Message, %{ + chat_id: chat.id, + content: "Third", + sent_at: ~U[2025-01-03 10:00:00Z] + }) # This should work - sorting by single has_one relationship calculation result = @@ -313,8 +328,18 @@ defmodule AshPostgres.SortTest do chat = Ash.create!(Chat, %{name: "Test Chat"}) # Create some messages - Ash.create!(Message, %{chat_id: chat.id, content: "First", sent_at: ~U[2025-01-01 10:00:00Z]}) - Ash.create!(Message, %{chat_id: chat.id, content: "Second", sent_at: ~U[2025-01-02 10:00:00Z], read_at: ~U[2025-01-02 11:00:00Z]}) + Ash.create!(Message, %{ + chat_id: chat.id, + content: "First", + sent_at: ~U[2025-01-01 10:00:00Z] + }) + + Ash.create!(Message, %{ + chat_id: chat.id, + content: "Second", + sent_at: ~U[2025-01-02 10:00:00Z], + read_at: ~U[2025-01-02 11:00:00Z] + }) # This should work - sorting by different single has_one relationship calculation result = @@ -329,9 +354,24 @@ defmodule AshPostgres.SortTest do chat = Ash.create!(Chat, %{name: "Test Chat"}) # Create some messages - Ash.create!(Message, %{chat_id: chat.id, content: "First", sent_at: ~U[2025-01-01 10:00:00Z]}) - Ash.create!(Message, %{chat_id: chat.id, content: "Second", sent_at: ~U[2025-01-02 10:00:00Z], read_at: ~U[2025-01-02 11:00:00Z]}) - Ash.create!(Message, %{chat_id: chat.id, content: "Third", sent_at: ~U[2025-01-03 10:00:00Z]}) + Ash.create!(Message, %{ + chat_id: chat.id, + content: "First", + sent_at: ~U[2025-01-01 10:00:00Z] + }) + + Ash.create!(Message, %{ + chat_id: chat.id, + content: "Second", + sent_at: ~U[2025-01-02 10:00:00Z], + read_at: ~U[2025-01-02 11:00:00Z] + }) + + Ash.create!(Message, %{ + chat_id: chat.id, + content: "Third", + sent_at: ~U[2025-01-03 10:00:00Z] + }) Chat |> Ash.Query.sort([ diff --git a/test/support/resources/chat.ex b/test/support/resources/chat.ex index 853c3c17..9a035f4c 100644 --- a/test/support/resources/chat.ex +++ b/test/support/resources/chat.ex @@ -37,4 +37,4 @@ defmodule AshPostgres.Test.Chat do sort(sent_at: :desc) end end -end \ No newline at end of file +end diff --git a/test/support/resources/customer.ex b/test/support/resources/customer.ex index 2bd94105..d5cff43e 100644 --- a/test/support/resources/customer.ex +++ b/test/support/resources/customer.ex @@ -32,4 +32,4 @@ defmodule AshPostgres.Test.Customer do filter(expr(orders.customer_id == parent(id))) end end -end \ No newline at end of file +end diff --git a/test/support/resources/message.ex b/test/support/resources/message.ex index 6e0a2ded..25896e04 100644 --- a/test/support/resources/message.ex +++ b/test/support/resources/message.ex @@ -27,4 +27,4 @@ defmodule AshPostgres.Test.Message do allow_nil?(false) end end -end \ No newline at end of file +end diff --git a/test/support/resources/order.ex b/test/support/resources/order.ex index 83c6751a..27566cb4 100644 --- a/test/support/resources/order.ex +++ b/test/support/resources/order.ex @@ -29,4 +29,4 @@ defmodule AshPostgres.Test.Order do allow_nil?(false) end end -end \ No newline at end of file +end diff --git a/test/support/resources/product.ex b/test/support/resources/product.ex index 0ddb9169..199bbff8 100644 --- a/test/support/resources/product.ex +++ b/test/support/resources/product.ex @@ -17,7 +17,7 @@ defmodule AshPostgres.Test.Product do # This preparation reproduces the bug described in: # https://github.com/ash-project/ash_sql/issues/172#issuecomment-3264660128 preparations do - prepare build(sort: [:id]) + prepare(build(sort: [:id])) end attributes do @@ -30,4 +30,4 @@ defmodule AshPostgres.Test.Product do public?(true) end end -end \ No newline at end of file +end From 2c4e6fdd19ce9217e08c85e00f67b44873bd58f4 Mon Sep 17 00:00:00 2001 From: Zach Daniel Date: Mon, 8 Sep 2025 16:08:06 +0200 Subject: [PATCH 119/174] chore: update test name --- test/parent_filter_test.exs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/parent_filter_test.exs b/test/parent_filter_test.exs index aa2e7af3..b7f8f8dc 100644 --- a/test/parent_filter_test.exs +++ b/test/parent_filter_test.exs @@ -45,7 +45,7 @@ defmodule AshPostgres.Test.ParentFilterTest do |> Ash.read(authorize?: false) end - test "something else" do + test "aggregates from related filters are properly added to the query" do organization = Organization |> Ash.Changeset.for_create(:create, %{name: "test_org"}) From 14ec89d20b9af74adb27849106ce922d884f0b77 Mon Sep 17 00:00:00 2001 From: Zach Daniel Date: Sat, 13 Sep 2025 17:32:02 +0200 Subject: [PATCH 120/174] test: tests and reproductions for get_path composition --- mix.lock | 8 +- .../test_repo/authors/20250908212414.json | 106 ++++++++++++++++++ .../20250908212414_migrate_resources61.exs | 21 ++++ test/storage_types_test.exs | 46 ++++++++ test/support/resources/author.ex | 5 +- 5 files changed, 180 insertions(+), 6 deletions(-) create mode 100644 priv/resource_snapshots/test_repo/authors/20250908212414.json create mode 100644 priv/test_repo/migrations/20250908212414_migrate_resources61.exs diff --git a/mix.lock b/mix.lock index a6ba65e8..90a49a91 100644 --- a/mix.lock +++ b/mix.lock @@ -1,10 +1,10 @@ %{ - "ash": {:hex, :ash, "3.5.35", "ff63b9d3670a05ad036ecc8732c0143770aff4e23f07662931a9ebd1f4aba3c4", [:mix], [{:decimal, "~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:ecto, "~> 3.7", [hex: :ecto, repo: "hexpm", optional: false]}, {:ets, "~> 0.8", [hex: :ets, repo: "hexpm", optional: false]}, {:igniter, ">= 0.6.4 and < 1.0.0-0", [hex: :igniter, repo: "hexpm", optional: true]}, {:jason, ">= 1.0.0", [hex: :jason, repo: "hexpm", optional: false]}, {:picosat_elixir, "~> 0.2", [hex: :picosat_elixir, repo: "hexpm", optional: true]}, {:plug, ">= 0.0.0", [hex: :plug, repo: "hexpm", optional: true]}, {:reactor, "~> 0.11", [hex: :reactor, repo: "hexpm", optional: false]}, {:simple_sat, ">= 0.1.1 and < 1.0.0-0", [hex: :simple_sat, repo: "hexpm", optional: true]}, {:spark, ">= 2.2.68 and < 3.0.0-0", [hex: :spark, repo: "hexpm", optional: false]}, {:splode, ">= 0.2.6 and < 1.0.0-0", [hex: :splode, repo: "hexpm", optional: false]}, {:stream_data, "~> 1.0", [hex: :stream_data, repo: "hexpm", optional: false]}, {:telemetry, "~> 1.1", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "b6ff48f80efabcc1867af9847c8656fa376d9b800e8988b82ec0a42bee4f6b58"}, - "ash_sql": {:hex, :ash_sql, "0.2.90", "6b533e963e4b7c0855654597d8eb7bb87c30db0be7328628cb9bb63e2e547a54", [:mix], [{:ash, ">= 3.5.35 and < 4.0.0-0", [hex: :ash, repo: "hexpm", optional: false]}, {:ecto, "~> 3.9", [hex: :ecto, repo: "hexpm", optional: false]}, {:ecto_sql, "~> 3.9", [hex: :ecto_sql, repo: "hexpm", optional: false]}], "hexpm", "57a7235f22f01381b1a2d63364c353fe6fa31278f3bbd402aacab6dba78a7e6b"}, + "ash": {:hex, :ash, "3.5.40", "19b82796359f32520acd83581c5edfefd06e177fb3c15875f52d5f437f90d902", [:mix], [{:decimal, "~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:ecto, "~> 3.7", [hex: :ecto, repo: "hexpm", optional: false]}, {:ets, "~> 0.8", [hex: :ets, repo: "hexpm", optional: false]}, {:igniter, ">= 0.6.4 and < 1.0.0-0", [hex: :igniter, repo: "hexpm", optional: true]}, {:jason, ">= 1.0.0", [hex: :jason, repo: "hexpm", optional: false]}, {:picosat_elixir, "~> 0.2", [hex: :picosat_elixir, repo: "hexpm", optional: true]}, {:plug, ">= 0.0.0", [hex: :plug, repo: "hexpm", optional: true]}, {:reactor, "~> 0.11", [hex: :reactor, repo: "hexpm", optional: false]}, {:simple_sat, ">= 0.1.1 and < 1.0.0-0", [hex: :simple_sat, repo: "hexpm", optional: true]}, {:spark, ">= 2.2.68 and < 3.0.0-0", [hex: :spark, repo: "hexpm", optional: false]}, {:splode, ">= 0.2.6 and < 1.0.0-0", [hex: :splode, repo: "hexpm", optional: false]}, {:stream_data, "~> 1.0", [hex: :stream_data, repo: "hexpm", optional: false]}, {:telemetry, "~> 1.1", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "278959afb7e54fd3e7184650bfd4ee6a45979aa3d37913d9e19a7400097eae2d"}, + "ash_sql": {:hex, :ash_sql, "0.2.92", "7ef55c307944e68bfd9de07a186fda4bc3b6b7b401f5c5a5cdd0fafafe75d7d2", [:mix], [{:ash, ">= 3.5.35 and < 4.0.0-0", [hex: :ash, repo: "hexpm", optional: false]}, {:ecto, "~> 3.9", [hex: :ecto, repo: "hexpm", optional: false]}, {:ecto_sql, "~> 3.9", [hex: :ecto_sql, repo: "hexpm", optional: false]}], "hexpm", "445fea8343a17d3842ad48007ef07b09ffa28209b3e03ea8772062c42fc50df1"}, "benchee": {:hex, :benchee, "1.4.0", "9f1f96a30ac80bab94faad644b39a9031d5632e517416a8ab0a6b0ac4df124ce", [:mix], [{:deep_merge, "~> 1.0", [hex: :deep_merge, repo: "hexpm", optional: false]}, {:statistex, "~> 1.0", [hex: :statistex, repo: "hexpm", optional: false]}, {:table, "~> 0.1.0", [hex: :table, repo: "hexpm", optional: true]}], "hexpm", "299cd10dd8ce51c9ea3ddb74bb150f93d25e968f93e4c1fa31698a8e4fa5d715"}, "bunt": {:hex, :bunt, "1.0.0", "081c2c665f086849e6d57900292b3a161727ab40431219529f13c4ddcf3e7a44", [:mix], [], "hexpm", "dc5f86aa08a5f6fa6b8096f0735c4e76d54ae5c9fa2c143e5a1fc7c1cd9bb6b5"}, "credo": {:hex, :credo, "1.7.12", "9e3c20463de4b5f3f23721527fcaf16722ec815e70ff6c60b86412c695d426c1", [:mix], [{:bunt, "~> 0.2.1 or ~> 1.0", [hex: :bunt, repo: "hexpm", optional: false]}, {:file_system, "~> 0.2 or ~> 1.0", [hex: :file_system, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "8493d45c656c5427d9c729235b99d498bd133421f3e0a683e5c1b561471291e5"}, - "db_connection": {:hex, :db_connection, "2.8.0", "64fd82cfa6d8e25ec6660cea73e92a4cbc6a18b31343910427b702838c4b33b2", [:mix], [{:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "008399dae5eee1bf5caa6e86d204dcb44242c82b1ed5e22c881f2c34da201b15"}, + "db_connection": {:hex, :db_connection, "2.8.1", "9abdc1e68c34c6163f6fb96a96532272d13ad7ca45262156ae8b7ec6d9dc4bec", [:mix], [{:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "a61a3d489b239d76f326e03b98794fb8e45168396c925ef25feb405ed09da8fd"}, "decimal": {:hex, :decimal, "2.3.0", "3ad6255aa77b4a3c4f818171b12d237500e63525c2fd056699967a3e7ea20f62", [:mix], [], "hexpm", "a4d66355cb29cb47c3cf30e71329e58361cfcb37c34235ef3bf1d7bf3773aeac"}, "deep_merge": {:hex, :deep_merge, "1.0.0", "b4aa1a0d1acac393bdf38b2291af38cb1d4a52806cf7a4906f718e1feb5ee961", [:mix], [], "hexpm", "ce708e5f094b9cd4e8f2be4f00d2f4250c4095be93f8cd6d018c753894885430"}, "dialyxir": {:hex, :dialyxir, "1.4.5", "ca1571ac18e0f88d4ab245f0b60fa31ff1b12cbae2b11bd25d207f865e8ae78a", [:mix], [{:erlex, ">= 0.2.7", [hex: :erlex, repo: "hexpm", optional: false]}], "hexpm", "b0fb08bb8107c750db5c0b324fa2df5ceaa0f9307690ee3c1f6ba5b9eb5d35c3"}, @@ -36,7 +36,7 @@ "nimble_options": {:hex, :nimble_options, "1.1.1", "e3a492d54d85fc3fd7c5baf411d9d2852922f66e69476317787a7b2bb000a61b", [:mix], [], "hexpm", "821b2470ca9442c4b6984882fe9bb0389371b8ddec4d45a9504f00a66f650b44"}, "nimble_parsec": {:hex, :nimble_parsec, "1.4.2", "8efba0122db06df95bfaa78f791344a89352ba04baedd3849593bfce4d0dc1c6", [:mix], [], "hexpm", "4b21398942dda052b403bbe1da991ccd03a053668d147d53fb8c4e0efe09c973"}, "nimble_pool": {:hex, :nimble_pool, "1.1.0", "bf9c29fbdcba3564a8b800d1eeb5a3c58f36e1e11d7b7fb2e084a643f645f06b", [:mix], [], "hexpm", "af2e4e6b34197db81f7aad230c1118eac993acc0dae6bc83bac0126d4ae0813a"}, - "owl": {:hex, :owl, "0.12.2", "65906b525e5c3ef51bab6cba7687152be017aebe1da077bb719a5ee9f7e60762", [:mix], [{:ucwidth, "~> 0.2", [hex: :ucwidth, repo: "hexpm", optional: true]}], "hexpm", "6398efa9e1fea70a04d24231e10dcd66c1ac1aa2da418d20ef5357ec61de2880"}, + "owl": {:hex, :owl, "0.13.0", "26010e066d5992774268f3163506972ddac0a7e77bfe57fa42a250f24d6b876e", [:mix], [{:ucwidth, "~> 0.2", [hex: :ucwidth, repo: "hexpm", optional: true]}], "hexpm", "59bf9d11ce37a4db98f57cb68fbfd61593bf419ec4ed302852b6683d3d2f7475"}, "postgrex": {:hex, :postgrex, "0.21.1", "2c5cc830ec11e7a0067dd4d623c049b3ef807e9507a424985b8dcf921224cd88", [:mix], [{:db_connection, "~> 2.1", [hex: :db_connection, repo: "hexpm", optional: false]}, {:decimal, "~> 1.5 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:table, "~> 0.1.0", [hex: :table, repo: "hexpm", optional: true]}], "hexpm", "27d8d21c103c3cc68851b533ff99eef353e6a0ff98dc444ea751de43eb48bdac"}, "reactor": {:hex, :reactor, "0.15.6", "d717f9add549b25a089a94c90197718d2d838e35d81dd776b1d81587d4cf2aaa", [:mix], [{:igniter, "~> 0.4", [hex: :igniter, repo: "hexpm", optional: true]}, {:iterex, "~> 0.1", [hex: :iterex, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}, {:libgraph, "~> 0.16", [hex: :libgraph, repo: "hexpm", optional: false]}, {:spark, "~> 2.0", [hex: :spark, repo: "hexpm", optional: false]}, {:splode, "~> 0.2", [hex: :splode, repo: "hexpm", optional: false]}, {:telemetry, "~> 1.2", [hex: :telemetry, repo: "hexpm", optional: false]}, {:yaml_elixir, "~> 2.11", [hex: :yaml_elixir, repo: "hexpm", optional: false]}, {:ymlr, "~> 5.0", [hex: :ymlr, repo: "hexpm", optional: false]}], "hexpm", "74db98165e3644d86e0f723672d91ceca4339eaa935bcad7e78bf146a46d77b9"}, "req": {:hex, :req, "0.5.15", "662020efb6ea60b9f0e0fac9be88cd7558b53fe51155a2d9899de594f9906ba9", [:mix], [{:brotli, "~> 0.3.1", [hex: :brotli, repo: "hexpm", optional: true]}, {:ezstd, "~> 1.0", [hex: :ezstd, repo: "hexpm", optional: true]}, {:finch, "~> 0.17", [hex: :finch, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}, {:mime, "~> 2.0.6 or ~> 2.1", [hex: :mime, repo: "hexpm", optional: false]}, {:nimble_csv, "~> 1.0", [hex: :nimble_csv, repo: "hexpm", optional: true]}, {:plug, "~> 1.0", [hex: :plug, repo: "hexpm", optional: true]}], "hexpm", "a6513a35fad65467893ced9785457e91693352c70b58bbc045b47e5eb2ef0c53"}, diff --git a/priv/resource_snapshots/test_repo/authors/20250908212414.json b/priv/resource_snapshots/test_repo/authors/20250908212414.json new file mode 100644 index 00000000..b271e003 --- /dev/null +++ b/priv/resource_snapshots/test_repo/authors/20250908212414.json @@ -0,0 +1,106 @@ +{ + "attributes": [ + { + "allow_nil?": false, + "default": "fragment(\"gen_random_uuid()\")", + "generated?": false, + "precision": null, + "primary_key?": true, + "references": null, + "scale": null, + "size": null, + "source": "id", + "type": "uuid" + }, + { + "allow_nil?": true, + "default": "nil", + "generated?": false, + "precision": null, + "primary_key?": false, + "references": null, + "scale": null, + "size": null, + "source": "first_name", + "type": "text" + }, + { + "allow_nil?": true, + "default": "nil", + "generated?": false, + "precision": null, + "primary_key?": false, + "references": null, + "scale": null, + "size": null, + "source": "last_name", + "type": "text" + }, + { + "allow_nil?": true, + "default": "nil", + "generated?": false, + "precision": null, + "primary_key?": false, + "references": null, + "scale": null, + "size": null, + "source": "bio", + "type": "map" + }, + { + "allow_nil?": true, + "default": "nil", + "generated?": false, + "precision": null, + "primary_key?": false, + "references": null, + "scale": null, + "size": null, + "source": "bios", + "type": "jsonb" + }, + { + "allow_nil?": true, + "default": "nil", + "generated?": false, + "precision": null, + "primary_key?": false, + "references": null, + "scale": null, + "size": null, + "source": "badges", + "type": [ + "array", + "text" + ] + }, + { + "allow_nil?": true, + "default": "nil", + "generated?": false, + "precision": null, + "primary_key?": false, + "references": null, + "scale": null, + "size": null, + "source": "settings", + "type": "jsonb" + } + ], + "base_filter": null, + "check_constraints": [], + "custom_indexes": [], + "custom_statements": [], + "has_create_action": true, + "hash": "DD102A40219E8086BECBF5306AAA1196B59CC38B6FAA0BCEECFD24E82FF24DCD", + "identities": [], + "multitenancy": { + "attribute": null, + "global": null, + "strategy": null + }, + "repo": "Elixir.AshPostgres.TestRepo", + "schema": null, + "table": "authors" +} \ No newline at end of file diff --git a/priv/test_repo/migrations/20250908212414_migrate_resources61.exs b/priv/test_repo/migrations/20250908212414_migrate_resources61.exs new file mode 100644 index 00000000..303a4e53 --- /dev/null +++ b/priv/test_repo/migrations/20250908212414_migrate_resources61.exs @@ -0,0 +1,21 @@ +defmodule AshPostgres.TestRepo.Migrations.MigrateResources61 do + @moduledoc """ + Updates resources based on their most recent snapshots. + + This file was autogenerated with `mix ash_postgres.generate_migrations` + """ + + use Ecto.Migration + + def up do + alter table(:authors) do + add(:settings, :jsonb) + end + end + + def down do + alter table(:authors) do + remove(:settings) + end + end +end diff --git a/test/storage_types_test.exs b/test/storage_types_test.exs index dde647b3..88783e54 100644 --- a/test/storage_types_test.exs +++ b/test/storage_types_test.exs @@ -42,4 +42,50 @@ defmodule AshPostgres.StorageTypesTest do assert author.bios == [%{"a" => 1}] end + + test "`in` operator works on get_path results" do + %{id: id} = + Author + |> Ash.Changeset.for_create( + :create, + %{ + first_name: "Test", + last_name: "User", + settings: %{ + "dues_reminders" => ["email", "sms"], + "newsletter" => ["email"], + "optional_field" => nil + } + } + ) + |> Ash.create!() + + assert [%Author{id: ^id}] = + Author + |> Ash.Query.filter("email" in settings["dues_reminders"]) + |> Ash.read!() + end + + test "`is_nil` operator works on get_path results" do + %{id: id} = + Author + |> Ash.Changeset.for_create( + :create, + %{ + first_name: "Test", + last_name: "User", + settings: %{ + "dues_reminders" => ["email", "sms"], + "newsletter" => ["email"], + "optional_field" => nil + } + } + ) + |> Ash.create!() + + assert [%Author{id: ^id}] = + Author + |> Ash.Query.filter(is_nil(settings["optional_field"])) + |> Ash.read!() + end end diff --git a/test/support/resources/author.ex b/test/support/resources/author.ex index 54568518..77ad0d15 100644 --- a/test/support/resources/author.ex +++ b/test/support/resources/author.ex @@ -19,8 +19,8 @@ defmodule AshPostgres.Test.Author do table("authors") repo(AshPostgres.TestRepo) - migration_types bios: :jsonb - storage_types(bios: :jsonb) + migration_types bios: :jsonb, settings: :jsonb + storage_types(bios: :jsonb, settings: :jsonb) end attributes do @@ -30,6 +30,7 @@ defmodule AshPostgres.Test.Author do attribute(:bio, AshPostgres.Test.Bio, public?: true) attribute(:bios, {:array, :map}, public?: true) attribute(:badges, {:array, :atom}, public?: true) + attribute(:settings, :map, public?: true) end actions do From 19ed5ef68c6ab3d09e3e30169d838b17dbc30f21 Mon Sep 17 00:00:00 2001 From: Trond A Ekseth Date: Sat, 13 Sep 2025 17:57:54 +0200 Subject: [PATCH 121/174] docs: Fix duplicate `public` option in ash_postgres.gen.resources (#613) --- lib/mix/tasks/ash_postgres.gen.resources.ex | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/mix/tasks/ash_postgres.gen.resources.ex b/lib/mix/tasks/ash_postgres.gen.resources.ex index a187f8d9..babac4f1 100644 --- a/lib/mix/tasks/ash_postgres.gen.resources.ex +++ b/lib/mix/tasks/ash_postgres.gen.resources.ex @@ -30,7 +30,6 @@ if Code.ensure_loaded?(Igniter) do - `public` - Mark all attributes and relationships as `public? true`. Defaults to `true`. - `no-migrations` - Do not generate snapshots & migrations for the resources. Defaults to `false`. - `skip-unknown` - Skip any attributes with types that we don't have a corresponding Elixir type for, and relationships that we can't assume the name of. - - `public` - Mark all attributes and relationships as `public? true`. Defaults to `true`. ## Tables From b2f98cf6de47daa094942be0f31f9f9fccfebb2c Mon Sep 17 00:00:00 2001 From: Trond A Ekseth Date: Mon, 15 Sep 2025 21:12:29 +0200 Subject: [PATCH 122/174] fix: Handle optional/empty input in relationship name guesser (#616) --- lib/resource_generator/spec.ex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/resource_generator/spec.ex b/lib/resource_generator/spec.ex index 8b6d4ae6..f2da7ec5 100644 --- a/lib/resource_generator/spec.ex +++ b/lib/resource_generator/spec.ex @@ -781,7 +781,7 @@ defmodule AshPostgres.ResourceGenerator.Spec do end Owl.IO.input(label: label, optional: true) - |> String.trim() + |> Kernel.||("") # common typo |> String.trim_leading(":") |> case do From f33cfbecd86870715de3532d69d23d66f7424a4d Mon Sep 17 00:00:00 2001 From: Moxley Stratton Date: Thu, 18 Sep 2025 04:12:32 -0700 Subject: [PATCH 123/174] test: Demonstrate failed query for is_nil on array within jsonb (#615) --- test/storage_types_test.exs | 3 ++- test/support/resources/author.ex | 2 +- test/support/resources/settings.ex | 10 ++++++++++ 3 files changed, 13 insertions(+), 2 deletions(-) create mode 100644 test/support/resources/settings.ex diff --git a/test/storage_types_test.exs b/test/storage_types_test.exs index 88783e54..6b5a44cd 100644 --- a/test/storage_types_test.exs +++ b/test/storage_types_test.exs @@ -66,6 +66,7 @@ defmodule AshPostgres.StorageTypesTest do |> Ash.read!() end + @tag capture_log: false test "`is_nil` operator works on get_path results" do %{id: id} = Author @@ -85,7 +86,7 @@ defmodule AshPostgres.StorageTypesTest do assert [%Author{id: ^id}] = Author - |> Ash.Query.filter(is_nil(settings["optional_field"])) + |> Ash.Query.filter(is_nil(settings["dues_reminders"])) |> Ash.read!() end end diff --git a/test/support/resources/author.ex b/test/support/resources/author.ex index 77ad0d15..e30f7592 100644 --- a/test/support/resources/author.ex +++ b/test/support/resources/author.ex @@ -30,7 +30,7 @@ defmodule AshPostgres.Test.Author do attribute(:bio, AshPostgres.Test.Bio, public?: true) attribute(:bios, {:array, :map}, public?: true) attribute(:badges, {:array, :atom}, public?: true) - attribute(:settings, :map, public?: true) + attribute(:settings, AshPostgres.Test.Settings, public?: true) end actions do diff --git a/test/support/resources/settings.ex b/test/support/resources/settings.ex new file mode 100644 index 00000000..681584db --- /dev/null +++ b/test/support/resources/settings.ex @@ -0,0 +1,10 @@ +defmodule AshPostgres.Test.Settings do + @moduledoc false + use Ash.Resource, data_layer: :embedded + + attributes do + attribute :dues_reminders, {:array, :string}, public?: true + attribute :newsletter, {:array, :string}, public?: true + attribute :optional_field, :string, public?: true + end +end From 850f7d267c8e2ffd6d558323327d01d74cff71b7 Mon Sep 17 00:00:00 2001 From: Zach Daniel Date: Thu, 18 Sep 2025 10:09:41 -0400 Subject: [PATCH 124/174] chore: update test to pass against ash_sql main --- test/storage_types_test.exs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/storage_types_test.exs b/test/storage_types_test.exs index 6b5a44cd..ca433860 100644 --- a/test/storage_types_test.exs +++ b/test/storage_types_test.exs @@ -86,7 +86,7 @@ defmodule AshPostgres.StorageTypesTest do assert [%Author{id: ^id}] = Author - |> Ash.Query.filter(is_nil(settings["dues_reminders"])) + |> Ash.Query.filter(not is_nil(settings["dues_reminders"])) |> Ash.read!() end end From 58c9543f2c8ce7ad8243a8296cf924c828c4e540 Mon Sep 17 00:00:00 2001 From: Robert Ellen Date: Fri, 19 Sep 2025 04:35:54 +1000 Subject: [PATCH 125/174] test: Add a test for an expr calc using an aggregation in a sort (#617) This replicates an issue seen. We have an expression calculation using a aggregation from a transitive relationship. If that calculation is used in a sort, the text of the expression is passed as the aggregate name, instead of a variable name such as "aggregate0" etc. E.g. ``` * ** (RuntimeError) Unbound aggregate field: "first(comments[field: :created_at, query: [filter: author_id == \"54c6b3da-d3a5-41f6-8409-780fed9fe184\"]])" ``` --- test/calculation_test.exs | 41 ++++++++++++++++++++++++++++++++++ test/support/resources/post.ex | 28 +++++++++++++++++++++++ 2 files changed, 69 insertions(+) diff --git a/test/calculation_test.exs b/test/calculation_test.exs index 68c975d9..cf539f18 100644 --- a/test/calculation_test.exs +++ b/test/calculation_test.exs @@ -1076,4 +1076,45 @@ defmodule AshPostgres.CalculationTest do highest_score = hd(Enum.sort(scores, :desc)) assert post_with_highest_score.score == highest_score end + + test "an expression calculation can use an aggregate" do + post = + Post + |> Ash.Changeset.for_create(:create, %{title: "my post"}) + |> Ash.create!() + + author = + Author + |> Ash.Changeset.for_create(:create, %{ + first_name: "ashley" + }) + |> Ash.create!() + + Comment + |> Ash.Changeset.for_create(:create, %{title: "first comment"}) + |> Ash.Changeset.manage_relationship(:post, post, type: :append_and_remove) + |> Ash.create!() + + first_comment_by_author = + Comment + |> Ash.Changeset.for_create(:create, %{title: "first comment by Ashley"}) + |> Ash.Changeset.manage_relationship(:author, author, type: :append_and_remove) + |> Ash.Changeset.manage_relationship(:post, post, type: :append_and_remove) + |> Ash.create!() + + post = + Post + |> Ash.Query.for_read(:read_by_comment_author, %{ + author_id: author.id + }) + |> Ash.Query.sort_input([ + {"datetime_of_first_comment_by_author", {%{author_id: author.id}, :desc}} + ]) + |> Ash.read_one!() + + assert DateTime.compare( + post.datetime_of_first_comment_by_author, + first_comment_by_author.created_at + ) + end end diff --git a/test/support/resources/post.ex b/test/support/resources/post.ex index e6009d57..817e0ff9 100644 --- a/test/support/resources/post.ex +++ b/test/support/resources/post.ex @@ -488,6 +488,20 @@ defmodule AshPostgres.Test.Post do pagination(keyset?: true, default_limit: 25) filter(expr(count_nils(latest_comment.linked_comment_post_ids) == 0)) end + + read :read_by_comment_author do + argument(:author_id, :uuid, allow_nil?: false) + + filter(expr(comments.author_id == ^arg(:author_id))) + + prepare( + build( + load: [ + datetime_of_first_comment_by_author: %{author_id: arg(:author_id)} + ] + ) + ) + end end identities do @@ -1030,6 +1044,20 @@ defmodule AshPostgres.Test.Post do calculate(:latest_comment_title, :string, expr(latest_comment.title), allow_nil?: true) calculate(:concated_comment_titles, :string, expr(fragment("concat(?)", comment_titles))) + + calculate :datetime_of_first_comment_by_author, + :utc_datetime_usec, + expr( + first(comments, + field: :created_at, + query: [ + filter: author_id == ^arg(:author_id) + ] + ) + ) do + public?(true) + argument(:author_id, :uuid, allow_nil?: false) + end end aggregates do From 1e09ef3e8031fea0f7fb62880468aa6c9b44279b Mon Sep 17 00:00:00 2001 From: Zach Daniel Date: Fri, 19 Sep 2025 07:37:03 -0400 Subject: [PATCH 126/174] chore: update ash_sql --- mix.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mix.lock b/mix.lock index 90a49a91..602a8e67 100644 --- a/mix.lock +++ b/mix.lock @@ -1,6 +1,6 @@ %{ "ash": {:hex, :ash, "3.5.40", "19b82796359f32520acd83581c5edfefd06e177fb3c15875f52d5f437f90d902", [:mix], [{:decimal, "~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:ecto, "~> 3.7", [hex: :ecto, repo: "hexpm", optional: false]}, {:ets, "~> 0.8", [hex: :ets, repo: "hexpm", optional: false]}, {:igniter, ">= 0.6.4 and < 1.0.0-0", [hex: :igniter, repo: "hexpm", optional: true]}, {:jason, ">= 1.0.0", [hex: :jason, repo: "hexpm", optional: false]}, {:picosat_elixir, "~> 0.2", [hex: :picosat_elixir, repo: "hexpm", optional: true]}, {:plug, ">= 0.0.0", [hex: :plug, repo: "hexpm", optional: true]}, {:reactor, "~> 0.11", [hex: :reactor, repo: "hexpm", optional: false]}, {:simple_sat, ">= 0.1.1 and < 1.0.0-0", [hex: :simple_sat, repo: "hexpm", optional: true]}, {:spark, ">= 2.2.68 and < 3.0.0-0", [hex: :spark, repo: "hexpm", optional: false]}, {:splode, ">= 0.2.6 and < 1.0.0-0", [hex: :splode, repo: "hexpm", optional: false]}, {:stream_data, "~> 1.0", [hex: :stream_data, repo: "hexpm", optional: false]}, {:telemetry, "~> 1.1", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "278959afb7e54fd3e7184650bfd4ee6a45979aa3d37913d9e19a7400097eae2d"}, - "ash_sql": {:hex, :ash_sql, "0.2.92", "7ef55c307944e68bfd9de07a186fda4bc3b6b7b401f5c5a5cdd0fafafe75d7d2", [:mix], [{:ash, ">= 3.5.35 and < 4.0.0-0", [hex: :ash, repo: "hexpm", optional: false]}, {:ecto, "~> 3.9", [hex: :ecto, repo: "hexpm", optional: false]}, {:ecto_sql, "~> 3.9", [hex: :ecto_sql, repo: "hexpm", optional: false]}], "hexpm", "445fea8343a17d3842ad48007ef07b09ffa28209b3e03ea8772062c42fc50df1"}, + "ash_sql": {:hex, :ash_sql, "0.2.93", "d2e50a718f18e67bffa8fd9c7bea39d260ca746ca4df357bd9726a3ad4a39294", [:mix], [{:ash, ">= 3.5.35 and < 4.0.0-0", [hex: :ash, repo: "hexpm", optional: false]}, {:ecto, "~> 3.9", [hex: :ecto, repo: "hexpm", optional: false]}, {:ecto_sql, "~> 3.9", [hex: :ecto_sql, repo: "hexpm", optional: false]}], "hexpm", "492d811a636c19dad990c4f1af83761c0006ec5650970252f78cf4bd2b50b500"}, "benchee": {:hex, :benchee, "1.4.0", "9f1f96a30ac80bab94faad644b39a9031d5632e517416a8ab0a6b0ac4df124ce", [:mix], [{:deep_merge, "~> 1.0", [hex: :deep_merge, repo: "hexpm", optional: false]}, {:statistex, "~> 1.0", [hex: :statistex, repo: "hexpm", optional: false]}, {:table, "~> 0.1.0", [hex: :table, repo: "hexpm", optional: true]}], "hexpm", "299cd10dd8ce51c9ea3ddb74bb150f93d25e968f93e4c1fa31698a8e4fa5d715"}, "bunt": {:hex, :bunt, "1.0.0", "081c2c665f086849e6d57900292b3a161727ab40431219529f13c4ddcf3e7a44", [:mix], [], "hexpm", "dc5f86aa08a5f6fa6b8096f0735c4e76d54ae5c9fa2c143e5a1fc7c1cd9bb6b5"}, "credo": {:hex, :credo, "1.7.12", "9e3c20463de4b5f3f23721527fcaf16722ec815e70ff6c60b86412c695d426c1", [:mix], [{:bunt, "~> 0.2.1 or ~> 1.0", [hex: :bunt, repo: "hexpm", optional: false]}, {:file_system, "~> 0.2 or ~> 1.0", [hex: :file_system, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "8493d45c656c5427d9c729235b99d498bd133421f3e0a683e5c1b561471291e5"}, From 798f37d0250e7298fd3b1fb60f197b19ddca2596 Mon Sep 17 00:00:00 2001 From: Zach Daniel Date: Fri, 19 Sep 2025 07:37:24 -0400 Subject: [PATCH 127/174] chore: release version v2.6.18 --- CHANGELOG.md | 13 +++++++++++++ mix.exs | 2 +- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 08169773..09e31680 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,19 @@ See [Conventional Commits](https://www.conventionalcommits.org) for commit guide +## [v2.6.18](https://github.com/ash-project/ash_postgres/compare/v2.6.17...v2.6.18) (2025-09-19) + + + + +### Bug Fixes: + +* Handle optional/empty input in relationship name guesser (#616) by Trond A Ekseth + +* properly handle sorts w/ parent refs on lateral joins by Zach Daniel + +* annotate unrelated exists expressions as supported by Zach Daniel + ## [v2.6.17](https://github.com/ash-project/ash_postgres/compare/v2.6.16...v2.6.17) (2025-08-31) diff --git a/mix.exs b/mix.exs index 3e8719c1..ebb4daba 100644 --- a/mix.exs +++ b/mix.exs @@ -5,7 +5,7 @@ defmodule AshPostgres.MixProject do The PostgreSQL data layer for Ash Framework """ - @version "2.6.17" + @version "2.6.18" def project do [ From cd34939b5b4f9359d1d8b1c6056359fbfeb05795 Mon Sep 17 00:00:00 2001 From: Kantum <43590963+kantum@users.noreply.github.com> Date: Sat, 20 Sep 2025 21:05:06 +0200 Subject: [PATCH 128/174] docs: list_tenants -> all_tenants (#619) --- documentation/topics/development/migrations-and-tasks.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/documentation/topics/development/migrations-and-tasks.md b/documentation/topics/development/migrations-and-tasks.md index 04fefc93..5fd26271 100644 --- a/documentation/topics/development/migrations-and-tasks.md +++ b/documentation/topics/development/migrations-and-tasks.md @@ -19,9 +19,9 @@ dev migrations and run them. For more information on generating migrations, run `mix help ash_postgres.generate_migrations` (the underlying task that is called by `mix ash.migrate`) -> ### list_tenants/0 {: .info} +> ### all_tenants/0 {: .info} > -> If you have are using schema-based multitenancy, you will also need to define a `list_tenants/0` function in your repo module. See `AshPostgres.Repo` for more. +> If you have are using schema-based multitenancy, you will also need to define a `all_tenants/0` function in your repo module. See `AshPostgres.Repo` for more. ### Regenerating Migrations From 98ea317e02dfe6034603f1be60ba2a895cadd2d0 Mon Sep 17 00:00:00 2001 From: Zach Daniel Date: Sat, 20 Sep 2025 17:43:17 -0400 Subject: [PATCH 129/174] fix: fix conditional on installing ash in installer --- lib/mix/tasks/ash_postgres.install.ex | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/mix/tasks/ash_postgres.install.ex b/lib/mix/tasks/ash_postgres.install.ex index 5bfa39f4..6808cbfb 100644 --- a/lib/mix/tasks/ash_postgres.install.ex +++ b/lib/mix/tasks/ash_postgres.install.ex @@ -39,6 +39,8 @@ if Code.ensure_loaded?(Igniter) do igniter = if Igniter.Project.Deps.has_dep?(igniter, :ash) do igniter + else + igniter |> Igniter.Project.Deps.add_dep({:ash, "~> 3.0"}, yes: opts[:yes]) |> then(fn %{assigns: %{test_mode?: true}} = igniter -> @@ -52,8 +54,6 @@ if Code.ensure_loaded?(Igniter) do ) end) |> Igniter.compose_task("ash.install", argv) - else - igniter end igniter From dce5c4b3e29546fff543df12b26d8adf8fa586f9 Mon Sep 17 00:00:00 2001 From: Zach Daniel Date: Sat, 20 Sep 2025 17:43:42 -0400 Subject: [PATCH 130/174] chore: release version v2.6.19 --- CHANGELOG.md | 9 +++++++++ mix.exs | 2 +- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 09e31680..4b9eaa03 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,15 @@ See [Conventional Commits](https://www.conventionalcommits.org) for commit guide +## [v2.6.19](https://github.com/ash-project/ash_postgres/compare/v2.6.18...v2.6.19) (2025-09-20) + + + + +### Bug Fixes: + +* fix conditional on installing ash in installer by Zach Daniel + ## [v2.6.18](https://github.com/ash-project/ash_postgres/compare/v2.6.17...v2.6.18) (2025-09-19) diff --git a/mix.exs b/mix.exs index ebb4daba..22d502f0 100644 --- a/mix.exs +++ b/mix.exs @@ -5,7 +5,7 @@ defmodule AshPostgres.MixProject do The PostgreSQL data layer for Ash Framework """ - @version "2.6.18" + @version "2.6.19" def project do [ From 53d2a9525eb726a45f81bbaba59f3e93efcd4065 Mon Sep 17 00:00:00 2001 From: Zach Daniel Date: Sat, 20 Sep 2025 23:03:39 -0400 Subject: [PATCH 131/174] fix: use `:mutate` repo for on_transaction_begin callback --- lib/data_layer.ex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/data_layer.ex b/lib/data_layer.ex index e4cde133..43b8f5a1 100644 --- a/lib/data_layer.ex +++ b/lib/data_layer.ex @@ -3561,7 +3561,7 @@ defmodule AshPostgres.DataLayer do repo _ -> - AshPostgres.DataLayer.Info.repo(resource, :read) + AshPostgres.DataLayer.Info.repo(resource, :mutate) end func = fn -> From ee2d2f5f9dea646c4a3bccd7a2f6f19b22f878b9 Mon Sep 17 00:00:00 2001 From: Zach Daniel Date: Sun, 21 Sep 2025 09:47:46 -0400 Subject: [PATCH 132/174] chore: remove ash installation step in ash_postgres --- lib/mix/tasks/ash_postgres.install.ex | 21 --------------------- mix.lock | 8 ++++---- 2 files changed, 4 insertions(+), 25 deletions(-) diff --git a/lib/mix/tasks/ash_postgres.install.ex b/lib/mix/tasks/ash_postgres.install.ex index 6808cbfb..4935fdf1 100644 --- a/lib/mix/tasks/ash_postgres.install.ex +++ b/lib/mix/tasks/ash_postgres.install.ex @@ -22,7 +22,6 @@ if Code.ensure_loaded?(Igniter) do @impl true def igniter(igniter) do - argv = igniter.args.argv opts = igniter.args.options repo = @@ -36,26 +35,6 @@ if Code.ensure_loaded?(Igniter) do otp_app = Igniter.Project.Application.app_name(igniter) - igniter = - if Igniter.Project.Deps.has_dep?(igniter, :ash) do - igniter - else - igniter - |> Igniter.Project.Deps.add_dep({:ash, "~> 3.0"}, yes: opts[:yes]) - |> then(fn - %{assigns: %{test_mode?: true}} = igniter -> - igniter - - igniter -> - Igniter.apply_and_fetch_dependencies(igniter, - error_on_abort?: true, - yes: opts[:yes], - yes_to_deps: true - ) - end) - |> Igniter.compose_task("ash.install", argv) - end - igniter |> Igniter.Project.Formatter.import_dep(:ash_postgres) |> setup_aliases() diff --git a/mix.lock b/mix.lock index 602a8e67..78a54f83 100644 --- a/mix.lock +++ b/mix.lock @@ -1,5 +1,5 @@ %{ - "ash": {:hex, :ash, "3.5.40", "19b82796359f32520acd83581c5edfefd06e177fb3c15875f52d5f437f90d902", [:mix], [{:decimal, "~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:ecto, "~> 3.7", [hex: :ecto, repo: "hexpm", optional: false]}, {:ets, "~> 0.8", [hex: :ets, repo: "hexpm", optional: false]}, {:igniter, ">= 0.6.4 and < 1.0.0-0", [hex: :igniter, repo: "hexpm", optional: true]}, {:jason, ">= 1.0.0", [hex: :jason, repo: "hexpm", optional: false]}, {:picosat_elixir, "~> 0.2", [hex: :picosat_elixir, repo: "hexpm", optional: true]}, {:plug, ">= 0.0.0", [hex: :plug, repo: "hexpm", optional: true]}, {:reactor, "~> 0.11", [hex: :reactor, repo: "hexpm", optional: false]}, {:simple_sat, ">= 0.1.1 and < 1.0.0-0", [hex: :simple_sat, repo: "hexpm", optional: true]}, {:spark, ">= 2.2.68 and < 3.0.0-0", [hex: :spark, repo: "hexpm", optional: false]}, {:splode, ">= 0.2.6 and < 1.0.0-0", [hex: :splode, repo: "hexpm", optional: false]}, {:stream_data, "~> 1.0", [hex: :stream_data, repo: "hexpm", optional: false]}, {:telemetry, "~> 1.1", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "278959afb7e54fd3e7184650bfd4ee6a45979aa3d37913d9e19a7400097eae2d"}, + "ash": {:hex, :ash, "3.5.42", "bdd84c468c05e497a8b1ee579901274125c540b66df82ed67c35f889a529ee70", [:mix], [{:decimal, "~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:ecto, "~> 3.7", [hex: :ecto, repo: "hexpm", optional: false]}, {:ets, "~> 0.8", [hex: :ets, repo: "hexpm", optional: false]}, {:igniter, ">= 0.6.29 and < 1.0.0-0", [hex: :igniter, repo: "hexpm", optional: true]}, {:jason, ">= 1.0.0", [hex: :jason, repo: "hexpm", optional: false]}, {:picosat_elixir, "~> 0.2", [hex: :picosat_elixir, repo: "hexpm", optional: true]}, {:plug, ">= 0.0.0", [hex: :plug, repo: "hexpm", optional: true]}, {:reactor, "~> 0.11", [hex: :reactor, repo: "hexpm", optional: false]}, {:simple_sat, ">= 0.1.1 and < 1.0.0-0", [hex: :simple_sat, repo: "hexpm", optional: true]}, {:spark, ">= 2.2.68 and < 3.0.0-0", [hex: :spark, repo: "hexpm", optional: false]}, {:splode, ">= 0.2.6 and < 1.0.0-0", [hex: :splode, repo: "hexpm", optional: false]}, {:stream_data, "~> 1.0", [hex: :stream_data, repo: "hexpm", optional: false]}, {:telemetry, "~> 1.1", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "dc0988e171630401e8eab65c95ac33c04b8fe47084fc038e80f4d713cb2d44ba"}, "ash_sql": {:hex, :ash_sql, "0.2.93", "d2e50a718f18e67bffa8fd9c7bea39d260ca746ca4df357bd9726a3ad4a39294", [:mix], [{:ash, ">= 3.5.35 and < 4.0.0-0", [hex: :ash, repo: "hexpm", optional: false]}, {:ecto, "~> 3.9", [hex: :ecto, repo: "hexpm", optional: false]}, {:ecto_sql, "~> 3.9", [hex: :ecto_sql, repo: "hexpm", optional: false]}], "hexpm", "492d811a636c19dad990c4f1af83761c0006ec5650970252f78cf4bd2b50b500"}, "benchee": {:hex, :benchee, "1.4.0", "9f1f96a30ac80bab94faad644b39a9031d5632e517416a8ab0a6b0ac4df124ce", [:mix], [{:deep_merge, "~> 1.0", [hex: :deep_merge, repo: "hexpm", optional: false]}, {:statistex, "~> 1.0", [hex: :statistex, repo: "hexpm", optional: false]}, {:table, "~> 0.1.0", [hex: :table, repo: "hexpm", optional: true]}], "hexpm", "299cd10dd8ce51c9ea3ddb74bb150f93d25e968f93e4c1fa31698a8e4fa5d715"}, "bunt": {:hex, :bunt, "1.0.0", "081c2c665f086849e6d57900292b3a161727ab40431219529f13c4ddcf3e7a44", [:mix], [], "hexpm", "dc5f86aa08a5f6fa6b8096f0735c4e76d54ae5c9fa2c143e5a1fc7c1cd9bb6b5"}, @@ -9,7 +9,7 @@ "deep_merge": {:hex, :deep_merge, "1.0.0", "b4aa1a0d1acac393bdf38b2291af38cb1d4a52806cf7a4906f718e1feb5ee961", [:mix], [], "hexpm", "ce708e5f094b9cd4e8f2be4f00d2f4250c4095be93f8cd6d018c753894885430"}, "dialyxir": {:hex, :dialyxir, "1.4.5", "ca1571ac18e0f88d4ab245f0b60fa31ff1b12cbae2b11bd25d207f865e8ae78a", [:mix], [{:erlex, ">= 0.2.7", [hex: :erlex, repo: "hexpm", optional: false]}], "hexpm", "b0fb08bb8107c750db5c0b324fa2df5ceaa0f9307690ee3c1f6ba5b9eb5d35c3"}, "earmark_parser": {:hex, :earmark_parser, "1.4.44", "f20830dd6b5c77afe2b063777ddbbff09f9759396500cdbe7523efd58d7a339c", [:mix], [], "hexpm", "4778ac752b4701a5599215f7030989c989ffdc4f6df457c5f36938cc2d2a2750"}, - "ecto": {:hex, :ecto, "3.13.2", "7d0c0863f3fc8d71d17fc3ad3b9424beae13f02712ad84191a826c7169484f01", [:mix], [{:decimal, "~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "669d9291370513ff56e7b7e7081b7af3283d02e046cf3d403053c557894a0b3e"}, + "ecto": {:hex, :ecto, "3.13.3", "6a983f0917f8bdc7a89e96f2bf013f220503a0da5d8623224ba987515b3f0d80", [:mix], [{:decimal, "~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "1927db768f53a88843ff25b6ba7946599a8ca8a055f69ad8058a1432a399af94"}, "ecto_dev_logger": {:hex, :ecto_dev_logger, "0.14.1", "af385ce1af1c4210ad67a4c46b985c370713446a179144a1da2885138c9fb242", [:mix], [{:ecto, "~> 3.7", [hex: :ecto, repo: "hexpm", optional: false]}, {:geo, "~> 3.5 or ~> 4.0", [hex: :geo, repo: "hexpm", optional: true]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "14a64ebae728b3c45db6ba8bb185979c8e01fc1b0d3d1d9c01c7a2b798e8c698"}, "ecto_sql": {:hex, :ecto_sql, "3.13.2", "a07d2461d84107b3d037097c822ffdd36ed69d1cf7c0f70e12a3d1decf04e2e1", [:mix], [{:db_connection, "~> 2.4.1 or ~> 2.5", [hex: :db_connection, repo: "hexpm", optional: false]}, {:ecto, "~> 3.13.0", [hex: :ecto, repo: "hexpm", optional: false]}, {:myxql, "~> 0.7", [hex: :myxql, repo: "hexpm", optional: true]}, {:postgrex, "~> 0.19 or ~> 1.0", [hex: :postgrex, repo: "hexpm", optional: true]}, {:tds, "~> 2.1.1 or ~> 2.2", [hex: :tds, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4.0 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "539274ab0ecf1a0078a6a72ef3465629e4d6018a3028095dc90f60a19c371717"}, "eflame": {:hex, :eflame, "1.0.1", "0664d287e39eef3c413749254b3af5f4f8b00be71c1af67d325331c4890be0fc", [:mix], [], "hexpm", "e0b08854a66f9013129de0b008488f3411ae9b69b902187837f994d7a99cf04e"}, @@ -23,7 +23,7 @@ "git_ops": {:hex, :git_ops, "2.8.0", "29ac9ab68bf9645973cb2752047b987e75cbd3d9761489c615e3ba80018fa885", [:mix], [{:git_cli, "~> 0.2", [hex: :git_cli, repo: "hexpm", optional: false]}, {:igniter, ">= 0.5.27 and < 1.0.0-0", [hex: :igniter, repo: "hexpm", optional: true]}, {:nimble_parsec, "~> 1.0", [hex: :nimble_parsec, repo: "hexpm", optional: false]}, {:req, "~> 0.5", [hex: :req, repo: "hexpm", optional: false]}], "hexpm", "b535e4ad6b5d13e14c455e76f65825659081b5530b0827eb0232d18719530eec"}, "glob_ex": {:hex, :glob_ex, "0.1.11", "cb50d3f1ef53f6ca04d6252c7fde09fd7a1cf63387714fe96f340a1349e62c93", [:mix], [], "hexpm", "342729363056e3145e61766b416769984c329e4378f1d558b63e341020525de4"}, "hpax": {:hex, :hpax, "1.0.3", "ed67ef51ad4df91e75cc6a1494f851850c0bd98ebc0be6e81b026e765ee535aa", [:mix], [], "hexpm", "8eab6e1cfa8d5918c2ce4ba43588e894af35dbd8e91e6e55c817bca5847df34a"}, - "igniter": {:hex, :igniter, "0.6.28", "9db10192f19f10b924f14c805f5b2ad992617fccaff9cf9582b7f065d562d4d8", [:mix], [{:glob_ex, "~> 0.1.7", [hex: :glob_ex, repo: "hexpm", optional: false]}, {:jason, "~> 1.4", [hex: :jason, repo: "hexpm", optional: false]}, {:owl, "~> 0.11", [hex: :owl, repo: "hexpm", optional: false]}, {:phx_new, "~> 1.7", [hex: :phx_new, repo: "hexpm", optional: true]}, {:req, "~> 0.5", [hex: :req, repo: "hexpm", optional: false]}, {:rewrite, ">= 1.1.1 and < 2.0.0-0", [hex: :rewrite, repo: "hexpm", optional: false]}, {:sourceror, "~> 1.4", [hex: :sourceror, repo: "hexpm", optional: false]}, {:spitfire, ">= 0.1.3 and < 1.0.0-0", [hex: :spitfire, repo: "hexpm", optional: false]}], "hexpm", "ad9369d626aeca21079ef17661a2672fb32598610c5e5bccae2537efd36b27d4"}, + "igniter": {:hex, :igniter, "0.6.29", "58ec46e601445df5ff3d98e65dce1305b10f23391d8f43558bc22bcbb3e1a7f0", [:mix], [{:glob_ex, "~> 0.1.7", [hex: :glob_ex, repo: "hexpm", optional: false]}, {:jason, "~> 1.4", [hex: :jason, repo: "hexpm", optional: false]}, {:owl, "~> 0.11", [hex: :owl, repo: "hexpm", optional: false]}, {:phx_new, "~> 1.7", [hex: :phx_new, repo: "hexpm", optional: true]}, {:req, "~> 0.5", [hex: :req, repo: "hexpm", optional: false]}, {:rewrite, ">= 1.1.1 and < 2.0.0-0", [hex: :rewrite, repo: "hexpm", optional: false]}, {:sourceror, "~> 1.4", [hex: :sourceror, repo: "hexpm", optional: false]}, {:spitfire, ">= 0.1.3 and < 1.0.0-0", [hex: :spitfire, repo: "hexpm", optional: false]}], "hexpm", "b45a5c70dcee77afd81a71c707fda7d0a8637061c60cdee639dc38d049443e02"}, "iterex": {:hex, :iterex, "0.1.2", "58f9b9b9a22a55cbfc7b5234a9c9c63eaac26d276b3db80936c0e1c60355a5a6", [:mix], [], "hexpm", "2e103b8bcc81757a9af121f6dc0df312c9a17220f302b1193ef720460d03029d"}, "jason": {:hex, :jason, "1.4.4", "b9226785a9aa77b6857ca22832cffa5d5011a667207eb2a0ad56adb5db443b8a", [:mix], [{:decimal, "~> 1.0 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm", "c5eb0cab91f094599f94d55bc63409236a8ec69a21a67814529e8d5f6cc90b3b"}, "libgraph": {:hex, :libgraph, "0.16.0", "3936f3eca6ef826e08880230f806bfea13193e49bf153f93edcf0239d4fd1d07", [:mix], [], "hexpm", "41ca92240e8a4138c30a7e06466acc709b0cbb795c643e9e17174a178982d6bf"}, @@ -38,7 +38,7 @@ "nimble_pool": {:hex, :nimble_pool, "1.1.0", "bf9c29fbdcba3564a8b800d1eeb5a3c58f36e1e11d7b7fb2e084a643f645f06b", [:mix], [], "hexpm", "af2e4e6b34197db81f7aad230c1118eac993acc0dae6bc83bac0126d4ae0813a"}, "owl": {:hex, :owl, "0.13.0", "26010e066d5992774268f3163506972ddac0a7e77bfe57fa42a250f24d6b876e", [:mix], [{:ucwidth, "~> 0.2", [hex: :ucwidth, repo: "hexpm", optional: true]}], "hexpm", "59bf9d11ce37a4db98f57cb68fbfd61593bf419ec4ed302852b6683d3d2f7475"}, "postgrex": {:hex, :postgrex, "0.21.1", "2c5cc830ec11e7a0067dd4d623c049b3ef807e9507a424985b8dcf921224cd88", [:mix], [{:db_connection, "~> 2.1", [hex: :db_connection, repo: "hexpm", optional: false]}, {:decimal, "~> 1.5 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:table, "~> 0.1.0", [hex: :table, repo: "hexpm", optional: true]}], "hexpm", "27d8d21c103c3cc68851b533ff99eef353e6a0ff98dc444ea751de43eb48bdac"}, - "reactor": {:hex, :reactor, "0.15.6", "d717f9add549b25a089a94c90197718d2d838e35d81dd776b1d81587d4cf2aaa", [:mix], [{:igniter, "~> 0.4", [hex: :igniter, repo: "hexpm", optional: true]}, {:iterex, "~> 0.1", [hex: :iterex, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}, {:libgraph, "~> 0.16", [hex: :libgraph, repo: "hexpm", optional: false]}, {:spark, "~> 2.0", [hex: :spark, repo: "hexpm", optional: false]}, {:splode, "~> 0.2", [hex: :splode, repo: "hexpm", optional: false]}, {:telemetry, "~> 1.2", [hex: :telemetry, repo: "hexpm", optional: false]}, {:yaml_elixir, "~> 2.11", [hex: :yaml_elixir, repo: "hexpm", optional: false]}, {:ymlr, "~> 5.0", [hex: :ymlr, repo: "hexpm", optional: false]}], "hexpm", "74db98165e3644d86e0f723672d91ceca4339eaa935bcad7e78bf146a46d77b9"}, + "reactor": {:hex, :reactor, "0.16.0", "394087fe0f01b09e5cbcbf6525d9a54cd484582214e0e9e59f69ebc8d79eb70c", [:mix], [{:igniter, "~> 0.4", [hex: :igniter, repo: "hexpm", optional: true]}, {:iterex, "~> 0.1", [hex: :iterex, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}, {:libgraph, "~> 0.16", [hex: :libgraph, repo: "hexpm", optional: false]}, {:spark, "~> 2.0", [hex: :spark, repo: "hexpm", optional: false]}, {:splode, "~> 0.2", [hex: :splode, repo: "hexpm", optional: false]}, {:telemetry, "~> 1.2", [hex: :telemetry, repo: "hexpm", optional: false]}, {:yaml_elixir, "~> 2.11", [hex: :yaml_elixir, repo: "hexpm", optional: false]}, {:ymlr, "~> 5.0", [hex: :ymlr, repo: "hexpm", optional: false]}], "hexpm", "9ac43e70a9a36c5a016b02b6c068933dfd36edc0e3abd9cd6325a30194900c66"}, "req": {:hex, :req, "0.5.15", "662020efb6ea60b9f0e0fac9be88cd7558b53fe51155a2d9899de594f9906ba9", [:mix], [{:brotli, "~> 0.3.1", [hex: :brotli, repo: "hexpm", optional: true]}, {:ezstd, "~> 1.0", [hex: :ezstd, repo: "hexpm", optional: true]}, {:finch, "~> 0.17", [hex: :finch, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}, {:mime, "~> 2.0.6 or ~> 2.1", [hex: :mime, repo: "hexpm", optional: false]}, {:nimble_csv, "~> 1.0", [hex: :nimble_csv, repo: "hexpm", optional: true]}, {:plug, "~> 1.0", [hex: :plug, repo: "hexpm", optional: true]}], "hexpm", "a6513a35fad65467893ced9785457e91693352c70b58bbc045b47e5eb2ef0c53"}, "rewrite": {:hex, :rewrite, "1.1.2", "f5a5d10f5fed1491a6ff48e078d4585882695962ccc9e6c779bae025d1f92eda", [:mix], [{:glob_ex, "~> 0.1", [hex: :glob_ex, repo: "hexpm", optional: false]}, {:sourceror, "~> 1.0", [hex: :sourceror, repo: "hexpm", optional: false]}, {:text_diff, "~> 0.1", [hex: :text_diff, repo: "hexpm", optional: false]}], "hexpm", "7f8b94b1e3528d0a47b3e8b7bfeca559d2948a65fa7418a9ad7d7712703d39d4"}, "simple_sat": {:hex, :simple_sat, "0.1.3", "f650fc3c184a5fe741868b5ac56dc77fdbb428468f6dbf1978e14d0334497578", [:mix], [], "hexpm", "a54305066a356b7194dc81db2a89232bacdc0b3edaef68ed9aba28dcbc34887b"}, From fefb612c3c873b65638e68df45f12edc41dcbd81 Mon Sep 17 00:00:00 2001 From: Zach Daniel Date: Sun, 21 Sep 2025 22:02:04 -0400 Subject: [PATCH 133/174] chore: format --- test/support/resources/settings.ex | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test/support/resources/settings.ex b/test/support/resources/settings.ex index 681584db..b24b3afc 100644 --- a/test/support/resources/settings.ex +++ b/test/support/resources/settings.ex @@ -3,8 +3,8 @@ defmodule AshPostgres.Test.Settings do use Ash.Resource, data_layer: :embedded attributes do - attribute :dues_reminders, {:array, :string}, public?: true - attribute :newsletter, {:array, :string}, public?: true - attribute :optional_field, :string, public?: true + attribute(:dues_reminders, {:array, :string}, public?: true) + attribute(:newsletter, {:array, :string}, public?: true) + attribute(:optional_field, :string, public?: true) end end From 36ccc75f52fcc545a6bccf45d0531e277bc38fde Mon Sep 17 00:00:00 2001 From: siassaj Date: Sat, 27 Sep 2025 11:59:43 +0300 Subject: [PATCH 134/174] improvement: use default constraint of 'now()' for AshPostgres.Timestamptz (#621) AshPostgres.Timestamptz creates a pg column of type 'timestamptz', however the existing default behaviour was to implement the default constraint as a 'timestamp' type. Effectively 'now()::timestamptz' was converted to 'timestamp' then back to 'timestamptz'. This has been changed to 'now()'. --- lib/migration_generator/migration_generator.ex | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/lib/migration_generator/migration_generator.ex b/lib/migration_generator/migration_generator.ex index 86920ed4..1a3a396d 100644 --- a/lib/migration_generator/migration_generator.ex +++ b/lib/migration_generator/migration_generator.ex @@ -3489,7 +3489,7 @@ defmodule AshPostgres.MigrationGenerator do @uuid_functions [&Ash.UUID.generate/0, &Ecto.UUID.generate/0] - defp default(%{name: name, default: default}, resource, _repo) when is_function(default) do + defp default(%{name: name, default: default, type: type}, resource, _repo) when is_function(default) do configured_default(resource, name) || cond do default in @uuid_functions -> @@ -3498,6 +3498,9 @@ defmodule AshPostgres.MigrationGenerator do default == (&Ash.UUIDv7.generate/0) -> ~S[fragment("uuid_generate_v7()")] + default == (&DateTime.utc_now/0) && type == AshPostgres.Timestamptz -> + ~S[fragment("now()")] + default == (&DateTime.utc_now/0) -> ~S[fragment("(now() AT TIME ZONE 'utc')")] From 4021b73e2609439c0cf853c7837b118bebfa1fc0 Mon Sep 17 00:00:00 2001 From: Zach Daniel Date: Sat, 27 Sep 2025 05:26:12 -0400 Subject: [PATCH 135/174] chore: update spark & fix warnings --- lib/check_constraint.ex | 2 +- lib/custom_index.ex | 3 ++- lib/reference.ex | 1 + lib/statement.ex | 3 ++- mix.exs | 1 + mix.lock | 4 ++-- 6 files changed, 9 insertions(+), 5 deletions(-) diff --git a/lib/check_constraint.ex b/lib/check_constraint.ex index 3cfeecd7..a16e7346 100644 --- a/lib/check_constraint.ex +++ b/lib/check_constraint.ex @@ -1,7 +1,7 @@ defmodule AshPostgres.CheckConstraint do @moduledoc "Represents a configured check constraint on the table backing a resource" - defstruct [:attribute, :name, :message, :check] + defstruct [:attribute, :name, :message, :check, :__spark_metadata__] def schema do [ diff --git a/lib/custom_index.ex b/lib/custom_index.ex index 9d037331..9972e4da 100644 --- a/lib/custom_index.ex +++ b/lib/custom_index.ex @@ -13,7 +13,8 @@ defmodule AshPostgres.CustomIndex do :include, :nulls_distinct, :message, - :all_tenants? + :all_tenants?, + :__spark_metadata__ ] defstruct @fields diff --git a/lib/reference.ex b/lib/reference.ex index 724251e0..e724a0b6 100644 --- a/lib/reference.ex +++ b/lib/reference.ex @@ -9,6 +9,7 @@ defmodule AshPostgres.Reference do :match_type, :deferrable, :index?, + :__spark_metadata__, ignore?: false ] diff --git a/lib/statement.ex b/lib/statement.ex index ae04496e..ba51622d 100644 --- a/lib/statement.ex +++ b/lib/statement.ex @@ -5,7 +5,8 @@ defmodule AshPostgres.Statement do :name, :up, :down, - :code? + :code?, + :__spark_metadata__ ] defstruct @fields diff --git a/mix.exs b/mix.exs index 22d502f0..6c02fab0 100644 --- a/mix.exs +++ b/mix.exs @@ -167,6 +167,7 @@ defmodule AshPostgres.MixProject do defp deps do [ {:ash, ash_version("~> 3.5 and >= 3.5.35")}, + {:spark, "~> 2.3 and >= 2.3.4"}, {:ash_sql, ash_sql_version("~> 0.2 and >= 0.2.90")}, {:igniter, "~> 0.6 and >= 0.6.14", optional: true}, {:ecto_sql, "~> 3.13"}, diff --git a/mix.lock b/mix.lock index 78a54f83..90c38313 100644 --- a/mix.lock +++ b/mix.lock @@ -23,7 +23,7 @@ "git_ops": {:hex, :git_ops, "2.8.0", "29ac9ab68bf9645973cb2752047b987e75cbd3d9761489c615e3ba80018fa885", [:mix], [{:git_cli, "~> 0.2", [hex: :git_cli, repo: "hexpm", optional: false]}, {:igniter, ">= 0.5.27 and < 1.0.0-0", [hex: :igniter, repo: "hexpm", optional: true]}, {:nimble_parsec, "~> 1.0", [hex: :nimble_parsec, repo: "hexpm", optional: false]}, {:req, "~> 0.5", [hex: :req, repo: "hexpm", optional: false]}], "hexpm", "b535e4ad6b5d13e14c455e76f65825659081b5530b0827eb0232d18719530eec"}, "glob_ex": {:hex, :glob_ex, "0.1.11", "cb50d3f1ef53f6ca04d6252c7fde09fd7a1cf63387714fe96f340a1349e62c93", [:mix], [], "hexpm", "342729363056e3145e61766b416769984c329e4378f1d558b63e341020525de4"}, "hpax": {:hex, :hpax, "1.0.3", "ed67ef51ad4df91e75cc6a1494f851850c0bd98ebc0be6e81b026e765ee535aa", [:mix], [], "hexpm", "8eab6e1cfa8d5918c2ce4ba43588e894af35dbd8e91e6e55c817bca5847df34a"}, - "igniter": {:hex, :igniter, "0.6.29", "58ec46e601445df5ff3d98e65dce1305b10f23391d8f43558bc22bcbb3e1a7f0", [:mix], [{:glob_ex, "~> 0.1.7", [hex: :glob_ex, repo: "hexpm", optional: false]}, {:jason, "~> 1.4", [hex: :jason, repo: "hexpm", optional: false]}, {:owl, "~> 0.11", [hex: :owl, repo: "hexpm", optional: false]}, {:phx_new, "~> 1.7", [hex: :phx_new, repo: "hexpm", optional: true]}, {:req, "~> 0.5", [hex: :req, repo: "hexpm", optional: false]}, {:rewrite, ">= 1.1.1 and < 2.0.0-0", [hex: :rewrite, repo: "hexpm", optional: false]}, {:sourceror, "~> 1.4", [hex: :sourceror, repo: "hexpm", optional: false]}, {:spitfire, ">= 0.1.3 and < 1.0.0-0", [hex: :spitfire, repo: "hexpm", optional: false]}], "hexpm", "b45a5c70dcee77afd81a71c707fda7d0a8637061c60cdee639dc38d049443e02"}, + "igniter": {:hex, :igniter, "0.6.30", "83a466369ebb8fe009e0823c7bf04314dc545122c2d48f896172fc79df33e99d", [:mix], [{:glob_ex, "~> 0.1.7", [hex: :glob_ex, repo: "hexpm", optional: false]}, {:jason, "~> 1.4", [hex: :jason, repo: "hexpm", optional: false]}, {:owl, "~> 0.11", [hex: :owl, repo: "hexpm", optional: false]}, {:phx_new, "~> 1.7", [hex: :phx_new, repo: "hexpm", optional: true]}, {:req, "~> 0.5", [hex: :req, repo: "hexpm", optional: false]}, {:rewrite, ">= 1.1.1 and < 2.0.0-0", [hex: :rewrite, repo: "hexpm", optional: false]}, {:sourceror, "~> 1.4", [hex: :sourceror, repo: "hexpm", optional: false]}, {:spitfire, ">= 0.1.3 and < 1.0.0-0", [hex: :spitfire, repo: "hexpm", optional: false]}], "hexpm", "76a14d5b7f850bb03b5243088c3649d54a2e52e34a2aa1104dee23cf50a8bae0"}, "iterex": {:hex, :iterex, "0.1.2", "58f9b9b9a22a55cbfc7b5234a9c9c63eaac26d276b3db80936c0e1c60355a5a6", [:mix], [], "hexpm", "2e103b8bcc81757a9af121f6dc0df312c9a17220f302b1193ef720460d03029d"}, "jason": {:hex, :jason, "1.4.4", "b9226785a9aa77b6857ca22832cffa5d5011a667207eb2a0ad56adb5db443b8a", [:mix], [{:decimal, "~> 1.0 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm", "c5eb0cab91f094599f94d55bc63409236a8ec69a21a67814529e8d5f6cc90b3b"}, "libgraph": {:hex, :libgraph, "0.16.0", "3936f3eca6ef826e08880230f806bfea13193e49bf153f93edcf0239d4fd1d07", [:mix], [], "hexpm", "41ca92240e8a4138c30a7e06466acc709b0cbb795c643e9e17174a178982d6bf"}, @@ -44,7 +44,7 @@ "simple_sat": {:hex, :simple_sat, "0.1.3", "f650fc3c184a5fe741868b5ac56dc77fdbb428468f6dbf1978e14d0334497578", [:mix], [], "hexpm", "a54305066a356b7194dc81db2a89232bacdc0b3edaef68ed9aba28dcbc34887b"}, "sobelow": {:hex, :sobelow, "0.14.0", "dd82aae8f72503f924fe9dd97ffe4ca694d2f17ec463dcfd365987c9752af6ee", [:mix], [{:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "7ecf91e298acfd9b24f5d761f19e8f6e6ac585b9387fb6301023f1f2cd5eed5f"}, "sourceror": {:hex, :sourceror, "1.10.0", "38397dedbbc286966ec48c7af13e228b171332be1ad731974438c77791945ce9", [:mix], [], "hexpm", "29dbdfc92e04569c9d8e6efdc422fc1d815f4bd0055dc7c51b8800fb75c4b3f1"}, - "spark": {:hex, :spark, "2.2.68", "4c4547c88d73311e3157bc402ab27f3a7bbd5e55a2ee92bcf7cd3a0a475d201e", [:mix], [{:igniter, ">= 0.3.64 and < 1.0.0-0", [hex: :igniter, repo: "hexpm", optional: true]}, {:jason, "~> 1.4", [hex: :jason, repo: "hexpm", optional: true]}, {:sourceror, "~> 1.2", [hex: :sourceror, repo: "hexpm", optional: true]}], "hexpm", "2fa4dd89801415a098a421589633f0e3df7ed9ff4046e80a65d35a413bc0d194"}, + "spark": {:hex, :spark, "2.3.4", "3fe37fdfa01e3f7c9f4ced16b7b9950d5bfbb7fab024148e1968b0460ce1336b", [:mix], [{:igniter, ">= 0.3.64 and < 1.0.0-0", [hex: :igniter, repo: "hexpm", optional: true]}, {:jason, "~> 1.4", [hex: :jason, repo: "hexpm", optional: true]}, {:sourceror, "~> 1.2", [hex: :sourceror, repo: "hexpm", optional: true]}], "hexpm", "c0293d41461f1c1f1774379c668a240b008f4f8dcd550ea82b06163a55dcd53b"}, "spitfire": {:hex, :spitfire, "0.2.1", "29e154873f05444669c7453d3d931820822cbca5170e88f0f8faa1de74a79b47", [:mix], [], "hexpm", "6eeed75054a38341b2e1814d41bb0a250564092358de2669fdb57ff88141d91b"}, "splode": {:hex, :splode, "0.2.9", "3a2776e187c82f42f5226b33b1220ccbff74f4bcc523dd4039c804caaa3ffdc7", [:mix], [], "hexpm", "8002b00c6e24f8bd1bcced3fbaa5c33346048047bb7e13d2f3ad428babbd95c3"}, "statistex": {:hex, :statistex, "1.1.0", "7fec1eb2f580a0d2c1a05ed27396a084ab064a40cfc84246dbfb0c72a5c761e5", [:mix], [], "hexpm", "f5950ea26ad43246ba2cce54324ac394a4e7408fdcf98b8e230f503a0cba9cf5"}, From 702ce5e56052a8ffd5399a9b52f7f9b2df94bf84 Mon Sep 17 00:00:00 2001 From: Zach Daniel Date: Sat, 27 Sep 2025 05:58:47 -0400 Subject: [PATCH 136/174] chore: update tests to account for warnings --- test/aggregate_test.exs | 55 ++++++++++++++++++--------------- test/references_test.exs | 66 +++++++++++++++++++++------------------- 2 files changed, 65 insertions(+), 56 deletions(-) diff --git a/test/aggregate_test.exs b/test/aggregate_test.exs index d17b753b..e26ca964 100644 --- a/test/aggregate_test.exs +++ b/test/aggregate_test.exs @@ -1,5 +1,6 @@ defmodule AshSql.AggregateTest do use AshPostgres.RepoCase, async: false + import ExUnit.CaptureIO alias AshPostgres.Test.{Author, Comment, Organization, Post, Rating, User} require Ash.Query @@ -970,37 +971,41 @@ defmodule AshSql.AggregateTest do end test "can't define multidimensional array aggregate types" do - assert_raise Spark.Error.DslError, ~r/Aggregate not supported/, fn -> - defmodule Foo do - @moduledoc false - use Ash.Resource, - domain: nil, - data_layer: AshPostgres.DataLayer - - postgres do - table("profile") - repo(AshPostgres.TestRepo) - end + # This used to raise an error, but now should only emit a warning and allow the module to compile + {_, io} = + with_io(:stderr, fn -> + defmodule Foo do + @moduledoc false + use Ash.Resource, + domain: nil, + data_layer: AshPostgres.DataLayer + + postgres do + table("profile") + repo(AshPostgres.TestRepo) + end - attributes do - uuid_primary_key(:id, writable?: true) - end + attributes do + uuid_primary_key(:id, writable?: true) + end - actions do - defaults([:create, :read, :update, :destroy]) - end + actions do + defaults([:create, :read, :update, :destroy]) + end - relationships do - belongs_to(:author, AshPostgres.Test.Author) do - public?(true) + relationships do + belongs_to(:author, AshPostgres.Test.Author) do + public?(true) + end end - end - aggregates do - first(:author_badges, :author, :badges) + aggregates do + first(:author_badges, :author, :badges) + end end - end - end + end) + + assert io =~ "Aggregate not supported" end test "related aggregates can be filtered on" do diff --git a/test/references_test.exs b/test/references_test.exs index a8be1d07..7632c9f8 100644 --- a/test/references_test.exs +++ b/test/references_test.exs @@ -1,5 +1,6 @@ defmodule AshPostgres.ReferencesTest do use AshPostgres.RepoCase + import ExUnit.CaptureIO test "can't use match_type != :full when referencing an non-primary key index" do Code.compiler_options(ignore_module_conflict: true) @@ -66,44 +67,47 @@ defmodule AshPostgres.ReferencesTest do end end - assert_raise Spark.Error.DslError, ~r/Unsupported match_type./, fn -> - defmodule UserThing do - @moduledoc false - use Ash.Resource, - domain: nil, - data_layer: AshPostgres.DataLayer - - attributes do - attribute(:id, :string, primary_key?: true, allow_nil?: false, public?: true) - attribute(:name, :string, public?: true) - attribute(:org_id, :uuid, public?: true) - attribute(:foo_id, :uuid, public?: true) - end + {_, io} = + with_io(:stderr, fn -> + defmodule UserThing do + @moduledoc false + use Ash.Resource, + domain: nil, + data_layer: AshPostgres.DataLayer + + attributes do + attribute(:id, :string, primary_key?: true, allow_nil?: false, public?: true) + attribute(:name, :string, public?: true) + attribute(:org_id, :uuid, public?: true) + attribute(:foo_id, :uuid, public?: true) + end - multitenancy do - strategy(:attribute) - attribute(:org_id) - end + multitenancy do + strategy(:attribute) + attribute(:org_id) + end - relationships do - belongs_to(:org, Org) - belongs_to(:user, User, destination_attribute: :secondary_id) - end + relationships do + belongs_to(:org, Org) + belongs_to(:user, User, destination_attribute: :secondary_id) + end - postgres do - table("user_things") - repo(AshPostgres.TestRepo) + postgres do + table("user_things") + repo(AshPostgres.TestRepo) - references do - reference :user, match_with: [foo_id: :foo_id], match_type: :simple + references do + reference :user, match_with: [foo_id: :foo_id], match_type: :simple + end end - end - actions do - defaults([:create, :read, :update, :destroy]) + actions do + defaults([:create, :read, :update, :destroy]) + end end - end - end + end) + + assert io =~ "Unsupported match_type" end test "named reference results in properly applied foreign_key_constraint/3 on the underlying changeset" do From a35894b08caf915e3b205cd19f6b3735b30cc2aa Mon Sep 17 00:00:00 2001 From: Zach Daniel Date: Sat, 27 Sep 2025 06:18:14 -0400 Subject: [PATCH 137/174] improvement: location in spark errors and migration generator fixes --- lib/custom_index.ex | 5 ++--- lib/migration_generator/migration_generator.ex | 8 ++++++-- lib/statement.ex | 5 ++--- lib/verifiers/ensure_table_or_polymorphic.ex | 3 ++- ...ent_attribute_multitenancy_and_non_full_match_type.ex | 3 ++- .../prevent_multidimensional_array_aggregates.ex | 3 ++- lib/verifiers/validate_identity_index_names.ex | 9 ++++++--- lib/verifiers/validate_references.ex | 3 ++- 8 files changed, 24 insertions(+), 15 deletions(-) diff --git a/lib/custom_index.ex b/lib/custom_index.ex index 9972e4da..29496ceb 100644 --- a/lib/custom_index.ex +++ b/lib/custom_index.ex @@ -13,11 +13,10 @@ defmodule AshPostgres.CustomIndex do :include, :nulls_distinct, :message, - :all_tenants?, - :__spark_metadata__ + :all_tenants? ] - defstruct @fields + defstruct @fields ++ [:__spark_metadata__] def fields, do: @fields diff --git a/lib/migration_generator/migration_generator.ex b/lib/migration_generator/migration_generator.ex index 1a3a396d..c0a1abac 100644 --- a/lib/migration_generator/migration_generator.ex +++ b/lib/migration_generator/migration_generator.ex @@ -3044,6 +3044,7 @@ defmodule AshPostgres.MigrationGenerator do identity_index_names[identity.name] || "#{relationship.context[:data_layer][:table]}_#{identity.name}_index" ) + |> Map.delete(:__spark_metadata__) end) end) |> Map.update!(:attributes, fn attributes -> @@ -3057,7 +3058,9 @@ defmodule AshPostgres.MigrationGenerator do source_attribute = Ash.Resource.Info.attribute(relationship.source, relationship.source_attribute) - Map.put(attribute, :references, %{ + attribute + |> Map.delete(:__spark_metadata__) + |> Map.put(:references, %{ destination_attribute: source_attribute.source, destination_attribute_default: default( @@ -3489,7 +3492,8 @@ defmodule AshPostgres.MigrationGenerator do @uuid_functions [&Ash.UUID.generate/0, &Ecto.UUID.generate/0] - defp default(%{name: name, default: default, type: type}, resource, _repo) when is_function(default) do + defp default(%{name: name, default: default, type: type}, resource, _repo) + when is_function(default) do configured_default(resource, name) || cond do default in @uuid_functions -> diff --git a/lib/statement.ex b/lib/statement.ex index ba51622d..dfc49322 100644 --- a/lib/statement.ex +++ b/lib/statement.ex @@ -5,11 +5,10 @@ defmodule AshPostgres.Statement do :name, :up, :down, - :code?, - :__spark_metadata__ + :code? ] - defstruct @fields + defstruct @fields ++ [:__spark_metadata__] def fields, do: @fields diff --git a/lib/verifiers/ensure_table_or_polymorphic.ex b/lib/verifiers/ensure_table_or_polymorphic.ex index 1f60b8ed..c2e612ca 100644 --- a/lib/verifiers/ensure_table_or_polymorphic.ex +++ b/lib/verifiers/ensure_table_or_polymorphic.ex @@ -24,7 +24,8 @@ defmodule AshPostgres.Verifiers.EnsureTableOrPolymorphic do end ``` """, - path: [:postgres, :table] + path: [:postgres, :table], + location: Spark.Dsl.Transformer.get_section_anno(dsl, [:postgres]) end end end diff --git a/lib/verifiers/prevent_attribute_multitenancy_and_non_full_match_type.ex b/lib/verifiers/prevent_attribute_multitenancy_and_non_full_match_type.ex index 0d9e71c8..5e0a25cc 100644 --- a/lib/verifiers/prevent_attribute_multitenancy_and_non_full_match_type.ex +++ b/lib/verifiers/prevent_attribute_multitenancy_and_non_full_match_type.ex @@ -23,7 +23,8 @@ defmodule AshPostgres.Verifiers.PreventAttributeMultitenancyAndNonFullMatchType The reference #{inspect(resource)}.#{reference.relationship} can't have `match_type: :#{reference.match_type}` because it's referencing another multitenant resource with attribute strategy using a non-primary key index, which requires using `match_type: :full`. """, - path: [:postgres, :references, reference.relationship] + path: [:postgres, :references, reference.relationship], + location: Spark.Dsl.Transformer.get_section_anno(dsl, [:postgres, :references]) else :ok end diff --git a/lib/verifiers/prevent_multidimensional_array_aggregates.ex b/lib/verifiers/prevent_multidimensional_array_aggregates.ex index cdb688b4..5bea26eb 100644 --- a/lib/verifiers/prevent_multidimensional_array_aggregates.ex +++ b/lib/verifiers/prevent_multidimensional_array_aggregates.ex @@ -35,7 +35,8 @@ defmodule AshPostgres.Verifiers.PreventMultidimensionalArrayAggregates do Postgres does not support multidimensional arrays with differing lengths internally. In the future we may be able to remove this restriction for the `:first` type aggregate, but likely never for `:list`. In the meantime, you will have to use a custom calculation to get this data. - """ + """, + location: Ash.Resource.Info.aggregate(resource, aggregate.name) |> Spark.Dsl.Entity.anno() _ -> :ok diff --git a/lib/verifiers/validate_identity_index_names.ex b/lib/verifiers/validate_identity_index_names.ex index 269e881e..91ef203c 100644 --- a/lib/verifiers/validate_identity_index_names.ex +++ b/lib/verifiers/validate_identity_index_names.ex @@ -14,7 +14,8 @@ defmodule AshPostgres.Verifiers.ValidateIdentityIndexNames do module: Verifier.get_persisted(dsl, :module), message: """ Identity #{identity} has a name that is too long. Names must be 63 characters or less. - """ + """, + location: Spark.Dsl.Transformer.get_opt_anno(dsl, [:postgres, :identity_index_names], identity) end end) @@ -36,7 +37,8 @@ defmodule AshPostgres.Verifiers.ValidateIdentityIndexNames do Multiple identities would result in the same index name: #{name} Identities: #{inspect(Enum.map(identities, & &1.name))} - """ + """, + location: Spark.Dsl.Transformer.get_section_anno(dsl, [:postgres, :identity_index_names]) {name, [identity]} -> if String.length(name) > 63 do @@ -51,7 +53,8 @@ defmodule AshPostgres.Verifiers.ValidateIdentityIndexNames do postgres do identity_index_names #{identity.name}: "a_shorter_name" end - """ + """, + location: Spark.Dsl.Entity.anno(identity) end end) end diff --git a/lib/verifiers/validate_references.ex b/lib/verifiers/validate_references.ex index 3f2c90aa..40c47a8e 100644 --- a/lib/verifiers/validate_references.ex +++ b/lib/verifiers/validate_references.ex @@ -12,7 +12,8 @@ defmodule AshPostgres.Verifiers.ValidateReferences do path: [:postgres, :references, reference.relationship], module: Verifier.get_persisted(dsl, :module), message: - "Found reference configuration for relationship `#{reference.relationship}`, but no such relationship exists" + "Found reference configuration for relationship `#{reference.relationship}`, but no such relationship exists", + location: Spark.Dsl.Transformer.get_section_anno(dsl, [:postgres, :references]) end end) From 03d26cbbb4fdda321834267a10ef72e119180763 Mon Sep 17 00:00:00 2001 From: Zach Daniel Date: Sat, 27 Sep 2025 06:29:51 -0400 Subject: [PATCH 138/174] chore: more fixes around spark_metadata --- lib/migration_generator/migration_generator.ex | 3 +++ 1 file changed, 3 insertions(+) diff --git a/lib/migration_generator/migration_generator.ex b/lib/migration_generator/migration_generator.ex index c0a1abac..fcb44c95 100644 --- a/lib/migration_generator/migration_generator.ex +++ b/lib/migration_generator/migration_generator.ex @@ -3580,6 +3580,7 @@ defmodule AshPostgres.MigrationGenerator do end) %{index | fields: fields} + |> Map.delete(:__spark_metadata__) end) end) |> Map.update!(:identities, fn identities -> @@ -3591,6 +3592,7 @@ defmodule AshPostgres.MigrationGenerator do end) %{identity | keys: keys} + |> Map.delete(:__spark_metadata__) end) end) |> to_ordered_object() @@ -3610,6 +3612,7 @@ defmodule AshPostgres.MigrationGenerator do |> Map.update!(:type, fn type -> sanitize_type(type, attribute[:size], attribute[:precision], attribute[:scale]) end) + |> Map.delete(:__spark_metadata__) end defp references_on_delete_to_binary(value) when is_atom(value), do: value From 7be8af41ffdd4650c2e70d380b2b44b20d2faf6e Mon Sep 17 00:00:00 2001 From: Zach Daniel Date: Sat, 27 Sep 2025 06:31:44 -0400 Subject: [PATCH 139/174] chore: format --- lib/verifiers/prevent_multidimensional_array_aggregates.ex | 3 ++- lib/verifiers/validate_identity_index_names.ex | 6 ++++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/lib/verifiers/prevent_multidimensional_array_aggregates.ex b/lib/verifiers/prevent_multidimensional_array_aggregates.ex index 5bea26eb..82a38202 100644 --- a/lib/verifiers/prevent_multidimensional_array_aggregates.ex +++ b/lib/verifiers/prevent_multidimensional_array_aggregates.ex @@ -36,7 +36,8 @@ defmodule AshPostgres.Verifiers.PreventMultidimensionalArrayAggregates do Postgres does not support multidimensional arrays with differing lengths internally. In the future we may be able to remove this restriction for the `:first` type aggregate, but likely never for `:list`. In the meantime, you will have to use a custom calculation to get this data. """, - location: Ash.Resource.Info.aggregate(resource, aggregate.name) |> Spark.Dsl.Entity.anno() + location: + Ash.Resource.Info.aggregate(resource, aggregate.name) |> Spark.Dsl.Entity.anno() _ -> :ok diff --git a/lib/verifiers/validate_identity_index_names.ex b/lib/verifiers/validate_identity_index_names.ex index 91ef203c..82457eb2 100644 --- a/lib/verifiers/validate_identity_index_names.ex +++ b/lib/verifiers/validate_identity_index_names.ex @@ -15,7 +15,8 @@ defmodule AshPostgres.Verifiers.ValidateIdentityIndexNames do message: """ Identity #{identity} has a name that is too long. Names must be 63 characters or less. """, - location: Spark.Dsl.Transformer.get_opt_anno(dsl, [:postgres, :identity_index_names], identity) + location: + Spark.Dsl.Transformer.get_opt_anno(dsl, [:postgres, :identity_index_names], identity) end end) @@ -38,7 +39,8 @@ defmodule AshPostgres.Verifiers.ValidateIdentityIndexNames do Identities: #{inspect(Enum.map(identities, & &1.name))} """, - location: Spark.Dsl.Transformer.get_section_anno(dsl, [:postgres, :identity_index_names]) + location: + Spark.Dsl.Transformer.get_section_anno(dsl, [:postgres, :identity_index_names]) {name, [identity]} -> if String.length(name) > 63 do From ed3ff07c8c1287b36f2ad4925c79c5590bc38e6c Mon Sep 17 00:00:00 2001 From: Zach Daniel Date: Sat, 27 Sep 2025 06:31:55 -0400 Subject: [PATCH 140/174] chore: release version v2.6.20 --- CHANGELOG.md | 15 +++++++++++++++ mix.exs | 2 +- 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4b9eaa03..f6546f3a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,21 @@ See [Conventional Commits](https://www.conventionalcommits.org) for commit guide +## [v2.6.20](https://github.com/ash-project/ash_postgres/compare/v2.6.19...v2.6.20) (2025-09-27) + + + + +### Bug Fixes: + +* use `:mutate` repo for on_transaction_begin callback by Zach Daniel + +### Improvements: + +* location in spark errors and migration generator fixes by Zach Daniel + +* use default constraint of 'now()' for AshPostgres.Timestamptz (#621) by siassaj + ## [v2.6.19](https://github.com/ash-project/ash_postgres/compare/v2.6.18...v2.6.19) (2025-09-20) diff --git a/mix.exs b/mix.exs index 6c02fab0..00778fec 100644 --- a/mix.exs +++ b/mix.exs @@ -5,7 +5,7 @@ defmodule AshPostgres.MixProject do The PostgreSQL data layer for Ash Framework """ - @version "2.6.19" + @version "2.6.20" def project do [ From 1130a0235da46e82d452ea9ca08b415cebf8678a Mon Sep 17 00:00:00 2001 From: Chris O'Donnell Date: Sun, 28 Sep 2025 21:11:05 -0400 Subject: [PATCH 141/174] test: write failing test to illustrate regression (#622) --- test/aggregate_test.exs | 47 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/test/aggregate_test.exs b/test/aggregate_test.exs index e26ca964..4803ec5c 100644 --- a/test/aggregate_test.exs +++ b/test/aggregate_test.exs @@ -1683,4 +1683,51 @@ defmodule AshSql.AggregateTest do |> Ash.read_one!() end end + + @tag :regression + test "count is accurate" do + org = + AshPostgres.Test.Organization + |> Ash.Changeset.for_create(:create, %{name: "Test Org"}) + |> Ash.create!() + + user = + AshPostgres.Test.User + |> Ash.Changeset.for_create(:create, %{name: "test_user", organization_id: org.id}) + |> Ash.create!() + + AshPostgres.Test.User + |> Ash.Changeset.for_create(:create, %{name: "another_user", organization_id: org.id}) + |> Ash.create!() + + author = + AshPostgres.Test.Author + |> Ash.Changeset.for_create(:create, %{first_name: "Test", last_name: "Author"}) + |> Ash.create!() + + post = + AshPostgres.Test.Post + |> Ash.Changeset.for_create(:create, %{ + title: "Test Post", + organization_id: org.id, + author_id: author.id + }) + |> Ash.create!() + + AshPostgres.Test.Comment + |> Ash.Changeset.for_create(:create, %{ + title: "First comment", + post_id: post.id, + author_id: author.id + }) + |> Ash.create!() + + loaded_post = + AshPostgres.Test.Post + |> Ash.Query.filter(id == ^post.id) + |> Ash.Query.load(:count_of_comments) + |> Ash.read_one!(actor: user) + + assert loaded_post.count_of_comments == 1 + end end From 28862b1c78ebb1277f7571824e39b7f8ec689a12 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 1 Oct 2025 23:19:13 -0400 Subject: [PATCH 142/174] chore(deps): bump the production-dependencies group with 3 updates (#625) Bumps the production-dependencies group with 3 updates: [ash](https://github.com/ash-project/ash), [ash_sql](https://github.com/ash-project/ash_sql) and [spark](https://github.com/ash-project/spark). Updates `ash` from 3.5.42 to 3.5.43 - [Release notes](https://github.com/ash-project/ash/releases) - [Changelog](https://github.com/ash-project/ash/blob/main/CHANGELOG.md) - [Commits](https://github.com/ash-project/ash/compare/v3.5.42...v3.5.43) Updates `ash_sql` from 0.2.93 to 0.3.0 - [Release notes](https://github.com/ash-project/ash_sql/releases) - [Changelog](https://github.com/ash-project/ash_sql/blob/main/CHANGELOG.md) - [Commits](https://github.com/ash-project/ash_sql/compare/v0.2.93...v0.3.0) Updates `spark` from 2.3.4 to 2.3.5 - [Release notes](https://github.com/ash-project/spark/releases) - [Changelog](https://github.com/ash-project/spark/blob/main/CHANGELOG.md) - [Commits](https://github.com/ash-project/spark/compare/v2.3.4...v2.3.5) --- updated-dependencies: - dependency-name: ash dependency-version: 3.5.43 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: production-dependencies - dependency-name: ash_sql dependency-version: 0.3.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: production-dependencies - dependency-name: spark dependency-version: 2.3.5 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: production-dependencies ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- mix.lock | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/mix.lock b/mix.lock index 90c38313..726124db 100644 --- a/mix.lock +++ b/mix.lock @@ -1,6 +1,6 @@ %{ - "ash": {:hex, :ash, "3.5.42", "bdd84c468c05e497a8b1ee579901274125c540b66df82ed67c35f889a529ee70", [:mix], [{:decimal, "~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:ecto, "~> 3.7", [hex: :ecto, repo: "hexpm", optional: false]}, {:ets, "~> 0.8", [hex: :ets, repo: "hexpm", optional: false]}, {:igniter, ">= 0.6.29 and < 1.0.0-0", [hex: :igniter, repo: "hexpm", optional: true]}, {:jason, ">= 1.0.0", [hex: :jason, repo: "hexpm", optional: false]}, {:picosat_elixir, "~> 0.2", [hex: :picosat_elixir, repo: "hexpm", optional: true]}, {:plug, ">= 0.0.0", [hex: :plug, repo: "hexpm", optional: true]}, {:reactor, "~> 0.11", [hex: :reactor, repo: "hexpm", optional: false]}, {:simple_sat, ">= 0.1.1 and < 1.0.0-0", [hex: :simple_sat, repo: "hexpm", optional: true]}, {:spark, ">= 2.2.68 and < 3.0.0-0", [hex: :spark, repo: "hexpm", optional: false]}, {:splode, ">= 0.2.6 and < 1.0.0-0", [hex: :splode, repo: "hexpm", optional: false]}, {:stream_data, "~> 1.0", [hex: :stream_data, repo: "hexpm", optional: false]}, {:telemetry, "~> 1.1", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "dc0988e171630401e8eab65c95ac33c04b8fe47084fc038e80f4d713cb2d44ba"}, - "ash_sql": {:hex, :ash_sql, "0.2.93", "d2e50a718f18e67bffa8fd9c7bea39d260ca746ca4df357bd9726a3ad4a39294", [:mix], [{:ash, ">= 3.5.35 and < 4.0.0-0", [hex: :ash, repo: "hexpm", optional: false]}, {:ecto, "~> 3.9", [hex: :ecto, repo: "hexpm", optional: false]}, {:ecto_sql, "~> 3.9", [hex: :ecto_sql, repo: "hexpm", optional: false]}], "hexpm", "492d811a636c19dad990c4f1af83761c0006ec5650970252f78cf4bd2b50b500"}, + "ash": {:hex, :ash, "3.5.43", "222f9a8ac26ad3b029f8e69306cc83091c992d858b4538af12e33a148f301cab", [:mix], [{:decimal, "~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:ecto, "~> 3.7", [hex: :ecto, repo: "hexpm", optional: false]}, {:ets, "~> 0.8", [hex: :ets, repo: "hexpm", optional: false]}, {:igniter, ">= 0.6.29 and < 1.0.0-0", [hex: :igniter, repo: "hexpm", optional: true]}, {:jason, ">= 1.0.0", [hex: :jason, repo: "hexpm", optional: false]}, {:picosat_elixir, "~> 0.2", [hex: :picosat_elixir, repo: "hexpm", optional: true]}, {:plug, ">= 0.0.0", [hex: :plug, repo: "hexpm", optional: true]}, {:reactor, "~> 0.11", [hex: :reactor, repo: "hexpm", optional: false]}, {:simple_sat, ">= 0.1.1 and < 1.0.0-0", [hex: :simple_sat, repo: "hexpm", optional: true]}, {:spark, ">= 2.3.3 and < 3.0.0-0", [hex: :spark, repo: "hexpm", optional: false]}, {:splode, ">= 0.2.6 and < 1.0.0-0", [hex: :splode, repo: "hexpm", optional: false]}, {:stream_data, "~> 1.0", [hex: :stream_data, repo: "hexpm", optional: false]}, {:telemetry, "~> 1.1", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "48b2aa274c524f5b968c563dd56aec8f9b278c529c8aa46e6fe0ca564c26cc1c"}, + "ash_sql": {:hex, :ash_sql, "0.3.0", "2c43ddcc8c7fb51dc25ba3bca965d8b68e7aaecb290cabfed3cf213965aca937", [:mix], [{:ash, ">= 3.5.43 and < 4.0.0-0", [hex: :ash, repo: "hexpm", optional: false]}, {:ecto, "~> 3.9", [hex: :ecto, repo: "hexpm", optional: false]}, {:ecto_sql, "~> 3.9", [hex: :ecto_sql, repo: "hexpm", optional: false]}], "hexpm", "ef03759d6a1d4cb189fcadbd183cf047f0565d7d88ea8612d85c9e6e724835e7"}, "benchee": {:hex, :benchee, "1.4.0", "9f1f96a30ac80bab94faad644b39a9031d5632e517416a8ab0a6b0ac4df124ce", [:mix], [{:deep_merge, "~> 1.0", [hex: :deep_merge, repo: "hexpm", optional: false]}, {:statistex, "~> 1.0", [hex: :statistex, repo: "hexpm", optional: false]}, {:table, "~> 0.1.0", [hex: :table, repo: "hexpm", optional: true]}], "hexpm", "299cd10dd8ce51c9ea3ddb74bb150f93d25e968f93e4c1fa31698a8e4fa5d715"}, "bunt": {:hex, :bunt, "1.0.0", "081c2c665f086849e6d57900292b3a161727ab40431219529f13c4ddcf3e7a44", [:mix], [], "hexpm", "dc5f86aa08a5f6fa6b8096f0735c4e76d54ae5c9fa2c143e5a1fc7c1cd9bb6b5"}, "credo": {:hex, :credo, "1.7.12", "9e3c20463de4b5f3f23721527fcaf16722ec815e70ff6c60b86412c695d426c1", [:mix], [{:bunt, "~> 0.2.1 or ~> 1.0", [hex: :bunt, repo: "hexpm", optional: false]}, {:file_system, "~> 0.2 or ~> 1.0", [hex: :file_system, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "8493d45c656c5427d9c729235b99d498bd133421f3e0a683e5c1b561471291e5"}, @@ -38,13 +38,13 @@ "nimble_pool": {:hex, :nimble_pool, "1.1.0", "bf9c29fbdcba3564a8b800d1eeb5a3c58f36e1e11d7b7fb2e084a643f645f06b", [:mix], [], "hexpm", "af2e4e6b34197db81f7aad230c1118eac993acc0dae6bc83bac0126d4ae0813a"}, "owl": {:hex, :owl, "0.13.0", "26010e066d5992774268f3163506972ddac0a7e77bfe57fa42a250f24d6b876e", [:mix], [{:ucwidth, "~> 0.2", [hex: :ucwidth, repo: "hexpm", optional: true]}], "hexpm", "59bf9d11ce37a4db98f57cb68fbfd61593bf419ec4ed302852b6683d3d2f7475"}, "postgrex": {:hex, :postgrex, "0.21.1", "2c5cc830ec11e7a0067dd4d623c049b3ef807e9507a424985b8dcf921224cd88", [:mix], [{:db_connection, "~> 2.1", [hex: :db_connection, repo: "hexpm", optional: false]}, {:decimal, "~> 1.5 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:table, "~> 0.1.0", [hex: :table, repo: "hexpm", optional: true]}], "hexpm", "27d8d21c103c3cc68851b533ff99eef353e6a0ff98dc444ea751de43eb48bdac"}, - "reactor": {:hex, :reactor, "0.16.0", "394087fe0f01b09e5cbcbf6525d9a54cd484582214e0e9e59f69ebc8d79eb70c", [:mix], [{:igniter, "~> 0.4", [hex: :igniter, repo: "hexpm", optional: true]}, {:iterex, "~> 0.1", [hex: :iterex, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}, {:libgraph, "~> 0.16", [hex: :libgraph, repo: "hexpm", optional: false]}, {:spark, "~> 2.0", [hex: :spark, repo: "hexpm", optional: false]}, {:splode, "~> 0.2", [hex: :splode, repo: "hexpm", optional: false]}, {:telemetry, "~> 1.2", [hex: :telemetry, repo: "hexpm", optional: false]}, {:yaml_elixir, "~> 2.11", [hex: :yaml_elixir, repo: "hexpm", optional: false]}, {:ymlr, "~> 5.0", [hex: :ymlr, repo: "hexpm", optional: false]}], "hexpm", "9ac43e70a9a36c5a016b02b6c068933dfd36edc0e3abd9cd6325a30194900c66"}, + "reactor": {:hex, :reactor, "0.17.0", "eb8bdb530dbae824e2d36a8538f8ec4f3aa7c2d1b61b04959fa787c634f88b49", [:mix], [{:igniter, "~> 0.4", [hex: :igniter, repo: "hexpm", optional: true]}, {:iterex, "~> 0.1", [hex: :iterex, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}, {:libgraph, "~> 0.16", [hex: :libgraph, repo: "hexpm", optional: false]}, {:spark, ">= 2.3.3 and < 3.0.0-0", [hex: :spark, repo: "hexpm", optional: false]}, {:splode, "~> 0.2", [hex: :splode, repo: "hexpm", optional: false]}, {:telemetry, "~> 1.2", [hex: :telemetry, repo: "hexpm", optional: false]}, {:yaml_elixir, "~> 2.11", [hex: :yaml_elixir, repo: "hexpm", optional: false]}, {:ymlr, "~> 5.0", [hex: :ymlr, repo: "hexpm", optional: false]}], "hexpm", "3c3bf71693adbad9117b11ec83cfed7d5851b916ade508ed9718de7ae165bf25"}, "req": {:hex, :req, "0.5.15", "662020efb6ea60b9f0e0fac9be88cd7558b53fe51155a2d9899de594f9906ba9", [:mix], [{:brotli, "~> 0.3.1", [hex: :brotli, repo: "hexpm", optional: true]}, {:ezstd, "~> 1.0", [hex: :ezstd, repo: "hexpm", optional: true]}, {:finch, "~> 0.17", [hex: :finch, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}, {:mime, "~> 2.0.6 or ~> 2.1", [hex: :mime, repo: "hexpm", optional: false]}, {:nimble_csv, "~> 1.0", [hex: :nimble_csv, repo: "hexpm", optional: true]}, {:plug, "~> 1.0", [hex: :plug, repo: "hexpm", optional: true]}], "hexpm", "a6513a35fad65467893ced9785457e91693352c70b58bbc045b47e5eb2ef0c53"}, "rewrite": {:hex, :rewrite, "1.1.2", "f5a5d10f5fed1491a6ff48e078d4585882695962ccc9e6c779bae025d1f92eda", [:mix], [{:glob_ex, "~> 0.1", [hex: :glob_ex, repo: "hexpm", optional: false]}, {:sourceror, "~> 1.0", [hex: :sourceror, repo: "hexpm", optional: false]}, {:text_diff, "~> 0.1", [hex: :text_diff, repo: "hexpm", optional: false]}], "hexpm", "7f8b94b1e3528d0a47b3e8b7bfeca559d2948a65fa7418a9ad7d7712703d39d4"}, "simple_sat": {:hex, :simple_sat, "0.1.3", "f650fc3c184a5fe741868b5ac56dc77fdbb428468f6dbf1978e14d0334497578", [:mix], [], "hexpm", "a54305066a356b7194dc81db2a89232bacdc0b3edaef68ed9aba28dcbc34887b"}, "sobelow": {:hex, :sobelow, "0.14.0", "dd82aae8f72503f924fe9dd97ffe4ca694d2f17ec463dcfd365987c9752af6ee", [:mix], [{:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "7ecf91e298acfd9b24f5d761f19e8f6e6ac585b9387fb6301023f1f2cd5eed5f"}, "sourceror": {:hex, :sourceror, "1.10.0", "38397dedbbc286966ec48c7af13e228b171332be1ad731974438c77791945ce9", [:mix], [], "hexpm", "29dbdfc92e04569c9d8e6efdc422fc1d815f4bd0055dc7c51b8800fb75c4b3f1"}, - "spark": {:hex, :spark, "2.3.4", "3fe37fdfa01e3f7c9f4ced16b7b9950d5bfbb7fab024148e1968b0460ce1336b", [:mix], [{:igniter, ">= 0.3.64 and < 1.0.0-0", [hex: :igniter, repo: "hexpm", optional: true]}, {:jason, "~> 1.4", [hex: :jason, repo: "hexpm", optional: true]}, {:sourceror, "~> 1.2", [hex: :sourceror, repo: "hexpm", optional: true]}], "hexpm", "c0293d41461f1c1f1774379c668a240b008f4f8dcd550ea82b06163a55dcd53b"}, + "spark": {:hex, :spark, "2.3.5", "f30d30ecc3b4ab9b932d9aada66af7677fc1f297a2c349b0bcec3eafb9f996e8", [:mix], [{:igniter, ">= 0.3.64 and < 1.0.0-0", [hex: :igniter, repo: "hexpm", optional: true]}, {:jason, "~> 1.4", [hex: :jason, repo: "hexpm", optional: true]}, {:sourceror, "~> 1.2", [hex: :sourceror, repo: "hexpm", optional: true]}], "hexpm", "0e9d339704d5d148f77f2b2fef3bcfc873a9e9bb4224fcf289c545d65827202f"}, "spitfire": {:hex, :spitfire, "0.2.1", "29e154873f05444669c7453d3d931820822cbca5170e88f0f8faa1de74a79b47", [:mix], [], "hexpm", "6eeed75054a38341b2e1814d41bb0a250564092358de2669fdb57ff88141d91b"}, "splode": {:hex, :splode, "0.2.9", "3a2776e187c82f42f5226b33b1220ccbff74f4bcc523dd4039c804caaa3ffdc7", [:mix], [], "hexpm", "8002b00c6e24f8bd1bcced3fbaa5c33346048047bb7e13d2f3ad428babbd95c3"}, "statistex": {:hex, :statistex, "1.1.0", "7fec1eb2f580a0d2c1a05ed27396a084ab064a40cfc84246dbfb0c72a5c761e5", [:mix], [], "hexpm", "f5950ea26ad43246ba2cce54324ac394a4e7408fdcf98b8e230f503a0cba9cf5"}, @@ -53,6 +53,6 @@ "text_diff": {:hex, :text_diff, "0.1.0", "1caf3175e11a53a9a139bc9339bd607c47b9e376b073d4571c031913317fecaa", [:mix], [], "hexpm", "d1ffaaecab338e49357b6daa82e435f877e0649041ace7755583a0ea3362dbd7"}, "tz": {:hex, :tz, "0.28.1", "717f5ffddfd1e475e2a233e221dc0b4b76c35c4b3650b060c8e3ba29dd6632e9", [:mix], [{:castore, "~> 0.1 or ~> 1.0", [hex: :castore, repo: "hexpm", optional: true]}, {:mint, "~> 1.6", [hex: :mint, repo: "hexpm", optional: true]}], "hexpm", "bfdca1aa1902643c6c43b77c1fb0cb3d744fd2f09a8a98405468afdee0848c8a"}, "yamerl": {:hex, :yamerl, "0.10.0", "4ff81fee2f1f6a46f1700c0d880b24d193ddb74bd14ef42cb0bcf46e81ef2f8e", [:rebar3], [], "hexpm", "346adb2963f1051dc837a2364e4acf6eb7d80097c0f53cbdc3046ec8ec4b4e6e"}, - "yaml_elixir": {:hex, :yaml_elixir, "2.11.0", "9e9ccd134e861c66b84825a3542a1c22ba33f338d82c07282f4f1f52d847bd50", [:mix], [{:yamerl, "~> 0.10", [hex: :yamerl, repo: "hexpm", optional: false]}], "hexpm", "53cc28357ee7eb952344995787f4bb8cc3cecbf189652236e9b163e8ce1bc242"}, + "yaml_elixir": {:hex, :yaml_elixir, "2.12.0", "30343ff5018637a64b1b7de1ed2a3ca03bc641410c1f311a4dbdc1ffbbf449c7", [:mix], [{:yamerl, "~> 0.10", [hex: :yamerl, repo: "hexpm", optional: false]}], "hexpm", "ca6bacae7bac917a7155dca0ab6149088aa7bc800c94d0fe18c5238f53b313c6"}, "ymlr": {:hex, :ymlr, "5.1.4", "b924d61e1fc1ec371cde6ab3ccd9311110b1e052fc5c2460fb322e8380e7712a", [:mix], [], "hexpm", "75f16cf0709fbd911b30311a0359a7aa4b5476346c01882addefd5f2b1cfaa51"}, } From 14581be77761b62f26597f8f0648540523fef96e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 1 Oct 2025 23:19:22 -0400 Subject: [PATCH 143/174] chore(deps-dev): bump the dev-dependencies group with 4 updates (#624) Bumps the dev-dependencies group with 4 updates: [dialyxir](https://github.com/jeremyjh/dialyxir), [ecto_dev_logger](https://github.com/fuelen/ecto_dev_logger), [ex_doc](https://github.com/elixir-lang/ex_doc) and [git_ops](https://github.com/zachdaniel/git_ops). Updates `dialyxir` from 1.4.5 to 1.4.6 - [Release notes](https://github.com/jeremyjh/dialyxir/releases) - [Changelog](https://github.com/jeremyjh/dialyxir/blob/master/CHANGELOG.md) - [Commits](https://github.com/jeremyjh/dialyxir/compare/1.4.5...1.4.6) Updates `ecto_dev_logger` from 0.14.1 to 0.15.0 - [Release notes](https://github.com/fuelen/ecto_dev_logger/releases) - [Commits](https://github.com/fuelen/ecto_dev_logger/compare/v0.14.1...v0.15.0) Updates `ex_doc` from 0.38.2 to 0.38.4 - [Release notes](https://github.com/elixir-lang/ex_doc/releases) - [Changelog](https://github.com/elixir-lang/ex_doc/blob/main/CHANGELOG.md) - [Commits](https://github.com/elixir-lang/ex_doc/compare/v0.38.2...v0.38.4) Updates `git_ops` from 2.8.0 to 2.9.0 - [Changelog](https://github.com/zachdaniel/git_ops/blob/master/CHANGELOG.md) - [Commits](https://github.com/zachdaniel/git_ops/compare/v2.8.0...v2.9.0) --- updated-dependencies: - dependency-name: dialyxir dependency-version: 1.4.6 dependency-type: direct:development update-type: version-update:semver-patch dependency-group: dev-dependencies - dependency-name: ecto_dev_logger dependency-version: 0.15.0 dependency-type: direct:development update-type: version-update:semver-minor dependency-group: dev-dependencies - dependency-name: ex_doc dependency-version: 0.38.4 dependency-type: direct:development update-type: version-update:semver-patch dependency-group: dev-dependencies - dependency-name: git_ops dependency-version: 2.9.0 dependency-type: direct:development update-type: version-update:semver-minor dependency-group: dev-dependencies ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- mix.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/mix.lock b/mix.lock index 726124db..be72f892 100644 --- a/mix.lock +++ b/mix.lock @@ -7,20 +7,20 @@ "db_connection": {:hex, :db_connection, "2.8.1", "9abdc1e68c34c6163f6fb96a96532272d13ad7ca45262156ae8b7ec6d9dc4bec", [:mix], [{:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "a61a3d489b239d76f326e03b98794fb8e45168396c925ef25feb405ed09da8fd"}, "decimal": {:hex, :decimal, "2.3.0", "3ad6255aa77b4a3c4f818171b12d237500e63525c2fd056699967a3e7ea20f62", [:mix], [], "hexpm", "a4d66355cb29cb47c3cf30e71329e58361cfcb37c34235ef3bf1d7bf3773aeac"}, "deep_merge": {:hex, :deep_merge, "1.0.0", "b4aa1a0d1acac393bdf38b2291af38cb1d4a52806cf7a4906f718e1feb5ee961", [:mix], [], "hexpm", "ce708e5f094b9cd4e8f2be4f00d2f4250c4095be93f8cd6d018c753894885430"}, - "dialyxir": {:hex, :dialyxir, "1.4.5", "ca1571ac18e0f88d4ab245f0b60fa31ff1b12cbae2b11bd25d207f865e8ae78a", [:mix], [{:erlex, ">= 0.2.7", [hex: :erlex, repo: "hexpm", optional: false]}], "hexpm", "b0fb08bb8107c750db5c0b324fa2df5ceaa0f9307690ee3c1f6ba5b9eb5d35c3"}, + "dialyxir": {:hex, :dialyxir, "1.4.6", "7cca478334bf8307e968664343cbdb432ee95b4b68a9cba95bdabb0ad5bdfd9a", [:mix], [{:erlex, ">= 0.2.7", [hex: :erlex, repo: "hexpm", optional: false]}], "hexpm", "8cf5615c5cd4c2da6c501faae642839c8405b49f8aa057ad4ae401cb808ef64d"}, "earmark_parser": {:hex, :earmark_parser, "1.4.44", "f20830dd6b5c77afe2b063777ddbbff09f9759396500cdbe7523efd58d7a339c", [:mix], [], "hexpm", "4778ac752b4701a5599215f7030989c989ffdc4f6df457c5f36938cc2d2a2750"}, "ecto": {:hex, :ecto, "3.13.3", "6a983f0917f8bdc7a89e96f2bf013f220503a0da5d8623224ba987515b3f0d80", [:mix], [{:decimal, "~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "1927db768f53a88843ff25b6ba7946599a8ca8a055f69ad8058a1432a399af94"}, - "ecto_dev_logger": {:hex, :ecto_dev_logger, "0.14.1", "af385ce1af1c4210ad67a4c46b985c370713446a179144a1da2885138c9fb242", [:mix], [{:ecto, "~> 3.7", [hex: :ecto, repo: "hexpm", optional: false]}, {:geo, "~> 3.5 or ~> 4.0", [hex: :geo, repo: "hexpm", optional: true]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "14a64ebae728b3c45db6ba8bb185979c8e01fc1b0d3d1d9c01c7a2b798e8c698"}, + "ecto_dev_logger": {:hex, :ecto_dev_logger, "0.15.0", "df5a997ffb17dca9011556857a0f5b7d8cd53ca7c452ef98828664b6e48d4400", [:mix], [{:ecto, "~> 3.7", [hex: :ecto, repo: "hexpm", optional: false]}, {:geo, "~> 3.5 or ~> 4.0", [hex: :geo, repo: "hexpm", optional: true]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}, {:postgrex, "~> 0.17", [hex: :postgrex, repo: "hexpm", optional: true]}], "hexpm", "b2c807d7d599a4fcf288139851c09262333b193bdb41f8d65f515853d117e88a"}, "ecto_sql": {:hex, :ecto_sql, "3.13.2", "a07d2461d84107b3d037097c822ffdd36ed69d1cf7c0f70e12a3d1decf04e2e1", [:mix], [{:db_connection, "~> 2.4.1 or ~> 2.5", [hex: :db_connection, repo: "hexpm", optional: false]}, {:ecto, "~> 3.13.0", [hex: :ecto, repo: "hexpm", optional: false]}, {:myxql, "~> 0.7", [hex: :myxql, repo: "hexpm", optional: true]}, {:postgrex, "~> 0.19 or ~> 1.0", [hex: :postgrex, repo: "hexpm", optional: true]}, {:tds, "~> 2.1.1 or ~> 2.2", [hex: :tds, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4.0 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "539274ab0ecf1a0078a6a72ef3465629e4d6018a3028095dc90f60a19c371717"}, "eflame": {:hex, :eflame, "1.0.1", "0664d287e39eef3c413749254b3af5f4f8b00be71c1af67d325331c4890be0fc", [:mix], [], "hexpm", "e0b08854a66f9013129de0b008488f3411ae9b69b902187837f994d7a99cf04e"}, "erlex": {:hex, :erlex, "0.2.7", "810e8725f96ab74d17aac676e748627a07bc87eb950d2b83acd29dc047a30595", [:mix], [], "hexpm", "3ed95f79d1a844c3f6bf0cea61e0d5612a42ce56da9c03f01df538685365efb0"}, "ets": {:hex, :ets, "0.9.0", "79c6a6c205436780486f72d84230c6cba2f8a9920456750ddd1e47389107d5fd", [:mix], [], "hexpm", "2861fdfb04bcaeff370f1a5904eec864f0a56dcfebe5921ea9aadf2a481c822b"}, "ex_check": {:hex, :ex_check, "0.16.0", "07615bef493c5b8d12d5119de3914274277299c6483989e52b0f6b8358a26b5f", [:mix], [], "hexpm", "4d809b72a18d405514dda4809257d8e665ae7cf37a7aee3be6b74a34dec310f5"}, - "ex_doc": {:hex, :ex_doc, "0.38.2", "504d25eef296b4dec3b8e33e810bc8b5344d565998cd83914ffe1b8503737c02", [:mix], [{:earmark_parser, "~> 1.4.44", [hex: :earmark_parser, repo: "hexpm", optional: false]}, {:makeup_c, ">= 0.1.0", [hex: :makeup_c, repo: "hexpm", optional: true]}, {:makeup_elixir, "~> 0.14 or ~> 1.0", [hex: :makeup_elixir, repo: "hexpm", optional: false]}, {:makeup_erlang, "~> 0.1 or ~> 1.0", [hex: :makeup_erlang, repo: "hexpm", optional: false]}, {:makeup_html, ">= 0.1.0", [hex: :makeup_html, repo: "hexpm", optional: true]}], "hexpm", "732f2d972e42c116a70802f9898c51b54916e542cc50968ac6980512ec90f42b"}, + "ex_doc": {:hex, :ex_doc, "0.38.4", "ab48dff7a8af84226bf23baddcdda329f467255d924380a0cf0cee97bb9a9ede", [:mix], [{:earmark_parser, "~> 1.4.44", [hex: :earmark_parser, repo: "hexpm", optional: false]}, {:makeup_c, ">= 0.1.0", [hex: :makeup_c, repo: "hexpm", optional: true]}, {:makeup_elixir, "~> 0.14 or ~> 1.0", [hex: :makeup_elixir, repo: "hexpm", optional: false]}, {:makeup_erlang, "~> 0.1 or ~> 1.0", [hex: :makeup_erlang, repo: "hexpm", optional: false]}, {:makeup_html, ">= 0.1.0", [hex: :makeup_html, repo: "hexpm", optional: true]}], "hexpm", "f7b62346408a83911c2580154e35613eb314e0278aeea72ed7fedef9c1f165b2"}, "file_system": {:hex, :file_system, "1.1.0", "08d232062284546c6c34426997dd7ef6ec9f8bbd090eb91780283c9016840e8f", [:mix], [], "hexpm", "bfcf81244f416871f2a2e15c1b515287faa5db9c6bcf290222206d120b3d43f6"}, "finch": {:hex, :finch, "0.20.0", "5330aefb6b010f424dcbbc4615d914e9e3deae40095e73ab0c1bb0968933cadf", [:mix], [{:mime, "~> 1.0 or ~> 2.0", [hex: :mime, repo: "hexpm", optional: false]}, {:mint, "~> 1.6.2 or ~> 1.7", [hex: :mint, repo: "hexpm", optional: false]}, {:nimble_options, "~> 0.4 or ~> 1.0", [hex: :nimble_options, repo: "hexpm", optional: false]}, {:nimble_pool, "~> 1.1", [hex: :nimble_pool, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "2658131a74d051aabfcba936093c903b8e89da9a1b63e430bee62045fa9b2ee2"}, "git_cli": {:hex, :git_cli, "0.3.0", "a5422f9b95c99483385b976f5d43f7e8233283a47cda13533d7c16131cb14df5", [:mix], [], "hexpm", "78cb952f4c86a41f4d3511f1d3ecb28edb268e3a7df278de2faa1bd4672eaf9b"}, - "git_ops": {:hex, :git_ops, "2.8.0", "29ac9ab68bf9645973cb2752047b987e75cbd3d9761489c615e3ba80018fa885", [:mix], [{:git_cli, "~> 0.2", [hex: :git_cli, repo: "hexpm", optional: false]}, {:igniter, ">= 0.5.27 and < 1.0.0-0", [hex: :igniter, repo: "hexpm", optional: true]}, {:nimble_parsec, "~> 1.0", [hex: :nimble_parsec, repo: "hexpm", optional: false]}, {:req, "~> 0.5", [hex: :req, repo: "hexpm", optional: false]}], "hexpm", "b535e4ad6b5d13e14c455e76f65825659081b5530b0827eb0232d18719530eec"}, + "git_ops": {:hex, :git_ops, "2.9.0", "b74f6040084f523055b720cc7ef718da47f2cbe726a5f30c2871118635cb91c1", [:mix], [{:git_cli, "~> 0.2", [hex: :git_cli, repo: "hexpm", optional: false]}, {:igniter, ">= 0.5.27 and < 1.0.0-0", [hex: :igniter, repo: "hexpm", optional: true]}, {:nimble_parsec, "~> 1.0", [hex: :nimble_parsec, repo: "hexpm", optional: false]}, {:req, "~> 0.5", [hex: :req, repo: "hexpm", optional: false]}], "hexpm", "7fdf84be3490e5692c5dc1f8a1084eed47a221c1063e41938c73312f0bfea259"}, "glob_ex": {:hex, :glob_ex, "0.1.11", "cb50d3f1ef53f6ca04d6252c7fde09fd7a1cf63387714fe96f340a1349e62c93", [:mix], [], "hexpm", "342729363056e3145e61766b416769984c329e4378f1d558b63e341020525de4"}, "hpax": {:hex, :hpax, "1.0.3", "ed67ef51ad4df91e75cc6a1494f851850c0bd98ebc0be6e81b026e765ee535aa", [:mix], [], "hexpm", "8eab6e1cfa8d5918c2ce4ba43588e894af35dbd8e91e6e55c817bca5847df34a"}, "igniter": {:hex, :igniter, "0.6.30", "83a466369ebb8fe009e0823c7bf04314dc545122c2d48f896172fc79df33e99d", [:mix], [{:glob_ex, "~> 0.1.7", [hex: :glob_ex, repo: "hexpm", optional: false]}, {:jason, "~> 1.4", [hex: :jason, repo: "hexpm", optional: false]}, {:owl, "~> 0.11", [hex: :owl, repo: "hexpm", optional: false]}, {:phx_new, "~> 1.7", [hex: :phx_new, repo: "hexpm", optional: true]}, {:req, "~> 0.5", [hex: :req, repo: "hexpm", optional: false]}, {:rewrite, ">= 1.1.1 and < 2.0.0-0", [hex: :rewrite, repo: "hexpm", optional: false]}, {:sourceror, "~> 1.4", [hex: :sourceror, repo: "hexpm", optional: false]}, {:spitfire, ">= 0.1.3 and < 1.0.0-0", [hex: :spitfire, repo: "hexpm", optional: false]}], "hexpm", "76a14d5b7f850bb03b5243088c3649d54a2e52e34a2aa1104dee23cf50a8bae0"}, From 5c4a429b0f404bd8ef5d803b80ff462c129cf807 Mon Sep 17 00:00:00 2001 From: Steve Brambilla Date: Thu, 2 Oct 2025 23:09:32 -0400 Subject: [PATCH 144/174] improvement: Add immutable version of `ash_raise_error` function to support extensions like Citus (#620) --- lib/extensions/immutable_raise_error.ex | 74 +++++++++++++++++++++++++ lib/repo.ex | 11 +++- lib/sql_implementation.ex | 5 ++ mix.exs | 4 +- mix.lock | 2 +- 5 files changed, 93 insertions(+), 3 deletions(-) create mode 100644 lib/extensions/immutable_raise_error.ex diff --git a/lib/extensions/immutable_raise_error.ex b/lib/extensions/immutable_raise_error.ex new file mode 100644 index 00000000..7cda113d --- /dev/null +++ b/lib/extensions/immutable_raise_error.ex @@ -0,0 +1,74 @@ +defmodule AshPostgres.Extensions.ImmutableRaiseError do + @moduledoc """ + An extension that installs an immutable version of ash_raise_error. + + This can be used to improve compatibility with Postgres sharding extensions like Citus, + which requires functions used in CASE or COALESCE expressions to be immutable. + + The new `ash_raise_error_immutable` functions add an additional row-dependent argument to ensure + the planner doesn't constant-fold error expressions. + + To install, add this module to your repo's `installed_extensions` list: + + ```elixir + def installed_extensions do + ["ash-functions", AshPostgres.Extensions.ImmutableRaiseError] + end + ``` + + And run `mix ash_postgres.generate_migrations` to generate the migrations. + + Once installed, you can control whether the immutable function is used by adding this to your + repo: + + ```elixir + def immutable_expr_error?, do: true + ``` + """ + + use AshPostgres.CustomExtension, name: "immutable_raise_error", latest_version: 1 + + @impl true + def install(0) do + ash_raise_error_immutable() + end + + @impl true + def uninstall(_version) do + "execute(\"DROP FUNCTION IF EXISTS ash_raise_error_immutable(jsonb, ANYCOMPATIBLE), ash_raise_error_immutable(jsonb, ANYELEMENT, ANYCOMPATIBLE)\")" + end + + defp ash_raise_error_immutable do + """ + execute(\"\"\" + CREATE OR REPLACE FUNCTION ash_raise_error_immutable(json_data jsonb, token ANYCOMPATIBLE) + RETURNS BOOLEAN AS $$ + BEGIN + -- Raise an error with the provided JSON data. + -- The JSON object is converted to text for inclusion in the error message. + -- 'token' is intentionally ignored; its presence makes the call non-constant at the call site. + RAISE EXCEPTION 'ash_error: %', json_data::text; + RETURN NULL; + END; + $$ LANGUAGE plpgsql + IMMUTABLE + SET search_path = ''; + \"\"\") + + execute(\"\"\" + CREATE OR REPLACE FUNCTION ash_raise_error_immutable(json_data jsonb, type_signal ANYELEMENT, token ANYCOMPATIBLE) + RETURNS ANYELEMENT AS $$ + BEGIN + -- Raise an error with the provided JSON data. + -- The JSON object is converted to text for inclusion in the error message. + -- 'token' is intentionally ignored; its presence makes the call non-constant at the call site. + RAISE EXCEPTION 'ash_error: %', json_data::text; + RETURN NULL; + END; + $$ LANGUAGE plpgsql + IMMUTABLE + SET search_path = ''; + \"\"\") + """ + end +end diff --git a/lib/repo.ex b/lib/repo.ex index fb7cb7eb..e1b0726d 100644 --- a/lib/repo.ex +++ b/lib/repo.ex @@ -113,6 +113,13 @@ defmodule AshPostgres.Repo do @doc "Disable expression errors for this repo" @callback disable_expr_error?() :: boolean + @doc """ + Opt-in to using immutable versions of the expression error functions. + + Requires the `AshPostgres.Extensions.ImmutableRaiseError` extension. + """ + @callback immutable_expr_error?() :: boolean + defmacro __using__(opts) do quote bind_quoted: [opts: opts] do if Keyword.get(opts, :define_ecto_repo?, true) do @@ -145,6 +152,7 @@ defmodule AshPostgres.Repo do def drop?, do: true def disable_atomic_actions?, do: false def disable_expr_error?, do: false + def immutable_expr_error?, do: false # default to false in 4.0 def prefer_transaction?, do: true @@ -315,7 +323,8 @@ defmodule AshPostgres.Repo do create?: 0, drop?: 0, disable_atomic_actions?: 0, - disable_expr_error?: 0 + disable_expr_error?: 0, + immutable_expr_error?: 0 # We do this switch because `!@warn_on_missing_ash_functions` in the function body triggers # a dialyzer error diff --git a/lib/sql_implementation.ex b/lib/sql_implementation.ex index 99d80f8f..fefdf876 100644 --- a/lib/sql_implementation.ex +++ b/lib/sql_implementation.ex @@ -334,4 +334,9 @@ defmodule AshPostgres.SqlImplementation do {types, new_returns || returns} end + + @impl true + def immutable_errors?(repo) do + repo.immutable_expr_error?() + end end diff --git a/mix.exs b/mix.exs index 00778fec..c06ca801 100644 --- a/mix.exs +++ b/mix.exs @@ -168,7 +168,9 @@ defmodule AshPostgres.MixProject do [ {:ash, ash_version("~> 3.5 and >= 3.5.35")}, {:spark, "~> 2.3 and >= 2.3.4"}, - {:ash_sql, ash_sql_version("~> 0.2 and >= 0.2.90")}, + # TODO: bump to next ash_sql release + # {:ash_sql, ash_sql_version("~> 0.2 and >= 0.2.90")}, + {:ash_sql, git: "https://github.com/ash-project/ash_sql.git"}, {:igniter, "~> 0.6 and >= 0.6.14", optional: true}, {:ecto_sql, "~> 3.13"}, {:ecto, "~> 3.13"}, diff --git a/mix.lock b/mix.lock index be72f892..7cd067b4 100644 --- a/mix.lock +++ b/mix.lock @@ -1,6 +1,6 @@ %{ "ash": {:hex, :ash, "3.5.43", "222f9a8ac26ad3b029f8e69306cc83091c992d858b4538af12e33a148f301cab", [:mix], [{:decimal, "~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:ecto, "~> 3.7", [hex: :ecto, repo: "hexpm", optional: false]}, {:ets, "~> 0.8", [hex: :ets, repo: "hexpm", optional: false]}, {:igniter, ">= 0.6.29 and < 1.0.0-0", [hex: :igniter, repo: "hexpm", optional: true]}, {:jason, ">= 1.0.0", [hex: :jason, repo: "hexpm", optional: false]}, {:picosat_elixir, "~> 0.2", [hex: :picosat_elixir, repo: "hexpm", optional: true]}, {:plug, ">= 0.0.0", [hex: :plug, repo: "hexpm", optional: true]}, {:reactor, "~> 0.11", [hex: :reactor, repo: "hexpm", optional: false]}, {:simple_sat, ">= 0.1.1 and < 1.0.0-0", [hex: :simple_sat, repo: "hexpm", optional: true]}, {:spark, ">= 2.3.3 and < 3.0.0-0", [hex: :spark, repo: "hexpm", optional: false]}, {:splode, ">= 0.2.6 and < 1.0.0-0", [hex: :splode, repo: "hexpm", optional: false]}, {:stream_data, "~> 1.0", [hex: :stream_data, repo: "hexpm", optional: false]}, {:telemetry, "~> 1.1", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "48b2aa274c524f5b968c563dd56aec8f9b278c529c8aa46e6fe0ca564c26cc1c"}, - "ash_sql": {:hex, :ash_sql, "0.3.0", "2c43ddcc8c7fb51dc25ba3bca965d8b68e7aaecb290cabfed3cf213965aca937", [:mix], [{:ash, ">= 3.5.43 and < 4.0.0-0", [hex: :ash, repo: "hexpm", optional: false]}, {:ecto, "~> 3.9", [hex: :ecto, repo: "hexpm", optional: false]}, {:ecto_sql, "~> 3.9", [hex: :ecto_sql, repo: "hexpm", optional: false]}], "hexpm", "ef03759d6a1d4cb189fcadbd183cf047f0565d7d88ea8612d85c9e6e724835e7"}, + "ash_sql": {:git, "https://github.com/ash-project/ash_sql.git", "65854408e7ce129f78fabafb0a4393f0142da6a6", []}, "benchee": {:hex, :benchee, "1.4.0", "9f1f96a30ac80bab94faad644b39a9031d5632e517416a8ab0a6b0ac4df124ce", [:mix], [{:deep_merge, "~> 1.0", [hex: :deep_merge, repo: "hexpm", optional: false]}, {:statistex, "~> 1.0", [hex: :statistex, repo: "hexpm", optional: false]}, {:table, "~> 0.1.0", [hex: :table, repo: "hexpm", optional: true]}], "hexpm", "299cd10dd8ce51c9ea3ddb74bb150f93d25e968f93e4c1fa31698a8e4fa5d715"}, "bunt": {:hex, :bunt, "1.0.0", "081c2c665f086849e6d57900292b3a161727ab40431219529f13c4ddcf3e7a44", [:mix], [], "hexpm", "dc5f86aa08a5f6fa6b8096f0735c4e76d54ae5c9fa2c143e5a1fc7c1cd9bb6b5"}, "credo": {:hex, :credo, "1.7.12", "9e3c20463de4b5f3f23721527fcaf16722ec815e70ff6c60b86412c695d426c1", [:mix], [{:bunt, "~> 0.2.1 or ~> 1.0", [hex: :bunt, repo: "hexpm", optional: false]}, {:file_system, "~> 0.2 or ~> 1.0", [hex: :file_system, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "8493d45c656c5427d9c729235b99d498bd133421f3e0a683e5c1b561471291e5"}, From 6a2675cd8865cb5d3b38dc052e98b944a7355282 Mon Sep 17 00:00:00 2001 From: Steve Brambilla Date: Fri, 3 Oct 2025 09:52:31 -0400 Subject: [PATCH 145/174] test: add repro for ash_sql issue (#629) --- .../test_repo/rsvps/20251002180954.json | 43 +++++++++++ .../20251002180954_migrate_resources62.exs | 20 +++++ test/support/domain.ex | 1 + test/support/resources/rsvp.ex | 42 +++++++++++ test/support/types/response.ex | 75 +++++++++++++++++++ test/type_test.exs | 9 +++ 6 files changed, 190 insertions(+) create mode 100644 priv/resource_snapshots/test_repo/rsvps/20251002180954.json create mode 100644 priv/test_repo/migrations/20251002180954_migrate_resources62.exs create mode 100644 test/support/resources/rsvp.ex create mode 100644 test/support/types/response.ex diff --git a/priv/resource_snapshots/test_repo/rsvps/20251002180954.json b/priv/resource_snapshots/test_repo/rsvps/20251002180954.json new file mode 100644 index 00000000..31e6d18f --- /dev/null +++ b/priv/resource_snapshots/test_repo/rsvps/20251002180954.json @@ -0,0 +1,43 @@ +{ + "attributes": [ + { + "allow_nil?": false, + "default": "fragment(\"gen_random_uuid()\")", + "generated?": false, + "precision": null, + "primary_key?": true, + "references": null, + "scale": null, + "size": null, + "source": "id", + "type": "uuid" + }, + { + "allow_nil?": false, + "default": "0", + "generated?": false, + "precision": null, + "primary_key?": false, + "references": null, + "scale": null, + "size": null, + "source": "response", + "type": "integer" + } + ], + "base_filter": null, + "check_constraints": [], + "custom_indexes": [], + "custom_statements": [], + "has_create_action": true, + "hash": "8ADC3A631361A18B1B9A2070D5E8477428EDE39DE3B43FA5FF8E50CE7710B9E5", + "identities": [], + "multitenancy": { + "attribute": null, + "global": null, + "strategy": null + }, + "repo": "Elixir.AshPostgres.TestRepo", + "schema": null, + "table": "rsvps" +} \ No newline at end of file diff --git a/priv/test_repo/migrations/20251002180954_migrate_resources62.exs b/priv/test_repo/migrations/20251002180954_migrate_resources62.exs new file mode 100644 index 00000000..fe90b42c --- /dev/null +++ b/priv/test_repo/migrations/20251002180954_migrate_resources62.exs @@ -0,0 +1,20 @@ +defmodule AshPostgres.TestRepo.Migrations.MigrateResources62 do + @moduledoc """ + Updates resources based on their most recent snapshots. + + This file was autogenerated with `mix ash_postgres.generate_migrations` + """ + + use Ecto.Migration + + def up do + create table(:rsvps, primary_key: false) do + add(:id, :uuid, null: false, default: fragment("gen_random_uuid()"), primary_key: true) + add(:response, :integer, null: false, default: 0) + end + end + + def down do + drop(table(:rsvps)) + end +end diff --git a/test/support/domain.ex b/test/support/domain.ex index 2bf55a0b..ec992cbe 100644 --- a/test/support/domain.ex +++ b/test/support/domain.ex @@ -53,6 +53,7 @@ defmodule AshPostgres.Test.Domain do resource(AshPostgres.Test.Order) resource(AshPostgres.Test.Chat) resource(AshPostgres.Test.Message) + resource(AshPostgres.Test.RSVP) end authorization do diff --git a/test/support/resources/rsvp.ex b/test/support/resources/rsvp.ex new file mode 100644 index 00000000..965f053d --- /dev/null +++ b/test/support/resources/rsvp.ex @@ -0,0 +1,42 @@ +defmodule AshPostgres.Test.RSVP do + @moduledoc false + use Ash.Resource, + domain: AshPostgres.Test.Domain, + data_layer: AshPostgres.DataLayer + + postgres do + table "rsvps" + repo AshPostgres.TestRepo + end + + actions do + default_accept(:*) + defaults([:create, :read, :update, :destroy]) + + # Uses an expression with an array of atoms for a custom type backed by integers. + update :clear_response do + change( + atomic_update( + :response, + expr( + if response in [:accepted, :declined] do + :awaiting + else + response + end + ) + ) + ) + end + end + + attributes do + uuid_primary_key(:id) + + attribute(:response, AshPostgres.Test.Types.Response, + allow_nil?: false, + public?: true, + default: 0 + ) + end +end diff --git a/test/support/types/response.ex b/test/support/types/response.ex new file mode 100644 index 00000000..51f475e0 --- /dev/null +++ b/test/support/types/response.ex @@ -0,0 +1,75 @@ +defmodule AshPostgres.Test.Types.Response do + @moduledoc false + use Ash.Type + use AshPostgres.Type + require Ash.Expr + + @atoms_to_ints %{accepted: 1, declined: 2, awaiting: 0} + @ints_to_atoms Map.new(@atoms_to_ints, fn {k, v} -> {v, k} end) + @atom_values Map.keys(@atoms_to_ints) + @string_values Enum.map(@atom_values, &to_string/1) + + @impl Ash.Type + def storage_type, do: :integer + + @impl Ash.Type + def cast_input(nil, _), do: {:ok, nil} + + def cast_input(value, _) when value in @atom_values, do: {:ok, value} + def cast_input(value, _) when value in @string_values, do: {:ok, String.to_existing_atom(value)} + + def cast_input(integer, _) when is_integer(integer), + do: Map.fetch(@ints_to_atoms, integer) + + def cast_input(_, _), do: :error + + @impl Ash.Type + def matches_type?(value, _) when is_atom(value) and value in @atom_values, do: true + def matches_type?(_, _), do: false + + @impl Ash.Type + def cast_stored(nil, _), do: {:ok, nil} + def cast_stored(integer, _) when is_integer(integer), do: Map.fetch(@ints_to_atoms, integer) + def cast_stored(_, _), do: :error + + @impl Ash.Type + def dump_to_native(nil, _), do: {:ok, nil} + def dump_to_native(atom, _) when is_atom(atom), do: Map.fetch(@atoms_to_ints, atom) + def dump_to_native(_, _), do: :error + + @impl Ash.Type + def cast_atomic(new_value, constraints) do + if Ash.Expr.expr?(new_value) do + {:atomic, new_value} + else + case cast_input(new_value, constraints) do + {:ok, value} -> {:atomic, value} + {:error, error} -> {:error, error} + end + end + end + + @impl Ash.Type + def apply_atomic_constraints(new_value, _constraints) do + {:ok, + Ash.Expr.expr( + if ^new_value in ^@atom_values do + ^new_value + else + error( + Ash.Error.Changes.InvalidChanges, + message: "must be one of %{values}", + vars: %{values: ^Enum.join(@atom_values, ", ")} + ) + end + )} + end + + @impl AshPostgres.Type + def value_to_postgres_default(_, _, value) do + case Map.fetch(@atoms_to_ints, value) do + {:ok, integer} -> {:ok, Integer.to_string(integer)} + :error -> :error + end + end +end diff --git a/test/type_test.exs b/test/type_test.exs index 4c3731e7..6355fe92 100644 --- a/test/type_test.exs +++ b/test/type_test.exs @@ -1,6 +1,7 @@ defmodule AshPostgres.Test.TypeTest do use AshPostgres.RepoCase, async: false alias AshPostgres.Test.Post + alias AshPostgres.Test.RSVP require Ash.Query @@ -107,4 +108,12 @@ defmodule AshPostgres.Test.TypeTest do post = Ash.Query.for_read(Post, :with_version_check, version: 1) |> Ash.read!() refute is_nil(post) end + + test "array expressions work with custom types that map atoms to integers" do + rsvp = RSVP |> Ash.Changeset.for_create(:create, %{response: :accepted}) |> Ash.create!() + + updated = rsvp |> Ash.Changeset.for_update(:clear_response, %{}) |> Ash.update!() + + assert updated.response == :awaiting + end end From c9a6e3e7b580361274fdd7102b9dbe23bb1223a6 Mon Sep 17 00:00:00 2001 From: Alexandre Moreau Date: Sat, 4 Oct 2025 22:33:37 +0200 Subject: [PATCH 146/174] test:add failing test (#627) --- .../20251001120813.json | 124 ++++++++++++++++++ .../20251001120813_migrate_resources7.exs | 78 +++++++++++ test/multitenancy_test.exs | 20 ++- test/support/multitenancy/domain.ex | 1 + .../non_multitenant_post_multitenant_link.ex | 52 ++++++++ test/support/multitenancy/resources/post.ex | 11 ++ 6 files changed, 285 insertions(+), 1 deletion(-) create mode 100644 priv/resource_snapshots/test_repo/tenants/non_multitenant_post_multitenant_links/20251001120813.json create mode 100644 priv/test_repo/tenant_migrations/20251001120813_migrate_resources7.exs create mode 100644 test/support/multitenancy/resources/non_multitenant_post_multitenant_link.ex diff --git a/priv/resource_snapshots/test_repo/tenants/non_multitenant_post_multitenant_links/20251001120813.json b/priv/resource_snapshots/test_repo/tenants/non_multitenant_post_multitenant_links/20251001120813.json new file mode 100644 index 00000000..16e8af1a --- /dev/null +++ b/priv/resource_snapshots/test_repo/tenants/non_multitenant_post_multitenant_links/20251001120813.json @@ -0,0 +1,124 @@ +{ + "attributes": [ + { + "allow_nil?": false, + "default": "fragment(\"gen_random_uuid()\")", + "generated?": false, + "precision": null, + "primary_key?": true, + "references": null, + "scale": null, + "size": null, + "source": "id", + "type": "uuid" + }, + { + "allow_nil?": true, + "default": "\"active\"", + "generated?": false, + "precision": null, + "primary_key?": false, + "references": null, + "scale": null, + "size": null, + "source": "state", + "type": "text" + }, + { + "allow_nil?": false, + "default": "nil", + "generated?": false, + "precision": null, + "primary_key?": false, + "references": { + "deferrable": false, + "destination_attribute": "id", + "destination_attribute_default": null, + "destination_attribute_generated": null, + "index?": true, + "match_type": null, + "match_with": null, + "multitenancy": { + "attribute": null, + "global": false, + "strategy": "context" + }, + "name": "non_multitenant_post_multitenant_links_source_id_fkey", + "on_delete": "delete", + "on_update": null, + "primary_key?": true, + "schema": "public", + "table": "multitenant_posts" + }, + "scale": null, + "size": null, + "source": "source_id", + "type": "uuid" + }, + { + "allow_nil?": false, + "default": "nil", + "generated?": false, + "precision": null, + "primary_key?": false, + "references": { + "deferrable": false, + "destination_attribute": "id", + "destination_attribute_default": null, + "destination_attribute_generated": null, + "index?": true, + "match_type": null, + "match_with": null, + "multitenancy": { + "attribute": null, + "global": null, + "strategy": null + }, + "name": "non_multitenant_post_multitenant_links_dest_id_fkey", + "on_delete": "delete", + "on_update": null, + "primary_key?": true, + "schema": "public", + "table": "posts" + }, + "scale": null, + "size": null, + "source": "dest_id", + "type": "uuid" + } + ], + "base_filter": null, + "check_constraints": [], + "custom_indexes": [], + "custom_statements": [], + "has_create_action": true, + "hash": "F19D22A316D43A64BF2F1E052F545346BD0BCBC660E8EF559D1D4D73D8969A4D", + "identities": [ + { + "all_tenants?": false, + "base_filter": null, + "index_name": "non_multitenant_post_multitenant_links_unique_link_index", + "keys": [ + { + "type": "atom", + "value": "source_id" + }, + { + "type": "atom", + "value": "dest_id" + } + ], + "name": "unique_link", + "nils_distinct?": true, + "where": null + } + ], + "multitenancy": { + "attribute": null, + "global": false, + "strategy": "context" + }, + "repo": "Elixir.AshPostgres.TestRepo", + "schema": null, + "table": "non_multitenant_post_multitenant_links" +} \ No newline at end of file diff --git a/priv/test_repo/tenant_migrations/20251001120813_migrate_resources7.exs b/priv/test_repo/tenant_migrations/20251001120813_migrate_resources7.exs new file mode 100644 index 00000000..42a6f5a3 --- /dev/null +++ b/priv/test_repo/tenant_migrations/20251001120813_migrate_resources7.exs @@ -0,0 +1,78 @@ +defmodule AshPostgres.TestRepo.TenantMigrations.MigrateResources7 do + @moduledoc """ + Updates resources based on their most recent snapshots. + + This file was autogenerated with `mix ash_postgres.generate_migrations` + """ + + use Ecto.Migration + + def up do + create table(:non_multitenant_post_multitenant_links, primary_key: false, prefix: prefix()) do + add(:id, :uuid, null: false, default: fragment("gen_random_uuid()"), primary_key: true) + add(:state, :text, default: "active") + + add( + :source_id, + references(:multitenant_posts, + column: :id, + name: "non_multitenant_post_multitenant_links_source_id_fkey", + type: :uuid, + prefix: prefix(), + on_delete: :delete_all + ), + null: false + ) + + add( + :dest_id, + references(:posts, + column: :id, + name: "non_multitenant_post_multitenant_links_dest_id_fkey", + type: :uuid, + prefix: "public", + on_delete: :delete_all + ), + null: false + ) + end + + create(index(:non_multitenant_post_multitenant_links, [:source_id])) + + create(index(:non_multitenant_post_multitenant_links, [:dest_id])) + + create( + unique_index(:non_multitenant_post_multitenant_links, [:source_id, :dest_id], + name: "non_multitenant_post_multitenant_links_unique_link_index" + ) + ) + end + + def down do + drop_if_exists( + unique_index(:non_multitenant_post_multitenant_links, [:source_id, :dest_id], + name: "non_multitenant_post_multitenant_links_unique_link_index" + ) + ) + + drop_if_exists(index(:non_multitenant_post_multitenant_links, [:dest_id])) + + drop_if_exists(index(:non_multitenant_post_multitenant_links, [:source_id])) + + drop( + constraint( + :non_multitenant_post_multitenant_links, + "non_multitenant_post_multitenant_links_source_id_fkey" + ) + ) + + drop( + constraint( + :non_multitenant_post_multitenant_links, + "non_multitenant_post_multitenant_links_dest_id_fkey" + ) + ) + + drop(table(:non_multitenant_post_multitenant_links, prefix: prefix())) + end +end diff --git a/test/multitenancy_test.exs b/test/multitenancy_test.exs index 0dd99520..89034434 100644 --- a/test/multitenancy_test.exs +++ b/test/multitenancy_test.exs @@ -2,7 +2,7 @@ defmodule AshPostgres.Test.MultitenancyTest do use AshPostgres.RepoCase, async: false require Ash.Query - alias AshPostgres.MultitenancyTest.{CompositeKeyPost, NamedOrg, Org, Post, User} + alias AshPostgres.MultitenancyTest.{CompositeKeyPost, NamedOrg, Org, Post, User, NonMultitenantPostMultitenantLink} alias AshPostgres.Test.Post, as: GlobalPost setup do @@ -226,6 +226,24 @@ defmodule AshPostgres.Test.MultitenancyTest do ) end + test "loading non multitenant resource across a many_to_many works", %{org1: org1} do + post = Post + |> Ash.Changeset.for_create(:create, %{name: "foo"}) + |> Ash.Changeset.set_tenant(org1) + |> Ash.create!() + + GlobalPost + |> Ash.Changeset.for_create(:create, %{title: "fred"}) + |> Ash.create!() + + NonMultitenantPostMultitenantLink + |> Ash.Changeset.for_create(:create, %{source_id: post.id, dest_id: global_post.id}, tenant: org1) + |> Ash.create!() + + post |> Ash.load!([:linked_non_multitenant_posts_through_multitenant_link], tenant: org1) |> IO.inspect() + end + + test "manage_relationship from context multitenant resource to attribute multitenant resource doesn't raise an error" do org = Org |> Ash.Changeset.new() |> Ash.create!() user = User |> Ash.Changeset.new() |> Ash.create!() diff --git a/test/support/multitenancy/domain.ex b/test/support/multitenancy/domain.ex index 52ffbc63..6c1db197 100644 --- a/test/support/multitenancy/domain.ex +++ b/test/support/multitenancy/domain.ex @@ -12,6 +12,7 @@ defmodule AshPostgres.MultitenancyTest.Domain do resource(AshPostgres.MultitenancyTest.NonMultitenantPostLink) resource(AshPostgres.MultitenancyTest.CrossTenantPostLink) resource(AshPostgres.MultitenancyTest.CompositeKeyPost) + resource(AshPostgres.MultitenancyTest.NonMultitenantPostMultitenantLink) end authorization do diff --git a/test/support/multitenancy/resources/non_multitenant_post_multitenant_link.ex b/test/support/multitenancy/resources/non_multitenant_post_multitenant_link.ex new file mode 100644 index 00000000..4dff4d41 --- /dev/null +++ b/test/support/multitenancy/resources/non_multitenant_post_multitenant_link.ex @@ -0,0 +1,52 @@ +defmodule AshPostgres.MultitenancyTest.NonMultitenantPostMultitenantLink do + @moduledoc false + use Ash.Resource, + domain: AshPostgres.MultitenancyTest.Domain, + data_layer: AshPostgres.DataLayer + + postgres do + table "non_multitenant_post_multitenant_links" + repo AshPostgres.TestRepo + + references do + reference :source, on_delete: :delete, index?: true + reference :dest, on_delete: :delete, index?: true + end + end + + multitenancy do + strategy(:context) + end + + actions do + default_accept(:*) + + defaults([:create, :read, :update, :destroy]) + end + + identities do + identity(:unique_link, [:source_id, :dest_id]) + end + + attributes do + uuid_primary_key :id + + attribute :state, :atom do + public?(true) + constraints(one_of: [:active, :archived]) + default(:active) + end + end + + relationships do + belongs_to :source, AshPostgres.MultitenancyTest.Post do + public? true + allow_nil? false + end + + belongs_to :dest, AshPostgres.Test.Post do + public? true + allow_nil? false + end + end +end diff --git a/test/support/multitenancy/resources/post.ex b/test/support/multitenancy/resources/post.ex index e097fffb..b3358361 100644 --- a/test/support/multitenancy/resources/post.ex +++ b/test/support/multitenancy/resources/post.ex @@ -59,12 +59,23 @@ defmodule AshPostgres.MultitenancyTest.Post do # has_many(:non_multitenant_post_links, AshPostgres.MultitenancyTest.NonMultitenantPostLink) + has_many :non_multitenant_post_multitenant_links, AshPostgres.MultitenancyTest.NonMultitenantPostMultitenantLink do + destination_attribute :source_id + end + many_to_many :linked_non_multitenant_posts, AshPostgres.Test.Post do through(AshPostgres.MultitenancyTest.NonMultitenantPostLink) join_relationship(:non_multitenant_post_links) source_attribute_on_join_resource(:source_id) destination_attribute_on_join_resource(:dest_id) end + + many_to_many :linked_non_multitenant_posts_through_multitenant_link, AshPostgres.Test.Post do + through(AshPostgres.MultitenancyTest.NonMultitenantPostMultitenantLink) + join_relationship(:non_multitenant_post_links_through_multitenant_link) + source_attribute_on_join_resource(:source_id) + destination_attribute_on_join_resource(:dest_id) + end end calculations do From 7ad0b86d145d4760882248d463222b742a872741 Mon Sep 17 00:00:00 2001 From: Zach Daniel Date: Sat, 4 Oct 2025 16:53:54 -0400 Subject: [PATCH 147/174] fix: ensure that tenant is properly used in many-to-many joins --- lib/data_layer.ex | 6 +++-- mix.exs | 3 +-- test/multitenancy_test.exs | 27 ++++++++++++++----- .../non_multitenant_post_multitenant_link.ex | 10 +++---- test/support/multitenancy/resources/post.ex | 5 ++-- 5 files changed, 33 insertions(+), 18 deletions(-) diff --git a/lib/data_layer.ex b/lib/data_layer.ex index 43b8f5a1..d9b2f41a 100644 --- a/lib/data_layer.ex +++ b/lib/data_layer.ex @@ -1247,7 +1247,9 @@ defmodule AshPostgres.DataLayer do through_query = Ecto.Query.exclude(through_query, :select) through_query = - if through_query.joins && through_query.joins != [] do + if (through_query.joins && through_query.joins != []) || + (Ash.Resource.Info.multitenancy_strategy(relationship.through) == :context && + source_query.tenant) do subquery( set_subquery_prefix( through_query, @@ -1256,7 +1258,7 @@ defmodule AshPostgres.DataLayer do ) ) else - through_query + set_subquery_prefix(through_query, source_query, relationship.through) end if query.__ash_bindings__[:__order__?] do diff --git a/mix.exs b/mix.exs index c06ca801..cdc61840 100644 --- a/mix.exs +++ b/mix.exs @@ -169,8 +169,7 @@ defmodule AshPostgres.MixProject do {:ash, ash_version("~> 3.5 and >= 3.5.35")}, {:spark, "~> 2.3 and >= 2.3.4"}, # TODO: bump to next ash_sql release - # {:ash_sql, ash_sql_version("~> 0.2 and >= 0.2.90")}, - {:ash_sql, git: "https://github.com/ash-project/ash_sql.git"}, + {:ash_sql, ash_sql_version(git: "https://github.com/ash-project/ash_sql.git")}, {:igniter, "~> 0.6 and >= 0.6.14", optional: true}, {:ecto_sql, "~> 3.13"}, {:ecto, "~> 3.13"}, diff --git a/test/multitenancy_test.exs b/test/multitenancy_test.exs index 89034434..6253e46f 100644 --- a/test/multitenancy_test.exs +++ b/test/multitenancy_test.exs @@ -2,7 +2,16 @@ defmodule AshPostgres.Test.MultitenancyTest do use AshPostgres.RepoCase, async: false require Ash.Query - alias AshPostgres.MultitenancyTest.{CompositeKeyPost, NamedOrg, Org, Post, User, NonMultitenantPostMultitenantLink} + + alias AshPostgres.MultitenancyTest.{ + CompositeKeyPost, + NamedOrg, + Org, + Post, + User, + NonMultitenantPostMultitenantLink + } + alias AshPostgres.Test.Post, as: GlobalPost setup do @@ -227,23 +236,27 @@ defmodule AshPostgres.Test.MultitenancyTest do end test "loading non multitenant resource across a many_to_many works", %{org1: org1} do - post = Post + post = + Post |> Ash.Changeset.for_create(:create, %{name: "foo"}) |> Ash.Changeset.set_tenant(org1) |> Ash.create!() - GlobalPost + global_post = + GlobalPost |> Ash.Changeset.for_create(:create, %{title: "fred"}) |> Ash.create!() NonMultitenantPostMultitenantLink - |> Ash.Changeset.for_create(:create, %{source_id: post.id, dest_id: global_post.id}, tenant: org1) - |> Ash.create!() + |> Ash.Changeset.for_create(:create, %{source_id: post.id, dest_id: global_post.id}, + tenant: org1 + ) + |> Ash.create!() - post |> Ash.load!([:linked_non_multitenant_posts_through_multitenant_link], tenant: org1) |> IO.inspect() + post + |> Ash.load!([:linked_non_multitenant_posts_through_multitenant_link], tenant: org1) end - test "manage_relationship from context multitenant resource to attribute multitenant resource doesn't raise an error" do org = Org |> Ash.Changeset.new() |> Ash.create!() user = User |> Ash.Changeset.new() |> Ash.create!() diff --git a/test/support/multitenancy/resources/non_multitenant_post_multitenant_link.ex b/test/support/multitenancy/resources/non_multitenant_post_multitenant_link.ex index 4dff4d41..56dd8d26 100644 --- a/test/support/multitenancy/resources/non_multitenant_post_multitenant_link.ex +++ b/test/support/multitenancy/resources/non_multitenant_post_multitenant_link.ex @@ -29,7 +29,7 @@ defmodule AshPostgres.MultitenancyTest.NonMultitenantPostMultitenantLink do end attributes do - uuid_primary_key :id + uuid_primary_key(:id) attribute :state, :atom do public?(true) @@ -40,13 +40,13 @@ defmodule AshPostgres.MultitenancyTest.NonMultitenantPostMultitenantLink do relationships do belongs_to :source, AshPostgres.MultitenancyTest.Post do - public? true - allow_nil? false + public?(true) + allow_nil?(false) end belongs_to :dest, AshPostgres.Test.Post do - public? true - allow_nil? false + public?(true) + allow_nil?(false) end end end diff --git a/test/support/multitenancy/resources/post.ex b/test/support/multitenancy/resources/post.ex index b3358361..6f9a943a 100644 --- a/test/support/multitenancy/resources/post.ex +++ b/test/support/multitenancy/resources/post.ex @@ -59,8 +59,9 @@ defmodule AshPostgres.MultitenancyTest.Post do # has_many(:non_multitenant_post_links, AshPostgres.MultitenancyTest.NonMultitenantPostLink) - has_many :non_multitenant_post_multitenant_links, AshPostgres.MultitenancyTest.NonMultitenantPostMultitenantLink do - destination_attribute :source_id + has_many :non_multitenant_post_multitenant_links, + AshPostgres.MultitenancyTest.NonMultitenantPostMultitenantLink do + destination_attribute(:source_id) end many_to_many :linked_non_multitenant_posts, AshPostgres.Test.Post do From 588b1cbd28a15a3a19fd1cc59a3ff78a65ddd715 Mon Sep 17 00:00:00 2001 From: Zach Daniel Date: Sat, 4 Oct 2025 17:00:47 -0400 Subject: [PATCH 148/174] chore: credo --- test/multitenancy_test.exs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/multitenancy_test.exs b/test/multitenancy_test.exs index 6253e46f..85a97cbe 100644 --- a/test/multitenancy_test.exs +++ b/test/multitenancy_test.exs @@ -6,10 +6,10 @@ defmodule AshPostgres.Test.MultitenancyTest do alias AshPostgres.MultitenancyTest.{ CompositeKeyPost, NamedOrg, + NonMultitenantPostMultitenantLink, Org, Post, - User, - NonMultitenantPostMultitenantLink + User } alias AshPostgres.Test.Post, as: GlobalPost From 7d4d4a4f879cae82c363635179717367584e8c9b Mon Sep 17 00:00:00 2001 From: Frank Polasek Dugan III Date: Sun, 5 Oct 2025 14:41:42 -0500 Subject: [PATCH 149/174] chore: remove deprecated script documentation; fix mise confusion in .tool-versions (#630) * chore: remove deprecated script * chore: fix mise confusion in .tool-versions --- .tool-versions | 2 +- .../development/migrations-and-tasks.md | 29 ------------------- 2 files changed, 1 insertion(+), 30 deletions(-) diff --git a/.tool-versions b/.tool-versions index 32823875..6c947239 100644 --- a/.tool-versions +++ b/.tool-versions @@ -1,2 +1,2 @@ erlang 27.1.2 -elixir 1.18.4 \ No newline at end of file +elixir 1.18.4-otp-27 diff --git a/documentation/topics/development/migrations-and-tasks.md b/documentation/topics/development/migrations-and-tasks.md index 5fd26271..592bb9a9 100644 --- a/documentation/topics/development/migrations-and-tasks.md +++ b/documentation/topics/development/migrations-and-tasks.md @@ -23,35 +23,6 @@ For more information on generating migrations, run `mix help ash_postgres.genera > > If you have are using schema-based multitenancy, you will also need to define a `all_tenants/0` function in your repo module. See `AshPostgres.Repo` for more. -### Regenerating Migrations - -Often, you will run into a situation where you want to make a slight change to a resource after you've already generated and run migrations. If you are using git and would like to undo those changes, then regenerate the migrations, this script may prove useful: - -```bash -#!/bin/bash - -# Get count of untracked migrations -N_MIGRATIONS=$(git ls-files --others priv/repo/migrations | wc -l) - -# Rollback untracked migrations -mix ash_postgres.rollback -n $N_MIGRATIONS - -# Delete untracked migrations and snapshots -git ls-files --others priv/repo/migrations | xargs rm -git ls-files --others priv/resource_snapshots | xargs rm - -# Regenerate migrations -mix ash.codegen --name $1 - -# Run migrations if flag -if echo $* | grep -e "-m" -q -then - mix ash.migrate -fi -``` - -After saving this file to something like `regen.sh`, make it executable with `chmod +x regen.sh`. Now you can run it with `./regen.sh name_of_operation`. If you would like the migrations to automatically run after regeneration, add the `-m` flag: `./regen.sh name_of_operation -m`. - ## Running Migrations in Production Define a module similar to the following: From c45b3366f95c3419da576eaadc7f37860d5873a9 Mon Sep 17 00:00:00 2001 From: Elliot Bowes Date: Sun, 5 Oct 2025 22:45:54 +0100 Subject: [PATCH 150/174] fix: Support non-public PostgreSQL schemas in resource generator (#631) - Add schema field to generated resources when table is in non-public schema - Fix SQL queries to use schema-qualified table names for foreign keys and constraints - Update index queries to respect actual schema instead of hardcoded 'public' - Add test coverage for tables in custom schemas with foreign keys and indexes * fix: guard against missing snapshot directories in migration generator Fixes crash when generating migrations for resources in non-public schemas where the snapshot directory doesn't exist yet. * chore: run mix format --- .../migration_generator.ex | 19 ++- lib/resource_generator/resource_generator.ex | 7 + lib/resource_generator/spec.ex | 16 ++- test/resource_generator_test.exs | 130 ++++++++++++++++++ 4 files changed, 161 insertions(+), 11 deletions(-) diff --git a/lib/migration_generator/migration_generator.ex b/lib/migration_generator/migration_generator.ex index fcb44c95..00276e25 100644 --- a/lib/migration_generator/migration_generator.ex +++ b/lib/migration_generator/migration_generator.ex @@ -649,14 +649,19 @@ defmodule AshPostgres.MigrationGenerator do folder = get_snapshot_folder(snapshot, opts) snapshot_path = get_snapshot_path(snapshot, folder) - snapshot_path - |> File.ls!() - |> Enum.filter(&String.contains?(&1, "_dev.json")) - |> Enum.each(fn snapshot_name -> + # Guard against missing directories - can happen for new resources or when + # get_snapshot_path's fallback logic returns a non-existent path for + # resources in non-public schemas + if File.dir?(snapshot_path) do snapshot_path - |> Path.join(snapshot_name) - |> File.rm!() - end) + |> File.ls!() + |> Enum.filter(&String.contains?(&1, "_dev.json")) + |> Enum.each(fn snapshot_name -> + snapshot_path + |> Path.join(snapshot_name) + |> File.rm!() + end) + end end) end diff --git a/lib/resource_generator/resource_generator.ex b/lib/resource_generator/resource_generator.ex index 99da8386..b3a507b7 100644 --- a/lib/resource_generator/resource_generator.ex +++ b/lib/resource_generator/resource_generator.ex @@ -115,6 +115,7 @@ if Code.ensure_loaded?(Igniter) do postgres do table #{inspect(table_spec.table_name)} repo #{inspect(table_spec.repo)} + #{schema_option(table_spec)} #{no_migrate_flag} #{references(table_spec, opts[:no_migrations])} #{custom_indexes(table_spec, opts[:no_migrations])} @@ -144,6 +145,12 @@ if Code.ensure_loaded?(Igniter) do end) end + defp schema_option(%{schema: schema}) when schema != "public" do + "schema #{inspect(schema)}" + end + + defp schema_option(_), do: "" + defp default_actions(opts) do cond do opts[:default_actions] && opts[:public] -> diff --git a/lib/resource_generator/spec.ex b/lib/resource_generator/spec.ex index f2da7ec5..9997bbac 100644 --- a/lib/resource_generator/spec.ex +++ b/lib/resource_generator/spec.ex @@ -122,7 +122,13 @@ defmodule AshPostgres.ResourceGenerator.Spec do result end + defp qualified_table_name(%{schema: schema, table_name: table_name}) do + "#{schema}.#{table_name}" + end + defp add_foreign_keys(spec) do + qualified_table = qualified_table_name(spec) + %Postgrex.Result{rows: fkey_rows} = spec.repo.query!( """ @@ -178,7 +184,7 @@ defmodule AshPostgres.ResourceGenerator.Spec do constraints.update_rule, constraints.delete_rule """, - [spec.table_name, spec.schema], + [qualified_table, spec.schema], log: false ) @@ -218,6 +224,8 @@ defmodule AshPostgres.ResourceGenerator.Spec do end defp add_check_constraints(spec) do + qualified_table = qualified_table_name(spec) + %Postgrex.Result{rows: check_constraint_rows} = spec.repo.query!( """ @@ -230,7 +238,7 @@ defmodule AshPostgres.ResourceGenerator.Spec do contype = 'c' AND conrelid::regclass::text = $1 """, - [spec.table_name], + [qualified_table], log: false ) @@ -278,7 +286,7 @@ defmodule AshPostgres.ResourceGenerator.Spec do LEFT JOIN pg_constraint c ON c.conindid = ix.indexrelid AND c.contype = 'p' JOIN - pg_indexes idx ON idx.indexname = i.relname AND idx.schemaname = 'public' -- Adjust schema name if necessary + pg_indexes idx ON idx.indexname = i.relname AND idx.schemaname = $2 JOIN information_schema.tables ta ON ta.table_name = t.relname WHERE @@ -312,7 +320,7 @@ defmodule AshPostgres.ResourceGenerator.Spec do LEFT JOIN pg_constraint c ON c.conindid = ix.indexrelid AND c.contype = 'p' JOIN - pg_indexes idx ON idx.indexname = i.relname AND idx.schemaname = 'public' -- Adjust schema name if necessary + pg_indexes idx ON idx.indexname = i.relname AND idx.schemaname = $2 JOIN information_schema.tables ta ON ta.table_name = t.relname WHERE diff --git a/test/resource_generator_test.exs b/test/resource_generator_test.exs index c50292aa..4878cf6d 100644 --- a/test/resource_generator_test.exs +++ b/test/resource_generator_test.exs @@ -62,4 +62,134 @@ defmodule AshPostgres.ResourceGeenratorTests do end """) end + + test "a resource is generated from a table in a non-public schema with foreign keys and indexes" do + AshPostgres.TestRepo.query!("CREATE SCHEMA IF NOT EXISTS inventory") + + AshPostgres.TestRepo.query!("DROP TABLE IF EXISTS inventory.products CASCADE") + AshPostgres.TestRepo.query!("DROP TABLE IF EXISTS inventory.warehouses CASCADE") + + AshPostgres.TestRepo.query!(""" + CREATE TABLE inventory.warehouses ( + id UUID DEFAULT uuid_generate_v4() PRIMARY KEY, + name VARCHAR(255) NOT NULL, + location VARCHAR(255) + ) + """) + + AshPostgres.TestRepo.query!("CREATE INDEX warehouses_name_idx ON inventory.warehouses(name)") + + AshPostgres.TestRepo.query!(""" + CREATE TABLE inventory.products ( + id UUID DEFAULT uuid_generate_v4() PRIMARY KEY, + name VARCHAR(255) NOT NULL, + warehouse_id UUID REFERENCES inventory.warehouses(id) ON DELETE CASCADE, + quantity INTEGER + ) + """) + + AshPostgres.TestRepo.query!( + "CREATE INDEX products_warehouse_id_idx ON inventory.products(warehouse_id)" + ) + + test_project() + |> Igniter.compose_task("ash_postgres.gen.resources", [ + "MyApp.Inventory", + "--tables", + "inventory.warehouses,inventory.products", + "--yes", + "--repo", + "AshPostgres.TestRepo" + ]) + |> assert_creates("lib/my_app/inventory/warehouse.ex", """ + defmodule MyApp.Inventory.Warehouse do + use Ash.Resource, + domain: MyApp.Inventory, + data_layer: AshPostgres.DataLayer + + actions do + defaults([:read, :destroy, create: :*, update: :*]) + end + + postgres do + table("warehouses") + repo(AshPostgres.TestRepo) + schema("inventory") + end + + attributes do + uuid_primary_key :id do + public?(true) + end + + attribute :name, :string do + allow_nil?(false) + public?(true) + end + + attribute :location, :string do + public?(true) + end + end + + relationships do + has_many :products, MyApp.Inventory.Product do + public?(true) + end + end + end + """) + |> assert_creates("lib/my_app/inventory/product.ex", """ + defmodule MyApp.Inventory.Product do + use Ash.Resource, + domain: MyApp.Inventory, + data_layer: AshPostgres.DataLayer + + actions do + defaults([:read, :destroy, create: :*, update: :*]) + end + + postgres do + table("products") + repo(AshPostgres.TestRepo) + schema("inventory") + + references do + reference :warehouse do + on_delete(:delete) + end + end + end + + attributes do + uuid_primary_key :id do + public?(true) + end + + uuid_primary_key :id do + public?(true) + end + + attribute :name, :string do + public?(true) + end + + attribute :name, :string do + allow_nil?(false) + public?(true) + end + + attribute :quantity, :integer do + public?(true) + end + end + + relationships do + belongs_to :warehouse, MyApp.Inventory.Warehouse do + public?(true) + end + end + end + """) + end end From cf0d1df59476c263002aeae37d90a3ea21ae4c87 Mon Sep 17 00:00:00 2001 From: Steve Brambilla Date: Wed, 8 Oct 2025 23:18:05 -0400 Subject: [PATCH 151/174] refactor: move immutable error expr from AshSql into AshPostgres (#633) --- lib/extensions/immutable_raise_error.ex | 155 ++++++++++++++++++++++++ lib/sql_implementation.ex | 30 ++++- mix.exs | 1 - mix.lock | 2 +- 4 files changed, 181 insertions(+), 7 deletions(-) diff --git a/lib/extensions/immutable_raise_error.ex b/lib/extensions/immutable_raise_error.ex index 7cda113d..b7ccf347 100644 --- a/lib/extensions/immutable_raise_error.ex +++ b/lib/extensions/immutable_raise_error.ex @@ -28,6 +28,8 @@ defmodule AshPostgres.Extensions.ImmutableRaiseError do use AshPostgres.CustomExtension, name: "immutable_raise_error", latest_version: 1 + require Ecto.Query + @impl true def install(0) do ash_raise_error_immutable() @@ -71,4 +73,157 @@ defmodule AshPostgres.Extensions.ImmutableRaiseError do \"\"\") """ end + + @doc false + def immutable_error_expr( + query, + %Ash.Query.Function.Error{arguments: [exception, input]} = value, + bindings, + embedded?, + acc, + type + ) do + acc = %{acc | has_error?: true} + + {encoded, acc} = + if Ash.Expr.expr?(input) do + frag_parts = + Enum.flat_map(input, fn {key, value} -> + if Ash.Expr.expr?(value) do + [ + expr: to_string(key), + raw: "::text, ", + expr: value, + raw: ", " + ] + else + [ + expr: to_string(key), + raw: "::text, ", + expr: value, + raw: "::jsonb, " + ] + end + end) + + frag_parts = + List.update_at(frag_parts, -1, fn {:raw, text} -> + {:raw, String.trim_trailing(text, ", ") <> "))"} + end) + + AshSql.Expr.dynamic_expr( + query, + %Ash.Query.Function.Fragment{ + embedded?: false, + arguments: + [ + raw: "jsonb_build_object('exception', ", + expr: inspect(exception), + raw: "::text, 'input', jsonb_build_object(" + ] ++ + frag_parts + }, + bindings, + embedded?, + nil, + acc + ) + else + {Jason.encode!(%{exception: inspect(exception), input: Map.new(input)}), acc} + end + + dynamic_type = + if type do + # This is a type hint, if we're raising an error, we tell it what the value + # type *would* be in this expression so that we can return a "NULL" of that type + # its weird, but there isn't any other way that I can tell :) + AshSql.Expr.validate_type!(query, type, value) + + type = + AshSql.Expr.parameterized_type( + bindings.sql_behaviour, + type, + [], + :expr + ) + + Ecto.Query.dynamic(type(fragment("NULL"), ^type)) + else + nil + end + + case {dynamic_type, immutable_error_expr_token(query, bindings)} do + {_, nil} -> + :error + + {nil, row_token} -> + {:ok, + Ecto.Query.dynamic( + fragment("ash_raise_error_immutable(?::jsonb, ?)", ^encoded, ^row_token) + ), acc} + + {dynamic_type, row_token} -> + {:ok, + Ecto.Query.dynamic( + fragment( + "ash_raise_error_immutable(?::jsonb, ?, ?)", + ^encoded, + ^dynamic_type, + ^row_token + ) + ), acc} + end + end + + # Returns a row-dependent token to prevent constant-folding for immutable functions. + defp immutable_error_expr_token(query, bindings) do + resource = query.__ash_bindings__.resource + ref_binding = bindings.root_binding + + pk_attr_names = Ash.Resource.Info.primary_key(resource) + + attr_names = + case pk_attr_names do + [] -> + case Ash.Resource.Info.attributes(resource) do + [%{name: name} | _] -> [name] + _ -> [] + end + + pk -> + pk + end + + if ref_binding && attr_names != [] do + value_exprs = + Enum.map(attr_names, fn attr_name -> + if bindings[:parent?] && + ref_binding not in List.wrap(bindings[:lateral_join_bindings]) do + Ecto.Query.dynamic(field(parent_as(^ref_binding), ^attr_name)) + else + Ecto.Query.dynamic(field(as(^ref_binding), ^attr_name)) + end + end) + + row_parts = + value_exprs + |> Enum.map(&{:casted_expr, &1}) + |> Enum.intersperse({:raw, ", "}) + + {%Ecto.Query.DynamicExpr{} = token, _acc} = + AshSql.Expr.dynamic_expr( + query, + %Ash.Query.Function.Fragment{ + embedded?: false, + arguments: [raw: "ROW("] ++ row_parts ++ [raw: ")"] + }, + AshSql.Expr.set_location(bindings, :sub_expr), + false + ) + + token + else + nil + end + end end diff --git a/lib/sql_implementation.ex b/lib/sql_implementation.ex index fefdf876..71b7f03d 100644 --- a/lib/sql_implementation.ex +++ b/lib/sql_implementation.ex @@ -200,6 +200,31 @@ defmodule AshPostgres.SqlImplementation do end end + def expr( + query, + %Ash.Query.Function.Error{} = value, + bindings, + embedded?, + acc, + type + ) do + resource = query.__ash_bindings__.resource + repo = AshSql.dynamic_repo(resource, AshPostgres.SqlImplementation, query) + + if repo.immutable_expr_error?() do + AshPostgres.Extensions.ImmutableRaiseError.immutable_error_expr( + query, + value, + bindings, + embedded?, + acc, + type + ) + else + :error + end + end + def expr( _query, _expr, @@ -334,9 +359,4 @@ defmodule AshPostgres.SqlImplementation do {types, new_returns || returns} end - - @impl true - def immutable_errors?(repo) do - repo.immutable_expr_error?() - end end diff --git a/mix.exs b/mix.exs index cdc61840..79848b88 100644 --- a/mix.exs +++ b/mix.exs @@ -168,7 +168,6 @@ defmodule AshPostgres.MixProject do [ {:ash, ash_version("~> 3.5 and >= 3.5.35")}, {:spark, "~> 2.3 and >= 2.3.4"}, - # TODO: bump to next ash_sql release {:ash_sql, ash_sql_version(git: "https://github.com/ash-project/ash_sql.git")}, {:igniter, "~> 0.6 and >= 0.6.14", optional: true}, {:ecto_sql, "~> 3.13"}, diff --git a/mix.lock b/mix.lock index 7cd067b4..f5d12abd 100644 --- a/mix.lock +++ b/mix.lock @@ -1,6 +1,6 @@ %{ "ash": {:hex, :ash, "3.5.43", "222f9a8ac26ad3b029f8e69306cc83091c992d858b4538af12e33a148f301cab", [:mix], [{:decimal, "~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:ecto, "~> 3.7", [hex: :ecto, repo: "hexpm", optional: false]}, {:ets, "~> 0.8", [hex: :ets, repo: "hexpm", optional: false]}, {:igniter, ">= 0.6.29 and < 1.0.0-0", [hex: :igniter, repo: "hexpm", optional: true]}, {:jason, ">= 1.0.0", [hex: :jason, repo: "hexpm", optional: false]}, {:picosat_elixir, "~> 0.2", [hex: :picosat_elixir, repo: "hexpm", optional: true]}, {:plug, ">= 0.0.0", [hex: :plug, repo: "hexpm", optional: true]}, {:reactor, "~> 0.11", [hex: :reactor, repo: "hexpm", optional: false]}, {:simple_sat, ">= 0.1.1 and < 1.0.0-0", [hex: :simple_sat, repo: "hexpm", optional: true]}, {:spark, ">= 2.3.3 and < 3.0.0-0", [hex: :spark, repo: "hexpm", optional: false]}, {:splode, ">= 0.2.6 and < 1.0.0-0", [hex: :splode, repo: "hexpm", optional: false]}, {:stream_data, "~> 1.0", [hex: :stream_data, repo: "hexpm", optional: false]}, {:telemetry, "~> 1.1", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "48b2aa274c524f5b968c563dd56aec8f9b278c529c8aa46e6fe0ca564c26cc1c"}, - "ash_sql": {:git, "https://github.com/ash-project/ash_sql.git", "65854408e7ce129f78fabafb0a4393f0142da6a6", []}, + "ash_sql": {:git, "https://github.com/ash-project/ash_sql.git", "3044c0555dbe6733d16868951ee89e6d5ef336fa", []}, "benchee": {:hex, :benchee, "1.4.0", "9f1f96a30ac80bab94faad644b39a9031d5632e517416a8ab0a6b0ac4df124ce", [:mix], [{:deep_merge, "~> 1.0", [hex: :deep_merge, repo: "hexpm", optional: false]}, {:statistex, "~> 1.0", [hex: :statistex, repo: "hexpm", optional: false]}, {:table, "~> 0.1.0", [hex: :table, repo: "hexpm", optional: true]}], "hexpm", "299cd10dd8ce51c9ea3ddb74bb150f93d25e968f93e4c1fa31698a8e4fa5d715"}, "bunt": {:hex, :bunt, "1.0.0", "081c2c665f086849e6d57900292b3a161727ab40431219529f13c4ddcf3e7a44", [:mix], [], "hexpm", "dc5f86aa08a5f6fa6b8096f0735c4e76d54ae5c9fa2c143e5a1fc7c1cd9bb6b5"}, "credo": {:hex, :credo, "1.7.12", "9e3c20463de4b5f3f23721527fcaf16722ec815e70ff6c60b86412c695d426c1", [:mix], [{:bunt, "~> 0.2.1 or ~> 1.0", [hex: :bunt, repo: "hexpm", optional: false]}, {:file_system, "~> 0.2 or ~> 1.0", [hex: :file_system, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "8493d45c656c5427d9c729235b99d498bd133421f3e0a683e5c1b561471291e5"}, From 84e528cbf7d43655dec367350d7b020e88fc38f8 Mon Sep 17 00:00:00 2001 From: Daniel Gollings Date: Thu, 9 Oct 2025 06:01:51 +0200 Subject: [PATCH 152/174] fix: update ash_postgresql to handle the new bulk_create response in Ash v3.5.44 (#632) --- lib/data_layer.ex | 33 ++++++-- test/bulk_create_test.exs | 147 +++++++++++++++++++++++++++++++++ test/support/resources/post.ex | 50 +++++++++++ 3 files changed, 225 insertions(+), 5 deletions(-) diff --git a/lib/data_layer.ex b/lib/data_layer.ex index d9b2f41a..aaa2738f 100644 --- a/lib/data_layer.ex +++ b/lib/data_layer.ex @@ -2047,11 +2047,18 @@ defmodule AshPostgres.DataLayer do maybe_create_tenant!(resource, result) end - Ash.Resource.put_metadata( - result, - :bulk_create_index, - changeset.context.bulk_create.index - ) + case get_bulk_operation_metadata(changeset, :bulk_create) do + {index, metadata_key} -> + Ash.Resource.put_metadata(result, metadata_key, index) + + nil -> + # Compatibility fallback + Ash.Resource.put_metadata( + result, + :bulk_create_index, + changeset.context[:bulk_create][:index] + ) + end end)} end end @@ -3638,4 +3645,20 @@ defmodule AshPostgres.DataLayer do resource end end + + defp get_bulk_operation_metadata(changeset, bulk_action_type) do + changeset.context + |> Enum.find_value(fn + # New format: {{:bulk_create, ref}, value} -> {index, metadata_key} + {{^bulk_action_type, ref}, value} -> + {value.index, {:"#{bulk_action_type}_index", ref}} + + # Fallback for old format: {:bulk_create, value} -> {index, metadata_key} + {^bulk_action_type, value} when is_map(value) -> + {value.index, :"#{bulk_action_type}_index"} + + _ -> + nil + end) + end end diff --git a/test/bulk_create_test.exs b/test/bulk_create_test.exs index 01769ccb..d6fd8c17 100644 --- a/test/bulk_create_test.exs +++ b/test/bulk_create_test.exs @@ -2,6 +2,7 @@ defmodule AshPostgres.BulkCreateTest do use AshPostgres.RepoCase, async: false alias AshPostgres.Test.{Post, Record} + require Ash.Query import Ash.Expr describe "bulk creates" do @@ -355,4 +356,150 @@ defmodule AshPostgres.BulkCreateTest do |> Ash.read!() end end + + describe "nested bulk operations" do + test "supports bulk_create in after_action callbacks" do + result = + Ash.bulk_create!( + [%{title: "trigger_nested"}], + Post, + :create_with_nested_bulk_create, + return_records?: true, + authorize?: false + ) + + # Assert the bulk result contains the expected data + assert %Ash.BulkResult{records: [original_post]} = result + assert original_post.title == "trigger_nested" + + # Verify all posts that should exist after the nested operation + all_posts = + Post + |> Ash.Query.sort(:title) + |> Ash.read!() + + # Should have: 1 original + 2 nested = 3 total posts + assert length(all_posts) == 3 + + # Verify we have the expected posts with correct titles + post_titles = Enum.map(all_posts, & &1.title) |> Enum.sort() + assert post_titles == ["nested_post_1", "nested_post_2", "trigger_nested"] + + # Verify the specific nested posts were created by the after_action callback + nested_posts = + Post + |> Ash.Query.filter(expr(title in ["nested_post_1", "nested_post_2"])) + |> Ash.Query.sort(:title) + |> Ash.read!() + + assert length(nested_posts) == 2 + assert [%{title: "nested_post_1"}, %{title: "nested_post_2"}] = nested_posts + + # Verify that each nested post has proper metadata + Enum.each(nested_posts, fn post -> + assert is_binary(post.id) + assert post.title in ["nested_post_1", "nested_post_2"] + end) + end + + test "supports bulk_update in after_action callbacks" do + # Create the original post - the after_action callback will create and update additional posts + result = + Ash.bulk_create!( + [%{title: "trigger_nested_update"}], + Post, + :create_with_nested_bulk_update, + return_records?: true, + authorize?: false + ) + + # Assert the bulk result contains the expected data + assert %Ash.BulkResult{records: [original_post]} = result + assert original_post.title == "trigger_nested_update" + + # Verify all posts that should exist after the nested operations + # The after_action callback should have created 2 posts and updated them + all_posts = + Post + |> Ash.Query.sort(:title) + |> Ash.read!() + + # Should have: 1 original + 2 created and updated = 3 total posts + assert length(all_posts) == 3 + + # Verify the original post still exists + original_posts = + Post + |> Ash.Query.filter(expr(title == "trigger_nested_update")) + |> Ash.read!() + + assert length(original_posts) == 1 + assert hd(original_posts).title == "trigger_nested_update" + + # Verify the nested posts were created and then updated by the after_action callback + updated_posts = + Post + |> Ash.Query.filter(expr(title == "updated_via_nested_bulk")) + |> Ash.read!() + + assert length(updated_posts) == 2 + + # Verify that the updated posts have proper metadata and were actually updated + Enum.each(updated_posts, fn post -> + assert is_binary(post.id) + assert post.title == "updated_via_nested_bulk" + end) + + # Verify no posts remain with the intermediate titles (they should have been updated) + intermediate_posts = + Post + |> Ash.Query.filter(expr(title in ["post_to_update_1", "post_to_update_2"])) + |> Ash.read!() + + assert intermediate_posts == [], + "Posts should have been updated, not left with intermediate titles" + end + + test "nested bulk operations handle metadata indexing correctly" do + # Create multiple posts in the parent bulk operation to test indexing + # Each parent post's after_action callback will create nested posts + result = + Ash.bulk_create!( + [ + %{title: "trigger_nested"}, + %{title: "trigger_nested_2"} + ], + Post, + :create_with_nested_bulk_create, + return_records?: true, + authorize?: false + ) + + # Assert both parent posts were created + assert %Ash.BulkResult{records: parent_posts} = result + assert length(parent_posts) == 2 + + parent_titles = Enum.map(parent_posts, & &1.title) |> Enum.sort() + assert parent_titles == ["trigger_nested", "trigger_nested_2"] + + # Verify total posts: 2 parent + (2 nested per parent from after_action) = 6 total + all_posts = Post |> Ash.Query.sort(:title) |> Ash.read!() + assert length(all_posts) == 6 + + # Count posts by type + nested_posts = + Post + |> Ash.Query.filter(expr(title in ["nested_post_1", "nested_post_2"])) + |> Ash.read!() + + # Should have 4 nested posts (2 for each parent operation via after_action callbacks) + assert length(nested_posts) == 4 + + # Verify each nested post has proper structure + Enum.each(nested_posts, fn post -> + assert is_binary(post.id) + assert post.title in ["nested_post_1", "nested_post_2"] + end) + end + end end diff --git a/test/support/resources/post.ex b/test/support/resources/post.ex index 817e0ff9..69791a38 100644 --- a/test/support/resources/post.ex +++ b/test/support/resources/post.ex @@ -432,6 +432,56 @@ defmodule AshPostgres.Test.Post do upsert_fields([:price]) end + create :create_with_nested_bulk_create do + change( + after_action(fn changeset, result, context -> + Ash.bulk_create!( + [%{title: "nested_post_1"}, %{title: "nested_post_2"}], + __MODULE__, + :create, + authorize?: false, + tenant: changeset.tenant, + return_records?: true + ) + + {:ok, result} + end) + ) + end + + create :create_with_nested_bulk_update do + change( + after_action(fn changeset, result, context -> + created_posts = + Ash.bulk_create!( + [%{title: "post_to_update_1"}, %{title: "post_to_update_2"}], + __MODULE__, + :create, + authorize?: false, + tenant: changeset.tenant, + return_records?: true + ) + + post_ids = Enum.map(created_posts.records, & &1.id) + + Ash.bulk_update!( + __MODULE__, + :set_title, + %{title: "updated_via_nested_bulk"}, + filter: [id: [in: post_ids]], + authorize?: false, + tenant: changeset.tenant + ) + + {:ok, result} + end) + ) + end + + update :set_title do + accept([:title]) + end + update :set_title_from_author do change(atomic_update(:title, expr(author.first_name))) end From a2aac8ae84547f2f828383052abcb4f7e89ad459 Mon Sep 17 00:00:00 2001 From: Zach Daniel Date: Thu, 9 Oct 2025 23:38:09 -0400 Subject: [PATCH 153/174] chore: update ash_sql fix: simplify bulk operation metadata handling --- lib/data_layer.ex | 12 ++++++------ mix.exs | 2 +- mix.lock | 4 ++-- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/lib/data_layer.ex b/lib/data_layer.ex index aaa2738f..6e3354d8 100644 --- a/lib/data_layer.ex +++ b/lib/data_layer.ex @@ -2047,7 +2047,7 @@ defmodule AshPostgres.DataLayer do maybe_create_tenant!(resource, result) end - case get_bulk_operation_metadata(changeset, :bulk_create) do + case get_bulk_operation_metadata(changeset) do {index, metadata_key} -> Ash.Resource.put_metadata(result, metadata_key, index) @@ -3646,16 +3646,16 @@ defmodule AshPostgres.DataLayer do end end - defp get_bulk_operation_metadata(changeset, bulk_action_type) do + defp get_bulk_operation_metadata(changeset) do changeset.context |> Enum.find_value(fn # New format: {{:bulk_create, ref}, value} -> {index, metadata_key} - {{^bulk_action_type, ref}, value} -> - {value.index, {:"#{bulk_action_type}_index", ref}} + {{:bulk_create, ref}, value} -> + {value.index, {:bulk_create_index, ref}} # Fallback for old format: {:bulk_create, value} -> {index, metadata_key} - {^bulk_action_type, value} when is_map(value) -> - {value.index, :"#{bulk_action_type}_index"} + {:bulk_create, value} when is_map(value) -> + {value.index, :bulk_create_index} _ -> nil diff --git a/mix.exs b/mix.exs index 79848b88..260de0d3 100644 --- a/mix.exs +++ b/mix.exs @@ -168,7 +168,7 @@ defmodule AshPostgres.MixProject do [ {:ash, ash_version("~> 3.5 and >= 3.5.35")}, {:spark, "~> 2.3 and >= 2.3.4"}, - {:ash_sql, ash_sql_version(git: "https://github.com/ash-project/ash_sql.git")}, + {:ash_sql, ash_sql_version("~> 0.3 and >= 0.3.2")}, {:igniter, "~> 0.6 and >= 0.6.14", optional: true}, {:ecto_sql, "~> 3.13"}, {:ecto, "~> 3.13"}, diff --git a/mix.lock b/mix.lock index f5d12abd..0c876d7c 100644 --- a/mix.lock +++ b/mix.lock @@ -1,6 +1,6 @@ %{ "ash": {:hex, :ash, "3.5.43", "222f9a8ac26ad3b029f8e69306cc83091c992d858b4538af12e33a148f301cab", [:mix], [{:decimal, "~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:ecto, "~> 3.7", [hex: :ecto, repo: "hexpm", optional: false]}, {:ets, "~> 0.8", [hex: :ets, repo: "hexpm", optional: false]}, {:igniter, ">= 0.6.29 and < 1.0.0-0", [hex: :igniter, repo: "hexpm", optional: true]}, {:jason, ">= 1.0.0", [hex: :jason, repo: "hexpm", optional: false]}, {:picosat_elixir, "~> 0.2", [hex: :picosat_elixir, repo: "hexpm", optional: true]}, {:plug, ">= 0.0.0", [hex: :plug, repo: "hexpm", optional: true]}, {:reactor, "~> 0.11", [hex: :reactor, repo: "hexpm", optional: false]}, {:simple_sat, ">= 0.1.1 and < 1.0.0-0", [hex: :simple_sat, repo: "hexpm", optional: true]}, {:spark, ">= 2.3.3 and < 3.0.0-0", [hex: :spark, repo: "hexpm", optional: false]}, {:splode, ">= 0.2.6 and < 1.0.0-0", [hex: :splode, repo: "hexpm", optional: false]}, {:stream_data, "~> 1.0", [hex: :stream_data, repo: "hexpm", optional: false]}, {:telemetry, "~> 1.1", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "48b2aa274c524f5b968c563dd56aec8f9b278c529c8aa46e6fe0ca564c26cc1c"}, - "ash_sql": {:git, "https://github.com/ash-project/ash_sql.git", "3044c0555dbe6733d16868951ee89e6d5ef336fa", []}, + "ash_sql": {:hex, :ash_sql, "0.3.1", "10c6b69d5b860d1162733324d249624399ade42ecfaff17573617a00f09eb66a", [:mix], [{:ash, ">= 3.5.43 and < 4.0.0-0", [hex: :ash, repo: "hexpm", optional: false]}, {:ecto, "~> 3.9", [hex: :ecto, repo: "hexpm", optional: false]}, {:ecto_sql, "~> 3.9", [hex: :ecto_sql, repo: "hexpm", optional: false]}], "hexpm", "a6f69c8709afd6581cfebf4713b90be8e63c530bde162b2691da850599da4a2c"}, "benchee": {:hex, :benchee, "1.4.0", "9f1f96a30ac80bab94faad644b39a9031d5632e517416a8ab0a6b0ac4df124ce", [:mix], [{:deep_merge, "~> 1.0", [hex: :deep_merge, repo: "hexpm", optional: false]}, {:statistex, "~> 1.0", [hex: :statistex, repo: "hexpm", optional: false]}, {:table, "~> 0.1.0", [hex: :table, repo: "hexpm", optional: true]}], "hexpm", "299cd10dd8ce51c9ea3ddb74bb150f93d25e968f93e4c1fa31698a8e4fa5d715"}, "bunt": {:hex, :bunt, "1.0.0", "081c2c665f086849e6d57900292b3a161727ab40431219529f13c4ddcf3e7a44", [:mix], [], "hexpm", "dc5f86aa08a5f6fa6b8096f0735c4e76d54ae5c9fa2c143e5a1fc7c1cd9bb6b5"}, "credo": {:hex, :credo, "1.7.12", "9e3c20463de4b5f3f23721527fcaf16722ec815e70ff6c60b86412c695d426c1", [:mix], [{:bunt, "~> 0.2.1 or ~> 1.0", [hex: :bunt, repo: "hexpm", optional: false]}, {:file_system, "~> 0.2 or ~> 1.0", [hex: :file_system, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "8493d45c656c5427d9c729235b99d498bd133421f3e0a683e5c1b561471291e5"}, @@ -40,7 +40,7 @@ "postgrex": {:hex, :postgrex, "0.21.1", "2c5cc830ec11e7a0067dd4d623c049b3ef807e9507a424985b8dcf921224cd88", [:mix], [{:db_connection, "~> 2.1", [hex: :db_connection, repo: "hexpm", optional: false]}, {:decimal, "~> 1.5 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:table, "~> 0.1.0", [hex: :table, repo: "hexpm", optional: true]}], "hexpm", "27d8d21c103c3cc68851b533ff99eef353e6a0ff98dc444ea751de43eb48bdac"}, "reactor": {:hex, :reactor, "0.17.0", "eb8bdb530dbae824e2d36a8538f8ec4f3aa7c2d1b61b04959fa787c634f88b49", [:mix], [{:igniter, "~> 0.4", [hex: :igniter, repo: "hexpm", optional: true]}, {:iterex, "~> 0.1", [hex: :iterex, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}, {:libgraph, "~> 0.16", [hex: :libgraph, repo: "hexpm", optional: false]}, {:spark, ">= 2.3.3 and < 3.0.0-0", [hex: :spark, repo: "hexpm", optional: false]}, {:splode, "~> 0.2", [hex: :splode, repo: "hexpm", optional: false]}, {:telemetry, "~> 1.2", [hex: :telemetry, repo: "hexpm", optional: false]}, {:yaml_elixir, "~> 2.11", [hex: :yaml_elixir, repo: "hexpm", optional: false]}, {:ymlr, "~> 5.0", [hex: :ymlr, repo: "hexpm", optional: false]}], "hexpm", "3c3bf71693adbad9117b11ec83cfed7d5851b916ade508ed9718de7ae165bf25"}, "req": {:hex, :req, "0.5.15", "662020efb6ea60b9f0e0fac9be88cd7558b53fe51155a2d9899de594f9906ba9", [:mix], [{:brotli, "~> 0.3.1", [hex: :brotli, repo: "hexpm", optional: true]}, {:ezstd, "~> 1.0", [hex: :ezstd, repo: "hexpm", optional: true]}, {:finch, "~> 0.17", [hex: :finch, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}, {:mime, "~> 2.0.6 or ~> 2.1", [hex: :mime, repo: "hexpm", optional: false]}, {:nimble_csv, "~> 1.0", [hex: :nimble_csv, repo: "hexpm", optional: true]}, {:plug, "~> 1.0", [hex: :plug, repo: "hexpm", optional: true]}], "hexpm", "a6513a35fad65467893ced9785457e91693352c70b58bbc045b47e5eb2ef0c53"}, - "rewrite": {:hex, :rewrite, "1.1.2", "f5a5d10f5fed1491a6ff48e078d4585882695962ccc9e6c779bae025d1f92eda", [:mix], [{:glob_ex, "~> 0.1", [hex: :glob_ex, repo: "hexpm", optional: false]}, {:sourceror, "~> 1.0", [hex: :sourceror, repo: "hexpm", optional: false]}, {:text_diff, "~> 0.1", [hex: :text_diff, repo: "hexpm", optional: false]}], "hexpm", "7f8b94b1e3528d0a47b3e8b7bfeca559d2948a65fa7418a9ad7d7712703d39d4"}, + "rewrite": {:hex, :rewrite, "1.2.0", "80220eb14010e175b67c939397e1a8cdaa2c32db6e2e0a9d5e23e45c0414ce21", [:mix], [{:glob_ex, "~> 0.1", [hex: :glob_ex, repo: "hexpm", optional: false]}, {:sourceror, "~> 1.0", [hex: :sourceror, repo: "hexpm", optional: false]}, {:text_diff, "~> 0.1", [hex: :text_diff, repo: "hexpm", optional: false]}], "hexpm", "a1cd702bbb9d51613ab21091f04a386d750fc6f4516b81900df082d78b2d8c50"}, "simple_sat": {:hex, :simple_sat, "0.1.3", "f650fc3c184a5fe741868b5ac56dc77fdbb428468f6dbf1978e14d0334497578", [:mix], [], "hexpm", "a54305066a356b7194dc81db2a89232bacdc0b3edaef68ed9aba28dcbc34887b"}, "sobelow": {:hex, :sobelow, "0.14.0", "dd82aae8f72503f924fe9dd97ffe4ca694d2f17ec463dcfd365987c9752af6ee", [:mix], [{:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "7ecf91e298acfd9b24f5d761f19e8f6e6ac585b9387fb6301023f1f2cd5eed5f"}, "sourceror": {:hex, :sourceror, "1.10.0", "38397dedbbc286966ec48c7af13e228b171332be1ad731974438c77791945ce9", [:mix], [], "hexpm", "29dbdfc92e04569c9d8e6efdc422fc1d815f4bd0055dc7c51b8800fb75c4b3f1"}, From 9aaebc60f0f8015d8344aa7fc1ab2deaf5900d86 Mon Sep 17 00:00:00 2001 From: Zach Daniel Date: Thu, 9 Oct 2025 23:38:56 -0400 Subject: [PATCH 154/174] chore: update ash_sql --- mix.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mix.lock b/mix.lock index 0c876d7c..1827dcb4 100644 --- a/mix.lock +++ b/mix.lock @@ -1,6 +1,6 @@ %{ "ash": {:hex, :ash, "3.5.43", "222f9a8ac26ad3b029f8e69306cc83091c992d858b4538af12e33a148f301cab", [:mix], [{:decimal, "~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:ecto, "~> 3.7", [hex: :ecto, repo: "hexpm", optional: false]}, {:ets, "~> 0.8", [hex: :ets, repo: "hexpm", optional: false]}, {:igniter, ">= 0.6.29 and < 1.0.0-0", [hex: :igniter, repo: "hexpm", optional: true]}, {:jason, ">= 1.0.0", [hex: :jason, repo: "hexpm", optional: false]}, {:picosat_elixir, "~> 0.2", [hex: :picosat_elixir, repo: "hexpm", optional: true]}, {:plug, ">= 0.0.0", [hex: :plug, repo: "hexpm", optional: true]}, {:reactor, "~> 0.11", [hex: :reactor, repo: "hexpm", optional: false]}, {:simple_sat, ">= 0.1.1 and < 1.0.0-0", [hex: :simple_sat, repo: "hexpm", optional: true]}, {:spark, ">= 2.3.3 and < 3.0.0-0", [hex: :spark, repo: "hexpm", optional: false]}, {:splode, ">= 0.2.6 and < 1.0.0-0", [hex: :splode, repo: "hexpm", optional: false]}, {:stream_data, "~> 1.0", [hex: :stream_data, repo: "hexpm", optional: false]}, {:telemetry, "~> 1.1", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "48b2aa274c524f5b968c563dd56aec8f9b278c529c8aa46e6fe0ca564c26cc1c"}, - "ash_sql": {:hex, :ash_sql, "0.3.1", "10c6b69d5b860d1162733324d249624399ade42ecfaff17573617a00f09eb66a", [:mix], [{:ash, ">= 3.5.43 and < 4.0.0-0", [hex: :ash, repo: "hexpm", optional: false]}, {:ecto, "~> 3.9", [hex: :ecto, repo: "hexpm", optional: false]}, {:ecto_sql, "~> 3.9", [hex: :ecto_sql, repo: "hexpm", optional: false]}], "hexpm", "a6f69c8709afd6581cfebf4713b90be8e63c530bde162b2691da850599da4a2c"}, + "ash_sql": {:hex, :ash_sql, "0.3.2", "e2d65dac1c813cbd2569a750bf1c063109778e840052e44535ced294d7638a19", [:mix], [{:ash, ">= 3.5.43 and < 4.0.0-0", [hex: :ash, repo: "hexpm", optional: false]}, {:ecto, "~> 3.9", [hex: :ecto, repo: "hexpm", optional: false]}, {:ecto_sql, "~> 3.9", [hex: :ecto_sql, repo: "hexpm", optional: false]}], "hexpm", "1f6e5d827c0eb55fc5a07f58eb97f9bb3e6b290d83df75883f422537b98c9c68"}, "benchee": {:hex, :benchee, "1.4.0", "9f1f96a30ac80bab94faad644b39a9031d5632e517416a8ab0a6b0ac4df124ce", [:mix], [{:deep_merge, "~> 1.0", [hex: :deep_merge, repo: "hexpm", optional: false]}, {:statistex, "~> 1.0", [hex: :statistex, repo: "hexpm", optional: false]}, {:table, "~> 0.1.0", [hex: :table, repo: "hexpm", optional: true]}], "hexpm", "299cd10dd8ce51c9ea3ddb74bb150f93d25e968f93e4c1fa31698a8e4fa5d715"}, "bunt": {:hex, :bunt, "1.0.0", "081c2c665f086849e6d57900292b3a161727ab40431219529f13c4ddcf3e7a44", [:mix], [], "hexpm", "dc5f86aa08a5f6fa6b8096f0735c4e76d54ae5c9fa2c143e5a1fc7c1cd9bb6b5"}, "credo": {:hex, :credo, "1.7.12", "9e3c20463de4b5f3f23721527fcaf16722ec815e70ff6c60b86412c695d426c1", [:mix], [{:bunt, "~> 0.2.1 or ~> 1.0", [hex: :bunt, repo: "hexpm", optional: false]}, {:file_system, "~> 0.2 or ~> 1.0", [hex: :file_system, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "8493d45c656c5427d9c729235b99d498bd133421f3e0a683e5c1b561471291e5"}, From c50052fde2aae223e2eb7949b7c5b869f3eb2da4 Mon Sep 17 00:00:00 2001 From: Zach Daniel Date: Thu, 9 Oct 2025 23:39:09 -0400 Subject: [PATCH 155/174] chore: release version v2.6.21 --- CHANGELOG.md | 21 +++++++++++++++++++++ mix.exs | 2 +- 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f6546f3a..2778d41d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,27 @@ See [Conventional Commits](https://www.conventionalcommits.org) for commit guide +## [v2.6.21](https://github.com/ash-project/ash_postgres/compare/v2.6.20...v2.6.21) (2025-10-10) + + + + +### Bug Fixes: + +* simplify bulk operation metadata handling by Zach Daniel + +* update ash_postgresql to handle the new bulk_create response in Ash v3.5.44 (#632) by Daniel Gollings + +* Support non-public PostgreSQL schemas in resource generator (#631) by Elliot Bowes + +* guard against missing snapshot directories in migration generator by Elliot Bowes + +* ensure that tenant is properly used in many-to-many joins by Zach Daniel + +### Improvements: + +* Add immutable version of `ash_raise_error` function to support extensions like Citus (#620) by Steve Brambilla + ## [v2.6.20](https://github.com/ash-project/ash_postgres/compare/v2.6.19...v2.6.20) (2025-09-27) diff --git a/mix.exs b/mix.exs index 260de0d3..f1d82380 100644 --- a/mix.exs +++ b/mix.exs @@ -5,7 +5,7 @@ defmodule AshPostgres.MixProject do The PostgreSQL data layer for Ash Framework """ - @version "2.6.20" + @version "2.6.21" def project do [ From e43b89f4381ac4dcf6e4fbe5cfc5a2a7db270b9d Mon Sep 17 00:00:00 2001 From: James Harton Date: Sat, 11 Oct 2025 12:51:55 +1300 Subject: [PATCH 156/174] chore: REUSE compliance (#635) --- .check.exs | 7 ++++++- .credo.exs | 4 ++++ .formatter.exs | 4 ++++ .github/dependabot.yml | 4 ++++ .github/workflows/elixir.yml | 6 +++++- .gitignore | 4 ++++ .tool-versions | 1 + .tool-versions.license | 3 +++ .vscode/settings.json.license | 3 +++ CHANGELOG.md | 6 ++++++ LICENSE | 21 ------------------- LICENSES/MIT.txt | 18 ++++++++++++++++ README.md | 7 +++++++ SECURITY.md | 6 ++++++ benchmarks/bulk_create.exs | 4 ++++ config/config.exs | 4 ++++ documentation/1.0-CHANGELOG.md | 6 ++++++ .../dsls/DSL-AshPostgres.DataLayer.md.license | 3 +++ .../what-is-ash-postgres.md | 6 ++++++ documentation/topics/advanced/expressions.md | 6 ++++++ .../topics/advanced/manual-relationships.md | 6 ++++++ .../advanced/schema-based-multitenancy.md | 6 ++++++ .../topics/advanced/using-multiple-repos.md | 6 ++++++ .../development/migrations-and-tasks.md | 6 ++++++ documentation/topics/development/testing.md | 6 ++++++ .../topics/development/upgrading-to-2.0.md | 6 ++++++ .../topics/resources/polymorphic-resources.md | 6 ++++++ documentation/topics/resources/references.md | 6 ++++++ .../get-started-with-ash-postgres.md | 6 ++++++ .../set-up-with-existing-database.md | 6 ++++++ lib/ash_postgres.ex | 4 ++++ lib/check_constraint.ex | 4 ++++ lib/custom_aggregate.ex | 4 ++++ lib/custom_extension.ex | 4 ++++ lib/custom_index.ex | 4 ++++ lib/data_layer.ex | 4 ++++ lib/data_layer/info.ex | 4 ++++ lib/ecto_migration_default.ex | 4 ++++ lib/extensions/immutable_raise_error.ex | 4 ++++ lib/extensions/vector.ex | 4 ++++ lib/functions/binding.ex | 4 ++++ lib/functions/ilike.ex | 4 ++++ lib/functions/like.ex | 4 ++++ lib/functions/trigram_similarity.ex | 4 ++++ lib/functions/vector_cosine_distance.ex | 4 ++++ lib/functions/vector_l2_distance.ex | 4 ++++ lib/igniter.ex | 4 ++++ lib/manual_relationship.ex | 4 ++++ lib/migration.ex | 4 ++++ lib/migration_compile_cache.ex | 4 ++++ lib/migration_generator/ash_functions.ex | 4 ++++ .../migration_generator.ex | 4 ++++ lib/migration_generator/operation.ex | 4 ++++ lib/migration_generator/phase.ex | 4 ++++ lib/mix/helpers.ex | 4 ++++ lib/mix/tasks/ash_postgres.create.ex | 4 ++++ lib/mix/tasks/ash_postgres.drop.ex | 4 ++++ lib/mix/tasks/ash_postgres.gen.resources.ex | 4 ++++ .../tasks/ash_postgres.generate_migrations.ex | 4 ++++ lib/mix/tasks/ash_postgres.install.ex | 4 ++++ lib/mix/tasks/ash_postgres.migrate.ex | 4 ++++ lib/mix/tasks/ash_postgres.rollback.ex | 4 ++++ lib/mix/tasks/ash_postgres.setup_vector.ex | 4 ++++ .../tasks/ash_postgres.squash_snapshots.ex | 4 ++++ lib/multitenancy.ex | 4 ++++ lib/reference.ex | 4 ++++ lib/repo.ex | 4 ++++ lib/repo/before_compile.ex | 4 ++++ lib/resource_generator/resource_generator.ex | 4 ++++ lib/resource_generator/sensitive_data.ex | 4 ++++ lib/resource_generator/spec.ex | 4 ++++ lib/sql_implementation.ex | 4 ++++ lib/statement.ex | 4 ++++ lib/type.ex | 4 ++++ lib/types/ci_string_wrapper.ex | 4 ++++ lib/types/ltree.ex | 4 ++++ lib/types/string_wrapper.ex | 4 ++++ lib/types/timestamptz.ex | 4 ++++ lib/types/timestamptz_usec.ex | 4 ++++ lib/types/tsquery.ex | 4 ++++ lib/types/tsvector.ex | 4 ++++ lib/verifiers/ensure_table_or_polymorphic.ex | 4 ++++ ...te_multitenancy_and_non_full_match_type.ex | 4 ++++ ...event_multidimensional_array_aggregates.ex | 4 ++++ .../validate_identity_index_names.ex | 4 ++++ lib/verifiers/validate_references.ex | 4 ++++ lib/version_agent.ex | 3 +++ logos/small-logo.png.license | 3 +++ mix.exs | 17 ++++++++++++--- mix.lock.license | 3 +++ ...6214825_migrate_resources_extensions_1.exs | 4 ++++ .../20250526214827_migrate_resources1.exs | 4 ++++ .../dev_test_repo/extensions.json.license | 3 +++ .../20250526214827.json.license | 3 +++ .../extensions.json.license | 3 +++ .../accounts/20221217123726.json.license | 3 +++ .../accounts/20240327211150.json.license | 3 +++ .../authors/20220805191443.json.license | 3 +++ .../authors/20220914104733.json.license | 3 +++ .../authors/20240327211150.json.license | 3 +++ .../authors/20240705113722.json.license | 3 +++ .../authors/20250908212414.json.license | 3 +++ .../chats/20250908093505.json.license | 3 +++ .../20241208221219.json.license | 3 +++ .../comedians/20241217232254.json.license | 3 +++ .../comedians/20250413141328.json.license | 3 +++ .../comment_links/20250123161002.json.license | 3 +++ .../20220805191443.json.license | 3 +++ .../20240327211150.json.license | 3 +++ .../comments/20220805191443.json.license | 3 +++ .../comments/20240327211150.json.license | 3 +++ .../comments/20240327211917.json.license | 3 +++ .../20230816231942.json.license | 3 +++ .../20240327211150.json.license | 3 +++ .../20231116013020.json.license | 3 +++ .../20240327211150.json.license | 3 +++ .../20240327211917.json.license | 3 +++ .../20231116013020.json.license | 3 +++ .../20240327211150.json.license | 3 +++ .../20240327211917.json.license | 3 +++ .../20230816231942.json.license | 3 +++ .../20240327211150.json.license | 3 +++ .../20240327211917.json.license | 3 +++ .../20250714225304.json.license | 3 +++ .../20250714225304.json.license | 3 +++ .../20230816231942.json.license | 3 +++ .../20240327211150.json.license | 3 +++ .../content/20250123164209.json.license | 3 +++ .../20250123164209.json.license | 3 +++ .../test_repo/csv/20250320225052.json.license | 3 +++ .../customers/20250908073737.json.license | 3 +++ .../entities/20240109160153.json.license | 3 +++ .../entities/20240327211150.json.license | 3 +++ .../entities/20240327211917.json.license | 3 +++ .../test_repo/extensions.json.license | 3 +++ .../integer_posts/20220805191443.json.license | 3 +++ .../items/20240713134055.json.license | 3 +++ .../items/20240717104854.json.license | 3 +++ .../items/20240717153736.json.license | 3 +++ .../jokes/20241217232254.json.license | 3 +++ .../jokes/20250413141328.json.license | 3 +++ .../managers/20230526144249.json.license | 3 +++ .../managers/20240327211150.json.license | 3 +++ .../messages/20250908093505.json.license | 3 +++ .../20250519103535.json.license | 3 +++ .../20220805191443.json.license | 3 +++ .../20240327211150.json.license | 3 +++ .../20240627223225.json.license | 3 +++ .../20240702164513.json.license | 3 +++ .../20240703155134.json.license | 3 +++ .../20250122190558.json.license | 3 +++ .../note/20250123164209.json.license | 3 +++ .../orders/20250908073737.json.license | 3 +++ .../orgs/20230129050950.json.license | 3 +++ .../orgs/20240327211150.json.license | 3 +++ .../orgs/20250210191116.json.license | 3 +++ .../other_items/20240713134055.json.license | 3 +++ .../other_items/20240717151815.json.license | 3 +++ .../points/20250313112823.json.license | 3 +++ .../20240227180858.json.license | 3 +++ .../20240227181137.json.license | 3 +++ .../20240327211150.json.license | 3 +++ .../20240516205244.json.license | 3 +++ .../20240517223946.json.license | 3 +++ .../post_links/20220805191443.json.license | 3 +++ .../post_links/20221017133955.json.license | 3 +++ .../post_links/20221202194704.json.license | 3 +++ .../post_links/20240610195853.json.license | 3 +++ .../post_links/20240617193218.json.license | 3 +++ .../20240906170759.json.license | 3 +++ .../post_ratings/20220805191443.json.license | 3 +++ .../post_ratings/20240327211150.json.license | 3 +++ .../post_tags/20250810102512.json.license | 3 +++ .../post_views/20230905050351.json.license | 3 +++ .../post_views/20240327211917.json.license | 3 +++ .../posts/20220805191443.json.license | 3 +++ .../posts/20221125171150.json.license | 3 +++ .../posts/20221125171204.json.license | 3 +++ .../posts/20230129050950.json.license | 3 +++ .../posts/20230823161017.json.license | 3 +++ .../posts/20231127215636.json.license | 3 +++ .../posts/20231129141453.json.license | 3 +++ .../posts/20231219132807.json.license | 3 +++ .../posts/20240129221511.json.license | 3 +++ .../posts/20240224001913.json.license | 3 +++ .../posts/20240327211150.json.license | 3 +++ .../posts/20240327211917.json.license | 3 +++ .../posts/20240503012410.json.license | 3 +++ .../posts/20240504185511.json.license | 3 +++ .../posts/20240524031113.json.license | 3 +++ .../posts/20240524041750.json.license | 3 +++ .../posts/20240617193218.json.license | 3 +++ .../posts/20240618102809.json.license | 3 +++ .../posts/20240712232026.json.license | 3 +++ .../posts/20240715135403.json.license | 3 +++ .../posts/20240910180107.json.license | 3 +++ .../posts/20240911225320.json.license | 3 +++ .../posts/20240918104740.json.license | 3 +++ .../posts/20240929121224.json.license | 3 +++ .../posts/20250217054207.json.license | 3 +++ .../posts/20250313112823.json.license | 3 +++ .../posts/20250520130634.json.license | 3 +++ .../posts/20250521105654.json.license | 3 +++ .../posts/20250612113920.json.license | 3 +++ .../posts/20250618011917.json.license | 3 +++ .../products/20250908073737.json.license | 3 +++ .../profile/20220805191443.json.license | 3 +++ .../20240327211150.json.license | 3 +++ .../punchlines/20250413141328.json.license | 3 +++ .../records/20240109160153.json.license | 3 +++ .../records/20240327211150.json.license | 3 +++ .../records/20240327211917.json.license | 3 +++ .../20250605230457.json.license | 3 +++ .../20240717153736.json.license | 3 +++ .../rsvps/20251002180954.json.license | 3 +++ .../20240821213522.json.license | 3 +++ .../staff_group/20250123164209.json.license | 3 +++ .../20250123164209.json.license | 3 +++ .../standup_clubs/20250413141328.json.license | 3 +++ .../20240618085942.json.license | 3 +++ .../string_points/20250313112823.json.license | 3 +++ .../sub_items/20240713134055.json.license | 3 +++ .../20240130133933.json.license | 3 +++ .../20240130133933.json.license | 3 +++ .../20240130133933.json.license | 3 +++ .../20240130133933.json.license | 3 +++ .../tags/20250810102512.json.license | 3 +++ .../20240327211150.json.license | 3 +++ .../20240327211917.json.license | 3 +++ .../temp_entities/20240109160153.json.license | 3 +++ .../composite_key/20250220073135.json.license | 3 +++ .../composite_key/20250220073141.json.license | 3 +++ .../20250122203454.json.license | 3 +++ .../friend_links/20240610162043.json.license | 3 +++ .../20220805191441.json.license | 3 +++ .../20240327211149.json.license | 3 +++ .../20251001120813.json.license | 3 +++ .../20250731124648.json.license | 3 +++ .../20250731124648.json.license | 3 +++ .../20250731124648.json.license | 3 +++ .../20250731124648.json.license | 3 +++ .../user_invites/20240727145758.json.license | 3 +++ .../users/20220805191443.json.license | 3 +++ .../users/20221217123726.json.license | 3 +++ .../users/20230129050950.json.license | 3 +++ .../users/20240327211150.json.license | 3 +++ .../users/20240727145758.json.license | 3 +++ .../users/20240929124728.json.license | 3 +++ .../users/20250320225052.json.license | 3 +++ .../users/20250321142835.json.license | 3 +++ .../migrations/.gitkeep.license | 3 +++ .../20240627223224_install_5_extensions.exs | 4 ++++ ...2025_install_ash-functions_extension_4.exs | 4 ++++ ...3205301_migrate_resources_extensions_1.exs | 4 ++++ .../20220805191440_install_4_extensions.exs | 4 ++++ .../20220805191443_migrate_resources1.exs | 4 ++++ .../20220914104733_migrate_resources2.exs | 4 ++++ .../20221017133955_migrate_resources3.exs | 4 ++++ .../20221125171148_migrate_resources4.exs | 4 ++++ .../20221125171150_migrate_resources5.exs | 4 ++++ .../20221202194704_migrate_resources6.exs | 4 ++++ .../20221217123726_migrate_resources7.exs | 4 ++++ .../20230129050950_migrate_resources8.exs | 4 ++++ .../20230526144249_migrate_resources9.exs | 4 ++++ ...182523_install_ash-functions_extension.exs | 4 ++++ ...59_install_demo-functions_v0_extension.exs | 4 ++++ ...18_install_demo-functions_v1_extension.exs | 4 ++++ ...6231942_add_complex_calculation_tables.exs | 4 ++++ .../20230823161017_migrate_resources10.exs | 4 ++++ .../20230905050351_add_post_views.exs | 4 ++++ ...3020_add_complex_calculations_channels.exs | 4 ++++ .../20231127212608_add_composite_type.exs | 4 ++++ .../20231127215636_migrate_resources11.exs | 4 ++++ .../20231129141453_migrate_resources12.exs | 4 ++++ ...0937_install_ash-functions_extension_2.exs | 4 ++++ .../20231219132807_migrate_resources13.exs | 4 ++++ ...1611_install_ash-functions_extension_3.exs | 4 ++++ .../20240109155951_create_temp_schema.exs | 4 ++++ .../20240109160153_migrate_resources14.exs | 4 ++++ .../20240129221511_migrate_resources15.exs | 4 ++++ ...133933_add_resources_for_subquery_test.exs | 4 ++++ .../20240224001913_migrate_resources16.exs | 4 ++++ .../20240227180858_migrate_resources17.exs | 4 ++++ .../20240227181137_migrate_resources18.exs | 4 ++++ .../20240229050455_install_5_extensions.exs | 4 ++++ .../20240327211150_migrate_resources19.exs | 4 ++++ .../20240327211917_migrate_resources20.exs | 4 ++++ .../20240503012410_migrate_resources21.exs | 4 ++++ .../20240504185511_migrate_resources22.exs | 4 ++++ .../20240516205244_migrate_resources23.exs | 4 ++++ .../20240517223946_migrate_resources24.exs | 4 ++++ .../20240524031113_migrate_resources25.exs | 4 ++++ .../20240524041750_migrate_resources26.exs | 4 ++++ .../20240610195853_migrate_resources27.exs | 4 ++++ .../20240617193218_migrate_resources28.exs | 4 ++++ .../20240618085942_migrate_resources29.exs | 4 ++++ .../20240618102809_migrate_resources30.exs | 4 ++++ ...2715_install_ash-functions_extension_4.exs | 4 ++++ .../20240627223225_migrate_resources31.exs | 4 ++++ .../20240703155134_migrate_resources32.exs | 4 ++++ .../20240705113722_migrate_resources33.exs | 4 ++++ .../20240712232026_migrate_resources34.exs | 4 ++++ ...240713134055_multi_domain_calculations.exs | 4 ++++ .../20240715135403_migrate_resources35.exs | 4 ++++ ...7104854_no_attributes_calculation_test.exs | 4 ++++ .../20240717151815_migrate_resources36.exs | 4 ++++ .../20240717153736_migrate_resources37.exs | 4 ++++ .../20240727145758_user_invites.exs | 4 ++++ .../20240906170759_migrate_resources38.exs | 4 ++++ .../20240910180107_migrate_resources39.exs | 4 ++++ .../20240911225319_install_1_extensions.exs | 4 ++++ .../20240911225320_migrate_resources40.exs | 4 ++++ .../20240918104740_migrate_resources41.exs | 4 ++++ .../20240929121224_migrate_resources42.exs | 4 ++++ .../20240929124728_migrate_resources43.exs | 4 ++++ .../20241208221219_migrate_resources44.exs | 4 ++++ .../20241217232254_migrate_resources45.exs | 4 ++++ ...3205259_migrate_resources_extensions_1.exs | 4 ++++ .../20250122190558_migrate_resources46.exs | 4 ++++ .../20250123161002_migrate_resources47.exs | 4 ++++ .../20250123164209_migrate_resources48.exs | 4 ++++ .../20250210191116_migrate_resources49.exs | 4 ++++ .../20250217054207_migrate_resources50.exs | 4 ++++ .../20250313112823_migrate_resources51.exs | 4 ++++ .../20250320225052_add_csv_resource.exs | 4 ++++ .../20250321142835_migrate_resources52.exs | 4 ++++ ...41328_add_punchlines_and_standup_clubs.exs | 4 ++++ .../20250519103535_migrate_resources53.exs | 4 ++++ .../20250520130634_migrate_resources54.exs | 4 ++++ ...20250521105654_add_model_tuple_to_post.exs | 4 ++++ ...0457_create_record_temp_entities_table.exs | 4 ++++ .../20250612113920_migrate_resources55.exs | 4 ++++ .../20250618011917_migrate_resources56.exs | 4 ++++ ..._complex_calculations_folder_and_items.exs | 4 ++++ .../20250731124648_migrate_resources57.exs | 4 ++++ .../20250810102512_migrate_resources58.exs | 4 ++++ .../20250908073737_migrate_resources59.exs | 4 ++++ .../20250908093505_migrate_resources60.exs | 4 ++++ .../20250908212414_migrate_resources61.exs | 4 ++++ .../20251002180954_migrate_resources62.exs | 4 ++++ .../20220805191441_migrate_resources1.exs | 4 ++++ .../20240327211149_migrate_resources2.exs | 4 ++++ .../20240610162043_migrate_resources3.exs | 4 ++++ .../20250122203454_migrate_resources4.exs | 4 ++++ .../20250220073135_migrate_resources5.exs | 4 ++++ .../20250220073141_migrate_resources6.exs | 4 ++++ .../20251001120813_migrate_resources7.exs | 4 ++++ test/aggregate_test.exs | 4 ++++ test/ash_postgres_test.exs | 4 ++++ test/atomics_test.exs | 4 ++++ test/bulk_create_test.exs | 4 ++++ test/bulk_destroy_test.exs | 4 ++++ test/bulk_update_test.exs | 4 ++++ test/calculation_test.exs | 4 ++++ test/cascade_destroy_test.exs | 4 ++++ test/combination_test.exs | 4 ++++ test/complex_calculations_test.exs | 4 ++++ test/composite_type_test.exs | 4 ++++ test/constraint_test.exs | 4 ++++ test/create_test.exs | 4 ++++ test/custom_expression_test.exs | 4 ++++ test/custom_index_test.exs | 4 ++++ ...ic_non_bulk_actions_policy_bypass_test.exs | 4 ++++ test/destroy_test.exs | 4 ++++ test/dev_migrations_test.exs | 4 ++++ test/distinct_test.exs | 4 ++++ test/ecto_compatibility_test.exs | 4 ++++ test/embeddable_resource_test.exs | 4 ++++ test/enum_test.exs | 4 ++++ test/error_expr_test.exs | 4 ++++ ...lationship_by_parent_relationship_test.exs | 4 ++++ test/filter_field_policy_test.exs | 4 ++++ test/filter_test.exs | 4 ++++ test/load_test.exs | 4 ++++ test/lock_test.exs | 4 ++++ test/ltree_test.exs | 4 ++++ test/manual_relationships_test.exs | 4 ++++ test/manual_update_test.exs | 4 ++++ test/many_to_many_expr_test.exs | 4 ++++ test/migration_generator_test.exs | 4 ++++ test/mix/tasks/ash_postgres.install_test.exs | 4 ++++ test/mix_squash_snapshots_test.exs | 4 ++++ test/multi_domain_calculations_test.exs | 4 ++++ test/multitenancy_test.exs | 4 ++++ test/parent_filter_test.exs | 4 ++++ test/parent_sort_test.exs | 4 ++++ test/polymorphism_test.exs | 4 ++++ test/primary_key_test.exs | 4 ++++ test/references_test.exs | 4 ++++ test/rel_with_parent_filter_test.exs | 4 ++++ test/resource_generator_test.exs | 4 ++++ test/schema_test.exs | 4 ++++ test/select_test.exs | 4 ++++ test/sort_test.exs | 4 ++++ test/storage_types_test.exs | 4 ++++ test/subquery_test.exs | 4 ++++ test/support/complex_calculations/domain.ex | 4 ++++ .../resources/certification.ex | 4 ++++ .../complex_calculations/resources/channel.ex | 4 ++++ .../resources/channel_member.ex | 4 ++++ .../resources/dm_channel.ex | 4 ++++ .../resources/documentation.ex | 4 ++++ .../complex_calculations/resources/folder.ex | 4 ++++ .../resources/folder_item.ex | 4 ++++ .../complex_calculations/resources/skill.ex | 4 ++++ test/support/concat.ex | 4 ++++ test/support/dev_test_repo.ex | 4 ++++ test/support/domain.ex | 4 ++++ .../multi_domain_calculations/domain_one.ex | 4 ++++ .../domain_one/item.ex | 4 ++++ .../multi_domain_calculations/domain_three.ex | 4 ++++ .../domain_three/relationship_item.ex | 4 ++++ .../multi_domain_calculations/domain_two.ex | 4 ++++ .../domain_two/other_item.ex | 4 ++++ .../domain_two/sub_item.ex | 4 ++++ test/support/multitenancy/domain.ex | 4 ++++ .../resources/composite_key_post.ex | 4 ++++ .../resources/cross_tenant_post_link.ex | 4 ++++ .../resources/dev_migrations_org.ex | 4 ++++ .../multitenancy/resources/named_org.ex | 4 ++++ .../resources/non_multitenant_post_link.ex | 4 ++++ .../non_multitenant_post_multitenant_link.ex | 4 ++++ test/support/multitenancy/resources/org.ex | 4 ++++ test/support/multitenancy/resources/post.ex | 4 ++++ .../multitenancy/resources/post_link.ex | 4 ++++ test/support/multitenancy/resources/user.ex | 4 ++++ .../comments_containing_title.ex | 4 ++++ test/support/repo_case.ex | 4 ++++ test/support/resources/account.ex | 4 ++++ test/support/resources/author.ex | 4 ++++ test/support/resources/bio.ex | 4 ++++ test/support/resources/chat.ex | 4 ++++ test/support/resources/co_authored_post.ex | 4 ++++ test/support/resources/comedian.ex | 4 ++++ test/support/resources/comment.ex | 4 ++++ test/support/resources/comment_link.ex | 4 ++++ test/support/resources/content.ex | 4 ++++ .../resources/content_visibility_group.ex | 4 ++++ test/support/resources/csv.ex | 4 ++++ test/support/resources/customer.ex | 4 ++++ test/support/resources/db_point.ex | 4 ++++ test/support/resources/db_string_point.ex | 4 ++++ test/support/resources/entity.ex | 4 ++++ test/support/resources/integer_post.ex | 4 ++++ test/support/resources/invite.ex | 4 ++++ test/support/resources/joke.ex | 4 ++++ test/support/resources/manager.ex | 4 ++++ test/support/resources/message.ex | 4 ++++ test/support/resources/note.ex | 4 ++++ test/support/resources/order.ex | 4 ++++ test/support/resources/organization.ex | 4 ++++ test/support/resources/permalink.ex | 4 ++++ test/support/resources/post.ex | 4 ++++ test/support/resources/post_follower.ex | 4 ++++ test/support/resources/post_link.ex | 4 ++++ test/support/resources/post_tag.ex | 4 ++++ test/support/resources/post_views.ex | 4 ++++ .../resources/post_with_empty_update.ex | 4 ++++ test/support/resources/product.ex | 4 ++++ test/support/resources/profile.ex | 4 ++++ test/support/resources/punchline.ex | 4 ++++ test/support/resources/rating.ex | 4 ++++ test/support/resources/record.ex | 4 ++++ test/support/resources/record_temp_entity.ex | 4 ++++ test/support/resources/role.ex | 4 ++++ test/support/resources/rsvp.ex | 4 ++++ test/support/resources/settings.ex | 4 ++++ test/support/resources/staff_group.ex | 4 ++++ test/support/resources/staff_group_member.ex | 4 ++++ test/support/resources/standup_club.ex | 4 ++++ .../resources/stateful_post_follwer.ex | 4 ++++ test/support/resources/subquery/access.ex | 4 ++++ test/support/resources/subquery/child.ex | 4 ++++ .../resources/subquery/child_domain.ex | 4 ++++ test/support/resources/subquery/parent.ex | 4 ++++ .../resources/subquery/parent_domain.ex | 4 ++++ test/support/resources/subquery/through.ex | 4 ++++ test/support/resources/tag.ex | 4 ++++ test/support/resources/temp_entity.ex | 4 ++++ test/support/resources/user.ex | 4 ++++ test/support/string_agg.ex | 4 ++++ test/support/test_app.ex | 4 ++++ test/support/test_custom_extension.ex | 4 ++++ test/support/test_no_sandbox_repo.ex | 4 ++++ test/support/test_repo.ex | 4 ++++ test/support/trigram_word_similarity.ex | 4 ++++ test/support/types/composite_point.ex | 4 ++++ test/support/types/email.ex | 4 ++++ test/support/types/money.ex | 4 ++++ test/support/types/person_detail.ex | 4 ++++ test/support/types/point.ex | 4 ++++ test/support/types/response.ex | 4 ++++ test/support/types/status.ex | 4 ++++ test/support/types/status_enum.ex | 4 ++++ test/support/types/status_enum_no_cast.ex | 4 ++++ test/support/types/string_point.ex | 4 ++++ test/support/unrelated_aggregates/profile.ex | 4 ++++ test/support/unrelated_aggregates/report.ex | 4 ++++ .../unrelated_aggregates/secure_profile.ex | 4 ++++ test/support/unrelated_aggregates/user.ex | 4 ++++ test/test_helper.exs | 4 ++++ test/transaction_test.exs | 4 ++++ test/tuple_test.exs | 4 ++++ test/type_test.exs | 4 ++++ test/unique_identity_test.exs | 4 ++++ test/unrelated_aggregates_test.exs | 4 ++++ test/update_test.exs | 4 ++++ test/upsert_test.exs | 4 ++++ usage-rules.md | 6 ++++++ 509 files changed, 1926 insertions(+), 26 deletions(-) create mode 100644 .tool-versions.license create mode 100644 .vscode/settings.json.license delete mode 100644 LICENSE create mode 100644 LICENSES/MIT.txt create mode 100644 documentation/dsls/DSL-AshPostgres.DataLayer.md.license create mode 100644 logos/small-logo.png.license create mode 100644 mix.lock.license create mode 100644 priv/resource_snapshots/dev_test_repo/extensions.json.license create mode 100644 priv/resource_snapshots/dev_test_repo/multitenant_orgs/20250526214827.json.license create mode 100644 priv/resource_snapshots/test_no_sandbox_repo/extensions.json.license create mode 100644 priv/resource_snapshots/test_repo/accounts/20221217123726.json.license create mode 100644 priv/resource_snapshots/test_repo/accounts/20240327211150.json.license create mode 100644 priv/resource_snapshots/test_repo/authors/20220805191443.json.license create mode 100644 priv/resource_snapshots/test_repo/authors/20220914104733.json.license create mode 100644 priv/resource_snapshots/test_repo/authors/20240327211150.json.license create mode 100644 priv/resource_snapshots/test_repo/authors/20240705113722.json.license create mode 100644 priv/resource_snapshots/test_repo/authors/20250908212414.json.license create mode 100644 priv/resource_snapshots/test_repo/chats/20250908093505.json.license create mode 100644 priv/resource_snapshots/test_repo/co_authored_posts/20241208221219.json.license create mode 100644 priv/resource_snapshots/test_repo/comedians/20241217232254.json.license create mode 100644 priv/resource_snapshots/test_repo/comedians/20250413141328.json.license create mode 100644 priv/resource_snapshots/test_repo/comment_links/20250123161002.json.license create mode 100644 priv/resource_snapshots/test_repo/comment_ratings/20220805191443.json.license create mode 100644 priv/resource_snapshots/test_repo/comment_ratings/20240327211150.json.license create mode 100644 priv/resource_snapshots/test_repo/comments/20220805191443.json.license create mode 100644 priv/resource_snapshots/test_repo/comments/20240327211150.json.license create mode 100644 priv/resource_snapshots/test_repo/comments/20240327211917.json.license create mode 100644 priv/resource_snapshots/test_repo/complex_calculations_certifications/20230816231942.json.license create mode 100644 priv/resource_snapshots/test_repo/complex_calculations_certifications/20240327211150.json.license create mode 100644 priv/resource_snapshots/test_repo/complex_calculations_certifications_channel_members/20231116013020.json.license create mode 100644 priv/resource_snapshots/test_repo/complex_calculations_certifications_channel_members/20240327211150.json.license create mode 100644 priv/resource_snapshots/test_repo/complex_calculations_certifications_channel_members/20240327211917.json.license create mode 100644 priv/resource_snapshots/test_repo/complex_calculations_channels/20231116013020.json.license create mode 100644 priv/resource_snapshots/test_repo/complex_calculations_channels/20240327211150.json.license create mode 100644 priv/resource_snapshots/test_repo/complex_calculations_channels/20240327211917.json.license create mode 100644 priv/resource_snapshots/test_repo/complex_calculations_documentations/20230816231942.json.license create mode 100644 priv/resource_snapshots/test_repo/complex_calculations_documentations/20240327211150.json.license create mode 100644 priv/resource_snapshots/test_repo/complex_calculations_documentations/20240327211917.json.license create mode 100644 priv/resource_snapshots/test_repo/complex_calculations_folder_items/20250714225304.json.license create mode 100644 priv/resource_snapshots/test_repo/complex_calculations_folders/20250714225304.json.license create mode 100644 priv/resource_snapshots/test_repo/complex_calculations_skills/20230816231942.json.license create mode 100644 priv/resource_snapshots/test_repo/complex_calculations_skills/20240327211150.json.license create mode 100644 priv/resource_snapshots/test_repo/content/20250123164209.json.license create mode 100644 priv/resource_snapshots/test_repo/content_visibility_group/20250123164209.json.license create mode 100644 priv/resource_snapshots/test_repo/csv/20250320225052.json.license create mode 100644 priv/resource_snapshots/test_repo/customers/20250908073737.json.license create mode 100644 priv/resource_snapshots/test_repo/entities/20240109160153.json.license create mode 100644 priv/resource_snapshots/test_repo/entities/20240327211150.json.license create mode 100644 priv/resource_snapshots/test_repo/entities/20240327211917.json.license create mode 100644 priv/resource_snapshots/test_repo/extensions.json.license create mode 100644 priv/resource_snapshots/test_repo/integer_posts/20220805191443.json.license create mode 100644 priv/resource_snapshots/test_repo/items/20240713134055.json.license create mode 100644 priv/resource_snapshots/test_repo/items/20240717104854.json.license create mode 100644 priv/resource_snapshots/test_repo/items/20240717153736.json.license create mode 100644 priv/resource_snapshots/test_repo/jokes/20241217232254.json.license create mode 100644 priv/resource_snapshots/test_repo/jokes/20250413141328.json.license create mode 100644 priv/resource_snapshots/test_repo/managers/20230526144249.json.license create mode 100644 priv/resource_snapshots/test_repo/managers/20240327211150.json.license create mode 100644 priv/resource_snapshots/test_repo/messages/20250908093505.json.license create mode 100644 priv/resource_snapshots/test_repo/multitenant_named_orgs/20250519103535.json.license create mode 100644 priv/resource_snapshots/test_repo/multitenant_orgs/20220805191443.json.license create mode 100644 priv/resource_snapshots/test_repo/multitenant_orgs/20240327211150.json.license create mode 100644 priv/resource_snapshots/test_repo/multitenant_orgs/20240627223225.json.license create mode 100644 priv/resource_snapshots/test_repo/multitenant_orgs/20240702164513.json.license create mode 100644 priv/resource_snapshots/test_repo/multitenant_orgs/20240703155134.json.license create mode 100644 priv/resource_snapshots/test_repo/non_multitenant_post_links/20250122190558.json.license create mode 100644 priv/resource_snapshots/test_repo/note/20250123164209.json.license create mode 100644 priv/resource_snapshots/test_repo/orders/20250908073737.json.license create mode 100644 priv/resource_snapshots/test_repo/orgs/20230129050950.json.license create mode 100644 priv/resource_snapshots/test_repo/orgs/20240327211150.json.license create mode 100644 priv/resource_snapshots/test_repo/orgs/20250210191116.json.license create mode 100644 priv/resource_snapshots/test_repo/other_items/20240713134055.json.license create mode 100644 priv/resource_snapshots/test_repo/other_items/20240717151815.json.license create mode 100644 priv/resource_snapshots/test_repo/points/20250313112823.json.license create mode 100644 priv/resource_snapshots/test_repo/post_followers/20240227180858.json.license create mode 100644 priv/resource_snapshots/test_repo/post_followers/20240227181137.json.license create mode 100644 priv/resource_snapshots/test_repo/post_followers/20240327211150.json.license create mode 100644 priv/resource_snapshots/test_repo/post_followers/20240516205244.json.license create mode 100644 priv/resource_snapshots/test_repo/post_followers/20240517223946.json.license create mode 100644 priv/resource_snapshots/test_repo/post_links/20220805191443.json.license create mode 100644 priv/resource_snapshots/test_repo/post_links/20221017133955.json.license create mode 100644 priv/resource_snapshots/test_repo/post_links/20221202194704.json.license create mode 100644 priv/resource_snapshots/test_repo/post_links/20240610195853.json.license create mode 100644 priv/resource_snapshots/test_repo/post_links/20240617193218.json.license create mode 100644 priv/resource_snapshots/test_repo/post_permalinks/20240906170759.json.license create mode 100644 priv/resource_snapshots/test_repo/post_ratings/20220805191443.json.license create mode 100644 priv/resource_snapshots/test_repo/post_ratings/20240327211150.json.license create mode 100644 priv/resource_snapshots/test_repo/post_tags/20250810102512.json.license create mode 100644 priv/resource_snapshots/test_repo/post_views/20230905050351.json.license create mode 100644 priv/resource_snapshots/test_repo/post_views/20240327211917.json.license create mode 100644 priv/resource_snapshots/test_repo/posts/20220805191443.json.license create mode 100644 priv/resource_snapshots/test_repo/posts/20221125171150.json.license create mode 100644 priv/resource_snapshots/test_repo/posts/20221125171204.json.license create mode 100644 priv/resource_snapshots/test_repo/posts/20230129050950.json.license create mode 100644 priv/resource_snapshots/test_repo/posts/20230823161017.json.license create mode 100644 priv/resource_snapshots/test_repo/posts/20231127215636.json.license create mode 100644 priv/resource_snapshots/test_repo/posts/20231129141453.json.license create mode 100644 priv/resource_snapshots/test_repo/posts/20231219132807.json.license create mode 100644 priv/resource_snapshots/test_repo/posts/20240129221511.json.license create mode 100644 priv/resource_snapshots/test_repo/posts/20240224001913.json.license create mode 100644 priv/resource_snapshots/test_repo/posts/20240327211150.json.license create mode 100644 priv/resource_snapshots/test_repo/posts/20240327211917.json.license create mode 100644 priv/resource_snapshots/test_repo/posts/20240503012410.json.license create mode 100644 priv/resource_snapshots/test_repo/posts/20240504185511.json.license create mode 100644 priv/resource_snapshots/test_repo/posts/20240524031113.json.license create mode 100644 priv/resource_snapshots/test_repo/posts/20240524041750.json.license create mode 100644 priv/resource_snapshots/test_repo/posts/20240617193218.json.license create mode 100644 priv/resource_snapshots/test_repo/posts/20240618102809.json.license create mode 100644 priv/resource_snapshots/test_repo/posts/20240712232026.json.license create mode 100644 priv/resource_snapshots/test_repo/posts/20240715135403.json.license create mode 100644 priv/resource_snapshots/test_repo/posts/20240910180107.json.license create mode 100644 priv/resource_snapshots/test_repo/posts/20240911225320.json.license create mode 100644 priv/resource_snapshots/test_repo/posts/20240918104740.json.license create mode 100644 priv/resource_snapshots/test_repo/posts/20240929121224.json.license create mode 100644 priv/resource_snapshots/test_repo/posts/20250217054207.json.license create mode 100644 priv/resource_snapshots/test_repo/posts/20250313112823.json.license create mode 100644 priv/resource_snapshots/test_repo/posts/20250520130634.json.license create mode 100644 priv/resource_snapshots/test_repo/posts/20250521105654.json.license create mode 100644 priv/resource_snapshots/test_repo/posts/20250612113920.json.license create mode 100644 priv/resource_snapshots/test_repo/posts/20250618011917.json.license create mode 100644 priv/resource_snapshots/test_repo/products/20250908073737.json.license create mode 100644 priv/resource_snapshots/test_repo/profile/20220805191443.json.license create mode 100644 priv/resource_snapshots/test_repo/profiles.profile/20240327211150.json.license create mode 100644 priv/resource_snapshots/test_repo/punchlines/20250413141328.json.license create mode 100644 priv/resource_snapshots/test_repo/records/20240109160153.json.license create mode 100644 priv/resource_snapshots/test_repo/records/20240327211150.json.license create mode 100644 priv/resource_snapshots/test_repo/records/20240327211917.json.license create mode 100644 priv/resource_snapshots/test_repo/records_temp_entities/20250605230457.json.license create mode 100644 priv/resource_snapshots/test_repo/relationship_items/20240717153736.json.license create mode 100644 priv/resource_snapshots/test_repo/rsvps/20251002180954.json.license create mode 100644 priv/resource_snapshots/test_repo/schematic_groups/20240821213522.json.license create mode 100644 priv/resource_snapshots/test_repo/staff_group/20250123164209.json.license create mode 100644 priv/resource_snapshots/test_repo/staff_group_member/20250123164209.json.license create mode 100644 priv/resource_snapshots/test_repo/standup_clubs/20250413141328.json.license create mode 100644 priv/resource_snapshots/test_repo/stateful_post_followers/20240618085942.json.license create mode 100644 priv/resource_snapshots/test_repo/string_points/20250313112823.json.license create mode 100644 priv/resource_snapshots/test_repo/sub_items/20240713134055.json.license create mode 100644 priv/resource_snapshots/test_repo/subquery_access/20240130133933.json.license create mode 100644 priv/resource_snapshots/test_repo/subquery_child/20240130133933.json.license create mode 100644 priv/resource_snapshots/test_repo/subquery_parent/20240130133933.json.license create mode 100644 priv/resource_snapshots/test_repo/subquery_through/20240130133933.json.license create mode 100644 priv/resource_snapshots/test_repo/tags/20250810102512.json.license create mode 100644 priv/resource_snapshots/test_repo/temp.temp_entities/20240327211150.json.license create mode 100644 priv/resource_snapshots/test_repo/temp.temp_entities/20240327211917.json.license create mode 100644 priv/resource_snapshots/test_repo/temp_entities/20240109160153.json.license create mode 100644 priv/resource_snapshots/test_repo/tenants/composite_key/20250220073135.json.license create mode 100644 priv/resource_snapshots/test_repo/tenants/composite_key/20250220073141.json.license create mode 100644 priv/resource_snapshots/test_repo/tenants/cross_tenant_post_links/20250122203454.json.license create mode 100644 priv/resource_snapshots/test_repo/tenants/friend_links/20240610162043.json.license create mode 100644 priv/resource_snapshots/test_repo/tenants/multitenant_posts/20220805191441.json.license create mode 100644 priv/resource_snapshots/test_repo/tenants/multitenant_posts/20240327211149.json.license create mode 100644 priv/resource_snapshots/test_repo/tenants/non_multitenant_post_multitenant_links/20251001120813.json.license create mode 100644 priv/resource_snapshots/test_repo/unrelated_profiles/20250731124648.json.license create mode 100644 priv/resource_snapshots/test_repo/unrelated_reports/20250731124648.json.license create mode 100644 priv/resource_snapshots/test_repo/unrelated_secure_profiles/20250731124648.json.license create mode 100644 priv/resource_snapshots/test_repo/unrelated_users/20250731124648.json.license create mode 100644 priv/resource_snapshots/test_repo/user_invites/20240727145758.json.license create mode 100644 priv/resource_snapshots/test_repo/users/20220805191443.json.license create mode 100644 priv/resource_snapshots/test_repo/users/20221217123726.json.license create mode 100644 priv/resource_snapshots/test_repo/users/20230129050950.json.license create mode 100644 priv/resource_snapshots/test_repo/users/20240327211150.json.license create mode 100644 priv/resource_snapshots/test_repo/users/20240727145758.json.license create mode 100644 priv/resource_snapshots/test_repo/users/20240929124728.json.license create mode 100644 priv/resource_snapshots/test_repo/users/20250320225052.json.license create mode 100644 priv/resource_snapshots/test_repo/users/20250321142835.json.license create mode 100644 priv/test_no_sandbox_repo/migrations/.gitkeep.license diff --git a/.check.exs b/.check.exs index 91e14cb1..cecfbc08 100644 --- a/.check.exs +++ b/.check.exs @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + [ ## all available options with default values (see `mix check` docs for description) # parallel: true, @@ -12,7 +16,8 @@ # {:credo, "mix credo --format oneline"}, {:check_formatter, command: "mix spark.formatter --check"}, - {:check_migrations, command: "mix test.check_migrations"} + {:check_migrations, command: "mix test.check_migrations"}, + {:reuse, command: ["pipx", "run", "reuse", "lint", "-q"]} ## custom new tools may be added (mix tasks or arbitrary commands) # {:my_mix_task, command: "mix release", env: %{"MIX_ENV" => "prod"}}, # {:my_arbitrary_tool, command: "npm test", cd: "assets"}, diff --git a/.credo.exs b/.credo.exs index fa9affad..1e1ebe4c 100644 --- a/.credo.exs +++ b/.credo.exs @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + # This file contains the configuration for Credo and you are probably reading # this after creating it with `mix credo.gen.config`. # diff --git a/.formatter.exs b/.formatter.exs index b9c6f498..07bd4f93 100644 --- a/.formatter.exs +++ b/.formatter.exs @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + spark_locals_without_parens = [ all_tenants?: 1, base_filter_sql: 1, diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 597c8ec7..09b96595 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + --- updates: - directory: / diff --git a/.github/workflows/elixir.yml b/.github/workflows/elixir.yml index 084df209..cf4e4897 100644 --- a/.github/workflows/elixir.yml +++ b/.github/workflows/elixir.yml @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + name: CI on: push: @@ -19,6 +23,6 @@ jobs: publish-docs: ${{ matrix.postgres-version == '16' }} release: ${{ matrix.postgres-version == '16' }} igniter-upgrade: ${{matrix.postgres-version == '16'}} - + reuse: true secrets: hex_api_key: ${{ secrets.HEX_API_KEY }} diff --git a/.gitignore b/.gitignore index 7d849d6b..b16f7ffb 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + # The directory Mix will write compiled artifacts to. /_build/ diff --git a/.tool-versions b/.tool-versions index 6c947239..0fa52d96 100644 --- a/.tool-versions +++ b/.tool-versions @@ -1,2 +1,3 @@ erlang 27.1.2 elixir 1.18.4-otp-27 +pipx 1.8.0 diff --git a/.tool-versions.license b/.tool-versions.license new file mode 100644 index 00000000..815664f3 --- /dev/null +++ b/.tool-versions.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2020 Zach Daniel + +SPDX-License-Identifier: MIT diff --git a/.vscode/settings.json.license b/.vscode/settings.json.license new file mode 100644 index 00000000..815664f3 --- /dev/null +++ b/.vscode/settings.json.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2020 Zach Daniel + +SPDX-License-Identifier: MIT diff --git a/CHANGELOG.md b/CHANGELOG.md index 2778d41d..4b045424 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,9 @@ + + # Change Log All notable changes to this project will be documented in this file. diff --git a/LICENSE b/LICENSE deleted file mode 100644 index 4eb51a51..00000000 --- a/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2020 Zachary Scott Daniel - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/LICENSES/MIT.txt b/LICENSES/MIT.txt new file mode 100644 index 00000000..d817195d --- /dev/null +++ b/LICENSES/MIT.txt @@ -0,0 +1,18 @@ +MIT License + +Copyright (c) + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and +associated documentation files (the "Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the +following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial +portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT +LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO +EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/README.md b/README.md index 1bef9edc..98ba97ee 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,9 @@ + + ![Logo](https://github.com/ash-project/ash/blob/main/logos/cropped-for-header-black-text.png?raw=true#gh-light-mode-only) ![Logo](https://github.com/ash-project/ash/blob/main/logos/cropped-for-header-white-text.png?raw=true#gh-dark-mode-only) @@ -5,6 +11,7 @@ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/license/MIT) [![Hex version badge](https://img.shields.io/hexpm/v/ash_postgres.svg)](https://hex.pm/packages/ash_postgres) [![Hexdocs badge](https://img.shields.io/badge/docs-hexdocs-purple)](https://hexdocs.pm/ash_postgres) +[![REUSE status](https://api.reuse.software/badge/github.com/ash-project/ash_postgres)](https://api.reuse.software/info/github.com/ash-project/ash_postgres) # AshPostgres diff --git a/SECURITY.md b/SECURITY.md index 87d03b8b..8b1473d6 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -1,3 +1,9 @@ + + # Security Policy This is a copy of the security policy in the core Ash repo. That is the authoritative source. diff --git a/benchmarks/bulk_create.exs b/benchmarks/bulk_create.exs index 99f235a1..5e665f19 100644 --- a/benchmarks/bulk_create.exs +++ b/benchmarks/bulk_create.exs @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + alias AshPostgres.Test.{Domain, Post} AshPostgres.TestRepo.start_link() diff --git a/config/config.exs b/config/config.exs index 0041c0ac..5a179e32 100644 --- a/config/config.exs +++ b/config/config.exs @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + import Config if Mix.env() == :dev do diff --git a/documentation/1.0-CHANGELOG.md b/documentation/1.0-CHANGELOG.md index 222e3265..0e65a587 100644 --- a/documentation/1.0-CHANGELOG.md +++ b/documentation/1.0-CHANGELOG.md @@ -1,3 +1,9 @@ + + ## [v2.0.0-rc.14](https://github.com/ash-project/ash_postgres/compare/v2.0.0-rc.13...v2.0.0-rc.14) (2024-04-29) ### Improvements: diff --git a/documentation/dsls/DSL-AshPostgres.DataLayer.md.license b/documentation/dsls/DSL-AshPostgres.DataLayer.md.license new file mode 100644 index 00000000..815664f3 --- /dev/null +++ b/documentation/dsls/DSL-AshPostgres.DataLayer.md.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2020 Zach Daniel + +SPDX-License-Identifier: MIT diff --git a/documentation/topics/about-ash-postgres/what-is-ash-postgres.md b/documentation/topics/about-ash-postgres/what-is-ash-postgres.md index 883b3512..b88bac60 100644 --- a/documentation/topics/about-ash-postgres/what-is-ash-postgres.md +++ b/documentation/topics/about-ash-postgres/what-is-ash-postgres.md @@ -1,3 +1,9 @@ + + # What is AshPostgres? AshPostgres is the PostgreSQL `Ash.DataLayer` for [Ash Framework](https://hexdocs.pm/ash). This is the most fully-featured Ash data layer, and unless you need a specific characteristic or feature of another data layer, you should use `AshPostgres`. diff --git a/documentation/topics/advanced/expressions.md b/documentation/topics/advanced/expressions.md index 953e402d..c5a6a759 100644 --- a/documentation/topics/advanced/expressions.md +++ b/documentation/topics/advanced/expressions.md @@ -1,3 +1,9 @@ + + # Expressions In addition to the expressions listed in the [Ash expressions guide](https://hexdocs.pm/ash/expressions.html), AshPostgres provides the following expressions diff --git a/documentation/topics/advanced/manual-relationships.md b/documentation/topics/advanced/manual-relationships.md index a7adaac3..1bd438b5 100644 --- a/documentation/topics/advanced/manual-relationships.md +++ b/documentation/topics/advanced/manual-relationships.md @@ -1,3 +1,9 @@ + + # Manual Relationships See [Manual Relationships](https://hexdocs.pm/ash/relationships.html#manual-relationships) for an idea of manual relationships in general. diff --git a/documentation/topics/advanced/schema-based-multitenancy.md b/documentation/topics/advanced/schema-based-multitenancy.md index 69d7add1..f1459c1f 100644 --- a/documentation/topics/advanced/schema-based-multitenancy.md +++ b/documentation/topics/advanced/schema-based-multitenancy.md @@ -1,3 +1,9 @@ + + # Schema Based Multitenancy Multitenancy in AshPostgres is implemented via postgres schemas. For more information on schemas, see postgres' [schema documentation](https://www.postgresql.org/docs/current/ddl-schemas.html) diff --git a/documentation/topics/advanced/using-multiple-repos.md b/documentation/topics/advanced/using-multiple-repos.md index 3c85ff5c..02378413 100644 --- a/documentation/topics/advanced/using-multiple-repos.md +++ b/documentation/topics/advanced/using-multiple-repos.md @@ -1,3 +1,9 @@ + + # Using Multiple Repos When scaling PostgreSQL you may want to setup _read_ replicas to improve diff --git a/documentation/topics/development/migrations-and-tasks.md b/documentation/topics/development/migrations-and-tasks.md index 592bb9a9..2d163da4 100644 --- a/documentation/topics/development/migrations-and-tasks.md +++ b/documentation/topics/development/migrations-and-tasks.md @@ -1,3 +1,9 @@ + + # Migrations ## Tasks diff --git a/documentation/topics/development/testing.md b/documentation/topics/development/testing.md index 3fe7662b..eaf826f1 100644 --- a/documentation/topics/development/testing.md +++ b/documentation/topics/development/testing.md @@ -1,3 +1,9 @@ + + # Testing with AshPostgres When using AshPostgres resources in tests, you will likely want to include use a test case similar to the following. This will ensure that your repo runs everything in a transaction. diff --git a/documentation/topics/development/upgrading-to-2.0.md b/documentation/topics/development/upgrading-to-2.0.md index 34eeb78c..fd3e1cc7 100644 --- a/documentation/topics/development/upgrading-to-2.0.md +++ b/documentation/topics/development/upgrading-to-2.0.md @@ -1,3 +1,9 @@ + + # Upgrading to 2.0 There are only three breaking changes in this release, one of them is very significant, the other two are minor. diff --git a/documentation/topics/resources/polymorphic-resources.md b/documentation/topics/resources/polymorphic-resources.md index e7852795..9f6d11ac 100644 --- a/documentation/topics/resources/polymorphic-resources.md +++ b/documentation/topics/resources/polymorphic-resources.md @@ -1,3 +1,9 @@ + + # Polymorphic Resources To support leveraging the same resource backed by multiple tables (useful for things like polymorphic associations), AshPostgres supports setting the `data_layer.table` context for a given resource. For this example, lets assume that you have a `MyApp.Post` resource and a `MyApp.Comment` resource. For each of those resources, users can submit `reactions`. However, you want a separate table for `post_reactions` and `comment_reactions`. You could accomplish that like so: diff --git a/documentation/topics/resources/references.md b/documentation/topics/resources/references.md index 10ed6575..494c73b7 100644 --- a/documentation/topics/resources/references.md +++ b/documentation/topics/resources/references.md @@ -1,3 +1,9 @@ + + # References To configure the behavior of generated foreign keys on a resource, we use the `references` section, within the `postgres` configuration block. diff --git a/documentation/tutorials/get-started-with-ash-postgres.md b/documentation/tutorials/get-started-with-ash-postgres.md index 8e02c72a..f96c8659 100644 --- a/documentation/tutorials/get-started-with-ash-postgres.md +++ b/documentation/tutorials/get-started-with-ash-postgres.md @@ -1,3 +1,9 @@ + + # Get Started With Postgres ## Installation diff --git a/documentation/tutorials/set-up-with-existing-database.md b/documentation/tutorials/set-up-with-existing-database.md index 0c5d92c0..79b6a061 100644 --- a/documentation/tutorials/set-up-with-existing-database.md +++ b/documentation/tutorials/set-up-with-existing-database.md @@ -1,3 +1,9 @@ + + # Setting AshPostgres up with an existing database If you already have a postgres database and you'd like to get diff --git a/lib/ash_postgres.ex b/lib/ash_postgres.ex index d26103e4..34f5cd43 100644 --- a/lib/ash_postgres.ex +++ b/lib/ash_postgres.ex @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres do @moduledoc """ The AshPostgres extension gives you tools to map a resource to a postgres database table. diff --git a/lib/check_constraint.ex b/lib/check_constraint.ex index a16e7346..6534a464 100644 --- a/lib/check_constraint.ex +++ b/lib/check_constraint.ex @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.CheckConstraint do @moduledoc "Represents a configured check constraint on the table backing a resource" diff --git a/lib/custom_aggregate.ex b/lib/custom_aggregate.ex index 9e581ce4..6a42b026 100644 --- a/lib/custom_aggregate.ex +++ b/lib/custom_aggregate.ex @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.CustomAggregate do @moduledoc """ A custom aggregate implementation for ecto. diff --git a/lib/custom_extension.ex b/lib/custom_extension.ex index 9360dc5c..968a748c 100644 --- a/lib/custom_extension.ex +++ b/lib/custom_extension.ex @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.CustomExtension do @moduledoc """ A custom extension implementation. diff --git a/lib/custom_index.ex b/lib/custom_index.ex index 29496ceb..240b30d2 100644 --- a/lib/custom_index.ex +++ b/lib/custom_index.ex @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.CustomIndex do @moduledoc "Represents a custom index on the table backing a resource" @fields [ diff --git a/lib/data_layer.ex b/lib/data_layer.ex index 6e3354d8..07812631 100644 --- a/lib/data_layer.ex +++ b/lib/data_layer.ex @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.DataLayer do require Ecto.Query require Ash.Expr diff --git a/lib/data_layer/info.ex b/lib/data_layer/info.ex index 696439ae..933ca6e8 100644 --- a/lib/data_layer/info.ex +++ b/lib/data_layer/info.ex @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.DataLayer.Info do @moduledoc "Introspection functions for " diff --git a/lib/ecto_migration_default.ex b/lib/ecto_migration_default.ex index d0ba6dbb..d865471b 100644 --- a/lib/ecto_migration_default.ex +++ b/lib/ecto_migration_default.ex @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defprotocol EctoMigrationDefault do @moduledoc """ Allows configuring how values are translated to default values in migrations. diff --git a/lib/extensions/immutable_raise_error.ex b/lib/extensions/immutable_raise_error.ex index b7ccf347..22760442 100644 --- a/lib/extensions/immutable_raise_error.ex +++ b/lib/extensions/immutable_raise_error.ex @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.Extensions.ImmutableRaiseError do @moduledoc """ An extension that installs an immutable version of ash_raise_error. diff --git a/lib/extensions/vector.ex b/lib/extensions/vector.ex index 3280e629..c029dcf4 100644 --- a/lib/extensions/vector.ex +++ b/lib/extensions/vector.ex @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.Extensions.Vector do @moduledoc """ An extension that adds support for the `vector` type. diff --git a/lib/functions/binding.ex b/lib/functions/binding.ex index 92fc9d6f..df20a209 100644 --- a/lib/functions/binding.ex +++ b/lib/functions/binding.ex @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.Functions.Binding do @moduledoc """ Refers to the current table binding. diff --git a/lib/functions/ilike.ex b/lib/functions/ilike.ex index 8fa403d4..dd960f5f 100644 --- a/lib/functions/ilike.ex +++ b/lib/functions/ilike.ex @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.Functions.ILike do @moduledoc """ Maps to the builtin postgres function `ilike`. diff --git a/lib/functions/like.ex b/lib/functions/like.ex index 8b2d51b0..fdc76c6b 100644 --- a/lib/functions/like.ex +++ b/lib/functions/like.ex @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.Functions.Like do @moduledoc """ Maps to the builtin postgres function `like`. diff --git a/lib/functions/trigram_similarity.ex b/lib/functions/trigram_similarity.ex index 97177ae6..19622647 100644 --- a/lib/functions/trigram_similarity.ex +++ b/lib/functions/trigram_similarity.ex @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.Functions.TrigramSimilarity do @moduledoc """ Maps to the builtin postgres trigram similarity function. Requires `pgtrgm` extension to be installed. diff --git a/lib/functions/vector_cosine_distance.ex b/lib/functions/vector_cosine_distance.ex index 349c1977..1a811583 100644 --- a/lib/functions/vector_cosine_distance.ex +++ b/lib/functions/vector_cosine_distance.ex @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.Functions.VectorCosineDistance do @moduledoc """ Maps to the vector cosine distance operator. Requires `vector` extension to be installed. diff --git a/lib/functions/vector_l2_distance.ex b/lib/functions/vector_l2_distance.ex index c3f13ca0..063a1432 100644 --- a/lib/functions/vector_l2_distance.ex +++ b/lib/functions/vector_l2_distance.ex @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.Functions.VectorL2Distance do @moduledoc """ Maps to the vector l2 distance operator. Requires `vector` extension to be installed. diff --git a/lib/igniter.ex b/lib/igniter.ex index 02ef4476..aa20746d 100644 --- a/lib/igniter.ex +++ b/lib/igniter.ex @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + if Code.ensure_loaded?(Igniter) do defmodule AshPostgres.Igniter do @moduledoc "Codemods and utilities for working with AshPostgres & Igniter" diff --git a/lib/manual_relationship.ex b/lib/manual_relationship.ex index 081aee13..b6322de9 100644 --- a/lib/manual_relationship.ex +++ b/lib/manual_relationship.ex @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.ManualRelationship do @moduledoc "A behavior for postgres-specific manual relationship functionality" diff --git a/lib/migration.ex b/lib/migration.ex index 78e76f97..9102d2a9 100644 --- a/lib/migration.ex +++ b/lib/migration.ex @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.Migration do @moduledoc "Utilities for use in migrations" diff --git a/lib/migration_compile_cache.ex b/lib/migration_compile_cache.ex index 802c21ad..f421d3b6 100644 --- a/lib/migration_compile_cache.ex +++ b/lib/migration_compile_cache.ex @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.MigrationCompileCache do @moduledoc """ A cache for the compiled migrations. diff --git a/lib/migration_generator/ash_functions.ex b/lib/migration_generator/ash_functions.ex index a9c4659c..1206d829 100644 --- a/lib/migration_generator/ash_functions.ex +++ b/lib/migration_generator/ash_functions.ex @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.MigrationGenerator.AshFunctions do @latest_version 5 diff --git a/lib/migration_generator/migration_generator.ex b/lib/migration_generator/migration_generator.ex index 00276e25..bdd82fba 100644 --- a/lib/migration_generator/migration_generator.ex +++ b/lib/migration_generator/migration_generator.ex @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.MigrationGenerator do @moduledoc false diff --git a/lib/migration_generator/operation.ex b/lib/migration_generator/operation.ex index 88525c11..21af504b 100644 --- a/lib/migration_generator/operation.ex +++ b/lib/migration_generator/operation.ex @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.MigrationGenerator.Operation do @moduledoc false diff --git a/lib/migration_generator/phase.ex b/lib/migration_generator/phase.ex index a4e5861b..9b13dadd 100644 --- a/lib/migration_generator/phase.ex +++ b/lib/migration_generator/phase.ex @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.MigrationGenerator.Phase do @moduledoc false diff --git a/lib/mix/helpers.ex b/lib/mix/helpers.ex index 316778fd..51db8a64 100644 --- a/lib/mix/helpers.ex +++ b/lib/mix/helpers.ex @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.Mix.Helpers do @moduledoc false def domains!(opts, args) do diff --git a/lib/mix/tasks/ash_postgres.create.ex b/lib/mix/tasks/ash_postgres.create.ex index a99baf33..61129c48 100644 --- a/lib/mix/tasks/ash_postgres.create.ex +++ b/lib/mix/tasks/ash_postgres.create.ex @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule Mix.Tasks.AshPostgres.Create do use Mix.Task diff --git a/lib/mix/tasks/ash_postgres.drop.ex b/lib/mix/tasks/ash_postgres.drop.ex index e54ffddb..2c50e9b3 100644 --- a/lib/mix/tasks/ash_postgres.drop.ex +++ b/lib/mix/tasks/ash_postgres.drop.ex @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule Mix.Tasks.AshPostgres.Drop do use Mix.Task diff --git a/lib/mix/tasks/ash_postgres.gen.resources.ex b/lib/mix/tasks/ash_postgres.gen.resources.ex index babac4f1..d207ea3f 100644 --- a/lib/mix/tasks/ash_postgres.gen.resources.ex +++ b/lib/mix/tasks/ash_postgres.gen.resources.ex @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + if Code.ensure_loaded?(Igniter) do defmodule Mix.Tasks.AshPostgres.Gen.Resources do use Igniter.Mix.Task diff --git a/lib/mix/tasks/ash_postgres.generate_migrations.ex b/lib/mix/tasks/ash_postgres.generate_migrations.ex index 028ac8bb..ca16404d 100644 --- a/lib/mix/tasks/ash_postgres.generate_migrations.ex +++ b/lib/mix/tasks/ash_postgres.generate_migrations.ex @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule Mix.Tasks.AshPostgres.GenerateMigrations do @moduledoc """ Generates migrations, and stores a snapshot of your resources. diff --git a/lib/mix/tasks/ash_postgres.install.ex b/lib/mix/tasks/ash_postgres.install.ex index 4935fdf1..e7b6e0fb 100644 --- a/lib/mix/tasks/ash_postgres.install.ex +++ b/lib/mix/tasks/ash_postgres.install.ex @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + if Code.ensure_loaded?(Igniter) do defmodule Mix.Tasks.AshPostgres.Install do @moduledoc "Installs AshPostgres. Should be run with `mix igniter.install ash_postgres`" diff --git a/lib/mix/tasks/ash_postgres.migrate.ex b/lib/mix/tasks/ash_postgres.migrate.ex index 7da14a78..601a5daf 100644 --- a/lib/mix/tasks/ash_postgres.migrate.ex +++ b/lib/mix/tasks/ash_postgres.migrate.ex @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule Mix.Tasks.AshPostgres.Migrate do use Mix.Task diff --git a/lib/mix/tasks/ash_postgres.rollback.ex b/lib/mix/tasks/ash_postgres.rollback.ex index d59fc1bf..da11f74c 100644 --- a/lib/mix/tasks/ash_postgres.rollback.ex +++ b/lib/mix/tasks/ash_postgres.rollback.ex @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule Mix.Tasks.AshPostgres.Rollback do use Mix.Task diff --git a/lib/mix/tasks/ash_postgres.setup_vector.ex b/lib/mix/tasks/ash_postgres.setup_vector.ex index c58b6f56..209c8241 100644 --- a/lib/mix/tasks/ash_postgres.setup_vector.ex +++ b/lib/mix/tasks/ash_postgres.setup_vector.ex @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule Mix.Tasks.AshPostgres.SetupVector.Docs do @moduledoc false diff --git a/lib/mix/tasks/ash_postgres.squash_snapshots.ex b/lib/mix/tasks/ash_postgres.squash_snapshots.ex index 84032c9b..8e40a597 100644 --- a/lib/mix/tasks/ash_postgres.squash_snapshots.ex +++ b/lib/mix/tasks/ash_postgres.squash_snapshots.ex @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule Mix.Tasks.AshPostgres.SquashSnapshots do use Mix.Task diff --git a/lib/multitenancy.ex b/lib/multitenancy.ex index 6d70aa49..5660e963 100644 --- a/lib/multitenancy.ex +++ b/lib/multitenancy.ex @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.MultiTenancy do @moduledoc false diff --git a/lib/reference.ex b/lib/reference.ex index e724a0b6..f22abc1f 100644 --- a/lib/reference.ex +++ b/lib/reference.ex @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.Reference do @moduledoc "Represents the configuration of a reference (i.e foreign key)." defstruct [ diff --git a/lib/repo.ex b/lib/repo.ex index e1b0726d..fdc2d522 100644 --- a/lib/repo.ex +++ b/lib/repo.ex @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.Repo do @moduledoc """ Resources that use `AshPostgres.DataLayer` use a `Repo` to access the database. diff --git a/lib/repo/before_compile.ex b/lib/repo/before_compile.ex index c2e9a310..c8306507 100644 --- a/lib/repo/before_compile.ex +++ b/lib/repo/before_compile.ex @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.Repo.BeforeCompile do @moduledoc false diff --git a/lib/resource_generator/resource_generator.ex b/lib/resource_generator/resource_generator.ex index b3a507b7..0f633f7b 100644 --- a/lib/resource_generator/resource_generator.ex +++ b/lib/resource_generator/resource_generator.ex @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + if Code.ensure_loaded?(Igniter) do defmodule AshPostgres.ResourceGenerator do @moduledoc false diff --git a/lib/resource_generator/sensitive_data.ex b/lib/resource_generator/sensitive_data.ex index 7b720aef..30c94857 100644 --- a/lib/resource_generator/sensitive_data.ex +++ b/lib/resource_generator/sensitive_data.ex @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.ResourceGenerator.SensitiveData do @moduledoc false # I got this from ChatGPT, but this is a best effort transformation diff --git a/lib/resource_generator/spec.ex b/lib/resource_generator/spec.ex index 9997bbac..c4d8088e 100644 --- a/lib/resource_generator/spec.ex +++ b/lib/resource_generator/spec.ex @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.ResourceGenerator.Spec do @moduledoc false require Logger diff --git a/lib/sql_implementation.ex b/lib/sql_implementation.ex index 71b7f03d..84d31935 100644 --- a/lib/sql_implementation.ex +++ b/lib/sql_implementation.ex @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.SqlImplementation do @moduledoc false use AshSql.Implementation diff --git a/lib/statement.ex b/lib/statement.ex index dfc49322..5902d730 100644 --- a/lib/statement.ex +++ b/lib/statement.ex @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.Statement do @moduledoc "Represents a custom statement to be run in generated migrations" diff --git a/lib/type.ex b/lib/type.ex index 22a3ec07..88c6ef63 100644 --- a/lib/type.ex +++ b/lib/type.ex @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.Type do @moduledoc """ Postgres specific callbacks for `Ash.Type`. diff --git a/lib/types/ci_string_wrapper.ex b/lib/types/ci_string_wrapper.ex index 74e47347..5c7bb8cb 100644 --- a/lib/types/ci_string_wrapper.ex +++ b/lib/types/ci_string_wrapper.ex @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.Type.CiStringWrapper do @moduledoc false use Ash.Type.NewType, subtype_of: :ci_string, constraints: [allow_empty?: true, trim?: false] diff --git a/lib/types/ltree.ex b/lib/types/ltree.ex index 512758e2..0997bdff 100644 --- a/lib/types/ltree.ex +++ b/lib/types/ltree.ex @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.Ltree do @constraints [ escape?: [ diff --git a/lib/types/string_wrapper.ex b/lib/types/string_wrapper.ex index 84b5cd2c..5d8c33ea 100644 --- a/lib/types/string_wrapper.ex +++ b/lib/types/string_wrapper.ex @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.Type.StringWrapper do @moduledoc false use Ash.Type.NewType, subtype_of: :string, constraints: [allow_empty?: true, trim?: false] diff --git a/lib/types/timestamptz.ex b/lib/types/timestamptz.ex index 11b007a3..c684751c 100644 --- a/lib/types/timestamptz.ex +++ b/lib/types/timestamptz.ex @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.Timestamptz do @moduledoc """ Implements the PostgresSQL [timestamptz](https://www.postgresql.org/docs/current/datatype-datetime.html) (aka `timestamp with time zone`) type. diff --git a/lib/types/timestamptz_usec.ex b/lib/types/timestamptz_usec.ex index f1dae8fd..8bd0a38d 100644 --- a/lib/types/timestamptz_usec.ex +++ b/lib/types/timestamptz_usec.ex @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.TimestamptzUsec do @moduledoc """ Implements the PostgresSQL [timestamptz](https://www.postgresql.org/docs/current/datatype-datetime.html) (aka `timestamp with time zone`) type with nanosecond precision. diff --git a/lib/types/tsquery.ex b/lib/types/tsquery.ex index 9115b0e1..8e1fb7ad 100644 --- a/lib/types/tsquery.ex +++ b/lib/types/tsquery.ex @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.Tsquery do @moduledoc """ A thin wrapper around `:string` for working with tsquery types in calculations. diff --git a/lib/types/tsvector.ex b/lib/types/tsvector.ex index f753b2b1..1a29a359 100644 --- a/lib/types/tsvector.ex +++ b/lib/types/tsvector.ex @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.Tsvector do @moduledoc """ A type for representing postgres' tsvectors. diff --git a/lib/verifiers/ensure_table_or_polymorphic.ex b/lib/verifiers/ensure_table_or_polymorphic.ex index c2e612ca..9c1d17bc 100644 --- a/lib/verifiers/ensure_table_or_polymorphic.ex +++ b/lib/verifiers/ensure_table_or_polymorphic.ex @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.Verifiers.EnsureTableOrPolymorphic do @moduledoc false use Spark.Dsl.Verifier diff --git a/lib/verifiers/prevent_attribute_multitenancy_and_non_full_match_type.ex b/lib/verifiers/prevent_attribute_multitenancy_and_non_full_match_type.ex index 5e0a25cc..a595c95c 100644 --- a/lib/verifiers/prevent_attribute_multitenancy_and_non_full_match_type.ex +++ b/lib/verifiers/prevent_attribute_multitenancy_and_non_full_match_type.ex @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.Verifiers.PreventAttributeMultitenancyAndNonFullMatchType do @moduledoc false use Spark.Dsl.Verifier diff --git a/lib/verifiers/prevent_multidimensional_array_aggregates.ex b/lib/verifiers/prevent_multidimensional_array_aggregates.ex index 82a38202..7589b277 100644 --- a/lib/verifiers/prevent_multidimensional_array_aggregates.ex +++ b/lib/verifiers/prevent_multidimensional_array_aggregates.ex @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.Verifiers.PreventMultidimensionalArrayAggregates do @moduledoc false use Spark.Dsl.Verifier diff --git a/lib/verifiers/validate_identity_index_names.ex b/lib/verifiers/validate_identity_index_names.ex index 82457eb2..1c2fbad8 100644 --- a/lib/verifiers/validate_identity_index_names.ex +++ b/lib/verifiers/validate_identity_index_names.ex @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.Verifiers.ValidateIdentityIndexNames do @moduledoc false use Spark.Dsl.Verifier diff --git a/lib/verifiers/validate_references.ex b/lib/verifiers/validate_references.ex index 40c47a8e..efcffd2d 100644 --- a/lib/verifiers/validate_references.ex +++ b/lib/verifiers/validate_references.ex @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.Verifiers.ValidateReferences do @moduledoc false use Spark.Dsl.Verifier diff --git a/lib/version_agent.ex b/lib/version_agent.ex index e69de29b..0db6f4ff 100644 --- a/lib/version_agent.ex +++ b/lib/version_agent.ex @@ -0,0 +1,3 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT diff --git a/logos/small-logo.png.license b/logos/small-logo.png.license new file mode 100644 index 00000000..815664f3 --- /dev/null +++ b/logos/small-logo.png.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2020 Zach Daniel + +SPDX-License-Identifier: MIT diff --git a/mix.exs b/mix.exs index f1d82380..cf59bf71 100644 --- a/mix.exs +++ b/mix.exs @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.MixProject do use Mix.Project @@ -54,13 +58,20 @@ defmodule AshPostgres.MixProject do defp package do [ - name: :ash_postgres, + maintainers: [ + "Zach Daniel " + ], licenses: ["MIT"], files: ~w(lib .formatter.exs mix.exs README* LICENSE* CHANGELOG* documentation usage-rules.md), links: %{ - Changelog: "https://hexdocs.pm/ash_postgres/changelog.html", - GitHub: "https://github.com/ash-project/ash_postgres" + "GitHub" => "https://github.com/ash-project/ash_postgres", + "Changelog" => "https://github.com/ash-project/ash_postgres/blob/main/CHANGELOG.md", + "Discord" => "https://discord.gg/HTHRaaVPUc", + "Website" => "https://ash-hq.org/", + "Forum" => "https://elixirforum.com/c/elixir-framework-forums/ash-framework-forum", + "REUSE Compliance" => + "https://api.reuse.software/info/github.com/ash-project/ash_postgres" } ] end diff --git a/mix.lock.license b/mix.lock.license new file mode 100644 index 00000000..815664f3 --- /dev/null +++ b/mix.lock.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2020 Zach Daniel + +SPDX-License-Identifier: MIT diff --git a/priv/dev_test_repo/migrations/20250526214825_migrate_resources_extensions_1.exs b/priv/dev_test_repo/migrations/20250526214825_migrate_resources_extensions_1.exs index 389b0b27..57fc3e50 100644 --- a/priv/dev_test_repo/migrations/20250526214825_migrate_resources_extensions_1.exs +++ b/priv/dev_test_repo/migrations/20250526214825_migrate_resources_extensions_1.exs @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.DevTestRepo.Migrations.MigrateResourcesExtensions1 do @moduledoc """ Installs any extensions that are mentioned in the repo's `installed_extensions/0` callback diff --git a/priv/dev_test_repo/migrations/20250526214827_migrate_resources1.exs b/priv/dev_test_repo/migrations/20250526214827_migrate_resources1.exs index 3a56462c..bc0f2abf 100644 --- a/priv/dev_test_repo/migrations/20250526214827_migrate_resources1.exs +++ b/priv/dev_test_repo/migrations/20250526214827_migrate_resources1.exs @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.DevTestRepo.Migrations.MigrateResources1 do @moduledoc """ Updates resources based on their most recent snapshots. diff --git a/priv/resource_snapshots/dev_test_repo/extensions.json.license b/priv/resource_snapshots/dev_test_repo/extensions.json.license new file mode 100644 index 00000000..815664f3 --- /dev/null +++ b/priv/resource_snapshots/dev_test_repo/extensions.json.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2020 Zach Daniel + +SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/dev_test_repo/multitenant_orgs/20250526214827.json.license b/priv/resource_snapshots/dev_test_repo/multitenant_orgs/20250526214827.json.license new file mode 100644 index 00000000..815664f3 --- /dev/null +++ b/priv/resource_snapshots/dev_test_repo/multitenant_orgs/20250526214827.json.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2020 Zach Daniel + +SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_no_sandbox_repo/extensions.json.license b/priv/resource_snapshots/test_no_sandbox_repo/extensions.json.license new file mode 100644 index 00000000..815664f3 --- /dev/null +++ b/priv/resource_snapshots/test_no_sandbox_repo/extensions.json.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2020 Zach Daniel + +SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/accounts/20221217123726.json.license b/priv/resource_snapshots/test_repo/accounts/20221217123726.json.license new file mode 100644 index 00000000..815664f3 --- /dev/null +++ b/priv/resource_snapshots/test_repo/accounts/20221217123726.json.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2020 Zach Daniel + +SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/accounts/20240327211150.json.license b/priv/resource_snapshots/test_repo/accounts/20240327211150.json.license new file mode 100644 index 00000000..815664f3 --- /dev/null +++ b/priv/resource_snapshots/test_repo/accounts/20240327211150.json.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2020 Zach Daniel + +SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/authors/20220805191443.json.license b/priv/resource_snapshots/test_repo/authors/20220805191443.json.license new file mode 100644 index 00000000..815664f3 --- /dev/null +++ b/priv/resource_snapshots/test_repo/authors/20220805191443.json.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2020 Zach Daniel + +SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/authors/20220914104733.json.license b/priv/resource_snapshots/test_repo/authors/20220914104733.json.license new file mode 100644 index 00000000..815664f3 --- /dev/null +++ b/priv/resource_snapshots/test_repo/authors/20220914104733.json.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2020 Zach Daniel + +SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/authors/20240327211150.json.license b/priv/resource_snapshots/test_repo/authors/20240327211150.json.license new file mode 100644 index 00000000..815664f3 --- /dev/null +++ b/priv/resource_snapshots/test_repo/authors/20240327211150.json.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2020 Zach Daniel + +SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/authors/20240705113722.json.license b/priv/resource_snapshots/test_repo/authors/20240705113722.json.license new file mode 100644 index 00000000..815664f3 --- /dev/null +++ b/priv/resource_snapshots/test_repo/authors/20240705113722.json.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2020 Zach Daniel + +SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/authors/20250908212414.json.license b/priv/resource_snapshots/test_repo/authors/20250908212414.json.license new file mode 100644 index 00000000..815664f3 --- /dev/null +++ b/priv/resource_snapshots/test_repo/authors/20250908212414.json.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2020 Zach Daniel + +SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/chats/20250908093505.json.license b/priv/resource_snapshots/test_repo/chats/20250908093505.json.license new file mode 100644 index 00000000..815664f3 --- /dev/null +++ b/priv/resource_snapshots/test_repo/chats/20250908093505.json.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2020 Zach Daniel + +SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/co_authored_posts/20241208221219.json.license b/priv/resource_snapshots/test_repo/co_authored_posts/20241208221219.json.license new file mode 100644 index 00000000..815664f3 --- /dev/null +++ b/priv/resource_snapshots/test_repo/co_authored_posts/20241208221219.json.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2020 Zach Daniel + +SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/comedians/20241217232254.json.license b/priv/resource_snapshots/test_repo/comedians/20241217232254.json.license new file mode 100644 index 00000000..815664f3 --- /dev/null +++ b/priv/resource_snapshots/test_repo/comedians/20241217232254.json.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2020 Zach Daniel + +SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/comedians/20250413141328.json.license b/priv/resource_snapshots/test_repo/comedians/20250413141328.json.license new file mode 100644 index 00000000..815664f3 --- /dev/null +++ b/priv/resource_snapshots/test_repo/comedians/20250413141328.json.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2020 Zach Daniel + +SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/comment_links/20250123161002.json.license b/priv/resource_snapshots/test_repo/comment_links/20250123161002.json.license new file mode 100644 index 00000000..815664f3 --- /dev/null +++ b/priv/resource_snapshots/test_repo/comment_links/20250123161002.json.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2020 Zach Daniel + +SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/comment_ratings/20220805191443.json.license b/priv/resource_snapshots/test_repo/comment_ratings/20220805191443.json.license new file mode 100644 index 00000000..815664f3 --- /dev/null +++ b/priv/resource_snapshots/test_repo/comment_ratings/20220805191443.json.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2020 Zach Daniel + +SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/comment_ratings/20240327211150.json.license b/priv/resource_snapshots/test_repo/comment_ratings/20240327211150.json.license new file mode 100644 index 00000000..815664f3 --- /dev/null +++ b/priv/resource_snapshots/test_repo/comment_ratings/20240327211150.json.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2020 Zach Daniel + +SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/comments/20220805191443.json.license b/priv/resource_snapshots/test_repo/comments/20220805191443.json.license new file mode 100644 index 00000000..815664f3 --- /dev/null +++ b/priv/resource_snapshots/test_repo/comments/20220805191443.json.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2020 Zach Daniel + +SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/comments/20240327211150.json.license b/priv/resource_snapshots/test_repo/comments/20240327211150.json.license new file mode 100644 index 00000000..815664f3 --- /dev/null +++ b/priv/resource_snapshots/test_repo/comments/20240327211150.json.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2020 Zach Daniel + +SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/comments/20240327211917.json.license b/priv/resource_snapshots/test_repo/comments/20240327211917.json.license new file mode 100644 index 00000000..815664f3 --- /dev/null +++ b/priv/resource_snapshots/test_repo/comments/20240327211917.json.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2020 Zach Daniel + +SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/complex_calculations_certifications/20230816231942.json.license b/priv/resource_snapshots/test_repo/complex_calculations_certifications/20230816231942.json.license new file mode 100644 index 00000000..815664f3 --- /dev/null +++ b/priv/resource_snapshots/test_repo/complex_calculations_certifications/20230816231942.json.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2020 Zach Daniel + +SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/complex_calculations_certifications/20240327211150.json.license b/priv/resource_snapshots/test_repo/complex_calculations_certifications/20240327211150.json.license new file mode 100644 index 00000000..815664f3 --- /dev/null +++ b/priv/resource_snapshots/test_repo/complex_calculations_certifications/20240327211150.json.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2020 Zach Daniel + +SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/complex_calculations_certifications_channel_members/20231116013020.json.license b/priv/resource_snapshots/test_repo/complex_calculations_certifications_channel_members/20231116013020.json.license new file mode 100644 index 00000000..815664f3 --- /dev/null +++ b/priv/resource_snapshots/test_repo/complex_calculations_certifications_channel_members/20231116013020.json.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2020 Zach Daniel + +SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/complex_calculations_certifications_channel_members/20240327211150.json.license b/priv/resource_snapshots/test_repo/complex_calculations_certifications_channel_members/20240327211150.json.license new file mode 100644 index 00000000..815664f3 --- /dev/null +++ b/priv/resource_snapshots/test_repo/complex_calculations_certifications_channel_members/20240327211150.json.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2020 Zach Daniel + +SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/complex_calculations_certifications_channel_members/20240327211917.json.license b/priv/resource_snapshots/test_repo/complex_calculations_certifications_channel_members/20240327211917.json.license new file mode 100644 index 00000000..815664f3 --- /dev/null +++ b/priv/resource_snapshots/test_repo/complex_calculations_certifications_channel_members/20240327211917.json.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2020 Zach Daniel + +SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/complex_calculations_channels/20231116013020.json.license b/priv/resource_snapshots/test_repo/complex_calculations_channels/20231116013020.json.license new file mode 100644 index 00000000..815664f3 --- /dev/null +++ b/priv/resource_snapshots/test_repo/complex_calculations_channels/20231116013020.json.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2020 Zach Daniel + +SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/complex_calculations_channels/20240327211150.json.license b/priv/resource_snapshots/test_repo/complex_calculations_channels/20240327211150.json.license new file mode 100644 index 00000000..815664f3 --- /dev/null +++ b/priv/resource_snapshots/test_repo/complex_calculations_channels/20240327211150.json.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2020 Zach Daniel + +SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/complex_calculations_channels/20240327211917.json.license b/priv/resource_snapshots/test_repo/complex_calculations_channels/20240327211917.json.license new file mode 100644 index 00000000..815664f3 --- /dev/null +++ b/priv/resource_snapshots/test_repo/complex_calculations_channels/20240327211917.json.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2020 Zach Daniel + +SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/complex_calculations_documentations/20230816231942.json.license b/priv/resource_snapshots/test_repo/complex_calculations_documentations/20230816231942.json.license new file mode 100644 index 00000000..815664f3 --- /dev/null +++ b/priv/resource_snapshots/test_repo/complex_calculations_documentations/20230816231942.json.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2020 Zach Daniel + +SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/complex_calculations_documentations/20240327211150.json.license b/priv/resource_snapshots/test_repo/complex_calculations_documentations/20240327211150.json.license new file mode 100644 index 00000000..815664f3 --- /dev/null +++ b/priv/resource_snapshots/test_repo/complex_calculations_documentations/20240327211150.json.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2020 Zach Daniel + +SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/complex_calculations_documentations/20240327211917.json.license b/priv/resource_snapshots/test_repo/complex_calculations_documentations/20240327211917.json.license new file mode 100644 index 00000000..815664f3 --- /dev/null +++ b/priv/resource_snapshots/test_repo/complex_calculations_documentations/20240327211917.json.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2020 Zach Daniel + +SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/complex_calculations_folder_items/20250714225304.json.license b/priv/resource_snapshots/test_repo/complex_calculations_folder_items/20250714225304.json.license new file mode 100644 index 00000000..815664f3 --- /dev/null +++ b/priv/resource_snapshots/test_repo/complex_calculations_folder_items/20250714225304.json.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2020 Zach Daniel + +SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/complex_calculations_folders/20250714225304.json.license b/priv/resource_snapshots/test_repo/complex_calculations_folders/20250714225304.json.license new file mode 100644 index 00000000..815664f3 --- /dev/null +++ b/priv/resource_snapshots/test_repo/complex_calculations_folders/20250714225304.json.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2020 Zach Daniel + +SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/complex_calculations_skills/20230816231942.json.license b/priv/resource_snapshots/test_repo/complex_calculations_skills/20230816231942.json.license new file mode 100644 index 00000000..815664f3 --- /dev/null +++ b/priv/resource_snapshots/test_repo/complex_calculations_skills/20230816231942.json.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2020 Zach Daniel + +SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/complex_calculations_skills/20240327211150.json.license b/priv/resource_snapshots/test_repo/complex_calculations_skills/20240327211150.json.license new file mode 100644 index 00000000..815664f3 --- /dev/null +++ b/priv/resource_snapshots/test_repo/complex_calculations_skills/20240327211150.json.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2020 Zach Daniel + +SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/content/20250123164209.json.license b/priv/resource_snapshots/test_repo/content/20250123164209.json.license new file mode 100644 index 00000000..815664f3 --- /dev/null +++ b/priv/resource_snapshots/test_repo/content/20250123164209.json.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2020 Zach Daniel + +SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/content_visibility_group/20250123164209.json.license b/priv/resource_snapshots/test_repo/content_visibility_group/20250123164209.json.license new file mode 100644 index 00000000..815664f3 --- /dev/null +++ b/priv/resource_snapshots/test_repo/content_visibility_group/20250123164209.json.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2020 Zach Daniel + +SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/csv/20250320225052.json.license b/priv/resource_snapshots/test_repo/csv/20250320225052.json.license new file mode 100644 index 00000000..815664f3 --- /dev/null +++ b/priv/resource_snapshots/test_repo/csv/20250320225052.json.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2020 Zach Daniel + +SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/customers/20250908073737.json.license b/priv/resource_snapshots/test_repo/customers/20250908073737.json.license new file mode 100644 index 00000000..815664f3 --- /dev/null +++ b/priv/resource_snapshots/test_repo/customers/20250908073737.json.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2020 Zach Daniel + +SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/entities/20240109160153.json.license b/priv/resource_snapshots/test_repo/entities/20240109160153.json.license new file mode 100644 index 00000000..815664f3 --- /dev/null +++ b/priv/resource_snapshots/test_repo/entities/20240109160153.json.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2020 Zach Daniel + +SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/entities/20240327211150.json.license b/priv/resource_snapshots/test_repo/entities/20240327211150.json.license new file mode 100644 index 00000000..815664f3 --- /dev/null +++ b/priv/resource_snapshots/test_repo/entities/20240327211150.json.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2020 Zach Daniel + +SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/entities/20240327211917.json.license b/priv/resource_snapshots/test_repo/entities/20240327211917.json.license new file mode 100644 index 00000000..815664f3 --- /dev/null +++ b/priv/resource_snapshots/test_repo/entities/20240327211917.json.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2020 Zach Daniel + +SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/extensions.json.license b/priv/resource_snapshots/test_repo/extensions.json.license new file mode 100644 index 00000000..815664f3 --- /dev/null +++ b/priv/resource_snapshots/test_repo/extensions.json.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2020 Zach Daniel + +SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/integer_posts/20220805191443.json.license b/priv/resource_snapshots/test_repo/integer_posts/20220805191443.json.license new file mode 100644 index 00000000..815664f3 --- /dev/null +++ b/priv/resource_snapshots/test_repo/integer_posts/20220805191443.json.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2020 Zach Daniel + +SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/items/20240713134055.json.license b/priv/resource_snapshots/test_repo/items/20240713134055.json.license new file mode 100644 index 00000000..815664f3 --- /dev/null +++ b/priv/resource_snapshots/test_repo/items/20240713134055.json.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2020 Zach Daniel + +SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/items/20240717104854.json.license b/priv/resource_snapshots/test_repo/items/20240717104854.json.license new file mode 100644 index 00000000..815664f3 --- /dev/null +++ b/priv/resource_snapshots/test_repo/items/20240717104854.json.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2020 Zach Daniel + +SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/items/20240717153736.json.license b/priv/resource_snapshots/test_repo/items/20240717153736.json.license new file mode 100644 index 00000000..815664f3 --- /dev/null +++ b/priv/resource_snapshots/test_repo/items/20240717153736.json.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2020 Zach Daniel + +SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/jokes/20241217232254.json.license b/priv/resource_snapshots/test_repo/jokes/20241217232254.json.license new file mode 100644 index 00000000..815664f3 --- /dev/null +++ b/priv/resource_snapshots/test_repo/jokes/20241217232254.json.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2020 Zach Daniel + +SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/jokes/20250413141328.json.license b/priv/resource_snapshots/test_repo/jokes/20250413141328.json.license new file mode 100644 index 00000000..815664f3 --- /dev/null +++ b/priv/resource_snapshots/test_repo/jokes/20250413141328.json.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2020 Zach Daniel + +SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/managers/20230526144249.json.license b/priv/resource_snapshots/test_repo/managers/20230526144249.json.license new file mode 100644 index 00000000..815664f3 --- /dev/null +++ b/priv/resource_snapshots/test_repo/managers/20230526144249.json.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2020 Zach Daniel + +SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/managers/20240327211150.json.license b/priv/resource_snapshots/test_repo/managers/20240327211150.json.license new file mode 100644 index 00000000..815664f3 --- /dev/null +++ b/priv/resource_snapshots/test_repo/managers/20240327211150.json.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2020 Zach Daniel + +SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/messages/20250908093505.json.license b/priv/resource_snapshots/test_repo/messages/20250908093505.json.license new file mode 100644 index 00000000..815664f3 --- /dev/null +++ b/priv/resource_snapshots/test_repo/messages/20250908093505.json.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2020 Zach Daniel + +SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/multitenant_named_orgs/20250519103535.json.license b/priv/resource_snapshots/test_repo/multitenant_named_orgs/20250519103535.json.license new file mode 100644 index 00000000..815664f3 --- /dev/null +++ b/priv/resource_snapshots/test_repo/multitenant_named_orgs/20250519103535.json.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2020 Zach Daniel + +SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/multitenant_orgs/20220805191443.json.license b/priv/resource_snapshots/test_repo/multitenant_orgs/20220805191443.json.license new file mode 100644 index 00000000..815664f3 --- /dev/null +++ b/priv/resource_snapshots/test_repo/multitenant_orgs/20220805191443.json.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2020 Zach Daniel + +SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/multitenant_orgs/20240327211150.json.license b/priv/resource_snapshots/test_repo/multitenant_orgs/20240327211150.json.license new file mode 100644 index 00000000..815664f3 --- /dev/null +++ b/priv/resource_snapshots/test_repo/multitenant_orgs/20240327211150.json.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2020 Zach Daniel + +SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/multitenant_orgs/20240627223225.json.license b/priv/resource_snapshots/test_repo/multitenant_orgs/20240627223225.json.license new file mode 100644 index 00000000..815664f3 --- /dev/null +++ b/priv/resource_snapshots/test_repo/multitenant_orgs/20240627223225.json.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2020 Zach Daniel + +SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/multitenant_orgs/20240702164513.json.license b/priv/resource_snapshots/test_repo/multitenant_orgs/20240702164513.json.license new file mode 100644 index 00000000..815664f3 --- /dev/null +++ b/priv/resource_snapshots/test_repo/multitenant_orgs/20240702164513.json.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2020 Zach Daniel + +SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/multitenant_orgs/20240703155134.json.license b/priv/resource_snapshots/test_repo/multitenant_orgs/20240703155134.json.license new file mode 100644 index 00000000..815664f3 --- /dev/null +++ b/priv/resource_snapshots/test_repo/multitenant_orgs/20240703155134.json.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2020 Zach Daniel + +SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/non_multitenant_post_links/20250122190558.json.license b/priv/resource_snapshots/test_repo/non_multitenant_post_links/20250122190558.json.license new file mode 100644 index 00000000..815664f3 --- /dev/null +++ b/priv/resource_snapshots/test_repo/non_multitenant_post_links/20250122190558.json.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2020 Zach Daniel + +SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/note/20250123164209.json.license b/priv/resource_snapshots/test_repo/note/20250123164209.json.license new file mode 100644 index 00000000..815664f3 --- /dev/null +++ b/priv/resource_snapshots/test_repo/note/20250123164209.json.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2020 Zach Daniel + +SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/orders/20250908073737.json.license b/priv/resource_snapshots/test_repo/orders/20250908073737.json.license new file mode 100644 index 00000000..815664f3 --- /dev/null +++ b/priv/resource_snapshots/test_repo/orders/20250908073737.json.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2020 Zach Daniel + +SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/orgs/20230129050950.json.license b/priv/resource_snapshots/test_repo/orgs/20230129050950.json.license new file mode 100644 index 00000000..815664f3 --- /dev/null +++ b/priv/resource_snapshots/test_repo/orgs/20230129050950.json.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2020 Zach Daniel + +SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/orgs/20240327211150.json.license b/priv/resource_snapshots/test_repo/orgs/20240327211150.json.license new file mode 100644 index 00000000..815664f3 --- /dev/null +++ b/priv/resource_snapshots/test_repo/orgs/20240327211150.json.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2020 Zach Daniel + +SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/orgs/20250210191116.json.license b/priv/resource_snapshots/test_repo/orgs/20250210191116.json.license new file mode 100644 index 00000000..815664f3 --- /dev/null +++ b/priv/resource_snapshots/test_repo/orgs/20250210191116.json.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2020 Zach Daniel + +SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/other_items/20240713134055.json.license b/priv/resource_snapshots/test_repo/other_items/20240713134055.json.license new file mode 100644 index 00000000..815664f3 --- /dev/null +++ b/priv/resource_snapshots/test_repo/other_items/20240713134055.json.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2020 Zach Daniel + +SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/other_items/20240717151815.json.license b/priv/resource_snapshots/test_repo/other_items/20240717151815.json.license new file mode 100644 index 00000000..815664f3 --- /dev/null +++ b/priv/resource_snapshots/test_repo/other_items/20240717151815.json.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2020 Zach Daniel + +SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/points/20250313112823.json.license b/priv/resource_snapshots/test_repo/points/20250313112823.json.license new file mode 100644 index 00000000..815664f3 --- /dev/null +++ b/priv/resource_snapshots/test_repo/points/20250313112823.json.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2020 Zach Daniel + +SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/post_followers/20240227180858.json.license b/priv/resource_snapshots/test_repo/post_followers/20240227180858.json.license new file mode 100644 index 00000000..815664f3 --- /dev/null +++ b/priv/resource_snapshots/test_repo/post_followers/20240227180858.json.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2020 Zach Daniel + +SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/post_followers/20240227181137.json.license b/priv/resource_snapshots/test_repo/post_followers/20240227181137.json.license new file mode 100644 index 00000000..815664f3 --- /dev/null +++ b/priv/resource_snapshots/test_repo/post_followers/20240227181137.json.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2020 Zach Daniel + +SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/post_followers/20240327211150.json.license b/priv/resource_snapshots/test_repo/post_followers/20240327211150.json.license new file mode 100644 index 00000000..815664f3 --- /dev/null +++ b/priv/resource_snapshots/test_repo/post_followers/20240327211150.json.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2020 Zach Daniel + +SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/post_followers/20240516205244.json.license b/priv/resource_snapshots/test_repo/post_followers/20240516205244.json.license new file mode 100644 index 00000000..815664f3 --- /dev/null +++ b/priv/resource_snapshots/test_repo/post_followers/20240516205244.json.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2020 Zach Daniel + +SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/post_followers/20240517223946.json.license b/priv/resource_snapshots/test_repo/post_followers/20240517223946.json.license new file mode 100644 index 00000000..815664f3 --- /dev/null +++ b/priv/resource_snapshots/test_repo/post_followers/20240517223946.json.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2020 Zach Daniel + +SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/post_links/20220805191443.json.license b/priv/resource_snapshots/test_repo/post_links/20220805191443.json.license new file mode 100644 index 00000000..815664f3 --- /dev/null +++ b/priv/resource_snapshots/test_repo/post_links/20220805191443.json.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2020 Zach Daniel + +SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/post_links/20221017133955.json.license b/priv/resource_snapshots/test_repo/post_links/20221017133955.json.license new file mode 100644 index 00000000..815664f3 --- /dev/null +++ b/priv/resource_snapshots/test_repo/post_links/20221017133955.json.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2020 Zach Daniel + +SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/post_links/20221202194704.json.license b/priv/resource_snapshots/test_repo/post_links/20221202194704.json.license new file mode 100644 index 00000000..815664f3 --- /dev/null +++ b/priv/resource_snapshots/test_repo/post_links/20221202194704.json.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2020 Zach Daniel + +SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/post_links/20240610195853.json.license b/priv/resource_snapshots/test_repo/post_links/20240610195853.json.license new file mode 100644 index 00000000..815664f3 --- /dev/null +++ b/priv/resource_snapshots/test_repo/post_links/20240610195853.json.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2020 Zach Daniel + +SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/post_links/20240617193218.json.license b/priv/resource_snapshots/test_repo/post_links/20240617193218.json.license new file mode 100644 index 00000000..815664f3 --- /dev/null +++ b/priv/resource_snapshots/test_repo/post_links/20240617193218.json.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2020 Zach Daniel + +SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/post_permalinks/20240906170759.json.license b/priv/resource_snapshots/test_repo/post_permalinks/20240906170759.json.license new file mode 100644 index 00000000..815664f3 --- /dev/null +++ b/priv/resource_snapshots/test_repo/post_permalinks/20240906170759.json.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2020 Zach Daniel + +SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/post_ratings/20220805191443.json.license b/priv/resource_snapshots/test_repo/post_ratings/20220805191443.json.license new file mode 100644 index 00000000..815664f3 --- /dev/null +++ b/priv/resource_snapshots/test_repo/post_ratings/20220805191443.json.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2020 Zach Daniel + +SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/post_ratings/20240327211150.json.license b/priv/resource_snapshots/test_repo/post_ratings/20240327211150.json.license new file mode 100644 index 00000000..815664f3 --- /dev/null +++ b/priv/resource_snapshots/test_repo/post_ratings/20240327211150.json.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2020 Zach Daniel + +SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/post_tags/20250810102512.json.license b/priv/resource_snapshots/test_repo/post_tags/20250810102512.json.license new file mode 100644 index 00000000..815664f3 --- /dev/null +++ b/priv/resource_snapshots/test_repo/post_tags/20250810102512.json.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2020 Zach Daniel + +SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/post_views/20230905050351.json.license b/priv/resource_snapshots/test_repo/post_views/20230905050351.json.license new file mode 100644 index 00000000..815664f3 --- /dev/null +++ b/priv/resource_snapshots/test_repo/post_views/20230905050351.json.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2020 Zach Daniel + +SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/post_views/20240327211917.json.license b/priv/resource_snapshots/test_repo/post_views/20240327211917.json.license new file mode 100644 index 00000000..815664f3 --- /dev/null +++ b/priv/resource_snapshots/test_repo/post_views/20240327211917.json.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2020 Zach Daniel + +SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/posts/20220805191443.json.license b/priv/resource_snapshots/test_repo/posts/20220805191443.json.license new file mode 100644 index 00000000..815664f3 --- /dev/null +++ b/priv/resource_snapshots/test_repo/posts/20220805191443.json.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2020 Zach Daniel + +SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/posts/20221125171150.json.license b/priv/resource_snapshots/test_repo/posts/20221125171150.json.license new file mode 100644 index 00000000..815664f3 --- /dev/null +++ b/priv/resource_snapshots/test_repo/posts/20221125171150.json.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2020 Zach Daniel + +SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/posts/20221125171204.json.license b/priv/resource_snapshots/test_repo/posts/20221125171204.json.license new file mode 100644 index 00000000..815664f3 --- /dev/null +++ b/priv/resource_snapshots/test_repo/posts/20221125171204.json.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2020 Zach Daniel + +SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/posts/20230129050950.json.license b/priv/resource_snapshots/test_repo/posts/20230129050950.json.license new file mode 100644 index 00000000..815664f3 --- /dev/null +++ b/priv/resource_snapshots/test_repo/posts/20230129050950.json.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2020 Zach Daniel + +SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/posts/20230823161017.json.license b/priv/resource_snapshots/test_repo/posts/20230823161017.json.license new file mode 100644 index 00000000..815664f3 --- /dev/null +++ b/priv/resource_snapshots/test_repo/posts/20230823161017.json.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2020 Zach Daniel + +SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/posts/20231127215636.json.license b/priv/resource_snapshots/test_repo/posts/20231127215636.json.license new file mode 100644 index 00000000..815664f3 --- /dev/null +++ b/priv/resource_snapshots/test_repo/posts/20231127215636.json.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2020 Zach Daniel + +SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/posts/20231129141453.json.license b/priv/resource_snapshots/test_repo/posts/20231129141453.json.license new file mode 100644 index 00000000..815664f3 --- /dev/null +++ b/priv/resource_snapshots/test_repo/posts/20231129141453.json.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2020 Zach Daniel + +SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/posts/20231219132807.json.license b/priv/resource_snapshots/test_repo/posts/20231219132807.json.license new file mode 100644 index 00000000..815664f3 --- /dev/null +++ b/priv/resource_snapshots/test_repo/posts/20231219132807.json.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2020 Zach Daniel + +SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/posts/20240129221511.json.license b/priv/resource_snapshots/test_repo/posts/20240129221511.json.license new file mode 100644 index 00000000..815664f3 --- /dev/null +++ b/priv/resource_snapshots/test_repo/posts/20240129221511.json.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2020 Zach Daniel + +SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/posts/20240224001913.json.license b/priv/resource_snapshots/test_repo/posts/20240224001913.json.license new file mode 100644 index 00000000..815664f3 --- /dev/null +++ b/priv/resource_snapshots/test_repo/posts/20240224001913.json.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2020 Zach Daniel + +SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/posts/20240327211150.json.license b/priv/resource_snapshots/test_repo/posts/20240327211150.json.license new file mode 100644 index 00000000..815664f3 --- /dev/null +++ b/priv/resource_snapshots/test_repo/posts/20240327211150.json.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2020 Zach Daniel + +SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/posts/20240327211917.json.license b/priv/resource_snapshots/test_repo/posts/20240327211917.json.license new file mode 100644 index 00000000..815664f3 --- /dev/null +++ b/priv/resource_snapshots/test_repo/posts/20240327211917.json.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2020 Zach Daniel + +SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/posts/20240503012410.json.license b/priv/resource_snapshots/test_repo/posts/20240503012410.json.license new file mode 100644 index 00000000..815664f3 --- /dev/null +++ b/priv/resource_snapshots/test_repo/posts/20240503012410.json.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2020 Zach Daniel + +SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/posts/20240504185511.json.license b/priv/resource_snapshots/test_repo/posts/20240504185511.json.license new file mode 100644 index 00000000..815664f3 --- /dev/null +++ b/priv/resource_snapshots/test_repo/posts/20240504185511.json.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2020 Zach Daniel + +SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/posts/20240524031113.json.license b/priv/resource_snapshots/test_repo/posts/20240524031113.json.license new file mode 100644 index 00000000..815664f3 --- /dev/null +++ b/priv/resource_snapshots/test_repo/posts/20240524031113.json.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2020 Zach Daniel + +SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/posts/20240524041750.json.license b/priv/resource_snapshots/test_repo/posts/20240524041750.json.license new file mode 100644 index 00000000..815664f3 --- /dev/null +++ b/priv/resource_snapshots/test_repo/posts/20240524041750.json.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2020 Zach Daniel + +SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/posts/20240617193218.json.license b/priv/resource_snapshots/test_repo/posts/20240617193218.json.license new file mode 100644 index 00000000..815664f3 --- /dev/null +++ b/priv/resource_snapshots/test_repo/posts/20240617193218.json.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2020 Zach Daniel + +SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/posts/20240618102809.json.license b/priv/resource_snapshots/test_repo/posts/20240618102809.json.license new file mode 100644 index 00000000..815664f3 --- /dev/null +++ b/priv/resource_snapshots/test_repo/posts/20240618102809.json.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2020 Zach Daniel + +SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/posts/20240712232026.json.license b/priv/resource_snapshots/test_repo/posts/20240712232026.json.license new file mode 100644 index 00000000..815664f3 --- /dev/null +++ b/priv/resource_snapshots/test_repo/posts/20240712232026.json.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2020 Zach Daniel + +SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/posts/20240715135403.json.license b/priv/resource_snapshots/test_repo/posts/20240715135403.json.license new file mode 100644 index 00000000..815664f3 --- /dev/null +++ b/priv/resource_snapshots/test_repo/posts/20240715135403.json.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2020 Zach Daniel + +SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/posts/20240910180107.json.license b/priv/resource_snapshots/test_repo/posts/20240910180107.json.license new file mode 100644 index 00000000..815664f3 --- /dev/null +++ b/priv/resource_snapshots/test_repo/posts/20240910180107.json.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2020 Zach Daniel + +SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/posts/20240911225320.json.license b/priv/resource_snapshots/test_repo/posts/20240911225320.json.license new file mode 100644 index 00000000..815664f3 --- /dev/null +++ b/priv/resource_snapshots/test_repo/posts/20240911225320.json.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2020 Zach Daniel + +SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/posts/20240918104740.json.license b/priv/resource_snapshots/test_repo/posts/20240918104740.json.license new file mode 100644 index 00000000..815664f3 --- /dev/null +++ b/priv/resource_snapshots/test_repo/posts/20240918104740.json.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2020 Zach Daniel + +SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/posts/20240929121224.json.license b/priv/resource_snapshots/test_repo/posts/20240929121224.json.license new file mode 100644 index 00000000..815664f3 --- /dev/null +++ b/priv/resource_snapshots/test_repo/posts/20240929121224.json.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2020 Zach Daniel + +SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/posts/20250217054207.json.license b/priv/resource_snapshots/test_repo/posts/20250217054207.json.license new file mode 100644 index 00000000..815664f3 --- /dev/null +++ b/priv/resource_snapshots/test_repo/posts/20250217054207.json.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2020 Zach Daniel + +SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/posts/20250313112823.json.license b/priv/resource_snapshots/test_repo/posts/20250313112823.json.license new file mode 100644 index 00000000..815664f3 --- /dev/null +++ b/priv/resource_snapshots/test_repo/posts/20250313112823.json.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2020 Zach Daniel + +SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/posts/20250520130634.json.license b/priv/resource_snapshots/test_repo/posts/20250520130634.json.license new file mode 100644 index 00000000..815664f3 --- /dev/null +++ b/priv/resource_snapshots/test_repo/posts/20250520130634.json.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2020 Zach Daniel + +SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/posts/20250521105654.json.license b/priv/resource_snapshots/test_repo/posts/20250521105654.json.license new file mode 100644 index 00000000..815664f3 --- /dev/null +++ b/priv/resource_snapshots/test_repo/posts/20250521105654.json.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2020 Zach Daniel + +SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/posts/20250612113920.json.license b/priv/resource_snapshots/test_repo/posts/20250612113920.json.license new file mode 100644 index 00000000..815664f3 --- /dev/null +++ b/priv/resource_snapshots/test_repo/posts/20250612113920.json.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2020 Zach Daniel + +SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/posts/20250618011917.json.license b/priv/resource_snapshots/test_repo/posts/20250618011917.json.license new file mode 100644 index 00000000..815664f3 --- /dev/null +++ b/priv/resource_snapshots/test_repo/posts/20250618011917.json.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2020 Zach Daniel + +SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/products/20250908073737.json.license b/priv/resource_snapshots/test_repo/products/20250908073737.json.license new file mode 100644 index 00000000..815664f3 --- /dev/null +++ b/priv/resource_snapshots/test_repo/products/20250908073737.json.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2020 Zach Daniel + +SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/profile/20220805191443.json.license b/priv/resource_snapshots/test_repo/profile/20220805191443.json.license new file mode 100644 index 00000000..815664f3 --- /dev/null +++ b/priv/resource_snapshots/test_repo/profile/20220805191443.json.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2020 Zach Daniel + +SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/profiles.profile/20240327211150.json.license b/priv/resource_snapshots/test_repo/profiles.profile/20240327211150.json.license new file mode 100644 index 00000000..815664f3 --- /dev/null +++ b/priv/resource_snapshots/test_repo/profiles.profile/20240327211150.json.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2020 Zach Daniel + +SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/punchlines/20250413141328.json.license b/priv/resource_snapshots/test_repo/punchlines/20250413141328.json.license new file mode 100644 index 00000000..815664f3 --- /dev/null +++ b/priv/resource_snapshots/test_repo/punchlines/20250413141328.json.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2020 Zach Daniel + +SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/records/20240109160153.json.license b/priv/resource_snapshots/test_repo/records/20240109160153.json.license new file mode 100644 index 00000000..815664f3 --- /dev/null +++ b/priv/resource_snapshots/test_repo/records/20240109160153.json.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2020 Zach Daniel + +SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/records/20240327211150.json.license b/priv/resource_snapshots/test_repo/records/20240327211150.json.license new file mode 100644 index 00000000..815664f3 --- /dev/null +++ b/priv/resource_snapshots/test_repo/records/20240327211150.json.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2020 Zach Daniel + +SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/records/20240327211917.json.license b/priv/resource_snapshots/test_repo/records/20240327211917.json.license new file mode 100644 index 00000000..815664f3 --- /dev/null +++ b/priv/resource_snapshots/test_repo/records/20240327211917.json.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2020 Zach Daniel + +SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/records_temp_entities/20250605230457.json.license b/priv/resource_snapshots/test_repo/records_temp_entities/20250605230457.json.license new file mode 100644 index 00000000..815664f3 --- /dev/null +++ b/priv/resource_snapshots/test_repo/records_temp_entities/20250605230457.json.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2020 Zach Daniel + +SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/relationship_items/20240717153736.json.license b/priv/resource_snapshots/test_repo/relationship_items/20240717153736.json.license new file mode 100644 index 00000000..815664f3 --- /dev/null +++ b/priv/resource_snapshots/test_repo/relationship_items/20240717153736.json.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2020 Zach Daniel + +SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/rsvps/20251002180954.json.license b/priv/resource_snapshots/test_repo/rsvps/20251002180954.json.license new file mode 100644 index 00000000..815664f3 --- /dev/null +++ b/priv/resource_snapshots/test_repo/rsvps/20251002180954.json.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2020 Zach Daniel + +SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/schematic_groups/20240821213522.json.license b/priv/resource_snapshots/test_repo/schematic_groups/20240821213522.json.license new file mode 100644 index 00000000..815664f3 --- /dev/null +++ b/priv/resource_snapshots/test_repo/schematic_groups/20240821213522.json.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2020 Zach Daniel + +SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/staff_group/20250123164209.json.license b/priv/resource_snapshots/test_repo/staff_group/20250123164209.json.license new file mode 100644 index 00000000..815664f3 --- /dev/null +++ b/priv/resource_snapshots/test_repo/staff_group/20250123164209.json.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2020 Zach Daniel + +SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/staff_group_member/20250123164209.json.license b/priv/resource_snapshots/test_repo/staff_group_member/20250123164209.json.license new file mode 100644 index 00000000..815664f3 --- /dev/null +++ b/priv/resource_snapshots/test_repo/staff_group_member/20250123164209.json.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2020 Zach Daniel + +SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/standup_clubs/20250413141328.json.license b/priv/resource_snapshots/test_repo/standup_clubs/20250413141328.json.license new file mode 100644 index 00000000..815664f3 --- /dev/null +++ b/priv/resource_snapshots/test_repo/standup_clubs/20250413141328.json.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2020 Zach Daniel + +SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/stateful_post_followers/20240618085942.json.license b/priv/resource_snapshots/test_repo/stateful_post_followers/20240618085942.json.license new file mode 100644 index 00000000..815664f3 --- /dev/null +++ b/priv/resource_snapshots/test_repo/stateful_post_followers/20240618085942.json.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2020 Zach Daniel + +SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/string_points/20250313112823.json.license b/priv/resource_snapshots/test_repo/string_points/20250313112823.json.license new file mode 100644 index 00000000..815664f3 --- /dev/null +++ b/priv/resource_snapshots/test_repo/string_points/20250313112823.json.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2020 Zach Daniel + +SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/sub_items/20240713134055.json.license b/priv/resource_snapshots/test_repo/sub_items/20240713134055.json.license new file mode 100644 index 00000000..815664f3 --- /dev/null +++ b/priv/resource_snapshots/test_repo/sub_items/20240713134055.json.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2020 Zach Daniel + +SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/subquery_access/20240130133933.json.license b/priv/resource_snapshots/test_repo/subquery_access/20240130133933.json.license new file mode 100644 index 00000000..815664f3 --- /dev/null +++ b/priv/resource_snapshots/test_repo/subquery_access/20240130133933.json.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2020 Zach Daniel + +SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/subquery_child/20240130133933.json.license b/priv/resource_snapshots/test_repo/subquery_child/20240130133933.json.license new file mode 100644 index 00000000..815664f3 --- /dev/null +++ b/priv/resource_snapshots/test_repo/subquery_child/20240130133933.json.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2020 Zach Daniel + +SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/subquery_parent/20240130133933.json.license b/priv/resource_snapshots/test_repo/subquery_parent/20240130133933.json.license new file mode 100644 index 00000000..815664f3 --- /dev/null +++ b/priv/resource_snapshots/test_repo/subquery_parent/20240130133933.json.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2020 Zach Daniel + +SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/subquery_through/20240130133933.json.license b/priv/resource_snapshots/test_repo/subquery_through/20240130133933.json.license new file mode 100644 index 00000000..815664f3 --- /dev/null +++ b/priv/resource_snapshots/test_repo/subquery_through/20240130133933.json.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2020 Zach Daniel + +SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/tags/20250810102512.json.license b/priv/resource_snapshots/test_repo/tags/20250810102512.json.license new file mode 100644 index 00000000..815664f3 --- /dev/null +++ b/priv/resource_snapshots/test_repo/tags/20250810102512.json.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2020 Zach Daniel + +SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/temp.temp_entities/20240327211150.json.license b/priv/resource_snapshots/test_repo/temp.temp_entities/20240327211150.json.license new file mode 100644 index 00000000..815664f3 --- /dev/null +++ b/priv/resource_snapshots/test_repo/temp.temp_entities/20240327211150.json.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2020 Zach Daniel + +SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/temp.temp_entities/20240327211917.json.license b/priv/resource_snapshots/test_repo/temp.temp_entities/20240327211917.json.license new file mode 100644 index 00000000..815664f3 --- /dev/null +++ b/priv/resource_snapshots/test_repo/temp.temp_entities/20240327211917.json.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2020 Zach Daniel + +SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/temp_entities/20240109160153.json.license b/priv/resource_snapshots/test_repo/temp_entities/20240109160153.json.license new file mode 100644 index 00000000..815664f3 --- /dev/null +++ b/priv/resource_snapshots/test_repo/temp_entities/20240109160153.json.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2020 Zach Daniel + +SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/tenants/composite_key/20250220073135.json.license b/priv/resource_snapshots/test_repo/tenants/composite_key/20250220073135.json.license new file mode 100644 index 00000000..815664f3 --- /dev/null +++ b/priv/resource_snapshots/test_repo/tenants/composite_key/20250220073135.json.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2020 Zach Daniel + +SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/tenants/composite_key/20250220073141.json.license b/priv/resource_snapshots/test_repo/tenants/composite_key/20250220073141.json.license new file mode 100644 index 00000000..815664f3 --- /dev/null +++ b/priv/resource_snapshots/test_repo/tenants/composite_key/20250220073141.json.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2020 Zach Daniel + +SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/tenants/cross_tenant_post_links/20250122203454.json.license b/priv/resource_snapshots/test_repo/tenants/cross_tenant_post_links/20250122203454.json.license new file mode 100644 index 00000000..815664f3 --- /dev/null +++ b/priv/resource_snapshots/test_repo/tenants/cross_tenant_post_links/20250122203454.json.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2020 Zach Daniel + +SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/tenants/friend_links/20240610162043.json.license b/priv/resource_snapshots/test_repo/tenants/friend_links/20240610162043.json.license new file mode 100644 index 00000000..815664f3 --- /dev/null +++ b/priv/resource_snapshots/test_repo/tenants/friend_links/20240610162043.json.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2020 Zach Daniel + +SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/tenants/multitenant_posts/20220805191441.json.license b/priv/resource_snapshots/test_repo/tenants/multitenant_posts/20220805191441.json.license new file mode 100644 index 00000000..815664f3 --- /dev/null +++ b/priv/resource_snapshots/test_repo/tenants/multitenant_posts/20220805191441.json.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2020 Zach Daniel + +SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/tenants/multitenant_posts/20240327211149.json.license b/priv/resource_snapshots/test_repo/tenants/multitenant_posts/20240327211149.json.license new file mode 100644 index 00000000..815664f3 --- /dev/null +++ b/priv/resource_snapshots/test_repo/tenants/multitenant_posts/20240327211149.json.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2020 Zach Daniel + +SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/tenants/non_multitenant_post_multitenant_links/20251001120813.json.license b/priv/resource_snapshots/test_repo/tenants/non_multitenant_post_multitenant_links/20251001120813.json.license new file mode 100644 index 00000000..815664f3 --- /dev/null +++ b/priv/resource_snapshots/test_repo/tenants/non_multitenant_post_multitenant_links/20251001120813.json.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2020 Zach Daniel + +SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/unrelated_profiles/20250731124648.json.license b/priv/resource_snapshots/test_repo/unrelated_profiles/20250731124648.json.license new file mode 100644 index 00000000..815664f3 --- /dev/null +++ b/priv/resource_snapshots/test_repo/unrelated_profiles/20250731124648.json.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2020 Zach Daniel + +SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/unrelated_reports/20250731124648.json.license b/priv/resource_snapshots/test_repo/unrelated_reports/20250731124648.json.license new file mode 100644 index 00000000..815664f3 --- /dev/null +++ b/priv/resource_snapshots/test_repo/unrelated_reports/20250731124648.json.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2020 Zach Daniel + +SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/unrelated_secure_profiles/20250731124648.json.license b/priv/resource_snapshots/test_repo/unrelated_secure_profiles/20250731124648.json.license new file mode 100644 index 00000000..815664f3 --- /dev/null +++ b/priv/resource_snapshots/test_repo/unrelated_secure_profiles/20250731124648.json.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2020 Zach Daniel + +SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/unrelated_users/20250731124648.json.license b/priv/resource_snapshots/test_repo/unrelated_users/20250731124648.json.license new file mode 100644 index 00000000..815664f3 --- /dev/null +++ b/priv/resource_snapshots/test_repo/unrelated_users/20250731124648.json.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2020 Zach Daniel + +SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/user_invites/20240727145758.json.license b/priv/resource_snapshots/test_repo/user_invites/20240727145758.json.license new file mode 100644 index 00000000..815664f3 --- /dev/null +++ b/priv/resource_snapshots/test_repo/user_invites/20240727145758.json.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2020 Zach Daniel + +SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/users/20220805191443.json.license b/priv/resource_snapshots/test_repo/users/20220805191443.json.license new file mode 100644 index 00000000..815664f3 --- /dev/null +++ b/priv/resource_snapshots/test_repo/users/20220805191443.json.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2020 Zach Daniel + +SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/users/20221217123726.json.license b/priv/resource_snapshots/test_repo/users/20221217123726.json.license new file mode 100644 index 00000000..815664f3 --- /dev/null +++ b/priv/resource_snapshots/test_repo/users/20221217123726.json.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2020 Zach Daniel + +SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/users/20230129050950.json.license b/priv/resource_snapshots/test_repo/users/20230129050950.json.license new file mode 100644 index 00000000..815664f3 --- /dev/null +++ b/priv/resource_snapshots/test_repo/users/20230129050950.json.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2020 Zach Daniel + +SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/users/20240327211150.json.license b/priv/resource_snapshots/test_repo/users/20240327211150.json.license new file mode 100644 index 00000000..815664f3 --- /dev/null +++ b/priv/resource_snapshots/test_repo/users/20240327211150.json.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2020 Zach Daniel + +SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/users/20240727145758.json.license b/priv/resource_snapshots/test_repo/users/20240727145758.json.license new file mode 100644 index 00000000..815664f3 --- /dev/null +++ b/priv/resource_snapshots/test_repo/users/20240727145758.json.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2020 Zach Daniel + +SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/users/20240929124728.json.license b/priv/resource_snapshots/test_repo/users/20240929124728.json.license new file mode 100644 index 00000000..815664f3 --- /dev/null +++ b/priv/resource_snapshots/test_repo/users/20240929124728.json.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2020 Zach Daniel + +SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/users/20250320225052.json.license b/priv/resource_snapshots/test_repo/users/20250320225052.json.license new file mode 100644 index 00000000..815664f3 --- /dev/null +++ b/priv/resource_snapshots/test_repo/users/20250320225052.json.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2020 Zach Daniel + +SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/users/20250321142835.json.license b/priv/resource_snapshots/test_repo/users/20250321142835.json.license new file mode 100644 index 00000000..815664f3 --- /dev/null +++ b/priv/resource_snapshots/test_repo/users/20250321142835.json.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2020 Zach Daniel + +SPDX-License-Identifier: MIT diff --git a/priv/test_no_sandbox_repo/migrations/.gitkeep.license b/priv/test_no_sandbox_repo/migrations/.gitkeep.license new file mode 100644 index 00000000..815664f3 --- /dev/null +++ b/priv/test_no_sandbox_repo/migrations/.gitkeep.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2020 Zach Daniel + +SPDX-License-Identifier: MIT diff --git a/priv/test_no_sandbox_repo/migrations/20240627223224_install_5_extensions.exs b/priv/test_no_sandbox_repo/migrations/20240627223224_install_5_extensions.exs index 09446bc3..94e450c6 100644 --- a/priv/test_no_sandbox_repo/migrations/20240627223224_install_5_extensions.exs +++ b/priv/test_no_sandbox_repo/migrations/20240627223224_install_5_extensions.exs @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.TestNoSandboxRepo.Migrations.Install5Extensions20240627223222 do @moduledoc """ Installs any extensions that are mentioned in the repo's `installed_extensions/0` callback diff --git a/priv/test_no_sandbox_repo/migrations/20240712232025_install_ash-functions_extension_4.exs b/priv/test_no_sandbox_repo/migrations/20240712232025_install_ash-functions_extension_4.exs index 97101dca..ecf0a75f 100644 --- a/priv/test_no_sandbox_repo/migrations/20240712232025_install_ash-functions_extension_4.exs +++ b/priv/test_no_sandbox_repo/migrations/20240712232025_install_ash-functions_extension_4.exs @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.TestNoSandboxRepo.Migrations.InstallAshFunctionsExtension420240712232023 do @moduledoc """ Installs any extensions that are mentioned in the repo's `installed_extensions/0` callback diff --git a/priv/test_no_sandbox_repo/migrations/20250113205301_migrate_resources_extensions_1.exs b/priv/test_no_sandbox_repo/migrations/20250113205301_migrate_resources_extensions_1.exs index 9794c3be..01697a60 100644 --- a/priv/test_no_sandbox_repo/migrations/20250113205301_migrate_resources_extensions_1.exs +++ b/priv/test_no_sandbox_repo/migrations/20250113205301_migrate_resources_extensions_1.exs @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.TestNoSandboxRepo.Migrations.MigrateResourcesExtensions1 do @moduledoc """ Installs any extensions that are mentioned in the repo's `installed_extensions/0` callback diff --git a/priv/test_repo/migrations/20220805191440_install_4_extensions.exs b/priv/test_repo/migrations/20220805191440_install_4_extensions.exs index f301710b..a20aa8e9 100644 --- a/priv/test_repo/migrations/20220805191440_install_4_extensions.exs +++ b/priv/test_repo/migrations/20220805191440_install_4_extensions.exs @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.TestRepo.Migrations.Install4Extensions do @moduledoc """ Installs any extensions that are mentioned in the repo's `installed_extensions/0` callback diff --git a/priv/test_repo/migrations/20220805191443_migrate_resources1.exs b/priv/test_repo/migrations/20220805191443_migrate_resources1.exs index 886d2de2..b9b7fdd0 100644 --- a/priv/test_repo/migrations/20220805191443_migrate_resources1.exs +++ b/priv/test_repo/migrations/20220805191443_migrate_resources1.exs @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.TestRepo.Migrations.MigrateResources1 do @moduledoc """ Updates resources based on their most recent snapshots. diff --git a/priv/test_repo/migrations/20220914104733_migrate_resources2.exs b/priv/test_repo/migrations/20220914104733_migrate_resources2.exs index 17ecb49f..fbbeb8e0 100644 --- a/priv/test_repo/migrations/20220914104733_migrate_resources2.exs +++ b/priv/test_repo/migrations/20220914104733_migrate_resources2.exs @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.TestRepo.Migrations.MigrateResources2 do @moduledoc """ Updates resources based on their most recent snapshots. diff --git a/priv/test_repo/migrations/20221017133955_migrate_resources3.exs b/priv/test_repo/migrations/20221017133955_migrate_resources3.exs index b30a8ba4..12f282d6 100644 --- a/priv/test_repo/migrations/20221017133955_migrate_resources3.exs +++ b/priv/test_repo/migrations/20221017133955_migrate_resources3.exs @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.TestRepo.Migrations.MigrateResources3 do @moduledoc """ Updates resources based on their most recent snapshots. diff --git a/priv/test_repo/migrations/20221125171148_migrate_resources4.exs b/priv/test_repo/migrations/20221125171148_migrate_resources4.exs index e58db10c..b6749230 100644 --- a/priv/test_repo/migrations/20221125171148_migrate_resources4.exs +++ b/priv/test_repo/migrations/20221125171148_migrate_resources4.exs @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.TestRepo.Migrations.MigrateResources4 do @moduledoc """ Updates resources based on their most recent snapshots. diff --git a/priv/test_repo/migrations/20221125171150_migrate_resources5.exs b/priv/test_repo/migrations/20221125171150_migrate_resources5.exs index e9268571..f4d14b56 100644 --- a/priv/test_repo/migrations/20221125171150_migrate_resources5.exs +++ b/priv/test_repo/migrations/20221125171150_migrate_resources5.exs @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.TestRepo.Migrations.MigrateResources5 do @moduledoc """ Updates resources based on their most recent snapshots. diff --git a/priv/test_repo/migrations/20221202194704_migrate_resources6.exs b/priv/test_repo/migrations/20221202194704_migrate_resources6.exs index 2d77266a..6b6f174a 100644 --- a/priv/test_repo/migrations/20221202194704_migrate_resources6.exs +++ b/priv/test_repo/migrations/20221202194704_migrate_resources6.exs @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.TestRepo.Migrations.MigrateResources6 do @moduledoc """ Updates resources based on their most recent snapshots. diff --git a/priv/test_repo/migrations/20221217123726_migrate_resources7.exs b/priv/test_repo/migrations/20221217123726_migrate_resources7.exs index 8ca2e4f2..95edab52 100644 --- a/priv/test_repo/migrations/20221217123726_migrate_resources7.exs +++ b/priv/test_repo/migrations/20221217123726_migrate_resources7.exs @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.TestRepo.Migrations.MigrateResources7 do @moduledoc """ Updates resources based on their most recent snapshots. diff --git a/priv/test_repo/migrations/20230129050950_migrate_resources8.exs b/priv/test_repo/migrations/20230129050950_migrate_resources8.exs index 4cfaa7da..3aba9340 100644 --- a/priv/test_repo/migrations/20230129050950_migrate_resources8.exs +++ b/priv/test_repo/migrations/20230129050950_migrate_resources8.exs @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.TestRepo.Migrations.MigrateResources8 do @moduledoc """ Updates resources based on their most recent snapshots. diff --git a/priv/test_repo/migrations/20230526144249_migrate_resources9.exs b/priv/test_repo/migrations/20230526144249_migrate_resources9.exs index a4008d52..d3a907b8 100644 --- a/priv/test_repo/migrations/20230526144249_migrate_resources9.exs +++ b/priv/test_repo/migrations/20230526144249_migrate_resources9.exs @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.TestRepo.Migrations.MigrateResources9 do @moduledoc """ Updates resources based on their most recent snapshots. diff --git a/priv/test_repo/migrations/20230712182523_install_ash-functions_extension.exs b/priv/test_repo/migrations/20230712182523_install_ash-functions_extension.exs index 8c0b5fef..6f9ee9e4 100644 --- a/priv/test_repo/migrations/20230712182523_install_ash-functions_extension.exs +++ b/priv/test_repo/migrations/20230712182523_install_ash-functions_extension.exs @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.TestRepo.Migrations.InstallAshFunctions do @moduledoc """ Installs any extensions that are mentioned in the repo's `installed_extensions/0` callback diff --git a/priv/test_repo/migrations/20230804223759_install_demo-functions_v0_extension.exs b/priv/test_repo/migrations/20230804223759_install_demo-functions_v0_extension.exs index 5521466e..edfac408 100644 --- a/priv/test_repo/migrations/20230804223759_install_demo-functions_v0_extension.exs +++ b/priv/test_repo/migrations/20230804223759_install_demo-functions_v0_extension.exs @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.TestRepo.Migrations.InstallDemoFunctionsV0 do @moduledoc """ Installs any extensions that are mentioned in the repo's `installed_extensions/0` callback diff --git a/priv/test_repo/migrations/20230804223818_install_demo-functions_v1_extension.exs b/priv/test_repo/migrations/20230804223818_install_demo-functions_v1_extension.exs index b82ee5c7..2222a781 100644 --- a/priv/test_repo/migrations/20230804223818_install_demo-functions_v1_extension.exs +++ b/priv/test_repo/migrations/20230804223818_install_demo-functions_v1_extension.exs @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.TestRepo.Migrations.InstallDemoFunctionsV1 do @moduledoc """ Installs any extensions that are mentioned in the repo's `installed_extensions/0` callback diff --git a/priv/test_repo/migrations/20230816231942_add_complex_calculation_tables.exs b/priv/test_repo/migrations/20230816231942_add_complex_calculation_tables.exs index 19ded080..1cc444b7 100644 --- a/priv/test_repo/migrations/20230816231942_add_complex_calculation_tables.exs +++ b/priv/test_repo/migrations/20230816231942_add_complex_calculation_tables.exs @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.TestRepo.Migrations.AddComplexCalculationTables do @moduledoc """ Updates resources based on their most recent snapshots. diff --git a/priv/test_repo/migrations/20230823161017_migrate_resources10.exs b/priv/test_repo/migrations/20230823161017_migrate_resources10.exs index 314d7bea..18e6f479 100644 --- a/priv/test_repo/migrations/20230823161017_migrate_resources10.exs +++ b/priv/test_repo/migrations/20230823161017_migrate_resources10.exs @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.TestRepo.Migrations.MigrateResources10 do @moduledoc """ Updates resources based on their most recent snapshots. diff --git a/priv/test_repo/migrations/20230905050351_add_post_views.exs b/priv/test_repo/migrations/20230905050351_add_post_views.exs index b09ea4af..3ea0cbb1 100644 --- a/priv/test_repo/migrations/20230905050351_add_post_views.exs +++ b/priv/test_repo/migrations/20230905050351_add_post_views.exs @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.TestRepo.Migrations.AddPostViews do @moduledoc """ Updates resources based on their most recent snapshots. diff --git a/priv/test_repo/migrations/20231116013020_add_complex_calculations_channels.exs b/priv/test_repo/migrations/20231116013020_add_complex_calculations_channels.exs index e090e448..c3f768f0 100644 --- a/priv/test_repo/migrations/20231116013020_add_complex_calculations_channels.exs +++ b/priv/test_repo/migrations/20231116013020_add_complex_calculations_channels.exs @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.TestRepo.Migrations.AddComplexCalculationsChannels do @moduledoc """ Updates resources based on their most recent snapshots. diff --git a/priv/test_repo/migrations/20231127212608_add_composite_type.exs b/priv/test_repo/migrations/20231127212608_add_composite_type.exs index 9f1217ff..8a85a46f 100644 --- a/priv/test_repo/migrations/20231127212608_add_composite_type.exs +++ b/priv/test_repo/migrations/20231127212608_add_composite_type.exs @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.TestRepo.Migrations.AddCompositeType do use Ecto.Migration diff --git a/priv/test_repo/migrations/20231127215636_migrate_resources11.exs b/priv/test_repo/migrations/20231127215636_migrate_resources11.exs index 06eb1c5b..c4da8e77 100644 --- a/priv/test_repo/migrations/20231127215636_migrate_resources11.exs +++ b/priv/test_repo/migrations/20231127215636_migrate_resources11.exs @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.TestRepo.Migrations.MigrateResources11 do @moduledoc """ Updates resources based on their most recent snapshots. diff --git a/priv/test_repo/migrations/20231129141453_migrate_resources12.exs b/priv/test_repo/migrations/20231129141453_migrate_resources12.exs index 1fbcbd28..613a6b42 100644 --- a/priv/test_repo/migrations/20231129141453_migrate_resources12.exs +++ b/priv/test_repo/migrations/20231129141453_migrate_resources12.exs @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.TestRepo.Migrations.MigrateResources12 do @moduledoc """ Updates resources based on their most recent snapshots. diff --git a/priv/test_repo/migrations/20231214220937_install_ash-functions_extension_2.exs b/priv/test_repo/migrations/20231214220937_install_ash-functions_extension_2.exs index d3192fdc..e02f5467 100644 --- a/priv/test_repo/migrations/20231214220937_install_ash-functions_extension_2.exs +++ b/priv/test_repo/migrations/20231214220937_install_ash-functions_extension_2.exs @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.TestRepo.Migrations.InstallAshFunctionsExtension2 do @moduledoc """ Installs any extensions that are mentioned in the repo's `installed_extensions/0` callback diff --git a/priv/test_repo/migrations/20231219132807_migrate_resources13.exs b/priv/test_repo/migrations/20231219132807_migrate_resources13.exs index 088d2ae3..55fc4bbe 100644 --- a/priv/test_repo/migrations/20231219132807_migrate_resources13.exs +++ b/priv/test_repo/migrations/20231219132807_migrate_resources13.exs @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.TestRepo.Migrations.MigrateResources13 do @moduledoc """ Updates resources based on their most recent snapshots. diff --git a/priv/test_repo/migrations/20231231051611_install_ash-functions_extension_3.exs b/priv/test_repo/migrations/20231231051611_install_ash-functions_extension_3.exs index 2417e5d7..e841dfba 100644 --- a/priv/test_repo/migrations/20231231051611_install_ash-functions_extension_3.exs +++ b/priv/test_repo/migrations/20231231051611_install_ash-functions_extension_3.exs @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.TestRepo.Migrations.InstallAshFunctionsExtension3 do @moduledoc """ Installs any extensions that are mentioned in the repo's `installed_extensions/0` callback diff --git a/priv/test_repo/migrations/20240109155951_create_temp_schema.exs b/priv/test_repo/migrations/20240109155951_create_temp_schema.exs index 2ecb9500..ada02c90 100644 --- a/priv/test_repo/migrations/20240109155951_create_temp_schema.exs +++ b/priv/test_repo/migrations/20240109155951_create_temp_schema.exs @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.TestRepo.Migrations.CreateTempSchema do use Ecto.Migration diff --git a/priv/test_repo/migrations/20240109160153_migrate_resources14.exs b/priv/test_repo/migrations/20240109160153_migrate_resources14.exs index 22bec37b..c70f9357 100644 --- a/priv/test_repo/migrations/20240109160153_migrate_resources14.exs +++ b/priv/test_repo/migrations/20240109160153_migrate_resources14.exs @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.TestRepo.Migrations.MigrateResources14 do @moduledoc """ Updates resources based on their most recent snapshots. diff --git a/priv/test_repo/migrations/20240129221511_migrate_resources15.exs b/priv/test_repo/migrations/20240129221511_migrate_resources15.exs index 3ee35d6b..88ae8d08 100644 --- a/priv/test_repo/migrations/20240129221511_migrate_resources15.exs +++ b/priv/test_repo/migrations/20240129221511_migrate_resources15.exs @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.TestRepo.Migrations.MigrateResources15 do @moduledoc """ Updates resources based on their most recent snapshots. diff --git a/priv/test_repo/migrations/20240130133933_add_resources_for_subquery_test.exs b/priv/test_repo/migrations/20240130133933_add_resources_for_subquery_test.exs index f54f17a0..36ad998e 100644 --- a/priv/test_repo/migrations/20240130133933_add_resources_for_subquery_test.exs +++ b/priv/test_repo/migrations/20240130133933_add_resources_for_subquery_test.exs @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.TestRepo.Migrations.AddResourcesForSubqueryTest do @moduledoc """ Updates resources based on their most recent snapshots. diff --git a/priv/test_repo/migrations/20240224001913_migrate_resources16.exs b/priv/test_repo/migrations/20240224001913_migrate_resources16.exs index a9b687e1..00decc17 100644 --- a/priv/test_repo/migrations/20240224001913_migrate_resources16.exs +++ b/priv/test_repo/migrations/20240224001913_migrate_resources16.exs @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.TestRepo.Migrations.MigrateResources16 do @moduledoc """ Updates resources based on their most recent snapshots. diff --git a/priv/test_repo/migrations/20240227180858_migrate_resources17.exs b/priv/test_repo/migrations/20240227180858_migrate_resources17.exs index 1778a5e2..93fc8bd5 100644 --- a/priv/test_repo/migrations/20240227180858_migrate_resources17.exs +++ b/priv/test_repo/migrations/20240227180858_migrate_resources17.exs @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.TestRepo.Migrations.MigrateResources17 do @moduledoc """ Updates resources based on their most recent snapshots. diff --git a/priv/test_repo/migrations/20240227181137_migrate_resources18.exs b/priv/test_repo/migrations/20240227181137_migrate_resources18.exs index f55f7b3c..4e6db225 100644 --- a/priv/test_repo/migrations/20240227181137_migrate_resources18.exs +++ b/priv/test_repo/migrations/20240227181137_migrate_resources18.exs @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.TestRepo.Migrations.MigrateResources18 do @moduledoc """ Updates resources based on their most recent snapshots. diff --git a/priv/test_repo/migrations/20240229050455_install_5_extensions.exs b/priv/test_repo/migrations/20240229050455_install_5_extensions.exs index c3708b31..bdecc817 100644 --- a/priv/test_repo/migrations/20240229050455_install_5_extensions.exs +++ b/priv/test_repo/migrations/20240229050455_install_5_extensions.exs @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.TestRepo.Migrations.Install5Extensions do @moduledoc """ Installs any extensions that are mentioned in the repo's `installed_extensions/0` callback diff --git a/priv/test_repo/migrations/20240327211150_migrate_resources19.exs b/priv/test_repo/migrations/20240327211150_migrate_resources19.exs index 787d0e26..7fc2c8c3 100644 --- a/priv/test_repo/migrations/20240327211150_migrate_resources19.exs +++ b/priv/test_repo/migrations/20240327211150_migrate_resources19.exs @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.TestRepo.Migrations.MigrateResources19 do @moduledoc """ Updates resources based on their most recent snapshots. diff --git a/priv/test_repo/migrations/20240327211917_migrate_resources20.exs b/priv/test_repo/migrations/20240327211917_migrate_resources20.exs index 030206f5..bd30cc5b 100644 --- a/priv/test_repo/migrations/20240327211917_migrate_resources20.exs +++ b/priv/test_repo/migrations/20240327211917_migrate_resources20.exs @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.TestRepo.Migrations.MigrateResources20 do @moduledoc """ Updates resources based on their most recent snapshots. diff --git a/priv/test_repo/migrations/20240503012410_migrate_resources21.exs b/priv/test_repo/migrations/20240503012410_migrate_resources21.exs index 70781d33..9230a78a 100644 --- a/priv/test_repo/migrations/20240503012410_migrate_resources21.exs +++ b/priv/test_repo/migrations/20240503012410_migrate_resources21.exs @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.TestRepo.Migrations.MigrateResources21 do @moduledoc """ Updates resources based on their most recent snapshots. diff --git a/priv/test_repo/migrations/20240504185511_migrate_resources22.exs b/priv/test_repo/migrations/20240504185511_migrate_resources22.exs index 86257d61..19ae6c87 100644 --- a/priv/test_repo/migrations/20240504185511_migrate_resources22.exs +++ b/priv/test_repo/migrations/20240504185511_migrate_resources22.exs @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.TestRepo.Migrations.MigrateResources22 do @moduledoc """ Updates resources based on their most recent snapshots. diff --git a/priv/test_repo/migrations/20240516205244_migrate_resources23.exs b/priv/test_repo/migrations/20240516205244_migrate_resources23.exs index 1d0eec51..cebacd08 100644 --- a/priv/test_repo/migrations/20240516205244_migrate_resources23.exs +++ b/priv/test_repo/migrations/20240516205244_migrate_resources23.exs @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.TestRepo.Migrations.MigrateResources23 do @moduledoc """ Updates resources based on their most recent snapshots. diff --git a/priv/test_repo/migrations/20240517223946_migrate_resources24.exs b/priv/test_repo/migrations/20240517223946_migrate_resources24.exs index 22998699..09e71bd5 100644 --- a/priv/test_repo/migrations/20240517223946_migrate_resources24.exs +++ b/priv/test_repo/migrations/20240517223946_migrate_resources24.exs @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.TestRepo.Migrations.MigrateResources24 do @moduledoc """ Updates resources based on their most recent snapshots. diff --git a/priv/test_repo/migrations/20240524031113_migrate_resources25.exs b/priv/test_repo/migrations/20240524031113_migrate_resources25.exs index 9c524d71..0b829659 100644 --- a/priv/test_repo/migrations/20240524031113_migrate_resources25.exs +++ b/priv/test_repo/migrations/20240524031113_migrate_resources25.exs @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.TestRepo.Migrations.MigrateResources25 do @moduledoc """ Updates resources based on their most recent snapshots. diff --git a/priv/test_repo/migrations/20240524041750_migrate_resources26.exs b/priv/test_repo/migrations/20240524041750_migrate_resources26.exs index a65fb877..e27aff26 100644 --- a/priv/test_repo/migrations/20240524041750_migrate_resources26.exs +++ b/priv/test_repo/migrations/20240524041750_migrate_resources26.exs @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.TestRepo.Migrations.MigrateResources26 do @moduledoc """ Updates resources based on their most recent snapshots. diff --git a/priv/test_repo/migrations/20240610195853_migrate_resources27.exs b/priv/test_repo/migrations/20240610195853_migrate_resources27.exs index c31f8819..f156231e 100644 --- a/priv/test_repo/migrations/20240610195853_migrate_resources27.exs +++ b/priv/test_repo/migrations/20240610195853_migrate_resources27.exs @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.TestRepo.Migrations.MigrateResources27 do @moduledoc """ Updates resources based on their most recent snapshots. diff --git a/priv/test_repo/migrations/20240617193218_migrate_resources28.exs b/priv/test_repo/migrations/20240617193218_migrate_resources28.exs index d112c67a..d864e25b 100644 --- a/priv/test_repo/migrations/20240617193218_migrate_resources28.exs +++ b/priv/test_repo/migrations/20240617193218_migrate_resources28.exs @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.TestRepo.Migrations.MigrateResources28 do @moduledoc """ Updates resources based on their most recent snapshots. diff --git a/priv/test_repo/migrations/20240618085942_migrate_resources29.exs b/priv/test_repo/migrations/20240618085942_migrate_resources29.exs index f8e6fe26..0c6b8de3 100644 --- a/priv/test_repo/migrations/20240618085942_migrate_resources29.exs +++ b/priv/test_repo/migrations/20240618085942_migrate_resources29.exs @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.TestRepo.Migrations.MigrateResources29 do @moduledoc """ Updates resources based on their most recent snapshots. diff --git a/priv/test_repo/migrations/20240618102809_migrate_resources30.exs b/priv/test_repo/migrations/20240618102809_migrate_resources30.exs index f3cec44b..4d1f8ad8 100644 --- a/priv/test_repo/migrations/20240618102809_migrate_resources30.exs +++ b/priv/test_repo/migrations/20240618102809_migrate_resources30.exs @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.TestRepo.Migrations.MigrateResources30 do @moduledoc """ Updates resources based on their most recent snapshots. diff --git a/priv/test_repo/migrations/20240622192715_install_ash-functions_extension_4.exs b/priv/test_repo/migrations/20240622192715_install_ash-functions_extension_4.exs index 17c00fcc..3a544490 100644 --- a/priv/test_repo/migrations/20240622192715_install_ash-functions_extension_4.exs +++ b/priv/test_repo/migrations/20240622192715_install_ash-functions_extension_4.exs @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.TestRepo.Migrations.InstallAshFunctionsExtension420240622192713 do @moduledoc """ Installs any extensions that are mentioned in the repo's `installed_extensions/0` callback diff --git a/priv/test_repo/migrations/20240627223225_migrate_resources31.exs b/priv/test_repo/migrations/20240627223225_migrate_resources31.exs index 8a90e3d4..cd97c368 100644 --- a/priv/test_repo/migrations/20240627223225_migrate_resources31.exs +++ b/priv/test_repo/migrations/20240627223225_migrate_resources31.exs @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.TestRepo.Migrations.MigrateResources31 do @moduledoc """ Updates resources based on their most recent snapshots. diff --git a/priv/test_repo/migrations/20240703155134_migrate_resources32.exs b/priv/test_repo/migrations/20240703155134_migrate_resources32.exs index 47f472a2..1364a828 100644 --- a/priv/test_repo/migrations/20240703155134_migrate_resources32.exs +++ b/priv/test_repo/migrations/20240703155134_migrate_resources32.exs @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.TestRepo.Migrations.MigrateResources32 do @moduledoc """ Updates resources based on their most recent snapshots. diff --git a/priv/test_repo/migrations/20240705113722_migrate_resources33.exs b/priv/test_repo/migrations/20240705113722_migrate_resources33.exs index e06ec7c7..e6f7a1a8 100644 --- a/priv/test_repo/migrations/20240705113722_migrate_resources33.exs +++ b/priv/test_repo/migrations/20240705113722_migrate_resources33.exs @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.TestRepo.Migrations.MigrateResources33 do @moduledoc """ Updates resources based on their most recent snapshots. diff --git a/priv/test_repo/migrations/20240712232026_migrate_resources34.exs b/priv/test_repo/migrations/20240712232026_migrate_resources34.exs index af406cf3..22af731f 100644 --- a/priv/test_repo/migrations/20240712232026_migrate_resources34.exs +++ b/priv/test_repo/migrations/20240712232026_migrate_resources34.exs @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.TestRepo.Migrations.MigrateResources34 do @moduledoc """ Updates resources based on their most recent snapshots. diff --git a/priv/test_repo/migrations/20240713134055_multi_domain_calculations.exs b/priv/test_repo/migrations/20240713134055_multi_domain_calculations.exs index 04dce9a0..d6c57db6 100644 --- a/priv/test_repo/migrations/20240713134055_multi_domain_calculations.exs +++ b/priv/test_repo/migrations/20240713134055_multi_domain_calculations.exs @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.TestRepo.Migrations.MultiDomainCalculations do @moduledoc """ Updates resources based on their most recent snapshots. diff --git a/priv/test_repo/migrations/20240715135403_migrate_resources35.exs b/priv/test_repo/migrations/20240715135403_migrate_resources35.exs index 5819ea53..2349c59d 100644 --- a/priv/test_repo/migrations/20240715135403_migrate_resources35.exs +++ b/priv/test_repo/migrations/20240715135403_migrate_resources35.exs @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.TestRepo.Migrations.MigrateResources35 do @moduledoc """ Updates resources based on their most recent snapshots. diff --git a/priv/test_repo/migrations/20240717104854_no_attributes_calculation_test.exs b/priv/test_repo/migrations/20240717104854_no_attributes_calculation_test.exs index 04a9f3f6..2c9269fa 100644 --- a/priv/test_repo/migrations/20240717104854_no_attributes_calculation_test.exs +++ b/priv/test_repo/migrations/20240717104854_no_attributes_calculation_test.exs @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.TestRepo.Migrations.NoAttributesCalculationTest do @moduledoc """ Updates resources based on their most recent snapshots. diff --git a/priv/test_repo/migrations/20240717151815_migrate_resources36.exs b/priv/test_repo/migrations/20240717151815_migrate_resources36.exs index 1a885fcf..e8b21183 100644 --- a/priv/test_repo/migrations/20240717151815_migrate_resources36.exs +++ b/priv/test_repo/migrations/20240717151815_migrate_resources36.exs @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.TestRepo.Migrations.MigrateResources36 do @moduledoc """ Updates resources based on their most recent snapshots. diff --git a/priv/test_repo/migrations/20240717153736_migrate_resources37.exs b/priv/test_repo/migrations/20240717153736_migrate_resources37.exs index ba2f6bfe..4d5777a4 100644 --- a/priv/test_repo/migrations/20240717153736_migrate_resources37.exs +++ b/priv/test_repo/migrations/20240717153736_migrate_resources37.exs @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.TestRepo.Migrations.MigrateResources37 do @moduledoc """ Updates resources based on their most recent snapshots. diff --git a/priv/test_repo/migrations/20240727145758_user_invites.exs b/priv/test_repo/migrations/20240727145758_user_invites.exs index abfce2fb..c054a440 100644 --- a/priv/test_repo/migrations/20240727145758_user_invites.exs +++ b/priv/test_repo/migrations/20240727145758_user_invites.exs @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.TestRepo.Migrations.UserInvites do @moduledoc """ Updates resources based on their most recent snapshots. diff --git a/priv/test_repo/migrations/20240906170759_migrate_resources38.exs b/priv/test_repo/migrations/20240906170759_migrate_resources38.exs index f1211140..78637f88 100644 --- a/priv/test_repo/migrations/20240906170759_migrate_resources38.exs +++ b/priv/test_repo/migrations/20240906170759_migrate_resources38.exs @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.TestRepo.Migrations.MigrateResources38 do @moduledoc """ Updates resources based on their most recent snapshots. diff --git a/priv/test_repo/migrations/20240910180107_migrate_resources39.exs b/priv/test_repo/migrations/20240910180107_migrate_resources39.exs index adf27660..dc7f6502 100644 --- a/priv/test_repo/migrations/20240910180107_migrate_resources39.exs +++ b/priv/test_repo/migrations/20240910180107_migrate_resources39.exs @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.TestRepo.Migrations.MigrateResources39 do @moduledoc """ Updates resources based on their most recent snapshots. diff --git a/priv/test_repo/migrations/20240911225319_install_1_extensions.exs b/priv/test_repo/migrations/20240911225319_install_1_extensions.exs index 0f2eb12b..dede4e89 100644 --- a/priv/test_repo/migrations/20240911225319_install_1_extensions.exs +++ b/priv/test_repo/migrations/20240911225319_install_1_extensions.exs @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.TestRepo.Migrations.Install1Extensions20240911225317 do @moduledoc """ Installs any extensions that are mentioned in the repo's `installed_extensions/0` callback diff --git a/priv/test_repo/migrations/20240911225320_migrate_resources40.exs b/priv/test_repo/migrations/20240911225320_migrate_resources40.exs index 1e1cd754..fd10a2f0 100644 --- a/priv/test_repo/migrations/20240911225320_migrate_resources40.exs +++ b/priv/test_repo/migrations/20240911225320_migrate_resources40.exs @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.TestRepo.Migrations.MigrateResources40 do @moduledoc """ Updates resources based on their most recent snapshots. diff --git a/priv/test_repo/migrations/20240918104740_migrate_resources41.exs b/priv/test_repo/migrations/20240918104740_migrate_resources41.exs index 118fe8fc..41ce709a 100644 --- a/priv/test_repo/migrations/20240918104740_migrate_resources41.exs +++ b/priv/test_repo/migrations/20240918104740_migrate_resources41.exs @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.TestRepo.Migrations.MigrateResources41 do @moduledoc """ Updates resources based on their most recent snapshots. diff --git a/priv/test_repo/migrations/20240929121224_migrate_resources42.exs b/priv/test_repo/migrations/20240929121224_migrate_resources42.exs index 529a2338..23a14e4a 100644 --- a/priv/test_repo/migrations/20240929121224_migrate_resources42.exs +++ b/priv/test_repo/migrations/20240929121224_migrate_resources42.exs @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.TestRepo.Migrations.MigrateResources42 do @moduledoc """ Updates resources based on their most recent snapshots. diff --git a/priv/test_repo/migrations/20240929124728_migrate_resources43.exs b/priv/test_repo/migrations/20240929124728_migrate_resources43.exs index 31e815f9..c91d401a 100644 --- a/priv/test_repo/migrations/20240929124728_migrate_resources43.exs +++ b/priv/test_repo/migrations/20240929124728_migrate_resources43.exs @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.TestRepo.Migrations.MigrateResources43 do @moduledoc """ Updates resources based on their most recent snapshots. diff --git a/priv/test_repo/migrations/20241208221219_migrate_resources44.exs b/priv/test_repo/migrations/20241208221219_migrate_resources44.exs index 3665d579..af546799 100644 --- a/priv/test_repo/migrations/20241208221219_migrate_resources44.exs +++ b/priv/test_repo/migrations/20241208221219_migrate_resources44.exs @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.TestRepo.Migrations.MigrateResources44 do @moduledoc """ Updates resources based on their most recent snapshots. diff --git a/priv/test_repo/migrations/20241217232254_migrate_resources45.exs b/priv/test_repo/migrations/20241217232254_migrate_resources45.exs index acfc2b39..94454ef2 100644 --- a/priv/test_repo/migrations/20241217232254_migrate_resources45.exs +++ b/priv/test_repo/migrations/20241217232254_migrate_resources45.exs @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.TestRepo.Migrations.MigrateResources45 do @moduledoc """ Updates resources based on their most recent snapshots. diff --git a/priv/test_repo/migrations/20250113205259_migrate_resources_extensions_1.exs b/priv/test_repo/migrations/20250113205259_migrate_resources_extensions_1.exs index e6efdcb9..68c52ef7 100644 --- a/priv/test_repo/migrations/20250113205259_migrate_resources_extensions_1.exs +++ b/priv/test_repo/migrations/20250113205259_migrate_resources_extensions_1.exs @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.TestRepo.Migrations.MigrateResourcesExtensions1 do @moduledoc """ Installs any extensions that are mentioned in the repo's `installed_extensions/0` callback diff --git a/priv/test_repo/migrations/20250122190558_migrate_resources46.exs b/priv/test_repo/migrations/20250122190558_migrate_resources46.exs index 9f7eec04..c9cfed58 100644 --- a/priv/test_repo/migrations/20250122190558_migrate_resources46.exs +++ b/priv/test_repo/migrations/20250122190558_migrate_resources46.exs @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.TestRepo.Migrations.MigrateResources46 do @moduledoc """ Updates resources based on their most recent snapshots. diff --git a/priv/test_repo/migrations/20250123161002_migrate_resources47.exs b/priv/test_repo/migrations/20250123161002_migrate_resources47.exs index 59036b61..32e5ff54 100644 --- a/priv/test_repo/migrations/20250123161002_migrate_resources47.exs +++ b/priv/test_repo/migrations/20250123161002_migrate_resources47.exs @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.TestRepo.Migrations.MigrateResources47 do @moduledoc """ Updates resources based on their most recent snapshots. diff --git a/priv/test_repo/migrations/20250123164209_migrate_resources48.exs b/priv/test_repo/migrations/20250123164209_migrate_resources48.exs index 99bc4982..b07394fb 100644 --- a/priv/test_repo/migrations/20250123164209_migrate_resources48.exs +++ b/priv/test_repo/migrations/20250123164209_migrate_resources48.exs @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.TestRepo.Migrations.MigrateResources48 do @moduledoc """ Updates resources based on their most recent snapshots. diff --git a/priv/test_repo/migrations/20250210191116_migrate_resources49.exs b/priv/test_repo/migrations/20250210191116_migrate_resources49.exs index 622dddc6..f147420b 100644 --- a/priv/test_repo/migrations/20250210191116_migrate_resources49.exs +++ b/priv/test_repo/migrations/20250210191116_migrate_resources49.exs @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.TestRepo.Migrations.MigrateResources49 do @moduledoc """ Updates resources based on their most recent snapshots. diff --git a/priv/test_repo/migrations/20250217054207_migrate_resources50.exs b/priv/test_repo/migrations/20250217054207_migrate_resources50.exs index 58a69c80..1ea35a4a 100644 --- a/priv/test_repo/migrations/20250217054207_migrate_resources50.exs +++ b/priv/test_repo/migrations/20250217054207_migrate_resources50.exs @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.TestRepo.Migrations.MigrateResources50 do @moduledoc """ Updates resources based on their most recent snapshots. diff --git a/priv/test_repo/migrations/20250313112823_migrate_resources51.exs b/priv/test_repo/migrations/20250313112823_migrate_resources51.exs index fe51caf5..37609641 100644 --- a/priv/test_repo/migrations/20250313112823_migrate_resources51.exs +++ b/priv/test_repo/migrations/20250313112823_migrate_resources51.exs @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.TestRepo.Migrations.MigrateResources51 do @moduledoc """ Updates resources based on their most recent snapshots. diff --git a/priv/test_repo/migrations/20250320225052_add_csv_resource.exs b/priv/test_repo/migrations/20250320225052_add_csv_resource.exs index b02499d1..11159d77 100644 --- a/priv/test_repo/migrations/20250320225052_add_csv_resource.exs +++ b/priv/test_repo/migrations/20250320225052_add_csv_resource.exs @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.TestRepo.Migrations.AddCsvResource do @moduledoc """ Updates resources based on their most recent snapshots. diff --git a/priv/test_repo/migrations/20250321142835_migrate_resources52.exs b/priv/test_repo/migrations/20250321142835_migrate_resources52.exs index a347e279..68ee928c 100644 --- a/priv/test_repo/migrations/20250321142835_migrate_resources52.exs +++ b/priv/test_repo/migrations/20250321142835_migrate_resources52.exs @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.TestRepo.Migrations.MigrateResources52 do @moduledoc """ Updates resources based on their most recent snapshots. diff --git a/priv/test_repo/migrations/20250413141328_add_punchlines_and_standup_clubs.exs b/priv/test_repo/migrations/20250413141328_add_punchlines_and_standup_clubs.exs index 1e565f40..ff4a368c 100644 --- a/priv/test_repo/migrations/20250413141328_add_punchlines_and_standup_clubs.exs +++ b/priv/test_repo/migrations/20250413141328_add_punchlines_and_standup_clubs.exs @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.TestRepo.Migrations.AddPunchlinesAndStandupClubs do @moduledoc """ Updates resources based on their most recent snapshots. diff --git a/priv/test_repo/migrations/20250519103535_migrate_resources53.exs b/priv/test_repo/migrations/20250519103535_migrate_resources53.exs index 6059ae3e..cabe0ee7 100644 --- a/priv/test_repo/migrations/20250519103535_migrate_resources53.exs +++ b/priv/test_repo/migrations/20250519103535_migrate_resources53.exs @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.TestRepo.Migrations.MigrateResources53 do @moduledoc """ Updates resources based on their most recent snapshots. diff --git a/priv/test_repo/migrations/20250520130634_migrate_resources54.exs b/priv/test_repo/migrations/20250520130634_migrate_resources54.exs index 9d8a51cb..063d79b9 100644 --- a/priv/test_repo/migrations/20250520130634_migrate_resources54.exs +++ b/priv/test_repo/migrations/20250520130634_migrate_resources54.exs @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.TestRepo.Migrations.MigrateResources54 do @moduledoc """ Updates resources based on their most recent snapshots. diff --git a/priv/test_repo/migrations/20250521105654_add_model_tuple_to_post.exs b/priv/test_repo/migrations/20250521105654_add_model_tuple_to_post.exs index bde744b0..734de6d5 100644 --- a/priv/test_repo/migrations/20250521105654_add_model_tuple_to_post.exs +++ b/priv/test_repo/migrations/20250521105654_add_model_tuple_to_post.exs @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.TestRepo.Migrations.AddModelTupleToPost do @moduledoc """ Updates resources based on their most recent snapshots. diff --git a/priv/test_repo/migrations/20250605230457_create_record_temp_entities_table.exs b/priv/test_repo/migrations/20250605230457_create_record_temp_entities_table.exs index fe910c8c..90c3fcba 100644 --- a/priv/test_repo/migrations/20250605230457_create_record_temp_entities_table.exs +++ b/priv/test_repo/migrations/20250605230457_create_record_temp_entities_table.exs @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.TestRepo.Migrations.CreateRecordTempEntitiesTable do @moduledoc """ Updates resources based on their most recent snapshots. diff --git a/priv/test_repo/migrations/20250612113920_migrate_resources55.exs b/priv/test_repo/migrations/20250612113920_migrate_resources55.exs index 082dad95..b91c4fa9 100644 --- a/priv/test_repo/migrations/20250612113920_migrate_resources55.exs +++ b/priv/test_repo/migrations/20250612113920_migrate_resources55.exs @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.TestRepo.Migrations.MigrateResources55 do @moduledoc """ Updates resources based on their most recent snapshots. diff --git a/priv/test_repo/migrations/20250618011917_migrate_resources56.exs b/priv/test_repo/migrations/20250618011917_migrate_resources56.exs index 641aa008..97d68971 100644 --- a/priv/test_repo/migrations/20250618011917_migrate_resources56.exs +++ b/priv/test_repo/migrations/20250618011917_migrate_resources56.exs @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.TestRepo.Migrations.MigrateResources56 do @moduledoc """ Updates resources based on their most recent snapshots. diff --git a/priv/test_repo/migrations/20250714225304_add_complex_calculations_folder_and_items.exs b/priv/test_repo/migrations/20250714225304_add_complex_calculations_folder_and_items.exs index 88d73d15..fdcd91e4 100644 --- a/priv/test_repo/migrations/20250714225304_add_complex_calculations_folder_and_items.exs +++ b/priv/test_repo/migrations/20250714225304_add_complex_calculations_folder_and_items.exs @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.TestRepo.Migrations.AddComplexCalculationsFolderAndItems do @moduledoc """ Updates resources based on their most recent snapshots. diff --git a/priv/test_repo/migrations/20250731124648_migrate_resources57.exs b/priv/test_repo/migrations/20250731124648_migrate_resources57.exs index 3493fd6b..3fea4408 100644 --- a/priv/test_repo/migrations/20250731124648_migrate_resources57.exs +++ b/priv/test_repo/migrations/20250731124648_migrate_resources57.exs @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.TestRepo.Migrations.MigrateResources57 do @moduledoc """ Updates resources based on their most recent snapshots. diff --git a/priv/test_repo/migrations/20250810102512_migrate_resources58.exs b/priv/test_repo/migrations/20250810102512_migrate_resources58.exs index 484e4dc0..de4bbd5a 100644 --- a/priv/test_repo/migrations/20250810102512_migrate_resources58.exs +++ b/priv/test_repo/migrations/20250810102512_migrate_resources58.exs @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.TestRepo.Migrations.MigrateResources58 do @moduledoc """ Updates resources based on their most recent snapshots. diff --git a/priv/test_repo/migrations/20250908073737_migrate_resources59.exs b/priv/test_repo/migrations/20250908073737_migrate_resources59.exs index a4acd79a..dee8b387 100644 --- a/priv/test_repo/migrations/20250908073737_migrate_resources59.exs +++ b/priv/test_repo/migrations/20250908073737_migrate_resources59.exs @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.TestRepo.Migrations.MigrateResources59 do @moduledoc """ Updates resources based on their most recent snapshots. diff --git a/priv/test_repo/migrations/20250908093505_migrate_resources60.exs b/priv/test_repo/migrations/20250908093505_migrate_resources60.exs index 404906e5..d3747224 100644 --- a/priv/test_repo/migrations/20250908093505_migrate_resources60.exs +++ b/priv/test_repo/migrations/20250908093505_migrate_resources60.exs @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.TestRepo.Migrations.MigrateResources60 do @moduledoc """ Updates resources based on their most recent snapshots. diff --git a/priv/test_repo/migrations/20250908212414_migrate_resources61.exs b/priv/test_repo/migrations/20250908212414_migrate_resources61.exs index 303a4e53..2bd3d6bf 100644 --- a/priv/test_repo/migrations/20250908212414_migrate_resources61.exs +++ b/priv/test_repo/migrations/20250908212414_migrate_resources61.exs @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.TestRepo.Migrations.MigrateResources61 do @moduledoc """ Updates resources based on their most recent snapshots. diff --git a/priv/test_repo/migrations/20251002180954_migrate_resources62.exs b/priv/test_repo/migrations/20251002180954_migrate_resources62.exs index fe90b42c..8fd9c180 100644 --- a/priv/test_repo/migrations/20251002180954_migrate_resources62.exs +++ b/priv/test_repo/migrations/20251002180954_migrate_resources62.exs @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.TestRepo.Migrations.MigrateResources62 do @moduledoc """ Updates resources based on their most recent snapshots. diff --git a/priv/test_repo/tenant_migrations/20220805191441_migrate_resources1.exs b/priv/test_repo/tenant_migrations/20220805191441_migrate_resources1.exs index 0ce1caf3..5a5bd69b 100644 --- a/priv/test_repo/tenant_migrations/20220805191441_migrate_resources1.exs +++ b/priv/test_repo/tenant_migrations/20220805191441_migrate_resources1.exs @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.TestRepo.TenantMigrations.MigrateResources1 do @moduledoc """ Updates resources based on their most recent snapshots. diff --git a/priv/test_repo/tenant_migrations/20240327211149_migrate_resources2.exs b/priv/test_repo/tenant_migrations/20240327211149_migrate_resources2.exs index 0e4da87a..56751e6c 100644 --- a/priv/test_repo/tenant_migrations/20240327211149_migrate_resources2.exs +++ b/priv/test_repo/tenant_migrations/20240327211149_migrate_resources2.exs @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.TestRepo.TenantMigrations.MigrateResources2 do @moduledoc """ Updates resources based on their most recent snapshots. diff --git a/priv/test_repo/tenant_migrations/20240610162043_migrate_resources3.exs b/priv/test_repo/tenant_migrations/20240610162043_migrate_resources3.exs index dc378342..8c913034 100644 --- a/priv/test_repo/tenant_migrations/20240610162043_migrate_resources3.exs +++ b/priv/test_repo/tenant_migrations/20240610162043_migrate_resources3.exs @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.TestRepo.TenantMigrations.MigrateResources3 do @moduledoc """ Updates resources based on their most recent snapshots. diff --git a/priv/test_repo/tenant_migrations/20250122203454_migrate_resources4.exs b/priv/test_repo/tenant_migrations/20250122203454_migrate_resources4.exs index 36cbc1d1..ab537413 100644 --- a/priv/test_repo/tenant_migrations/20250122203454_migrate_resources4.exs +++ b/priv/test_repo/tenant_migrations/20250122203454_migrate_resources4.exs @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.TestRepo.TenantMigrations.MigrateResources4 do @moduledoc """ Updates resources based on their most recent snapshots. diff --git a/priv/test_repo/tenant_migrations/20250220073135_migrate_resources5.exs b/priv/test_repo/tenant_migrations/20250220073135_migrate_resources5.exs index 923ba511..2a52a954 100644 --- a/priv/test_repo/tenant_migrations/20250220073135_migrate_resources5.exs +++ b/priv/test_repo/tenant_migrations/20250220073135_migrate_resources5.exs @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.TestRepo.TenantMigrations.MigrateResources5 do @moduledoc """ Updates resources based on their most recent snapshots. diff --git a/priv/test_repo/tenant_migrations/20250220073141_migrate_resources6.exs b/priv/test_repo/tenant_migrations/20250220073141_migrate_resources6.exs index f5018509..18a7fdfd 100644 --- a/priv/test_repo/tenant_migrations/20250220073141_migrate_resources6.exs +++ b/priv/test_repo/tenant_migrations/20250220073141_migrate_resources6.exs @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.TestRepo.TenantMigrations.MigrateResources6 do @moduledoc """ Updates resources based on their most recent snapshots. diff --git a/priv/test_repo/tenant_migrations/20251001120813_migrate_resources7.exs b/priv/test_repo/tenant_migrations/20251001120813_migrate_resources7.exs index 42a6f5a3..6170f2f2 100644 --- a/priv/test_repo/tenant_migrations/20251001120813_migrate_resources7.exs +++ b/priv/test_repo/tenant_migrations/20251001120813_migrate_resources7.exs @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.TestRepo.TenantMigrations.MigrateResources7 do @moduledoc """ Updates resources based on their most recent snapshots. diff --git a/test/aggregate_test.exs b/test/aggregate_test.exs index 4803ec5c..ff51bf26 100644 --- a/test/aggregate_test.exs +++ b/test/aggregate_test.exs @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshSql.AggregateTest do use AshPostgres.RepoCase, async: false import ExUnit.CaptureIO diff --git a/test/ash_postgres_test.exs b/test/ash_postgres_test.exs index a3318b57..41c46e31 100644 --- a/test/ash_postgres_test.exs +++ b/test/ash_postgres_test.exs @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgresTest do use AshPostgres.RepoCase, async: false import ExUnit.CaptureLog diff --git a/test/atomics_test.exs b/test/atomics_test.exs index 2439ab9d..b9443acf 100644 --- a/test/atomics_test.exs +++ b/test/atomics_test.exs @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.AtomicsTest do alias AshPostgres.Test.Author alias AshPostgres.Test.Comment diff --git a/test/bulk_create_test.exs b/test/bulk_create_test.exs index d6fd8c17..e48d0238 100644 --- a/test/bulk_create_test.exs +++ b/test/bulk_create_test.exs @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.BulkCreateTest do use AshPostgres.RepoCase, async: false alias AshPostgres.Test.{Post, Record} diff --git a/test/bulk_destroy_test.exs b/test/bulk_destroy_test.exs index ff159a8f..24cf2395 100644 --- a/test/bulk_destroy_test.exs +++ b/test/bulk_destroy_test.exs @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.BulkDestroyTest do use AshPostgres.RepoCase, async: false alias AshPostgres.Test.Permalink diff --git a/test/bulk_update_test.exs b/test/bulk_update_test.exs index 092f964d..38ce2f45 100644 --- a/test/bulk_update_test.exs +++ b/test/bulk_update_test.exs @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.BulkUpdateTest do use AshPostgres.RepoCase, async: false alias AshPostgres.Test.{CSV, Post, Record} diff --git a/test/calculation_test.exs b/test/calculation_test.exs index cf539f18..38e4cf5b 100644 --- a/test/calculation_test.exs +++ b/test/calculation_test.exs @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.CalculationTest do alias AshPostgres.Test.RecordTempEntity use AshPostgres.RepoCase, async: false diff --git a/test/cascade_destroy_test.exs b/test/cascade_destroy_test.exs index a407ea35..062e0378 100644 --- a/test/cascade_destroy_test.exs +++ b/test/cascade_destroy_test.exs @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgresTest.CascadeDestroyTest do use AshPostgres.RepoCase, async: true diff --git a/test/combination_test.exs b/test/combination_test.exs index 5faaa020..fdb55d35 100644 --- a/test/combination_test.exs +++ b/test/combination_test.exs @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.CombinationTest do use AshPostgres.RepoCase, async: false alias AshPostgres.Test.Post diff --git a/test/complex_calculations_test.exs b/test/complex_calculations_test.exs index 5617a6d1..815071f7 100644 --- a/test/complex_calculations_test.exs +++ b/test/complex_calculations_test.exs @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.Test.ComplexCalculationsTest do use AshPostgres.RepoCase, async: false diff --git a/test/composite_type_test.exs b/test/composite_type_test.exs index b1a3990c..7e73e198 100644 --- a/test/composite_type_test.exs +++ b/test/composite_type_test.exs @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.Test.CompositeTypeTest do use AshPostgres.RepoCase alias AshPostgres.Test.Post diff --git a/test/constraint_test.exs b/test/constraint_test.exs index b2ec9fb8..7c63f3c5 100644 --- a/test/constraint_test.exs +++ b/test/constraint_test.exs @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.ConstraintTest do @moduledoc false use AshPostgres.RepoCase, async: false diff --git a/test/create_test.exs b/test/create_test.exs index 84607880..92effd16 100644 --- a/test/create_test.exs +++ b/test/create_test.exs @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.CreateTest do use AshPostgres.RepoCase, async: false alias AshPostgres.Test.Post diff --git a/test/custom_expression_test.exs b/test/custom_expression_test.exs index e88737ad..7f204eef 100644 --- a/test/custom_expression_test.exs +++ b/test/custom_expression_test.exs @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.Test.CustomExpressionTest do use AshPostgres.RepoCase, async: false diff --git a/test/custom_index_test.exs b/test/custom_index_test.exs index 1b021813..9d02b655 100644 --- a/test/custom_index_test.exs +++ b/test/custom_index_test.exs @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.Test.CustomIndexTest do use AshPostgres.RepoCase, async: false alias AshPostgres.Test.Post diff --git a/test/cve/empty_atomic_non_bulk_actions_policy_bypass_test.exs b/test/cve/empty_atomic_non_bulk_actions_policy_bypass_test.exs index 8b204f25..02d702f5 100644 --- a/test/cve/empty_atomic_non_bulk_actions_policy_bypass_test.exs +++ b/test/cve/empty_atomic_non_bulk_actions_policy_bypass_test.exs @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.EmptyAtomicNonBulkActionsPolicyBypassTest do @moduledoc """ This is test verifies the fix for the following CVE: diff --git a/test/destroy_test.exs b/test/destroy_test.exs index 974f2cb3..208b2038 100644 --- a/test/destroy_test.exs +++ b/test/destroy_test.exs @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.DestroyTest do use AshPostgres.RepoCase, async: false alias AshPostgres.Test.Post diff --git a/test/dev_migrations_test.exs b/test/dev_migrations_test.exs index fdaeeff9..64cbb7c1 100644 --- a/test/dev_migrations_test.exs +++ b/test/dev_migrations_test.exs @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.DevMigrationsTest do use AshPostgres.RepoCase, async: false @moduletag :migration diff --git a/test/distinct_test.exs b/test/distinct_test.exs index 284ed5b5..a616cac8 100644 --- a/test/distinct_test.exs +++ b/test/distinct_test.exs @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.DistinctTest do @moduledoc false use AshPostgres.RepoCase, async: false diff --git a/test/ecto_compatibility_test.exs b/test/ecto_compatibility_test.exs index 3b3555ec..3670d021 100644 --- a/test/ecto_compatibility_test.exs +++ b/test/ecto_compatibility_test.exs @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.EctoCompatibilityTest do use AshPostgres.RepoCase, async: false require Ash.Query diff --git a/test/embeddable_resource_test.exs b/test/embeddable_resource_test.exs index 4edb0903..d30c11c3 100644 --- a/test/embeddable_resource_test.exs +++ b/test/embeddable_resource_test.exs @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.EmbeddableResourceTest do @moduledoc false use AshPostgres.RepoCase, async: false diff --git a/test/enum_test.exs b/test/enum_test.exs index 537944c4..0dea90a8 100644 --- a/test/enum_test.exs +++ b/test/enum_test.exs @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.EnumTest do @moduledoc false use AshPostgres.RepoCase, async: false diff --git a/test/error_expr_test.exs b/test/error_expr_test.exs index d73577ad..98719104 100644 --- a/test/error_expr_test.exs +++ b/test/error_expr_test.exs @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.ErrorExprTest do use AshPostgres.RepoCase, async: false alias AshPostgres.Test.Post diff --git a/test/filter_child_relationship_by_parent_relationship_test.exs b/test/filter_child_relationship_by_parent_relationship_test.exs index fb2f4e52..63a50eef 100644 --- a/test/filter_child_relationship_by_parent_relationship_test.exs +++ b/test/filter_child_relationship_by_parent_relationship_test.exs @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.Test.Support.Relationships.FilterChileRelationshipByParentRelationshipTest do use AshPostgres.RepoCase, async: false alias AshPostgres.Test.{Comment, Post} diff --git a/test/filter_field_policy_test.exs b/test/filter_field_policy_test.exs index a69f2429..6778e70b 100644 --- a/test/filter_field_policy_test.exs +++ b/test/filter_field_policy_test.exs @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule FilterFieldPolicyTest do use AshPostgres.RepoCase, async: false diff --git a/test/filter_test.exs b/test/filter_test.exs index d0332301..0172fb81 100644 --- a/test/filter_test.exs +++ b/test/filter_test.exs @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.FilterTest do use AshPostgres.RepoCase, async: false diff --git a/test/load_test.exs b/test/load_test.exs index 63b142cd..fa9c8aba 100644 --- a/test/load_test.exs +++ b/test/load_test.exs @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.Test.LoadTest do use AshPostgres.RepoCase, async: false diff --git a/test/lock_test.exs b/test/lock_test.exs index f36c8ed2..01122f50 100644 --- a/test/lock_test.exs +++ b/test/lock_test.exs @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.Test.LockTest do use AshPostgres.RepoCase, async: false alias AshPostgres.Test.Post diff --git a/test/ltree_test.exs b/test/ltree_test.exs index cbd54ab1..33b3c1ba 100644 --- a/test/ltree_test.exs +++ b/test/ltree_test.exs @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.LtreeTest do use AshPostgres.RepoCase, async: true use ExUnitProperties diff --git a/test/manual_relationships_test.exs b/test/manual_relationships_test.exs index c1921dde..3f4af170 100644 --- a/test/manual_relationships_test.exs +++ b/test/manual_relationships_test.exs @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.Test.ManualRelationshipsTest do use AshPostgres.RepoCase, async: false alias AshPostgres.Test.{Comment, Post} diff --git a/test/manual_update_test.exs b/test/manual_update_test.exs index e5a286cf..74a6ec35 100644 --- a/test/manual_update_test.exs +++ b/test/manual_update_test.exs @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.ManualUpdateTest do use AshPostgres.RepoCase, async: true diff --git a/test/many_to_many_expr_test.exs b/test/many_to_many_expr_test.exs index a19fe509..942168fc 100644 --- a/test/many_to_many_expr_test.exs +++ b/test/many_to_many_expr_test.exs @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.ManyToManyExprTest do use AshPostgres.RepoCase, async: false diff --git a/test/migration_generator_test.exs b/test/migration_generator_test.exs index a12a09a0..41b16774 100644 --- a/test/migration_generator_test.exs +++ b/test/migration_generator_test.exs @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.MigrationGeneratorTest do use AshPostgres.RepoCase, async: false @moduletag :migration diff --git a/test/mix/tasks/ash_postgres.install_test.exs b/test/mix/tasks/ash_postgres.install_test.exs index e90b69ee..e8ac1154 100644 --- a/test/mix/tasks/ash_postgres.install_test.exs +++ b/test/mix/tasks/ash_postgres.install_test.exs @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule Mix.Tasks.AshPostgres.InstallTest do use ExUnit.Case diff --git a/test/mix_squash_snapshots_test.exs b/test/mix_squash_snapshots_test.exs index dcdce819..352430ae 100644 --- a/test/mix_squash_snapshots_test.exs +++ b/test/mix_squash_snapshots_test.exs @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.MixSquashSnapshotsTest do use AshPostgres.RepoCase, async: false @moduletag :migration diff --git a/test/multi_domain_calculations_test.exs b/test/multi_domain_calculations_test.exs index 8cc9bc55..54652f63 100644 --- a/test/multi_domain_calculations_test.exs +++ b/test/multi_domain_calculations_test.exs @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.Test.MultiDomainCalculationsTest do use AshPostgres.RepoCase, async: false diff --git a/test/multitenancy_test.exs b/test/multitenancy_test.exs index 85a97cbe..3e17c1ad 100644 --- a/test/multitenancy_test.exs +++ b/test/multitenancy_test.exs @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.Test.MultitenancyTest do use AshPostgres.RepoCase, async: false diff --git a/test/parent_filter_test.exs b/test/parent_filter_test.exs index b7f8f8dc..42f8326e 100644 --- a/test/parent_filter_test.exs +++ b/test/parent_filter_test.exs @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.Test.ParentFilterTest do use AshPostgres.RepoCase, async: false diff --git a/test/parent_sort_test.exs b/test/parent_sort_test.exs index 423d6634..7d472f2d 100644 --- a/test/parent_sort_test.exs +++ b/test/parent_sort_test.exs @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.Test.ParentSortTest do use AshPostgres.RepoCase, async: false diff --git a/test/polymorphism_test.exs b/test/polymorphism_test.exs index 4612a3c8..ecd8dc9d 100644 --- a/test/polymorphism_test.exs +++ b/test/polymorphism_test.exs @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.PolymorphismTest do use AshPostgres.RepoCase, async: false alias AshPostgres.Test.{Post, Rating} diff --git a/test/primary_key_test.exs b/test/primary_key_test.exs index af12e799..8812bc0e 100644 --- a/test/primary_key_test.exs +++ b/test/primary_key_test.exs @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.Test.PrimaryKeyTest do @moduledoc false use AshPostgres.RepoCase, async: false diff --git a/test/references_test.exs b/test/references_test.exs index 7632c9f8..59151ba3 100644 --- a/test/references_test.exs +++ b/test/references_test.exs @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.ReferencesTest do use AshPostgres.RepoCase import ExUnit.CaptureIO diff --git a/test/rel_with_parent_filter_test.exs b/test/rel_with_parent_filter_test.exs index d8fa5161..bdcc301d 100644 --- a/test/rel_with_parent_filter_test.exs +++ b/test/rel_with_parent_filter_test.exs @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.RelWithParentFilterTest do use AshPostgres.RepoCase, async: false diff --git a/test/resource_generator_test.exs b/test/resource_generator_test.exs index 4878cf6d..4c1f916c 100644 --- a/test/resource_generator_test.exs +++ b/test/resource_generator_test.exs @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.ResourceGeenratorTests do use AshPostgres.RepoCase, async: false diff --git a/test/schema_test.exs b/test/schema_test.exs index c8be1cf8..be04d3bb 100644 --- a/test/schema_test.exs +++ b/test/schema_test.exs @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.SchemaTest do @moduledoc false use AshPostgres.RepoCase, async: false diff --git a/test/select_test.exs b/test/select_test.exs index 219fdc77..7c440b10 100644 --- a/test/select_test.exs +++ b/test/select_test.exs @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.SelectTest do @moduledoc false use AshPostgres.RepoCase, async: false diff --git a/test/sort_test.exs b/test/sort_test.exs index e7d949da..c1afc99a 100644 --- a/test/sort_test.exs +++ b/test/sort_test.exs @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.SortTest do @moduledoc false use AshPostgres.RepoCase, async: false diff --git a/test/storage_types_test.exs b/test/storage_types_test.exs index ca433860..efdb0195 100644 --- a/test/storage_types_test.exs +++ b/test/storage_types_test.exs @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.StorageTypesTest do use AshPostgres.RepoCase, async: false diff --git a/test/subquery_test.exs b/test/subquery_test.exs index 1a9e69dd..9795730b 100644 --- a/test/subquery_test.exs +++ b/test/subquery_test.exs @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.SubqueryTest do use AshPostgres.RepoCase, async: false diff --git a/test/support/complex_calculations/domain.ex b/test/support/complex_calculations/domain.ex index 15a306ef..6356daa3 100644 --- a/test/support/complex_calculations/domain.ex +++ b/test/support/complex_calculations/domain.ex @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.Test.ComplexCalculations.Domain do @moduledoc false use Ash.Domain diff --git a/test/support/complex_calculations/resources/certification.ex b/test/support/complex_calculations/resources/certification.ex index 6310d1c7..317a5dc1 100644 --- a/test/support/complex_calculations/resources/certification.ex +++ b/test/support/complex_calculations/resources/certification.ex @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.Test.ComplexCalculations.Certification do @moduledoc false use Ash.Resource, diff --git a/test/support/complex_calculations/resources/channel.ex b/test/support/complex_calculations/resources/channel.ex index eed91879..af99ed29 100644 --- a/test/support/complex_calculations/resources/channel.ex +++ b/test/support/complex_calculations/resources/channel.ex @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.Test.ComplexCalculations.Channel do @moduledoc false use Ash.Resource, diff --git a/test/support/complex_calculations/resources/channel_member.ex b/test/support/complex_calculations/resources/channel_member.ex index c9d99997..7feb3c9d 100644 --- a/test/support/complex_calculations/resources/channel_member.ex +++ b/test/support/complex_calculations/resources/channel_member.ex @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.Test.ComplexCalculations.ChannelMember do @moduledoc false use Ash.Resource, diff --git a/test/support/complex_calculations/resources/dm_channel.ex b/test/support/complex_calculations/resources/dm_channel.ex index ed3a6397..2113a3d5 100644 --- a/test/support/complex_calculations/resources/dm_channel.ex +++ b/test/support/complex_calculations/resources/dm_channel.ex @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.Test.ComplexCalculations.DMChannel do @moduledoc false use Ash.Resource, diff --git a/test/support/complex_calculations/resources/documentation.ex b/test/support/complex_calculations/resources/documentation.ex index 405c9dae..88a3b7df 100644 --- a/test/support/complex_calculations/resources/documentation.ex +++ b/test/support/complex_calculations/resources/documentation.ex @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.Test.ComplexCalculations.Documentation do @moduledoc false use Ash.Resource, diff --git a/test/support/complex_calculations/resources/folder.ex b/test/support/complex_calculations/resources/folder.ex index d4b31e38..c0faefe6 100644 --- a/test/support/complex_calculations/resources/folder.ex +++ b/test/support/complex_calculations/resources/folder.ex @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.Test.Support.ComplexCalculations.Folder do @moduledoc """ A tree structure using the ltree type. diff --git a/test/support/complex_calculations/resources/folder_item.ex b/test/support/complex_calculations/resources/folder_item.ex index ac115aef..7404970e 100644 --- a/test/support/complex_calculations/resources/folder_item.ex +++ b/test/support/complex_calculations/resources/folder_item.ex @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.Test.Support.ComplexCalculations.FolderItem do @moduledoc false use Ash.Resource, diff --git a/test/support/complex_calculations/resources/skill.ex b/test/support/complex_calculations/resources/skill.ex index 6c81ceda..44e8dfff 100644 --- a/test/support/complex_calculations/resources/skill.ex +++ b/test/support/complex_calculations/resources/skill.ex @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.Test.ComplexCalculations.Skill do @moduledoc false use Ash.Resource, diff --git a/test/support/concat.ex b/test/support/concat.ex index 353bbfa4..50b34373 100644 --- a/test/support/concat.ex +++ b/test/support/concat.ex @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.Test.Concat do @moduledoc false use Ash.Resource.Calculation diff --git a/test/support/dev_test_repo.ex b/test/support/dev_test_repo.ex index 2b1fe929..c69abe43 100644 --- a/test/support/dev_test_repo.ex +++ b/test/support/dev_test_repo.ex @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.DevTestRepo do @moduledoc false use AshPostgres.Repo, diff --git a/test/support/domain.ex b/test/support/domain.ex index ec992cbe..ecd82d96 100644 --- a/test/support/domain.ex +++ b/test/support/domain.ex @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.Test.Domain do @moduledoc false use Ash.Domain diff --git a/test/support/multi_domain_calculations/domain_one.ex b/test/support/multi_domain_calculations/domain_one.ex index ff4e072f..b5e091f4 100644 --- a/test/support/multi_domain_calculations/domain_one.ex +++ b/test/support/multi_domain_calculations/domain_one.ex @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.Test.MultiDomainCalculations.DomainOne do @moduledoc false use Ash.Domain diff --git a/test/support/multi_domain_calculations/domain_one/item.ex b/test/support/multi_domain_calculations/domain_one/item.ex index 36090798..fa07ac9a 100644 --- a/test/support/multi_domain_calculations/domain_one/item.ex +++ b/test/support/multi_domain_calculations/domain_one/item.ex @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.Test.MultiDomainCalculations.DomainOne.Item do @moduledoc false diff --git a/test/support/multi_domain_calculations/domain_three.ex b/test/support/multi_domain_calculations/domain_three.ex index 95eda02d..a452e013 100644 --- a/test/support/multi_domain_calculations/domain_three.ex +++ b/test/support/multi_domain_calculations/domain_three.ex @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.Test.MultiDomainCalculations.DomainThree do @moduledoc false use Ash.Domain diff --git a/test/support/multi_domain_calculations/domain_three/relationship_item.ex b/test/support/multi_domain_calculations/domain_three/relationship_item.ex index b90b93a7..9c15eb0c 100644 --- a/test/support/multi_domain_calculations/domain_three/relationship_item.ex +++ b/test/support/multi_domain_calculations/domain_three/relationship_item.ex @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.Test.MultiDomainCalculations.DomainThree.RelationshipItem do @moduledoc false diff --git a/test/support/multi_domain_calculations/domain_two.ex b/test/support/multi_domain_calculations/domain_two.ex index f9ccde38..715960fb 100644 --- a/test/support/multi_domain_calculations/domain_two.ex +++ b/test/support/multi_domain_calculations/domain_two.ex @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.Test.MultiDomainCalculations.DomainTwo do @moduledoc false use Ash.Domain diff --git a/test/support/multi_domain_calculations/domain_two/other_item.ex b/test/support/multi_domain_calculations/domain_two/other_item.ex index 1524b47d..b7e65fd7 100644 --- a/test/support/multi_domain_calculations/domain_two/other_item.ex +++ b/test/support/multi_domain_calculations/domain_two/other_item.ex @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.Test.MultiDomainCalculations.DomainTwo.OtherItem do @moduledoc false diff --git a/test/support/multi_domain_calculations/domain_two/sub_item.ex b/test/support/multi_domain_calculations/domain_two/sub_item.ex index c9f8b491..76550194 100644 --- a/test/support/multi_domain_calculations/domain_two/sub_item.ex +++ b/test/support/multi_domain_calculations/domain_two/sub_item.ex @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.Test.MultiDomainCalculations.DomainTwo.SubItem do @moduledoc false diff --git a/test/support/multitenancy/domain.ex b/test/support/multitenancy/domain.ex index 6c1db197..1ee5e90b 100644 --- a/test/support/multitenancy/domain.ex +++ b/test/support/multitenancy/domain.ex @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.MultitenancyTest.Domain do @moduledoc false use Ash.Domain diff --git a/test/support/multitenancy/resources/composite_key_post.ex b/test/support/multitenancy/resources/composite_key_post.ex index 84f7881a..b7856998 100644 --- a/test/support/multitenancy/resources/composite_key_post.ex +++ b/test/support/multitenancy/resources/composite_key_post.ex @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.MultitenancyTest.CompositeKeyPost do @moduledoc false use Ash.Resource, diff --git a/test/support/multitenancy/resources/cross_tenant_post_link.ex b/test/support/multitenancy/resources/cross_tenant_post_link.ex index 0bcc7111..e79e0cf8 100644 --- a/test/support/multitenancy/resources/cross_tenant_post_link.ex +++ b/test/support/multitenancy/resources/cross_tenant_post_link.ex @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.MultitenancyTest.CrossTenantPostLink do @moduledoc false use Ash.Resource, diff --git a/test/support/multitenancy/resources/dev_migrations_org.ex b/test/support/multitenancy/resources/dev_migrations_org.ex index 6ebd3394..0cc59783 100644 --- a/test/support/multitenancy/resources/dev_migrations_org.ex +++ b/test/support/multitenancy/resources/dev_migrations_org.ex @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.MultitenancyTest.DevMigrationsOrg do @moduledoc false use Ash.Resource, diff --git a/test/support/multitenancy/resources/named_org.ex b/test/support/multitenancy/resources/named_org.ex index 537ea337..714c090d 100644 --- a/test/support/multitenancy/resources/named_org.ex +++ b/test/support/multitenancy/resources/named_org.ex @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.MultitenancyTest.NamedOrg do @moduledoc false use Ash.Resource, diff --git a/test/support/multitenancy/resources/non_multitenant_post_link.ex b/test/support/multitenancy/resources/non_multitenant_post_link.ex index 9d986bdb..8f2a990e 100644 --- a/test/support/multitenancy/resources/non_multitenant_post_link.ex +++ b/test/support/multitenancy/resources/non_multitenant_post_link.ex @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.MultitenancyTest.NonMultitenantPostLink do @moduledoc false use Ash.Resource, diff --git a/test/support/multitenancy/resources/non_multitenant_post_multitenant_link.ex b/test/support/multitenancy/resources/non_multitenant_post_multitenant_link.ex index 56dd8d26..0eb78386 100644 --- a/test/support/multitenancy/resources/non_multitenant_post_multitenant_link.ex +++ b/test/support/multitenancy/resources/non_multitenant_post_multitenant_link.ex @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.MultitenancyTest.NonMultitenantPostMultitenantLink do @moduledoc false use Ash.Resource, diff --git a/test/support/multitenancy/resources/org.ex b/test/support/multitenancy/resources/org.ex index aa68daf4..21638793 100644 --- a/test/support/multitenancy/resources/org.ex +++ b/test/support/multitenancy/resources/org.ex @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.MultitenancyTest.Org do @moduledoc false use Ash.Resource, diff --git a/test/support/multitenancy/resources/post.ex b/test/support/multitenancy/resources/post.ex index 6f9a943a..cab27827 100644 --- a/test/support/multitenancy/resources/post.ex +++ b/test/support/multitenancy/resources/post.ex @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.MultitenancyTest.Post do @moduledoc false use Ash.Resource, diff --git a/test/support/multitenancy/resources/post_link.ex b/test/support/multitenancy/resources/post_link.ex index bd22c558..dcdfdc41 100644 --- a/test/support/multitenancy/resources/post_link.ex +++ b/test/support/multitenancy/resources/post_link.ex @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.MultitenancyTest.PostLink do @moduledoc false use Ash.Resource, diff --git a/test/support/multitenancy/resources/user.ex b/test/support/multitenancy/resources/user.ex index 77149182..7406eb07 100644 --- a/test/support/multitenancy/resources/user.ex +++ b/test/support/multitenancy/resources/user.ex @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.MultitenancyTest.User do @moduledoc false use Ash.Resource, diff --git a/test/support/relationships/comments_containing_title.ex b/test/support/relationships/comments_containing_title.ex index a58a6b93..e17ee933 100644 --- a/test/support/relationships/comments_containing_title.ex +++ b/test/support/relationships/comments_containing_title.ex @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.Test.Post.CommentsContainingTitle do @moduledoc false diff --git a/test/support/repo_case.ex b/test/support/repo_case.ex index 28d9f3d2..708e2d42 100644 --- a/test/support/repo_case.ex +++ b/test/support/repo_case.ex @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.RepoCase do @moduledoc false use ExUnit.CaseTemplate diff --git a/test/support/resources/account.ex b/test/support/resources/account.ex index c771b9ce..87e6544a 100644 --- a/test/support/resources/account.ex +++ b/test/support/resources/account.ex @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.Test.Account do @moduledoc false use Ash.Resource, diff --git a/test/support/resources/author.ex b/test/support/resources/author.ex index e30f7592..097a771c 100644 --- a/test/support/resources/author.ex +++ b/test/support/resources/author.ex @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.Test.Author do @moduledoc false use Ash.Resource, diff --git a/test/support/resources/bio.ex b/test/support/resources/bio.ex index 59dd2dfb..8c0b33f0 100644 --- a/test/support/resources/bio.ex +++ b/test/support/resources/bio.ex @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.Test.Bio do @moduledoc false use Ash.Resource, data_layer: :embedded diff --git a/test/support/resources/chat.ex b/test/support/resources/chat.ex index 9a035f4c..5c04c1af 100644 --- a/test/support/resources/chat.ex +++ b/test/support/resources/chat.ex @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.Test.Chat do @moduledoc false use Ash.Resource, diff --git a/test/support/resources/co_authored_post.ex b/test/support/resources/co_authored_post.ex index 5519144b..022c9eca 100644 --- a/test/support/resources/co_authored_post.ex +++ b/test/support/resources/co_authored_post.ex @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.Test.CoAuthorPost do @moduledoc false use Ash.Resource, diff --git a/test/support/resources/comedian.ex b/test/support/resources/comedian.ex index a61f3c41..2404d56c 100644 --- a/test/support/resources/comedian.ex +++ b/test/support/resources/comedian.ex @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.Test.Comedian do @moduledoc false use Ash.Resource, diff --git a/test/support/resources/comment.ex b/test/support/resources/comment.ex index 517c42af..cbbc6abb 100644 --- a/test/support/resources/comment.ex +++ b/test/support/resources/comment.ex @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.Test.Comment do @moduledoc false use Ash.Resource, diff --git a/test/support/resources/comment_link.ex b/test/support/resources/comment_link.ex index 2654ff0f..5caab846 100644 --- a/test/support/resources/comment_link.ex +++ b/test/support/resources/comment_link.ex @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.Test.CommentLink do @moduledoc false use Ash.Resource, diff --git a/test/support/resources/content.ex b/test/support/resources/content.ex index 370d7016..8b823644 100644 --- a/test/support/resources/content.ex +++ b/test/support/resources/content.ex @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.Test.Content do @moduledoc false use Ash.Resource, diff --git a/test/support/resources/content_visibility_group.ex b/test/support/resources/content_visibility_group.ex index d618fcb4..797d7c7e 100644 --- a/test/support/resources/content_visibility_group.ex +++ b/test/support/resources/content_visibility_group.ex @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.Test.ContentVisibilityGroup do @moduledoc false use Ash.Resource, diff --git a/test/support/resources/csv.ex b/test/support/resources/csv.ex index 91894ed4..ccf5b418 100644 --- a/test/support/resources/csv.ex +++ b/test/support/resources/csv.ex @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.Test.CSVColumnMatchingEmbedded do @moduledoc false use Ash.Resource, diff --git a/test/support/resources/customer.ex b/test/support/resources/customer.ex index d5cff43e..834fcead 100644 --- a/test/support/resources/customer.ex +++ b/test/support/resources/customer.ex @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.Test.Customer do @moduledoc false use Ash.Resource, diff --git a/test/support/resources/db_point.ex b/test/support/resources/db_point.ex index 25b9ca93..cf018f4a 100644 --- a/test/support/resources/db_point.ex +++ b/test/support/resources/db_point.ex @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.Test.DbPoint do @moduledoc false use Ash.Resource, diff --git a/test/support/resources/db_string_point.ex b/test/support/resources/db_string_point.ex index 8908527b..e78c7536 100644 --- a/test/support/resources/db_string_point.ex +++ b/test/support/resources/db_string_point.ex @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.Test.DbStringPoint do @moduledoc false use Ash.Resource, diff --git a/test/support/resources/entity.ex b/test/support/resources/entity.ex index 732f760f..c693d02a 100644 --- a/test/support/resources/entity.ex +++ b/test/support/resources/entity.ex @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.Test.Entity do @moduledoc false diff --git a/test/support/resources/integer_post.ex b/test/support/resources/integer_post.ex index 13b37b4b..2237e723 100644 --- a/test/support/resources/integer_post.ex +++ b/test/support/resources/integer_post.ex @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.Test.IntegerPost do @moduledoc false use Ash.Resource, diff --git a/test/support/resources/invite.ex b/test/support/resources/invite.ex index 32406d1f..06d3ea70 100644 --- a/test/support/resources/invite.ex +++ b/test/support/resources/invite.ex @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.Test.Invite do @moduledoc false use Ash.Resource, diff --git a/test/support/resources/joke.ex b/test/support/resources/joke.ex index 7f6318f8..16414cb4 100644 --- a/test/support/resources/joke.ex +++ b/test/support/resources/joke.ex @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.Test.Joke do @moduledoc false use Ash.Resource, diff --git a/test/support/resources/manager.ex b/test/support/resources/manager.ex index 43105c21..e5b2cce9 100644 --- a/test/support/resources/manager.ex +++ b/test/support/resources/manager.ex @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.Test.Manager do @moduledoc false use Ash.Resource, diff --git a/test/support/resources/message.ex b/test/support/resources/message.ex index 25896e04..4cbc9533 100644 --- a/test/support/resources/message.ex +++ b/test/support/resources/message.ex @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.Test.Message do @moduledoc false use Ash.Resource, diff --git a/test/support/resources/note.ex b/test/support/resources/note.ex index b5880dfd..0facb927 100644 --- a/test/support/resources/note.ex +++ b/test/support/resources/note.ex @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.Test.Note do @moduledoc false use Ash.Resource, diff --git a/test/support/resources/order.ex b/test/support/resources/order.ex index 27566cb4..fead194c 100644 --- a/test/support/resources/order.ex +++ b/test/support/resources/order.ex @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.Test.Order do @moduledoc false use Ash.Resource, diff --git a/test/support/resources/organization.ex b/test/support/resources/organization.ex index 0013f909..d375a2db 100644 --- a/test/support/resources/organization.ex +++ b/test/support/resources/organization.ex @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.Test.Organization do @moduledoc false use Ash.Resource, diff --git a/test/support/resources/permalink.ex b/test/support/resources/permalink.ex index 21df7959..adca302f 100644 --- a/test/support/resources/permalink.ex +++ b/test/support/resources/permalink.ex @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.Test.Permalink do @moduledoc false use Ash.Resource, diff --git a/test/support/resources/post.ex b/test/support/resources/post.ex index 69791a38..2b85570a 100644 --- a/test/support/resources/post.ex +++ b/test/support/resources/post.ex @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule PassIfOriginalDataPresent do @moduledoc false use Ash.Policy.SimpleCheck diff --git a/test/support/resources/post_follower.ex b/test/support/resources/post_follower.ex index c00ef226..9e71b398 100644 --- a/test/support/resources/post_follower.ex +++ b/test/support/resources/post_follower.ex @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.Test.PostFollower do @moduledoc false use Ash.Resource, diff --git a/test/support/resources/post_link.ex b/test/support/resources/post_link.ex index 910486b2..bc6390c8 100644 --- a/test/support/resources/post_link.ex +++ b/test/support/resources/post_link.ex @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.Test.PostLink do @moduledoc false use Ash.Resource, diff --git a/test/support/resources/post_tag.ex b/test/support/resources/post_tag.ex index c1cb13e8..2ae47876 100644 --- a/test/support/resources/post_tag.ex +++ b/test/support/resources/post_tag.ex @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.Test.PostTag do @moduledoc false use Ash.Resource, diff --git a/test/support/resources/post_views.ex b/test/support/resources/post_views.ex index 929fbb45..c3b3aaaa 100644 --- a/test/support/resources/post_views.ex +++ b/test/support/resources/post_views.ex @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.Test.PostView do @moduledoc false use Ash.Resource, diff --git a/test/support/resources/post_with_empty_update.ex b/test/support/resources/post_with_empty_update.ex index da61629d..06693738 100644 --- a/test/support/resources/post_with_empty_update.ex +++ b/test/support/resources/post_with_empty_update.ex @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.Test.PostWithEmptyUpdate do @moduledoc false use Ash.Resource, diff --git a/test/support/resources/product.ex b/test/support/resources/product.ex index 199bbff8..fa2bbee9 100644 --- a/test/support/resources/product.ex +++ b/test/support/resources/product.ex @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.Test.Product do @moduledoc false use Ash.Resource, diff --git a/test/support/resources/profile.ex b/test/support/resources/profile.ex index 862887c4..b06bab6f 100644 --- a/test/support/resources/profile.ex +++ b/test/support/resources/profile.ex @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.Test.Profile do @moduledoc false use Ash.Resource, diff --git a/test/support/resources/punchline.ex b/test/support/resources/punchline.ex index 90e905d9..66da6063 100644 --- a/test/support/resources/punchline.ex +++ b/test/support/resources/punchline.ex @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.Test.Punchline do @moduledoc false use Ash.Resource, diff --git a/test/support/resources/rating.ex b/test/support/resources/rating.ex index 99509206..1fab32b1 100644 --- a/test/support/resources/rating.ex +++ b/test/support/resources/rating.ex @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.Test.Rating do @moduledoc false use Ash.Resource, diff --git a/test/support/resources/record.ex b/test/support/resources/record.ex index 804c981a..0045db83 100644 --- a/test/support/resources/record.ex +++ b/test/support/resources/record.ex @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.Test.Record do @moduledoc false diff --git a/test/support/resources/record_temp_entity.ex b/test/support/resources/record_temp_entity.ex index 7750a1df..ba0f73e3 100644 --- a/test/support/resources/record_temp_entity.ex +++ b/test/support/resources/record_temp_entity.ex @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.Test.RecordTempEntity do @moduledoc false diff --git a/test/support/resources/role.ex b/test/support/resources/role.ex index 5ce35a73..df3635be 100644 --- a/test/support/resources/role.ex +++ b/test/support/resources/role.ex @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.Test.Role do @moduledoc false diff --git a/test/support/resources/rsvp.ex b/test/support/resources/rsvp.ex index 965f053d..f364c333 100644 --- a/test/support/resources/rsvp.ex +++ b/test/support/resources/rsvp.ex @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.Test.RSVP do @moduledoc false use Ash.Resource, diff --git a/test/support/resources/settings.ex b/test/support/resources/settings.ex index b24b3afc..e348f847 100644 --- a/test/support/resources/settings.ex +++ b/test/support/resources/settings.ex @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.Test.Settings do @moduledoc false use Ash.Resource, data_layer: :embedded diff --git a/test/support/resources/staff_group.ex b/test/support/resources/staff_group.ex index 3902ca07..4aafeca8 100644 --- a/test/support/resources/staff_group.ex +++ b/test/support/resources/staff_group.ex @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.Test.StaffGroup do @moduledoc false use Ash.Resource, diff --git a/test/support/resources/staff_group_member.ex b/test/support/resources/staff_group_member.ex index 7624a9ce..a9ce9e97 100644 --- a/test/support/resources/staff_group_member.ex +++ b/test/support/resources/staff_group_member.ex @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.Test.StaffGroupMember do @moduledoc false use Ash.Resource, diff --git a/test/support/resources/standup_club.ex b/test/support/resources/standup_club.ex index 3dd2e075..ffa91044 100644 --- a/test/support/resources/standup_club.ex +++ b/test/support/resources/standup_club.ex @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.Test.StandupClub do @moduledoc false use Ash.Resource, diff --git a/test/support/resources/stateful_post_follwer.ex b/test/support/resources/stateful_post_follwer.ex index b6fd8dab..cb66359c 100644 --- a/test/support/resources/stateful_post_follwer.ex +++ b/test/support/resources/stateful_post_follwer.ex @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.Test.StatefulPostFollower do @moduledoc false use Ash.Resource, diff --git a/test/support/resources/subquery/access.ex b/test/support/resources/subquery/access.ex index 90a356ff..9c971486 100644 --- a/test/support/resources/subquery/access.ex +++ b/test/support/resources/subquery/access.ex @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.Test.Subquery.Access do @moduledoc false alias AshPostgres.Test.Subquery.Parent diff --git a/test/support/resources/subquery/child.ex b/test/support/resources/subquery/child.ex index cf089bd5..5a9cd6af 100644 --- a/test/support/resources/subquery/child.ex +++ b/test/support/resources/subquery/child.ex @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.Test.Subquery.Child do @moduledoc false alias AshPostgres.Test.Subquery.Through diff --git a/test/support/resources/subquery/child_domain.ex b/test/support/resources/subquery/child_domain.ex index 7e427331..ab33df34 100644 --- a/test/support/resources/subquery/child_domain.ex +++ b/test/support/resources/subquery/child_domain.ex @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.Test.Subquery.ChildDomain do @moduledoc false alias AshPostgres.Test.Subquery.Child diff --git a/test/support/resources/subquery/parent.ex b/test/support/resources/subquery/parent.ex index 9de04b9f..a72c0054 100644 --- a/test/support/resources/subquery/parent.ex +++ b/test/support/resources/subquery/parent.ex @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.Test.Subquery.Parent do @moduledoc false use Ash.Resource, diff --git a/test/support/resources/subquery/parent_domain.ex b/test/support/resources/subquery/parent_domain.ex index 9d73f6af..d2e200d3 100644 --- a/test/support/resources/subquery/parent_domain.ex +++ b/test/support/resources/subquery/parent_domain.ex @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.Test.Subquery.ParentDomain do @moduledoc false alias AshPostgres.Test.Subquery.Access diff --git a/test/support/resources/subquery/through.ex b/test/support/resources/subquery/through.ex index 7f1e96e9..3c0f4e75 100644 --- a/test/support/resources/subquery/through.ex +++ b/test/support/resources/subquery/through.ex @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.Test.Subquery.Through do @moduledoc false alias AshPostgres.Test.Subquery.Child diff --git a/test/support/resources/tag.ex b/test/support/resources/tag.ex index 20d8d5a8..66bec825 100644 --- a/test/support/resources/tag.ex +++ b/test/support/resources/tag.ex @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.Test.Tag do @moduledoc false use Ash.Resource, diff --git a/test/support/resources/temp_entity.ex b/test/support/resources/temp_entity.ex index eb29bf1c..5507836e 100644 --- a/test/support/resources/temp_entity.ex +++ b/test/support/resources/temp_entity.ex @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.Test.TempEntity do @moduledoc false diff --git a/test/support/resources/user.ex b/test/support/resources/user.ex index b07b3e7c..1009dccd 100644 --- a/test/support/resources/user.ex +++ b/test/support/resources/user.ex @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.Test.User do @moduledoc false use Ash.Resource, diff --git a/test/support/string_agg.ex b/test/support/string_agg.ex index 53a6a950..e6f92821 100644 --- a/test/support/string_agg.ex +++ b/test/support/string_agg.ex @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.Test.StringAgg do @moduledoc false use Ash.Resource.Aggregate.CustomAggregate diff --git a/test/support/test_app.ex b/test/support/test_app.ex index 94c990d6..97d98fc2 100644 --- a/test/support/test_app.ex +++ b/test/support/test_app.ex @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.TestApp do @moduledoc false def start(_type, _args) do diff --git a/test/support/test_custom_extension.ex b/test/support/test_custom_extension.ex index fba66809..bd6d26d3 100644 --- a/test/support/test_custom_extension.ex +++ b/test/support/test_custom_extension.ex @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.TestCustomExtension do @moduledoc false diff --git a/test/support/test_no_sandbox_repo.ex b/test/support/test_no_sandbox_repo.ex index fca4bf13..14ec8160 100644 --- a/test/support/test_no_sandbox_repo.ex +++ b/test/support/test_no_sandbox_repo.ex @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.TestNoSandboxRepo do @moduledoc false use AshPostgres.Repo, diff --git a/test/support/test_repo.ex b/test/support/test_repo.ex index 351c94ac..8dbc64c1 100644 --- a/test/support/test_repo.ex +++ b/test/support/test_repo.ex @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.TestRepo do @moduledoc false use AshPostgres.Repo, diff --git a/test/support/trigram_word_similarity.ex b/test/support/trigram_word_similarity.ex index 4b7d0bfb..77c267c7 100644 --- a/test/support/trigram_word_similarity.ex +++ b/test/support/trigram_word_similarity.ex @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.Expressions.TrigramWordSimilarity do @moduledoc false use Ash.CustomExpression, diff --git a/test/support/types/composite_point.ex b/test/support/types/composite_point.ex index 6b6f37dc..b82887b9 100644 --- a/test/support/types/composite_point.ex +++ b/test/support/types/composite_point.ex @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.Test.CompositePoint do @moduledoc false use Ash.Type diff --git a/test/support/types/email.ex b/test/support/types/email.ex index c14190d5..9f552b6d 100644 --- a/test/support/types/email.ex +++ b/test/support/types/email.ex @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule Test.Support.Types.Email do @moduledoc false use Ash.Type.NewType, diff --git a/test/support/types/money.ex b/test/support/types/money.ex index c1569be4..6b2d79f8 100644 --- a/test/support/types/money.ex +++ b/test/support/types/money.ex @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.Test.Money do @moduledoc false use Ash.Resource, diff --git a/test/support/types/person_detail.ex b/test/support/types/person_detail.ex index 551d17d5..3666300f 100644 --- a/test/support/types/person_detail.ex +++ b/test/support/types/person_detail.ex @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.Test.PersonDetail do @moduledoc """ A tuple type for testing Ash.Type.Tuple diff --git a/test/support/types/point.ex b/test/support/types/point.ex index ea3db339..819d0287 100644 --- a/test/support/types/point.ex +++ b/test/support/types/point.ex @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.Test.Point do @moduledoc false use Ash.Type diff --git a/test/support/types/response.ex b/test/support/types/response.ex index 51f475e0..9428ee15 100644 --- a/test/support/types/response.ex +++ b/test/support/types/response.ex @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.Test.Types.Response do @moduledoc false use Ash.Type diff --git a/test/support/types/status.ex b/test/support/types/status.ex index 2aa3e4a7..7453e955 100644 --- a/test/support/types/status.ex +++ b/test/support/types/status.ex @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.Test.Types.Status do @moduledoc false use Ash.Type.Enum, values: [:open, :closed] diff --git a/test/support/types/status_enum.ex b/test/support/types/status_enum.ex index dfd46a25..2a845ff2 100644 --- a/test/support/types/status_enum.ex +++ b/test/support/types/status_enum.ex @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.Test.Types.StatusEnum do @moduledoc false use Ash.Type.Enum, values: [:open, :closed] diff --git a/test/support/types/status_enum_no_cast.ex b/test/support/types/status_enum_no_cast.ex index ec4a5e6b..032266de 100644 --- a/test/support/types/status_enum_no_cast.ex +++ b/test/support/types/status_enum_no_cast.ex @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.Test.Types.StatusEnumNoCast do @moduledoc false use Ash.Type.Enum, values: [:open, :closed] diff --git a/test/support/types/string_point.ex b/test/support/types/string_point.ex index 0550a904..1be38e28 100644 --- a/test/support/types/string_point.ex +++ b/test/support/types/string_point.ex @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.Test.StringPoint do @moduledoc false use Ash.Type diff --git a/test/support/unrelated_aggregates/profile.ex b/test/support/unrelated_aggregates/profile.ex index 87a9fa9f..257a44e3 100644 --- a/test/support/unrelated_aggregates/profile.ex +++ b/test/support/unrelated_aggregates/profile.ex @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.Test.UnrelatedAggregatesTest.Profile do @moduledoc false use Ash.Resource, diff --git a/test/support/unrelated_aggregates/report.ex b/test/support/unrelated_aggregates/report.ex index 652df03c..025e550c 100644 --- a/test/support/unrelated_aggregates/report.ex +++ b/test/support/unrelated_aggregates/report.ex @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.Test.UnrelatedAggregatesTest.Report do @moduledoc false use Ash.Resource, diff --git a/test/support/unrelated_aggregates/secure_profile.ex b/test/support/unrelated_aggregates/secure_profile.ex index 3f50bf73..7f380da2 100644 --- a/test/support/unrelated_aggregates/secure_profile.ex +++ b/test/support/unrelated_aggregates/secure_profile.ex @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.Test.UnrelatedAggregatesTest.SecureProfile do @moduledoc false use Ash.Resource, diff --git a/test/support/unrelated_aggregates/user.ex b/test/support/unrelated_aggregates/user.ex index ce143489..22529079 100644 --- a/test/support/unrelated_aggregates/user.ex +++ b/test/support/unrelated_aggregates/user.ex @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.Test.UnrelatedAggregatesTest.User do @moduledoc false use Ash.Resource, diff --git a/test/test_helper.exs b/test/test_helper.exs index 6745f6eb..aba4a697 100644 --- a/test/test_helper.exs +++ b/test/test_helper.exs @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + ExUnit.start(capture_log: true) Logger.configure(level: :debug) diff --git a/test/transaction_test.exs b/test/transaction_test.exs index 603fe0df..a4403a16 100644 --- a/test/transaction_test.exs +++ b/test/transaction_test.exs @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.Test.TransactionTest do use AshPostgres.RepoCase, async: false alias AshPostgres.Test.Post diff --git a/test/tuple_test.exs b/test/tuple_test.exs index 1233ac28..5901f5c4 100644 --- a/test/tuple_test.exs +++ b/test/tuple_test.exs @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.Test.TupleTest do use AshPostgres.RepoCase, async: false alias AshPostgres.Test.Post diff --git a/test/type_test.exs b/test/type_test.exs index 6355fe92..2e7c3132 100644 --- a/test/type_test.exs +++ b/test/type_test.exs @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.Test.TypeTest do use AshPostgres.RepoCase, async: false alias AshPostgres.Test.Post diff --git a/test/unique_identity_test.exs b/test/unique_identity_test.exs index 47638025..618ead15 100644 --- a/test/unique_identity_test.exs +++ b/test/unique_identity_test.exs @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.Test.UniqueIdentityTest do use AshPostgres.RepoCase, async: false alias AshPostgres.Test.Organization diff --git a/test/unrelated_aggregates_test.exs b/test/unrelated_aggregates_test.exs index 0ec55535..1c4ca107 100644 --- a/test/unrelated_aggregates_test.exs +++ b/test/unrelated_aggregates_test.exs @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.Test.UnrelatedAggregatesTest do @moduledoc false use AshPostgres.RepoCase, async: false diff --git a/test/update_test.exs b/test/update_test.exs index d05f9863..22fb4af2 100644 --- a/test/update_test.exs +++ b/test/update_test.exs @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.UpdateTest do use AshPostgres.RepoCase, async: false alias AshPostgres.Test.Post diff --git a/test/upsert_test.exs b/test/upsert_test.exs index 08058701..0f3308a7 100644 --- a/test/upsert_test.exs +++ b/test/upsert_test.exs @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Zach Daniel +# +# SPDX-License-Identifier: MIT + defmodule AshPostgres.Test.UpsertTest do use AshPostgres.RepoCase, async: false alias AshPostgres.Test.Post diff --git a/usage-rules.md b/usage-rules.md index 632fc52d..84e0c138 100644 --- a/usage-rules.md +++ b/usage-rules.md @@ -1,3 +1,9 @@ + + # Rules for working with AshPostgres ## Understanding AshPostgres From efc4e38a6c1e43d713fa0ae2356fa53d1102898c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 11 Oct 2025 16:54:36 -0400 Subject: [PATCH 157/174] chore(deps): bump ash in the production-dependencies group (#636) Bumps the production-dependencies group with 1 update: [ash](https://github.com/ash-project/ash). Updates `ash` from 3.5.43 to 3.6.2 - [Release notes](https://github.com/ash-project/ash/releases) - [Changelog](https://github.com/ash-project/ash/blob/main/CHANGELOG.md) - [Commits](https://github.com/ash-project/ash/compare/v3.5.43...v3.6.2) --- updated-dependencies: - dependency-name: ash dependency-version: 3.6.2 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: production-dependencies ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- mix.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mix.lock b/mix.lock index 1827dcb4..05bd993c 100644 --- a/mix.lock +++ b/mix.lock @@ -1,5 +1,5 @@ %{ - "ash": {:hex, :ash, "3.5.43", "222f9a8ac26ad3b029f8e69306cc83091c992d858b4538af12e33a148f301cab", [:mix], [{:decimal, "~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:ecto, "~> 3.7", [hex: :ecto, repo: "hexpm", optional: false]}, {:ets, "~> 0.8", [hex: :ets, repo: "hexpm", optional: false]}, {:igniter, ">= 0.6.29 and < 1.0.0-0", [hex: :igniter, repo: "hexpm", optional: true]}, {:jason, ">= 1.0.0", [hex: :jason, repo: "hexpm", optional: false]}, {:picosat_elixir, "~> 0.2", [hex: :picosat_elixir, repo: "hexpm", optional: true]}, {:plug, ">= 0.0.0", [hex: :plug, repo: "hexpm", optional: true]}, {:reactor, "~> 0.11", [hex: :reactor, repo: "hexpm", optional: false]}, {:simple_sat, ">= 0.1.1 and < 1.0.0-0", [hex: :simple_sat, repo: "hexpm", optional: true]}, {:spark, ">= 2.3.3 and < 3.0.0-0", [hex: :spark, repo: "hexpm", optional: false]}, {:splode, ">= 0.2.6 and < 1.0.0-0", [hex: :splode, repo: "hexpm", optional: false]}, {:stream_data, "~> 1.0", [hex: :stream_data, repo: "hexpm", optional: false]}, {:telemetry, "~> 1.1", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "48b2aa274c524f5b968c563dd56aec8f9b278c529c8aa46e6fe0ca564c26cc1c"}, + "ash": {:hex, :ash, "3.6.2", "90d1c8296be777b90caabf51b99323d6618a0b92594dfab92b02bdf848ac38bf", [:mix], [{:decimal, "~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:ecto, "~> 3.7", [hex: :ecto, repo: "hexpm", optional: false]}, {:ets, "~> 0.8", [hex: :ets, repo: "hexpm", optional: false]}, {:igniter, ">= 0.6.29 and < 1.0.0-0", [hex: :igniter, repo: "hexpm", optional: true]}, {:jason, ">= 1.0.0", [hex: :jason, repo: "hexpm", optional: false]}, {:picosat_elixir, "~> 0.2", [hex: :picosat_elixir, repo: "hexpm", optional: true]}, {:plug, ">= 0.0.0", [hex: :plug, repo: "hexpm", optional: true]}, {:reactor, "~> 0.11", [hex: :reactor, repo: "hexpm", optional: false]}, {:simple_sat, ">= 0.1.1 and < 1.0.0-0", [hex: :simple_sat, repo: "hexpm", optional: true]}, {:spark, ">= 2.3.3 and < 3.0.0-0", [hex: :spark, repo: "hexpm", optional: false]}, {:splode, ">= 0.2.6 and < 1.0.0-0", [hex: :splode, repo: "hexpm", optional: false]}, {:stream_data, "~> 1.0", [hex: :stream_data, repo: "hexpm", optional: false]}, {:telemetry, "~> 1.1", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "3546b5798dd24576cc451f6e03f3d6e3bb62666c0921bfe8aae700c599d9c38d"}, "ash_sql": {:hex, :ash_sql, "0.3.2", "e2d65dac1c813cbd2569a750bf1c063109778e840052e44535ced294d7638a19", [:mix], [{:ash, ">= 3.5.43 and < 4.0.0-0", [hex: :ash, repo: "hexpm", optional: false]}, {:ecto, "~> 3.9", [hex: :ecto, repo: "hexpm", optional: false]}, {:ecto_sql, "~> 3.9", [hex: :ecto_sql, repo: "hexpm", optional: false]}], "hexpm", "1f6e5d827c0eb55fc5a07f58eb97f9bb3e6b290d83df75883f422537b98c9c68"}, "benchee": {:hex, :benchee, "1.4.0", "9f1f96a30ac80bab94faad644b39a9031d5632e517416a8ab0a6b0ac4df124ce", [:mix], [{:deep_merge, "~> 1.0", [hex: :deep_merge, repo: "hexpm", optional: false]}, {:statistex, "~> 1.0", [hex: :statistex, repo: "hexpm", optional: false]}, {:table, "~> 0.1.0", [hex: :table, repo: "hexpm", optional: true]}], "hexpm", "299cd10dd8ce51c9ea3ddb74bb150f93d25e968f93e4c1fa31698a8e4fa5d715"}, "bunt": {:hex, :bunt, "1.0.0", "081c2c665f086849e6d57900292b3a161727ab40431219529f13c4ddcf3e7a44", [:mix], [], "hexpm", "dc5f86aa08a5f6fa6b8096f0735c4e76d54ae5c9fa2c143e5a1fc7c1cd9bb6b5"}, From af0903f1380468bbe1b61fe65acb33772b5e24a5 Mon Sep 17 00:00:00 2001 From: Barnabas Jovanovics Date: Tue, 14 Oct 2025 02:03:13 +0200 Subject: [PATCH 158/174] fix: return skipped upserts in bulk_create (#626) --- lib/data_layer.ex | 125 ++++++++++++++++++++++++++++++++------ mix.exs | 4 +- test/bulk_create_test.exs | 61 +++++++++++++++++++ 3 files changed, 169 insertions(+), 21 deletions(-) diff --git a/lib/data_layer.ex b/lib/data_layer.ex index 07812631..9755eedf 100644 --- a/lib/data_layer.ex +++ b/lib/data_layer.ex @@ -662,6 +662,7 @@ defmodule AshPostgres.DataLayer do def can?(_, :combine), do: true def can?(_, {:combine, _}), do: true def can?(_, :bulk_create), do: true + def can?(_, :bulk_upsert_return_skipped), do: true def can?(_, :action_select), do: true @@ -2035,6 +2036,74 @@ defmodule AshPostgres.DataLayer do repo.insert_all(source, ecto_changesets, opts) end) + identity = options[:identity] + keys = Map.get(identity || %{}, :keys) || Ash.Resource.Info.primary_key(resource) + + # if it's single the return_skipped_upsert? is handled at the + # call site https://github.com/ash-project/ash_postgres/blob/0b21d4a99cc3f6d8676947e291ac9b9d57ad6e2e/lib/data_layer.ex#L3046-L3046 + result = + if options[:return_skipped_upsert?] && !opts[:single?] do + [changeset | _] = changesets + + results_by_identity = + result + |> elem(1) + |> List.wrap() + |> Enum.into(%{}, fn r -> + {Map.take(r, keys), r} + end) + + ash_query = + resource + |> Ash.Query.do_filter( + or: + changesets + |> Enum.filter(fn changeset -> + not Map.has_key?( + results_by_identity, + Map.take(changeset.attributes, keys) + ) + end) + |> Enum.map(fn changeset -> + changeset.attributes + |> Map.take(keys) + |> Keyword.new() + end) + ) + |> then(fn + query when is_nil(identity) or is_nil(identity.where) -> query + query -> Ash.Query.do_filter(query, identity.where) + end) + |> Ash.Query.set_tenant(changeset.tenant) + + skipped_upserts = + with {:ok, ecto_query} <- Ash.Query.data_layer_query(ash_query), + {:ok, results} <- run_query(ecto_query, resource) do + results + |> Enum.map(fn result -> + Ash.Resource.put_metadata(result, :upsert_skipped, true) + end) + |> Enum.reduce(%{}, fn r, acc -> + Map.put(acc, Map.take(r, keys), r) + end) + end + + results = + changesets + |> Enum.map(fn changeset -> + identity = + changeset.attributes + |> Map.take(keys) + + Map.get(results_by_identity, identity, Map.get(skipped_upserts, identity)) + end) + |> Enum.filter(& &1) + + {length(results), results} + else + result + end + case result do {_, nil} -> :ok @@ -2045,25 +2114,43 @@ defmodule AshPostgres.DataLayer do {:ok, results} else - {:ok, - Stream.zip_with(results, changesets, fn result, changeset -> - if !opts[:upsert?] do - maybe_create_tenant!(resource, result) - end - - case get_bulk_operation_metadata(changeset) do - {index, metadata_key} -> - Ash.Resource.put_metadata(result, metadata_key, index) - - nil -> - # Compatibility fallback - Ash.Resource.put_metadata( - result, - :bulk_create_index, - changeset.context[:bulk_create][:index] - ) - end - end)} + results_by_identity = + results + |> Enum.into(%{}, fn r -> + {Map.take(r, keys), r} + end) + + results = + changesets + |> Enum.map(fn changeset -> + identity = + changeset.attributes + |> Map.take(keys) + + result_for_changeset = Map.get(results_by_identity, identity) + + if result_for_changeset do + if !opts[:upsert?] do + maybe_create_tenant!(resource, result_for_changeset) + end + + case get_bulk_operation_metadata(changeset) do + {index, metadata_key} -> + Ash.Resource.put_metadata(result_for_changeset, metadata_key, index) + + nil -> + # Compatibility fallback + Ash.Resource.put_metadata( + result_for_changeset, + :bulk_create_index, + changeset.context[:bulk_create][:index] + ) + end + end + end) + |> Enum.filter(& &1) + + {:ok, results} end end rescue diff --git a/mix.exs b/mix.exs index cf59bf71..af4055bf 100644 --- a/mix.exs +++ b/mix.exs @@ -177,10 +177,10 @@ defmodule AshPostgres.MixProject do # Run "mix help deps" to learn about dependencies. defp deps do [ - {:ash, ash_version("~> 3.5 and >= 3.5.35")}, + {:ash, ash_version("~> 3.5 and >= 3.6.2")}, {:spark, "~> 2.3 and >= 2.3.4"}, {:ash_sql, ash_sql_version("~> 0.3 and >= 0.3.2")}, - {:igniter, "~> 0.6 and >= 0.6.14", optional: true}, + {:igniter, "~> 0.6 and >= 0.6.29", optional: true}, {:ecto_sql, "~> 3.13"}, {:ecto, "~> 3.13"}, {:jason, "~> 1.0"}, diff --git a/test/bulk_create_test.exs b/test/bulk_create_test.exs index e48d0238..420ff219 100644 --- a/test/bulk_create_test.exs +++ b/test/bulk_create_test.exs @@ -176,6 +176,67 @@ defmodule AshPostgres.BulkCreateTest do end) end + test "bulk upsert returns skipped records with return_skipped_upsert?" do + assert [ + {:ok, %{title: "fredfoo", uniq_if_contains_foo: "1foo", price: 10}}, + {:ok, %{title: "georgefoo", uniq_if_contains_foo: "2foo", price: 20}}, + {:ok, %{title: "herbert", uniq_if_contains_foo: "3", price: 30}} + ] = + Ash.bulk_create!( + [ + %{title: "fredfoo", uniq_if_contains_foo: "1foo", price: 10}, + %{title: "georgefoo", uniq_if_contains_foo: "2foo", price: 20}, + %{title: "herbert", uniq_if_contains_foo: "3", price: 30} + ], + Post, + :create, + return_stream?: true, + return_records?: true + ) + |> Enum.sort_by(fn {:ok, result} -> result.title end) + + results = + Ash.bulk_create!( + [ + %{title: "fredfoo", uniq_if_contains_foo: "1foo", price: 10}, + %{title: "georgefoo", uniq_if_contains_foo: "2foo", price: 20_000}, + %{title: "herbert", uniq_if_contains_foo: "3", price: 30} + ], + Post, + :upsert_with_no_filter, + return_stream?: true, + upsert_condition: expr(price != upsert_conflict(:price)), + return_errors?: true, + return_records?: true, + return_skipped_upsert?: true + ) + |> Enum.sort_by(fn + {:ok, result} -> + result.title + + _ -> + nil + end) + + assert [ + {:ok, skipped}, + {:ok, updated}, + {:ok, no_conflict} + ] = results + + assert skipped.title == "fredfoo" + assert skipped.price == 10 + assert Ash.Resource.get_metadata(skipped, :upsert_skipped) == true + + assert updated.title == "georgefoo" + assert updated.price == 20_000 + refute Ash.Resource.get_metadata(updated, :upsert_skipped) + + assert no_conflict.title == "herbert" + assert no_conflict.price == 30 + refute Ash.Resource.get_metadata(no_conflict, :upsert_skipped) + end + # confirmed that this doesn't work because it can't. An upsert must map to a potentially successful insert. # leaving this test here for posterity # test "bulk creates can upsert with id" do From 10fa4c981476ee38ef355b34e8c8cc46aca474d1 Mon Sep 17 00:00:00 2001 From: Zach Daniel Date: Mon, 13 Oct 2025 22:28:40 -0400 Subject: [PATCH 159/174] improvement: leverage new aggregate loading optimization --- lib/data_layer.ex | 13 ++--- mix.lock | 6 +- test/aggregate_test.exs | 126 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 134 insertions(+), 11 deletions(-) diff --git a/lib/data_layer.ex b/lib/data_layer.ex index 9755eedf..637b21f4 100644 --- a/lib/data_layer.ex +++ b/lib/data_layer.ex @@ -3619,14 +3619,11 @@ defmodule AshPostgres.DataLayer do end @impl true - def add_aggregates(query, aggregates, resource) do - AshSql.Aggregate.add_aggregates( - query, - aggregates, - resource, - true, - query.__ash_bindings__.root_binding - ) + def add_aggregates(query, aggregates, _resource) do + {:ok, + Map.update!(query, :__ash_bindings__, fn bindings -> + Map.put(bindings, :load_aggregates, aggregates) + end)} end @impl true diff --git a/mix.lock b/mix.lock index 05bd993c..96080205 100644 --- a/mix.lock +++ b/mix.lock @@ -1,6 +1,6 @@ %{ "ash": {:hex, :ash, "3.6.2", "90d1c8296be777b90caabf51b99323d6618a0b92594dfab92b02bdf848ac38bf", [:mix], [{:decimal, "~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:ecto, "~> 3.7", [hex: :ecto, repo: "hexpm", optional: false]}, {:ets, "~> 0.8", [hex: :ets, repo: "hexpm", optional: false]}, {:igniter, ">= 0.6.29 and < 1.0.0-0", [hex: :igniter, repo: "hexpm", optional: true]}, {:jason, ">= 1.0.0", [hex: :jason, repo: "hexpm", optional: false]}, {:picosat_elixir, "~> 0.2", [hex: :picosat_elixir, repo: "hexpm", optional: true]}, {:plug, ">= 0.0.0", [hex: :plug, repo: "hexpm", optional: true]}, {:reactor, "~> 0.11", [hex: :reactor, repo: "hexpm", optional: false]}, {:simple_sat, ">= 0.1.1 and < 1.0.0-0", [hex: :simple_sat, repo: "hexpm", optional: true]}, {:spark, ">= 2.3.3 and < 3.0.0-0", [hex: :spark, repo: "hexpm", optional: false]}, {:splode, ">= 0.2.6 and < 1.0.0-0", [hex: :splode, repo: "hexpm", optional: false]}, {:stream_data, "~> 1.0", [hex: :stream_data, repo: "hexpm", optional: false]}, {:telemetry, "~> 1.1", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "3546b5798dd24576cc451f6e03f3d6e3bb62666c0921bfe8aae700c599d9c38d"}, - "ash_sql": {:hex, :ash_sql, "0.3.2", "e2d65dac1c813cbd2569a750bf1c063109778e840052e44535ced294d7638a19", [:mix], [{:ash, ">= 3.5.43 and < 4.0.0-0", [hex: :ash, repo: "hexpm", optional: false]}, {:ecto, "~> 3.9", [hex: :ecto, repo: "hexpm", optional: false]}, {:ecto_sql, "~> 3.9", [hex: :ecto_sql, repo: "hexpm", optional: false]}], "hexpm", "1f6e5d827c0eb55fc5a07f58eb97f9bb3e6b290d83df75883f422537b98c9c68"}, + "ash_sql": {:hex, :ash_sql, "0.3.4", "c8c0446fbd6d3e6920f793b971c83ba3d14f96095036366d313b72656400509d", [:mix], [{:ash, ">= 3.5.43 and < 4.0.0-0", [hex: :ash, repo: "hexpm", optional: false]}, {:ecto, "~> 3.9", [hex: :ecto, repo: "hexpm", optional: false]}, {:ecto_sql, "~> 3.9", [hex: :ecto_sql, repo: "hexpm", optional: false]}], "hexpm", "4edb1fb707048a41f7944274b1a0b571aa3c9117b8a7a12809ca023b6f955cb4"}, "benchee": {:hex, :benchee, "1.4.0", "9f1f96a30ac80bab94faad644b39a9031d5632e517416a8ab0a6b0ac4df124ce", [:mix], [{:deep_merge, "~> 1.0", [hex: :deep_merge, repo: "hexpm", optional: false]}, {:statistex, "~> 1.0", [hex: :statistex, repo: "hexpm", optional: false]}, {:table, "~> 0.1.0", [hex: :table, repo: "hexpm", optional: true]}], "hexpm", "299cd10dd8ce51c9ea3ddb74bb150f93d25e968f93e4c1fa31698a8e4fa5d715"}, "bunt": {:hex, :bunt, "1.0.0", "081c2c665f086849e6d57900292b3a161727ab40431219529f13c4ddcf3e7a44", [:mix], [], "hexpm", "dc5f86aa08a5f6fa6b8096f0735c4e76d54ae5c9fa2c143e5a1fc7c1cd9bb6b5"}, "credo": {:hex, :credo, "1.7.12", "9e3c20463de4b5f3f23721527fcaf16722ec815e70ff6c60b86412c695d426c1", [:mix], [{:bunt, "~> 0.2.1 or ~> 1.0", [hex: :bunt, repo: "hexpm", optional: false]}, {:file_system, "~> 0.2 or ~> 1.0", [hex: :file_system, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "8493d45c656c5427d9c729235b99d498bd133421f3e0a683e5c1b561471291e5"}, @@ -17,7 +17,7 @@ "ets": {:hex, :ets, "0.9.0", "79c6a6c205436780486f72d84230c6cba2f8a9920456750ddd1e47389107d5fd", [:mix], [], "hexpm", "2861fdfb04bcaeff370f1a5904eec864f0a56dcfebe5921ea9aadf2a481c822b"}, "ex_check": {:hex, :ex_check, "0.16.0", "07615bef493c5b8d12d5119de3914274277299c6483989e52b0f6b8358a26b5f", [:mix], [], "hexpm", "4d809b72a18d405514dda4809257d8e665ae7cf37a7aee3be6b74a34dec310f5"}, "ex_doc": {:hex, :ex_doc, "0.38.4", "ab48dff7a8af84226bf23baddcdda329f467255d924380a0cf0cee97bb9a9ede", [:mix], [{:earmark_parser, "~> 1.4.44", [hex: :earmark_parser, repo: "hexpm", optional: false]}, {:makeup_c, ">= 0.1.0", [hex: :makeup_c, repo: "hexpm", optional: true]}, {:makeup_elixir, "~> 0.14 or ~> 1.0", [hex: :makeup_elixir, repo: "hexpm", optional: false]}, {:makeup_erlang, "~> 0.1 or ~> 1.0", [hex: :makeup_erlang, repo: "hexpm", optional: false]}, {:makeup_html, ">= 0.1.0", [hex: :makeup_html, repo: "hexpm", optional: true]}], "hexpm", "f7b62346408a83911c2580154e35613eb314e0278aeea72ed7fedef9c1f165b2"}, - "file_system": {:hex, :file_system, "1.1.0", "08d232062284546c6c34426997dd7ef6ec9f8bbd090eb91780283c9016840e8f", [:mix], [], "hexpm", "bfcf81244f416871f2a2e15c1b515287faa5db9c6bcf290222206d120b3d43f6"}, + "file_system": {:hex, :file_system, "1.1.1", "31864f4685b0148f25bd3fbef2b1228457c0c89024ad67f7a81a3ffbc0bbad3a", [:mix], [], "hexpm", "7a15ff97dfe526aeefb090a7a9d3d03aa907e100e262a0f8f7746b78f8f87a5d"}, "finch": {:hex, :finch, "0.20.0", "5330aefb6b010f424dcbbc4615d914e9e3deae40095e73ab0c1bb0968933cadf", [:mix], [{:mime, "~> 1.0 or ~> 2.0", [hex: :mime, repo: "hexpm", optional: false]}, {:mint, "~> 1.6.2 or ~> 1.7", [hex: :mint, repo: "hexpm", optional: false]}, {:nimble_options, "~> 0.4 or ~> 1.0", [hex: :nimble_options, repo: "hexpm", optional: false]}, {:nimble_pool, "~> 1.1", [hex: :nimble_pool, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "2658131a74d051aabfcba936093c903b8e89da9a1b63e430bee62045fa9b2ee2"}, "git_cli": {:hex, :git_cli, "0.3.0", "a5422f9b95c99483385b976f5d43f7e8233283a47cda13533d7c16131cb14df5", [:mix], [], "hexpm", "78cb952f4c86a41f4d3511f1d3ecb28edb268e3a7df278de2faa1bd4672eaf9b"}, "git_ops": {:hex, :git_ops, "2.9.0", "b74f6040084f523055b720cc7ef718da47f2cbe726a5f30c2871118635cb91c1", [:mix], [{:git_cli, "~> 0.2", [hex: :git_cli, repo: "hexpm", optional: false]}, {:igniter, ">= 0.5.27 and < 1.0.0-0", [hex: :igniter, repo: "hexpm", optional: true]}, {:nimble_parsec, "~> 1.0", [hex: :nimble_parsec, repo: "hexpm", optional: false]}, {:req, "~> 0.5", [hex: :req, repo: "hexpm", optional: false]}], "hexpm", "7fdf84be3490e5692c5dc1f8a1084eed47a221c1063e41938c73312f0bfea259"}, @@ -42,7 +42,7 @@ "req": {:hex, :req, "0.5.15", "662020efb6ea60b9f0e0fac9be88cd7558b53fe51155a2d9899de594f9906ba9", [:mix], [{:brotli, "~> 0.3.1", [hex: :brotli, repo: "hexpm", optional: true]}, {:ezstd, "~> 1.0", [hex: :ezstd, repo: "hexpm", optional: true]}, {:finch, "~> 0.17", [hex: :finch, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}, {:mime, "~> 2.0.6 or ~> 2.1", [hex: :mime, repo: "hexpm", optional: false]}, {:nimble_csv, "~> 1.0", [hex: :nimble_csv, repo: "hexpm", optional: true]}, {:plug, "~> 1.0", [hex: :plug, repo: "hexpm", optional: true]}], "hexpm", "a6513a35fad65467893ced9785457e91693352c70b58bbc045b47e5eb2ef0c53"}, "rewrite": {:hex, :rewrite, "1.2.0", "80220eb14010e175b67c939397e1a8cdaa2c32db6e2e0a9d5e23e45c0414ce21", [:mix], [{:glob_ex, "~> 0.1", [hex: :glob_ex, repo: "hexpm", optional: false]}, {:sourceror, "~> 1.0", [hex: :sourceror, repo: "hexpm", optional: false]}, {:text_diff, "~> 0.1", [hex: :text_diff, repo: "hexpm", optional: false]}], "hexpm", "a1cd702bbb9d51613ab21091f04a386d750fc6f4516b81900df082d78b2d8c50"}, "simple_sat": {:hex, :simple_sat, "0.1.3", "f650fc3c184a5fe741868b5ac56dc77fdbb428468f6dbf1978e14d0334497578", [:mix], [], "hexpm", "a54305066a356b7194dc81db2a89232bacdc0b3edaef68ed9aba28dcbc34887b"}, - "sobelow": {:hex, :sobelow, "0.14.0", "dd82aae8f72503f924fe9dd97ffe4ca694d2f17ec463dcfd365987c9752af6ee", [:mix], [{:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "7ecf91e298acfd9b24f5d761f19e8f6e6ac585b9387fb6301023f1f2cd5eed5f"}, + "sobelow": {:hex, :sobelow, "0.14.1", "2f81e8632f15574cba2402bcddff5497b413c01e6f094bc0ab94e83c2f74db81", [:mix], [{:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "8fac9a2bd90fdc4b15d6fca6e1608efb7f7c600fa75800813b794ee9364c87f2"}, "sourceror": {:hex, :sourceror, "1.10.0", "38397dedbbc286966ec48c7af13e228b171332be1ad731974438c77791945ce9", [:mix], [], "hexpm", "29dbdfc92e04569c9d8e6efdc422fc1d815f4bd0055dc7c51b8800fb75c4b3f1"}, "spark": {:hex, :spark, "2.3.5", "f30d30ecc3b4ab9b932d9aada66af7677fc1f297a2c349b0bcec3eafb9f996e8", [:mix], [{:igniter, ">= 0.3.64 and < 1.0.0-0", [hex: :igniter, repo: "hexpm", optional: true]}, {:jason, "~> 1.4", [hex: :jason, repo: "hexpm", optional: true]}, {:sourceror, "~> 1.2", [hex: :sourceror, repo: "hexpm", optional: true]}], "hexpm", "0e9d339704d5d148f77f2b2fef3bcfc873a9e9bb4224fcf289c545d65827202f"}, "spitfire": {:hex, :spitfire, "0.2.1", "29e154873f05444669c7453d3d931820822cbca5170e88f0f8faa1de74a79b47", [:mix], [], "hexpm", "6eeed75054a38341b2e1814d41bb0a250564092358de2669fdb57ff88141d91b"}, diff --git a/test/aggregate_test.exs b/test/aggregate_test.exs index ff51bf26..3e64440f 100644 --- a/test/aggregate_test.exs +++ b/test/aggregate_test.exs @@ -1734,4 +1734,130 @@ defmodule AshSql.AggregateTest do assert loaded_post.count_of_comments == 1 end + + test "aggregate with sort and limit is accurate" do + # Setup: Create an author with multiple posts + author = + Author + |> Ash.Changeset.for_create(:create, %{first_name: "John", last_name: "Doe"}) + |> Ash.create!() + + # Create posts with different titles to test sorting + post1 = + Post + |> Ash.Changeset.for_create(:create, %{title: "A First Post"}) + |> Ash.Changeset.manage_relationship(:author, author, type: :append_and_remove) + |> Ash.create!() + + post2 = + Post + |> Ash.Changeset.for_create(:create, %{title: "Z Last Post"}) + |> Ash.Changeset.manage_relationship(:author, author, type: :append_and_remove) + |> Ash.create!() + + post3 = + Post + |> Ash.Changeset.for_create(:create, %{title: "M Middle Post"}) + |> Ash.Changeset.manage_relationship(:author, author, type: :append_and_remove) + |> Ash.create!() + + # Add comments to posts + Comment + |> Ash.Changeset.for_create(:create, %{title: "Comment 1"}) + |> Ash.Changeset.manage_relationship(:post, post1, type: :append_and_remove) + |> Ash.create!() + + Comment + |> Ash.Changeset.for_create(:create, %{title: "Comment 2"}) + |> Ash.Changeset.manage_relationship(:post, post1, type: :append_and_remove) + |> Ash.create!() + + Comment + |> Ash.Changeset.for_create(:create, %{title: "Comment 3"}) + |> Ash.Changeset.manage_relationship(:post, post2, type: :append_and_remove) + |> Ash.create!() + + Comment + |> Ash.Changeset.for_create(:create, %{title: "Comment 4"}) + |> Ash.Changeset.manage_relationship(:post, post3, type: :append_and_remove) + |> Ash.create!() + + # Query with aggregate, sort, and limit + # This should ideally use a subquery to apply sort/limit before loading the aggregate + results = + Post + |> Ash.Query.load(:count_of_comments) + |> Ash.Query.sort(:title) + |> Ash.Query.limit(2) + |> Ash.read!() + + # Verify we got the right posts (sorted by title, limited to 2) + assert length(results) == 2 + assert Enum.at(results, 0).title == "A First Post" + assert Enum.at(results, 1).title == "M Middle Post" + + # Verify the aggregates are correct + assert Enum.at(results, 0).count_of_comments == 2 + assert Enum.at(results, 1).count_of_comments == 1 + end + + test "aggregate with sort by aggregate value and limit is accurate" do + # This tests sorting by the aggregate itself, not by another field + author = + Author + |> Ash.Changeset.for_create(:create, %{first_name: "Jane", last_name: "Smith"}) + |> Ash.create!() + + # Create posts with different numbers of comments + post1 = + Post + |> Ash.Changeset.for_create(:create, %{title: "Post with 3 comments"}) + |> Ash.Changeset.manage_relationship(:author, author, type: :append_and_remove) + |> Ash.create!() + + post2 = + Post + |> Ash.Changeset.for_create(:create, %{title: "Post with 1 comment"}) + |> Ash.Changeset.manage_relationship(:author, author, type: :append_and_remove) + |> Ash.create!() + + post3 = + Post + |> Ash.Changeset.for_create(:create, %{title: "Post with 2 comments"}) + |> Ash.Changeset.manage_relationship(:author, author, type: :append_and_remove) + |> Ash.create!() + + # Add varying numbers of comments + for _i <- 1..3 do + Comment + |> Ash.Changeset.for_create(:create, %{title: "Comment on post 1"}) + |> Ash.Changeset.manage_relationship(:post, post1, type: :append_and_remove) + |> Ash.create!() + end + + Comment + |> Ash.Changeset.for_create(:create, %{title: "Comment on post 2"}) + |> Ash.Changeset.manage_relationship(:post, post2, type: :append_and_remove) + |> Ash.create!() + + for _i <- 1..2 do + Comment + |> Ash.Changeset.for_create(:create, %{title: "Comment on post 3"}) + |> Ash.Changeset.manage_relationship(:post, post3, type: :append_and_remove) + |> Ash.create!() + end + + # Query sorting by the aggregate value itself + results = + Post + |> Ash.Query.load(:count_of_comments) + |> Ash.Query.sort(count_of_comments: :desc) + |> Ash.Query.limit(2) + |> Ash.read!() + + # Should get the posts with most comments first + assert length(results) == 2 + assert Enum.at(results, 0).count_of_comments == 3 + assert Enum.at(results, 1).count_of_comments == 2 + end end From d011d0ef554b5d9be747965d32e3bcd87b82bcb4 Mon Sep 17 00:00:00 2001 From: Zach Daniel Date: Mon, 13 Oct 2025 22:55:09 -0400 Subject: [PATCH 160/174] chore: release version v2.6.22 --- CHANGELOG.md | 13 +++++++++++++ mix.exs | 2 +- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4b045424..67570853 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,19 @@ See [Conventional Commits](https://www.conventionalcommits.org) for commit guide +## [v2.6.22](https://github.com/ash-project/ash_postgres/compare/v2.6.21...v2.6.22) (2025-10-14) + + + + +### Bug Fixes: + +* return skipped upserts in bulk_create (#626) by Barnabas Jovanovics + +### Improvements: + +* leverage new aggregate loading optimization by Zach Daniel + ## [v2.6.21](https://github.com/ash-project/ash_postgres/compare/v2.6.20...v2.6.21) (2025-10-10) diff --git a/mix.exs b/mix.exs index af4055bf..0bd7385a 100644 --- a/mix.exs +++ b/mix.exs @@ -9,7 +9,7 @@ defmodule AshPostgres.MixProject do The PostgreSQL data layer for Ash Framework """ - @version "2.6.21" + @version "2.6.22" def project do [ From 4da5f3b00cdf6b3d2d0292659494ecebb5a2928c Mon Sep 17 00:00:00 2001 From: James Harton Date: Wed, 15 Oct 2025 08:43:52 +1300 Subject: [PATCH 161/174] chore: Fix REUSE copyright attributions --- .check.exs | 2 +- .credo.exs | 2 +- .formatter.exs | 2 +- .github/dependabot.yml | 2 +- .github/workflows/elixir.yml | 2 +- .gitignore | 2 +- .tool-versions.license | 2 +- .vscode/settings.json.license | 2 +- benchmarks/bulk_create.exs | 2 +- config/config.exs | 2 +- documentation/dsls/DSL-AshPostgres.DataLayer.md.license | 2 +- lib/ash_postgres.ex | 2 +- lib/check_constraint.ex | 2 +- lib/custom_aggregate.ex | 2 +- lib/custom_extension.ex | 2 +- lib/custom_index.ex | 2 +- lib/data_layer.ex | 2 +- lib/data_layer/info.ex | 2 +- lib/ecto_migration_default.ex | 2 +- lib/extensions/immutable_raise_error.ex | 2 +- lib/extensions/vector.ex | 2 +- lib/functions/binding.ex | 2 +- lib/functions/ilike.ex | 2 +- lib/functions/like.ex | 2 +- lib/functions/trigram_similarity.ex | 2 +- lib/functions/vector_cosine_distance.ex | 2 +- lib/functions/vector_l2_distance.ex | 2 +- lib/igniter.ex | 2 +- lib/manual_relationship.ex | 2 +- lib/migration.ex | 2 +- lib/migration_compile_cache.ex | 2 +- lib/migration_generator/ash_functions.ex | 2 +- lib/migration_generator/migration_generator.ex | 2 +- lib/migration_generator/operation.ex | 2 +- lib/migration_generator/phase.ex | 2 +- lib/mix/helpers.ex | 2 +- lib/mix/tasks/ash_postgres.create.ex | 2 +- lib/mix/tasks/ash_postgres.drop.ex | 2 +- lib/mix/tasks/ash_postgres.gen.resources.ex | 2 +- lib/mix/tasks/ash_postgres.generate_migrations.ex | 2 +- lib/mix/tasks/ash_postgres.install.ex | 2 +- lib/mix/tasks/ash_postgres.migrate.ex | 2 +- lib/mix/tasks/ash_postgres.rollback.ex | 2 +- lib/mix/tasks/ash_postgres.setup_vector.ex | 2 +- lib/mix/tasks/ash_postgres.squash_snapshots.ex | 2 +- lib/multitenancy.ex | 2 +- lib/reference.ex | 2 +- lib/repo.ex | 2 +- lib/repo/before_compile.ex | 2 +- lib/resource_generator/resource_generator.ex | 2 +- lib/resource_generator/sensitive_data.ex | 2 +- lib/resource_generator/spec.ex | 2 +- lib/sql_implementation.ex | 2 +- lib/statement.ex | 2 +- lib/type.ex | 2 +- lib/types/ci_string_wrapper.ex | 2 +- lib/types/ltree.ex | 2 +- lib/types/string_wrapper.ex | 2 +- lib/types/timestamptz.ex | 2 +- lib/types/timestamptz_usec.ex | 2 +- lib/types/tsquery.ex | 2 +- lib/types/tsvector.ex | 2 +- lib/verifiers/ensure_table_or_polymorphic.ex | 2 +- .../prevent_attribute_multitenancy_and_non_full_match_type.ex | 2 +- lib/verifiers/prevent_multidimensional_array_aggregates.ex | 2 +- lib/verifiers/validate_identity_index_names.ex | 2 +- lib/verifiers/validate_references.ex | 2 +- lib/version_agent.ex | 2 +- logos/small-logo.png.license | 2 +- mix.exs | 2 +- mix.lock.license | 2 +- .../20250526214825_migrate_resources_extensions_1.exs | 2 +- .../migrations/20250526214827_migrate_resources1.exs | 2 +- priv/resource_snapshots/dev_test_repo/extensions.json.license | 2 +- .../multitenant_orgs/20250526214827.json.license | 2 +- .../test_no_sandbox_repo/extensions.json.license | 2 +- .../test_repo/accounts/20221217123726.json.license | 2 +- .../test_repo/accounts/20240327211150.json.license | 2 +- .../test_repo/authors/20220805191443.json.license | 2 +- .../test_repo/authors/20220914104733.json.license | 2 +- .../test_repo/authors/20240327211150.json.license | 2 +- .../test_repo/authors/20240705113722.json.license | 2 +- .../test_repo/authors/20250908212414.json.license | 2 +- .../test_repo/chats/20250908093505.json.license | 2 +- .../test_repo/co_authored_posts/20241208221219.json.license | 2 +- .../test_repo/comedians/20241217232254.json.license | 2 +- .../test_repo/comedians/20250413141328.json.license | 2 +- .../test_repo/comment_links/20250123161002.json.license | 2 +- .../test_repo/comment_ratings/20220805191443.json.license | 2 +- .../test_repo/comment_ratings/20240327211150.json.license | 2 +- .../test_repo/comments/20220805191443.json.license | 2 +- .../test_repo/comments/20240327211150.json.license | 2 +- .../test_repo/comments/20240327211917.json.license | 2 +- .../20230816231942.json.license | 2 +- .../20240327211150.json.license | 2 +- .../20231116013020.json.license | 2 +- .../20240327211150.json.license | 2 +- .../20240327211917.json.license | 2 +- .../complex_calculations_channels/20231116013020.json.license | 2 +- .../complex_calculations_channels/20240327211150.json.license | 2 +- .../complex_calculations_channels/20240327211917.json.license | 2 +- .../20230816231942.json.license | 2 +- .../20240327211150.json.license | 2 +- .../20240327211917.json.license | 2 +- .../20250714225304.json.license | 2 +- .../complex_calculations_folders/20250714225304.json.license | 2 +- .../complex_calculations_skills/20230816231942.json.license | 2 +- .../complex_calculations_skills/20240327211150.json.license | 2 +- .../test_repo/content/20250123164209.json.license | 2 +- .../content_visibility_group/20250123164209.json.license | 2 +- .../test_repo/csv/20250320225052.json.license | 2 +- .../test_repo/customers/20250908073737.json.license | 2 +- .../test_repo/entities/20240109160153.json.license | 2 +- .../test_repo/entities/20240327211150.json.license | 2 +- .../test_repo/entities/20240327211917.json.license | 2 +- priv/resource_snapshots/test_repo/extensions.json.license | 2 +- .../test_repo/integer_posts/20220805191443.json.license | 2 +- .../test_repo/items/20240713134055.json.license | 2 +- .../test_repo/items/20240717104854.json.license | 2 +- .../test_repo/items/20240717153736.json.license | 2 +- .../test_repo/jokes/20241217232254.json.license | 2 +- .../test_repo/jokes/20250413141328.json.license | 2 +- .../test_repo/managers/20230526144249.json.license | 2 +- .../test_repo/managers/20240327211150.json.license | 2 +- .../test_repo/messages/20250908093505.json.license | 2 +- .../multitenant_named_orgs/20250519103535.json.license | 2 +- .../test_repo/multitenant_orgs/20220805191443.json.license | 2 +- .../test_repo/multitenant_orgs/20240327211150.json.license | 2 +- .../test_repo/multitenant_orgs/20240627223225.json.license | 2 +- .../test_repo/multitenant_orgs/20240702164513.json.license | 2 +- .../test_repo/multitenant_orgs/20240703155134.json.license | 2 +- .../non_multitenant_post_links/20250122190558.json.license | 2 +- .../test_repo/note/20250123164209.json.license | 2 +- .../test_repo/orders/20250908073737.json.license | 2 +- .../test_repo/orgs/20230129050950.json.license | 2 +- .../test_repo/orgs/20240327211150.json.license | 2 +- .../test_repo/orgs/20250210191116.json.license | 2 +- .../test_repo/other_items/20240713134055.json.license | 2 +- .../test_repo/other_items/20240717151815.json.license | 2 +- .../test_repo/points/20250313112823.json.license | 2 +- .../test_repo/post_followers/20240227180858.json.license | 2 +- .../test_repo/post_followers/20240227181137.json.license | 2 +- .../test_repo/post_followers/20240327211150.json.license | 2 +- .../test_repo/post_followers/20240516205244.json.license | 2 +- .../test_repo/post_followers/20240517223946.json.license | 2 +- .../test_repo/post_links/20220805191443.json.license | 2 +- .../test_repo/post_links/20221017133955.json.license | 2 +- .../test_repo/post_links/20221202194704.json.license | 2 +- .../test_repo/post_links/20240610195853.json.license | 2 +- .../test_repo/post_links/20240617193218.json.license | 2 +- .../test_repo/post_permalinks/20240906170759.json.license | 2 +- .../test_repo/post_ratings/20220805191443.json.license | 2 +- .../test_repo/post_ratings/20240327211150.json.license | 2 +- .../test_repo/post_tags/20250810102512.json.license | 2 +- .../test_repo/post_views/20230905050351.json.license | 2 +- .../test_repo/post_views/20240327211917.json.license | 2 +- .../test_repo/posts/20220805191443.json.license | 2 +- .../test_repo/posts/20221125171150.json.license | 2 +- .../test_repo/posts/20221125171204.json.license | 2 +- .../test_repo/posts/20230129050950.json.license | 2 +- .../test_repo/posts/20230823161017.json.license | 2 +- .../test_repo/posts/20231127215636.json.license | 2 +- .../test_repo/posts/20231129141453.json.license | 2 +- .../test_repo/posts/20231219132807.json.license | 2 +- .../test_repo/posts/20240129221511.json.license | 2 +- .../test_repo/posts/20240224001913.json.license | 2 +- .../test_repo/posts/20240327211150.json.license | 2 +- .../test_repo/posts/20240327211917.json.license | 2 +- .../test_repo/posts/20240503012410.json.license | 2 +- .../test_repo/posts/20240504185511.json.license | 2 +- .../test_repo/posts/20240524031113.json.license | 2 +- .../test_repo/posts/20240524041750.json.license | 2 +- .../test_repo/posts/20240617193218.json.license | 2 +- .../test_repo/posts/20240618102809.json.license | 2 +- .../test_repo/posts/20240712232026.json.license | 2 +- .../test_repo/posts/20240715135403.json.license | 2 +- .../test_repo/posts/20240910180107.json.license | 2 +- .../test_repo/posts/20240911225320.json.license | 2 +- .../test_repo/posts/20240918104740.json.license | 2 +- .../test_repo/posts/20240929121224.json.license | 2 +- .../test_repo/posts/20250217054207.json.license | 2 +- .../test_repo/posts/20250313112823.json.license | 2 +- .../test_repo/posts/20250520130634.json.license | 2 +- .../test_repo/posts/20250521105654.json.license | 2 +- .../test_repo/posts/20250612113920.json.license | 2 +- .../test_repo/posts/20250618011917.json.license | 2 +- .../test_repo/products/20250908073737.json.license | 2 +- .../test_repo/profile/20220805191443.json.license | 2 +- .../test_repo/profiles.profile/20240327211150.json.license | 2 +- .../test_repo/punchlines/20250413141328.json.license | 2 +- .../test_repo/records/20240109160153.json.license | 2 +- .../test_repo/records/20240327211150.json.license | 2 +- .../test_repo/records/20240327211917.json.license | 2 +- .../records_temp_entities/20250605230457.json.license | 2 +- .../test_repo/relationship_items/20240717153736.json.license | 2 +- .../test_repo/rsvps/20251002180954.json.license | 2 +- .../test_repo/schematic_groups/20240821213522.json.license | 2 +- .../test_repo/staff_group/20250123164209.json.license | 2 +- .../test_repo/staff_group_member/20250123164209.json.license | 2 +- .../test_repo/standup_clubs/20250413141328.json.license | 2 +- .../stateful_post_followers/20240618085942.json.license | 2 +- .../test_repo/string_points/20250313112823.json.license | 2 +- .../test_repo/sub_items/20240713134055.json.license | 2 +- .../test_repo/subquery_access/20240130133933.json.license | 2 +- .../test_repo/subquery_child/20240130133933.json.license | 2 +- .../test_repo/subquery_parent/20240130133933.json.license | 2 +- .../test_repo/subquery_through/20240130133933.json.license | 2 +- .../test_repo/tags/20250810102512.json.license | 2 +- .../test_repo/temp.temp_entities/20240327211150.json.license | 2 +- .../test_repo/temp.temp_entities/20240327211917.json.license | 2 +- .../test_repo/temp_entities/20240109160153.json.license | 2 +- .../tenants/composite_key/20250220073135.json.license | 2 +- .../tenants/composite_key/20250220073141.json.license | 2 +- .../cross_tenant_post_links/20250122203454.json.license | 2 +- .../tenants/friend_links/20240610162043.json.license | 2 +- .../tenants/multitenant_posts/20220805191441.json.license | 2 +- .../tenants/multitenant_posts/20240327211149.json.license | 2 +- .../20251001120813.json.license | 2 +- .../test_repo/unrelated_profiles/20250731124648.json.license | 2 +- .../test_repo/unrelated_reports/20250731124648.json.license | 2 +- .../unrelated_secure_profiles/20250731124648.json.license | 2 +- .../test_repo/unrelated_users/20250731124648.json.license | 2 +- .../test_repo/user_invites/20240727145758.json.license | 2 +- .../test_repo/users/20220805191443.json.license | 2 +- .../test_repo/users/20221217123726.json.license | 2 +- .../test_repo/users/20230129050950.json.license | 2 +- .../test_repo/users/20240327211150.json.license | 2 +- .../test_repo/users/20240727145758.json.license | 2 +- .../test_repo/users/20240929124728.json.license | 2 +- .../test_repo/users/20250320225052.json.license | 2 +- .../test_repo/users/20250321142835.json.license | 2 +- priv/test_no_sandbox_repo/migrations/.gitkeep.license | 2 +- .../migrations/20240627223224_install_5_extensions.exs | 2 +- .../20240712232025_install_ash-functions_extension_4.exs | 2 +- .../20250113205301_migrate_resources_extensions_1.exs | 2 +- .../migrations/20220805191440_install_4_extensions.exs | 4 ++-- .../migrations/20220805191443_migrate_resources1.exs | 2 +- .../migrations/20220914104733_migrate_resources2.exs | 4 ++-- .../migrations/20221017133955_migrate_resources3.exs | 4 ++-- .../migrations/20221125171148_migrate_resources4.exs | 4 ++-- .../migrations/20221125171150_migrate_resources5.exs | 4 ++-- .../migrations/20221202194704_migrate_resources6.exs | 4 ++-- .../migrations/20221217123726_migrate_resources7.exs | 4 ++-- .../migrations/20230129050950_migrate_resources8.exs | 4 ++-- .../migrations/20230526144249_migrate_resources9.exs | 4 ++-- .../20230712182523_install_ash-functions_extension.exs | 2 +- .../20230804223759_install_demo-functions_v0_extension.exs | 4 ++-- .../20230804223818_install_demo-functions_v1_extension.exs | 4 ++-- .../20230816231942_add_complex_calculation_tables.exs | 4 ++-- .../migrations/20230823161017_migrate_resources10.exs | 4 ++-- priv/test_repo/migrations/20230905050351_add_post_views.exs | 4 ++-- .../20231116013020_add_complex_calculations_channels.exs | 4 ++-- .../migrations/20231127212608_add_composite_type.exs | 2 +- .../migrations/20231127215636_migrate_resources11.exs | 2 +- .../migrations/20231129141453_migrate_resources12.exs | 4 ++-- .../20231214220937_install_ash-functions_extension_2.exs | 2 +- .../migrations/20231219132807_migrate_resources13.exs | 4 ++-- .../20231231051611_install_ash-functions_extension_3.exs | 4 ++-- .../migrations/20240109155951_create_temp_schema.exs | 2 +- .../migrations/20240109160153_migrate_resources14.exs | 4 ++-- .../migrations/20240129221511_migrate_resources15.exs | 4 ++-- .../20240130133933_add_resources_for_subquery_test.exs | 2 +- .../migrations/20240224001913_migrate_resources16.exs | 4 ++-- .../migrations/20240227180858_migrate_resources17.exs | 4 ++-- .../migrations/20240227181137_migrate_resources18.exs | 4 ++-- .../migrations/20240229050455_install_5_extensions.exs | 2 +- .../migrations/20240327211150_migrate_resources19.exs | 2 +- .../migrations/20240327211917_migrate_resources20.exs | 2 +- .../migrations/20240503012410_migrate_resources21.exs | 2 +- .../migrations/20240504185511_migrate_resources22.exs | 2 +- .../migrations/20240516205244_migrate_resources23.exs | 2 +- .../migrations/20240517223946_migrate_resources24.exs | 2 +- .../migrations/20240524031113_migrate_resources25.exs | 2 +- .../migrations/20240524041750_migrate_resources26.exs | 2 +- .../migrations/20240610195853_migrate_resources27.exs | 2 +- .../migrations/20240617193218_migrate_resources28.exs | 2 +- .../migrations/20240618085942_migrate_resources29.exs | 2 +- .../migrations/20240618102809_migrate_resources30.exs | 2 +- .../20240622192715_install_ash-functions_extension_4.exs | 2 +- .../migrations/20240627223225_migrate_resources31.exs | 2 +- .../migrations/20240703155134_migrate_resources32.exs | 2 +- .../migrations/20240705113722_migrate_resources33.exs | 2 +- .../migrations/20240712232026_migrate_resources34.exs | 2 +- .../migrations/20240713134055_multi_domain_calculations.exs | 2 +- .../migrations/20240715135403_migrate_resources35.exs | 2 +- .../20240717104854_no_attributes_calculation_test.exs | 2 +- .../migrations/20240717151815_migrate_resources36.exs | 2 +- .../migrations/20240717153736_migrate_resources37.exs | 2 +- priv/test_repo/migrations/20240727145758_user_invites.exs | 2 +- .../migrations/20240906170759_migrate_resources38.exs | 2 +- .../migrations/20240910180107_migrate_resources39.exs | 2 +- .../migrations/20240911225319_install_1_extensions.exs | 2 +- .../migrations/20240911225320_migrate_resources40.exs | 2 +- .../migrations/20240918104740_migrate_resources41.exs | 2 +- .../migrations/20240929121224_migrate_resources42.exs | 2 +- .../migrations/20240929124728_migrate_resources43.exs | 2 +- .../migrations/20241208221219_migrate_resources44.exs | 2 +- .../migrations/20241217232254_migrate_resources45.exs | 2 +- .../20250113205259_migrate_resources_extensions_1.exs | 2 +- .../migrations/20250122190558_migrate_resources46.exs | 2 +- .../migrations/20250123161002_migrate_resources47.exs | 2 +- .../migrations/20250123164209_migrate_resources48.exs | 2 +- .../migrations/20250210191116_migrate_resources49.exs | 2 +- .../migrations/20250217054207_migrate_resources50.exs | 2 +- .../migrations/20250313112823_migrate_resources51.exs | 2 +- priv/test_repo/migrations/20250320225052_add_csv_resource.exs | 2 +- .../migrations/20250321142835_migrate_resources52.exs | 2 +- .../20250413141328_add_punchlines_and_standup_clubs.exs | 2 +- .../migrations/20250519103535_migrate_resources53.exs | 2 +- .../migrations/20250520130634_migrate_resources54.exs | 2 +- .../migrations/20250521105654_add_model_tuple_to_post.exs | 2 +- .../20250605230457_create_record_temp_entities_table.exs | 2 +- .../migrations/20250612113920_migrate_resources55.exs | 2 +- .../migrations/20250618011917_migrate_resources56.exs | 2 +- ...250714225304_add_complex_calculations_folder_and_items.exs | 2 +- .../migrations/20250731124648_migrate_resources57.exs | 2 +- .../migrations/20250810102512_migrate_resources58.exs | 2 +- .../migrations/20250908073737_migrate_resources59.exs | 2 +- .../migrations/20250908093505_migrate_resources60.exs | 2 +- .../migrations/20250908212414_migrate_resources61.exs | 2 +- .../migrations/20251002180954_migrate_resources62.exs | 2 +- .../tenant_migrations/20220805191441_migrate_resources1.exs | 4 ++-- .../tenant_migrations/20240327211149_migrate_resources2.exs | 2 +- .../tenant_migrations/20240610162043_migrate_resources3.exs | 2 +- .../tenant_migrations/20250122203454_migrate_resources4.exs | 2 +- .../tenant_migrations/20250220073135_migrate_resources5.exs | 2 +- .../tenant_migrations/20250220073141_migrate_resources6.exs | 2 +- .../tenant_migrations/20251001120813_migrate_resources7.exs | 2 +- test/aggregate_test.exs | 2 +- test/ash_postgres_test.exs | 2 +- test/atomics_test.exs | 2 +- test/bulk_create_test.exs | 2 +- test/bulk_destroy_test.exs | 2 +- test/bulk_update_test.exs | 2 +- test/calculation_test.exs | 2 +- test/cascade_destroy_test.exs | 2 +- test/combination_test.exs | 2 +- test/complex_calculations_test.exs | 2 +- test/composite_type_test.exs | 2 +- test/constraint_test.exs | 2 +- test/create_test.exs | 2 +- test/custom_expression_test.exs | 2 +- test/custom_index_test.exs | 2 +- test/cve/empty_atomic_non_bulk_actions_policy_bypass_test.exs | 2 +- test/destroy_test.exs | 2 +- test/dev_migrations_test.exs | 2 +- test/distinct_test.exs | 2 +- test/ecto_compatibility_test.exs | 2 +- test/embeddable_resource_test.exs | 2 +- test/enum_test.exs | 2 +- test/error_expr_test.exs | 2 +- .../filter_child_relationship_by_parent_relationship_test.exs | 2 +- test/filter_field_policy_test.exs | 2 +- test/filter_test.exs | 2 +- test/load_test.exs | 2 +- test/lock_test.exs | 2 +- test/ltree_test.exs | 2 +- test/manual_relationships_test.exs | 2 +- test/manual_update_test.exs | 2 +- test/many_to_many_expr_test.exs | 2 +- test/migration_generator_test.exs | 2 +- test/mix/tasks/ash_postgres.install_test.exs | 2 +- test/mix_squash_snapshots_test.exs | 2 +- test/multi_domain_calculations_test.exs | 2 +- test/multitenancy_test.exs | 2 +- test/parent_filter_test.exs | 2 +- test/parent_sort_test.exs | 2 +- test/polymorphism_test.exs | 2 +- test/primary_key_test.exs | 2 +- test/references_test.exs | 2 +- test/rel_with_parent_filter_test.exs | 2 +- test/resource_generator_test.exs | 2 +- test/schema_test.exs | 2 +- test/select_test.exs | 2 +- test/sort_test.exs | 2 +- test/storage_types_test.exs | 2 +- test/subquery_test.exs | 2 +- test/support/complex_calculations/domain.ex | 2 +- test/support/complex_calculations/resources/certification.ex | 2 +- test/support/complex_calculations/resources/channel.ex | 2 +- test/support/complex_calculations/resources/channel_member.ex | 2 +- test/support/complex_calculations/resources/dm_channel.ex | 2 +- test/support/complex_calculations/resources/documentation.ex | 2 +- test/support/complex_calculations/resources/folder.ex | 2 +- test/support/complex_calculations/resources/folder_item.ex | 2 +- test/support/complex_calculations/resources/skill.ex | 2 +- test/support/concat.ex | 2 +- test/support/dev_test_repo.ex | 2 +- test/support/domain.ex | 2 +- test/support/multi_domain_calculations/domain_one.ex | 2 +- test/support/multi_domain_calculations/domain_one/item.ex | 2 +- test/support/multi_domain_calculations/domain_three.ex | 2 +- .../domain_three/relationship_item.ex | 2 +- test/support/multi_domain_calculations/domain_two.ex | 2 +- .../multi_domain_calculations/domain_two/other_item.ex | 2 +- test/support/multi_domain_calculations/domain_two/sub_item.ex | 2 +- test/support/multitenancy/domain.ex | 2 +- test/support/multitenancy/resources/composite_key_post.ex | 2 +- test/support/multitenancy/resources/cross_tenant_post_link.ex | 2 +- test/support/multitenancy/resources/dev_migrations_org.ex | 2 +- test/support/multitenancy/resources/named_org.ex | 2 +- .../multitenancy/resources/non_multitenant_post_link.ex | 2 +- .../resources/non_multitenant_post_multitenant_link.ex | 2 +- test/support/multitenancy/resources/org.ex | 2 +- test/support/multitenancy/resources/post.ex | 2 +- test/support/multitenancy/resources/post_link.ex | 2 +- test/support/multitenancy/resources/user.ex | 2 +- test/support/relationships/comments_containing_title.ex | 2 +- test/support/repo_case.ex | 2 +- test/support/resources/account.ex | 2 +- test/support/resources/author.ex | 2 +- test/support/resources/bio.ex | 2 +- test/support/resources/chat.ex | 2 +- test/support/resources/co_authored_post.ex | 2 +- test/support/resources/comedian.ex | 2 +- test/support/resources/comment.ex | 2 +- test/support/resources/comment_link.ex | 2 +- test/support/resources/content.ex | 2 +- test/support/resources/content_visibility_group.ex | 2 +- test/support/resources/csv.ex | 2 +- test/support/resources/customer.ex | 2 +- test/support/resources/db_point.ex | 2 +- test/support/resources/db_string_point.ex | 2 +- test/support/resources/entity.ex | 2 +- test/support/resources/integer_post.ex | 2 +- test/support/resources/invite.ex | 2 +- test/support/resources/joke.ex | 2 +- test/support/resources/manager.ex | 2 +- test/support/resources/message.ex | 2 +- test/support/resources/note.ex | 2 +- test/support/resources/order.ex | 2 +- test/support/resources/organization.ex | 2 +- test/support/resources/permalink.ex | 2 +- test/support/resources/post.ex | 2 +- test/support/resources/post_follower.ex | 2 +- test/support/resources/post_link.ex | 2 +- test/support/resources/post_tag.ex | 2 +- test/support/resources/post_views.ex | 2 +- test/support/resources/post_with_empty_update.ex | 2 +- test/support/resources/product.ex | 2 +- test/support/resources/profile.ex | 2 +- test/support/resources/punchline.ex | 2 +- test/support/resources/rating.ex | 2 +- test/support/resources/record.ex | 2 +- test/support/resources/record_temp_entity.ex | 2 +- test/support/resources/role.ex | 2 +- test/support/resources/rsvp.ex | 2 +- test/support/resources/settings.ex | 2 +- test/support/resources/staff_group.ex | 2 +- test/support/resources/staff_group_member.ex | 2 +- test/support/resources/standup_club.ex | 2 +- test/support/resources/stateful_post_follwer.ex | 2 +- test/support/resources/subquery/access.ex | 2 +- test/support/resources/subquery/child.ex | 2 +- test/support/resources/subquery/child_domain.ex | 2 +- test/support/resources/subquery/parent.ex | 2 +- test/support/resources/subquery/parent_domain.ex | 2 +- test/support/resources/subquery/through.ex | 2 +- test/support/resources/tag.ex | 2 +- test/support/resources/temp_entity.ex | 2 +- test/support/resources/user.ex | 2 +- test/support/string_agg.ex | 2 +- test/support/test_app.ex | 2 +- test/support/test_custom_extension.ex | 2 +- test/support/test_no_sandbox_repo.ex | 2 +- test/support/test_repo.ex | 2 +- test/support/trigram_word_similarity.ex | 2 +- test/support/types/composite_point.ex | 2 +- test/support/types/email.ex | 2 +- test/support/types/money.ex | 2 +- test/support/types/person_detail.ex | 2 +- test/support/types/point.ex | 2 +- test/support/types/response.ex | 2 +- test/support/types/status.ex | 2 +- test/support/types/status_enum.ex | 2 +- test/support/types/status_enum_no_cast.ex | 2 +- test/support/types/string_point.ex | 2 +- test/support/unrelated_aggregates/profile.ex | 2 +- test/support/unrelated_aggregates/report.ex | 2 +- test/support/unrelated_aggregates/secure_profile.ex | 2 +- test/support/unrelated_aggregates/user.ex | 2 +- test/test_helper.exs | 2 +- test/transaction_test.exs | 2 +- test/tuple_test.exs | 2 +- test/type_test.exs | 2 +- test/unique_identity_test.exs | 2 +- test/unrelated_aggregates_test.exs | 2 +- test/update_test.exs | 2 +- test/upsert_test.exs | 2 +- 489 files changed, 513 insertions(+), 513 deletions(-) diff --git a/.check.exs b/.check.exs index cecfbc08..25e480f8 100644 --- a/.check.exs +++ b/.check.exs @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/.credo.exs b/.credo.exs index 1e1ebe4c..233f96e7 100644 --- a/.credo.exs +++ b/.credo.exs @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/.formatter.exs b/.formatter.exs index 07bd4f93..71cf7ae6 100644 --- a/.formatter.exs +++ b/.formatter.exs @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 09b96595..16a96790 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/.github/workflows/elixir.yml b/.github/workflows/elixir.yml index cf4e4897..bec3b86f 100644 --- a/.github/workflows/elixir.yml +++ b/.github/workflows/elixir.yml @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/.gitignore b/.gitignore index b16f7ffb..b7c11866 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/.tool-versions.license b/.tool-versions.license index 815664f3..b0a44fab 100644 --- a/.tool-versions.license +++ b/.tool-versions.license @@ -1,3 +1,3 @@ -SPDX-FileCopyrightText: 2020 Zach Daniel +SPDX-FileCopyrightText: 2019 ash_postgres contributors SPDX-License-Identifier: MIT diff --git a/.vscode/settings.json.license b/.vscode/settings.json.license index 815664f3..b0a44fab 100644 --- a/.vscode/settings.json.license +++ b/.vscode/settings.json.license @@ -1,3 +1,3 @@ -SPDX-FileCopyrightText: 2020 Zach Daniel +SPDX-FileCopyrightText: 2019 ash_postgres contributors SPDX-License-Identifier: MIT diff --git a/benchmarks/bulk_create.exs b/benchmarks/bulk_create.exs index 5e665f19..c242f236 100644 --- a/benchmarks/bulk_create.exs +++ b/benchmarks/bulk_create.exs @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/config/config.exs b/config/config.exs index 5a179e32..b7f0c0b3 100644 --- a/config/config.exs +++ b/config/config.exs @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/documentation/dsls/DSL-AshPostgres.DataLayer.md.license b/documentation/dsls/DSL-AshPostgres.DataLayer.md.license index 815664f3..b0a44fab 100644 --- a/documentation/dsls/DSL-AshPostgres.DataLayer.md.license +++ b/documentation/dsls/DSL-AshPostgres.DataLayer.md.license @@ -1,3 +1,3 @@ -SPDX-FileCopyrightText: 2020 Zach Daniel +SPDX-FileCopyrightText: 2019 ash_postgres contributors SPDX-License-Identifier: MIT diff --git a/lib/ash_postgres.ex b/lib/ash_postgres.ex index 34f5cd43..f3c69313 100644 --- a/lib/ash_postgres.ex +++ b/lib/ash_postgres.ex @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/lib/check_constraint.ex b/lib/check_constraint.ex index 6534a464..679ee2a4 100644 --- a/lib/check_constraint.ex +++ b/lib/check_constraint.ex @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/lib/custom_aggregate.ex b/lib/custom_aggregate.ex index 6a42b026..af5936a9 100644 --- a/lib/custom_aggregate.ex +++ b/lib/custom_aggregate.ex @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/lib/custom_extension.ex b/lib/custom_extension.ex index 968a748c..95262e6a 100644 --- a/lib/custom_extension.ex +++ b/lib/custom_extension.ex @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/lib/custom_index.ex b/lib/custom_index.ex index 240b30d2..909dc07d 100644 --- a/lib/custom_index.ex +++ b/lib/custom_index.ex @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/lib/data_layer.ex b/lib/data_layer.ex index 637b21f4..894de3fb 100644 --- a/lib/data_layer.ex +++ b/lib/data_layer.ex @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/lib/data_layer/info.ex b/lib/data_layer/info.ex index 933ca6e8..b36e9f86 100644 --- a/lib/data_layer/info.ex +++ b/lib/data_layer/info.ex @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/lib/ecto_migration_default.ex b/lib/ecto_migration_default.ex index d865471b..1e417126 100644 --- a/lib/ecto_migration_default.ex +++ b/lib/ecto_migration_default.ex @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/lib/extensions/immutable_raise_error.ex b/lib/extensions/immutable_raise_error.ex index 22760442..a1a4032c 100644 --- a/lib/extensions/immutable_raise_error.ex +++ b/lib/extensions/immutable_raise_error.ex @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/lib/extensions/vector.ex b/lib/extensions/vector.ex index c029dcf4..ffd281af 100644 --- a/lib/extensions/vector.ex +++ b/lib/extensions/vector.ex @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/lib/functions/binding.ex b/lib/functions/binding.ex index df20a209..9f6a15e7 100644 --- a/lib/functions/binding.ex +++ b/lib/functions/binding.ex @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/lib/functions/ilike.ex b/lib/functions/ilike.ex index dd960f5f..35ee4bf0 100644 --- a/lib/functions/ilike.ex +++ b/lib/functions/ilike.ex @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/lib/functions/like.ex b/lib/functions/like.ex index fdc76c6b..bd160f66 100644 --- a/lib/functions/like.ex +++ b/lib/functions/like.ex @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/lib/functions/trigram_similarity.ex b/lib/functions/trigram_similarity.ex index 19622647..20250d90 100644 --- a/lib/functions/trigram_similarity.ex +++ b/lib/functions/trigram_similarity.ex @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/lib/functions/vector_cosine_distance.ex b/lib/functions/vector_cosine_distance.ex index 1a811583..afbb9b89 100644 --- a/lib/functions/vector_cosine_distance.ex +++ b/lib/functions/vector_cosine_distance.ex @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/lib/functions/vector_l2_distance.ex b/lib/functions/vector_l2_distance.ex index 063a1432..5d1ec62b 100644 --- a/lib/functions/vector_l2_distance.ex +++ b/lib/functions/vector_l2_distance.ex @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/lib/igniter.ex b/lib/igniter.ex index aa20746d..8d9e0808 100644 --- a/lib/igniter.ex +++ b/lib/igniter.ex @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/lib/manual_relationship.ex b/lib/manual_relationship.ex index b6322de9..c3c4f030 100644 --- a/lib/manual_relationship.ex +++ b/lib/manual_relationship.ex @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/lib/migration.ex b/lib/migration.ex index 9102d2a9..9ff83c94 100644 --- a/lib/migration.ex +++ b/lib/migration.ex @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/lib/migration_compile_cache.ex b/lib/migration_compile_cache.ex index f421d3b6..5993dffd 100644 --- a/lib/migration_compile_cache.ex +++ b/lib/migration_compile_cache.ex @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/lib/migration_generator/ash_functions.ex b/lib/migration_generator/ash_functions.ex index 1206d829..0ad49bdc 100644 --- a/lib/migration_generator/ash_functions.ex +++ b/lib/migration_generator/ash_functions.ex @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/lib/migration_generator/migration_generator.ex b/lib/migration_generator/migration_generator.ex index bdd82fba..6cdbc469 100644 --- a/lib/migration_generator/migration_generator.ex +++ b/lib/migration_generator/migration_generator.ex @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/lib/migration_generator/operation.ex b/lib/migration_generator/operation.ex index 21af504b..b7b09792 100644 --- a/lib/migration_generator/operation.ex +++ b/lib/migration_generator/operation.ex @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/lib/migration_generator/phase.ex b/lib/migration_generator/phase.ex index 9b13dadd..28e380d9 100644 --- a/lib/migration_generator/phase.ex +++ b/lib/migration_generator/phase.ex @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/lib/mix/helpers.ex b/lib/mix/helpers.ex index 51db8a64..be9b15ea 100644 --- a/lib/mix/helpers.ex +++ b/lib/mix/helpers.ex @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/lib/mix/tasks/ash_postgres.create.ex b/lib/mix/tasks/ash_postgres.create.ex index 61129c48..392f8d40 100644 --- a/lib/mix/tasks/ash_postgres.create.ex +++ b/lib/mix/tasks/ash_postgres.create.ex @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/lib/mix/tasks/ash_postgres.drop.ex b/lib/mix/tasks/ash_postgres.drop.ex index 2c50e9b3..9c3c3888 100644 --- a/lib/mix/tasks/ash_postgres.drop.ex +++ b/lib/mix/tasks/ash_postgres.drop.ex @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/lib/mix/tasks/ash_postgres.gen.resources.ex b/lib/mix/tasks/ash_postgres.gen.resources.ex index d207ea3f..1bd6125c 100644 --- a/lib/mix/tasks/ash_postgres.gen.resources.ex +++ b/lib/mix/tasks/ash_postgres.gen.resources.ex @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/lib/mix/tasks/ash_postgres.generate_migrations.ex b/lib/mix/tasks/ash_postgres.generate_migrations.ex index ca16404d..41936ce7 100644 --- a/lib/mix/tasks/ash_postgres.generate_migrations.ex +++ b/lib/mix/tasks/ash_postgres.generate_migrations.ex @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/lib/mix/tasks/ash_postgres.install.ex b/lib/mix/tasks/ash_postgres.install.ex index e7b6e0fb..321ac0e5 100644 --- a/lib/mix/tasks/ash_postgres.install.ex +++ b/lib/mix/tasks/ash_postgres.install.ex @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/lib/mix/tasks/ash_postgres.migrate.ex b/lib/mix/tasks/ash_postgres.migrate.ex index 601a5daf..9295d7d4 100644 --- a/lib/mix/tasks/ash_postgres.migrate.ex +++ b/lib/mix/tasks/ash_postgres.migrate.ex @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/lib/mix/tasks/ash_postgres.rollback.ex b/lib/mix/tasks/ash_postgres.rollback.ex index da11f74c..30e39780 100644 --- a/lib/mix/tasks/ash_postgres.rollback.ex +++ b/lib/mix/tasks/ash_postgres.rollback.ex @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/lib/mix/tasks/ash_postgres.setup_vector.ex b/lib/mix/tasks/ash_postgres.setup_vector.ex index 209c8241..80c12911 100644 --- a/lib/mix/tasks/ash_postgres.setup_vector.ex +++ b/lib/mix/tasks/ash_postgres.setup_vector.ex @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/lib/mix/tasks/ash_postgres.squash_snapshots.ex b/lib/mix/tasks/ash_postgres.squash_snapshots.ex index 8e40a597..8729d870 100644 --- a/lib/mix/tasks/ash_postgres.squash_snapshots.ex +++ b/lib/mix/tasks/ash_postgres.squash_snapshots.ex @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/lib/multitenancy.ex b/lib/multitenancy.ex index 5660e963..56d3f721 100644 --- a/lib/multitenancy.ex +++ b/lib/multitenancy.ex @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/lib/reference.ex b/lib/reference.ex index f22abc1f..68763581 100644 --- a/lib/reference.ex +++ b/lib/reference.ex @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/lib/repo.ex b/lib/repo.ex index fdc2d522..696c2442 100644 --- a/lib/repo.ex +++ b/lib/repo.ex @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/lib/repo/before_compile.ex b/lib/repo/before_compile.ex index c8306507..adb79837 100644 --- a/lib/repo/before_compile.ex +++ b/lib/repo/before_compile.ex @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/lib/resource_generator/resource_generator.ex b/lib/resource_generator/resource_generator.ex index 0f633f7b..b61a0f56 100644 --- a/lib/resource_generator/resource_generator.ex +++ b/lib/resource_generator/resource_generator.ex @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/lib/resource_generator/sensitive_data.ex b/lib/resource_generator/sensitive_data.ex index 30c94857..2adf0c18 100644 --- a/lib/resource_generator/sensitive_data.ex +++ b/lib/resource_generator/sensitive_data.ex @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/lib/resource_generator/spec.ex b/lib/resource_generator/spec.ex index c4d8088e..1a39a960 100644 --- a/lib/resource_generator/spec.ex +++ b/lib/resource_generator/spec.ex @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/lib/sql_implementation.ex b/lib/sql_implementation.ex index 84d31935..3aed4340 100644 --- a/lib/sql_implementation.ex +++ b/lib/sql_implementation.ex @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/lib/statement.ex b/lib/statement.ex index 5902d730..926d6169 100644 --- a/lib/statement.ex +++ b/lib/statement.ex @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/lib/type.ex b/lib/type.ex index 88c6ef63..d0870002 100644 --- a/lib/type.ex +++ b/lib/type.ex @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/lib/types/ci_string_wrapper.ex b/lib/types/ci_string_wrapper.ex index 5c7bb8cb..b243f71e 100644 --- a/lib/types/ci_string_wrapper.ex +++ b/lib/types/ci_string_wrapper.ex @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/lib/types/ltree.ex b/lib/types/ltree.ex index 0997bdff..29d7f9f7 100644 --- a/lib/types/ltree.ex +++ b/lib/types/ltree.ex @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/lib/types/string_wrapper.ex b/lib/types/string_wrapper.ex index 5d8c33ea..18bedc34 100644 --- a/lib/types/string_wrapper.ex +++ b/lib/types/string_wrapper.ex @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/lib/types/timestamptz.ex b/lib/types/timestamptz.ex index c684751c..83746e1b 100644 --- a/lib/types/timestamptz.ex +++ b/lib/types/timestamptz.ex @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/lib/types/timestamptz_usec.ex b/lib/types/timestamptz_usec.ex index 8bd0a38d..6c998a00 100644 --- a/lib/types/timestamptz_usec.ex +++ b/lib/types/timestamptz_usec.ex @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/lib/types/tsquery.ex b/lib/types/tsquery.ex index 8e1fb7ad..d4a97470 100644 --- a/lib/types/tsquery.ex +++ b/lib/types/tsquery.ex @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/lib/types/tsvector.ex b/lib/types/tsvector.ex index 1a29a359..193a4c0b 100644 --- a/lib/types/tsvector.ex +++ b/lib/types/tsvector.ex @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/lib/verifiers/ensure_table_or_polymorphic.ex b/lib/verifiers/ensure_table_or_polymorphic.ex index 9c1d17bc..a4268f8c 100644 --- a/lib/verifiers/ensure_table_or_polymorphic.ex +++ b/lib/verifiers/ensure_table_or_polymorphic.ex @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/lib/verifiers/prevent_attribute_multitenancy_and_non_full_match_type.ex b/lib/verifiers/prevent_attribute_multitenancy_and_non_full_match_type.ex index a595c95c..2ac5e693 100644 --- a/lib/verifiers/prevent_attribute_multitenancy_and_non_full_match_type.ex +++ b/lib/verifiers/prevent_attribute_multitenancy_and_non_full_match_type.ex @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/lib/verifiers/prevent_multidimensional_array_aggregates.ex b/lib/verifiers/prevent_multidimensional_array_aggregates.ex index 7589b277..f2c76924 100644 --- a/lib/verifiers/prevent_multidimensional_array_aggregates.ex +++ b/lib/verifiers/prevent_multidimensional_array_aggregates.ex @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/lib/verifiers/validate_identity_index_names.ex b/lib/verifiers/validate_identity_index_names.ex index 1c2fbad8..e5cf22c4 100644 --- a/lib/verifiers/validate_identity_index_names.ex +++ b/lib/verifiers/validate_identity_index_names.ex @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/lib/verifiers/validate_references.ex b/lib/verifiers/validate_references.ex index efcffd2d..50be8a30 100644 --- a/lib/verifiers/validate_references.ex +++ b/lib/verifiers/validate_references.ex @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/lib/version_agent.ex b/lib/version_agent.ex index 0db6f4ff..da93d184 100644 --- a/lib/version_agent.ex +++ b/lib/version_agent.ex @@ -1,3 +1,3 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/logos/small-logo.png.license b/logos/small-logo.png.license index 815664f3..b0a44fab 100644 --- a/logos/small-logo.png.license +++ b/logos/small-logo.png.license @@ -1,3 +1,3 @@ -SPDX-FileCopyrightText: 2020 Zach Daniel +SPDX-FileCopyrightText: 2019 ash_postgres contributors SPDX-License-Identifier: MIT diff --git a/mix.exs b/mix.exs index 0bd7385a..2c0f979c 100644 --- a/mix.exs +++ b/mix.exs @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/mix.lock.license b/mix.lock.license index 815664f3..b0a44fab 100644 --- a/mix.lock.license +++ b/mix.lock.license @@ -1,3 +1,3 @@ -SPDX-FileCopyrightText: 2020 Zach Daniel +SPDX-FileCopyrightText: 2019 ash_postgres contributors SPDX-License-Identifier: MIT diff --git a/priv/dev_test_repo/migrations/20250526214825_migrate_resources_extensions_1.exs b/priv/dev_test_repo/migrations/20250526214825_migrate_resources_extensions_1.exs index 57fc3e50..1b4d0d71 100644 --- a/priv/dev_test_repo/migrations/20250526214825_migrate_resources_extensions_1.exs +++ b/priv/dev_test_repo/migrations/20250526214825_migrate_resources_extensions_1.exs @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/priv/dev_test_repo/migrations/20250526214827_migrate_resources1.exs b/priv/dev_test_repo/migrations/20250526214827_migrate_resources1.exs index bc0f2abf..da8cdb0f 100644 --- a/priv/dev_test_repo/migrations/20250526214827_migrate_resources1.exs +++ b/priv/dev_test_repo/migrations/20250526214827_migrate_resources1.exs @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/dev_test_repo/extensions.json.license b/priv/resource_snapshots/dev_test_repo/extensions.json.license index 815664f3..b0a44fab 100644 --- a/priv/resource_snapshots/dev_test_repo/extensions.json.license +++ b/priv/resource_snapshots/dev_test_repo/extensions.json.license @@ -1,3 +1,3 @@ -SPDX-FileCopyrightText: 2020 Zach Daniel +SPDX-FileCopyrightText: 2019 ash_postgres contributors SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/dev_test_repo/multitenant_orgs/20250526214827.json.license b/priv/resource_snapshots/dev_test_repo/multitenant_orgs/20250526214827.json.license index 815664f3..b0a44fab 100644 --- a/priv/resource_snapshots/dev_test_repo/multitenant_orgs/20250526214827.json.license +++ b/priv/resource_snapshots/dev_test_repo/multitenant_orgs/20250526214827.json.license @@ -1,3 +1,3 @@ -SPDX-FileCopyrightText: 2020 Zach Daniel +SPDX-FileCopyrightText: 2019 ash_postgres contributors SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_no_sandbox_repo/extensions.json.license b/priv/resource_snapshots/test_no_sandbox_repo/extensions.json.license index 815664f3..b0a44fab 100644 --- a/priv/resource_snapshots/test_no_sandbox_repo/extensions.json.license +++ b/priv/resource_snapshots/test_no_sandbox_repo/extensions.json.license @@ -1,3 +1,3 @@ -SPDX-FileCopyrightText: 2020 Zach Daniel +SPDX-FileCopyrightText: 2019 ash_postgres contributors SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/accounts/20221217123726.json.license b/priv/resource_snapshots/test_repo/accounts/20221217123726.json.license index 815664f3..b0a44fab 100644 --- a/priv/resource_snapshots/test_repo/accounts/20221217123726.json.license +++ b/priv/resource_snapshots/test_repo/accounts/20221217123726.json.license @@ -1,3 +1,3 @@ -SPDX-FileCopyrightText: 2020 Zach Daniel +SPDX-FileCopyrightText: 2019 ash_postgres contributors SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/accounts/20240327211150.json.license b/priv/resource_snapshots/test_repo/accounts/20240327211150.json.license index 815664f3..b0a44fab 100644 --- a/priv/resource_snapshots/test_repo/accounts/20240327211150.json.license +++ b/priv/resource_snapshots/test_repo/accounts/20240327211150.json.license @@ -1,3 +1,3 @@ -SPDX-FileCopyrightText: 2020 Zach Daniel +SPDX-FileCopyrightText: 2019 ash_postgres contributors SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/authors/20220805191443.json.license b/priv/resource_snapshots/test_repo/authors/20220805191443.json.license index 815664f3..b0a44fab 100644 --- a/priv/resource_snapshots/test_repo/authors/20220805191443.json.license +++ b/priv/resource_snapshots/test_repo/authors/20220805191443.json.license @@ -1,3 +1,3 @@ -SPDX-FileCopyrightText: 2020 Zach Daniel +SPDX-FileCopyrightText: 2019 ash_postgres contributors SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/authors/20220914104733.json.license b/priv/resource_snapshots/test_repo/authors/20220914104733.json.license index 815664f3..b0a44fab 100644 --- a/priv/resource_snapshots/test_repo/authors/20220914104733.json.license +++ b/priv/resource_snapshots/test_repo/authors/20220914104733.json.license @@ -1,3 +1,3 @@ -SPDX-FileCopyrightText: 2020 Zach Daniel +SPDX-FileCopyrightText: 2019 ash_postgres contributors SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/authors/20240327211150.json.license b/priv/resource_snapshots/test_repo/authors/20240327211150.json.license index 815664f3..b0a44fab 100644 --- a/priv/resource_snapshots/test_repo/authors/20240327211150.json.license +++ b/priv/resource_snapshots/test_repo/authors/20240327211150.json.license @@ -1,3 +1,3 @@ -SPDX-FileCopyrightText: 2020 Zach Daniel +SPDX-FileCopyrightText: 2019 ash_postgres contributors SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/authors/20240705113722.json.license b/priv/resource_snapshots/test_repo/authors/20240705113722.json.license index 815664f3..b0a44fab 100644 --- a/priv/resource_snapshots/test_repo/authors/20240705113722.json.license +++ b/priv/resource_snapshots/test_repo/authors/20240705113722.json.license @@ -1,3 +1,3 @@ -SPDX-FileCopyrightText: 2020 Zach Daniel +SPDX-FileCopyrightText: 2019 ash_postgres contributors SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/authors/20250908212414.json.license b/priv/resource_snapshots/test_repo/authors/20250908212414.json.license index 815664f3..b0a44fab 100644 --- a/priv/resource_snapshots/test_repo/authors/20250908212414.json.license +++ b/priv/resource_snapshots/test_repo/authors/20250908212414.json.license @@ -1,3 +1,3 @@ -SPDX-FileCopyrightText: 2020 Zach Daniel +SPDX-FileCopyrightText: 2019 ash_postgres contributors SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/chats/20250908093505.json.license b/priv/resource_snapshots/test_repo/chats/20250908093505.json.license index 815664f3..b0a44fab 100644 --- a/priv/resource_snapshots/test_repo/chats/20250908093505.json.license +++ b/priv/resource_snapshots/test_repo/chats/20250908093505.json.license @@ -1,3 +1,3 @@ -SPDX-FileCopyrightText: 2020 Zach Daniel +SPDX-FileCopyrightText: 2019 ash_postgres contributors SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/co_authored_posts/20241208221219.json.license b/priv/resource_snapshots/test_repo/co_authored_posts/20241208221219.json.license index 815664f3..b0a44fab 100644 --- a/priv/resource_snapshots/test_repo/co_authored_posts/20241208221219.json.license +++ b/priv/resource_snapshots/test_repo/co_authored_posts/20241208221219.json.license @@ -1,3 +1,3 @@ -SPDX-FileCopyrightText: 2020 Zach Daniel +SPDX-FileCopyrightText: 2019 ash_postgres contributors SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/comedians/20241217232254.json.license b/priv/resource_snapshots/test_repo/comedians/20241217232254.json.license index 815664f3..b0a44fab 100644 --- a/priv/resource_snapshots/test_repo/comedians/20241217232254.json.license +++ b/priv/resource_snapshots/test_repo/comedians/20241217232254.json.license @@ -1,3 +1,3 @@ -SPDX-FileCopyrightText: 2020 Zach Daniel +SPDX-FileCopyrightText: 2019 ash_postgres contributors SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/comedians/20250413141328.json.license b/priv/resource_snapshots/test_repo/comedians/20250413141328.json.license index 815664f3..b0a44fab 100644 --- a/priv/resource_snapshots/test_repo/comedians/20250413141328.json.license +++ b/priv/resource_snapshots/test_repo/comedians/20250413141328.json.license @@ -1,3 +1,3 @@ -SPDX-FileCopyrightText: 2020 Zach Daniel +SPDX-FileCopyrightText: 2019 ash_postgres contributors SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/comment_links/20250123161002.json.license b/priv/resource_snapshots/test_repo/comment_links/20250123161002.json.license index 815664f3..b0a44fab 100644 --- a/priv/resource_snapshots/test_repo/comment_links/20250123161002.json.license +++ b/priv/resource_snapshots/test_repo/comment_links/20250123161002.json.license @@ -1,3 +1,3 @@ -SPDX-FileCopyrightText: 2020 Zach Daniel +SPDX-FileCopyrightText: 2019 ash_postgres contributors SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/comment_ratings/20220805191443.json.license b/priv/resource_snapshots/test_repo/comment_ratings/20220805191443.json.license index 815664f3..b0a44fab 100644 --- a/priv/resource_snapshots/test_repo/comment_ratings/20220805191443.json.license +++ b/priv/resource_snapshots/test_repo/comment_ratings/20220805191443.json.license @@ -1,3 +1,3 @@ -SPDX-FileCopyrightText: 2020 Zach Daniel +SPDX-FileCopyrightText: 2019 ash_postgres contributors SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/comment_ratings/20240327211150.json.license b/priv/resource_snapshots/test_repo/comment_ratings/20240327211150.json.license index 815664f3..b0a44fab 100644 --- a/priv/resource_snapshots/test_repo/comment_ratings/20240327211150.json.license +++ b/priv/resource_snapshots/test_repo/comment_ratings/20240327211150.json.license @@ -1,3 +1,3 @@ -SPDX-FileCopyrightText: 2020 Zach Daniel +SPDX-FileCopyrightText: 2019 ash_postgres contributors SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/comments/20220805191443.json.license b/priv/resource_snapshots/test_repo/comments/20220805191443.json.license index 815664f3..b0a44fab 100644 --- a/priv/resource_snapshots/test_repo/comments/20220805191443.json.license +++ b/priv/resource_snapshots/test_repo/comments/20220805191443.json.license @@ -1,3 +1,3 @@ -SPDX-FileCopyrightText: 2020 Zach Daniel +SPDX-FileCopyrightText: 2019 ash_postgres contributors SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/comments/20240327211150.json.license b/priv/resource_snapshots/test_repo/comments/20240327211150.json.license index 815664f3..b0a44fab 100644 --- a/priv/resource_snapshots/test_repo/comments/20240327211150.json.license +++ b/priv/resource_snapshots/test_repo/comments/20240327211150.json.license @@ -1,3 +1,3 @@ -SPDX-FileCopyrightText: 2020 Zach Daniel +SPDX-FileCopyrightText: 2019 ash_postgres contributors SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/comments/20240327211917.json.license b/priv/resource_snapshots/test_repo/comments/20240327211917.json.license index 815664f3..b0a44fab 100644 --- a/priv/resource_snapshots/test_repo/comments/20240327211917.json.license +++ b/priv/resource_snapshots/test_repo/comments/20240327211917.json.license @@ -1,3 +1,3 @@ -SPDX-FileCopyrightText: 2020 Zach Daniel +SPDX-FileCopyrightText: 2019 ash_postgres contributors SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/complex_calculations_certifications/20230816231942.json.license b/priv/resource_snapshots/test_repo/complex_calculations_certifications/20230816231942.json.license index 815664f3..b0a44fab 100644 --- a/priv/resource_snapshots/test_repo/complex_calculations_certifications/20230816231942.json.license +++ b/priv/resource_snapshots/test_repo/complex_calculations_certifications/20230816231942.json.license @@ -1,3 +1,3 @@ -SPDX-FileCopyrightText: 2020 Zach Daniel +SPDX-FileCopyrightText: 2019 ash_postgres contributors SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/complex_calculations_certifications/20240327211150.json.license b/priv/resource_snapshots/test_repo/complex_calculations_certifications/20240327211150.json.license index 815664f3..b0a44fab 100644 --- a/priv/resource_snapshots/test_repo/complex_calculations_certifications/20240327211150.json.license +++ b/priv/resource_snapshots/test_repo/complex_calculations_certifications/20240327211150.json.license @@ -1,3 +1,3 @@ -SPDX-FileCopyrightText: 2020 Zach Daniel +SPDX-FileCopyrightText: 2019 ash_postgres contributors SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/complex_calculations_certifications_channel_members/20231116013020.json.license b/priv/resource_snapshots/test_repo/complex_calculations_certifications_channel_members/20231116013020.json.license index 815664f3..b0a44fab 100644 --- a/priv/resource_snapshots/test_repo/complex_calculations_certifications_channel_members/20231116013020.json.license +++ b/priv/resource_snapshots/test_repo/complex_calculations_certifications_channel_members/20231116013020.json.license @@ -1,3 +1,3 @@ -SPDX-FileCopyrightText: 2020 Zach Daniel +SPDX-FileCopyrightText: 2019 ash_postgres contributors SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/complex_calculations_certifications_channel_members/20240327211150.json.license b/priv/resource_snapshots/test_repo/complex_calculations_certifications_channel_members/20240327211150.json.license index 815664f3..b0a44fab 100644 --- a/priv/resource_snapshots/test_repo/complex_calculations_certifications_channel_members/20240327211150.json.license +++ b/priv/resource_snapshots/test_repo/complex_calculations_certifications_channel_members/20240327211150.json.license @@ -1,3 +1,3 @@ -SPDX-FileCopyrightText: 2020 Zach Daniel +SPDX-FileCopyrightText: 2019 ash_postgres contributors SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/complex_calculations_certifications_channel_members/20240327211917.json.license b/priv/resource_snapshots/test_repo/complex_calculations_certifications_channel_members/20240327211917.json.license index 815664f3..b0a44fab 100644 --- a/priv/resource_snapshots/test_repo/complex_calculations_certifications_channel_members/20240327211917.json.license +++ b/priv/resource_snapshots/test_repo/complex_calculations_certifications_channel_members/20240327211917.json.license @@ -1,3 +1,3 @@ -SPDX-FileCopyrightText: 2020 Zach Daniel +SPDX-FileCopyrightText: 2019 ash_postgres contributors SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/complex_calculations_channels/20231116013020.json.license b/priv/resource_snapshots/test_repo/complex_calculations_channels/20231116013020.json.license index 815664f3..b0a44fab 100644 --- a/priv/resource_snapshots/test_repo/complex_calculations_channels/20231116013020.json.license +++ b/priv/resource_snapshots/test_repo/complex_calculations_channels/20231116013020.json.license @@ -1,3 +1,3 @@ -SPDX-FileCopyrightText: 2020 Zach Daniel +SPDX-FileCopyrightText: 2019 ash_postgres contributors SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/complex_calculations_channels/20240327211150.json.license b/priv/resource_snapshots/test_repo/complex_calculations_channels/20240327211150.json.license index 815664f3..b0a44fab 100644 --- a/priv/resource_snapshots/test_repo/complex_calculations_channels/20240327211150.json.license +++ b/priv/resource_snapshots/test_repo/complex_calculations_channels/20240327211150.json.license @@ -1,3 +1,3 @@ -SPDX-FileCopyrightText: 2020 Zach Daniel +SPDX-FileCopyrightText: 2019 ash_postgres contributors SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/complex_calculations_channels/20240327211917.json.license b/priv/resource_snapshots/test_repo/complex_calculations_channels/20240327211917.json.license index 815664f3..b0a44fab 100644 --- a/priv/resource_snapshots/test_repo/complex_calculations_channels/20240327211917.json.license +++ b/priv/resource_snapshots/test_repo/complex_calculations_channels/20240327211917.json.license @@ -1,3 +1,3 @@ -SPDX-FileCopyrightText: 2020 Zach Daniel +SPDX-FileCopyrightText: 2019 ash_postgres contributors SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/complex_calculations_documentations/20230816231942.json.license b/priv/resource_snapshots/test_repo/complex_calculations_documentations/20230816231942.json.license index 815664f3..b0a44fab 100644 --- a/priv/resource_snapshots/test_repo/complex_calculations_documentations/20230816231942.json.license +++ b/priv/resource_snapshots/test_repo/complex_calculations_documentations/20230816231942.json.license @@ -1,3 +1,3 @@ -SPDX-FileCopyrightText: 2020 Zach Daniel +SPDX-FileCopyrightText: 2019 ash_postgres contributors SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/complex_calculations_documentations/20240327211150.json.license b/priv/resource_snapshots/test_repo/complex_calculations_documentations/20240327211150.json.license index 815664f3..b0a44fab 100644 --- a/priv/resource_snapshots/test_repo/complex_calculations_documentations/20240327211150.json.license +++ b/priv/resource_snapshots/test_repo/complex_calculations_documentations/20240327211150.json.license @@ -1,3 +1,3 @@ -SPDX-FileCopyrightText: 2020 Zach Daniel +SPDX-FileCopyrightText: 2019 ash_postgres contributors SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/complex_calculations_documentations/20240327211917.json.license b/priv/resource_snapshots/test_repo/complex_calculations_documentations/20240327211917.json.license index 815664f3..b0a44fab 100644 --- a/priv/resource_snapshots/test_repo/complex_calculations_documentations/20240327211917.json.license +++ b/priv/resource_snapshots/test_repo/complex_calculations_documentations/20240327211917.json.license @@ -1,3 +1,3 @@ -SPDX-FileCopyrightText: 2020 Zach Daniel +SPDX-FileCopyrightText: 2019 ash_postgres contributors SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/complex_calculations_folder_items/20250714225304.json.license b/priv/resource_snapshots/test_repo/complex_calculations_folder_items/20250714225304.json.license index 815664f3..b0a44fab 100644 --- a/priv/resource_snapshots/test_repo/complex_calculations_folder_items/20250714225304.json.license +++ b/priv/resource_snapshots/test_repo/complex_calculations_folder_items/20250714225304.json.license @@ -1,3 +1,3 @@ -SPDX-FileCopyrightText: 2020 Zach Daniel +SPDX-FileCopyrightText: 2019 ash_postgres contributors SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/complex_calculations_folders/20250714225304.json.license b/priv/resource_snapshots/test_repo/complex_calculations_folders/20250714225304.json.license index 815664f3..b0a44fab 100644 --- a/priv/resource_snapshots/test_repo/complex_calculations_folders/20250714225304.json.license +++ b/priv/resource_snapshots/test_repo/complex_calculations_folders/20250714225304.json.license @@ -1,3 +1,3 @@ -SPDX-FileCopyrightText: 2020 Zach Daniel +SPDX-FileCopyrightText: 2019 ash_postgres contributors SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/complex_calculations_skills/20230816231942.json.license b/priv/resource_snapshots/test_repo/complex_calculations_skills/20230816231942.json.license index 815664f3..b0a44fab 100644 --- a/priv/resource_snapshots/test_repo/complex_calculations_skills/20230816231942.json.license +++ b/priv/resource_snapshots/test_repo/complex_calculations_skills/20230816231942.json.license @@ -1,3 +1,3 @@ -SPDX-FileCopyrightText: 2020 Zach Daniel +SPDX-FileCopyrightText: 2019 ash_postgres contributors SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/complex_calculations_skills/20240327211150.json.license b/priv/resource_snapshots/test_repo/complex_calculations_skills/20240327211150.json.license index 815664f3..b0a44fab 100644 --- a/priv/resource_snapshots/test_repo/complex_calculations_skills/20240327211150.json.license +++ b/priv/resource_snapshots/test_repo/complex_calculations_skills/20240327211150.json.license @@ -1,3 +1,3 @@ -SPDX-FileCopyrightText: 2020 Zach Daniel +SPDX-FileCopyrightText: 2019 ash_postgres contributors SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/content/20250123164209.json.license b/priv/resource_snapshots/test_repo/content/20250123164209.json.license index 815664f3..b0a44fab 100644 --- a/priv/resource_snapshots/test_repo/content/20250123164209.json.license +++ b/priv/resource_snapshots/test_repo/content/20250123164209.json.license @@ -1,3 +1,3 @@ -SPDX-FileCopyrightText: 2020 Zach Daniel +SPDX-FileCopyrightText: 2019 ash_postgres contributors SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/content_visibility_group/20250123164209.json.license b/priv/resource_snapshots/test_repo/content_visibility_group/20250123164209.json.license index 815664f3..b0a44fab 100644 --- a/priv/resource_snapshots/test_repo/content_visibility_group/20250123164209.json.license +++ b/priv/resource_snapshots/test_repo/content_visibility_group/20250123164209.json.license @@ -1,3 +1,3 @@ -SPDX-FileCopyrightText: 2020 Zach Daniel +SPDX-FileCopyrightText: 2019 ash_postgres contributors SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/csv/20250320225052.json.license b/priv/resource_snapshots/test_repo/csv/20250320225052.json.license index 815664f3..b0a44fab 100644 --- a/priv/resource_snapshots/test_repo/csv/20250320225052.json.license +++ b/priv/resource_snapshots/test_repo/csv/20250320225052.json.license @@ -1,3 +1,3 @@ -SPDX-FileCopyrightText: 2020 Zach Daniel +SPDX-FileCopyrightText: 2019 ash_postgres contributors SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/customers/20250908073737.json.license b/priv/resource_snapshots/test_repo/customers/20250908073737.json.license index 815664f3..b0a44fab 100644 --- a/priv/resource_snapshots/test_repo/customers/20250908073737.json.license +++ b/priv/resource_snapshots/test_repo/customers/20250908073737.json.license @@ -1,3 +1,3 @@ -SPDX-FileCopyrightText: 2020 Zach Daniel +SPDX-FileCopyrightText: 2019 ash_postgres contributors SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/entities/20240109160153.json.license b/priv/resource_snapshots/test_repo/entities/20240109160153.json.license index 815664f3..b0a44fab 100644 --- a/priv/resource_snapshots/test_repo/entities/20240109160153.json.license +++ b/priv/resource_snapshots/test_repo/entities/20240109160153.json.license @@ -1,3 +1,3 @@ -SPDX-FileCopyrightText: 2020 Zach Daniel +SPDX-FileCopyrightText: 2019 ash_postgres contributors SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/entities/20240327211150.json.license b/priv/resource_snapshots/test_repo/entities/20240327211150.json.license index 815664f3..b0a44fab 100644 --- a/priv/resource_snapshots/test_repo/entities/20240327211150.json.license +++ b/priv/resource_snapshots/test_repo/entities/20240327211150.json.license @@ -1,3 +1,3 @@ -SPDX-FileCopyrightText: 2020 Zach Daniel +SPDX-FileCopyrightText: 2019 ash_postgres contributors SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/entities/20240327211917.json.license b/priv/resource_snapshots/test_repo/entities/20240327211917.json.license index 815664f3..b0a44fab 100644 --- a/priv/resource_snapshots/test_repo/entities/20240327211917.json.license +++ b/priv/resource_snapshots/test_repo/entities/20240327211917.json.license @@ -1,3 +1,3 @@ -SPDX-FileCopyrightText: 2020 Zach Daniel +SPDX-FileCopyrightText: 2019 ash_postgres contributors SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/extensions.json.license b/priv/resource_snapshots/test_repo/extensions.json.license index 815664f3..b0a44fab 100644 --- a/priv/resource_snapshots/test_repo/extensions.json.license +++ b/priv/resource_snapshots/test_repo/extensions.json.license @@ -1,3 +1,3 @@ -SPDX-FileCopyrightText: 2020 Zach Daniel +SPDX-FileCopyrightText: 2019 ash_postgres contributors SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/integer_posts/20220805191443.json.license b/priv/resource_snapshots/test_repo/integer_posts/20220805191443.json.license index 815664f3..b0a44fab 100644 --- a/priv/resource_snapshots/test_repo/integer_posts/20220805191443.json.license +++ b/priv/resource_snapshots/test_repo/integer_posts/20220805191443.json.license @@ -1,3 +1,3 @@ -SPDX-FileCopyrightText: 2020 Zach Daniel +SPDX-FileCopyrightText: 2019 ash_postgres contributors SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/items/20240713134055.json.license b/priv/resource_snapshots/test_repo/items/20240713134055.json.license index 815664f3..b0a44fab 100644 --- a/priv/resource_snapshots/test_repo/items/20240713134055.json.license +++ b/priv/resource_snapshots/test_repo/items/20240713134055.json.license @@ -1,3 +1,3 @@ -SPDX-FileCopyrightText: 2020 Zach Daniel +SPDX-FileCopyrightText: 2019 ash_postgres contributors SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/items/20240717104854.json.license b/priv/resource_snapshots/test_repo/items/20240717104854.json.license index 815664f3..b0a44fab 100644 --- a/priv/resource_snapshots/test_repo/items/20240717104854.json.license +++ b/priv/resource_snapshots/test_repo/items/20240717104854.json.license @@ -1,3 +1,3 @@ -SPDX-FileCopyrightText: 2020 Zach Daniel +SPDX-FileCopyrightText: 2019 ash_postgres contributors SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/items/20240717153736.json.license b/priv/resource_snapshots/test_repo/items/20240717153736.json.license index 815664f3..b0a44fab 100644 --- a/priv/resource_snapshots/test_repo/items/20240717153736.json.license +++ b/priv/resource_snapshots/test_repo/items/20240717153736.json.license @@ -1,3 +1,3 @@ -SPDX-FileCopyrightText: 2020 Zach Daniel +SPDX-FileCopyrightText: 2019 ash_postgres contributors SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/jokes/20241217232254.json.license b/priv/resource_snapshots/test_repo/jokes/20241217232254.json.license index 815664f3..b0a44fab 100644 --- a/priv/resource_snapshots/test_repo/jokes/20241217232254.json.license +++ b/priv/resource_snapshots/test_repo/jokes/20241217232254.json.license @@ -1,3 +1,3 @@ -SPDX-FileCopyrightText: 2020 Zach Daniel +SPDX-FileCopyrightText: 2019 ash_postgres contributors SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/jokes/20250413141328.json.license b/priv/resource_snapshots/test_repo/jokes/20250413141328.json.license index 815664f3..b0a44fab 100644 --- a/priv/resource_snapshots/test_repo/jokes/20250413141328.json.license +++ b/priv/resource_snapshots/test_repo/jokes/20250413141328.json.license @@ -1,3 +1,3 @@ -SPDX-FileCopyrightText: 2020 Zach Daniel +SPDX-FileCopyrightText: 2019 ash_postgres contributors SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/managers/20230526144249.json.license b/priv/resource_snapshots/test_repo/managers/20230526144249.json.license index 815664f3..b0a44fab 100644 --- a/priv/resource_snapshots/test_repo/managers/20230526144249.json.license +++ b/priv/resource_snapshots/test_repo/managers/20230526144249.json.license @@ -1,3 +1,3 @@ -SPDX-FileCopyrightText: 2020 Zach Daniel +SPDX-FileCopyrightText: 2019 ash_postgres contributors SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/managers/20240327211150.json.license b/priv/resource_snapshots/test_repo/managers/20240327211150.json.license index 815664f3..b0a44fab 100644 --- a/priv/resource_snapshots/test_repo/managers/20240327211150.json.license +++ b/priv/resource_snapshots/test_repo/managers/20240327211150.json.license @@ -1,3 +1,3 @@ -SPDX-FileCopyrightText: 2020 Zach Daniel +SPDX-FileCopyrightText: 2019 ash_postgres contributors SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/messages/20250908093505.json.license b/priv/resource_snapshots/test_repo/messages/20250908093505.json.license index 815664f3..b0a44fab 100644 --- a/priv/resource_snapshots/test_repo/messages/20250908093505.json.license +++ b/priv/resource_snapshots/test_repo/messages/20250908093505.json.license @@ -1,3 +1,3 @@ -SPDX-FileCopyrightText: 2020 Zach Daniel +SPDX-FileCopyrightText: 2019 ash_postgres contributors SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/multitenant_named_orgs/20250519103535.json.license b/priv/resource_snapshots/test_repo/multitenant_named_orgs/20250519103535.json.license index 815664f3..b0a44fab 100644 --- a/priv/resource_snapshots/test_repo/multitenant_named_orgs/20250519103535.json.license +++ b/priv/resource_snapshots/test_repo/multitenant_named_orgs/20250519103535.json.license @@ -1,3 +1,3 @@ -SPDX-FileCopyrightText: 2020 Zach Daniel +SPDX-FileCopyrightText: 2019 ash_postgres contributors SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/multitenant_orgs/20220805191443.json.license b/priv/resource_snapshots/test_repo/multitenant_orgs/20220805191443.json.license index 815664f3..b0a44fab 100644 --- a/priv/resource_snapshots/test_repo/multitenant_orgs/20220805191443.json.license +++ b/priv/resource_snapshots/test_repo/multitenant_orgs/20220805191443.json.license @@ -1,3 +1,3 @@ -SPDX-FileCopyrightText: 2020 Zach Daniel +SPDX-FileCopyrightText: 2019 ash_postgres contributors SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/multitenant_orgs/20240327211150.json.license b/priv/resource_snapshots/test_repo/multitenant_orgs/20240327211150.json.license index 815664f3..b0a44fab 100644 --- a/priv/resource_snapshots/test_repo/multitenant_orgs/20240327211150.json.license +++ b/priv/resource_snapshots/test_repo/multitenant_orgs/20240327211150.json.license @@ -1,3 +1,3 @@ -SPDX-FileCopyrightText: 2020 Zach Daniel +SPDX-FileCopyrightText: 2019 ash_postgres contributors SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/multitenant_orgs/20240627223225.json.license b/priv/resource_snapshots/test_repo/multitenant_orgs/20240627223225.json.license index 815664f3..b0a44fab 100644 --- a/priv/resource_snapshots/test_repo/multitenant_orgs/20240627223225.json.license +++ b/priv/resource_snapshots/test_repo/multitenant_orgs/20240627223225.json.license @@ -1,3 +1,3 @@ -SPDX-FileCopyrightText: 2020 Zach Daniel +SPDX-FileCopyrightText: 2019 ash_postgres contributors SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/multitenant_orgs/20240702164513.json.license b/priv/resource_snapshots/test_repo/multitenant_orgs/20240702164513.json.license index 815664f3..b0a44fab 100644 --- a/priv/resource_snapshots/test_repo/multitenant_orgs/20240702164513.json.license +++ b/priv/resource_snapshots/test_repo/multitenant_orgs/20240702164513.json.license @@ -1,3 +1,3 @@ -SPDX-FileCopyrightText: 2020 Zach Daniel +SPDX-FileCopyrightText: 2019 ash_postgres contributors SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/multitenant_orgs/20240703155134.json.license b/priv/resource_snapshots/test_repo/multitenant_orgs/20240703155134.json.license index 815664f3..b0a44fab 100644 --- a/priv/resource_snapshots/test_repo/multitenant_orgs/20240703155134.json.license +++ b/priv/resource_snapshots/test_repo/multitenant_orgs/20240703155134.json.license @@ -1,3 +1,3 @@ -SPDX-FileCopyrightText: 2020 Zach Daniel +SPDX-FileCopyrightText: 2019 ash_postgres contributors SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/non_multitenant_post_links/20250122190558.json.license b/priv/resource_snapshots/test_repo/non_multitenant_post_links/20250122190558.json.license index 815664f3..b0a44fab 100644 --- a/priv/resource_snapshots/test_repo/non_multitenant_post_links/20250122190558.json.license +++ b/priv/resource_snapshots/test_repo/non_multitenant_post_links/20250122190558.json.license @@ -1,3 +1,3 @@ -SPDX-FileCopyrightText: 2020 Zach Daniel +SPDX-FileCopyrightText: 2019 ash_postgres contributors SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/note/20250123164209.json.license b/priv/resource_snapshots/test_repo/note/20250123164209.json.license index 815664f3..b0a44fab 100644 --- a/priv/resource_snapshots/test_repo/note/20250123164209.json.license +++ b/priv/resource_snapshots/test_repo/note/20250123164209.json.license @@ -1,3 +1,3 @@ -SPDX-FileCopyrightText: 2020 Zach Daniel +SPDX-FileCopyrightText: 2019 ash_postgres contributors SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/orders/20250908073737.json.license b/priv/resource_snapshots/test_repo/orders/20250908073737.json.license index 815664f3..b0a44fab 100644 --- a/priv/resource_snapshots/test_repo/orders/20250908073737.json.license +++ b/priv/resource_snapshots/test_repo/orders/20250908073737.json.license @@ -1,3 +1,3 @@ -SPDX-FileCopyrightText: 2020 Zach Daniel +SPDX-FileCopyrightText: 2019 ash_postgres contributors SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/orgs/20230129050950.json.license b/priv/resource_snapshots/test_repo/orgs/20230129050950.json.license index 815664f3..b0a44fab 100644 --- a/priv/resource_snapshots/test_repo/orgs/20230129050950.json.license +++ b/priv/resource_snapshots/test_repo/orgs/20230129050950.json.license @@ -1,3 +1,3 @@ -SPDX-FileCopyrightText: 2020 Zach Daniel +SPDX-FileCopyrightText: 2019 ash_postgres contributors SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/orgs/20240327211150.json.license b/priv/resource_snapshots/test_repo/orgs/20240327211150.json.license index 815664f3..b0a44fab 100644 --- a/priv/resource_snapshots/test_repo/orgs/20240327211150.json.license +++ b/priv/resource_snapshots/test_repo/orgs/20240327211150.json.license @@ -1,3 +1,3 @@ -SPDX-FileCopyrightText: 2020 Zach Daniel +SPDX-FileCopyrightText: 2019 ash_postgres contributors SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/orgs/20250210191116.json.license b/priv/resource_snapshots/test_repo/orgs/20250210191116.json.license index 815664f3..b0a44fab 100644 --- a/priv/resource_snapshots/test_repo/orgs/20250210191116.json.license +++ b/priv/resource_snapshots/test_repo/orgs/20250210191116.json.license @@ -1,3 +1,3 @@ -SPDX-FileCopyrightText: 2020 Zach Daniel +SPDX-FileCopyrightText: 2019 ash_postgres contributors SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/other_items/20240713134055.json.license b/priv/resource_snapshots/test_repo/other_items/20240713134055.json.license index 815664f3..b0a44fab 100644 --- a/priv/resource_snapshots/test_repo/other_items/20240713134055.json.license +++ b/priv/resource_snapshots/test_repo/other_items/20240713134055.json.license @@ -1,3 +1,3 @@ -SPDX-FileCopyrightText: 2020 Zach Daniel +SPDX-FileCopyrightText: 2019 ash_postgres contributors SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/other_items/20240717151815.json.license b/priv/resource_snapshots/test_repo/other_items/20240717151815.json.license index 815664f3..b0a44fab 100644 --- a/priv/resource_snapshots/test_repo/other_items/20240717151815.json.license +++ b/priv/resource_snapshots/test_repo/other_items/20240717151815.json.license @@ -1,3 +1,3 @@ -SPDX-FileCopyrightText: 2020 Zach Daniel +SPDX-FileCopyrightText: 2019 ash_postgres contributors SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/points/20250313112823.json.license b/priv/resource_snapshots/test_repo/points/20250313112823.json.license index 815664f3..b0a44fab 100644 --- a/priv/resource_snapshots/test_repo/points/20250313112823.json.license +++ b/priv/resource_snapshots/test_repo/points/20250313112823.json.license @@ -1,3 +1,3 @@ -SPDX-FileCopyrightText: 2020 Zach Daniel +SPDX-FileCopyrightText: 2019 ash_postgres contributors SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/post_followers/20240227180858.json.license b/priv/resource_snapshots/test_repo/post_followers/20240227180858.json.license index 815664f3..b0a44fab 100644 --- a/priv/resource_snapshots/test_repo/post_followers/20240227180858.json.license +++ b/priv/resource_snapshots/test_repo/post_followers/20240227180858.json.license @@ -1,3 +1,3 @@ -SPDX-FileCopyrightText: 2020 Zach Daniel +SPDX-FileCopyrightText: 2019 ash_postgres contributors SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/post_followers/20240227181137.json.license b/priv/resource_snapshots/test_repo/post_followers/20240227181137.json.license index 815664f3..b0a44fab 100644 --- a/priv/resource_snapshots/test_repo/post_followers/20240227181137.json.license +++ b/priv/resource_snapshots/test_repo/post_followers/20240227181137.json.license @@ -1,3 +1,3 @@ -SPDX-FileCopyrightText: 2020 Zach Daniel +SPDX-FileCopyrightText: 2019 ash_postgres contributors SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/post_followers/20240327211150.json.license b/priv/resource_snapshots/test_repo/post_followers/20240327211150.json.license index 815664f3..b0a44fab 100644 --- a/priv/resource_snapshots/test_repo/post_followers/20240327211150.json.license +++ b/priv/resource_snapshots/test_repo/post_followers/20240327211150.json.license @@ -1,3 +1,3 @@ -SPDX-FileCopyrightText: 2020 Zach Daniel +SPDX-FileCopyrightText: 2019 ash_postgres contributors SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/post_followers/20240516205244.json.license b/priv/resource_snapshots/test_repo/post_followers/20240516205244.json.license index 815664f3..b0a44fab 100644 --- a/priv/resource_snapshots/test_repo/post_followers/20240516205244.json.license +++ b/priv/resource_snapshots/test_repo/post_followers/20240516205244.json.license @@ -1,3 +1,3 @@ -SPDX-FileCopyrightText: 2020 Zach Daniel +SPDX-FileCopyrightText: 2019 ash_postgres contributors SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/post_followers/20240517223946.json.license b/priv/resource_snapshots/test_repo/post_followers/20240517223946.json.license index 815664f3..b0a44fab 100644 --- a/priv/resource_snapshots/test_repo/post_followers/20240517223946.json.license +++ b/priv/resource_snapshots/test_repo/post_followers/20240517223946.json.license @@ -1,3 +1,3 @@ -SPDX-FileCopyrightText: 2020 Zach Daniel +SPDX-FileCopyrightText: 2019 ash_postgres contributors SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/post_links/20220805191443.json.license b/priv/resource_snapshots/test_repo/post_links/20220805191443.json.license index 815664f3..b0a44fab 100644 --- a/priv/resource_snapshots/test_repo/post_links/20220805191443.json.license +++ b/priv/resource_snapshots/test_repo/post_links/20220805191443.json.license @@ -1,3 +1,3 @@ -SPDX-FileCopyrightText: 2020 Zach Daniel +SPDX-FileCopyrightText: 2019 ash_postgres contributors SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/post_links/20221017133955.json.license b/priv/resource_snapshots/test_repo/post_links/20221017133955.json.license index 815664f3..b0a44fab 100644 --- a/priv/resource_snapshots/test_repo/post_links/20221017133955.json.license +++ b/priv/resource_snapshots/test_repo/post_links/20221017133955.json.license @@ -1,3 +1,3 @@ -SPDX-FileCopyrightText: 2020 Zach Daniel +SPDX-FileCopyrightText: 2019 ash_postgres contributors SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/post_links/20221202194704.json.license b/priv/resource_snapshots/test_repo/post_links/20221202194704.json.license index 815664f3..b0a44fab 100644 --- a/priv/resource_snapshots/test_repo/post_links/20221202194704.json.license +++ b/priv/resource_snapshots/test_repo/post_links/20221202194704.json.license @@ -1,3 +1,3 @@ -SPDX-FileCopyrightText: 2020 Zach Daniel +SPDX-FileCopyrightText: 2019 ash_postgres contributors SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/post_links/20240610195853.json.license b/priv/resource_snapshots/test_repo/post_links/20240610195853.json.license index 815664f3..b0a44fab 100644 --- a/priv/resource_snapshots/test_repo/post_links/20240610195853.json.license +++ b/priv/resource_snapshots/test_repo/post_links/20240610195853.json.license @@ -1,3 +1,3 @@ -SPDX-FileCopyrightText: 2020 Zach Daniel +SPDX-FileCopyrightText: 2019 ash_postgres contributors SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/post_links/20240617193218.json.license b/priv/resource_snapshots/test_repo/post_links/20240617193218.json.license index 815664f3..b0a44fab 100644 --- a/priv/resource_snapshots/test_repo/post_links/20240617193218.json.license +++ b/priv/resource_snapshots/test_repo/post_links/20240617193218.json.license @@ -1,3 +1,3 @@ -SPDX-FileCopyrightText: 2020 Zach Daniel +SPDX-FileCopyrightText: 2019 ash_postgres contributors SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/post_permalinks/20240906170759.json.license b/priv/resource_snapshots/test_repo/post_permalinks/20240906170759.json.license index 815664f3..b0a44fab 100644 --- a/priv/resource_snapshots/test_repo/post_permalinks/20240906170759.json.license +++ b/priv/resource_snapshots/test_repo/post_permalinks/20240906170759.json.license @@ -1,3 +1,3 @@ -SPDX-FileCopyrightText: 2020 Zach Daniel +SPDX-FileCopyrightText: 2019 ash_postgres contributors SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/post_ratings/20220805191443.json.license b/priv/resource_snapshots/test_repo/post_ratings/20220805191443.json.license index 815664f3..b0a44fab 100644 --- a/priv/resource_snapshots/test_repo/post_ratings/20220805191443.json.license +++ b/priv/resource_snapshots/test_repo/post_ratings/20220805191443.json.license @@ -1,3 +1,3 @@ -SPDX-FileCopyrightText: 2020 Zach Daniel +SPDX-FileCopyrightText: 2019 ash_postgres contributors SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/post_ratings/20240327211150.json.license b/priv/resource_snapshots/test_repo/post_ratings/20240327211150.json.license index 815664f3..b0a44fab 100644 --- a/priv/resource_snapshots/test_repo/post_ratings/20240327211150.json.license +++ b/priv/resource_snapshots/test_repo/post_ratings/20240327211150.json.license @@ -1,3 +1,3 @@ -SPDX-FileCopyrightText: 2020 Zach Daniel +SPDX-FileCopyrightText: 2019 ash_postgres contributors SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/post_tags/20250810102512.json.license b/priv/resource_snapshots/test_repo/post_tags/20250810102512.json.license index 815664f3..b0a44fab 100644 --- a/priv/resource_snapshots/test_repo/post_tags/20250810102512.json.license +++ b/priv/resource_snapshots/test_repo/post_tags/20250810102512.json.license @@ -1,3 +1,3 @@ -SPDX-FileCopyrightText: 2020 Zach Daniel +SPDX-FileCopyrightText: 2019 ash_postgres contributors SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/post_views/20230905050351.json.license b/priv/resource_snapshots/test_repo/post_views/20230905050351.json.license index 815664f3..b0a44fab 100644 --- a/priv/resource_snapshots/test_repo/post_views/20230905050351.json.license +++ b/priv/resource_snapshots/test_repo/post_views/20230905050351.json.license @@ -1,3 +1,3 @@ -SPDX-FileCopyrightText: 2020 Zach Daniel +SPDX-FileCopyrightText: 2019 ash_postgres contributors SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/post_views/20240327211917.json.license b/priv/resource_snapshots/test_repo/post_views/20240327211917.json.license index 815664f3..b0a44fab 100644 --- a/priv/resource_snapshots/test_repo/post_views/20240327211917.json.license +++ b/priv/resource_snapshots/test_repo/post_views/20240327211917.json.license @@ -1,3 +1,3 @@ -SPDX-FileCopyrightText: 2020 Zach Daniel +SPDX-FileCopyrightText: 2019 ash_postgres contributors SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/posts/20220805191443.json.license b/priv/resource_snapshots/test_repo/posts/20220805191443.json.license index 815664f3..b0a44fab 100644 --- a/priv/resource_snapshots/test_repo/posts/20220805191443.json.license +++ b/priv/resource_snapshots/test_repo/posts/20220805191443.json.license @@ -1,3 +1,3 @@ -SPDX-FileCopyrightText: 2020 Zach Daniel +SPDX-FileCopyrightText: 2019 ash_postgres contributors SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/posts/20221125171150.json.license b/priv/resource_snapshots/test_repo/posts/20221125171150.json.license index 815664f3..b0a44fab 100644 --- a/priv/resource_snapshots/test_repo/posts/20221125171150.json.license +++ b/priv/resource_snapshots/test_repo/posts/20221125171150.json.license @@ -1,3 +1,3 @@ -SPDX-FileCopyrightText: 2020 Zach Daniel +SPDX-FileCopyrightText: 2019 ash_postgres contributors SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/posts/20221125171204.json.license b/priv/resource_snapshots/test_repo/posts/20221125171204.json.license index 815664f3..b0a44fab 100644 --- a/priv/resource_snapshots/test_repo/posts/20221125171204.json.license +++ b/priv/resource_snapshots/test_repo/posts/20221125171204.json.license @@ -1,3 +1,3 @@ -SPDX-FileCopyrightText: 2020 Zach Daniel +SPDX-FileCopyrightText: 2019 ash_postgres contributors SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/posts/20230129050950.json.license b/priv/resource_snapshots/test_repo/posts/20230129050950.json.license index 815664f3..b0a44fab 100644 --- a/priv/resource_snapshots/test_repo/posts/20230129050950.json.license +++ b/priv/resource_snapshots/test_repo/posts/20230129050950.json.license @@ -1,3 +1,3 @@ -SPDX-FileCopyrightText: 2020 Zach Daniel +SPDX-FileCopyrightText: 2019 ash_postgres contributors SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/posts/20230823161017.json.license b/priv/resource_snapshots/test_repo/posts/20230823161017.json.license index 815664f3..b0a44fab 100644 --- a/priv/resource_snapshots/test_repo/posts/20230823161017.json.license +++ b/priv/resource_snapshots/test_repo/posts/20230823161017.json.license @@ -1,3 +1,3 @@ -SPDX-FileCopyrightText: 2020 Zach Daniel +SPDX-FileCopyrightText: 2019 ash_postgres contributors SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/posts/20231127215636.json.license b/priv/resource_snapshots/test_repo/posts/20231127215636.json.license index 815664f3..b0a44fab 100644 --- a/priv/resource_snapshots/test_repo/posts/20231127215636.json.license +++ b/priv/resource_snapshots/test_repo/posts/20231127215636.json.license @@ -1,3 +1,3 @@ -SPDX-FileCopyrightText: 2020 Zach Daniel +SPDX-FileCopyrightText: 2019 ash_postgres contributors SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/posts/20231129141453.json.license b/priv/resource_snapshots/test_repo/posts/20231129141453.json.license index 815664f3..b0a44fab 100644 --- a/priv/resource_snapshots/test_repo/posts/20231129141453.json.license +++ b/priv/resource_snapshots/test_repo/posts/20231129141453.json.license @@ -1,3 +1,3 @@ -SPDX-FileCopyrightText: 2020 Zach Daniel +SPDX-FileCopyrightText: 2019 ash_postgres contributors SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/posts/20231219132807.json.license b/priv/resource_snapshots/test_repo/posts/20231219132807.json.license index 815664f3..b0a44fab 100644 --- a/priv/resource_snapshots/test_repo/posts/20231219132807.json.license +++ b/priv/resource_snapshots/test_repo/posts/20231219132807.json.license @@ -1,3 +1,3 @@ -SPDX-FileCopyrightText: 2020 Zach Daniel +SPDX-FileCopyrightText: 2019 ash_postgres contributors SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/posts/20240129221511.json.license b/priv/resource_snapshots/test_repo/posts/20240129221511.json.license index 815664f3..b0a44fab 100644 --- a/priv/resource_snapshots/test_repo/posts/20240129221511.json.license +++ b/priv/resource_snapshots/test_repo/posts/20240129221511.json.license @@ -1,3 +1,3 @@ -SPDX-FileCopyrightText: 2020 Zach Daniel +SPDX-FileCopyrightText: 2019 ash_postgres contributors SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/posts/20240224001913.json.license b/priv/resource_snapshots/test_repo/posts/20240224001913.json.license index 815664f3..b0a44fab 100644 --- a/priv/resource_snapshots/test_repo/posts/20240224001913.json.license +++ b/priv/resource_snapshots/test_repo/posts/20240224001913.json.license @@ -1,3 +1,3 @@ -SPDX-FileCopyrightText: 2020 Zach Daniel +SPDX-FileCopyrightText: 2019 ash_postgres contributors SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/posts/20240327211150.json.license b/priv/resource_snapshots/test_repo/posts/20240327211150.json.license index 815664f3..b0a44fab 100644 --- a/priv/resource_snapshots/test_repo/posts/20240327211150.json.license +++ b/priv/resource_snapshots/test_repo/posts/20240327211150.json.license @@ -1,3 +1,3 @@ -SPDX-FileCopyrightText: 2020 Zach Daniel +SPDX-FileCopyrightText: 2019 ash_postgres contributors SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/posts/20240327211917.json.license b/priv/resource_snapshots/test_repo/posts/20240327211917.json.license index 815664f3..b0a44fab 100644 --- a/priv/resource_snapshots/test_repo/posts/20240327211917.json.license +++ b/priv/resource_snapshots/test_repo/posts/20240327211917.json.license @@ -1,3 +1,3 @@ -SPDX-FileCopyrightText: 2020 Zach Daniel +SPDX-FileCopyrightText: 2019 ash_postgres contributors SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/posts/20240503012410.json.license b/priv/resource_snapshots/test_repo/posts/20240503012410.json.license index 815664f3..b0a44fab 100644 --- a/priv/resource_snapshots/test_repo/posts/20240503012410.json.license +++ b/priv/resource_snapshots/test_repo/posts/20240503012410.json.license @@ -1,3 +1,3 @@ -SPDX-FileCopyrightText: 2020 Zach Daniel +SPDX-FileCopyrightText: 2019 ash_postgres contributors SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/posts/20240504185511.json.license b/priv/resource_snapshots/test_repo/posts/20240504185511.json.license index 815664f3..b0a44fab 100644 --- a/priv/resource_snapshots/test_repo/posts/20240504185511.json.license +++ b/priv/resource_snapshots/test_repo/posts/20240504185511.json.license @@ -1,3 +1,3 @@ -SPDX-FileCopyrightText: 2020 Zach Daniel +SPDX-FileCopyrightText: 2019 ash_postgres contributors SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/posts/20240524031113.json.license b/priv/resource_snapshots/test_repo/posts/20240524031113.json.license index 815664f3..b0a44fab 100644 --- a/priv/resource_snapshots/test_repo/posts/20240524031113.json.license +++ b/priv/resource_snapshots/test_repo/posts/20240524031113.json.license @@ -1,3 +1,3 @@ -SPDX-FileCopyrightText: 2020 Zach Daniel +SPDX-FileCopyrightText: 2019 ash_postgres contributors SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/posts/20240524041750.json.license b/priv/resource_snapshots/test_repo/posts/20240524041750.json.license index 815664f3..b0a44fab 100644 --- a/priv/resource_snapshots/test_repo/posts/20240524041750.json.license +++ b/priv/resource_snapshots/test_repo/posts/20240524041750.json.license @@ -1,3 +1,3 @@ -SPDX-FileCopyrightText: 2020 Zach Daniel +SPDX-FileCopyrightText: 2019 ash_postgres contributors SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/posts/20240617193218.json.license b/priv/resource_snapshots/test_repo/posts/20240617193218.json.license index 815664f3..b0a44fab 100644 --- a/priv/resource_snapshots/test_repo/posts/20240617193218.json.license +++ b/priv/resource_snapshots/test_repo/posts/20240617193218.json.license @@ -1,3 +1,3 @@ -SPDX-FileCopyrightText: 2020 Zach Daniel +SPDX-FileCopyrightText: 2019 ash_postgres contributors SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/posts/20240618102809.json.license b/priv/resource_snapshots/test_repo/posts/20240618102809.json.license index 815664f3..b0a44fab 100644 --- a/priv/resource_snapshots/test_repo/posts/20240618102809.json.license +++ b/priv/resource_snapshots/test_repo/posts/20240618102809.json.license @@ -1,3 +1,3 @@ -SPDX-FileCopyrightText: 2020 Zach Daniel +SPDX-FileCopyrightText: 2019 ash_postgres contributors SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/posts/20240712232026.json.license b/priv/resource_snapshots/test_repo/posts/20240712232026.json.license index 815664f3..b0a44fab 100644 --- a/priv/resource_snapshots/test_repo/posts/20240712232026.json.license +++ b/priv/resource_snapshots/test_repo/posts/20240712232026.json.license @@ -1,3 +1,3 @@ -SPDX-FileCopyrightText: 2020 Zach Daniel +SPDX-FileCopyrightText: 2019 ash_postgres contributors SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/posts/20240715135403.json.license b/priv/resource_snapshots/test_repo/posts/20240715135403.json.license index 815664f3..b0a44fab 100644 --- a/priv/resource_snapshots/test_repo/posts/20240715135403.json.license +++ b/priv/resource_snapshots/test_repo/posts/20240715135403.json.license @@ -1,3 +1,3 @@ -SPDX-FileCopyrightText: 2020 Zach Daniel +SPDX-FileCopyrightText: 2019 ash_postgres contributors SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/posts/20240910180107.json.license b/priv/resource_snapshots/test_repo/posts/20240910180107.json.license index 815664f3..b0a44fab 100644 --- a/priv/resource_snapshots/test_repo/posts/20240910180107.json.license +++ b/priv/resource_snapshots/test_repo/posts/20240910180107.json.license @@ -1,3 +1,3 @@ -SPDX-FileCopyrightText: 2020 Zach Daniel +SPDX-FileCopyrightText: 2019 ash_postgres contributors SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/posts/20240911225320.json.license b/priv/resource_snapshots/test_repo/posts/20240911225320.json.license index 815664f3..b0a44fab 100644 --- a/priv/resource_snapshots/test_repo/posts/20240911225320.json.license +++ b/priv/resource_snapshots/test_repo/posts/20240911225320.json.license @@ -1,3 +1,3 @@ -SPDX-FileCopyrightText: 2020 Zach Daniel +SPDX-FileCopyrightText: 2019 ash_postgres contributors SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/posts/20240918104740.json.license b/priv/resource_snapshots/test_repo/posts/20240918104740.json.license index 815664f3..b0a44fab 100644 --- a/priv/resource_snapshots/test_repo/posts/20240918104740.json.license +++ b/priv/resource_snapshots/test_repo/posts/20240918104740.json.license @@ -1,3 +1,3 @@ -SPDX-FileCopyrightText: 2020 Zach Daniel +SPDX-FileCopyrightText: 2019 ash_postgres contributors SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/posts/20240929121224.json.license b/priv/resource_snapshots/test_repo/posts/20240929121224.json.license index 815664f3..b0a44fab 100644 --- a/priv/resource_snapshots/test_repo/posts/20240929121224.json.license +++ b/priv/resource_snapshots/test_repo/posts/20240929121224.json.license @@ -1,3 +1,3 @@ -SPDX-FileCopyrightText: 2020 Zach Daniel +SPDX-FileCopyrightText: 2019 ash_postgres contributors SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/posts/20250217054207.json.license b/priv/resource_snapshots/test_repo/posts/20250217054207.json.license index 815664f3..b0a44fab 100644 --- a/priv/resource_snapshots/test_repo/posts/20250217054207.json.license +++ b/priv/resource_snapshots/test_repo/posts/20250217054207.json.license @@ -1,3 +1,3 @@ -SPDX-FileCopyrightText: 2020 Zach Daniel +SPDX-FileCopyrightText: 2019 ash_postgres contributors SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/posts/20250313112823.json.license b/priv/resource_snapshots/test_repo/posts/20250313112823.json.license index 815664f3..b0a44fab 100644 --- a/priv/resource_snapshots/test_repo/posts/20250313112823.json.license +++ b/priv/resource_snapshots/test_repo/posts/20250313112823.json.license @@ -1,3 +1,3 @@ -SPDX-FileCopyrightText: 2020 Zach Daniel +SPDX-FileCopyrightText: 2019 ash_postgres contributors SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/posts/20250520130634.json.license b/priv/resource_snapshots/test_repo/posts/20250520130634.json.license index 815664f3..b0a44fab 100644 --- a/priv/resource_snapshots/test_repo/posts/20250520130634.json.license +++ b/priv/resource_snapshots/test_repo/posts/20250520130634.json.license @@ -1,3 +1,3 @@ -SPDX-FileCopyrightText: 2020 Zach Daniel +SPDX-FileCopyrightText: 2019 ash_postgres contributors SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/posts/20250521105654.json.license b/priv/resource_snapshots/test_repo/posts/20250521105654.json.license index 815664f3..b0a44fab 100644 --- a/priv/resource_snapshots/test_repo/posts/20250521105654.json.license +++ b/priv/resource_snapshots/test_repo/posts/20250521105654.json.license @@ -1,3 +1,3 @@ -SPDX-FileCopyrightText: 2020 Zach Daniel +SPDX-FileCopyrightText: 2019 ash_postgres contributors SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/posts/20250612113920.json.license b/priv/resource_snapshots/test_repo/posts/20250612113920.json.license index 815664f3..b0a44fab 100644 --- a/priv/resource_snapshots/test_repo/posts/20250612113920.json.license +++ b/priv/resource_snapshots/test_repo/posts/20250612113920.json.license @@ -1,3 +1,3 @@ -SPDX-FileCopyrightText: 2020 Zach Daniel +SPDX-FileCopyrightText: 2019 ash_postgres contributors SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/posts/20250618011917.json.license b/priv/resource_snapshots/test_repo/posts/20250618011917.json.license index 815664f3..b0a44fab 100644 --- a/priv/resource_snapshots/test_repo/posts/20250618011917.json.license +++ b/priv/resource_snapshots/test_repo/posts/20250618011917.json.license @@ -1,3 +1,3 @@ -SPDX-FileCopyrightText: 2020 Zach Daniel +SPDX-FileCopyrightText: 2019 ash_postgres contributors SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/products/20250908073737.json.license b/priv/resource_snapshots/test_repo/products/20250908073737.json.license index 815664f3..b0a44fab 100644 --- a/priv/resource_snapshots/test_repo/products/20250908073737.json.license +++ b/priv/resource_snapshots/test_repo/products/20250908073737.json.license @@ -1,3 +1,3 @@ -SPDX-FileCopyrightText: 2020 Zach Daniel +SPDX-FileCopyrightText: 2019 ash_postgres contributors SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/profile/20220805191443.json.license b/priv/resource_snapshots/test_repo/profile/20220805191443.json.license index 815664f3..b0a44fab 100644 --- a/priv/resource_snapshots/test_repo/profile/20220805191443.json.license +++ b/priv/resource_snapshots/test_repo/profile/20220805191443.json.license @@ -1,3 +1,3 @@ -SPDX-FileCopyrightText: 2020 Zach Daniel +SPDX-FileCopyrightText: 2019 ash_postgres contributors SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/profiles.profile/20240327211150.json.license b/priv/resource_snapshots/test_repo/profiles.profile/20240327211150.json.license index 815664f3..b0a44fab 100644 --- a/priv/resource_snapshots/test_repo/profiles.profile/20240327211150.json.license +++ b/priv/resource_snapshots/test_repo/profiles.profile/20240327211150.json.license @@ -1,3 +1,3 @@ -SPDX-FileCopyrightText: 2020 Zach Daniel +SPDX-FileCopyrightText: 2019 ash_postgres contributors SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/punchlines/20250413141328.json.license b/priv/resource_snapshots/test_repo/punchlines/20250413141328.json.license index 815664f3..b0a44fab 100644 --- a/priv/resource_snapshots/test_repo/punchlines/20250413141328.json.license +++ b/priv/resource_snapshots/test_repo/punchlines/20250413141328.json.license @@ -1,3 +1,3 @@ -SPDX-FileCopyrightText: 2020 Zach Daniel +SPDX-FileCopyrightText: 2019 ash_postgres contributors SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/records/20240109160153.json.license b/priv/resource_snapshots/test_repo/records/20240109160153.json.license index 815664f3..b0a44fab 100644 --- a/priv/resource_snapshots/test_repo/records/20240109160153.json.license +++ b/priv/resource_snapshots/test_repo/records/20240109160153.json.license @@ -1,3 +1,3 @@ -SPDX-FileCopyrightText: 2020 Zach Daniel +SPDX-FileCopyrightText: 2019 ash_postgres contributors SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/records/20240327211150.json.license b/priv/resource_snapshots/test_repo/records/20240327211150.json.license index 815664f3..b0a44fab 100644 --- a/priv/resource_snapshots/test_repo/records/20240327211150.json.license +++ b/priv/resource_snapshots/test_repo/records/20240327211150.json.license @@ -1,3 +1,3 @@ -SPDX-FileCopyrightText: 2020 Zach Daniel +SPDX-FileCopyrightText: 2019 ash_postgres contributors SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/records/20240327211917.json.license b/priv/resource_snapshots/test_repo/records/20240327211917.json.license index 815664f3..b0a44fab 100644 --- a/priv/resource_snapshots/test_repo/records/20240327211917.json.license +++ b/priv/resource_snapshots/test_repo/records/20240327211917.json.license @@ -1,3 +1,3 @@ -SPDX-FileCopyrightText: 2020 Zach Daniel +SPDX-FileCopyrightText: 2019 ash_postgres contributors SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/records_temp_entities/20250605230457.json.license b/priv/resource_snapshots/test_repo/records_temp_entities/20250605230457.json.license index 815664f3..b0a44fab 100644 --- a/priv/resource_snapshots/test_repo/records_temp_entities/20250605230457.json.license +++ b/priv/resource_snapshots/test_repo/records_temp_entities/20250605230457.json.license @@ -1,3 +1,3 @@ -SPDX-FileCopyrightText: 2020 Zach Daniel +SPDX-FileCopyrightText: 2019 ash_postgres contributors SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/relationship_items/20240717153736.json.license b/priv/resource_snapshots/test_repo/relationship_items/20240717153736.json.license index 815664f3..b0a44fab 100644 --- a/priv/resource_snapshots/test_repo/relationship_items/20240717153736.json.license +++ b/priv/resource_snapshots/test_repo/relationship_items/20240717153736.json.license @@ -1,3 +1,3 @@ -SPDX-FileCopyrightText: 2020 Zach Daniel +SPDX-FileCopyrightText: 2019 ash_postgres contributors SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/rsvps/20251002180954.json.license b/priv/resource_snapshots/test_repo/rsvps/20251002180954.json.license index 815664f3..b0a44fab 100644 --- a/priv/resource_snapshots/test_repo/rsvps/20251002180954.json.license +++ b/priv/resource_snapshots/test_repo/rsvps/20251002180954.json.license @@ -1,3 +1,3 @@ -SPDX-FileCopyrightText: 2020 Zach Daniel +SPDX-FileCopyrightText: 2019 ash_postgres contributors SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/schematic_groups/20240821213522.json.license b/priv/resource_snapshots/test_repo/schematic_groups/20240821213522.json.license index 815664f3..b0a44fab 100644 --- a/priv/resource_snapshots/test_repo/schematic_groups/20240821213522.json.license +++ b/priv/resource_snapshots/test_repo/schematic_groups/20240821213522.json.license @@ -1,3 +1,3 @@ -SPDX-FileCopyrightText: 2020 Zach Daniel +SPDX-FileCopyrightText: 2019 ash_postgres contributors SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/staff_group/20250123164209.json.license b/priv/resource_snapshots/test_repo/staff_group/20250123164209.json.license index 815664f3..b0a44fab 100644 --- a/priv/resource_snapshots/test_repo/staff_group/20250123164209.json.license +++ b/priv/resource_snapshots/test_repo/staff_group/20250123164209.json.license @@ -1,3 +1,3 @@ -SPDX-FileCopyrightText: 2020 Zach Daniel +SPDX-FileCopyrightText: 2019 ash_postgres contributors SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/staff_group_member/20250123164209.json.license b/priv/resource_snapshots/test_repo/staff_group_member/20250123164209.json.license index 815664f3..b0a44fab 100644 --- a/priv/resource_snapshots/test_repo/staff_group_member/20250123164209.json.license +++ b/priv/resource_snapshots/test_repo/staff_group_member/20250123164209.json.license @@ -1,3 +1,3 @@ -SPDX-FileCopyrightText: 2020 Zach Daniel +SPDX-FileCopyrightText: 2019 ash_postgres contributors SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/standup_clubs/20250413141328.json.license b/priv/resource_snapshots/test_repo/standup_clubs/20250413141328.json.license index 815664f3..b0a44fab 100644 --- a/priv/resource_snapshots/test_repo/standup_clubs/20250413141328.json.license +++ b/priv/resource_snapshots/test_repo/standup_clubs/20250413141328.json.license @@ -1,3 +1,3 @@ -SPDX-FileCopyrightText: 2020 Zach Daniel +SPDX-FileCopyrightText: 2019 ash_postgres contributors SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/stateful_post_followers/20240618085942.json.license b/priv/resource_snapshots/test_repo/stateful_post_followers/20240618085942.json.license index 815664f3..b0a44fab 100644 --- a/priv/resource_snapshots/test_repo/stateful_post_followers/20240618085942.json.license +++ b/priv/resource_snapshots/test_repo/stateful_post_followers/20240618085942.json.license @@ -1,3 +1,3 @@ -SPDX-FileCopyrightText: 2020 Zach Daniel +SPDX-FileCopyrightText: 2019 ash_postgres contributors SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/string_points/20250313112823.json.license b/priv/resource_snapshots/test_repo/string_points/20250313112823.json.license index 815664f3..b0a44fab 100644 --- a/priv/resource_snapshots/test_repo/string_points/20250313112823.json.license +++ b/priv/resource_snapshots/test_repo/string_points/20250313112823.json.license @@ -1,3 +1,3 @@ -SPDX-FileCopyrightText: 2020 Zach Daniel +SPDX-FileCopyrightText: 2019 ash_postgres contributors SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/sub_items/20240713134055.json.license b/priv/resource_snapshots/test_repo/sub_items/20240713134055.json.license index 815664f3..b0a44fab 100644 --- a/priv/resource_snapshots/test_repo/sub_items/20240713134055.json.license +++ b/priv/resource_snapshots/test_repo/sub_items/20240713134055.json.license @@ -1,3 +1,3 @@ -SPDX-FileCopyrightText: 2020 Zach Daniel +SPDX-FileCopyrightText: 2019 ash_postgres contributors SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/subquery_access/20240130133933.json.license b/priv/resource_snapshots/test_repo/subquery_access/20240130133933.json.license index 815664f3..b0a44fab 100644 --- a/priv/resource_snapshots/test_repo/subquery_access/20240130133933.json.license +++ b/priv/resource_snapshots/test_repo/subquery_access/20240130133933.json.license @@ -1,3 +1,3 @@ -SPDX-FileCopyrightText: 2020 Zach Daniel +SPDX-FileCopyrightText: 2019 ash_postgres contributors SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/subquery_child/20240130133933.json.license b/priv/resource_snapshots/test_repo/subquery_child/20240130133933.json.license index 815664f3..b0a44fab 100644 --- a/priv/resource_snapshots/test_repo/subquery_child/20240130133933.json.license +++ b/priv/resource_snapshots/test_repo/subquery_child/20240130133933.json.license @@ -1,3 +1,3 @@ -SPDX-FileCopyrightText: 2020 Zach Daniel +SPDX-FileCopyrightText: 2019 ash_postgres contributors SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/subquery_parent/20240130133933.json.license b/priv/resource_snapshots/test_repo/subquery_parent/20240130133933.json.license index 815664f3..b0a44fab 100644 --- a/priv/resource_snapshots/test_repo/subquery_parent/20240130133933.json.license +++ b/priv/resource_snapshots/test_repo/subquery_parent/20240130133933.json.license @@ -1,3 +1,3 @@ -SPDX-FileCopyrightText: 2020 Zach Daniel +SPDX-FileCopyrightText: 2019 ash_postgres contributors SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/subquery_through/20240130133933.json.license b/priv/resource_snapshots/test_repo/subquery_through/20240130133933.json.license index 815664f3..b0a44fab 100644 --- a/priv/resource_snapshots/test_repo/subquery_through/20240130133933.json.license +++ b/priv/resource_snapshots/test_repo/subquery_through/20240130133933.json.license @@ -1,3 +1,3 @@ -SPDX-FileCopyrightText: 2020 Zach Daniel +SPDX-FileCopyrightText: 2019 ash_postgres contributors SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/tags/20250810102512.json.license b/priv/resource_snapshots/test_repo/tags/20250810102512.json.license index 815664f3..b0a44fab 100644 --- a/priv/resource_snapshots/test_repo/tags/20250810102512.json.license +++ b/priv/resource_snapshots/test_repo/tags/20250810102512.json.license @@ -1,3 +1,3 @@ -SPDX-FileCopyrightText: 2020 Zach Daniel +SPDX-FileCopyrightText: 2019 ash_postgres contributors SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/temp.temp_entities/20240327211150.json.license b/priv/resource_snapshots/test_repo/temp.temp_entities/20240327211150.json.license index 815664f3..b0a44fab 100644 --- a/priv/resource_snapshots/test_repo/temp.temp_entities/20240327211150.json.license +++ b/priv/resource_snapshots/test_repo/temp.temp_entities/20240327211150.json.license @@ -1,3 +1,3 @@ -SPDX-FileCopyrightText: 2020 Zach Daniel +SPDX-FileCopyrightText: 2019 ash_postgres contributors SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/temp.temp_entities/20240327211917.json.license b/priv/resource_snapshots/test_repo/temp.temp_entities/20240327211917.json.license index 815664f3..b0a44fab 100644 --- a/priv/resource_snapshots/test_repo/temp.temp_entities/20240327211917.json.license +++ b/priv/resource_snapshots/test_repo/temp.temp_entities/20240327211917.json.license @@ -1,3 +1,3 @@ -SPDX-FileCopyrightText: 2020 Zach Daniel +SPDX-FileCopyrightText: 2019 ash_postgres contributors SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/temp_entities/20240109160153.json.license b/priv/resource_snapshots/test_repo/temp_entities/20240109160153.json.license index 815664f3..b0a44fab 100644 --- a/priv/resource_snapshots/test_repo/temp_entities/20240109160153.json.license +++ b/priv/resource_snapshots/test_repo/temp_entities/20240109160153.json.license @@ -1,3 +1,3 @@ -SPDX-FileCopyrightText: 2020 Zach Daniel +SPDX-FileCopyrightText: 2019 ash_postgres contributors SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/tenants/composite_key/20250220073135.json.license b/priv/resource_snapshots/test_repo/tenants/composite_key/20250220073135.json.license index 815664f3..b0a44fab 100644 --- a/priv/resource_snapshots/test_repo/tenants/composite_key/20250220073135.json.license +++ b/priv/resource_snapshots/test_repo/tenants/composite_key/20250220073135.json.license @@ -1,3 +1,3 @@ -SPDX-FileCopyrightText: 2020 Zach Daniel +SPDX-FileCopyrightText: 2019 ash_postgres contributors SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/tenants/composite_key/20250220073141.json.license b/priv/resource_snapshots/test_repo/tenants/composite_key/20250220073141.json.license index 815664f3..b0a44fab 100644 --- a/priv/resource_snapshots/test_repo/tenants/composite_key/20250220073141.json.license +++ b/priv/resource_snapshots/test_repo/tenants/composite_key/20250220073141.json.license @@ -1,3 +1,3 @@ -SPDX-FileCopyrightText: 2020 Zach Daniel +SPDX-FileCopyrightText: 2019 ash_postgres contributors SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/tenants/cross_tenant_post_links/20250122203454.json.license b/priv/resource_snapshots/test_repo/tenants/cross_tenant_post_links/20250122203454.json.license index 815664f3..b0a44fab 100644 --- a/priv/resource_snapshots/test_repo/tenants/cross_tenant_post_links/20250122203454.json.license +++ b/priv/resource_snapshots/test_repo/tenants/cross_tenant_post_links/20250122203454.json.license @@ -1,3 +1,3 @@ -SPDX-FileCopyrightText: 2020 Zach Daniel +SPDX-FileCopyrightText: 2019 ash_postgres contributors SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/tenants/friend_links/20240610162043.json.license b/priv/resource_snapshots/test_repo/tenants/friend_links/20240610162043.json.license index 815664f3..b0a44fab 100644 --- a/priv/resource_snapshots/test_repo/tenants/friend_links/20240610162043.json.license +++ b/priv/resource_snapshots/test_repo/tenants/friend_links/20240610162043.json.license @@ -1,3 +1,3 @@ -SPDX-FileCopyrightText: 2020 Zach Daniel +SPDX-FileCopyrightText: 2019 ash_postgres contributors SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/tenants/multitenant_posts/20220805191441.json.license b/priv/resource_snapshots/test_repo/tenants/multitenant_posts/20220805191441.json.license index 815664f3..b0a44fab 100644 --- a/priv/resource_snapshots/test_repo/tenants/multitenant_posts/20220805191441.json.license +++ b/priv/resource_snapshots/test_repo/tenants/multitenant_posts/20220805191441.json.license @@ -1,3 +1,3 @@ -SPDX-FileCopyrightText: 2020 Zach Daniel +SPDX-FileCopyrightText: 2019 ash_postgres contributors SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/tenants/multitenant_posts/20240327211149.json.license b/priv/resource_snapshots/test_repo/tenants/multitenant_posts/20240327211149.json.license index 815664f3..b0a44fab 100644 --- a/priv/resource_snapshots/test_repo/tenants/multitenant_posts/20240327211149.json.license +++ b/priv/resource_snapshots/test_repo/tenants/multitenant_posts/20240327211149.json.license @@ -1,3 +1,3 @@ -SPDX-FileCopyrightText: 2020 Zach Daniel +SPDX-FileCopyrightText: 2019 ash_postgres contributors SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/tenants/non_multitenant_post_multitenant_links/20251001120813.json.license b/priv/resource_snapshots/test_repo/tenants/non_multitenant_post_multitenant_links/20251001120813.json.license index 815664f3..b0a44fab 100644 --- a/priv/resource_snapshots/test_repo/tenants/non_multitenant_post_multitenant_links/20251001120813.json.license +++ b/priv/resource_snapshots/test_repo/tenants/non_multitenant_post_multitenant_links/20251001120813.json.license @@ -1,3 +1,3 @@ -SPDX-FileCopyrightText: 2020 Zach Daniel +SPDX-FileCopyrightText: 2019 ash_postgres contributors SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/unrelated_profiles/20250731124648.json.license b/priv/resource_snapshots/test_repo/unrelated_profiles/20250731124648.json.license index 815664f3..b0a44fab 100644 --- a/priv/resource_snapshots/test_repo/unrelated_profiles/20250731124648.json.license +++ b/priv/resource_snapshots/test_repo/unrelated_profiles/20250731124648.json.license @@ -1,3 +1,3 @@ -SPDX-FileCopyrightText: 2020 Zach Daniel +SPDX-FileCopyrightText: 2019 ash_postgres contributors SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/unrelated_reports/20250731124648.json.license b/priv/resource_snapshots/test_repo/unrelated_reports/20250731124648.json.license index 815664f3..b0a44fab 100644 --- a/priv/resource_snapshots/test_repo/unrelated_reports/20250731124648.json.license +++ b/priv/resource_snapshots/test_repo/unrelated_reports/20250731124648.json.license @@ -1,3 +1,3 @@ -SPDX-FileCopyrightText: 2020 Zach Daniel +SPDX-FileCopyrightText: 2019 ash_postgres contributors SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/unrelated_secure_profiles/20250731124648.json.license b/priv/resource_snapshots/test_repo/unrelated_secure_profiles/20250731124648.json.license index 815664f3..b0a44fab 100644 --- a/priv/resource_snapshots/test_repo/unrelated_secure_profiles/20250731124648.json.license +++ b/priv/resource_snapshots/test_repo/unrelated_secure_profiles/20250731124648.json.license @@ -1,3 +1,3 @@ -SPDX-FileCopyrightText: 2020 Zach Daniel +SPDX-FileCopyrightText: 2019 ash_postgres contributors SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/unrelated_users/20250731124648.json.license b/priv/resource_snapshots/test_repo/unrelated_users/20250731124648.json.license index 815664f3..b0a44fab 100644 --- a/priv/resource_snapshots/test_repo/unrelated_users/20250731124648.json.license +++ b/priv/resource_snapshots/test_repo/unrelated_users/20250731124648.json.license @@ -1,3 +1,3 @@ -SPDX-FileCopyrightText: 2020 Zach Daniel +SPDX-FileCopyrightText: 2019 ash_postgres contributors SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/user_invites/20240727145758.json.license b/priv/resource_snapshots/test_repo/user_invites/20240727145758.json.license index 815664f3..b0a44fab 100644 --- a/priv/resource_snapshots/test_repo/user_invites/20240727145758.json.license +++ b/priv/resource_snapshots/test_repo/user_invites/20240727145758.json.license @@ -1,3 +1,3 @@ -SPDX-FileCopyrightText: 2020 Zach Daniel +SPDX-FileCopyrightText: 2019 ash_postgres contributors SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/users/20220805191443.json.license b/priv/resource_snapshots/test_repo/users/20220805191443.json.license index 815664f3..b0a44fab 100644 --- a/priv/resource_snapshots/test_repo/users/20220805191443.json.license +++ b/priv/resource_snapshots/test_repo/users/20220805191443.json.license @@ -1,3 +1,3 @@ -SPDX-FileCopyrightText: 2020 Zach Daniel +SPDX-FileCopyrightText: 2019 ash_postgres contributors SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/users/20221217123726.json.license b/priv/resource_snapshots/test_repo/users/20221217123726.json.license index 815664f3..b0a44fab 100644 --- a/priv/resource_snapshots/test_repo/users/20221217123726.json.license +++ b/priv/resource_snapshots/test_repo/users/20221217123726.json.license @@ -1,3 +1,3 @@ -SPDX-FileCopyrightText: 2020 Zach Daniel +SPDX-FileCopyrightText: 2019 ash_postgres contributors SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/users/20230129050950.json.license b/priv/resource_snapshots/test_repo/users/20230129050950.json.license index 815664f3..b0a44fab 100644 --- a/priv/resource_snapshots/test_repo/users/20230129050950.json.license +++ b/priv/resource_snapshots/test_repo/users/20230129050950.json.license @@ -1,3 +1,3 @@ -SPDX-FileCopyrightText: 2020 Zach Daniel +SPDX-FileCopyrightText: 2019 ash_postgres contributors SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/users/20240327211150.json.license b/priv/resource_snapshots/test_repo/users/20240327211150.json.license index 815664f3..b0a44fab 100644 --- a/priv/resource_snapshots/test_repo/users/20240327211150.json.license +++ b/priv/resource_snapshots/test_repo/users/20240327211150.json.license @@ -1,3 +1,3 @@ -SPDX-FileCopyrightText: 2020 Zach Daniel +SPDX-FileCopyrightText: 2019 ash_postgres contributors SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/users/20240727145758.json.license b/priv/resource_snapshots/test_repo/users/20240727145758.json.license index 815664f3..b0a44fab 100644 --- a/priv/resource_snapshots/test_repo/users/20240727145758.json.license +++ b/priv/resource_snapshots/test_repo/users/20240727145758.json.license @@ -1,3 +1,3 @@ -SPDX-FileCopyrightText: 2020 Zach Daniel +SPDX-FileCopyrightText: 2019 ash_postgres contributors SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/users/20240929124728.json.license b/priv/resource_snapshots/test_repo/users/20240929124728.json.license index 815664f3..b0a44fab 100644 --- a/priv/resource_snapshots/test_repo/users/20240929124728.json.license +++ b/priv/resource_snapshots/test_repo/users/20240929124728.json.license @@ -1,3 +1,3 @@ -SPDX-FileCopyrightText: 2020 Zach Daniel +SPDX-FileCopyrightText: 2019 ash_postgres contributors SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/users/20250320225052.json.license b/priv/resource_snapshots/test_repo/users/20250320225052.json.license index 815664f3..b0a44fab 100644 --- a/priv/resource_snapshots/test_repo/users/20250320225052.json.license +++ b/priv/resource_snapshots/test_repo/users/20250320225052.json.license @@ -1,3 +1,3 @@ -SPDX-FileCopyrightText: 2020 Zach Daniel +SPDX-FileCopyrightText: 2019 ash_postgres contributors SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/users/20250321142835.json.license b/priv/resource_snapshots/test_repo/users/20250321142835.json.license index 815664f3..b0a44fab 100644 --- a/priv/resource_snapshots/test_repo/users/20250321142835.json.license +++ b/priv/resource_snapshots/test_repo/users/20250321142835.json.license @@ -1,3 +1,3 @@ -SPDX-FileCopyrightText: 2020 Zach Daniel +SPDX-FileCopyrightText: 2019 ash_postgres contributors SPDX-License-Identifier: MIT diff --git a/priv/test_no_sandbox_repo/migrations/.gitkeep.license b/priv/test_no_sandbox_repo/migrations/.gitkeep.license index 815664f3..b0a44fab 100644 --- a/priv/test_no_sandbox_repo/migrations/.gitkeep.license +++ b/priv/test_no_sandbox_repo/migrations/.gitkeep.license @@ -1,3 +1,3 @@ -SPDX-FileCopyrightText: 2020 Zach Daniel +SPDX-FileCopyrightText: 2019 ash_postgres contributors SPDX-License-Identifier: MIT diff --git a/priv/test_no_sandbox_repo/migrations/20240627223224_install_5_extensions.exs b/priv/test_no_sandbox_repo/migrations/20240627223224_install_5_extensions.exs index 94e450c6..f64c49e7 100644 --- a/priv/test_no_sandbox_repo/migrations/20240627223224_install_5_extensions.exs +++ b/priv/test_no_sandbox_repo/migrations/20240627223224_install_5_extensions.exs @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/priv/test_no_sandbox_repo/migrations/20240712232025_install_ash-functions_extension_4.exs b/priv/test_no_sandbox_repo/migrations/20240712232025_install_ash-functions_extension_4.exs index ecf0a75f..3b0c3d9d 100644 --- a/priv/test_no_sandbox_repo/migrations/20240712232025_install_ash-functions_extension_4.exs +++ b/priv/test_no_sandbox_repo/migrations/20240712232025_install_ash-functions_extension_4.exs @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/priv/test_no_sandbox_repo/migrations/20250113205301_migrate_resources_extensions_1.exs b/priv/test_no_sandbox_repo/migrations/20250113205301_migrate_resources_extensions_1.exs index 01697a60..8ab2eb47 100644 --- a/priv/test_no_sandbox_repo/migrations/20250113205301_migrate_resources_extensions_1.exs +++ b/priv/test_no_sandbox_repo/migrations/20250113205301_migrate_resources_extensions_1.exs @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/priv/test_repo/migrations/20220805191440_install_4_extensions.exs b/priv/test_repo/migrations/20220805191440_install_4_extensions.exs index a20aa8e9..a1d465dc 100644 --- a/priv/test_repo/migrations/20220805191440_install_4_extensions.exs +++ b/priv/test_repo/migrations/20220805191440_install_4_extensions.exs @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT @@ -88,4 +88,4 @@ defmodule AshPostgres.TestRepo.Migrations.Install4Extensions do # execute("DROP EXTENSION IF EXISTS \"pg_trgm\"") # execute("DROP EXTENSION IF EXISTS \"citext\"") end -end \ No newline at end of file +end diff --git a/priv/test_repo/migrations/20220805191443_migrate_resources1.exs b/priv/test_repo/migrations/20220805191443_migrate_resources1.exs index b9b7fdd0..8cb31e0c 100644 --- a/priv/test_repo/migrations/20220805191443_migrate_resources1.exs +++ b/priv/test_repo/migrations/20220805191443_migrate_resources1.exs @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/priv/test_repo/migrations/20220914104733_migrate_resources2.exs b/priv/test_repo/migrations/20220914104733_migrate_resources2.exs index fbbeb8e0..b7da4e0d 100644 --- a/priv/test_repo/migrations/20220914104733_migrate_resources2.exs +++ b/priv/test_repo/migrations/20220914104733_migrate_resources2.exs @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT @@ -22,4 +22,4 @@ defmodule AshPostgres.TestRepo.Migrations.MigrateResources2 do remove :badges end end -end \ No newline at end of file +end diff --git a/priv/test_repo/migrations/20221017133955_migrate_resources3.exs b/priv/test_repo/migrations/20221017133955_migrate_resources3.exs index 12f282d6..f0593998 100644 --- a/priv/test_repo/migrations/20221017133955_migrate_resources3.exs +++ b/priv/test_repo/migrations/20221017133955_migrate_resources3.exs @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT @@ -22,4 +22,4 @@ defmodule AshPostgres.TestRepo.Migrations.MigrateResources3 do name: "post_links_unique_link_index" ) end -end \ No newline at end of file +end diff --git a/priv/test_repo/migrations/20221125171148_migrate_resources4.exs b/priv/test_repo/migrations/20221125171148_migrate_resources4.exs index b6749230..9e65c9a7 100644 --- a/priv/test_repo/migrations/20221125171148_migrate_resources4.exs +++ b/priv/test_repo/migrations/20221125171148_migrate_resources4.exs @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT @@ -24,4 +24,4 @@ defmodule AshPostgres.TestRepo.Migrations.MigrateResources4 do remove :uniq_custom_one end end -end \ No newline at end of file +end diff --git a/priv/test_repo/migrations/20221125171150_migrate_resources5.exs b/priv/test_repo/migrations/20221125171150_migrate_resources5.exs index f4d14b56..acccc8af 100644 --- a/priv/test_repo/migrations/20221125171150_migrate_resources5.exs +++ b/priv/test_repo/migrations/20221125171150_migrate_resources5.exs @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT @@ -23,4 +23,4 @@ defmodule AshPostgres.TestRepo.Migrations.MigrateResources5 do name: "posts_uniq_custom_one_uniq_custom_two_index" ) end -end \ No newline at end of file +end diff --git a/priv/test_repo/migrations/20221202194704_migrate_resources6.exs b/priv/test_repo/migrations/20221202194704_migrate_resources6.exs index 6b6f174a..57200540 100644 --- a/priv/test_repo/migrations/20221202194704_migrate_resources6.exs +++ b/priv/test_repo/migrations/20221202194704_migrate_resources6.exs @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT @@ -22,4 +22,4 @@ defmodule AshPostgres.TestRepo.Migrations.MigrateResources6 do remove :state end end -end \ No newline at end of file +end diff --git a/priv/test_repo/migrations/20221217123726_migrate_resources7.exs b/priv/test_repo/migrations/20221217123726_migrate_resources7.exs index 95edab52..2793bd5c 100644 --- a/priv/test_repo/migrations/20221217123726_migrate_resources7.exs +++ b/priv/test_repo/migrations/20221217123726_migrate_resources7.exs @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT @@ -39,4 +39,4 @@ defmodule AshPostgres.TestRepo.Migrations.MigrateResources7 do remove :is_active end end -end \ No newline at end of file +end diff --git a/priv/test_repo/migrations/20230129050950_migrate_resources8.exs b/priv/test_repo/migrations/20230129050950_migrate_resources8.exs index 3aba9340..30a4ab95 100644 --- a/priv/test_repo/migrations/20230129050950_migrate_resources8.exs +++ b/priv/test_repo/migrations/20230129050950_migrate_resources8.exs @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT @@ -76,4 +76,4 @@ defmodule AshPostgres.TestRepo.Migrations.MigrateResources8 do remove :organization_id end end -end \ No newline at end of file +end diff --git a/priv/test_repo/migrations/20230526144249_migrate_resources9.exs b/priv/test_repo/migrations/20230526144249_migrate_resources9.exs index d3a907b8..1ff50786 100644 --- a/priv/test_repo/migrations/20230526144249_migrate_resources9.exs +++ b/priv/test_repo/migrations/20230526144249_migrate_resources9.exs @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT @@ -38,4 +38,4 @@ defmodule AshPostgres.TestRepo.Migrations.MigrateResources9 do drop table(:managers) end -end \ No newline at end of file +end diff --git a/priv/test_repo/migrations/20230712182523_install_ash-functions_extension.exs b/priv/test_repo/migrations/20230712182523_install_ash-functions_extension.exs index 6f9ee9e4..9aad4684 100644 --- a/priv/test_repo/migrations/20230712182523_install_ash-functions_extension.exs +++ b/priv/test_repo/migrations/20230712182523_install_ash-functions_extension.exs @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/priv/test_repo/migrations/20230804223759_install_demo-functions_v0_extension.exs b/priv/test_repo/migrations/20230804223759_install_demo-functions_v0_extension.exs index edfac408..79f9f0d0 100644 --- a/priv/test_repo/migrations/20230804223759_install_demo-functions_v0_extension.exs +++ b/priv/test_repo/migrations/20230804223759_install_demo-functions_v0_extension.exs @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT @@ -27,4 +27,4 @@ defmodule AshPostgres.TestRepo.Migrations.InstallDemoFunctionsV0 do DROP FUNCTION IF EXISTS ash_demo_functions() """) end -end \ No newline at end of file +end diff --git a/priv/test_repo/migrations/20230804223818_install_demo-functions_v1_extension.exs b/priv/test_repo/migrations/20230804223818_install_demo-functions_v1_extension.exs index 2222a781..5b88cec1 100644 --- a/priv/test_repo/migrations/20230804223818_install_demo-functions_v1_extension.exs +++ b/priv/test_repo/migrations/20230804223818_install_demo-functions_v1_extension.exs @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT @@ -27,4 +27,4 @@ defmodule AshPostgres.TestRepo.Migrations.InstallDemoFunctionsV1 do DROP FUNCTION IF EXISTS ash_demo_functions() """) end -end \ No newline at end of file +end diff --git a/priv/test_repo/migrations/20230816231942_add_complex_calculation_tables.exs b/priv/test_repo/migrations/20230816231942_add_complex_calculation_tables.exs index 1cc444b7..4070e6d3 100644 --- a/priv/test_repo/migrations/20230816231942_add_complex_calculation_tables.exs +++ b/priv/test_repo/migrations/20230816231942_add_complex_calculation_tables.exs @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT @@ -70,4 +70,4 @@ defmodule AshPostgres.TestRepo.Migrations.AddComplexCalculationTables do drop table(:complex_calculations_skills) end -end \ No newline at end of file +end diff --git a/priv/test_repo/migrations/20230823161017_migrate_resources10.exs b/priv/test_repo/migrations/20230823161017_migrate_resources10.exs index 18e6f479..6cf19472 100644 --- a/priv/test_repo/migrations/20230823161017_migrate_resources10.exs +++ b/priv/test_repo/migrations/20230823161017_migrate_resources10.exs @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT @@ -22,4 +22,4 @@ defmodule AshPostgres.TestRepo.Migrations.MigrateResources10 do remove :stuff end end -end \ No newline at end of file +end diff --git a/priv/test_repo/migrations/20230905050351_add_post_views.exs b/priv/test_repo/migrations/20230905050351_add_post_views.exs index 3ea0cbb1..e19c1d62 100644 --- a/priv/test_repo/migrations/20230905050351_add_post_views.exs +++ b/priv/test_repo/migrations/20230905050351_add_post_views.exs @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT @@ -22,4 +22,4 @@ defmodule AshPostgres.TestRepo.Migrations.AddPostViews do def down do drop table(:post_views) end -end \ No newline at end of file +end diff --git a/priv/test_repo/migrations/20231116013020_add_complex_calculations_channels.exs b/priv/test_repo/migrations/20231116013020_add_complex_calculations_channels.exs index c3f768f0..29045f0f 100644 --- a/priv/test_repo/migrations/20231116013020_add_complex_calculations_channels.exs +++ b/priv/test_repo/migrations/20231116013020_add_complex_calculations_channels.exs @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT @@ -56,4 +56,4 @@ defmodule AshPostgres.TestRepo.Migrations.AddComplexCalculationsChannels do drop table(:complex_calculations_channels) end -end \ No newline at end of file +end diff --git a/priv/test_repo/migrations/20231127212608_add_composite_type.exs b/priv/test_repo/migrations/20231127212608_add_composite_type.exs index 8a85a46f..1ae28125 100644 --- a/priv/test_repo/migrations/20231127212608_add_composite_type.exs +++ b/priv/test_repo/migrations/20231127212608_add_composite_type.exs @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/priv/test_repo/migrations/20231127215636_migrate_resources11.exs b/priv/test_repo/migrations/20231127215636_migrate_resources11.exs index c4da8e77..97ce50c1 100644 --- a/priv/test_repo/migrations/20231127215636_migrate_resources11.exs +++ b/priv/test_repo/migrations/20231127215636_migrate_resources11.exs @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/priv/test_repo/migrations/20231129141453_migrate_resources12.exs b/priv/test_repo/migrations/20231129141453_migrate_resources12.exs index 613a6b42..0063cd3e 100644 --- a/priv/test_repo/migrations/20231129141453_migrate_resources12.exs +++ b/priv/test_repo/migrations/20231129141453_migrate_resources12.exs @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT @@ -22,4 +22,4 @@ defmodule AshPostgres.TestRepo.Migrations.MigrateResources12 do modify :composite_point, :point end end -end \ No newline at end of file +end diff --git a/priv/test_repo/migrations/20231214220937_install_ash-functions_extension_2.exs b/priv/test_repo/migrations/20231214220937_install_ash-functions_extension_2.exs index e02f5467..8b3a89f4 100644 --- a/priv/test_repo/migrations/20231214220937_install_ash-functions_extension_2.exs +++ b/priv/test_repo/migrations/20231214220937_install_ash-functions_extension_2.exs @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/priv/test_repo/migrations/20231219132807_migrate_resources13.exs b/priv/test_repo/migrations/20231219132807_migrate_resources13.exs index 55fc4bbe..b73022f0 100644 --- a/priv/test_repo/migrations/20231219132807_migrate_resources13.exs +++ b/priv/test_repo/migrations/20231219132807_migrate_resources13.exs @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT @@ -18,4 +18,4 @@ defmodule AshPostgres.TestRepo.Migrations.MigrateResources13 do def down do rename table(:posts), :title_column, to: :title end -end \ No newline at end of file +end diff --git a/priv/test_repo/migrations/20231231051611_install_ash-functions_extension_3.exs b/priv/test_repo/migrations/20231231051611_install_ash-functions_extension_3.exs index e841dfba..75e5d807 100644 --- a/priv/test_repo/migrations/20231231051611_install_ash-functions_extension_3.exs +++ b/priv/test_repo/migrations/20231231051611_install_ash-functions_extension_3.exs @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT @@ -64,4 +64,4 @@ defmodule AshPostgres.TestRepo.Migrations.InstallAshFunctionsExtension3 do $$ LANGUAGE plpgsql; """) end -end \ No newline at end of file +end diff --git a/priv/test_repo/migrations/20240109155951_create_temp_schema.exs b/priv/test_repo/migrations/20240109155951_create_temp_schema.exs index ada02c90..c528b9d0 100644 --- a/priv/test_repo/migrations/20240109155951_create_temp_schema.exs +++ b/priv/test_repo/migrations/20240109155951_create_temp_schema.exs @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/priv/test_repo/migrations/20240109160153_migrate_resources14.exs b/priv/test_repo/migrations/20240109160153_migrate_resources14.exs index c70f9357..de65bcfa 100644 --- a/priv/test_repo/migrations/20240109160153_migrate_resources14.exs +++ b/priv/test_repo/migrations/20240109160153_migrate_resources14.exs @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT @@ -41,4 +41,4 @@ defmodule AshPostgres.TestRepo.Migrations.MigrateResources14 do drop table(:temp_entities, prefix: "temp") end -end \ No newline at end of file +end diff --git a/priv/test_repo/migrations/20240129221511_migrate_resources15.exs b/priv/test_repo/migrations/20240129221511_migrate_resources15.exs index 88ae8d08..6f8f055a 100644 --- a/priv/test_repo/migrations/20240129221511_migrate_resources15.exs +++ b/priv/test_repo/migrations/20240129221511_migrate_resources15.exs @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT @@ -22,4 +22,4 @@ defmodule AshPostgres.TestRepo.Migrations.MigrateResources15 do remove :list_containing_nils end end -end \ No newline at end of file +end diff --git a/priv/test_repo/migrations/20240130133933_add_resources_for_subquery_test.exs b/priv/test_repo/migrations/20240130133933_add_resources_for_subquery_test.exs index 36ad998e..4d45ac33 100644 --- a/priv/test_repo/migrations/20240130133933_add_resources_for_subquery_test.exs +++ b/priv/test_repo/migrations/20240130133933_add_resources_for_subquery_test.exs @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/priv/test_repo/migrations/20240224001913_migrate_resources16.exs b/priv/test_repo/migrations/20240224001913_migrate_resources16.exs index 00decc17..f3b7a8ed 100644 --- a/priv/test_repo/migrations/20240224001913_migrate_resources16.exs +++ b/priv/test_repo/migrations/20240224001913_migrate_resources16.exs @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT @@ -22,4 +22,4 @@ defmodule AshPostgres.TestRepo.Migrations.MigrateResources16 do remove :list_of_stuff end end -end \ No newline at end of file +end diff --git a/priv/test_repo/migrations/20240227180858_migrate_resources17.exs b/priv/test_repo/migrations/20240227180858_migrate_resources17.exs index 93fc8bd5..f59df09c 100644 --- a/priv/test_repo/migrations/20240227180858_migrate_resources17.exs +++ b/priv/test_repo/migrations/20240227180858_migrate_resources17.exs @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT @@ -42,4 +42,4 @@ defmodule AshPostgres.TestRepo.Migrations.MigrateResources17 do drop table(:post_followers) end -end \ No newline at end of file +end diff --git a/priv/test_repo/migrations/20240227181137_migrate_resources18.exs b/priv/test_repo/migrations/20240227181137_migrate_resources18.exs index 4e6db225..7e831d9e 100644 --- a/priv/test_repo/migrations/20240227181137_migrate_resources18.exs +++ b/priv/test_repo/migrations/20240227181137_migrate_resources18.exs @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT @@ -46,4 +46,4 @@ defmodule AshPostgres.TestRepo.Migrations.MigrateResources18 do rename table(:post_followers), :follower_id, to: :user_id end -end \ No newline at end of file +end diff --git a/priv/test_repo/migrations/20240229050455_install_5_extensions.exs b/priv/test_repo/migrations/20240229050455_install_5_extensions.exs index bdecc817..4bb4f7fa 100644 --- a/priv/test_repo/migrations/20240229050455_install_5_extensions.exs +++ b/priv/test_repo/migrations/20240229050455_install_5_extensions.exs @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/priv/test_repo/migrations/20240327211150_migrate_resources19.exs b/priv/test_repo/migrations/20240327211150_migrate_resources19.exs index 7fc2c8c3..100d11a9 100644 --- a/priv/test_repo/migrations/20240327211150_migrate_resources19.exs +++ b/priv/test_repo/migrations/20240327211150_migrate_resources19.exs @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/priv/test_repo/migrations/20240327211917_migrate_resources20.exs b/priv/test_repo/migrations/20240327211917_migrate_resources20.exs index bd30cc5b..8358e319 100644 --- a/priv/test_repo/migrations/20240327211917_migrate_resources20.exs +++ b/priv/test_repo/migrations/20240327211917_migrate_resources20.exs @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/priv/test_repo/migrations/20240503012410_migrate_resources21.exs b/priv/test_repo/migrations/20240503012410_migrate_resources21.exs index 9230a78a..7f66c108 100644 --- a/priv/test_repo/migrations/20240503012410_migrate_resources21.exs +++ b/priv/test_repo/migrations/20240503012410_migrate_resources21.exs @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/priv/test_repo/migrations/20240504185511_migrate_resources22.exs b/priv/test_repo/migrations/20240504185511_migrate_resources22.exs index 19ae6c87..ef35bc07 100644 --- a/priv/test_repo/migrations/20240504185511_migrate_resources22.exs +++ b/priv/test_repo/migrations/20240504185511_migrate_resources22.exs @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/priv/test_repo/migrations/20240516205244_migrate_resources23.exs b/priv/test_repo/migrations/20240516205244_migrate_resources23.exs index cebacd08..1ee5dfad 100644 --- a/priv/test_repo/migrations/20240516205244_migrate_resources23.exs +++ b/priv/test_repo/migrations/20240516205244_migrate_resources23.exs @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/priv/test_repo/migrations/20240517223946_migrate_resources24.exs b/priv/test_repo/migrations/20240517223946_migrate_resources24.exs index 09e71bd5..e7f09782 100644 --- a/priv/test_repo/migrations/20240517223946_migrate_resources24.exs +++ b/priv/test_repo/migrations/20240517223946_migrate_resources24.exs @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/priv/test_repo/migrations/20240524031113_migrate_resources25.exs b/priv/test_repo/migrations/20240524031113_migrate_resources25.exs index 0b829659..38e5384f 100644 --- a/priv/test_repo/migrations/20240524031113_migrate_resources25.exs +++ b/priv/test_repo/migrations/20240524031113_migrate_resources25.exs @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/priv/test_repo/migrations/20240524041750_migrate_resources26.exs b/priv/test_repo/migrations/20240524041750_migrate_resources26.exs index e27aff26..255bf9c9 100644 --- a/priv/test_repo/migrations/20240524041750_migrate_resources26.exs +++ b/priv/test_repo/migrations/20240524041750_migrate_resources26.exs @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/priv/test_repo/migrations/20240610195853_migrate_resources27.exs b/priv/test_repo/migrations/20240610195853_migrate_resources27.exs index f156231e..e22c4de7 100644 --- a/priv/test_repo/migrations/20240610195853_migrate_resources27.exs +++ b/priv/test_repo/migrations/20240610195853_migrate_resources27.exs @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/priv/test_repo/migrations/20240617193218_migrate_resources28.exs b/priv/test_repo/migrations/20240617193218_migrate_resources28.exs index d864e25b..019a5dbe 100644 --- a/priv/test_repo/migrations/20240617193218_migrate_resources28.exs +++ b/priv/test_repo/migrations/20240617193218_migrate_resources28.exs @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/priv/test_repo/migrations/20240618085942_migrate_resources29.exs b/priv/test_repo/migrations/20240618085942_migrate_resources29.exs index 0c6b8de3..9c8fbf81 100644 --- a/priv/test_repo/migrations/20240618085942_migrate_resources29.exs +++ b/priv/test_repo/migrations/20240618085942_migrate_resources29.exs @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/priv/test_repo/migrations/20240618102809_migrate_resources30.exs b/priv/test_repo/migrations/20240618102809_migrate_resources30.exs index 4d1f8ad8..37399ecc 100644 --- a/priv/test_repo/migrations/20240618102809_migrate_resources30.exs +++ b/priv/test_repo/migrations/20240618102809_migrate_resources30.exs @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/priv/test_repo/migrations/20240622192715_install_ash-functions_extension_4.exs b/priv/test_repo/migrations/20240622192715_install_ash-functions_extension_4.exs index 3a544490..d4ce735f 100644 --- a/priv/test_repo/migrations/20240622192715_install_ash-functions_extension_4.exs +++ b/priv/test_repo/migrations/20240622192715_install_ash-functions_extension_4.exs @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/priv/test_repo/migrations/20240627223225_migrate_resources31.exs b/priv/test_repo/migrations/20240627223225_migrate_resources31.exs index cd97c368..7b9f813b 100644 --- a/priv/test_repo/migrations/20240627223225_migrate_resources31.exs +++ b/priv/test_repo/migrations/20240627223225_migrate_resources31.exs @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/priv/test_repo/migrations/20240703155134_migrate_resources32.exs b/priv/test_repo/migrations/20240703155134_migrate_resources32.exs index 1364a828..1895ad19 100644 --- a/priv/test_repo/migrations/20240703155134_migrate_resources32.exs +++ b/priv/test_repo/migrations/20240703155134_migrate_resources32.exs @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/priv/test_repo/migrations/20240705113722_migrate_resources33.exs b/priv/test_repo/migrations/20240705113722_migrate_resources33.exs index e6f7a1a8..adf3fa29 100644 --- a/priv/test_repo/migrations/20240705113722_migrate_resources33.exs +++ b/priv/test_repo/migrations/20240705113722_migrate_resources33.exs @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/priv/test_repo/migrations/20240712232026_migrate_resources34.exs b/priv/test_repo/migrations/20240712232026_migrate_resources34.exs index 22af731f..da51100e 100644 --- a/priv/test_repo/migrations/20240712232026_migrate_resources34.exs +++ b/priv/test_repo/migrations/20240712232026_migrate_resources34.exs @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/priv/test_repo/migrations/20240713134055_multi_domain_calculations.exs b/priv/test_repo/migrations/20240713134055_multi_domain_calculations.exs index d6c57db6..60a98ad1 100644 --- a/priv/test_repo/migrations/20240713134055_multi_domain_calculations.exs +++ b/priv/test_repo/migrations/20240713134055_multi_domain_calculations.exs @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/priv/test_repo/migrations/20240715135403_migrate_resources35.exs b/priv/test_repo/migrations/20240715135403_migrate_resources35.exs index 2349c59d..a818451a 100644 --- a/priv/test_repo/migrations/20240715135403_migrate_resources35.exs +++ b/priv/test_repo/migrations/20240715135403_migrate_resources35.exs @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/priv/test_repo/migrations/20240717104854_no_attributes_calculation_test.exs b/priv/test_repo/migrations/20240717104854_no_attributes_calculation_test.exs index 2c9269fa..7d0b19b7 100644 --- a/priv/test_repo/migrations/20240717104854_no_attributes_calculation_test.exs +++ b/priv/test_repo/migrations/20240717104854_no_attributes_calculation_test.exs @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/priv/test_repo/migrations/20240717151815_migrate_resources36.exs b/priv/test_repo/migrations/20240717151815_migrate_resources36.exs index e8b21183..df6b0087 100644 --- a/priv/test_repo/migrations/20240717151815_migrate_resources36.exs +++ b/priv/test_repo/migrations/20240717151815_migrate_resources36.exs @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/priv/test_repo/migrations/20240717153736_migrate_resources37.exs b/priv/test_repo/migrations/20240717153736_migrate_resources37.exs index 4d5777a4..8e14b6ce 100644 --- a/priv/test_repo/migrations/20240717153736_migrate_resources37.exs +++ b/priv/test_repo/migrations/20240717153736_migrate_resources37.exs @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/priv/test_repo/migrations/20240727145758_user_invites.exs b/priv/test_repo/migrations/20240727145758_user_invites.exs index c054a440..61c522bc 100644 --- a/priv/test_repo/migrations/20240727145758_user_invites.exs +++ b/priv/test_repo/migrations/20240727145758_user_invites.exs @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/priv/test_repo/migrations/20240906170759_migrate_resources38.exs b/priv/test_repo/migrations/20240906170759_migrate_resources38.exs index 78637f88..7a7ab279 100644 --- a/priv/test_repo/migrations/20240906170759_migrate_resources38.exs +++ b/priv/test_repo/migrations/20240906170759_migrate_resources38.exs @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/priv/test_repo/migrations/20240910180107_migrate_resources39.exs b/priv/test_repo/migrations/20240910180107_migrate_resources39.exs index dc7f6502..da7e7728 100644 --- a/priv/test_repo/migrations/20240910180107_migrate_resources39.exs +++ b/priv/test_repo/migrations/20240910180107_migrate_resources39.exs @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/priv/test_repo/migrations/20240911225319_install_1_extensions.exs b/priv/test_repo/migrations/20240911225319_install_1_extensions.exs index dede4e89..2bac3ea7 100644 --- a/priv/test_repo/migrations/20240911225319_install_1_extensions.exs +++ b/priv/test_repo/migrations/20240911225319_install_1_extensions.exs @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/priv/test_repo/migrations/20240911225320_migrate_resources40.exs b/priv/test_repo/migrations/20240911225320_migrate_resources40.exs index fd10a2f0..95f01067 100644 --- a/priv/test_repo/migrations/20240911225320_migrate_resources40.exs +++ b/priv/test_repo/migrations/20240911225320_migrate_resources40.exs @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/priv/test_repo/migrations/20240918104740_migrate_resources41.exs b/priv/test_repo/migrations/20240918104740_migrate_resources41.exs index 41ce709a..3d604b97 100644 --- a/priv/test_repo/migrations/20240918104740_migrate_resources41.exs +++ b/priv/test_repo/migrations/20240918104740_migrate_resources41.exs @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/priv/test_repo/migrations/20240929121224_migrate_resources42.exs b/priv/test_repo/migrations/20240929121224_migrate_resources42.exs index 23a14e4a..91c49fb4 100644 --- a/priv/test_repo/migrations/20240929121224_migrate_resources42.exs +++ b/priv/test_repo/migrations/20240929121224_migrate_resources42.exs @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/priv/test_repo/migrations/20240929124728_migrate_resources43.exs b/priv/test_repo/migrations/20240929124728_migrate_resources43.exs index c91d401a..86b28970 100644 --- a/priv/test_repo/migrations/20240929124728_migrate_resources43.exs +++ b/priv/test_repo/migrations/20240929124728_migrate_resources43.exs @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/priv/test_repo/migrations/20241208221219_migrate_resources44.exs b/priv/test_repo/migrations/20241208221219_migrate_resources44.exs index af546799..35a52b61 100644 --- a/priv/test_repo/migrations/20241208221219_migrate_resources44.exs +++ b/priv/test_repo/migrations/20241208221219_migrate_resources44.exs @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/priv/test_repo/migrations/20241217232254_migrate_resources45.exs b/priv/test_repo/migrations/20241217232254_migrate_resources45.exs index 94454ef2..c44417ca 100644 --- a/priv/test_repo/migrations/20241217232254_migrate_resources45.exs +++ b/priv/test_repo/migrations/20241217232254_migrate_resources45.exs @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/priv/test_repo/migrations/20250113205259_migrate_resources_extensions_1.exs b/priv/test_repo/migrations/20250113205259_migrate_resources_extensions_1.exs index 68c52ef7..842097ce 100644 --- a/priv/test_repo/migrations/20250113205259_migrate_resources_extensions_1.exs +++ b/priv/test_repo/migrations/20250113205259_migrate_resources_extensions_1.exs @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/priv/test_repo/migrations/20250122190558_migrate_resources46.exs b/priv/test_repo/migrations/20250122190558_migrate_resources46.exs index c9cfed58..a4455b1b 100644 --- a/priv/test_repo/migrations/20250122190558_migrate_resources46.exs +++ b/priv/test_repo/migrations/20250122190558_migrate_resources46.exs @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/priv/test_repo/migrations/20250123161002_migrate_resources47.exs b/priv/test_repo/migrations/20250123161002_migrate_resources47.exs index 32e5ff54..582a215e 100644 --- a/priv/test_repo/migrations/20250123161002_migrate_resources47.exs +++ b/priv/test_repo/migrations/20250123161002_migrate_resources47.exs @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/priv/test_repo/migrations/20250123164209_migrate_resources48.exs b/priv/test_repo/migrations/20250123164209_migrate_resources48.exs index b07394fb..8f4eccef 100644 --- a/priv/test_repo/migrations/20250123164209_migrate_resources48.exs +++ b/priv/test_repo/migrations/20250123164209_migrate_resources48.exs @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/priv/test_repo/migrations/20250210191116_migrate_resources49.exs b/priv/test_repo/migrations/20250210191116_migrate_resources49.exs index f147420b..1df9270e 100644 --- a/priv/test_repo/migrations/20250210191116_migrate_resources49.exs +++ b/priv/test_repo/migrations/20250210191116_migrate_resources49.exs @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/priv/test_repo/migrations/20250217054207_migrate_resources50.exs b/priv/test_repo/migrations/20250217054207_migrate_resources50.exs index 1ea35a4a..7d077e11 100644 --- a/priv/test_repo/migrations/20250217054207_migrate_resources50.exs +++ b/priv/test_repo/migrations/20250217054207_migrate_resources50.exs @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/priv/test_repo/migrations/20250313112823_migrate_resources51.exs b/priv/test_repo/migrations/20250313112823_migrate_resources51.exs index 37609641..98fd8624 100644 --- a/priv/test_repo/migrations/20250313112823_migrate_resources51.exs +++ b/priv/test_repo/migrations/20250313112823_migrate_resources51.exs @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/priv/test_repo/migrations/20250320225052_add_csv_resource.exs b/priv/test_repo/migrations/20250320225052_add_csv_resource.exs index 11159d77..e1d72242 100644 --- a/priv/test_repo/migrations/20250320225052_add_csv_resource.exs +++ b/priv/test_repo/migrations/20250320225052_add_csv_resource.exs @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/priv/test_repo/migrations/20250321142835_migrate_resources52.exs b/priv/test_repo/migrations/20250321142835_migrate_resources52.exs index 68ee928c..7856790b 100644 --- a/priv/test_repo/migrations/20250321142835_migrate_resources52.exs +++ b/priv/test_repo/migrations/20250321142835_migrate_resources52.exs @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/priv/test_repo/migrations/20250413141328_add_punchlines_and_standup_clubs.exs b/priv/test_repo/migrations/20250413141328_add_punchlines_and_standup_clubs.exs index ff4a368c..638be99f 100644 --- a/priv/test_repo/migrations/20250413141328_add_punchlines_and_standup_clubs.exs +++ b/priv/test_repo/migrations/20250413141328_add_punchlines_and_standup_clubs.exs @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/priv/test_repo/migrations/20250519103535_migrate_resources53.exs b/priv/test_repo/migrations/20250519103535_migrate_resources53.exs index cabe0ee7..3f56a6cb 100644 --- a/priv/test_repo/migrations/20250519103535_migrate_resources53.exs +++ b/priv/test_repo/migrations/20250519103535_migrate_resources53.exs @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/priv/test_repo/migrations/20250520130634_migrate_resources54.exs b/priv/test_repo/migrations/20250520130634_migrate_resources54.exs index 063d79b9..e70723cd 100644 --- a/priv/test_repo/migrations/20250520130634_migrate_resources54.exs +++ b/priv/test_repo/migrations/20250520130634_migrate_resources54.exs @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/priv/test_repo/migrations/20250521105654_add_model_tuple_to_post.exs b/priv/test_repo/migrations/20250521105654_add_model_tuple_to_post.exs index 734de6d5..ccc88809 100644 --- a/priv/test_repo/migrations/20250521105654_add_model_tuple_to_post.exs +++ b/priv/test_repo/migrations/20250521105654_add_model_tuple_to_post.exs @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/priv/test_repo/migrations/20250605230457_create_record_temp_entities_table.exs b/priv/test_repo/migrations/20250605230457_create_record_temp_entities_table.exs index 90c3fcba..264c19e2 100644 --- a/priv/test_repo/migrations/20250605230457_create_record_temp_entities_table.exs +++ b/priv/test_repo/migrations/20250605230457_create_record_temp_entities_table.exs @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/priv/test_repo/migrations/20250612113920_migrate_resources55.exs b/priv/test_repo/migrations/20250612113920_migrate_resources55.exs index b91c4fa9..7ab54998 100644 --- a/priv/test_repo/migrations/20250612113920_migrate_resources55.exs +++ b/priv/test_repo/migrations/20250612113920_migrate_resources55.exs @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/priv/test_repo/migrations/20250618011917_migrate_resources56.exs b/priv/test_repo/migrations/20250618011917_migrate_resources56.exs index 97d68971..5c4105b3 100644 --- a/priv/test_repo/migrations/20250618011917_migrate_resources56.exs +++ b/priv/test_repo/migrations/20250618011917_migrate_resources56.exs @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/priv/test_repo/migrations/20250714225304_add_complex_calculations_folder_and_items.exs b/priv/test_repo/migrations/20250714225304_add_complex_calculations_folder_and_items.exs index fdcd91e4..16dd2efc 100644 --- a/priv/test_repo/migrations/20250714225304_add_complex_calculations_folder_and_items.exs +++ b/priv/test_repo/migrations/20250714225304_add_complex_calculations_folder_and_items.exs @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/priv/test_repo/migrations/20250731124648_migrate_resources57.exs b/priv/test_repo/migrations/20250731124648_migrate_resources57.exs index 3fea4408..2c54e133 100644 --- a/priv/test_repo/migrations/20250731124648_migrate_resources57.exs +++ b/priv/test_repo/migrations/20250731124648_migrate_resources57.exs @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/priv/test_repo/migrations/20250810102512_migrate_resources58.exs b/priv/test_repo/migrations/20250810102512_migrate_resources58.exs index de4bbd5a..592824b4 100644 --- a/priv/test_repo/migrations/20250810102512_migrate_resources58.exs +++ b/priv/test_repo/migrations/20250810102512_migrate_resources58.exs @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/priv/test_repo/migrations/20250908073737_migrate_resources59.exs b/priv/test_repo/migrations/20250908073737_migrate_resources59.exs index dee8b387..962338ef 100644 --- a/priv/test_repo/migrations/20250908073737_migrate_resources59.exs +++ b/priv/test_repo/migrations/20250908073737_migrate_resources59.exs @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/priv/test_repo/migrations/20250908093505_migrate_resources60.exs b/priv/test_repo/migrations/20250908093505_migrate_resources60.exs index d3747224..f3137214 100644 --- a/priv/test_repo/migrations/20250908093505_migrate_resources60.exs +++ b/priv/test_repo/migrations/20250908093505_migrate_resources60.exs @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/priv/test_repo/migrations/20250908212414_migrate_resources61.exs b/priv/test_repo/migrations/20250908212414_migrate_resources61.exs index 2bd3d6bf..9730c75e 100644 --- a/priv/test_repo/migrations/20250908212414_migrate_resources61.exs +++ b/priv/test_repo/migrations/20250908212414_migrate_resources61.exs @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/priv/test_repo/migrations/20251002180954_migrate_resources62.exs b/priv/test_repo/migrations/20251002180954_migrate_resources62.exs index 8fd9c180..9c2dd09c 100644 --- a/priv/test_repo/migrations/20251002180954_migrate_resources62.exs +++ b/priv/test_repo/migrations/20251002180954_migrate_resources62.exs @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/priv/test_repo/tenant_migrations/20220805191441_migrate_resources1.exs b/priv/test_repo/tenant_migrations/20220805191441_migrate_resources1.exs index 5a5bd69b..6ef57f23 100644 --- a/priv/test_repo/tenant_migrations/20220805191441_migrate_resources1.exs +++ b/priv/test_repo/tenant_migrations/20220805191441_migrate_resources1.exs @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT @@ -41,4 +41,4 @@ defmodule AshPostgres.TestRepo.TenantMigrations.MigrateResources1 do drop table(:multitenant_posts, prefix: prefix()) end -end \ No newline at end of file +end diff --git a/priv/test_repo/tenant_migrations/20240327211149_migrate_resources2.exs b/priv/test_repo/tenant_migrations/20240327211149_migrate_resources2.exs index 56751e6c..a97ed282 100644 --- a/priv/test_repo/tenant_migrations/20240327211149_migrate_resources2.exs +++ b/priv/test_repo/tenant_migrations/20240327211149_migrate_resources2.exs @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/priv/test_repo/tenant_migrations/20240610162043_migrate_resources3.exs b/priv/test_repo/tenant_migrations/20240610162043_migrate_resources3.exs index 8c913034..795b70c4 100644 --- a/priv/test_repo/tenant_migrations/20240610162043_migrate_resources3.exs +++ b/priv/test_repo/tenant_migrations/20240610162043_migrate_resources3.exs @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/priv/test_repo/tenant_migrations/20250122203454_migrate_resources4.exs b/priv/test_repo/tenant_migrations/20250122203454_migrate_resources4.exs index ab537413..b4b10a97 100644 --- a/priv/test_repo/tenant_migrations/20250122203454_migrate_resources4.exs +++ b/priv/test_repo/tenant_migrations/20250122203454_migrate_resources4.exs @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/priv/test_repo/tenant_migrations/20250220073135_migrate_resources5.exs b/priv/test_repo/tenant_migrations/20250220073135_migrate_resources5.exs index 2a52a954..881bde93 100644 --- a/priv/test_repo/tenant_migrations/20250220073135_migrate_resources5.exs +++ b/priv/test_repo/tenant_migrations/20250220073135_migrate_resources5.exs @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/priv/test_repo/tenant_migrations/20250220073141_migrate_resources6.exs b/priv/test_repo/tenant_migrations/20250220073141_migrate_resources6.exs index 18a7fdfd..a195cfce 100644 --- a/priv/test_repo/tenant_migrations/20250220073141_migrate_resources6.exs +++ b/priv/test_repo/tenant_migrations/20250220073141_migrate_resources6.exs @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/priv/test_repo/tenant_migrations/20251001120813_migrate_resources7.exs b/priv/test_repo/tenant_migrations/20251001120813_migrate_resources7.exs index 6170f2f2..85509bbf 100644 --- a/priv/test_repo/tenant_migrations/20251001120813_migrate_resources7.exs +++ b/priv/test_repo/tenant_migrations/20251001120813_migrate_resources7.exs @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/test/aggregate_test.exs b/test/aggregate_test.exs index 3e64440f..ad66b36e 100644 --- a/test/aggregate_test.exs +++ b/test/aggregate_test.exs @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/test/ash_postgres_test.exs b/test/ash_postgres_test.exs index 41c46e31..cfb6b0d7 100644 --- a/test/ash_postgres_test.exs +++ b/test/ash_postgres_test.exs @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/test/atomics_test.exs b/test/atomics_test.exs index b9443acf..d5680ac8 100644 --- a/test/atomics_test.exs +++ b/test/atomics_test.exs @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/test/bulk_create_test.exs b/test/bulk_create_test.exs index 420ff219..296742fd 100644 --- a/test/bulk_create_test.exs +++ b/test/bulk_create_test.exs @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/test/bulk_destroy_test.exs b/test/bulk_destroy_test.exs index 24cf2395..cd07a684 100644 --- a/test/bulk_destroy_test.exs +++ b/test/bulk_destroy_test.exs @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/test/bulk_update_test.exs b/test/bulk_update_test.exs index 38ce2f45..4dc7dc30 100644 --- a/test/bulk_update_test.exs +++ b/test/bulk_update_test.exs @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/test/calculation_test.exs b/test/calculation_test.exs index 38e4cf5b..cdad5c18 100644 --- a/test/calculation_test.exs +++ b/test/calculation_test.exs @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/test/cascade_destroy_test.exs b/test/cascade_destroy_test.exs index 062e0378..aa9408ac 100644 --- a/test/cascade_destroy_test.exs +++ b/test/cascade_destroy_test.exs @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/test/combination_test.exs b/test/combination_test.exs index fdb55d35..c1143721 100644 --- a/test/combination_test.exs +++ b/test/combination_test.exs @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/test/complex_calculations_test.exs b/test/complex_calculations_test.exs index 815071f7..39cccefc 100644 --- a/test/complex_calculations_test.exs +++ b/test/complex_calculations_test.exs @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/test/composite_type_test.exs b/test/composite_type_test.exs index 7e73e198..edf1af9c 100644 --- a/test/composite_type_test.exs +++ b/test/composite_type_test.exs @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/test/constraint_test.exs b/test/constraint_test.exs index 7c63f3c5..5266f194 100644 --- a/test/constraint_test.exs +++ b/test/constraint_test.exs @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/test/create_test.exs b/test/create_test.exs index 92effd16..e605910f 100644 --- a/test/create_test.exs +++ b/test/create_test.exs @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/test/custom_expression_test.exs b/test/custom_expression_test.exs index 7f204eef..959cbd89 100644 --- a/test/custom_expression_test.exs +++ b/test/custom_expression_test.exs @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/test/custom_index_test.exs b/test/custom_index_test.exs index 9d02b655..7e866f62 100644 --- a/test/custom_index_test.exs +++ b/test/custom_index_test.exs @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/test/cve/empty_atomic_non_bulk_actions_policy_bypass_test.exs b/test/cve/empty_atomic_non_bulk_actions_policy_bypass_test.exs index 02d702f5..d0911302 100644 --- a/test/cve/empty_atomic_non_bulk_actions_policy_bypass_test.exs +++ b/test/cve/empty_atomic_non_bulk_actions_policy_bypass_test.exs @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/test/destroy_test.exs b/test/destroy_test.exs index 208b2038..65ee4365 100644 --- a/test/destroy_test.exs +++ b/test/destroy_test.exs @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/test/dev_migrations_test.exs b/test/dev_migrations_test.exs index 64cbb7c1..5716fffb 100644 --- a/test/dev_migrations_test.exs +++ b/test/dev_migrations_test.exs @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/test/distinct_test.exs b/test/distinct_test.exs index a616cac8..8e7ccaac 100644 --- a/test/distinct_test.exs +++ b/test/distinct_test.exs @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/test/ecto_compatibility_test.exs b/test/ecto_compatibility_test.exs index 3670d021..178ea920 100644 --- a/test/ecto_compatibility_test.exs +++ b/test/ecto_compatibility_test.exs @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/test/embeddable_resource_test.exs b/test/embeddable_resource_test.exs index d30c11c3..ba2609b0 100644 --- a/test/embeddable_resource_test.exs +++ b/test/embeddable_resource_test.exs @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/test/enum_test.exs b/test/enum_test.exs index 0dea90a8..07ee697d 100644 --- a/test/enum_test.exs +++ b/test/enum_test.exs @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/test/error_expr_test.exs b/test/error_expr_test.exs index 98719104..f4a4f35b 100644 --- a/test/error_expr_test.exs +++ b/test/error_expr_test.exs @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/test/filter_child_relationship_by_parent_relationship_test.exs b/test/filter_child_relationship_by_parent_relationship_test.exs index 63a50eef..5b224ddb 100644 --- a/test/filter_child_relationship_by_parent_relationship_test.exs +++ b/test/filter_child_relationship_by_parent_relationship_test.exs @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/test/filter_field_policy_test.exs b/test/filter_field_policy_test.exs index 6778e70b..a6485bf9 100644 --- a/test/filter_field_policy_test.exs +++ b/test/filter_field_policy_test.exs @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/test/filter_test.exs b/test/filter_test.exs index 0172fb81..5492864b 100644 --- a/test/filter_test.exs +++ b/test/filter_test.exs @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/test/load_test.exs b/test/load_test.exs index fa9c8aba..64300139 100644 --- a/test/load_test.exs +++ b/test/load_test.exs @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/test/lock_test.exs b/test/lock_test.exs index 01122f50..40cebf44 100644 --- a/test/lock_test.exs +++ b/test/lock_test.exs @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/test/ltree_test.exs b/test/ltree_test.exs index 33b3c1ba..36de46fc 100644 --- a/test/ltree_test.exs +++ b/test/ltree_test.exs @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/test/manual_relationships_test.exs b/test/manual_relationships_test.exs index 3f4af170..b1a7689b 100644 --- a/test/manual_relationships_test.exs +++ b/test/manual_relationships_test.exs @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/test/manual_update_test.exs b/test/manual_update_test.exs index 74a6ec35..bfc5e322 100644 --- a/test/manual_update_test.exs +++ b/test/manual_update_test.exs @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/test/many_to_many_expr_test.exs b/test/many_to_many_expr_test.exs index 942168fc..4067fb51 100644 --- a/test/many_to_many_expr_test.exs +++ b/test/many_to_many_expr_test.exs @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/test/migration_generator_test.exs b/test/migration_generator_test.exs index 41b16774..b3d1fd17 100644 --- a/test/migration_generator_test.exs +++ b/test/migration_generator_test.exs @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/test/mix/tasks/ash_postgres.install_test.exs b/test/mix/tasks/ash_postgres.install_test.exs index e8ac1154..44e00c46 100644 --- a/test/mix/tasks/ash_postgres.install_test.exs +++ b/test/mix/tasks/ash_postgres.install_test.exs @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/test/mix_squash_snapshots_test.exs b/test/mix_squash_snapshots_test.exs index 352430ae..68f34973 100644 --- a/test/mix_squash_snapshots_test.exs +++ b/test/mix_squash_snapshots_test.exs @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/test/multi_domain_calculations_test.exs b/test/multi_domain_calculations_test.exs index 54652f63..fd9a8059 100644 --- a/test/multi_domain_calculations_test.exs +++ b/test/multi_domain_calculations_test.exs @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/test/multitenancy_test.exs b/test/multitenancy_test.exs index 3e17c1ad..56ee9ef6 100644 --- a/test/multitenancy_test.exs +++ b/test/multitenancy_test.exs @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/test/parent_filter_test.exs b/test/parent_filter_test.exs index 42f8326e..4e364211 100644 --- a/test/parent_filter_test.exs +++ b/test/parent_filter_test.exs @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/test/parent_sort_test.exs b/test/parent_sort_test.exs index 7d472f2d..b1532416 100644 --- a/test/parent_sort_test.exs +++ b/test/parent_sort_test.exs @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/test/polymorphism_test.exs b/test/polymorphism_test.exs index ecd8dc9d..630b7da1 100644 --- a/test/polymorphism_test.exs +++ b/test/polymorphism_test.exs @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/test/primary_key_test.exs b/test/primary_key_test.exs index 8812bc0e..792520c3 100644 --- a/test/primary_key_test.exs +++ b/test/primary_key_test.exs @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/test/references_test.exs b/test/references_test.exs index 59151ba3..49a661bd 100644 --- a/test/references_test.exs +++ b/test/references_test.exs @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/test/rel_with_parent_filter_test.exs b/test/rel_with_parent_filter_test.exs index bdcc301d..ba178713 100644 --- a/test/rel_with_parent_filter_test.exs +++ b/test/rel_with_parent_filter_test.exs @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/test/resource_generator_test.exs b/test/resource_generator_test.exs index 4c1f916c..1c793ba0 100644 --- a/test/resource_generator_test.exs +++ b/test/resource_generator_test.exs @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/test/schema_test.exs b/test/schema_test.exs index be04d3bb..235a027a 100644 --- a/test/schema_test.exs +++ b/test/schema_test.exs @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/test/select_test.exs b/test/select_test.exs index 7c440b10..cf21a6cb 100644 --- a/test/select_test.exs +++ b/test/select_test.exs @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/test/sort_test.exs b/test/sort_test.exs index c1afc99a..da34a304 100644 --- a/test/sort_test.exs +++ b/test/sort_test.exs @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/test/storage_types_test.exs b/test/storage_types_test.exs index efdb0195..ad414bf8 100644 --- a/test/storage_types_test.exs +++ b/test/storage_types_test.exs @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/test/subquery_test.exs b/test/subquery_test.exs index 9795730b..6d4da873 100644 --- a/test/subquery_test.exs +++ b/test/subquery_test.exs @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/test/support/complex_calculations/domain.ex b/test/support/complex_calculations/domain.ex index 6356daa3..bf5b416d 100644 --- a/test/support/complex_calculations/domain.ex +++ b/test/support/complex_calculations/domain.ex @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/test/support/complex_calculations/resources/certification.ex b/test/support/complex_calculations/resources/certification.ex index 317a5dc1..ea5ae573 100644 --- a/test/support/complex_calculations/resources/certification.ex +++ b/test/support/complex_calculations/resources/certification.ex @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/test/support/complex_calculations/resources/channel.ex b/test/support/complex_calculations/resources/channel.ex index af99ed29..a59f14bf 100644 --- a/test/support/complex_calculations/resources/channel.ex +++ b/test/support/complex_calculations/resources/channel.ex @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/test/support/complex_calculations/resources/channel_member.ex b/test/support/complex_calculations/resources/channel_member.ex index 7feb3c9d..ba4d1b8f 100644 --- a/test/support/complex_calculations/resources/channel_member.ex +++ b/test/support/complex_calculations/resources/channel_member.ex @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/test/support/complex_calculations/resources/dm_channel.ex b/test/support/complex_calculations/resources/dm_channel.ex index 2113a3d5..2dd67b9b 100644 --- a/test/support/complex_calculations/resources/dm_channel.ex +++ b/test/support/complex_calculations/resources/dm_channel.ex @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/test/support/complex_calculations/resources/documentation.ex b/test/support/complex_calculations/resources/documentation.ex index 88a3b7df..aadc0c81 100644 --- a/test/support/complex_calculations/resources/documentation.ex +++ b/test/support/complex_calculations/resources/documentation.ex @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/test/support/complex_calculations/resources/folder.ex b/test/support/complex_calculations/resources/folder.ex index c0faefe6..5b131c25 100644 --- a/test/support/complex_calculations/resources/folder.ex +++ b/test/support/complex_calculations/resources/folder.ex @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/test/support/complex_calculations/resources/folder_item.ex b/test/support/complex_calculations/resources/folder_item.ex index 7404970e..38f7cac7 100644 --- a/test/support/complex_calculations/resources/folder_item.ex +++ b/test/support/complex_calculations/resources/folder_item.ex @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/test/support/complex_calculations/resources/skill.ex b/test/support/complex_calculations/resources/skill.ex index 44e8dfff..20874506 100644 --- a/test/support/complex_calculations/resources/skill.ex +++ b/test/support/complex_calculations/resources/skill.ex @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/test/support/concat.ex b/test/support/concat.ex index 50b34373..cb2ffd7c 100644 --- a/test/support/concat.ex +++ b/test/support/concat.ex @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/test/support/dev_test_repo.ex b/test/support/dev_test_repo.ex index c69abe43..23fcbe37 100644 --- a/test/support/dev_test_repo.ex +++ b/test/support/dev_test_repo.ex @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/test/support/domain.ex b/test/support/domain.ex index ecd82d96..2fb81323 100644 --- a/test/support/domain.ex +++ b/test/support/domain.ex @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/test/support/multi_domain_calculations/domain_one.ex b/test/support/multi_domain_calculations/domain_one.ex index b5e091f4..0414e955 100644 --- a/test/support/multi_domain_calculations/domain_one.ex +++ b/test/support/multi_domain_calculations/domain_one.ex @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/test/support/multi_domain_calculations/domain_one/item.ex b/test/support/multi_domain_calculations/domain_one/item.ex index fa07ac9a..709ef7a0 100644 --- a/test/support/multi_domain_calculations/domain_one/item.ex +++ b/test/support/multi_domain_calculations/domain_one/item.ex @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/test/support/multi_domain_calculations/domain_three.ex b/test/support/multi_domain_calculations/domain_three.ex index a452e013..4689f0a5 100644 --- a/test/support/multi_domain_calculations/domain_three.ex +++ b/test/support/multi_domain_calculations/domain_three.ex @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/test/support/multi_domain_calculations/domain_three/relationship_item.ex b/test/support/multi_domain_calculations/domain_three/relationship_item.ex index 9c15eb0c..67185dfc 100644 --- a/test/support/multi_domain_calculations/domain_three/relationship_item.ex +++ b/test/support/multi_domain_calculations/domain_three/relationship_item.ex @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/test/support/multi_domain_calculations/domain_two.ex b/test/support/multi_domain_calculations/domain_two.ex index 715960fb..8ff13982 100644 --- a/test/support/multi_domain_calculations/domain_two.ex +++ b/test/support/multi_domain_calculations/domain_two.ex @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/test/support/multi_domain_calculations/domain_two/other_item.ex b/test/support/multi_domain_calculations/domain_two/other_item.ex index b7e65fd7..be9d7e95 100644 --- a/test/support/multi_domain_calculations/domain_two/other_item.ex +++ b/test/support/multi_domain_calculations/domain_two/other_item.ex @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/test/support/multi_domain_calculations/domain_two/sub_item.ex b/test/support/multi_domain_calculations/domain_two/sub_item.ex index 76550194..941368e5 100644 --- a/test/support/multi_domain_calculations/domain_two/sub_item.ex +++ b/test/support/multi_domain_calculations/domain_two/sub_item.ex @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/test/support/multitenancy/domain.ex b/test/support/multitenancy/domain.ex index 1ee5e90b..c711e7be 100644 --- a/test/support/multitenancy/domain.ex +++ b/test/support/multitenancy/domain.ex @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/test/support/multitenancy/resources/composite_key_post.ex b/test/support/multitenancy/resources/composite_key_post.ex index b7856998..55bc4b45 100644 --- a/test/support/multitenancy/resources/composite_key_post.ex +++ b/test/support/multitenancy/resources/composite_key_post.ex @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/test/support/multitenancy/resources/cross_tenant_post_link.ex b/test/support/multitenancy/resources/cross_tenant_post_link.ex index e79e0cf8..eee4b60f 100644 --- a/test/support/multitenancy/resources/cross_tenant_post_link.ex +++ b/test/support/multitenancy/resources/cross_tenant_post_link.ex @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/test/support/multitenancy/resources/dev_migrations_org.ex b/test/support/multitenancy/resources/dev_migrations_org.ex index 0cc59783..33d19785 100644 --- a/test/support/multitenancy/resources/dev_migrations_org.ex +++ b/test/support/multitenancy/resources/dev_migrations_org.ex @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/test/support/multitenancy/resources/named_org.ex b/test/support/multitenancy/resources/named_org.ex index 714c090d..0b800106 100644 --- a/test/support/multitenancy/resources/named_org.ex +++ b/test/support/multitenancy/resources/named_org.ex @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/test/support/multitenancy/resources/non_multitenant_post_link.ex b/test/support/multitenancy/resources/non_multitenant_post_link.ex index 8f2a990e..e8e0cca6 100644 --- a/test/support/multitenancy/resources/non_multitenant_post_link.ex +++ b/test/support/multitenancy/resources/non_multitenant_post_link.ex @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/test/support/multitenancy/resources/non_multitenant_post_multitenant_link.ex b/test/support/multitenancy/resources/non_multitenant_post_multitenant_link.ex index 0eb78386..79478246 100644 --- a/test/support/multitenancy/resources/non_multitenant_post_multitenant_link.ex +++ b/test/support/multitenancy/resources/non_multitenant_post_multitenant_link.ex @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/test/support/multitenancy/resources/org.ex b/test/support/multitenancy/resources/org.ex index 21638793..66e75a23 100644 --- a/test/support/multitenancy/resources/org.ex +++ b/test/support/multitenancy/resources/org.ex @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/test/support/multitenancy/resources/post.ex b/test/support/multitenancy/resources/post.ex index cab27827..871e504b 100644 --- a/test/support/multitenancy/resources/post.ex +++ b/test/support/multitenancy/resources/post.ex @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/test/support/multitenancy/resources/post_link.ex b/test/support/multitenancy/resources/post_link.ex index dcdfdc41..6d45a2ae 100644 --- a/test/support/multitenancy/resources/post_link.ex +++ b/test/support/multitenancy/resources/post_link.ex @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/test/support/multitenancy/resources/user.ex b/test/support/multitenancy/resources/user.ex index 7406eb07..0713b966 100644 --- a/test/support/multitenancy/resources/user.ex +++ b/test/support/multitenancy/resources/user.ex @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/test/support/relationships/comments_containing_title.ex b/test/support/relationships/comments_containing_title.ex index e17ee933..156d4ec7 100644 --- a/test/support/relationships/comments_containing_title.ex +++ b/test/support/relationships/comments_containing_title.ex @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/test/support/repo_case.ex b/test/support/repo_case.ex index 708e2d42..5e94fe98 100644 --- a/test/support/repo_case.ex +++ b/test/support/repo_case.ex @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/test/support/resources/account.ex b/test/support/resources/account.ex index 87e6544a..cf4b7f30 100644 --- a/test/support/resources/account.ex +++ b/test/support/resources/account.ex @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/test/support/resources/author.ex b/test/support/resources/author.ex index 097a771c..16ca5a8e 100644 --- a/test/support/resources/author.ex +++ b/test/support/resources/author.ex @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/test/support/resources/bio.ex b/test/support/resources/bio.ex index 8c0b33f0..e173bc05 100644 --- a/test/support/resources/bio.ex +++ b/test/support/resources/bio.ex @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/test/support/resources/chat.ex b/test/support/resources/chat.ex index 5c04c1af..c237fe42 100644 --- a/test/support/resources/chat.ex +++ b/test/support/resources/chat.ex @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/test/support/resources/co_authored_post.ex b/test/support/resources/co_authored_post.ex index 022c9eca..c49c3c2b 100644 --- a/test/support/resources/co_authored_post.ex +++ b/test/support/resources/co_authored_post.ex @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/test/support/resources/comedian.ex b/test/support/resources/comedian.ex index 2404d56c..f2b14cbf 100644 --- a/test/support/resources/comedian.ex +++ b/test/support/resources/comedian.ex @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/test/support/resources/comment.ex b/test/support/resources/comment.ex index cbbc6abb..133005db 100644 --- a/test/support/resources/comment.ex +++ b/test/support/resources/comment.ex @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/test/support/resources/comment_link.ex b/test/support/resources/comment_link.ex index 5caab846..42fba683 100644 --- a/test/support/resources/comment_link.ex +++ b/test/support/resources/comment_link.ex @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/test/support/resources/content.ex b/test/support/resources/content.ex index 8b823644..4e57c7be 100644 --- a/test/support/resources/content.ex +++ b/test/support/resources/content.ex @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/test/support/resources/content_visibility_group.ex b/test/support/resources/content_visibility_group.ex index 797d7c7e..b261f1f3 100644 --- a/test/support/resources/content_visibility_group.ex +++ b/test/support/resources/content_visibility_group.ex @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/test/support/resources/csv.ex b/test/support/resources/csv.ex index ccf5b418..c4e14393 100644 --- a/test/support/resources/csv.ex +++ b/test/support/resources/csv.ex @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/test/support/resources/customer.ex b/test/support/resources/customer.ex index 834fcead..0ab674b9 100644 --- a/test/support/resources/customer.ex +++ b/test/support/resources/customer.ex @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/test/support/resources/db_point.ex b/test/support/resources/db_point.ex index cf018f4a..e9e20131 100644 --- a/test/support/resources/db_point.ex +++ b/test/support/resources/db_point.ex @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/test/support/resources/db_string_point.ex b/test/support/resources/db_string_point.ex index e78c7536..48edf2dd 100644 --- a/test/support/resources/db_string_point.ex +++ b/test/support/resources/db_string_point.ex @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/test/support/resources/entity.ex b/test/support/resources/entity.ex index c693d02a..18c1b3f2 100644 --- a/test/support/resources/entity.ex +++ b/test/support/resources/entity.ex @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/test/support/resources/integer_post.ex b/test/support/resources/integer_post.ex index 2237e723..d270a933 100644 --- a/test/support/resources/integer_post.ex +++ b/test/support/resources/integer_post.ex @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/test/support/resources/invite.ex b/test/support/resources/invite.ex index 06d3ea70..07456bfc 100644 --- a/test/support/resources/invite.ex +++ b/test/support/resources/invite.ex @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/test/support/resources/joke.ex b/test/support/resources/joke.ex index 16414cb4..b66c1970 100644 --- a/test/support/resources/joke.ex +++ b/test/support/resources/joke.ex @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/test/support/resources/manager.ex b/test/support/resources/manager.ex index e5b2cce9..9ef2a0a1 100644 --- a/test/support/resources/manager.ex +++ b/test/support/resources/manager.ex @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/test/support/resources/message.ex b/test/support/resources/message.ex index 4cbc9533..1085c337 100644 --- a/test/support/resources/message.ex +++ b/test/support/resources/message.ex @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/test/support/resources/note.ex b/test/support/resources/note.ex index 0facb927..98ccef89 100644 --- a/test/support/resources/note.ex +++ b/test/support/resources/note.ex @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/test/support/resources/order.ex b/test/support/resources/order.ex index fead194c..76c7ef6f 100644 --- a/test/support/resources/order.ex +++ b/test/support/resources/order.ex @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/test/support/resources/organization.ex b/test/support/resources/organization.ex index d375a2db..e5dfd492 100644 --- a/test/support/resources/organization.ex +++ b/test/support/resources/organization.ex @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/test/support/resources/permalink.ex b/test/support/resources/permalink.ex index adca302f..e3aadaa9 100644 --- a/test/support/resources/permalink.ex +++ b/test/support/resources/permalink.ex @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/test/support/resources/post.ex b/test/support/resources/post.ex index 2b85570a..c15b6b0e 100644 --- a/test/support/resources/post.ex +++ b/test/support/resources/post.ex @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/test/support/resources/post_follower.ex b/test/support/resources/post_follower.ex index 9e71b398..aa28f149 100644 --- a/test/support/resources/post_follower.ex +++ b/test/support/resources/post_follower.ex @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/test/support/resources/post_link.ex b/test/support/resources/post_link.ex index bc6390c8..147e09a9 100644 --- a/test/support/resources/post_link.ex +++ b/test/support/resources/post_link.ex @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/test/support/resources/post_tag.ex b/test/support/resources/post_tag.ex index 2ae47876..96306f91 100644 --- a/test/support/resources/post_tag.ex +++ b/test/support/resources/post_tag.ex @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/test/support/resources/post_views.ex b/test/support/resources/post_views.ex index c3b3aaaa..37bc2f54 100644 --- a/test/support/resources/post_views.ex +++ b/test/support/resources/post_views.ex @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/test/support/resources/post_with_empty_update.ex b/test/support/resources/post_with_empty_update.ex index 06693738..2e808ea4 100644 --- a/test/support/resources/post_with_empty_update.ex +++ b/test/support/resources/post_with_empty_update.ex @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/test/support/resources/product.ex b/test/support/resources/product.ex index fa2bbee9..194f0586 100644 --- a/test/support/resources/product.ex +++ b/test/support/resources/product.ex @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/test/support/resources/profile.ex b/test/support/resources/profile.ex index b06bab6f..9a14ee30 100644 --- a/test/support/resources/profile.ex +++ b/test/support/resources/profile.ex @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/test/support/resources/punchline.ex b/test/support/resources/punchline.ex index 66da6063..701fe540 100644 --- a/test/support/resources/punchline.ex +++ b/test/support/resources/punchline.ex @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/test/support/resources/rating.ex b/test/support/resources/rating.ex index 1fab32b1..b4ac159c 100644 --- a/test/support/resources/rating.ex +++ b/test/support/resources/rating.ex @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/test/support/resources/record.ex b/test/support/resources/record.ex index 0045db83..658b5f3d 100644 --- a/test/support/resources/record.ex +++ b/test/support/resources/record.ex @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/test/support/resources/record_temp_entity.ex b/test/support/resources/record_temp_entity.ex index ba0f73e3..c44bfdbf 100644 --- a/test/support/resources/record_temp_entity.ex +++ b/test/support/resources/record_temp_entity.ex @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/test/support/resources/role.ex b/test/support/resources/role.ex index df3635be..894e83bc 100644 --- a/test/support/resources/role.ex +++ b/test/support/resources/role.ex @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/test/support/resources/rsvp.ex b/test/support/resources/rsvp.ex index f364c333..af39eab0 100644 --- a/test/support/resources/rsvp.ex +++ b/test/support/resources/rsvp.ex @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/test/support/resources/settings.ex b/test/support/resources/settings.ex index e348f847..b18acb2c 100644 --- a/test/support/resources/settings.ex +++ b/test/support/resources/settings.ex @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/test/support/resources/staff_group.ex b/test/support/resources/staff_group.ex index 4aafeca8..dc3a23b1 100644 --- a/test/support/resources/staff_group.ex +++ b/test/support/resources/staff_group.ex @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/test/support/resources/staff_group_member.ex b/test/support/resources/staff_group_member.ex index a9ce9e97..fad757a6 100644 --- a/test/support/resources/staff_group_member.ex +++ b/test/support/resources/staff_group_member.ex @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/test/support/resources/standup_club.ex b/test/support/resources/standup_club.ex index ffa91044..af3047a2 100644 --- a/test/support/resources/standup_club.ex +++ b/test/support/resources/standup_club.ex @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/test/support/resources/stateful_post_follwer.ex b/test/support/resources/stateful_post_follwer.ex index cb66359c..017e979c 100644 --- a/test/support/resources/stateful_post_follwer.ex +++ b/test/support/resources/stateful_post_follwer.ex @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/test/support/resources/subquery/access.ex b/test/support/resources/subquery/access.ex index 9c971486..2ef87bb7 100644 --- a/test/support/resources/subquery/access.ex +++ b/test/support/resources/subquery/access.ex @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/test/support/resources/subquery/child.ex b/test/support/resources/subquery/child.ex index 5a9cd6af..4a078ebd 100644 --- a/test/support/resources/subquery/child.ex +++ b/test/support/resources/subquery/child.ex @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/test/support/resources/subquery/child_domain.ex b/test/support/resources/subquery/child_domain.ex index ab33df34..3ab11eef 100644 --- a/test/support/resources/subquery/child_domain.ex +++ b/test/support/resources/subquery/child_domain.ex @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/test/support/resources/subquery/parent.ex b/test/support/resources/subquery/parent.ex index a72c0054..66b5d0ea 100644 --- a/test/support/resources/subquery/parent.ex +++ b/test/support/resources/subquery/parent.ex @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/test/support/resources/subquery/parent_domain.ex b/test/support/resources/subquery/parent_domain.ex index d2e200d3..77d3d246 100644 --- a/test/support/resources/subquery/parent_domain.ex +++ b/test/support/resources/subquery/parent_domain.ex @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/test/support/resources/subquery/through.ex b/test/support/resources/subquery/through.ex index 3c0f4e75..a0e59604 100644 --- a/test/support/resources/subquery/through.ex +++ b/test/support/resources/subquery/through.ex @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/test/support/resources/tag.ex b/test/support/resources/tag.ex index 66bec825..b29a2cd0 100644 --- a/test/support/resources/tag.ex +++ b/test/support/resources/tag.ex @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/test/support/resources/temp_entity.ex b/test/support/resources/temp_entity.ex index 5507836e..308c6f75 100644 --- a/test/support/resources/temp_entity.ex +++ b/test/support/resources/temp_entity.ex @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/test/support/resources/user.ex b/test/support/resources/user.ex index 1009dccd..8dd88866 100644 --- a/test/support/resources/user.ex +++ b/test/support/resources/user.ex @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/test/support/string_agg.ex b/test/support/string_agg.ex index e6f92821..9cc5a8da 100644 --- a/test/support/string_agg.ex +++ b/test/support/string_agg.ex @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/test/support/test_app.ex b/test/support/test_app.ex index 97d98fc2..bcc80e91 100644 --- a/test/support/test_app.ex +++ b/test/support/test_app.ex @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/test/support/test_custom_extension.ex b/test/support/test_custom_extension.ex index bd6d26d3..35955d79 100644 --- a/test/support/test_custom_extension.ex +++ b/test/support/test_custom_extension.ex @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/test/support/test_no_sandbox_repo.ex b/test/support/test_no_sandbox_repo.ex index 14ec8160..fb1437d6 100644 --- a/test/support/test_no_sandbox_repo.ex +++ b/test/support/test_no_sandbox_repo.ex @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/test/support/test_repo.ex b/test/support/test_repo.ex index 8dbc64c1..cf45c646 100644 --- a/test/support/test_repo.ex +++ b/test/support/test_repo.ex @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/test/support/trigram_word_similarity.ex b/test/support/trigram_word_similarity.ex index 77c267c7..7b23166b 100644 --- a/test/support/trigram_word_similarity.ex +++ b/test/support/trigram_word_similarity.ex @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/test/support/types/composite_point.ex b/test/support/types/composite_point.ex index b82887b9..db660894 100644 --- a/test/support/types/composite_point.ex +++ b/test/support/types/composite_point.ex @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/test/support/types/email.ex b/test/support/types/email.ex index 9f552b6d..5f7412ea 100644 --- a/test/support/types/email.ex +++ b/test/support/types/email.ex @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/test/support/types/money.ex b/test/support/types/money.ex index 6b2d79f8..09cc162d 100644 --- a/test/support/types/money.ex +++ b/test/support/types/money.ex @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/test/support/types/person_detail.ex b/test/support/types/person_detail.ex index 3666300f..5b80861a 100644 --- a/test/support/types/person_detail.ex +++ b/test/support/types/person_detail.ex @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/test/support/types/point.ex b/test/support/types/point.ex index 819d0287..7647688c 100644 --- a/test/support/types/point.ex +++ b/test/support/types/point.ex @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/test/support/types/response.ex b/test/support/types/response.ex index 9428ee15..8c20dbf3 100644 --- a/test/support/types/response.ex +++ b/test/support/types/response.ex @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/test/support/types/status.ex b/test/support/types/status.ex index 7453e955..b6eab647 100644 --- a/test/support/types/status.ex +++ b/test/support/types/status.ex @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/test/support/types/status_enum.ex b/test/support/types/status_enum.ex index 2a845ff2..ac93d3b9 100644 --- a/test/support/types/status_enum.ex +++ b/test/support/types/status_enum.ex @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/test/support/types/status_enum_no_cast.ex b/test/support/types/status_enum_no_cast.ex index 032266de..94cc6125 100644 --- a/test/support/types/status_enum_no_cast.ex +++ b/test/support/types/status_enum_no_cast.ex @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/test/support/types/string_point.ex b/test/support/types/string_point.ex index 1be38e28..42430c6d 100644 --- a/test/support/types/string_point.ex +++ b/test/support/types/string_point.ex @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/test/support/unrelated_aggregates/profile.ex b/test/support/unrelated_aggregates/profile.ex index 257a44e3..4f17f63e 100644 --- a/test/support/unrelated_aggregates/profile.ex +++ b/test/support/unrelated_aggregates/profile.ex @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/test/support/unrelated_aggregates/report.ex b/test/support/unrelated_aggregates/report.ex index 025e550c..4619aa12 100644 --- a/test/support/unrelated_aggregates/report.ex +++ b/test/support/unrelated_aggregates/report.ex @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/test/support/unrelated_aggregates/secure_profile.ex b/test/support/unrelated_aggregates/secure_profile.ex index 7f380da2..f345769b 100644 --- a/test/support/unrelated_aggregates/secure_profile.ex +++ b/test/support/unrelated_aggregates/secure_profile.ex @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/test/support/unrelated_aggregates/user.ex b/test/support/unrelated_aggregates/user.ex index 22529079..f3a20de8 100644 --- a/test/support/unrelated_aggregates/user.ex +++ b/test/support/unrelated_aggregates/user.ex @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/test/test_helper.exs b/test/test_helper.exs index aba4a697..81659b92 100644 --- a/test/test_helper.exs +++ b/test/test_helper.exs @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/test/transaction_test.exs b/test/transaction_test.exs index a4403a16..7939024f 100644 --- a/test/transaction_test.exs +++ b/test/transaction_test.exs @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/test/tuple_test.exs b/test/tuple_test.exs index 5901f5c4..364c0e69 100644 --- a/test/tuple_test.exs +++ b/test/tuple_test.exs @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/test/type_test.exs b/test/type_test.exs index 2e7c3132..99c866ac 100644 --- a/test/type_test.exs +++ b/test/type_test.exs @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/test/unique_identity_test.exs b/test/unique_identity_test.exs index 618ead15..10c3d4aa 100644 --- a/test/unique_identity_test.exs +++ b/test/unique_identity_test.exs @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/test/unrelated_aggregates_test.exs b/test/unrelated_aggregates_test.exs index 1c4ca107..82d466ae 100644 --- a/test/unrelated_aggregates_test.exs +++ b/test/unrelated_aggregates_test.exs @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/test/update_test.exs b/test/update_test.exs index 22fb4af2..17756840 100644 --- a/test/update_test.exs +++ b/test/update_test.exs @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT diff --git a/test/upsert_test.exs b/test/upsert_test.exs index 0f3308a7..dc1accaa 100644 --- a/test/upsert_test.exs +++ b/test/upsert_test.exs @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2020 Zach Daniel +# SPDX-FileCopyrightText: 2019 ash_postgres contributors # # SPDX-License-Identifier: MIT From f44cee5e185da7dff4ddb26b8bd65bbc78e75238 Mon Sep 17 00:00:00 2001 From: Zach Daniel Date: Tue, 14 Oct 2025 22:23:15 -0400 Subject: [PATCH 162/174] chore: check `upsert?` as well inside of new code not technically necessary but doesn't hurt --- lib/data_layer.ex | 2 +- mix.lock | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/data_layer.ex b/lib/data_layer.ex index 894de3fb..7dbb19d2 100644 --- a/lib/data_layer.ex +++ b/lib/data_layer.ex @@ -2042,7 +2042,7 @@ defmodule AshPostgres.DataLayer do # if it's single the return_skipped_upsert? is handled at the # call site https://github.com/ash-project/ash_postgres/blob/0b21d4a99cc3f6d8676947e291ac9b9d57ad6e2e/lib/data_layer.ex#L3046-L3046 result = - if options[:return_skipped_upsert?] && !opts[:single?] do + if options[:upsert?] && options[:return_skipped_upsert?] && !opts[:single?] do [changeset | _] = changesets results_by_identity = diff --git a/mix.lock b/mix.lock index 96080205..03a5fd8e 100644 --- a/mix.lock +++ b/mix.lock @@ -1,5 +1,5 @@ %{ - "ash": {:hex, :ash, "3.6.2", "90d1c8296be777b90caabf51b99323d6618a0b92594dfab92b02bdf848ac38bf", [:mix], [{:decimal, "~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:ecto, "~> 3.7", [hex: :ecto, repo: "hexpm", optional: false]}, {:ets, "~> 0.8", [hex: :ets, repo: "hexpm", optional: false]}, {:igniter, ">= 0.6.29 and < 1.0.0-0", [hex: :igniter, repo: "hexpm", optional: true]}, {:jason, ">= 1.0.0", [hex: :jason, repo: "hexpm", optional: false]}, {:picosat_elixir, "~> 0.2", [hex: :picosat_elixir, repo: "hexpm", optional: true]}, {:plug, ">= 0.0.0", [hex: :plug, repo: "hexpm", optional: true]}, {:reactor, "~> 0.11", [hex: :reactor, repo: "hexpm", optional: false]}, {:simple_sat, ">= 0.1.1 and < 1.0.0-0", [hex: :simple_sat, repo: "hexpm", optional: true]}, {:spark, ">= 2.3.3 and < 3.0.0-0", [hex: :spark, repo: "hexpm", optional: false]}, {:splode, ">= 0.2.6 and < 1.0.0-0", [hex: :splode, repo: "hexpm", optional: false]}, {:stream_data, "~> 1.0", [hex: :stream_data, repo: "hexpm", optional: false]}, {:telemetry, "~> 1.1", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "3546b5798dd24576cc451f6e03f3d6e3bb62666c0921bfe8aae700c599d9c38d"}, + "ash": {:hex, :ash, "3.6.3", "526ec1989a6be80798f585a8ad9e08752330e8a5e32e223fe7161955f994dfd4", [:mix], [{:decimal, "~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:ecto, "~> 3.7", [hex: :ecto, repo: "hexpm", optional: false]}, {:ets, "~> 0.8", [hex: :ets, repo: "hexpm", optional: false]}, {:igniter, ">= 0.6.29 and < 1.0.0-0", [hex: :igniter, repo: "hexpm", optional: true]}, {:jason, ">= 1.0.0", [hex: :jason, repo: "hexpm", optional: false]}, {:picosat_elixir, "~> 0.2", [hex: :picosat_elixir, repo: "hexpm", optional: true]}, {:plug, ">= 0.0.0", [hex: :plug, repo: "hexpm", optional: true]}, {:reactor, "~> 0.11", [hex: :reactor, repo: "hexpm", optional: false]}, {:simple_sat, ">= 0.1.1 and < 1.0.0-0", [hex: :simple_sat, repo: "hexpm", optional: true]}, {:spark, ">= 2.3.3 and < 3.0.0-0", [hex: :spark, repo: "hexpm", optional: false]}, {:splode, ">= 0.2.6 and < 1.0.0-0", [hex: :splode, repo: "hexpm", optional: false]}, {:stream_data, "~> 1.0", [hex: :stream_data, repo: "hexpm", optional: false]}, {:telemetry, "~> 1.1", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "23f9b85d545aee27011e371ffc4a19f7af9195e89c2038e50007084cdd1d31b5"}, "ash_sql": {:hex, :ash_sql, "0.3.4", "c8c0446fbd6d3e6920f793b971c83ba3d14f96095036366d313b72656400509d", [:mix], [{:ash, ">= 3.5.43 and < 4.0.0-0", [hex: :ash, repo: "hexpm", optional: false]}, {:ecto, "~> 3.9", [hex: :ecto, repo: "hexpm", optional: false]}, {:ecto_sql, "~> 3.9", [hex: :ecto_sql, repo: "hexpm", optional: false]}], "hexpm", "4edb1fb707048a41f7944274b1a0b571aa3c9117b8a7a12809ca023b6f955cb4"}, "benchee": {:hex, :benchee, "1.4.0", "9f1f96a30ac80bab94faad644b39a9031d5632e517416a8ab0a6b0ac4df124ce", [:mix], [{:deep_merge, "~> 1.0", [hex: :deep_merge, repo: "hexpm", optional: false]}, {:statistex, "~> 1.0", [hex: :statistex, repo: "hexpm", optional: false]}, {:table, "~> 0.1.0", [hex: :table, repo: "hexpm", optional: true]}], "hexpm", "299cd10dd8ce51c9ea3ddb74bb150f93d25e968f93e4c1fa31698a8e4fa5d715"}, "bunt": {:hex, :bunt, "1.0.0", "081c2c665f086849e6d57900292b3a161727ab40431219529f13c4ddcf3e7a44", [:mix], [], "hexpm", "dc5f86aa08a5f6fa6b8096f0735c4e76d54ae5c9fa2c143e5a1fc7c1cd9bb6b5"}, From eb3f91682464e29a971dc3e188093d841facc55c Mon Sep 17 00:00:00 2001 From: Zach Daniel Date: Tue, 14 Oct 2025 23:08:03 -0400 Subject: [PATCH 163/174] chore: cleanup function_exported? checks --- lib/migration_generator/migration_generator.ex | 2 +- lib/sql_implementation.ex | 6 +----- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/lib/migration_generator/migration_generator.ex b/lib/migration_generator/migration_generator.ex index 6cdbc469..9881818c 100644 --- a/lib/migration_generator/migration_generator.ex +++ b/lib/migration_generator/migration_generator.ex @@ -3227,7 +3227,7 @@ defmodule AshPostgres.MigrationGenerator do migration_type(attribute.type, attribute.constraints) type = - if :erlang.function_exported(repo, :override_migration_type, 1) do + if function_exported?(repo, :override_migration_type, 1) do repo.override_migration_type(type) else type diff --git a/lib/sql_implementation.ex b/lib/sql_implementation.ex index 3aed4340..fae3fede 100644 --- a/lib/sql_implementation.ex +++ b/lib/sql_implementation.ex @@ -311,11 +311,7 @@ defmodule AshPostgres.SqlImplementation do def parameterized_type(type, constraints) do if Ash.Type.ash_type?(type) do cast_in_query? = - if function_exported?(Ash.Type, :cast_in_query?, 2) do - Ash.Type.cast_in_query?(type, constraints) - else - Ash.Type.cast_in_query?(type) - end + Ash.Type.cast_in_query?(type, constraints) if cast_in_query? do type = Ash.Type.ecto_type(type) From 7375bfb0d90138e4dd943848ae49102bca39f5ae Mon Sep 17 00:00:00 2001 From: Zach Daniel Date: Wed, 15 Oct 2025 18:36:47 -0400 Subject: [PATCH 164/174] improvement: implement combination_acc/1 --- lib/data_layer.ex | 3 +++ mix.exs | 4 ++-- mix.lock | 4 ++-- 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/lib/data_layer.ex b/lib/data_layer.ex index 7dbb19d2..3bad7f45 100644 --- a/lib/data_layer.ex +++ b/lib/data_layer.ex @@ -889,6 +889,9 @@ defmodule AshPostgres.DataLayer do end end + @impl true + def combination_acc(query), do: AshSql.Query.combination_acc(query) + @impl true def run_aggregate_query(original_query, aggregates, resource) do AshSql.AggregateQuery.run_aggregate_query( diff --git a/mix.exs b/mix.exs index 2c0f979c..9c70ce1d 100644 --- a/mix.exs +++ b/mix.exs @@ -177,9 +177,9 @@ defmodule AshPostgres.MixProject do # Run "mix help deps" to learn about dependencies. defp deps do [ - {:ash, ash_version("~> 3.5 and >= 3.6.2")}, + {:ash, ash_version("~> 3.7")}, {:spark, "~> 2.3 and >= 2.3.4"}, - {:ash_sql, ash_sql_version("~> 0.3 and >= 0.3.2")}, + {:ash_sql, ash_sql_version("~> 0.3 and >= 0.3.6")}, {:igniter, "~> 0.6 and >= 0.6.29", optional: true}, {:ecto_sql, "~> 3.13"}, {:ecto, "~> 3.13"}, diff --git a/mix.lock b/mix.lock index 03a5fd8e..dd24d9a9 100644 --- a/mix.lock +++ b/mix.lock @@ -1,6 +1,6 @@ %{ "ash": {:hex, :ash, "3.6.3", "526ec1989a6be80798f585a8ad9e08752330e8a5e32e223fe7161955f994dfd4", [:mix], [{:decimal, "~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:ecto, "~> 3.7", [hex: :ecto, repo: "hexpm", optional: false]}, {:ets, "~> 0.8", [hex: :ets, repo: "hexpm", optional: false]}, {:igniter, ">= 0.6.29 and < 1.0.0-0", [hex: :igniter, repo: "hexpm", optional: true]}, {:jason, ">= 1.0.0", [hex: :jason, repo: "hexpm", optional: false]}, {:picosat_elixir, "~> 0.2", [hex: :picosat_elixir, repo: "hexpm", optional: true]}, {:plug, ">= 0.0.0", [hex: :plug, repo: "hexpm", optional: true]}, {:reactor, "~> 0.11", [hex: :reactor, repo: "hexpm", optional: false]}, {:simple_sat, ">= 0.1.1 and < 1.0.0-0", [hex: :simple_sat, repo: "hexpm", optional: true]}, {:spark, ">= 2.3.3 and < 3.0.0-0", [hex: :spark, repo: "hexpm", optional: false]}, {:splode, ">= 0.2.6 and < 1.0.0-0", [hex: :splode, repo: "hexpm", optional: false]}, {:stream_data, "~> 1.0", [hex: :stream_data, repo: "hexpm", optional: false]}, {:telemetry, "~> 1.1", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "23f9b85d545aee27011e371ffc4a19f7af9195e89c2038e50007084cdd1d31b5"}, - "ash_sql": {:hex, :ash_sql, "0.3.4", "c8c0446fbd6d3e6920f793b971c83ba3d14f96095036366d313b72656400509d", [:mix], [{:ash, ">= 3.5.43 and < 4.0.0-0", [hex: :ash, repo: "hexpm", optional: false]}, {:ecto, "~> 3.9", [hex: :ecto, repo: "hexpm", optional: false]}, {:ecto_sql, "~> 3.9", [hex: :ecto_sql, repo: "hexpm", optional: false]}], "hexpm", "4edb1fb707048a41f7944274b1a0b571aa3c9117b8a7a12809ca023b6f955cb4"}, + "ash_sql": {:hex, :ash_sql, "0.3.6", "6036e57243448b1cc20f8afa0b8f6dcdbd14d4ccc4aa32e7feb5ca2465b3e13a", [:mix], [{:ash, ">= 3.5.43 and < 4.0.0-0", [hex: :ash, repo: "hexpm", optional: false]}, {:ecto, "~> 3.9", [hex: :ecto, repo: "hexpm", optional: false]}, {:ecto_sql, "~> 3.9", [hex: :ecto_sql, repo: "hexpm", optional: false]}], "hexpm", "2cab83c09bc0a3d32c545691f35bb94199b4058dca6e254e8d99532d995fb8f7"}, "benchee": {:hex, :benchee, "1.4.0", "9f1f96a30ac80bab94faad644b39a9031d5632e517416a8ab0a6b0ac4df124ce", [:mix], [{:deep_merge, "~> 1.0", [hex: :deep_merge, repo: "hexpm", optional: false]}, {:statistex, "~> 1.0", [hex: :statistex, repo: "hexpm", optional: false]}, {:table, "~> 0.1.0", [hex: :table, repo: "hexpm", optional: true]}], "hexpm", "299cd10dd8ce51c9ea3ddb74bb150f93d25e968f93e4c1fa31698a8e4fa5d715"}, "bunt": {:hex, :bunt, "1.0.0", "081c2c665f086849e6d57900292b3a161727ab40431219529f13c4ddcf3e7a44", [:mix], [], "hexpm", "dc5f86aa08a5f6fa6b8096f0735c4e76d54ae5c9fa2c143e5a1fc7c1cd9bb6b5"}, "credo": {:hex, :credo, "1.7.12", "9e3c20463de4b5f3f23721527fcaf16722ec815e70ff6c60b86412c695d426c1", [:mix], [{:bunt, "~> 0.2.1 or ~> 1.0", [hex: :bunt, repo: "hexpm", optional: false]}, {:file_system, "~> 0.2 or ~> 1.0", [hex: :file_system, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "8493d45c656c5427d9c729235b99d498bd133421f3e0a683e5c1b561471291e5"}, @@ -41,7 +41,7 @@ "reactor": {:hex, :reactor, "0.17.0", "eb8bdb530dbae824e2d36a8538f8ec4f3aa7c2d1b61b04959fa787c634f88b49", [:mix], [{:igniter, "~> 0.4", [hex: :igniter, repo: "hexpm", optional: true]}, {:iterex, "~> 0.1", [hex: :iterex, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}, {:libgraph, "~> 0.16", [hex: :libgraph, repo: "hexpm", optional: false]}, {:spark, ">= 2.3.3 and < 3.0.0-0", [hex: :spark, repo: "hexpm", optional: false]}, {:splode, "~> 0.2", [hex: :splode, repo: "hexpm", optional: false]}, {:telemetry, "~> 1.2", [hex: :telemetry, repo: "hexpm", optional: false]}, {:yaml_elixir, "~> 2.11", [hex: :yaml_elixir, repo: "hexpm", optional: false]}, {:ymlr, "~> 5.0", [hex: :ymlr, repo: "hexpm", optional: false]}], "hexpm", "3c3bf71693adbad9117b11ec83cfed7d5851b916ade508ed9718de7ae165bf25"}, "req": {:hex, :req, "0.5.15", "662020efb6ea60b9f0e0fac9be88cd7558b53fe51155a2d9899de594f9906ba9", [:mix], [{:brotli, "~> 0.3.1", [hex: :brotli, repo: "hexpm", optional: true]}, {:ezstd, "~> 1.0", [hex: :ezstd, repo: "hexpm", optional: true]}, {:finch, "~> 0.17", [hex: :finch, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}, {:mime, "~> 2.0.6 or ~> 2.1", [hex: :mime, repo: "hexpm", optional: false]}, {:nimble_csv, "~> 1.0", [hex: :nimble_csv, repo: "hexpm", optional: true]}, {:plug, "~> 1.0", [hex: :plug, repo: "hexpm", optional: true]}], "hexpm", "a6513a35fad65467893ced9785457e91693352c70b58bbc045b47e5eb2ef0c53"}, "rewrite": {:hex, :rewrite, "1.2.0", "80220eb14010e175b67c939397e1a8cdaa2c32db6e2e0a9d5e23e45c0414ce21", [:mix], [{:glob_ex, "~> 0.1", [hex: :glob_ex, repo: "hexpm", optional: false]}, {:sourceror, "~> 1.0", [hex: :sourceror, repo: "hexpm", optional: false]}, {:text_diff, "~> 0.1", [hex: :text_diff, repo: "hexpm", optional: false]}], "hexpm", "a1cd702bbb9d51613ab21091f04a386d750fc6f4516b81900df082d78b2d8c50"}, - "simple_sat": {:hex, :simple_sat, "0.1.3", "f650fc3c184a5fe741868b5ac56dc77fdbb428468f6dbf1978e14d0334497578", [:mix], [], "hexpm", "a54305066a356b7194dc81db2a89232bacdc0b3edaef68ed9aba28dcbc34887b"}, + "simple_sat": {:hex, :simple_sat, "0.1.4", "39baf72cdca14f93c0b6ce2b6418b72bbb67da98fa9ca4384e2f79bbc299899d", [:mix], [], "hexpm", "3569b68e346a5fd7154b8d14173ff8bcc829f2eb7b088c30c3f42a383443930b"}, "sobelow": {:hex, :sobelow, "0.14.1", "2f81e8632f15574cba2402bcddff5497b413c01e6f094bc0ab94e83c2f74db81", [:mix], [{:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "8fac9a2bd90fdc4b15d6fca6e1608efb7f7c600fa75800813b794ee9364c87f2"}, "sourceror": {:hex, :sourceror, "1.10.0", "38397dedbbc286966ec48c7af13e228b171332be1ad731974438c77791945ce9", [:mix], [], "hexpm", "29dbdfc92e04569c9d8e6efdc422fc1d815f4bd0055dc7c51b8800fb75c4b3f1"}, "spark": {:hex, :spark, "2.3.5", "f30d30ecc3b4ab9b932d9aada66af7677fc1f297a2c349b0bcec3eafb9f996e8", [:mix], [{:igniter, ">= 0.3.64 and < 1.0.0-0", [hex: :igniter, repo: "hexpm", optional: true]}, {:jason, "~> 1.4", [hex: :jason, repo: "hexpm", optional: true]}, {:sourceror, "~> 1.2", [hex: :sourceror, repo: "hexpm", optional: true]}], "hexpm", "0e9d339704d5d148f77f2b2fef3bcfc873a9e9bb4224fcf289c545d65827202f"}, From 9bc0bede7f8d482d5c8e85b54cabbed61fa68629 Mon Sep 17 00:00:00 2001 From: Zach Daniel Date: Wed, 15 Oct 2025 18:42:01 -0400 Subject: [PATCH 165/174] chore: update ash --- mix.lock | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/mix.lock b/mix.lock index dd24d9a9..7b15d0ea 100644 --- a/mix.lock +++ b/mix.lock @@ -1,9 +1,10 @@ %{ - "ash": {:hex, :ash, "3.6.3", "526ec1989a6be80798f585a8ad9e08752330e8a5e32e223fe7161955f994dfd4", [:mix], [{:decimal, "~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:ecto, "~> 3.7", [hex: :ecto, repo: "hexpm", optional: false]}, {:ets, "~> 0.8", [hex: :ets, repo: "hexpm", optional: false]}, {:igniter, ">= 0.6.29 and < 1.0.0-0", [hex: :igniter, repo: "hexpm", optional: true]}, {:jason, ">= 1.0.0", [hex: :jason, repo: "hexpm", optional: false]}, {:picosat_elixir, "~> 0.2", [hex: :picosat_elixir, repo: "hexpm", optional: true]}, {:plug, ">= 0.0.0", [hex: :plug, repo: "hexpm", optional: true]}, {:reactor, "~> 0.11", [hex: :reactor, repo: "hexpm", optional: false]}, {:simple_sat, ">= 0.1.1 and < 1.0.0-0", [hex: :simple_sat, repo: "hexpm", optional: true]}, {:spark, ">= 2.3.3 and < 3.0.0-0", [hex: :spark, repo: "hexpm", optional: false]}, {:splode, ">= 0.2.6 and < 1.0.0-0", [hex: :splode, repo: "hexpm", optional: false]}, {:stream_data, "~> 1.0", [hex: :stream_data, repo: "hexpm", optional: false]}, {:telemetry, "~> 1.1", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "23f9b85d545aee27011e371ffc4a19f7af9195e89c2038e50007084cdd1d31b5"}, - "ash_sql": {:hex, :ash_sql, "0.3.6", "6036e57243448b1cc20f8afa0b8f6dcdbd14d4ccc4aa32e7feb5ca2465b3e13a", [:mix], [{:ash, ">= 3.5.43 and < 4.0.0-0", [hex: :ash, repo: "hexpm", optional: false]}, {:ecto, "~> 3.9", [hex: :ecto, repo: "hexpm", optional: false]}, {:ecto_sql, "~> 3.9", [hex: :ecto_sql, repo: "hexpm", optional: false]}], "hexpm", "2cab83c09bc0a3d32c545691f35bb94199b4058dca6e254e8d99532d995fb8f7"}, + "ash": {:hex, :ash, "3.7.0", "711b9eb200f81e0a071e8fe52272fde27e3548a5f3d30589dfcf23eaf34b0d12", [:mix], [{:crux, "~> 0.1.0", [hex: :crux, repo: "hexpm", optional: false]}, {:decimal, "~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:ecto, "~> 3.7", [hex: :ecto, repo: "hexpm", optional: false]}, {:ets, "~> 0.8", [hex: :ets, repo: "hexpm", optional: false]}, {:igniter, ">= 0.6.29 and < 1.0.0-0", [hex: :igniter, repo: "hexpm", optional: true]}, {:jason, ">= 1.0.0", [hex: :jason, repo: "hexpm", optional: false]}, {:picosat_elixir, "~> 0.2", [hex: :picosat_elixir, repo: "hexpm", optional: true]}, {:plug, ">= 0.0.0", [hex: :plug, repo: "hexpm", optional: true]}, {:reactor, "~> 0.11", [hex: :reactor, repo: "hexpm", optional: false]}, {:simple_sat, ">= 0.1.1 and < 1.0.0-0", [hex: :simple_sat, repo: "hexpm", optional: true]}, {:spark, ">= 2.3.3 and < 3.0.0-0", [hex: :spark, repo: "hexpm", optional: false]}, {:splode, ">= 0.2.6 and < 1.0.0-0", [hex: :splode, repo: "hexpm", optional: false]}, {:stream_data, "~> 1.0", [hex: :stream_data, repo: "hexpm", optional: false]}, {:telemetry, "~> 1.1", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "2581e3e2ad21aff8157b25c0f58c884524bee8d06ae8dc94d38ef0b8ae67b2a3"}, + "ash_sql": {:hex, :ash_sql, "0.3.7", "80affa5446075d71deb157c67290685a84b392d723be766bfb684f58fe0143de", [:mix], [{:ash, "~> 3.7", [hex: :ash, repo: "hexpm", optional: false]}, {:ecto, "~> 3.9", [hex: :ecto, repo: "hexpm", optional: false]}, {:ecto_sql, "~> 3.9", [hex: :ecto_sql, repo: "hexpm", optional: false]}], "hexpm", "ce4d974b8e784171c5a2a62593b3672b42dfd4888fa2239f01a6b32bad769038"}, "benchee": {:hex, :benchee, "1.4.0", "9f1f96a30ac80bab94faad644b39a9031d5632e517416a8ab0a6b0ac4df124ce", [:mix], [{:deep_merge, "~> 1.0", [hex: :deep_merge, repo: "hexpm", optional: false]}, {:statistex, "~> 1.0", [hex: :statistex, repo: "hexpm", optional: false]}, {:table, "~> 0.1.0", [hex: :table, repo: "hexpm", optional: true]}], "hexpm", "299cd10dd8ce51c9ea3ddb74bb150f93d25e968f93e4c1fa31698a8e4fa5d715"}, "bunt": {:hex, :bunt, "1.0.0", "081c2c665f086849e6d57900292b3a161727ab40431219529f13c4ddcf3e7a44", [:mix], [], "hexpm", "dc5f86aa08a5f6fa6b8096f0735c4e76d54ae5c9fa2c143e5a1fc7c1cd9bb6b5"}, "credo": {:hex, :credo, "1.7.12", "9e3c20463de4b5f3f23721527fcaf16722ec815e70ff6c60b86412c695d426c1", [:mix], [{:bunt, "~> 0.2.1 or ~> 1.0", [hex: :bunt, repo: "hexpm", optional: false]}, {:file_system, "~> 0.2 or ~> 1.0", [hex: :file_system, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "8493d45c656c5427d9c729235b99d498bd133421f3e0a683e5c1b561471291e5"}, + "crux": {:hex, :crux, "0.1.1", "94f2f97d2a6079ae3c57f356412bc3b307f9579a80e43f526447b1d508dd4a72", [:mix], [{:picosat_elixir, "~> 0.2", [hex: :picosat_elixir, repo: "hexpm", optional: true]}, {:simple_sat, ">= 0.1.1 and < 1.0.0-0", [hex: :simple_sat, repo: "hexpm", optional: true]}, {:stream_data, "~> 1.0", [hex: :stream_data, repo: "hexpm", optional: true]}], "hexpm", "e59d498f038193cbe31e448f9199f5b4c53a4c67cece9922bb839595189dd2b6"}, "db_connection": {:hex, :db_connection, "2.8.1", "9abdc1e68c34c6163f6fb96a96532272d13ad7ca45262156ae8b7ec6d9dc4bec", [:mix], [{:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "a61a3d489b239d76f326e03b98794fb8e45168396c925ef25feb405ed09da8fd"}, "decimal": {:hex, :decimal, "2.3.0", "3ad6255aa77b4a3c4f818171b12d237500e63525c2fd056699967a3e7ea20f62", [:mix], [], "hexpm", "a4d66355cb29cb47c3cf30e71329e58361cfcb37c34235ef3bf1d7bf3773aeac"}, "deep_merge": {:hex, :deep_merge, "1.0.0", "b4aa1a0d1acac393bdf38b2291af38cb1d4a52806cf7a4906f718e1feb5ee961", [:mix], [], "hexpm", "ce708e5f094b9cd4e8f2be4f00d2f4250c4095be93f8cd6d018c753894885430"}, From f48e1a4f0a210c822e564c8834e5a494272b5562 Mon Sep 17 00:00:00 2001 From: Zach Daniel Date: Wed, 15 Oct 2025 18:51:47 -0400 Subject: [PATCH 166/174] chore: update ash_sql --- mix.exs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mix.exs b/mix.exs index 9c70ce1d..9463f940 100644 --- a/mix.exs +++ b/mix.exs @@ -179,7 +179,7 @@ defmodule AshPostgres.MixProject do [ {:ash, ash_version("~> 3.7")}, {:spark, "~> 2.3 and >= 2.3.4"}, - {:ash_sql, ash_sql_version("~> 0.3 and >= 0.3.6")}, + {:ash_sql, ash_sql_version("~> 0.3 and >= 0.3.7")}, {:igniter, "~> 0.6 and >= 0.6.29", optional: true}, {:ecto_sql, "~> 3.13"}, {:ecto, "~> 3.13"}, From d54f93c1937962fe17f3a412c91d144f1b8abfb7 Mon Sep 17 00:00:00 2001 From: Zach Daniel Date: Wed, 15 Oct 2025 18:51:57 -0400 Subject: [PATCH 167/174] chore: release version v2.6.23 --- CHANGELOG.md | 9 +++++++++ mix.exs | 2 +- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 67570853..cd50c84d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,15 @@ See [Conventional Commits](https://www.conventionalcommits.org) for commit guide +## [v2.6.23](https://github.com/ash-project/ash_postgres/compare/v2.6.22...v2.6.23) (2025-10-15) + + + + +### Improvements: + +* implement combination_acc/1 by Zach Daniel + ## [v2.6.22](https://github.com/ash-project/ash_postgres/compare/v2.6.21...v2.6.22) (2025-10-14) diff --git a/mix.exs b/mix.exs index 9463f940..5e14da8d 100644 --- a/mix.exs +++ b/mix.exs @@ -9,7 +9,7 @@ defmodule AshPostgres.MixProject do The PostgreSQL data layer for Ash Framework """ - @version "2.6.22" + @version "2.6.23" def project do [ From f9bd1715b5aa8981caff4887495f376e18dfbf5f Mon Sep 17 00:00:00 2001 From: Barnabas Jovanovics Date: Thu, 16 Oct 2025 21:16:58 +0200 Subject: [PATCH 168/174] fix: handle results that can't be mapped to the changeset in bulk_create (#638) * fix: handle results that can't be mapped to the changeset in bulk_create If the identity used has attibutes that can be generated by the datalayer, we can't map the result back to the changeset and we need to just zip the results with the changesets and return them that way. * refactor: do a simple check for `upsert?` instead --- lib/data_layer.ex | 49 ++++++++++++++++++++++++++++----------- test/bulk_create_test.exs | 14 ++++++++++- 2 files changed, 49 insertions(+), 14 deletions(-) diff --git a/lib/data_layer.ex b/lib/data_layer.ex index 3bad7f45..b984c4db 100644 --- a/lib/data_layer.ex +++ b/lib/data_layer.ex @@ -2124,34 +2124,57 @@ defmodule AshPostgres.DataLayer do end) results = - changesets - |> Enum.map(fn changeset -> - identity = - changeset.attributes - |> Map.take(keys) + if opts[:upsert?] do + changesets + |> Enum.map(fn changeset -> + identity = + changeset.attributes + |> Map.take(keys) - result_for_changeset = Map.get(results_by_identity, identity) + result_for_changeset = Map.get(results_by_identity, identity) - if result_for_changeset do + if result_for_changeset do + if !opts[:upsert?] do + maybe_create_tenant!(resource, result_for_changeset) + end + + case get_bulk_operation_metadata(changeset) do + {index, metadata_key} -> + Ash.Resource.put_metadata(result_for_changeset, metadata_key, index) + + nil -> + # Compatibility fallback + Ash.Resource.put_metadata( + result_for_changeset, + :bulk_create_index, + changeset.context[:bulk_create][:index] + ) + end + end + end) + |> Enum.filter(& &1) + else + results + |> Enum.zip(changesets) + |> Enum.map(fn {result, changeset} -> if !opts[:upsert?] do - maybe_create_tenant!(resource, result_for_changeset) + maybe_create_tenant!(resource, result) end case get_bulk_operation_metadata(changeset) do {index, metadata_key} -> - Ash.Resource.put_metadata(result_for_changeset, metadata_key, index) + Ash.Resource.put_metadata(result, metadata_key, index) nil -> # Compatibility fallback Ash.Resource.put_metadata( - result_for_changeset, + result, :bulk_create_index, changeset.context[:bulk_create][:index] ) end - end - end) - |> Enum.filter(& &1) + end) + end {:ok, results} end diff --git a/test/bulk_create_test.exs b/test/bulk_create_test.exs index 296742fd..c18d8d1a 100644 --- a/test/bulk_create_test.exs +++ b/test/bulk_create_test.exs @@ -4,7 +4,7 @@ defmodule AshPostgres.BulkCreateTest do use AshPostgres.RepoCase, async: false - alias AshPostgres.Test.{Post, Record} + alias AshPostgres.Test.{IntegerPost, Post, Record} require Ash.Query import Ash.Expr @@ -356,6 +356,18 @@ defmodule AshPostgres.BulkCreateTest do |> Ash.Query.load(:ratings) |> Ash.read!() end + + test "bulk creates with integer primary key return records" do + %Ash.BulkResult{records: records} = + Ash.bulk_create!( + [%{title: "first"}, %{title: "second"}, %{title: "third"}], + IntegerPost, + :create, + return_records?: true + ) + + assert length(records) == 3 + end end describe "validation errors" do From 39475a7a278b4eb0731683bee9fca1f7e96ba611 Mon Sep 17 00:00:00 2001 From: Steve Brambilla Date: Fri, 17 Oct 2025 17:55:17 -0400 Subject: [PATCH 169/174] * feat: support building error payloads using immutable functions (#639) Citus compatibility: replace `jsonb_build_object` with immutable functions when `immutable_expr_error?` is true --- lib/extensions/immutable_raise_error.ex | 153 ++++++++---- .../test_repo/extensions.json | 1 + .../20251015134240.json | 226 ++++++++++++++++++ .../20251015134240.json.license | 3 + ...all_immutable_raise_error_v2_extension.exs | 69 ++++++ .../20251015134240_migrate_resources63.exs | 39 +++ test/immutable_raise_error_test.exs | 124 ++++++++++ test/support/domain.ex | 1 + .../resources/immutable_error_tester/error.ex | 31 +++ .../immutable_error_tester.ex | 67 ++++++ .../immutable_error_tester/struct.ex | 14 ++ .../validations/update_literal.ex | 33 +++ .../validations/update_many.ex | 45 ++++ .../validations/update_one.ex | 32 +++ test/support/test_repo.ex | 14 +- 15 files changed, 799 insertions(+), 53 deletions(-) create mode 100644 priv/resource_snapshots/test_repo/immutable_error_testers/20251015134240.json create mode 100644 priv/resource_snapshots/test_repo/immutable_error_testers/20251015134240.json.license create mode 100644 priv/test_repo/migrations/20251015134238_install_immutable_raise_error_v2_extension.exs create mode 100644 priv/test_repo/migrations/20251015134240_migrate_resources63.exs create mode 100644 test/immutable_raise_error_test.exs create mode 100644 test/support/resources/immutable_error_tester/error.ex create mode 100644 test/support/resources/immutable_error_tester/immutable_error_tester.ex create mode 100644 test/support/resources/immutable_error_tester/struct.ex create mode 100644 test/support/resources/immutable_error_tester/validations/update_literal.ex create mode 100644 test/support/resources/immutable_error_tester/validations/update_many.ex create mode 100644 test/support/resources/immutable_error_tester/validations/update_one.ex diff --git a/lib/extensions/immutable_raise_error.ex b/lib/extensions/immutable_raise_error.ex index a1a4032c..3026602c 100644 --- a/lib/extensions/immutable_raise_error.ex +++ b/lib/extensions/immutable_raise_error.ex @@ -30,25 +30,37 @@ defmodule AshPostgres.Extensions.ImmutableRaiseError do ``` """ - use AshPostgres.CustomExtension, name: "immutable_raise_error", latest_version: 1 + use AshPostgres.CustomExtension, name: "immutable_raise_error", latest_version: 2 require Ecto.Query @impl true def install(0) do - ash_raise_error_immutable() + """ + #{ash_raise_error_immutable()} + + #{ash_to_jsonb_immutable()} + """ + end + + def install(1) do + ash_to_jsonb_immutable() end @impl true + def uninstall(2) do + "execute(\"DROP FUNCTION IF EXISTS ash_to_jsonb_immutable(anyelement)\")" + end + def uninstall(_version) do - "execute(\"DROP FUNCTION IF EXISTS ash_raise_error_immutable(jsonb, ANYCOMPATIBLE), ash_raise_error_immutable(jsonb, ANYELEMENT, ANYCOMPATIBLE)\")" + "execute(\"DROP FUNCTION IF EXISTS ash_to_jsonb_immutable(anyelement), ash_raise_error_immutable(jsonb, anycompatible), ash_raise_error_immutable(jsonb, anyelement, anycompatible)\")" end defp ash_raise_error_immutable do """ execute(\"\"\" - CREATE OR REPLACE FUNCTION ash_raise_error_immutable(json_data jsonb, token ANYCOMPATIBLE) - RETURNS BOOLEAN AS $$ + CREATE OR REPLACE FUNCTION ash_raise_error_immutable(json_data jsonb, token anycompatible) + RETURNS boolean AS $$ BEGIN -- Raise an error with the provided JSON data. -- The JSON object is converted to text for inclusion in the error message. @@ -62,8 +74,8 @@ defmodule AshPostgres.Extensions.ImmutableRaiseError do \"\"\") execute(\"\"\" - CREATE OR REPLACE FUNCTION ash_raise_error_immutable(json_data jsonb, type_signal ANYELEMENT, token ANYCOMPATIBLE) - RETURNS ANYELEMENT AS $$ + CREATE OR REPLACE FUNCTION ash_raise_error_immutable(json_data jsonb, type_signal anyelement, token anycompatible) + RETURNS anyelement AS $$ BEGIN -- Raise an error with the provided JSON data. -- The JSON object is converted to text for inclusion in the error message. @@ -78,60 +90,48 @@ defmodule AshPostgres.Extensions.ImmutableRaiseError do """ end + # Wraps to_jsonb and pins session GUCs that affect JSON. This makes the function’s result + # deterministic, so it is safe to mark IMMUTABLE. + defp ash_to_jsonb_immutable do + """ + execute(\"\"\" + CREATE OR REPLACE FUNCTION ash_to_jsonb_immutable(value anyelement) + RETURNS jsonb + LANGUAGE plpgsql + IMMUTABLE + SET search_path TO 'pg_catalog' + SET \"TimeZone\" TO 'UTC' + SET \"DateStyle\" TO 'ISO, YMD' + SET \"IntervalStyle\" TO 'iso_8601' + SET extra_float_digits TO '0' + SET bytea_output TO 'hex' + AS $function$ + BEGIN + RETURN COALESCE(to_jsonb(value), 'null'::jsonb); + END; + $function$ + \"\"\") + """ + end + @doc false def immutable_error_expr( query, %Ash.Query.Function.Error{arguments: [exception, input]} = value, bindings, - embedded?, + _embedded?, acc, type ) do + if !(Keyword.keyword?(input) or is_map(input)) do + raise "Input expression to `error` must be a map or keyword list" + end + acc = %{acc | has_error?: true} - {encoded, acc} = + {error_payload, acc} = if Ash.Expr.expr?(input) do - frag_parts = - Enum.flat_map(input, fn {key, value} -> - if Ash.Expr.expr?(value) do - [ - expr: to_string(key), - raw: "::text, ", - expr: value, - raw: ", " - ] - else - [ - expr: to_string(key), - raw: "::text, ", - expr: value, - raw: "::jsonb, " - ] - end - end) - - frag_parts = - List.update_at(frag_parts, -1, fn {:raw, text} -> - {:raw, String.trim_trailing(text, ", ") <> "))"} - end) - - AshSql.Expr.dynamic_expr( - query, - %Ash.Query.Function.Fragment{ - embedded?: false, - arguments: - [ - raw: "jsonb_build_object('exception', ", - expr: inspect(exception), - raw: "::text, 'input', jsonb_build_object(" - ] ++ - frag_parts - }, - bindings, - embedded?, - nil, - acc - ) + expression_error_payload(exception, input, query, bindings, acc) else {Jason.encode!(%{exception: inspect(exception), input: Map.new(input)}), acc} end @@ -163,7 +163,7 @@ defmodule AshPostgres.Extensions.ImmutableRaiseError do {nil, row_token} -> {:ok, Ecto.Query.dynamic( - fragment("ash_raise_error_immutable(?::jsonb, ?)", ^encoded, ^row_token) + fragment("ash_raise_error_immutable(?::jsonb, ?)", ^error_payload, ^row_token) ), acc} {dynamic_type, row_token} -> @@ -171,7 +171,7 @@ defmodule AshPostgres.Extensions.ImmutableRaiseError do Ecto.Query.dynamic( fragment( "ash_raise_error_immutable(?::jsonb, ?, ?)", - ^encoded, + ^error_payload, ^dynamic_type, ^row_token ) @@ -179,6 +179,55 @@ defmodule AshPostgres.Extensions.ImmutableRaiseError do end end + # Encodes an error payload as jsonb using only IMMUTABLE SQL functions. + # + # Strategy: + # * Split the 'input' into Ash expressions and literal values + # * Build the base json map with the exception name and literal input values + # * For each expression value, use nested calls to `jsonb_set` (IMMUTABLE) to add the value to + # 'input', converting each expression to jsonb using `ash_to_jsonb_immutable` (which pins + # session GUCs for deterministic encoding) + defp expression_error_payload(exception, input, query, bindings, acc) do + {expr_inputs, literal_inputs} = + Enum.split_with(input, fn {_key, value} -> Ash.Expr.expr?(value) end) + + base_json = %{exception: inspect(exception), input: Map.new(literal_inputs)} + + Enum.reduce(expr_inputs, {base_json, acc}, fn + {key, expr_value}, {current_payload, acc} -> + path_expr = %Ash.Query.Function.Type{ + arguments: [["input", to_string(key)], {:array, :string}, []] + } + + new_value_jsonb = + %Ash.Query.Function.Fragment{ + arguments: [raw: "ash_to_jsonb_immutable(", expr: expr_value, raw: ")"] + } + + {%Ecto.Query.DynamicExpr{} = new_payload, acc} = + AshSql.Expr.dynamic_expr( + query, + %Ash.Query.Function.Fragment{ + arguments: [ + raw: "jsonb_set(", + expr: current_payload, + raw: "::jsonb, ", + expr: path_expr, + raw: ", ", + expr: new_value_jsonb, + raw: "::jsonb, true)" + ] + }, + bindings, + false, + nil, + acc + ) + + {new_payload, acc} + end) + end + # Returns a row-dependent token to prevent constant-folding for immutable functions. defp immutable_error_expr_token(query, bindings) do resource = query.__ash_bindings__.resource diff --git a/priv/resource_snapshots/test_repo/extensions.json b/priv/resource_snapshots/test_repo/extensions.json index d1c5a122..35a36695 100644 --- a/priv/resource_snapshots/test_repo/extensions.json +++ b/priv/resource_snapshots/test_repo/extensions.json @@ -6,6 +6,7 @@ "pg_trgm", "citext", "demo-functions_v1", + "immutable_raise_error_v2", "ltree" ] } \ No newline at end of file diff --git a/priv/resource_snapshots/test_repo/immutable_error_testers/20251015134240.json b/priv/resource_snapshots/test_repo/immutable_error_testers/20251015134240.json new file mode 100644 index 00000000..5917eec5 --- /dev/null +++ b/priv/resource_snapshots/test_repo/immutable_error_testers/20251015134240.json @@ -0,0 +1,226 @@ +{ + "attributes": [ + { + "allow_nil?": false, + "default": "fragment(\"gen_random_uuid()\")", + "generated?": false, + "precision": null, + "primary_key?": true, + "references": null, + "scale": null, + "size": null, + "source": "id", + "type": "uuid" + }, + { + "allow_nil?": false, + "default": "nil", + "generated?": false, + "precision": null, + "primary_key?": false, + "references": null, + "scale": null, + "size": null, + "source": "atom_value", + "type": "text" + }, + { + "allow_nil?": false, + "default": "nil", + "generated?": false, + "precision": null, + "primary_key?": false, + "references": null, + "scale": null, + "size": null, + "source": "string_value", + "type": "text" + }, + { + "allow_nil?": false, + "default": "nil", + "generated?": false, + "precision": null, + "primary_key?": false, + "references": null, + "scale": null, + "size": null, + "source": "integer_value", + "type": "bigint" + }, + { + "allow_nil?": false, + "default": "nil", + "generated?": false, + "precision": null, + "primary_key?": false, + "references": null, + "scale": null, + "size": null, + "source": "float_value", + "type": "float" + }, + { + "allow_nil?": false, + "default": "nil", + "generated?": false, + "precision": null, + "primary_key?": false, + "references": null, + "scale": null, + "size": null, + "source": "boolean_value", + "type": "boolean" + }, + { + "allow_nil?": false, + "default": "nil", + "generated?": false, + "precision": null, + "primary_key?": false, + "references": null, + "scale": null, + "size": null, + "source": "struct_value", + "type": "map" + }, + { + "allow_nil?": false, + "default": "nil", + "generated?": false, + "precision": null, + "primary_key?": false, + "references": null, + "scale": null, + "size": null, + "source": "uuid_value", + "type": "uuid" + }, + { + "allow_nil?": false, + "default": "nil", + "generated?": false, + "precision": null, + "primary_key?": false, + "references": null, + "scale": null, + "size": null, + "source": "date_value", + "type": "date" + }, + { + "allow_nil?": false, + "default": "nil", + "generated?": false, + "precision": null, + "primary_key?": false, + "references": null, + "scale": null, + "size": null, + "source": "time_value", + "type": "time" + }, + { + "allow_nil?": false, + "default": "nil", + "generated?": false, + "precision": null, + "primary_key?": false, + "references": null, + "scale": null, + "size": null, + "source": "ci_string_value", + "type": "citext" + }, + { + "allow_nil?": false, + "default": "nil", + "generated?": false, + "precision": null, + "primary_key?": false, + "references": null, + "scale": null, + "size": null, + "source": "naive_datetime_value", + "type": "naive_datetime" + }, + { + "allow_nil?": false, + "default": "nil", + "generated?": false, + "precision": null, + "primary_key?": false, + "references": null, + "scale": null, + "size": null, + "source": "utc_datetime_value", + "type": "utc_datetime" + }, + { + "allow_nil?": false, + "default": "nil", + "generated?": false, + "precision": null, + "primary_key?": false, + "references": null, + "scale": null, + "size": null, + "source": "timestamptz_value", + "type": "timestamptz" + }, + { + "allow_nil?": false, + "default": "nil", + "generated?": false, + "precision": null, + "primary_key?": false, + "references": null, + "scale": null, + "size": null, + "source": "string_array_value", + "type": [ + "array", + "text" + ] + }, + { + "allow_nil?": false, + "default": "nil", + "generated?": false, + "precision": null, + "primary_key?": false, + "references": null, + "scale": null, + "size": null, + "source": "response_value", + "type": "integer" + }, + { + "allow_nil?": true, + "default": "nil", + "generated?": false, + "precision": null, + "primary_key?": false, + "references": null, + "scale": null, + "size": null, + "source": "nullable_string_value", + "type": "text" + } + ], + "base_filter": null, + "check_constraints": [], + "custom_indexes": [], + "custom_statements": [], + "has_create_action": true, + "hash": "BB177B855B058F50CA20AFCF6F624072C1395BFDF3FB0B2F60BDC14A15A053F1", + "identities": [], + "multitenancy": { + "attribute": null, + "global": null, + "strategy": null + }, + "repo": "Elixir.AshPostgres.TestRepo", + "schema": null, + "table": "immutable_error_testers" +} \ No newline at end of file diff --git a/priv/resource_snapshots/test_repo/immutable_error_testers/20251015134240.json.license b/priv/resource_snapshots/test_repo/immutable_error_testers/20251015134240.json.license new file mode 100644 index 00000000..b0a44fab --- /dev/null +++ b/priv/resource_snapshots/test_repo/immutable_error_testers/20251015134240.json.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2019 ash_postgres contributors + +SPDX-License-Identifier: MIT diff --git a/priv/test_repo/migrations/20251015134238_install_immutable_raise_error_v2_extension.exs b/priv/test_repo/migrations/20251015134238_install_immutable_raise_error_v2_extension.exs new file mode 100644 index 00000000..eb4a8d77 --- /dev/null +++ b/priv/test_repo/migrations/20251015134238_install_immutable_raise_error_v2_extension.exs @@ -0,0 +1,69 @@ +# SPDX-FileCopyrightText: 2019 ash_postgres contributors +# +# SPDX-License-Identifier: MIT + +defmodule AshPostgres.TestRepo.Migrations.InstallImmutableRaiseErrorV220251015134237 do + @moduledoc """ + Installs any extensions that are mentioned in the repo's `installed_extensions/0` callback + + This file was autogenerated with `mix ash_postgres.generate_migrations` + """ + + use Ecto.Migration + + def up do + execute(""" + CREATE OR REPLACE FUNCTION ash_raise_error_immutable(json_data jsonb, token anycompatible) + RETURNS boolean AS $$ + BEGIN + -- Raise an error with the provided JSON data. + -- The JSON object is converted to text for inclusion in the error message. + -- 'token' is intentionally ignored; its presence makes the call non-constant at the call site. + RAISE EXCEPTION 'ash_error: %', json_data::text; + RETURN NULL; + END; + $$ LANGUAGE plpgsql + IMMUTABLE + SET search_path = ''; + """) + + execute(""" + CREATE OR REPLACE FUNCTION ash_raise_error_immutable(json_data jsonb, type_signal anyelement, token anycompatible) + RETURNS anyelement AS $$ + BEGIN + -- Raise an error with the provided JSON data. + -- The JSON object is converted to text for inclusion in the error message. + -- 'token' is intentionally ignored; its presence makes the call non-constant at the call site. + RAISE EXCEPTION 'ash_error: %', json_data::text; + RETURN NULL; + END; + $$ LANGUAGE plpgsql + IMMUTABLE + SET search_path = ''; + """) + + execute(""" + CREATE OR REPLACE FUNCTION ash_to_jsonb_immutable(value anyelement) + RETURNS jsonb + LANGUAGE plpgsql + IMMUTABLE + SET search_path TO 'pg_catalog' + SET "TimeZone" TO 'UTC' + SET "DateStyle" TO 'ISO, YMD' + SET "IntervalStyle" TO 'iso_8601' + SET extra_float_digits TO '0' + SET bytea_output TO 'hex' + AS $function$ + BEGIN + RETURN COALESCE(to_jsonb(value), 'null'::jsonb); + END; + $function$ + """) + end + + def down do + # Uncomment this if you actually want to uninstall the extensions + # when this migration is rolled back: + execute("DROP FUNCTION IF EXISTS ash_to_jsonb_immutable(anyelement)") + end +end diff --git a/priv/test_repo/migrations/20251015134240_migrate_resources63.exs b/priv/test_repo/migrations/20251015134240_migrate_resources63.exs new file mode 100644 index 00000000..0454f8a4 --- /dev/null +++ b/priv/test_repo/migrations/20251015134240_migrate_resources63.exs @@ -0,0 +1,39 @@ +# SPDX-FileCopyrightText: 2019 ash_postgres contributors +# +# SPDX-License-Identifier: MIT + +defmodule AshPostgres.TestRepo.Migrations.MigrateResources63 do + @moduledoc """ + Updates resources based on their most recent snapshots. + + This file was autogenerated with `mix ash_postgres.generate_migrations` + """ + + use Ecto.Migration + + def up do + create table(:immutable_error_testers, primary_key: false) do + add(:id, :uuid, null: false, default: fragment("gen_random_uuid()"), primary_key: true) + add(:atom_value, :text, null: false) + add(:string_value, :text, null: false) + add(:integer_value, :bigint, null: false) + add(:float_value, :float, null: false) + add(:boolean_value, :boolean, null: false) + add(:struct_value, :map, null: false) + add(:uuid_value, :uuid, null: false) + add(:date_value, :date, null: false) + add(:time_value, :time, null: false) + add(:ci_string_value, :citext, null: false) + add(:naive_datetime_value, :naive_datetime, null: false) + add(:utc_datetime_value, :utc_datetime, null: false) + add(:timestamptz_value, :timestamptz, null: false) + add(:string_array_value, {:array, :text}, null: false) + add(:response_value, :integer, null: false) + add(:nullable_string_value, :text) + end + end + + def down do + drop(table(:immutable_error_testers)) + end +end diff --git a/test/immutable_raise_error_test.exs b/test/immutable_raise_error_test.exs new file mode 100644 index 00000000..076efeaf --- /dev/null +++ b/test/immutable_raise_error_test.exs @@ -0,0 +1,124 @@ +# SPDX-FileCopyrightText: 2019 ash_postgres contributors +# +# SPDX-License-Identifier: MIT + +defmodule AshPostgres.ImmutableRaiseErrorTest do + use AshPostgres.RepoCase, async: false + + alias AshPostgres.Test.ImmutableErrorTester + + require Ash.Query + + setup do + original = Application.get_env(:ash_postgres, :test_repo_use_immutable_errors?) + Application.put_env(:ash_postgres, :test_repo_use_immutable_errors?, true) + + on_exit(fn -> + if is_nil(original) do + Application.delete_env(:ash_postgres, :test_repo_use_immutable_errors?) + else + Application.put_env(:ash_postgres, :test_repo_use_immutable_errors?, original) + end + end) + + :ok + end + + describe "atomic error payloads" do + test "update_one returns InvalidAttribute error with expression value" do + tester = create_tester() + + # The :update_one validation builds an error with a single expression value and literal + # values (non-empty base input). + assert {:error, %Ash.Error.Invalid{errors: [error]}} = + tester + |> Ash.Changeset.for_update(:update_one, %{integer_value: 99}) + |> Ash.update() + + assert %Ash.Error.Changes.InvalidAttribute{} = error + assert error.field == :integer_value + assert error.value == 99 + end + + test "update_many returns custom error containing all expression values" do + tester = create_tester() + + # The :update_many validation builds an error that include many (all attributes) value + # expressions, and zero literal values (empty base input). + assert {:error, %Ash.Error.Invalid{errors: [error]}} = + tester + |> Ash.Changeset.for_update(:update_many, %{}) + |> Ash.update() + + assert %ImmutableErrorTester.Error{} = error + + assert error.atom_value == "initial_atom" + assert error.string_value == "initial string" + assert error.integer_value == 10 + assert error.float_value == 1.5 + assert error.boolean_value == true + + assert error.struct_value == %{ + "active?" => true, + "count" => 1, + "name" => "initial" + } + + assert error.uuid_value == "00000000-0000-0000-0000-000000000000" + assert error.date_value == "2024-01-01" + assert error.time_value == "12:00:00" + assert error.ci_string_value == "Initial String" + assert error.naive_datetime_value == "2024-01-01T12:00:00" + assert error.utc_datetime_value == "2024-01-01T00:01:00" + assert error.timestamptz_value == "2024-01-01T00:02:00+00:00" + assert error.string_array_value == ["one", "two"] + + # Native value for :awaiting is 0 + assert error.response_value == 0 + assert error.nullable_string_value == nil + end + + test "update_literal returns literal payload" do + tester = create_tester() + + # The :update_literal validation builds an error with only literal values, zero expression values. + assert {:error, %Ash.Error.Invalid{errors: [error]}} = + tester + |> Ash.Changeset.for_update(:update_literal, %{}) + |> Ash.update() + + assert error.string_value == "literal string" + assert error.integer_value == 123 + assert error.float_value == 9.99 + assert error.boolean_value == false + assert error.string_array_value == ["alpha", "beta"] + assert error.nullable_string_value == nil + end + end + + defp create_tester do + input = + %{ + atom_value: :initial_atom, + string_value: "initial string", + integer_value: 10, + float_value: 1.5, + boolean_value: true, + struct_value: ImmutableErrorTester.Struct.new!(name: "initial", count: 1, active?: true), + uuid_value: "00000000-0000-0000-0000-000000000000", + date_value: ~D[2024-01-01], + time_value: ~T[12:00:00], + ci_string_value: "Initial String", + naive_datetime_value: ~N[2024-01-01 12:00:00], + utc_datetime_value: ~U[2024-01-01 00:01:00.00Z], + timestamptz_value: ~U[2024-01-01 00:02:00.00Z], + string_array_value: ["one", "two"], + response_value: :awaiting, + nullable_string_value: nil + } + + ImmutableErrorTester + |> Ash.Changeset.for_create(:create, input) + |> Ash.create!() + end +end diff --git a/test/support/domain.ex b/test/support/domain.ex index 2fb81323..8e9a19d3 100644 --- a/test/support/domain.ex +++ b/test/support/domain.ex @@ -58,6 +58,7 @@ defmodule AshPostgres.Test.Domain do resource(AshPostgres.Test.Chat) resource(AshPostgres.Test.Message) resource(AshPostgres.Test.RSVP) + resource(AshPostgres.Test.ImmutableErrorTester) end authorization do diff --git a/test/support/resources/immutable_error_tester/error.ex b/test/support/resources/immutable_error_tester/error.ex new file mode 100644 index 00000000..15dca8ee --- /dev/null +++ b/test/support/resources/immutable_error_tester/error.ex @@ -0,0 +1,31 @@ +# SPDX-FileCopyrightText: 2019 ash_postgres contributors +# +# SPDX-License-Identifier: MIT + +defmodule AshPostgres.Test.ImmutableErrorTester.Error do + @moduledoc false + use Splode.Error, + class: :invalid, + fields: [ + :atom_value, + :string_value, + :integer_value, + :float_value, + :boolean_value, + :struct_value, + :uuid_value, + :date_value, + :time_value, + :ci_string_value, + :naive_datetime_value, + :utc_datetime_value, + :timestamptz_value, + :string_array_value, + :response_value, + :nullable_string_value + ] + + def message(_error) do + "Immutable Error" + end +end diff --git a/test/support/resources/immutable_error_tester/immutable_error_tester.ex b/test/support/resources/immutable_error_tester/immutable_error_tester.ex new file mode 100644 index 00000000..50ec1613 --- /dev/null +++ b/test/support/resources/immutable_error_tester/immutable_error_tester.ex @@ -0,0 +1,67 @@ +# SPDX-FileCopyrightText: 2019 ash_postgres contributors +# +# SPDX-License-Identifier: MIT + +defmodule AshPostgres.Test.ImmutableErrorTester do + @moduledoc false + use Ash.Resource, + domain: AshPostgres.Test.Domain, + data_layer: AshPostgres.DataLayer + + require Ash.Expr + import Ash.Expr + + postgres do + table "immutable_error_testers" + repo(AshPostgres.TestRepo) + end + + attributes do + uuid_primary_key(:id) + + attribute(:atom_value, :atom, allow_nil?: false, public?: true) + attribute(:string_value, :string, allow_nil?: false, public?: true) + attribute(:integer_value, :integer, allow_nil?: false, public?: true) + attribute(:float_value, :float, allow_nil?: false, public?: true) + attribute(:boolean_value, :boolean, allow_nil?: false, public?: true) + + attribute(:struct_value, AshPostgres.Test.ImmutableErrorTester.Struct, + allow_nil?: false, + public?: true + ) + + attribute(:uuid_value, Ash.Type.UUID, allow_nil?: false, public?: true) + attribute(:date_value, :date, allow_nil?: false, public?: true) + attribute(:time_value, :time, allow_nil?: false, public?: true) + attribute(:ci_string_value, :ci_string, allow_nil?: false, public?: true) + attribute(:naive_datetime_value, :naive_datetime, allow_nil?: false, public?: true) + attribute(:utc_datetime_value, :utc_datetime, allow_nil?: false, public?: true) + attribute(:timestamptz_value, AshPostgres.Timestamptz, allow_nil?: false, public?: true) + attribute(:string_array_value, {:array, :string}, allow_nil?: false, public?: true) + attribute(:response_value, AshPostgres.Test.Types.Response, allow_nil?: false, public?: true) + attribute(:nullable_string_value, :string, public?: true) + end + + actions do + defaults([:read]) + + create :create do + accept(:*) + end + + update :update_one do + argument(:integer_value, :integer, allow_nil?: false) + change(atomic_update(:integer_value, expr(^arg(:integer_value)))) + validate(AshPostgres.Test.ImmutableErrorTester.Validations.UpdateOne) + end + + update :update_many do + accept(:*) + validate(AshPostgres.Test.ImmutableErrorTester.Validations.UpdateMany) + end + + update :update_literal do + validate(AshPostgres.Test.ImmutableErrorTester.Validations.UpdateLiteral) + end + end +end diff --git a/test/support/resources/immutable_error_tester/struct.ex b/test/support/resources/immutable_error_tester/struct.ex new file mode 100644 index 00000000..2b24494f --- /dev/null +++ b/test/support/resources/immutable_error_tester/struct.ex @@ -0,0 +1,14 @@ +# SPDX-FileCopyrightText: 2019 ash_postgres contributors +# +# SPDX-License-Identifier: MIT + +defmodule AshPostgres.Test.ImmutableErrorTester.Struct do + @moduledoc false + use Ash.TypedStruct + + typed_struct do + field(:name, :string, allow_nil?: false) + field(:count, :integer, allow_nil?: false) + field(:active?, :boolean, allow_nil?: false) + end +end diff --git a/test/support/resources/immutable_error_tester/validations/update_literal.ex b/test/support/resources/immutable_error_tester/validations/update_literal.ex new file mode 100644 index 00000000..453ec37e --- /dev/null +++ b/test/support/resources/immutable_error_tester/validations/update_literal.ex @@ -0,0 +1,33 @@ +# SPDX-FileCopyrightText: 2019 ash_postgres contributors +# +# SPDX-License-Identifier: MIT + +defmodule AshPostgres.Test.ImmutableErrorTester.Validations.UpdateLiteral do + @moduledoc false + use Ash.Resource.Validation + + import Ash.Expr + + @impl true + def init(opts), do: {:ok, opts} + + # Validation that always fails. Builds an error with only literal values, zero expression values. + # + # Use fragment with PG function to ensure the validation runs as part of the query. + @impl true + def atomic(_changeset, _opts, _context) do + [ + {:atomic, :*, expr(fragment("pg_column_size(?) != 0", ^ref(:id))), + expr( + error(AshPostgres.Test.ImmutableErrorTester.Error, + string_value: "literal string", + integer_value: 123, + float_value: 9.99, + boolean_value: false, + string_array_value: ["alpha", "beta"], + nullable_string_value: nil + ) + )} + ] + end +end diff --git a/test/support/resources/immutable_error_tester/validations/update_many.ex b/test/support/resources/immutable_error_tester/validations/update_many.ex new file mode 100644 index 00000000..e41959dc --- /dev/null +++ b/test/support/resources/immutable_error_tester/validations/update_many.ex @@ -0,0 +1,45 @@ +# SPDX-FileCopyrightText: 2019 ash_postgres contributors +# +# SPDX-License-Identifier: MIT + +defmodule AshPostgres.Test.ImmutableErrorTester.Validations.UpdateMany do + @moduledoc false + use Ash.Resource.Validation + + import Ash.Expr + + @impl true + def init(opts), do: {:ok, opts} + + # Validation that always fails. Builds an error that include many (all attributes) value + # expressions, and zero literal values (empty base input). + # + # Use fragment with PG function to ensure the validation runs as part of the query. + @impl true + def atomic(_changeset, _opts, _context) do + [ + {:atomic, :*, expr(fragment("pg_column_size(?) != 0", ^ref(:id))), + expr( + error( + AshPostgres.Test.ImmutableErrorTester.Error, + atom_value: ^atomic_ref(:atom_value), + string_value: ^atomic_ref(:string_value), + integer_value: ^atomic_ref(:integer_value), + float_value: ^atomic_ref(:float_value), + boolean_value: ^atomic_ref(:boolean_value), + struct_value: ^atomic_ref(:struct_value), + uuid_value: ^atomic_ref(:uuid_value), + date_value: ^atomic_ref(:date_value), + time_value: ^atomic_ref(:time_value), + ci_string_value: ^atomic_ref(:ci_string_value), + naive_datetime_value: ^atomic_ref(:naive_datetime_value), + utc_datetime_value: ^atomic_ref(:utc_datetime_value), + timestamptz_value: ^atomic_ref(:timestamptz_value), + string_array_value: ^atomic_ref(:string_array_value), + response_value: ^atomic_ref(:response_value), + nullable_string_value: ^atomic_ref(:nullable_string_value) + ) + )} + ] + end +end diff --git a/test/support/resources/immutable_error_tester/validations/update_one.ex b/test/support/resources/immutable_error_tester/validations/update_one.ex new file mode 100644 index 00000000..a7351e56 --- /dev/null +++ b/test/support/resources/immutable_error_tester/validations/update_one.ex @@ -0,0 +1,32 @@ +# SPDX-FileCopyrightText: 2019 ash_postgres contributors +# +# SPDX-License-Identifier: MIT + +defmodule AshPostgres.Test.ImmutableErrorTester.Validations.UpdateOne do + @moduledoc false + use Ash.Resource.Validation + + import Ash.Expr + + @impl true + def init(opts), do: {:ok, opts} + + # Validation that always fails. Builds an error with a single expression value and literal + # values (non-empty base input). + # + # Use fragment with PG function to ensure the validation runs as part of the query. + @impl true + def atomic(_changeset, _opts, _context) do + [ + {:atomic, [:integer_value, :id], expr(fragment("pg_column_size(?) != 0", ^ref(:id))), + expr( + error( + Ash.Error.Changes.InvalidAttribute, + field: :integer_value, + value: ^atomic_ref(:integer_value), + message: "integer_value failed validation" + ) + )} + ] + end +end diff --git a/test/support/test_repo.ex b/test/support/test_repo.ex index cf45c646..b21721e8 100644 --- a/test/support/test_repo.ex +++ b/test/support/test_repo.ex @@ -16,7 +16,15 @@ defmodule AshPostgres.TestRepo do def prefer_transaction_for_atomic_updates?, do: false def installed_extensions do - ["ash-functions", "uuid-ossp", "pg_trgm", "citext", AshPostgres.TestCustomExtension, "ltree"] -- + [ + "ash-functions", + "uuid-ossp", + "pg_trgm", + "citext", + AshPostgres.TestCustomExtension, + AshPostgres.Extensions.ImmutableRaiseError, + "ltree" + ] -- Application.get_env(:ash_postgres, :no_extensions, []) end @@ -40,4 +48,8 @@ defmodule AshPostgres.TestRepo do |> Ash.read!() |> Enum.map(&"org_#{&1.id}") end + + def immutable_expr_error? do + Application.get_env(:ash_postgres, :test_repo_use_immutable_errors?, false) + end end From b2216c4b509137ca9c364ac5368e91f542827e7a Mon Sep 17 00:00:00 2001 From: Zach Daniel Date: Sat, 18 Oct 2025 01:28:08 -0400 Subject: [PATCH 170/174] test: add tests for ash_sql fix for exists paths in calculations chore: update ash --- mix.lock | 2 +- test/calculation_test.exs | 21 +++++++++++++++++++++ test/support/resources/author.ex | 6 ++++++ test/support/resources/post.ex | 6 ++++++ 4 files changed, 34 insertions(+), 1 deletion(-) diff --git a/mix.lock b/mix.lock index 7b15d0ea..c988302d 100644 --- a/mix.lock +++ b/mix.lock @@ -1,5 +1,5 @@ %{ - "ash": {:hex, :ash, "3.7.0", "711b9eb200f81e0a071e8fe52272fde27e3548a5f3d30589dfcf23eaf34b0d12", [:mix], [{:crux, "~> 0.1.0", [hex: :crux, repo: "hexpm", optional: false]}, {:decimal, "~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:ecto, "~> 3.7", [hex: :ecto, repo: "hexpm", optional: false]}, {:ets, "~> 0.8", [hex: :ets, repo: "hexpm", optional: false]}, {:igniter, ">= 0.6.29 and < 1.0.0-0", [hex: :igniter, repo: "hexpm", optional: true]}, {:jason, ">= 1.0.0", [hex: :jason, repo: "hexpm", optional: false]}, {:picosat_elixir, "~> 0.2", [hex: :picosat_elixir, repo: "hexpm", optional: true]}, {:plug, ">= 0.0.0", [hex: :plug, repo: "hexpm", optional: true]}, {:reactor, "~> 0.11", [hex: :reactor, repo: "hexpm", optional: false]}, {:simple_sat, ">= 0.1.1 and < 1.0.0-0", [hex: :simple_sat, repo: "hexpm", optional: true]}, {:spark, ">= 2.3.3 and < 3.0.0-0", [hex: :spark, repo: "hexpm", optional: false]}, {:splode, ">= 0.2.6 and < 1.0.0-0", [hex: :splode, repo: "hexpm", optional: false]}, {:stream_data, "~> 1.0", [hex: :stream_data, repo: "hexpm", optional: false]}, {:telemetry, "~> 1.1", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "2581e3e2ad21aff8157b25c0f58c884524bee8d06ae8dc94d38ef0b8ae67b2a3"}, + "ash": {:hex, :ash, "3.7.1", "abb55dee19e0959e529e52fe0622468825ae05400f535484919713e492d9a9e7", [:mix], [{:crux, "~> 0.1.0", [hex: :crux, repo: "hexpm", optional: false]}, {:decimal, "~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:ecto, "~> 3.7", [hex: :ecto, repo: "hexpm", optional: false]}, {:ets, "~> 0.8", [hex: :ets, repo: "hexpm", optional: false]}, {:igniter, ">= 0.6.29 and < 1.0.0-0", [hex: :igniter, repo: "hexpm", optional: true]}, {:jason, ">= 1.0.0", [hex: :jason, repo: "hexpm", optional: false]}, {:picosat_elixir, "~> 0.2", [hex: :picosat_elixir, repo: "hexpm", optional: true]}, {:plug, ">= 0.0.0", [hex: :plug, repo: "hexpm", optional: true]}, {:reactor, "~> 0.11", [hex: :reactor, repo: "hexpm", optional: false]}, {:simple_sat, ">= 0.1.1 and < 1.0.0-0", [hex: :simple_sat, repo: "hexpm", optional: true]}, {:spark, ">= 2.3.3 and < 3.0.0-0", [hex: :spark, repo: "hexpm", optional: false]}, {:splode, ">= 0.2.6 and < 1.0.0-0", [hex: :splode, repo: "hexpm", optional: false]}, {:stream_data, "~> 1.0", [hex: :stream_data, repo: "hexpm", optional: false]}, {:telemetry, "~> 1.1", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "4474ce9befe9862d1ed73cadf8a755e836c45a14a7b3b952d02e1a12f2b2e529"}, "ash_sql": {:hex, :ash_sql, "0.3.7", "80affa5446075d71deb157c67290685a84b392d723be766bfb684f58fe0143de", [:mix], [{:ash, "~> 3.7", [hex: :ash, repo: "hexpm", optional: false]}, {:ecto, "~> 3.9", [hex: :ecto, repo: "hexpm", optional: false]}, {:ecto_sql, "~> 3.9", [hex: :ecto_sql, repo: "hexpm", optional: false]}], "hexpm", "ce4d974b8e784171c5a2a62593b3672b42dfd4888fa2239f01a6b32bad769038"}, "benchee": {:hex, :benchee, "1.4.0", "9f1f96a30ac80bab94faad644b39a9031d5632e517416a8ab0a6b0ac4df124ce", [:mix], [{:deep_merge, "~> 1.0", [hex: :deep_merge, repo: "hexpm", optional: false]}, {:statistex, "~> 1.0", [hex: :statistex, repo: "hexpm", optional: false]}, {:table, "~> 0.1.0", [hex: :table, repo: "hexpm", optional: true]}], "hexpm", "299cd10dd8ce51c9ea3ddb74bb150f93d25e968f93e4c1fa31698a8e4fa5d715"}, "bunt": {:hex, :bunt, "1.0.0", "081c2c665f086849e6d57900292b3a161727ab40431219529f13c4ddcf3e7a44", [:mix], [], "hexpm", "dc5f86aa08a5f6fa6b8096f0735c4e76d54ae5c9fa2c143e5a1fc7c1cd9bb6b5"}, diff --git a/test/calculation_test.exs b/test/calculation_test.exs index cdad5c18..5e3a2a68 100644 --- a/test/calculation_test.exs +++ b/test/calculation_test.exs @@ -1121,4 +1121,25 @@ defmodule AshPostgres.CalculationTest do first_comment_by_author.created_at ) end + + test "nested calculation with parent() in exists works" do + author = + Author + |> Ash.Changeset.for_create(:create, %{first_name: "John", last_name: "Doe"}) + |> Ash.create!() + + _post = + Post + |> Ash.Changeset.for_create(:create, %{title: "test", author_id: author.id}) + |> Ash.create!() + + result = + Post + |> Ash.Query.load(:author_has_post_with_title_matching_their_first_name) + |> Ash.read!() + |> List.first() + + # Should be false since post title doesn't match author first name + refute result.author_has_post_with_title_matching_their_first_name + end end diff --git a/test/support/resources/author.ex b/test/support/resources/author.ex index 16ca5a8e..3530513c 100644 --- a/test/support/resources/author.ex +++ b/test/support/resources/author.ex @@ -181,6 +181,12 @@ defmodule AshPostgres.Test.Author do calculate(:has_posts, :boolean, expr(exists(posts, true == true))) calculate(:has_no_posts, :boolean, expr(has_posts == false)) + calculate( + :has_post_with_title_matching_first_name, + :boolean, + expr(exists(posts, title == parent(first_name))) + ) + calculate(:profile_description_calc, :string, expr(profile.description), allow_nil?: true) end diff --git a/test/support/resources/post.ex b/test/support/resources/post.ex index c15b6b0e..a4f04f7d 100644 --- a/test/support/resources/post.ex +++ b/test/support/resources/post.ex @@ -924,6 +924,12 @@ defmodule AshPostgres.Test.Post do ) ) + calculate( + :author_has_post_with_title_matching_their_first_name, + :boolean, + expr(author.has_post_with_title_matching_first_name) + ) + calculate(:has_author, :boolean, expr(exists(author, true == true))) calculate(:has_comments, :boolean, expr(exists(comments, true == true))) From 449ae3ff8715c3bb5598ff19d844e1ac728e25b7 Mon Sep 17 00:00:00 2001 From: Torkild Gundersen Kjevik Date: Sun, 19 Oct 2025 05:17:31 +0200 Subject: [PATCH 171/174] test: typed struct arrays with storage_type :jsonb & {:array, map} (#640) --- .../test_repo/authors/20251018130654_dev.json | 133 ++++++++++++++++++ .../authors/20251018130654_dev.json.license | 3 + ...20251018130654_migrate_resources64_dev.exs | 27 ++++ test/storage_types_test.exs | 82 +++++++++++ test/support/resources/author.ex | 6 +- test/support/resources/identity.ex | 13 ++ test/support/resources/preference.ex | 13 ++ 7 files changed, 275 insertions(+), 2 deletions(-) create mode 100644 priv/resource_snapshots/test_repo/authors/20251018130654_dev.json create mode 100644 priv/resource_snapshots/test_repo/authors/20251018130654_dev.json.license create mode 100644 priv/test_repo/migrations/20251018130654_migrate_resources64_dev.exs create mode 100644 test/support/resources/identity.ex create mode 100644 test/support/resources/preference.ex diff --git a/priv/resource_snapshots/test_repo/authors/20251018130654_dev.json b/priv/resource_snapshots/test_repo/authors/20251018130654_dev.json new file mode 100644 index 00000000..e14b635e --- /dev/null +++ b/priv/resource_snapshots/test_repo/authors/20251018130654_dev.json @@ -0,0 +1,133 @@ +{ + "attributes": [ + { + "allow_nil?": false, + "default": "fragment(\"gen_random_uuid()\")", + "generated?": false, + "precision": null, + "primary_key?": true, + "references": null, + "scale": null, + "size": null, + "source": "id", + "type": "uuid" + }, + { + "allow_nil?": true, + "default": "nil", + "generated?": false, + "precision": null, + "primary_key?": false, + "references": null, + "scale": null, + "size": null, + "source": "first_name", + "type": "text" + }, + { + "allow_nil?": true, + "default": "nil", + "generated?": false, + "precision": null, + "primary_key?": false, + "references": null, + "scale": null, + "size": null, + "source": "last_name", + "type": "text" + }, + { + "allow_nil?": true, + "default": "nil", + "generated?": false, + "precision": null, + "primary_key?": false, + "references": null, + "scale": null, + "size": null, + "source": "bio", + "type": "map" + }, + { + "allow_nil?": true, + "default": "nil", + "generated?": false, + "precision": null, + "primary_key?": false, + "references": null, + "scale": null, + "size": null, + "source": "bios", + "type": "jsonb" + }, + { + "allow_nil?": true, + "default": "nil", + "generated?": false, + "precision": null, + "primary_key?": false, + "references": null, + "scale": null, + "size": null, + "source": "badges", + "type": [ + "array", + "text" + ] + }, + { + "allow_nil?": true, + "default": "nil", + "generated?": false, + "precision": null, + "primary_key?": false, + "references": null, + "scale": null, + "size": null, + "source": "settings", + "type": "jsonb" + }, + { + "allow_nil?": true, + "default": "nil", + "generated?": false, + "precision": null, + "primary_key?": false, + "references": null, + "scale": null, + "size": null, + "source": "identities", + "type": "jsonb" + }, + { + "allow_nil?": true, + "default": "nil", + "generated?": false, + "precision": null, + "primary_key?": false, + "references": null, + "scale": null, + "size": null, + "source": "preferences", + "type": [ + "array", + "map" + ] + } + ], + "base_filter": null, + "check_constraints": [], + "custom_indexes": [], + "custom_statements": [], + "has_create_action": true, + "hash": "55CFEDA4CB07DD89D2807B080A6F0E14A0370D7EA0C48E67C36ACAC568137D95", + "identities": [], + "multitenancy": { + "attribute": null, + "global": null, + "strategy": null + }, + "repo": "Elixir.AshPostgres.TestRepo", + "schema": null, + "table": "authors" +} \ No newline at end of file diff --git a/priv/resource_snapshots/test_repo/authors/20251018130654_dev.json.license b/priv/resource_snapshots/test_repo/authors/20251018130654_dev.json.license new file mode 100644 index 00000000..b0a44fab --- /dev/null +++ b/priv/resource_snapshots/test_repo/authors/20251018130654_dev.json.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2019 ash_postgres contributors + +SPDX-License-Identifier: MIT diff --git a/priv/test_repo/migrations/20251018130654_migrate_resources64_dev.exs b/priv/test_repo/migrations/20251018130654_migrate_resources64_dev.exs new file mode 100644 index 00000000..ba9e1baf --- /dev/null +++ b/priv/test_repo/migrations/20251018130654_migrate_resources64_dev.exs @@ -0,0 +1,27 @@ +# SPDX-FileCopyrightText: 2019 ash_postgres contributors +# +# SPDX-License-Identifier: MIT + +defmodule AshPostgres.TestRepo.Migrations.MigrateResources64 do + @moduledoc """ + Updates resources based on their most recent snapshots. + + This file was autogenerated with `mix ash_postgres.generate_migrations` + """ + + use Ecto.Migration + + def up do + alter table(:authors) do + add(:identities, :jsonb) + add(:preferences, {:array, :map}) + end + end + + def down do + alter table(:authors) do + remove(:preferences) + remove(:identities) + end + end +end diff --git a/test/storage_types_test.exs b/test/storage_types_test.exs index ad414bf8..0f818048 100644 --- a/test/storage_types_test.exs +++ b/test/storage_types_test.exs @@ -93,4 +93,86 @@ defmodule AshPostgres.StorageTypesTest do |> Ash.Query.filter(not is_nil(settings["dues_reminders"])) |> Ash.read!() end + + test "can bulk update {:array, CustomTypedStruct} stored as jsonb" do + %{id: id} = + Author + |> Ash.Changeset.for_create( + :create, + %{ + first_name: "Test", + last_name: "User", + identities: [%{provider: "github", uid: "123"}, %{provider: "google", uid: "456"}] + } + ) + |> Ash.create!() + + %BulkResult{records: [author]} = + Author + |> Ash.Query.filter(id == ^id) + |> Ash.bulk_update(:update, %{identities: [%{provider: "gitlab", uid: "789"}]}, + return_errors?: true, + notify?: true, + strategy: [:atomic, :stream, :atomic_batches], + allow_stream_with: :full_read, + return_records?: true + ) + + assert length(author.identities) == 1 + assert %{provider: "gitlab", uid: "789"} = hd(author.identities) + + %BulkResult{records: [author]} = + Author + |> Ash.Query.filter(id == ^id) + |> Ash.bulk_update(:update, %{identities: []}, + return_errors?: true, + notify?: true, + strategy: [:atomic, :stream, :atomic_batches], + allow_stream_with: :full_read, + return_records?: true + ) + + assert author.identities == [] + end + + test "can bulk update {:array, CustomTypedStruct} stored as {:array, :map}" do + %{id: id} = + Author + |> Ash.Changeset.for_create( + :create, + %{ + first_name: "Test", + last_name: "User", + preferences: [%{key: "theme", value: "dark"}, %{key: "lang", value: "en"}] + } + ) + |> Ash.create!() + + %BulkResult{records: [author]} = + Author + |> Ash.Query.filter(id == ^id) + |> Ash.bulk_update(:update, %{preferences: [%{key: "theme", value: "light"}]}, + return_errors?: true, + notify?: true, + strategy: [:atomic, :stream, :atomic_batches], + allow_stream_with: :full_read, + return_records?: true + ) + + assert length(author.preferences) == 1 + assert %{key: "theme", value: "light"} = hd(author.preferences) + + %BulkResult{records: [author]} = + Author + |> Ash.Query.filter(id == ^id) + |> Ash.bulk_update(:update, %{preferences: []}, + return_errors?: true, + notify?: true, + strategy: [:atomic, :stream, :atomic_batches], + allow_stream_with: :full_read, + return_records?: true + ) + + assert author.preferences == [] + end end diff --git a/test/support/resources/author.ex b/test/support/resources/author.ex index 3530513c..4203b262 100644 --- a/test/support/resources/author.ex +++ b/test/support/resources/author.ex @@ -23,8 +23,8 @@ defmodule AshPostgres.Test.Author do table("authors") repo(AshPostgres.TestRepo) - migration_types bios: :jsonb, settings: :jsonb - storage_types(bios: :jsonb, settings: :jsonb) + migration_types bios: :jsonb, settings: :jsonb, identities: :jsonb + storage_types(bios: :jsonb, settings: :jsonb, identities: :jsonb) end attributes do @@ -35,6 +35,8 @@ defmodule AshPostgres.Test.Author do attribute(:bios, {:array, :map}, public?: true) attribute(:badges, {:array, :atom}, public?: true) attribute(:settings, AshPostgres.Test.Settings, public?: true) + attribute(:identities, {:array, AshPostgres.Test.Identity}, public?: true) + attribute(:preferences, {:array, AshPostgres.Test.Preference}, public?: true) end actions do diff --git a/test/support/resources/identity.ex b/test/support/resources/identity.ex new file mode 100644 index 00000000..d29aaa07 --- /dev/null +++ b/test/support/resources/identity.ex @@ -0,0 +1,13 @@ +# SPDX-FileCopyrightText: 2019 ash_postgres contributors +# +# SPDX-License-Identifier: MIT + +defmodule AshPostgres.Test.Identity do + @moduledoc false + use Ash.TypedStruct + + typed_struct do + field(:provider, :string, allow_nil?: false) + field(:uid, :string, allow_nil?: false) + end +end diff --git a/test/support/resources/preference.ex b/test/support/resources/preference.ex new file mode 100644 index 00000000..b5e707fa --- /dev/null +++ b/test/support/resources/preference.ex @@ -0,0 +1,13 @@ +# SPDX-FileCopyrightText: 2019 ash_postgres contributors +# +# SPDX-License-Identifier: MIT + +defmodule AshPostgres.Test.Preference do + @moduledoc false + use Ash.TypedStruct + + typed_struct do + field(:key, :string, allow_nil?: false) + field(:value, :string, allow_nil?: false) + end +end From 1023dedf41af0f9772240c42f7cf369b1b29b5c1 Mon Sep 17 00:00:00 2001 From: Zach Daniel Date: Sun, 19 Oct 2025 12:27:55 -0400 Subject: [PATCH 172/174] improvement: remove unused bulk operation metadata function & update ash --- lib/data_layer.ex | 52 +++++++++++------------------------------------ mix.exs | 2 +- mix.lock | 6 +++--- 3 files changed, 16 insertions(+), 44 deletions(-) diff --git a/lib/data_layer.ex b/lib/data_layer.ex index b984c4db..4469f369 100644 --- a/lib/data_layer.ex +++ b/lib/data_layer.ex @@ -2138,18 +2138,12 @@ defmodule AshPostgres.DataLayer do maybe_create_tenant!(resource, result_for_changeset) end - case get_bulk_operation_metadata(changeset) do - {index, metadata_key} -> - Ash.Resource.put_metadata(result_for_changeset, metadata_key, index) - - nil -> - # Compatibility fallback - Ash.Resource.put_metadata( - result_for_changeset, - :bulk_create_index, - changeset.context[:bulk_create][:index] - ) - end + # Compatibility fallback + Ash.Resource.put_metadata( + result_for_changeset, + :bulk_create_index, + changeset.context[:bulk_create][:index] + ) end end) |> Enum.filter(& &1) @@ -2161,18 +2155,12 @@ defmodule AshPostgres.DataLayer do maybe_create_tenant!(resource, result) end - case get_bulk_operation_metadata(changeset) do - {index, metadata_key} -> - Ash.Resource.put_metadata(result, metadata_key, index) - - nil -> - # Compatibility fallback - Ash.Resource.put_metadata( - result, - :bulk_create_index, - changeset.context[:bulk_create][:index] - ) - end + # Compatibility fallback + Ash.Resource.put_metadata( + result, + :bulk_create_index, + changeset.context[:bulk_create][:index] + ) end) end @@ -3759,20 +3747,4 @@ defmodule AshPostgres.DataLayer do resource end end - - defp get_bulk_operation_metadata(changeset) do - changeset.context - |> Enum.find_value(fn - # New format: {{:bulk_create, ref}, value} -> {index, metadata_key} - {{:bulk_create, ref}, value} -> - {value.index, {:bulk_create_index, ref}} - - # Fallback for old format: {:bulk_create, value} -> {index, metadata_key} - {:bulk_create, value} when is_map(value) -> - {value.index, :bulk_create_index} - - _ -> - nil - end) - end end diff --git a/mix.exs b/mix.exs index 5e14da8d..526064c2 100644 --- a/mix.exs +++ b/mix.exs @@ -177,7 +177,7 @@ defmodule AshPostgres.MixProject do # Run "mix help deps" to learn about dependencies. defp deps do [ - {:ash, ash_version("~> 3.7")}, + {:ash, ash_version("~> 3.7 and >= 3.7.5")}, {:spark, "~> 2.3 and >= 2.3.4"}, {:ash_sql, ash_sql_version("~> 0.3 and >= 0.3.7")}, {:igniter, "~> 0.6 and >= 0.6.29", optional: true}, diff --git a/mix.lock b/mix.lock index c988302d..a40b623c 100644 --- a/mix.lock +++ b/mix.lock @@ -1,10 +1,10 @@ %{ - "ash": {:hex, :ash, "3.7.1", "abb55dee19e0959e529e52fe0622468825ae05400f535484919713e492d9a9e7", [:mix], [{:crux, "~> 0.1.0", [hex: :crux, repo: "hexpm", optional: false]}, {:decimal, "~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:ecto, "~> 3.7", [hex: :ecto, repo: "hexpm", optional: false]}, {:ets, "~> 0.8", [hex: :ets, repo: "hexpm", optional: false]}, {:igniter, ">= 0.6.29 and < 1.0.0-0", [hex: :igniter, repo: "hexpm", optional: true]}, {:jason, ">= 1.0.0", [hex: :jason, repo: "hexpm", optional: false]}, {:picosat_elixir, "~> 0.2", [hex: :picosat_elixir, repo: "hexpm", optional: true]}, {:plug, ">= 0.0.0", [hex: :plug, repo: "hexpm", optional: true]}, {:reactor, "~> 0.11", [hex: :reactor, repo: "hexpm", optional: false]}, {:simple_sat, ">= 0.1.1 and < 1.0.0-0", [hex: :simple_sat, repo: "hexpm", optional: true]}, {:spark, ">= 2.3.3 and < 3.0.0-0", [hex: :spark, repo: "hexpm", optional: false]}, {:splode, ">= 0.2.6 and < 1.0.0-0", [hex: :splode, repo: "hexpm", optional: false]}, {:stream_data, "~> 1.0", [hex: :stream_data, repo: "hexpm", optional: false]}, {:telemetry, "~> 1.1", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "4474ce9befe9862d1ed73cadf8a755e836c45a14a7b3b952d02e1a12f2b2e529"}, + "ash": {:hex, :ash, "3.7.5", "91e926d14f51a6b406660bd136c3165316d37f2ce68f0ca6118d7c0e41174f0c", [:mix], [{:crux, ">= 0.1.2 and < 1.0.0-0", [hex: :crux, repo: "hexpm", optional: false]}, {:decimal, "~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:ecto, "~> 3.7", [hex: :ecto, repo: "hexpm", optional: false]}, {:ets, "~> 0.8", [hex: :ets, repo: "hexpm", optional: false]}, {:igniter, ">= 0.6.29 and < 1.0.0-0", [hex: :igniter, repo: "hexpm", optional: true]}, {:jason, ">= 1.0.0", [hex: :jason, repo: "hexpm", optional: false]}, {:picosat_elixir, "~> 0.2", [hex: :picosat_elixir, repo: "hexpm", optional: true]}, {:plug, ">= 0.0.0", [hex: :plug, repo: "hexpm", optional: true]}, {:reactor, "~> 0.11", [hex: :reactor, repo: "hexpm", optional: false]}, {:simple_sat, ">= 0.1.1 and < 1.0.0-0", [hex: :simple_sat, repo: "hexpm", optional: true]}, {:spark, ">= 2.3.3 and < 3.0.0-0", [hex: :spark, repo: "hexpm", optional: false]}, {:splode, ">= 0.2.6 and < 1.0.0-0", [hex: :splode, repo: "hexpm", optional: false]}, {:stream_data, "~> 1.0", [hex: :stream_data, repo: "hexpm", optional: false]}, {:telemetry, "~> 1.1", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "df839ac2321768dde1216e317e5a824a136251699f8837a1e8a9ee4508f7e47a"}, "ash_sql": {:hex, :ash_sql, "0.3.7", "80affa5446075d71deb157c67290685a84b392d723be766bfb684f58fe0143de", [:mix], [{:ash, "~> 3.7", [hex: :ash, repo: "hexpm", optional: false]}, {:ecto, "~> 3.9", [hex: :ecto, repo: "hexpm", optional: false]}, {:ecto_sql, "~> 3.9", [hex: :ecto_sql, repo: "hexpm", optional: false]}], "hexpm", "ce4d974b8e784171c5a2a62593b3672b42dfd4888fa2239f01a6b32bad769038"}, "benchee": {:hex, :benchee, "1.4.0", "9f1f96a30ac80bab94faad644b39a9031d5632e517416a8ab0a6b0ac4df124ce", [:mix], [{:deep_merge, "~> 1.0", [hex: :deep_merge, repo: "hexpm", optional: false]}, {:statistex, "~> 1.0", [hex: :statistex, repo: "hexpm", optional: false]}, {:table, "~> 0.1.0", [hex: :table, repo: "hexpm", optional: true]}], "hexpm", "299cd10dd8ce51c9ea3ddb74bb150f93d25e968f93e4c1fa31698a8e4fa5d715"}, "bunt": {:hex, :bunt, "1.0.0", "081c2c665f086849e6d57900292b3a161727ab40431219529f13c4ddcf3e7a44", [:mix], [], "hexpm", "dc5f86aa08a5f6fa6b8096f0735c4e76d54ae5c9fa2c143e5a1fc7c1cd9bb6b5"}, - "credo": {:hex, :credo, "1.7.12", "9e3c20463de4b5f3f23721527fcaf16722ec815e70ff6c60b86412c695d426c1", [:mix], [{:bunt, "~> 0.2.1 or ~> 1.0", [hex: :bunt, repo: "hexpm", optional: false]}, {:file_system, "~> 0.2 or ~> 1.0", [hex: :file_system, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "8493d45c656c5427d9c729235b99d498bd133421f3e0a683e5c1b561471291e5"}, - "crux": {:hex, :crux, "0.1.1", "94f2f97d2a6079ae3c57f356412bc3b307f9579a80e43f526447b1d508dd4a72", [:mix], [{:picosat_elixir, "~> 0.2", [hex: :picosat_elixir, repo: "hexpm", optional: true]}, {:simple_sat, ">= 0.1.1 and < 1.0.0-0", [hex: :simple_sat, repo: "hexpm", optional: true]}, {:stream_data, "~> 1.0", [hex: :stream_data, repo: "hexpm", optional: true]}], "hexpm", "e59d498f038193cbe31e448f9199f5b4c53a4c67cece9922bb839595189dd2b6"}, + "credo": {:hex, :credo, "1.7.13", "126a0697df6b7b71cd18c81bc92335297839a806b6f62b61d417500d1070ff4e", [:mix], [{:bunt, "~> 0.2.1 or ~> 1.0", [hex: :bunt, repo: "hexpm", optional: false]}, {:file_system, "~> 0.2 or ~> 1.0", [hex: :file_system, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "47641e6d2bbff1e241e87695b29f617f1a8f912adea34296fb10ecc3d7e9e84f"}, + "crux": {:hex, :crux, "0.1.2", "4441c9e3a34f1e340954ce96b9ad5a2de13ceb4f97b3f910211227bb92e2ca90", [:mix], [{:picosat_elixir, "~> 0.2", [hex: :picosat_elixir, repo: "hexpm", optional: true]}, {:simple_sat, ">= 0.1.1 and < 1.0.0-0", [hex: :simple_sat, repo: "hexpm", optional: true]}, {:stream_data, "~> 1.0", [hex: :stream_data, repo: "hexpm", optional: true]}], "hexpm", "563ea3748ebfba9cc078e6d198a1d6a06015a8fae503f0b721363139f0ddb350"}, "db_connection": {:hex, :db_connection, "2.8.1", "9abdc1e68c34c6163f6fb96a96532272d13ad7ca45262156ae8b7ec6d9dc4bec", [:mix], [{:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "a61a3d489b239d76f326e03b98794fb8e45168396c925ef25feb405ed09da8fd"}, "decimal": {:hex, :decimal, "2.3.0", "3ad6255aa77b4a3c4f818171b12d237500e63525c2fd056699967a3e7ea20f62", [:mix], [], "hexpm", "a4d66355cb29cb47c3cf30e71329e58361cfcb37c34235ef3bf1d7bf3773aeac"}, "deep_merge": {:hex, :deep_merge, "1.0.0", "b4aa1a0d1acac393bdf38b2291af38cb1d4a52806cf7a4906f718e1feb5ee961", [:mix], [], "hexpm", "ce708e5f094b9cd4e8f2be4f00d2f4250c4095be93f8cd6d018c753894885430"}, From 89ca1fe164cb9c24ac1ff822ec6891d23a5bf91f Mon Sep 17 00:00:00 2001 From: Zach Daniel Date: Sun, 19 Oct 2025 12:30:18 -0400 Subject: [PATCH 173/174] chore: update mix.lock --- mix.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mix.lock b/mix.lock index a40b623c..9b2bc487 100644 --- a/mix.lock +++ b/mix.lock @@ -1,6 +1,6 @@ %{ "ash": {:hex, :ash, "3.7.5", "91e926d14f51a6b406660bd136c3165316d37f2ce68f0ca6118d7c0e41174f0c", [:mix], [{:crux, ">= 0.1.2 and < 1.0.0-0", [hex: :crux, repo: "hexpm", optional: false]}, {:decimal, "~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:ecto, "~> 3.7", [hex: :ecto, repo: "hexpm", optional: false]}, {:ets, "~> 0.8", [hex: :ets, repo: "hexpm", optional: false]}, {:igniter, ">= 0.6.29 and < 1.0.0-0", [hex: :igniter, repo: "hexpm", optional: true]}, {:jason, ">= 1.0.0", [hex: :jason, repo: "hexpm", optional: false]}, {:picosat_elixir, "~> 0.2", [hex: :picosat_elixir, repo: "hexpm", optional: true]}, {:plug, ">= 0.0.0", [hex: :plug, repo: "hexpm", optional: true]}, {:reactor, "~> 0.11", [hex: :reactor, repo: "hexpm", optional: false]}, {:simple_sat, ">= 0.1.1 and < 1.0.0-0", [hex: :simple_sat, repo: "hexpm", optional: true]}, {:spark, ">= 2.3.3 and < 3.0.0-0", [hex: :spark, repo: "hexpm", optional: false]}, {:splode, ">= 0.2.6 and < 1.0.0-0", [hex: :splode, repo: "hexpm", optional: false]}, {:stream_data, "~> 1.0", [hex: :stream_data, repo: "hexpm", optional: false]}, {:telemetry, "~> 1.1", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "df839ac2321768dde1216e317e5a824a136251699f8837a1e8a9ee4508f7e47a"}, - "ash_sql": {:hex, :ash_sql, "0.3.7", "80affa5446075d71deb157c67290685a84b392d723be766bfb684f58fe0143de", [:mix], [{:ash, "~> 3.7", [hex: :ash, repo: "hexpm", optional: false]}, {:ecto, "~> 3.9", [hex: :ecto, repo: "hexpm", optional: false]}, {:ecto_sql, "~> 3.9", [hex: :ecto_sql, repo: "hexpm", optional: false]}], "hexpm", "ce4d974b8e784171c5a2a62593b3672b42dfd4888fa2239f01a6b32bad769038"}, + "ash_sql": {:hex, :ash_sql, "0.3.8", "9f55866149b4fc092eb37c346e0734143f70dbfae8793c86a5a46803c2b47a12", [:mix], [{:ash, "~> 3.7", [hex: :ash, repo: "hexpm", optional: false]}, {:ecto, "~> 3.9", [hex: :ecto, repo: "hexpm", optional: false]}, {:ecto_sql, "~> 3.9", [hex: :ecto_sql, repo: "hexpm", optional: false]}], "hexpm", "0b58a8191744347bb349ace9affb3effc5ceaf8f1bc572915a5cf2ec4c45b72d"}, "benchee": {:hex, :benchee, "1.4.0", "9f1f96a30ac80bab94faad644b39a9031d5632e517416a8ab0a6b0ac4df124ce", [:mix], [{:deep_merge, "~> 1.0", [hex: :deep_merge, repo: "hexpm", optional: false]}, {:statistex, "~> 1.0", [hex: :statistex, repo: "hexpm", optional: false]}, {:table, "~> 0.1.0", [hex: :table, repo: "hexpm", optional: true]}], "hexpm", "299cd10dd8ce51c9ea3ddb74bb150f93d25e968f93e4c1fa31698a8e4fa5d715"}, "bunt": {:hex, :bunt, "1.0.0", "081c2c665f086849e6d57900292b3a161727ab40431219529f13c4ddcf3e7a44", [:mix], [], "hexpm", "dc5f86aa08a5f6fa6b8096f0735c4e76d54ae5c9fa2c143e5a1fc7c1cd9bb6b5"}, "credo": {:hex, :credo, "1.7.13", "126a0697df6b7b71cd18c81bc92335297839a806b6f62b61d417500d1070ff4e", [:mix], [{:bunt, "~> 0.2.1 or ~> 1.0", [hex: :bunt, repo: "hexpm", optional: false]}, {:file_system, "~> 0.2 or ~> 1.0", [hex: :file_system, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "47641e6d2bbff1e241e87695b29f617f1a8f912adea34296fb10ecc3d7e9e84f"}, From 913f9360a5c590c56ed80b984d2f434133ff773c Mon Sep 17 00:00:00 2001 From: Zach Daniel Date: Sun, 19 Oct 2025 22:41:24 -0400 Subject: [PATCH 174/174] chore: fix tests & don't do normal rollbacks with `--tenant` option --- lib/data_layer.ex | 130 +++++++++--------- .../migration_generator.ex | 14 +- .../authors/20251018130654_dev.json.license | 3 - ...018130654_dev.json => 20251020024026.json} | 2 +- ...=> 20251020024026_migrate_resources64.exs} | 4 - 5 files changed, 69 insertions(+), 84 deletions(-) delete mode 100644 priv/resource_snapshots/test_repo/authors/20251018130654_dev.json.license rename priv/resource_snapshots/test_repo/authors/{20251018130654_dev.json => 20251020024026.json} (97%) rename priv/test_repo/migrations/{20251018130654_migrate_resources64_dev.exs => 20251020024026_migrate_resources64.exs} (75%) diff --git a/lib/data_layer.ex b/lib/data_layer.ex index 4469f369..910e0e87 100644 --- a/lib/data_layer.ex +++ b/lib/data_layer.ex @@ -453,72 +453,74 @@ defmodule AshPostgres.DataLayer do migrations_path = AshPostgres.Mix.Helpers.migrations_path([], repo) tenant_migrations_path = AshPostgres.Mix.Helpers.tenant_migrations_path([], repo) - current_migrations = - Ecto.Query.from(row in "schema_migrations", - select: row.version - ) - |> repo.all() - |> Enum.map(&to_string/1) + if "--tenants" not in args do + current_migrations = + Ecto.Query.from(row in "schema_migrations", + select: row.version + ) + |> repo.all() + |> Enum.map(&to_string/1) + + files = + migrations_path + |> Path.join("**/*.exs") + |> Path.wildcard() + |> Enum.sort() + |> Enum.reverse() + |> Enum.filter(fn file -> + Enum.any?(current_migrations, &String.starts_with?(Path.basename(file), &1)) + end) + |> Enum.take(20) + |> Enum.map(&String.trim_leading(&1, migrations_path)) + |> Enum.map(&String.trim_leading(&1, "/")) + + indexed = + files + |> Enum.with_index() + |> Enum.map(fn {file, index} -> "#{index + 1}: #{file}" end) + + to = + Mix.shell().prompt( + """ + How many migrations should be rolled back#{for_repo}? (default: 0) + + Last 20 migration names, with the input you must provide to + rollback up to *and including* that migration: + + #{Enum.join(indexed, "\n")} + Rollback to: + """ + |> String.trim_trailing() + ) + |> String.trim() + |> case do + "" -> + nil - files = - migrations_path - |> Path.join("**/*.exs") - |> Path.wildcard() - |> Enum.sort() - |> Enum.reverse() - |> Enum.filter(fn file -> - Enum.any?(current_migrations, &String.starts_with?(Path.basename(file), &1)) - end) - |> Enum.take(20) - |> Enum.map(&String.trim_leading(&1, migrations_path)) - |> Enum.map(&String.trim_leading(&1, "/")) - - indexed = - files - |> Enum.with_index() - |> Enum.map(fn {file, index} -> "#{index + 1}: #{file}" end) - - to = - Mix.shell().prompt( - """ - How many migrations should be rolled back#{for_repo}? (default: 0) - - Last 20 migration names, with the input you must provide to - rollback up to *and including* that migration: - - #{Enum.join(indexed, "\n")} - Rollback to: - """ - |> String.trim_trailing() - ) - |> String.trim() - |> case do - "" -> - nil - - "0" -> - nil - - n -> - try do - files - |> Enum.at(String.to_integer(n) - 1) - rescue - _ -> - reraise "Required an integer value, got: #{n}", __STACKTRACE__ - end - |> String.split("_", parts: 2) - |> Enum.at(0) - |> String.to_integer() - end + "0" -> + nil - if to do - Mix.Task.run( - "ash_postgres.rollback", - args ++ ["-r", inspect(repo), "--to", to_string(to)] - ) + n -> + try do + files + |> Enum.at(String.to_integer(n) - 1) + rescue + _ -> + reraise "Required an integer value, got: #{n}", __STACKTRACE__ + end + |> String.split("_", parts: 2) + |> Enum.at(0) + |> String.to_integer() + end - Mix.Task.reenable("ash_postgres.rollback") + if to do + Mix.Task.run( + "ash_postgres.rollback", + args ++ ["-r", inspect(repo), "--to", to_string(to)] + ) + + Mix.Task.reenable("ash_postgres.rollback") + end end tenant_files = @@ -599,7 +601,7 @@ defmodule AshPostgres.DataLayer do if to do Mix.Task.run( "ash_postgres.rollback", - args ++ ["--tenants", "-r", inspect(repo), "--to", to] + args ++ ["--tenants", "-r", inspect(repo), "--to", to_string(to)] ) Mix.Task.reenable("ash_postgres.rollback") diff --git a/lib/migration_generator/migration_generator.ex b/lib/migration_generator/migration_generator.ex index 9881818c..425ccb53 100644 --- a/lib/migration_generator/migration_generator.ex +++ b/lib/migration_generator/migration_generator.ex @@ -514,16 +514,6 @@ defmodule AshPostgres.MigrationGenerator do end end - if Mix.env() == :test do - defp with_repo_not_in_test(repo, fun) do - fun.(repo) - end - else - defp with_repo_not_in_test(repo, fun) do - Ecto.Migrator.with_repo(repo, fun) - end - end - defp require_name!(opts) do if !opts.name && !opts.dry_run && !opts.check && !opts.snapshots_only && !opts.dev && !opts.auto_name do @@ -548,7 +538,7 @@ defmodule AshPostgres.MigrationGenerator do end) if tenant? do - with_repo_not_in_test(repo, fn repo -> + Ecto.Migrator.with_repo(repo, fn repo -> for prefix <- repo.all_tenants() do {repo, query, opts} = Ecto.Migration.SchemaMigration.versions(repo, [], prefix) @@ -583,7 +573,7 @@ defmodule AshPostgres.MigrationGenerator do end end) else - with_repo_not_in_test(repo, fn repo -> + Ecto.Migrator.with_repo(repo, fn repo -> {repo, query, opts} = Ecto.Migration.SchemaMigration.versions(repo, [], nil) repo.transaction(fn -> diff --git a/priv/resource_snapshots/test_repo/authors/20251018130654_dev.json.license b/priv/resource_snapshots/test_repo/authors/20251018130654_dev.json.license deleted file mode 100644 index b0a44fab..00000000 --- a/priv/resource_snapshots/test_repo/authors/20251018130654_dev.json.license +++ /dev/null @@ -1,3 +0,0 @@ -SPDX-FileCopyrightText: 2019 ash_postgres contributors - -SPDX-License-Identifier: MIT diff --git a/priv/resource_snapshots/test_repo/authors/20251018130654_dev.json b/priv/resource_snapshots/test_repo/authors/20251020024026.json similarity index 97% rename from priv/resource_snapshots/test_repo/authors/20251018130654_dev.json rename to priv/resource_snapshots/test_repo/authors/20251020024026.json index e14b635e..761a9e2a 100644 --- a/priv/resource_snapshots/test_repo/authors/20251018130654_dev.json +++ b/priv/resource_snapshots/test_repo/authors/20251020024026.json @@ -120,7 +120,7 @@ "custom_indexes": [], "custom_statements": [], "has_create_action": true, - "hash": "55CFEDA4CB07DD89D2807B080A6F0E14A0370D7EA0C48E67C36ACAC568137D95", + "hash": "DEDCEFDB71DE94818B8D624B0BFE438AD7AEDC6279FD05B83C11C216E7A0F991", "identities": [], "multitenancy": { "attribute": null, diff --git a/priv/test_repo/migrations/20251018130654_migrate_resources64_dev.exs b/priv/test_repo/migrations/20251020024026_migrate_resources64.exs similarity index 75% rename from priv/test_repo/migrations/20251018130654_migrate_resources64_dev.exs rename to priv/test_repo/migrations/20251020024026_migrate_resources64.exs index ba9e1baf..ff7d63f3 100644 --- a/priv/test_repo/migrations/20251018130654_migrate_resources64_dev.exs +++ b/priv/test_repo/migrations/20251020024026_migrate_resources64.exs @@ -1,7 +1,3 @@ -# SPDX-FileCopyrightText: 2019 ash_postgres contributors -# -# SPDX-License-Identifier: MIT - defmodule AshPostgres.TestRepo.Migrations.MigrateResources64 do @moduledoc """ Updates resources based on their most recent snapshots.