diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml
index 384d5c6..c87aec8 100644
--- a/.github/workflows/main.yml
+++ b/.github/workflows/main.yml
@@ -14,7 +14,7 @@ jobs:
strategy:
fail-fast: false
matrix:
- php: [ '7.4', '8.0' ]
+ php: [ '7.4', '8.0', '8.1' ]
os: [ ubuntu-latest ]
stability: [ prefer-lowest, prefer-stable ]
@@ -43,25 +43,19 @@ jobs:
id: composer-cache
run: echo "::set-output name=dir::$(composer config cache-files-dir)"
- name: Restore Composer Cache
- uses: actions/cache@v1
+ uses: actions/cache@v2
with:
path: ${{ steps.composer-cache.outputs.dir }}
key: ${{ runner.os }}-${{ matrix.php }}-composer-${{ hashFiles('**/composer.json') }}
restore-keys: ${{ runner.os }}-${{ matrix.php }}-composer-
- - name: Install Dependencies
- uses: nick-invision/retry@v1
- with:
- timeout_minutes: 5
- max_attempts: 5
- command: composer update --${{ matrix.stability }} --prefer-dist --no-interaction --no-progress
- # Upgrade mockery on PHP 8
- - name: Install Dependencies
- if: ${{ matrix.php == '8.0' }}
- uses: nick-invision/retry@v1
- with:
- timeout_minutes: 5
- max_attempts: 5
- command: composer update mockery/mockery --prefer-dist --no-interaction --no-progress
+
+ - name: Install dependencies with composer
+ if: matrix.php-version != '8.1'
+ run: composer update --${{ matrix.stability }} --prefer-dist --no-interaction --no-progress --optimize-autoloader --ansi
+
+ - name: Install dependencies with composer php 8.1
+ if: matrix.php-version == '8.1'
+ run: composer update --${{ matrix.stability }} --prefer-dist --no-interaction --no-progress --optimize-autoloader --ansi --ignore-platform-reqs
# Execution
- name: Execute Tests
@@ -71,4 +65,4 @@ jobs:
with:
token: ${{ secrets.CODECOV_TOKEN }}
file: ./coverage.xml
- fail_ci_if_error: false
\ No newline at end of file
+ fail_ci_if_error: false
diff --git a/.github/workflows/static.yml b/.github/workflows/static.yml
new file mode 100644
index 0000000..9e32920
--- /dev/null
+++ b/.github/workflows/static.yml
@@ -0,0 +1,52 @@
+name: static analysis
+
+on:
+ pull_request:
+ push:
+ schedule:
+ - cron: '0 0 * * *'
+
+jobs:
+ mutation:
+ name: PHP ${{ matrix.php }}-${{ matrix.os }}
+
+ runs-on: ${{ matrix.os }}
+
+ strategy:
+ matrix:
+ os:
+ - ubuntu-latest
+
+ php:
+ - "8.0"
+
+ steps:
+ - name: Checkout
+ uses: actions/checkout@v2
+
+ - name: Install PHP
+ uses: shivammathur/setup-php@v2
+ with:
+ php-version: "${{ matrix.php }}"
+ tools: composer:v2, cs2pr
+ coverage: none
+
+ - name: Determine composer cache directory
+ run: echo "COMPOSER_CACHE_DIR=$(composer config cache-dir)" >> $GITHUB_ENV
+
+ - name: Cache dependencies installed with composer
+ uses: actions/cache@v2
+ with:
+ path: ${{ env.COMPOSER_CACHE_DIR }}
+ key: php${{ matrix.php }}-composer-${{ hashFiles('**/composer.json') }}
+ restore-keys: |
+ php${{ matrix.php }}-composer-
+
+ - name: Update composer
+ run: composer self-update
+
+ - name: Install dependencies with composer
+ run: composer update --prefer-dist --no-interaction --no-progress --optimize-autoloader --ansi
+
+ - name: Static analysis
+ run: vendor/bin/psalm --shepherd --stats --output-format=checkstyle | cs2pr --graceful-warnings --colorize
diff --git a/.styleci.yml b/.styleci.yml
index a6cd886..4fe219f 100644
--- a/.styleci.yml
+++ b/.styleci.yml
@@ -1,7 +1,11 @@
preset: psr12
risky: true
-version: 8
+version: 7
+
+finder:
+ not-name:
+ - "*.stub.txt"
enabled:
- alpha_ordered_traits
@@ -12,7 +16,6 @@ enabled:
- combine_nested_dirname
- declare_strict_types
- dir_constant
- - final_static_access
- fully_qualified_strict_types
- function_to_constant
- hash_to_slash_comment
diff --git a/LICENSE b/LICENSE
index 068b0e7..586cdb0 100644
--- a/LICENSE
+++ b/LICENSE
@@ -1,6 +1,6 @@
The MIT License (MIT)
-Copyright (c) 2019 Spiral Scout
+Copyright (c) 2021 Spiral Scout
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
diff --git a/README.md b/README.md
index 7a50236..045213d 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,16 @@
-# CycleORM Schema renderer
+# Cycle ORM Schema renderer
-This package may be used to render schema roles in a terminal or generate php representation for CycleORM schema.
+This package may be used to render Cycle ORM Schema in a terminal or generate php representation.
+
+## Installation
+
+The preferred way to install this package is through [Composer](https://getcomposer.org/download/):
+
+```bash
+composer require cycle/schema-renderer
+```
+
+## Example
### Convert schema to array
@@ -11,15 +21,17 @@ $converter = new \Cycle\Schema\Renderer\SchemaToArrayConverter();
$schemaArray = $converter->convert($schema);
```
-By default, SchemaToArrayConverter converts only common properties from `Cycle\ORM\SchemaInterface`.
+If passed `SchemaInterface` doesn't contain `toArray()` method then the `SchemaToArrayConverter` will convert
+only common properties from `Cycle\ORM\SchemaInterface`. Null values will be skipped also.
+
+In this case Iif you want to use custom properties you can pass them to the constructor
-But if you want to use custom properties you can pass them to the constructor
```php
$converter = new \Cycle\Schema\Renderer\SchemaToArrayConverter();
$schemaArray = $converter->convert($schema, [
- 'my_custom_property',
- SchemaInterface::SOURCE,
+ 42,
+ CustomClass::CUSTOM_PROPERTY,
...
]);
```
@@ -27,29 +39,23 @@ $schemaArray = $converter->convert($schema, [
### Render schema to a terminal
```php
-use Cycle\Schema\Renderer\ConsoleRenderer\DefaultSchemaOutputRenderer;
-use Cycle\Schema\Renderer\ConsoleRenderer\Formatters\StyledFormatter;
-use Cycle\Schema\Renderer\ConsoleRenderer\Formatters\PlainFormatter;
+use Cycle\Schema\Renderer\OutputSchemaRenderer;
$output = new \Symfony\Component\Console\Output\ConsoleOutput();
-$formatter = new StyledFormatter(); // Colorized output
-// or
-$formatter = new PlainFormatter(); // Plain output without colors
+$renderer = new OutputSchemaRenderer(colorize: true);
-$renderer = new DefaultSchemaOutputRenderer($schemaArray, $formatter);
-
-foreach ($renderer as $role => $rows) {
- $output->writeln($rows);
-}
+$output->write($renderer->render($schemaArray));
```
-By default, DefaultSchemaOutputRenderer renders only common properties.
-If you want to extend default CycleORM schema you can create custom renderers and add them to the Output renderer.
+By default, `DefaultSchemaOutputRenderer` renders in template only common properties and relations.
+Custom properties will be rendered as is in separated block.
+If you want to extend default rendering template you can create custom renderers and add them to the Output renderer.
```php
use Cycle\Schema\Renderer\ConsoleRenderer\Renderer;
use Cycle\Schema\Renderer\ConsoleRenderer\Formatter;
+use Cycle\Schema\Renderer\OutputSchemaRenderer;
class CustomPropertyRenderer implements Renderer {
@@ -65,60 +71,32 @@ class CustomPropertyRenderer implements Renderer {
}
}
-$renderer = new DefaultSchemaOutputRenderer($schemaArray, $formatter);
+$renderer = new OutputSchemaRenderer();
$renderer->addRenderer(
new CustomPropertyRenderer(),
new PropertyRenderer('my_custom_property', 'My super property')
);
-foreach ($renderer as $role => $rows) {
- $output->writeln($rows);
-}
+$output->write($renderer->render($schemaArray))
```
### Store schema in a PHP file
```php
-use Cycle\Schema\Renderer\SchemaToPhpFileRenderer;
-use Cycle\Schema\Renderer\PhpFileRenderer\DefaultSchemaGenerator;
+use Cycle\Schema\Renderer\PhpSchemaRenderer;
$path = __DIR__. '/schema.php'
-$generator = new DefaultSchemaGenerator();
-
-$renderer = new SchemaToPhpFileRenderer(
- $orm->getSchema(), $generator
-);
+$renderer = new PhpSchemaRenderer();
-file_put_contents($path, $renderer->render());
+file_put_contents($path, $renderer->render($schemaArray));
```
-By default, DefaultSchemaGenerator generates only common properties.
-If you want to extend default CycleORM schema you can create custom generators and add them to the Output php file renderer.
+The Renderer generates valid PHP code, in which constants from Cycle ORM classes are substituted
+for better readability.
+## License:
-```php
-use Cycle\Schema\Renderer\SchemaToPhpFileRenderer;
-use Cycle\Schema\Renderer\PhpFileRenderer\DefaultSchemaGenerator;
-use Cycle\Schema\Renderer\PhpFileRenderer\Generator;
-use Cycle\Schema\Renderer\PhpFileRenderer\VarExporter;
-
-class CustomPropertyGenerator implements Generator {
-
- public function generate(array $schema, string $role): VarExporter
- {
- $key = 'my_custom_property';
-
- return new VarExporter($key, $schema[$key] ?? null);
- }
-}
-
-$generator = new DefaultSchemaGenerator([
- 'my_custom_property' => new CustomPropertyGenerator()
-]);
-
-$renderer = new SchemaToPhpFileRenderer(
- $orm->getSchema(), $generator
-);
-```
+The MIT License (MIT). Please see [`LICENSE`](./LICENSE) for more information.
+Maintained by [Spiral Scout](https://spiralscout.com).
diff --git a/composer.json b/composer.json
index 40aaa07..cef7e63 100644
--- a/composer.json
+++ b/composer.json
@@ -1,25 +1,37 @@
{
- "name": "cycle/schema-renderer",
- "type": "library",
- "license": "MIT",
- "description": "Utils for Cycle Schema rendering",
- "require": {
- "php": ">=7.4",
- "cycle/orm": "^1.5|2.0.x-dev"
- },
- "require-dev": {
- "phpunit/phpunit": "^9.5",
- "spiral/code-style": "^1.0",
- "vimeo/psalm": "^4.9"
- },
- "autoload": {
- "psr-4": {
- "Cycle\\Schema\\Renderer\\": "src/"
- }
- },
- "autoload-dev": {
- "psr-4": {
- "Cycle\\Schema\\Renderer\\Tests\\": "tests/Schema/Renderer/"
- }
- }
+ "name": "cycle/schema-renderer",
+ "type": "library",
+ "license": "MIT",
+ "description": "Utils for Cycle ORM Schema rendering",
+ "require": {
+ "php": ">=7.4",
+ "cycle/orm": "1.2 - 2"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^9.5",
+ "spiral/code-style": "^1.0",
+ "vimeo/psalm": "^4.10"
+ },
+ "autoload": {
+ "psr-4": {
+ "Cycle\\Schema\\Renderer\\": "src/"
+ }
+ },
+ "autoload-dev": {
+ "psr-4": {
+ "Cycle\\Schema\\Renderer\\Tests\\": "tests/Schema/Renderer/"
+ }
+ },
+ "scripts": {
+ "test": [
+ "phpcs --standard=phpcs.xml",
+ "psalm --no-cache",
+ "phpunit"
+ ]
+ },
+ "config": {
+ "sort-packages": true
+ },
+ "minimum-stability": "dev",
+ "prefer-stable": true
}
diff --git a/phpcs.xml b/phpcs.xml
new file mode 100644
index 0000000..a81e173
--- /dev/null
+++ b/phpcs.xml
@@ -0,0 +1,45 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ./src
+
diff --git a/psalm.xml b/psalm.xml
index 30258a7..4e9226b 100644
--- a/psalm.xml
+++ b/psalm.xml
@@ -1,6 +1,6 @@
'Role',
- SchemaInterface::ENTITY => 'Entity',
- SchemaInterface::MAPPER => 'Mapper',
- SchemaInterface::SCOPE => 'Constrain',
- SchemaInterface::REPOSITORY => 'Repository',
- ];
-
- public function __construct(array $schema, Formatter $formatter)
- {
- parent::__construct($schema, $formatter);
-
- $this->addRenderer(...[
- new TitleRenderer(),
-
- // Default properties renderer (Without extra logic)
- ...array_map(static function ($property, string $title) {
- return new PropertyRenderer($property, $title);
- }, array_keys(static::DEFAULT_PROPERTY_LIST), static::DEFAULT_PROPERTY_LIST),
-
- new PrimaryKeysRenderer(),
- new ColumnsRenderer(),
- new RelationsRenderer(),
- new CustomPropertiesRenderer(),
- ]);
- }
-}
diff --git a/src/ConsoleRenderer/Formatter.php b/src/ConsoleRenderer/Formatter.php
index a6934d5..0fdf6da 100644
--- a/src/ConsoleRenderer/Formatter.php
+++ b/src/ConsoleRenderer/Formatter.php
@@ -6,13 +6,21 @@
interface Formatter
{
- const TITLE_LENGTH = 13;
+ public const TITLE_LENGTH = 13;
+ public const LINE_SEPARATOR = "\n";
+ public const ROLE_BLOCK_SEPARATOR = "\n\n";
public function title(string $title): string;
+
public function property(string $string): string;
+
public function column(string $string): string;
+
public function info(string $string): string;
+
public function typecast(string $string): string;
+
public function entity(string $string): string;
+
public function error(string $string): string;
}
diff --git a/src/ConsoleRenderer/Formatters/PlainFormatter.php b/src/ConsoleRenderer/Formatter/PlainFormatter.php
similarity index 92%
rename from src/ConsoleRenderer/Formatters/PlainFormatter.php
rename to src/ConsoleRenderer/Formatter/PlainFormatter.php
index e5d9828..bcd0eb0 100644
--- a/src/ConsoleRenderer/Formatters/PlainFormatter.php
+++ b/src/ConsoleRenderer/Formatter/PlainFormatter.php
@@ -2,13 +2,12 @@
declare(strict_types=1);
-namespace Cycle\Schema\Renderer\ConsoleRenderer\Formatters;
+namespace Cycle\Schema\Renderer\ConsoleRenderer\Formatter;
use Cycle\Schema\Renderer\ConsoleRenderer\Formatter;
final class PlainFormatter implements Formatter
{
-
public function title(string $title): string
{
return str_pad($title, self::TITLE_LENGTH, ' ', STR_PAD_LEFT);
diff --git a/src/ConsoleRenderer/Formatters/StyledFormatter.php b/src/ConsoleRenderer/Formatter/StyledFormatter.php
similarity index 90%
rename from src/ConsoleRenderer/Formatters/StyledFormatter.php
rename to src/ConsoleRenderer/Formatter/StyledFormatter.php
index 81ad9ae..6c4847b 100644
--- a/src/ConsoleRenderer/Formatters/StyledFormatter.php
+++ b/src/ConsoleRenderer/Formatter/StyledFormatter.php
@@ -2,7 +2,7 @@
declare(strict_types=1);
-namespace Cycle\Schema\Renderer\ConsoleRenderer\Formatters;
+namespace Cycle\Schema\Renderer\ConsoleRenderer\Formatter;
use Cycle\Schema\Renderer\ConsoleRenderer\Formatter;
@@ -59,7 +59,8 @@ public function error(string $string): string
private function colorize(string $string): string
{
return str_replace(
- array_keys(self::COLORS_MAP), array_values(self::COLORS_MAP),
+ array_keys(self::COLORS_MAP),
+ array_values(self::COLORS_MAP),
$string
);
}
diff --git a/src/ConsoleRenderer/OutputRenderer.php b/src/ConsoleRenderer/OutputRenderer.php
index 24dfc57..1eb906a 100644
--- a/src/ConsoleRenderer/OutputRenderer.php
+++ b/src/ConsoleRenderer/OutputRenderer.php
@@ -4,42 +4,37 @@
namespace Cycle\Schema\Renderer\ConsoleRenderer;
-use IteratorAggregate;
-use Traversable;
+use Cycle\Schema\Renderer\SchemaRenderer;
-class OutputRenderer implements IteratorAggregate
+class OutputRenderer implements SchemaRenderer
{
/** @var Renderer[] */
private array $renderers = [];
- private array $schema;
private Formatter $formatter;
- public function __construct(array $schema, Formatter $formatter, array $renderers = [])
+ public function __construct(Formatter $formatter, array $renderers = [])
{
- $this->addRenderer(...$renderers);
-
$this->formatter = $formatter;
- $this->schema = $schema;
+ $this->addRenderer(...$renderers);
}
- public function addRenderer(Renderer ...$renderers): void
+ final public function addRenderer(Renderer ...$renderers): void
{
foreach ($renderers as $renderer) {
$this->renderers[] = $renderer;
}
}
- /**
- * @return Traversable
- */
- public function getIterator(): Traversable
+ final public function render(array $schema): string
{
- foreach ($this->schema as $role => $schema) {
- yield $role => $this->renderSchema($schema, $role);
+ $result = '';
+ foreach ($schema as $role => $roleSchema) {
+ $result .= $this->renderRole($roleSchema, $role) . $this->formatter::ROLE_BLOCK_SEPARATOR;
}
+ return $result;
}
- private function renderSchema(array $schema, string $role): string
+ private function renderRole(array $schema, string $role): string
{
$rows = [];
@@ -49,6 +44,6 @@ private function renderSchema(array $schema, string $role): string
}
}
- return implode("\n", $rows);
+ return \implode($this->formatter::LINE_SEPARATOR, $rows);
}
}
diff --git a/src/ConsoleRenderer/Renderers/ColumnsRenderer.php b/src/ConsoleRenderer/Renderer/ColumnsRenderer.php
similarity index 88%
rename from src/ConsoleRenderer/Renderers/ColumnsRenderer.php
rename to src/ConsoleRenderer/Renderer/ColumnsRenderer.php
index 558c8d9..4ef4064 100644
--- a/src/ConsoleRenderer/Renderers/ColumnsRenderer.php
+++ b/src/ConsoleRenderer/Renderer/ColumnsRenderer.php
@@ -2,7 +2,7 @@
declare(strict_types=1);
-namespace Cycle\Schema\Renderer\ConsoleRenderer\Renderers;
+namespace Cycle\Schema\Renderer\ConsoleRenderer\Renderer;
use Cycle\ORM\SchemaInterface;
use Cycle\Schema\Renderer\ConsoleRenderer\Formatter;
@@ -43,13 +43,13 @@ public function render(Formatter $formatter, array $schema, string $role): ?stri
if ($typecast !== null) {
$row .= sprintf(
' -> %s',
- $formatter->typecast(implode('::', (array)$typecast))
+ $formatter->typecast(\implode('::', (array)$typecast))
);
}
$rows[] = $row;
}
- return implode("\n", $rows);
+ return \implode("\n", $rows);
}
}
diff --git a/src/ConsoleRenderer/Renderers/CustomPropertiesRenderer.php b/src/ConsoleRenderer/Renderer/CustomPropertiesRenderer.php
similarity index 52%
rename from src/ConsoleRenderer/Renderers/CustomPropertiesRenderer.php
rename to src/ConsoleRenderer/Renderer/CustomPropertiesRenderer.php
index 8223a1d..1f9dd81 100644
--- a/src/ConsoleRenderer/Renderers/CustomPropertiesRenderer.php
+++ b/src/ConsoleRenderer/Renderer/CustomPropertiesRenderer.php
@@ -1,26 +1,34 @@
$exclude Values list that should be excluded
+ */
+ public function __construct(array $exclude)
{
- $refl = new ReflectionClass(SchemaInterface::class);
+ $this->exclude = $exclude;
+ }
- $customProperties = array_diff(array_keys($schema), $refl->getConstants());
+ public function render(Formatter $formatter, array $schema, string $role): ?string
+ {
+ $customProperties = array_diff(array_keys($schema), $this->exclude);
if ($customProperties === []) {
return null;
}
$rows = [
- sprintf('%s:', $formatter->title('Custom props'))
+ sprintf('%s:', $formatter->title('Custom props')),
];
foreach ($customProperties as $property) {
@@ -29,10 +37,10 @@ public function render(Formatter $formatter, array $schema, string $role): ?stri
$rows[] = sprintf(
' %s: %s',
$property,
- $formatter->typecast($data)
+ $formatter->typecast(print_r($data, true))
);
}
- return implode("\n", $rows);
+ return \implode("\n", $rows);
}
}
diff --git a/src/ConsoleRenderer/Renderer/KeysRenderer.php b/src/ConsoleRenderer/Renderer/KeysRenderer.php
new file mode 100644
index 0000000..4fb59b5
--- /dev/null
+++ b/src/ConsoleRenderer/Renderer/KeysRenderer.php
@@ -0,0 +1,44 @@
+title = $title;
+ $this->key = $key;
+ $this->required = $required;
+ }
+
+ public function render(Formatter $formatter, array $schema, string $role): ?string
+ {
+ $keys = $schema[$this->key] ?? null;
+
+ $row = sprintf('%s: ', $formatter->title($this->title));
+
+ if ($keys === null) {
+ return $this->required ? $row . $formatter->error('not defined') : null;
+ }
+
+ $keys = \array_map(
+ static fn (string $key) => $formatter->property($key),
+ (array)$keys
+ );
+
+ return $row . \implode(', ', $keys);
+ }
+}
diff --git a/src/ConsoleRenderer/Renderers/PropertyRenderer.php b/src/ConsoleRenderer/Renderer/PropertyRenderer.php
similarity index 56%
rename from src/ConsoleRenderer/Renderers/PropertyRenderer.php
rename to src/ConsoleRenderer/Renderer/PropertyRenderer.php
index d217c6e..9416c8f 100644
--- a/src/ConsoleRenderer/Renderers/PropertyRenderer.php
+++ b/src/ConsoleRenderer/Renderer/PropertyRenderer.php
@@ -2,32 +2,35 @@
declare(strict_types=1);
-namespace Cycle\Schema\Renderer\ConsoleRenderer\Renderers;
+namespace Cycle\Schema\Renderer\ConsoleRenderer\Renderer;
use Cycle\Schema\Renderer\ConsoleRenderer\Formatter;
use Cycle\Schema\Renderer\ConsoleRenderer\Renderer;
class PropertyRenderer implements Renderer
{
- /** @var int|string */
- private $property;
+ private int $property;
private string $title;
+ private bool $required;
- public function __construct($property, string $title)
+ public function __construct(int $property, string $title, bool $required = false)
{
$this->property = $property;
$this->title = $title;
+ $this->required = $required;
}
public function render(Formatter $formatter, array $schema, string $role): ?string
{
+ $row = sprintf('%s: ', $formatter->title($this->title));
+
if (!array_key_exists($this->property, $schema)) {
- return null;
+ return $this->required ? $row . $formatter->error('not defined') : null;
}
return sprintf(
- '%s: %s',
- $formatter->title($this->title),
+ '%s%s',
+ $row,
$formatter->typecast($schema[$this->property])
);
}
diff --git a/src/ConsoleRenderer/Renderers/RelationsRenderer.php b/src/ConsoleRenderer/Renderer/RelationsRenderer.php
similarity index 70%
rename from src/ConsoleRenderer/Renderers/RelationsRenderer.php
rename to src/ConsoleRenderer/Renderer/RelationsRenderer.php
index a743a7b..d74f2a2 100644
--- a/src/ConsoleRenderer/Renderers/RelationsRenderer.php
+++ b/src/ConsoleRenderer/Renderer/RelationsRenderer.php
@@ -2,7 +2,7 @@
declare(strict_types=1);
-namespace Cycle\Schema\Renderer\ConsoleRenderer\Renderers;
+namespace Cycle\Schema\Renderer\ConsoleRenderer\Renderer;
use Cycle\ORM\Relation;
use Cycle\ORM\SchemaInterface;
@@ -23,14 +23,13 @@ class RelationsRenderer implements Renderer
];
private const STR_PREFETCH_MODE = [
- Relation::LOAD_PROMISE => 'promise',
+ Relation::LOAD_PROMISE => 'lazy',
Relation::LOAD_EAGER => 'eager',
];
public function render(Formatter $formatter, array $schema, string $role): ?string
{
$title = sprintf('%s:', $formatter->title('Relations'));
- $table = $schema[SchemaInterface::TABLE] ?? null;
$relations = $schema[SchemaInterface::RELATIONS] ?? [];
if (count($relations) === 0) {
@@ -42,7 +41,7 @@ public function render(Formatter $formatter, array $schema, string $role): ?stri
foreach ($relations as $field => $relation) {
$type = self::STR_RELATION[$relation[Relation::TYPE] ?? ''] ?? '?';
$target = $relation[Relation::TARGET] ?? '?';
- $loading = self::STR_PREFETCH_MODE[$relation[Relation::LOAD] ?? ''] ?? '?';
+ $loading = self::STR_PREFETCH_MODE[$relation[Relation::LOAD] ?? ''] ?? 'default';
$relSchema = $relation[Relation::SCHEMA];
$innerKey = $relSchema[Relation::INNER_KEY] ?? '?';
$outerKey = $relSchema[Relation::OUTER_KEY] ?? '?';
@@ -61,42 +60,46 @@ public function render(Formatter $formatter, array $schema, string $role): ?stri
// print
$row = sprintf(
- " %s->%s %s %s %s load",
+ ' %s->%s %s %s',
$formatter->entity($role),
$formatter->property($field),
$type,
- $formatter->entity($target),
- $loading
+ $formatter->entity($target)
);
if ($morphKey !== null) {
$row .= sprintf(
- '%s: %s',
- $formatter->title('Morphed key'),
- $formatter->column($morphKey)
+ ', %s: %s',
+ $formatter->title('morphed key'),
+ $this->renderKeys($formatter, $morphKey)
);
}
- $rows[] = $row . ' ' . $formatter->info($cascadeStr);
+ $rows[] = $row . sprintf(', %s loading, %s', $formatter->info($loading), $formatter->info($cascadeStr));
$row = sprintf(
- " %s %s.%s <=",
+ ' %s %s.%s <=',
$nullableStr,
- $formatter->column($table),
- $formatter->column($innerKey),
+ $formatter->entity($role),
+ $this->renderKeys($formatter, $innerKey)
);
if ($mmEntity !== null) {
$row .= sprintf(
- " %s.%s | %s.%s ",
+ ' %s.%s | %s.%s ',
$formatter->entity($mmEntity),
- $formatter->column($mmInnerKey),
+ $this->renderKeys($formatter, $mmInnerKey),
$formatter->entity($mmEntity),
- $formatter->column($mmOuterKey),
+ $this->renderKeys($formatter, $mmOuterKey)
);
}
- $rows[] = $row . sprintf("=> %s.%s", $formatter->entity($target), $formatter->column($outerKey));
+ // todo: composite $outerKey
+ $rows[] = $row . sprintf(
+ '=> %s.%s',
+ $formatter->entity($target),
+ $this->renderKeys($formatter, $outerKey)
+ );
if (count($where)) {
$rows[] = sprintf(
@@ -115,6 +118,25 @@ public function render(Formatter $formatter, array $schema, string $role): ?stri
}
}
- return implode("\n", $rows);
+ return \implode("\n", $rows);
+ }
+
+ /**
+ * @param array|string $keys
+ */
+ private function renderKeys(Formatter $formatter, $keys): string
+ {
+ $keys = (array)$keys;
+ $braces = \count($keys) > 1;
+ $keys = \array_map(
+ static fn (string $key) => $formatter->property($key),
+ $keys
+ );
+ return sprintf(
+ '%s%s%s',
+ $braces ? '[' : '',
+ \implode(', ', $keys),
+ $braces ? ']' : ''
+ );
}
}
diff --git a/src/ConsoleRenderer/Renderers/TitleRenderer.php b/src/ConsoleRenderer/Renderer/TitleRenderer.php
similarity index 70%
rename from src/ConsoleRenderer/Renderers/TitleRenderer.php
rename to src/ConsoleRenderer/Renderer/TitleRenderer.php
index d6a2893..8f302cb 100644
--- a/src/ConsoleRenderer/Renderers/TitleRenderer.php
+++ b/src/ConsoleRenderer/Renderer/TitleRenderer.php
@@ -2,7 +2,7 @@
declare(strict_types=1);
-namespace Cycle\Schema\Renderer\ConsoleRenderer\Renderers;
+namespace Cycle\Schema\Renderer\ConsoleRenderer\Renderer;
use Cycle\ORM\SchemaInterface;
use Cycle\Schema\Renderer\ConsoleRenderer\Formatter;
@@ -12,14 +12,14 @@ class TitleRenderer implements Renderer
{
public function render(Formatter $formatter, array $schema, string $role): ?string
{
- $database = $schema[SchemaInterface::DATABASE] ?? null;
- $table = $schema[SchemaInterface::TABLE] ?? null;
+ $database = $schema[SchemaInterface::DATABASE] ?? '';
+ $table = $schema[SchemaInterface::TABLE] ?? '';
$row = $formatter->entity("[{$role}]");
if ($database !== null) {
$row .= sprintf(
- " :: %s.%s",
+ ' :: %s.%s',
$formatter->column($database),
$formatter->column($table)
);
diff --git a/src/ConsoleRenderer/Renderers/PrimaryKeysRenderer.php b/src/ConsoleRenderer/Renderers/PrimaryKeysRenderer.php
deleted file mode 100644
index 2577c90..0000000
--- a/src/ConsoleRenderer/Renderers/PrimaryKeysRenderer.php
+++ /dev/null
@@ -1,29 +0,0 @@
-title('Primary key'));
-
- if ($pk === null) {
- return $row . $formatter->error('not defined');
- }
-
- $pk = array_map(static function (string $key) use ($formatter) {
- return $formatter->column($key);
- }, (array)$pk);
-
- return $row . implode(', ', $pk);
- }
-}
diff --git a/src/OutputSchemaRenderer.php b/src/OutputSchemaRenderer.php
new file mode 100644
index 0000000..780cd9a
--- /dev/null
+++ b/src/OutputSchemaRenderer.php
@@ -0,0 +1,102 @@
+ 'Role',
+ 'ENTITY' => 'Entity',
+ 'MAPPER' => 'Mapper',
+ 'SCOPE' => 'Constrain',
+ 'REPOSITORY' => 'Repository',
+ ];
+
+ public function __construct(int $format = self::FORMAT_CONSOLE_COLOR)
+ {
+ $formatter = $format === self::FORMAT_CONSOLE_COLOR
+ ? new StyledFormatter()
+ : new PlainFormatter();
+ parent::__construct($formatter);
+
+ $constants = $this->getOrmConstants();
+ $properties = $this->getOrmProperties($constants);
+
+ $this->addRenderer(...[
+ new TitleRenderer(),
+
+ // Default properties renderer (Without extra logic)
+ ...array_map(static function ($property, string $title) {
+ return new PropertyRenderer($property, $title);
+ }, array_keys($properties), $properties),
+
+ new KeysRenderer(SchemaInterface::PRIMARY_KEY, 'Primary key', true),
+ ]);
+
+ // JTI support
+ if (isset($constants['PARENT'], $constants['PARENT_KEY'])) {
+ $this->addRenderer(...[
+ new PropertyRenderer($constants['PARENT'], 'CHILDREN'),
+ new KeysRenderer($constants['PARENT_KEY'], 'STI key', false),
+ ]);
+ }
+
+ // STI support
+ if (isset($constants['CHILDREN'], $constants['DISCRIMINATOR'])) {
+ $this->addRenderer(...[
+ new PropertyRenderer($constants['CHILDREN'], 'Parent'),
+ new KeysRenderer($constants['DISCRIMINATOR'], 'Parent key', false),
+ ]);
+ }
+
+ $this->addRenderer(...[
+ new ColumnsRenderer(),
+ new RelationsRenderer(),
+ new CustomPropertiesRenderer(array_values($constants)),
+ ]);
+ }
+
+ /**
+ * @param array $constants
+ *
+ * @return array
+ */
+ private function getOrmProperties(array $constants): array
+ {
+ $result = [];
+ foreach ($constants as $name => $value) {
+ if (!array_key_exists($name, self::DEFAULT_PROPERTY_LIST)) {
+ continue;
+ }
+ $result[$value] = self::DEFAULT_PROPERTY_LIST[$name];
+ }
+ return $result;
+ }
+
+ private function getOrmConstants(): array
+ {
+ return array_filter(
+ (new \ReflectionClass(SchemaInterface::class))->getConstants(),
+ 'is_int'
+ );
+ }
+}
diff --git a/src/PhpFileRenderer/DefaultSchemaGenerator.php b/src/PhpFileRenderer/DefaultSchemaGenerator.php
deleted file mode 100644
index 1258a75..0000000
--- a/src/PhpFileRenderer/DefaultSchemaGenerator.php
+++ /dev/null
@@ -1,34 +0,0 @@
-getConstants() as $key => $value) {
- if (!array_key_exists($value, $generators)) {
- if ($key === 'RELATIONS') {
- $generators[$value] = new RelationsGenerator();
- continue;
- }
-
- $generators[$value] = new PrimitiveGenerator('SchemaInterface::' . $key, $value);
- }
- }
-
- parent::__construct([
- ...$generators,
- new CustomPropertiesGenerator(array_keys($generators))
- ]);
- }
-}
diff --git a/src/PhpFileRenderer/Exporter/ArrayBlock.php b/src/PhpFileRenderer/Exporter/ArrayBlock.php
new file mode 100644
index 0000000..2e02b74
--- /dev/null
+++ b/src/PhpFileRenderer/Exporter/ArrayBlock.php
@@ -0,0 +1,65 @@
+value = $value;
+ $this->replaceKeys = $replaceKeys;
+ $this->replaceValues = $replaceValues;
+ }
+
+ final public function setIndentLevel(int $indentLevel = 0): self
+ {
+ $this->indentLevel = $indentLevel;
+ return $this;
+ }
+
+ final public function toString(): string
+ {
+ $result = [];
+ foreach ($this->value as $key => $value) {
+ if ($value instanceof ArrayItem) {
+ $value->setIndentLevel($this->indentLevel + 1);
+ $result[] = $value->toString();
+ continue;
+ }
+ $item = $this->wrapItem($key, $value);
+ $item->setIndentLevel($this->indentLevel + 1);
+
+ $result[] = $item->toString();
+ }
+ $indent = \str_repeat(self::INDENT, $this->indentLevel + 1);
+ $closedIndent = \str_repeat(self::INDENT, $this->indentLevel);
+ return $result === []
+ ? '[]'
+ : "[\n$indent" . \implode(",\n$indent", $result) . ",\n$closedIndent]";
+ }
+
+ /**
+ * @param int|string $key
+ * @param mixed $value
+ */
+ protected function wrapItem($key, $value): ArrayItem
+ {
+ $item = isset($this->replaceKeys[$key])
+ ? new ArrayItem($value, (string)$this->replaceKeys[$key], false)
+ : new ArrayItem($value, (string)$key, true);
+
+ if (is_scalar($value) && isset($this->replaceValues[$key][$value])) {
+ $item->setValue($this->replaceValues[$key][$value], false);
+ }
+ return $item;
+ }
+}
diff --git a/src/PhpFileRenderer/Exporter/ArrayItem.php b/src/PhpFileRenderer/Exporter/ArrayItem.php
new file mode 100644
index 0000000..de157e1
--- /dev/null
+++ b/src/PhpFileRenderer/Exporter/ArrayItem.php
@@ -0,0 +1,58 @@
+key = $key;
+ $this->value = $value;
+ $this->wrapKey = $wrapKey;
+ }
+
+ public function setIndentLevel(int $indentLevel = 0): self
+ {
+ $this->indentLevel = $indentLevel;
+ return $this;
+ }
+
+ public function toString(): string
+ {
+ $result = \str_repeat(self::INDENT, $this->indentLevel);
+ if ($this->key !== null) {
+ $result = $this->wrapKey ? "'{$this->key}' => " : "{$this->key} => ";
+ }
+ if ($this->value instanceof Indentable) {
+ $this->value->setIndentLevel($this->indentLevel);
+ }
+ return $result . ValueRenderer::render($this->value, $this->wrapValue, $this->indentLevel);
+ }
+
+ /**
+ * @param mixed $value
+ */
+ public function setValue($value, bool $wrapValue = true): self
+ {
+ $this->value = $value;
+ $this->wrapValue = $wrapValue;
+
+ return $this;
+ }
+}
diff --git a/src/PhpFileRenderer/Exporter/ExporterItem.php b/src/PhpFileRenderer/Exporter/ExporterItem.php
new file mode 100644
index 0000000..062eae2
--- /dev/null
+++ b/src/PhpFileRenderer/Exporter/ExporterItem.php
@@ -0,0 +1,12 @@
+ $item) {
+ $str = '';
+ if (!$item instanceof self && $withKeys) {
+ $str .= is_int($key) ? "{$key} => " : "'{$key}' => ";
+ }
+ $elements[] = $str . self::renderValue($item);
+ }
+ return '[' . \implode(', ', $elements) . ']';
+ }
+
+ private static function renderArrayBlock(array $value, bool $withKeys = true, int $indentLevel = 0): string
+ {
+ $braceIdent = \str_repeat(Indentable::INDENT, $indentLevel);
+ $itemIndent = \str_repeat(Indentable::INDENT, $indentLevel + 1);
+ $result = '[';
+ foreach ($value as $key => $item) {
+ $result .= "\n" . $itemIndent;
+ if ($item instanceof Indentable) {
+ $item->setIndentLevel($indentLevel + 1);
+ } elseif ($withKeys) {
+ $result .= is_int($key) ? "{$key} => " : "'{$key}' => ";
+ }
+ $result .= self::renderValue($item, true, $indentLevel + 1) . ',';
+ }
+ return $result . "\n$braceIdent]";
+ }
+
+ private static function isAutoIncrementedKeys(array $array): bool
+ {
+ return count($array) === 0 || array_keys($array) === range(0, count($array) - 1);
+ }
+
+ private static function isScalarArrayValues(array $array): bool
+ {
+ foreach ($array as $value) {
+ if (!is_scalar($value)) {
+ return false;
+ }
+ }
+ return true;
+ }
+}
diff --git a/src/PhpFileRenderer/Exporter/Rendering/Indentable.php b/src/PhpFileRenderer/Exporter/Rendering/Indentable.php
new file mode 100644
index 0000000..90ee678
--- /dev/null
+++ b/src/PhpFileRenderer/Exporter/Rendering/Indentable.php
@@ -0,0 +1,12 @@
+toString();
+ case !$wrapValue || is_int($value):
+ return (string)$value;
+ case is_string($value):
+ return "'" . addslashes($value) . "'";
+ default:
+ return "unserialize('" . addslashes(serialize($value)) . "')";
+ }
+ }
+}
diff --git a/src/PhpFileRenderer/Generator.php b/src/PhpFileRenderer/Generator.php
deleted file mode 100644
index 4a6069a..0000000
--- a/src/PhpFileRenderer/Generator.php
+++ /dev/null
@@ -1,15 +0,0 @@
-
- */
- public function generate(array $schema, string $role): array;
-}
diff --git a/src/PhpFileRenderer/Generators/CustomPropertiesGenerator.php b/src/PhpFileRenderer/Generators/CustomPropertiesGenerator.php
deleted file mode 100644
index 3ccf6f9..0000000
--- a/src/PhpFileRenderer/Generators/CustomPropertiesGenerator.php
+++ /dev/null
@@ -1,30 +0,0 @@
-propertiesWithGenerator = $propertiesWithGenerator;
- }
-
- public function generate(array $schema, string $role): array
- {
- $properties = [];
-
- foreach ($schema as $key => $data) {
- if (in_array($key, $this->propertiesWithGenerator, true)) {
- continue;
- }
- $properties[] = new VarExporter($key, $data, is_string($key));
- }
-
- return $properties;
- }
-}
diff --git a/src/PhpFileRenderer/Generators/PrimitiveGenerator.php b/src/PhpFileRenderer/Generators/PrimitiveGenerator.php
deleted file mode 100644
index 38677db..0000000
--- a/src/PhpFileRenderer/Generators/PrimitiveGenerator.php
+++ /dev/null
@@ -1,29 +0,0 @@
-key = $key;
- $this->property = $property;
- }
-
- public function generate(array $schema, string $role): array
- {
- return [
- new VarExporter($this->key, $schema[$this->property] ?? null)
- ];
- }
-}
diff --git a/src/PhpFileRenderer/Generators/RelationsGenerator.php b/src/PhpFileRenderer/Generators/RelationsGenerator.php
deleted file mode 100644
index 2dcd413..0000000
--- a/src/PhpFileRenderer/Generators/RelationsGenerator.php
+++ /dev/null
@@ -1,97 +0,0 @@
- 'Relation::HAS_ONE',
- Relation::HAS_MANY => 'Relation::HAS_MANY',
- Relation::BELONGS_TO => 'Relation::BELONGS_TO',
- Relation::REFERS_TO => 'Relation::REFERS_TO',
- Relation::MANY_TO_MANY => 'Relation::MANY_TO_MANY',
- Relation::BELONGS_TO_MORPHED => 'Relation::BELONGS_TO_MORPHED',
- Relation::MORPHED_HAS_ONE => 'Relation::MORPHED_HAS_ONE',
- Relation::MORPHED_HAS_MANY => 'Relation::MORPHED_HAS_MANY',
- ];
-
- private const PREFETCH_MODE = [
- Relation::LOAD_PROMISE => 'Relation::LOAD_PROMISE',
- Relation::LOAD_EAGER => 'Relation::LOAD_EAGER',
- ];
-
- private const RELATION_OPTION = [
- Relation::MORPH_KEY => 'Relation::MORPH_KEY',
- Relation::CASCADE => 'Relation::CASCADE',
- Relation::NULLABLE => 'Relation::NULLABLE',
- Relation::OUTER_KEY => 'Relation::OUTER_KEY',
- Relation::INNER_KEY => 'Relation::INNER_KEY',
- Relation::WHERE => 'Relation::WHERE',
- Relation::THROUGH_INNER_KEY => 'Relation::THROUGH_INNER_KEY',
- Relation::THROUGH_OUTER_KEY => 'Relation::THROUGH_OUTER_KEY',
- Relation::THROUGH_ENTITY => 'Relation::THROUGH_ENTITY',
- Relation::THROUGH_WHERE => 'Relation::THROUGH_WHERE',
- ];
-
- private const GENERAL_OPTION = [
- Relation::TYPE => 'Relation::TYPE',
- Relation::TARGET => 'Relation::TARGET',
- Relation::SCHEMA => 'Relation::SCHEMA',
- Relation::LOAD => 'Relation::LOAD',
- ];
-
- public function generate(array $schema, string $role): array
- {
- $relations = $schema[SchemaInterface::RELATIONS] ?? [];
-
- $results = [];
- foreach ($relations as $field => $relation) {
- $relationResult = [];
- foreach ($relation as $option => $value) {
- $relationResult[] = $this->renderRelationOption($option, $value);
- }
-
- $results[] = new VarExporter($field, $relationResult, true);
- }
-
- return [
- new VarExporter('SchemaInterface::RELATIONS', $results)
- ];
- }
-
- private function renderRelationOption(int $option, $value): VarExporter
- {
- $item = new VarExporter(self::GENERAL_OPTION[$option] ?? (string)$option, $value);
-
- // replace numeric keys and values with constants
- if ($option === Relation::LOAD && array_key_exists($value, self::PREFETCH_MODE)) {
- $item->setValue(self::PREFETCH_MODE[$value], false);
- } elseif ($option === Relation::TYPE && array_key_exists($value, self::RELATION)) {
- $item->setValue(self::RELATION[$value], false);
- } elseif ($option === Relation::SCHEMA && is_array($value)) {
- $item->setValue($this->renderRelationSchemaKeys($value));
- }
-
- return $item;
- }
-
- private function renderRelationSchemaKeys(array $value): array
- {
- $result = [];
- foreach ($value as $listKey => $listValue) {
- $result[] = new VarExporter(
- array_key_exists($listKey, self::RELATION_OPTION) ? self::RELATION_OPTION[$listKey] : (string)$listKey,
- $listValue
- );
- }
-
- return $result;
- }
-}
diff --git a/src/PhpFileRenderer/Item/RelationBlock.php b/src/PhpFileRenderer/Item/RelationBlock.php
new file mode 100644
index 0000000..fbd6306
--- /dev/null
+++ b/src/PhpFileRenderer/Item/RelationBlock.php
@@ -0,0 +1,63 @@
+setValue(new self($value, $this->getReplaceKeys()), false);
+ }
+ return $item;
+ }
+
+ /**
+ * @return array
+ */
+ private function getReplaceKeys(): array
+ {
+ static $result = [];
+ if ($result !== []) {
+ return $result;
+ }
+ $constants = (new \ReflectionClass(Relation::class))->getConstants();
+ foreach ($constants as $name => $value) {
+ if (!in_array($name, self::RELATION_SCHEMA_KEYS, true) || array_key_exists($value, $result)) {
+ continue;
+ }
+ $result[$value] = 'Relation::' . $name;
+ }
+
+ return $result;
+ }
+}
diff --git a/src/PhpFileRenderer/Item/RelationsBlock.php b/src/PhpFileRenderer/Item/RelationsBlock.php
new file mode 100644
index 0000000..fe8b8a6
--- /dev/null
+++ b/src/PhpFileRenderer/Item/RelationsBlock.php
@@ -0,0 +1,49 @@
+ 'Relation::TYPE',
+ Relation::TARGET => 'Relation::TARGET',
+ Relation::SCHEMA => 'Relation::SCHEMA',
+ Relation::LOAD => 'Relation::LOAD',
+ ];
+
+ private const OPTION_VALUES = [
+ Relation::LOAD => [
+ Relation::LOAD_PROMISE => 'Relation::LOAD_PROMISE',
+ Relation::LOAD_EAGER => 'Relation::LOAD_EAGER',
+ ],
+ Relation::TYPE => [
+ Relation::HAS_ONE => 'Relation::HAS_ONE',
+ Relation::HAS_MANY => 'Relation::HAS_MANY',
+ Relation::BELONGS_TO => 'Relation::BELONGS_TO',
+ Relation::REFERS_TO => 'Relation::REFERS_TO',
+ Relation::MANY_TO_MANY => 'Relation::MANY_TO_MANY',
+ Relation::BELONGS_TO_MORPHED => 'Relation::BELONGS_TO_MORPHED',
+ Relation::MORPHED_HAS_ONE => 'Relation::MORPHED_HAS_ONE',
+ Relation::MORPHED_HAS_MANY => 'Relation::MORPHED_HAS_MANY',
+ ],
+ ];
+
+ /**
+ * @param int|string $key
+ * @param mixed $value
+ */
+ protected function wrapItem($key, $value): ArrayItem
+ {
+ $item = parent::wrapItem($key, $value);
+ if (is_array($value)) {
+ $item->setValue(new RelationBlock($value, self::OPTION_KEYS, self::OPTION_VALUES), false);
+ }
+ return $item;
+ }
+}
diff --git a/src/PhpFileRenderer/Item/RoleBlock.php b/src/PhpFileRenderer/Item/RoleBlock.php
new file mode 100644
index 0000000..0afcb81
--- /dev/null
+++ b/src/PhpFileRenderer/Item/RoleBlock.php
@@ -0,0 +1,25 @@
+setValue(new RelationsBlock($value), false);
+ }
+ return $item;
+ }
+}
diff --git a/src/PhpFileRenderer/SchemaGenerator.php b/src/PhpFileRenderer/SchemaGenerator.php
deleted file mode 100644
index 7458d19..0000000
--- a/src/PhpFileRenderer/SchemaGenerator.php
+++ /dev/null
@@ -1,30 +0,0 @@
-generators = $generators;
- }
-
- public function generate(array $schema, string $role): array
- {
- /** @var array $array */
- $array = [];
-
- foreach ($this->generators as $generator) {
- foreach ($generator->generate($schema, $role) as $property) {
- $array[] = $property;
- }
- }
-
- return $array;
- }
-}
diff --git a/src/PhpFileRenderer/VarExporter.php b/src/PhpFileRenderer/VarExporter.php
deleted file mode 100644
index 456621f..0000000
--- a/src/PhpFileRenderer/VarExporter.php
+++ /dev/null
@@ -1,118 +0,0 @@
-key = $key;
- $this->value = $value;
- $this->wrapKey = $wrapKey;
- }
-
- public function __toString()
- {
- $result = '';
- if ($this->key !== null) {
- $result = $this->wrapKey ? "'{$this->key}' => " : "{$this->key} => ";
- }
- return $result . $this->renderValue($this->value);
- }
-
- public function setValue($value, bool $wrapValue = true): self
- {
- $this->value = $value;
- $this->wrapValue = $wrapValue;
-
- return $this;
- }
-
- /**
- * @param mixed $value
- *
- * @return string
- */
- private function renderValue($value): string
- {
- switch (true) {
- case $value === null:
- return 'null';
- case is_bool($value):
- return $value ? 'true' : 'false';
- case is_array($value):
- return $this->renderArray($value);
- case !$this->wrapValue || is_int($value) || $value instanceof self:
- return (string)$value;
- case is_string($value):
- return "'" . addslashes($value) . "'";
- default:
- return "unserialize('" . addslashes(serialize($value)) . "')";
- }
- }
-
- private function renderArray(array $value): string
- {
- $aiKeys = $this->isAutoIncrementedKeys($value);
- $inline = $aiKeys && $this->isScalarArrayValues($value);
- if ($inline) {
- $result = $this->renderArrayInline($value, !$aiKeys);
- if (strlen($result) <= self::MIX_LINE_LENGTH) {
- return $result;
- }
- }
- return $this->renderArrayBlock($value, !$aiKeys);
- }
-
- private function renderArrayInline(array $value, bool $withKeys = true): string
- {
- $elements = [];
- foreach ($value as $key => $item) {
- $str = '';
- if (!$item instanceof self && $withKeys) {
- $str .= is_int($key) ? "{$key} => " : "'{$key}' => ";
- }
- $elements[] = $str . $this->renderValue($item);
- }
- return '[' . implode(', ', $elements) . ']';
- }
-
- private function renderArrayBlock(array $value, bool $withKeys = true): string
- {
- $result = '[';
- foreach ($value as $key => $item) {
- $result .= "\n";
- if (!$item instanceof self && $withKeys) {
- $result .= is_int($key) ? "{$key} => " : "'{$key}' => ";
- }
- $result .= $this->renderValue($item) . ',';
- }
- return str_replace("\n", "\n ", $result) . "\n]";
- }
-
- private function isAutoIncrementedKeys(array $array): bool
- {
- return count($array) === 0 || array_keys($array) === range(0, count($array) - 1);
- }
-
- private function isScalarArrayValues(array $array): bool
- {
- foreach ($array as $value) {
- if (!is_scalar($value)) {
- return false;
- }
- }
- return true;
- }
-}
diff --git a/src/PhpSchemaRenderer.php b/src/PhpSchemaRenderer.php
new file mode 100644
index 0000000..8d685d5
--- /dev/null
+++ b/src/PhpSchemaRenderer.php
@@ -0,0 +1,71 @@
+ $roleSchema) {
+ $item = new ArrayItem(
+ $this->wrapRoleSchema($roleSchema),
+ $role,
+ true
+ );
+ $items[] = $item->setIndentLevel();
+ }
+
+ $rendered = (new ArrayBlock($items))->toString();
+
+ return $result . "\nreturn {$rendered};\n";
+ }
+
+ protected function wrapRoleSchema(array $roleSchema): ExporterItem
+ {
+ return new RoleBlock(
+ $roleSchema,
+ $this->getSchemaConstants()
+ );
+ }
+
+ /**
+ * @return array (Option value => constant name) array
+ */
+ final protected function getSchemaConstants(): array
+ {
+ $result = array_filter(
+ (new \ReflectionClass(SchemaInterface::class))->getConstants(),
+ static fn ($value): bool => is_int($value)
+ );
+ $result = array_flip($result);
+ array_walk($result, static function (string &$name): void {
+ $name = "Schema::$name";
+ });
+ return $result;
+ }
+}
diff --git a/src/SchemaRenderer.php b/src/SchemaRenderer.php
new file mode 100644
index 0000000..52c1977
--- /dev/null
+++ b/src/SchemaRenderer.php
@@ -0,0 +1,16 @@
+> $schema Cycle ORM schema as array. You can convert {@see SchemaInterface}
+ * instance via {@see SchemaToArrayConverter}
+ */
+ public function render(array $schema): string;
+}
diff --git a/src/SchemaToArrayConverter.php b/src/SchemaToArrayConverter.php
index f68aa98..5a546f9 100644
--- a/src/SchemaToArrayConverter.php
+++ b/src/SchemaToArrayConverter.php
@@ -6,28 +6,15 @@
use Cycle\ORM\SchemaInterface;
-class SchemaToArrayConverter
+/**
+ * The class converts the {@see SchemaInterface} class implementation into a Cycle ORM specific array
+ */
+final class SchemaToArrayConverter
{
- private const PROPERTIES = [
- SchemaInterface::ENTITY,
- SchemaInterface::MAPPER,
- SchemaInterface::SOURCE,
- SchemaInterface::REPOSITORY,
- SchemaInterface::DATABASE,
- SchemaInterface::TABLE,
- SchemaInterface::PRIMARY_KEY,
- SchemaInterface::FIND_BY_KEYS,
- SchemaInterface::COLUMNS,
- SchemaInterface::RELATIONS,
- SchemaInterface::CHILDREN,
- SchemaInterface::SCOPE,
- SchemaInterface::TYPECAST,
- SchemaInterface::SCHEMA,
- ];
-
/**
* @param SchemaInterface $schema
- * @param array $customProperties
+ * @param array $customProperties
+ *
* @return array>
*/
public function convert(SchemaInterface $schema, array $customProperties = []): array
@@ -39,21 +26,31 @@ public function convert(SchemaInterface $schema, array $customProperties = []):
$result = [];
- $properties = [...self::PROPERTIES, ...$customProperties];
+ $properties = array_merge($this->getSchemaConstants(), $customProperties);
foreach ($schema->getRoles() as $role) {
- $aliasOf = $schema->resolveAlias($role);
-
- if ($aliasOf !== null && $aliasOf !== $role) {
- // This role is an alias
- continue;
- }
-
foreach ($properties as $property) {
- $result[$role][$property] = $schema->define($role, $property);
+ /** @psalm-suppress ReservedWord */
+ $value = $schema->define($role, $property);
+ if ($value === null) {
+ continue;
+ }
+ $result[$role][$property] = $value;
}
}
return $result;
}
+
+ /**
+ * @return array
+ */
+ private function getSchemaConstants(): array
+ {
+ $result = array_filter(
+ (new \ReflectionClass(SchemaInterface::class))->getConstants(),
+ static fn ($value): bool => is_int($value)
+ );
+ return array_values($result);
+ }
}
diff --git a/src/SchemaToPhpFileRenderer.php b/src/SchemaToPhpFileRenderer.php
deleted file mode 100644
index c09e63c..0000000
--- a/src/SchemaToPhpFileRenderer.php
+++ /dev/null
@@ -1,49 +0,0 @@
-generator = $generator;
- $this->schema = $schema;
- }
-
- public function render(): string
- {
- $schema = [];
-
- $result = "schema as $role => $roleSchema) {
- $schema[] = new VarExporter(
- $role,
- $this->generator->generate($roleSchema, $role),
- true
- );
- }
-
- $renderedArray = implode(",\n", $schema);
-
- return $result . "\nreturn [\n{$renderedArray}\n];";
- }
-}
diff --git a/tests/Schema/Renderer/ConsoleRenderer/OutputRendererTest.php b/tests/Schema/Renderer/ConsoleRenderer/OutputRendererTest.php
index 5b9f8f4..a5a2453 100644
--- a/tests/Schema/Renderer/ConsoleRenderer/OutputRendererTest.php
+++ b/tests/Schema/Renderer/ConsoleRenderer/OutputRendererTest.php
@@ -1,22 +1,23 @@
['id', 'name'],
SchemaInterface::TYPECAST => ['id' => 'int'],
SchemaInterface::SCHEMA => [],
- SchemaInterface::RELATIONS => []
+ SchemaInterface::RELATIONS => [],
],
TagContext::class => [
SchemaInterface::ROLE => 'tag_context',
@@ -43,8 +44,8 @@ protected function setUp(): void
SchemaInterface::COLUMNS => [],
SchemaInterface::TYPECAST => ['id' => 'int', 'user_id' => 'int', 'tag_id' => 'int'],
SchemaInterface::SCHEMA => [],
- SchemaInterface::RELATIONS => []
- ]
+ SchemaInterface::RELATIONS => [],
+ ],
]);
$this->schemaArray = (new SchemaToArrayConverter())->convert($schema);
@@ -52,35 +53,37 @@ protected function setUp(): void
public function testSchemaShouldBeRenderedByGivenRenderers(): void
{
- $renderer = new OutputRenderer(
- $this->schemaArray, new StyledFormatter(), [
- new TitleRenderer()
- ]
- );
+ $renderer = new OutputRenderer(new StyledFormatter(), [
+ new TitleRenderer(),
+ ]);
$this->assertSame(
- "[35m[tag][39m :: [32mdefault[39m.[32mtag[39m
+ <<render($this->schemaArray)
);
}
public function testSchemaShouldBeRenderedByGivenFormatter(): void
{
- $renderer = new OutputRenderer(
- $this->schemaArray, new PlainFormatter(), [
- new TitleRenderer()
- ]
- );
+ $renderer = new OutputRenderer(new PlainFormatter(), [
+ new TitleRenderer(),
+ ]);
$this->assertSame(
- "[tag] :: default.tag
+ <<render($this->schemaArray)
);
}
}
diff --git a/tests/Schema/Renderer/Fixtures/Tag.php b/tests/Schema/Renderer/Fixture/Tag.php
similarity index 50%
rename from tests/Schema/Renderer/Fixtures/Tag.php
rename to tests/Schema/Renderer/Fixture/Tag.php
index b43f72a..9402ad4 100644
--- a/tests/Schema/Renderer/Fixtures/Tag.php
+++ b/tests/Schema/Renderer/Fixture/Tag.php
@@ -2,7 +2,7 @@
declare(strict_types=1);
-namespace Cycle\Schema\Renderer\Tests\Fixtures;
+namespace Cycle\Schema\Renderer\Tests\Fixture;
class Tag
{
diff --git a/tests/Schema/Renderer/Fixtures/TagContext.php b/tests/Schema/Renderer/Fixture/TagContext.php
similarity index 53%
rename from tests/Schema/Renderer/Fixtures/TagContext.php
rename to tests/Schema/Renderer/Fixture/TagContext.php
index 121b782..559beac 100644
--- a/tests/Schema/Renderer/Fixtures/TagContext.php
+++ b/tests/Schema/Renderer/Fixture/TagContext.php
@@ -2,7 +2,7 @@
declare(strict_types=1);
-namespace Cycle\Schema\Renderer\Tests\Fixtures;
+namespace Cycle\Schema\Renderer\Tests\Fixture;
class TagContext
{
diff --git a/tests/Schema/Renderer/Fixtures/User.php b/tests/Schema/Renderer/Fixture/User.php
similarity index 71%
rename from tests/Schema/Renderer/Fixtures/User.php
rename to tests/Schema/Renderer/Fixture/User.php
index f3647a8..80e7395 100644
--- a/tests/Schema/Renderer/Fixtures/User.php
+++ b/tests/Schema/Renderer/Fixture/User.php
@@ -2,7 +2,7 @@
declare(strict_types=1);
-namespace Cycle\Schema\Renderer\Tests\Fixtures;
+namespace Cycle\Schema\Renderer\Tests\Fixture;
class User
{
diff --git a/tests/Schema/Renderer/Fixture/console_output.stub.txt b/tests/Schema/Renderer/Fixture/console_output.stub.txt
new file mode 100644
index 0000000..376d08b
--- /dev/null
+++ b/tests/Schema/Renderer/Fixture/console_output.stub.txt
@@ -0,0 +1,37 @@
+[35m[Cycle\Schema\Renderer\Tests\Fixture\User][39m :: [32mdefault[39m.[32muser[39m
+ Role: [34muser[39m
+ Mapper: [34mCycle\ORM\Mapper\Mapper[39m
+ Primary key: [36mid[39m
+ Fields:
+ ([36mproperty[39m -> [32mdb.field[39m -> [34mtypecast[39m)
+ [36m0[39m -> [32mid[39m -> [34mint[39m
+ [36m1[39m -> [32memail[39m
+ [36m2[39m -> [32mbalance[39m -> [34mfloat[39m
+ Relations:
+ [35mCycle\Schema\Renderer\Tests\Fixture\User[39m->[36mtags[39m many to many [35mCycle\Schema\Renderer\Tests\Fixture\Tag[39m, [33mdefault[39m loading, [33mcascaded[39m
+ n/a [35mCycle\Schema\Renderer\Tests\Fixture\User[39m.[36mid[39m <= [35mtag_context[39m.[36muser_id[39m | [35mtag_context[39m.[36mtag_id[39m => [35mCycle\Schema\Renderer\Tests\Fixture\Tag[39m.[36mid[39m
+ [35mCycle\Schema\Renderer\Tests\Fixture\User[39m->[36mtag[39m belongs to [35mCycle\Schema\Renderer\Tests\Fixture\Tag[39m, [33mdefault[39m loading, [33mcascaded[39m
+ n/a [35mCycle\Schema\Renderer\Tests\Fixture\User[39m.[36mtag_id[39m <==> [35mCycle\Schema\Renderer\Tests\Fixture\Tag[39m.[36mid[39m
+
+[35m[Cycle\Schema\Renderer\Tests\Fixture\Tag][39m :: [32mdefault[39m.[32mtag[39m
+ Role: [34mtag[39m
+ Mapper: [34mCycle\ORM\Mapper\Mapper[39m
+ Primary key: [36mid[39m, [36mname[39m
+ Fields:
+ ([36mproperty[39m -> [32mdb.field[39m -> [34mtypecast[39m)
+ [36m0[39m -> [32mid[39m -> [34mint[39m
+ [36m1[39m -> [32mname[39m
+ Relations:
+ [35mCycle\Schema\Renderer\Tests\Fixture\Tag[39m->[36muser[39m belongs to [35mCycle\Schema\Renderer\Tests\Fixture\User[39m, [33mdefault[39m loading, [33mcascaded[39m
+ n/a [35mCycle\Schema\Renderer\Tests\Fixture\Tag[39m.[36muser_id[39m <==> [35mCycle\Schema\Renderer\Tests\Fixture\User[39m.[36mid[39m
+
+[35m[Cycle\Schema\Renderer\Tests\Fixture\TagContext][39m :: [32mdefault[39m.[32mtag_user_map[39m
+ Role: [34mtag_context[39m
+ Mapper: [34mCycle\ORM\Mapper\Mapper[39m
+ Primary key: [31mnot defined[39m
+ Fields: [31mnot defined[39m
+ Relations: [31mnot defined[39m
+ Custom props:
+ my_custom_property: [34msuper_value[39m
+ 25: [34msuper_value[39m
+
diff --git a/tests/Schema/Renderer/Fixture/console_output_plain.stub.txt b/tests/Schema/Renderer/Fixture/console_output_plain.stub.txt
new file mode 100644
index 0000000..93a9f2b
--- /dev/null
+++ b/tests/Schema/Renderer/Fixture/console_output_plain.stub.txt
@@ -0,0 +1,34 @@
+[user] :: default.user
+ Entity: Cycle\Schema\Renderer\Tests\Fixture\User
+ Mapper: Cycle\ORM\Mapper\Mapper
+ Primary key: id
+ Fields:
+ (property -> db.field -> typecast)
+ 0 -> id -> int
+ 1 -> email
+ 2 -> balance -> float
+ Relations:
+ user->tags many to many tag, default loading, cascaded
+ n/a user.id <= tag_context.user_id | tag_context.tag_id => tag.id
+ user->tag belongs to tag, default loading, cascaded
+ n/a user.tag_id <==> tag.id
+
+[tag] :: default.tag
+ Entity: Cycle\Schema\Renderer\Tests\Fixture\Tag
+ Mapper: Cycle\ORM\Mapper\Mapper
+ Primary key: id, name
+ Fields:
+ (property -> db.field -> typecast)
+ 0 -> id -> int
+ 1 -> name
+ Relations:
+ tag->user belongs to user, default loading, cascaded
+ n/a tag.user_id <==> user.id
+
+[tag_context] :: default.tag_user_map
+ Entity: Cycle\Schema\Renderer\Tests\Fixture\TagContext
+ Mapper: Cycle\ORM\Mapper\Mapper
+ Primary key: not defined
+ Fields: not defined
+ Relations: not defined
+
diff --git a/tests/Schema/Renderer/Fixture/console_output_with_custom_properties.stub.txt b/tests/Schema/Renderer/Fixture/console_output_with_custom_properties.stub.txt
new file mode 100644
index 0000000..ef96217
--- /dev/null
+++ b/tests/Schema/Renderer/Fixture/console_output_with_custom_properties.stub.txt
@@ -0,0 +1,38 @@
+[35m[Cycle\Schema\Renderer\Tests\Fixture\User][39m :: [32mdefault[39m.[32muser[39m
+ Role: [34muser[39m
+ Mapper: [34mCycle\ORM\Mapper\Mapper[39m
+ Primary key: [36mid[39m
+ Fields:
+ ([36mproperty[39m -> [32mdb.field[39m -> [34mtypecast[39m)
+ [36m0[39m -> [32mid[39m -> [34mint[39m
+ [36m1[39m -> [32memail[39m
+ [36m2[39m -> [32mbalance[39m -> [34mfloat[39m
+ Relations:
+ [35mCycle\Schema\Renderer\Tests\Fixture\User[39m->[36mtags[39m many to many [35mCycle\Schema\Renderer\Tests\Fixture\Tag[39m, [33mdefault[39m loading, [33mcascaded[39m
+ n/a [35mCycle\Schema\Renderer\Tests\Fixture\User[39m.[36mid[39m <= [35mtag_context[39m.[36muser_id[39m | [35mtag_context[39m.[36mtag_id[39m => [35mCycle\Schema\Renderer\Tests\Fixture\Tag[39m.[36mid[39m
+ [35mCycle\Schema\Renderer\Tests\Fixture\User[39m->[36mtag[39m belongs to [35mCycle\Schema\Renderer\Tests\Fixture\Tag[39m, [33mdefault[39m loading, [33mcascaded[39m
+ n/a [35mCycle\Schema\Renderer\Tests\Fixture\User[39m.[36mtag_id[39m <==> [35mCycle\Schema\Renderer\Tests\Fixture\Tag[39m.[36mid[39m
+ Source: [34mtest[39m
+
+[35m[Cycle\Schema\Renderer\Tests\Fixture\Tag][39m :: [32mdefault[39m.[32mtag[39m
+ Role: [34mtag[39m
+ Mapper: [34mCycle\ORM\Mapper\Mapper[39m
+ Primary key: [36mid[39m, [36mname[39m
+ Fields:
+ ([36mproperty[39m -> [32mdb.field[39m -> [34mtypecast[39m)
+ [36m0[39m -> [32mid[39m -> [34mint[39m
+ [36m1[39m -> [32mname[39m
+ Relations:
+ [35mCycle\Schema\Renderer\Tests\Fixture\Tag[39m->[36muser[39m belongs to [35mCycle\Schema\Renderer\Tests\Fixture\User[39m, [33mdefault[39m loading, [33mcascaded[39m
+ n/a [35mCycle\Schema\Renderer\Tests\Fixture\Tag[39m.[36muser_id[39m <==> [35mCycle\Schema\Renderer\Tests\Fixture\User[39m.[36mid[39m
+
+[35m[Cycle\Schema\Renderer\Tests\Fixture\TagContext][39m :: [32mdefault[39m.[32mtag_user_map[39m
+ Role: [34mtag_context[39m
+ Mapper: [34mCycle\ORM\Mapper\Mapper[39m
+ Primary key: [31mnot defined[39m
+ Fields: [31mnot defined[39m
+ Relations: [31mnot defined[39m
+ Custom props:
+ my_custom_property: [34msuper_value[39m
+ 25: [34msuper_value[39m
+
diff --git a/tests/Schema/Renderer/Fixture/generated_schema.stub.php b/tests/Schema/Renderer/Fixture/generated_schema.stub.php
new file mode 100644
index 0000000..208186f
--- /dev/null
+++ b/tests/Schema/Renderer/Fixture/generated_schema.stub.php
@@ -0,0 +1,82 @@
+ [
+ Schema::ENTITY => 'Cycle\\Schema\\Renderer\\Tests\\Fixture\\User',
+ Schema::MAPPER => 'Cycle\\ORM\\Mapper\\Mapper',
+ Schema::DATABASE => 'default',
+ Schema::TABLE => 'user',
+ Schema::PRIMARY_KEY => 'id',
+ Schema::COLUMNS => ['id', 'email', 'balance'],
+ Schema::RELATIONS => [
+ 'tags' => [
+ Relation::TYPE => Relation::MANY_TO_MANY,
+ Relation::TARGET => 'tag',
+ Relation::SCHEMA => [
+ Relation::CASCADE => true,
+ Relation::THROUGH_ENTITY => 'tag_context',
+ Relation::INNER_KEY => 'id',
+ Relation::OUTER_KEY => 'id',
+ Relation::THROUGH_INNER_KEY => 'user_id',
+ Relation::THROUGH_OUTER_KEY => 'tag_id',
+ ],
+ ],
+ 'tag' => [
+ Relation::TYPE => Relation::BELONGS_TO,
+ Relation::TARGET => 'tag',
+ Relation::SCHEMA => [
+ Relation::CASCADE => true,
+ Relation::INNER_KEY => 'tag_id',
+ Relation::OUTER_KEY => 'id',
+ ],
+ ],
+ ],
+ Schema::TYPECAST => [
+ 'id' => 'int',
+ 'balance' => 'float',
+ ],
+ Schema::SCHEMA => [],
+ ],
+ 'tag' => [
+ Schema::ENTITY => 'Cycle\\Schema\\Renderer\\Tests\\Fixture\\Tag',
+ Schema::MAPPER => 'Cycle\\ORM\\Mapper\\Mapper',
+ Schema::DATABASE => 'default',
+ Schema::TABLE => 'tag',
+ Schema::PRIMARY_KEY => ['id', 'name'],
+ Schema::COLUMNS => ['id', 'name'],
+ Schema::RELATIONS => [
+ 'user' => [
+ Relation::TYPE => Relation::BELONGS_TO,
+ Relation::TARGET => 'user',
+ Relation::SCHEMA => [
+ Relation::CASCADE => true,
+ Relation::INNER_KEY => 'user_id',
+ Relation::OUTER_KEY => 'id',
+ ],
+ ],
+ ],
+ Schema::TYPECAST => [
+ 'id' => 'int',
+ ],
+ Schema::SCHEMA => [],
+ ],
+ 'tag_context' => [
+ Schema::ENTITY => 'Cycle\\Schema\\Renderer\\Tests\\Fixture\\TagContext',
+ Schema::MAPPER => 'Cycle\\ORM\\Mapper\\Mapper',
+ Schema::DATABASE => 'default',
+ Schema::TABLE => 'tag_user_map',
+ Schema::COLUMNS => [],
+ Schema::RELATIONS => [],
+ Schema::TYPECAST => [
+ 'id' => 'int',
+ 'user_id' => 'int',
+ 'tag_id' => 'int',
+ ],
+ Schema::SCHEMA => [],
+ ],
+];
diff --git a/tests/Schema/Renderer/Fixtures/console_output.txt b/tests/Schema/Renderer/Fixtures/console_output.txt
deleted file mode 100644
index 09f2258..0000000
--- a/tests/Schema/Renderer/Fixtures/console_output.txt
+++ /dev/null
@@ -1,36 +0,0 @@
-[35m[Cycle\Schema\Renderer\Tests\Fixtures\User][39m :: [32mdefault[39m.[32muser[39m
- Role: [34muser[39m
- Mapper: [34mCycle\ORM\Mapper\Mapper[39m
- Primary key: [32mid[39m
- Fields:
- ([36mproperty[39m -> [32mdb.field[39m -> [34mtypecast[39m)
- [36m0[39m -> [32mid[39m -> [34mint[39m
- [36m1[39m -> [32memail[39m
- [36m2[39m -> [32mbalance[39m -> [34mfloat[39m
- Relations:
- [35mCycle\Schema\Renderer\Tests\Fixtures\User[39m->[36mtags[39m many to many [35mCycle\Schema\Renderer\Tests\Fixtures\Tag[39m ? load [33mcascaded[39m
- n/a [32muser[39m.[32mid[39m <= [35mtag_context[39m.[32muser_id[39m | [35mtag_context[39m.[32mtag_id[39m => [35mCycle\Schema\Renderer\Tests\Fixtures\Tag[39m.[32mid[39m
- [35mCycle\Schema\Renderer\Tests\Fixtures\User[39m->[36mtag[39m belongs to [35mCycle\Schema\Renderer\Tests\Fixtures\Tag[39m ? load [33mcascaded[39m
- n/a [32muser[39m.[32mtag_id[39m <==> [35mCycle\Schema\Renderer\Tests\Fixtures\Tag[39m.[32mid[39m
-
-[35m[Cycle\Schema\Renderer\Tests\Fixtures\Tag][39m :: [32mdefault[39m.[32mtag[39m
- Role: [34mtag[39m
- Mapper: [34mCycle\ORM\Mapper\Mapper[39m
- Primary key: [32mid[39m, [32mname[39m
- Fields:
- ([36mproperty[39m -> [32mdb.field[39m -> [34mtypecast[39m)
- [36m0[39m -> [32mid[39m -> [34mint[39m
- [36m1[39m -> [32mname[39m
- Relations:
- [35mCycle\Schema\Renderer\Tests\Fixtures\Tag[39m->[36muser[39m belongs to [35mCycle\Schema\Renderer\Tests\Fixtures\User[39m ? load [33mcascaded[39m
- n/a [32mtag[39m.[32muser_id[39m <==> [35mCycle\Schema\Renderer\Tests\Fixtures\User[39m.[32mid[39m
-
-[35m[Cycle\Schema\Renderer\Tests\Fixtures\TagContext][39m :: [32mdefault[39m.[32mtag_user_map[39m
- Role: [34mtag_context[39m
- Mapper: [34mCycle\ORM\Mapper\Mapper[39m
- Primary key: [31mnot defined[39m
- Fields: [31mnot defined[39m
- Relations: [31mnot defined[39m
- Custom props:
- my_custom_property: [34msuper_value[39m
- 25: [34msuper_value[39m
\ No newline at end of file
diff --git a/tests/Schema/Renderer/Fixtures/console_output_plain.txt b/tests/Schema/Renderer/Fixtures/console_output_plain.txt
deleted file mode 100644
index c3ea56c..0000000
--- a/tests/Schema/Renderer/Fixtures/console_output_plain.txt
+++ /dev/null
@@ -1,42 +0,0 @@
-[user] :: default.user
- Entity: Cycle\Schema\Renderer\Tests\Fixtures\User
- Mapper: Cycle\ORM\Mapper\Mapper
- Constrain: not defined
- Repository: not defined
- Primary key: id
- Fields:
- (property -> db.field -> typecast)
- 0 -> id -> int
- 1 -> email
- 2 -> balance -> float
- Relations:
- user->tags many to many tag ? load cascaded
- n/a user.id <= tag_context.user_id | tag_context.tag_id => tag.id
- user->tag belongs to tag ? load cascaded
- n/a user.tag_id <==> tag.id
-Custom props:
- 123 : sdasd
- abc : [111, 11]
-
-[tag] :: default.tag
- Entity: Cycle\Schema\Renderer\Tests\Fixtures\Tag
- Mapper: Cycle\ORM\Mapper\Mapper
- Constrain: not defined
- Repository: not defined
- Primary key: id, name
- Fields:
- (property -> db.field -> typecast)
- 0 -> id -> int
- 1 -> name
- Relations:
- tag->user belongs to user ? load cascaded
- n/a tag.user_id <==> user.id
-
-[tag_context] :: default.tag_user_map
- Entity: Cycle\Schema\Renderer\Tests\Fixtures\TagContext
- Mapper: Cycle\ORM\Mapper\Mapper
- Constrain: not defined
- Repository: not defined
- Primary key: not defined
- Fields: not defined
- Relations: not defined
diff --git a/tests/Schema/Renderer/Fixtures/console_output_with_custom_properties.txt b/tests/Schema/Renderer/Fixtures/console_output_with_custom_properties.txt
deleted file mode 100644
index 964d430..0000000
--- a/tests/Schema/Renderer/Fixtures/console_output_with_custom_properties.txt
+++ /dev/null
@@ -1,37 +0,0 @@
-[35m[Cycle\Schema\Renderer\Tests\Fixtures\User][39m :: [32mdefault[39m.[32muser[39m
- Role: [34muser[39m
- Mapper: [34mCycle\ORM\Mapper\Mapper[39m
- Primary key: [32mid[39m
- Fields:
- ([36mproperty[39m -> [32mdb.field[39m -> [34mtypecast[39m)
- [36m0[39m -> [32mid[39m -> [34mint[39m
- [36m1[39m -> [32memail[39m
- [36m2[39m -> [32mbalance[39m -> [34mfloat[39m
- Relations:
- [35mCycle\Schema\Renderer\Tests\Fixtures\User[39m->[36mtags[39m many to many [35mCycle\Schema\Renderer\Tests\Fixtures\Tag[39m ? load [33mcascaded[39m
- n/a [32muser[39m.[32mid[39m <= [35mtag_context[39m.[32muser_id[39m | [35mtag_context[39m.[32mtag_id[39m => [35mCycle\Schema\Renderer\Tests\Fixtures\Tag[39m.[32mid[39m
- [35mCycle\Schema\Renderer\Tests\Fixtures\User[39m->[36mtag[39m belongs to [35mCycle\Schema\Renderer\Tests\Fixtures\Tag[39m ? load [33mcascaded[39m
- n/a [32muser[39m.[32mtag_id[39m <==> [35mCycle\Schema\Renderer\Tests\Fixtures\Tag[39m.[32mid[39m
- Source: [34mtest[39m
-
-[35m[Cycle\Schema\Renderer\Tests\Fixtures\Tag][39m :: [32mdefault[39m.[32mtag[39m
- Role: [34mtag[39m
- Mapper: [34mCycle\ORM\Mapper\Mapper[39m
- Primary key: [32mid[39m, [32mname[39m
- Fields:
- ([36mproperty[39m -> [32mdb.field[39m -> [34mtypecast[39m)
- [36m0[39m -> [32mid[39m -> [34mint[39m
- [36m1[39m -> [32mname[39m
- Relations:
- [35mCycle\Schema\Renderer\Tests\Fixtures\Tag[39m->[36muser[39m belongs to [35mCycle\Schema\Renderer\Tests\Fixtures\User[39m ? load [33mcascaded[39m
- n/a [32mtag[39m.[32muser_id[39m <==> [35mCycle\Schema\Renderer\Tests\Fixtures\User[39m.[32mid[39m
-
-[35m[Cycle\Schema\Renderer\Tests\Fixtures\TagContext][39m :: [32mdefault[39m.[32mtag_user_map[39m
- Role: [34mtag_context[39m
- Mapper: [34mCycle\ORM\Mapper\Mapper[39m
- Primary key: [31mnot defined[39m
- Fields: [31mnot defined[39m
- Relations: [31mnot defined[39m
- Custom props:
- my_custom_property: [34msuper_value[39m
- 25: [34msuper_value[39m
\ No newline at end of file
diff --git a/tests/Schema/Renderer/Fixtures/generated_schema.php b/tests/Schema/Renderer/Fixtures/generated_schema.php
deleted file mode 100644
index cfb1d02..0000000
--- a/tests/Schema/Renderer/Fixtures/generated_schema.php
+++ /dev/null
@@ -1,101 +0,0 @@
- [
- SchemaInterface::ROLE => null,
- SchemaInterface::ENTITY => 'Cycle\\Schema\\Renderer\\Tests\\Fixtures\\User',
- SchemaInterface::MAPPER => 'Cycle\\ORM\\Mapper\\Mapper',
- SchemaInterface::SOURCE => null,
- SchemaInterface::REPOSITORY => null,
- SchemaInterface::DATABASE => 'default',
- SchemaInterface::TABLE => 'user',
- SchemaInterface::PRIMARY_KEY => 'id',
- SchemaInterface::FIND_BY_KEYS => null,
- SchemaInterface::COLUMNS => ['id', 'email', 'balance'],
- SchemaInterface::RELATIONS => [
- 'tags' => [
- Relation::TYPE => Relation::MANY_TO_MANY,
- Relation::TARGET => 'tag',
- Relation::SCHEMA => [
- Relation::CASCADE => true,
- Relation::THROUGH_ENTITY => 'tag_context',
- Relation::INNER_KEY => 'id',
- Relation::OUTER_KEY => 'id',
- Relation::THROUGH_INNER_KEY => 'user_id',
- Relation::THROUGH_OUTER_KEY => 'tag_id',
- ],
- ],
- 'tag' => [
- Relation::TYPE => Relation::BELONGS_TO,
- Relation::TARGET => 'tag',
- Relation::SCHEMA => [
- Relation::CASCADE => true,
- Relation::INNER_KEY => 'tag_id',
- Relation::OUTER_KEY => 'id',
- ],
- ],
- ],
- SchemaInterface::CHILDREN => null,
- SchemaInterface::SCOPE => null,
- SchemaInterface::TYPECAST => [
- 'id' => 'int',
- 'balance' => 'float',
- ],
- SchemaInterface::SCHEMA => [],
-],
-'tag' => [
- SchemaInterface::ROLE => null,
- SchemaInterface::ENTITY => 'Cycle\\Schema\\Renderer\\Tests\\Fixtures\\Tag',
- SchemaInterface::MAPPER => 'Cycle\\ORM\\Mapper\\Mapper',
- SchemaInterface::SOURCE => null,
- SchemaInterface::REPOSITORY => null,
- SchemaInterface::DATABASE => 'default',
- SchemaInterface::TABLE => 'tag',
- SchemaInterface::PRIMARY_KEY => ['id', 'name'],
- SchemaInterface::FIND_BY_KEYS => null,
- SchemaInterface::COLUMNS => ['id', 'name'],
- SchemaInterface::RELATIONS => [
- 'user' => [
- Relation::TYPE => Relation::BELONGS_TO,
- Relation::TARGET => 'user',
- Relation::SCHEMA => [
- Relation::CASCADE => true,
- Relation::INNER_KEY => 'user_id',
- Relation::OUTER_KEY => 'id',
- ],
- ],
- ],
- SchemaInterface::CHILDREN => null,
- SchemaInterface::SCOPE => null,
- SchemaInterface::TYPECAST => [
- 'id' => 'int',
- ],
- SchemaInterface::SCHEMA => [],
-],
-'tag_context' => [
- SchemaInterface::ROLE => null,
- SchemaInterface::ENTITY => 'Cycle\\Schema\\Renderer\\Tests\\Fixtures\\TagContext',
- SchemaInterface::MAPPER => 'Cycle\\ORM\\Mapper\\Mapper',
- SchemaInterface::SOURCE => null,
- SchemaInterface::REPOSITORY => null,
- SchemaInterface::DATABASE => 'default',
- SchemaInterface::TABLE => 'tag_user_map',
- SchemaInterface::PRIMARY_KEY => null,
- SchemaInterface::FIND_BY_KEYS => null,
- SchemaInterface::COLUMNS => [],
- SchemaInterface::RELATIONS => [],
- SchemaInterface::CHILDREN => null,
- SchemaInterface::SCOPE => null,
- SchemaInterface::TYPECAST => [
- 'id' => 'int',
- 'user_id' => 'int',
- 'tag_id' => 'int',
- ],
- SchemaInterface::SCHEMA => [],
-]
-];
\ No newline at end of file
diff --git a/tests/Schema/Renderer/ConsoleRenderer/DefaultSchemaOutputRendererTest.php b/tests/Schema/Renderer/OutputSchemaRendererTest.php
similarity index 71%
rename from tests/Schema/Renderer/ConsoleRenderer/DefaultSchemaOutputRendererTest.php
rename to tests/Schema/Renderer/OutputSchemaRendererTest.php
index 05dc5a6..8affa67 100644
--- a/tests/Schema/Renderer/ConsoleRenderer/DefaultSchemaOutputRendererTest.php
+++ b/tests/Schema/Renderer/OutputSchemaRendererTest.php
@@ -2,20 +2,21 @@
declare(strict_types=1);
-namespace Cycle\Schema\Renderer\Tests\ConsoleRenderer;
+namespace Cycle\Schema\Renderer\Tests;
use Cycle\ORM\Mapper\Mapper;
use Cycle\ORM\Relation;
+use Cycle\ORM\Schema;
use Cycle\ORM\SchemaInterface;
-use Cycle\Schema\Renderer\ConsoleRenderer\DefaultSchemaOutputRenderer;
-use Cycle\Schema\Renderer\ConsoleRenderer\Formatters\StyledFormatter;
-use Cycle\Schema\Renderer\ConsoleRenderer\Renderers\PropertyRenderer;
-use Cycle\Schema\Renderer\Tests\Fixtures\Tag;
-use Cycle\Schema\Renderer\Tests\Fixtures\TagContext;
-use Cycle\Schema\Renderer\Tests\Fixtures\User;
+use Cycle\Schema\Renderer\ConsoleRenderer\Renderer\PropertyRenderer;
+use Cycle\Schema\Renderer\OutputSchemaRenderer;
+use Cycle\Schema\Renderer\SchemaToArrayConverter;
+use Cycle\Schema\Renderer\Tests\Fixture\Tag;
+use Cycle\Schema\Renderer\Tests\Fixture\TagContext;
+use Cycle\Schema\Renderer\Tests\Fixture\User;
use PHPUnit\Framework\TestCase;
-class DefaultSchemaOutputRendererTest extends TestCase
+final class OutputSchemaRendererTest extends TestCase
{
private array $schemaArray;
@@ -56,7 +57,7 @@ protected function setUp(): void
Relation::OUTER_KEY => 'id',
],
],
- ]
+ ],
],
Tag::class => [
SchemaInterface::ROLE => 'tag',
@@ -76,8 +77,8 @@ protected function setUp(): void
Relation::INNER_KEY => 'user_id',
Relation::OUTER_KEY => 'id',
],
- ]
- ]
+ ],
+ ],
],
TagContext::class => [
SchemaInterface::ROLE => 'tag_context',
@@ -89,34 +90,47 @@ protected function setUp(): void
SchemaInterface::SCHEMA => [],
SchemaInterface::RELATIONS => [],
'my_custom_property' => 'super_value',
- 25 => 'super_value'
- ]
+ 25 => 'super_value',
+ ],
];
}
public function testSchemaShouldBeRendered(): void
{
- $renderer = new DefaultSchemaOutputRenderer(
- $this->schemaArray, new StyledFormatter()
- );
+ $renderer = new OutputSchemaRenderer(OutputSchemaRenderer::FORMAT_CONSOLE_COLOR);
+
+ $expected = file_get_contents(__DIR__ . '/Fixture/console_output.stub.txt');
$this->assertSame(
- file_get_contents(__DIR__ . '/../Fixtures/console_output.txt'),
- implode("\n\n", iterator_to_array($renderer))
+ $expected,
+ $renderer->render($this->schemaArray)
);
}
- public function testSchemaWithExtraPropertiesShouldBeRendered(): void
+ public function testPlainFormat(): void
{
- $renderer = new DefaultSchemaOutputRenderer(
- $this->schemaArray, new StyledFormatter()
+ $schema = new Schema($this->schemaArray);
+ $schemaArray = (new SchemaToArrayConverter())->convert($schema);
+ $renderer = new OutputSchemaRenderer(OutputSchemaRenderer::FORMAT_PLAIN_TEXT);
+
+ $expected = file_get_contents(__DIR__ . '/Fixture/console_output_plain.stub.txt');
+
+ $this->assertSame(
+ $expected,
+ $renderer->render($schemaArray)
);
+ }
+ public function testSchemaWithExtraPropertiesShouldBeRendered(): void
+ {
+ $renderer = new OutputSchemaRenderer(OutputSchemaRenderer::FORMAT_CONSOLE_COLOR);
$renderer->addRenderer(new PropertyRenderer(SchemaInterface::SOURCE, 'Source'));
+ $expected = file_get_contents(__DIR__ . '/Fixture/console_output_with_custom_properties.stub.txt');
+
$this->assertSame(
- file_get_contents(__DIR__ . '/../Fixtures/console_output_with_custom_properties.txt'),
- implode("\n\n", iterator_to_array($renderer))
+ $expected,
+ $renderer->render($this->schemaArray)
);
}
}
diff --git a/tests/Schema/Renderer/PhpSchemaRendererTest.php b/tests/Schema/Renderer/PhpSchemaRendererTest.php
new file mode 100644
index 0000000..b25e9d6
--- /dev/null
+++ b/tests/Schema/Renderer/PhpSchemaRendererTest.php
@@ -0,0 +1,176 @@
+ [
+ SchemaInterface::ROLE => 'user',
+ SchemaInterface::MAPPER => Mapper::class,
+ SchemaInterface::DATABASE => 'default',
+ SchemaInterface::TABLE => 'user',
+ SchemaInterface::PRIMARY_KEY => 'id',
+ SchemaInterface::COLUMNS => ['id', 'email', 'balance'],
+ SchemaInterface::TYPECAST => ['id' => 'int', 'balance' => 'float'],
+ SchemaInterface::SCHEMA => [],
+ SchemaInterface::RELATIONS => [
+ 'tags' => [
+ Relation::TYPE => Relation::MANY_TO_MANY,
+ Relation::TARGET => Tag::class,
+ Relation::SCHEMA => [
+ Relation::CASCADE => true,
+ Relation::THROUGH_ENTITY => 'tag_context',
+ Relation::INNER_KEY => 'id',
+ Relation::OUTER_KEY => 'id',
+ Relation::THROUGH_INNER_KEY => 'user_id',
+ Relation::THROUGH_OUTER_KEY => 'tag_id',
+ ],
+ ],
+ 'tag' => [
+ Relation::TYPE => Relation::BELONGS_TO,
+ Relation::TARGET => Tag::class,
+ Relation::SCHEMA => [
+ Relation::CASCADE => true,
+ Relation::INNER_KEY => 'tag_id',
+ Relation::OUTER_KEY => 'id',
+ ],
+ ],
+ ],
+ ],
+ Tag::class => [
+ SchemaInterface::ROLE => 'tag',
+ SchemaInterface::MAPPER => Mapper::class,
+ SchemaInterface::DATABASE => 'default',
+ SchemaInterface::TABLE => 'tag',
+ SchemaInterface::PRIMARY_KEY => ['id', 'name'],
+ SchemaInterface::COLUMNS => ['id', 'name'],
+ SchemaInterface::TYPECAST => ['id' => 'int'],
+ SchemaInterface::SCHEMA => [],
+ SchemaInterface::RELATIONS => [
+ 'user' => [
+ Relation::TYPE => Relation::BELONGS_TO,
+ Relation::TARGET => User::class,
+ Relation::SCHEMA => [
+ Relation::CASCADE => true,
+ Relation::INNER_KEY => 'user_id',
+ Relation::OUTER_KEY => 'id',
+ ],
+ ],
+ ],
+ ],
+ TagContext::class => [
+ SchemaInterface::ROLE => 'tag_context',
+ SchemaInterface::MAPPER => Mapper::class,
+ SchemaInterface::DATABASE => 'default',
+ SchemaInterface::TABLE => 'tag_user_map',
+ SchemaInterface::COLUMNS => [],
+ SchemaInterface::TYPECAST => ['id' => 'int', 'user_id' => 'int', 'tag_id' => 'int'],
+ SchemaInterface::SCHEMA => [],
+ SchemaInterface::RELATIONS => [],
+ ],
+ ]);
+
+ $this->schema = (new SchemaToArrayConverter())->convert($schema);
+ }
+
+ public function testRenderSchemaToPhpCode(): void
+ {
+ $renderer = new PhpSchemaRenderer();
+ $expected = file_get_contents(__DIR__ . '/Fixture/generated_schema.stub.php');
+
+ $this->assertSame(
+ $expected,
+ $renderer->render($this->schema)
+ );
+ }
+
+ public function testRenderEmptySchemaToPhpCode(): void
+ {
+ $renderer = new PhpSchemaRenderer();
+
+ $this->assertSame(
+ <<render([])
+ );
+ }
+
+ public function testRenderSchemaWithCustomPropertyToPhpCode(): void
+ {
+ $renderer = new PhpSchemaRenderer();
+
+ $this->assertSame(
+ << [
+ Schema::ROLE => 'tag_context',
+ Schema::MAPPER => 'Cycle\\\\ORM\\\\Mapper\\\\Mapper',
+ Schema::DATABASE => 'default',
+ Schema::TABLE => 'tag_user_map',
+ Schema::COLUMNS => [],
+ Schema::TYPECAST => [
+ 'id' => 'int',
+ 'user_id' => 'int',
+ 'tag_id' => 'int',
+ ],
+ Schema::SCHEMA => [],
+ '100' => 'Hello world',
+ 'hello' => 'world',
+ ],
+ ];
+
+ PHP
+ ,
+ $renderer->render([
+ TagContext::class => [
+ SchemaInterface::ROLE => 'tag_context',
+ SchemaInterface::MAPPER => Mapper::class,
+ SchemaInterface::DATABASE => 'default',
+ SchemaInterface::TABLE => 'tag_user_map',
+ SchemaInterface::COLUMNS => [],
+ SchemaInterface::TYPECAST => ['id' => 'int', 'user_id' => 'int', 'tag_id' => 'int'],
+ SchemaInterface::SCHEMA => [],
+ 100 => 'Hello world',
+ 'hello' => 'world',
+ ],
+ ])
+ );
+ }
+}
diff --git a/tests/Schema/Renderer/SchemaToArrayConverterTest.php b/tests/Schema/Renderer/SchemaToArrayConverterTest.php
index affdde9..717122a 100644
--- a/tests/Schema/Renderer/SchemaToArrayConverterTest.php
+++ b/tests/Schema/Renderer/SchemaToArrayConverterTest.php
@@ -1,5 +1,7 @@
'value'
+ 123 => 'value',
],
-
]);
}
@@ -67,43 +68,39 @@ public function testObjectShouldBeConvertedToArray()
SchemaInterface::ENTITY => User::class,
SchemaInterface::MAPPER => Mapper::class,
SchemaInterface::SOURCE => 'users',
- SchemaInterface::REPOSITORY => null,
SchemaInterface::DATABASE => 'default',
SchemaInterface::TABLE => 'user',
SchemaInterface::PRIMARY_KEY => 'id',
- SchemaInterface::FIND_BY_KEYS => null,
SchemaInterface::COLUMNS => ['id', 'email', 'balance'],
SchemaInterface::RELATIONS => [
'tags' => [
Relation::TYPE => Relation::MANY_TO_MANY,
- Relation::TARGET => 'Cycle\Schema\Renderer\Tests\Fixtures\Tag',
+ Relation::TARGET => 'Cycle\Schema\Renderer\Tests\Fixture\Tag',
Relation::SCHEMA => [
Relation::CASCADE => true,
- Relation::THROUGH_ENTITY => 'Cycle\Schema\Renderer\Tests\Fixtures\TagContext',
+ Relation::THROUGH_ENTITY => 'Cycle\Schema\Renderer\Tests\Fixture\TagContext',
Relation::INNER_KEY => 'id',
Relation::OUTER_KEY => 'id',
Relation::THROUGH_INNER_KEY => 'user_id',
Relation::THROUGH_OUTER_KEY => 'tag_id',
- ]
+ ],
],
'tag' => [
Relation::TYPE => 12,
- Relation::TARGET => 'Cycle\Schema\Renderer\Tests\Fixtures\Tag',
+ Relation::TARGET => 'Cycle\Schema\Renderer\Tests\Fixture\Tag',
Relation::SCHEMA => [
Relation::CASCADE => true,
Relation::INNER_KEY => 'tag_id',
Relation::OUTER_KEY => 'id',
- ]
- ]
+ ],
+ ],
],
- SchemaInterface::CHILDREN => null,
- SchemaInterface::SCOPE => null,
SchemaInterface::TYPECAST => [
'id' => 'int',
'balance' => 'float',
],
SchemaInterface::SCHEMA => [],
- ]
+ ],
], (new SchemaToArrayConverter())->convert($this->schema));
}
@@ -114,44 +111,40 @@ public function testObjectWithCustomPropertiesShouldBeConvertedToArray()
SchemaInterface::ENTITY => User::class,
SchemaInterface::MAPPER => Mapper::class,
SchemaInterface::SOURCE => 'users',
- SchemaInterface::REPOSITORY => null,
SchemaInterface::DATABASE => 'default',
SchemaInterface::TABLE => 'user',
SchemaInterface::PRIMARY_KEY => 'id',
- SchemaInterface::FIND_BY_KEYS => null,
SchemaInterface::COLUMNS => ['id', 'email', 'balance'],
SchemaInterface::RELATIONS => [
'tags' => [
Relation::TYPE => Relation::MANY_TO_MANY,
- Relation::TARGET => 'Cycle\Schema\Renderer\Tests\Fixtures\Tag',
+ Relation::TARGET => 'Cycle\Schema\Renderer\Tests\Fixture\Tag',
Relation::SCHEMA => [
Relation::CASCADE => true,
- Relation::THROUGH_ENTITY => 'Cycle\Schema\Renderer\Tests\Fixtures\TagContext',
+ Relation::THROUGH_ENTITY => 'Cycle\Schema\Renderer\Tests\Fixture\TagContext',
Relation::INNER_KEY => 'id',
Relation::OUTER_KEY => 'id',
Relation::THROUGH_INNER_KEY => 'user_id',
Relation::THROUGH_OUTER_KEY => 'tag_id',
- ]
+ ],
],
'tag' => [
Relation::TYPE => 12,
- Relation::TARGET => 'Cycle\Schema\Renderer\Tests\Fixtures\Tag',
+ Relation::TARGET => 'Cycle\Schema\Renderer\Tests\Fixture\Tag',
Relation::SCHEMA => [
Relation::CASCADE => true,
Relation::INNER_KEY => 'tag_id',
Relation::OUTER_KEY => 'id',
- ]
- ]
+ ],
+ ],
],
- SchemaInterface::CHILDREN => null,
- SchemaInterface::SCOPE => null,
SchemaInterface::TYPECAST => [
'id' => 'int',
'balance' => 'float',
],
SchemaInterface::SCHEMA => [],
- 123 => 'value'
- ]
+ 123 => 'value',
+ ],
], (new SchemaToArrayConverter())->convert($this->schema, [123]));
}
}
diff --git a/tests/Schema/Renderer/SchemaToPhpFileRendererTest.php b/tests/Schema/Renderer/SchemaToPhpFileRendererTest.php
deleted file mode 100644
index a853583..0000000
--- a/tests/Schema/Renderer/SchemaToPhpFileRendererTest.php
+++ /dev/null
@@ -1,253 +0,0 @@
- [
- SchemaInterface::ROLE => 'user',
- SchemaInterface::MAPPER => Mapper::class,
- SchemaInterface::DATABASE => 'default',
- SchemaInterface::TABLE => 'user',
- SchemaInterface::PRIMARY_KEY => 'id',
- SchemaInterface::COLUMNS => ['id', 'email', 'balance'],
- SchemaInterface::TYPECAST => ['id' => 'int', 'balance' => 'float'],
- SchemaInterface::SCHEMA => [],
- SchemaInterface::RELATIONS => [
- 'tags' => [
- Relation::TYPE => Relation::MANY_TO_MANY,
- Relation::TARGET => Tag::class,
- Relation::SCHEMA => [
- Relation::CASCADE => true,
- Relation::THROUGH_ENTITY => 'tag_context',
- Relation::INNER_KEY => 'id',
- Relation::OUTER_KEY => 'id',
- Relation::THROUGH_INNER_KEY => 'user_id',
- Relation::THROUGH_OUTER_KEY => 'tag_id',
- ],
- ],
- 'tag' => [
- Relation::TYPE => Relation::BELONGS_TO,
- Relation::TARGET => Tag::class,
- Relation::SCHEMA => [
- Relation::CASCADE => true,
- Relation::INNER_KEY => 'tag_id',
- Relation::OUTER_KEY => 'id',
- ],
- ],
- ]
- ],
- Tag::class => [
- SchemaInterface::ROLE => 'tag',
- SchemaInterface::MAPPER => Mapper::class,
- SchemaInterface::DATABASE => 'default',
- SchemaInterface::TABLE => 'tag',
- SchemaInterface::PRIMARY_KEY => ['id', 'name'],
- SchemaInterface::COLUMNS => ['id', 'name'],
- SchemaInterface::TYPECAST => ['id' => 'int'],
- SchemaInterface::SCHEMA => [],
- SchemaInterface::RELATIONS => [
- 'user' => [
- Relation::TYPE => Relation::BELONGS_TO,
- Relation::TARGET => User::class,
- Relation::SCHEMA => [
- Relation::CASCADE => true,
- Relation::INNER_KEY => 'user_id',
- Relation::OUTER_KEY => 'id',
- ],
- ]
- ]
- ],
- TagContext::class => [
- SchemaInterface::ROLE => 'tag_context',
- SchemaInterface::MAPPER => Mapper::class,
- SchemaInterface::DATABASE => 'default',
- SchemaInterface::TABLE => 'tag_user_map',
- SchemaInterface::COLUMNS => [],
- SchemaInterface::TYPECAST => ['id' => 'int', 'user_id' => 'int', 'tag_id' => 'int'],
- SchemaInterface::SCHEMA => [],
- SchemaInterface::RELATIONS => []
- ]
- ]);
-
- $this->schema = (new SchemaToArrayConverter())->convert($schema);
- }
-
- public function testRenderSchemaToPhpCode(): void
- {
- $renderer = new SchemaToPhpFileRenderer($this->schema, new DefaultSchemaGenerator());
-
- $this->assertSame(
- file_get_contents(__DIR__ . '/Fixtures/generated_schema.php'),
- $renderer->render()
- );
- }
-
- public function testRenderEmptySchemaToPhpCode(): void
- {
- $renderer = new SchemaToPhpFileRenderer([], new DefaultSchemaGenerator());
-
- $this->assertSame(
- <<render()
- );
- }
-
- public function testRenderSchemaWithCustomPropertyToPhpCode(): void
- {
- $renderer = new SchemaToPhpFileRenderer([
- TagContext::class => [
- SchemaInterface::ROLE => 'tag_context',
- SchemaInterface::MAPPER => Mapper::class,
- SchemaInterface::DATABASE => 'default',
- SchemaInterface::TABLE => 'tag_user_map',
- SchemaInterface::COLUMNS => [],
- SchemaInterface::TYPECAST => ['id' => 'int', 'user_id' => 'int', 'tag_id' => 'int'],
- SchemaInterface::SCHEMA => [],
- 100 => 'Hello world',
- 'hello' => 'world'
- ]
- ], new DefaultSchemaGenerator());
-
- $this->assertSame(
- << [
- SchemaInterface::ROLE => 'tag_context',
- SchemaInterface::ENTITY => null,
- SchemaInterface::MAPPER => 'Cycle\\\\ORM\\\\Mapper\\\\Mapper',
- SchemaInterface::SOURCE => null,
- SchemaInterface::REPOSITORY => null,
- SchemaInterface::DATABASE => 'default',
- SchemaInterface::TABLE => 'tag_user_map',
- SchemaInterface::PRIMARY_KEY => null,
- SchemaInterface::FIND_BY_KEYS => null,
- SchemaInterface::COLUMNS => [],
- SchemaInterface::RELATIONS => [],
- SchemaInterface::CHILDREN => null,
- SchemaInterface::SCOPE => null,
- SchemaInterface::TYPECAST => [
- 'id' => 'int',
- 'user_id' => 'int',
- 'tag_id' => 'int',
- ],
- SchemaInterface::SCHEMA => [],
- 100 => 'Hello world',
- 'hello' => 'world',
-]
-];
-EOL
- ,
- $renderer->render()
- );
- }
-
- public function testRenderSchemaWithCustomPropertyWithDefinedGeneratorToPhpCode(): void
- {
- $generator = new DefaultSchemaGenerator([
- 100 => new class implements Generator {
- public function generate(array $schema, string $role): array
- {
- return [
- new VarExporter('Hello', 'World', true)
- ];
- }
- }
- ]);
-
- $renderer = new SchemaToPhpFileRenderer([
- TagContext::class => [
- SchemaInterface::ROLE => 'tag_context',
- SchemaInterface::MAPPER => Mapper::class,
- SchemaInterface::DATABASE => 'default',
- SchemaInterface::TABLE => 'tag_user_map',
- SchemaInterface::COLUMNS => [],
- SchemaInterface::TYPECAST => ['id' => 'int', 'user_id' => 'int', 'tag_id' => 'int'],
- SchemaInterface::SCHEMA => [],
- 100 => 'Hello world',
- 'hello' => 'world',
- ]
- ], $generator);
-
- $this->assertSame(
- << [
- 'Hello' => 'World',
- SchemaInterface::ROLE => 'tag_context',
- SchemaInterface::ENTITY => null,
- SchemaInterface::MAPPER => 'Cycle\\\\ORM\\\\Mapper\\\\Mapper',
- SchemaInterface::SOURCE => null,
- SchemaInterface::REPOSITORY => null,
- SchemaInterface::DATABASE => 'default',
- SchemaInterface::TABLE => 'tag_user_map',
- SchemaInterface::PRIMARY_KEY => null,
- SchemaInterface::FIND_BY_KEYS => null,
- SchemaInterface::COLUMNS => [],
- SchemaInterface::RELATIONS => [],
- SchemaInterface::CHILDREN => null,
- SchemaInterface::SCOPE => null,
- SchemaInterface::TYPECAST => [
- 'id' => 'int',
- 'user_id' => 'int',
- 'tag_id' => 'int',
- ],
- SchemaInterface::SCHEMA => [],
- 'hello' => 'world',
-]
-];
-EOL
- ,
- $renderer->render()
- );
- }
-}