-
Notifications
You must be signed in to change notification settings - Fork 63
/
vector.ex
63 lines (49 loc) · 1.51 KB
/
vector.ex
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
defmodule AshPostgres.Extensions.Vector do
@moduledoc """
An extension that adds support for the `vector` type.
Create a file with these contents, not inside of a module:
```elixir
Postgrex.Types.define(<YourApp>.PostgrexTypes, [AshPostgres.Extensions.Vector] ++ Ecto.Adapters.Postgres.extensions(), [])
```
And then ensure that you refer to these types in your repo configuration, i.e
```elixir
config :my_app, YourApp.Repo,
types: <YourApp>.PostgrexTypes
```
"""
import Postgrex.BinaryUtils, warn: false
def init(opts), do: Keyword.get(opts, :decode_binary, :copy)
def matching(_), do: [type: "vector"]
def format(_), do: :binary
def encode(_) do
quote do
vec when is_struct(vec, Ash.Vector) ->
data = vec |> Ash.Vector.to_binary()
[<<IO.iodata_length(data)::int32()>> | data]
vec ->
case Ash.Vector.new(vec) do
{:ok, vector} ->
data = Ash.Vector.to_binary(vector)
[<<IO.iodata_length(data)::int32()>> | data]
{:error, error} ->
raise """
Attempting to encode invalid vector, error: #{inspect(error)}
Vector:
#{inspect(vec)}
"""
end
end
end
def decode(:copy) do
quote do
<<len::int32(), bin::binary-size(len)>> ->
bin |> :binary.copy() |> Ash.Vector.from_binary()
end
end
def decode(_) do
quote do
<<len::int32(), bin::binary-size(len)>> ->
bin |> Ash.Vector.from_binary()
end
end
end