mirror of https://github.com/mitchell/shortnr.git
Refactor to delegate pattern
This commit is contained in:
parent
e212eee751
commit
b492d338cd
|
@ -14,7 +14,7 @@ Vagrant.configure('2') do |config| # rubocop:disable Metrics/BlockLength
|
|||
dev.vm.network 'private_network', ip: '192.168.50.11'
|
||||
|
||||
dev.vm.provider 'virtualbox' do |vb|
|
||||
vb.memory = '2048'
|
||||
vb.memory = '4096'
|
||||
vb.cpus = 4
|
||||
end
|
||||
|
||||
|
@ -131,7 +131,7 @@ Vagrant.configure('2') do |config| # rubocop:disable Metrics/BlockLength
|
|||
prod.vm.network 'private_network', ip: '192.168.50.10'
|
||||
|
||||
prod.vm.provider 'virtualbox' do |vb|
|
||||
vb.memory = '2048'
|
||||
vb.memory = '4096'
|
||||
vb.cpus = 4
|
||||
end
|
||||
|
||||
|
|
|
@ -4,6 +4,7 @@ defmodule Shortnr.URL do
|
|||
domain service.
|
||||
"""
|
||||
alias Shortnr.Transport
|
||||
alias Shortnr.URL.Repo
|
||||
|
||||
defstruct id: "",
|
||||
created_at: DateTime.utc_now(),
|
||||
|
@ -17,37 +18,39 @@ defmodule Shortnr.URL do
|
|||
url: URI.t()
|
||||
}
|
||||
|
||||
@spec create(String.t(), module()) :: {:ok, String.t()} | Transport.error()
|
||||
def create(url, repo) do
|
||||
@spec create(String.t()) :: {:ok, String.t()} | Transport.error()
|
||||
def create(url) when is_binary(url) do
|
||||
url_struct = %__MODULE__{id: generate_id(), url: URI.parse(url)}
|
||||
|
||||
{:ok, extant_url} = repo.get(url_struct.id)
|
||||
|
||||
if extant_url do
|
||||
create(url, repo)
|
||||
else
|
||||
:ok = repo.put(url_struct)
|
||||
{:ok, url_struct.id}
|
||||
end
|
||||
url_struct.id
|
||||
|> Repo.get()
|
||||
|> create_if_no_collision(url_struct, url)
|
||||
end
|
||||
|
||||
@spec get(String.t(), module()) :: {:ok, t()} | Transport.error()
|
||||
def get(key, repo) do
|
||||
case repo.get(key) do
|
||||
{:ok, nil} -> {:error, {:not_found, "url could not be found with the given id"}}
|
||||
{:ok, url} -> {:ok, url}
|
||||
end
|
||||
defp create_if_no_collision({:ok, nil}, %__MODULE__{id: id} = url, _url) do
|
||||
:ok = Repo.put(url)
|
||||
{:ok, id}
|
||||
end
|
||||
|
||||
@spec list(module()) :: {:ok, list(t())} | Transport.error()
|
||||
def list(repo) do
|
||||
{:ok, _} = repo.list
|
||||
defp create_if_no_collision({:ok, _}, _url_struct, url) when is_binary(url), do: create(url)
|
||||
|
||||
@spec get(String.t()) :: {:ok, t()} | Transport.error()
|
||||
def get(key) do
|
||||
key
|
||||
|> Repo.get()
|
||||
|> handle_errors
|
||||
end
|
||||
|
||||
@spec delete(String.t(), module()) :: {:ok, String.t()} | Transport.error()
|
||||
def delete(key, repo) do
|
||||
:ok = repo.delete(key)
|
||||
{:ok, "Success"}
|
||||
@spec list() :: {:ok, list(t())}
|
||||
def list do
|
||||
handle_errors(Repo.list())
|
||||
end
|
||||
|
||||
@spec delete(String.t()) :: {:ok, String.t()}
|
||||
def delete(key) do
|
||||
key
|
||||
|> Repo.delete()
|
||||
|> handle_errors
|
||||
end
|
||||
|
||||
@id_chars String.codepoints("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXWYZ0123456789")
|
||||
|
@ -58,6 +61,13 @@ defmodule Shortnr.URL do
|
|||
do: Enum.random(@id_chars)
|
||||
end
|
||||
|
||||
defp handle_errors({:ok, nil}),
|
||||
do: {:error, {:not_found, "url could not be found with the given id"}}
|
||||
|
||||
defp handle_errors({:ok, _} = response), do: response
|
||||
|
||||
defp handle_errors(:ok), do: {:ok, "Success"}
|
||||
|
||||
defimpl Transport.Text.Encodable do
|
||||
alias Shortnr.URL
|
||||
@spec encode(URL.t()) :: String.t()
|
||||
|
|
|
@ -8,7 +8,7 @@ defmodule Shortnr.URL.Endpoints do
|
|||
def list(conn) do
|
||||
conn
|
||||
|> HTTP.wrap()
|
||||
|> HTTP.handle(fn -> URL.list(URL.Repo.ETS) end)
|
||||
|> HTTP.handle(&URL.list/0)
|
||||
|> Text.encode()
|
||||
|> HTTP.send(:ok)
|
||||
end
|
||||
|
@ -16,7 +16,7 @@ defmodule Shortnr.URL.Endpoints do
|
|||
def create(conn, url) do
|
||||
conn
|
||||
|> HTTP.wrap(url)
|
||||
|> HTTP.handle(&URL.create(&1, URL.Repo.ETS))
|
||||
|> HTTP.handle(&URL.create(&1))
|
||||
|> Text.encode()
|
||||
|> HTTP.send(:created)
|
||||
end
|
||||
|
@ -24,7 +24,7 @@ defmodule Shortnr.URL.Endpoints do
|
|||
def get(conn, id) do
|
||||
conn
|
||||
|> HTTP.wrap(id)
|
||||
|> HTTP.handle(&URL.get(&1, URL.Repo.ETS))
|
||||
|> HTTP.handle(&URL.get(&1))
|
||||
|> Text.encode()
|
||||
|> HTTP.send(:found)
|
||||
end
|
||||
|
@ -32,7 +32,7 @@ defmodule Shortnr.URL.Endpoints do
|
|||
def delete(conn, id) do
|
||||
conn
|
||||
|> HTTP.wrap(id)
|
||||
|> HTTP.handle(&URL.delete(&1, URL.Repo.ETS))
|
||||
|> HTTP.handle(&URL.delete(&1))
|
||||
|> Text.encode()
|
||||
|> HTTP.send(:ok)
|
||||
end
|
||||
|
|
|
@ -7,9 +7,18 @@ defmodule Shortnr.URL.Repo do
|
|||
alias Shortnr.Transport
|
||||
alias Shortnr.URL
|
||||
|
||||
@callback put(URL.t()) :: :ok | Transport.error()
|
||||
@callback get(String.t()) :: {:ok, URL.t()} | Transport.error()
|
||||
@callback delete(String.t()) :: :ok | Transport.error()
|
||||
@callback list() :: {:ok, list(URL.t())} | Transport.error()
|
||||
@callback reset() :: :ok | Transport.error()
|
||||
@spec put(URL.t()) :: :ok | Transport.error()
|
||||
defdelegate put(url), to: Shortnr.URL.Repo.ETS
|
||||
|
||||
@spec get(String.t()) :: {:ok, URL.t() | nil} | Transport.error()
|
||||
defdelegate get(url), to: Shortnr.URL.Repo.ETS
|
||||
|
||||
@spec delete(String.t()) :: :ok | Transport.error()
|
||||
defdelegate delete(url), to: Shortnr.URL.Repo.ETS
|
||||
|
||||
@spec list() :: {:ok, list(URL.t())} | Transport.error()
|
||||
defdelegate list(), to: Shortnr.URL.Repo.ETS
|
||||
|
||||
@spec reset() :: :ok | Transport.error()
|
||||
defdelegate reset(), to: Shortnr.URL.Repo.ETS
|
||||
end
|
||||
|
|
|
@ -2,11 +2,7 @@ defmodule Shortnr.URL.Repo.ETS do
|
|||
@moduledoc """
|
||||
This module is an implemention of the Repo behaviour using the Erlang ETS library.
|
||||
"""
|
||||
alias Shortnr.URL.Repo
|
||||
|
||||
@behaviour Repo
|
||||
|
||||
@impl true
|
||||
def get(key) do
|
||||
case ets().lookup(:urls, key) |> List.first() do
|
||||
{_, url} -> {:ok, url}
|
||||
|
@ -14,25 +10,21 @@ defmodule Shortnr.URL.Repo.ETS do
|
|||
end
|
||||
end
|
||||
|
||||
@impl true
|
||||
def put(url) do
|
||||
:ok = ets().insert(:urls, {url.id, url})
|
||||
:ok
|
||||
end
|
||||
|
||||
@impl true
|
||||
def list do
|
||||
resp = ets().select(:urls, [{:"$1", [], [:"$1"]}])
|
||||
{:ok, resp |> Enum.map(&elem(&1, 1))}
|
||||
end
|
||||
|
||||
@impl true
|
||||
def delete(key) do
|
||||
:ok = ets().delete(:urls, key)
|
||||
:ok
|
||||
end
|
||||
|
||||
@impl true
|
||||
def reset do
|
||||
:ok = ets().delete_all_objects(:urls)
|
||||
end
|
||||
|
|
Loading…
Reference in New Issue