DDD.Dialect behaviour (vicander v0.1.1)

Copy Markdown View Source

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 adapterDialect
Ecto.Adapters.PostgresDDD.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.

Summary

Callbacks

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

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.

The database's current time in UTC.

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.

Functions

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

Callbacks

columns(repo, table)

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

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

lock_for_claim(t)

@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(repo)

@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(repo, fun)

@callback read_only(repo :: module(), fun :: (-> 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.

Functions

for_repo(repo)

@spec for_repo(module()) :: module()

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