Skip to content

Commit 418aaab

Browse files
Added support for Laravel 11.36
1 parent befc917 commit 418aaab

File tree

8 files changed

+137
-34
lines changed

8 files changed

+137
-34
lines changed

README.md

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -86,16 +86,19 @@ After that, add to the array the names of the tables for which you want to expor
8686
That's it. Now you can run the [`php artisan schema:dump`](https://laravel.com/docs/migrations#squashing-migrations)
8787
console command and enjoy the result.
8888

89-
> Note
89+
> [!NOTE]
9090
>
9191
> If you need to delete files from a folder to which a table is related (for example, the `migrations` table),
9292
> you can specify an array of two values in the parameter, where the first element should be the name of the column
9393
> containing the file name, and the second element should be absolute or relative folder path.
9494
95-
> Attention!
95+
> [!WARNING]
9696
>
97-
> Laravel does not know how to report the presence of the `--prune` parameter when calling the `artisan schema:dump`
98-
> console command, so specifying paths to folders will always delete files from them.
97+
> Laravel 11.35.2 and below does not know how to report the presence of the `--prune` parameter when calling the
98+
> `artisan schema:dump` console command, so specifying paths to folders will always delete files from them.
99+
>
100+
> Starting with Laravel version 11.36, files will be deleted only when calling the console command with the
101+
> `--prune` parameter.
99102
100103

101104
## License

src/Listeners/DumpListener.php renamed to src/Listeners/DumpedListener.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
use DragonCode\LaravelDataDumper\Service\Tables;
99
use Illuminate\Database\Events\SchemaDumped;
1010

