Packages

Ecto helpers for creating database views and functions

Current section

Files

Jump to
familiar lib mix tasks familiar.gen.view.ex
Raw

lib/mix/tasks/familiar.gen.view.ex

defmodule Mix.Tasks.Familiar.Gen.View do
use Mix.Task
import Mix.Generator
import Mix.Ecto
import Mix.EctoSQL
@shortdoc "Creates a new view definition file"
@moduledoc """
Creates a new view definition file.
If no view with that name currently exists, an empty file version 1 of the
view will be created.
If one does exist, a new file will be created with an incremented version
number and a copy of the contents of the previous latest version.
## Examples
mix familiar.gen.view my_view
mix familiar.gen.view my_view --version 1
## Command line options
* `--version` - the version to create
* `--schema` - the schema to create the view in
"""
@switches [
version: :integer,
schema: :string
]
@impl true
def run(args) do
no_umbrella!("familiar.gen.view")
repos = parse_repo(args)
case OptionParser.parse!(args, strict: @switches) do
{opts, [name]} ->
repo = hd(repos)
ensure_repo(repo, args)
dir = make_dir(repo, Keyword.get(opts, :schema))
{version, contents} = get_version(name, dir, opts)
filename = "#{name}_v#{version}.sql"
path = "#{dir}/#{filename}"
create_file(path, contents)
end
end
defp make_dir(repo, schema) when not is_nil(schema) do
Path.join(make_dir(repo, nil), schema)
end
defp make_dir(repo, nil) do
Path.join(source_repo_priv(repo), "views")
end
defp get_version(name, dir, opts) do
if version = Keyword.get(opts, :version) do
{version, ""}
else
possible_views = Path.wildcard("#{dir}/#{name}_v*")
versions =
Enum.flat_map(possible_views, fn filename ->
case Regex.run(~r|#{name}_v(\d+).sql$|, filename) do
[_, v] -> [{filename, String.to_integer(v)}]
_ -> []
end
end)
if versions == [] do
{1, ""}
else
{filename, version} = Enum.max_by(versions, &elem(&1, 1))
old_contents = File.read!(filename)
{version + 1, old_contents}
end
end
end
end