Packages
postgrex
0.13.1
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
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 Bitwise
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 ArgumentError, 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
Enum.map(values, 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