Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add the ability to use schema providers #91

Draft
wants to merge 1 commit into
base: 2.x
Choose a base branch
from
Draft
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
1 change: 1 addition & 0 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
"cycle/schema-migrations-generator": "^2.1",
"cycle/schema-renderer": "^1.2",
"cycle/schema-builder": "^2.7",
"cycle/schema-provider": "^1.0",
"doctrine/inflector": "^1.4 || ^2.0",
"spiral/attributes": "^2.10 || ^3.0",
"spiral/reactor": "^3.0",
Expand Down
68 changes: 37 additions & 31 deletions src/Bootloader/AnnotatedBootloader.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,72 +5,78 @@
namespace Spiral\Cycle\Bootloader;

use Cycle\Annotated;
use Cycle\Annotated\Locator\EmbeddingLocatorInterface;
use Cycle\Annotated\Locator\EntityLocatorInterface;
use Spiral\Attributes\ReaderInterface;
use Spiral\Boot\Bootloader\Bootloader;
use Spiral\Bootloader\Attributes\AttributesBootloader;
use Spiral\Core\FactoryInterface;
use Spiral\Cycle\Annotated\Locator\ListenerEmbeddingsLocator;
use Spiral\Cycle\Annotated\Locator\ListenerEntityLocator;
use Spiral\Cycle\Config\CycleConfig;
use Spiral\Cycle\Schema\Provider\AnnotatedSchemaProvider;
use Spiral\Tokenizer\Bootloader\TokenizerListenerBootloader;

final class AnnotatedBootloader extends Bootloader
{
protected const DEPENDENCIES = [
SchemaBootloader::class,
TokenizerListenerBootloader::class,
AttributesBootloader::class,
];

protected const BINDINGS = [
Annotated\Embeddings::class => [self::class, 'initEmbeddings'],
Annotated\Entities::class => [self::class, 'initEntities'],
Annotated\MergeColumns::class => [self::class, 'initMergeColumns'],
Annotated\TableInheritance::class => [self::class, 'initTableInheritance'],
Annotated\MergeIndexes::class => [self::class, 'initMergeIndexes'],
];
public function defineDependencies(): array
{
return [
SchemaBootloader::class,
TokenizerListenerBootloader::class,
AttributesBootloader::class,
];
}

protected const SINGLETONS = [
ListenerEntityLocator::class => ListenerEntityLocator::class,
ListenerEmbeddingsLocator::class => ListenerEmbeddingsLocator::class,
];
public function defineSingletons(): array
{
return [
ListenerEntityLocator::class => ListenerEntityLocator::class,
ListenerEmbeddingsLocator::class => ListenerEmbeddingsLocator::class,
EmbeddingLocatorInterface::class => ListenerEmbeddingsLocator::class,
EntityLocatorInterface::class => ListenerEntityLocator::class,
AnnotatedSchemaProvider::class => static function (FactoryInterface $factory, SchemaBootloader $schema, CycleConfig $config) {
return $factory->make(AnnotatedSchemaProvider::class, ['generators' => $schema->getGenerators($config)]);
},
];
}

public function init(
SchemaBootloader $schema,
TokenizerListenerBootloader $tokenizer,
ListenerEntityLocator $entityLocator,
ListenerEmbeddingsLocator $embeddingsLocator
): void {
$tokenizer->addListener($entityLocator);
$tokenizer->addListener($embeddingsLocator);

$schema->addGenerator(SchemaBootloader::GROUP_INDEX, Annotated\Embeddings::class);
$schema->addGenerator(SchemaBootloader::GROUP_INDEX, Annotated\Entities::class);
$schema->addGenerator(SchemaBootloader::GROUP_INDEX, Annotated\TableInheritance::class);
$schema->addGenerator(SchemaBootloader::GROUP_INDEX, Annotated\MergeColumns::class);
$schema->addGenerator(SchemaBootloader::GROUP_RENDER, Annotated\MergeIndexes::class);
}

private function initEmbeddings(
ReaderInterface $reader,
ListenerEmbeddingsLocator $embeddingsLocator
): Annotated\Embeddings {
return new Annotated\Embeddings($embeddingsLocator, $reader);
}

/**
* @deprecated since v2.10.0. Will be removed in v3.0.0.
*/
public function initEntities(ReaderInterface $reader, ListenerEntityLocator $entityLocator): Annotated\Entities
{
return new Annotated\Entities($entityLocator, $reader);
}

/**
* @deprecated since v2.10.0. Will be removed in v3.0.0.
*/
public function initMergeColumns(ReaderInterface $reader): Annotated\MergeColumns
{
return new Annotated\MergeColumns($reader);
}

/**
* @deprecated since v2.10.0. Will be removed in v3.0.0.
*/
public function initTableInheritance(ReaderInterface $reader): Annotated\TableInheritance
{
return new Annotated\TableInheritance($reader);
}

/**
* @deprecated since v2.10.0. Will be removed in v3.0.0.
*/
public function initMergeIndexes(ReaderInterface $reader): Annotated\MergeIndexes
{
return new Annotated\MergeIndexes($reader);
Expand Down
13 changes: 12 additions & 1 deletion src/Bootloader/CycleOrmBootloader.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,18 @@
use Cycle\ORM\ORM;
use Cycle\ORM\ORMInterface;
use Cycle\ORM\RepositoryInterface;
use Cycle\Schema\Provider\PhpFileSchemaProvider;
use Psr\Container\ContainerInterface;
use Spiral\Boot\AbstractKernel;
use Spiral\Boot\Bootloader\Bootloader;
use Spiral\Boot\DirectoriesInterface;
use Spiral\Boot\EnvironmentInterface;
use Spiral\Boot\FinalizerInterface;
use Spiral\Config\ConfiguratorInterface;
use Spiral\Core\Container;
use Spiral\Cycle\Config\CycleConfig;
use Spiral\Cycle\Injector\RepositoryInjector;
use Spiral\Cycle\Schema\Provider\AnnotatedSchemaProvider;

final class CycleOrmBootloader extends Bootloader
{
Expand All @@ -39,7 +42,8 @@ final class CycleOrmBootloader extends Bootloader

public function __construct(
private readonly ConfiguratorInterface $config,
private readonly EnvironmentInterface $env
private readonly EnvironmentInterface $env,
private readonly DirectoriesInterface $dirs,
) {
}

Expand Down Expand Up @@ -113,6 +117,13 @@ private function initOrmConfig(): void
'collections' => [],
],
'warmup' => $this->env->get('CYCLE_SCHEMA_WARMUP', false),
'schemaProviders' => [
PhpFileSchemaProvider::class => PhpFileSchemaProvider::config(
file: $this->dirs->get('runtime') . '/cycle.php',
mode: PhpFileSchemaProvider::MODE_READ_AND_WRITE
),
AnnotatedSchemaProvider::class
],
]
);
}
Expand Down
62 changes: 29 additions & 33 deletions src/Bootloader/SchemaBootloader.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,19 @@

