Current section
Files
Jump to
Current section
Files
lib/adapters/redis.ex
defmodule Bouncer.Adapters.Redis do
@moduledoc """
The Redis adapter is used by Bouncer.Token to save and retrieve generated
tokens and associated data.
"""
alias Bouncer.RedixPool
@doc """
Saves data to Redis using a given key. If ttl is not nil, the value will be
converted from seconds to miliseconds and set as the key's time-to-live.
## Examples
iex> Bouncer.Adapters.Redis.save %{id: 1}, "UdOnTkNoW", nil
{:ok, "UdOnTkNoW"}
"""
def save(data, key, ttl) do
{status, _} = RedixPool.command(~w(SET) ++ [key] ++ [Poison.encode! data])
if ttl, do: expire(key, ttl), else: {status, key}
end
@doc """
Sets the TTL (time-to-live in seconds) of the given key.
## Examples
iex> Bouncer.Adapters.Redis.save %{id: 1}, "UdOnTkNoW", nil
...> Bouncer.Adapters.Redis.expire "UdOnTkNoW", 1
{:ok, "UdOnTkNoW"}
iex> Bouncer.Adapters.Redis.expire "Arcadia", 1
{:error, "Could not set TTL, key 'Arcadia' not found"}
"""
def expire(key, ttl) do
case RedixPool.command(~w(EXPIRE) ++ [key] ++ [ttl * 1000]) do
{:ok, 1} -> {:ok, key}
{:ok, 0} -> {:error, "Could not set TTL, key '#{key}' not found"}
end
end
@doc """
Retrieves data from Redis using a given key.
## Examples
iex> Bouncer.Adapters.Redis.save %{id: 1},"UdOnTkNoW", nil
...> Bouncer.Adapters.Redis.get "UdOnTkNoW"
{:ok, %{id: 1}}
iex> Bouncer.Adapters.Redis.get "Arcadia"
{:error, nil}
"""
def get(key) do
case RedixPool.command(~w(GET) ++ [key]) do
{_, nil} -> {:error, nil}
{_, data} -> {:ok, Poison.Parser.parse!(data, keys: :atoms!)}
end
end
@doc """
Adds item(s) to a Redis list identified by the given key.
## Examples
iex> Bouncer.Adapters.Redis.add 1, "Arcadia"
{:ok, 1}
"""
def add(id, token), do: RedixPool.command(~w(SADD) ++ [id] ++ [token])
@doc """
Retrieves a user's collection of tokens given their ID.
## Examples
iex> Bouncer.Adapters.Redis.add 2, "divine_hammer"
...> Bouncer.Adapters.Redis.all 2
{:ok, ["divine_hammer"]}
iex> Bouncer.Adapters.Redis.all 3
{:ok, []}
"""
def all(id) do
case RedixPool.command(~w(SMEMBERS) ++ [id]) do
{_, members} when members === nil -> {:ok, []}
{_, members} when is_bitstring(members) -> {:ok, [members]}
{_, members} -> {:ok, members}
end
end
@doc """
Removes item(s) from the Redis list identified by a given key.
"""
def remove(key, items) when is_list(items) do
RedixPool.command(~w(SREM) ++ [key] ++ items)
end
@doc """
Removes a item from the Redis list identified by a given key.
"""
def remove(key, item), do: RedixPool.command(~w(SREM) ++ [key] ++ [item])
@doc """
Deletes given key(s) from Redis.
## Examples
iex> Bouncer.Adapters.Redis.save %{id: 1}, "UdOnTkNoW", nil
...> Bouncer.Adapters.Redis.save %{id: 2}, "Arcadia", nil
...> Bouncer.Adapters.Redis.delete ["UdOnTkNoW", "Arcadia"]
{:ok, ["UdOnTkNoW", "Arcadia"]}
iex> Bouncer.Adapters.Redis.delete []
{:error, "Keys '[]' not found"}
"""
def delete(keys) when is_list(keys) do
case RedixPool.command(~w(DEL) ++ keys) do
{:ok, 0} -> {:error, "Keys '#{keys}' not found"}
_ -> {:ok, keys}
end
end
@doc """
Deletes a given key from Redis.
## Examples
iex> Bouncer.Adapters.Redis.save %{id: 1}, "UdOnTkNoW", nil
...> Bouncer.Adapters.Redis.delete "UdOnTkNoW"
{:ok, "UdOnTkNoW"}
iex> Bouncer.Adapters.Redis.delete "Arcadia"
{:error, "Key 'Arcadia' not found"}
"""
def delete(key) do
case RedixPool.command(~w(DEL) ++ [key]) do
{:ok, 0} -> {:error, "Key '#{key}' not found"}
_ -> {:ok, key}
end
end
end