Проблема
Научившись использовать Mnesia с Elixir, я создал таблицу с несколькими функциями (такими как чтение, запись ...). Один из них - обновить набор полей (размер от 1 до count - 1) без изменения остальных данных и ограничения логики до минимума внутри транзакции mnesia.
Во время поиска я случайно нашел это: Erlang: Mnesia: обновление одного значения поля в строке (код ниже). Это тот же вопрос, но для Erlang, а не для Elixir.
Код
Насколько я понимаю, он работает в Erlang, поскольку чтение возвращает кортеж, который непосредственно устанавливается внутри записи, что позволяет нам сохранять определенные данные в действии записи в том виде, в каком они названы.
update_a(Tab, Key, Value) ->
fun() ->
[P] = mnesia:wread({Tab, Key}),
mnesia:write(P#pixel{a=Value})
end.
Где для Elixir, несмотря на то, что записи существуют, это будет просто кортеж, в котором вы можете только изменять данные в индексе и возвращать полный кортеж для действия записи.
Table: {table_name, id, data1, data2, data3, data4}
changes = [{2, new_val_for_data1}, {4, new_val_for_data3}]
def handle_call({:update_and_read, table, {id, changes}}, _, state) do
{:atomic, new_object} =
:mnesia.transaction(fn ->
object =
:mnesia.wread({table, id})
|> List.first()
ret =
Enum.reduce(changes, object, fn {index, value}, acc ->
acc |> Tuple.delete_at(index) |> Tuple.insert_at(index, value)
end)
:mnesia.write(object)
ret
end)
{:reply, {:ok, new_object}, state}
end
Вопрос
Можно ли иметь более короткую функцию в Elixir (в идеале, две строки, как в Erlang)?