# `Gno.EffectiveChangeset`
[🔗](https://github.com/rdf-elixir/gno/blob/v0.1.0/lib/gno/changeset/effective_changeset.ex#L1)

A changeset containing only the minimal changes needed to achieve the desired state.

Unlike `Gno.Changeset`, an effective changeset is computed by querying the
current repository state. Statements that already exist are removed from
`:add`/`:update`/`:replace`, and statements that don't exist are removed
from `:remove`.

## The `:overwrite` Field

When `:update` or `:replace` actions take effect, existing statements are
implicitly removed. The `:overwrite` field makes these removals explicit:

- `:update` overwrites at **property level**: existing values for the same
  subject+predicate combinations are captured as overwrites
- `:replace` overwrites at **subject level**: all existing statements about
  the same subjects are captured as overwrites

This tracking enables reliable inversion via `invert/1` - without knowing
what was overwritten, the original state cannot be reconstructed.

# `t`

```elixir
@type t() :: %Gno.EffectiveChangeset{
  add: RDF.Graph.t() | nil,
  overwrite: RDF.Graph.t() | nil,
  remove: RDF.Graph.t() | nil,
  replace: RDF.Graph.t() | nil,
  update: RDF.Graph.t() | nil
}
```

# `deletes`

Returns a combined graph of all statements that will be deleted by the changeset.

# `empty`

```elixir
@spec empty() :: t()
```

Creates the empty changeset.

# `empty?`

Returns if the given changeset is empty.

# `extract`

Extracts a `Gno.EffectiveChangeset` from the given keywords and returns it with the remaining unprocessed keywords.

# `from_rdf`

Deserializes an effective changeset from an `RDF.Dataset`.

# `inserts`

Returns a combined graph of all statements that will be inserted by the changeset.

# `invert`

Inverts the changeset.

# `limit`

Limits the changeset to the given scope.

The scope can be one of `:dataset`, or `:resource`.
For `:resource` the scope can be given as a list of resources.

# `merge`

Merge the changes of a list of `Gno.EffectiveChangeset`s into one.

> #### Warning {: .warning}
>
> This function can be used to collapse the changes of multiple consecutive
> `EffectiveChangeset`s from a changeset sequence into one and relies on the fact that these
> consist of complete effective changes incl. overwrites, which might lead to surprising
> results and limits its general applicability. E.g. a single merged `replace` does not
> remove the statements with only matching subjects from the other actions, but only
> the fully matching statements, since we rely on the fact that a complete `EffectiveChangeset`
> includes also the `overwrite`s of these statements, leading to the removals of
> these statements during the merge.

# `merge`

Merge the changes of two `Gno.EffectiveChangeset`s into one.

> #### Warning {: .warning}
>
> This function can be used to collapse the changes of multiple consecutive
> `EffectiveChangeset`s from a changeset sequence into one and relies on the fact that these
> consist of complete effective changes incl. overwrites, which might lead to surprising
> results and limits its general applicability. E.g. a single merged `replace` does not
> remove the statements with only matching subjects from the other actions, but only
> the fully matching statements, since we rely on the fact that a complete `EffectiveChangeset`
> includes also the `overwrite`s of these statements, leading to the removals of
> these statements during the merge.

# `new`

```elixir
@spec new(Gno.Changeset.Action.changes(), opts :: keyword()) ::
  {:ok, t()} | {:error, any()}
```

Creates a new valid changeset.

# `new!`

```elixir
@spec new!(Gno.Changeset.Action.changes(), opts :: keyword()) :: t()
```

Creates a new valid changeset.

As opposed to `new/1` this function fails in error cases.

# `to_rdf`

Serializes the effective changeset to an `RDF.Dataset`.

# `validate`

Validates the given changeset structure.

If valid, the given structure is returned unchanged in an `:ok` tuple.
Otherwise, an `:error` tuple is returned.

---

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