Skip to content

Commit 5ddb7a5

Browse files
greg-rychlewskiGreg Rychlewski
andauthored
Fix binary uuid casting (#121)
Co-authored-by: Greg Rychlewski <[email protected]>
1 parent e484517 commit 5ddb7a5

File tree

4 files changed

+60
-0
lines changed

4 files changed

+60
-0
lines changed

lib/ecto/adapters/sqlite3/connection.ex

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1431,6 +1431,26 @@ defmodule Ecto.Adapters.SQLite3.Connection do
14311431
[?x, ?', hex, ?']
14321432
end
14331433

1434+
def expr(%Ecto.Query.Tagged{value: expr, type: :binary_id}, sources, query) do
1435+
case Application.get_env(:ecto_sqlite3, :binary_id_type, :string) do
1436+
:string ->
1437+
["CAST(", expr(expr, sources, query), " AS ", column_type(:string, query), ?)]
1438+
1439+
:binary ->
1440+
[expr(expr, sources, query)]
1441+
end
1442+
end
1443+
1444+
def expr(%Ecto.Query.Tagged{value: expr, type: :uuid}, sources, query) do
1445+
case Application.get_env(:ecto_sqlite3, :uuid_type, :string) do
1446+
:string ->
1447+
["CAST(", expr(expr, sources, query), " AS ", column_type(:string, query), ?)]
1448+
1449+
:binary ->
1450+
[expr(expr, sources, query)]
1451+
end
1452+
end
1453+
14341454
def expr(%Ecto.Query.Tagged{value: other, type: type}, sources, query)
14351455
when type in [:decimal, :float] do
14361456
["CAST(", expr(other, sources, query), " AS REAL)"]

test/ecto/integration/uuid_test.exs

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ defmodule Ecto.Integration.UUIDTest do
44
alias Ecto.Integration.TestRepo
55
alias EctoSQLite3.Schemas.Product
66

7+
import Ecto.Query, only: [from: 2]
8+
79
setup do
810
Application.put_env(:ecto_sqlite3, :uuid_type, :string)
911
on_exit(fn -> Application.put_env(:ecto_sqlite3, :uuid_type, :string) end)
@@ -34,4 +36,40 @@ defmodule Ecto.Integration.UUIDTest do
3436
assert found
3537
assert found.external_id == external_id
3638
end
39+
40+
test "handles uuid casting with binary format" do
41+
Application.put_env(:ecto_sqlite3, :uuid_type, :binary)
42+
Application.put_env(:ecto_sqlite3, :binary_id_type, :binary)
43+
44+
external_id = Ecto.UUID.generate()
45+
TestRepo.insert!(%Product{external_id: external_id, bid: external_id})
46+
47+
product =
48+
TestRepo.one(from(p in Product, where: p.external_id == type(p.bid, Ecto.UUID)))
49+
50+
assert %{external_id: ^external_id} = product
51+
52+
product =
53+
TestRepo.one(
54+
from(p in Product, where: p.external_id == type(^external_id, Ecto.UUID))
55+
)
56+
57+
assert %{external_id: ^external_id} = product
58+
end
59+
60+
test "handles binary_id casting with binary format" do
61+
Application.put_env(:ecto_sqlite3, :uuid_type, :binary)
62+
Application.put_env(:ecto_sqlite3, :binary_id_type, :binary)
63+
64+
bid = Ecto.UUID.generate()
65+
TestRepo.insert!(%Product{bid: bid, external_id: bid})
66+
67+
product =
68+
TestRepo.one(from(p in Product, where: p.bid == type(p.external_id, :binary_id)))
69+
70+
assert %{bid: ^bid} = product
71+
72+
product = TestRepo.one(from(p in Product, where: p.bid == type(^bid, :binary_id)))
73+
assert %{bid: ^bid} = product
74+
end
3775
end

test/support/migration.ex

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ defmodule EctoSQLite3.Integration.Migration do
2828
add(:name, :string)
2929
add(:description, :text)
3030
add(:external_id, :uuid)
31+
add(:bid, :binary_id)
3132
add(:tags, {:array, :string})
3233
add(:approved_at, :naive_datetime)
3334
add(:price, :decimal)

test/support/schemas/product.ex

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ defmodule EctoSQLite3.Schemas.Product do
1111
field(:name, :string)
1212
field(:description, :string)
1313
field(:external_id, Ecto.UUID)
14+
field(:bid, :binary_id)
1415
field(:tags, {:array, :string}, default: [])
1516
field(:approved_at, :naive_datetime)
1617
field(:price, :decimal)

0 commit comments

Comments
 (0)