Arcadic.Transport behaviour (Arcadic v0.1.0)

Copy Markdown View Source

The transport seam (charter D2). One implementation ships — Arcadic.Transport.HTTP (Req/Finch). A future Bolt adapter implements the same callbacks. Callbacks are SEMANTIC (mode/session), not HTTP-verb-shaped, so a non-HTTP transport can honor them. This behaviour is also the mock seam consumed by ash_arcadic's tests.

request is the logical statement bundle %{statement: String.t(), params: map(), language: String.t()}; the transport shapes its own wire format from it.

Summary

Callbacks

Begin a session transaction; returns the session id.

Commit the session carried by conn.session_id.

Whether a database exists.

Run a read (:read → idempotent endpoint) or write (:write) statement.

Fire-and-forget write (server enqueues, does not await). Optional — HTTP implements it.

List all database names (GET /api/v1/databases).

Lazily stream a large read result as raw row maps (Bolt-only). Optional — HTTP has no cursor contract.

Server readiness.

Roll back the session carried by conn.session_id.

Run a server-level admin command (create/drop database).

Native fun-based transaction (for transports whose sessions are not detachable, e.g. Bolt). Optional.

Types

request()

@type request() :: %{statement: String.t(), params: map(), language: String.t()}

result()

@type result() ::
  {:ok, [map()]} | {:error, Arcadic.Error.t() | Arcadic.TransportError.t()}

Callbacks

begin(t, opts)

(optional)
@callback begin(Arcadic.Conn.t(), opts :: keyword()) ::
  {:ok, String.t()} | {:error, Arcadic.Error.t() | Arcadic.TransportError.t()}

Begin a session transaction; returns the session id.

commit(t)

(optional)
@callback commit(Arcadic.Conn.t()) ::
  :ok | {:error, Arcadic.Error.t() | Arcadic.TransportError.t()}

Commit the session carried by conn.session_id.

database_exists?(t, name)

(optional)
@callback database_exists?(Arcadic.Conn.t(), name :: String.t()) ::
  {:ok, boolean()} | {:error, Arcadic.Error.t() | Arcadic.TransportError.t()}

Whether a database exists.

execute(t, mode, request, opts)

@callback execute(Arcadic.Conn.t(), mode :: :read | :write, request(), opts :: keyword()) ::
  result()

Run a read (:read → idempotent endpoint) or write (:write) statement.

execute_async(t, request, opts)

(optional)
@callback execute_async(Arcadic.Conn.t(), request(), opts :: keyword()) ::
  :ok | {:error, Arcadic.Error.t() | Arcadic.TransportError.t()}

Fire-and-forget write (server enqueues, does not await). Optional — HTTP implements it.

list_databases(t)

(optional)
@callback list_databases(Arcadic.Conn.t()) ::
  {:ok, [String.t()]} | {:error, Arcadic.Error.t() | Arcadic.TransportError.t()}

List all database names (GET /api/v1/databases).

query_stream(t, request, opts)

(optional)
@callback query_stream(Arcadic.Conn.t(), request(), opts :: keyword()) ::
  {:ok, Enumerable.t()}
  | {:error, Arcadic.Error.t() | Arcadic.TransportError.t()}

Lazily stream a large read result as raw row maps (Bolt-only). Optional — HTTP has no cursor contract.

ready?(t)

(optional)
@callback ready?(Arcadic.Conn.t()) ::
  {:ok, boolean()} | {:error, Arcadic.TransportError.t()}

Server readiness.

rollback(t)

(optional)
@callback rollback(Arcadic.Conn.t()) ::
  :ok | {:error, Arcadic.Error.t() | Arcadic.TransportError.t()}

Roll back the session carried by conn.session_id.

server_command(t, command)

(optional)
@callback server_command(Arcadic.Conn.t(), command :: String.t()) ::
  {:ok, map()} | {:error, Arcadic.Error.t() | Arcadic.TransportError.t()}

Run a server-level admin command (create/drop database).

transaction(t, function, opts)

(optional)
@callback transaction(Arcadic.Conn.t(), (Arcadic.Conn.t() -> result), opts :: keyword()) ::
  {:ok, result} | {:error, term()}
when result: var

Native fun-based transaction (for transports whose sessions are not detachable, e.g. Bolt). Optional.