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