mnesia + file:consult

file:consult はファイルからそのまま Erlang オブジェクト?に変換できます。
もちろんファイルは Erlang 形式で書いておく必要があります。

{users, <<"spam">>, <<"eubIZs47">>}.
{users, <<"eggs">>, <<"bgOYF0bT">>}.
{users, <<"bacon">>, <<"QekmMgcP">>}.
{users, <<"ham">>, <<"XQQS5R91">>}.

do は普通に呼び出しています。
あとは auth_demo をもう少しわかりやすくしたいと思います。
そして gen_server で callback を使って書き直そうかと思っています。

%% vim: fileencoding=utf8 sts=4 sw=4

-module(mnesia_test).
-compile(export_all).
%-export([init/0, start/0, auth_demo/1]).
-include_lib("stdlib/include/qlc.hrl").

-record(users, {user_name, user_password}).

% > c(mnesia_test).
% > mnesia_test:init().
% > mnesia_test:start().
% > mnesia_test:auth_demo(accept).
% > mnesia_test:auth_demo(reject).
% > mnesia_test:auth_demo("ham", "XQQS5R91").

% > timer:tc(mnesia_test, auth_demo, [{"eggs", "bgOYF0bT"}]).
% {9,{user,<<"eggs">>,<<"bgOYF0bT">>}}
% accept
% > timer:tc(mnesia_test, auth_demo, [{"bacon", "XQQS5R91"}]).
% {9,{user,<<"bacon">>,<<"XQQS5R91">>}}
% reject

insert_users_table() ->
    case file:consult("users") of
        {ok, Terms} ->
            F = fun() ->
                    lists:foreach(fun mnesia:write/1, Terms)
                end,
            mnesia:transaction(F);
        {error, _} ->
            error
    end.

init() ->
    mnesia:create_schema([node()]),
    mnesia:start(),
    mnesia:create_table(users, [{attributes, record_info(fields, users)}]),
    mnesia:stop().

start() ->
    mnesia:start(),
    insert_users_table(),
    register(loop, spawn(fun() -> loop() end)).

stop() ->
    loop ! stop.

auth_demo({UserName, Password}) ->
    Pid = spawn(?MODULE, auth, []),
    Pid ! {user, list_to_binary(UserName), list_to_binary(Password)};
auth_demo(accept) ->
    Pid = spawn(?MODULE, auth, []),
    Pid ! {user, <<"spam">>, <<"eubIZs47">>};
auth_demo(reject) ->
    Pid = spawn(?MODULE, auth, []),
    Pid ! {user, <<"spam">>, <<"spam">>}.

loop() ->
    receive
        {result, Result} ->
            result(Result),
            loop();
        stop ->
            stop
    end.

result(Result) ->
    case Result of
        [] ->
            io:format("~p~n", [reject]);
        [{_, _}] ->
            io:format("~p~n", [accept])
    end.

auth() ->
    receive
        {user, UserName, UserPassword} ->
            Result = do(qlc:q([{User#users.user_name, User#users.user_password} || 
                                    User <- mnesia:table(users),
                                    User#users.user_name =:= UserName,
                                    User#users.user_password =:= UserPassword],
                                    {cache, ets})),
            loop ! {result, Result}
    end.

do(Q) ->
    F = fun() -> qlc:e(Q) end,
    {atomic, Result} = mnesia:transaction(F),
    Result.