kura_changeset (kura v1.19.2)

View Source

Changesets for casting external data, validating fields, and declaring constraints.

A changeset tracks changes against existing data, accumulates errors, and declares database constraints for friendly error handling on insert/update.

CS = kura_changeset:cast(my_user, #{}, Params, [name, email]),
CS1 = kura_changeset:validate_required(CS, [name, email]),
CS2 = kura_changeset:validate_format(CS1, email, <<"@">>),
CS3 = kura_changeset:unique_constraint(CS2, email).

Summary

Functions

Add an error to the changeset for Field.

Apply changes if valid, returning {ok, Map} or {error, Changeset} with the action set.

Merge changes into data, returning the resulting map (does not validate).

Create a changeset by casting Params against type definitions, filtering to Allowed fields.

Cast nested association parameters into child changesets.

Cast nested association parameters with options. Opts: with — custom changeset function.

Cast nested embedded schema parameters into parent changes.

Cast nested embedded schema parameters with options. Opts: with — custom changeset function.

Declare a check constraint with the given Constraint name mapped to Field.

Declare a foreign key constraint on Field.

Get a change value, or undefined if the field was not changed.

Get a change value, or Default if the field was not changed.

Get the field value from changes (preferred) or data.

Enable optimistic locking on Field, incrementing it on each update.

Register a callback to run just before repo operations (insert/update).

Put pre-built changesets or raw maps directly as association changes.

Put a change value directly, bypassing casting.

Transform errors via a callback, returning #{field => [transformed_messages]}.

Declare a unique constraint on Field for friendly DB error mapping.

Validate Field with a custom function returning ok or {error, Message}.

Validate that Field has a matching confirmation field in params.

Validate confirmation with options. Opts: #{message => binary()}.

Validate that Field value is NOT in the given list of DisallowedValues.

Validate that Field matches the regex Pattern.

Validate that Field value is in the given list of Values.

Validate length of Field. Opts: {min, N}, {max, N}, {is, N}.

Validate numeric Field. Opts: {greater_than, N}, {less_than, N}, etc.

Validate that all Fields are present and non-blank.

Validate that all values in an array Field are within AllowedValues.

Functions

add_error/3

-spec add_error(#kura_changeset{valid :: boolean(),
                                schema :: module() | undefined,
                                data :: map(),
                                params :: map(),
                                changes :: map(),
                                errors :: [{atom(), binary()}],
                                types :: #{atom() => kura_types:kura_type()},
                                required :: [atom()],
                                action :: atom() | undefined,
                                constraints ::
                                    [#kura_constraint{type :: unique | foreign_key | check | exclusion,
                                                      constraint :: binary(),
                                                      field :: atom(),
                                                      message :: binary()}],
                                assoc_changes :: #{atom() => #kura_changeset{} | [#kura_changeset{}]},
                                prepare :: [fun((#kura_changeset{}) -> #kura_changeset{})],
                                optimistic_lock :: atom() | undefined},
                atom(),
                binary()) ->
                   #kura_changeset{valid :: boolean(),
                                   schema :: module() | undefined,
                                   data :: map(),
                                   params :: map(),
                                   changes :: map(),
                                   errors :: [{atom(), binary()}],
                                   types :: #{atom() => kura_types:kura_type()},
                                   required :: [atom()],
                                   action :: atom() | undefined,
                                   constraints ::
                                       [#kura_constraint{type ::
                                                             unique | foreign_key | check | exclusion,
                                                         constraint :: binary(),
                                                         field :: atom(),
                                                         message :: binary()}],
                                   assoc_changes :: #{atom() => #kura_changeset{} | [#kura_changeset{}]},
                                   prepare :: [fun((#kura_changeset{}) -> #kura_changeset{})],
                                   optimistic_lock :: atom() | undefined}.

Add an error to the changeset for Field.

apply_action/2

-spec apply_action(#kura_changeset{valid :: boolean(),
                                   schema :: module() | undefined,
                                   data :: map(),
                                   params :: map(),
                                   changes :: map(),
                                   errors :: [{atom(), binary()}],
                                   types :: #{atom() => kura_types:kura_type()},
                                   required :: [atom()],
                                   action :: atom() | undefined,
                                   constraints ::
                                       [#kura_constraint{type ::
                                                             unique | foreign_key | check | exclusion,
                                                         constraint :: binary(),
                                                         field :: atom(),
                                                         message :: binary()}],
                                   assoc_changes :: #{atom() => #kura_changeset{} | [#kura_changeset{}]},
                                   prepare :: [fun((#kura_changeset{}) -> #kura_changeset{})],
                                   optimistic_lock :: atom() | undefined},
                   atom()) ->
                      {ok, map()} |
                      {error,
                       #kura_changeset{valid :: boolean(),
                                       schema :: module() | undefined,
                                       data :: map(),
                                       params :: map(),
                                       changes :: map(),
                                       errors :: [{atom(), binary()}],
                                       types :: #{atom() => kura_types:kura_type()},
                                       required :: [atom()],
                                       action :: atom() | undefined,
                                       constraints ::
                                           [#kura_constraint{type ::
                                                                 unique | foreign_key | check |
                                                                 exclusion,
                                                             constraint :: binary(),
                                                             field :: atom(),
                                                             message :: binary()}],
                                       assoc_changes ::
                                           #{atom() => #kura_changeset{} | [#kura_changeset{}]},
                                       prepare :: [fun((#kura_changeset{}) -> #kura_changeset{})],
                                       optimistic_lock :: atom() | undefined}}.

Apply changes if valid, returning {ok, Map} or {error, Changeset} with the action set.

apply_changes/1

-spec apply_changes(#kura_changeset{valid :: boolean(),
                                    schema :: module() | undefined,
                                    data :: map(),
                                    params :: map(),
                                    changes :: map(),
                                    errors :: [{atom(), binary()}],
                                    types :: #{atom() => kura_types:kura_type()},
                                    required :: [atom()],
                                    action :: atom() | undefined,
                                    constraints ::
                                        [#kura_constraint{type ::
                                                              unique | foreign_key | check | exclusion,
                                                          constraint :: binary(),
                                                          field :: atom(),
                                                          message :: binary()}],
                                    assoc_changes ::
                                        #{atom() => #kura_changeset{} | [#kura_changeset{}]},
                                    prepare :: [fun((#kura_changeset{}) -> #kura_changeset{})],
                                    optimistic_lock :: atom() | undefined}) ->
                       map().

Merge changes into data, returning the resulting map (does not validate).

cast/4

-spec cast(module() | #{atom() => kura_types:kura_type()}, map(), map(), [atom()]) ->
              #kura_changeset{valid :: boolean(),
                              schema :: module() | undefined,
                              data :: map(),
                              params :: map(),
                              changes :: map(),
                              errors :: [{atom(), binary()}],
                              types :: #{atom() => kura_types:kura_type()},
                              required :: [atom()],
                              action :: atom() | undefined,
                              constraints ::
                                  [#kura_constraint{type :: unique | foreign_key | check | exclusion,
                                                    constraint :: binary(),
                                                    field :: atom(),
                                                    message :: binary()}],
                              assoc_changes :: #{atom() => #kura_changeset{} | [#kura_changeset{}]},
                              prepare :: [fun((#kura_changeset{}) -> #kura_changeset{})],
                              optimistic_lock :: atom() | undefined}.

Create a changeset by casting Params against type definitions, filtering to Allowed fields.

The first argument can be either a schema module (atom) or a types map for schemaless changesets:

%% Schema-based
CS = kura_changeset:cast(my_user, #{}, Params, [name, email]).

%% Schemaless
Types = #{email => string, password => string},
CS = kura_changeset:cast(Types, #{}, Params, [email, password]).

Schemaless changesets are validation-only — they cannot be persisted via kura_repo.

cast_assoc(CS, AssocName)

-spec cast_assoc(#kura_changeset{valid :: boolean(),
                                 schema :: module() | undefined,
                                 data :: map(),
                                 params :: map(),
                                 changes :: map(),
                                 errors :: [{atom(), binary()}],
                                 types :: #{atom() => kura_types:kura_type()},
                                 required :: [atom()],
                                 action :: atom() | undefined,
                                 constraints ::
                                     [#kura_constraint{type :: unique | foreign_key | check | exclusion,
                                                       constraint :: binary(),
                                                       field :: atom(),
                                                       message :: binary()}],
                                 assoc_changes :: #{atom() => #kura_changeset{} | [#kura_changeset{}]},
                                 prepare :: [fun((#kura_changeset{}) -> #kura_changeset{})],
                                 optimistic_lock :: atom() | undefined},
                 atom()) ->
                    #kura_changeset{valid :: boolean(),
                                    schema :: module() | undefined,
                                    data :: map(),
                                    params :: map(),
                                    changes :: map(),
                                    errors :: [{atom(), binary()}],
                                    types :: #{atom() => kura_types:kura_type()},
                                    required :: [atom()],
                                    action :: atom() | undefined,
                                    constraints ::
                                        [#kura_constraint{type ::
                                                              unique | foreign_key | check | exclusion,
                                                          constraint :: binary(),
                                                          field :: atom(),
                                                          message :: binary()}],
                                    assoc_changes ::
                                        #{atom() => #kura_changeset{} | [#kura_changeset{}]},
                                    prepare :: [fun((#kura_changeset{}) -> #kura_changeset{})],
                                    optimistic_lock :: atom() | undefined}.

Cast nested association parameters into child changesets.

cast_assoc(CS, AssocName, Opts)

-spec cast_assoc(#kura_changeset{valid :: boolean(),
                                 schema :: module() | undefined,
                                 data :: map(),
                                 params :: map(),
                                 changes :: map(),
                                 errors :: [{atom(), binary()}],
                                 types :: #{atom() => kura_types:kura_type()},
                                 required :: [atom()],
                                 action :: atom() | undefined,
                                 constraints ::
                                     [#kura_constraint{type :: unique | foreign_key | check | exclusion,
                                                       constraint :: binary(),
                                                       field :: atom(),
                                                       message :: binary()}],
                                 assoc_changes :: #{atom() => #kura_changeset{} | [#kura_changeset{}]},
                                 prepare :: [fun((#kura_changeset{}) -> #kura_changeset{})],
                                 optimistic_lock :: atom() | undefined},
                 atom(),
                 map()) ->
                    #kura_changeset{valid :: boolean(),
                                    schema :: module() | undefined,
                                    data :: map(),
                                    params :: map(),
                                    changes :: map(),
                                    errors :: [{atom(), binary()}],
                                    types :: #{atom() => kura_types:kura_type()},
                                    required :: [atom()],
                                    action :: atom() | undefined,
                                    constraints ::
                                        [#kura_constraint{type ::
                                                              unique | foreign_key | check | exclusion,
                                                          constraint :: binary(),
                                                          field :: atom(),
                                                          message :: binary()}],
                                    assoc_changes ::
                                        #{atom() => #kura_changeset{} | [#kura_changeset{}]},
                                    prepare :: [fun((#kura_changeset{}) -> #kura_changeset{})],
                                    optimistic_lock :: atom() | undefined}.

Cast nested association parameters with options. Opts: with — custom changeset function.

cast_embed(CS, EmbedName)

-spec cast_embed(#kura_changeset{valid :: boolean(),
                                 schema :: module() | undefined,
                                 data :: map(),
                                 params :: map(),
                                 changes :: map(),
                                 errors :: [{atom(), binary()}],
                                 types :: #{atom() => kura_types:kura_type()},
                                 required :: [atom()],
                                 action :: atom() | undefined,
                                 constraints ::
                                     [#kura_constraint{type :: unique | foreign_key | check | exclusion,
                                                       constraint :: binary(),
                                                       field :: atom(),
                                                       message :: binary()}],
                                 assoc_changes :: #{atom() => #kura_changeset{} | [#kura_changeset{}]},
                                 prepare :: [fun((#kura_changeset{}) -> #kura_changeset{})],
                                 optimistic_lock :: atom() | undefined},
                 atom()) ->
                    #kura_changeset{valid :: boolean(),
                                    schema :: module() | undefined,
                                    data :: map(),
                                    params :: map(),
                                    changes :: map(),
                                    errors :: [{atom(), binary()}],
                                    types :: #{atom() => kura_types:kura_type()},
                                    required :: [atom()],
                                    action :: atom() | undefined,
                                    constraints ::
                                        [#kura_constraint{type ::
                                                              unique | foreign_key | check | exclusion,
                                                          constraint :: binary(),
                                                          field :: atom(),
                                                          message :: binary()}],
                                    assoc_changes ::
                                        #{atom() => #kura_changeset{} | [#kura_changeset{}]},
                                    prepare :: [fun((#kura_changeset{}) -> #kura_changeset{})],
                                    optimistic_lock :: atom() | undefined}.

Cast nested embedded schema parameters into parent changes.

cast_embed(CS, EmbedName, Opts)

-spec cast_embed(#kura_changeset{valid :: boolean(),
                                 schema :: module() | undefined,
                                 data :: map(),
                                 params :: map(),
                                 changes :: map(),
                                 errors :: [{atom(), binary()}],
                                 types :: #{atom() => kura_types:kura_type()},
                                 required :: [atom()],
                                 action :: atom() | undefined,
                                 constraints ::
                                     [#kura_constraint{type :: unique | foreign_key | check | exclusion,
                                                       constraint :: binary(),
                                                       field :: atom(),
                                                       message :: binary()}],
                                 assoc_changes :: #{atom() => #kura_changeset{} | [#kura_changeset{}]},
                                 prepare :: [fun((#kura_changeset{}) -> #kura_changeset{})],
                                 optimistic_lock :: atom() | undefined},
                 atom(),
                 map()) ->
                    #kura_changeset{valid :: boolean(),
                                    schema :: module() | undefined,
                                    data :: map(),
                                    params :: map(),
                                    changes :: map(),
                                    errors :: [{atom(), binary()}],
                                    types :: #{atom() => kura_types:kura_type()},
                                    required :: [atom()],
                                    action :: atom() | undefined,
                                    constraints ::
                                        [#kura_constraint{type ::
                                                              unique | foreign_key | check | exclusion,
                                                          constraint :: binary(),
                                                          field :: atom(),
                                                          message :: binary()}],
                                    assoc_changes ::
                                        #{atom() => #kura_changeset{} | [#kura_changeset{}]},
                                    prepare :: [fun((#kura_changeset{}) -> #kura_changeset{})],
                                    optimistic_lock :: atom() | undefined}.

Cast nested embedded schema parameters with options. Opts: with — custom changeset function.

check_constraint(CS, Constraint, Field)

-spec check_constraint(#kura_changeset{valid :: boolean(),
                                       schema :: module() | undefined,
                                       data :: map(),
                                       params :: map(),
                                       changes :: map(),
                                       errors :: [{atom(), binary()}],
                                       types :: #{atom() => kura_types:kura_type()},
                                       required :: [atom()],
                                       action :: atom() | undefined,
                                       constraints ::
                                           [#kura_constraint{type ::
                                                                 unique | foreign_key | check |
                                                                 exclusion,
                                                             constraint :: binary(),
                                                             field :: atom(),
                                                             message :: binary()}],
                                       assoc_changes ::
                                           #{atom() => #kura_changeset{} | [#kura_changeset{}]},
                                       prepare :: [fun((#kura_changeset{}) -> #kura_changeset{})],
                                       optimistic_lock :: atom() | undefined},
                       binary(),
                       atom()) ->
                          #kura_changeset{valid :: boolean(),
                                          schema :: module() | undefined,
                                          data :: map(),
                                          params :: map(),
                                          changes :: map(),
                                          errors :: [{atom(), binary()}],
                                          types :: #{atom() => kura_types:kura_type()},
                                          required :: [atom()],
                                          action :: atom() | undefined,
                                          constraints ::
                                              [#kura_constraint{type ::
                                                                    unique | foreign_key | check |
                                                                    exclusion,
                                                                constraint :: binary(),
                                                                field :: atom(),
                                                                message :: binary()}],
                                          assoc_changes ::
                                              #{atom() => #kura_changeset{} | [#kura_changeset{}]},
                                          prepare :: [fun((#kura_changeset{}) -> #kura_changeset{})],
                                          optimistic_lock :: atom() | undefined}.

Declare a check constraint with the given Constraint name mapped to Field.

check_constraint/4

-spec check_constraint(#kura_changeset{valid :: boolean(),
                                       schema :: module() | undefined,
                                       data :: map(),
                                       params :: map(),
                                       changes :: map(),
                                       errors :: [{atom(), binary()}],
                                       types :: #{atom() => kura_types:kura_type()},
                                       required :: [atom()],
                                       action :: atom() | undefined,
                                       constraints ::
                                           [#kura_constraint{type ::
                                                                 unique | foreign_key | check |
                                                                 exclusion,
                                                             constraint :: binary(),
                                                             field :: atom(),
                                                             message :: binary()}],
                                       assoc_changes ::
                                           #{atom() => #kura_changeset{} | [#kura_changeset{}]},
                                       prepare :: [fun((#kura_changeset{}) -> #kura_changeset{})],
                                       optimistic_lock :: atom() | undefined},
                       binary(),
                       atom(),
                       map()) ->
                          #kura_changeset{valid :: boolean(),
                                          schema :: module() | undefined,
                                          data :: map(),
                                          params :: map(),
                                          changes :: map(),
                                          errors :: [{atom(), binary()}],
                                          types :: #{atom() => kura_types:kura_type()},
                                          required :: [atom()],
                                          action :: atom() | undefined,
                                          constraints ::
                                              [#kura_constraint{type ::
                                                                    unique | foreign_key | check |
                                                                    exclusion,
                                                                constraint :: binary(),
                                                                field :: atom(),
                                                                message :: binary()}],
                                          assoc_changes ::
                                              #{atom() => #kura_changeset{} | [#kura_changeset{}]},
                                          prepare :: [fun((#kura_changeset{}) -> #kura_changeset{})],
                                          optimistic_lock :: atom() | undefined}.

foreign_key_constraint(CS, Field)

-spec foreign_key_constraint(#kura_changeset{valid :: boolean(),
                                             schema :: module() | undefined,
                                             data :: map(),
                                             params :: map(),
                                             changes :: map(),
                                             errors :: [{atom(), binary()}],
                                             types :: #{atom() => kura_types:kura_type()},
                                             required :: [atom()],
                                             action :: atom() | undefined,
                                             constraints ::
                                                 [#kura_constraint{type ::
                                                                       unique | foreign_key | check |
                                                                       exclusion,
                                                                   constraint :: binary(),
                                                                   field :: atom(),
                                                                   message :: binary()}],
                                             assoc_changes ::
                                                 #{atom() => #kura_changeset{} | [#kura_changeset{}]},
                                             prepare :: [fun((#kura_changeset{}) -> #kura_changeset{})],
                                             optimistic_lock :: atom() | undefined},
                             atom()) ->
                                #kura_changeset{valid :: boolean(),
                                                schema :: module() | undefined,
                                                data :: map(),
                                                params :: map(),
                                                changes :: map(),
                                                errors :: [{atom(), binary()}],
                                                types :: #{atom() => kura_types:kura_type()},
                                                required :: [atom()],
                                                action :: atom() | undefined,
                                                constraints ::
                                                    [#kura_constraint{type ::
                                                                          unique | foreign_key | check |
                                                                          exclusion,
                                                                      constraint :: binary(),
                                                                      field :: atom(),
                                                                      message :: binary()}],
                                                assoc_changes ::
                                                    #{atom() => #kura_changeset{} | [#kura_changeset{}]},
                                                prepare ::
                                                    [fun((#kura_changeset{}) -> #kura_changeset{})],
                                                optimistic_lock :: atom() | undefined}.

Declare a foreign key constraint on Field.

foreign_key_constraint/3

-spec foreign_key_constraint(#kura_changeset{valid :: boolean(),
                                             schema :: module() | undefined,
                                             data :: map(),
                                             params :: map(),
                                             changes :: map(),
                                             errors :: [{atom(), binary()}],
                                             types :: #{atom() => kura_types:kura_type()},
                                             required :: [atom()],
                                             action :: atom() | undefined,
                                             constraints ::
                                                 [#kura_constraint{type ::
                                                                       unique | foreign_key | check |
                                                                       exclusion,
                                                                   constraint :: binary(),
                                                                   field :: atom(),
                                                                   message :: binary()}],
                                             assoc_changes ::
                                                 #{atom() => #kura_changeset{} | [#kura_changeset{}]},
                                             prepare :: [fun((#kura_changeset{}) -> #kura_changeset{})],
                                             optimistic_lock :: atom() | undefined},
                             atom(),
                             map()) ->
                                #kura_changeset{valid :: boolean(),
                                                schema :: module() | undefined,
                                                data :: map(),
                                                params :: map(),
                                                changes :: map(),
                                                errors :: [{atom(), binary()}],
                                                types :: #{atom() => kura_types:kura_type()},
                                                required :: [atom()],
                                                action :: atom() | undefined,
                                                constraints ::
                                                    [#kura_constraint{type ::
                                                                          unique | foreign_key | check |
                                                                          exclusion,
                                                                      constraint :: binary(),
                                                                      field :: atom(),
                                                                      message :: binary()}],
                                                assoc_changes ::
                                                    #{atom() => #kura_changeset{} | [#kura_changeset{}]},
                                                prepare ::
                                                    [fun((#kura_changeset{}) -> #kura_changeset{})],
                                                optimistic_lock :: atom() | undefined}.

get_change/2

-spec get_change(#kura_changeset{valid :: boolean(),
                                 schema :: module() | undefined,
                                 data :: map(),
                                 params :: map(),
                                 changes :: map(),
                                 errors :: [{atom(), binary()}],
                                 types :: #{atom() => kura_types:kura_type()},
                                 required :: [atom()],
                                 action :: atom() | undefined,
                                 constraints ::
                                     [#kura_constraint{type :: unique | foreign_key | check | exclusion,
                                                       constraint :: binary(),
                                                       field :: atom(),
                                                       message :: binary()}],
                                 assoc_changes :: #{atom() => #kura_changeset{} | [#kura_changeset{}]},
                                 prepare :: [fun((#kura_changeset{}) -> #kura_changeset{})],
                                 optimistic_lock :: atom() | undefined},
                 atom()) ->
                    term().

Get a change value, or undefined if the field was not changed.

get_change/3

-spec get_change(#kura_changeset{valid :: boolean(),
                                 schema :: module() | undefined,
                                 data :: map(),
                                 params :: map(),
                                 changes :: map(),
                                 errors :: [{atom(), binary()}],
                                 types :: #{atom() => kura_types:kura_type()},
                                 required :: [atom()],
                                 action :: atom() | undefined,
                                 constraints ::
                                     [#kura_constraint{type :: unique | foreign_key | check | exclusion,
                                                       constraint :: binary(),
                                                       field :: atom(),
                                                       message :: binary()}],
                                 assoc_changes :: #{atom() => #kura_changeset{} | [#kura_changeset{}]},
                                 prepare :: [fun((#kura_changeset{}) -> #kura_changeset{})],
                                 optimistic_lock :: atom() | undefined},
                 atom(),
                 term()) ->
                    term().

Get a change value, or Default if the field was not changed.

get_field(ChangeSet, Field)

-spec get_field(#kura_changeset{valid :: boolean(),
                                schema :: module() | undefined,
                                data :: map(),
                                params :: map(),
                                changes :: map(),
                                errors :: [{atom(), binary()}],
                                types :: #{atom() => kura_types:kura_type()},
                                required :: [atom()],
                                action :: atom() | undefined,
                                constraints ::
                                    [#kura_constraint{type :: unique | foreign_key | check | exclusion,
                                                      constraint :: binary(),
                                                      field :: atom(),
                                                      message :: binary()}],
                                assoc_changes :: #{atom() => #kura_changeset{} | [#kura_changeset{}]},
                                prepare :: [fun((#kura_changeset{}) -> #kura_changeset{})],
                                optimistic_lock :: atom() | undefined},
                atom()) ->
                   term().

Get the field value from changes (preferred) or data.

get_field/3

-spec get_field(#kura_changeset{valid :: boolean(),
                                schema :: module() | undefined,
                                data :: map(),
                                params :: map(),
                                changes :: map(),
                                errors :: [{atom(), binary()}],
                                types :: #{atom() => kura_types:kura_type()},
                                required :: [atom()],
                                action :: atom() | undefined,
                                constraints ::
                                    [#kura_constraint{type :: unique | foreign_key | check | exclusion,
                                                      constraint :: binary(),
                                                      field :: atom(),
                                                      message :: binary()}],
                                assoc_changes :: #{atom() => #kura_changeset{} | [#kura_changeset{}]},
                                prepare :: [fun((#kura_changeset{}) -> #kura_changeset{})],
                                optimistic_lock :: atom() | undefined},
                atom(),
                term()) ->
                   term().

normalize_params(Params)

optimistic_lock/2

-spec optimistic_lock(#kura_changeset{valid :: boolean(),
                                      schema :: module() | undefined,
                                      data :: map(),
                                      params :: map(),
                                      changes :: map(),
                                      errors :: [{atom(), binary()}],
                                      types :: #{atom() => kura_types:kura_type()},
                                      required :: [atom()],
                                      action :: atom() | undefined,
                                      constraints ::
                                          [#kura_constraint{type ::
                                                                unique | foreign_key | check | exclusion,
                                                            constraint :: binary(),
                                                            field :: atom(),
                                                            message :: binary()}],
                                      assoc_changes ::
                                          #{atom() => #kura_changeset{} | [#kura_changeset{}]},
                                      prepare :: [fun((#kura_changeset{}) -> #kura_changeset{})],
                                      optimistic_lock :: atom() | undefined},
                      atom()) ->
                         #kura_changeset{valid :: boolean(),
                                         schema :: module() | undefined,
                                         data :: map(),
                                         params :: map(),
                                         changes :: map(),
                                         errors :: [{atom(), binary()}],
                                         types :: #{atom() => kura_types:kura_type()},
                                         required :: [atom()],
                                         action :: atom() | undefined,
                                         constraints ::
                                             [#kura_constraint{type ::
                                                                   unique | foreign_key | check |
                                                                   exclusion,
                                                               constraint :: binary(),
                                                               field :: atom(),
                                                               message :: binary()}],
                                         assoc_changes ::
                                             #{atom() => #kura_changeset{} | [#kura_changeset{}]},
                                         prepare :: [fun((#kura_changeset{}) -> #kura_changeset{})],
                                         optimistic_lock :: atom() | undefined}.

Enable optimistic locking on Field, incrementing it on each update.

prepare_changes/2

-spec prepare_changes(#kura_changeset{valid :: boolean(),
                                      schema :: module() | undefined,
                                      data :: map(),
                                      params :: map(),
                                      changes :: map(),
                                      errors :: [{atom(), binary()}],
                                      types :: #{atom() => kura_types:kura_type()},
                                      required :: [atom()],
                                      action :: atom() | undefined,
                                      constraints ::
                                          [#kura_constraint{type ::
                                                                unique | foreign_key | check | exclusion,
                                                            constraint :: binary(),
                                                            field :: atom(),
                                                            message :: binary()}],
                                      assoc_changes ::
                                          #{atom() => #kura_changeset{} | [#kura_changeset{}]},
                                      prepare :: [fun((#kura_changeset{}) -> #kura_changeset{})],
                                      optimistic_lock :: atom() | undefined},
                      fun((#kura_changeset{valid :: boolean(),
                                           schema :: module() | undefined,
                                           data :: map(),
                                           params :: map(),
                                           changes :: map(),
                                           errors :: [{atom(), binary()}],
                                           types :: #{atom() => kura_types:kura_type()},
                                           required :: [atom()],
                                           action :: atom() | undefined,
                                           constraints ::
                                               [#kura_constraint{type ::
                                                                     unique | foreign_key | check |
                                                                     exclusion,
                                                                 constraint :: binary(),
                                                                 field :: atom(),
                                                                 message :: binary()}],
                                           assoc_changes ::
                                               #{atom() => #kura_changeset{} | [#kura_changeset{}]},
                                           prepare :: [fun((#kura_changeset{}) -> #kura_changeset{})],
                                           optimistic_lock :: atom() | undefined}) ->
                              #kura_changeset{valid :: boolean(),
                                              schema :: module() | undefined,
                                              data :: map(),
                                              params :: map(),
                                              changes :: map(),
                                              errors :: [{atom(), binary()}],
                                              types :: #{atom() => kura_types:kura_type()},
                                              required :: [atom()],
                                              action :: atom() | undefined,
                                              constraints ::
                                                  [#kura_constraint{type ::
                                                                        unique | foreign_key | check |
                                                                        exclusion,
                                                                    constraint :: binary(),
                                                                    field :: atom(),
                                                                    message :: binary()}],
                                              assoc_changes ::
                                                  #{atom() => #kura_changeset{} | [#kura_changeset{}]},
                                              prepare :: [fun((#kura_changeset{}) -> #kura_changeset{})],
                                              optimistic_lock :: atom() | undefined})) ->
                         #kura_changeset{valid :: boolean(),
                                         schema :: module() | undefined,
                                         data :: map(),
                                         params :: map(),
                                         changes :: map(),
                                         errors :: [{atom(), binary()}],
                                         types :: #{atom() => kura_types:kura_type()},
                                         required :: [atom()],
                                         action :: atom() | undefined,
                                         constraints ::
                                             [#kura_constraint{type ::
                                                                   unique | foreign_key | check |
                                                                   exclusion,
                                                               constraint :: binary(),
                                                               field :: atom(),
                                                               message :: binary()}],
                                         assoc_changes ::
                                             #{atom() => #kura_changeset{} | [#kura_changeset{}]},
                                         prepare :: [fun((#kura_changeset{}) -> #kura_changeset{})],
                                         optimistic_lock :: atom() | undefined}.

Register a callback to run just before repo operations (insert/update).

put_assoc(CS, AssocName, Value)

-spec put_assoc(#kura_changeset{valid :: boolean(),
                                schema :: module() | undefined,
                                data :: map(),
                                params :: map(),
                                changes :: map(),
                                errors :: [{atom(), binary()}],
                                types :: #{atom() => kura_types:kura_type()},
                                required :: [atom()],
                                action :: atom() | undefined,
                                constraints ::
                                    [#kura_constraint{type :: unique | foreign_key | check | exclusion,
                                                      constraint :: binary(),
                                                      field :: atom(),
                                                      message :: binary()}],
                                assoc_changes :: #{atom() => #kura_changeset{} | [#kura_changeset{}]},
                                prepare :: [fun((#kura_changeset{}) -> #kura_changeset{})],
                                optimistic_lock :: atom() | undefined},
                atom(),
                term()) ->
                   #kura_changeset{valid :: boolean(),
                                   schema :: module() | undefined,
                                   data :: map(),
                                   params :: map(),
                                   changes :: map(),
                                   errors :: [{atom(), binary()}],
                                   types :: #{atom() => kura_types:kura_type()},
                                   required :: [atom()],
                                   action :: atom() | undefined,
                                   constraints ::
                                       [#kura_constraint{type ::
                                                             unique | foreign_key | check | exclusion,
                                                         constraint :: binary(),
                                                         field :: atom(),
                                                         message :: binary()}],
                                   assoc_changes :: #{atom() => #kura_changeset{} | [#kura_changeset{}]},
                                   prepare :: [fun((#kura_changeset{}) -> #kura_changeset{})],
                                   optimistic_lock :: atom() | undefined}.

Put pre-built changesets or raw maps directly as association changes.

put_change/3

-spec put_change(#kura_changeset{valid :: boolean(),
                                 schema :: module() | undefined,
                                 data :: map(),
                                 params :: map(),
                                 changes :: map(),
                                 errors :: [{atom(), binary()}],
                                 types :: #{atom() => kura_types:kura_type()},
                                 required :: [atom()],
                                 action :: atom() | undefined,
                                 constraints ::
                                     [#kura_constraint{type :: unique | foreign_key | check | exclusion,
                                                       constraint :: binary(),
                                                       field :: atom(),
                                                       message :: binary()}],
                                 assoc_changes :: #{atom() => #kura_changeset{} | [#kura_changeset{}]},
                                 prepare :: [fun((#kura_changeset{}) -> #kura_changeset{})],
                                 optimistic_lock :: atom() | undefined},
                 atom(),
                 term()) ->
                    #kura_changeset{valid :: boolean(),
                                    schema :: module() | undefined,
                                    data :: map(),
                                    params :: map(),
                                    changes :: map(),
                                    errors :: [{atom(), binary()}],
                                    types :: #{atom() => kura_types:kura_type()},
                                    required :: [atom()],
                                    action :: atom() | undefined,
                                    constraints ::
                                        [#kura_constraint{type ::
                                                              unique | foreign_key | check | exclusion,
                                                          constraint :: binary(),
                                                          field :: atom(),
                                                          message :: binary()}],
                                    assoc_changes ::
                                        #{atom() => #kura_changeset{} | [#kura_changeset{}]},
                                    prepare :: [fun((#kura_changeset{}) -> #kura_changeset{})],
                                    optimistic_lock :: atom() | undefined}.

Put a change value directly, bypassing casting.

traverse_errors/2

-spec traverse_errors(#kura_changeset{valid :: boolean(),
                                      schema :: module() | undefined,
                                      data :: map(),
                                      params :: map(),
                                      changes :: map(),
                                      errors :: [{atom(), binary()}],
                                      types :: #{atom() => kura_types:kura_type()},
                                      required :: [atom()],
                                      action :: atom() | undefined,
                                      constraints ::
                                          [#kura_constraint{type ::
                                                                unique | foreign_key | check | exclusion,
                                                            constraint :: binary(),
                                                            field :: atom(),
                                                            message :: binary()}],
                                      assoc_changes ::
                                          #{atom() => #kura_changeset{} | [#kura_changeset{}]},
                                      prepare :: [fun((#kura_changeset{}) -> #kura_changeset{})],
                                      optimistic_lock :: atom() | undefined},
                      fun((atom(), binary()) -> term())) ->
                         map().

Transform errors via a callback, returning #{field => [transformed_messages]}.

unique_constraint(CS, Field)

-spec unique_constraint(#kura_changeset{valid :: boolean(),
                                        schema :: module() | undefined,
                                        data :: map(),
                                        params :: map(),
                                        changes :: map(),
                                        errors :: [{atom(), binary()}],
                                        types :: #{atom() => kura_types:kura_type()},
                                        required :: [atom()],
                                        action :: atom() | undefined,
                                        constraints ::
                                            [#kura_constraint{type ::
                                                                  unique | foreign_key | check |
                                                                  exclusion,
                                                              constraint :: binary(),
                                                              field :: atom(),
                                                              message :: binary()}],
                                        assoc_changes ::
                                            #{atom() => #kura_changeset{} | [#kura_changeset{}]},
                                        prepare :: [fun((#kura_changeset{}) -> #kura_changeset{})],
                                        optimistic_lock :: atom() | undefined},
                        atom()) ->
                           #kura_changeset{valid :: boolean(),
                                           schema :: module() | undefined,
                                           data :: map(),
                                           params :: map(),
                                           changes :: map(),
                                           errors :: [{atom(), binary()}],
                                           types :: #{atom() => kura_types:kura_type()},
                                           required :: [atom()],
                                           action :: atom() | undefined,
                                           constraints ::
                                               [#kura_constraint{type ::
                                                                     unique | foreign_key | check |
                                                                     exclusion,
                                                                 constraint :: binary(),
                                                                 field :: atom(),
                                                                 message :: binary()}],
                                           assoc_changes ::
                                               #{atom() => #kura_changeset{} | [#kura_changeset{}]},
                                           prepare :: [fun((#kura_changeset{}) -> #kura_changeset{})],
                                           optimistic_lock :: atom() | undefined}.

Declare a unique constraint on Field for friendly DB error mapping.

unique_constraint/3

-spec unique_constraint(#kura_changeset{valid :: boolean(),
                                        schema :: module() | undefined,
                                        data :: map(),
                                        params :: map(),
                                        changes :: map(),
                                        errors :: [{atom(), binary()}],
                                        types :: #{atom() => kura_types:kura_type()},
                                        required :: [atom()],
                                        action :: atom() | undefined,
                                        constraints ::
                                            [#kura_constraint{type ::
                                                                  unique | foreign_key | check |
                                                                  exclusion,
                                                              constraint :: binary(),
                                                              field :: atom(),
                                                              message :: binary()}],
                                        assoc_changes ::
                                            #{atom() => #kura_changeset{} | [#kura_changeset{}]},
                                        prepare :: [fun((#kura_changeset{}) -> #kura_changeset{})],
                                        optimistic_lock :: atom() | undefined},
                        atom(),
                        map()) ->
                           #kura_changeset{valid :: boolean(),
                                           schema :: module() | undefined,
                                           data :: map(),
                                           params :: map(),
                                           changes :: map(),
                                           errors :: [{atom(), binary()}],
                                           types :: #{atom() => kura_types:kura_type()},
                                           required :: [atom()],
                                           action :: atom() | undefined,
                                           constraints ::
                                               [#kura_constraint{type ::
                                                                     unique | foreign_key | check |
                                                                     exclusion,
                                                                 constraint :: binary(),
                                                                 field :: atom(),
                                                                 message :: binary()}],
                                           assoc_changes ::
                                               #{atom() => #kura_changeset{} | [#kura_changeset{}]},
                                           prepare :: [fun((#kura_changeset{}) -> #kura_changeset{})],
                                           optimistic_lock :: atom() | undefined}.

validate_change(CS, Field, Fun)

-spec validate_change(#kura_changeset{valid :: boolean(),
                                      schema :: module() | undefined,
                                      data :: map(),
                                      params :: map(),
                                      changes :: map(),
                                      errors :: [{atom(), binary()}],
                                      types :: #{atom() => kura_types:kura_type()},
                                      required :: [atom()],
                                      action :: atom() | undefined,
                                      constraints ::
                                          [#kura_constraint{type ::
                                                                unique | foreign_key | check | exclusion,
                                                            constraint :: binary(),
                                                            field :: atom(),
                                                            message :: binary()}],
                                      assoc_changes ::
                                          #{atom() => #kura_changeset{} | [#kura_changeset{}]},
                                      prepare :: [fun((#kura_changeset{}) -> #kura_changeset{})],
                                      optimistic_lock :: atom() | undefined},
                      atom(),
                      fun((term()) -> ok | {error, binary()})) ->
                         #kura_changeset{valid :: boolean(),
                                         schema :: module() | undefined,
                                         data :: map(),
                                         params :: map(),
                                         changes :: map(),
                                         errors :: [{atom(), binary()}],
                                         types :: #{atom() => kura_types:kura_type()},
                                         required :: [atom()],
                                         action :: atom() | undefined,
                                         constraints ::
                                             [#kura_constraint{type ::
                                                                   unique | foreign_key | check |
                                                                   exclusion,
                                                               constraint :: binary(),
                                                               field :: atom(),
                                                               message :: binary()}],
                                         assoc_changes ::
                                             #{atom() => #kura_changeset{} | [#kura_changeset{}]},
                                         prepare :: [fun((#kura_changeset{}) -> #kura_changeset{})],
                                         optimistic_lock :: atom() | undefined}.

Validate Field with a custom function returning ok or {error, Message}.

validate_confirmation(CS, Field)

-spec validate_confirmation(#kura_changeset{valid :: boolean(),
                                            schema :: module() | undefined,
                                            data :: map(),
                                            params :: map(),
                                            changes :: map(),
                                            errors :: [{atom(), binary()}],
                                            types :: #{atom() => kura_types:kura_type()},
                                            required :: [atom()],
                                            action :: atom() | undefined,
                                            constraints ::
                                                [#kura_constraint{type ::
                                                                      unique | foreign_key | check |
                                                                      exclusion,
                                                                  constraint :: binary(),
                                                                  field :: atom(),
                                                                  message :: binary()}],
                                            assoc_changes ::
                                                #{atom() => #kura_changeset{} | [#kura_changeset{}]},
                                            prepare :: [fun((#kura_changeset{}) -> #kura_changeset{})],
                                            optimistic_lock :: atom() | undefined},
                            atom()) ->
                               #kura_changeset{valid :: boolean(),
                                               schema :: module() | undefined,
                                               data :: map(),
                                               params :: map(),
                                               changes :: map(),
                                               errors :: [{atom(), binary()}],
                                               types :: #{atom() => kura_types:kura_type()},
                                               required :: [atom()],
                                               action :: atom() | undefined,
                                               constraints ::
                                                   [#kura_constraint{type ::
                                                                         unique | foreign_key | check |
                                                                         exclusion,
                                                                     constraint :: binary(),
                                                                     field :: atom(),
                                                                     message :: binary()}],
                                               assoc_changes ::
                                                   #{atom() => #kura_changeset{} | [#kura_changeset{}]},
                                               prepare ::
                                                   [fun((#kura_changeset{}) -> #kura_changeset{})],
                                               optimistic_lock :: atom() | undefined}.

Validate that Field has a matching confirmation field in params.

validate_confirmation(CS, Field, Opts)

-spec validate_confirmation(#kura_changeset{valid :: boolean(),
                                            schema :: module() | undefined,
                                            data :: map(),
                                            params :: map(),
                                            changes :: map(),
                                            errors :: [{atom(), binary()}],
                                            types :: #{atom() => kura_types:kura_type()},
                                            required :: [atom()],
                                            action :: atom() | undefined,
                                            constraints ::
                                                [#kura_constraint{type ::
                                                                      unique | foreign_key | check |
                                                                      exclusion,
                                                                  constraint :: binary(),
                                                                  field :: atom(),
                                                                  message :: binary()}],
                                            assoc_changes ::
                                                #{atom() => #kura_changeset{} | [#kura_changeset{}]},
                                            prepare :: [fun((#kura_changeset{}) -> #kura_changeset{})],
                                            optimistic_lock :: atom() | undefined},
                            atom(),
                            map()) ->
                               #kura_changeset{valid :: boolean(),
                                               schema :: module() | undefined,
                                               data :: map(),
                                               params :: map(),
                                               changes :: map(),
                                               errors :: [{atom(), binary()}],
                                               types :: #{atom() => kura_types:kura_type()},
                                               required :: [atom()],
                                               action :: atom() | undefined,
                                               constraints ::
                                                   [#kura_constraint{type ::
                                                                         unique | foreign_key | check |
                                                                         exclusion,
                                                                     constraint :: binary(),
                                                                     field :: atom(),
                                                                     message :: binary()}],
                                               assoc_changes ::
                                                   #{atom() => #kura_changeset{} | [#kura_changeset{}]},
                                               prepare ::
                                                   [fun((#kura_changeset{}) -> #kura_changeset{})],
                                               optimistic_lock :: atom() | undefined}.

Validate confirmation with options. Opts: #{message => binary()}.

validate_exclusion(CS, Field, DisallowedValues)

-spec validate_exclusion(#kura_changeset{valid :: boolean(),
                                         schema :: module() | undefined,
                                         data :: map(),
                                         params :: map(),
                                         changes :: map(),
                                         errors :: [{atom(), binary()}],
                                         types :: #{atom() => kura_types:kura_type()},
                                         required :: [atom()],
                                         action :: atom() | undefined,
                                         constraints ::
                                             [#kura_constraint{type ::
                                                                   unique | foreign_key | check |
                                                                   exclusion,
                                                               constraint :: binary(),
                                                               field :: atom(),
                                                               message :: binary()}],
                                         assoc_changes ::
                                             #{atom() => #kura_changeset{} | [#kura_changeset{}]},
                                         prepare :: [fun((#kura_changeset{}) -> #kura_changeset{})],
                                         optimistic_lock :: atom() | undefined},
                         atom(),
                         [term()]) ->
                            #kura_changeset{valid :: boolean(),
                                            schema :: module() | undefined,
                                            data :: map(),
                                            params :: map(),
                                            changes :: map(),
                                            errors :: [{atom(), binary()}],
                                            types :: #{atom() => kura_types:kura_type()},
                                            required :: [atom()],
                                            action :: atom() | undefined,
                                            constraints ::
                                                [#kura_constraint{type ::
                                                                      unique | foreign_key | check |
                                                                      exclusion,
                                                                  constraint :: binary(),
                                                                  field :: atom(),
                                                                  message :: binary()}],
                                            assoc_changes ::
                                                #{atom() => #kura_changeset{} | [#kura_changeset{}]},
                                            prepare :: [fun((#kura_changeset{}) -> #kura_changeset{})],
                                            optimistic_lock :: atom() | undefined}.

Validate that Field value is NOT in the given list of DisallowedValues.

validate_format(CS, Field, Pattern)

-spec validate_format(#kura_changeset{valid :: boolean(),
                                      schema :: module() | undefined,
                                      data :: map(),
                                      params :: map(),
                                      changes :: map(),
                                      errors :: [{atom(), binary()}],
                                      types :: #{atom() => kura_types:kura_type()},
                                      required :: [atom()],
                                      action :: atom() | undefined,
                                      constraints ::
                                          [#kura_constraint{type ::
                                                                unique | foreign_key | check | exclusion,
                                                            constraint :: binary(),
                                                            field :: atom(),
                                                            message :: binary()}],
                                      assoc_changes ::
                                          #{atom() => #kura_changeset{} | [#kura_changeset{}]},
                                      prepare :: [fun((#kura_changeset{}) -> #kura_changeset{})],
                                      optimistic_lock :: atom() | undefined},
                      atom(),
                      binary()) ->
                         #kura_changeset{valid :: boolean(),
                                         schema :: module() | undefined,
                                         data :: map(),
                                         params :: map(),
                                         changes :: map(),
                                         errors :: [{atom(), binary()}],
                                         types :: #{atom() => kura_types:kura_type()},
                                         required :: [atom()],
                                         action :: atom() | undefined,
                                         constraints ::
                                             [#kura_constraint{type ::
                                                                   unique | foreign_key | check |
                                                                   exclusion,
                                                               constraint :: binary(),
                                                               field :: atom(),
                                                               message :: binary()}],
                                         assoc_changes ::
                                             #{atom() => #kura_changeset{} | [#kura_changeset{}]},
                                         prepare :: [fun((#kura_changeset{}) -> #kura_changeset{})],
                                         optimistic_lock :: atom() | undefined}.

Validate that Field matches the regex Pattern.

validate_inclusion(CS, Field, Values)

-spec validate_inclusion(#kura_changeset{valid :: boolean(),
                                         schema :: module() | undefined,
                                         data :: map(),
                                         params :: map(),
                                         changes :: map(),
                                         errors :: [{atom(), binary()}],
                                         types :: #{atom() => kura_types:kura_type()},
                                         required :: [atom()],
                                         action :: atom() | undefined,
                                         constraints ::
                                             [#kura_constraint{type ::
                                                                   unique | foreign_key | check |
                                                                   exclusion,
                                                               constraint :: binary(),
                                                               field :: atom(),
                                                               message :: binary()}],
                                         assoc_changes ::
                                             #{atom() => #kura_changeset{} | [#kura_changeset{}]},
                                         prepare :: [fun((#kura_changeset{}) -> #kura_changeset{})],
                                         optimistic_lock :: atom() | undefined},
                         atom(),
                         [term()]) ->
                            #kura_changeset{valid :: boolean(),
                                            schema :: module() | undefined,
                                            data :: map(),
                                            params :: map(),
                                            changes :: map(),
                                            errors :: [{atom(), binary()}],
                                            types :: #{atom() => kura_types:kura_type()},
                                            required :: [atom()],
                                            action :: atom() | undefined,
                                            constraints ::
                                                [#kura_constraint{type ::
                                                                      unique | foreign_key | check |
                                                                      exclusion,
                                                                  constraint :: binary(),
                                                                  field :: atom(),
                                                                  message :: binary()}],
                                            assoc_changes ::
                                                #{atom() => #kura_changeset{} | [#kura_changeset{}]},
                                            prepare :: [fun((#kura_changeset{}) -> #kura_changeset{})],
                                            optimistic_lock :: atom() | undefined}.

Validate that Field value is in the given list of Values.

validate_length(CS, Field, Opts)

-spec validate_length(#kura_changeset{valid :: boolean(),
                                      schema :: module() | undefined,
                                      data :: map(),
                                      params :: map(),
                                      changes :: map(),
                                      errors :: [{atom(), binary()}],
                                      types :: #{atom() => kura_types:kura_type()},
                                      required :: [atom()],
                                      action :: atom() | undefined,
                                      constraints ::
                                          [#kura_constraint{type ::
                                                                unique | foreign_key | check | exclusion,
                                                            constraint :: binary(),
                                                            field :: atom(),
                                                            message :: binary()}],
                                      assoc_changes ::
                                          #{atom() => #kura_changeset{} | [#kura_changeset{}]},
                                      prepare :: [fun((#kura_changeset{}) -> #kura_changeset{})],
                                      optimistic_lock :: atom() | undefined},
                      atom(),
                      [{atom(), non_neg_integer()}]) ->
                         #kura_changeset{valid :: boolean(),
                                         schema :: module() | undefined,
                                         data :: map(),
                                         params :: map(),
                                         changes :: map(),
                                         errors :: [{atom(), binary()}],
                                         types :: #{atom() => kura_types:kura_type()},
                                         required :: [atom()],
                                         action :: atom() | undefined,
                                         constraints ::
                                             [#kura_constraint{type ::
                                                                   unique | foreign_key | check |
                                                                   exclusion,
                                                               constraint :: binary(),
                                                               field :: atom(),
                                                               message :: binary()}],
                                         assoc_changes ::
                                             #{atom() => #kura_changeset{} | [#kura_changeset{}]},
                                         prepare :: [fun((#kura_changeset{}) -> #kura_changeset{})],
                                         optimistic_lock :: atom() | undefined}.

Validate length of Field. Opts: {min, N}, {max, N}, {is, N}.

validate_number(CS, Field, Opts)

-spec validate_number(#kura_changeset{valid :: boolean(),
                                      schema :: module() | undefined,
                                      data :: map(),
                                      params :: map(),
                                      changes :: map(),
                                      errors :: [{atom(), binary()}],
                                      types :: #{atom() => kura_types:kura_type()},
                                      required :: [atom()],
                                      action :: atom() | undefined,
                                      constraints ::
                                          [#kura_constraint{type ::
                                                                unique | foreign_key | check | exclusion,
                                                            constraint :: binary(),
                                                            field :: atom(),
                                                            message :: binary()}],
                                      assoc_changes ::
                                          #{atom() => #kura_changeset{} | [#kura_changeset{}]},
                                      prepare :: [fun((#kura_changeset{}) -> #kura_changeset{})],
                                      optimistic_lock :: atom() | undefined},
                      atom(),
                      [{atom(), number()}]) ->
                         #kura_changeset{valid :: boolean(),
                                         schema :: module() | undefined,
                                         data :: map(),
                                         params :: map(),
                                         changes :: map(),
                                         errors :: [{atom(), binary()}],
                                         types :: #{atom() => kura_types:kura_type()},
                                         required :: [atom()],
                                         action :: atom() | undefined,
                                         constraints ::
                                             [#kura_constraint{type ::
                                                                   unique | foreign_key | check |
                                                                   exclusion,
                                                               constraint :: binary(),
                                                               field :: atom(),
                                                               message :: binary()}],
                                         assoc_changes ::
                                             #{atom() => #kura_changeset{} | [#kura_changeset{}]},
                                         prepare :: [fun((#kura_changeset{}) -> #kura_changeset{})],
                                         optimistic_lock :: atom() | undefined}.

Validate numeric Field. Opts: {greater_than, N}, {less_than, N}, etc.

validate_required/2

-spec validate_required(#kura_changeset{valid :: boolean(),
                                        schema :: module() | undefined,
                                        data :: map(),
                                        params :: map(),
                                        changes :: map(),
                                        errors :: [{atom(), binary()}],
                                        types :: #{atom() => kura_types:kura_type()},
                                        required :: [atom()],
                                        action :: atom() | undefined,
                                        constraints ::
                                            [#kura_constraint{type ::
                                                                  unique | foreign_key | check |
                                                                  exclusion,
                                                              constraint :: binary(),
                                                              field :: atom(),
                                                              message :: binary()}],
                                        assoc_changes ::
                                            #{atom() => #kura_changeset{} | [#kura_changeset{}]},
                                        prepare :: [fun((#kura_changeset{}) -> #kura_changeset{})],
                                        optimistic_lock :: atom() | undefined},
                        [atom()]) ->
                           #kura_changeset{valid :: boolean(),
                                           schema :: module() | undefined,
                                           data :: map(),
                                           params :: map(),
                                           changes :: map(),
                                           errors :: [{atom(), binary()}],
                                           types :: #{atom() => kura_types:kura_type()},
                                           required :: [atom()],
                                           action :: atom() | undefined,
                                           constraints ::
                                               [#kura_constraint{type ::
                                                                     unique | foreign_key | check |
                                                                     exclusion,
                                                                 constraint :: binary(),
                                                                 field :: atom(),
                                                                 message :: binary()}],
                                           assoc_changes ::
                                               #{atom() => #kura_changeset{} | [#kura_changeset{}]},
                                           prepare :: [fun((#kura_changeset{}) -> #kura_changeset{})],
                                           optimistic_lock :: atom() | undefined}.

Validate that all Fields are present and non-blank.

validate_subset(CS, Field, AllowedValues)

-spec validate_subset(#kura_changeset{valid :: boolean(),
                                      schema :: module() | undefined,
                                      data :: map(),
                                      params :: map(),
                                      changes :: map(),
                                      errors :: [{atom(), binary()}],
                                      types :: #{atom() => kura_types:kura_type()},
                                      required :: [atom()],
                                      action :: atom() | undefined,
                                      constraints ::
                                          [#kura_constraint{type ::
                                                                unique | foreign_key | check | exclusion,
                                                            constraint :: binary(),
                                                            field :: atom(),
                                                            message :: binary()}],
                                      assoc_changes ::
                                          #{atom() => #kura_changeset{} | [#kura_changeset{}]},
                                      prepare :: [fun((#kura_changeset{}) -> #kura_changeset{})],
                                      optimistic_lock :: atom() | undefined},
                      atom(),
                      [term()]) ->
                         #kura_changeset{valid :: boolean(),
                                         schema :: module() | undefined,
                                         data :: map(),
                                         params :: map(),
                                         changes :: map(),
                                         errors :: [{atom(), binary()}],
                                         types :: #{atom() => kura_types:kura_type()},
                                         required :: [atom()],
                                         action :: atom() | undefined,
                                         constraints ::
                                             [#kura_constraint{type ::
                                                                   unique | foreign_key | check |
                                                                   exclusion,
                                                               constraint :: binary(),
                                                               field :: atom(),
                                                               message :: binary()}],
                                         assoc_changes ::
                                             #{atom() => #kura_changeset{} | [#kura_changeset{}]},
                                         prepare :: [fun((#kura_changeset{}) -> #kura_changeset{})],
                                         optimistic_lock :: atom() | undefined}.

Validate that all values in an array Field are within AllowedValues.