namespace Spiral\Cycle\Bootloader;

use Cycle\ORM\Schema;
use Cycle\ORM\SchemaInterface;
use Cycle\Schema\Defaults;
use Cycle\Schema\Generator;
use Cycle\Schema\GeneratorInterface;
use Cycle\Schema\Provider\SchemaProviderInterface;
use Cycle\Schema\Provider\Support\SchemaProviderPipeline;
use Cycle\Schema\Registry;
use Psr\Container\ContainerInterface;
use Spiral\Boot\Bootloader\Bootloader;
use Spiral\Boot\MemoryInterface;
use Spiral\Core\Container;
use Spiral\Core\FactoryInterface;
use Spiral\Cycle\Config\CycleConfig;
use Spiral\Cycle\Schema\Compiler;
use Spiral\Tokenizer\Bootloader\TokenizerBootloader;

final class SchemaBootloader extends Bootloader implements Container\SingletonInterface
Expand All @@ -23,16 +25,6 @@ final class SchemaBootloader extends Bootloader implements Container\SingletonIn
public const GROUP_RENDER = 'render';
public const GROUP_POSTPROCESS = 'postprocess';

protected const DEPENDENCIES = [
TokenizerBootloader::class,
CycleOrmBootloader::class,
];

protected const BINDINGS = [
SchemaInterface::class => [self::class, 'schema'],
Registry::class => [self::class, 'initRegistry']
];

/** @var string[][]|GeneratorInterface[][] */
private array $defaultGenerators;

Expand Down Expand Up @@ -61,7 +53,31 @@ public function __construct(
];
}

public function addGenerator(string $group, string $generator): void
public function defineDependencies(): array
{
return [
TokenizerBootloader::class,
CycleOrmBootloader::class,
];
}

public function defineBindings(): array
{
return [
Registry::class => [self::class, 'initRegistry'],
SchemaInterface::class => static fn (SchemaProviderInterface $provider): SchemaInterface => new Schema(
$provider->read() ?? []
),
SchemaProviderInterface::class => static function (ContainerInterface $container): SchemaProviderInterface {
/** @var CycleConfig $config */
$config = $container->get(CycleConfig::class);

return (new SchemaProviderPipeline($container))->withConfig($config->getSchemaProviders());
},
];
}

public function addGenerator(string $group, string|GeneratorInterface $generator): void
{
$this->defaultGenerators[$group][] = $generator;
}
Expand Down Expand Up @@ -93,26 +109,6 @@ public function getGenerators(CycleConfig $config): array
return $result;
}

/**
* @throws \Throwable
*/
protected function schema(MemoryInterface $memory, CycleConfig $config): SchemaInterface
{
$schemaCompiler = Compiler::fromMemory($memory);

if ($schemaCompiler->isEmpty() || ! $config->cacheSchema()) {
$schemaCompiler = Compiler::compile(
$this->container->get(Registry::class),
$this->getGenerators($config),
$config->getSchemaDefaults()
);

$schemaCompiler->toMemory($memory);
}

return $schemaCompiler->toSchema();
}

