Packages
ecto
2.2.0
3.14.1
3.14.0
3.13.6
3.13.5
3.13.4
3.13.3
3.13.2
3.13.1
3.13.0
3.12.6
3.12.5
3.12.4
3.12.3
3.12.2
3.12.1
3.12.0
3.11.2
3.11.1
3.11.0
3.10.3
3.10.2
3.10.1
3.10.0
3.9.6
3.9.5
3.9.4
3.9.3
3.9.2
3.9.1
3.9.0
3.8.4
3.8.3
3.8.2
3.8.1
3.8.0
3.7.2
3.7.1
3.7.0
3.6.2
3.6.1
3.6.0
3.5.8
3.5.7
3.5.6
3.5.5
3.5.4
3.5.3
3.5.2
3.5.1
3.5.0
3.5.0-rc.1
3.5.0-rc.0
3.4.6
3.4.5
3.4.4
3.4.3
3.4.2
3.4.1
3.4.0
3.3.4
3.3.3
3.3.2
3.3.1
3.3.0
3.2.5
3.2.4
3.2.3
3.2.2
3.2.1
3.2.0
3.1.7
3.1.6
3.1.5
3.1.4
3.1.3
3.1.2
3.1.1
3.1.0
3.0.9
3.0.8
3.0.7
3.0.6
3.0.5
3.0.4
3.0.3
3.0.2
3.0.1
3.0.0
3.0.0-rc.1
3.0.0-rc.0
2.2.12
2.2.11
2.2.10
2.2.9
2.2.8
2.2.7
2.2.6
2.2.5
2.2.4
2.2.3
2.2.2
2.2.1
2.2.0
2.2.0-rc.1
2.2.0-rc.0
2.1.6
2.1.5
2.1.4
2.1.3
2.1.2
2.1.1
2.1.0
2.1.0-rc.5
2.1.0-rc.4
2.1.0-rc.3
2.1.0-rc.2
2.1.0-rc.1
2.1.0-rc.0
2.0.6
2.0.5
2.0.4
2.0.3
2.0.2
2.0.1
2.0.0
2.0.0-rc.6
2.0.0-rc.5
2.0.0-rc.4
2.0.0-rc.3
2.0.0-rc.2
2.0.0-rc.1
2.0.0-rc.0
2.0.0-beta.2
2.0.0-beta.1
2.0.0-beta.0
1.1.9
1.1.8
1.1.7
1.1.6
1.1.5
1.1.4
1.1.3
1.1.2
1.1.1
1.1.0
1.0.7
1.0.6
1.0.5
1.0.4
1.0.3
1.0.2
1.0.1
1.0.0
0.16.0
0.15.0
0.14.3
0.14.2
0.14.1
0.14.0
0.13.1
0.13.0
0.12.1
0.12.0
0.12.0-rc
0.11.3
0.11.2
0.11.1
0.11.0
0.10.3
0.10.2
0.10.1
0.10.0
0.9.0
0.8.1
0.8.0
0.7.2
0.7.1
0.7.0
0.6.0
0.5.1
0.5.0
0.4.0
0.3.0
0.2.8
0.2.7
0.2.6
0.2.5
0.2.4
0.2.3
0.2.2
0.2.1
0.2.0
0.1.0
A toolkit for data mapping and language integrated query for Elixir
Security advisory:
This version has known vulnerabilities.
View advisories
Current section
Files
Jump to
Current section
Files
lib/mix/ecto.ex
defmodule Mix.Ecto do
# Conveniences for writing Mix.Tasks in Ecto.
@moduledoc false
@doc """
Parses the repository option from the given list.
If no repo option is given, we get one from the environment.
"""
@spec parse_repo([term]) :: [Ecto.Repo.t]
def parse_repo(args) do
parse_repo(args, [])
end
defp parse_repo([key, value|t], acc) when key in ~w(--repo -r) do
parse_repo t, [Module.concat([value])|acc]
end
defp parse_repo([_|t], acc) do
parse_repo t, acc
end
defp parse_repo([], []) do
apps =
if apps_paths = Mix.Project.apps_paths do
Map.keys(apps_paths)
else
[Mix.Project.config[:app]]
end
apps
|> Enum.flat_map(&Application.get_env(&1, :ecto_repos, []))
|> Enum.uniq()
|> case do
[] ->
Mix.shell.error """
warning: could not find Ecto repos in any of the apps: #{inspect apps}.
You can avoid this warning by passing the -r flag or by setting the
repositories managed by those applications in your config/config.exs:
config #{inspect hd(apps)}, ecto_repos: [...]
"""
[]
repos ->
repos
end
end
defp parse_repo([], acc) do
Enum.reverse(acc)
end
@doc """
Ensures the given module is a repository.
"""
@spec ensure_repo(module, list) :: Ecto.Repo.t | no_return
def ensure_repo(repo, args) do
Mix.Task.run "loadpaths", args
unless "--no-compile" in args do
Mix.Project.compile(args)
end
case Code.ensure_compiled(repo) do
{:module, _} ->
if function_exported?(repo, :__adapter__, 0) do
repo
else
Mix.raise "Module #{inspect repo} is not an Ecto.Repo. " <>
"Please configure your app accordingly or pass a repo with the -r option."
end
{:error, error} ->
Mix.raise "Could not load #{inspect repo}, error: #{inspect error}. " <>
"Please configure your app accordingly or pass a repo with the -r option."
end
end
@doc """
Ensures the given repository is started and running.
"""
@spec ensure_started(Ecto.Repo.t, Keyword.t) :: {:ok, pid, [atom]} | no_return
def ensure_started(repo, opts) do
{:ok, started} = Application.ensure_all_started(:ecto)
# If we starting Ecto just now, assume
# logger has not been properly booted yet.
if :ecto in started && Process.whereis(Logger) do
Logger.App.stop
:ok = Logger.App.start
end
{:ok, apps} = repo.__adapter__.ensure_all_started(repo, :temporary)
pool_size = Keyword.get(opts, :pool_size, 1)
case repo.start_link(pool_size: pool_size) do
{:ok, pid} ->
{:ok, pid, apps}
{:error, {:already_started, _pid}} ->
{:ok, nil, apps}
{:error, error} ->
Mix.raise "Could not start repo #{inspect repo}, error: #{inspect error}"
end
end
@doc """
Ensures the given repository's migrations path exists on the file system.
"""
@spec ensure_migrations_path(Ecto.Repo.t) :: Ecto.Repo.t | no_return
def ensure_migrations_path(repo) do
with false <- Mix.Project.umbrella?,
path = Path.relative_to(migrations_path(repo), Mix.Project.app_path),
false <- File.dir?(path),
do: raise_missing_migrations(path, repo)
repo
end
defp raise_missing_migrations(path, repo) do
Mix.raise """
Could not find migrations directory #{inspect path}
for repo #{inspect repo}.
This may be because you are in a new project and the
migration directory has not been created yet. Creating an
empty directory at the path above will fix this error.
If you expected existing migrations to be found, please
make sure your repository has been properly configured
and the configured path exists.
"""
end
@doc """
Restarts the app if there was any migration command.
"""
@spec restart_apps_if_migrated([atom], list()) :: :ok
def restart_apps_if_migrated(_apps, []), do: :ok
def restart_apps_if_migrated(apps, [_|_]) do
# Silence the logger to avoid application down messages.
Logger.remove_backend(:console)
for app <- Enum.reverse(apps) do
Application.stop(app)
end
for app <- apps do
Application.ensure_all_started(app)
end
:ok
after
Logger.add_backend(:console, flush: true)
end
@doc """
Gets the migrations path from a repository.
"""
@spec migrations_path(Ecto.Repo.t) :: String.t
def migrations_path(repo) do
Path.join(source_repo_priv(repo), "migrations")
end
@doc """
Returns the private repository path relative to the source.
"""
def source_repo_priv(repo) do
priv = repo.config()[:priv] || "priv/#{repo |> Module.split |> List.last |> Macro.underscore}"
app = Keyword.fetch!(repo.config(), :otp_app)
Path.join(Mix.Project.deps_paths[app] || File.cwd!, priv)
end
@doc """
Asks if the user wants to open a file based on ECTO_EDITOR.
"""
@spec open?(binary) :: boolean
def open?(file) do
editor = System.get_env("ECTO_EDITOR") || ""
if editor != "" do
:os.cmd(to_charlist(editor <> " " <> inspect(file)))
true
else
false
end
end
@doc """
Gets a path relative to the application path.
Raises on umbrella application.
"""
def no_umbrella!(task) do
if Mix.Project.umbrella? do
Mix.raise "Cannot run task #{inspect task} from umbrella application"
end
end
@doc """
Returns `true` if module implements behaviour.
"""
def ensure_implements(module, behaviour, message) do
all = Keyword.take(module.__info__(:attributes), [:behaviour])
unless [behaviour] in Keyword.values(all) do
Mix.raise "Expected #{inspect module} to implement #{inspect behaviour} " <>
"in order to #{message}"
end
end
end