# `DDD.Dialect`
[🔗](https://github.com/blackuprise/vicander/blob/v0.1.1/lib/ddd/persistence/dialect.ex#L1)

The few things that differ between databases.

Almost everything the framework does against the database is an Ecto query, so it runs on
whatever adapter the application's repo uses. What cannot be expressed in Ecto is behind this
behaviour, and the implementation is chosen from the repo's adapter:

| Ecto adapter             | Dialect                |
|--------------------------|------------------------|
| `Ecto.Adapters.Postgres` | `DDD.Dialect.Postgres` |

The framework has no dependency on a driver: the application adds the one it needs (for
example `postgrex`), and the dialect follows from the repo. For an adapter that has no
dialect here, write one and name it in the configuration:

    config :vicander, dialect: MyApp.Dialect

A repo that has no dialect raises `ArgumentError` the first time the framework needs one,
naming the adapter, rather than running SQL it does not understand.

# `columns`

```elixir
@callback columns(repo :: module(), table :: String.t()) :: [String.t()]
```

The names of the columns of `table`, as the database reports them.

# `lock_for_claim`

```elixir
@callback lock_for_claim(Ecto.Query.t()) :: Ecto.Query.t()
```

`query` with the lock that makes a claim skip rows another transaction has locked
(`FOR UPDATE SKIP LOCKED`), or `query` unchanged when the database has none. Unchanged, the
claim relies on the database serialising writers, which is only correct for a single node.

Ecto accepts only a literal lock, so the dialect applies it rather than naming it.

# `now`

```elixir
@callback now(repo :: module()) :: DateTime.t()
```

The database's current time in UTC.

Leases and retry times are compared with this clock, never with the clock of the node that
wrote them, so nodes whose clocks differ still agree on when a lease is over.

# `read_only`

```elixir
@callback read_only(repo :: module(), fun :: (-&gt; result)) :: result when result: term()
```

Run `fun` in a read-only transaction on `repo` and return its result. The transaction is
rolled back, so nothing it did, including switching the mode on, outlives the call.

# `for_repo`

```elixir
@spec for_repo(module()) :: module()
```

The dialect for `repo`: the configured one, else the one for its adapter.

---

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