# `Masu.Source.Ecto`
[🔗](https://github.com/hattoriai/masu/blob/v0.1.0/lib/masu/source/ecto.ex#L2)

The source of a grid given an Ecto query or schema and a repo:
`<.data_grid source={from(o in Order, where: o.shop_id == ^shop.id)} repo={Repo}>`.

The database does the work. A sort is an `ORDER BY`, a filter and the
search a `WHERE`, the count a `count(*)` of the query, and each block
the browser asks for one `LIMIT` and `OFFSET`. The LiveView never holds
more rows than the screen shows.

The query may already have its own `where`, `join` and `preload`: the
grid's filters are added to them. The grid's order replaces the
query's while the person sorts, and the query's order is used when
they do not. After the grid's order comes the schema's primary key, so
that rows of equal values do not move from one block to the next.

A column sorts and filters in the database when it names a field of
the query's first source (`field={:total}`). A column with a `value`
function is shown, but does not sort or filter.

The text filters and the search compare without case with
`lower(field) LIKE ...`, which PostgreSQL, MySQL and SQLite all run.
An index on `lower(field)` makes them fast on a large table.

## A tree

With the grid's `tree` (a field that holds the parent's id), the rows
are a tree (`Masu.Tree`). The source keeps the ids of the rows that
show, not the rows: the roots, in the grid's order, and the children
of each row the person opens, read when it opens; each block of rows
is then read by its ids. A filter or a search reads the ids of the
rows that match and climbs to their ancestors, a level per query. The
schema needs one primary key.

## Options

  * `:repo` (required) - the repo that runs the queries.
  * `:repo_opts` - options for each call to the repo, such as
    `prefix:` for a tenant's schema.

---

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