Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 23 additions & 2 deletions src/batch-doctrine-dbal/src/DoctrineDBALJobExecutionStorage.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,15 @@
use Yokai\Batch\Storage\JobExecutionStorageInterface;
use Yokai\Batch\Storage\Query;
use Yokai\Batch\Storage\QueryableJobExecutionStorageInterface;
use Yokai\Batch\Storage\SetupableJobExecutionStorageInterface;

/**
* This {@see JobExecutionStorageInterface} will store
* {@see JobExecution} in an SQL database using doctrine/dbal.
*/
final class DoctrineDBALJobExecutionStorage implements QueryableJobExecutionStorageInterface
final class DoctrineDBALJobExecutionStorage implements
QueryableJobExecutionStorageInterface,
SetupableJobExecutionStorageInterface
{
private const DEFAULT_OPTIONS = [
'table' => 'yokai_batch_job_execution',
Expand Down Expand Up @@ -54,7 +57,7 @@ public function __construct(ConnectionRegistry $doctrine, array $options)
/**
* Create required table for this storage.
*/
public function createSchema(): void
public function setup(): void
{
$assetFilter = $this->connection->getConfiguration()->getSchemaAssetsFilter();
$this->connection->getConfiguration()->setSchemaAssetsFilter(null);
Expand Down Expand Up @@ -88,6 +91,24 @@ public function createSchema(): void
$this->connection->getConfiguration()->setSchemaAssetsFilter($assetFilter);
}

/**
* Create required table for this storage.
* @deprecated
*/
public function createSchema(): void
{
@\trigger_error(
\sprintf(
'Since yokai/batch-doctrine-dbal 0.5.8: ' .
'Method "%s()" is deprecated and will be removed in 0.6.0. Use %s::setup() instead.',
__METHOD__,
__CLASS__,
),
\E_USER_DEPRECATED,
);
$this->setup();
}

public function store(JobExecution $execution): void
{
try {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ public function testCreateStandardTable(): void
$schemaManager = $this->connection->getSchemaManager();

self::assertFalse($schemaManager->tablesExist(['yokai_batch_job_execution']));
$this->createStorage()->createSchema();
$this->createStorage()->setup();
self::assertTrue($schemaManager->tablesExist(['yokai_batch_job_execution']));

$columns = $schemaManager->listTableColumns('yokai_batch_job_execution');
Expand All @@ -61,7 +61,7 @@ public function testCreateCustomTable(): void
$schemaManager = $this->connection->getSchemaManager();

self::assertFalse($schemaManager->tablesExist(['acme_job_executions']));
$this->createStorage(['table' => 'acme_job_executions'])->createSchema();
$this->createStorage(['table' => 'acme_job_executions'])->setup();
self::assertTrue($schemaManager->tablesExist(['acme_job_executions']));

$columns = $schemaManager->listTableColumns('acme_job_executions');
Expand All @@ -86,7 +86,7 @@ public function testCreateCustomTable(): void
public function testStoreInsert(): void
{
$storage = $this->createStorage();
$storage->createSchema();
$storage->setup();

$export = JobExecution::createRoot('123', 'export', new BatchStatus(BatchStatus::RUNNING));
$export->setStartTime(new DateTimeImmutable('2021-09-23 11:05:00'));
Expand Down Expand Up @@ -122,7 +122,7 @@ public function testStoreInsert(): void
public function testStoreUpdate(): void
{
$storage = $this->createStorage();
$storage->createSchema();
$storage->setup();
$storage->store($execution = JobExecution::createRoot('123', 'export'));
$execution->setStatus(BatchStatus::COMPLETED);
$storage->store($execution);
Expand All @@ -138,7 +138,7 @@ public function testStoreFailing(): void
$this->expectException(CannotStoreJobExecutionException::class);

$storage = $this->createStorage();
/** not calling {@see DoctrineDBALJobExecutionStorage::createSchema} will cause table to not exists */
/** not calling {@see DoctrineDBALJobExecutionStorage::setup} will cause table to not exists */
$storage->store(JobExecution::createRoot('123', 'export'));
}

Expand All @@ -147,7 +147,7 @@ public function testRemove(): void
$this->expectException(JobExecutionNotFoundException::class);

$storage = $this->createStorage();
$storage->createSchema();
$storage->setup();
$storage->store($execution = JobExecution::createRoot('123', 'export'));
$storage->remove($execution);

Expand All @@ -159,14 +159,14 @@ public function testRemoveFailing(): void
$this->expectException(CannotRemoveJobExecutionException::class);

$storage = $this->createStorage();
/** not calling {@see DoctrineDBALJobExecutionStorage::createSchema} will cause table to not exists */
/** not calling {@see DoctrineDBALJobExecutionStorage::setup} will cause table to not exists */
$storage->remove(JobExecution::createRoot('123', 'export'));
}

public function testRetrieve(): void
{
$storage = $this->createStorage();
$storage->createSchema();
$storage->setup();
$storage->store(JobExecution::createRoot('123', 'export'));
$storage->store(JobExecution::createRoot('456', 'import'));

Expand All @@ -184,7 +184,7 @@ public function testRetrieveNotFound(): void
$this->expectException(JobExecutionNotFoundException::class);

$storage = $this->createStorage();
$storage->createSchema();
$storage->setup();
$storage->store(JobExecution::createRoot('123', 'export'));

$storage->retrieve('export', '456');
Expand All @@ -195,7 +195,7 @@ public function testRetrieveFailing(): void
$this->expectException(JobExecutionNotFoundException::class);

$storage = $this->createStorage();
/** not calling {@see DoctrineDBALJobExecutionStorage::createSchema} will cause table to not exists */
/** not calling {@see DoctrineDBALJobExecutionStorage::setup} will cause table to not exists */
$storage->retrieve('export', '456');
}

Expand All @@ -217,7 +217,7 @@ public function testRetrieveInvalid(array $data, Throwable $error): void
$data['logs'] ??= '';

$storage = $this->createStorage();
$storage->createSchema();
$storage->setup();
$this->connection->insert('yokai_batch_job_execution', $data);
$storage->retrieve('export', '123');
}
Expand Down Expand Up @@ -249,7 +249,7 @@ public function retrieveInvalid(): \Generator
public function testList(): void
{
$storage = $this->createStorage();
$storage->createSchema();
$storage->setup();
$this->loadFixtures($storage);

self::assertExecutionIds(['123'], $storage->list('export'));
Expand All @@ -262,7 +262,7 @@ public function testList(): void
public function testQuery(QueryBuilder $queryBuilder, array $expectedCouples): void
{
$storage = $this->createStorage();
$storage->createSchema();
$storage->setup();
$this->loadFixtures($storage);

self::assertExecutions($expectedCouples, $storage->query($queryBuilder->getQuery()));
Expand Down Expand Up @@ -343,6 +343,14 @@ public function queries(): Generator
];
}

public function testCreateSchemaDeprecated(): void
{
$schemaManager = $this->connection->getSchemaManager();
self::assertFalse($schemaManager->tablesExist(['yokai_batch_job_execution']));
$this->createStorage()->createSchema();
self::assertTrue($schemaManager->tablesExist(['yokai_batch_job_execution']));
}

public static function assertExecutionIds(array $ids, iterable $executions): void
{
$actualIds = [];
Expand Down
53 changes: 53 additions & 0 deletions src/batch-symfony-console/src/SetupStorageCommand.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
<?php

declare(strict_types=1);

namespace Yokai\Batch\Bridge\Symfony\Console;

use Symfony\Component\Console\Attribute\AsCommand;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Style\SymfonyStyle;
use Yokai\Batch\Storage\JobExecutionStorageInterface;
use Yokai\Batch\Storage\SetupableJobExecutionStorageInterface;

/**
* Prepare the required infrastructure for the job execution storage.
*/
#[AsCommand(name: 'yokai:batch:setup-storage', description: 'Prepare the required infrastructure for the storage')]
final class SetupStorageCommand extends Command
{
public function __construct(
private JobExecutionStorageInterface $storage,
) {
parent::__construct();
}

protected function configure(): void
{
$this
->setHelp(
<<<EOF
The <info>%command.name%</info> command setups the job execution storage:

<info>php %command.full_name%</info>
EOF
)
;
}

protected function execute(InputInterface $input, OutputInterface $output): int
{
$io = new SymfonyStyle($input, $output);

if ($this->storage instanceof SetupableJobExecutionStorageInterface) {
$this->storage->setup();
$io->success('The storage was set up successfully.');
} else {
$io->note('The storage does not support setup.');
}

return self::SUCCESS;
}
}
76 changes: 76 additions & 0 deletions src/batch-symfony-console/tests/SetupStorageCommandTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
<?php

declare(strict_types=1);

namespace Yokai\Batch\Tests\Bridge\Symfony\Console;

use PHPUnit\Framework\TestCase;
use Symfony\Component\Console\Tester\CommandTester;
use Yokai\Batch\Bridge\Symfony\Console\SetupStorageCommand;
use Yokai\Batch\Exception\JobExecutionNotFoundException;
use Yokai\Batch\JobExecution;
use Yokai\Batch\Storage\JobExecutionStorageInterface;
use Yokai\Batch\Storage\SetupableJobExecutionStorageInterface;

final class SetupStorageCommandTest extends TestCase
{
public function testSetupRequired(): void
{
$this->execute(
$storage = new class() implements
JobExecutionStorageInterface,
SetupableJobExecutionStorageInterface {
public bool $wasSetup = false;

public function setup(): void
{
$this->wasSetup = true;
}

public function store(JobExecution $execution): void
{
}

public function remove(JobExecution $execution): void
{
}

public function retrieve(string $jobName, string $executionId): JobExecution
{
throw new JobExecutionNotFoundException($jobName, $executionId);
}
},
'[OK] The storage was set up successfully.',
);
self::assertTrue($storage->wasSetup);
}

public function testSetupNotRequired(): void
{
$this->execute(
new class() implements JobExecutionStorageInterface {
public function store(JobExecution $execution): void
{
}

public function remove(JobExecution $execution): void
{
}

public function retrieve(string $jobName, string $executionId): JobExecution
{
throw new JobExecutionNotFoundException($jobName, $executionId);
}
},
'! [NOTE] The storage does not support setup.',
);
}

private function execute(JobExecutionStorageInterface $storage, string $expected): void
{
$tester = new CommandTester(new SetupStorageCommand($storage));
$tester->execute([]);
$tester->assertCommandIsSuccessful();
self::assertSame($expected, \trim($tester->getDisplay(true)));
}
}
1 change: 1 addition & 0 deletions src/batch-symfony-framework/composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
"php": "^8.0",
"composer-runtime-api": "^2.0",
"symfony/config": "^5.0|^6.0",
"symfony/console": "^5.0|^6.0",
"symfony/dependency-injection": "^5.0|^6.0",
"symfony/http-kernel": "^5.0|^6.0",
"symfony/framework-bundle": "^5.0|^6.0",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,5 +13,11 @@
<argument type="service" id="yokai_batch.job_executor"/>
<tag name="console.command"/>
</service>

<service id="yokai_batch.cli.setup_storage_command"
class="Yokai\Batch\Bridge\Symfony\Console\SetupStorageCommand">
<argument type="service" id="Yokai\Batch\Storage\JobExecutionStorageInterface"/>
<tag name="console.command"/>
</service>
</services>
</container>
26 changes: 26 additions & 0 deletions src/batch-symfony-framework/tests/CliTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<?php

declare(strict_types=1);

namespace Yokai\Batch\Tests\Bridge\Symfony\Framework;

use Symfony\Bundle\FrameworkBundle\Console\Application;
use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase;

final class CliTest extends KernelTestCase
{
public function testRegisteredCommands(): void
{
$names = \array_keys(
(new Application(self::bootKernel()))->all('yokai'),
);
\sort($names);
self::assertSame(
[
'yokai:batch:run',
'yokai:batch:setup-storage',
],
$names,
);
}
}
16 changes: 16 additions & 0 deletions src/batch/src/Storage/SetupableJobExecutionStorageInterface.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<?php

declare(strict_types=1);

namespace Yokai\Batch\Storage;

/**
* A job execution having this interface tells the developers it should be setuped before being used.
*/
interface SetupableJobExecutionStorageInterface
{
/**
* Setup the storage.
*/
public function setup(): void;
}