mirror of
https://github.com/wanderer-industries/wanderer
synced 2025-12-08 00:35:53 +00:00
147 lines
4.0 KiB
Elixir
147 lines
4.0 KiB
Elixir
defmodule WandererApp.Cache do
|
|
@moduledoc false
|
|
use Nebulex.Cache,
|
|
otp_app: :wanderer_app,
|
|
adapter: Nebulex.Adapters.Local
|
|
|
|
require Logger
|
|
|
|
def lookup(key, default \\ nil)
|
|
|
|
def lookup({id, key}, default) when is_binary(id) and (is_binary(key) or is_atom(key)),
|
|
do: lookup("#{id}:#{key}", default)
|
|
|
|
def lookup(key, default) when is_binary(key) or is_atom(key) do
|
|
case get(key) do
|
|
nil -> {:ok, default}
|
|
value -> {:ok, value}
|
|
end
|
|
end
|
|
|
|
def lookup!(key, default \\ nil)
|
|
|
|
def lookup!({id, key}, default) when is_binary(id) and (is_binary(key) or is_atom(key)),
|
|
do: lookup!("#{id}:#{key}", default)
|
|
|
|
def lookup!(key, default) when is_binary(key) or is_atom(key) do
|
|
{:ok, result} = lookup(key, default)
|
|
result
|
|
end
|
|
|
|
def get_and_remove(key, default) when is_binary(key) or is_atom(key) do
|
|
case take(key) do
|
|
nil -> {:ok, default}
|
|
value -> {:ok, value}
|
|
end
|
|
end
|
|
|
|
def get_and_remove!(key, default) when is_binary(key) or is_atom(key) do
|
|
{:ok, result} = get_and_remove(key, default)
|
|
result
|
|
end
|
|
|
|
def insert(key, value, opts \\ [])
|
|
|
|
def insert({id, key}, value, opts) when is_binary(id) and (is_binary(key) or is_atom(key)),
|
|
do: insert("#{id}:#{key}", value, opts)
|
|
|
|
def insert(key, nil, _opts) when is_binary(key) or is_atom(key), do: delete(key)
|
|
def insert(key, value, opts) when is_binary(key) or is_atom(key), do: put(key, value, opts)
|
|
|
|
def insert_or_update(key, value, update_fn, opts \\ [])
|
|
|
|
def insert_or_update({id, key}, value, update_fn, opts)
|
|
when is_binary(id) and (is_binary(key) or is_atom(key)),
|
|
do: insert_or_update("#{id}:#{key}", value, update_fn, opts)
|
|
|
|
def insert_or_update(key, value, update_fn, opts) when is_binary(key) or is_atom(key) do
|
|
case lookup(key) do
|
|
{:ok, nil} ->
|
|
insert(key, value, opts)
|
|
|
|
{:ok, data} ->
|
|
insert(key, update_fn.(data), opts)
|
|
end
|
|
end
|
|
|
|
def find_by_attrs(type, attrs, match \\ :any) do
|
|
case type |> get() |> find(attrs, match: match) do
|
|
%{} = item -> {:ok, item}
|
|
nil -> {:error, :item_not_found}
|
|
end
|
|
end
|
|
|
|
def filter_by_attr_in(type, attr, includes), do: type |> get() |> filter_in(attr, includes)
|
|
|
|
@doc """
|
|
Batch lookup multiple keys from cache.
|
|
Returns a map of key => value pairs, with `default` used for missing keys.
|
|
"""
|
|
def lookup_all(keys, default \\ nil) when is_list(keys) do
|
|
# Get all values from cache
|
|
values = get_all(keys)
|
|
|
|
# Build result map with defaults for missing keys
|
|
result =
|
|
keys
|
|
|> Enum.map(fn key ->
|
|
value = Map.get(values, key, default)
|
|
{key, value}
|
|
end)
|
|
|> Map.new()
|
|
|
|
{:ok, result}
|
|
end
|
|
|
|
@doc """
|
|
Batch insert multiple key-value pairs into cache.
|
|
Accepts a map of key => value pairs or a list of {key, value} tuples.
|
|
Skips nil values (deletes the key instead).
|
|
"""
|
|
def insert_all(entries, opts \\ [])
|
|
|
|
def insert_all(entries, opts) when is_map(entries) do
|
|
# Filter out nil values and delete those keys
|
|
{to_delete, to_insert} =
|
|
entries
|
|
|> Enum.split_with(fn {_key, value} -> is_nil(value) end)
|
|
|
|
# Delete keys with nil values
|
|
Enum.each(to_delete, fn {key, _} -> delete(key) end)
|
|
|
|
# Insert non-nil values
|
|
unless Enum.empty?(to_insert) do
|
|
put_all(to_insert, opts)
|
|
end
|
|
|
|
:ok
|
|
end
|
|
|
|
def insert_all(entries, opts) when is_list(entries) do
|
|
insert_all(Map.new(entries), opts)
|
|
end
|
|
|
|
defp find(list, %{} = attrs, match: match) do
|
|
list
|
|
|> Enum.find(fn item ->
|
|
case match do
|
|
:any -> Enum.any?(attrs, &has_equal_attribute?(item, &1))
|
|
:all -> Enum.all?(attrs, &has_equal_attribute?(item, &1))
|
|
end
|
|
end)
|
|
end
|
|
|
|
defp filter_in(nil, _attr, _includes), do: []
|
|
|
|
defp filter_in(list, attr, includes),
|
|
do:
|
|
list
|
|
|> Enum.filter(&(&1[attr] in includes))
|
|
|
|
defp has_equal_attribute?(%{} = map, {key, {:case_insensitive, value}}) when is_binary(value) do
|
|
String.downcase(Map.get(map, key, "")) == String.downcase(value)
|
|
end
|
|
|
|
defp has_equal_attribute?(%{} = map, {key, value}), do: Map.get(map, key) == value
|
|
end
|