From 7f9e7b20037ad5e43903b1661a9cd4c7308f85a6 Mon Sep 17 00:00:00 2001 From: Shalvah Date: Fri, 24 Sep 2021 16:05:16 +0100 Subject: [PATCH 1/4] Add --pretend option for model:prune command --- .../Database/Console/PruneCommand.php | 32 ++++++++++++++++++- tests/Database/PruneCommandTest.php | 14 ++++++++ 2 files changed, 45 insertions(+), 1 deletion(-) diff --git a/src/Illuminate/Database/Console/PruneCommand.php b/src/Illuminate/Database/Console/PruneCommand.php index 74be6b92669d..526bfb01bd34 100644 --- a/src/Illuminate/Database/Console/PruneCommand.php +++ b/src/Illuminate/Database/Console/PruneCommand.php @@ -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 : Print the number of prunable records found instead of deleting them}'; /** * The console command description. @@ -43,6 +44,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."); @@ -104,4 +113,25 @@ protected function isPrunable($model) return in_array(Prunable::class, $uses) || in_array(MassPrunable::class, $uses); } + + /** + * Report how many models will be pruned, instead of actually pruning them. + * + * @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."); + } + } } diff --git a/tests/Database/PruneCommandTest.php b/tests/Database/PruneCommandTest.php index 2b98680c0da4..9a5ee58fc274 100644 --- a/tests/Database/PruneCommandTest.php +++ b/tests/Database/PruneCommandTest.php @@ -57,6 +57,20 @@ public function testNonPrunableTest() $this->assertEquals(<<<'EOF' No prunable [Illuminate\Tests\Database\NonPrunableTestModel] records found. +EOF, str_replace("\r", '', $output->fetch())); + } + + public function testPretendPrunableModelWithPrunableRecords() + { + $output = $this->artisan([ + '--model' => PrunableTestModelWithPrunableRecords::class, + '--pretend' => true + ]); + + $this->assertEquals(<<<'EOF' +10 [Illuminate\Tests\Database\PrunableTestModelWithPrunableRecords] records will be pruned. +20 [Illuminate\Tests\Database\PrunableTestModelWithPrunableRecords] records will be pruned. + EOF, str_replace("\r", '', $output->fetch())); } From 459ac61bf335fbcb72058784bb41399b396a1ee6 Mon Sep 17 00:00:00 2001 From: Shalvah Date: Fri, 24 Sep 2021 16:54:07 +0100 Subject: [PATCH 2/4] Fix tests --- tests/Database/PruneCommandTest.php | 38 ++++++++++++++++++++++++++--- 1 file changed, 35 insertions(+), 3 deletions(-) diff --git a/tests/Database/PruneCommandTest.php b/tests/Database/PruneCommandTest.php index 9a5ee58fc274..2925ae4a533e 100644 --- a/tests/Database/PruneCommandTest.php +++ b/tests/Database/PruneCommandTest.php @@ -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; @@ -60,18 +63,39 @@ public function testNonPrunableTest() EOF, str_replace("\r", '', $output->fetch())); } - public function testPretendPrunableModelWithPrunableRecords() + 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' -10 [Illuminate\Tests\Database\PrunableTestModelWithPrunableRecords] records will be pruned. -20 [Illuminate\Tests\Database\PrunableTestModelWithPrunableRecords] records will be pruned. +3 [Illuminate\Tests\Database\PrunableTestModelWithPrunableRecords] records will be pruned. EOF, str_replace("\r", '', $output->fetch())); + + $this->assertEquals(5, PrunableTestModelWithPrunableRecords::count()); } protected function artisan($arguments) @@ -98,6 +122,9 @@ class PrunableTestModelWithPrunableRecords extends Model { use MassPrunable; + protected $table = 'prunables'; + protected $connection = 'default'; + public function pruneAll() { event(new ModelsPruned(static::class, 10)); @@ -105,6 +132,11 @@ public function pruneAll() return 20; } + + public function prunable() + { + return static::where('value', '>=', 3); + } } class PrunableTestModelWithoutPrunableRecords extends Model From 0772f411a62c72b98853d1b229c9a701fa117661 Mon Sep 17 00:00:00 2001 From: shalvah Date: Fri, 24 Sep 2021 17:50:01 +0100 Subject: [PATCH 3/4] Fix code style --- src/Illuminate/Database/Console/PruneCommand.php | 4 ++-- tests/Database/PruneCommandTest.php | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Illuminate/Database/Console/PruneCommand.php b/src/Illuminate/Database/Console/PruneCommand.php index 526bfb01bd34..11c327123674 100644 --- a/src/Illuminate/Database/Console/PruneCommand.php +++ b/src/Illuminate/Database/Console/PruneCommand.php @@ -44,12 +44,12 @@ public function handle(Dispatcher $events) return; } - + if ($this->option('pretend')) { $models->each(function ($model) { $this->pretendToPrune($model); }); - + return; } diff --git a/tests/Database/PruneCommandTest.php b/tests/Database/PruneCommandTest.php index 2925ae4a533e..de5c42f5a228 100644 --- a/tests/Database/PruneCommandTest.php +++ b/tests/Database/PruneCommandTest.php @@ -87,7 +87,7 @@ public function testTheCommandMayBePretended() $output = $this->artisan([ '--model' => PrunableTestModelWithPrunableRecords::class, - '--pretend' => true + '--pretend' => true, ]); $this->assertEquals(<<<'EOF' From 83363cb5e74683c89b096d9567fca5528a01053b Mon Sep 17 00:00:00 2001 From: Taylor Otwell Date: Fri, 24 Sep 2021 12:53:23 -0500 Subject: [PATCH 4/4] formatting --- src/Illuminate/Database/Console/PruneCommand.php | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/Illuminate/Database/Console/PruneCommand.php b/src/Illuminate/Database/Console/PruneCommand.php index 11c327123674..9aa9f62923e8 100644 --- a/src/Illuminate/Database/Console/PruneCommand.php +++ b/src/Illuminate/Database/Console/PruneCommand.php @@ -20,7 +20,7 @@ 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} - {--pretend : Print the number of prunable records found instead of deleting them}'; + {--pretend : Display the number of prunable records found instead of deleting them}'; /** * The console command description. @@ -115,7 +115,7 @@ protected function isPrunable($model) } /** - * Report how many models will be pruned, instead of actually pruning them. + * Display how many models will be pruned. * * @param string $model * @return void @@ -123,12 +123,13 @@ protected function isPrunable($model) 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) { + if ($count === 0) { $this->info("No prunable [$model] records found."); } else { $this->info("{$count} [{$model}] records will be pruned.");