zf

zenflows testing
git clone https://s.sonu.ch/~srfsh/zf.git
Log | Files | Refs | Submodules | README | LICENSE

error_code.ex (2515B)


      1 defmodule Postgrex.ErrorCode do
      2   @moduledoc false
      3   # We put this file in the repo because the last real change happened in 2011.
      4   # https://github.com/postgres/postgres/blob/master/src/backend/utils/errcodes.txt
      5   @external_resource errcodes_path = Path.join(__DIR__, "errcodes.txt")
      6 
      7   errcodes =
      8     for line <- File.stream!(errcodes_path),
      9         match?(<<_code::5*8, "    ", _::binary>>, line) do
     10       case String.split(line, " ", trim: true) do
     11         [code, _, _, name] -> {code, name |> String.trim() |> String.to_atom()}
     12         # duplicated code without name
     13         [code, _, _] -> {code}
     14       end
     15     end
     16 
     17   {errcodes, duplicates} = Enum.split_with(errcodes, &match?({_, _}, &1))
     18 
     19   # The errcodes.txt file does contain some codes twice, but the duplicates
     20   # don't have a name. Make sure every every code without a name has another
     21   # entry with a name.
     22   for {duplicate} <- duplicates do
     23     unless Enum.find(errcodes, fn {code, _} -> code == duplicate end) do
     24       raise RuntimeError, "found errcode #{duplicate} without name"
     25     end
     26   end
     27 
     28   @doc ~S"""
     29   Translates a PostgreSQL error code into a name
     30 
     31   Examples:
     32       iex> code_to_name("23505")
     33       :unique_violation
     34   """
     35   @spec code_to_name(String.t()) :: atom | no_return
     36   def code_to_name(code)
     37 
     38   for {code, errcodes} <- Enum.group_by(errcodes, &elem(&1, 0)) do
     39     [{^code, name}] = errcodes
     40     def code_to_name(unquote(code)), do: unquote(name)
     41   end
     42 
     43   def code_to_name(_), do: nil
     44 
     45   @doc ~S"""
     46   Translates a PostgreSQL error name into a list of possible codes.
     47   Most error names have only a single code, but there are exceptions.
     48 
     49   Examples:
     50       iex> name_to_code(:prohibited_sql_statement_attempted)
     51       "2F003"
     52   """
     53   @spec name_to_code(atom) :: String.t()
     54   def name_to_code(name)
     55 
     56   @code_decision_table [
     57     # 01004 not used
     58     string_data_right_truncation: "22001",
     59     # 38002 or 2F002 not used
     60     modifying_sql_data_not_permitted: nil,
     61     # 38003 not used
     62     prohibited_sql_statement_attempted: "2F003",
     63     # 38004 or 2F004 not used
     64     reading_sql_data_not_permitted: nil,
     65     # 39004 not used
     66     null_value_not_allowed: "22004"
     67   ]
     68 
     69   for {name, errcodes} <- Enum.group_by(errcodes, &elem(&1, 1)) do
     70     case Keyword.fetch(@code_decision_table, name) do
     71       {:ok, nil} ->
     72         :ok
     73 
     74       {:ok, code} ->
     75         def name_to_code(unquote(name)), do: unquote(code)
     76 
     77       :error ->
     78         [{code, ^name}] = errcodes
     79         def name_to_code(unquote(name)), do: unquote(code)
     80     end
     81   end
     82 end