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.
Summary
Functions
Fills the ancestry column (and the depth and counter caches) from an adjacency list column, with a single recursive query.
Checks the ancestry of every node of schema.
Like check/3 but raises AncestryEx.IntegrityError.
Recomputes the counter cache column by counting the children of every node.
Does nothing unless the schema uses :counter_cache.
Recomputes the depth cache column from the ancestry column.
Does nothing unless the schema uses cache_depth: true.
Repairs the ancestry column of schema.
Types
Functions
@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_idby default.:prefix- the schema prefix.
Returns {:ok, number_of_updated_nodes}.
@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.
@spec check!(Ecto.Repo.t(), module(), keyword()) :: :ok
Like check/3 but raises AncestryEx.IntegrityError.
@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.
@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.
@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}.