Current section

Files

Jump to
eddb lib database Entry.ex
Raw

lib/database/Entry.ex

defmodule Database.Entry do
alias Database.Entry
defstruct key: nil,
history: [
%{
timestamp: nil,
data: nil
}
]
def new(key, data) when is_bitstring(key) do
%Entry{
key: key,
history: [
%{
timestamp: DateTime.utc_now() |> DateTime.to_unix(:millisecond),
data: data
}
]
}
end
def get_keys(entries) do
entries
|> Stream.map(& &1.key)
|> Enum.uniq()
end
@doc """
Combine a list of Databse.Entry's for a specific key.
This does also sort by timestamp
"""
def combine(entries, key) do
# TODO: This works to some degree... There is currently an "issue" where history entries
# with the same entries will be filtered out
history =
entries
|> Stream.filter(&(&1.key == key))
|> Enum.map(& &1.history)
|> Stream.flat_map(& &1)
|> Stream.uniq_by(fn %{timestamp: timestamp, data: _data} -> timestamp end)
|> Enum.sort_by(fn %{timestamp: timestamp, data: _data} -> timestamp end, :desc)
|> Enum.to_list()
%Entry{
key: key,
history: history
}
end
@doc """
Combine a list of Databse.Entry's by key.
The parameter is usually obtained by getting them from multiple topics, map to the entries and flatten the result:
entries =
topics # <-- A list of topics usually with the same topic name
|> Enum.map(fn topic -> topic.entries end)
|> List.flatten()
|> Entry.combine()
"""
def combine(entries) do
keys =
get_keys(entries)
|> Enum.uniq()
combine_helper([], entries, keys)
end
defp combine_helper(result, _entries, []), do: result
defp combine_helper(result, entries, keys) do
key = List.first(keys)
keys = List.delete(keys, key)
combine_helper([combine(entries, key) | result], entries, keys)
end
def update(%Entry{} = entry, data) do
%Entry{
entry
| history:
List.insert_at(
entry.history,
0,
%{
timestamp: DateTime.utc_now() |> DateTime.to_unix(:millisecond),
data: data
}
)
}
end
end