mirror of
https://github.com/ash-project/ash_postgres.git
synced 2024-09-19 21:13:19 +12:00
improvement: handle UUID types better
This commit is contained in:
parent
fb8a13f33d
commit
5222e1e755
4 changed files with 130 additions and 6 deletions
30
lib/expr.ex
30
lib/expr.ex
|
@ -662,16 +662,15 @@ defmodule AshPostgres.Expr do
|
|||
|
||||
defp do_dynamic_expr(
|
||||
query,
|
||||
%Type{arguments: [arg1, arg2, constraints]} = type_expr,
|
||||
%Type{arguments: [arg1, arg2, constraints]},
|
||||
bindings,
|
||||
_embedded?,
|
||||
embedded?,
|
||||
_type
|
||||
) do
|
||||
arg1 = do_dynamic_expr(query, arg1, bindings, false)
|
||||
arg2 = Ash.Type.get_type(arg2)
|
||||
arg1 = maybe_uuid_to_binary(arg2, arg1, arg1)
|
||||
type = AshPostgres.Types.parameterized_type(arg2, constraints)
|
||||
validate_type!(query, type, type_expr)
|
||||
|
||||
Ecto.Query.dynamic(type(^arg1, ^type))
|
||||
do_dynamic_expr(query, arg1, bindings, embedded?, type)
|
||||
end
|
||||
|
||||
defp do_dynamic_expr(
|
||||
|
@ -795,10 +794,29 @@ defmodule AshPostgres.Expr do
|
|||
|
||||
defp do_dynamic_expr(query, value, _bindings, false, type) do
|
||||
value = maybe_sanitize_list(value)
|
||||
type = AshPostgres.Types.parameterized_type(type, [])
|
||||
validate_type!(query, type, value)
|
||||
|
||||
Ecto.Query.dynamic(type(^value, ^type))
|
||||
end
|
||||
|
||||
defp maybe_uuid_to_binary({:array, type}, value, _original_value) when is_list(value) do
|
||||
Enum.map(value, &maybe_uuid_to_binary(type, &1, &1))
|
||||
end
|
||||
|
||||
defp maybe_uuid_to_binary(type, value, original_value)
|
||||
when type in [
|
||||
Ash.Type.UUID.EctoType,
|
||||
:uuid
|
||||
] and is_binary(value) do
|
||||
case Ecto.UUID.dump(value) do
|
||||
{:ok, encoded} -> encoded
|
||||
_ -> original_value
|
||||
end
|
||||
end
|
||||
|
||||
defp maybe_uuid_to_binary(_type, _value, original_value), do: original_value
|
||||
|
||||
defp validate_type!(query, type, context) do
|
||||
case type do
|
||||
{:parameterized, Ash.Type.CiStringWrapper.EctoType, _} ->
|
||||
|
|
|
@ -0,0 +1,77 @@
|
|||
{
|
||||
"attributes": [
|
||||
{
|
||||
"allow_nil?": false,
|
||||
"default": "nil",
|
||||
"generated?": false,
|
||||
"primary_key?": true,
|
||||
"references": {
|
||||
"destination_attribute": "id",
|
||||
"destination_attribute_default": null,
|
||||
"destination_attribute_generated": null,
|
||||
"multitenancy": {
|
||||
"attribute": null,
|
||||
"global": null,
|
||||
"strategy": null
|
||||
},
|
||||
"name": "post_links_source_post_id_fkey",
|
||||
"on_delete": null,
|
||||
"on_update": null,
|
||||
"schema": "public",
|
||||
"table": "posts"
|
||||
},
|
||||
"size": null,
|
||||
"source": "source_post_id",
|
||||
"type": "uuid"
|
||||
},
|
||||
{
|
||||
"allow_nil?": false,
|
||||
"default": "nil",
|
||||
"generated?": false,
|
||||
"primary_key?": true,
|
||||
"references": {
|
||||
"destination_attribute": "id",
|
||||
"destination_attribute_default": null,
|
||||
"destination_attribute_generated": null,
|
||||
"multitenancy": {
|
||||
"attribute": null,
|
||||
"global": null,
|
||||
"strategy": null
|
||||
},
|
||||
"name": "post_links_destination_post_id_fkey",
|
||||
"on_delete": null,
|
||||
"on_update": null,
|
||||
"schema": "public",
|
||||
"table": "posts"
|
||||
},
|
||||
"size": null,
|
||||
"source": "destination_post_id",
|
||||
"type": "uuid"
|
||||
}
|
||||
],
|
||||
"base_filter": null,
|
||||
"check_constraints": [],
|
||||
"custom_indexes": [],
|
||||
"custom_statements": [],
|
||||
"has_create_action": true,
|
||||
"hash": "D5A5182C6A632C61F04477975186F608E1B6FA336CE6DAF40DBEF8A4E5689DB4",
|
||||
"identities": [
|
||||
{
|
||||
"base_filter": null,
|
||||
"index_name": "post_links_unique_link_index",
|
||||
"keys": [
|
||||
"source_post_id",
|
||||
"destination_post_id"
|
||||
],
|
||||
"name": "unique_link"
|
||||
}
|
||||
],
|
||||
"multitenancy": {
|
||||
"attribute": null,
|
||||
"global": null,
|
||||
"strategy": null
|
||||
},
|
||||
"repo": "Elixir.AshPostgres.TestRepo",
|
||||
"schema": null,
|
||||
"table": "post_links"
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
defmodule AshPostgres.TestRepo.Migrations.MigrateResources3 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 unique_index(:post_links, [:source_post_id, :destination_post_id],
|
||||
name: "post_links_unique_link_index"
|
||||
)
|
||||
end
|
||||
|
||||
def down do
|
||||
drop_if_exists unique_index(:post_links, [:source_post_id, :destination_post_id],
|
||||
name: "post_links_unique_link_index"
|
||||
)
|
||||
end
|
||||
end
|
|
@ -27,4 +27,12 @@ defmodule AshPostgres.Test.TypeTest do
|
|||
|> Ash.Query.filter(fragment("(?)[1] > (?)[2]", point, point))
|
||||
|> Api.read!()
|
||||
end
|
||||
|
||||
test "uuids can be used as strings in fragments" do
|
||||
uuid = Ash.UUID.generate()
|
||||
|
||||
Post
|
||||
|> Ash.Query.filter(fragment("? = ?", id, type(^uuid, :uuid)))
|
||||
|> Api.read!()
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Reference in a new issue