Packages
postgrex
0.20.0
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/error_code.ex
defmodule Postgrex.ErrorCode do
@moduledoc false
# We put this file in the repo because the last real change happened in 2011.
# https://github.com/postgres/postgres/blob/master/src/backend/utils/errcodes.txt
@external_resource errcodes_path = Path.join(__DIR__, "errcodes.txt")
errcodes =
for line <- File.stream!(errcodes_path),
match?(<<_code::5*8, " ", _::binary>>, line) do
case String.split(line, " ", trim: true) do
[code, _, _, name] -> {code, name |> String.trim() |> String.to_atom()}
# duplicated code without name
[code, _, _] -> {code}
end
end
{errcodes, duplicates} = Enum.split_with(errcodes, &match?({_, _}, &1))
# The errcodes.txt file does contain some codes twice, but the duplicates
# don't have a name. Make sure every code without a name has another
# entry with a name.
for {duplicate} <- duplicates do
unless Enum.find(errcodes, fn {code, _} -> code == duplicate end) do
raise RuntimeError, "found errcode #{duplicate} without name"
end
end
@doc ~S"""
Translates a PostgreSQL error code into a name
Examples:
iex> code_to_name("23505")
:unique_violation
"""
@spec code_to_name(String.t()) :: atom | no_return
def code_to_name(code)
for {code, errcodes} <- Enum.group_by(errcodes, &elem(&1, 0)) do
[{^code, name}] = errcodes
def code_to_name(unquote(code)), do: unquote(name)
end
def code_to_name(_), do: nil
@doc ~S"""
Translates a PostgreSQL error name into a list of possible codes.
Most error names have only a single code, but there are exceptions.
Examples:
iex> name_to_code(:prohibited_sql_statement_attempted)
"2F003"
"""
@spec name_to_code(atom) :: String.t()
def name_to_code(name)
@code_decision_table [
# 01004 not used
string_data_right_truncation: "22001",
# 38002 or 2F002 not used
modifying_sql_data_not_permitted: nil,
# 38003 not used
prohibited_sql_statement_attempted: "2F003",
# 38004 or 2F004 not used
reading_sql_data_not_permitted: nil,
# 39004 not used
null_value_not_allowed: "22004"
]
for {name, errcodes} <- Enum.group_by(errcodes, &elem(&1, 1)) do
case Keyword.fetch(@code_decision_table, name) do
{:ok, nil} ->
:ok
{:ok, code} ->
def name_to_code(unquote(name)), do: unquote(code)
:error ->
[{code, ^name}] = errcodes
def name_to_code(unquote(name)), do: unquote(code)
end
end
end