kura_schema behaviour (kura v1.19.2)

View Source

Behaviour for defining database-backed schemas.

Implement the table/0 and fields/0 callbacks to define a schema module. Mark one field with primary_key = true. Optionally implement timestamps/0 and associations/0.

-module(my_user).
-behaviour(kura_schema).
-include_lib("kura/include/kura.hrl").

table() -> <<"users">>.
fields() ->
    [#kura_field{name = id, type = id, primary_key = true},
     #kura_field{name = name, type = string},
     #kura_field{name = email, type = string}].

Summary

Functions

Look up a single association by name.

Return all associations defined on a schema module.

Return map of field name to column name (binary), excluding virtual fields.

Return all table-level constraints defined on a schema module.

Look up a single embed by name.

Return all embeds defined on a schema module.

Return list of field names for a schema module.

Return map of field name to kura type for a schema module.

Generate a primary key value if the schema defines generate_id/0.

Check if a schema module has an after_* hook for the given action.

Return all indexes defined on a schema module.

Return list of non-virtual field names.

Return the primary key field name for a schema module.

Return the primary key field record, or undefined if not found.

Run after_delete hook if defined. Returns ok or {error, Reason}.

Run after_insert hook if defined. Returns {ok, Record} or {error, Reason}.

Run after_update hook if defined. Returns {ok, Record} or {error, Reason}.

Run before_delete hook if defined. Returns ok or {error, Reason}.

Run before_insert hook if defined. Returns {ok, CS} or {error, CS}.

Run before_update hook if defined. Returns {ok, CS} or {error, CS}.

Callbacks

after_delete/1

(optional)
-callback after_delete(map()) -> ok | {error, term()}.

after_insert/1

(optional)
-callback after_insert(map()) -> {ok, map()} | {error, term()}.

after_update/1

(optional)
-callback after_update(map()) -> {ok, map()} | {error, term()}.

associations()

(optional)
-callback associations() ->
                          [#kura_assoc{name :: atom(),
                                       type :: belongs_to | has_one | has_many | many_to_many,
                                       schema :: module(),
                                       foreign_key :: atom() | undefined,
                                       join_through :: binary() | module() | undefined,
                                       join_keys :: {atom(), atom()} | undefined,
                                       through :: [atom()] | undefined}].

before_delete/1

(optional)
-callback before_delete(map()) -> ok | {error, term()}.

before_insert/1

(optional)
-callback before_insert(#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}) ->
                           {ok,
                            #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}} |
                           {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}}.

before_update/1

(optional)
-callback before_update(#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}) ->
                           {ok,
                            #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}} |
                           {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}}.

constraints()

(optional)
-callback constraints() -> [kura_migration:table_constraint()].

embeds()

(optional)
-callback embeds() -> [#kura_embed{name :: atom(), type :: embeds_one | embeds_many, schema :: module()}].

fields()

-callback fields() ->
                    [#kura_field{name :: atom(),
                                 type :: kura_types:kura_type(),
                                 column :: binary() | undefined,
                                 default :: term(),
                                 primary_key :: boolean(),
                                 nullable :: boolean(),
                                 virtual :: boolean()}].

generate_id()

(optional)
-callback generate_id() -> term().

indexes()

(optional)
-callback indexes() -> [kura_migration:index_def()].

table()

-callback table() -> binary().

timestamps()

(optional)
-callback timestamps() -> [{atom(), kura_types:kura_type()}].

Functions

association(Mod, Name)

-spec association(module(), atom()) ->
                     {ok,
                      #kura_assoc{name :: atom(),
                                  type :: belongs_to | has_one | has_many | many_to_many,
                                  schema :: module(),
                                  foreign_key :: atom() | undefined,
                                  join_through :: binary() | module() | undefined,
                                  join_keys :: {atom(), atom()} | undefined,
                                  through :: [atom()] | undefined}} |
                     {error, not_found}.

Look up a single association by name.

associations(Mod)

-spec associations(module()) ->
                      [#kura_assoc{name :: atom(),
                                   type :: belongs_to | has_one | has_many | many_to_many,
                                   schema :: module(),
                                   foreign_key :: atom() | undefined,
                                   join_through :: binary() | module() | undefined,
                                   join_keys :: {atom(), atom()} | undefined,
                                   through :: [atom()] | undefined}].

Return all associations defined on a schema module.

column_map(Mod)

-spec column_map(module()) -> #{atom() => binary()}.

Return map of field name to column name (binary), excluding virtual fields.

constraints(Mod)

-spec constraints(module()) -> [kura_migration:table_constraint()].

Return all table-level constraints defined on a schema module.

embed(Mod, Name)

-spec embed(module(), atom()) ->
               {ok, #kura_embed{name :: atom(), type :: embeds_one | embeds_many, schema :: module()}} |
               {error, not_found}.

Look up a single embed by name.

embeds(Mod)

-spec embeds(module()) ->
                [#kura_embed{name :: atom(), type :: embeds_one | embeds_many, schema :: module()}].

Return all embeds defined on a schema module.

field_names(Mod)

-spec field_names(module()) -> [atom()].

Return list of field names for a schema module.

field_types(Mod)

-spec field_types(module()) -> #{atom() => kura_types:kura_type()}.

Return map of field name to kura type for a schema module.

generate_id(Mod)

-spec generate_id(module()) -> {ok, term()} | undefined.

Generate a primary key value if the schema defines generate_id/0.

has_after_hook(Mod, Action)

-spec has_after_hook(module(), insert | update | delete) -> boolean().

Check if a schema module has an after_* hook for the given action.

indexes(Mod)

-spec indexes(module()) -> [kura_migration:index_def()].

Return all indexes defined on a schema module.

non_virtual_fields(Mod)

-spec non_virtual_fields(module()) -> [atom()].

Return list of non-virtual field names.

primary_key(Mod)

-spec primary_key(module()) -> atom().

Return the primary key field name for a schema module.

primary_key_field(Mod)

-spec primary_key_field(module()) ->
                           #kura_field{name :: atom(),
                                       type :: kura_types:kura_type(),
                                       column :: binary() | undefined,
                                       default :: term(),
                                       primary_key :: boolean(),
                                       nullable :: boolean(),
                                       virtual :: boolean()} |
                           undefined.

Return the primary key field record, or undefined if not found.

run_after_delete(Mod, Record)

-spec run_after_delete(module(), map()) -> ok | {error, term()}.

Run after_delete hook if defined. Returns ok or {error, Reason}.

run_after_insert(Mod, Record)

-spec run_after_insert(module(), map()) -> {ok, map()} | {error, term()}.

Run after_insert hook if defined. Returns {ok, Record} or {error, Reason}.

run_after_update(Mod, Record)

-spec run_after_update(module(), map()) -> {ok, map()} | {error, term()}.

Run after_update hook if defined. Returns {ok, Record} or {error, Reason}.

run_before_delete(Mod, Record)

-spec run_before_delete(module(), map()) -> ok | {error, term()}.

Run before_delete hook if defined. Returns ok or {error, Reason}.

run_before_insert(Mod, CS)

-spec run_before_insert(module(),
                        #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}) ->
                           {ok,
                            #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}} |
                           {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}}.

Run before_insert hook if defined. Returns {ok, CS} or {error, CS}.

run_before_update(Mod, CS)

-spec run_before_update(module(),
                        #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}) ->
                           {ok,
                            #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}} |
                           {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}}.

Run before_update hook if defined. Returns {ok, CS} or {error, CS}.