Skip to content

Commit 22e2686

Browse files
committed
wip
1 parent ebde2c6 commit 22e2686

File tree

10 files changed

+242
-3
lines changed

10 files changed

+242
-3
lines changed
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<?php
2+
3+
namespace Tempest\Database\Config;
4+
5+
final class SeederConfig
6+
{
7+
public function __construct(
8+
/** @var array<array-key, class-string<\Tempest\Database\DatabaseSeeder>> */
9+
public array $seeders = [],
10+
) {}
11+
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
<?php
2+
3+
use Tempest\Database\Config\SeederConfig;
4+
5+
return new SeederConfig();
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<?php
2+
3+
namespace Tempest\Database;
4+
5+
use UnitEnum;
6+
7+
interface DatabaseSeeder
8+
{
9+
public function run(null|string|UnitEnum $database): void;
10+
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
<?php
2+
3+
namespace Tempest\Database;
4+
5+
use Tempest\Database\Config\SeederConfig;
6+
use Tempest\Discovery\Discovery;
7+
use Tempest\Discovery\DiscoveryLocation;
8+
use Tempest\Discovery\IsDiscovery;
9+
use Tempest\Reflection\ClassReflector;
10+
11+
final class SeederDiscovery implements Discovery
12+
{
13+
use IsDiscovery;
14+
15+
public function __construct(
16+
private SeederConfig $seederConfig,
17+
) {}
18+
19+
public function discover(DiscoveryLocation $location, ClassReflector $class): void
20+
{
21+
if ($class->implements(DatabaseSeeder::class)) {
22+
$this->discoveryItems->add($location, $class->getName());
23+
}
24+
}
25+
26+
public function apply(): void
27+
{
28+
foreach ($this->discoveryItems as $discoveryItem) {
29+
$this->seederConfig->seeders[] = $discoveryItem;
30+
}
31+
}
32+
}
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
<?php
2+
3+
namespace Tempest\Framework\Commands;
4+
5+
use Tempest\Console\ConsoleArgument;
6+
use Tempest\Console\ConsoleCommand;
7+
use Tempest\Console\HasConsole;
8+
use Tempest\Console\Middleware\CautionMiddleware;
9+
use Tempest\Console\Middleware\ForceMiddleware;
10+
use Tempest\Container\Container;
11+
use Tempest\Database\Config\SeederConfig;
12+
13+
final class DatabaseSeedCommand
14+
{
15+
use HasConsole;
16+
17+
public function __construct(
18+
private readonly Container $container,
19+
private readonly SeederConfig $seederConfig,
20+
) {}
21+
22+
#[ConsoleCommand(
23+
aliases: ['db:seed'],
24+
middleware: [ForceMiddleware::class, CautionMiddleware::class],
25+
)]
26+
public function __invoke(
27+
#[ConsoleArgument(description: 'Use a specific database.')]
28+
?string $database = null,
29+
): void
30+
{
31+
foreach ($this->seederConfig->seeders as $seederClass) {
32+
/** @var \Tempest\Database\DatabaseSeeder $seeder */
33+
$seeder = $this->container->get($seederClass);
34+
$seeder->run($database);
35+
36+
$this->console->keyValue(
37+
key: "<style='fg-gray'>{$seederClass}</style>",
38+
value: "<style='fg-green'>SEEDED</style>",
39+
);
40+
}
41+
}
42+
}

src/Tempest/Framework/Commands/MigrateFreshCommand.php

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,8 @@ public function __invoke(
3636
bool $validate = true,
3737
#[ConsoleArgument(description: 'Use a specific database.')]
3838
?string $database = null,
39+
#[ConsoleArgument(description: 'Run all database seeders after the database has been migrated')]
40+
bool $seed = false,
3941
): ExitCode {
4042
if ($validate) {
4143
$validationSuccess = $this->console->call(MigrateValidateCommand::class);
@@ -52,7 +54,14 @@ public function __invoke(
5254
$this->console->info('There is no migration to drop.');
5355
}
5456

55-
return $this->console->call(MigrateUpCommand::class, ['fresh' => false, 'validate' => false, 'database' => $database]);
57+
$this->console->call(MigrateUpCommand::class, ['fresh' => false, 'validate' => false, 'database' => $database]);
58+
59+
if ($seed) {
60+
$this->console->header('Seeding database');
61+
$this->console->call(DatabaseSeedCommand::class, ['--database' => $database]);
62+
}
63+
64+
return ExitCode::SUCCESS;
5665
}
5766

5867
#[EventHandler]

src/Tempest/Framework/Commands/MigrateUpCommand.php

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@
88
use Tempest\Console\ConsoleArgument;
99
use Tempest\Console\ConsoleCommand;
1010
use Tempest\Console\ExitCode;
11-
use Tempest\Console\Input\ConsoleArgumentBag;
1211
use Tempest\Console\Middleware\CautionMiddleware;
1312
use Tempest\Console\Middleware\ForceMiddleware;
1413
use Tempest\Container\Singleton;
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
<?php
2+
3+
namespace Tests\Tempest\Fixtures;
4+
5+
use Tempest\Database\DatabaseSeeder;
6+
use Tests\Tempest\Fixtures\Modules\Books\Models\Book;
7+
use UnitEnum;
8+
use function Tempest\Database\query;
9+
10+
final class TestDatabaseSeeder implements DatabaseSeeder
11+
{
12+
public function run(null|string|UnitEnum $database): void
13+
{
14+
query(Book::class)
15+
->insert(
16+
title: 'Timeline Taxi',
17+
)
18+
->onDatabase($database)
19+
->execute();
20+
}
21+
}

tests/Integration/Database/MultiDatabaseTest.php

Lines changed: 61 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<?php
22

3-
namespace Integration\Database;
3+
namespace Tests\Tempest\Integration\Database;
44

55
use PDOException;
66
use Tempest\Container\Exceptions\TaggedDependencyCouldNotBeResolved;
@@ -13,7 +13,9 @@
1313
use Tempest\Database\Migrations\CreateMigrationsTable;
1414
use Tempest\Database\Migrations\Migration;
1515
use Tempest\Database\Migrations\MigrationManager;
16+
use Tests\Tempest\Fixtures\Migrations\CreateBookTable;
1617
use Tests\Tempest\Fixtures\Migrations\CreatePublishersTable;
18+
use Tests\Tempest\Fixtures\Modules\Books\Models\Book;
1719
use Tests\Tempest\Fixtures\Modules\Books\Models\Publisher;
1820
use Tests\Tempest\Integration\Database\Fixtures\MigrationForBackup;
1921
use Tests\Tempest\Integration\Database\Fixtures\MigrationForMain;
@@ -271,6 +273,64 @@ public function test_should_migrate(): void
271273
$this->assertTableDoesNotExist('main_table', 'backup');
272274
}
273275

