Packages
postgrex
0.17.5
1.0.0-rc.1
retired
1.0.0-rc.0
retired
0.22.3
0.22.2
0.22.1
0.22.0
0.21.1
0.21.0
0.20.0
0.19.3
0.19.2
0.19.1
0.19.0
0.18.0
0.17.5
0.17.4
0.17.3
0.17.2
0.17.1
0.17.0
0.16.5
0.16.4
0.16.3
0.16.2
0.16.1
0.16.0
0.15.13
0.15.12
0.15.11
0.15.10
0.15.9
0.15.8
0.15.7
0.15.6
0.15.5
0.15.4
0.15.3
0.15.2
0.15.1
0.15.0
0.14.3
0.14.2
0.14.1
0.14.0
0.14.0-rc.1
0.14.0-rc.0
0.13.5
0.13.4
0.13.3
0.13.2
0.13.1
0.13.0
0.13.0-rc.0
0.12.2
0.12.1
0.12.0
0.11.2
0.11.1
0.11.0
0.10.0
0.9.1
0.9.0
0.8.4
0.8.3
0.8.2
0.8.1
0.8.0
0.7.0
0.6.0
0.5.5
0.5.4
0.5.3
0.5.2
0.5.1
0.5.0
0.4.2
PostgreSQL driver for Elixir
Security advisory:
This version has known vulnerabilities.
View advisories
Current section
Files
Jump to
Current section
Files
lib/postgrex/extensions/tsvector.ex
defmodule Postgrex.Extensions.TSVector do
@moduledoc false
import Postgrex.BinaryUtils, warn: false
use Postgrex.BinaryExtension, send: "tsvectorsend"
def encode(_) do
quote location: :keep do
values when is_list(values) ->
encoded_tsvectors = unquote(__MODULE__).encode_tsvector(values)
<<byte_size(encoded_tsvectors)::int32(), encoded_tsvectors::binary>>
other ->
raise DBConnection.EncodeError, Postgrex.Utils.encode_msg(other, "a list of tsvectors")
end
end
def decode(_) do
quote do
<<len::int32(), value::binary-size(len)>> ->
<<nb_lexemes::int32(), words::binary>> = value
unquote(__MODULE__).decode_tsvector_values(words)
end
end
## Helpers
def encode_tsvector(values) do
<<length(values)::int32(), encode_lexemes(values)::binary>>
end
defp encode_lexemes(values) do
values |> Enum.map(fn x -> encode_positions(x) end) |> IO.iodata_to_binary()
end
defp encode_positions(%Postgrex.Lexeme{word: word, positions: positions}) do
positions =
Enum.map(positions, fn {position, weight} ->
<<encode_weight_binary(weight)::2, position::14>>
end)
[word, 0, <<length(positions)::16>> | positions]
end
def decode_tsvector_values("") do
[]
end
def decode_tsvector_values(words) do
[word, <<positions_count::16, rest::binary>>] = :binary.split(words, <<0>>)
positions_bytes = positions_count * 2
<<positions::binary-size(positions_bytes), remaining_data::binary>> = rest
positions =
for <<weight::2, position::14 <- positions>>, do: {position, decode_weight(weight)}
[%Postgrex.Lexeme{word: word, positions: positions} | decode_tsvector_values(remaining_data)]
end
defp encode_weight_binary(:A) do
3
end
defp encode_weight_binary(:B) do
2
end
defp encode_weight_binary(:C) do
1
end
defp encode_weight_binary(nil) do
0
end
defp decode_weight(0), do: nil
defp decode_weight(1), do: :C
defp decode_weight(2), do: :B
defp decode_weight(3), do: :A
end