# `AncestryEx.Integrity`
[🔗](https://github.com/rocket4ce/ancestry_ex/blob/v0.1.0/lib/ancestry_ex/integrity.ex#L11)

Maintenance functions: integrity checks and repairs, building the ancestry
column from an adjacency list (`parent_id`), and rebuilding caches.

They operate on the whole table and are meant for migrations, console
sessions or periodic jobs. All of them accept a `:prefix` option.

# `issue`

```elixir
@type issue() ::
  {:invalid_ancestry, id :: term(), ancestry :: term()}
  | {:cyclic_ancestry, id :: term()}
  | {:missing_ancestor, id :: term(), ancestor_id :: term()}
  | {:conflicting_ancestry, id :: term(), parent_id :: term()}
```

# `build_ancestry_from_parent_ids`

```elixir
@spec build_ancestry_from_parent_ids(Ecto.Repo.t(), module(), keyword()) ::
  {:ok, non_neg_integer()}
```

Fills the ancestry column (and the depth and counter caches) from an
adjacency list column, with a single recursive query.

Useful to migrate a table that used a `parent_id` column. Nodes whose
parent does not exist, or that are part of a cycle, are left untouched.

## Options

  * `:parent_column` - the column holding the parent id, `:parent_id` by default.
  * `:prefix` - the schema prefix.

Returns `{:ok, number_of_updated_nodes}`.

# `check`

```elixir
@spec check(Ecto.Repo.t(), module(), keyword()) :: :ok | {:error, [issue()]}
```

Checks the ancestry of every node of `schema`.

Returns `:ok` or `{:error, issues}` where each issue is one of:

  * `{:invalid_ancestry, id, ancestry}` - the value is not well formed,
  * `{:cyclic_ancestry, id}` - the node appears in its own ancestry,
  * `{:missing_ancestor, id, ancestor_id}` - an ancestor does not exist,
  * `{:conflicting_ancestry, id, parent_id}` - the ancestry of the node does
    not extend the ancestry of its parent.

# `check!`

```elixir
@spec check!(Ecto.Repo.t(), module(), keyword()) :: :ok
```

Like `check/3` but raises `AncestryEx.IntegrityError`.

# `rebuild_counter_cache`

```elixir
@spec rebuild_counter_cache(Ecto.Repo.t(), module(), keyword()) :: :ok
```

Recomputes the counter cache column by counting the children of every node.
Does nothing unless the schema uses `:counter_cache`.

# `rebuild_depth_cache`

```elixir
@spec rebuild_depth_cache(Ecto.Repo.t(), module(), keyword()) :: :ok
```

Recomputes the depth cache column from the ancestry column.
Does nothing unless the schema uses `cache_depth: true`.

# `restore`

```elixir
@spec restore(Ecto.Repo.t(), module(), keyword()) :: {:ok, non_neg_integer()}
```

Repairs the ancestry column of `schema`.

Every node is attached to the nearest of its ancestors that still exists
(or becomes a root), cycles are broken by turning a node of the cycle into a
root, and the ancestry of every node is rebuilt from those parents. Depth and
counter caches are rebuilt as well.

Returns `{:ok, number_of_updated_nodes}`.

---

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