Skip to content

Commit

Permalink
[8.x] Add --pretend option for model:prune command (laravel#38945)
Browse files Browse the repository at this point in the history
* Add --pretend option for model:prune command

* Fix tests

* Fix code style
  • Loading branch information
shalvah authored and victorvilella committed Oct 12, 2021
1 parent 396704a commit b6550d9
Show file tree
Hide file tree
Showing 2 changed files with 78 additions and 1 deletion.
33 changes: 32 additions & 1 deletion src/Illuminate/Database/Console/PruneCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@ class PruneCommand extends Command
*/
protected $signature = 'model:prune
{--model=* : Class names of the models to be pruned}
{--chunk=1000 : The number of models to retrieve per chunk of models to be deleted}';
{--chunk=1000 : The number of models to retrieve per chunk of models to be deleted}
{--pretend : Display the number of prunable records found instead of deleting them}';

/**
* The console command description.
Expand All @@ -44,6 +45,14 @@ public function handle(Dispatcher $events)
return;
}

if ($this->option('pretend')) {
$models->each(function ($model) {
$this->pretendToPrune($model);
});

return;
}

$events->listen(ModelsPruned::class, function ($event) {
$this->info("{$event->count} [{$event->model}] records have been pruned.");
});
Expand Down Expand Up @@ -104,4 +113,26 @@ protected function isPrunable($model)

return in_array(Prunable::class, $uses) || in_array(MassPrunable::class, $uses);
}

/**
* Display how many models will be pruned.
*
* @param string $model
* @return void
*/
protected function pretendToPrune($model)
{
$instance = new $model;

$count = $instance->prunable()
->when(in_array(SoftDeletes::class, class_uses_recursive(get_class($instance))), function ($query) {
$query->withTrashed();
})->count();

if ($count === 0) {
$this->info("No prunable [$model] records found.");
} else {
$this->info("{$count} [{$model}] records will be pruned.");
}
}
}
46 changes: 46 additions & 0 deletions tests/Database/PruneCommandTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,15 @@

use Illuminate\Container\Container;
use Illuminate\Contracts\Events\Dispatcher as DispatcherContract;
use Illuminate\Database\Capsule\Manager as DB;
use Illuminate\Database\ConnectionResolverInterface;
use Illuminate\Database\Console\PruneCommand;
use Illuminate\Database\Eloquent\MassPrunable;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Prunable;
use Illuminate\Database\Events\ModelsPruned;
use Illuminate\Events\Dispatcher;
use Mockery as m;
use PHPUnit\Framework\TestCase;
use Symfony\Component\Console\Input\ArrayInput;
use Symfony\Component\Console\Output\BufferedOutput;
Expand Down Expand Up @@ -60,6 +63,41 @@ public function testNonPrunableTest()
EOF, str_replace("\r", '', $output->fetch()));
}

public function testTheCommandMayBePretended()
{
$db = new DB;
$db->addConnection([
'driver' => 'sqlite',
'database' => ':memory:',
]);
$db->setAsGlobal();
DB::connection('default')->getSchemaBuilder()->create('prunables', function ($table) {
$table->string('name')->nullable();
$table->string('value')->nullable();
});
DB::connection('default')->table('prunables')->insert([
['name' => 'zain', 'value' => 1],
['name' => 'patrice', 'value' => 2],
['name' => 'amelia', 'value' => 3],
['name' => 'stuart', 'value' => 4],
['name' => 'bello', 'value' => 5],
]);
$resolver = m::mock(ConnectionResolverInterface::class, ['connection' => $db->getConnection('default')]);
PrunableTestModelWithPrunableRecords::setConnectionResolver($resolver);

$output = $this->artisan([
'--model' => PrunableTestModelWithPrunableRecords::class,
'--pretend' => true,
]);

$this->assertEquals(<<<'EOF'
3 [Illuminate\Tests\Database\PrunableTestModelWithPrunableRecords] records will be pruned.

EOF, str_replace("\r", '', $output->fetch()));

$this->assertEquals(5, PrunableTestModelWithPrunableRecords::count());
}

protected function artisan($arguments)
{
$input = new ArrayInput($arguments);
Expand All @@ -84,13 +122,21 @@ class PrunableTestModelWithPrunableRecords extends Model
{
use MassPrunable;

protected $table = 'prunables';
protected $connection = 'default';

public function pruneAll()
{
event(new ModelsPruned(static::class, 10));
event(new ModelsPruned(static::class, 20));

return 20;
}

public function prunable()
{
return static::where('value', '>=', 3);
}
}

class PrunableTestModelWithoutPrunableRecords extends Model
Expand Down

0 comments on commit b6550d9

Please sign in to comment.