diff --git a/README.md b/README.md index 10b1f77..0e1eace 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ ![Laravel After Seeders](https://cdn.davidvandertuijn.nl/github/laravel-after-seeders.png) -This library adds seeder functionality with ***versioning*** support for [Laravel](https://laravel.com/), making it ideal for a ***production environment***. Seeders are stored in the *database/after_seeders* directory in JSON format. The execution progress of each seeder is tracked in the after_seeders table, ensuring that each seeder is only run once. +This library adds seeder functionality with ***versioning*** support for [Laravel](https://laravel.com/), making it ideal for a ***production environment***. Seeders are stored in the *database/after_seeders* directory in JSON format. The execution progress of each seeder is tracked in the after_seeders table, ensuring that each seeder is only seed once. [!["Buy Me A Coffee"](https://www.buymeacoffee.com/assets/img/custom_images/orange_img.png)](https://www.buymeacoffee.com/davidvandertuijn) @@ -37,7 +37,7 @@ php artisan vendor:publish --provider="Davidvandertuijn\LaravelAfterSeeders\Serv Use the command below to create a complete seeder based on existing records in a database table. ```shell -php artisan after-seeders:generate my_table +php artisan after-seeders:make my_table ``` The command will prompt you to include or exclude specific columns from the table. If you skip a column, it won’t be included in the seeder file. You can also define a range of record IDs to include. @@ -57,7 +57,7 @@ Enter the ending ID [13]: 13 After completion, you’ll get the following message: ``` -database/after_seeders/YYYY_MM_DD_XXXXXX_my_table.json ... SUCCESS +database/after_seeders/YYYY_MM_DD_XXXXXX_my_table.json ... DONE ``` And the seeder will look like this: @@ -79,16 +79,16 @@ And the seeder will look like this: ### Create a New Seeder Manually -Use the following command to generate an empty “after seeder” file. This option is ideal if you’re already familiar with the JSON structure and prefer to manually input the data. +Use the following command to create an empty “after seeder” file. This option is ideal if you’re already familiar with the JSON structure and prefer to manually input the data. ```shell -php artisan after-seeders:make my_table +php artisan after-seeders:placeholder my_table ``` You’ll see the following output upon success: ``` -database/after_seeders/YYYY_MM_DD_XXXXXX_my_table.json ... SUCCESS +database/after_seeders/YYYY_MM_DD_XXXXXX_my_table.json ... DONE ``` A basic structure for the JSON file will look like this: @@ -110,7 +110,7 @@ If you use [Navicat for MySQL](https://www.navicat.com/en/products/navicat-for-m To execute pending “after seeders,” run the following command: ```shell -php artisan after-seeders:run +php artisan after-seeders:seed ``` The command checks whether the specified table and columns exist. If not, the seeder will be skipped. @@ -119,7 +119,7 @@ After completion, you’ll get the following message: ``` Run batch "X". -database/after_seeders/YYYY_MM_DD_XXXXXX_my_table.json ... SUCCESS +database/after_seeders/YYYY_MM_DD_XXXXXX_my_table.json ... 1.23ms DONE ``` --- @@ -131,3 +131,46 @@ If the table has a ***created_at*** column and it’s missing from the seeder, t ***Update Or Insert*** If the seeder contains an ***id*** column, the [updateOrInsert](https://laravel.com/docs/10.x/queries#update-or-insert) method will be used. Otherwise, the [insert](https://laravel.com/docs/10.x/queries#insert-statements) method will be applied. + +### Tags + +You can use tags to organize and manage your seeders more effectively. By adding a tag, you can group seeders and seed specific groups when needed. + +#### Create a Seeder with a Tag + +To generate a seeder based on existing records and assign a tag, use the --tag option: + +```shell +php artisan after-seeders:make my_table --tag=my_tag +``` + +Similarly, you can create an empty seeder and assign a tag: + +```shell +php artisan after-seeders:placeholder my_table --tag=my_tag +``` + +Running Seeders by Tag + +When running seeders, you can specify a tag to seed only the seeders that belong to that group: + +```shell +php artisan after-seeders:seed --tag=my_tag +``` +This allows you to selectively execute seeders based on tags, making it easier to control which seeders are applied in different environments or scenarios. + +### Deployment + +When deploying your application, you can execute seeders with specific tags using the deployment command. Before doing this, you’ll need to define the tags in your project’s configuration file located at *config/after_seeders.php.* + +```php +'tags' => [ + ... +], +``` + +To run the seeders during deployment, simply use the following command: + +```shell +php artisan after-seeders:deploy +``` \ No newline at end of file diff --git a/composer.json b/composer.json index 8705779..768927e 100644 --- a/composer.json +++ b/composer.json @@ -24,5 +24,8 @@ "Davidvandertuijn\\LaravelAfterSeeders\\ServiceProvider" ] } + }, + "support": { + "url": "https://www.buymeacoffee.com/davidvandertuijn" } } diff --git a/src/Exceptions/InvalidJson.php b/src/Exceptions/ColumnNotFoundException.php similarity index 61% rename from src/Exceptions/InvalidJson.php rename to src/Exceptions/ColumnNotFoundException.php index 327fae8..455b136 100644 --- a/src/Exceptions/InvalidJson.php +++ b/src/Exceptions/ColumnNotFoundException.php @@ -4,4 +4,4 @@ use Exception; -class InvalidJson extends Exception {} +class ColumnNotFoundException extends Exception {} diff --git a/src/Exceptions/TableNotFound.php b/src/Exceptions/ColumnsNotAddedException.php similarity index 61% rename from src/Exceptions/TableNotFound.php rename to src/Exceptions/ColumnsNotAddedException.php index 0ff2f35..aae09d2 100644 --- a/src/Exceptions/TableNotFound.php +++ b/src/Exceptions/ColumnsNotAddedException.php @@ -4,4 +4,4 @@ use Exception; -class TableNotFound extends Exception {} +class ColumnsNotAddedException extends Exception {} diff --git a/src/Exceptions/ColumnNotFound.php b/src/Exceptions/InvalidJsonException.php similarity index 63% rename from src/Exceptions/ColumnNotFound.php rename to src/Exceptions/InvalidJsonException.php index d5ee39a..be1ec88 100644 --- a/src/Exceptions/ColumnNotFound.php +++ b/src/Exceptions/InvalidJsonException.php @@ -4,4 +4,4 @@ use Exception; -class ColumnNotFound extends Exception {} +class InvalidJsonException extends Exception {} diff --git a/src/Exceptions/ColumnsNotAdded.php b/src/Exceptions/TableNotFoundException.php similarity index 62% rename from src/Exceptions/ColumnsNotAdded.php rename to src/Exceptions/TableNotFoundException.php index efd6afe..b3a27b6 100644 --- a/src/Exceptions/ColumnsNotAdded.php +++ b/src/Exceptions/TableNotFoundException.php @@ -4,4 +4,4 @@ use Exception; -class ColumnsNotAdded extends Exception {} +class TableNotFoundException extends Exception {} diff --git a/src/ServiceProvider.php b/src/ServiceProvider.php index f932774..46f0b70 100644 --- a/src/ServiceProvider.php +++ b/src/ServiceProvider.php @@ -2,9 +2,10 @@ namespace Davidvandertuijn\LaravelAfterSeeders; -use Davidvandertuijn\LaravelAfterSeeders\app\Console\Commands\AfterSeeders\Generate as GenerateCommand; +use Davidvandertuijn\LaravelAfterSeeders\app\Console\Commands\AfterSeeders\Deploy as DeployCommand; use Davidvandertuijn\LaravelAfterSeeders\app\Console\Commands\AfterSeeders\Make as MakeCommand; -use Davidvandertuijn\LaravelAfterSeeders\app\Console\Commands\AfterSeeders\Run as RunCommand; +use Davidvandertuijn\LaravelAfterSeeders\app\Console\Commands\AfterSeeders\Placeholder as PlaceholderCommand; +use Davidvandertuijn\LaravelAfterSeeders\app\Console\Commands\AfterSeeders\Seed as SeedCommand; use Illuminate\Support\Facades\Config; use Illuminate\Support\Facades\File; @@ -39,9 +40,10 @@ public function boot() // Commands $this->commands([ - GenerateCommand::class, + DeployCommand::class, MakeCommand::class, - RunCommand::class, + PlaceholderCommand::class, + SeedCommand::class, ]); } } diff --git a/src/app/Console/Commands/AfterSeeders/Deploy.php b/src/app/Console/Commands/AfterSeeders/Deploy.php new file mode 100644 index 0000000..985a2ed --- /dev/null +++ b/src/app/Console/Commands/AfterSeeders/Deploy.php @@ -0,0 +1,52 @@ +getTags(); + + if (empty($tags)) { + $this->components->warn('There are no tags available.'); + + return; + } + + foreach ($tags as $tag) { + $this->components->info(sprintf( + 'Deployment tag "%s"', + $tag + )); + + $this->call('after-seeders:seed', [ + '--tag' => $tag, + ]); + } + } + + /** + * Get Tags. + */ + public function getTags() + { + return Config::get('after_seeders.tags'); + } +} diff --git a/src/app/Console/Commands/AfterSeeders/Generate.php b/src/app/Console/Commands/AfterSeeders/Generate.php deleted file mode 100644 index 5182b02..0000000 --- a/src/app/Console/Commands/AfterSeeders/Generate.php +++ /dev/null @@ -1,205 +0,0 @@ -argument('table'); - - $this->components->info(sprintf( - 'Generate after seeder for table "%s".', - $table - )); - - try { - $this->ensureTableExist($table); - } catch (TableNotFoundException) { - $this->components->error(sprintf( - 'Table "%s" does not exists.', - $table - )); - - return; - } - - $path = $this->getPath(); - $filename = $this->getFilename($table); - $columns = $this->getColumns($table); - - try { - $this->checkColumns($columns); - } catch (ColumnsNotAddedException) { - $this->components->error('Columns not added.'); - - return; - } - - $range = $this->getRange($table); - $records = $this->getRecords($table, $columns, $range); - $json = $this->getJson($records); - - $this->create($path, $filename, $json); - } - - /** - * Check Columns. - */ - protected function checkColumns(array $columns): void - { - if (count($columns) == 0) { - throw new ColumnsNotAddedException; - } - } - - /** - * Create. - */ - protected function create(string $path, string $filename, string $json): void - { - File::put($path.'/'.$filename, $json); - - $this->components->twoColumnDetail( - sprintf('%s/%s', - $path, - $filename - ), - 'SUCCESS' - ); - } - - /** - * Ensure Table Exist. - */ - protected function ensureTableExist(string $table): void - { - if (! Schema::hasTable($table)) { - throw new TableNotFoundException; - } - } - - /** - * Get Columns - */ - protected function getColumns(string $table): array - { - $columns = []; - - $this->line(sprintf( - '%s', - sprintf( - 'Columns for table "%s".', - $table - ) - )); - - $columnListing = Schema::getColumnListing($table); - - foreach ($columnListing as $column) { - if ($this->confirm(sprintf( - 'Would you like to add the column "%s" ?', - $column - ))) { - $columns[] = $column; - } - } - - return $columns; - } - - /** - * Get Date Prefix. - */ - protected function getDatePrefix(): string - { - return date('Y_m_d_His'); - } - - /** - * Get Filename. - */ - protected function getFilename(string $table): string - { - return $this->getDatePrefix().'_'.$table.'.json'; - } - - /** - * Get Json. - */ - protected function getJson(\Illuminate\Support\Collection $records): string - { - $records = [ - 'RECORDS' => $records->toArray(), - ]; - - return json_encode($records, JSON_PRETTY_PRINT | JSON_HEX_TAG | JSON_HEX_AMP | JSON_HEX_APOS | JSON_HEX_QUOT); - } - - /** - * Get Max Id. - */ - protected function getMaxId(string $table) - { - return DB::table($table)->max('id'); - } - - /** - * Get Path. - */ - protected function getPath(): string - { - return Config::get('after_seeders.path'); - } - - /** - * Get Range - */ - protected function getRange(string $table): array - { - $this->line(sprintf( - '%s', - sprintf( - 'Select range for table "%s".', - $table - ) - )); - - $from = $this->ask('Enter the starting ID', 0); - $to = $this->ask('Enter the ending ID', $this->getMaxId($table)); - - return range($from, $to); - } - - /** - * Get Records. - */ - protected function getRecords(string $table, array $columns, array $range): \Illuminate\Support\Collection - { - return DB::table($table) - ->select($columns) - ->whereIn('id', $range) - ->get(); - } -} diff --git a/src/app/Console/Commands/AfterSeeders/Make.php b/src/app/Console/Commands/AfterSeeders/Make.php index a374aec..89c02d6 100644 --- a/src/app/Console/Commands/AfterSeeders/Make.php +++ b/src/app/Console/Commands/AfterSeeders/Make.php @@ -2,10 +2,11 @@ namespace Davidvandertuijn\LaravelAfterSeeders\app\Console\Commands\AfterSeeders; -use Davidvandertuijn\LaravelAfterSeeders\Exceptions\TableNotFound as TableNotFoundException; -use Exception; +use Davidvandertuijn\LaravelAfterSeeders\Exceptions\ColumnsNotAddedException; +use Davidvandertuijn\LaravelAfterSeeders\Exceptions\TableNotFoundException; use Illuminate\Console\Command; use Illuminate\Support\Facades\Config; +use Illuminate\Support\Facades\DB; use Illuminate\Support\Facades\File; use Illuminate\Support\Facades\Schema; @@ -19,7 +20,7 @@ class Make extends Command /** * @var string */ - protected $description = 'Make after seeder'; + protected $description = 'Make an after seeder'; /** * Handle. @@ -29,7 +30,7 @@ public function handle(): void $table = $this->argument('table'); $this->components->info(sprintf( - 'Make after seeder for table "%s".', + 'Make an after seeder for table "%s".', $table )); @@ -46,30 +47,46 @@ public function handle(): void $path = $this->getPath(); $filename = $this->getFilename($table); - $json = $this->getJson(); + $columns = $this->getColumns($table); + + try { + $this->checkColumns($columns); + } catch (ColumnsNotAddedException) { + $this->components->error('Columns not added.'); + + return; + } + + $range = $this->getRange($table); + $records = $this->getRecords($table, $columns, $range); + $json = $this->getJson($records); $this->create($path, $filename, $json); } + /** + * Check Columns. + */ + protected function checkColumns(array $columns): void + { + if (count($columns) == 0) { + throw new ColumnsNotAddedException; + } + } + /** * Create. */ protected function create(string $path, string $filename, string $json): void { - try { - File::put($path.'/'.$filename, $json); - } catch (Exception $e) { - $this->components->error($e->getMessage()); - - return; - } + File::put($path.'/'.$filename, $json); $this->components->twoColumnDetail( sprintf('%s/%s', $path, $filename ), - 'SUCCESS' + 'DONE' ); } @@ -83,6 +100,35 @@ protected function ensureTableExist(string $table): void } } + /** + * Get Columns + */ + protected function getColumns(string $table): array + { + $columns = []; + + $this->line(sprintf( + '%s', + sprintf( + 'Columns for table "%s".', + $table + ) + )); + + $columnListing = Schema::getColumnListing($table); + + foreach ($columnListing as $column) { + if ($this->confirm(sprintf( + 'Would you like to add the column "%s" ?', + $column + ))) { + $columns[] = $column; + } + } + + return $columns; + } + /** * Get Date Prefix. */ @@ -102,19 +148,31 @@ protected function getFilename(string $table): string /** * Get Json. */ - protected function getJson(): string + protected function getJson(\Illuminate\Support\Collection $records): string { - $records = [ - 'RECORDS' => [ - [ - 'name' => 'Example', - ], - ], - ]; + $records = []; + + $tag = $this->option('tag'); + + if (! empty($tag)) { + $records['TAG'] = $tag; + } + + $records = array_merge($records, [ + 'RECORDS' => $records->toArray(), + ]); return json_encode($records, JSON_PRETTY_PRINT | JSON_HEX_TAG | JSON_HEX_AMP | JSON_HEX_APOS | JSON_HEX_QUOT); } + /** + * Get Max Id. + */ + protected function getMaxId(string $table) + { + return DB::table($table)->max('id'); + } + /** * Get Path. */ @@ -122,4 +180,34 @@ protected function getPath(): string { return Config::get('after_seeders.path'); } + + /** + * Get Range + */ + protected function getRange(string $table): array + { + $this->line(sprintf( + '%s', + sprintf( + 'Select range for table "%s".', + $table + ) + )); + + $from = $this->ask('Enter the starting ID', 0); + $to = $this->ask('Enter the ending ID', $this->getMaxId($table)); + + return range($from, $to); + } + + /** + * Get Records. + */ + protected function getRecords(string $table, array $columns, array $range): \Illuminate\Support\Collection + { + return DB::table($table) + ->select($columns) + ->whereIn('id', $range) + ->get(); + } } diff --git a/src/app/Console/Commands/AfterSeeders/Placeholder.php b/src/app/Console/Commands/AfterSeeders/Placeholder.php new file mode 100644 index 0000000..afb1521 --- /dev/null +++ b/src/app/Console/Commands/AfterSeeders/Placeholder.php @@ -0,0 +1,133 @@ +argument('table'); + + $this->components->info(sprintf( + 'Create an after seeder placeholder for table "%s".', + $table + )); + + try { + $this->ensureTableExist($table); + } catch (TableNotFoundException) { + $this->components->error(sprintf( + 'Table "%s" does not exists.', + $table + )); + + return; + } + + $path = $this->getPath(); + $filename = $this->getFilename($table); + $json = $this->getJson(); + + $this->create($path, $filename, $json); + } + + /** + * Create. + */ + protected function create(string $path, string $filename, string $json): void + { + try { + File::put($path.'/'.$filename, $json); + } catch (Exception $e) { + $this->components->error($e->getMessage()); + + return; + } + + $this->components->twoColumnDetail( + sprintf('%s/%s', + $path, + $filename + ), + 'DONE' + ); + } + + /** + * Ensure Table Exist. + */ + protected function ensureTableExist(string $table): void + { + if (! Schema::hasTable($table)) { + throw new TableNotFoundException; + } + } + + /** + * Get Date Prefix. + */ + protected function getDatePrefix(): string + { + return date('Y_m_d_His'); + } + + /** + * Get Filename. + */ + protected function getFilename(string $table): string + { + return $this->getDatePrefix().'_'.$table.'.json'; + } + + /** + * Get Json. + */ + protected function getJson(): string + { + $records = []; + + $tag = $this->option('tag'); + + if (! empty($tag)) { + $records['TAG'] = $tag; + } + + $records = array_merge($records, [ + 'RECORDS' => [ + [ + 'name' => 'Example', + ], + ], + ]); + + return json_encode($records, JSON_PRETTY_PRINT | JSON_HEX_TAG | JSON_HEX_AMP | JSON_HEX_APOS | JSON_HEX_QUOT); + } + + /** + * Get Path. + */ + protected function getPath(): string + { + return Config::get('after_seeders.path'); + } +} diff --git a/src/app/Console/Commands/AfterSeeders/Run.php b/src/app/Console/Commands/AfterSeeders/Seed.php similarity index 74% rename from src/app/Console/Commands/AfterSeeders/Run.php rename to src/app/Console/Commands/AfterSeeders/Seed.php index 09246aa..9de982a 100644 --- a/src/app/Console/Commands/AfterSeeders/Run.php +++ b/src/app/Console/Commands/AfterSeeders/Seed.php @@ -2,26 +2,28 @@ namespace Davidvandertuijn\LaravelAfterSeeders\app\Console\Commands\AfterSeeders; -use Davidvandertuijn\LaravelAfterSeeders\Exceptions\ColumnNotFound as ColumnNotFoundException; -use Davidvandertuijn\LaravelAfterSeeders\Exceptions\InvalidJson as InvalidJsonException; -use Davidvandertuijn\LaravelAfterSeeders\Exceptions\TableNotFound as TableNotFoundException; +use Davidvandertuijn\LaravelAfterSeeders\Exceptions\ColumnNotFoundException; +use Davidvandertuijn\LaravelAfterSeeders\Exceptions\InvalidJsonException; +use Davidvandertuijn\LaravelAfterSeeders\Exceptions\TableNotFoundException; use Illuminate\Console\Command; use Illuminate\Support\Arr; use Illuminate\Support\Facades\Config; use Illuminate\Support\Facades\DB; use Illuminate\Support\Facades\Schema; -class Run extends Command +class Seed extends Command { + public ConsoleService $consoleService; + /** * @var string */ - protected $signature = 'after-seeders:run'; + protected $signature = 'after-seeders:seed {--tag=}'; /** * @var string */ - protected $description = 'Running after seeders'; + protected $description = 'Seed after seeders'; /** * Handle. @@ -33,8 +35,7 @@ public function handle(): void $seederNames = $this->getSeederNames($files); $ran = $this->getRan(); $pendingSeeders = $this->pendingSeeders($seederNames, $ran); - - $this->runPending($pendingSeeders); + $this->seedPending($pendingSeeders); } /** @@ -50,28 +51,12 @@ protected function checkPendingSeeders(array $seeders): bool foreach ($seeders as $seeder) { $table = $this->getTable($seeder); - - // Ensure table exist - - try { - $this->ensureTableExist($table); - } catch (TableNotFoundException) { - $errors++; - - $this->components->error(sprintf( - 'Table "%s" does not exists.', - $table - )); - - continue; - } - $file = $this->getPath().'/'.$seeder.'.json'; - // Get records + // Contents try { - $records = $this->getRecords($file); + $contents = $this->getContents($file); } catch (InvalidJsonException) { $errors++; @@ -88,8 +73,39 @@ protected function checkPendingSeeders(array $seeders): bool continue; } + $records = Arr::get($contents, 'RECORDS', []); $columns = $this->getColumns($records); + // Tag + + $tag = Arr::get($contents, 'TAG'); + if ($tag !== $this->option('tag')) { + $this->components->twoColumnDetail( + $seeder, + $tag.' '.sprintf( + '%s', + 'SKIPPED' + ) + ); + + continue; + } + + // Ensure table exist + + try { + $this->ensureTableExist($table); + } catch (TableNotFoundException) { + $errors++; + + $this->components->error(sprintf( + 'Table "%s" does not exists.', + $table + )); + + continue; + } + // Ensure columns exist try { @@ -117,7 +133,7 @@ protected function checkPendingSeeders(array $seeders): bool $seeder, sprintf( '%s', - 'SUCCESS' + 'DONE' ) ); } @@ -156,11 +172,11 @@ protected function ensureTableExist(string $table): void /** * Get Columns. */ - protected function getColumns(&$records): array + protected function getColumns(array $records): array { $columns = []; - foreach ($records['RECORDS'] as $record) { + foreach ($records as $record) { foreach (array_keys($record) as $column) { if (! in_array($column, $columns)) { $columns[] = $column; @@ -200,29 +216,29 @@ protected function getRan(): array } /** - * Get Records. + * Get Contents. */ - protected function getRecords(string $file): array + protected function getContents(string $file): array { - $records = file_get_contents($file); + $contents = file_get_contents($file); if (function_exists('json_validate')) { - $isValid = json_validate($records); + $isValid = json_validate($contents); } else { - $isValid = json_decode($records) !== null && json_last_error() === JSON_ERROR_NONE; + $isValid = json_decode($contents) !== null && json_last_error() === JSON_ERROR_NONE; } if (! $isValid) { throw new InvalidJsonException; } - $records = json_decode($records, true); + $contents = json_decode($contents, true); - if (! Arr::exists($records, 'RECORDS')) { + if (! Arr::exists($contents, 'RECORDS')) { throw new InvalidJsonException; } - return $records; + return $contents; } /** @@ -261,7 +277,7 @@ protected function getSeederNames(array $files): array */ protected function getTable(string $seeder): string { - // Remove Prefix 'YYYY_MM_DD_XXXXXX_' + // Remove prefix 'YYYY_MM_DD_XXXXXX_'. $prefix = substr($seeder, 0, 18); return str_replace($prefix, '', $seeder); @@ -274,6 +290,7 @@ protected function log(string $seeder, int $batch) { DB::table('after_seeders')->insert([ 'seeder' => $seeder, + 'tag' => $this->option('tag'), 'batch' => $batch, 'created_at' => now(), ]); @@ -288,9 +305,9 @@ protected function pendingSeeders(array $seederNames, array $ran): array } /** - * Run Pending. + * Seed Pending. */ - protected function runPending(array $seeders): void + protected function seedPending(array $seeders): void { if (count($seeders) == 0) { $this->components->warn('There are no after seeders available.'); @@ -302,27 +319,31 @@ protected function runPending(array $seeders): void return; } - $this->runPendingSeeders($seeders); + $this->seedPendingSeeders($seeders); } /** - * Run Pending Seeders. + * Seed Pending Seeders. */ - protected function runPendingSeeders(array $seeders): void + protected function seedPendingSeeders(array $seeders): void { $batch = $this->getNextBatchNumber(); $this->components->info(sprintf( - 'Run batch "%s"', + 'Seed batch "%s"', $batch )); + $skipped = 0; + foreach ($seeders as $seeder) { $table = $this->getTable($seeder); $file = $this->getPath().'/'.$seeder.'.json'; + // Contents + try { - $records = $this->getRecords($file); + $contents = $this->getContents($file); } catch (InvalidJsonException) { $this->components->twoColumnDetail( $seeder, @@ -337,35 +358,55 @@ protected function runPendingSeeders(array $seeders): void continue; } + // Tag + + $tag = Arr::get($contents, 'TAG'); + if ($tag !== $this->option('tag')) { + $skipped++; + + continue; + } + + $records = Arr::get($contents, 'RECORDS', []); + + $start = microtime(true); + $this->seed($table, $records); + $stop = microtime(true); + $time = ($stop - $start) * 1000; + + $this->log($seeder, $batch); + $this->components->twoColumnDetail( $seeder, sprintf( - '%s', - 'SUCCESS' + '%s %s', + number_format($time, 2).'ms', + 'DONE' ) ); + } - $this->seed($table, $records); - $this->log($seeder, $batch); + if ($skipped == count($seeders)) { + $this->components->warn('There are no after seeders available.'); } } /** * Seed. */ - protected function seed(string $table, array &$records): void + protected function seed(string $table, array $records): void { Schema::disableForeignKeyConstraints(); - foreach ($records['RECORDS'] as $record) { - // Created At + foreach ($records as $record) { + // Created at if (! array_key_exists('created_at', $record) && Schema::hasColumn($table, 'created_at')) { $record['created_at'] = now(); } - // Update Or Insert + // Update or insert if (Arr::exists($record, 'id')) { DB::table($table)->updateOrInsert( diff --git a/src/config/after_seeders.php b/src/config/after_seeders.php index d6cbaca..e95d4fe 100644 --- a/src/config/after_seeders.php +++ b/src/config/after_seeders.php @@ -3,5 +3,6 @@ return [ 'path' => env('AFTER_SEEDERS_PATH', database_path('after_seeders')), + 'tags' => [], ]; diff --git a/src/database/migrations/2020_10_26_000001_create_after_seeders_table.php b/src/database/migrations/2020_10_26_000001_create_after_seeders_table.php index 15b7005..127c4c6 100644 --- a/src/database/migrations/2020_10_26_000001_create_after_seeders_table.php +++ b/src/database/migrations/2020_10_26_000001_create_after_seeders_table.php @@ -4,12 +4,12 @@ use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\Schema; -class CreateAfterSeedersTable extends Migration +return new class extends Migration { /** * Run the migrations. */ - public function up() + public function up(): void { Schema::create('after_seeders', function (Blueprint $table) { $table->bigIncrements('id'); @@ -22,8 +22,8 @@ public function up() /** * Reverse the migrations. */ - public function down() + public function down(): void { Schema::dropIfExists('after_seeders'); } -} +}; diff --git a/src/database/migrations/2024_10_05_000001_add_tag_to_after_seeders_table.php b/src/database/migrations/2024_10_05_000001_add_tag_to_after_seeders_table.php new file mode 100644 index 0000000..e6b84e7 --- /dev/null +++ b/src/database/migrations/2024_10_05_000001_add_tag_to_after_seeders_table.php @@ -0,0 +1,28 @@ +string('tag', 191)->after('seeder')->nullable(); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::table('after_seeders', function (Blueprint $table) { + // + }); + } +};