Reputation: 215
I want to be able to store a map using :dets
Currently, that is the solution I am trying to implement:
# a list of strings
topics = GenServer.call(MessageBroker.TopicsProvider, {:get_topics})
# a map with each element of the list as key and an empty list as value
topics_map =
topics
|> Enum.chunk_every(1)
|> Map.new(fn [k] -> {k, []} end)
{:ok, table} = :dets.open_file(:messages, type: :set)
# trying to store the map
:dets.insert(table, [topics_map])
:dets.close(table)
However, I get
** (EXIT) an exception was raised:
** (ArgumentError) argument error
(stdlib 3.12) dets.erl:1259: :dets.insert(:messages, [%{"tweet" => [], "user" => []}])
How is it possible to accomplish this?
Upvotes: 0
Views: 521
Reputation: 121000
As I understood your intent, you want to store users
and tweets
under separate keys. For that, you need to construct a keyword list, not a map, in the first place.
topics = for topic <- topics, do: {topic, []}
# or topics = Enum.map(topics, &{&1, []})
# or topics = Enum.map(topics, fn topic -> {topic, []} end)
then you might use this keyword list to create dets
.
{:ok, table} = :dets.open_file(:messages, type: :set)
:dets.insert(table, topics)
:dets.close(table)
Upvotes: 1
Reputation: 215
Chen Yu's solution is good, but before getting it I already found another solution. Basically, you can just add the map to a tuple
:dets.insert(table, {:map, topics_map})
Then, you can get this map by using
:dets.lookup(table, :map)
Upvotes: 1
Reputation: 4077
I have tested by erlang. You should convert the map to list first.
Following from dets:insert_new() doc
insert_new(Name, Objects) -> boolean() | {error, Reason}
Types
Name = tab_name()
Objects = object() | [object()]
Reason = term()
Inserts one or more objects into table Name. If there already exists some object with a key matching the key of any of the specified objects, the table is not updated and false is returned. Otherwise the objects are inserted and true returned.
test code
dets:open_file(dets_a,[{file,"/tmp/aab"}]).
Map = #{a => 2, b => 3, c=> 4, "a" => 1, "b" => 2, "c" => 4}.
List_a = maps:to_list(Map). %% <----- this line
dets:insert(dets_a,List_a).
Upvotes: 1