# `Electric.Postgres.Identifiers`
[🔗](https://github.com/electric-sql/electric/tree/%40core/sync-service%401.6.2/packages/sync-service/lib/electric/postgres/identifiers.ex#L1)

# `downcase`

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`

```elixir
@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`

```elixir
@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`

```elixir
@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|}

---

*Consult [api-reference.md](api-reference.md) for complete listing*
