# `Selecto.DB.Adapter`

Behaviour contract for Selecto database adapters.

Adapter modules are responsible for:

- establishing a connection handle from adapter-specific options,
- executing SQL with bound params,
- providing adapter placeholder strategy,
- quoting identifiers when needed by adapter-specific tooling, and
- declaring coarse feature support.

Streaming contract:

- `supports?(:stream)` should return `true` only when `stream/4` is
  implemented and can produce rows for the given connection context.
- `stream/4` is optional; adapters that do not support streaming should omit
  it and return `false` for `supports?(:stream)`.

# `connection`

```elixir
@type connection() :: term()
```

# `connection_options`

```elixir
@type connection_options() :: keyword() | map() | term()
```

# `execute_options`

```elixir
@type execute_options() :: keyword()
```

# `introspection_options`

```elixir
@type introspection_options() :: keyword()
```

# `params`

```elixir
@type params() :: [term()]
```

# `query`

```elixir
@type query() :: String.t() | iodata()
```

# `result`

```elixir
@type result() :: %{rows: list(), columns: [String.t()]}
```

# `schema_metadata`

```elixir
@type schema_metadata() :: map()
```

# `server_version_result`

```elixir
@type server_version_result() :: {:ok, pos_integer()} | {:error, term()}
```

# `stream_result`

```elixir
@type stream_result() ::
  {:ok, Enumerable.t()} | {:ok, Enumerable.t(), [String.t()]} | {:error, term()}
```

# `connect`

```elixir
@callback connect(connection_options()) :: {:ok, connection()} | {:error, term()}
```

# `connection_info`
*optional* 

```elixir
@callback connection_info(connection()) :: map()
```

# `execute`

```elixir
@callback execute(connection(), query(), params(), execute_options()) ::
  {:ok, result()} | {:error, term()}
```

# `execute_pool`
*optional* 

```elixir
@callback execute_pool(term(), query(), params(), execute_options()) ::
  {:ok, term()} | {:error, term()}
```

# `execute_raw`
*optional* 

```elixir
@callback execute_raw(connection(), query(), params()) ::
  {:ok, result()} | {:error, term()}
```

# `execute_repo_fallback`
*optional* 

```elixir
@callback execute_repo_fallback(module(), query(), params()) ::
  {:ok, result()} | {:error, term()}
```

# `format_datetime`
*optional* 

```elixir
@callback format_datetime(iodata(), String.t()) :: iodata()
```

# `introspect_table`
*optional* 

```elixir
@callback introspect_table(connection(), String.t(), introspection_options()) ::
  {:ok, schema_metadata()} | {:error, term()}
```

# `list_relations`
*optional* 

```elixir
@callback list_relations(connection(), introspection_options()) ::
  {:ok, [map()]} | {:error, term()}
```

# `list_tables`
*optional* 

```elixir
@callback list_tables(connection(), introspection_options()) ::
  {:ok, [String.t()]} | {:error, term()}
```

# `name`

```elixir
@callback name() :: atom()
```

# `placeholder`

```elixir
@callback placeholder(pos_integer()) :: iodata()
```

# `quote_identifier`

```elixir
@callback quote_identifier(String.t()) :: String.t()
```

# `refresh_materialized_view`
*optional* 

```elixir
@callback refresh_materialized_view(connection(), String.t(), keyword()) ::
  {:ok, term()} | {:error, term()}
```

# `rollup_literal_order`
*optional* 

```elixir
@callback rollup_literal_order(pos_integer()) :: iodata() | String.t()
```

# `rollup_sort_fix`
*optional* 

```elixir
@callback rollup_sort_fix(connection()) :: boolean()
```

# `rollup_sql`
*optional* 

```elixir
@callback rollup_sql(iodata()) :: iodata()
```

# `server_version_major`
*optional* 

```elixir
@callback server_version_major(connection()) :: server_version_result()
```

# `start_pool`
*optional* 

```elixir
@callback start_pool(keyword(), keyword(), atom()) :: {:ok, term()} | {:error, term()}
```

# `stream`
*optional* 

```elixir
@callback stream(connection(), query(), params(), execute_options()) :: stream_result()
```

# `supports?`

```elixir
@callback supports?(atom()) :: boolean()
```

# `transaction`
*optional* 

```elixir
@callback transaction(term(), (term() -&gt; term()), keyword()) ::
  {:ok, term()} | {:error, term()}
```

# `validate_connection`
*optional* 

```elixir
@callback validate_connection(connection()) :: :ok | {:error, term()}
```

# `with_connection`
*optional* 

```elixir
@callback with_connection(term(), (term() -&gt; term())) :: {:ok, term()} | {:error, term()}
```

---

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