mirror of
https://github.com/mgerb/classic-wow-forums
synced 2026-01-09 00:42:47 +00:00
82 lines
2.5 KiB
Elixir
82 lines
2.5 KiB
Elixir
defmodule MyApp.Data.User do
|
|
use Ecto.Schema
|
|
import Ecto.Query
|
|
import Ecto.Changeset
|
|
alias MyApp.Repo
|
|
alias MyApp.Data
|
|
|
|
@derive {Poison.Encoder, except: [:__meta__]}
|
|
schema "user" do
|
|
field :battle_net_id, :integer
|
|
field :battletag, :string
|
|
timestamps()
|
|
end
|
|
|
|
def changeset(user, params \\ %{}) do
|
|
user
|
|
|> cast(params, [:battle_net_id, :battletag])
|
|
|> validate_required([:battle_net_id, :battletag])
|
|
|> unique_constraint(:battle_net_id)
|
|
end
|
|
|
|
@spec get_user(integer) :: nil | map
|
|
defp get_user(battle_net_id) do
|
|
query = from u in "user",
|
|
where: u.battle_net_id == ^battle_net_id,
|
|
select: [:id, :battle_net_id, :battletag]
|
|
Repo.one(query)
|
|
end
|
|
|
|
# insert user info in database - if not exists - update battletag if it has changed
|
|
@spec upsert_user(%{"battle_net_id": integer, "battletag": String.t} | tuple) :: {:ok, map} | {:error, any}
|
|
def upsert_user(params) when is_map(params) do
|
|
# check for current user in database
|
|
case get_user(Map.get(params, "battle_net_id")) do
|
|
nil -> insert_user(params)
|
|
user ->
|
|
# update user if battletag has changed
|
|
if Map.get(user, :battletag) != Map.get(params, "battletag") do
|
|
update_battletag(user, params)
|
|
else
|
|
{:ok, user}
|
|
end
|
|
end
|
|
|> add_access_token(Map.get(params, "access_token"))
|
|
end
|
|
def upsert_user({:ok, params}), do: upsert_user(params)
|
|
def upsert_user({:error, error}), do: {:error, error}
|
|
|
|
# need to add token back to map because we don't store it in the database
|
|
defp add_access_token({:error, error}, _), do: {:error, error}
|
|
defp add_access_token({:ok, user}, access_token) do
|
|
{:ok, Map.merge(user, %{access_token: access_token})}
|
|
end
|
|
|
|
defp insert_user(params) do
|
|
cs = changeset(%Data.User{}, params)
|
|
cs
|
|
|> Repo.insert
|
|
|> process_insert_or_update
|
|
end
|
|
|
|
# it's possible for a user's battle tag to change - if so update it
|
|
defp update_battletag(user, params) do
|
|
cs = Data.User.changeset(Map.merge(%Data.User{}, user), %{battletag: Map.get(params, "battletag")})
|
|
cs
|
|
|> Repo.update
|
|
|> process_insert_or_update
|
|
end
|
|
|
|
defp process_insert_or_update({:error, changeset}), do: {:error, map_changeset(changeset)}
|
|
defp process_insert_or_update({:ok, user}) do
|
|
{:ok, Map.take(user, [:id, :battle_net_id, :battletag])} # only grab the fields we need
|
|
end
|
|
|
|
defp map_changeset(changeset) do
|
|
Enum.map(changeset.errors, fn {key, val} ->
|
|
%{key => elem(val, 0)}
|
|
end)
|
|
end
|
|
|
|
end
|