* Adds a basic settings model * Added more settings methods; Hooked up initial settings runner to app boot * Update onboarding flow to use settings model instead of session data
95 lines
2.7 KiB
Elixir
95 lines
2.7 KiB
Elixir
defmodule Pinchflat.Settings do
|
|
@moduledoc """
|
|
The Settings context.
|
|
"""
|
|
|
|
import Ecto.Query, warn: false
|
|
alias Pinchflat.Repo
|
|
|
|
alias Pinchflat.Settings.Setting
|
|
|
|
@doc """
|
|
Returns the list of settings.
|
|
|
|
Returns [%Setting{}, ...]
|
|
"""
|
|
def list_settings do
|
|
Repo.all(Setting)
|
|
end
|
|
|
|
@doc """
|
|
Creates or updates a setting, returning the parsed value.
|
|
Raises if an unsupported datatype is used. Optionally allows
|
|
specifying the datatype.
|
|
|
|
Returns value in type of `Ecto.Enum.mappings(Setting, :datatype)`
|
|
"""
|
|
def set!(name, value) do
|
|
set!(name, value, infer_datatype(value))
|
|
end
|
|
|
|
def set!(name, value, datatype) do
|
|
# Only create if doesn't exist
|
|
case Repo.get_by(Setting, name: to_string(name)) do
|
|
nil -> create_setting!(name, value, datatype)
|
|
setting -> update_setting!(setting, value, datatype)
|
|
end
|
|
end
|
|
|
|
@doc """
|
|
Gets the parsed value of a setting. Raises if the setting does not exist.
|
|
|
|
Returns value in type of `Ecto.Enum.mappings(Setting, :datatype)`
|
|
"""
|
|
def get!(name) do
|
|
Setting
|
|
|> Repo.get_by!(name: to_string(name))
|
|
|> read_setting()
|
|
end
|
|
|
|
@doc """
|
|
Attempts to find a setting by name or creates a setting with value
|
|
if one doesn't exist, returning the parsed value. Optionally allows
|
|
specifying the datatype.
|
|
|
|
Returns value in type of `Ecto.Enum.mappings(Setting, :datatype)`
|
|
"""
|
|
def fetch!(name, value) do
|
|
fetch!(name, value, infer_datatype(value))
|
|
end
|
|
|
|
def fetch!(name, value, datatype) do
|
|
case Repo.get_by(Setting, name: to_string(name)) do
|
|
nil -> create_setting!(name, value, datatype)
|
|
setting -> read_setting(setting)
|
|
end
|
|
end
|
|
|
|
defp change_setting(setting, attrs) do
|
|
Setting.changeset(setting, attrs)
|
|
end
|
|
|
|
defp create_setting!(name, value, datatype) do
|
|
%Setting{}
|
|
|> change_setting(%{name: to_string(name), value: to_string(value), datatype: datatype})
|
|
|> Repo.insert!()
|
|
|> read_setting()
|
|
end
|
|
|
|
defp update_setting!(setting, value, datatype) do
|
|
setting
|
|
|> change_setting(%{value: to_string(value), datatype: datatype})
|
|
|> Repo.update!()
|
|
|> read_setting()
|
|
end
|
|
|
|
defp read_setting(%{value: value, datatype: :string}), do: value
|
|
defp read_setting(%{value: value, datatype: :boolean}), do: value in ["true", "t", "1"]
|
|
defp read_setting(%{value: value, datatype: :integer}), do: String.to_integer(value)
|
|
defp read_setting(%{value: value, datatype: :float}), do: String.to_float(value)
|
|
|
|
defp infer_datatype(value) when is_boolean(value), do: :boolean
|
|
defp infer_datatype(value) when is_integer(value), do: :integer
|
|
defp infer_datatype(value) when is_float(value), do: :float
|
|
defp infer_datatype(value) when is_binary(value), do: :string
|
|
end
|