%% @doc Add ticket.source field and index on error_hash. %% No-op if `ticket` table is absent (e.g. migration_engine unit tests). -module('20260716230000_ticket_source_and_hash_index'). -export([up/0, down/0]). -include("records.hrl"). up() -> case ticket_table_exists() of false -> ok; true -> ensure_source_field(), ensure_error_hash_index(), ok end. down() -> case ticket_table_exists() of false -> ok; true -> case catch mnesia:del_table_index(ticket, error_hash) of {atomic, ok} -> ok; {aborted, {no_exists, _}} -> ok; {aborted, {no_exists, _, _}} -> ok; _ -> ok end end. ticket_table_exists() -> try lists:member(ticket, mnesia:system_info(tables)) catch _:_ -> false end. ensure_source_field() -> Attrs = mnesia:table_info(ticket, attributes), case lists:member(source, Attrs) of true -> ok; false -> Fun = fun(Rec) -> case tuple_size(Rec) of 14 -> %% ticket + 13 fields (pre-source) list_to_tuple(tuple_to_list(Rec) ++ [<<"backend">>]); _ -> Rec end end, case mnesia:transform_table(ticket, Fun, record_info(fields, ticket)) of {atomic, ok} -> ok; {aborted, Reason} -> error({transform_ticket_failed, Reason}) end end. ensure_error_hash_index() -> Indexes = mnesia:table_info(ticket, index), HasIndex = lists:any(fun (error_hash) -> true; (N) when is_integer(N) -> N =:= #ticket.error_hash; (_) -> false end, Indexes), case HasIndex of true -> ok; false -> case mnesia:add_table_index(ticket, error_hash) of {atomic, ok} -> ok; {aborted, {already_exists, _}} -> ok; {aborted, {already_exists, _, _}} -> ok; {aborted, Reason} -> error({add_index_failed, Reason}) end end.