private function initRegistry(FactoryInterface $factory, CycleConfig $config): Registry
{
$defaults = new Defaults();
Expand Down
5 changes: 5 additions & 0 deletions src/Config/CycleConfig.php
Original file line number Diff line number Diff line change
Expand Up @@ -59,4 +59,9 @@ public function warmup(): bool
{
return (bool)($this->config['warmup'] ?? false);
}

public function getSchemaProviders(): array
{
return (array)($this->config['schemaProviders'] ?? []);
}
}
1 change: 1 addition & 0 deletions src/Console/Command/CycleOrm/Generator/ShowChanges.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@

/**
* @deprecated. Use {@see \Cycle\Schema\Generator\PrintChanges} instead. Will be removed in v3.0.
* @codeCoverageIgnore
*/
final class ShowChanges implements GeneratorInterface
{
Expand Down
21 changes: 8 additions & 13 deletions src/Console/Command/CycleOrm/MigrateCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

namespace Spiral\Cycle\Console\Command\CycleOrm;

use Cycle\Schema\Compiler;
use Cycle\Schema\Generator\Migrations\Strategy\GeneratorStrategyInterface;
use Cycle\Schema\Generator\Migrations\Strategy\MultipleFilesStrategy;
use Cycle\Schema\Generator\PrintChanges;
Expand All @@ -13,11 +14,10 @@
use Spiral\Cycle\Console\Command\Migrate\AbstractCommand;
use Cycle\Migrations\State;
use Cycle\Schema\Generator\Migrations\GenerateMigrations;
use Spiral\Cycle\Schema\Compiler;
use Cycle\Schema\Registry;
use Spiral\Boot\MemoryInterface;
use Spiral\Console\Console;
use Cycle\Migrations\Migrator;
use Spiral\Cycle\Schema\Provider\AnnotatedSchemaProvider;
use Symfony\Component\Console\Input\InputOption;

final class MigrateCommand extends AbstractCommand
Expand All @@ -33,9 +33,9 @@ public function perform(
SchemaBootloader $bootloader,
CycleConfig $config,
Registry $registry,
MemoryInterface $memory,
Migrator $migrator,
Console $console,
AnnotatedSchemaProvider $provider,
): int {
$migrator->configure();

Expand All @@ -54,15 +54,10 @@ public function perform(

$this->comment('Detecting schema changes...');

$schemaCompiler = Compiler::compile(
$registry,
\array_merge($bootloader->getGenerators($config), [
$print = new PrintChanges($this->output),
]),
$config->getSchemaDefaults(),
);

$schemaCompiler->toMemory($memory);
$provider = $provider->withGenerators(\array_merge($bootloader->getGenerators($config), [
$print = new PrintChanges($this->output)
]));
$provider->read();

if ($print->hasChanges()) {
if ($this->option('split')) {
Expand All @@ -72,7 +67,7 @@ public function perform(

$migrations = $this->container->get(GenerateMigrations::class);

(new \Cycle\Schema\Compiler())->compile($registry, [$migrations]);
(new Compiler())->compile($registry, \array_merge($provider->getGenerators(), [$migrations]));

if ($this->option('run')) {
$console->run('migrate', [], $this->output);
Expand Down
16 changes: 5 additions & 11 deletions src/Console/Command/CycleOrm/SyncCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,9 @@
use Spiral\Cycle\Bootloader\SchemaBootloader;
use Cycle\Schema\Generator\PrintChanges;
use Cycle\Schema\Generator\SyncTables;
use Cycle\Schema\Registry;
use Spiral\Boot\MemoryInterface;
use Spiral\Cycle\Config\CycleConfig;
use Spiral\Cycle\Console\Command\Migrate\AbstractCommand;
use Spiral\Cycle\Schema\Compiler;
use Spiral\Cycle\Schema\Provider\AnnotatedSchemaProvider;

final class SyncCommand extends AbstractCommand
{
Expand All @@ -21,22 +19,18 @@ final class SyncCommand extends AbstractCommand
public function perform(
SchemaBootloader $bootloader,
CycleConfig $config,
Registry $registry,
MemoryInterface $memory,
AnnotatedSchemaProvider $provider,
): int {
if (!$this->verifyEnvironment(message: 'This operation is not recommended for production environment.')) {
return self::FAILURE;
}

$print = new PrintChanges($this->output);

$schemaCompiler = Compiler::compile(
$registry,
\array_merge($bootloader->getGenerators($config), [$print, new SyncTables()]),
$config->getSchemaDefaults(),
$provider = $provider->withGenerators(
\array_merge($bootloader->getGenerators($config), [$print, new SyncTables()])
);

$schemaCompiler->toMemory($memory);
$provider->read();

if ($print->hasChanges()) {
$this->info('ORM Schema has been synchronized with database.');
Expand Down
Loading
Loading