RefreshCommand.php 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163
  1. <?php
  2. namespace Illuminate\Database\Console\Migrations;
  3. use Illuminate\Console\Command;
  4. use Illuminate\Console\ConfirmableTrait;
  5. use Illuminate\Console\Prohibitable;
  6. use Illuminate\Contracts\Events\Dispatcher;
  7. use Illuminate\Database\Events\DatabaseRefreshed;
  8. use Symfony\Component\Console\Attribute\AsCommand;
  9. use Symfony\Component\Console\Input\InputOption;
  10. #[AsCommand(name: 'migrate:refresh')]
  11. class RefreshCommand extends Command
  12. {
  13. use ConfirmableTrait, Prohibitable;
  14. /**
  15. * The console command name.
  16. *
  17. * @var string
  18. */
  19. protected $name = 'migrate:refresh';
  20. /**
  21. * The console command description.
  22. *
  23. * @var string
  24. */
  25. protected $description = 'Reset and re-run all migrations';
  26. /**
  27. * Execute the console command.
  28. *
  29. * @return int
  30. */
  31. public function handle()
  32. {
  33. if ($this->isProhibited() ||
  34. ! $this->confirmToProceed()) {
  35. return 1;
  36. }
  37. // Next we'll gather some of the options so that we can have the right options
  38. // to pass to the commands. This includes options such as which database to
  39. // use and the path to use for the migration. Then we'll run the command.
  40. $database = $this->input->getOption('database');
  41. $path = $this->input->getOption('path');
  42. // If the "step" option is specified it means we only want to rollback a small
  43. // number of migrations before migrating again. For example, the user might
  44. // only rollback and remigrate the latest four migrations instead of all.
  45. $step = $this->input->getOption('step') ?: 0;
  46. if ($step > 0) {
  47. $this->runRollback($database, $path, $step);
  48. } else {
  49. $this->runReset($database, $path);
  50. }
  51. // The refresh command is essentially just a brief aggregate of a few other of
  52. // the migration commands and just provides a convenient wrapper to execute
  53. // them in succession. We'll also see if we need to re-seed the database.
  54. $this->call('migrate', array_filter([
  55. '--database' => $database,
  56. '--path' => $path,
  57. '--realpath' => $this->input->getOption('realpath'),
  58. '--force' => true,
  59. ]));
  60. if ($this->laravel->bound(Dispatcher::class)) {
  61. $this->laravel[Dispatcher::class]->dispatch(
  62. new DatabaseRefreshed($database, $this->needsSeeding())
  63. );
  64. }
  65. if ($this->needsSeeding()) {
  66. $this->runSeeder($database);
  67. }
  68. return 0;
  69. }
  70. /**
  71. * Run the rollback command.
  72. *
  73. * @param string $database
  74. * @param string $path
  75. * @param int $step
  76. * @return void
  77. */
  78. protected function runRollback($database, $path, $step)
  79. {
  80. $this->call('migrate:rollback', array_filter([
  81. '--database' => $database,
  82. '--path' => $path,
  83. '--realpath' => $this->input->getOption('realpath'),
  84. '--step' => $step,
  85. '--force' => true,
  86. ]));
  87. }
  88. /**
  89. * Run the reset command.
  90. *
  91. * @param string $database
  92. * @param string $path
  93. * @return void
  94. */
  95. protected function runReset($database, $path)
  96. {
  97. $this->call('migrate:reset', array_filter([
  98. '--database' => $database,
  99. '--path' => $path,
  100. '--realpath' => $this->input->getOption('realpath'),
  101. '--force' => true,
  102. ]));
  103. }
  104. /**
  105. * Determine if the developer has requested database seeding.
  106. *
  107. * @return bool
  108. */
  109. protected function needsSeeding()
  110. {
  111. return $this->option('seed') || $this->option('seeder');
  112. }
  113. /**
  114. * Run the database seeder command.
  115. *
  116. * @param string $database
  117. * @return void
  118. */
  119. protected function runSeeder($database)
  120. {
  121. $this->call('db:seed', array_filter([
  122. '--database' => $database,
  123. '--class' => $this->option('seeder') ?: 'Database\\Seeders\\DatabaseSeeder',
  124. '--force' => true,
  125. ]));
  126. }
  127. /**
  128. * Get the console command options.
  129. *
  130. * @return array
  131. */
  132. protected function getOptions()
  133. {
  134. return [
  135. ['database', null, InputOption::VALUE_OPTIONAL, 'The database connection to use'],
  136. ['force', null, InputOption::VALUE_NONE, 'Force the operation to run when in production'],
  137. ['path', null, InputOption::VALUE_OPTIONAL | InputOption::VALUE_IS_ARRAY, 'The path(s) to the migrations files to be executed'],
  138. ['realpath', null, InputOption::VALUE_NONE, 'Indicate any provided migration file paths are pre-resolved absolute paths'],
  139. ['seed', null, InputOption::VALUE_NONE, 'Indicates if the seed task should be re-run'],
  140. ['seeder', null, InputOption::VALUE_OPTIONAL, 'The class name of the root seeder'],
  141. ['step', null, InputOption::VALUE_OPTIONAL, 'The number of migrations to be reverted & re-run'],
  142. ];
  143. }
  144. }