11-
class DumpListener
11+
class DumpedListener extends Listener
1212
{
1313
public function __construct(
1414
protected readonly Tables $tables,

src/Listeners/FilesListener.php

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace DragonCode\LaravelDataDumper\Listeners;
6+
7+
use DragonCode\LaravelDataDumper\Service\Files;
8+
use DragonCode\LaravelDataDumper\Service\Tables;
9+
use Illuminate\Database\Events\MigrationsPruned;
10+
use Illuminate\Database\Events\SchemaDumped;
11+
12+
class FilesListener extends Listener
13+
{
14+
public function __construct(
15+
protected readonly Tables $tables,
16+
protected readonly Files $files
17+
) {}
18+
19+
public function handle(MigrationsPruned|SchemaDumped $event): void
20+
{
21+
$this->files->clean(
22+
$event->connection,
23+
$this->tables->dumpable()
24+
);
25+
}
26+
}

src/Listeners/Listener.php

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace DragonCode\LaravelDataDumper\Listeners;
6+
7+
abstract class Listener {}

src/Service/Dumper.php

Lines changed: 1 addition & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,11 @@
77
use DragonCode\LaravelDataDumper\Schema\MySqlSchemaState;
88
use DragonCode\LaravelDataDumper\Schema\PostgresSchemaState;
99
use DragonCode\LaravelDataDumper\Schema\SQLiteSchemaState;
10-
use Illuminate\Contracts\Database\Query\Builder;
1110
use Illuminate\Database\Connection;
1211
use Illuminate\Database\MySqlConnection;
1312
use Illuminate\Database\PostgresConnection;
1413
use Illuminate\Database\Schema\SchemaState;
1514
use Illuminate\Database\SQLiteConnection;
16-
use Illuminate\Support\Facades\Schema;
1715

1816
class Dumper
1917
{
@@ -23,13 +21,9 @@ public function __construct(
2321

2422
public function dump(Connection $connection, string $path, array $tables): void
2523
{
26-
foreach ($tables as $table => $params) {
24+
foreach (array_keys($tables) as $table) {
2725
if ($this->isNotMigration($table)) {
2826
$this->export($connection, $path, $table);
29-
30-
if (is_array($params) && count($params) === 2) {
31-
$this->deleteFiles($connection, $table, $params[0], $params[1]);
32-
}
3327
}
3428
}
3529
}
@@ -41,17 +35,6 @@ protected function export(Connection $connection, string $path, string $table):
4135
?->dump($connection, $path);
4236
}
4337

44-
protected function deleteFiles(Connection $connection, string $table, string $column, string $path): void
45-
{
46-
$connection->table($table)->when(
47-
$this->hasIdColumn($connection, $table),
48-
fn (Builder $query) => $query->lazyById(),
49-
fn (Builder $query) => $query->lazyById(column: $column),
50-
)->each(
51-
fn ($item) => $this->files->delete($path, $item->{$column})
52-
);
53-
}
54-
5538
protected function schemaState(Connection $connection): ?SchemaState
5639
{
5740
return match (get_class($connection)) {
@@ -71,9 +54,4 @@ protected function migrationTable(): string
7154
{
7255
return is_array($migration = config('database.migrations')) ? $migration['table'] : $migration;
7356
}
74-
75-
protected function hasIdColumn(Connection $connection, string $table): bool
76-
{
77-
return Schema::connection($connection->getName())->hasColumn($table, 'id');
78-
}
7957
}

src/Service/Files.php

Lines changed: 34 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,33 @@
77
use Closure;
88
use DragonCode\Support\Facades\Filesystem\File;
99
use DragonCode\Support\Facades\Helpers\Str;
10+
use Illuminate\Contracts\Database\Query\Builder;
11+
use Illuminate\Database\Connection;
12+
use Illuminate\Support\Facades\Schema;
1013

1114
class Files
1215
{
13-
public function delete(string $path, string $filename): void
16+
public function clean(Connection $connection, array $tables): void
17+
{
18+
foreach ($tables as $table => $params) {
19+
if (is_array($params) && count($params) === 2) {
20+
$this->deleteFiles($connection, $table, $params[0], $params[1]);
21+
}
22+
}
23+
}
24+
25+
protected function deleteFiles(Connection $connection, string $table, string $column, string $path): void
26+
{
27+
$connection->table($table)->when(
28+
$this->hasIdColumn($connection, $table),
29+
fn (Builder $query) => $query->lazyById(),
30+
fn (Builder $query) => $query->lazyById(column: $column),
31+
)->each(
32+
fn ($item) => $this->delete($path, $item->{$column})
33+
);
34+
}
35+
36+
protected function delete(string $path, string $filename): void
1437
{
1538
if (! $dir = $this->directory($path)) {
1639
return;
@@ -29,7 +52,11 @@ protected function directory(string $path): false|string
2952
return rtrim($path, '\\/');
3053
}
3154

32-
return realpath(base_path($path));
55+
if (is_dir($path = realpath(base_path($path)))) {
56+
return rtrim($path, '\\/');
57+
}
58+
59+
return false;
3360
}
3461

3562
protected function findFile(string $path, string $filename): string
@@ -48,4 +75,9 @@ protected function resolvePath(string $path): string
4875
{
4976
return str_replace('\\', '/', $path);
5077
}
78+
79+
protected function hasIdColumn(Connection $connection, string $table): bool
80+
{
81+
return Schema::connection($connection->getName())->hasColumn($table, 'id');
82+
}
5183
}

src/ServiceProvider.php

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,9 @@
55
namespace DragonCode\LaravelDataDumper;
66

77
use DragonCode\LaravelDataDumper\Concerns\About;
8-
use DragonCode\LaravelDataDumper\Listeners\DumpListener;
8+
use DragonCode\LaravelDataDumper\Listeners\DumpedListener;
9+
use DragonCode\LaravelDataDumper\Listeners\FilesListener;
10+
use Illuminate\Database\Events\MigrationsPruned;
911
use Illuminate\Database\Events\SchemaDumped;
1012
use Illuminate\Support\Facades\Event;
1113
use Illuminate\Support\ServiceProvider as BaseServiceProvider;
@@ -29,7 +31,11 @@ public function register(): void
2931

3032
protected function bootListener(): void
3133
{
32-
Event::listen(SchemaDumped::class, DumpListener::class);
34+
Event::listen(SchemaDumped::class, DumpedListener::class);
35+
36+
class_exists(MigrationsPruned::class)
37+
? Event::listen(MigrationsPruned::class, FilesListener::class)
38+
: Event::listen(SchemaDumped::class, FilesListener::class);
3339
}
3440

3541
protected function registerConfig(): void

tests/Unit/Dumps/DeleteFilesTest.php

Lines changed: 53 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,10 @@
33
use DragonCode\Support\Facades\Filesystem\Directory;
44
use DragonCode\Support\Facades\Filesystem\File;
55
use Illuminate\Database\Console\DumpCommand;
6+
use Illuminate\Foundation\Application;
67
use Illuminate\Support\Facades\Artisan;
78

8-
it('checks the export of data from tables to a dump file', function () {
9+
it('checks for file deletion on older versions of Laravel', function () {
910
Directory::ensureDelete(base_path('to_delete'));
1011

1112
circleProcess(fn (int $i) => File::store(base_path("to_delete/first/qwerty1File$i.stub"), '1'));
@@ -25,4 +26,54 @@
2526
circleProcess(fn (int $i) => expect(
2627
file_exists(base_path("to_delete/third/file$i.stub"))
2728
)->toBeTrue());
28-
})->group('SQLite', 'MySQL', 'Postgres');
29+
})->group('SQLite', 'MySQL', 'Postgres')->skip(
30+
version_compare(Application::VERSION, '11.36.0', '>=')
31+
);
32+
33+
it('checks for file deletion on new version of Laravel', function () {
34+
Directory::ensureDelete(base_path('to_delete'));
35+
36+
circleProcess(fn (int $i) => File::store(base_path("to_delete/first/qwerty1File$i.stub"), '1'));
37+
circleProcess(fn (int $i) => File::store(base_path("to_delete/second/sub/qwerty2File$i.stub"), '1'));
38+
circleProcess(fn (int $i) => File::store(base_path("to_delete/third/file$i.stub"), '1'));
39+
40+
Artisan::call(DumpCommand::class, ['--path' => dumpStoragePath(), '----prune' => true]);
41+
42+
circleProcess(fn (int $i) => expect(
43+
file_exists(base_path("to_delete/first/qwerty1File$i.stub"))
44+
)->toBe($i % 2 === 0));
45+
46+
circleProcess(fn (int $i) => expect(
47+
file_exists(base_path("to_delete/second/sub/qwerty2File$i.stub"))
48+
)->toBeFalse());
49+
50+
circleProcess(fn (int $i) => expect(
51+
file_exists(base_path("to_delete/third/file$i.stub"))
52+
)->toBeTrue());
53+
})->group('SQLite', 'MySQL', 'Postgres')->skip(
54+
version_compare(Application::VERSION, '11.36.0', '<')
55+
);
56+
57+
it('checks for skipping file deletion on new version of Laravel', function () {
58+
Directory::ensureDelete(base_path('to_delete'));
59+
60+
circleProcess(fn (int $i) => File::store(base_path("to_delete/first/qwerty1File$i.stub"), '1'));
61+
circleProcess(fn (int $i) => File::store(base_path("to_delete/second/sub/qwerty2File$i.stub"), '1'));
62+
circleProcess(fn (int $i) => File::store(base_path("to_delete/third/file$i.stub"), '1'));
63+
64+
Artisan::call(DumpCommand::class, ['--path' => dumpStoragePath()]);
65+
66+
circleProcess(fn (int $i) => expect(
67+
file_exists(base_path("to_delete/first/qwerty1File$i.stub"))
68+
)->toBeTrue());
69+
70+
circleProcess(fn (int $i) => expect(
71+
file_exists(base_path("to_delete/second/sub/qwerty2File$i.stub"))
72+
)->toBeTrue());
73+
74+
circleProcess(fn (int $i) => expect(
75+
file_exists(base_path("to_delete/third/file$i.stub"))
76+
)->toBeTrue());
77+
})->group('SQLite', 'MySQL', 'Postgres')->skip(
78+
version_compare(Application::VERSION, '11.36.0', '<')
79+
);

0 commit comments

Comments
 (0)