Skip to content

Commit

Permalink
Initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
Kyzegs committed Jan 19, 2023
0 parents commit 5277285
Show file tree
Hide file tree
Showing 7 changed files with 279 additions and 0 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
/vendor
25 changes: 25 additions & 0 deletions composer.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
{
"name": "kyzegs/prunable",
"description": "Laravel's prunable traits without force deleting",
"authors": [
{
"name": "Sebastiaan",
"email": "[email protected]"
}
],
"require-dev": {
"laravel/pint": "^1.0"
},
"autoload": {
"psr-4": {
"Kyzegs\\Prunable\\": "src/"
}
},
"extra": {
"laravel": {
"providers": [
"Kyzegs\\Providers\\PrunableProvider"
]
}
}
}
85 changes: 85 additions & 0 deletions composer.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

46 changes: 46 additions & 0 deletions src/Concerns/SafeMassPrunable.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
<?php

namespace Kyzegs\Prunable\Concerns;

use Illuminate\Database\Events\ModelsPruned;
use LogicException;

trait SafeMassPrunable
{
/**
* Prune all prunable models in the database.
*
* @param int $chunkSize
* @return int
*/
public function pruneAll(int $chunkSize = 1000)
{
$query = tap($this->prunable(), function ($query) use ($chunkSize) {
$query->when(! $query->getQuery()->limit, function ($query) use ($chunkSize) {
$query->limit($chunkSize);
});
});

$total = 0;

do {
$total += $count = $query->delete();

if ($count > 0) {
event(new ModelsPruned(static::class, $total));
}
} while ($count > 0);

return $total;
}

/**
* Get the prunable model query.
*
* @return \Illuminate\Database\Eloquent\Builder
*/
public function prunable()
{
throw new LogicException('Please implement the prunable method on your model.');
}
}
62 changes: 62 additions & 0 deletions src/Concerns/SafePrunable.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
<?php

namespace Kyzegs\Prunable\Concerns;

use Illuminate\Database\Events\ModelsPruned;
use LogicException;

trait SafePrunable
{
/**
* Prune all prunable models in the database.
*
* @param int $chunkSize
* @return int
*/
public function pruneAll(int $chunkSize = 1000)
{
$total = 0;

$this->prunable()->chunkById($chunkSize, function ($models) use (&$total) {
$models->each->prune();

$total += $models->count();

event(new ModelsPruned(static::class, $total));
});

return $total;
}

/**
* Get the prunable model query.
*
* @return \Illuminate\Database\Eloquent\Builder
*/
public function prunable()
{
throw new LogicException('Please implement the prunable method on your model.');
}

/**
* Prune the model in the database.
*
* @return bool|null
*/
public function prune()
{
$this->pruning();

return $this->delete();
}

/**
* Prepare the model for pruning.
*
* @return void
*/
protected function pruning()
{
//
}
}
29 changes: 29 additions & 0 deletions src/Console/Commands/PruneCommand.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<?php

namespace Kyzegs\Prunable\Console\Commands;

use Illuminate\Database\Eloquent\MassPrunable;
use Illuminate\Database\Eloquent\Prunable;
use Kyzegs\Prunable\Concerns\SafeMassPrunable;
use Kyzegs\Prunable\Concerns\SafePrunable;

class PruneCommand extends \Illuminate\Database\Console\PruneCommand
{
/**
* Determine if the given model class is prunable.
*
* @param string $model
* @return bool
*/
protected function isPrunable($model)
{
$uses = class_uses_recursive($model);

return ! empty(array_intersect($uses, [
Prunable::class,
MassPrunable::class,
SafePrunable::class,
SafeMassPrunable::class,
]));
}
}
31 changes: 31 additions & 0 deletions src/Providers/PrunableProvider.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<?php

namespace Kyzegs\Prunable\Providers;

use Illuminate\Support\ServiceProvider;
use Kyzegs\Prunable\Console\Commands\PruneCommand;

class PrunableProvider extends ServiceProvider
{
/**
* Register any application services.
*
* @return void
*/
public function register()
{
$this->app->extend(\Illuminate\Database\Console\PruneCommand::class, fn () => new PruneCommand());
}

/**
* Bootstrap any package services.
*
* @return void
*/
public function boot()
{
if ($this->app->runningInConsole()) {
$this->commands([PruneCommand::class]);
}
}
}

0 comments on commit 5277285

Please sign in to comment.