#erlang #mnesia
#эрланг #mnesia #erlang
Вопрос:
У меня есть таблица mnesia users
с полем пользователя и пароля.
Данные из моей таблицы:
[{users, <<"user_name">>, <<"password">>}].
Мне нужно получить пароль по имени пользователя. Я создаю:
mnesia:dirty_read({users, <<"user_name">>}).
Но оно возвращает []
.
Как я могу получить пароль по имени пользователя?
Ответ №1:
Вы не указали используемый вами синтаксис записи, но он выглядит как
-запись(пользователи, {имя пользователя, пароль}).
… или что-то подобное. Итак, предположим, что при создании таблицы вы сделали что-нибудь особенное для установки идентификатора? В этом примере «имя пользователя» (первая запись в записи пользователей) должно быть идентификатором по умолчанию, если вы не сделали что-то особенное.
Если у вас по-прежнему возникают проблемы, рассмотрите возможность использования mnesia:match_object/1 или / 3. Вы указываете в синтаксисе шаблона / записи ту часть, которой вы должны соответствовать (в данном случае, имя пользователя), и используете =’‘, чтобы соответствовать всему, чего вы не знаете или о чем не заботитесь (в данном случае это была бы часть пароля).
Я надеюсь, что это поможет!
Ответ №2:
Вы можете сделать что-то вроде приведенного ниже:
YourPasswd = mnesia:ets(fun()-> mnesia:dirty_read({пользователи, идентификатор пользователя}) конец), укажите ваш PASSWD из [] -> {ошибка, 'Пользователь не найден'}; [{users,_UserID,Passwd}] -> {успех, Passwd} завершение.
Надеюсь, данные правильно записаны в mnesia 🙂
Ответ №3:
посмотрите на эту функцию:
-определить(ИМЯ_ТАБЛИЦЫ,пользователи). get_password_by_username(Имя пользователя)-> F = fun(U)-> mnesia: прочитать({?ИМЯ_ТАБЛИЦЫ,U}) конец, mnesia: активность(транзакция,F, [Имя пользователя], mnesia_frag).
Это даст вам результат. Хорошая вещь с mnesia: activity / 4 заключается в том, что независимо от того, фрагментирована таблица или нет, ответы в порядке. удачи
Ответ №4:
Я понимаю, вы хотите, чтобы ваши пароли проверялись как можно быстрее, но находится ли ваш проект на той стадии, когда вам нужно это оптимизировать?
У меня есть модуль аутентификации в одном из моих проектов, и у меня такие же цели, как у вас. Поскольку у меня пока не было возможности оптимизировать, я использую транзакции mnsesia и списки для имен пользователей и паролей.
Вот часть моего модуля аутентификации.
-module(auth).
-export([init/1, add_user/2, start_session/2]).
-record(auth_user, {username, password}).
init(Nodes) ->
mnesia:create_table(auth_user,
[{disc_copies, Nodes},
{attributes, record_info(fields, auth_user)}]).
add_user(Username, Password) ->
T = fun() ->
mnesia:write(#auth_user {
username = Username,
password = Password})
end,
mnesia:transaction(T).
start_session(Username, Password) ->
T = fun() ->
mnesia:read(auth_user, Username)
end,
{atomic, Ret} = mnesia:transaction(T),
case Ret of
[U] ->
if (U#auth_user.password == Password) ->
true;
true ->
false
end;
_Else ->
false
end.
После компиляции и запуска оболочки erlang.
Eshell V5.8.3 (abort with ^G)
1> mnesia:create_schema([node()]).
ok
3> mnesia:start().
ok
4> auth:init([node()]).
{atomic,ok}
5> auth:add_user("rodericktaylor", "password").
{atomic,ok}
6> true = auth:start_session("rodericktaylor", "password").
true
7>
Чтобы увидеть, возникает ли у меня та же проблема, что и у вас, я переключился на двоичные значения и выполнил грязное чтение.
start_session_dirty(Username, Password) ->
case mnesia:dirty_read(auth_user, Username) of
[U] ->
if (U#auth_user.password == Password) ->
true;
true ->
false
end;
_Else ->
false
end.
Следующие команды в оболочке erl показывают, что это работает так, как вы ожидаете.
12> auth:add_user(<<"rodericktaylor">>, <<"binarypassword">>).
{atomic,ok}
14> true = auth:start_session_dirty(<<"rodericktaylor">>, <<"binarypassword">>).
true
15>
Я надеюсь, что я помог.