Electric.Postgres.Identifiers (electric v1.0.23)

View Source

Summary

Functions

Downcase the identifier using PostgreSQL's algorithm for downcasing.

Parse a PostgreSQL identifier, removing quotes if present and escaping internal ones and downcasing the identifier otherwise.

Parse a PostgreSQL relation identifier

Parse an unquoted PostgreSQL identifier, downcasing characters and failing if any special characters are present

Functions

downcase(ident, single_byte_encoding \\ false)

Downcase the identifier using PostgreSQL's algorithm for downcasing.

Setting single_byte_encoding to true will downcase the identifier using single byte encoding

See: https://github.com/postgres/postgres/blob/259a0a99fe3d45dcf624788c1724d9989f3382dc/src/backend/parser/scansup.c#L46-L80

Examples

iex> Electric.Postgres.Identifiers.downcase("FooBar")
"foobar"

parse(ident, single_byte_encoding \\ false)

@spec parse(binary(), boolean()) :: {:ok, binary()} | {:error, term()}

Parse a PostgreSQL identifier, removing quotes if present and escaping internal ones and downcasing the identifier otherwise.

Postgres identifiers are limited to 63 characters - Postgres will truncate them, but we'll fail if the identifier is too long to avoid api injection issues.

Examples

iex> Electric.Postgres.Identifiers.parse("FooBar")
{:ok, "foobar"}

iex> Electric.Postgres.Identifiers.parse(~S|"FooBar"|)
{:ok, "FooBar"}

iex> Electric.Postgres.Identifiers.parse(~S|Foo"Bar"|)
{:error, ~S|Invalid unquoted identifier contains special characters: Foo"Bar"|}

iex> Electric.Postgres.Identifiers.parse(~S| |)
{:error, ~S|Invalid unquoted identifier contains special characters:  |}

iex> Electric.Postgres.Identifiers.parse("foob@r")
{:error, ~S|Invalid unquoted identifier contains special characters: foob@r|}

iex> Electric.Postgres.Identifiers.parse(~S|"Foo"Bar"|)
{:error, ~S|Invalid identifier with unescaped quote: Foo"Bar|}

iex> Electric.Postgres.Identifiers.parse(~S|""|)
{:error, "Invalid zero-length delimited identifier"}

iex> Electric.Postgres.Identifiers.parse("")
{:error, "Invalid zero-length delimited identifier"}

iex> Electric.Postgres.Identifiers.parse(for(_ <- 1..64, into: "", do: "a"))
{:error, "Identifier is too long (max length is 63)"}

iex> Electric.Postgres.Identifiers.parse(~S|" "|)
{:ok, " "}

iex> Electric.Postgres.Identifiers.parse(~S|"Foo""Bar"|)
{:ok, ~S|Foo"Bar|}

parse_relation(ident)

@spec parse_relation(binary()) :: {:ok, Electric.relation()} | {:error, term()}

Parse a PostgreSQL relation identifier

Examples

iex> Electric.Postgres.Identifiers.parse_relation("foo")
{:ok, {"public", "foo"}}

iex> Electric.Postgres.Identifiers.parse_relation("foo.bar")
{:ok, {"foo", "bar"}}

iex> Electric.Postgres.Identifiers.parse_relation(~S|"foo"."bar"|)
{:ok, {"foo", "bar"}}

iex> Electric.Postgres.Identifiers.parse_relation(~S|"foo.woah"."bar"|)
{:ok, {"foo.woah", "bar"}}

iex> Electric.Postgres.Identifiers.parse_relation(~S|"foo".bar|)
{:ok, {"foo", "bar"}}

iex> Electric.Postgres.Identifiers.parse_relation(~S|"foo"."bar|)
{:error, ~S|Invalid unquoted identifier contains special characters: "bar|}

iex> Electric.Postgres.Identifiers.parse_relation("foo.bar.baz")
{:error, "Invalid relation identifier, too many delimiters: foo.bar.baz"}

parse_unquoted_identifier(ident, single_byte_encoding \\ false)

@spec parse_unquoted_identifier(binary(), boolean()) ::
  {:ok, binary()} | {:error, term()}

Parse an unquoted PostgreSQL identifier, downcasing characters and failing if any special characters are present

Examples

iex> Electric.Postgres.Identifiers.parse_unquoted_identifier("FooBar")
{:ok, "foobar"}

iex> Electric.Postgres.Identifiers.parse_unquoted_identifier("foob@r")
{:error, ~S|Invalid unquoted identifier contains special characters: foob@r|}