276+
public function test_database_seed_on_selected_database(): void
277+
{
278+
/** @var MigrationManager $migrationManager */
279+
$migrationManager = $this->container->get(MigrationManager::class);
280+
281+
$migrationManager->onDatabase('main')->executeUp(new CreateMigrationsTable());
282+
$migrationManager->onDatabase('main')->executeUp(new CreateBookTable());
283+
$migrationManager->onDatabase('backup')->executeUp(new CreateMigrationsTable());
284+
$migrationManager->onDatabase('backup')->executeUp(new CreateBookTable());
285+
286+
$this->console
287+
->call('db:seed --database=main')
288+
->assertSuccess();
289+
290+
$this->assertSame(
291+
'Timeline Taxi',
292+
query(Book::class)->select()->onDatabase('main')->first()->title
293+
);
294+
295+
$this->assertNull(
296+
query(Book::class)->select()->onDatabase('backup')->first()
297+
);
298+
299+
$this->console
300+
->call('db:seed --database=backup')
301+
->assertSuccess();
302+
303+
$this->assertSame(
304+
'Timeline Taxi',
305+
query(Book::class)->select()->onDatabase('backup')->first()->title
306+
);
307+
}
308+
309+
public function test_migrate_fresh_seed_on_selected_database(): void
310+
{
311+
$this->console
312+
->call('migrate:fresh --seed --database=main')
313+
->assertSuccess();
314+
315+
$this->assertSame(
316+
'Timeline Taxi',
317+
query(Book::class)->select()->onDatabase('main')->first()->title
318+
);
319+
320+
$this->assertException(PDOException::class, function () {
321+
query(Book::class)->select()->onDatabase('backup')->first();
322+
});
323+
324+
$this->console
325+
->call('migrate:fresh --seed --database=backup')
326+
->assertSuccess();
327+
328+
$this->assertSame(
329+
'Timeline Taxi',
330+
query(Book::class)->select()->onDatabase('backup')->first()->title
331+
);
332+
}
333+
274334
private function assertTableExists(string $tableName, string $onDatabase): void
275335
{
276336
$this->assertTrue(query($tableName)->count()->onDatabase($onDatabase)->execute() >= 0);
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
<?php
2+
3+
namespace Tests\Tempest\Integration\Framework\Commands;
4+
5+
use Tempest\Core\AppConfig;
6+
use Tempest\Core\Environment;
7+
use Tempest\Database\Migrations\CreateMigrationsTable;
8+
use Tests\Tempest\Fixtures\Migrations\CreateBookTable;
9+
use Tests\Tempest\Fixtures\Modules\Books\Models\Book;
10+
use Tests\Tempest\Integration\FrameworkIntegrationTestCase;
11+
12+
final class DatabaseSeedCommandTest extends FrameworkIntegrationTestCase
13+
{
14+
public function test_seed(): void
15+
{
16+
$this->migrate(
17+
CreateMigrationsTable::class,
18+
CreateBookTable::class,
19+
);
20+
21+
$this->console
22+
->call('db:seed')
23+
->assertSuccess();
24+
25+
$book = Book::get(1);
26+
27+
$this->assertSame('Timeline Taxi', $book->title);
28+
}
29+
30+
public function test_seed_via_migrate_fresh(): void
31+
{
32+
$this->console
33+
->call('migrate:fresh --seed')
34+
->assertSuccess();
35+
36+
$book = Book::get(1);
37+
38+
$this->assertSame('Timeline Taxi', $book->title);
39+
}
40+
41+
public function test_db_seed_caution(): void
42+
{
43+
$appConfig = $this->container->get(AppConfig::class);
44+
$appConfig->environment = Environment::PRODUCTION;
45+
46+
$this->console
47+
->call('migrate:fresh --seed')
48+
->assertSee('Do you wish to continue');
49+
}
50+
}

0 commit comments

Comments
 (0)