# `BoxTurtle.Schema.Query.API`
[🔗](https://github.com/twajjo/box_turtle/blob/v0.1.0/lib/schema/query/api.ex#L1)

Read operations generated by `use BoxTurtle.Schema.Query`.

Functions come in pairs: the plain form returns `{:ok, result}` / `{:error, reason}`, the `!` form returns the
result directly (`nil` when `get!/2` finds nothing).

## Call-time options

  * `:filters` - keyword list of filters, see `BoxTurtle.Schema.Filters`
  * `:sort` - sort specification, see `BoxTurtle.Schema.Sort`
  * `:page` - page number or `[number: n, size: s]`, see `BoxTurtle.Schema.Pagination`
  * `:preloads` - associations to preload, nested to any depth (`[:author, comments: :user]`). They are
    `LEFT JOIN`ed and loaded in the same query, see `BoxTurtle.Schema.Query.Helpers.preloads/3`.
    Ignored by aggregates
  * `:distinct` - columns for `DISTINCT ON` (PostgreSQL only); a count uses the first one as
    `COUNT(DISTINCT column)`, which works on every database
  * `:group_by` - columns to group by; `count` then returns a list of maps
  * `:aggregate` - `:count` (used internally by `count/1`)
  * `:ignore_defaults` - when true, the module's default sort, preloads and distinct are not applied
  * `:query_opts` - options passed to `c:Ecto.Repo.all/2` by `list/1`

Any `use`-time setting (`:repo`, `:schema`, `:default_sort`, ...) can also be overridden per call; see
`BoxTurtle.Schema.Query.Options.API`.

## Extension functions

The `*_by` callbacks are optional. They are generated with `BoxTurtle.Schema.Query.extend/2` and
`BoxTurtle.Schema.Query.delegate/1`, which scope a query by a pattern (e.g. "all posts of this `%Author{}`").

# `opts`

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

# `schema`

```elixir
@type schema() :: Ecto.Schema.t()
```

# `count`

```elixir
@callback count() :: {:ok, integer() | [map()]}
```

Counts rows, or rows per group when `:group_by` is given.

# `count`

```elixir
@callback count(opts()) :: {:ok, integer() | [map()]}
```

# `count!`

```elixir
@callback count!() :: integer() | [map()]
```

# `count!`

```elixir
@callback count!(opts()) :: integer() | [map()]
```

# `count_by`
*optional* 

```elixir
@callback count_by(pattern :: term()) :: {:ok, integer() | [map()]} | {:error, term()}
```

Counts rows scoped by a pattern. A `nil` pattern counts everything.

# `count_by`
*optional* 

```elixir
@callback count_by(pattern :: term(), opts()) ::
  {:ok, integer() | [map()]} | {:error, term()}
```

# `count_by!`
*optional* 

```elixir
@callback count_by!(pattern :: term()) :: integer() | [map()]
```

# `count_by!`
*optional* 

```elixir
@callback count_by!(pattern :: term(), opts()) :: integer() | [map()]
```

# `get`

```elixir
@callback get(key :: term()) :: {:ok, schema()} | {:error, :not_found}
```

Fetches a row by primary key (or by a map of key columns). `{:error, :not_found}` when absent.

# `get`

```elixir
@callback get(key :: term(), opts()) :: {:ok, schema()} | {:error, :not_found}
```

# `get!`

```elixir
@callback get!(key :: term()) :: schema() | nil
```

# `get!`

```elixir
@callback get!(key :: term(), opts()) :: schema() | nil
```

# `get_by`
*optional* 

```elixir
@callback get_by(pattern :: term()) :: {:ok, schema()} | {:error, term()}
```

Fetches the row identified by a pattern.

# `get_by`
*optional* 

```elixir
@callback get_by(pattern :: term(), opts()) :: {:ok, schema()} | {:error, term()}
```

# `get_by!`
*optional* 

```elixir
@callback get_by!(pattern :: term()) :: schema() | nil
```

# `get_by!`
*optional* 

```elixir
@callback get_by!(pattern :: term(), opts()) :: schema() | nil
```

# `list`

```elixir
@callback list() :: {:ok, [schema()]}
```

Lists rows.

# `list`

```elixir
@callback list(opts()) :: {:ok, [schema()]}
```

# `list!`

```elixir
@callback list!() :: [schema()]
```

# `list!`

```elixir
@callback list!(opts()) :: [schema()]
```

# `list_by`
*optional* 

```elixir
@callback list_by(pattern :: term()) :: {:ok, [schema()]} | {:error, term()}
```

Lists rows scoped by a pattern. A `nil` pattern lists everything.

# `list_by`
*optional* 

```elixir
@callback list_by(pattern :: term(), opts()) :: {:ok, [schema()]} | {:error, term()}
```

# `list_by!`
*optional* 

```elixir
@callback list_by!(pattern :: term()) :: [schema()]
```

# `list_by!`
*optional* 

```elixir
@callback list_by!(pattern :: term(), opts()) :: [schema()]
```

# `pipe_query!`

```elixir
@callback pipe_query!(Ecto.Queryable.t()) :: Ecto.Queryable.t()
```

Applies the options (sort, filters, paging, preloads or aggregation) to an existing queryable.

# `pipe_query!`

```elixir
@callback pipe_query!(Ecto.Queryable.t(), opts()) :: Ecto.Queryable.t()
```

# `query!`

```elixir
@callback query!() :: Ecto.Queryable.t()
```

Builds a query on the schema from the options, without running it.

# `query!`

```elixir
@callback query!(opts()) :: Ecto.Queryable.t()
```

# `query_by!`
*optional* 

```elixir
@callback query_by!(pattern :: term()) :: Ecto.Queryable.t()
```

Builds a query scoped by a pattern.

# `query_by!`
*optional* 

```elixir
@callback query_by!(pattern :: term(), opts()) :: Ecto.Queryable.t()
```

---

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