簡體   English   中英

Elixir:Mnesia:更新元素中的一組值的最簡潔方法是什么?

[英]Elixir : Mnesia : What is the most concise way to update a set of value in an element?

問題

通過 Elixir 學習使用 Mnesia,我創建了一個包含多個 function 的表(例如讀、寫...)。 其中之一是更新一組字段(大小從 1 到 count - 1)而不更改數據的 rest,並將 mnesia 事務內部的邏輯限制為最小。

在我的搜索過程中,我碰巧發現了這個: Erlang: Mnesia: Updating a single field value in a row but (code below). 這是同一個問題,但對於 Erlang,而不是 Elixir。

代碼

據我了解,它在 Erlang 中工作,因為 read 返回一個直接設置在記錄中的元組,這允許我們在寫入操作中保存特定數據,因為它們被命名。

update_a(Tab, Key, Value) ->
  fun() ->
    [P] = mnesia:wread({Tab, Key}),
    mnesia:write(P#pixel{a=Value})
  end.

其中,對於 Elixir,即使 Records 存在,它也只是一個元組,您只能更改索引中的數據,並將完整的元組返回給寫入操作。

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 中有更短的 function (理想情況下,兩行就像 Erlang 中的那一行)?

好吧,您可以通過一些初步步驟使用Record (例如在您的應用程序中定義記錄。)

defmodule Pixel do
  require Record
  Record.defrecord(:table_name, id: nil, data1: nil, data2: nil)
end

並在要更新表格的模塊中

import Pixel

def handle_call({:update_and_read, table, {id, changes}}, _, state) do
  # changes = [data2: new_val_for_data1, ...]
  {:atomic, result} =
    :mnesia.transaction(fn ->
      case :mnesia.wread({table, id}) do
        [object] -> 
          :mnesia.write(pixel(object, changes))
          {:ok, object}
        [] -> :error
      end
    end)

  {:reply, result, state}
end

另一種可能性是通過 go

changes = %{2 => new_val_for_data1, 4 => new_val_for_data3}
object
|> Tuple.to_list()
|> Enum.with_index()
|> Enum.map(fn {value, idx} -> Map.get(changes, idx, value) end)
|> List.to_tuple()

另一種可能性是聲明一個宏,該宏接受一個元組,表示一個表行和一個{idx, new_value}元組列表,並就地更改相應的元素。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM