ecto.migrate.ex (4662B)
1 defmodule Mix.Tasks.Ecto.Migrate do 2 use Mix.Task 3 import Mix.Ecto 4 import Mix.EctoSQL 5 6 @shortdoc "Runs the repository migrations" 7 8 @aliases [ 9 n: :step, 10 r: :repo 11 ] 12 13 @switches [ 14 all: :boolean, 15 step: :integer, 16 to: :integer, 17 to_exclusive: :integer, 18 quiet: :boolean, 19 prefix: :string, 20 pool_size: :integer, 21 log_sql: :boolean, 22 log_migrations_sql: :boolean, 23 log_migrator_sql: :boolean, 24 strict_version_order: :boolean, 25 repo: [:keep, :string], 26 no_compile: :boolean, 27 no_deps_check: :boolean, 28 migrations_path: :keep 29 ] 30 31 @moduledoc """ 32 Runs the pending migrations for the given repository. 33 34 Migrations are expected at "priv/YOUR_REPO/migrations" directory 35 of the current application, where "YOUR_REPO" is the last segment 36 in your repository name. For example, the repository `MyApp.Repo` 37 will use "priv/repo/migrations". The repository `Whatever.MyRepo` 38 will use "priv/my_repo/migrations". 39 40 You can configure a repository to use another directory by specifying 41 the `:priv` key under the repository configuration. The "migrations" 42 part will be automatically appended to it. For instance, to use 43 "priv/custom_repo/migrations": 44 45 config :my_app, MyApp.Repo, priv: "priv/custom_repo" 46 47 This task runs all pending migrations by default. To migrate up to a 48 specific version number, supply `--to version_number`. To migrate a 49 specific number of times, use `--step n`. 50 51 The repositories to migrate are the ones specified under the 52 `:ecto_repos` option in the current app configuration. However, 53 if the `-r` option is given, it replaces the `:ecto_repos` config. 54 55 Since Ecto tasks can only be executed once, if you need to migrate 56 multiple repositories, set `:ecto_repos` accordingly or pass the `-r` 57 flag multiple times. 58 59 If a repository has not yet been started, one will be started outside 60 your application supervision tree and shutdown afterwards. 61 62 ## Examples 63 64 $ mix ecto.migrate 65 $ mix ecto.migrate -r Custom.Repo 66 67 $ mix ecto.migrate -n 3 68 $ mix ecto.migrate --step 3 69 70 $ mix ecto.migrate --to 20080906120000 71 72 ## Command line options 73 74 * `--all` - run all pending migrations 75 76 * `--log-migrations-sql` - log SQL generated by migration commands 77 78 * `--log-migrator-sql` - log SQL generated by the migrator, such as 79 transactions, table locks, etc 80 81 * `--migrations-path` - the path to load the migrations from, defaults to 82 `"priv/repo/migrations"`. This option may be given multiple times in which 83 case the migrations are loaded from all the given directories and sorted 84 as if they were in the same one 85 86 * `--no-compile` - does not compile applications before migrating 87 88 * `--no-deps-check` - does not check dependencies before migrating 89 90 * `--pool-size` - the pool size if the repository is started 91 only for the task (defaults to 2) 92 93 * `--prefix` - the prefix to run migrations on 94 95 * `--quiet` - do not log migration commands 96 97 * `-r`, `--repo` - the repo to migrate 98 99 * `--step`, `-n` - run n number of pending migrations 100 101 * `--strict-version-order` - abort when applying a migration with old 102 timestamp (otherwise it emits a warning) 103 104 * `--to` - run all migrations up to and including version 105 106 * `--to-exclusive` - run all migrations up to and excluding version 107 108 """ 109 110 @impl true 111 def run(args, migrator \\ &Ecto.Migrator.run/4) do 112 repos = parse_repo(args) 113 {opts, _} = OptionParser.parse! args, strict: @switches, aliases: @aliases 114 115 opts = 116 if opts[:to] || opts[:to_exclusive] || opts[:step] || opts[:all], 117 do: opts, 118 else: Keyword.put(opts, :all, true) 119 120 opts = 121 if opts[:quiet], 122 do: Keyword.merge(opts, [log: false, log_migrations_sql: false, log_migrator_sql: false]), 123 else: opts 124 125 # Start ecto_sql explicitly before as we don't need 126 # to restart those apps if migrated. 127 {:ok, _} = Application.ensure_all_started(:ecto_sql) 128 129 for repo <- repos do 130 ensure_repo(repo, args) 131 paths = ensure_migrations_paths(repo, opts) 132 pool = repo.config[:pool] 133 134 fun = 135 if Code.ensure_loaded?(pool) and function_exported?(pool, :unboxed_run, 2) do 136 &pool.unboxed_run(&1, fn -> migrator.(&1, paths, :up, opts) end) 137 else 138 &migrator.(&1, paths, :up, opts) 139 end 140 141 case Ecto.Migrator.with_repo(repo, fun, [mode: :temporary] ++ opts) do 142 {:ok, _migrated, _apps} -> :ok 143 {:error, error} -> Mix.raise "Could not start repo #{inspect repo}, error: #{inspect error}" 144 end 145 end 146 147 :ok 148 end 149 end